summaryrefslogtreecommitdiff
path: root/src/tools/ivigenerator/generator/filters.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/tools/ivigenerator/generator/filters.py')
-rw-r--r--src/tools/ivigenerator/generator/filters.py734
1 files changed, 734 insertions, 0 deletions
diff --git a/src/tools/ivigenerator/generator/filters.py b/src/tools/ivigenerator/generator/filters.py
new file mode 100644
index 0000000..737143c
--- /dev/null
+++ b/src/tools/ivigenerator/generator/filters.py
@@ -0,0 +1,734 @@
+#!/usr/bin/env python3
+# Copyright (C) 2019 The Qt Company Ltd.
+# Copyright (C) 2019 Luxoft Sweden AB
+# Copyright (C) 2018 Pelagicore AG
+# Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB)
+# Contact: https://www.qt.io/licensing/
+#
+# This file is part of the QtIvi module of the Qt Toolkit.
+#
+# $QT_BEGIN_LICENSE:LGPL-QTAS$
+# Commercial License Usage
+# Licensees holding valid commercial Qt Automotive Suite licenses may use
+# this file in accordance with the commercial license agreement provided
+# with the Software or, alternatively, in accordance with the terms
+# contained in a written agreement between you and The Qt Company. For
+# licensing terms and conditions see https://www.qt.io/terms-conditions.
+# For further information use the contact form at https://www.qt.io/contact-us.
+#
+# GNU Lesser General Public License Usage
+# Alternatively, this file may be used under the terms of the GNU Lesser
+# General Public License version 3 as published by the Free Software
+# Foundation and appearing in the file LICENSE.LGPL3 included in the
+# packaging of this file. Please review the following information to
+# ensure the GNU Lesser General Public License version 3 requirements
+# will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+#
+# GNU General Public License Usage
+# Alternatively, this file may be used under the terms of the GNU
+# General Public License version 2.0 or (at your option) the GNU General
+# Public license version 3 or any later version approved by the KDE Free
+# Qt Foundation. The licenses are as published by the Free Software
+# Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+# included in the packaging of this file. Please review the following
+# information to ensure the GNU General Public License requirements will
+# be met: https://www.gnu.org/licenses/gpl-2.0.html and
+# https://www.gnu.org/licenses/gpl-3.0.html.
+#
+# $QT_END_LICENSE$
+#
+# SPDX-License-Identifier: LGPL-3.0
+
+import json
+
+from qface.idl.domain import Module, Interface, Property, Parameter, Field, Struct
+from qface.helper.generic import lower_first, upper_first
+from qface.helper.qtcpp import Filters
+
+from .global_functions import jinja_error, jinja_warning
+from . import builtin_config
+
+
+def tag_by_path(symbol, path, default_value=False):
+ """
+ Find the tag given by its full path in the object hierarchy,
+ like "property.config_sim.zones.right". If some part of the
+ path is missing, return None
+ """
+ path_parts = path.split(".")
+ cur_level_obj = symbol.tags
+ for path_part in path_parts:
+ if path_part in cur_level_obj:
+ cur_level_obj = cur_level_obj[path_part]
+ else:
+ cur_level_obj = None
+ break
+ if cur_level_obj is None:
+ cur_level_obj = default_value
+ return cur_level_obj
+
+
+def conf_sim_tag(symbol, path, default_value=False):
+ """
+ Find tag, given by its path, located under "config_simulator" sub-object.
+ Returns None, of any of the path parts is missing
+ """
+ return tag_by_path(symbol, "config_simulator." + path, default_value)
+
+
+def enum_value_to_cppliteral(value, module_name):
+ value = value.strip().rsplit('.', 1)[-1]
+ return '{0}{1}Module::{2}'.format(Filters.classPrefix, upper_first(module_name), value)
+
+
+def enum_value(value, module_name):
+ sub_values = value.split('|')
+ sub_values = [enum_value_to_cppliteral(v, module_name) for v in sub_values]
+ return "|".join(sub_values)
+
+
+def default_type_value(symbol):
+ """
+ Find the default value for the type. Models are initialized as nullptr
+ """
+ prefix = Filters.classPrefix
+ t = symbol.type
+ if t.is_primitive:
+ if t.is_int:
+ return 'int(0)'
+ if t.is_bool:
+ return 'bool(false)'
+ if t.is_string:
+ return 'QString()'
+ if t.is_real:
+ return 'qreal(0.0)'
+ if t.is_var:
+ return 'QVariant()'
+ elif t.is_void:
+ return ''
+ elif t.is_enum:
+ module_name = t.reference.module.module_name
+ value = next(iter(t.reference.members))
+ return '{0}{1}Module::{2}'.format(prefix, upper_first(module_name), value)
+ elif t.is_flag:
+ module_name = t.reference.module.module_name
+ return '{0}{1}Module::{2}()'.format(prefix, upper_first(module_name), flag_type(symbol))
+ elif symbol.type.is_list:
+ nested = Filters.returnType(symbol.type.nested)
+ return 'QVariantList()'.format(nested)
+ elif symbol.type.is_struct:
+ return '{0}{1}()'.format(prefix, symbol.type.reference.name)
+ elif symbol.type.is_model:
+ return 'nullptr'
+ jinja_error('default_type_value: Unknown parameter {0} of type {1}'.format(symbol, symbol.type))
+
+
+def test_type_value(symbol):
+ """
+ Find a value different than the default value for the type. Models are initialized as nullptr
+ """
+ prefix = Filters.classPrefix
+ t = symbol.type
+ if t.is_primitive:
+ if t.is_int:
+ return '111'
+ if t.is_bool:
+ return 'true'
+ if t.is_string:
+ return 'QStringLiteral("TEST STRING")'
+ if t.is_real:
+ return '1234.5678'
+ if t.is_var:
+ return 'QVariant("TEST VARIANT")'
+ elif t.is_void:
+ return ''
+ elif t.is_enum:
+ module_name = t.reference.module.module_name
+ value = list(iter(t.reference.members))[-1]
+ return '{0}{1}Module::{2}'.format(prefix, upper_first(module_name), value)
+ elif t.is_flag:
+ module_name = t.reference.module.module_name
+ value = next(iter(t.reference.members))
+ return '{0}{1}Module::{2}'.format(prefix, upper_first(module_name), value)
+ elif symbol.type.is_list:
+ value = test_type_value(t.nested.type)
+ if not (t.nested.type.is_primitive):
+ value = 'QVariant::fromValue({0})'.format(value)
+ return 'QVariantList({{{0}}})'.format(value)
+ elif symbol.type.is_struct:
+ values_string = ', '.join(test_type_value(e) for e in symbol.type.reference.fields)
+ return '{0}{1}({2})'.format(prefix, symbol.type.reference.name, values_string)
+ elif symbol.type.is_model:
+ return 'new QIviPagingModel()'
+ jinja_error('test_type_value: Unknown parameter {0} of type {1}'.format(symbol, symbol.type))
+
+
+def default_value_helper(symbol, res):
+ t = symbol.type
+ if t.is_struct:
+ if not (isinstance(res, dict) or isinstance(res, list)):
+ jinja_error('default_value: value in annotation is supposed to be a dict or list')
+ if len(res) != len(t.reference.fields):
+ jinja_error('default_value: argument count in annotation and number of struct fields '
+ 'does not match')
+ values = []
+ for idx, property in enumerate(res):
+ values.append(default_value_helper(list(t.reference.fields)[idx], property))
+ return '{0}({{{1}}})'.format(t.type, ', '.join(values))
+ if t.is_model or t.is_list:
+ if not isinstance(res, list):
+ jinja_error('default_value: value in annotation is supposed to be a list')
+ row_string = ''
+ if t.nested.is_struct and t.is_list:
+ row_string = ', '.join(('QVariant::fromValue({0})'.format(default_value_helper(t.nested, row))) for row in res)
+ else:
+ row_string = ', '.join(default_value_helper(t.nested, row) for row in res)
+ return '{{{0}}}'.format(row_string)
+ if t.is_enum or t.is_flag:
+ module_name = t.reference.module.module_name
+ return enum_value(res, module_name)
+ # in case it's bool, Python True is sent to the C++ as "True", let's take care of that
+ if t.is_bool:
+ if res:
+ return 'true'
+ else:
+ return 'false'
+ if t.is_string:
+ return 'QStringLiteral("{0}")'.format(res.replace("\\", "\\\\"))
+ if t.is_var:
+ if isinstance(res, str):
+ res = 'QStringLiteral("{0}")'.format(res)
+ return 'QVariant({0})'.format(res)
+
+ return '{0}'.format(res)
+
+
+def default_value(symbol, zone='='):
+ """
+ Find the default value used by the simulator backend
+ """
+ res = default_type_value(symbol)
+ if symbol.type.is_model:
+ res = '{}'
+ if 'config_simulator' in symbol.tags and 'default' in symbol.tags['config_simulator']:
+ res = symbol.tags['config_simulator']['default']
+ if isinstance(res, dict):
+ if zone in res:
+ res = res[zone]
+ elif '=' in res:
+ res = res['=']
+ return default_value_helper(symbol, res)
+
+ return res
+
+
+def parameter_type_default(symbol):
+ """
+ Return the parameter declaration for properties, handle camel case module name
+ """
+ prefix = Filters.classPrefix
+ if symbol.type.is_enum or symbol.type.is_flag:
+ return '{0}{1}Module::{2} {3}={4}'.format(prefix, upper_first(symbol.type.reference.module.module_name), flag_type(symbol), symbol, default_type_value(symbol))
+ if symbol.type.is_void or symbol.type.is_primitive:
+ if symbol.type.name == 'string':
+ return 'const QString &{0}=QString()'.format(symbol)
+ if symbol.type.name == 'var':
+ return 'const QVariant &{0}=QVariant()'.format(symbol)
+ if symbol.type.name == 'real':
+ return 'qreal {0}=qreal()'.format(symbol)
+ return '{0} {1}={2}'.format(symbol.type, symbol, default_type_value(symbol))
+ elif symbol.type.is_list:
+ nested = return_type(symbol.type.nested)
+ return 'const QVariantList &{1}=QVariantList()'.format(nested, symbol)
+ elif symbol.type.is_model:
+ nested = symbol.type.nested
+ if nested.is_primitive:
+ return '{0}VariantModel *{1}=QVariantModel'.format(prefix, symbol)
+ elif nested.is_complex:
+ return 'QIviPagingModel *{0}=nullptr'.format(symbol)
+ else:
+ return 'const {0}{1} &{2}={0}{1}()'.format(prefix, symbol.type.reference.name, symbol)
+ jinja_error('parameter_type_default: Unknown parameter {0} of type {1}'.format(symbol,
+ symbol.type))
+
+
+def parameter_type(symbol):
+ """
+ Return the parameter declaration for properties, handle camel case module name
+ """
+ prefix = Filters.classPrefix
+ if symbol.type.is_enum or symbol.type.is_flag:
+ return '{0}{1}Module::{2} {3}'.format(prefix, upper_first(symbol.type.reference.module.module_name), flag_type(symbol), symbol)
+ if symbol.type.is_void or symbol.type.is_primitive:
+ if symbol.type.name == 'string':
+ return 'const QString &{0}'.format(symbol)
+ if symbol.type.name == 'var':
+ return 'const QVariant &{0}'.format(symbol)
+ if symbol.type.name == 'real':
+ return 'qreal {0}'.format(symbol)
+ return '{0} {1}'.format(symbol.type, symbol)
+ elif symbol.type.is_list:
+ nested = return_type(symbol.type.nested)
+ return 'const QVariantList &{1}'.format(nested, symbol)
+ elif symbol.type.is_model:
+ nested = symbol.type.nested
+ if nested.is_primitive:
+ return '{0}VariantModel *{1}'.format(prefix, symbol)
+ elif nested.is_complex:
+ return 'QIviPagingModel *{0}'.format(symbol)
+ else:
+ return 'const {0}{1} &{2}'.format(prefix, symbol.type.reference.name, symbol)
+ jinja_error('parameter_type: Unknown parameter {0} of type {1}'.format(symbol, symbol.type))
+
+
+def return_type(symbol):
+ """
+ Return the type declaration for properties, handle camel case module name
+ """
+ prefix = Filters.classPrefix
+ if symbol.type.is_enum or symbol.type.is_flag:
+ return('{0}{1}Module::{2}'.format(prefix,
+ upper_first(symbol.type.reference.module.module_name),
+ flag_type(symbol)))
+ if symbol.type.is_void or symbol.type.is_primitive:
+ if symbol.type.name == 'string':
+ return 'QString'
+ if symbol.type.name == 'var':
+ return 'QVariant'
+ if symbol.type.name == 'real':
+ return 'qreal'
+ return symbol.type.name
+ elif symbol.type.is_list:
+ nested = return_type(symbol.type.nested)
+ return 'QVariantList'.format(nested)
+ elif symbol.type.is_model:
+ nested = symbol.type.nested
+ if nested.is_primitive:
+ return '{0}VariantModel *'.format(prefix)
+ elif nested.is_complex:
+ return 'QIviPagingModel *'
+ else:
+ return '{0}{1}'.format(prefix, symbol.type.reference.name)
+ jinja_error('return_type: Unknown symbol {0} of type {1}'.format(symbol, symbol.type))
+
+
+def flag_type(symbol):
+ """
+ Return the annotation for the flag type if available, the plural otherwise
+ """
+ actualType = symbol
+ if symbol.type.reference:
+ actualType = symbol.type.reference
+ if actualType.is_flag:
+ if 'config' in actualType.tags and 'type' in actualType.tags['config']:
+ return actualType.tags['config']['type']
+ return '{0}s'.format(actualType)
+ return actualType
+
+
+def domain_values(symbol):
+ """
+ Returns domain values for property (if defined by @domain)
+ """
+ if type(symbol) is Property:
+ if 'config_simulator' in symbol.tags:
+ if 'domain' in symbol.tags['config_simulator']:
+ return symbol.tags['config_simulator']['domain']
+ return None
+
+
+def getter_name(symbol):
+ """
+ Returns the getter name of the property
+ """
+ if type(symbol) is Property:
+ if 'config' in symbol.tags and 'getter_name' in symbol.tags['config']:
+ return symbol.tags['config']['getter_name']
+ return symbol
+
+
+def setter_name(symbol):
+ """
+ Returns the setter name of the property
+ """
+ if type(symbol) is Property:
+ if 'config' in symbol.tags and 'setter_name' in symbol.tags['config']:
+ return symbol.tags['config']['setter_name']
+ return 'set' + symbol.name[0].upper() + symbol.name[1:]
+
+
+def range_value(symbol, index, key):
+ """
+ Returns value for property (if defined by @range index or key)
+ """
+ if type(symbol) is Property and symbol.type.is_int or symbol.type.is_real:
+ if 'config_simulator' in symbol.tags:
+ if 'range' in symbol.tags['config_simulator']:
+ return symbol.tags['config_simulator']['range'][index]
+ if key in symbol.tags['config_simulator']:
+ return symbol.tags['config_simulator'][key]
+ return None
+
+
+def range_high(symbol):
+ """
+ Returns maximum value for property (if defined by @range or @maximum)
+ """
+ return range_value(symbol, 1, 'maximum')
+
+
+def range_low(symbol):
+ """
+ Returns minimum value for property (if defined by @range or @minimum)
+ """
+ return range_value(symbol, 0, 'minimum')
+
+
+def has_domains(properties):
+ """
+ Returns true if any property has range or domain tags
+ """
+ for property in properties:
+ if 'config_simulator' in property.tags:
+ for p in ['range', 'domain', 'minimum', 'maximum']:
+ if p in property.tags['config_simulator']:
+ return True
+ return False
+
+
+def strip_QT(s):
+ """
+ If the given string starts with QT, stip it away.
+ """
+ s = str(s)
+ if s.startswith('QT'):
+ return s[2:]
+ return s
+
+
+def json_domain(properties):
+ """
+ Returns property domains formated in json
+ """
+ data = {}
+ if len(properties):
+ data["iviVersion"] = builtin_config.config["VERSION"]
+ for property in properties:
+ if 'config_simulator' in property.tags:
+ for p in ['range', 'domain', 'minimum', 'maximum']:
+ if (property.tags['config_simulator'] is not None
+ and p in property.tags['config_simulator']):
+ if property.name not in data:
+ data[property.name] = {}
+ data[property.name][p] = property.tags['config_simulator'][p]
+ return json.dumps(data, separators=(',', ':'))
+
+
+def simulationData(module):
+ data = {}
+ for interface in module.interfaces:
+ iData = {}
+ if 'config_simulator' in interface.tags:
+ iData = interface.tags['config_simulator']
+ for property in interface.properties:
+ if 'config_simulator' in property.tags:
+ for p in ['range', 'domain', 'minimum', 'maximum', 'default']:
+ if (property.tags['config_simulator'] is not None
+ and p in property.tags['config_simulator']):
+ if property.name not in iData:
+ iData[property.name] = {}
+ iData[property.name][p] = symbolToJson(property.tags['config_simulator'][p],
+ property.type)
+ data[interface.name] = iData
+ return json.dumps(data, indent=' ')
+
+
+def symbolToJson(data, symbol):
+ if symbol.type.is_struct:
+ t = symbol.type
+ if not (isinstance(data, dict) or isinstance(data, list)):
+ jinja_error('simulationData: value in annotation is supposed to be a dict or list')
+ if len(data) != len(t.reference.fields):
+ jinja_error('simulationData: argument count in annotation and number of struct fields '
+ 'does not match')
+ newList = list(symbolToJson(property, list(t.reference.fields)[idx]) for idx, property in enumerate(data))
+ return {"type": symbol.type.name, "value": newList}
+ elif symbol.type.is_enum or symbol.type.is_flag:
+ module_name = symbol.type.reference.module.module_name
+ return {"type": "enum", "value": enum_value(data, module_name)}
+ elif symbol.type.is_list or symbol.type.is_model:
+ nested = symbol.type.nested
+ if nested.is_complex:
+ newList = []
+ for value in data:
+ newList.append(symbolToJson(value, nested))
+ return newList
+ return data
+
+
+def qml_control_properties(symbol, backend_object):
+ """
+ Returns properties of the QML control matching to this
+ IDL type (e.g. min/max properties)
+ """
+ prop_str = lower_first(symbol) + "Control"
+ if isinstance(symbol, Property):
+ top = range_high(symbol)
+ bottom = range_low(symbol)
+ binding = "value: {0}.{1};".format(backend_object, symbol.name)
+ if top is not None and bottom is not None:
+ return 'id: {0}; from: {1}; to: {2}; {3}'.format(prop_str, bottom, top, binding)
+
+ if top is not None or bottom is not None:
+ if top is None:
+ return 'id: {0}; from: {1}; to:100000; {2}'.format(prop_str, bottom, binding)
+ elif bottom is None:
+ return 'id: {0}; from:-100000; to: {1}; {2}'.format(prop_str, top, binding)
+
+ values = domain_values(symbol)
+ if values is None and (symbol.type.is_enum or symbol.type.is_flag):
+ values_string = ' '.join('ListElement {{ key: "{0}"; value: {1}.{0} }}'.format(e, qml_type(symbol.interface)) for e in symbol.type.reference.members)
+ return 'id: {0}; textRole: "key"; {2} model: ListModel {{ {1} }}'.format(prop_str,
+ values_string,
+ binding)
+ if values is not None:
+ values_string = ','.join('"'+str(e)+'"' for e in values)
+ return 'id: {0}; model: [ {1} ]; '.format(prop_str, values_string)
+ if symbol.type.is_bool:
+ binding = "checked: {0}.{1};".format(backend_object, symbol.name)
+ return 'id: {0}; {1}'.format(prop_str, binding)
+ if symbol.type.is_real or symbol.type.is_int or symbol.type.is_string:
+ binding = "text: {0}.{1};".format(backend_object, symbol.name)
+ return 'id: {0}; {1}'.format(prop_str, binding)
+
+ if isinstance(symbol, Parameter):
+ return 'id: {1}Param{0}'.format(prop_str, symbol.operation)
+ if isinstance(symbol, Field):
+ return 'id: {1}_{0}'.format(prop_str, lower_first(symbol.struct))
+
+
+def qml_control_signal_parameters(symbol):
+ """
+ Returns the parameters for calling the signal using the values from the ui controls
+ """
+ return ', '.join('{0}Param{1}Control.{2}'.format(e.operation, lower_first(e),qml_binding_property(e)) for e in symbol.parameters)
+
+
+def qml_meta_control_name(symbol):
+ """
+ Returns name of the QML control needed to display this type based on the meta
+ data of the symbol -- if symbol has some meta data (e.g. value limits or domain)
+ then control name is taken based on these constraints. Otherwise returns None.
+ """
+ top = range_high(symbol)
+ bottom = range_low(symbol)
+ if top is not None and bottom is not None:
+ return 'Slider'
+
+ if top is not None or bottom is not None:
+ return 'SpinBox'
+
+ values = domain_values(symbol)
+ if values is not None:
+ return "ComboBox"
+
+
+def qml_type_control_name(symbol):
+ """
+ Returns name of the QML control inferred based on the type of the symbol.
+ """
+ t = symbol.type
+ if t.is_string or t.is_int or t.is_real:
+ return "TextField"
+ elif t.is_bool:
+ return "CheckBox"
+ elif t.is_enum:
+ if t.reference.is_enum:
+ return "EnumControl"
+ elif t.reference.is_flag:
+ return "FlagControl"
+ elif t.is_flag:
+ return "FlagControl"
+ return "TextField"
+
+
+def qml_control_name(symbol):
+ """
+ Returns name of the QML control for the symbol. First it checks meta data (as it may
+ influence the control type) and if nothing is defined there, it falls back to the
+ symbol actual type.
+ """
+ # First try to calculate control name based on the tags
+ control_name = qml_meta_control_name(symbol)
+ # If nothing is defined, calculate it based on its type
+ if control_name is None:
+ control_name = qml_type_control_name(symbol)
+ return control_name
+
+
+def qml_control(symbol, backend_object):
+ """
+ Returns QML code for the control (or group of controls) to represent the editing UI for the
+ symbol.
+ """
+
+ if symbol.type.is_struct:
+ return qml_struct_control(symbol)
+
+ return "{0} {{ {1} }}".format(qml_control_name(symbol),
+ qml_control_properties(symbol, backend_object))
+
+
+def qml_binding_property(symbol):
+ """
+ :param symbol: property which is being bound by the control
+ :return: name of the property of the QML control to be bound with
+ """
+ control_name = qml_control_name(symbol)
+ if control_name == "CheckBox":
+ return "checked"
+ elif (control_name == "Slider" or control_name == "SpinBox" or control_name == "FlagControl"
+ or control_name == "EnumControl"):
+ return "value"
+ elif control_name == "TextField":
+ return "text"
+ elif control_name == "ComboBox":
+ return "currentIndex"
+
+
+def qml_struct_control(symbol):
+ if symbol.type.is_struct and symbol.type.reference.fields:
+ result = "Rectangle { ColumnLayout { "
+ for field in symbol.type.reference.fields:
+ result += qml_control(field)
+ result += "}}"
+ return result
+
+
+def qml_info_type(symbol):
+ """
+ Returns the correct type for the symbol, to be used inside the qmltype templates
+ """
+ prefix = Filters.classPrefix
+ if symbol.type.is_enum or symbol.type.is_flag:
+ return('{0}{1}Module::{2}'.format(prefix, upper_first(symbol.module.module_name),
+ flag_type(symbol)))
+ elif symbol.type.is_void or symbol.type.is_primitive:
+ if symbol.type.is_real:
+ return 'double'
+ return symbol.type.name
+ elif symbol.type.is_struct:
+ return 'QVariant'
+ elif symbol.type.is_list:
+ return 'QVariantList'
+ elif symbol.type.is_model:
+ return 'QIviPagingModel'
+ else:
+ jinja_error('qml_info_type: Unknown symbol {0} of type {1}'.format(symbol, symbol.type))
+
+
+def qml_type(symbol):
+ """
+ :param interface:
+ :return: Returns the name of the interface for using in QML. This name is defined in the IDL
+ under the "config" tag as "qml_type". This annotation is optional, if not provided, the
+ interface name is used.
+ """
+ result = symbol.name
+ if 'qml_type' in symbol.tags['config']:
+ result = symbol.tags['config']['qml_type']
+ elif 'qml_name' in symbol.tags['config']:
+ result = symbol.tags['config']['qml_name']
+ return result
+
+
+def model_type(symbol):
+ if symbol.type.is_model:
+ nested = symbol.type.nested
+ return '{0}Model'.format(nested)
+ return None
+
+
+def struct_includes(symbol):
+ includesSet = set()
+ tpl = '#include \"{0}.h\"'
+
+ if isinstance(symbol, Struct):
+ for val in symbol.fields:
+ if val.type.is_struct:
+ includesSet.add(tpl.format(val.type.reference.name).lower())
+ elif isinstance(symbol, Interface):
+ for val in symbol.properties:
+ if val.type.is_struct:
+ includesSet.add(tpl.format(val.type.reference.name).lower())
+ for op in symbol.operations:
+ for param in op.parameters:
+ if param.type.is_struct:
+ includesSet.add(tpl.format(param.type.reference.name).lower())
+ if op.type.is_struct:
+ includesSet.add(tpl.format(op.type.reference.name).lower())
+ for op in symbol.signals:
+ for param in op.parameters:
+ if param.type.is_struct:
+ includesSet.add(tpl.format(param.type.reference.name).lower())
+
+ return includesSet
+
+
+def comment_text(comment):
+ """
+ Returns the text of the passed comment without the leading/trailing comment tokens e.g. /**, *
+ """
+ comment_start = ['/**', '/*!', '/*']
+ processed = []
+ isComment = False
+
+ # No comment is NOT a error
+ if len(comment) == 0:
+ return processed
+
+ for token in comment_start:
+ if (comment.startswith(token)):
+ isComment = True
+ break
+ if isComment:
+ comment = comment[3:-2]
+ else:
+ jinja_error("comment_text: The provided comment needs to be start with one of these "
+ "strings: {}".format(comment_start))
+
+ for line in comment.splitlines():
+ line = line.lstrip(" *")
+ processed.append(line)
+ return processed
+
+
+def register_filters(generator):
+ generator.env.keep_trailing_newline = True
+ generator.register_filter('return_type', return_type)
+ generator.register_filter('parameter_type_default', parameter_type_default)
+ generator.register_filter('parameter_type', parameter_type)
+ generator.register_filter('getter_name', getter_name)
+ generator.register_filter('setter_name', setter_name)
+ generator.register_filter('test_type_value', test_type_value)
+ generator.register_filter('default_type_value', default_type_value)
+ generator.register_filter('default_value', default_value)
+ generator.register_filter('model_type', model_type)
+ generator.register_filter('flag_type', flag_type)
+ generator.register_filter('range_low', range_low)
+ generator.register_filter('range_high', range_high)
+ generator.register_filter('strip_QT', strip_QT)
+ generator.register_filter('domain_values', domain_values)
+ generator.register_filter("enum_value", enum_value)
+ generator.register_filter("tag_by_path", tag_by_path)
+ generator.register_filter("conf_sim_tag", conf_sim_tag)
+ generator.register_filter('has_domains', has_domains)
+ generator.register_filter('simulationData', simulationData)
+ generator.register_filter('json_domain', json_domain)
+ generator.register_filter('qml_info_type', qml_info_type)
+ generator.register_filter('qml_type', qml_type)
+ generator.register_filter('qml_control', qml_control)
+ generator.register_filter('qml_binding_property', qml_binding_property)
+ generator.register_filter('qml_control_signal_parameters', qml_control_signal_parameters)
+ generator.register_filter('struct_includes', struct_includes)
+ generator.register_filter('comment_text', comment_text)