aboutsummaryrefslogtreecommitdiff
path: root/xsd-frontend/transformations/restriction.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'xsd-frontend/transformations/restriction.cxx')
-rw-r--r--xsd-frontend/transformations/restriction.cxx575
1 files changed, 0 insertions, 575 deletions
diff --git a/xsd-frontend/transformations/restriction.cxx b/xsd-frontend/transformations/restriction.cxx
deleted file mode 100644
index ade1a22..0000000
--- a/xsd-frontend/transformations/restriction.cxx
+++ /dev/null
@@ -1,575 +0,0 @@
-// file : xsd-frontend/transformations/restriction.cxx
-// 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);
- }
- }
-}