black ifcopenshell-python

This commit is contained in:
htlcnn
2020-11-01 20:08:27 +07:00
committed by Dion Moult
parent 2c9d6a47f4
commit 286c77e3b0
27 changed files with 1502 additions and 979 deletions
@@ -22,6 +22,7 @@ import templates
from schema import OrderedCaseInsensitiveDict
class Implementation(codegen.Base):
def __init__(self, mapping):
enumeration_functions = []
@@ -31,230 +32,324 @@ class Implementation(codegen.Base):
schema_name = mapping.schema.name.capitalize()
schema_name_upper = mapping.schema.name.upper()
stringify = lambda s: '"%s"'%s
stringify = lambda s: '"%s"' % s
cat = lambda vs: "".join(vs)
catc = lambda vs: ", ".join(vs)
catnl = lambda vs: "\n".join(vs)
cator = lambda vs: " || ".join(vs)
nl = lambda s: "%s\n"%s if len(s) else s
nl = lambda s: "%s\n" % s if len(s) else s
write = lambda str, **kwargs: enumeration_functions.append(str%kwargs)
write = lambda str, **kwargs: enumeration_functions.append(str % kwargs)
for name, enum in mapping.schema.enumerations.items():
short_name = name[:-4] if name.endswith("Enum") else name
context = locals()
write(
templates.enumeration_function,
max_id = len(enum.values),
name = name,
schema_name = schema_name,
schema_name_upper = schema_name_upper,
values = catc(map(stringify, enum.values)),
from_string_statements = catnl(templates.enum_from_string_stmt%dict(context,**locals()) for value in enum.values)
max_id=len(enum.values),
name=name,
schema_name=schema_name,
schema_name_upper=schema_name_upper,
values=catc(map(stringify, enum.values)),
from_string_statements=catnl(
templates.enum_from_string_stmt % dict(context, **locals()) for value in enum.values
),
)
write = lambda str, **kwargs: entity_implementations.append(str%kwargs)
write = lambda str, **kwargs: entity_implementations.append(str % kwargs)
for name, type in mapping.schema.entities.items():
parent_type_test = "" if not type.supertypes or len(type.supertypes) != 1 \
else templates.parent_type_test%(type.supertypes[0])
constructor_arguments = mapping.get_assignable_arguments(type, include_derived = True)
constructor_arguments_str = catc("%(full_type)s v%(index)d_%(name)s"%a for a in constructor_arguments if not a['is_derived'])
for name, type in mapping.schema.entities.items():
parent_type_test = (
""
if not type.supertypes or len(type.supertypes) != 1
else templates.parent_type_test % (type.supertypes[0])
)
constructor_arguments = mapping.get_assignable_arguments(type, include_derived=True)
constructor_arguments_str = catc(
"%(full_type)s v%(index)d_%(name)s" % a for a in constructor_arguments if not a["is_derived"]
)
attributes = []
constructor_implementations = []
write_attr = lambda str, **kwargs: attributes.append(str%kwargs)
write_attr = lambda str, **kwargs: attributes.append(str % kwargs)
for arg in constructor_arguments:
if not arg['is_inherited'] and not arg['is_derived']:
if arg['is_optional']:
if not arg["is_inherited"] and not arg["is_derived"]:
if arg["is_optional"]:
write_attr(
templates.const_function,
class_name = name,
schema_name = schema_name,
schema_name_upper = schema_name_upper,
name = 'has%s'%arg['name'],
arguments = '',
return_type = 'bool',
body = templates.optional_attr_stmt % {'index':arg['index']-1}
class_name=name,
schema_name=schema_name,
schema_name_upper=schema_name_upper,
name="has%s" % arg["name"],
arguments="",
return_type="bool",
body=templates.optional_attr_stmt % {"index": arg["index"] - 1},
)
def find_template(arg):
simple = mapping.schema.is_simpletype(arg['list_instance_type'])
select = arg['list_instance_type'] == "IfcUtil::IfcBaseClass"
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'] and arg['is_templated_list']: return templates.get_attr_stmt_nested_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
simple = mapping.schema.is_simpletype(arg["list_instance_type"])
select = arg["list_instance_type"] == "IfcUtil::IfcBaseClass"
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"] and arg["is_templated_list"]:
return templates.get_attr_stmt_nested_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
tmpl = find_template(arg)
write_attr(
templates.const_function,
class_name = name,
name = arg['name'],
arguments = '',
schema_name = schema_name,
schema_name_upper = schema_name_upper,
return_type = arg['non_optional_type'],
body = tmpl % {'index': arg['index']-1,
'type' : arg['non_optional_type'].replace('::Value', ''),
'list_instance_type' : arg['list_instance_type']}
class_name=name,
name=arg["name"],
arguments="",
schema_name=schema_name,
schema_name_upper=schema_name_upper,
return_type=arg["non_optional_type"],
body=tmpl
% {
"index": arg["index"] - 1,
"type": arg["non_optional_type"].replace("::Value", ""),
"list_instance_type": arg["list_instance_type"],
},
)
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
if arg['is_enum']: return templates.set_attr_stmt_enum
elif arg['is_templated_list'] and not (select or simple or express): return templates.set_attr_stmt_array
else: return templates.set_attr_stmt
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
if arg["is_enum"]:
return templates.set_attr_stmt_enum
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)
write_attr(
templates.function,
class_name = name,
name = 'set%s'%arg['name'],
arguments = '%s v'%arg['non_optional_type'],
return_type = 'void',
schema_name = schema_name,
schema_name_upper = schema_name_upper,
body = tmpl % {'index': arg['index']-1,
'type' : arg['non_optional_type'].replace('::Value', '')}
class_name=name,
name="set%s" % arg["name"],
arguments="%s v" % arg["non_optional_type"],
return_type="void",
schema_name=schema_name,
schema_name_upper=schema_name_upper,
body=tmpl
% {"index": arg["index"] - 1, "type": arg["non_optional_type"].replace("::Value", "")},
)
if arg['is_derived']:
constructor_implementations.append(templates.constructor_stmt_derived % {'index' : arg['index']-1})
if arg["is_derived"]:
constructor_implementations.append(templates.constructor_stmt_derived % {"index": arg["index"] - 1})
else:
is_optional_non_naked_ptr = arg['is_optional'] and not arg['non_optional_type'].endswith('*')
arg_name = "v%(index)d_%(name)s"%arg
deref_name = ("*%s"%arg_name) if is_optional_non_naked_ptr else arg_name
is_optional_non_naked_ptr = arg["is_optional"] and not arg["non_optional_type"].endswith("*")
arg_name = "v%(index)d_%(name)s" % arg
deref_name = ("*%s" % arg_name) if is_optional_non_naked_ptr else arg_name
tmpl = templates.constructor_stmt_array if arg['is_templated_list'] \
else templates.constructor_stmt_enum if arg['is_enum'] \
tmpl = (
templates.constructor_stmt_array
if arg["is_templated_list"]
else templates.constructor_stmt_enum
if arg["is_enum"]
else templates.constructor_stmt
impl = tmpl % {'name' : deref_name,
'index' : arg['index']-1,
'type' : arg['non_optional_type'].replace('::Value', '')}
)
impl = tmpl % {
"name": deref_name,
"index": arg["index"] - 1,
"type": arg["non_optional_type"].replace("::Value", ""),
}
if is_optional_non_naked_ptr:
impl = templates.constructor_stmt_optional%{'name' : arg_name,
'index' : arg['index']-1,
'stmt' : impl}
impl = templates.constructor_stmt_optional % {
"name": arg_name,
"index": arg["index"] - 1,
"stmt": impl,
}
constructor_implementations.append(impl)
def get_attribute_index(entity, attr_name):
related_entity = mapping.schema.entities[entity]
return [a['name'].lower() for a in mapping.get_assignable_arguments(related_entity, include_derived=True)].index(attr_name.lower())
return [
a["name"].lower() for a in mapping.get_assignable_arguments(related_entity, include_derived=True)
].index(attr_name.lower())
inverse = [templates.const_function % {
'class_name' : name,
'schema_name' : schema_name,
'schema_name_upper' : schema_name_upper,
'name' : i.name,
'arguments' : '',
'return_type' : '::%s::%s::list::ptr' % (schema_name, i.entity),
'body' : templates.get_inverse % {'type': i.entity, 'index':get_attribute_index(i.entity, i.attribute), 'schema_name' : schema_name, 'schema_name_upper': schema_name_upper}
} for i in type.inverse]
inverse = [
templates.const_function
% {
"class_name": name,
"schema_name": schema_name,
"schema_name_upper": schema_name_upper,
"name": i.name,
"arguments": "",
"return_type": "::%s::%s::list::ptr" % (schema_name, i.entity),
"body": templates.get_inverse
% {
"type": i.entity,
"index": get_attribute_index(i.entity, i.attribute),
"schema_name": schema_name,
"schema_name_upper": schema_name_upper,
},
}
for i in type.inverse
]
superclass = "%s((IfcEntityInstanceData*)0)" % type.supertypes[0] if len(type.supertypes) == 1 else 'IfcUtil::IfcBaseEntity()'
superclass = (
"%s((IfcEntityInstanceData*)0)" % type.supertypes[0]
if len(type.supertypes) == 1
else "IfcUtil::IfcBaseEntity()"
)
write(
templates.entity_implementation,
name = name,
parent_type_test = parent_type_test,
constructor_arguments = constructor_arguments_str,
constructor_implementation = cat(constructor_implementations),
attributes = nl(catnl(attributes)),
inverse = nl(catnl(inverse)),
superclass = superclass,
schema_name = schema_name,
schema_name_upper = schema_name_upper
name=name,
parent_type_test=parent_type_test,
constructor_arguments=constructor_arguments_str,
constructor_implementation=cat(constructor_implementations),
attributes=nl(catnl(attributes)),
inverse=nl(catnl(inverse)),
superclass=superclass,
schema_name=schema_name,
schema_name_upper=schema_name_upper,
)
selectable_simple_types = sorted(set(sum([b.values for a,b in mapping.schema.selects.items()], [])) & set(map(str, mapping.schema.types.keys())))
schema_entity_statements += [templates.schema_entity_stmt%locals() for name, type in mapping.schema.simpletypes.items()]
schema_entity_statements += [templates.schema_entity_stmt%locals() for name, type in mapping.schema.entities.items()]
selectable_simple_types = sorted(
set(sum([b.values for a, b in mapping.schema.selects.items()], []))
& set(map(str, mapping.schema.types.keys()))
)
schema_entity_statements += [
templates.schema_entity_stmt % locals() for name, type in mapping.schema.simpletypes.items()
]
schema_entity_statements += [
templates.schema_entity_stmt % locals() for name, type in mapping.schema.entities.items()
]
enumerable_types = sorted(set([name for name, type in mapping.schema.types.items()] + [name for name, type in mapping.schema.entities.items()]))
enumerable_types = sorted(
set(
[name for name, type in mapping.schema.types.items()]
+ [name for name, type in mapping.schema.entities.items()]
)
)
max_len = max(map(len, enumerable_types))
type_name_strings = catc(map(stringify, enumerable_types))
string_map_statements = [templates.string_map_statement % {
'uppercase_name' : name.upper(),
'name' : name,
'padding' : ' ' * (max_len - len(name))
} for name in enumerable_types]
enumeration_index_by_str = OrderedCaseInsensitiveDict((j,i) for i,j in enumerate(enumerable_types))
string_map_statements = [
templates.string_map_statement
% {"uppercase_name": name.upper(), "name": name, "padding": " " * (max_len - len(name))}
for name in enumerable_types
]
enumeration_index_by_str = OrderedCaseInsensitiveDict((j, i) for i, j in enumerate(enumerable_types))
def get_parent_id(s):
e = mapping.schema.entities.get(s)
if e and e.supertypes:
return enumeration_index_by_str[e.supertypes[0]]
else: return -1
else:
return -1
parent_type_statements = ",".join(map(str, map(get_parent_id, enumerable_types)))
max_id = len(enumerable_types)
simple_type_statements = cator("v == Type::%s"%name for name in selectable_simple_types)
simple_type_statements = cator("v == Type::%s" % name for name in selectable_simple_types)
simple_type_impl = []
for class_name, type in mapping.schema.simpletypes.items():
type_str = mapping.make_type_string(mapping.flatten_type_string(type))
attr_type = mapping.make_argument_type(type)
superclass = mapping.simple_type_parent(class_name)
simpletype_impl_is = templates.simpletype_impl_is_with_supertype if superclass \
simpletype_impl_is = (
templates.simpletype_impl_is_with_supertype
if superclass
else templates.simpletype_impl_is_without_supertype
constructor = templates.constructor_single_initlist if superclass \
else templates.constructor
simpletype_impl_cast = templates.simpletype_impl_cast_templated if mapping.is_templated_list(type) \
)
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) \
)
simpletype_impl_constructor = (
templates.simpletype_impl_constructor_templated
if mapping.is_templated_list(type)
else templates.simpletype_impl_constructor
)
def compose(params, schema_name=schema_name, schema_name_upper=schema_name_upper):
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()
simple_type_impl.append(templates.simpletype_impl_comment % {'name': class_name})
simple_type_impl.extend(map(compose, map(lambda x: (class_name, attr_type, superclass, "(IfcEntityInstanceData*)0")+x, (
('Class', templates.function, 'const IfcParse::type_declaration&', (), templates.simpletype_impl_class ),
('declaration', templates.const_function, 'const IfcParse::type_declaration&', (), templates.simpletype_impl_declaration ),
('', constructor, '', ('IfcEntityInstanceData* e',), templates.simpletype_impl_explicit_constructor),
('', constructor, '', ("%s v" % type_str,), simpletype_impl_constructor ),
('', templates.cast_function, type_str, (), simpletype_impl_cast )
))))
simple_type_impl.append('')
external_definitions = [("extern entity* %s_%%s_type;" % schema_name_upper) % n for n in mapping.schema.entities.keys() ] + \
[("extern type_declaration* %s_%%s_type;" % schema_name_upper) % n for n in mapping.schema.simpletypes.keys()]
simple_type_impl.append(templates.simpletype_impl_comment % {"name": class_name})
simple_type_impl.extend(
map(
compose,
map(
lambda x: (class_name, attr_type, superclass, "(IfcEntityInstanceData*)0") + x,
(
(
"Class",
templates.function,
"const IfcParse::type_declaration&",
(),
templates.simpletype_impl_class,
),
(
"declaration",
templates.const_function,
"const IfcParse::type_declaration&",
(),
templates.simpletype_impl_declaration,
),
(
"",
constructor,
"",
("IfcEntityInstanceData* e",),
templates.simpletype_impl_explicit_constructor,
),
("", constructor, "", ("%s v" % type_str,), simpletype_impl_constructor),
("", templates.cast_function, type_str, (), simpletype_impl_cast),
),
),
)
)
simple_type_impl.append("")
external_definitions = [
("extern entity* %s_%%s_type;" % schema_name_upper) % n for n in mapping.schema.entities.keys()
] + [
("extern type_declaration* %s_%%s_type;" % schema_name_upper) % n for n in mapping.schema.simpletypes.keys()
]
self.str = templates.implementation % {
'schema_name_upper' : schema_name_upper,
'schema_name' : schema_name,
'max_id' : max_id,
'enumeration_functions' : cat(enumeration_functions),
'schema_entity_statements' : catnl(schema_entity_statements),
'type_name_strings' : type_name_strings,
'string_map_statements' : catnl(string_map_statements),
'simple_type_statement' : simple_type_statements,
'parent_type_statements' : parent_type_statements,
'entity_implementations' : catnl(entity_implementations),
'simple_type_impl' : catnl(simple_type_impl),
'external_definitions' : catnl(external_definitions)
"schema_name_upper": schema_name_upper,
"schema_name": schema_name,
"max_id": max_id,
"enumeration_functions": cat(enumeration_functions),
"schema_entity_statements": catnl(schema_entity_statements),
"type_name_strings": type_name_strings,
"string_map_statements": catnl(string_map_statements),
"simple_type_statement": simple_type_statements,
"parent_type_statements": parent_type_statements,
"entity_implementations": catnl(entity_implementations),
"simple_type_impl": catnl(simple_type_impl),
"external_definitions": catnl(external_definitions),
}
self.schema_name = mapping.schema.name.capitalize()
self.file_name = '%s.cpp'%self.schema_name
self.file_name = "%s.cpp" % self.schema_name
def __repr__(self):
return self.str