diff --git a/src/ifcexpressparser/bootstrap.py b/src/ifcexpressparser/bootstrap.py index 41e2d5270c..5d9ff3997e 100644 --- a/src/ifcexpressparser/bootstrap.py +++ b/src/ifcexpressparser/bootstrap.py @@ -114,7 +114,6 @@ actions = { 'aggregation_types' : "lambda t: AggregationType(t)", 'general_aggregation_types' : "lambda t: AggregationType(t)", 'select_type' : "lambda t: SelectType(t)", - 'binary_type' : "lambda t: BinaryType(t)", 'subtype_declaration' : "lambda t: SubtypeExpression(t)", 'derive_clause' : "lambda t: AttributeList('derive', t)", 'derived_attr' : "lambda t: DerivedAttribute(t)", diff --git a/src/ifcexpressparser/implementation.py b/src/ifcexpressparser/implementation.py index 94aed1a40f..369808af48 100644 --- a/src/ifcexpressparser/implementation.py +++ b/src/ifcexpressparser/implementation.py @@ -72,10 +72,10 @@ class Implementation: def find_template(arg): simple = mapping.schema.is_simpletype(arg['list_instance_type']) select = arg['list_instance_type'] == "IfcUtil::IfcBaseClass" - express = arg['list_instance_type'] in mapping.express_to_cpp_typemapping + express = mapping.flatten_type_string(arg['list_instance_type']) in mapping.express_to_cpp_typemapping if arg['is_enum']: return templates.get_attr_stmt_enum elif arg['is_nested']: return templates.get_attr_stmt_nested_array - elif arg['is_array'] and not (select or simple or express): return templates.get_attr_stmt_array + elif arg['is_templated_list'] and not (select or simple or express): return templates.get_attr_stmt_array elif arg['non_optional_type'].endswith('*'): return templates.get_attr_stmt_entity else: return templates.get_attr_stmt @@ -96,7 +96,7 @@ class Implementation: select = arg['list_instance_type'] == "IfcUtil::IfcBaseClass" express = arg['list_instance_type'] in mapping.express_to_cpp_typemapping if arg['is_enum']: return templates.set_attr_stmt_enum - elif arg['is_array'] and not (select or simple or express): return templates.set_attr_stmt_array + elif arg['is_templated_list'] and not (select or simple or express): return templates.set_attr_stmt_array else: return templates.set_attr_stmt tmpl = find_template(arg) @@ -189,8 +189,15 @@ class Implementation: constructor = templates.constructor_single_initlist if superclass \ else templates.constructor + simpletype_impl_cast = templates.simpletype_impl_cast_templated if mapping.is_templated_list(type) \ + else templates.simpletype_impl_cast + + simpletype_impl_constructor = templates.simpletype_impl_constructor_templated if mapping.is_templated_list(type) \ + else templates.simpletype_impl_constructor + def compose(params): class_name, attr_type, superclass, superclass_init, name, tmpl, return_type, args, body = params + underlying_type = mapping.list_instance_type(type) arguments = ",".join(args) body = body % locals() return tmpl % locals() @@ -203,8 +210,8 @@ class Implementation: ('type', templates.const_function, 'Type::Enum', (), templates.simpletype_impl_type ), ('Class', templates.function, 'Type::Enum', (), templates.simpletype_impl_class ), ('', constructor, '', ('IfcAbstractEntity* e',), templates.simpletype_impl_explicit_constructor), - ('', constructor, '', ("%s v" % type_str,), templates.simpletype_impl_constructor ), - ('', templates.cast_function, type_str, (), templates.simpletype_impl_cast ) + ('', constructor, '', ("%s v" % type_str,), simpletype_impl_constructor ), + ('', templates.cast_function, type_str, (), simpletype_impl_cast ) )))) simple_type_impl.append('') diff --git a/src/ifcexpressparser/mapping.py b/src/ifcexpressparser/mapping.py index 44e0082da2..fcebef7744 100644 --- a/src/ifcexpressparser/mapping.py +++ b/src/ifcexpressparser/mapping.py @@ -61,7 +61,7 @@ class Mapping: is_nested_list = isinstance(type.type, nodes.AggregationType) tmpl = templates.list_list_type if is_nested_list else templates.list_type if is_list else templates.array_type return tmpl % { - 'instance_type' : self.make_type_string(type.type), + 'instance_type' : self.make_type_string(self.flatten_type_string(type.type)), 'lower' : type.bounds.lower, 'upper' : type.bounds.upper, } @@ -77,7 +77,7 @@ class Mapping: def make_argument_entity(self, attr): type = attr.type if hasattr(attr, 'type') else attr while isinstance(type, nodes.AggregationType): type = type.type - if type in self.express_to_cpp_typemapping or isinstance(type, nodes.BinaryType): return "Type::UNDEFINED" + if type in self.express_to_cpp_typemapping: return "Type::UNDEFINED" else: return "Type::%s" % type def make_argument_type(self, attr): @@ -88,8 +88,6 @@ class Mapping: return "ENTITY_INSTANCE" elif self.schema.is_type(type): return _make_argument_type(self.schema.types[type].type.type) - elif isinstance(type, nodes.BinaryType): - return "BINARY" elif isinstance(type, nodes.EnumerationType): return "ENUMERATION" elif isinstance(type, nodes.AggregationType): @@ -154,23 +152,28 @@ class Mapping: return c + ([str(s) for s in t.derive.elements] if t.derive else []) def list_instance_type(self, attr): + attr_type = attr.type if isinstance(attr, nodes.ExplicitAttribute) else attr + if isinstance(attr_type, str): return None f = lambda v : 'IfcUtil::IfcBaseClass' if self.schema.is_select(v) else str(v) - if self.is_array(attr.type): - if not isinstance(attr.type, str) and self.is_array(attr.type.type): - if isinstance(attr.type.type, str): - return f(attr.type.type) - else: return f(attr.type.type.type) + if self.is_array(attr_type): + if not isinstance(attr_type, str) and self.is_array(attr_type.type): + if isinstance(attr_type.type, str): + return f(attr_type.type) + else: return f(attr_type.type.type) else: - if isinstance(attr.type, str): - return f(attr.type) - else: return f(attr.type.type) + if isinstance(attr_type, str): + return f(attr_type) + else: return f(attr_type.type) return None def is_templated_list(self, attr): + attr_type = attr.type if isinstance(attr, nodes.ExplicitAttribute) else attr + if isinstance(attr, str): return False ty = self.list_instance_type(attr) - arr = self.is_array(attr.type) + if ty is None: return False + arr = self.is_array(attr_type) simple = self.schema.is_simpletype(ty) - express = ty in self.express_to_cpp_typemapping + express = self.flatten_type_string(ty) in self.express_to_cpp_typemapping select = ty == 'IfcUtil::IfcBaseClass' return arr and not simple and not express and not select diff --git a/src/ifcexpressparser/nodes.py b/src/ifcexpressparser/nodes.py index d21a29df67..3bf6753dc8 100644 --- a/src/ifcexpressparser/nodes.py +++ b/src/ifcexpressparser/nodes.py @@ -145,13 +145,6 @@ class DerivedAttribute(Node): return str(self.name) -class BinaryType(Node): - def init(self): - pass - def __repr__(self): - return "binary" - - class BoundSpecification(Node): lower = property(lambda self: self.tokens[1]) upper = property(lambda self: self.tokens[3]) diff --git a/src/ifcexpressparser/templates.py b/src/ifcexpressparser/templates.py index e963d9652b..ea9dd11df9 100644 --- a/src/ifcexpressparser/templates.py +++ b/src/ifcexpressparser/templates.py @@ -346,7 +346,9 @@ simpletype_impl_type = "return Type::%(class_name)s;" simpletype_impl_class = "return Type::%(class_name)s;" simpletype_impl_explicit_constructor = "entity = e;" simpletype_impl_constructor = "IfcWritableEntity* e = new IfcWritableEntity(Type::%(class_name)s); e->setArgument(0, v); entity = e;" -simpletype_impl_cast = "return *entity->getArgument(0);" +simpletype_impl_constructor_templated = "IfcWritableEntity* e = new IfcWritableEntity(Type::%(class_name)s); e->setArgument(0, v->generalize()); entity = e;" +simpletype_impl_cast = "return *entity->getArgument(0);" +simpletype_impl_cast_templated = "IfcEntityList::ptr es = *entity->getArgument(0); return es->as<%(underlying_type)s>();" select = """%(documentation)s typedef IfcUtil::IfcBaseClass %(name)s;