diff options
Diffstat (limited to 'qface')
-rw-r--r-- | qface/__about__.py | 4 | ||||
-rw-r--r-- | qface/app.py | 42 | ||||
-rw-r--r-- | qface/filters.py | 68 | ||||
-rw-r--r-- | qface/generator.py | 7 | ||||
-rw-r--r-- | qface/helper/generic.py | 52 | ||||
-rw-r--r-- | qface/helper/qtcpp.py | 6 | ||||
-rw-r--r-- | qface/templates/qface/qtcpp.j2 | 12 | ||||
-rw-r--r-- | qface/utils.py | 13 |
8 files changed, 132 insertions, 72 deletions
diff --git a/qface/__about__.py b/qface/__about__.py index e63ff15..0ed253d 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.9.1" +__version__ = "2.0.0" __author__ = "JRyannel" -__author_email__ = "qface-generator@googlegroups.com" +__author_email__ = "" __copyright__ = "2019 Pelagicore" diff --git a/qface/app.py b/qface/app.py index 800744a..38a26d6 100644 --- a/qface/app.py +++ b/qface/app.py @@ -7,39 +7,61 @@ import logging from path import Path from qface.generator import FileSystem, RuleGenerator from qface.watch import monitor +from qface.utils import load_filters here = Path(__file__).dirname() logging.basicConfig() -def run(spec, src, dst): +def run(spec, src, dst, features, force): spec = Path(spec) project = Path(dst).name system = FileSystem.parse(src) - context = { + extra_filters_path = spec.dirname() / 'filters.py' + extra_filters = load_filters(extra_filters_path) + + ctx = { 'dst': dst, 'system': system, 'project': project, } - generator = RuleGenerator(search_path=spec.dirname() / 'templates', destination=dst, context=context) + generator = RuleGenerator( + search_path=spec.dirname() / 'templates', + destination=dst, + context=ctx, + features=features, + force=force + ) + generator.filters = extra_filters generator.process_rules(spec, system) @click.command() -@click.option('--spec', type=click.Path(exists=True, file_okay=True)) -@click.option('--dst', type=click.Path(exists=False, file_okay=False)) +@click.option('--rules', type=click.Path(exists=True, file_okay=True)) +@click.option('--target', type=click.Path(exists=False, file_okay=False)) @click.option('--reload/--no-reload', default=False, help="Auto reload script on changes") -@click.argument('src', nargs=-1, type=click.Path(exists=True)) -def main(spec, dst, reload, src): - spec = Path(spec) +@click.option('--scaffold/--no-scaffold', default=False, help="Add extrac scaffolding code") +@click.option('--watch', type=click.Path(exists=False, file_okay=False)) +@click.option('--feature', multiple=True) +@click.option('--force/--no-force', default=False, help="forces overwriting of files") +@click.argument('source', nargs=-1, type=click.Path(exists=True)) +def main(rules, target, reload, source, watch, scaffold, feature, force): + rules = Path(rules) if reload: argv = sys.argv.copy() argv.remove('--reload') - monitor(args=argv, watch=src + (spec.dirname(),)) + watch_list = list(source) + watch_list.append(rules.dirname()) + if watch: + watch_list.append(watch) + monitor(args=argv, watch=watch_list) else: - run(spec, src, dst) + features = set(feature) + if scaffold: + features.add('scaffold') + run(rules, source, target, features=features, force=force) if __name__ == '__main__': diff --git a/qface/filters.py b/qface/filters.py index 5969a64..236c7b3 100644 --- a/qface/filters.py +++ b/qface/filters.py @@ -1,58 +1,28 @@ -import json -import hashlib +from .helper import generic from .helper import qtqml from .helper import qtcpp from .helper import doc +import importlib.util -def jsonify(symbol): - """ returns json format for symbol """ - try: - # all symbols have a toJson method, try it - return json.dumps(symbol.toJson(), indent=' ') - except AttributeError: - pass - return json.dumps(symbol, indent=' ') +def get_filters(): + filters = {} + filters.update(generic.get_filters()) + filters.update(qtqml.Filters.get_filters()) + filters.update(qtcpp.Filters.get_filters()) + filters.update(doc.get_filters()) + return filters -def upper_first(s): - """ uppercase first letter """ - s = str(s) - return s[0].upper() + s[1:] +def load_filters(path): + if not path.exists(): + print('filter module does not exist') + return {} + extra_filters = {} + spec = importlib.util.spec_from_file_location('filters', path.abspath()) + filters_module = importlib.util.module_from_spec(spec) + spec.loader.exec_module(filters_module) + filters_module.get_filters(extra_filters) + return extra_filters -def lower_first(s): - s = str(s) - return s[0].lower() + s[1:] - - -def hash(symbol, hash_type='sha1'): - """ create a hash code from symbol """ - code = hashlib.new(hash_type) - code.update(str(symbol).encode('utf-8')) - return code.hexdigest() - - -def path(symbol): - """ replaces '.' with '/' """ - return str(symbol).replace('.', '/') - - -def identifier(s): - return str(s).lower().replace('.', '_') - - -filters = { - 'jsonify': jsonify, - 'upper_first': upper_first, - 'lower_first': lower_first, - 'upperfirst': upper_first, - 'lowerfirst': lower_first, - 'hash': hash, - 'path': path, - 'identifier': identifier, -} - -filters.update(qtqml.Filters.get_filters()) -filters.update(qtcpp.Filters.get_filters()) -filters.update(doc.get_filters()) diff --git a/qface/generator.py b/qface/generator.py index eb3172d..b4f93df 100644 --- a/qface/generator.py +++ b/qface/generator.py @@ -21,7 +21,7 @@ from .idl.parser.TListener import TListener from .idl.profile import EProfile from .idl.domain import System from .idl.listener import DomainListener -from .filters import filters +from .filters import get_filters from jinja2.debug import make_traceback as _make_traceback @@ -94,7 +94,7 @@ class Generator(object): lstrip_blocks=True, ) self.env.exception_handler = template_error_handler - self.env.filters.update(filters) + self.env.filters.update(get_filters()) self._destination = Path() self._path = Path() self._source = '' @@ -170,6 +170,9 @@ class Generator(object): """Using a template file name it renders a template into a file given a context """ + if not file_path or not template: + click.secho('source or target missing for document') + return if not context: context = self.context error = False diff --git a/qface/helper/generic.py b/qface/helper/generic.py new file mode 100644 index 0000000..713952d --- /dev/null +++ b/qface/helper/generic.py @@ -0,0 +1,52 @@ +import json +import hashlib + + +def jsonify(symbol): + """ returns json format for symbol """ + try: + # all symbols have a toJson method, try it + return json.dumps(symbol.toJson(), indent=' ') + except AttributeError: + pass + return json.dumps(symbol, indent=' ') + + +def upper_first(s): + """ uppercase first letter """ + s = str(s) + return s[0].upper() + s[1:] + + +def lower_first(s): + s = str(s) + return s[0].lower() + s[1:] + + +def hash(symbol, hash_type='sha1'): + """ create a hash code from symbol """ + code = hashlib.new(hash_type) + code.update(str(symbol).encode('utf-8')) + return code.hexdigest() + + +def path(symbol): + """ replaces '.' with '/' """ + return str(symbol).replace('.', '/') + + +def identifier(s): + return str(s).lower().replace('.', '_') + + +def get_filters(): + return { + 'jsonify': jsonify, + 'upper_first': upper_first, + 'lower_first': lower_first, + 'upperfirst': upper_first, + 'lowerfirst': lower_first, + 'hash': hash, + 'path': path, + 'identifier': identifier, + } diff --git a/qface/helper/qtcpp.py b/qface/helper/qtcpp.py index aeae6f0..c9e6835 100644 --- a/qface/helper/qtcpp.py +++ b/qface/helper/qtcpp.py @@ -36,7 +36,7 @@ class Filters(object): return 'QVariant()' elif t.is_void: return '' - elif t.is_enum: + elif t.is_enumeration: value = next(iter(t.reference.members)) return '{0}::{0}Enum::{1}'.format(symbol.type, value) elif symbol.kind == 'enum': @@ -58,7 +58,7 @@ class Filters(object): @staticmethod def parameterType(symbol): prefix = Filters.classPrefix - if symbol.type.is_enum: + if symbol.type.is_enumeration: return '{0}::{0}Enum {1}'.format(symbol.type, symbol) if symbol.type.is_void or symbol.type.is_primitive: if symbol.type.is_string: @@ -88,7 +88,7 @@ class Filters(object): def returnType(symbol): prefix = Filters.classPrefix t = symbol.type - if t.is_enum: + if t.is_enumeration: return '{0}::{0}Enum'.format(symbol.type) if symbol.type.is_void or symbol.type.is_primitive: if t.is_string: diff --git a/qface/templates/qface/qtcpp.j2 b/qface/templates/qface/qtcpp.j2 index 729bfc9..b2e3bff 100644 --- a/qface/templates/qface/qtcpp.j2 +++ b/qface/templates/qface/qtcpp.j2 @@ -14,15 +14,15 @@ {%- endmacro %} {% macro property_decl(property, notifiable=True) -%} -Q_PROPERTY({{property|qt.returnType}} {{property}} READ {{property}} {% if not property.readonly %}WRITE set{{property|upperfirst}}{% endif %}{% if not property.const and notifiable %} NOTIFY {{property}}Changed{% endif %}) +Q_PROPERTY({{property|qt.returnType}} {{property}} READ {{property}} {% if not property.readonly %}WRITE push{{property|upperfirst}}{% endif %}{% if not property.const and notifiable %} NOTIFY {{property}}Changed{% endif %}) {%- endmacro %} -{% macro property_setter_decl(property, ending=";") -%} -void set{{property|upperfirst}}({{ property|qt.parameterType }}){{ending}} +{% macro property_setter_decl(property, ending=";", prefix='virtual') -%} +{{prefix}} void push{{property|upperfirst}}({{ property|qt.parameterType }}){{ending}} {%- endmacro %} -{% macro property_getter_decl(property, ending=";") -%} -{{property|qt.returnType}} {{property}}() const{{ending}} +{% macro property_getter_decl(property, ending=";", prefix='virtual') -%} +{{prefix}} {{property|qt.returnType}} {{property}}() const{{ending}} {%- endmacro %} {% macro signal_decl(symbol, postfix="") -%} @@ -41,7 +41,7 @@ void {{symbol}}{{postfix}}(); {{doc.description|join("\n ")}} {% endwith %} */ -void {{class}}::set{{property|upperfirst}}({{ property|qt.parameterType }}) +void {{class}}::push{{property|upperfirst}}({{ property|qt.parameterType }}) { {% if notifiable %} if (m_{{property}} != {{property}}) { diff --git a/qface/utils.py b/qface/utils.py index f816b58..889d862 100644 --- a/qface/utils.py +++ b/qface/utils.py @@ -9,3 +9,16 @@ def module_info(text): 'title': module.name, 'brief': " ".join(doc.parse_doc(module.comment).brief) } + + +def load_filters(path): + if not path.exists(): + print('filter module does not exist') + return {} + + ctx = { + 'filters': {} + } + exec(path.text(), ctx) + return ctx['filters'] + |