Skip to content

Commit 37d4e9b

Browse files
committed
Fix express parser for simple types that redefine aggregates of entities
1 parent 7390faa commit 37d4e9b

5 files changed

Lines changed: 32 additions & 28 deletions

File tree

src/ifcexpressparser/bootstrap.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,6 @@ def find_keywords(expr, li = None):
114114
'aggregation_types' : "lambda t: AggregationType(t)",
115115
'general_aggregation_types' : "lambda t: AggregationType(t)",
116116
'select_type' : "lambda t: SelectType(t)",
117-
'binary_type' : "lambda t: BinaryType(t)",
118117
'subtype_declaration' : "lambda t: SubtypeExpression(t)",
119118
'derive_clause' : "lambda t: AttributeList('derive', t)",
120119
'derived_attr' : "lambda t: DerivedAttribute(t)",

src/ifcexpressparser/implementation.py

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -72,10 +72,10 @@ def __init__(self, mapping):
7272
def find_template(arg):
7373
simple = mapping.schema.is_simpletype(arg['list_instance_type'])
7474
select = arg['list_instance_type'] == "IfcUtil::IfcBaseClass"
75-
express = arg['list_instance_type'] in mapping.express_to_cpp_typemapping
75+
express = mapping.flatten_type_string(arg['list_instance_type']) in mapping.express_to_cpp_typemapping
7676
if arg['is_enum']: return templates.get_attr_stmt_enum
7777
elif arg['is_nested']: return templates.get_attr_stmt_nested_array
78-
elif arg['is_array'] and not (select or simple or express): return templates.get_attr_stmt_array
78+
elif arg['is_templated_list'] and not (select or simple or express): return templates.get_attr_stmt_array
7979
elif arg['non_optional_type'].endswith('*'): return templates.get_attr_stmt_entity
8080
else: return templates.get_attr_stmt
8181

@@ -96,7 +96,7 @@ def find_template(arg):
9696
select = arg['list_instance_type'] == "IfcUtil::IfcBaseClass"
9797
express = arg['list_instance_type'] in mapping.express_to_cpp_typemapping
9898
if arg['is_enum']: return templates.set_attr_stmt_enum
99-
elif arg['is_array'] and not (select or simple or express): return templates.set_attr_stmt_array
99+
elif arg['is_templated_list'] and not (select or simple or express): return templates.set_attr_stmt_array
100100
else: return templates.set_attr_stmt
101101

102102
tmpl = find_template(arg)
@@ -189,8 +189,15 @@ def get_attribute_index(entity, attr_name):
189189
constructor = templates.constructor_single_initlist if superclass \
190190
else templates.constructor
191191

192+
simpletype_impl_cast = templates.simpletype_impl_cast_templated if mapping.is_templated_list(type) \
193+
else templates.simpletype_impl_cast
194+
195+
simpletype_impl_constructor = templates.simpletype_impl_constructor_templated if mapping.is_templated_list(type) \
196+
else templates.simpletype_impl_constructor
197+
192198
def compose(params):
193199
class_name, attr_type, superclass, superclass_init, name, tmpl, return_type, args, body = params
200+
underlying_type = mapping.list_instance_type(type)
194201
arguments = ",".join(args)
195202
body = body % locals()
196203
return tmpl % locals()
@@ -203,8 +210,8 @@ def compose(params):
203210
('type', templates.const_function, 'Type::Enum', (), templates.simpletype_impl_type ),
204211
('Class', templates.function, 'Type::Enum', (), templates.simpletype_impl_class ),
205212
('', constructor, '', ('IfcAbstractEntity* e',), templates.simpletype_impl_explicit_constructor),
206-
('', constructor, '', ("%s v" % type_str,), templates.simpletype_impl_constructor ),
207-
('', templates.cast_function, type_str, (), templates.simpletype_impl_cast )
213+
('', constructor, '', ("%s v" % type_str,), simpletype_impl_constructor ),
214+
('', templates.cast_function, type_str, (), simpletype_impl_cast )
208215
))))
209216
simple_type_impl.append('')
210217

src/ifcexpressparser/mapping.py

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ def make_type_string(self, type):
6161
is_nested_list = isinstance(type.type, nodes.AggregationType)
6262
tmpl = templates.list_list_type if is_nested_list else templates.list_type if is_list else templates.array_type
6363
return tmpl % {
64-
'instance_type' : self.make_type_string(type.type),
64+
'instance_type' : self.make_type_string(self.flatten_type_string(type.type)),
6565
'lower' : type.bounds.lower,
6666
'upper' : type.bounds.upper,
6767
}
@@ -77,7 +77,7 @@ def is_array(self, type):
7777
def make_argument_entity(self, attr):
7878
type = attr.type if hasattr(attr, 'type') else attr
7979
while isinstance(type, nodes.AggregationType): type = type.type
80-
if type in self.express_to_cpp_typemapping or isinstance(type, nodes.BinaryType): return "Type::UNDEFINED"
80+
if type in self.express_to_cpp_typemapping: return "Type::UNDEFINED"
8181
else: return "Type::%s" % type
8282

8383
def make_argument_type(self, attr):
@@ -88,8 +88,6 @@ def _make_argument_type(type):
8888
return "ENTITY_INSTANCE"
8989
elif self.schema.is_type(type):
9090
return _make_argument_type(self.schema.types[type].type.type)
91-
elif isinstance(type, nodes.BinaryType):
92-
return "BINARY"
9391
elif isinstance(type, nodes.EnumerationType):
9492
return "ENUMERATION"
9593
elif isinstance(type, nodes.AggregationType):
@@ -154,23 +152,28 @@ def derived_in_supertype(self, t):
154152
return c + ([str(s) for s in t.derive.elements] if t.derive else [])
155153

156154
def list_instance_type(self, attr):
155+
attr_type = attr.type if isinstance(attr, nodes.ExplicitAttribute) else attr
156+
if isinstance(attr_type, str): return None
157157
f = lambda v : 'IfcUtil::IfcBaseClass' if self.schema.is_select(v) else str(v)
158-
if self.is_array(attr.type):
159-
if not isinstance(attr.type, str) and self.is_array(attr.type.type):
160-
if isinstance(attr.type.type, str):
161-
return f(attr.type.type)
162-
else: return f(attr.type.type.type)
158+
if self.is_array(attr_type):
159+
if not isinstance(attr_type, str) and self.is_array(attr_type.type):
160+
if isinstance(attr_type.type, str):
161+
return f(attr_type.type)
162+
else: return f(attr_type.type.type)
163163
else:
164-
if isinstance(attr.type, str):
165-
return f(attr.type)
166-
else: return f(attr.type.type)
164+
if isinstance(attr_type, str):
165+
return f(attr_type)
166+
else: return f(attr_type.type)
167167
return None
168168

169169
def is_templated_list(self, attr):
170+
attr_type = attr.type if isinstance(attr, nodes.ExplicitAttribute) else attr
171+
if isinstance(attr, str): return False
170172
ty = self.list_instance_type(attr)
171-
arr = self.is_array(attr.type)
173+
if ty is None: return False
174+
arr = self.is_array(attr_type)
172175
simple = self.schema.is_simpletype(ty)
173-
express = ty in self.express_to_cpp_typemapping
176+
express = self.flatten_type_string(ty) in self.express_to_cpp_typemapping
174177
select = ty == 'IfcUtil::IfcBaseClass'
175178
return arr and not simple and not express and not select
176179

src/ifcexpressparser/nodes.py

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -145,13 +145,6 @@ def __repr__(self):
145145
return str(self.name)
146146

147147

148-
class BinaryType(Node):
149-
def init(self):
150-
pass
151-
def __repr__(self):
152-
return "binary"
153-
154-
155148
class BoundSpecification(Node):
156149
lower = property(lambda self: self.tokens[1])
157150
upper = property(lambda self: self.tokens[3])

src/ifcexpressparser/templates.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -346,7 +346,9 @@ class %(name)s : public %(superclass)s {
346346
simpletype_impl_class = "return Type::%(class_name)s;"
347347
simpletype_impl_explicit_constructor = "entity = e;"
348348
simpletype_impl_constructor = "IfcWritableEntity* e = new IfcWritableEntity(Type::%(class_name)s); e->setArgument(0, v); entity = e;"
349-
simpletype_impl_cast = "return *entity->getArgument(0);"
349+
simpletype_impl_constructor_templated = "IfcWritableEntity* e = new IfcWritableEntity(Type::%(class_name)s); e->setArgument(0, v->generalize()); entity = e;"
350+
simpletype_impl_cast = "return *entity->getArgument(0);"
351+
simpletype_impl_cast_templated = "IfcEntityList::ptr es = *entity->getArgument(0); return es->as<%(underlying_type)s>();"
350352

351353
select = """%(documentation)s
352354
typedef IfcUtil::IfcBaseClass %(name)s;

0 commit comments

Comments
 (0)