mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-10 01:41:57 +00:00
Properly toposort type decl instantiation
This commit is contained in:
@@ -60,6 +60,12 @@ class Schema:
|
||||
return str(v) in self.types
|
||||
def is_entity(self, v):
|
||||
return str(v) in self.entities
|
||||
def __len__(self):
|
||||
return len(self.types) + len(self.entities)
|
||||
def __iter__(self):
|
||||
return iter(self.keys)
|
||||
def __getitem__(self, key):
|
||||
return self.types_entities[key]
|
||||
def __init__(self, parsetree):
|
||||
self.name = parsetree[1]
|
||||
|
||||
@@ -67,6 +73,9 @@ class Schema:
|
||||
|
||||
self.types = sort([(t.name,t) for t in parsetree if isinstance(t, nodes.TypeDeclaration)])
|
||||
self.entities = sort([(t.name,t) for t in parsetree if isinstance(t, nodes.EntityDeclaration)])
|
||||
|
||||
self.keys = list(self.types.keys()) + list(self.entities.keys())
|
||||
self.types_entities = {k: v for d in (self.types, self.entities) for k, v in d.items()}
|
||||
|
||||
of_type = lambda *types: sort([(a, b.type.type) for a,b in self.types.items() if any(isinstance(b.type.type, ty) for ty in types)])
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ class SchemaClass(codegen.Base):
|
||||
aggr_type = type.aggregate_type
|
||||
make_bound = lambda b: -1 if b == '?' else int(b)
|
||||
bound1, bound2 = map(make_bound, (type.bounds.lower, type.bounds.upper))
|
||||
decl_type = get_declared_type(type.type)
|
||||
decl_type = get_declared_type(type.type, emitted_names)
|
||||
return "new aggregation_type(aggregation_type::%(aggr_type)s_type, %(bound1)d, %(bound2)d, %(decl_type)s)" % locals()
|
||||
elif isinstance(type, nodes.BinaryType):
|
||||
return "new simple_type(simple_type::binary_type)"
|
||||
@@ -46,7 +46,7 @@ class SchemaClass(codegen.Base):
|
||||
return "new simple_type(simple_type::string_type)"
|
||||
elif isinstance(type, str):
|
||||
if mapping.schema.is_type(type) or mapping.schema.is_entity(type):
|
||||
if emitted_names is None or type.lower() in emitted_types:
|
||||
if emitted_names is None or type.lower() in emitted_names:
|
||||
return "new named_type(%s_%s_type)" % (schema_name, type)
|
||||
else:
|
||||
raise UnmetDependenciesException(type)
|
||||
@@ -101,63 +101,63 @@ class SchemaClass(codegen.Base):
|
||||
""")
|
||||
statements.append('IfcParse::schema_definition* %(schema_name)s_populate_schema() {' % locals())
|
||||
|
||||
emitted_types = set()
|
||||
while len(emitted_types) < len(mapping.schema.simpletypes):
|
||||
for name, type in mapping.schema.simpletypes.items():
|
||||
if name.lower() in emitted_types: continue
|
||||
|
||||
try:
|
||||
declared_type = get_declared_type(type, emitted_types)
|
||||
except UnmetDependenciesException:
|
||||
# print("Unmet", repr(name))
|
||||
continue
|
||||
emitted = set()
|
||||
len_to_emit = len(mapping.schema)
|
||||
|
||||
def write_simpletype(schema_name, name, type):
|
||||
try:
|
||||
declared_type = get_declared_type(type, emitted)
|
||||
except UnmetDependenciesException:
|
||||
print("Unmet", repr(name))
|
||||
return False
|
||||
|
||||
statements.append(' %(schema_name)s_%(name)s_type = new type_declaration("%(name)s", %%(index_in_schema_%(name)s)d, %(declared_type)s);' % locals())
|
||||
emitted_types.add(name.lower())
|
||||
|
||||
declared_types.append('%(schema_name)s_%(name)s_type' % locals())
|
||||
declarations_by_index.append(name)
|
||||
|
||||
for name, enum in mapping.schema.enumerations.items():
|
||||
statements.append(' %(schema_name)s_%(name)s_type = new type_declaration("%(name)s", %%(index_in_schema_%(name)s)d, %(declared_type)s);' % locals())
|
||||
|
||||
def write_enumeration(schema_name, name, enum):
|
||||
statements.append(' {')
|
||||
statements.append(' std::vector<std::string> items; items.reserve(%d);' % len(enum.values))
|
||||
statements.extend(map(lambda v: ' items.push_back("%s");' % v, sorted(enum.values)))
|
||||
statements.append(' %(schema_name)s_%(name)s_type = new enumeration_type("%(name)s", %%(index_in_schema_%(name)s)d, items);' % locals())
|
||||
statements.append(' }')
|
||||
|
||||
declared_types.append('%(schema_name)s_%(name)s_type' % locals())
|
||||
declarations_by_index.append(name)
|
||||
def write_entity(schema_name, name, type):
|
||||
if len(type.supertypes) == 0 or set(map(lambda s: s.lower(), type.supertypes)) < emitted:
|
||||
supertype = '0' if len(type.supertypes) == 0 else '%s_%s_type' % (schema_name, type.supertypes[0])
|
||||
statements.append(' %(schema_name)s_%(name)s_type = new entity("%(name)s", %%(index_in_schema_%(name)s)d, %(supertype)s);' % locals())
|
||||
else: return False
|
||||
|
||||
def write_select(schema_name, name, type):
|
||||
if set(map(lambda s: s.lower(),type.values)) < emitted:
|
||||
statements.append(' {')
|
||||
statements.append(' std::vector<const declaration*> items; items.reserve(%d);' % len(type.values))
|
||||
statements.extend(map(lambda v: ' items.push_back(%s_%s_type);' % (schema_name, v), sorted(type.values)))
|
||||
statements.append(' %(schema_name)s_%(name)s_type = new select_type("%(name)s", %%(index_in_schema_%(name)s)d, items);' % locals())
|
||||
statements.append(' }')
|
||||
else: return False
|
||||
|
||||
def write(name):
|
||||
if mapping.schema.is_simpletype(name):
|
||||
fn = write_simpletype
|
||||
elif mapping.schema.is_enumeration(name):
|
||||
fn = write_enumeration
|
||||
elif mapping.schema.is_entity(name):
|
||||
fn = write_entity
|
||||
elif mapping.schema.is_select(name):
|
||||
fn = write_select
|
||||
|
||||
decl = mapping.schema[name]
|
||||
if isinstance(decl, nodes.TypeDeclaration):
|
||||
decl = decl.type.type
|
||||
return fn(schema_name, name, decl) is not False
|
||||
|
||||
emitted_entities = set()
|
||||
while len(emitted_entities) < len(mapping.schema.entities):
|
||||
for name, type in mapping.schema.entities.items():
|
||||
if name.lower() in emitted_entities: continue
|
||||
if len(type.supertypes) == 0 or set(map(lambda s: s.lower(), type.supertypes)) < emitted_entities:
|
||||
supertype = '0' if len(type.supertypes) == 0 else '%s_%s_type' % (schema_name, type.supertypes[0])
|
||||
statements.append(' %(schema_name)s_%(name)s_type = new entity("%(name)s", %%(index_in_schema_%(name)s)d, %(supertype)s);' % locals())
|
||||
emitted_entities.add(name.lower())
|
||||
|
||||
declared_types.append('%(schema_name)s_%(name)s_type' % locals())
|
||||
while len(emitted) < len_to_emit:
|
||||
for name in mapping.schema:
|
||||
if name.lower() in emitted: continue
|
||||
if write(name):
|
||||
emitted.add(name.lower())
|
||||
declarations_by_index.append(name)
|
||||
|
||||
emmited = emitted_types | emitted_entities | set(mapping.schema.enumerations.keys())
|
||||
|
||||
emitted_selects = set()
|
||||
while len(emitted_selects) < len(mapping.schema.selects):
|
||||
for name, type in mapping.schema.selects.items():
|
||||
if name.lower() in emitted_selects: continue
|
||||
if set(map(lambda s: s.lower(),type.values)) < emmited:
|
||||
statements.append(' {')
|
||||
statements.append(' std::vector<const declaration*> items; items.reserve(%d);' % len(type.values))
|
||||
statements.extend(map(lambda v: ' items.push_back(%s_%s_type);' % (schema_name, v), sorted(type.values)))
|
||||
statements.append(' %(schema_name)s_%(name)s_type = new select_type("%(name)s", %%(index_in_schema_%(name)s)d, items);' % locals())
|
||||
statements.append(' }')
|
||||
emitted_selects.add(name.lower())
|
||||
emmited.add(name)
|
||||
|
||||
declared_types.append('%(schema_name)s_%(name)s_type' % locals())
|
||||
declarations_by_index.append(name)
|
||||
|
||||
|
||||
num_declarations = len(declared_types)
|
||||
|
||||
for name, type in mapping.schema.entities.items():
|
||||
|
||||
+681
-681
File diff suppressed because it is too large
Load Diff
+825
-825
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user