diff options
Diffstat (limited to 'libxsd-frontend/xsd-frontend/transformations/restriction.cxx')
-rw-r--r-- | libxsd-frontend/xsd-frontend/transformations/restriction.cxx | 576 |
1 files changed, 0 insertions, 576 deletions
diff --git a/libxsd-frontend/xsd-frontend/transformations/restriction.cxx b/libxsd-frontend/xsd-frontend/transformations/restriction.cxx deleted file mode 100644 index edd74be..0000000 --- a/libxsd-frontend/xsd-frontend/transformations/restriction.cxx +++ /dev/null @@ -1,576 +0,0 @@ -// file : xsd-frontend/transformations/restriction.cxx -// copyright : Copyright (c) 2006-2014 Code Synthesis Tools CC -// license : GNU GPL v2 + exceptions; see accompanying LICENSE file - -#include <vector> -#include <iostream> - -#include <xsd-frontend/semantic-graph.hxx> -#include <xsd-frontend/traversal.hxx> - -#include <xsd-frontend/transformations/restriction.hxx> - -using namespace std; - -namespace XSDFrontend -{ - typedef Transformations::Restriction::Failed Failed; - typedef std::vector<SemanticGraph::Complex*> BaseList; - - namespace - { - // - // - struct Complex: Traversal::Complex - { - Complex (SemanticGraph::Schema& schema) - : schema_ (schema) - { - } - - virtual void - traverse (Type& c) - { - using namespace SemanticGraph; - using SemanticGraph::Complex; - - if (c.context ().count ("xsd-frontend-restriction-seen")) - return; - - c.context ().set ("xsd-frontend-restriction-seen", true); - - // The base content model can be spread over several types - // in the inheritance-by-extension hierarchy. - // - BaseList base_model; - - // Since attribute wildcards don't have names, we will have - // to rely on their relative position to find association. - // - BaseList base_list; - - // Current implementation of semantic graph uses the same Restricts - // edge for both simple type/content restriction and complex content - // restriction. Here we are interested in the complex content only. - // - // - if (c.inherits_p () && - c.inherits ().is_a<Restricts> () && - !c.inherits ().base ().is_a<AnyType> ()) - { - // Go down our inheritance hierarchy until the end or the previous - // restriction. - // - Complex* base (&c); - - while ((base = dynamic_cast<Complex*> (&base->inherits ().base ()))) - { - traverse (*base); // Make sure our base is processed. - - // Handle attributes. - // - merge_attributes (c, *base); - - base_list.push_back (base); - - // Collect types that have complex content. - // - if (base->contains_compositor_p ()) - base_model.push_back (base); - - if (!base->inherits_p () || base->inherits ().is_a<Restricts> ()) - break; - } - - // Handle attribute wildcards. - // - handle_any_attributes (c, base_list); - - // Handle complex content (not for the faint of heart). - // - if (c.contains_compositor_p ()) - { - // Traverse both restricted content model and base content - // model (in base_model) while looking for matches. - // - Compositor& root (c.contains_compositor ().compositor ()); - - if (base_model.size () == 1) - handle (root, - base_model[0]->contains_compositor ().compositor ()); - else - { - Compositor::ContainsIterator i (root.contains_begin ()); - BaseList::reverse_iterator j (base_model.rbegin ()); - - for (; i != root.contains_end (); ++i, ++j) - { - Particle& p (i->particle ()); - - if (!p.is_a<Compositor> ()) - { - wcerr << p.file () << ":" << p.line () << ":" << p.column () - << ": error: expected compositor instead of particle" - << endl; - throw Failed (); - } - - for (; j != base_model.rend (); ++j) - { - if (match (p, (*j)->contains_compositor ().compositor ())) - { - handle (p, (*j)->contains_compositor ().compositor ()); - break; - } - } - - if (j == base_model.rend ()) - break; - } - - if (i != root.contains_end ()) - { - Particle& p (i->particle ()); - - wcerr << p.file () << ":" << p.line () << ":" << p.column () - << ": error: unable to match restricted compositor" - << endl; - throw Failed (); - } - } - } - } - - // Traverse anonymous types (via elements & attributes). - // - Traversal::Complex::names (c); - } - - private: - void - handle (SemanticGraph::Particle& r, SemanticGraph::Particle& b) - { - using namespace SemanticGraph; - - if (r.is_a<Compositor> ()) - { - Compositor& rc (dynamic_cast<Compositor&> (r)); - Compositor& bc (dynamic_cast<Compositor&> (b)); - - Compositor::ContainsIterator i (rc.contains_begin ()); - Compositor::ContainsIterator j (bc.contains_begin ()); - - for (; i != rc.contains_end (); ++i, ++j) - { - for (; j != bc.contains_end (); ++j) - { - Particle& rp (i->particle ()); - Particle& bp (j->particle ()); - - if (typeid (rp) != typeid (bp)) - continue; - - if (match (rp, bp)) - { - handle (rp, bp); - break; - } - } - - if (j == bc.contains_end ()) - break; - } - - if (i != rc.contains_end ()) - { - Particle& p (i->particle ()); - - wcerr << p.file () << ":" << p.line () << ":" << p.column () - << ": error: unable to match restricted particle" - << endl; - throw Failed (); - } - - rc.context ().set ("xsd-frontend-restriction-correspondence", &bc); - } - else if (r.is_a<Element> ()) - { - // Element - // - r.context ().set ("xsd-frontend-restriction-correspondence", - dynamic_cast<Element*> (&b)); - } - else - { - // Wildcard - // - r.context ().set ("xsd-frontend-restriction-correspondence", - dynamic_cast<Any*> (&b)); - } - } - - bool - match (SemanticGraph::Particle& r, SemanticGraph::Particle& b) - { - using namespace SemanticGraph; - - if (typeid (r) != typeid (b)) - return false; - - if (r.is_a<Compositor> ()) - { - Compositor& rc (dynamic_cast<Compositor&> (r)); - Compositor& bc (dynamic_cast<Compositor&> (b)); - - Compositor::ContainsIterator i (rc.contains_begin ()); - - if (i == rc.contains_end ()) - return true; - - Particle& rp (i->particle ()); - - for (Compositor::ContainsIterator j (bc.contains_begin ()); - j != bc.contains_end (); ++j) - { - Particle& bp (j->particle ()); - - if (typeid (rp) != typeid (bp)) - continue; - - if (match (rp, bp)) - return true; - } - } - else if (r.is_a<Element> ()) - { - Element& re (dynamic_cast<Element&> (r)); - Element& be (dynamic_cast<Element&> (b)); - - if (re.qualified_p ()) - { - if (be.qualified_p () && - re.name () == be.name () && - re.namespace_ ().name () == be.namespace_ ().name ()) - return true; - } - else - { - if (!be.qualified_p () && re.name () == be.name ()) - return true; - } - - // @@ Need to take into account substitution groups. - // - } - else - { - // Wildcard. - // - - // @@ To handle this properly we will need to analyze - // namespaces. - // - return true; - } - - return false; - } - - void - merge_attributes (SemanticGraph::Complex& c, - SemanticGraph::Complex& base) - { - using namespace SemanticGraph; - - for (Scope::NamesIterator i (base.names_begin ()), - e (base.names_end ()); i != e; ++i) - { - Attribute* prot (dynamic_cast<Attribute*> (&i->named ())); - - if (prot == 0) - continue; - - Name name (prot->name ()); - Scope::NamesIteratorPair r (c.find (name)); - - Attribute* a (0); - - for (; r.first != r.second; ++r.first) - { - a = dynamic_cast<Attribute*> (&r.first->named ()); - - if (a == 0) - continue; - - if (prot->qualified_p ()) - { - if (a->qualified_p () && - prot->namespace_ ().name () == a->namespace_ ().name ()) - { - break; - } - } - else - { - if (!a->qualified_p ()) - break; - } - - a = 0; - } - - if (a == 0) - { - a = &schema_.new_node<Attribute> (prot->file (), - prot->line (), - prot->column (), - prot->optional_p (), - prot->global_p (), - prot->qualified_p ()); - - schema_.new_edge<Names> (c, *a, name); - - // Transfer namespace. - // - if (prot->qualified_p ()) - { - schema_.new_edge<BelongsToNamespace> (*a, prot->namespace_ ()); - } - - // Default and fixed values if any. - // - if (prot->fixed_p ()) - a->fixed (prot->value ()); - else if (prot->default_p ()) - a->default_ (prot->value ()); - - // Belongs edge. - // - schema_.new_edge<Belongs> (*a, prot->type ()); - - // Transfer annotation. - // - if (prot->annotated_p ()) - schema_.new_edge<Annotates> (prot->annotation (), *a); - } - - a->context ().set ("xsd-frontend-restriction-correspondence", prot); - } - } - - void - handle_any_attributes (SemanticGraph::Complex& c, BaseList& bl) - { - using namespace SemanticGraph; - - BaseList::reverse_iterator bi (bl.rbegin ()), be (bl.rend ()); - Scope::NamesIterator si; - - if (bi != be) - si = (*bi)->names_begin (); - - for (Scope::NamesIterator i (c.names_begin ()), - e (c.names_end ()); i != e; ++i) - { - AnyAttribute* a (dynamic_cast<AnyAttribute*> (&i->named ())); - - if (a == 0) - continue; - - AnyAttribute* p (0); - - while (bi != be) - { - for (; si != (*bi)->names_end (); ++si) - { - p = dynamic_cast<AnyAttribute*> (&si->named ()); - - if (p != 0) - { - ++si; - break; - } - } - - if (p != 0) - break; - - // Didn't find anything in this base. Move on to the next. - // - ++bi; - - if (bi != be) - si = (*bi)->names_begin (); - } - - if (p != 0) - { - a->context ().set ("xsd-frontend-restriction-correspondence", p); - } - else - { - wcerr << a->file () << ":" << a->line () << ":" << a->column () - << ": error: unable to find matching wildcard in base type" - << endl; - throw Failed (); - } - } - } - - private: - SemanticGraph::Schema& schema_; - }; - - // - // - struct Anonymous : Traversal::Element, - Traversal::Attribute - { - Anonymous (Traversal::NodeDispatcher& d1) - : complex_ (&d1, 0) - { - *this >> belongs_ >> complex_; - } - - Anonymous (Traversal::NodeDispatcher& d1, - Traversal::NodeDispatcher& d2) - : complex_ (&d1, &d2) - { - *this >> belongs_ >> complex_; - } - - // Hooks. - // - public: - virtual void - member_pre (SemanticGraph::Member&) - { - } - - virtual void - member_post (SemanticGraph::Member&) - { - } - - public: - - virtual void - traverse (SemanticGraph::Element& e) - { - SemanticGraph::Type& t (e.type ()); - - if (!t.named_p () && !t.context ().count ("seen")) - { - t.context ().set ("seen", true); - - member_pre (e); - - Element::belongs (e, belongs_); - - member_post (e); - - t.context ().remove ("seen"); - } - } - - virtual void - traverse (SemanticGraph::Attribute& a) - { - SemanticGraph::Type& t (a.type ()); - - if (!t.named_p () && !t.context ().count ("seen")) - { - t.context ().set ("seen", true); - - member_pre (a); - - Attribute::belongs (a, belongs_); - - member_post (a); - - t.context ().remove ("seen"); - } - } - - private: - struct Complex : Traversal::Complex - { - Complex (Traversal::NodeDispatcher* d1, - Traversal::NodeDispatcher* d2) - : d1_ (d1), d2_ (d2) - { - } - - virtual void - traverse (SemanticGraph::Complex& c) - { - if (d1_) - d1_->dispatch (c); - - if (d2_) - d2_->dispatch (c); - } - - private: - Traversal::NodeDispatcher* d1_; - Traversal::NodeDispatcher* d2_; - - } complex_; - - Traversal::Belongs belongs_; - }; - - - // Go into implied/included/imported schemas while making sure - // we don't process the same stuff more than once. - // - struct Uses: Traversal::Uses - { - virtual void - traverse (Type& u) - { - SemanticGraph::Schema& s (u.schema ()); - - if (!s.context ().count ("xsd-frontend-restriction-seen")) - { - s.context ().set ("xsd-frontend-restriction-seen", true); - Traversal::Uses::traverse (u); - } - } - }; - } - - namespace Transformations - { - void Restriction:: - transform (SemanticGraph::Schema& s, SemanticGraph::Path const&) - { - Traversal::Schema schema; - Uses uses; - - schema >> uses >> schema; - - Traversal::Names schema_names; - Traversal::Namespace ns; - Traversal::Names ns_names; - - schema >> schema_names >> ns >> ns_names; - - Complex complex_type (s); - Anonymous anonymous (complex_type); - - ns_names >> complex_type; - ns_names >> anonymous; - - Traversal::Names names; - - complex_type >> names >> anonymous; - - // Some twisted schemas do recusive inclusions. - // - s.context ().set ("xsd-frontend-restriction-seen", true); - - schema.dispatch (s); - } - } -} |