diff options
Diffstat (limited to 'libxsd-frontend/xsd-frontend/semantic-graph/elements.hxx')
| -rw-r--r-- | libxsd-frontend/xsd-frontend/semantic-graph/elements.hxx | 997 | 
1 files changed, 997 insertions, 0 deletions
| diff --git a/libxsd-frontend/xsd-frontend/semantic-graph/elements.hxx b/libxsd-frontend/xsd-frontend/semantic-graph/elements.hxx new file mode 100644 index 0000000..98fb180 --- /dev/null +++ b/libxsd-frontend/xsd-frontend/semantic-graph/elements.hxx @@ -0,0 +1,997 @@ +// file      : xsd-frontend/semantic-graph/elements.hxx +// copyright : Copyright (c) 2005-2014 Code Synthesis Tools CC +// license   : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#ifndef XSD_FRONTEND_SEMANTIC_GRAPH_ELEMENTS_HXX +#define XSD_FRONTEND_SEMANTIC_GRAPH_ELEMENTS_HXX + +#include <set> +#include <map> +#include <list> +#include <vector> +#include <iosfwd> +#include <utility> // std::pair +#include <cstdlib> // abort +#include <cassert> + +#include <cutl/container/graph.hxx> +#include <cutl/container/pointer-iterator.hxx> +#include <cutl/compiler/context.hxx> +#include <cutl/fs/path.hxx> + +#include <xsd-frontend/types.hxx> + +namespace XSDFrontend +{ +  namespace SemanticGraph +  { +    using namespace cutl; + +    using container::pointer_iterator; + +    // +    // +    typedef fs::path Path; +    typedef fs::invalid_path InvalidPath; +    typedef std::vector<Path> Paths; + +    typedef compiler::context Context; + +    // +    // +    class Node; +    class Edge; + +    // +    // +    class Annotates; +    class Annotation; + +    // +    // +    class Edge +    { +    public: +      Context& +      context () const +      { +        return context_; +      } + +      virtual +      ~Edge () +      { +      } + +    public: +      template <typename X> +      bool +      is_a () const +      { +        return dynamic_cast<X const*> (this) != 0; +      } + +    private: +      mutable Context context_; +    }; + +    inline bool +    operator== (Edge const& x, Edge const& y) +    { +      return &x == &y; +    } + + +    // +    // +    class Node +    { +    public: +      Context& +      context () const +      { +        return context_; +      } + +    public: +      Path const& +      file () const +      { +        return file_; +      } + +      unsigned long +      line () const +      { +        return line_; +      } + +      unsigned long +      column () const +      { +        return column_; +      } + +    public: +      bool +      annotated_p () const +      { +        return annotates_ != 0; +      } + +      Annotates& +      annotated () const +      { +        return *annotates_; +      } + +      Annotation& +      annotation (); + +    public: +      template <typename X> +      bool +      is_a () const +      { +        return dynamic_cast<X const*> (this) != 0; +      } + +    public: +      virtual +      ~Node () {} + +      Node (Path const& file, unsigned long line, unsigned long column) +          : annotates_ (0), file_ (file), line_ (line), column_ (column) +      { +      } + +      void +      add_edge_right (Annotates& a) +      { +        annotates_ = &a; +      } + +    protected: +      Node () // For virtual inheritance. +      { +        abort (); // Told you so! +      } + +    private: +      mutable Context context_; +      Annotates* annotates_; +      Path file_; +      unsigned long line_; +      unsigned long column_; +    }; + +    inline bool +    operator== (Node const& x, Node const& y) +    { +      return &x == &y; +    } + +    // +    // +    typedef container::graph<Node, Edge> graph; + +    // +    // +    typedef String Name; + + +    // +    // +    class Scope; +    class Nameable; + + +    // +    // +    class Names: public virtual Edge +    { +    public: +      Name +      name () const +      { +        return name_; +      } + +      Scope& +      scope () const +      { +        return *scope_; +      } + +      Nameable& +      named () const +      { +        return *named_; +      } + +    public: +      Names (Name const& name): name_ (name) {} + +      void +      set_left_node (Scope& n) +      { +        scope_ = &n; +      } + +      void +      set_right_node (Nameable& n) +      { +        named_ = &n; +      } + +      void +      clear_left_node (Scope& n) +      { +        assert (scope_ == &n); +        scope_ = 0; +      } + +      void +      clear_right_node (Nameable& n) +      { +        assert (named_ == &n); +        named_ = 0; +      } + +    private: +      Scope* scope_; +      Nameable* named_; +      Name name_; +    }; + + +    class Nameable: public virtual Node +    { +    public: +      bool +      named_p () const +      { +        return named_ != 0; +      } + +      Name +      name () const +      { +        assert (named_p ()); +        return named_->name (); +      } + +      Scope& +      scope () +      { +        assert (named_p ()); +        return named_->scope (); +      } + +      Names& +      named () +      { +        assert (named_p ()); +        return *named_; +      } + +    public: +      Nameable (): named_ (0) {} + +      void +      add_edge_right (Names& e) +      { +        named_ = &e; +      } + +      void +      remove_edge_right (Names& e) +      { +        assert (named_ == &e); +        named_ = 0; +      } + +      using Node::add_edge_right; + +    private: +      Names* named_; +    }; + +    // +    // +    typedef std::set<Nameable*> Nameables; + +    // +    // +    class Scope: public virtual Nameable +    { +    protected: +      typedef std::list<Names*> NamesList; +      typedef std::map<Names*, NamesList::iterator> ListIteratorMap; +      typedef std::map<Name, NamesList> NamesMap; + +    public: +      typedef pointer_iterator<NamesList::iterator> NamesIterator; +      typedef pointer_iterator<NamesList::const_iterator> NamesConstIterator; + +      typedef +      std::pair<NamesConstIterator, NamesConstIterator> +      NamesIteratorPair; + +      NamesIterator +      names_begin () +      { +        return names_.begin (); +      } + +      NamesIterator +      names_end () +      { +        return names_.end (); +      } + +      NamesConstIterator +      names_begin () const +      { +        return names_.begin (); +      } + +      NamesConstIterator +      names_end () const +      { +        return names_.end (); +      } + +      virtual NamesIteratorPair +      find (Name 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 ()); +      } + +      NamesIterator +      find (Names& e) +      { +        ListIteratorMap::iterator i (iterator_map_.find (&e)); +        return i != iterator_map_.end () ? i->second : names_.end (); +      } + +    public: +      Scope (Path const& file, unsigned long line, unsigned long column) +          : Node (file, line, column) +      { +      } + +      void +      add_edge_left (Names& e) +      { +        NamesList::iterator i (names_.insert (names_.end (), &e)); +        iterator_map_[&e] = i; +        names_map_[e.name ()].push_back (&e); +      } + +      void +      remove_edge_left (Names& e) +      { +        ListIteratorMap::iterator i (iterator_map_.find (&e)); +        assert (i != iterator_map_.end ()); + +        names_.erase (i->second); +        iterator_map_.erase (i); + +        NamesMap::iterator j (names_map_.find (e.name ())); + +        for (NamesList::iterator i (j->second.begin ()); +             i != j->second.end (); ++i) +        { +          if (*i == &e) +            i = j->second.erase (i); +        } +      } + +      void +      add_edge_left (Names& e, NamesIterator const& after) +      { +        NamesList::iterator i; + +        if (after.base () == names_.end ()) +          i = names_.insert (names_.begin (), &e); +        else +        { +          NamesList::iterator j (after.base ()); +          i = names_.insert (++j, &e); +        } + +        iterator_map_[&e] = i; +        names_map_[e.name ()].push_back (&e); +      } + +      using Nameable::add_edge_right; + +    protected: +      Scope () {} + +    private: +      NamesList names_; +      ListIteratorMap iterator_map_; +      NamesMap names_map_; +    }; + + +    // +    // +    class Belongs; +    class Inherits; +    class Arguments; + +    class Type: public virtual Nameable +    { +    protected: +      typedef std::vector<Belongs*> Classifies; +      typedef std::vector<Inherits*> Begets; +      typedef std::set<Arguments*> ArgumentsSet; + +    public: +      typedef pointer_iterator<Classifies::const_iterator> ClassifiesIterator; + +      ClassifiesIterator +      classifies_begin () const +      { +        return classifies_.begin (); +      } + +      ClassifiesIterator +      classifies_end () const +      { +        return classifies_.end (); +      } + +      // +      // +      bool +      inherits_p () const +      { +        return inherits_ != 0; +      } + +      Inherits& +      inherits () const +      { +        assert (inherits_ != 0); +        return *inherits_; +      } + +      // +      // +      typedef pointer_iterator<Begets::const_iterator> BegetsIterator; + +      BegetsIterator +      begets_begin () const +      { +        return begets_.begin (); +      } + +      BegetsIterator +      begets_end () const +      { +        return begets_.end (); +      } + +      // +      // +      typedef pointer_iterator<ArgumentsSet::const_iterator> ArgumentsIterator; + +      ArgumentsIterator +      arguments_begin () const +      { +        return arguments_.begin (); +      } + +      ArgumentsIterator +      arguments_end () const +      { +        return arguments_.end (); +      } + +    public: +      Type (): inherits_ (0) {} + +      void +      add_edge_right (Belongs& e) +      { +        classifies_.push_back (&e); +      } + +      void +      add_edge_right (Inherits& e) +      { +        begets_.push_back (&e); +      } + +      using Nameable::add_edge_right; + +      void +      add_edge_left (Arguments& a) +      { +        arguments_.insert (&a); +      } + +      void +      remove_edge_left (Arguments&); + +      void +      add_edge_left (Inherits& e) +      { +        inherits_ = &e; +      } + +    private: +      Inherits* inherits_; +      Begets begets_; +      Classifies classifies_; +      ArgumentsSet arguments_; +    }; + +    class Instance: public virtual Nameable +    { +    public: +      Belongs& +      belongs () const +      { +        return *belongs_; +      } + +      Type& +      type () const; + +      bool +      typed_p () const +      { +        return belongs_ != 0; +      } + +    public: +      Instance (): belongs_ (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_; +      } + +    public: +      void +      set_left_node (Instance& n) +      { +        instance_ = &n; +      } + +      void +      set_right_node (Type& n) +      { +        type_ = &n; +      } + +    private: +      Instance* instance_; +      Type* type_; +    }; + + +    // +    // +    class Inherits: public virtual Edge +    { +    public: +      Type& +      base () const +      { +        return *base_; +      } + +      Type& +      derived () const +      { +        return *derived_; +      } + +    public: +      void +      set_left_node (Type& n) +      { +        derived_ = &n; +      } + +      void +      set_right_node (Type& n) +      { +        base_ = &n; +      } + +    private: +      Type* base_; +      Type* derived_; +    }; + +    class Extends: public virtual Inherits +    { +    }; + +    class Restricts: public virtual Inherits +    { +    public: +      typedef std::map<String, String> Facets; +      typedef Facets::iterator FacetIterator; + +      bool +      facet_empty () +      { +        return facets_.empty (); +      } + +      FacetIterator +      facet_begin () +      { +        return facets_.begin (); +      } + +      FacetIterator +      facet_end () +      { +        return facets_.end (); +      } + +      FacetIterator +      facet_find (String const& name) +      { +        return facets_.find (name); +      } + +      void +      facet_insert (String const& name, String const& value) +      { +        facets_[name] = value; +      } + +      Facets const& +      facets () const +      { +        return facets_; +      } + +    protected: +      Facets facets_; +    }; + + +    // +    // +    class Member; +    class Namespace; + +    class BelongsToNamespace: public virtual Edge +    { +    public: +      Member& +      member () const +      { +        assert (member_ != 0); +        return *member_; +      } + +      Namespace& +      namespace_ () const +      { +        assert (namespace__ != 0); +        return *namespace__; +      } + +    public: +      BelongsToNamespace (): member_ (0), namespace__ (0) {} + +      void +      set_left_node (Member& n) +      { +        member_ = &n; +      } + +      void +      set_right_node (Namespace& n) +      { +        namespace__ = &n; +      } + +    private: +      Member* member_; +      Namespace* namespace__; +    }; + +    // +    // +    class Member: public virtual Instance +    { +    public: +      // Member is global either if it is defined outside any type +      // or it is a ref="" of a global member. +      // +      bool +      global_p () const +      { +        return global_; +      } + +      bool +      qualified_p () const +      { +        return qualified_; +      } + +      // Note that only qualified members belong to a namespace. +      // +      Namespace& +      namespace_ () const +      { +        assert (belongs_to_namespace_ != 0); +        return belongs_to_namespace_->namespace_ (); +      } + + +      // Default and fixed value API. Note that the fixed value semantics +      // is a superset of the default value semantics. As such setting the +      // fixed value appears as if the default value was also set. +      // +      bool +      default_p () const +      { +        return value_type_ != ValueType::none; +      } + +      bool +      fixed_p () const +      { +        return value_type_ == ValueType::fixed; +      } + +      struct NoValue {}; + +      String +      value () const +      { +        if (value_type_ != ValueType::none) +          return value_; +        else +          throw NoValue (); +      } + +      // +      // +      void +      default_ (String const& v) +      { +        value_ = v; +        value_type_ = ValueType::default_; +      } + +      void +      fixed (String const& v) +      { +        value_ = v; +        value_type_ = ValueType::fixed; +      } + +    public: +      Member (bool global, bool qualified) +          : global_ (global), +            qualified_ (qualified), +            belongs_to_namespace_ (0), +            value_type_ (ValueType::none) +      { +      } + +      void +      add_edge_left (BelongsToNamespace& e) +      { +        // In the parser we sometimes re-add the same adge. +        // +        belongs_to_namespace_ = &e; +      } + +      using Instance::add_edge_left; + +    private: +      bool global_; +      bool qualified_; +      BelongsToNamespace* belongs_to_namespace_; + +      struct ValueType +      { +        enum Value +        { +          none, +          default_, +          fixed +        }; +      }; + +      String value_; +      ValueType::Value value_type_; +    }; + + +    // Parametric types. +    // + +    class Specialization: public virtual Type +    { +      typedef std::vector<Arguments*> Argumented; + +    public: +      typedef pointer_iterator<Argumented::iterator> ArgumentedIterator; +      typedef +      pointer_iterator<Argumented::const_iterator> +      ArgumentedConstIterator; + +      ArgumentedIterator +      argumented_begin () +      { +        return argumented_.begin (); +      } + +      ArgumentedConstIterator +      argumented_begin () const +      { +        return argumented_.begin (); +      } + +      ArgumentedIterator +      argumented_end () +      { +        return argumented_.end (); +      } + +      ArgumentedConstIterator +      argumented_end () const +      { +        return argumented_.end (); +      } + +      // Shortcut for one-argument specializations. +      // +      Arguments& +      argumented () const +      { +        return *argumented_[0]; +      } + +    public: +      using Type::add_edge_right; + +      void +      add_edge_right (Arguments& a) +      { +        argumented_.push_back (&a); +      } + +      void +      add_edge_right (Arguments& a, ArgumentedIterator const& pos) +      { +        argumented_.insert (pos.base (), &a); +      } + +      void +      remove_edge_right (Arguments&); + +    private: +      Argumented argumented_; +    }; + +    class Arguments: public virtual Edge +    { +    public: +      Type& +      type () const +      { +        return *type_; +      } + +      Specialization& +      specialization () const +      { +        return *specialization_; +      } + +    public: +      void +      set_left_node (Type& n) +      { +        type_ = &n; +      } + +      void +      clear_left_node (Type& n) +      { +        assert (type_ == &n); +        type_ = 0; +      } + +      void +      set_right_node (Specialization& s) +      { +        specialization_ = &s; +      } + +      void +      clear_right_node (Specialization& s) +      { +        assert (specialization_ == &s); +        specialization_ = 0; +      } + +    private: +      Type* type_; +      Specialization* specialization_; +    }; + + +    // +    // +    class AnyType: public virtual Type +    { +    public: +      AnyType (Path const& file, unsigned long line, unsigned long column) +          : Node (file, line, column) +      { +      } + +    protected: +      AnyType () {} // For virtual inheritance. +    }; + + +    // +    // +    class AnySimpleType: public virtual Type +    { +    public: +      AnySimpleType (Path const& file, unsigned long line, unsigned long column) +          : Node (file, line, column) +      { +      } + +    protected: +      AnySimpleType () {} // For virtual inheritance. +    }; +  } +} + +// ADL won't find it because Path is a typedef. Note that this +// function prints in native format. +// +std::wostream& +operator<< (std::wostream& os, XSDFrontend::SemanticGraph::Path const& path); + +#endif  // XSD_FRONTEND_SEMANTIC_GRAPH_ELEMENTS_HXX | 
