summaryrefslogtreecommitdiff
path: root/qface
diff options
context:
space:
mode:
Diffstat (limited to 'qface')
-rw-r--r--qface/__about__.py2
-rw-r--r--qface/generator.py39
-rw-r--r--qface/helper/qtcpp.py40
-rw-r--r--qface/idl/domain.py10
-rw-r--r--qface/templates/qface/qtcpp.j24
-rw-r--r--qface/watch.py1
6 files changed, 71 insertions, 25 deletions
diff --git a/qface/__about__.py b/qface/__about__.py
index c16b3dd..7073a0f 100644
--- a/qface/__about__.py
+++ b/qface/__about__.py
@@ -9,7 +9,7 @@ except NameError:
__title__ = "qface"
__summary__ = "A generator framework based on a common modern IDL"
__url__ = "https://pelagicore.github.io/qface/"
-__version__ = "1.8"
+__version__ = "1.8.1"
__author__ = "JRyannel"
__author_email__ = "qface-generator@googlegroups.com"
__copyright__ = "2017 Pelagicore"
diff --git a/qface/generator.py b/qface/generator.py
index ef02062..eca36f0 100644
--- a/qface/generator.py
+++ b/qface/generator.py
@@ -35,6 +35,7 @@ logger = logging.getLogger(__name__)
Provides an API for accessing the file system and controlling the generator
"""
+
class ReportingErrorListener(ErrorListener.ErrorListener):
def __init__(self, document):
self.document = document
@@ -71,6 +72,7 @@ class Generator(object):
)
self.env.filters.update(filters)
self._destination = Path()
+ self._source = ''
self.context = context
@property
@@ -84,6 +86,16 @@ class Generator(object):
self._destination = Path(self.apply(dst, self.context))
@property
+ def source(self):
+ """source prefix for template lookup"""
+ return self._source
+
+ @source.setter
+ def source(self, source: str):
+ if source:
+ self._source = source
+
+ @property
def filters(self):
return self.env.filters
@@ -93,7 +105,14 @@ class Generator(object):
def get_template(self, name: str):
"""Retrieves a single template file from the template loader"""
- return self.env.get_template(name)
+ source = name
+ if name and name[0] is '/':
+ source = name[1:]
+ elif self.source is not None:
+ source = '/'.join((self.source, name))
+ print('get_template: ', name, source)
+
+ return self.env.get_template(source)
def render(self, name: str, context: dict):
"""Returns the rendered text from a single template file from the
@@ -115,7 +134,6 @@ class Generator(object):
try:
self._write(file_path, template, context, preserve)
except TemplateSyntaxError as exc:
- # import pdb; pdb.set_trace()
message = '{0}:{1} error: {2}'.format(exc.filename, exc.lineno, exc.message)
click.secho(message, fg='red')
error = True
@@ -161,25 +179,29 @@ class RuleGenerator(Generator):
self.context.update({
'dst': destination,
'project': Path(destination).name,
+ 'features': features,
})
self.destination = '{{dst}}'
self.features = features
- def process_rules(self, path: Path, system: System, features:set=set()):
+ def process_rules(self, path: Path, system: System):
"""writes the templates read from the rules document"""
- self.features.update(features)
- self.context.update({'system': system})
+ self.context.update({
+ 'system': system,
+ })
document = FileSystem.load_yaml(path, required=True)
for module, rules in document.items():
- click.secho('module: {0}'.format(module), fg='green')
+ click.secho('process: {0}'.format(module), fg='green')
self._process_rules(rules, system)
def _process_rules(self, rules: dict, system: System):
""" process a set of rules for a target """
+ self._source = None # reset the template source
if not self._shall_proceed(rules):
return
self.context.update(rules.get('context', {}))
self.destination = rules.get('destination', '{{dst}}')
+ self.source = rules.get('source', None)
self._process_rule(rules.get('system', None), {'system': system})
for module in system.modules:
self._process_rule(rules.get('module', None), {'module': module})
@@ -197,7 +219,10 @@ class RuleGenerator(Generator):
self.context.update(context)
self.context.update(rule.get('context', {}))
self.destination = rule.get('destination', None)
+ self.source = rule.get('source', None)
preserved = rule.get('preserve', [])
+ if not preserved:
+ preserved = []
for target, source in rule.get('documents', {}).items():
preserve = target in preserved
self.write(target, source, preserve=preserve)
@@ -263,6 +288,8 @@ class FileSystem(object):
"""Read a YAML document and for each root symbol identifier
updates the tag information of that symbol
"""
+ if not Path(document).exists():
+ return
meta = FileSystem.load_yaml(document)
click.secho('merge: {0}'.format(document.name), fg='blue')
for identifier, data in meta.items():
diff --git a/qface/helper/qtcpp.py b/qface/helper/qtcpp.py
index 5561fe5..83aa8fc 100644
--- a/qface/helper/qtcpp.py
+++ b/qface/helper/qtcpp.py
@@ -28,7 +28,7 @@ class Filters(object):
return 'QString()'
if t.is_real:
return 'qreal(0.0)'
- if t.is_variant:
+ if t.is_var:
return 'QVariant()'
elif t.is_void:
return ''
@@ -58,12 +58,16 @@ class Filters(object):
if symbol.type.is_enum:
return '{0}{1}Module::{2} {3}'.format(prefix, module_name, symbol.type, symbol)
if symbol.type.is_void or symbol.type.is_primitive:
- if symbol.type.name == 'string':
+ if symbol.type.is_string:
return 'const QString &{0}'.format(symbol)
- if symbol.type.name == 'var':
+ if symbol.type.is_var:
return 'const QVariant &{0}'.format(symbol)
- if symbol.type.name == 'real':
+ if symbol.type.is_real:
return 'qreal {0}'.format(symbol)
+ if symbol.type.is_bool:
+ return 'bool {0}'.format(symbol)
+ if symbol.type.is_int:
+ return 'int {0}'.format(symbol)
return '{0} {1}'.format(symbol.type, symbol)
elif symbol.type.is_list:
nested = Filters.returnType(symbol.type.nested)
@@ -82,16 +86,24 @@ class Filters(object):
def returnType(symbol):
prefix = Filters.classPrefix
module_name = upper_first(symbol.module.module_name)
- if symbol.type.is_enum:
+ t = symbol.type
+ if t.is_enum:
return '{0}{1}Module::{2}'.format(prefix, module_name, symbol.type)
if symbol.type.is_void or symbol.type.is_primitive:
- if symbol.type.name == 'string':
+ if t.is_string:
return 'QString'
- if symbol.type.name == 'var':
+ if t.is_var:
return 'QVariant'
- if symbol.type.name == 'real':
+ if t.is_real:
return 'qreal'
- return symbol.type.name
+ if t.is_int:
+ return 'int'
+ if t.is_bool:
+ return 'bool'
+ if t.is_void:
+ return 'void'
+ print(t)
+ assert False
elif symbol.type.is_list:
nested = Filters.returnType(symbol.type.nested)
return 'QVariantList'.format(nested)
@@ -125,7 +137,14 @@ class Filters(object):
@staticmethod
def ns(symbol):
'''generates a namespace x::y::z statement from a symbol'''
- return '::'.join(symbol.module.name_parts)
+ if symbol.type and symbol.type.is_primitive:
+ return ''
+ return '{0}::'.format('::'.join(symbol.module.name_parts))
+
+ @staticmethod
+ def fqn(symbol):
+ '''generates a fully qualified name from symbol'''
+ return '{0}::{1}'.format(Filters.ns(symbol), symbol.name)
@staticmethod
def signalName(s):
@@ -193,6 +212,7 @@ class Filters(object):
'close_ns': Filters.close_ns,
'using_ns': Filters.using_ns,
'ns': Filters.ns,
+ 'fqn': Filters.fqn,
'signalName': Filters.signalName,
'parameters': Filters.parameters,
'signature': Filters.signature,
diff --git a/qface/idl/domain.py b/qface/idl/domain.py
index defdca3..d4f87ca 100644
--- a/qface/idl/domain.py
+++ b/qface/idl/domain.py
@@ -220,6 +220,11 @@ class TypeSymbol(NamedElement):
return self.is_primitive and self.name == 'string'
@property
+ def is_var(self):
+ '''checks if type is primitive and var'''
+ return self.is_primitive and self.name == 'var'
+
+ @property
def is_enumeration(self):
'''checks if type is complex and insytance of type Enum'''
return self.is_complex and isinstance(self.reference, Enum)
@@ -245,11 +250,6 @@ class TypeSymbol(NamedElement):
return self.is_complex and isinstance(self.reference, Interface)
@property
- def is_variant(self):
- '''checks if type is primitive and string'''
- return self.is_primitive and self.name == 'var'
-
- @property
def reference(self):
"""returns the symbol reference of the type name"""
if not self.__is_resolved:
diff --git a/qface/templates/qface/qtcpp.j2 b/qface/templates/qface/qtcpp.j2
index bf7824f..c2b13db 100644
--- a/qface/templates/qface/qtcpp.j2
+++ b/qface/templates/qface/qtcpp.j2
@@ -30,7 +30,7 @@ void {{symbol}}{{postfix}}({{symbol|parameters}});
{% macro property_setter_impl(class, property) -%}
/*!
- \qmlproperty {{property.type}} {{interface}}::{{property}}
+ \qmlproperty {{property.type}} {{class}}::{{property}}
{% with doc = property.comment|parse_doc %}
\brief {{doc.brief}}
@@ -42,7 +42,7 @@ void {{class}}::set{{property|upperfirst}}({{ property|parameterType }})
{
if (m_{{property}} != {{property}}) {
m_{{property}} = {{property}};
- emit {{property}}Changed({{property}});
+ Q_EMIT {{property}}Changed({{property}});
}
}
{%- endmacro %}
diff --git a/qface/watch.py b/qface/watch.py
index f99b45a..4667fe3 100644
--- a/qface/watch.py
+++ b/qface/watch.py
@@ -42,7 +42,6 @@ def monitor(script, src, dst):
click.secho('watch recursive: {0}'.format(script.dirname()), fg='blue')
observer.schedule(event_handler, script.dirname(), recursive=True)
for entry in src:
- entry = entry.dirname().expand().abspath()
click.secho('watch recursive: {0}'.format(entry), fg='blue')
observer.schedule(event_handler, entry, recursive=True)
event_handler.run() # run always once