aboutsummaryrefslogtreecommitdiff
path: root/xsd-frontend/transformations
diff options
context:
space:
mode:
Diffstat (limited to 'xsd-frontend/transformations')
-rw-r--r--xsd-frontend/transformations/anonymous.cxx1015
-rw-r--r--xsd-frontend/transformations/anonymous.hxx56
-rw-r--r--xsd-frontend/transformations/enum-synthesis.cxx244
-rw-r--r--xsd-frontend/transformations/enum-synthesis.hxx29
-rw-r--r--xsd-frontend/transformations/restriction.cxx575
-rw-r--r--xsd-frontend/transformations/restriction.hxx35
-rw-r--r--xsd-frontend/transformations/schema-per-type.cxx473
-rw-r--r--xsd-frontend/transformations/schema-per-type.hxx61
-rw-r--r--xsd-frontend/transformations/simplifier.cxx161
-rw-r--r--xsd-frontend/transformations/simplifier.hxx29
10 files changed, 0 insertions, 2678 deletions
diff --git a/xsd-frontend/transformations/anonymous.cxx b/xsd-frontend/transformations/anonymous.cxx
deleted file mode 100644
index 7b3e86d..0000000
--- a/xsd-frontend/transformations/anonymous.cxx
+++ /dev/null
@@ -1,1015 +0,0 @@
-// file : xsd-frontend/transformations/anonymous.cxx
-// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
-
-#include <xsd-frontend/transformations/anonymous.hxx>
-
-#include <xsd-frontend/semantic-graph.hxx>
-#include <xsd-frontend/traversal.hxx>
-
-#include <iostream>
-#include <sstream>
-#include <typeinfo>
-
-using std::wcerr;
-using std::endl;
-
-namespace XSDFrontend
-{
- namespace
- {
- using Transformations::AnonymousNameTranslator;
-
- //
- //
- struct CompareMembers: Traversal::Element,
- Traversal::Attribute,
- Traversal::Any,
- Traversal::AnyAttribute
- {
- CompareMembers (SemanticGraph::Nameable& m, bool& r)
- : member_ (m), result_ (r)
- {
- }
-
- virtual void
- traverse (SemanticGraph::Element& x)
- {
- using SemanticGraph::Element;
-
- Element& y (dynamic_cast<Element&> (member_));
-
- // Check cardinalities.
- //
- if (x.min () != y.min () || x.max () != y.max ())
- return;
-
- traverse_member (x);
- }
-
- virtual void
- traverse (SemanticGraph::Attribute& x)
- {
- using SemanticGraph::Attribute;
-
- Attribute& y (dynamic_cast<Attribute&> (member_));
-
- // Check cardinalities.
- //
- if (x.optional_p () != y.optional_p ())
- return;
-
- traverse_member (x);
- }
-
- virtual void
- traverse_member (SemanticGraph::Member& x)
- {
- using SemanticGraph::Member;
-
- Member& y (dynamic_cast<Member&> (member_));
-
- // Check name.
- //
- if (x.name () != y.name ())
- return;
-
- // Check namespace.
- //
- if (x.qualified_p () || y.qualified_p ())
- {
- if (!x.qualified_p () || !y.qualified_p ())
- return;
-
- if (x.namespace_ ().name () != y.namespace_ ().name ())
- return;
- }
-
- // Check type.
- //
- // @@ What if types are anonymous and structurally equal?
- //
- if (&x.type () != &y.type ())
- return;
-
- // Check default/fixed values.
- //
- if (x.default_p () != y.default_p () || x.fixed_p () != y.fixed_p ())
- return;
-
- if (x.default_p () && x.value () != y.value ())
- return;
-
- result_ = true;
- }
-
- virtual void
- traverse (SemanticGraph::Any&)
- {
- //@@ TODO
- }
-
- virtual void
- traverse (SemanticGraph::AnyAttribute&)
- {
- //@@ TODO
- }
-
- private:
- SemanticGraph::Nameable& member_;
- bool& result_;
- };
-
- // Compare two types for structural equality.
- //
- struct CompareTypes: Traversal::List,
- Traversal::Union,
- Traversal::Enumeration,
- Traversal::Complex
- {
- CompareTypes (SemanticGraph::Type& t, bool& r)
- : type_ (t), result_ (r)
- {
- }
-
-
- virtual void
- traverse (SemanticGraph::List&)
- {
- using SemanticGraph::List;
-
- //List& y (dynamic_cast<List&> (type_));
- }
-
- virtual void
- traverse (SemanticGraph::Union& x)
- {
- using SemanticGraph::Union;
-
- Union& y (dynamic_cast<Union&> (type_));
-
- Union::ArgumentedIterator ix (x.argumented_begin ()),
- iy (y.argumented_begin ());
-
- for (; ix != x.argumented_end () && iy != y.argumented_end ();
- ++ix, ++iy)
- {
- // @@ Anon structurally equivalent.
- //
- if (&iy->type () != &ix->type ())
- return;
- }
-
- result_ = true;
- }
-
- virtual void
- traverse (SemanticGraph::Enumeration& x)
- {
- using SemanticGraph::Enumeration;
-
- Enumeration& y (dynamic_cast<Enumeration&> (type_));
-
- // Bases should be the same.
- //
- if (&x.inherits ().base () != &y.inherits ().base ())
- return;
-
- // Make sure facets match.
- //
- using SemanticGraph::Restricts;
-
- Restricts& rx (dynamic_cast<Restricts&> (x.inherits ()));
- Restricts& ry (dynamic_cast<Restricts&> (y.inherits ()));
-
- if (rx.facets () != ry.facets ())
- return;
-
- // Compare enumerators.
- //
- using SemanticGraph::Scope;
-
- Scope::NamesIterator ix (x.names_begin ()), iy (y.names_begin ());
- for (; ix != x.names_end () && iy != y.names_end (); ++ix, ++iy)
- {
- if (ix->name () != iy->name ())
- return;
- }
-
- if (ix != x.names_end () || iy != y.names_end ())
- return;
-
- result_ = true;
- }
-
- virtual void
- traverse (SemanticGraph::Complex& x)
- {
- using SemanticGraph::Complex;
-
- Complex& y (dynamic_cast<Complex&> (type_));
-
- // Check inheritance.
- //
- if (x.inherits_p () || y.inherits_p ())
- {
- // They both must inherits.
- //
- if (!x.inherits_p () || !y.inherits_p ())
- return;
-
- // With the same kind of inheritance (restriction or extension).
- //
- if (typeid (x.inherits ()) != typeid (y.inherits ()))
- return;
-
- // Bases should be the same.
- //
- // @@ What if bases are anonymous?
- //
- if (&x.inherits ().base () != &y.inherits ().base ())
- return;
-
- // If it is a restriction, make sure facets match.
- //
- using SemanticGraph::Restricts;
-
- if (x.inherits ().is_a<Restricts> ())
- {
- Restricts& rx (dynamic_cast<Restricts&> (x.inherits ()));
- Restricts& ry (dynamic_cast<Restricts&> (y.inherits ()));
-
- if (rx.facets () != ry.facets ())
- return;
- }
- }
-
- // Check the member list.
- //
- // @@ Ignoring compositors at the moment.
- //
- using SemanticGraph::Scope;
-
- Scope::NamesIterator ix (x.names_begin ()), iy (y.names_begin ());
- for (; ix != x.names_end () && iy != y.names_end (); ++ix, ++iy)
- {
- if (typeid (ix->named ()) != typeid (iy->named ()))
- return;
-
- bool equal (false);
- CompareMembers t (iy->named (), equal);
- t.dispatch (ix->named ());
-
- if (!equal)
- return;
- }
-
- if (ix != x.names_end () || iy != y.names_end ())
- return;
-
- result_ = true;
- }
-
- private:
- SemanticGraph::Type& type_;
- bool& result_;
- };
-
- //
- //
- class Context
- {
- public:
- Context (SemanticGraph::Schema& schema_,
- SemanticGraph::Path const& file,
- AnonymousNameTranslator& trans_,
- bool du)
- : schema_path_ (file),
- ns_ (0),
- failed_ (false),
- trans (trans_),
- detect_unstable (du),
- schema (schema_),
- schema_path (schema_path_),
- ns (ns_),
- failed (failed_)
- {
-
- }
-
- protected:
- Context (Context& c)
- : trans (c.trans),
- detect_unstable (c.detect_unstable),
- schema (c.schema),
- schema_path (c.schema_path),
- ns (c.ns),
- failed (c.failed)
- {
- }
-
- public:
-
- bool
- structurally_equal (SemanticGraph::Type& x, SemanticGraph::Type& y)
- {
- if (typeid (x) != typeid (y))
- return false;
-
- bool r (false);
- CompareTypes t (y, r);
- t.dispatch (x);
- return r;
- }
-
- struct UnstableConflict
- {
- UnstableConflict (SemanticGraph::Type& type)
- : type_ (type)
- {
- }
-
- SemanticGraph::Type&
- type () const
- {
- return type_;
- }
-
- private:
- SemanticGraph::Type& type_;
- };
-
- SemanticGraph::Type*
- conflict (String const& name)
- {
- using SemanticGraph::Type;
- using SemanticGraph::Schema;
-
- if (Type* t1 = find (schema, name))
- {
- // Check if this is a stable conflict. A conflict is unstable
- // if a conflicting type is visible from the root schema but
- // is not visible from the schema where the conflicting
- // element is defined.
- //
- if (detect_unstable)
- {
- Schema& s (dynamic_cast<Schema&> (ns->scope ()));
-
- Type* t2 (find (s, name));
-
- if (t1 != t2)
- throw UnstableConflict (*t1);
- }
-
- return t1;
- }
-
- return 0;
- }
-
- SemanticGraph::Type*
- find (SemanticGraph::Schema& schema, String const& name)
- {
- using SemanticGraph::Type;
- using SemanticGraph::Scope;
- using SemanticGraph::Namespace;
-
- String ns_name (ns->name ());
-
- // Get all namespaces across include/import hierarchy with
- // our namespace name.
- //
- Scope::NamesIteratorPair nip (schema.find (ns_name));
-
- for (; nip.first != nip.second; ++nip.first)
- {
- Namespace& ns (dynamic_cast<Namespace&> (nip.first->named ()));
-
- Scope::NamesIteratorPair types (ns.find (name));
-
- for (; types.first != types.second; ++types.first)
- {
- if (Type* t = dynamic_cast<Type*> (&types.first->named ()))
- {
- return t;
- }
- }
- }
-
- return 0;
- }
-
- public:
- SemanticGraph::Path
- path (SemanticGraph::Nameable& n)
- {
- using SemanticGraph::Scope;
- using SemanticGraph::Schema;
- using SemanticGraph::Uses;
-
- Schema* schema (0);
-
- for (Scope* s (dynamic_cast<Scope*> (&n)
- ? dynamic_cast<Scope*> (&n) : &n.scope ());;
- s = &s->scope ())
- {
- if ((schema = dynamic_cast<Schema*> (s)))
- break;
- }
-
- if (!schema->used_p ())
- return schema_path;
-
- Uses& u (*schema->used_begin ());
- return u.path ();
- }
-
- public:
- String
- xpath (SemanticGraph::Nameable& n)
- {
- if (dynamic_cast<SemanticGraph::Namespace*> (&n) != 0)
- return L"<namespace-level>"; // There is a bug if you see this.
-
- assert (n.named_p ());
-
- SemanticGraph::Scope& scope (n.scope ());
-
- if (dynamic_cast<SemanticGraph::Namespace*> (&scope) != 0)
- return n.name ();
-
- return xpath (scope) + L"/" + n.name ();
- }
-
- private:
- SemanticGraph::Path const schema_path_;
- SemanticGraph::Namespace* ns_;
- bool failed_;
-
- public:
- AnonymousNameTranslator& trans;
- bool detect_unstable;
-
- public:
- SemanticGraph::Schema& schema;
- SemanticGraph::Path const& schema_path;
- SemanticGraph::Namespace*& ns;
- bool& failed;
- };
-
-
- // 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-anonymous-seen"))
- {
- s.context ().set ("xsd-frontend-anonymous-seen", true);
- Traversal::Uses::traverse (u);
- }
- }
- };
-
- // Keep track which namespace we are in.
- //
- struct Namespace: Traversal::Namespace
- {
- Namespace (SemanticGraph::Namespace*& ns)
- : ns_ (ns)
- {
- }
-
- void
- pre (SemanticGraph::Namespace& ns)
- {
- ns_ = &ns;
- }
-
- void
- post (SemanticGraph::Namespace&)
- {
- ns_ = 0;
- }
-
- private:
- SemanticGraph::Namespace*& ns_;
- };
-
- //
- //
- struct Type: Traversal::List,
- Traversal::Union,
- Traversal::Complex,
- protected virtual Context
- {
- Type (Context& c)
- : Context (c)
- {
- }
-
- virtual void
- traverse (SemanticGraph::List& l)
- {
- SemanticGraph::Type& t (l.argumented ().type ());
-
- //@@ This IDREF stuff is really ugly!
- //
- if (!t.named_p () &&
- !t.is_a<SemanticGraph::Fundamental::IdRef> () &&
- !t.is_a<SemanticGraph::Fundamental::IdRefs> ())
- {
- try
- {
- // Run the name through the translation service.
- //
- SemanticGraph::Path file (path (l));
- file.normalize ();
- String file_str;
-
- // Try to use the portable representation of the path. If that
- // fails, fall back to the native representation.
- //
- try
- {
- file_str = file.posix_string ();
- }
- catch (SemanticGraph::InvalidPath const&)
- {
- file_str = file.string ();
- }
-
- String name (
- trans.translate (
- file_str, ns->name (), l.name () + L"_item", xpath (l)));
-
- // Make sure the name is unique.
- //
- unsigned long n (1);
- String escaped (name);
-
- while (conflict (escaped))
- {
- std::wostringstream os;
- os << n++;
- escaped = name + os.str ();
- }
-
- t.context ().set ("anonymous", true);
- schema.new_edge<SemanticGraph::Names> (*ns, t, escaped);
- }
- catch (UnstableConflict const& ex)
- {
- SemanticGraph::Type& t (ex.type ());
-
- wcerr << l.file () << ":" << l.line () << ":" << l.column ()
- << ": error: list type name '" << xpath (l) << "' "
- << "creates an unstable conflict when used as a base "
- << "for the item type name"
- << endl;
-
- wcerr << t.file () << ":" << t.line () << ":" << t.column ()
- << ": info: conflicting type is defined here" << endl;
-
- wcerr << l.file () << ":" << l.line () << ":" << l.column ()
- << ": info: "
- << "use --anonymous-regex to resolve this conflict"
- << endl;
-
- wcerr << l.file () << ":" << l.line () << ":" << l.column ()
- << ": info: "
- << "and don't forget to pass the same option when "
- << "translating '" << l.file ().leaf () << "' and all "
- << "the schemas that refer to it" << endl;
-
- failed = true;
- }
- }
- }
-
- virtual void
- traverse (SemanticGraph::Union& u)
- {
- String file_str;
-
- for (SemanticGraph::Union::ArgumentedIterator i (
- u.argumented_begin ()); i != u.argumented_end (); ++i)
- {
- SemanticGraph::Type& t (i->type ());
-
- if (!t.named_p () &&
- !t.is_a<SemanticGraph::Fundamental::IdRef> () &&
- !t.is_a<SemanticGraph::Fundamental::IdRefs> ())
- {
- try
- {
- // Run the name through the translation service.
- //
-
- if (!file_str)
- {
- SemanticGraph::Path file (path (u));
- file.normalize ();
-
- // Try to use the portable representation of the path. If
- // that fails, fall back to the native representation.
- //
- try
- {
- file_str = file.posix_string ();
- }
- catch (SemanticGraph::InvalidPath const&)
- {
- file_str = file.string ();
- }
- }
-
- String name (
- trans.translate (
- file_str, ns->name (), u.name () + L"_member", xpath (u)));
-
- // Make sure the name is unique.
- //
- unsigned long n (1);
- String escaped (name);
-
- while (conflict (escaped))
- {
- std::wostringstream os;
- os << n++;
- escaped = name + os.str ();
- }
-
- t.context ().set ("anonymous", true);
- schema.new_edge<SemanticGraph::Names> (*ns, t, escaped);
- }
- catch (UnstableConflict const& ex)
- {
- SemanticGraph::Type& t (ex.type ());
-
- wcerr << u.file () << ":" << u.line () << ":" << u.column ()
- << ": error: union type name '" << xpath (u) << "' "
- << "creates an unstable conflict when used as a base "
- << "for the member type name"
- << endl;
-
- wcerr << t.file () << ":" << t.line () << ":" << t.column ()
- << ": info: conflicting type is defined here" << endl;
-
- wcerr << u.file () << ":" << u.line () << ":" << u.column ()
- << ": info: "
- << "use --anonymous-regex to resolve this conflict"
- << endl;
-
- wcerr << u.file () << ":" << u.line () << ":" << u.column ()
- << ": info: "
- << "and don't forget to pass the same option when "
- << "translating '" << u.file ().leaf () << "' and all "
- << "the schemas that refer to it" << endl;
-
- failed = true;
- }
- }
- }
- }
-
- virtual void
- traverse (SemanticGraph::Complex& c)
- {
- if (!c.inherits_p ())
- return;
-
- SemanticGraph::Type& t (c.inherits ().base ());
-
- //@@ This IDREF stuff is really ugly!
- //
- if (!t.named_p () &&
- !t.is_a<SemanticGraph::Fundamental::IdRef> () &&
- !t.is_a<SemanticGraph::Fundamental::IdRefs> ())
- {
- try
- {
- // Run the name through the translation service.
- //
- SemanticGraph::Path file (path (c));
- file.normalize ();
- String file_str;
-
- // Try to use the portable representation of the path. If that
- // fails, fall back to the native representation.
- //
- try
- {
- file_str = file.posix_string ();
- }
- catch (SemanticGraph::InvalidPath const&)
- {
- file_str = file.string ();
- }
-
- String name (
- trans.translate (
- file_str, ns->name (), c.name () + L"_base", xpath (c)));
-
- // Make sure the name is unique.
- //
- unsigned long n (1);
- String escaped (name);
-
- while (conflict (escaped))
- {
- std::wostringstream os;
- os << n++;
- escaped = name + os.str ();
- }
-
- t.context ().set ("anonymous", true);
- schema.new_edge<SemanticGraph::Names> (*ns, t, escaped);
- }
- catch (UnstableConflict const& ex)
- {
- SemanticGraph::Type& t (ex.type ());
-
- wcerr << c.file () << ":" << c.line () << ":" << c.column ()
- << ": error: simple type name '" << xpath (c) << "' "
- << "creates an unstable conflict when used as a base "
- << "for the base type name"
- << endl;
-
- wcerr << t.file () << ":" << t.line () << ":" << t.column ()
- << ": info: conflicting type is defined here" << endl;
-
- wcerr << c.file () << ":" << c.line () << ":" << c.column ()
- << ": info: "
- << "use --anonymous-regex to resolve this conflict"
- << endl;
-
- wcerr << c.file () << ":" << c.line () << ":" << c.column ()
- << ": info: "
- << "and don't forget to pass the same option when "
- << "translating '" << c.file ().leaf () << "' and all "
- << "the schemas that refer to it" << endl;
-
- failed = true;
- }
- }
- }
- };
-
-
- //
- //
- struct Member: Traversal::Element,
- Traversal::Attribute,
- protected virtual Context
- {
- Member (Context& c)
- : Context (c)
- {
- }
-
- virtual void
- traverse (SemanticGraph::Element& e)
- {
- SemanticGraph::Type& t (e.type ());
-
- //@@ This IDREF stuff is really ugly!
- //
- if (!t.named_p () &&
- !t.is_a<SemanticGraph::Fundamental::IdRef> () &&
- !t.is_a<SemanticGraph::Fundamental::IdRefs> ())
- {
- try
- {
- traverse_ (e);
- }
- catch (UnstableConflict const& ex)
- {
- SemanticGraph::Type& t (ex.type ());
-
- wcerr << e.file () << ":" << e.line () << ":" << e.column ()
- << ": error: element name '" << xpath (e) << "' "
- << "creates an unstable conflict when used as a type name"
- << endl;
-
- wcerr << t.file () << ":" << t.line () << ":" << t.column ()
- << ": info: conflicting type is defined here" << endl;
-
- wcerr << e.file () << ":" << e.line () << ":" << e.column ()
- << ": info: "
- << "use --anonymous-regex to resolve this conflict"
- << endl;
-
- wcerr << e.file () << ":" << e.line () << ":" << e.column ()
- << ": info: "
- << "and don't forget to pass the same option when "
- << "translating '" << e.file ().leaf () << "' and all "
- << "the schemas that refer to it" << endl;
-
- failed = true;
- }
- }
- }
-
- virtual void
- traverse (SemanticGraph::Attribute& a)
- {
- SemanticGraph::Type& t (a.type ());
-
- //@@ This IDREF stuff us really ugly!
- //
- if (!t.named_p () &&
- !t.is_a<SemanticGraph::Fundamental::IdRef> () &&
- !t.is_a<SemanticGraph::Fundamental::IdRefs> ())
- {
- try
- {
- traverse_ (a);
- }
- catch (UnstableConflict const& ex)
- {
- SemanticGraph::Type& t (ex.type ());
-
- wcerr << a.file () << ":" << a.line () << ":" << a.column ()
- << ": error: attribute name '" << xpath (a) << "' "
- << "creates an unstable conflict when used as a type name"
- << endl;
-
- wcerr << t.file () << ":" << t.line () << ":" << t.column ()
- << ": info: conflicting type is defined here" << endl;
-
- wcerr << a.file () << ":" << a.line () << ":" << a.column ()
- << ": info: "
- << "use --anonymous-regex to resolve this conflict"
- << endl;
-
- wcerr << a.file () << ":" << a.line () << ":" << a.column ()
- << ": info: "
- << "and don't forget to pass the same option when "
- << "translating '" << a.file ().leaf () << "' and all "
- << "the schemas that refer to it" << endl;
-
- failed = true;
- }
- }
- }
-
- void
- traverse_ (SemanticGraph::Member& m)
- {
- using SemanticGraph::Type;
-
- Type& t (m.type ());
-
- // Normally this will be the member which also "defined" the type.
- // However, in some cases of cyclic schema inclusion, this does
- // not happen. As a result we need an extra check that will make
- // sure we create the Names edge in the same Schema node as the
- // one which contains the member which initially defined this
- // type. See the cyclic-inclusion test for an example.
- //
-
- // Find the first member that this type classifies.
- //
- for (Type::ClassifiesIterator i (t.classifies_begin ());
- i != t.classifies_end (); ++i)
- {
- SemanticGraph::Instance& inst (i->instance ());
-
- if (inst.is_a<SemanticGraph::Member> ())
- {
- // If it is the same member as the one we are traversing,
- // then continue.
- //
- if (&inst == &m)
- break;
- else
- return;
- }
- }
-
- // Run the name through the translation service.
- //
- SemanticGraph::Path file (path (m));
- file.normalize ();
- String file_str;
-
- // Try to use the portable representation of the path. If that
- // fails, fall back to the native representation.
- //
- try
- {
- file_str = file.posix_string ();
- }
- catch (SemanticGraph::InvalidPath const&)
- {
- file_str = file.string ();
- }
-
- String name (
- trans.translate (file_str, ns->name (), m.name (), xpath (m)));
-
- // Check if this name conflicts.
- //
- unsigned long n (1);
- String escaped (name);
-
- while (SemanticGraph::Type* other = conflict (escaped))
- {
- // First see if we should just use the other type. It should
- // also have been anonymous and structurally equal to our type.
- //
- if (other->context ().count ("anonymous"))
- {
- if (structurally_equal (t, *other))
- {
- // Reset the elements that are classified by this type to point
- // to the other type.
- //
- for (Type::ClassifiesIterator i (t.classifies_begin ());
- i != t.classifies_end (); ++i)
- {
- schema.reset_right_node (*i, *other);
- }
-
- //wcerr << "equal " << name << endl;
- return;
- }
- //else
- //wcerr << "unequal " << name << endl;
- }
-
- std::wostringstream os;
- os << n++;
- escaped = name + os.str ();
- }
-
- t.context ().set ("anonymous", true);
- schema.new_edge<SemanticGraph::Names> (*ns, t, escaped);
- }
- };
- }
-
- namespace Transformations
- {
- Anonymous::
- Anonymous (AnonymousNameTranslator& trans)
- : trans_ (trans)
- {
- }
-
- void Anonymous::
- transform (SemanticGraph::Schema& s,
- SemanticGraph::Path const& f,
- bool duc)
- {
- Context ctx (s, f, trans_, duc);
-
- Traversal::Schema schema;
- Uses uses;
-
- schema >> uses >> schema;
-
- Traversal::Names schema_names;
- Namespace ns (ctx.ns);
- Traversal::Names ns_names_member;
- Traversal::Names ns_names_type;
-
- schema >> schema_names >> ns;
- ns >> ns_names_member;
- ns >> ns_names_type;
-
- Type type (ctx);
- ns_names_type >> type;
-
- Traversal::Scope scope; // Goes to both types and groups.
- Member member (ctx);
-
- ns_names_member >> scope;
- ns_names_member >> member;
-
- Traversal::Names names;
-
- scope >> names >> member;
-
- // Some twisted schemas do recusive inclusions.
- //
- s.context ().set ("xsd-frontend-anonymous-seen", true);
-
- schema.dispatch (s);
-
- if (ctx.failed)
- throw Failed ();
- }
-
- AnonymousNameTranslator::
- ~AnonymousNameTranslator ()
- {
- }
- }
-}
diff --git a/xsd-frontend/transformations/anonymous.hxx b/xsd-frontend/transformations/anonymous.hxx
deleted file mode 100644
index fcdf880..0000000
--- a/xsd-frontend/transformations/anonymous.hxx
+++ /dev/null
@@ -1,56 +0,0 @@
-// file : xsd-frontend/transformations/anonymous.hxx
-// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
-
-#ifndef XSD_FRONTEND_TRANSFORMATIONS_ANONYMOUS_HXX
-#define XSD_FRONTEND_TRANSFORMATIONS_ANONYMOUS_HXX
-
-#include <xsd-frontend/types.hxx>
-
-#include <xsd-frontend/semantic-graph/elements.hxx> // Path
-#include <xsd-frontend/semantic-graph/schema.hxx>
-
-namespace XSDFrontend
-{
- namespace Transformations
- {
- class AnonymousNameTranslator
- {
- public:
- virtual
- ~AnonymousNameTranslator ();
-
- // The file argument is empty for the currect translation
- // unit.
- //
- virtual String
- translate (String const& file,
- String const& ns,
- String const& name,
- String const& xpath) = 0;
- };
-
- // This transformation morphs anonymous types into named ones
- // with the names derived from the enclosing attributes and
- // elements. If the detect_unstable_conflicts argument is true
- // then the transformation detects and reports unstable conflicts
- // in name assignment.
- //
- class Anonymous
- {
- public:
- struct Failed {};
-
- Anonymous (AnonymousNameTranslator&);
-
- void
- transform (SemanticGraph::Schema&,
- SemanticGraph::Path const&,
- bool detect_unstable_conflicts);
-
- private:
- AnonymousNameTranslator& trans_;
- };
- }
-}
-
-#endif // XSD_FRONTEND_TRANSFORMATIONS_ANONYMOUS_HXX
diff --git a/xsd-frontend/transformations/enum-synthesis.cxx b/xsd-frontend/transformations/enum-synthesis.cxx
deleted file mode 100644
index 41b668b..0000000
--- a/xsd-frontend/transformations/enum-synthesis.cxx
+++ /dev/null
@@ -1,244 +0,0 @@
-// file : xsd-frontend/transformations/enum-synthesis.cxx
-// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
-
-#include <set>
-
-#include <xsd-frontend/semantic-graph.hxx>
-#include <xsd-frontend/traversal.hxx>
-
-#include <xsd-frontend/transformations/enum-synthesis.hxx>
-
-namespace XSDFrontend
-{
- namespace
- {
- typedef std::set<String> Enumerators;
-
- struct Enumerator: Traversal::Enumerator
- {
- Enumerator (SemanticGraph::Schema& s,
- SemanticGraph::Enumeration& e,
- Enumerators& enumerators)
- : schema_ (s), enum_ (e), enumerators_ (enumerators)
- {
- }
-
- virtual void
- traverse (Type& e)
- {
- String const& name (e.name ());
-
- if (enumerators_.find (name) == enumerators_.end ())
- {
- enumerators_.insert (name);
-
- // Clone the enumerator and add it to enum_.
- //
- Type& c (schema_.new_node<Type> (e.file (), e.line (), e.column ()));
-
- schema_.new_edge<SemanticGraph::Names> (enum_, c, name);
- schema_.new_edge<SemanticGraph::Belongs> (c, enum_);
-
- if (e.annotated_p ())
- schema_.new_edge<SemanticGraph::Annotates> (e.annotation (), c);
- }
- }
-
- private:
- SemanticGraph::Schema& schema_;
- SemanticGraph::Enumeration& enum_;
- Enumerators& enumerators_;
- };
-
- //
- //
- struct Union: Traversal::Union
- {
- Union (SemanticGraph::Schema& schema)
- : schema_ (schema)
- {
- }
-
- virtual void
- traverse (Type& u)
- {
- using SemanticGraph::Enumeration;
-
- SemanticGraph::Context& uc (u.context ());
-
- if (uc.count ("xsd-frontend-enum-synthesis-processed"))
- return;
-
- uc.set ("xsd-frontend-enum-synthesis-processed", true);
-
- // First see if this union is suitable for synthesis.
- //
- SemanticGraph::Type* base (0);
-
- for (Type::ArgumentedIterator i (u.argumented_begin ());
- i != u.argumented_end (); ++i)
- {
- if (i->type ().is_a<SemanticGraph::Union> ())
- {
- // See if we can synthesize an enum for this union. This
- // call can change the value i->type() returns.
- //
- dispatch (i->type ());
- }
-
- SemanticGraph::Type& t (i->type ());
-
- if (!t.is_a<Enumeration> ())
- return;
-
- // Make sure all the enums have a common base.
- //
- if (base == 0)
- base = &t;
- else
- {
- // Traverse the inheritance hierarchy until we fine a
- // common base.
- //
- while (base != 0)
- {
- SemanticGraph::Type* b (&t);
-
- for (; b != base && b->inherits_p ();
- b = &b->inherits ().base ()) ;
-
- if (base == b)
- break;
-
- // Could not find any match on this level. Go one step
- // lower and try again.
- //
- base = base->inherits_p () ? &base->inherits ().base () : 0;
- }
-
- if (base == 0)
- return; // No common base.
- }
- }
-
- if (base == 0)
- return; // Empty union.
-
- // So this union is suitable for synthesis. Base variable points
- // to the "most-derived" common base type.
- //
- Enumeration& e (schema_.new_node<Enumeration> (
- u.file (), u.line (), u.column ()));
-
- schema_.new_edge<SemanticGraph::Restricts> (e, *base);
-
- // Copy enumerators from the member enums.
- //
- {
- Enumerators set;
- Traversal::Enumeration en;
- Traversal::Names names;
- Enumerator er (schema_, e, set);
- en >> names >> er;
-
- for (Type::ArgumentedIterator i (u.argumented_begin ());
- i != u.argumented_end (); ++i)
- {
- en.dispatch (i->type ());
- }
- }
-
- // Reset edges pointing to union to point to enum.
- //
- if (u.annotated_p ())
- {
- schema_.reset_right_node (u.annotated (), e);
- schema_.add_edge_right (e, u.annotated ());
- }
-
- schema_.reset_right_node (u.named (), e);
- schema_.add_edge_right (e, u.named ());
-
- for (Type::ClassifiesIterator i (u.classifies_begin ()),
- end (u.classifies_end ()); i != end; ++i)
- {
- schema_.reset_right_node (*i, e);
- schema_.add_edge_right (e, *i);
- }
-
- for (Type::BegetsIterator i (u.begets_begin ()),
- end (u.begets_end ()); i != end; ++i)
- {
- schema_.reset_right_node (*i, e);
- schema_.add_edge_right (e, *i);
- }
-
- for (Type::ArgumentsIterator i (u.arguments_begin ()),
- end (u.arguments_end ()); i != end; ++i)
- {
- schema_.reset_left_node (*i, e);
- schema_.add_edge_left (e, *i);
- }
-
- // Remove Arguments edges pointing to the union.
- //
- while (u.argumented_begin () != u.argumented_end ())
- {
- SemanticGraph::Arguments& a (*u.argumented_begin ());
- schema_.delete_edge (a.type (), a.specialization (), a);
- }
-
- // Copy context and delete the union node.
- //
- e.context ().swap (uc);
- schema_.delete_node (u);
- }
-
- private:
- SemanticGraph::Schema& schema_;
- };
-
- // 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-enum-synthesis-seen"))
- {
- s.context ().set ("xsd-frontend-enum-synthesis-seen", true);
- Traversal::Uses::traverse (u);
- }
- }
- };
- }
-
- namespace Transformations
- {
- void EnumSynthesis::
- 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;
- Union u (s);
-
- schema >> schema_names >> ns >> ns_names >> u;
-
- // Some twisted schemas do recusive inclusions.
- //
- s.context ().set ("xsd-frontend-enum-synthesis-seen", true);
-
- schema.dispatch (s);
- }
- }
-}
diff --git a/xsd-frontend/transformations/enum-synthesis.hxx b/xsd-frontend/transformations/enum-synthesis.hxx
deleted file mode 100644
index c224b47..0000000
--- a/xsd-frontend/transformations/enum-synthesis.hxx
+++ /dev/null
@@ -1,29 +0,0 @@
-// file : xsd-frontend/transformations/enum-synthesis.hxx
-// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
-
-#ifndef XSD_FRONTEND_TRANSFORMATIONS_ENUM_SYNTHESIS_HXX
-#define XSD_FRONTEND_TRANSFORMATIONS_ENUM_SYNTHESIS_HXX
-
-#include <xsd-frontend/types.hxx>
-
-#include <xsd-frontend/semantic-graph/elements.hxx> // Path
-#include <xsd-frontend/semantic-graph/schema.hxx>
-
-namespace XSDFrontend
-{
- namespace Transformations
- {
- // This transformation replaces unions of one or more enumerations
- // with the same base with an equivalent synthesized enumeration.
- // This transformation assumes that there are no anonymous types.
- //
- class EnumSynthesis
- {
- public:
- void
- transform (SemanticGraph::Schema&, SemanticGraph::Path const&);
- };
- }
-}
-
-#endif // XSD_FRONTEND_TRANSFORMATIONS_ENUM_SYNTHESIS_HXX
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);
- }
- }
-}
diff --git a/xsd-frontend/transformations/restriction.hxx b/xsd-frontend/transformations/restriction.hxx
deleted file mode 100644
index 293904d..0000000
--- a/xsd-frontend/transformations/restriction.hxx
+++ /dev/null
@@ -1,35 +0,0 @@
-// file : xsd-frontend/transformations/restriction.hxx
-// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
-
-#ifndef XSD_FRONTEND_TRANSFORMATIONS_RESTRICTION_HXX
-#define XSD_FRONTEND_TRANSFORMATIONS_RESTRICTION_HXX
-
-#include <xsd-frontend/types.hxx>
-
-#include <xsd-frontend/semantic-graph/elements.hxx> // Path
-#include <xsd-frontend/semantic-graph/schema.hxx>
-
-namespace XSDFrontend
-{
- namespace Transformations
- {
- // This transformation performs two major tasks. It transfers omitted
- // attribute declarations from the base to derived-by-restriction type
- // and establishes correspondence between particles and compositors by
- // adding the "xsd-frontend-restriction-correspondence" key-value pair
- // in the context that contains a pointer to the corresponding particle
- // or compositor in the base. Note that restriction of anyType is
- // a special case and is not handled by this transformation.
- //
- class Restriction
- {
- public:
- struct Failed {};
-
- void
- transform (SemanticGraph::Schema&, SemanticGraph::Path const&);
- };
- }
-}
-
-#endif // XSD_FRONTEND_TRANSFORMATIONS_RESTRICTION_HXX
diff --git a/xsd-frontend/transformations/schema-per-type.cxx b/xsd-frontend/transformations/schema-per-type.cxx
deleted file mode 100644
index d8c8e3c..0000000
--- a/xsd-frontend/transformations/schema-per-type.cxx
+++ /dev/null
@@ -1,473 +0,0 @@
-// file : xsd-frontend/transformations/schema-per-type.cxx
-// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
-
-#include <strings.h> // strcasecmp
-
-#include <map>
-#include <set>
-#include <vector>
-
-#include <sstream>
-#include <iostream>
-
-#include <xsd-frontend/semantic-graph.hxx>
-#include <xsd-frontend/traversal.hxx>
-
-#include <xsd-frontend/transformations/schema-per-type.hxx>
-
-using std::wcerr;
-using std::endl;
-
-namespace XSDFrontend
-{
- typedef Transformations::SchemaPerType::Failed Failed;
- typedef std::vector<SemanticGraph::Schema*> Schemas;
- typedef std::map<SemanticGraph::Type*, SemanticGraph::Schema*> TypeSchemaMap;
-
- // Compare file paths case-insensitively.
- //
- struct FileComparator
- {
- bool
- operator() (NarrowString const& x, NarrowString const& y) const
- {
- return strcasecmp (x.c_str (), y.c_str ()) < 0;
- }
- };
-
- typedef std::set<NarrowString, FileComparator> FileSet;
-
- namespace
- {
- // Go into included and imported schemas while making sure
- // we don't process the same stuff more than once.
- //
- struct Uses: Traversal::Includes,
- Traversal::Imports,
- Traversal::Implies
- {
- Uses (Schemas& schemas, SemanticGraph::Schema*& xsd)
- : schemas_ (schemas), xsd_ (xsd)
- {
- xsd_ = 0;
- }
-
- virtual void
- traverse (SemanticGraph::Includes& i)
- {
- SemanticGraph::Schema& s (i.schema ());
-
- if (!s.context ().count ("xsd-frontend-schema-per-type-seen"))
- {
- schemas_.push_back (&s);
- s.context ().set ("xsd-frontend-schema-per-type-seen", true);
- Traversal::Includes::traverse (i);
- }
- }
-
- virtual void
- traverse (SemanticGraph::Imports& i)
- {
- SemanticGraph::Schema& s (i.schema ());
-
- if (!s.context ().count ("xsd-frontend-schema-per-type-seen"))
- {
- schemas_.push_back (&s);
- s.context ().set ("xsd-frontend-schema-per-type-seen", true);
- Traversal::Imports::traverse (i);
- }
- }
-
- virtual void
- traverse (SemanticGraph::Implies& i)
- {
- if (xsd_ == 0)
- xsd_ = &i.schema ();
- }
-
- private:
- Schemas& schemas_;
- SemanticGraph::Schema*& xsd_;
- };
-
- void
- process_schema (SemanticGraph::Schema& s,
- SemanticGraph::Schema& root,
- SemanticGraph::Schema& xsd,
- TypeSchemaMap& tsm,
- FileSet& file_set,
- bool fat_type_file,
- Transformations::SchemaPerTypeTranslator& trans)
- {
- using namespace SemanticGraph;
-
- Path xsd_path ("XMLSchema.xsd");
- Namespace& ns (dynamic_cast<Namespace&> (s.names_begin ()->named ()));
-
- // We should be careful with iterator caching since we are going to
- // remove some of the nodes.
- //
- for (Scope::NamesIterator i (ns.names_begin ()); i != ns.names_end ();)
- {
- Nameable& n (i->named ());
-
- if (n.is_a<Type> ())
- {
- String name (n.name ());
-
- // Remove from the namespace.
- //
- Scope::NamesIterator tmp (i++);
- root.delete_edge (ns, n, *tmp);
-
- // Add a new schema node.
- //
- Path path;
- String tn (trans.translate_type (ns.name (), name));
- String wbase (tn ? tn : name);
-
- try
- {
- NarrowString base (wbase.to_narrow ());
-
- // Escape directory separators unless they came from the
- // translator.
- //
- if (!tn)
- {
- for (NarrowString::iterator i (base.begin ()), e (base.end ());
- i != e; ++i)
- {
- if (*i == '/' || *i == '\\')
- *i = '_';
- }
- }
-
- // Make sure it is unique.
- //
- NarrowString file_name (base);
-
- for (unsigned long i (1);
- file_set.find (file_name) != file_set.end ();
- ++i)
- {
- std::ostringstream os;
- os << i;
- file_name = base + os.str ();
- }
-
- file_set.insert (file_name);
- file_name += ".xsd";
-
- try
- {
- path = Path (file_name);
- }
- catch (InvalidPath const&)
- {
- wcerr << "error: '" << file_name.c_str () << "' is not a valid "
- << "filesystem path" << endl;
-
- wcerr << "info: use type to file name translation mechanism "
- << "to resolve this" << endl;
-
- throw Failed ();
- }
- }
- catch (NonRepresentable const&)
- {
- wcerr << "error: '" << wbase << "' cannot be represented as a "
- << "narrow string" << endl;
-
- wcerr << "info: use type to file name translation mechanism "
- << "to resolve this" << endl;
-
- throw Failed ();
- }
-
- Type& t (dynamic_cast<Type&> (n));
-
- Schema& ts (root.new_node<Schema> (path, 1, 1));
- root.new_edge<Implies> (ts, xsd, xsd_path);
-
- Namespace& tns (root.new_node<Namespace> (path, 1, 1));
- root.new_edge<Names> (ts, tns, ns.name ());
- root.new_edge<Names> (tns, n, name);
-
- // If we are generating fat type files, then also move the global
- // elements this type classifies to the new schema.
- //
- if (fat_type_file)
- {
- for (Type::ClassifiesIterator j (t.classifies_begin ());
- j != t.classifies_end (); ++j)
- {
- Instance& e (j->instance ());
-
- // We can only move a global element from the same namespace.
- //
- if (e.is_a<Element> () &&
- e.scope ().is_a<Namespace> () &&
- e.scope ().name () == ns.name ())
- {
- Names& n (e.named ());
- String name (n.name ());
-
- // Watch out for the iterator validity: the edge we are
- // about to remove can be from the same list we are
- // currently iterating.
- //
- if (i != ns.names_end () && &*i == &n)
- ++i;
-
- root.delete_edge (n.scope (), e, n);
- root.new_edge<Names> (tns, e, name);
- }
- }
- }
-
- // Add include to the original schema and enter into the
- // type-schema map.
- //
- root.new_edge<Includes> (s, ts, path);
- tsm[&t] = &ts;
-
- // Also mark this schema as "type schema" in case someone
- // needs to distinguish between the two kinds.
- //
- ts.context ().set ("type-schema", true);
- }
- else
- ++i;
- }
- }
-
- struct Type: Traversal::List,
- Traversal::Complex,
- Traversal::Member
- {
- Type (SemanticGraph::Schema& schema,
- SemanticGraph::Schema& root,
- char const* by_value_key,
- TypeSchemaMap& tsm)
- : schema_ (schema),
- root_ (root),
- by_value_key_ (by_value_key),
- tsm_ (tsm)
- {
- *this >> names_ >> *this;
- }
-
- virtual void
- traverse (SemanticGraph::List& l)
- {
- // Treat item type as base type since it is impossible
- // to create recursive constructs using list.
- //
- SemanticGraph::Type& t (l.argumented ().type ());
- set_dep (t, false);
- }
-
- virtual void
- traverse (SemanticGraph::Complex& c)
- {
- if (c.inherits_p ())
- set_dep (c.inherits ().base (), false);
-
- Traversal::Complex::names (c);
- }
-
- virtual void
- traverse (SemanticGraph::Member& m)
- {
- SemanticGraph::Type& t (m.type ());
-
- bool weak (
- by_value_key_ == 0 ||
- !t.context ().count (by_value_key_) ||
- !t.context ().get<bool> (by_value_key_));
-
- set_dep (t, weak);
- }
-
- private:
- void
- set_dep (SemanticGraph::Type& t, bool weak)
- {
- using namespace SemanticGraph;
-
- TypeSchemaMap::iterator i (tsm_.find (&t));
-
- // If a type is not present in the map then it must be
- // a built-in type.
- //
- if (i == tsm_.end ())
- return;
-
- // Check if we already saw this type. Theoretically, it could
- // be that we need to upgrade the type of include from weak to
- // strong. But because inheritance is handled first, the type
- // in the set will already be with the right type.
- //
- if (type_set_.find (&t) != type_set_.end ())
- return;
-
- type_set_.insert (&t);
-
- Schema& s (*i->second);
- Path path (s.used_begin ()->path ());
- SemanticGraph::Uses* u;
-
- if (s.names_begin ()->name () == schema_.names_begin ()->name ())
- u = &root_.new_edge<Includes> (schema_, s, path);
- else
- u = &root_.new_edge<Imports> (schema_, s, path);
-
- if (weak)
- u->context().set ("weak", true);
- }
-
- private:
- SemanticGraph::Schema& schema_;
- SemanticGraph::Schema& root_;
- char const* by_value_key_;
- TypeSchemaMap& tsm_;
- std::set<SemanticGraph::Type*> type_set_;
-
- Traversal::Names names_;
- };
- }
-
- namespace Transformations
- {
- SchemaPerType::
- SchemaPerType (SchemaPerTypeTranslator& trans,
- bool fat,
- char const* key)
- : fat_type_file_ (fat), by_value_key_ (key), trans_ (trans)
- {
- }
-
- Schemas SchemaPerType::
- transform (SemanticGraph::Schema& root)
- {
- // Collect initial schema nodes.
- //
- Schemas schemas;
- SemanticGraph::Schema* xsd;
-
- {
- Traversal::Schema schema;
- Uses uses (schemas, xsd);
-
- schema >> uses >> schema;
-
- // Some twisted schemas do recusive inclusions.
- //
- root.context ().set ("xsd-frontend-schema-per-type-seen", true);
-
- schema.dispatch (root);
- }
-
- // wcerr << schemas.size () << " initial schema nodes" << endl;
-
- // Add the schema file names to the file set.
- //
- FileSet file_set;
-
- for (Schemas::iterator i (schemas.begin ()); i != schemas.end (); ++i)
- {
- // This path was already normalized by the parser.
- //
- SemanticGraph::Path const& path (
- (*i)->context ().get<SemanticGraph::Path> ("absolute-path"));
-
- // Translate the schema file name.
- //
- NarrowString abs_path;
-
- // Try to use the portable representation of the path. If that
- // fails, fall back to the native representation.
- //
- try
- {
- abs_path = path.posix_string ();
- }
- catch (SemanticGraph::InvalidPath const&)
- {
- abs_path = path.string ();
- }
-
- NarrowString tf (trans_.translate_schema (abs_path));
- NarrowString file (tf ? tf : path.leaf ().string ());
-
- size_t p (file.rfind ('.'));
- NarrowString ext (
- p != NarrowString::npos ? NarrowString (file, p) : "");
-
- NarrowString base (
- p != NarrowString::npos ? NarrowString (file, 0, p) : file);
-
- // Make sure it is unique.
- //
- NarrowString new_name (base);
-
- for (unsigned long n (1);
- file_set.find (new_name) != file_set.end ();
- ++n)
- {
- std::ostringstream os;
- os << n;
- new_name = base + os.str ();
- }
-
- file_set.insert (new_name);
- new_name += ext;
-
- try
- {
- (*i)->context ().set ("renamed", SemanticGraph::Path (new_name));
- }
- catch (SemanticGraph::InvalidPath const&)
- {
- wcerr << "error: '" << new_name.c_str () << "' is not a valid "
- << "filesystem path" << endl;
-
- wcerr << "info: use schema file name translation mechanism "
- << "to resolve this" << endl;
-
- throw Failed ();
- }
- }
-
- // Process each schema node.
- //
- TypeSchemaMap tsm;
-
- for (Schemas::iterator i (schemas.begin ()); i != schemas.end (); ++i)
- {
- process_schema (**i, root, *xsd, tsm, file_set, fat_type_file_, trans_);
- }
-
- // wcerr << tsm.size () << " type schema nodes" << endl;
-
- // Establish include/import dependencies. While at it add the
- // new schemas to the list which we will return.
- //
- for (TypeSchemaMap::iterator i (tsm.begin ()); i != tsm.end (); ++i)
- {
- SemanticGraph::Schema& s (*i->second);
- Type t (s, root, by_value_key_, tsm);
- t.dispatch (*i->first);
- schemas.push_back (&s);
- }
-
- return schemas;
- }
-
- SchemaPerTypeTranslator::
- ~SchemaPerTypeTranslator ()
- {
- }
- }
-}
diff --git a/xsd-frontend/transformations/schema-per-type.hxx b/xsd-frontend/transformations/schema-per-type.hxx
deleted file mode 100644
index 8fb5ac1..0000000
--- a/xsd-frontend/transformations/schema-per-type.hxx
+++ /dev/null
@@ -1,61 +0,0 @@
-// file : xsd-frontend/transformations/schema-per-type.hxx
-// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
-
-#ifndef XSD_FRONTEND_TRANSFORMATIONS_SCHEMA_PER_TYPE_HXX
-#define XSD_FRONTEND_TRANSFORMATIONS_SCHEMA_PER_TYPE_HXX
-
-#include <vector>
-
-#include <xsd-frontend/types.hxx>
-
-#include <xsd-frontend/semantic-graph/elements.hxx> // Path
-#include <xsd-frontend/semantic-graph/schema.hxx>
-
-namespace XSDFrontend
-{
- namespace Transformations
- {
- class SchemaPerTypeTranslator
- {
- public:
- virtual
- ~SchemaPerTypeTranslator ();
-
- // The following two functions should return empty string if
- // there is no match.
- //
- virtual String
- translate_type (String const& ns, String const& name) = 0;
-
- virtual NarrowString
- translate_schema (NarrowString const& abs_path) = 0;
- };
-
- // This transformation restructures the semantic graph to have
- // each type definition in a seperate schema file.
- //
- class SchemaPerType
- {
- public:
- struct Failed {};
-
- // If a type of an element or attribute has a context entry
- // with the by_value_key key and it is true, then the schema
- // for this type is included "strongly".
- //
- SchemaPerType (SchemaPerTypeTranslator&,
- bool fat_type_file,
- char const* by_value_key = 0);
-
- std::vector<SemanticGraph::Schema*>
- transform (SemanticGraph::Schema&);
-
- private:
- bool fat_type_file_;
- char const* by_value_key_;
- SchemaPerTypeTranslator& trans_;
- };
- }
-}
-
-#endif // XSD_FRONTEND_TRANSFORMATIONS_SCHEMA_PER_TYPE_HXX
diff --git a/xsd-frontend/transformations/simplifier.cxx b/xsd-frontend/transformations/simplifier.cxx
deleted file mode 100644
index e9b65c2..0000000
--- a/xsd-frontend/transformations/simplifier.cxx
+++ /dev/null
@@ -1,161 +0,0 @@
-// file : xsd-frontend/transformations/simplifier.cxx
-// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
-
-#include <xsd-frontend/semantic-graph.hxx>
-#include <xsd-frontend/traversal.hxx>
-
-#include <xsd-frontend/transformations/simplifier.hxx>
-
-namespace XSDFrontend
-{
- namespace
- {
- struct Compositor: Traversal::All,
- Traversal::Choice,
- Traversal::Sequence
- {
- Compositor (SemanticGraph::Schema& root)
- : root_ (root)
- {
- }
-
- virtual void
- traverse (SemanticGraph::All& a)
- {
- // The all compositor cannot contain compositors.
- //
- if (a.contains_begin () == a.contains_end ())
- remove (a);
- }
-
- virtual void
- traverse (SemanticGraph::Choice& c)
- {
- // Do the depth-first traversal so that we take into account
- // the potential removal of nested compositors.
- //
- using SemanticGraph::Compositor;
-
- for (Compositor::ContainsIterator i (c.contains_begin ());
- i != c.contains_end ();)
- {
- edge_traverser ().dispatch (*i++);
- }
-
- Choice::contains (c);
-
- if (c.contains_begin () == c.contains_end ())
- remove (c);
- }
-
- virtual void
- traverse (SemanticGraph::Sequence& s)
- {
- // Do the depth-first traversal so that we take into account
- // the potential removal of nested compositors.
- //
- using SemanticGraph::Compositor;
-
- for (Compositor::ContainsIterator i (s.contains_begin ());
- i != s.contains_end ();)
- {
- edge_traverser ().dispatch (*i++);
- }
-
- if (s.contains_begin () == s.contains_end ())
- remove (s);
- }
-
- private:
- virtual void
- remove (SemanticGraph::Compositor& c)
- {
- using SemanticGraph::Node;
- using SemanticGraph::Choice;
- using SemanticGraph::Complex;
- using SemanticGraph::Compositor;
-
- if (c.contained_particle_p ())
- {
- Compositor& com (c.contained_particle ().compositor ());
-
- // Empty compositors in choice are important.
- //
- if (!com.is_a<Choice> ())
- root_.delete_edge (com, c, c.contained_particle ());
- }
- else
- {
- Complex& con (
- dynamic_cast<Complex&> (c.contained_compositor ().container ()));
- root_.delete_edge (con, c, c.contained_compositor ());
- }
- }
-
- private:
- SemanticGraph::Schema& root_;
- };
-
- //
- //
- struct Type: Traversal::Complex
- {
- virtual void
- traverse (SemanticGraph::Complex& c)
- {
- if (c.contains_compositor_p ())
- Complex::contains_compositor (c);
- }
- };
-
- // 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-simplifier-seen"))
- {
- s.context ().set ("xsd-frontend-simplifier-seen", true);
- Traversal::Uses::traverse (u);
- }
- }
- };
- }
-
- namespace Transformations
- {
- void Simplifier::
- 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;
- Type type;
-
- schema >> schema_names >> ns >> ns_names >> type;
-
- Compositor compositor (s);
- Traversal::ContainsCompositor contains_compositor;
- Traversal::ContainsParticle contains_particle;
-
- type >> contains_compositor >> compositor;
- compositor >> contains_particle >> compositor;
-
- // Some twisted schemas do recusive inclusions.
- //
- s.context ().set ("xsd-frontend-simplifier-seen", true);
-
- schema.dispatch (s);
- }
- }
-}
diff --git a/xsd-frontend/transformations/simplifier.hxx b/xsd-frontend/transformations/simplifier.hxx
deleted file mode 100644
index d010e6b..0000000
--- a/xsd-frontend/transformations/simplifier.hxx
+++ /dev/null
@@ -1,29 +0,0 @@
-// file : xsd-frontend/transformations/simplifier.hxx
-// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
-
-#ifndef XSD_FRONTEND_TRANSFORMATIONS_SIMPLIFIER_HXX
-#define XSD_FRONTEND_TRANSFORMATIONS_SIMPLIFIER_HXX
-
-#include <xsd-frontend/types.hxx>
-
-#include <xsd-frontend/semantic-graph/elements.hxx> // Path
-#include <xsd-frontend/semantic-graph/schema.hxx>
-
-namespace XSDFrontend
-{
- namespace Transformations
- {
- // This transformation performs various schema simplifications
- // (e.g., removing empty compositors, etc). This transformation
- // assumes that there are no anonymous types.
- //
- class Simplifier
- {
- public:
- void
- transform (SemanticGraph::Schema&, SemanticGraph::Path const&);
- };
- }
-}
-
-#endif // XSD_FRONTEND_TRANSFORMATIONS_SIMPLIFIER_HXX