diff options
author | Juergen Bocklage-Ryannel <jbocklage-ryannel@luxoft.com> | 2017-07-11 14:55:19 +0200 |
---|---|---|
committer | Juergen Bocklage-Ryannel <jbocklage-ryannel@luxoft.com> | 2017-07-11 14:55:19 +0200 |
commit | 0d14afac1f67e8b6096e011af35a65051ac5d567 (patch) | |
tree | b5ee76b9462e883d8cd732bb38682a85010ae717 | |
parent | e033e0a8c6a90acad9069132c09641d52888aa99 (diff) | |
parent | 7f955af3b3c508ed5d6941d3b03fd34b83f73924 (diff) |
Merge branch 'release/1.3'1.3
58 files changed, 374 insertions, 1606 deletions
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 0000000..154e14a --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,10 @@ +image: "python:3.5" + +stages: + - test + +test: + stage: test + script: + - pip install -r requirements.txt + - ./cli.py test_ci diff --git a/qface/__about__.py b/qface/__about__.py index de7d0cf..6fe4300 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" __uri__ = "https://pelagicore.github.io/qface/" -__version__ = "1.2" +__version__ = "1.3" __author__ = "JRyannel" __author_email__ = "qface-generator@googlegroups.com" __copyright__ = "2017 Pelagicore" diff --git a/qface/builtin/__init__.py b/qface/builtin/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/qface/builtin/__init__.py +++ /dev/null diff --git a/qface/builtin/qtcpp/__init__.py b/qface/builtin/qtcpp/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/qface/builtin/qtcpp/__init__.py +++ /dev/null diff --git a/qface/builtin/qtcpp/log.yaml b/qface/builtin/qtcpp/log.yaml deleted file mode 100644 index 21b5bba..0000000 --- a/qface/builtin/qtcpp/log.yaml +++ /dev/null @@ -1,18 +0,0 @@ -version: 1 -formatters: - simple: - format: '%(asctime)s - %(name)s - %(levelname)s - %(message)s' -handlers: - console: - class: logging.StreamHandler - level: INFO - formatter: simple - stream: ext://sys.stdout -loggers: - qface.generator: - level: WARN - handlers: [console] - propagate: no -root: - level: DEBUG - handlers: [console] diff --git a/qface/builtin/qtcpp/qtcpp.py b/qface/builtin/qtcpp/qtcpp.py deleted file mode 100755 index 3a4af2e..0000000 --- a/qface/builtin/qtcpp/qtcpp.py +++ /dev/null @@ -1,82 +0,0 @@ -#!/usr/bin/env python3 -# Copyright (c) Pelagicore AB 2016 - -import click -import logging -import logging.config -import yaml -from path import Path - -from qface.generator import FileSystem, Generator -from qface.helper.qtcpp import Filters -from qface.helper.doc import parse_doc -from qface.watch import monitor - - -here = Path(__file__).dirname() - -logging.config.dictConfig(yaml.load(open(here / 'log.yaml'))) - -log = logging.getLogger(__file__) - - -def run(src, dst): - log.debug('run {0} {1}'.format(src, dst)) - system = FileSystem.parse(src) - generator = Generator(search_path=here / 'templates') - generator.register_filter('returnType', Filters.returnType) - generator.register_filter('parameterType', Filters.parameterType) - generator.register_filter('defaultValue', Filters.defaultValue) - generator.register_filter('parse_doc', parse_doc) - ctx = {'dst': dst} - for module in system.modules: - log.debug('generate code for module %s', module) - ctx.update({'module': module}) - dst = generator.apply('{{dst}}/{{module|lower|replace(".", "-")}}', ctx) - generator.destination = dst - generator.write('CMakeLists.txt', 'CMakeLists.txt', ctx) - generator.write('qmldir', 'qmldir', ctx, preserve=True) - generator.write('plugin.cpp', 'plugin.cpp', ctx, preserve=True) - generator.write('plugin.h', 'plugin.h', ctx, preserve=True) - generator.write('{{module|lower|replace(".", "-")}}.pro', 'plugin.pro', ctx, preserve=True) - generator.write('generated/generated.pri', 'generated.pri', ctx) - generator.write('generated/qml{{module.module_name|lower}}module.h', 'module.h', ctx) - generator.write('generated/qml{{module.module_name|lower}}module.cpp', 'module.cpp', ctx) - generator.write('generated/qmlvariantmodel.h', 'variantmodel.h', ctx) - generator.write('generated/qmlvariantmodel.cpp', 'variantmodel.cpp', ctx) - generator.write('docs/plugin.qdocconf', 'plugin.qdocconf', ctx) - generator.write('docs/plugin-project.qdocconf', 'plugin-project.qdocconf', ctx) - generator.write('docs/docs.pri', 'docs.pri', ctx) - generator.write('.qmake.conf', 'qmake.conf', ctx) - for interface in module.interfaces: - log.debug('generate code for interface %s', interface) - ctx.update({'interface': interface}) - generator.write('qml{{interface|lower}}.h', 'interface.h', ctx, preserve=True) - generator.write('qml{{interface|lower}}.cpp', 'interface.cpp', ctx, preserve=True) - generator.write('generated/qmlabstract{{interface|lower}}.h', 'abstractinterface.h', ctx) - generator.write('generated/qmlabstract{{interface|lower}}.cpp', 'abstractinterface.cpp', ctx) - for struct in module.structs: - log.debug('generate code for struct %s', struct) - ctx.update({'struct': struct}) - generator.write('generated/qml{{struct|lower}}.h', 'struct.h', ctx) - generator.write('generated/qml{{struct|lower}}.cpp', 'struct.cpp', ctx) - generator.write('generated/qml{{struct|lower}}model.h', 'structmodel.h', ctx) - generator.write('generated/qml{{struct|lower}}model.cpp', 'structmodel.cpp', ctx) - - -@click.command() -@click.option('--reload/--no-reload', default=False) -@click.argument('src', nargs=-1, type=click.Path(exists=True)) -@click.argument('dst', nargs=1, type=click.Path(exists=True)) -def app(src, dst, reload): - """Takes several files or directories as src and generates the code - in the given dst directory.""" - if reload: - script = Path(__file__).abspath() - monitor(script, src, dst) - else: - run(src, dst) - - -if __name__ == '__main__': - app() diff --git a/qface/builtin/qtcpp/templates/CMakeLists.txt b/qface/builtin/qtcpp/templates/CMakeLists.txt deleted file mode 100644 index bb7fdb9..0000000 --- a/qface/builtin/qtcpp/templates/CMakeLists.txt +++ /dev/null @@ -1,42 +0,0 @@ -{% set module_name = module.name.lower().replace(".", "_") %} -{% set module_path = module.name_parts|join('/') %} - -project({{module_name}}) - -cmake_minimum_required(VERSION 3.1) - -set(CMAKE_CXX_STANDARD 11) -set(CMAKE_AUTOMOC ON) - -set(INSTALL_PATH "${CMAKE_BINARY_DIR}/imports" CACHE STRING "Path where the plugins are deployed") - -find_package(Qt5Core REQUIRED) -find_package(Qt5Qml REQUIRED) - -set (SOURCES - generated/qml{{module.module_name|lower}}module.cpp -{% for interface in module.interfaces %} - generated/qmlabstract{{interface|lower}}.cpp -{% endfor %} -{% for struct in module.structs %} - generated/qml{{struct|lower}}.cpp - generated/qml{{struct|lower}}model.cpp -{% endfor %} - generated/qmlvariantmodel.cpp -{% for interface in module.interfaces %} - qml{{interface|lower}}.cpp -{% endfor %} - plugin.cpp -) - -add_library({{module_name}}_plugin SHARED ${SOURCES}) - -set(OUTPUT_PATH ${INSTALL_PATH}/{{module_path}}) - -set_target_properties({{module_name}}_plugin PROPERTIES - LIBRARY_OUTPUT_DIRECTORY ${OUTPUT_PATH} - RUNTIME_OUTPUT_DIRECTORY ${OUTPUT_PATH} -) - -target_link_libraries({{module_name}}_plugin PUBLIC Qt5::Core Qt5::Qml) -configure_file(${CMAKE_SOURCE_DIR}/qmldir ${OUTPUT_PATH}/qmldir COPYONLY) diff --git a/qface/builtin/qtcpp/templates/__init__.py b/qface/builtin/qtcpp/templates/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/qface/builtin/qtcpp/templates/__init__.py +++ /dev/null diff --git a/qface/builtin/qtcpp/templates/abstractinterface.cpp b/qface/builtin/qtcpp/templates/abstractinterface.cpp deleted file mode 100644 index 3a70cb6..0000000 --- a/qface/builtin/qtcpp/templates/abstractinterface.cpp +++ /dev/null @@ -1,77 +0,0 @@ -{# Copyright (c) Pelagicore AB 2016 #} -{% set class = 'QmlAbstract{0}'.format(interface) %} -/**************************************************************************** -** This is an auto-generated file. -** Do not edit! All changes made to it will be lost. -****************************************************************************/ - -#include "{{class|lower}}.h" - -#include <QtQml> - -/*! - \qmltype {{interface}} - \inqmlmodule {{module}} -{% with doc = interface.comment|parse_doc %} - \brief {{doc.brief}} - - {{doc.description}} -{% endwith %} -*/ -{{class}}::{{class}}(QObject *parent) - : QObject(parent) -{% for property in interface.properties %} - , m_{{property}}({{property|defaultValue}}) -{% endfor %} -{ -} - - -{{class}}::~{{class}}() -{ -} - -{% for property in interface.properties %} -/*! - \qmlproperty {{property.type}} {{interface}}::{{property}} -{% with doc = property.comment|parse_doc %} - \brief {{doc.brief}} - - {{doc.description}} -{% endwith %} -*/ - -void {{class}}::set{{property|upperfirst}}({{ property|parameterType }}) -{ - if(m_{{property}} == {{property}}) { - return; - } - m_{{property}} = {{property}}; - emit {{property}}Changed(); -} - -{{property|returnType}} {{class}}::{{property}}() const -{ - return m_{{property}}; -} -{% endfor %} - -{%- for operation in interface.operations %} -/*! - \qmlmethod {{operation.type}} {{interface}}::{{operation}}({{operation.parameters|map('parameterType')|join(', ')}}) -{% with doc = operation.comment|parse_doc %} - \brief {{doc.brief}} - {{doc.description}} -{% endwith %} -*/ -{{operation|returnType}} {{class}}::{{operation}}({{operation.parameters|map('parameterType')|join(', ')}}) -{ - {% for parameter in operation.parameters %} - Q_UNUSED({{parameter.name}}); - {% endfor %} - qWarning() << "{{class}}::{{operation}}(...) not implemented"; - return {{operation|defaultValue}}; -} -{% endfor %} - - diff --git a/qface/builtin/qtcpp/templates/abstractinterface.h b/qface/builtin/qtcpp/templates/abstractinterface.h deleted file mode 100644 index 17be77a..0000000 --- a/qface/builtin/qtcpp/templates/abstractinterface.h +++ /dev/null @@ -1,52 +0,0 @@ -{# Copyright (c) Pelagicore AB 2016 #} -{% set class = 'QmlAbstract{0}'.format(interface) %} -/**************************************************************************** -** This is an auto-generated file. -** Do not edit! All changes made to it will be lost. -****************************************************************************/ - -#pragma once - -#include <QtCore> - -#include "qml{{module.module_name|lower}}module.h" - -class {{class}} : public QObject -{ - Q_OBJECT -{% for property in interface.properties %} - Q_PROPERTY({{property|returnType}} {{property}} READ {{property}} {% if not property.readonly %}WRITE set{{property|upperfirst}} {% endif %}{% if not property.const %}NOTIFY {{property}}Changed{% endif %}) -{% endfor %} - -public: - {{class}}(QObject *parent = nullptr); - ~{{class}}(); - -public Q_SLOTS: -{% for operation in interface.operations %} - virtual {{operation|returnType}} {{operation}}({{operation.parameters|map('parameterType')|join(', ')}}); -{% endfor %} - -public: -{% for property in interface.properties %} - virtual void set{{property|upperfirst}}({{ property|parameterType }}); -{% endfor %} - -public: -{% for property in interface.properties %} - virtual {{property|returnType}} {{property}}() const; -{% endfor %} - -Q_SIGNALS: -{% for signal in interface.signals %} - void {{signal}}({{signal.parameters|map('parameterType')|join(', ')}}); -{% endfor %} -{% for property in interface.properties %} - void {{property}}Changed(); -{% endfor %} - -protected: -{% for property in interface.properties %} - {{property|returnType}} m_{{property}}; -{% endfor %} -}; diff --git a/qface/builtin/qtcpp/templates/docs.pri b/qface/builtin/qtcpp/templates/docs.pri deleted file mode 100644 index f6a3e81..0000000 --- a/qface/builtin/qtcpp/templates/docs.pri +++ /dev/null @@ -1,32 +0,0 @@ -exists($$[QT_INSTALL_BINS]/qdoc):exists($$[QT_INSTALL_BINS]/qhelpgenerator) { - check_qdoc = "qdoc/qhelpgenerator in $$[QT_INSTALL_BINS]" - QDOC = $$[QT_INSTALL_BINS]/qdoc - QHELPGENERATOR = $$[QT_INSTALL_BINS]/qhelpgenerator -} else { - check_qdoc = "qdoc/qhelpgenerator in PATH" - QDOC = qdoc - QHELPGENERATOR = qhelpgenerator -} - -defineReplace(cmdEnv) { - !equals(QMAKE_DIR_SEP, /): 1 ~= s,^(.*)$,(set \\1) &&,g - return("$$1") -} - -defineReplace(qdoc) { - return("$$cmdEnv(OUTDIR=$$1 QMLLIVE_VERSION=$$VERSION QMLLIVE_VERSION_TAG=$$VERSION_TAG QT_INSTALL_DOCS=$$[QT_INSTALL_DOCS/src]) $$QDOC") -} - -html-docs.commands = $$qdoc($$BUILD_DIR/doc/html) $$PWD/plugin.qdocconf -html-docs.files = $$BUILD_DIR/doc/html - -docs.depends = html-docs - -QMAKE_EXTRA_TARGETS += html-docs docs - - -OTHER_FILES += \ - $$PWD/*.qdocconf \ - $$PWD/*.qdoc \ - $$PWD/examples/*.qdoc \ - $$PWD/images/*.png diff --git a/qface/builtin/qtcpp/templates/generated.pri b/qface/builtin/qtcpp/templates/generated.pri deleted file mode 100644 index 7457474..0000000 --- a/qface/builtin/qtcpp/templates/generated.pri +++ /dev/null @@ -1,33 +0,0 @@ -{# Copyright (c) Pelagicore AB 2016 #} -############################################################################# -## This is an auto-generated file. -## Do not edit! All changes made to it will be lost. -############################################################################# - -QT += qml quick -CONFIG += c++11 - -HEADERS += \ - $$PWD/qml{{module.module_name|lower}}module.h \ -{% for interface in module.interfaces %} - $$PWD/qmlabstract{{interface|lower}}.h \ -{% endfor %} -{% for struct in module.structs %} - $$PWD/qml{{struct|lower}}.h \ - $$PWD/qml{{struct|lower}}model.h \ -{% endfor %} - $$PWD/qmlvariantmodel.h - - -SOURCES += \ - $$PWD/qml{{module.module_name|lower}}module.cpp \ -{% for interface in module.interfaces %} - $$PWD/qmlabstract{{interface|lower}}.cpp \ -{% endfor %} -{% for struct in module.structs %} - $$PWD/qml{{struct|lower}}.cpp \ - $$PWD/qml{{struct|lower}}model.cpp \ -{% endfor %} - $$PWD/qmlvariantmodel.cpp - - diff --git a/qface/builtin/qtcpp/templates/interface.cpp b/qface/builtin/qtcpp/templates/interface.cpp deleted file mode 100644 index 7aab4ae..0000000 --- a/qface/builtin/qtcpp/templates/interface.cpp +++ /dev/null @@ -1,51 +0,0 @@ -{# Copyright (c) Pelagicore AB 2016 #} -{% set class = 'Qml{0}'.format(interface) %} -/* - * This is a preserved file. - * Changes will not be overriden by the generator. - * To reset the file you need to delete it first. - */ - -#include "{{class|lower}}.h" - -#include <QtQml> - - -/*! - \inqmlmodule {{module}} 1.0 - */ - -QObject* {{class|lower}}_singletontype_provider(QQmlEngine*, QJSEngine*) -{ - return new {{class}}(); -} - - -/*! - \qmltype {{interface}} - \inqmlmodule {{module}} -{% with doc = interface.comment|parse_doc %} - \brief {{doc.brief}} - - {{doc.description}} -{% endwith %} -*/ - -{{interface.comment}} -{{class}}::{{class}}(QObject *parent) - : QmlAbstract{{interface}}(parent) -{ -} - -{{class}}::~{{class}}() -{ -} - -void {{class}}::registerQmlTypes(const QString& uri, int majorVersion, int minorVersion) -{ - {% if 'singleton' in interface.tags %} - qmlRegisterSingletonType<{{class}}>(uri.toLatin1(), majorVersion, minorVersion, "{{interface}}", {{class|lower}}_singletontype_provider); - {% else %} - qmlRegisterType<{{class}}>(uri.toLatin1(), majorVersion, minorVersion, "{{interface}}"); - {% endif %} -} diff --git a/qface/builtin/qtcpp/templates/interface.h b/qface/builtin/qtcpp/templates/interface.h deleted file mode 100644 index c1722f2..0000000 --- a/qface/builtin/qtcpp/templates/interface.h +++ /dev/null @@ -1,24 +0,0 @@ -{# Copyright (c) Pelagicore AB 2016 #} -{% set class = 'Qml{0}'.format(interface) %} -/* - * This is a preserved file. - * Changes will not be overriden by the generator. - * To reset the file you need to delete it first. - */ - -#pragma once - -#include <QtCore> - -#include "generated/qml{{module.module_name|lower}}module.h" -#include "generated/qmlabstract{{interface|lower}}.h" - -class {{class}} : public QmlAbstract{{interface}} -{ - Q_OBJECT -public: - {{class}}(QObject *parent = nullptr); - virtual ~{{class}}(); - - static void registerQmlTypes(const QString& uri, int majorVersion=1, int minorVersion=0); -}; diff --git a/qface/builtin/qtcpp/templates/module.cpp b/qface/builtin/qtcpp/templates/module.cpp deleted file mode 100644 index af2d2f1..0000000 --- a/qface/builtin/qtcpp/templates/module.cpp +++ /dev/null @@ -1,82 +0,0 @@ -{# Copyright (c) Pelagicore AB 2016 #} -/**************************************************************************** -** This is an auto-generated file. -** Do not edit! All changes made to it will be lost. -****************************************************************************/ -{% set class = 'Qml{0}Module'.format(module.module_name) %} - - -#include "{{class|lower}}.h" - -#include <QtQml> - -/*! - \qmlmodule {{module}} 1.0 -{% with doc = module.comment|parse_doc %} - - {{doc.brief}} - - - {{doc.description}} -{% endwith %} - */ - - -/*! - \qmltype {{module.module_name}}Module - \inqmlmodule {{module}} - \brief API to access module functionality - - Provides the enumerations and data type factories for - this module. -*/ -QObject* {{class|lower}}_singletontype_provider(QQmlEngine*, QJSEngine*) -{ - return new {{class}}(); -} - -{{class}}::{{class}}(QObject *parent) - : QObject(parent) -{ -} - -{% for struct in module.structs %} -/*! - \qmlmethod {{struct}} {{module.module_name}}Module::create{{struct}}() - \brief Creates a default constructed data object from type {{struct}} -*/ -Qml{{struct}} {{class}}::create{{struct}}() -{ - return Qml{{struct}}(); -} -{% endfor %} - -void {{class}}::registerTypes() -{ - {% for struct in module.structs %} - qRegisterMetaType<Qml{{struct}}>(); - {% endfor %} - {% for enum in module.enums %} - qRegisterMetaType<{{class}}::{{enum}}>(); - {% endfor %} -} - -void {{class}}::registerQmlTypes(const QString& uri, int majorVersion, int minorVersion) -{ - {% for struct in module.structs %} - qmlRegisterUncreatableType<Qml{{struct}}Model>(uri.toLatin1(), majorVersion, minorVersion, "{{struct}}Model", "Model can not be instantiated from QML"); - {% endfor %} - qmlRegisterSingletonType<{{class}}>(uri.toLatin1(), majorVersion, minorVersion, "{{module.module_name}}Module", {{class|lower}}_singletontype_provider); -} - - -{% for enum in module.enums %} -/** - * \qmlproperty enumeration {{module.module_name}}Module::{{enum}} - * \list - {% for member in enum.members %} - * \li {{member}} - {% endfor %} - * \endlist - */ -{% endfor %}
\ No newline at end of file diff --git a/qface/builtin/qtcpp/templates/module.h b/qface/builtin/qtcpp/templates/module.h deleted file mode 100644 index 5e9ff6f..0000000 --- a/qface/builtin/qtcpp/templates/module.h +++ /dev/null @@ -1,41 +0,0 @@ -{# Copyright (c) Pelagicore AB 2016 #} -/**************************************************************************** -** This is an auto-generated file. -** Do not edit! All changes made to it will be lost. -****************************************************************************/ -{% set class = 'Qml{0}Module'.format(module.module_name) %} - -#pragma once - -#include <QtCore> - -#include "qmlvariantmodel.h" -{% for struct in module.structs %} -#include "qml{{struct|lower}}.h" -#include "qml{{struct|lower}}model.h" -{% endfor %} - -class {{class}} : public QObject { - Q_OBJECT -public: - {{class}}(QObject *parent = nullptr); - -{% for enum in module.enums %} - {% set comma = joiner(",") %} - enum {{enum}} { - {%- for member in enum.members -%} - {{ comma() }} - {{member.name}} = {{member.value}} - {%- endfor %} - - }; - Q_ENUM({{enum}}) -{% endfor %} - -{% for struct in module.structs %} - Q_INVOKABLE Qml{{struct}} create{{struct}}(); -{% endfor %} - - static void registerTypes(); - static void registerQmlTypes(const QString& uri, int majorVersion = 1, int minorVersion = 0); -}; diff --git a/qface/builtin/qtcpp/templates/plugin-online.qdocconf b/qface/builtin/qtcpp/templates/plugin-online.qdocconf deleted file mode 100644 index 771cdae..0000000 --- a/qface/builtin/qtcpp/templates/plugin-online.qdocconf +++ /dev/null @@ -1,19 +0,0 @@ -HTML.footer = \ - " </div>\n" \ - " <p class=\"copy-notice\">\n" \ - " <acronym title=\"Copyright\">©</acronym> 2016 Pelagicore AG.\n" \ - " Documentation contributions included herein are the copyrights of\n" \ - " their respective owners. " \ - " The documentation provided herein is licensed under the terms of the" \ - " <a href=\"http://www.gnu.org/licenses/fdl.html\">GNU Free Documentation" \ - " License version 1.3</a> as published by the Free Software Foundation. " \ - " Qt and respective logos are trademarks of The Qt Company Ltd. " \ - " in Finland and/or other countries worldwide. All other trademarks are property\n" \ - " of their respective owners. </p>\n" - -include($QT_INSTALL_DOCS/global/qt-html-templates-online.qdocconf) - -# Add an .html file with sidebar content, used in the online style -# HTML.stylesheets += style/qt5-sidebar.html - -include(plugin-project.qdocconf) diff --git a/qface/builtin/qtcpp/templates/plugin-project.qdocconf b/qface/builtin/qtcpp/templates/plugin-project.qdocconf deleted file mode 100644 index 0a846cb..0000000 --- a/qface/builtin/qtcpp/templates/plugin-project.qdocconf +++ /dev/null @@ -1,27 +0,0 @@ -{% set module_name = module|lower|replace(".", "_")%} -project = {{module}} -description = {{module|upper}} Reference Documentation -version = 1.0 - -sources.fileextensions = "*.cpp *.qdoc *.mm *.qml" -headers.fileextensions = "*.h *.ch *.h++ *.hh *.hpp *.hxx" - -examples.fileextensions = "*.cpp *.h *.js *.xq *.svg *.xml *.ui *.qhp *.qhcp *.qml" -examples.imageextensions = "*.png *.jpeg *.jpg *.gif *.mng" - -outputdir = html - -exampledirs = ../examples ../src - -headerdirs = \ - .. \ - ../generated - -sourcedirs = \ - .. \ - ../generated - -imagedirs = images - -navigation.landingpage = "{{module}}" -buildversion = "{{module_name}} 1.0" diff --git a/qface/builtin/qtcpp/templates/plugin.cpp b/qface/builtin/qtcpp/templates/plugin.cpp deleted file mode 100644 index aa8fb9a..0000000 --- a/qface/builtin/qtcpp/templates/plugin.cpp +++ /dev/null @@ -1,26 +0,0 @@ -{# Copyright (c) Pelagicore AB 2016 #} -{% set module_name = 'Qml{0}Module'.format(module.module_name) %} -/**************************************************************************** -** This is an auto-generated file. -** Do not edit! All changes made to it will be lost. -****************************************************************************/ - -#include "plugin.h" - -#include <qqml.h> - -#include "generated/{{module_name|lower}}.h" - -{% for interface in module.interfaces %} -#include "qml{{interface|lower}}.h" -{% endfor %} - -void Plugin::registerTypes(const char *uri) -{ - {{module_name}}::registerTypes(); - // @uri {{module|lower}} - {{module_name}}::registerQmlTypes(uri, 1, 0); -{% for interface in module.interfaces %} - Qml{{interface}}::registerQmlTypes(uri, 1, 0); -{% endfor %} -} diff --git a/qface/builtin/qtcpp/templates/plugin.h b/qface/builtin/qtcpp/templates/plugin.h deleted file mode 100644 index 1952c35..0000000 --- a/qface/builtin/qtcpp/templates/plugin.h +++ /dev/null @@ -1,18 +0,0 @@ -{# Copyright (c) Pelagicore AB 2016 #} -/**************************************************************************** -** This is an auto-generated file. -** Do not edit! All changes made to it will be lost. -****************************************************************************/ - -#pragma once - -#include <QtQml> - -class Plugin : public QQmlExtensionPlugin -{ - Q_OBJECT - Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface") - -public: - void registerTypes(const char *uri); -}; diff --git a/qface/builtin/qtcpp/templates/plugin.pro b/qface/builtin/qtcpp/templates/plugin.pro deleted file mode 100644 index 4984015..0000000 --- a/qface/builtin/qtcpp/templates/plugin.pro +++ /dev/null @@ -1,47 +0,0 @@ -{# Copyright (c) Pelagicore AB 2016 #} - -## This is a preserved file and can be edited. -## All changes will not be override. - -TEMPLATE = lib -QT += qml quick -CONFIG += qt plugin c++11 -TARGET = $$qtLibraryTarget({{module|lower}}) - -uri = {{module}} - - -HEADERS += \ -{% for interface in module.interfaces %} - qml{{interface|lower}}.h \ -{% endfor %} - plugin.h - - -SOURCES += \ -{% for interface in module.interfaces %} - qml{{interface|lower}}.cpp \ -{% endfor %} - plugin.cpp - - -include( generated/generated.pri ) -include( docs/docs.pri ) - -DISTFILES = qmldir - -!equals(_PRO_FILE_PWD_, $$OUT_PWD) { - copy_qmldir.target = $$OUT_PWD/qmldir - copy_qmldir.depends = $$_PRO_FILE_PWD_/qmldir - copy_qmldir.commands = $(COPY_FILE) \"$$replace(copy_qmldir.depends, /, $$QMAKE_DIR_SEP)\" \"$$replace(copy_qmldir.target, /, $$QMAKE_DIR_SEP)\" - QMAKE_EXTRA_TARGETS += copy_qmldir - PRE_TARGETDEPS += $$copy_qmldir.target -} - -qmldir.files = qmldir -unix { - installPath = $$[QT_INSTALL_QML]/$$replace(uri, \\., /) - qmldir.path = $$installPath - target.path = $$installPath - INSTALLS += target qmldir -} diff --git a/qface/builtin/qtcpp/templates/plugin.qdocconf b/qface/builtin/qtcpp/templates/plugin.qdocconf deleted file mode 100644 index a45a34b..0000000 --- a/qface/builtin/qtcpp/templates/plugin.qdocconf +++ /dev/null @@ -1,21 +0,0 @@ -include($QT_INSTALL_DOCS/global/qt-html-templates-offline.qdocconf) -include(plugin-project.qdocconf) - -HTML.footer = \ - " </div>\n" \ - " </div>\n" \ - " </div>\n" \ - " </div>\n" \ - "</div>\n" \ - "<div class=\"footer\">\n" \ - " <p>\n" \ - " <acronym title=\"Copyright\">©</acronym> 2016 Pelagicore AG.\n" \ - " Documentation contributions included herein are the copyrights of\n" \ - " their respective owners.<br>" \ - " The documentation provided herein is licensed under the terms of the" \ - " <a href=\"http://www.gnu.org/licenses/fdl.html\">GNU Free Documentation" \ - " License version 1.3</a> as published by the Free Software Foundation.<br>" \ - " Qt and respective logos are trademarks of The Qt Company Ltd. " \ - " in Finland and/or other countries worldwide. All other trademarks are property\n" \ - " of their respective owners. </p>\n" \ - "</div>\n" diff --git a/qface/builtin/qtcpp/templates/qmake.conf b/qface/builtin/qtcpp/templates/qmake.conf deleted file mode 100644 index 03d3435..0000000 --- a/qface/builtin/qtcpp/templates/qmake.conf +++ /dev/null @@ -1,5 +0,0 @@ -SOURCE_DIR=$$PWD -BUILD_DIR=$$shadowed($$PWD) -QMAKEFEATURES=$$SOURCE_DIR/qmake-features - -VERSION = 1.0.0 diff --git a/qface/builtin/qtcpp/templates/qmldir b/qface/builtin/qtcpp/templates/qmldir deleted file mode 100644 index 9fe5d2b..0000000 --- a/qface/builtin/qtcpp/templates/qmldir +++ /dev/null @@ -1,3 +0,0 @@ -{# Copyright (c) Pelagicore AB 2016 #} -module {{module}} -plugin {{module}}
\ No newline at end of file diff --git a/qface/builtin/qtcpp/templates/struct.cpp b/qface/builtin/qtcpp/templates/struct.cpp deleted file mode 100644 index 86f358c..0000000 --- a/qface/builtin/qtcpp/templates/struct.cpp +++ /dev/null @@ -1,112 +0,0 @@ -{# Copyright (c) Pelagicore AB 2016 #} -{% set class = 'Qml{0}'.format(struct) %} -{% set ampersand = joiner(" &&") %} -/**************************************************************************** -** This is an auto-generated file. -** Do not edit! All changes made to it will be lost. -****************************************************************************/ - -#include "{{class|lower}}.h" - - -class {{class}}Data : public QSharedData -{ -public: - {{class}}Data() - : QSharedData() - {% for field in struct.fields %} - , {{field}}({{field|defaultValue}}) - {% endfor %} - { - } - {{class}}Data(const {{class}}Data &other) - : QSharedData(other) - {% for field in struct.fields %} - , {{field}}(other.{{field}}) - {% endfor %} - { - } - -public: -{% for field in struct.fields %} - {{field|returnType}} {{field}}; -{% endfor %} -}; - -// Class - -/*! - \qmltype {{struct}} - \inqmlmodule {{module}} -{% with doc = struct.comment|parse_doc %} - \brief {{doc.brief}} - - \note This is a none creatable data object - - Use the module factory method \l {{module.module_name}}Module::create{{struct}} to create - an instance. - - {{doc.description}} -{% endwith %} -*/ - -{{class}}::{{class}}() - : d(new {{class}}Data) -{ -} - -{{class}}::{{class}}(const {{class}} &other) - : d(other.d) -{ -} - -{{class}}::~{{class}}() -{ -} - -{% for field in struct.fields %} -/*! - \qmlproperty {{field.type}} {{struct}}::{{field}} (field) -{% with doc = field.comment|parse_doc %} - \brief {{doc.brief}} - - \note A none notifiable property - - {{doc.description}} -{% endwith %} -*/ -void {{class}}::set{{field|upperfirst}}({{field|parameterType}}) -{ - d->{{field}} = {{field}}; -} -{{field|returnType}} {{class}}::{{field}}() const -{ - return d->{{field}}; -} - -{% endfor %} - - - -{{class}} {{class}}::clone() -{ - {{class}} other(*this); - other.d.detach(); - return other; -} - -bool {{class}}::operator==(const {{class}} &other) const -{ - return ( - {%- for field in struct.fields %}{{ ampersand() }} - {{field}}() == other.{{field}}() - {%- endfor %} - ); -} - -{{class}} &{{class}}::operator=(const {{class}} &other) -{ - d = other.d; - return *this; -} - diff --git a/qface/builtin/qtcpp/templates/struct.h b/qface/builtin/qtcpp/templates/struct.h deleted file mode 100644 index 7c6a4e6..0000000 --- a/qface/builtin/qtcpp/templates/struct.h +++ /dev/null @@ -1,45 +0,0 @@ -{# Copyright (c) Pelagicore AB 2016 #} -{% set class = 'Qml{0}'.format(struct) %} -/**************************************************************************** -** This is an auto-generated file. -** Do not edit! All changes made to it will be lost. -****************************************************************************/ - -#pragma once - -#include <QtCore> - - -class {{class}}Data; - -class {{class}} -{ - Q_GADGET -{% for field in struct.fields %} - Q_PROPERTY({{field|returnType}} {{field}} READ {{field}} WRITE set{{field|upperfirst}}) -{% endfor %} - -public: - {{class}}(); - {{class}}(const {{class}} &other); - ~{{class}}(); - - Q_INVOKABLE {{class}} clone(); - - bool operator==(const {{class}} &other) const; - {{class}} &operator=(const {{class}} &other); - -{% for field in struct.fields %} - void set{{field|upperfirst}}({{field|parameterType}}); - {{field|returnType}} {{field}}() const; - -{% endfor %} - - -private: - QExplicitlySharedDataPointer <{{class}}Data> d; -}; - -Q_DECLARE_METATYPE({{class}}) - - diff --git a/qface/builtin/qtcpp/templates/structmodel.cpp b/qface/builtin/qtcpp/templates/structmodel.cpp deleted file mode 100644 index 2759dae..0000000 --- a/qface/builtin/qtcpp/templates/structmodel.cpp +++ /dev/null @@ -1,106 +0,0 @@ -{# Copyright (c) Pelagicore AB 2016 #} -{% set class = 'Qml{0}Model'.format(struct) %} -/**************************************************************************** -** This is an auto-generated file. -** Do not edit! All changes made to it will be lost. -****************************************************************************/ - -#include "{{class|lower}}.h" - -{{class}}::{{class}}(QObject *parent) - : QAbstractListModel(parent) -{ - {% for field in struct.fields %} - m_roleNames.insert(Roles::{{field|upperfirst}}, QByteArray("{{field}}")); - {% endfor %} -} - -int {{class}}::count() const -{ - return m_data.count(); -} - -Qml{{struct}} {{class}}::get(int index) -{ - return m_data.value(index); -} - -int {{class}}::rowCount(const QModelIndex &parent) const -{ - Q_UNUSED(parent) - return m_data.count(); -} - -QVariant {{class}}::data(const QModelIndex &index, int role) const -{ - if(index.row() < 0 || index.row() >= count()) { - return QVariant(); - } - const Qml{{struct}} &{{struct|lower}} = m_data.at(index.row()); - switch(role) { - {% for field in struct.fields %} - case Roles::{{field|upperfirst}}: - return QVariant::fromValue({{struct|lower}}.{{field}}()); - {% endfor %} - } - return QVariant(); -} - -QHash<int, QByteArray> {{class}}::roleNames() const -{ - return m_roleNames; -} - - -void {{class}}::insert(int row, const Qml{{struct}} &{{struct|lower}}) -{ - if (row < 0) - row = 0; - if (row >= m_data.count()) - row = m_data.count(); - - beginInsertRows(QModelIndex(), row, row); - m_data.insert(row, {{struct|lower}}); - endInsertRows(); - emit countChanged(count()); -} - -void {{class}}::reset(const QList<Qml{{struct}}> data) -{ - beginResetModel(); - m_data = data; - endResetModel(); -} - -void {{class}}::append(const Qml{{struct}} &{{struct|lower}}) -{ - insert(m_data.count(), {{struct|lower}}); -} - -void {{class}}::update(int row, const Qml{{struct}} &{{struct|lower}}) -{ - if(row < 0 || row >= m_data.count()) { - return; - } - m_data[row] = {{struct|lower}}; - const QModelIndex &index = createIndex(row, 0); - emit dataChanged(index, index); -} - -void {{class}}::remove(int row) -{ - if(row < 0 || row >= m_data.count()) { - return; - } - beginRemoveRows(QModelIndex(), row, row); - m_data.removeAt(row); - endRemoveRows(); -} - -void {{class}}::clear() -{ - beginResetModel(); - m_data.clear(); - endResetModel(); -} - diff --git a/qface/builtin/qtcpp/templates/structmodel.h b/qface/builtin/qtcpp/templates/structmodel.h deleted file mode 100644 index ab02b25..0000000 --- a/qface/builtin/qtcpp/templates/structmodel.h +++ /dev/null @@ -1,40 +0,0 @@ -{# Copyright (c) Pelagicore AB 2016 #} -{% set class = 'Qml{0}Model'.format(struct) %} -/**************************************************************************** -** This is an auto-generated file. -** Do not edit! All changes made to it will be lost. -****************************************************************************/ - -#pragma once - -#include <QtCore> - -#include "qml{{struct|lower}}.h" - -class {{class}} : public QAbstractListModel -{ - Q_OBJECT - Q_PROPERTY(int count READ count NOTIFY countChanged) -public: - enum Roles { {{struct.fields|map('upperfirst')|join(', ')}} }; - {{class}}(QObject *parent = nullptr); - Q_INVOKABLE Qml{{struct}} get(int index); - int count() const; - void insert(int row, const Qml{{struct}} &{{struct|lower}}); - void append(const Qml{{struct}} &{{struct|lower}}); - void update(int row, const Qml{{struct}} &{{struct|lower}}); - void remove(int row); - void reset(const QList<Qml{{struct}}> data); - void clear(); -public: // from QAbstractListModel - virtual int rowCount(const QModelIndex &parent) const; - virtual QVariant data(const QModelIndex &index, int role) const; - virtual QHash<int, QByteArray> roleNames() const; -Q_SIGNALS: - void countChanged(int count); -private: - QList<Qml{{struct}}> m_data; - QHash<int, QByteArray> m_roleNames; -}; - - diff --git a/qface/builtin/qtcpp/templates/variantmodel.cpp b/qface/builtin/qtcpp/templates/variantmodel.cpp deleted file mode 100644 index 6e197f4..0000000 --- a/qface/builtin/qtcpp/templates/variantmodel.cpp +++ /dev/null @@ -1,102 +0,0 @@ -{# Copyright (c) Pelagicore AB 2016 #} -{% set class = 'QmlVariantModel' %} -/**************************************************************************** -** This is an auto-generated file. -** Do not edit! All changes made to it will be lost. -****************************************************************************/ - -#include "{{class|lower}}.h" - -{{class}}::{{class}}(QObject *parent) - : QAbstractListModel(parent) -{ - m_roleNames.insert(Roles::ModelData, QByteArray("modelData")); -} - -int {{class}}::count() const -{ - return m_data.count(); -} - -QVariant {{class}}::get(int index) -{ - return m_data.value(index); -} - -int {{class}}::rowCount(const QModelIndex &parent) const -{ - Q_UNUSED(parent) - return m_data.count(); -} - -QVariant {{class}}::data(const QModelIndex &index, int role) const -{ - if(index.row() < 0 || index.row() >= count()) { - return QVariant(); - } - const QVariant &entry = m_data.at(index.row()); - switch(role) { - case Roles::ModelData: - return entry; - } - return QVariant(); -} - -QHash<int, QByteArray> {{class}}::roleNames() const -{ - return m_roleNames; -} - - -void {{class}}::insert(int row, const QVariant &entry) -{ - if (row < 0) - row = 0; - if (row >= m_data.count()) - row = m_data.count(); - - beginInsertRows(QModelIndex(), row, row); - m_data.insert(row, entry); - endInsertRows(); - emit countChanged(count()); -} - -void {{class}}::reset(const QVariantList entries) -{ - beginResetModel(); - m_data = entries; - endResetModel(); -} - -void {{class}}::append(const QVariant &entry) -{ - insert(m_data.count(), entry); -} - -void {{class}}::update(int row, const QVariant &entry) -{ - if(row < 0 || row >= m_data.count()) { - return; - } - m_data[row] = entry; - const QModelIndex &index = createIndex(row, 0); - emit dataChanged(index, index); -} - -void {{class}}::remove(int row) -{ - if(row < 0 || row >= m_data.count()) { - return; - } - beginRemoveRows(QModelIndex(), row, row); - m_data.removeAt(row); - endRemoveRows(); -} - -void {{class}}::clear() -{ - beginResetModel(); - m_data.clear(); - endResetModel(); -} - diff --git a/qface/builtin/qtcpp/templates/variantmodel.h b/qface/builtin/qtcpp/templates/variantmodel.h deleted file mode 100644 index 3f1bbd3..0000000 --- a/qface/builtin/qtcpp/templates/variantmodel.h +++ /dev/null @@ -1,38 +0,0 @@ -{# Copyright (c) Pelagicore AB 2016 #} -{% set class = 'QmlVariantModel' %} -/**************************************************************************** -** This is an auto-generated file. -** Do not edit! All changes made to it will be lost. -****************************************************************************/ - -#pragma once - -#include <QtCore> - -class {{class}} : public QAbstractListModel -{ - Q_OBJECT - Q_PROPERTY(int count READ count NOTIFY countChanged) -public: - enum Roles { ModelData = Qt::UserRole }; - {{class}}(QObject *parent = nullptr); - Q_INVOKABLE QVariant get(int index); - int count() const; - void insert(int row, const QVariant &entry); - void append(const QVariant &entry); - void update(int row, const QVariant &entry); - void remove(int row); - void reset(const QVariantList entries); - void clear(); -public: // from QAbstractListModel - virtual int rowCount(const QModelIndex &parent) const; - virtual QVariant data(const QModelIndex &index, int role) const; - virtual QHash<int, QByteArray> roleNames() const; -Q_SIGNALS: - void countChanged(int count); -private: - QVariantList m_data; - QHash<int, QByteArray> m_roleNames; -}; - - diff --git a/qface/builtin/qtqml/__init__.py b/qface/builtin/qtqml/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/qface/builtin/qtqml/__init__.py +++ /dev/null diff --git a/qface/builtin/qtqml/log.yaml b/qface/builtin/qtqml/log.yaml deleted file mode 100644 index 21b5bba..0000000 --- a/qface/builtin/qtqml/log.yaml +++ /dev/null @@ -1,18 +0,0 @@ -version: 1 -formatters: - simple: - format: '%(asctime)s - %(name)s - %(levelname)s - %(message)s' -handlers: - console: - class: logging.StreamHandler - level: INFO - formatter: simple - stream: ext://sys.stdout -loggers: - qface.generator: - level: WARN - handlers: [console] - propagate: no -root: - level: DEBUG - handlers: [console] diff --git a/qface/builtin/qtqml/qtqml.py b/qface/builtin/qtqml/qtqml.py deleted file mode 100755 index 57e3996..0000000 --- a/qface/builtin/qtqml/qtqml.py +++ /dev/null @@ -1,71 +0,0 @@ -#!/usr/bin/env python3 -# Copyright (c) Pelagicore AB 2016 - -import click -import logging -import logging.config -import yaml -from path import Path - -from qface.generator import FileSystem, Generator -from qface.helper.qtqml import Filters -from qface.watch import monitor - - -here = Path(__file__).dirname() - -logging.config.dictConfig(yaml.load(open(here / 'log.yaml'))) - -log = logging.getLogger(__file__) - - -def run(src, dst): - log.debug('run {0} {1}'.format(src, dst)) - system = FileSystem.parse(src) - search_path = [ - Path('_templates').abspath(), - Path(here / 'templates').abspath() - ] - generator = Generator(search_path=search_path) - generator.register_filter('defaultValue', Filters.defaultValue) - generator.register_filter('propertyType', Filters.propertyType) - ctx = {'dst': dst} - for module in system.modules: - module_name = module.module_name - module_path = '/'.join(module.name_parts) - plugin_name = "".join(module.name_parts[:2]) - ctx.update({ - 'module': module, - 'module_name': module_name, - 'module_path': module_path, - 'plugin_name': plugin_name, - }) - generator.destination = generator.apply("{{dst}}/{{module_path}}", ctx) - generator.write('private/{{module_name}}Module.js', 'module.js', ctx) - generator.write('qmldir', 'public_qmldir', ctx) - generator.write('private/qmldir', 'private_qmldir', ctx) - - for interface in module.interfaces: - ctx.update({ - 'interface': interface, - }) - generator.write('private/Abstract{{interface}}.qml', 'AbstractInterface.qml', ctx) - generator.write('{{interface}}.qml', 'Interface.qml', ctx, preserve=True) - - -@click.command() -@click.option('--reload/--no-reload', default=False) -@click.argument('src', nargs=-1, type=click.Path(exists=True)) -@click.argument('dst', nargs=1, type=click.Path(exists=True)) -def app(src, dst, reload): - """Takes several files or directories as src and generates the code - in the given dst directory.""" - if reload: - script = Path(__file__).abspath() - monitor(script, src, dst) - else: - run(src, dst) - - -if __name__ == '__main__': - app() diff --git a/qface/builtin/qtqml/templates/AbstractInterface.qml b/qface/builtin/qtqml/templates/AbstractInterface.qml deleted file mode 100644 index cac0847..0000000 --- a/qface/builtin/qtqml/templates/AbstractInterface.qml +++ /dev/null @@ -1,49 +0,0 @@ -{% include 'copyright.h' %} - - -/* - * This is an auto-generated file. - * Do not edit! All changes made to it will be lost. - */ - -import QtQml 2.2 -import QtQml.Models 2.2 - -import "." - -{{interface.comment}} -QtObject { - id: root - -{% for property in interface.properties %} -{% if property.readonly %} -{% if property.comment %} - {{ property.comment }} -{% endif %} - readonly property {{property|propertyType}} {{property}} : _{{property}} - property {{property|propertyType}} _{{property}} : {{property|defaultValue}} -{% else %} -{% if property.comment %} - {{ property.comment }} -{% endif %} - property {{property|propertyType}} {{property}} : {{property|defaultValue }} -{% endif %} -{% endfor %} - -{% for operation in interface.operations %} -{% if operation.comment %} - {{ operation.comment }} -{% endif %} - property var {{operation}} : function({{operation.parameters|join(', ')}}) {} -{% endfor %} - -{% for signal in interface.signals %} - signal {{signal}}( - {%- for parameter in signal.parameters %} - {{- parameter.type|propertyType }} {{ parameter.name -}} - {% if not loop.last %}, {% endif %} - {% endfor -%} - ) -{% endfor %} -} - diff --git a/qface/builtin/qtqml/templates/Interface.qml b/qface/builtin/qtqml/templates/Interface.qml deleted file mode 100644 index f4ebf70..0000000 --- a/qface/builtin/qtqml/templates/Interface.qml +++ /dev/null @@ -1,21 +0,0 @@ -{% include 'copyright.h' %} - - -/* - * This is a preserved file. - * Changes will not be overriden by the generator. - * To reset the file you need to delete it first. - */ - -{% if 'singleton' in interface.tags %} -pragma Singleton -{% endif %} - -import QtQml 2.2 - -import "private" - -Abstract{{interface}} { - id: root -} - diff --git a/qface/builtin/qtqml/templates/__init__.py b/qface/builtin/qtqml/templates/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/qface/builtin/qtqml/templates/__init__.py +++ /dev/null diff --git a/qface/builtin/qtqml/templates/copyright.h b/qface/builtin/qtqml/templates/copyright.h deleted file mode 100644 index a484f2e..0000000 --- a/qface/builtin/qtqml/templates/copyright.h +++ /dev/null @@ -1,23 +0,0 @@ -/* - * MIT License - * - * Copyright (c) 2017 Pelagicore AG - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ diff --git a/qface/builtin/qtqml/templates/module.js b/qface/builtin/qtqml/templates/module.js deleted file mode 100644 index c1a92a1..0000000 --- a/qface/builtin/qtqml/templates/module.js +++ /dev/null @@ -1,26 +0,0 @@ -{% include 'copyright.h' %} - - -/* - * This is an auto-generated file. - * Do not edit! All changes made to it will be lost. - */ - -.pragma library - -{% for enum in module.enums %} -// Enum: {{enum}} -{% for member in enum.members %} -var {{member}} = {{member.value}}; -{% endfor %} -{% endfor %} - -{% for struct in module.structs %} -function create{{struct}}() { - return { - {% for field in struct.fields %} - {{field}} : {{field | defaultValue}}, - {% endfor %} - }; -} -{% endfor %} diff --git a/qface/builtin/qtqml/templates/private_qmldir b/qface/builtin/qtqml/templates/private_qmldir deleted file mode 100644 index 152af67..0000000 --- a/qface/builtin/qtqml/templates/private_qmldir +++ /dev/null @@ -1,4 +0,0 @@ -{{module_name}}Module 1.0 {{module_name}}Module.js -{% for interface in module.interfaces %} -Abstract{{interface}} 1.0 Abstract{{interface}}.qml -{% endfor %} diff --git a/qface/builtin/qtqml/templates/public_qmldir b/qface/builtin/qtqml/templates/public_qmldir deleted file mode 100644 index 2fcfe50..0000000 --- a/qface/builtin/qtqml/templates/public_qmldir +++ /dev/null @@ -1,4 +0,0 @@ -{{module_name}}Module 1.0 private/{{module_name}}Module.js -{% for interface in module.interfaces %} -{% if 'singleton' in interface.tags %}singleton {% endif %}{{interface}} 1.0 {{interface}}.qml -{% endfor %} diff --git a/qface/builtin/schema/log.yaml b/qface/builtin/schema/log.yaml deleted file mode 100644 index 21b5bba..0000000 --- a/qface/builtin/schema/log.yaml +++ /dev/null @@ -1,18 +0,0 @@ -version: 1 -formatters: - simple: - format: '%(asctime)s - %(name)s - %(levelname)s - %(message)s' -handlers: - console: - class: logging.StreamHandler - level: INFO - formatter: simple - stream: ext://sys.stdout -loggers: - qface.generator: - level: WARN - handlers: [console] - propagate: no -root: - level: DEBUG - handlers: [console] diff --git a/qface/builtin/schema/schema.py b/qface/builtin/schema/schema.py deleted file mode 100755 index 5735844..0000000 --- a/qface/builtin/schema/schema.py +++ /dev/null @@ -1,55 +0,0 @@ -#!/usr/bin/env python3 -# Copyright (c) Pelagicore AB 2016 - -import click -import logging -import logging.config -import yaml -from path import Path - -from qface.generator import FileSystem, Generator -from qface.watch import monitor -from qface.filters import jsonify - - -here = Path(__file__).dirname() - -logging.config.dictConfig(yaml.load(open(here / 'log.yaml'))) - -log = logging.getLogger(__file__) - - -def run(src, dst): - log.debug('run {0} {1}'.format(src, dst)) - system = FileSystem.parse(src) - search_path = [ - Path('_templates').abspath(), - Path(here / 'templates').abspath() - ] - generator = Generator(search_path=search_path) - generator.register_filter('jsonify', jsonify) - ctx = {'dst': dst} - for module in system.modules: - ctx.update({ - 'module': module, - }) - generator.destination = generator.apply("{{dst}}", ctx) - generator.write('{{module}}.json', 'module.json', ctx) - - -@click.command() -@click.option('--reload/--no-reload', default=False) -@click.argument('src', nargs=-1, type=click.Path(exists=True)) -@click.argument('dst', nargs=1, type=click.Path(exists=True)) -def app(src, dst, reload): - """Takes several files or directories as src and generates the code - in the given dst directory.""" - if reload: - script = Path(__file__).abspath() - monitor(script, src, dst) - else: - run(src, dst) - - -if __name__ == '__main__': - app() diff --git a/qface/builtin/schema/templates/module.json b/qface/builtin/schema/templates/module.json deleted file mode 100644 index 288ea15..0000000 --- a/qface/builtin/schema/templates/module.json +++ /dev/null @@ -1 +0,0 @@ -{{module|jsonify}}
\ No newline at end of file diff --git a/qface/generator.py b/qface/generator.py index 22fbf55..997ace8 100644 --- a/qface/generator.py +++ b/qface/generator.py @@ -1,6 +1,8 @@ # Copyright (c) Pelagicore AB 2016 -from jinja2 import Environment, FileSystemLoader, Template +from jinja2 import Environment, Template +from jinja2 import FileSystemLoader, PackageLoader, ChoiceLoader +from jinja2 import TemplateSyntaxError, TemplateNotFound, TemplateError from path import Path from antlr4 import FileStream, CommonTokenStream, ParseTreeWalker from antlr4.error import DiagnosticErrorListener @@ -44,8 +46,12 @@ def lower_first_filter(s): class Generator(object): """Manages the templates and applies your context data""" def __init__(self, search_path: str): + loader = ChoiceLoader([ + FileSystemLoader(search_path), + PackageLoader('qface') + ]) self.env = Environment( - loader=FileSystemLoader(search_path), + loader=loader, trim_blocks=True, lstrip_blocks=True ) @@ -76,10 +82,24 @@ class Generator(object): """Return the rendered text of a template instance""" return self.env.from_string(template).render(context) - def write(self, file_path: str, template: str, context: dict, preserve=False): + def write(self, file_path: Path, template: str, context: dict, preserve: bool = False): """Using a template file name it renders a template into a file given a context """ + 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') + except TemplateNotFound as exc: + message = '{0} error: Template not found'.format(exc.name) + click.secho(message, fg='red') + except TemplateError as exc: + message = 'error: {0}'.format(exc.message) + click.secho(message, fg='red') + + def _write(self, file_path: Path, template: str, context: dict, preserve: bool = False): path = self.destination / Path(self.apply(file_path, context)) path.parent.makedirs_p() logger.info('write {0}'.format(path)) diff --git a/qface/helper/qtcpp.py b/qface/helper/qtcpp.py index c42f554..97a5d44 100644 --- a/qface/helper/qtcpp.py +++ b/qface/helper/qtcpp.py @@ -109,8 +109,8 @@ class Filters(object): @staticmethod def open_ns(symbol): ''' generates a open namespace from symbol namespace x { y { z {''' - blocks = ['{0} {{'.format(x) for x in symbol.module.name_parts] - return 'namespace {0}'.format(str.join(' ', blocks)) + blocks = ['namespace {0} {{'.format(x) for x in symbol.module.name_parts] + return ' '.join(blocks) @staticmethod def close_ns(symbol): @@ -121,7 +121,7 @@ class Filters(object): def using_ns(symbol): '''generates a using namespace x::y::z statement from a symbol''' id = '::'.join(symbol.module.name_parts) - return 'using namespace {0}'.format(id) + return 'using namespace {0};'.format(id) @staticmethod def signalName(s): @@ -144,18 +144,30 @@ class Filters(object): args = s.parameters elif isinstance(s, domain.Signal): args = s.parameters + elif isinstance(s, domain.Struct): + args = s.fields elif isinstance(s, domain.Property): args = [s] return indent.join([filter(a) for a in args]) @staticmethod - def signature(s): + def signature(s, expand=False, filter=None): + if not filter: + filter = Filters.returnType if isinstance(s, domain.Operation): args = s.parameters elif isinstance(s, domain.Signal): args = s.parameters elif isinstance(s, domain.Property): - args = [s.type] # for <property>Changed(<type>) + args = [s] # for <property>Changed(<type>) + elif isinstance(s, domain.Struct): + args = s.fields else: args = [] - return ','.join([Filters.returnType(a) for a in args]) + if expand: + return ', '.join(['{0} {1}'.format(filter(a), a.name) for a in args]) + return ','.join([filter(a) for a in args]) + + @staticmethod + def identifier(s): + return str(s).lower().replace('.', '_') diff --git a/qface/idl/domain.py b/qface/idl/domain.py index 3be53ff..327472e 100644 --- a/qface/idl/domain.py +++ b/qface/idl/domain.py @@ -102,7 +102,7 @@ class NamedElement(object): @property def qualified_name(self): - '''return the fully qualified name (`module + "." + name`)''' + '''return the fully qualified name (`<module>.<name>`)''' if self.module == self: return self.module.name else: @@ -125,6 +125,7 @@ class Symbol(NamedElement): self._contentMap = ChainMap() self.type = TypeSymbol('', self) + """ the associated type information """ @property def system(self): @@ -136,23 +137,28 @@ class Symbol(NamedElement): return self._tags def add_tag(self, tag): + """ add a tag to the tag list """ if tag not in self._tags: self._tags[tag] = dict() def add_attribute(self, tag, name, value): + """ add an attribute (nam, value pair) to the named tag """ self.add_tag(tag) d = self._tags[tag] d[name] = value def tag(self, name): + """ return tag by name """ return self._tags[name] def attribute(self, tag, name): + """ return attribute by tag and attribute name """ if tag in self._tags and name in self._tags[tag]: return self._tags[tag][name] @property def contents(self): + """ return general list of symbol contents """ return self._contentMap.values() def toJson(self): @@ -168,11 +174,17 @@ class TypeSymbol(NamedElement): super().__init__(name, parent.module) log.debug('TypeSymbol()') self.parent = parent + """ the parent symbol of this type """ self.is_void = False # type:bool + """ if type represents the void type """ self.is_primitive = False # type:bool + """ if type represents a primitive type """ self.is_complex = False # type:bool + """ if type represents a complex type """ self.is_list = False # type:bool + """ if type represents a list of nested types """ self.is_model = False # type:bool + """ if type represents a model of nested types """ self.nested = None """nested type if symbol is list or model""" self.__reference = None @@ -242,6 +254,7 @@ class TypeSymbol(NamedElement): @property def type(self): + """ return the type information. In this case: self """ return self def toJson(self): @@ -311,14 +324,17 @@ class Module(Symbol): @property def majorVersion(self): + """ returns the major version number of the version information """ return self.version.split('.')[0] @property def minorVersion(self): + """ returns the minor version number of the version information """ return self.version.split('.')[1] @property def module_name(self): + """ returns a capitalized name from the module name """ return self.name.split('.')[-1].capitalize() def lookup(self, name: str, fragment: str = None): @@ -369,6 +385,7 @@ class Interface(Symbol): @property def extends(self): + ''' returns the symbol defined by the extends interface attribute ''' return self.module.lookup(self._extends) def toJson(self): @@ -385,8 +402,16 @@ class Operation(Symbol): super().__init__(name, interface.module) log.debug('Operation()') self.interface = interface + """ the interface the operation is part of """ self.interface._operationMap[name] = self self._parameterMap = self._contentMap = OrderedDict() # type: dict[Parameter] + self.is_const = False #type: bool + """reflects is the operation was declared as const operation""" + + @property + def qualified_name(self): + '''return the fully qualified name (`<module>.<interface>#<operation>`)''' + return '{0}.{1}#{2}'.format(self.module.name, self.interface.name, self.name) @property def parameters(self): @@ -409,6 +434,11 @@ class Signal(Symbol): self._parameterMap = self._contentMap = OrderedDict() # type: dict[Parameter] @property + def qualified_name(self): + '''return the fully qualified name (`module + "." + name`)''' + return '{0}.{1}#{2}'.format(self.module.name, self.interface.name, self.name) + + @property def parameters(self): '''returns ordered list of parameters''' return self._parameterMap.values() @@ -438,6 +468,26 @@ class Property(Symbol): self.readonly = False self.const = False + @property + def is_model(self): + ''' true if type is a model ''' + return self.type.is_model + + @property + def is_primitive_model(self): + ''' true if type is a model of nested primitive types ''' + return self.type.is_model and self.type.nested.is_primitive + + @property + def is_complex_model(self): + ''' true if type is a model of nested complex types ''' + return self.type.is_model and self.type.nested.is_complex + + @property + def qualified_name(self): + '''return the fully qualified name (`<module>.<interface>#<property>`)''' + return '{0}.{1}#{2}'.format(self.module.name, self.interface.name, self.name) + def toJson(self): o = super().toJson() if self.readonly: @@ -474,6 +524,12 @@ class Field(Symbol): self.struct = struct # type:Struct self.struct._fieldMap[name] = self + @property + def qualified_name(self): + '''return the fully qualified name (`<module>.<struct>#<field>`)''' + return '{0}.{1}#{2}'.format(self.module.name, self.struct.name, self.name) + + class Enum(Symbol): """An enum (flag) inside a module""" @@ -509,6 +565,10 @@ class EnumMember(Symbol): self.enum._memberMap[name] = self self.value = 0 + def qualified_name(self): + '''return the fully qualified name (`<module>.<enum>#<member>`)''' + return '{0}.{1}#{2}'.format(self.module.name, self.enum.name, self.name) + def toJson(self): o = super().toJson() o['value'] = self.value diff --git a/qface/idl/listener.py b/qface/idl/listener.py index 8bc6d36..3704444 100644 --- a/qface/idl/listener.py +++ b/qface/idl/listener.py @@ -154,7 +154,7 @@ class DomainListener(TListener): self.operation = Operation(name, self.interface) modifier = ctx.operationModifierSymbol() if modifier: - self.operation.const = bool(modifier.is_const) + self.operation.is_const = bool(modifier.is_const) self.parse_annotations(ctx, self.operation) self.parse_type(ctx, self.operation.type) contextMap[ctx] = self.operation diff --git a/qface/idl/parser/TLexer.py b/qface/idl/parser/TLexer.py index c6aa4db..cb108c4 100644 --- a/qface/idl/parser/TLexer.py +++ b/qface/idl/parser/TLexer.py @@ -1,11 +1,13 @@ -# Generated from T.g4 by ANTLR 4.6 +# Generated from T.g4 by ANTLR 4.7 from antlr4 import * from io import StringIO +from typing.io import TextIO +import sys def serializedATN(): with StringIO() as buf: - buf.write("\3\u0430\ud6d1\u8206\uad2d\u4417\uaef1\u8d80\uaadd\2\'") + buf.write("\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\2\'") buf.write("\u0126\b\1\4\2\t\2\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7") buf.write("\t\7\4\b\t\b\4\t\t\t\4\n\t\n\4\13\t\13\4\f\t\f\4\r\t\r") buf.write("\4\16\t\16\4\17\t\17\4\20\t\20\4\21\t\21\4\22\t\22\4\23") @@ -36,12 +38,12 @@ def serializedATN(): buf.write("\22#\23%\24\'\25)\26+\27-\30/\31\61\32\63\33\65\34\67") buf.write("\359\36;\37= ?!A\"C#E$G%I&K\'\3\2\t\4\2\f\f\17\17\4\2") buf.write("--//\5\2\62;CHch\5\2C\\aac|\7\2\60\60\62;C\\aac|\3\2\62") - buf.write(";\5\2\13\f\17\17\"\"\u012f\2\3\3\2\2\2\2\5\3\2\2\2\2\7") - buf.write("\3\2\2\2\2\t\3\2\2\2\2\13\3\2\2\2\2\r\3\2\2\2\2\17\3\2") - buf.write("\2\2\2\21\3\2\2\2\2\23\3\2\2\2\2\25\3\2\2\2\2\27\3\2\2") - buf.write("\2\2\31\3\2\2\2\2\33\3\2\2\2\2\35\3\2\2\2\2\37\3\2\2\2") - buf.write("\2!\3\2\2\2\2#\3\2\2\2\2%\3\2\2\2\2\'\3\2\2\2\2)\3\2\2") - buf.write("\2\2+\3\2\2\2\2-\3\2\2\2\2/\3\2\2\2\2\61\3\2\2\2\2\63") + buf.write(";\5\2\13\f\17\17\"\"\2\u012f\2\3\3\2\2\2\2\5\3\2\2\2\2") + buf.write("\7\3\2\2\2\2\t\3\2\2\2\2\13\3\2\2\2\2\r\3\2\2\2\2\17\3") + buf.write("\2\2\2\2\21\3\2\2\2\2\23\3\2\2\2\2\25\3\2\2\2\2\27\3\2") + buf.write("\2\2\2\31\3\2\2\2\2\33\3\2\2\2\2\35\3\2\2\2\2\37\3\2\2") + buf.write("\2\2!\3\2\2\2\2#\3\2\2\2\2%\3\2\2\2\2\'\3\2\2\2\2)\3\2") + buf.write("\2\2\2+\3\2\2\2\2-\3\2\2\2\2/\3\2\2\2\2\61\3\2\2\2\2\63") buf.write("\3\2\2\2\2\65\3\2\2\2\2\67\3\2\2\2\29\3\2\2\2\2;\3\2\2") buf.write("\2\2=\3\2\2\2\2?\3\2\2\2\2A\3\2\2\2\2C\3\2\2\2\2E\3\2") buf.write("\2\2\2G\3\2\2\2\2I\3\2\2\2\2K\3\2\2\2\3M\3\2\2\2\5T\3") @@ -136,7 +138,6 @@ class TLexer(Lexer): decisionsToDFA = [ DFA(ds, i) for i, ds in enumerate(atn.decisionToState) ] - T__0 = 1 T__1 = 2 T__2 = 3 @@ -175,6 +176,8 @@ class TLexer(Lexer): COMMENT = 36 MULTICOMM = 37 + channelNames = [ u"DEFAULT_TOKEN_CHANNEL", u"HIDDEN" ] + modeNames = [ "DEFAULT_MODE" ] literalNames = [ "<INVALID>", @@ -197,9 +200,9 @@ class TLexer(Lexer): grammarFileName = "T.g4" - def __init__(self, input=None): - super().__init__(input) - self.checkVersion("4.6") + def __init__(self, input=None, output:TextIO = sys.stdout): + super().__init__(input, output) + self.checkVersion("4.7") self._interp = LexerATNSimulator(self, self.atn, self.decisionsToDFA, PredictionContextCache()) self._actions = None self._predicates = None diff --git a/qface/idl/parser/TListener.py b/qface/idl/parser/TListener.py index e908b46..54e764a 100644 --- a/qface/idl/parser/TListener.py +++ b/qface/idl/parser/TListener.py @@ -1,4 +1,4 @@ -# Generated from T.g4 by ANTLR 4.6 +# Generated from T.g4 by ANTLR 4.7 from antlr4 import * if __name__ is not None and "." in __name__: from .TParser import TParser diff --git a/qface/idl/parser/TParser.py b/qface/idl/parser/TParser.py index 835f86c..b180f95 100644 --- a/qface/idl/parser/TParser.py +++ b/qface/idl/parser/TParser.py @@ -1,11 +1,13 @@ -# Generated from T.g4 by ANTLR 4.6 +# Generated from T.g4 by ANTLR 4.7 # encoding: utf-8 from antlr4 import * from io import StringIO +from typing.io import TextIO +import sys def serializedATN(): with StringIO() as buf: - buf.write("\3\u0430\ud6d1\u8206\uad2d\u4417\uaef1\u8d80\uaadd\3\'") + buf.write("\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\3\'") buf.write("\u0142\4\2\t\2\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7") buf.write("\4\b\t\b\4\t\t\t\4\n\t\n\4\13\t\13\4\f\t\f\4\r\t\r\4\16") buf.write("\t\16\4\17\t\17\4\20\t\20\4\21\t\21\4\22\t\22\4\23\t\23") @@ -40,121 +42,122 @@ def serializedATN(): buf.write("\32\u0131\n\32\f\32\16\32\u0134\13\32\3\32\3\32\3\32\5") buf.write("\32\u0139\n\32\3\32\5\32\u013c\n\32\3\33\3\33\5\33\u0140") buf.write("\n\33\3\33\2\2\34\2\4\6\b\n\f\16\20\22\24\26\30\32\34") - buf.write("\36 \"$&(*,.\60\62\64\2\2\u0160\2\66\3\2\2\2\4=\3\2\2") - buf.write("\2\6D\3\2\2\2\bK\3\2\2\2\n\\\3\2\2\2\f_\3\2\2\2\16{\3") - buf.write("\2\2\2\20~\3\2\2\2\22\u0099\3\2\2\2\24\u009c\3\2\2\2\26") - buf.write("\u00b2\3\2\2\2\30\u00c4\3\2\2\2\32\u00c6\3\2\2\2\34\u00cb") - buf.write("\3\2\2\2\36\u00cd\3\2\2\2 \u00d9\3\2\2\2\"\u00db\3\2\2") - buf.write("\2$\u00e2\3\2\2\2&\u00e4\3\2\2\2(\u00e9\3\2\2\2*\u00ef") - buf.write("\3\2\2\2,\u0105\3\2\2\2.\u0113\3\2\2\2\60\u012a\3\2\2") - buf.write("\2\62\u012d\3\2\2\2\64\u013f\3\2\2\2\66:\5\4\3\2\679\5") - buf.write("\n\6\28\67\3\2\2\29<\3\2\2\2:8\3\2\2\2:;\3\2\2\2;\3\3") - buf.write("\2\2\2<:\3\2\2\2=A\5\b\5\2>@\5\6\4\2?>\3\2\2\2@C\3\2\2") - buf.write("\2A?\3\2\2\2AB\3\2\2\2B\5\3\2\2\2CA\3\2\2\2DE\7\3\2\2") - buf.write("EF\7\"\2\2FH\7#\2\2GI\7\4\2\2HG\3\2\2\2HI\3\2\2\2I\7\3") - buf.write("\2\2\2JL\7$\2\2KJ\3\2\2\2KL\3\2\2\2LP\3\2\2\2MO\5\34\17") - buf.write("\2NM\3\2\2\2OR\3\2\2\2PN\3\2\2\2PQ\3\2\2\2QS\3\2\2\2R") - buf.write("P\3\2\2\2ST\7\5\2\2TU\7\"\2\2UW\7#\2\2VX\7\4\2\2WV\3\2") - buf.write("\2\2WX\3\2\2\2X\t\3\2\2\2Y]\5\f\7\2Z]\5*\26\2[]\5.\30") - buf.write("\2\\Y\3\2\2\2\\Z\3\2\2\2\\[\3\2\2\2]\13\3\2\2\2^`\7$\2") - buf.write("\2_^\3\2\2\2_`\3\2\2\2`d\3\2\2\2ac\5\34\17\2ba\3\2\2\2") - buf.write("cf\3\2\2\2db\3\2\2\2de\3\2\2\2eg\3\2\2\2fd\3\2\2\2gh\7") - buf.write("\6\2\2hk\7\"\2\2ij\7\7\2\2jl\7\"\2\2ki\3\2\2\2kl\3\2\2") - buf.write("\2lm\3\2\2\2mq\7\b\2\2np\5\16\b\2on\3\2\2\2ps\3\2\2\2") - buf.write("qo\3\2\2\2qr\3\2\2\2rt\3\2\2\2sq\3\2\2\2tv\7\t\2\2uw\7") - buf.write("\4\2\2vu\3\2\2\2vw\3\2\2\2w\r\3\2\2\2x|\5\20\t\2y|\5\26") - buf.write("\f\2z|\5\24\13\2{x\3\2\2\2{y\3\2\2\2{z\3\2\2\2|\17\3\2") - buf.write("\2\2}\177\7$\2\2~}\3\2\2\2~\177\3\2\2\2\177\u0083\3\2") - buf.write("\2\2\u0080\u0082\5\34\17\2\u0081\u0080\3\2\2\2\u0082\u0085") - buf.write("\3\2\2\2\u0083\u0081\3\2\2\2\u0083\u0084\3\2\2\2\u0084") - buf.write("\u0088\3\2\2\2\u0085\u0083\3\2\2\2\u0086\u0089\5 \21\2") - buf.write("\u0087\u0089\7\n\2\2\u0088\u0086\3\2\2\2\u0088\u0087\3") - buf.write("\2\2\2\u0089\u008a\3\2\2\2\u008a\u008b\7\"\2\2\u008b\u008f") - buf.write("\7\13\2\2\u008c\u008e\5\32\16\2\u008d\u008c\3\2\2\2\u008e") - buf.write("\u0091\3\2\2\2\u008f\u008d\3\2\2\2\u008f\u0090\3\2\2\2") - buf.write("\u0090\u0092\3\2\2\2\u0091\u008f\3\2\2\2\u0092\u0094\7") - buf.write("\f\2\2\u0093\u0095\5\22\n\2\u0094\u0093\3\2\2\2\u0094") - buf.write("\u0095\3\2\2\2\u0095\u0097\3\2\2\2\u0096\u0098\7\4\2\2") - buf.write("\u0097\u0096\3\2\2\2\u0097\u0098\3\2\2\2\u0098\21\3\2") - buf.write("\2\2\u0099\u009a\7\r\2\2\u009a\23\3\2\2\2\u009b\u009d") - buf.write("\7$\2\2\u009c\u009b\3\2\2\2\u009c\u009d\3\2\2\2\u009d") - buf.write("\u00a1\3\2\2\2\u009e\u00a0\5\34\17\2\u009f\u009e\3\2\2") - buf.write("\2\u00a0\u00a3\3\2\2\2\u00a1\u009f\3\2\2\2\u00a1\u00a2") - buf.write("\3\2\2\2\u00a2\u00a4\3\2\2\2\u00a3\u00a1\3\2\2\2\u00a4") - buf.write("\u00a5\7\16\2\2\u00a5\u00a6\7\"\2\2\u00a6\u00aa\7\13\2") - buf.write("\2\u00a7\u00a9\5\32\16\2\u00a8\u00a7\3\2\2\2\u00a9\u00ac") - buf.write("\3\2\2\2\u00aa\u00a8\3\2\2\2\u00aa\u00ab\3\2\2\2\u00ab") - buf.write("\u00ad\3\2\2\2\u00ac\u00aa\3\2\2\2\u00ad\u00af\7\f\2\2") - buf.write("\u00ae\u00b0\7\4\2\2\u00af\u00ae\3\2\2\2\u00af\u00b0\3") - buf.write("\2\2\2\u00b0\25\3\2\2\2\u00b1\u00b3\7$\2\2\u00b2\u00b1") - buf.write("\3\2\2\2\u00b2\u00b3\3\2\2\2\u00b3\u00b7\3\2\2\2\u00b4") - buf.write("\u00b6\5\34\17\2\u00b5\u00b4\3\2\2\2\u00b6\u00b9\3\2\2") - buf.write("\2\u00b7\u00b5\3\2\2\2\u00b7\u00b8\3\2\2\2\u00b8\u00bb") - buf.write("\3\2\2\2\u00b9\u00b7\3\2\2\2\u00ba\u00bc\5\30\r\2\u00bb") - buf.write("\u00ba\3\2\2\2\u00bb\u00bc\3\2\2\2\u00bc\u00bd\3\2\2\2") - buf.write("\u00bd\u00be\5 \21\2\u00be\u00c0\7\"\2\2\u00bf\u00c1\7") - buf.write("\4\2\2\u00c0\u00bf\3\2\2\2\u00c0\u00c1\3\2\2\2\u00c1\27") - buf.write("\3\2\2\2\u00c2\u00c5\7\17\2\2\u00c3\u00c5\7\r\2\2\u00c4") - buf.write("\u00c2\3\2\2\2\u00c4\u00c3\3\2\2\2\u00c5\31\3\2\2\2\u00c6") - buf.write("\u00c7\5 \21\2\u00c7\u00c9\7\"\2\2\u00c8\u00ca\7\20\2") - buf.write("\2\u00c9\u00c8\3\2\2\2\u00c9\u00ca\3\2\2\2\u00ca\33\3") - buf.write("\2\2\2\u00cb\u00cc\7\36\2\2\u00cc\35\3\2\2\2\u00cd\u00d0") - buf.write("\7\"\2\2\u00ce\u00cf\7\21\2\2\u00cf\u00d1\7\"\2\2\u00d0") - buf.write("\u00ce\3\2\2\2\u00d0\u00d1\3\2\2\2\u00d1\u00d3\3\2\2\2") - buf.write("\u00d2\u00d4\7\20\2\2\u00d3\u00d2\3\2\2\2\u00d3\u00d4") - buf.write("\3\2\2\2\u00d4\37\3\2\2\2\u00d5\u00da\5$\23\2\u00d6\u00da") - buf.write("\5\"\22\2\u00d7\u00da\5&\24\2\u00d8\u00da\5(\25\2\u00d9") - buf.write("\u00d5\3\2\2\2\u00d9\u00d6\3\2\2\2\u00d9\u00d7\3\2\2\2") - buf.write("\u00d9\u00d8\3\2\2\2\u00da!\3\2\2\2\u00db\u00dc\7\"\2") - buf.write("\2\u00dc#\3\2\2\2\u00dd\u00e3\7\22\2\2\u00de\u00e3\7\23") - buf.write("\2\2\u00df\u00e3\7\24\2\2\u00e0\u00e3\7\25\2\2\u00e1\u00e3") - buf.write("\7\26\2\2\u00e2\u00dd\3\2\2\2\u00e2\u00de\3\2\2\2\u00e2") - buf.write("\u00df\3\2\2\2\u00e2\u00e0\3\2\2\2\u00e2\u00e1\3\2\2\2") - buf.write("\u00e3%\3\2\2\2\u00e4\u00e5\7\27\2\2\u00e5\u00e6\7\30") - buf.write("\2\2\u00e6\u00e7\5 \21\2\u00e7\u00e8\7\31\2\2\u00e8\'") - buf.write("\3\2\2\2\u00e9\u00ea\7\32\2\2\u00ea\u00eb\7\30\2\2\u00eb") - buf.write("\u00ec\5 \21\2\u00ec\u00ed\7\31\2\2\u00ed)\3\2\2\2\u00ee") - buf.write("\u00f0\7$\2\2\u00ef\u00ee\3\2\2\2\u00ef\u00f0\3\2\2\2") - buf.write("\u00f0\u00f4\3\2\2\2\u00f1\u00f3\5\34\17\2\u00f2\u00f1") - buf.write("\3\2\2\2\u00f3\u00f6\3\2\2\2\u00f4\u00f2\3\2\2\2\u00f4") - buf.write("\u00f5\3\2\2\2\u00f5\u00f7\3\2\2\2\u00f6\u00f4\3\2\2\2") - buf.write("\u00f7\u00f8\7\33\2\2\u00f8\u00f9\7\"\2\2\u00f9\u00fd") - buf.write("\7\b\2\2\u00fa\u00fc\5,\27\2\u00fb\u00fa\3\2\2\2\u00fc") - buf.write("\u00ff\3\2\2\2\u00fd\u00fb\3\2\2\2\u00fd\u00fe\3\2\2\2") - buf.write("\u00fe\u0100\3\2\2\2\u00ff\u00fd\3\2\2\2\u0100\u0102\7") - buf.write("\t\2\2\u0101\u0103\7\4\2\2\u0102\u0101\3\2\2\2\u0102\u0103") - buf.write("\3\2\2\2\u0103+\3\2\2\2\u0104\u0106\7$\2\2\u0105\u0104") - buf.write("\3\2\2\2\u0105\u0106\3\2\2\2\u0106\u010a\3\2\2\2\u0107") - buf.write("\u0109\5\34\17\2\u0108\u0107\3\2\2\2\u0109\u010c\3\2\2") - buf.write("\2\u010a\u0108\3\2\2\2\u010a\u010b\3\2\2\2\u010b\u010d") - buf.write("\3\2\2\2\u010c\u010a\3\2\2\2\u010d\u010e\5 \21\2\u010e") - buf.write("\u0110\7\"\2\2\u010f\u0111\7\4\2\2\u0110\u010f\3\2\2\2") - buf.write("\u0110\u0111\3\2\2\2\u0111-\3\2\2\2\u0112\u0114\7$\2\2") - buf.write("\u0113\u0112\3\2\2\2\u0113\u0114\3\2\2\2\u0114\u0118\3") - buf.write("\2\2\2\u0115\u0117\5\34\17\2\u0116\u0115\3\2\2\2\u0117") - buf.write("\u011a\3\2\2\2\u0118\u0116\3\2\2\2\u0118\u0119\3\2\2\2") - buf.write("\u0119\u011b\3\2\2\2\u011a\u0118\3\2\2\2\u011b\u011c\5") - buf.write("\60\31\2\u011c\u011d\7\"\2\2\u011d\u0121\7\b\2\2\u011e") - buf.write("\u0120\5\62\32\2\u011f\u011e\3\2\2\2\u0120\u0123\3\2\2") - buf.write("\2\u0121\u011f\3\2\2\2\u0121\u0122\3\2\2\2\u0122\u0124") - buf.write("\3\2\2\2\u0123\u0121\3\2\2\2\u0124\u0126\7\t\2\2\u0125") - buf.write("\u0127\7\4\2\2\u0126\u0125\3\2\2\2\u0126\u0127\3\2\2\2") - buf.write("\u0127/\3\2\2\2\u0128\u012b\7\34\2\2\u0129\u012b\7\35") - buf.write("\2\2\u012a\u0128\3\2\2\2\u012a\u0129\3\2\2\2\u012b\61") - buf.write("\3\2\2\2\u012c\u012e\7$\2\2\u012d\u012c\3\2\2\2\u012d") - buf.write("\u012e\3\2\2\2\u012e\u0132\3\2\2\2\u012f\u0131\5\34\17") - buf.write("\2\u0130\u012f\3\2\2\2\u0131\u0134\3\2\2\2\u0132\u0130") - buf.write("\3\2\2\2\u0132\u0133\3\2\2\2\u0133\u0135\3\2\2\2\u0134") - buf.write("\u0132\3\2\2\2\u0135\u0138\7\"\2\2\u0136\u0137\7\21\2") - buf.write("\2\u0137\u0139\5\64\33\2\u0138\u0136\3\2\2\2\u0138\u0139") - buf.write("\3\2\2\2\u0139\u013b\3\2\2\2\u013a\u013c\7\20\2\2\u013b") - buf.write("\u013a\3\2\2\2\u013b\u013c\3\2\2\2\u013c\63\3\2\2\2\u013d") - buf.write("\u0140\7\37\2\2\u013e\u0140\7 \2\2\u013f\u013d\3\2\2\2") - buf.write("\u013f\u013e\3\2\2\2\u0140\65\3\2\2\2\64:AHKPW\\_dkqv") - buf.write("{~\u0083\u0088\u008f\u0094\u0097\u009c\u00a1\u00aa\u00af") - buf.write("\u00b2\u00b7\u00bb\u00c0\u00c4\u00c9\u00d0\u00d3\u00d9") - buf.write("\u00e2\u00ef\u00f4\u00fd\u0102\u0105\u010a\u0110\u0113") - buf.write("\u0118\u0121\u0126\u012a\u012d\u0132\u0138\u013b\u013f") + buf.write("\36 \"$&(*,.\60\62\64\2\2\2\u0160\2\66\3\2\2\2\4=\3\2") + buf.write("\2\2\6D\3\2\2\2\bK\3\2\2\2\n\\\3\2\2\2\f_\3\2\2\2\16{") + buf.write("\3\2\2\2\20~\3\2\2\2\22\u0099\3\2\2\2\24\u009c\3\2\2\2") + buf.write("\26\u00b2\3\2\2\2\30\u00c4\3\2\2\2\32\u00c6\3\2\2\2\34") + buf.write("\u00cb\3\2\2\2\36\u00cd\3\2\2\2 \u00d9\3\2\2\2\"\u00db") + buf.write("\3\2\2\2$\u00e2\3\2\2\2&\u00e4\3\2\2\2(\u00e9\3\2\2\2") + buf.write("*\u00ef\3\2\2\2,\u0105\3\2\2\2.\u0113\3\2\2\2\60\u012a") + buf.write("\3\2\2\2\62\u012d\3\2\2\2\64\u013f\3\2\2\2\66:\5\4\3\2") + buf.write("\679\5\n\6\28\67\3\2\2\29<\3\2\2\2:8\3\2\2\2:;\3\2\2\2") + buf.write(";\3\3\2\2\2<:\3\2\2\2=A\5\b\5\2>@\5\6\4\2?>\3\2\2\2@C") + buf.write("\3\2\2\2A?\3\2\2\2AB\3\2\2\2B\5\3\2\2\2CA\3\2\2\2DE\7") + buf.write("\3\2\2EF\7\"\2\2FH\7#\2\2GI\7\4\2\2HG\3\2\2\2HI\3\2\2") + buf.write("\2I\7\3\2\2\2JL\7$\2\2KJ\3\2\2\2KL\3\2\2\2LP\3\2\2\2M") + buf.write("O\5\34\17\2NM\3\2\2\2OR\3\2\2\2PN\3\2\2\2PQ\3\2\2\2QS") + buf.write("\3\2\2\2RP\3\2\2\2ST\7\5\2\2TU\7\"\2\2UW\7#\2\2VX\7\4") + buf.write("\2\2WV\3\2\2\2WX\3\2\2\2X\t\3\2\2\2Y]\5\f\7\2Z]\5*\26") + buf.write("\2[]\5.\30\2\\Y\3\2\2\2\\Z\3\2\2\2\\[\3\2\2\2]\13\3\2") + buf.write("\2\2^`\7$\2\2_^\3\2\2\2_`\3\2\2\2`d\3\2\2\2ac\5\34\17") + buf.write("\2ba\3\2\2\2cf\3\2\2\2db\3\2\2\2de\3\2\2\2eg\3\2\2\2f") + buf.write("d\3\2\2\2gh\7\6\2\2hk\7\"\2\2ij\7\7\2\2jl\7\"\2\2ki\3") + buf.write("\2\2\2kl\3\2\2\2lm\3\2\2\2mq\7\b\2\2np\5\16\b\2on\3\2") + buf.write("\2\2ps\3\2\2\2qo\3\2\2\2qr\3\2\2\2rt\3\2\2\2sq\3\2\2\2") + buf.write("tv\7\t\2\2uw\7\4\2\2vu\3\2\2\2vw\3\2\2\2w\r\3\2\2\2x|") + buf.write("\5\20\t\2y|\5\26\f\2z|\5\24\13\2{x\3\2\2\2{y\3\2\2\2{") + buf.write("z\3\2\2\2|\17\3\2\2\2}\177\7$\2\2~}\3\2\2\2~\177\3\2\2") + buf.write("\2\177\u0083\3\2\2\2\u0080\u0082\5\34\17\2\u0081\u0080") + buf.write("\3\2\2\2\u0082\u0085\3\2\2\2\u0083\u0081\3\2\2\2\u0083") + buf.write("\u0084\3\2\2\2\u0084\u0088\3\2\2\2\u0085\u0083\3\2\2\2") + buf.write("\u0086\u0089\5 \21\2\u0087\u0089\7\n\2\2\u0088\u0086\3") + buf.write("\2\2\2\u0088\u0087\3\2\2\2\u0089\u008a\3\2\2\2\u008a\u008b") + buf.write("\7\"\2\2\u008b\u008f\7\13\2\2\u008c\u008e\5\32\16\2\u008d") + buf.write("\u008c\3\2\2\2\u008e\u0091\3\2\2\2\u008f\u008d\3\2\2\2") + buf.write("\u008f\u0090\3\2\2\2\u0090\u0092\3\2\2\2\u0091\u008f\3") + buf.write("\2\2\2\u0092\u0094\7\f\2\2\u0093\u0095\5\22\n\2\u0094") + buf.write("\u0093\3\2\2\2\u0094\u0095\3\2\2\2\u0095\u0097\3\2\2\2") + buf.write("\u0096\u0098\7\4\2\2\u0097\u0096\3\2\2\2\u0097\u0098\3") + buf.write("\2\2\2\u0098\21\3\2\2\2\u0099\u009a\7\r\2\2\u009a\23\3") + buf.write("\2\2\2\u009b\u009d\7$\2\2\u009c\u009b\3\2\2\2\u009c\u009d") + buf.write("\3\2\2\2\u009d\u00a1\3\2\2\2\u009e\u00a0\5\34\17\2\u009f") + buf.write("\u009e\3\2\2\2\u00a0\u00a3\3\2\2\2\u00a1\u009f\3\2\2\2") + buf.write("\u00a1\u00a2\3\2\2\2\u00a2\u00a4\3\2\2\2\u00a3\u00a1\3") + buf.write("\2\2\2\u00a4\u00a5\7\16\2\2\u00a5\u00a6\7\"\2\2\u00a6") + buf.write("\u00aa\7\13\2\2\u00a7\u00a9\5\32\16\2\u00a8\u00a7\3\2") + buf.write("\2\2\u00a9\u00ac\3\2\2\2\u00aa\u00a8\3\2\2\2\u00aa\u00ab") + buf.write("\3\2\2\2\u00ab\u00ad\3\2\2\2\u00ac\u00aa\3\2\2\2\u00ad") + buf.write("\u00af\7\f\2\2\u00ae\u00b0\7\4\2\2\u00af\u00ae\3\2\2\2") + buf.write("\u00af\u00b0\3\2\2\2\u00b0\25\3\2\2\2\u00b1\u00b3\7$\2") + buf.write("\2\u00b2\u00b1\3\2\2\2\u00b2\u00b3\3\2\2\2\u00b3\u00b7") + buf.write("\3\2\2\2\u00b4\u00b6\5\34\17\2\u00b5\u00b4\3\2\2\2\u00b6") + buf.write("\u00b9\3\2\2\2\u00b7\u00b5\3\2\2\2\u00b7\u00b8\3\2\2\2") + buf.write("\u00b8\u00bb\3\2\2\2\u00b9\u00b7\3\2\2\2\u00ba\u00bc\5") + buf.write("\30\r\2\u00bb\u00ba\3\2\2\2\u00bb\u00bc\3\2\2\2\u00bc") + buf.write("\u00bd\3\2\2\2\u00bd\u00be\5 \21\2\u00be\u00c0\7\"\2\2") + buf.write("\u00bf\u00c1\7\4\2\2\u00c0\u00bf\3\2\2\2\u00c0\u00c1\3") + buf.write("\2\2\2\u00c1\27\3\2\2\2\u00c2\u00c5\7\17\2\2\u00c3\u00c5") + buf.write("\7\r\2\2\u00c4\u00c2\3\2\2\2\u00c4\u00c3\3\2\2\2\u00c5") + buf.write("\31\3\2\2\2\u00c6\u00c7\5 \21\2\u00c7\u00c9\7\"\2\2\u00c8") + buf.write("\u00ca\7\20\2\2\u00c9\u00c8\3\2\2\2\u00c9\u00ca\3\2\2") + buf.write("\2\u00ca\33\3\2\2\2\u00cb\u00cc\7\36\2\2\u00cc\35\3\2") + buf.write("\2\2\u00cd\u00d0\7\"\2\2\u00ce\u00cf\7\21\2\2\u00cf\u00d1") + buf.write("\7\"\2\2\u00d0\u00ce\3\2\2\2\u00d0\u00d1\3\2\2\2\u00d1") + buf.write("\u00d3\3\2\2\2\u00d2\u00d4\7\20\2\2\u00d3\u00d2\3\2\2") + buf.write("\2\u00d3\u00d4\3\2\2\2\u00d4\37\3\2\2\2\u00d5\u00da\5") + buf.write("$\23\2\u00d6\u00da\5\"\22\2\u00d7\u00da\5&\24\2\u00d8") + buf.write("\u00da\5(\25\2\u00d9\u00d5\3\2\2\2\u00d9\u00d6\3\2\2\2") + buf.write("\u00d9\u00d7\3\2\2\2\u00d9\u00d8\3\2\2\2\u00da!\3\2\2") + buf.write("\2\u00db\u00dc\7\"\2\2\u00dc#\3\2\2\2\u00dd\u00e3\7\22") + buf.write("\2\2\u00de\u00e3\7\23\2\2\u00df\u00e3\7\24\2\2\u00e0\u00e3") + buf.write("\7\25\2\2\u00e1\u00e3\7\26\2\2\u00e2\u00dd\3\2\2\2\u00e2") + buf.write("\u00de\3\2\2\2\u00e2\u00df\3\2\2\2\u00e2\u00e0\3\2\2\2") + buf.write("\u00e2\u00e1\3\2\2\2\u00e3%\3\2\2\2\u00e4\u00e5\7\27\2") + buf.write("\2\u00e5\u00e6\7\30\2\2\u00e6\u00e7\5 \21\2\u00e7\u00e8") + buf.write("\7\31\2\2\u00e8\'\3\2\2\2\u00e9\u00ea\7\32\2\2\u00ea\u00eb") + buf.write("\7\30\2\2\u00eb\u00ec\5 \21\2\u00ec\u00ed\7\31\2\2\u00ed") + buf.write(")\3\2\2\2\u00ee\u00f0\7$\2\2\u00ef\u00ee\3\2\2\2\u00ef") + buf.write("\u00f0\3\2\2\2\u00f0\u00f4\3\2\2\2\u00f1\u00f3\5\34\17") + buf.write("\2\u00f2\u00f1\3\2\2\2\u00f3\u00f6\3\2\2\2\u00f4\u00f2") + buf.write("\3\2\2\2\u00f4\u00f5\3\2\2\2\u00f5\u00f7\3\2\2\2\u00f6") + buf.write("\u00f4\3\2\2\2\u00f7\u00f8\7\33\2\2\u00f8\u00f9\7\"\2") + buf.write("\2\u00f9\u00fd\7\b\2\2\u00fa\u00fc\5,\27\2\u00fb\u00fa") + buf.write("\3\2\2\2\u00fc\u00ff\3\2\2\2\u00fd\u00fb\3\2\2\2\u00fd") + buf.write("\u00fe\3\2\2\2\u00fe\u0100\3\2\2\2\u00ff\u00fd\3\2\2\2") + buf.write("\u0100\u0102\7\t\2\2\u0101\u0103\7\4\2\2\u0102\u0101\3") + buf.write("\2\2\2\u0102\u0103\3\2\2\2\u0103+\3\2\2\2\u0104\u0106") + buf.write("\7$\2\2\u0105\u0104\3\2\2\2\u0105\u0106\3\2\2\2\u0106") + buf.write("\u010a\3\2\2\2\u0107\u0109\5\34\17\2\u0108\u0107\3\2\2") + buf.write("\2\u0109\u010c\3\2\2\2\u010a\u0108\3\2\2\2\u010a\u010b") + buf.write("\3\2\2\2\u010b\u010d\3\2\2\2\u010c\u010a\3\2\2\2\u010d") + buf.write("\u010e\5 \21\2\u010e\u0110\7\"\2\2\u010f\u0111\7\4\2\2") + buf.write("\u0110\u010f\3\2\2\2\u0110\u0111\3\2\2\2\u0111-\3\2\2") + buf.write("\2\u0112\u0114\7$\2\2\u0113\u0112\3\2\2\2\u0113\u0114") + buf.write("\3\2\2\2\u0114\u0118\3\2\2\2\u0115\u0117\5\34\17\2\u0116") + buf.write("\u0115\3\2\2\2\u0117\u011a\3\2\2\2\u0118\u0116\3\2\2\2") + buf.write("\u0118\u0119\3\2\2\2\u0119\u011b\3\2\2\2\u011a\u0118\3") + buf.write("\2\2\2\u011b\u011c\5\60\31\2\u011c\u011d\7\"\2\2\u011d") + buf.write("\u0121\7\b\2\2\u011e\u0120\5\62\32\2\u011f\u011e\3\2\2") + buf.write("\2\u0120\u0123\3\2\2\2\u0121\u011f\3\2\2\2\u0121\u0122") + buf.write("\3\2\2\2\u0122\u0124\3\2\2\2\u0123\u0121\3\2\2\2\u0124") + buf.write("\u0126\7\t\2\2\u0125\u0127\7\4\2\2\u0126\u0125\3\2\2\2") + buf.write("\u0126\u0127\3\2\2\2\u0127/\3\2\2\2\u0128\u012b\7\34\2") + buf.write("\2\u0129\u012b\7\35\2\2\u012a\u0128\3\2\2\2\u012a\u0129") + buf.write("\3\2\2\2\u012b\61\3\2\2\2\u012c\u012e\7$\2\2\u012d\u012c") + buf.write("\3\2\2\2\u012d\u012e\3\2\2\2\u012e\u0132\3\2\2\2\u012f") + buf.write("\u0131\5\34\17\2\u0130\u012f\3\2\2\2\u0131\u0134\3\2\2") + buf.write("\2\u0132\u0130\3\2\2\2\u0132\u0133\3\2\2\2\u0133\u0135") + buf.write("\3\2\2\2\u0134\u0132\3\2\2\2\u0135\u0138\7\"\2\2\u0136") + buf.write("\u0137\7\21\2\2\u0137\u0139\5\64\33\2\u0138\u0136\3\2") + buf.write("\2\2\u0138\u0139\3\2\2\2\u0139\u013b\3\2\2\2\u013a\u013c") + buf.write("\7\20\2\2\u013b\u013a\3\2\2\2\u013b\u013c\3\2\2\2\u013c") + buf.write("\63\3\2\2\2\u013d\u0140\7\37\2\2\u013e\u0140\7 \2\2\u013f") + buf.write("\u013d\3\2\2\2\u013f\u013e\3\2\2\2\u0140\65\3\2\2\2\64") + buf.write(":AHKPW\\_dkqv{~\u0083\u0088\u008f\u0094\u0097\u009c\u00a1") + buf.write("\u00aa\u00af\u00b2\u00b7\u00bb\u00c0\u00c4\u00c9\u00d0") + buf.write("\u00d3\u00d9\u00e2\u00ef\u00f4\u00fd\u0102\u0105\u010a") + buf.write("\u0110\u0113\u0118\u0121\u0126\u012a\u012d\u0132\u0138") + buf.write("\u013b\u013f") return buf.getvalue() @@ -260,9 +263,9 @@ class TParser ( Parser ): COMMENT=36 MULTICOMM=37 - def __init__(self, input:TokenStream): - super().__init__(input) - self.checkVersion("4.6") + def __init__(self, input:TokenStream, output:TextIO = sys.stdout): + super().__init__(input, output) + self.checkVersion("4.7") self._interp = ParserATNSimulator(self, self.atn, self.decisionsToDFA, self.sharedContextCache) self._predicates = None diff --git a/qface/idl/parser/TVisitor.py b/qface/idl/parser/TVisitor.py index 9836d57..a87cdf4 100644 --- a/qface/idl/parser/TVisitor.py +++ b/qface/idl/parser/TVisitor.py @@ -1,4 +1,4 @@ -# Generated from T.g4 by ANTLR 4.6 +# Generated from T.g4 by ANTLR 4.7 from antlr4 import * if __name__ is not None and "." in __name__: from .TParser import TParser diff --git a/qface/templates/qface/qtcpp.j2 b/qface/templates/qface/qtcpp.j2 new file mode 100644 index 0000000..81b7d7a --- /dev/null +++ b/qface/templates/qface/qtcpp.j2 @@ -0,0 +1,100 @@ +{%+ macro enum_decl(enum) %} + enum {{enum}} { + {% for member in enum.members %} + {{member.name}} = {{member.value}}{% if not loop.last %},{%endif%} + + {% endfor %} + }; + Q_ENUM({{enum}}) +{%- endmacro %} + +{% macro property(property) -%} +Q_PROPERTY({{property|returnType}} {{property}} READ {{property}} {% if not property.readonly %}WRITE set{{property|upperfirst}} {% endif %}{% if not property.const %}NOTIFY {{property}}Changed{% endif %}) +{%- endmacro %} + +{% macro property_setter_decl(property) -%} +virtual void set{{property|upperfirst}}({{ property|parameterType }}); +{%- endmacro %} + +{% macro property_getter_decl(property) -%} +virtual {{property|returnType}} {{property}}() const; +{%- endmacro %} + +{% macro signal_decl(symbol) -%} +{% if symbol.is_property %} +void {{symbol}}Changed({{symbol|parameters}}); +{% else %} +void {{symbol}}({{symbol|parameters}}); +{%- endif %} + +{%- endmacro %} +{% macro property_member_decl(property) %} +{{property|returnType}} m_{{property}}; +{%- endmacro %} + +{% macro property_setter_impl(class, property) -%} +/*! + \qmlproperty {{property.type}} {{interface}}::{{property}} +{% with doc = property.comment|parse_doc %} + \brief {{doc.brief}} + + {{doc.description}} +{% endwith %} +*/ + +void {{class}}::set{{property|upperfirst}}({{ property|parameterType }}) +{ + if(m_{{property}} == {{property}}) { + return; + } + m_{{property}} = {{property}}; + emit {{property}}Changed(); +} +{%- endmacro %} + + +{% macro property_getter_impl(class, property) -%} +{{property|returnType}} {{class}}::{{property}}() const +{ + return m_{{property}}; +} +{%- endmacro %} + + +{% macro operation_impl(class, operation) %} +/*! + \qmlmethod {{operation.type}} {{class}}::{{operation}}({{operation|parameters}}) +{% with doc = operation.comment|parse_doc %} + \brief {{doc.brief}} + {{doc.description}} +{% endwith %} +*/ +{{operation|returnType}} {{class}}::{{operation}}({{operation|parameters}}) +{ + {% for parameter in operation.parameters %} + Q_UNUSED({{parameter.name}}); + {% endfor %} + qWarning() << "{{class}}::{{operation}}(...) not implemented"; + return {{operation|defaultValue}}; +} +{% endmacro %} + +{% macro operation_decl(operation) %} + virtual {{operation|returnType}} {{operation}}({{operation|parameters}}); +{% endmacro %} + +{% macro autogenerated(prefix="//") %} + +{{prefix}} This is an auto-generated file. +{{prefix}} Do not edit! All changes made to it will be lost. + +{% endmacro %} + +{% macro preserved(prefix="//") %} + +{{prefix}} This is a preserved file. +{{prefix}} Changes will not be overriden by the generator. +{{prefix}} To reset the file you need to delete it first. + +{% endmacro %} + diff --git a/qface/watch.py b/qface/watch.py index df1293e..f99b45a 100644 --- a/qface/watch.py +++ b/qface/watch.py @@ -24,7 +24,7 @@ class RunScriptChangeHandler(FileSystemEventHandler): if self.is_running: return self.is_running = True - sh(self.script, cwd=Path.getcwd()) + sh(str(self.script), cwd=Path.getcwd()) self.is_running = False @@ -33,13 +33,14 @@ def monitor(script, src, dst): reloads the script given by argv when src files changes """ src = src if isinstance(src, (list, tuple)) else [src] - script = '{0} {1} {2}'.format(script, ' '.join(src), dst) + dst = Path(dst).expand().abspath() src = [Path(entry).expand().abspath() for entry in src] - event_handler = RunScriptChangeHandler(script) + script = Path(script).expand().abspath() + command = '{0} {1} {2}'.format(script, ' '.join(src), dst) + event_handler = RunScriptChangeHandler(command) observer = Observer() - path = Path(script).dirname().expand().abspath() - click.secho('watch recursive: {0}'.format(path), fg='blue') - observer.schedule(event_handler, path, recursive=True) + 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') diff --git a/requirements.txt b/requirements.txt index 3cc9f80..dbbb4c7 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ -antlr4-python3-runtime==4.6 +antlr4-python3-runtime==4.7 typing jinja2 click @@ -32,16 +32,13 @@ setup( url=__uri__, author=__author__, author_email=__author_email__, - license='GPLV3', + license='MIT', classifiers=[ - 'Development Status :: 4 - Beta', + 'Development Status :: 5 - Production/Stable', 'Intended Audience :: Developers', 'Topic :: Software Development :: Code Generators', - 'License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)', + 'License :: OSI Approved :: MIT License', 'Programming Language :: Python :: 3', - 'Programming Language :: Python :: 3.3', - 'Programming Language :: Python :: 3.4', - 'Programming Language :: Python :: 3.5', ], keywords='qt code generator framework', packages=find_packages(), @@ -66,11 +63,5 @@ setup( 'watchdog', 'ipdb', ], - }, - entry_points={ - 'console_scripts': [ - 'qface-qtcpp = qface.builtin.qtcpp.qtcpp:app', - 'qface-qtqml = qface.builtin.qtqml.qtqml:app', - ], - }, + } ) diff --git a/tests/test_generator.py b/tests/test_generator.py index c99c561..9aa6e71 100644 --- a/tests/test_generator.py +++ b/tests/test_generator.py @@ -67,5 +67,5 @@ def test_destination_prefix(): ctx = {'out': out.abspath(), 'module': module} generator.write(dst_template, 'module.txt', ctx) path = generator.apply(dst_template, ctx) - assert Path(path).exists() + assert Path(path).exists() == True out.rmtree_p() diff --git a/tests/test_parser.py b/tests/test_parser.py index 128e691..764a7b9 100644 --- a/tests/test_parser.py +++ b/tests/test_parser.py @@ -68,9 +68,10 @@ def test_operation(): assert operation operation = interface._contentMap['previousStation'] assert operation + assert not operation.is_const operation = interface._contentMap['numStations'] assert operation - assert operation.const + assert operation.is_const def test_signals(): diff --git a/tests/test_qtcpp_helper.py b/tests/test_qtcpp_helper.py index 535905a..a25210e 100644 --- a/tests/test_qtcpp_helper.py +++ b/tests/test_qtcpp_helper.py @@ -106,9 +106,9 @@ def test_default_value(): parameter = operation._parameterMap['message'] types = { - 'bool': 'false', - 'int': '0', - 'real': '0.0', + 'bool': 'bool(false)', + 'int': 'int(0)', + 'real': 'qreal(0.0)', 'string': 'QString()', 'var': 'QVariant()' } @@ -205,10 +205,10 @@ def test_namespace(): module = system.lookup('org.example') assert module ns = qtcpp.Filters.open_ns(module) - assert ns == 'namespace org { example {' + assert ns == 'namespace org { namespace example {' ns = qtcpp.Filters.close_ns(module) assert ns == '} }' ns = qtcpp.Filters.using_ns(module) - assert ns == 'using namespace org::example' + assert ns == 'using namespace org::example;' |