diff options
Diffstat (limited to 'qface')
55 files changed, 1670 insertions, 2017 deletions
diff --git a/qface/__about__.py b/qface/__about__.py index 6c54abd..e63ff15 100644 --- a/qface/__about__.py +++ b/qface/__about__.py @@ -8,8 +8,8 @@ except NameError: __title__ = "qface" __summary__ = "A generator framework based on a common modern IDL" -__uri__ = "https://pelagicore.github.io/qface/" -__version__ = "1.1" +__url__ = "https://pelagicore.github.io/qface/" +__version__ = "1.9.1" __author__ = "JRyannel" __author_email__ = "qface-generator@googlegroups.com" -__copyright__ = "2017 Pelagicore" +__copyright__ = "2019 Pelagicore" 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 283b8f6..0000000 --- a/qface/builtin/qtcpp/qtcpp.py +++ /dev/null @@ -1,81 +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('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/__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 5335632..0000000 --- a/qface/builtin/qtcpp/templates/abstractinterface.h +++ /dev/null @@ -1,53 +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.is_readonly %} -WRITE set{{property|upperfirst}} {% endif %}NOTIFY {{property}}Changed) -{% 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 3e86be0..0000000 --- a/qface/builtin/qtcpp/templates/interface.cpp +++ /dev/null @@ -1,50 +0,0 @@ -{# Copyright (c) Pelagicore AB 2016 #} -{% set class = 'Qml{0}'.format(interface) %} -/* - * This is a preserved file and can be edited. - * All changes will not be override. - */ - -#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 6ada967..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 and can be edited. - * All changes will not be override. - */ - - -#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 1d00d74..0000000 --- a/qface/builtin/qtqml/qtqml.py +++ /dev/null @@ -1,67 +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) - generator = Generator(search_path=here / 'templates') - 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 b28d6b7..0000000 --- a/qface/builtin/qtqml/templates/AbstractInterface.qml +++ /dev/null @@ -1,27 +0,0 @@ -import QtQml 2.2 -import QtQml.Models 2.2 - -import "." - -{{interface.comment}} -QtObject { - id: root -{% for property in interface.properties %} - {{property.comment}} - {%+ if property.is_readonly %}readonly {% endif %}property {{property|propertyType}} {{property}} : {{property|defaultValue}} -{% endfor %} -{% for operation in interface.operations %} - {{operation.comment}} - 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 2dc9d5f..0000000 --- a/qface/builtin/qtqml/templates/Interface.qml +++ /dev/null @@ -1,7 +0,0 @@ -import QtQml 2.2 - -import "private" - -Abstract{{interface}} { - id: root -} diff --git a/qface/builtin/qtqml/templates/Module.qml b/qface/builtin/qtqml/templates/Module.qml deleted file mode 100644 index 7ededf2..0000000 --- a/qface/builtin/qtqml/templates/Module.qml +++ /dev/null @@ -1,24 +0,0 @@ -pragma Singleton - -import QtQml 2.2 - -/** - * {{module.comment}} - */ -QtObject { - id: root - - {% for enum in module.enums %} - // Enum: {{enum}} - {% for member in enum.members %} - readonly property int {{member}}: {{member.value}} - {% endfor %} - - {% endfor %} - - {% for struct in module.structs %} - function create{{struct}}() { - return {}; - } - {% endfor %} -} 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/module.js b/qface/builtin/qtqml/templates/module.js deleted file mode 100644 index 551f5c3..0000000 --- a/qface/builtin/qtqml/templates/module.js +++ /dev/null @@ -1,18 +0,0 @@ -.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 fc465a7..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 %} -{{interface}} 1.0 {{interface}}.qml -{% endfor %} diff --git a/qface/builtin/__init__.py b/qface/contrib/__init__.py index e69de29..e69de29 100644 --- a/qface/builtin/__init__.py +++ b/qface/contrib/__init__.py diff --git a/qface/contrib/logging.py b/qface/contrib/logging.py new file mode 100644 index 0000000..6b7625c --- /dev/null +++ b/qface/contrib/logging.py @@ -0,0 +1,28 @@ +import yaml +import logging +import logging.config +import coloredlogs +from path import Path +import os + + +def basic_log(level): + logging.basicConfig(level=level) + coloredlogs.install(level=level) + print('Fall back to basic logging') + + +def setup_log(path='logging.yaml', level=logging.INFO, env_key='QFACE_LOG_CFG'): + path = Path(os.getenv(env_key, path)) + if path.exists(): + try: + config = yaml.safe_load(path.text()) + logging.config.dictConfig(config) + coloredlogs.install() + except Exception as e: + print(e) + print('Error in logging configuration. Fall back to defaults.') + basic_log(level) + else: + basic_log(level) + print('Failed to load logging config file.') diff --git a/qface/filters.py b/qface/filters.py new file mode 100644 index 0000000..de424a4 --- /dev/null +++ b/qface/filters.py @@ -0,0 +1,46 @@ +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('.', '/') + + +filters = { + 'jsonify': jsonify, + 'upper_first': upper_first, + 'lower_first': lower_first, + 'upperfirst': upper_first, + 'lowerfirst': lower_first, + 'hash': hash, + 'path': path, +} diff --git a/qface/generator.py b/qface/generator.py index db1235c..eb7b24a 100644 --- a/qface/generator.py +++ b/qface/generator.py @@ -1,14 +1,18 @@ + # Copyright (c) Pelagicore AB 2016 -from jinja2 import Environment, FileSystemLoader, Template +from jinja2 import Environment, Template, Undefined, StrictUndefined +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 +from antlr4.error import DiagnosticErrorListener, ErrorListener import shelve import logging import hashlib import yaml import click +import sys, os from .idl.parser.TLexer import TLexer from .idl.parser.TParser import TParser @@ -16,7 +20,9 @@ from .idl.parser.TListener import TListener from .idl.domain import System from .idl.listener import DomainListener from .utils import merge +from .filters import filters +from jinja2.debug import make_traceback as _make_traceback try: from yaml import CLoader as Loader, CDumper as Dumper @@ -26,28 +32,61 @@ except ImportError: logger = logging.getLogger(__name__) -""" -Provides an API for accessing the file system and controlling the generator -""" +def template_error_handler(traceback): + exc_type, exc_obj, exc_tb = traceback.exc_info + error = exc_obj + if isinstance(exc_type, TemplateError): + error = exc_obj.message + message = '{0}:{1}: error: {2}'.format(exc_tb.tb_frame.f_code.co_filename, exc_tb.tb_lineno, error) + click.secho(message, fg='red', err=True) + + +class TestableUndefined(StrictUndefined): + """Return an error for all undefined values, but allow testing them in if statements""" + def __bool__(self): + return False + + +class ReportingErrorListener(ErrorListener.ErrorListener): + """ Provides an API for accessing the file system and controlling the generator """ + def __init__(self, document): + self.document = document + def syntaxError(self, recognizer, offendingSymbol, line, column, msg, e): + msg = '{0}:{1}:{2} {2}'.format(self.document, line, column, msg) + click.secho(msg, fg='red') + raise ValueError(msg) -def upper_first_filter(s): - s = str(s) - return s[0].upper() + s[1:] + def reportAmbiguity(self, recognizer, dfa, startIndex, stopIndex, exact, ambigAlts, configs): + click.secho('ambiguity', fg='red') + + def reportAttemptingFullContext(self, recognizer, dfa, startIndex, stopIndex, conflictingAlts, configs): + click.secho('reportAttemptingFullContext', fg='red') + + def reportContextSensitivity(self, recognizer, dfa, startIndex, stopIndex, prediction, configs): + click.secho('reportContextSensitivity', fg='red') class Generator(object): """Manages the templates and applies your context data""" - def __init__(self, search_path: str): - if search_path: - search_path = Path(search_path).expand() - self.env = Environment( - loader=FileSystemLoader(search_path), - trim_blocks=True, - lstrip_blocks=True - ) - self.env.filters['upperfirst'] = upper_first_filter + strict = False + """ enables strict code generation """ + + def __init__(self, search_path, context={}): + loader = ChoiceLoader([ + FileSystemLoader(search_path), + PackageLoader('qface') + ]) + self.env = Environment( + loader=loader, + trim_blocks=True, + lstrip_blocks=True, + ) + self.env.exception_handler = template_error_handler + self.env.filters.update(filters) self._destination = Path() + self._source = '' + self.context = context @property def destination(self): @@ -55,37 +94,86 @@ class Generator(object): return self._destination @destination.setter - def destination(self, dst: str): - self._destination = Path(dst) + def destination(self, dst): + if dst: + self._destination = Path(self.apply(dst, self.context)) + + @property + def source(self): + """source prefix for template lookup""" + return self._source - def get_template(self, name: str): + @source.setter + def source(self, source): + if source: + self._source = source + + @property + def filters(self): + return self.env.filters + + @filters.setter + def filters(self, filters): + self.env.filters.update(filters) + + def get_template(self, name): """Retrieves a single template file from the template loader""" - return self.env.get_template(name) + source = name + if name and name[0] is '/': + source = name[1:] + elif self.source is not None: + source = '/'.join((self.source, name)) + return self.env.get_template(source) - def render(self, name: str, context: dict): + def render(self, name, context): """Returns the rendered text from a single template file from the template loader using the given context data""" + if Generator.strict: + self.env.undefined = TestableUndefined + else: + self.env.undefined = Undefined template = self.get_template(name) return template.render(context) - def apply(self, template: str, context: dict): + def apply(self, template, context): """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, template, context={}, preserve=False, force=False): """Using a template file name it renders a template into a file given a context """ + if not context: + context = self.context + error = False + try: + self._write(file_path, template, context, preserve, force) + except TemplateSyntaxError as exc: + message = '{0}:{1}: error: {2}'.format(exc.filename, exc.lineno, exc.message) + click.secho(message, fg='red', err=True) + error = True + except TemplateNotFound as exc: + message = '{0}: error: Template not found'.format(exc.name) + click.secho(message, fg='red', err=True) + error = True + except TemplateError as exc: + # Just return with an error, the generic template_error_handler takes care of printing it + error = True + + if error and Generator.strict: + sys.exit(1) + + def _write(self, file_path: Path, template: str, context: dict, preserve: bool = False, force: bool = False): path = self.destination / Path(self.apply(file_path, context)) path.parent.makedirs_p() logger.info('write {0}'.format(path)) data = self.render(template, context) - if self._has_different_content(data, path): + if self._has_different_content(data, path) or force: if path.exists() and preserve: - click.secho('preserve changed file: {0}'.format(path), fg='blue') + click.secho('preserve: {0}'.format(path), fg='blue') else: - click.secho('write changed file: {0}'.format(path), fg='blue') - path.open('w').write(data) + click.secho('create: {0}'.format(path), fg='blue') + path.open('w', encoding='utf-8').write(data) def _has_different_content(self, data, path): if not path.exists(): @@ -99,11 +187,90 @@ class Generator(object): self.env.filters[name] = callback +class RuleGenerator(Generator): + """Generates documents based on a rule YAML document""" + def __init__(self, search_path: str, destination:Path, context:dict={}, features:set=set()): + super().__init__(search_path, context) + self.context.update({ + 'dst': destination, + 'project': Path(destination).name, + 'features': features, + }) + self.destination = '{{dst}}' + self.features = features + + def process_rules(self, path: Path, system: System): + """writes the templates read from the rules document""" + self.context.update({ + 'system': system, + }) + document = FileSystem.load_yaml(path, required=True) + for module, rules in document.items(): + click.secho('process: {0}'.format(module), fg='green') + self._process_rules(rules, system) + + def _process_rules(self, rules: dict, system: System): + """ process a set of rules for a target """ + self._source = None # reset the template source + if not self._shall_proceed(rules): + return + self.context.update(rules.get('context', {})) + self.destination = rules.get('destination', '{{dst}}') + self.source = rules.get('source', None) + self._process_rule(rules.get('system', None), {'system': system}) + for module in system.modules: + self._process_rule(rules.get('module', None), {'module': module}) + for interface in module.interfaces: + self._process_rule(rules.get('interface', None), {'interface': interface}) + for struct in module.structs: + self._process_rule(rules.get('struct', None), {'struct': struct}) + for enum in module.enums: + self._process_rule(rules.get('enum', None), {'enum': enum}) + + def _process_rule(self, rule: dict, context: dict): + """ process a single rule """ + if not rule or not self._shall_proceed(rule): + return + self.context.update(context) + self.context.update(rule.get('context', {})) + self.destination = rule.get('destination', None) + self.source = rule.get('source', None) + for target, source in rule.get('documents', {}).items(): + self.write(target, source) + for target, source in rule.get('preserve', {}).items(): + self.write(target, source, preserve=True) + + def _shall_proceed(self, obj): + conditions = obj.get('when', []) + if not conditions: + return True + if not isinstance(conditions, list): + conditions = [conditions] + result = self.features.intersection(set(conditions)) + return bool(len(result)) + + class FileSystem(object): """QFace helper functions to work with the file system""" + strict = False + """ enables strict parsing """ @staticmethod def parse_document(document: Path, system: System = None): + error = False + try: + return FileSystem._parse_document(document, system) + except FileNotFoundError as e: + click.secho('{0}: error: file not found'.format(document), fg='red', err=True) + error = True + except ValueError as e: + click.secho('Error parsing document {0}'.format(document), fg='red', err=True) + error = True + if error and FileSystem.strict: + sys.exit(-1) + + @staticmethod + def _parse_document(document: Path, system: System = None): """Parses a document and returns the resulting domain system :param path: document path to parse @@ -111,19 +278,19 @@ class FileSystem(object): """ logger.debug('parse document: {0}'.format(document)) stream = FileStream(str(document), encoding='utf-8') - system = FileSystem._parse_stream(stream, system) + system = FileSystem._parse_stream(stream, system, document) FileSystem.merge_annotations(system, document.stripext() + '.yaml') return system @staticmethod - def _parse_stream(stream, system: System = None): + def _parse_stream(stream, system: System = None, document=None): logger.debug('parse stream') system = system or System() lexer = TLexer(stream) stream = CommonTokenStream(lexer) parser = TParser(stream) - parser.addErrorListener(DiagnosticErrorListener.DiagnosticErrorListener()) + parser.addErrorListener(ReportingErrorListener(document)) tree = parser.documentSymbol() walker = ParseTreeWalker() walker.walk(DomainListener(system), tree) @@ -134,14 +301,10 @@ class FileSystem(object): """Read a YAML document and for each root symbol identifier updates the tag information of that symbol """ - if not document.exists(): + if not Path(document).exists(): return - meta = {} - try: - meta = yaml.load(document.text(), Loader=Loader) - except yaml.YAMLError as exc: - click.secho(exc, fg='red') - click.secho('merge tags from {0}'.format(document), fg='blue') + meta = FileSystem.load_yaml(document) + click.secho('merge: {0}'.format(document.name), fg='blue') for identifier, data in meta.items(): symbol = system.lookup(identifier) if symbol: @@ -181,3 +344,19 @@ class FileSystem(object): if use_cache: cache[identifier] = system return system + + @staticmethod + def load_yaml(document: Path, required=False): + document = Path(document) + if not document.exists(): + if required: + click.secho('yaml document does not exists: {0}'.format(document), fg='red', err=True) + return {} + try: + return yaml.load(document.text(), Loader=Loader) + except yaml.YAMLError as exc: + error = document + if hasattr(exc, 'problem_mark'): + error = '{0}:{1}'.format(error, exc.problem_mark.line+1) + click.secho('{0}: error: {1}'.format(error, str(exc)), fg='red', err=True) + return {} diff --git a/qface/helper/doc.py b/qface/helper/doc.py index c999227..2b1df51 100644 --- a/qface/helper/doc.py +++ b/qface/helper/doc.py @@ -1,9 +1,8 @@ import re - translate = None """ -The translare function used for transalting inline tags. The +The translate function used for translating inline tags. The function will be called with tag, value arguments. Example: @@ -22,7 +21,7 @@ class DocObject: The documentation object passed into the template engine """ def __init__(self): - self.brief = str() + self.brief = [] self.description = [] self.see = [] self.deprecated = False @@ -37,6 +36,8 @@ class DocObject: setattr(self, name, str(value)) elif attr_type is list: getattr(self, name).append(value) + else: + print('documentation tag @{0} not supported'.format(name)) @staticmethod def _translate(name, value): @@ -55,6 +56,8 @@ class DocObject: def parse_doc(s): + """ parse a comment in the format of JavaDoc and returns an object, where each JavaDoc tag + is a property of the object. """ if not s: return doc = DocObject() @@ -77,5 +80,6 @@ def parse_doc(s): doc.add_tag(tag, value) elif tag: # append to previous matched tag doc.add_tag(tag, line) + else: # append any loose lines to description + doc.add_tag('description', line) return doc - diff --git a/qface/helper/qtcpp.py b/qface/helper/qtcpp.py index 7e8f3ca..2c64e74 100644 --- a/qface/helper/qtcpp.py +++ b/qface/helper/qtcpp.py @@ -1,16 +1,14 @@ """ Provides helper functionality specificially for Qt C++/QML code generators """ - - -def upper_first(s): - s = str(s) - return s[0].upper() + s[1:] +import qface.idl.domain as domain +from jinja2 import environmentfilter +from ..filters import upper_first class Filters(object): """provides a set of filters to be used with the template engine""" - classPrefix = 'Qml' + classPrefix = '' @staticmethod def className(symbol): @@ -20,105 +18,236 @@ class Filters(object): @staticmethod def defaultValue(symbol): prefix = Filters.classPrefix - t = symbol.type # type: qface.domain.TypeSymbol + t = symbol.type if t.is_primitive: if t.is_int: - return '0' + return 'int(0)' if t.is_bool: - return 'false' + return 'bool(false)' if t.is_string: return 'QString()' if t.is_real: - return '0.0' - if t.is_variant: + return 'qreal(0.0)' + if t.is_var: return 'QVariant()' elif t.is_void: return '' elif t.is_enum: - module_name = t.reference.module.module_name value = next(iter(t.reference.members)) - return '{0}{1}Module::{2}'.format(prefix, module_name, value) - elif symbol.type.is_list: - nested = Filters.returnType(symbol.type.nested) + return '{0}::{0}Enum::{1}'.format(symbol.type, value) + elif symbol.kind == 'enum': + value = next(iter(symbol.members)) + return '{0}::{1}'.format(symbol, value) + elif t.is_flag: + return '0' + elif t.is_list: + nested = Filters.returnType(t.nested) return 'QVariantList()'.format(nested) - elif symbol.type.is_struct: - return '{0}{1}()'.format(prefix, symbol.type) - elif symbol.type.is_model: - nested = symbol.type.nested - if nested.is_primitive: - return 'new {0}VariantModel(this)'.format(prefix) - elif nested.is_complex: - return 'new {0}{1}Model(this)'.format(prefix, nested) - return 'XXX' + elif t.is_struct: + return '{0}{1}()'.format(prefix, t) + elif t.is_model: + return 'new VariantModel(this)' + elif t.is_interface: + return 'nullptr' + raise Exception("Unknown symbol type" + repr(symbol)) @staticmethod def parameterType(symbol): prefix = Filters.classPrefix - module_name = symbol.module.module_name if symbol.type.is_enum: - return '{0}{1}Module::{2} {3}'.format(prefix, module_name, symbol.type, symbol) + return '{0}::{0}Enum {1}'.format(symbol.type, symbol) if symbol.type.is_void or symbol.type.is_primitive: - if symbol.type.name == 'string': + if symbol.type.is_string: return 'const QString &{0}'.format(symbol) - if symbol.type.name == 'var': + if symbol.type.is_var: return 'const QVariant &{0}'.format(symbol) - if symbol.type.name == 'real': + if symbol.type.is_real: return 'qreal {0}'.format(symbol) + if symbol.type.is_bool: + return 'bool {0}'.format(symbol) + if symbol.type.is_int: + return 'int {0}'.format(symbol) return '{0} {1}'.format(symbol.type, symbol) elif symbol.type.is_list: nested = Filters.returnType(symbol.type.nested) return 'const QVariantList &{1}'.format(nested, symbol) elif symbol.type.is_model: - nested = symbol.type.nested - if nested.is_primitive: - return '{0}VariantModel *{1}'.format(prefix, symbol) - elif nested.is_complex: - return '{0}{1}Model *{2}'.format(prefix, nested, symbol) - else: - return 'const {0}{1} &{2}'.format(prefix, symbol.type, symbol) - return 'XXX' + return 'VariantModel *{0}'.format(symbol) + elif symbol.type.is_complex: + if symbol.type.is_interface: + return '{0}Base *{1}'.format(symbol.type, symbol) + else: + return 'const {0}{1} &{2}'.format(prefix, symbol.type, symbol) + raise Exception("Unknown symbol type") @staticmethod def returnType(symbol): prefix = Filters.classPrefix - module_name = symbol.module.module_name - if symbol.type.is_enum: - return '{0}{1}Module::{2}'.format(prefix, module_name, symbol.type) + t = symbol.type + if t.is_enum: + return '{0}::{0}Enum'.format(symbol.type) if symbol.type.is_void or symbol.type.is_primitive: - if symbol.type.name == 'string': + if t.is_string: return 'QString' - if symbol.type.name == 'var': + if t.is_var: return 'QVariant' - if symbol.type.name == 'real': + if t.is_real: return 'qreal' - return symbol.type.name + if t.is_int: + return 'int' + if t.is_bool: + return 'bool' + if t.is_void: + return 'void' + print(t) + assert False elif symbol.type.is_list: nested = Filters.returnType(symbol.type.nested) return 'QVariantList'.format(nested) elif symbol.type.is_model: - nested = symbol.type.nested - if nested.is_primitive: - return '{0}VariantModel *'.format(prefix) - elif nested.is_complex: - return '{0}{1}Model *'.format(prefix, nested) - else: - return '{0}{1}'.format(prefix, symbol.type) - return 'XXX' + return 'VariantModel *' + elif symbol.type.is_complex: + if symbol.type.is_interface: + return '{0}Base *'.format(symbol.type) + else: + return '{0}{1}'.format(prefix, symbol.type) + raise Exception("Unknown symbol type") + + @staticmethod + def header_dependencies(symbol): + types = symbol.dependencies + lines = [] + for t in types: + if t.is_primitive: + continue + if t.is_model: + lines.append('class VariantModel;') + if t.is_interface: + lines.append('class {0};'.format(t)) + if t.is_struct: + lines.append('#include "{0}.h"'.format(t)) + return "\n".join(lines) + + @staticmethod + def source_dependencies(symbol): + types = symbol.dependencies + lines = [] + module_name = symbol.module.module_name + if not symbol.kind == 'module': + lines.append('#include "{0}module.h"'.format(module_name.lower())) + for t in types: + if t.is_primitive: + continue + if t.is_model: + lines.append('#include "variantmodel.h"') + if t.is_interface: + lines.append('#include "{0}.h"'.format(t.name.lower())) + return "\n".join(lines) @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): '''generates a closing names statement from a symbol''' - return ' '.join(['}' for x in symbol.module.name_parts]) + closing = ' '.join(['}' for x in symbol.module.name_parts]) + name = '::'.join(symbol.module.name_parts) + return '{0} // namespace {1}'.format(closing, name) @staticmethod 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 ns(symbol): + '''generates a namespace x::y::z statement from a symbol''' + if symbol.type and symbol.type.is_primitive: + return '' + return '{0}::'.format('::'.join(symbol.module.name_parts)) + + @staticmethod + def fqn(symbol): + '''generates a fully qualified name from symbol''' + return '{0}::{1}'.format(Filters.ns(symbol), symbol.name) + + @staticmethod + def signalName(s): + if isinstance(s, domain.Property): + return '{0}Changed'.format(s) + return s + + @staticmethod + @environmentfilter + def parameters(env, s, filter=None, spaces=True): + if not filter: + filter = Filters.parameterType + elif isinstance(filter, str): + filter = env.filters[filter] + args = [] + indent = ', ' + if not spaces: + indent = ',' + if isinstance(s, domain.Operation): + 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 + @environmentfilter + def signature(env, s, expand=False, filter=None): + if not filter: + filter = Filters.returnType + elif isinstance(filter, str): + filter = env.filters[filter] + if isinstance(s, domain.Operation): + args = s.parameters + elif isinstance(s, domain.Signal): + args = s.parameters + elif isinstance(s, domain.Property): + args = [s] # for <property>Changed(<type>) + elif isinstance(s, domain.Struct): + args = s.fields + else: + 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('.', '_') + + @staticmethod + def path(s): + return str(s).replace('.', '/') + + @staticmethod + def get_filters(): + return { + 'defaultValue': Filters.defaultValue, + 'returnType': Filters.returnType, + 'parameterType': Filters.parameterType, + 'open_ns': Filters.open_ns, + 'close_ns': Filters.close_ns, + 'using_ns': Filters.using_ns, + 'ns': Filters.ns, + 'fqn': Filters.fqn, + 'signalName': Filters.signalName, + 'parameters': Filters.parameters, + 'signature': Filters.signature, + 'identifier': Filters.identifier, + 'path': Filters.path, + 'className': Filters.className, + 'source_dependencies': Filters.source_dependencies, + 'header_dependencies': Filters.header_dependencies, + } diff --git a/qface/helper/qtqml.py b/qface/helper/qtqml.py index 819000a..e29311f 100644 --- a/qface/helper/qtqml.py +++ b/qface/helper/qtqml.py @@ -3,6 +3,11 @@ Provides helper functionality specificially for Qt5 QML code generators """ +def upper_first(s): + s = str(s) + return s[0].upper() + s[1:] + + class Filters(object): """provides a set of filters to be used with the template engine""" classPrefix = '' @@ -14,15 +19,19 @@ class Filters(object): @staticmethod def defaultValue(symbol): - module = symbol.module.module_name + module = upper_first(symbol.module.module_name) t = symbol.type if t.is_primitive: if t.name == 'int': return '0' + elif t.name == 'real': + return "0.0" elif t.name == 'bool': return 'false' elif t.name == 'string': return "''" + elif t.name == 'var': + return "undefined" elif t.is_enum: value = next(iter(t.reference.members)) return '{0}Module.{1}'.format(module, value) @@ -50,3 +59,11 @@ class Filters(object): return 'ListModel' return t + @staticmethod + def path(s): + return str(s).replace('.', '/') + + @staticmethod + def identifier(s): + return str(s).lower().replace('.', '_') + diff --git a/qface/idl/domain.py b/qface/idl/domain.py index c774c16..fc0ec2c 100644 --- a/qface/idl/domain.py +++ b/qface/idl/domain.py @@ -78,6 +78,11 @@ class System(object): type_name = parts[1] return (module_name, type_name, fragment_name) + def toJson(self): + o = OrderedDict() + o['modules'] = [o.toJson() for o in self.modules] + return o + class NamedElement(object): def __init__(self, name, module: 'Module'): @@ -97,12 +102,18 @@ 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: return '{0}.{1}'.format(self.module.name, self.name) + def toJson(self): + o = OrderedDict() + if self.name: + o['name'] = self.name + return o + class Symbol(NamedElement): """A symbol represents a base class for names elements""" @@ -113,7 +124,10 @@ class Symbol(NamedElement): self._tags = dict() self._contentMap = ChainMap() + self._dependencies = set() self.type = TypeSymbol('', self) + self.kind = self.__class__.__name__.lower() + """ the associated type information """ @property def system(self): @@ -125,25 +139,41 @@ 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() + @property + def dependencies(self): + if not self._dependencies: + self._dependencies = [x.type for x in self.contents] + return self._dependencies + + def toJson(self): + o = super().toJson() + if self.type.is_valid: + o['type'] = self.type.toJson() + return o class TypeSymbol(NamedElement): @@ -152,11 +182,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 @@ -165,7 +201,10 @@ class TypeSymbol(NamedElement): @property def is_valid(self): '''checks if type is a valid type''' - return self.is_primitive or self.is_complex + return (self.is_primitive and self.name) \ + or (self.is_complex and self.name) \ + or (self.is_list and self.nested) \ + or (self.is_model and self.nested) @property def is_bool(self): @@ -188,19 +227,34 @@ class TypeSymbol(NamedElement): return self.is_primitive and self.name == 'string' @property - def is_enum(self): - '''checks if type is complex and enum''' + def is_var(self): + '''checks if type is primitive and var''' + return self.is_primitive and self.name == 'var' + + @property + def is_enumeration(self): + '''checks if type is complex and instance of type Enum''' return self.is_complex and isinstance(self.reference, Enum) @property + def is_enum(self): + '''checks if type is an enumeration and reference is enum''' + return self.is_enumeration and self.reference.is_enum + + @property + def is_flag(self): + '''checks if type is an enumeration and reference is flag ''' + return self.is_enumeration and self.reference.is_flag + + @property def is_struct(self): '''checks if type is complex and struct''' return self.is_complex and isinstance(self.reference, Struct) @property - def is_variant(self): - '''checks if type is primitive and string''' - return self.is_primitive and self.name == 'var' + def is_interface(self): + '''checks if type is interface''' + return self.is_complex and isinstance(self.reference, Interface) @property def reference(self): @@ -218,8 +272,25 @@ class TypeSymbol(NamedElement): @property def type(self): + """ return the type information. In this case: self """ return self + def toJson(self): + o = super().toJson() + if self.is_void: + o['void'] = self.is_void + if self.is_primitive: + o['primitive'] = self.is_primitive + if self.is_complex: + o['complex'] = self.is_complex + if self.is_list: + o['list'] = self.is_list + if self.is_model: + o['model'] = self.is_model + if self.nested: + o['nested'] = self.nested.toJson() + return o + class Module(Symbol): """Module is a namespace for types, e.g. interfaces, enums, structs""" @@ -270,8 +341,19 @@ class Module(Symbol): return self.name.split('.') @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): - return self.name.split('.')[-1].capitalize() + """ returns the last part of the module uri """ + return self.name.split('.')[-1] def lookup(self, name: str, fragment: str = None): '''lookup a symbol by name. If symbol is not local @@ -283,6 +365,14 @@ class Module(Symbol): return symbol return self.system.lookup(name) + def toJson(self): + o = super().toJson() + o['version'] = self.version + o['interfaces'] = [s.toJson() for s in self.interfaces] + o['structs'] = [s.toJson() for s in self.structs] + o['enums'] = [s.toJson() for s in self.enums] + return o + class Interface(Symbol): """A interface is an object with operations, properties and signals""" @@ -294,6 +384,7 @@ class Interface(Symbol): self._operationMap = OrderedDict() # type: dict[str, Operation] self._signalMap = OrderedDict() # type: dict[str, Signal] self._contentMap = ChainMap(self._propertyMap, self._operationMap, self._signalMap) + self._extends = None @property def properties(self): @@ -310,6 +401,18 @@ class Interface(Symbol): '''returns ordered list of signals''' return self._signalMap.values() + @property + def extends(self): + ''' returns the symbol defined by the extends interface attribute ''' + return self.module.lookup(self._extends) + + def toJson(self): + o = super().toJson() + o['properties'] = [s.toJson() for s in self.properties] + o['operations'] = [s.toJson() for s in self.operations] + o['signals'] = [s.toJson() for s in self.signals] + return o + class Operation(Symbol): """An operation inside a interface""" @@ -317,14 +420,28 @@ 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): '''returns ordered list of parameters''' return self._parameterMap.values() + def toJson(self): + o = super().toJson() + o['parameters'] = [s.toJson() for s in self.parameters] + o['type'] = self.type.toJson() + return o + class Signal(Symbol): """A signal inside an interface""" @@ -336,10 +453,20 @@ 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() + def toJson(self): + o = super().toJson() + o['parameters'] = [s.toJson() for s in self.parameters] + return o + class Parameter(Symbol): """An operation parameter""" @@ -357,7 +484,40 @@ class Property(Symbol): log.debug('Property()') self.interface = interface self.interface._propertyMap[name] = self - self.is_readonly = False + 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) + + @property + def writeable(self): + return not self.readonly and not self.const + + def toJson(self): + o = super().toJson() + if self.readonly: + o['readonly'] = True + if self.const: + o['const'] = True + return o class Struct(Symbol): @@ -366,13 +526,18 @@ class Struct(Symbol): super().__init__(name, module) log.debug('Struct()') self.module._structMap[name] = self - self._fieldMap = self._contentMap = OrderedDict() # type: dict[str, Field] + self._fieldMap = self._contentMap = OrderedDict() @property def fields(self): '''returns ordered list of members''' return self._fieldMap.values() + def toJson(self): + o = super().toJson() + o['fields'] = [s.toJson() for s in self.fields] + return o + class Field(Symbol): """A member in a struct""" @@ -382,6 +547,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""" @@ -398,6 +569,15 @@ class Enum(Symbol): '''returns ordered list of members''' return self._memberMap.values() + def toJson(self): + o = super().toJson() + if self.is_enum: + o['enum'] = self.is_enum + if self.is_flag: + o['flag'] = self.is_flag + o['members'] = [s.toJson() for s in self.members] + return o + class EnumMember(Symbol): """A enum value""" @@ -407,3 +587,13 @@ class EnumMember(Symbol): self.enum = enum 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 + return o + diff --git a/qface/idl/listener.py b/qface/idl/listener.py index feeb8c9..4e9e720 100644 --- a/qface/idl/listener.py +++ b/qface/idl/listener.py @@ -1,6 +1,5 @@ # Copyright (c) Pelagicore AB 2016 import logging -from _operator import concat from .parser.TListener import TListener from .parser.TParser import TParser @@ -11,9 +10,9 @@ import click from .profile import get_features, EProfile, EFeature try: - from yaml import CLoader as Loader, CDumper as Dumper + from yaml import CSafeLoader as Loader, CDumper as Dumper except ImportError: - from yaml import Loader, Dumper + from yaml import SafeLoader as Loader, Dumper log = logging.getLogger(__name__) @@ -99,7 +98,7 @@ class DomainListener(QFaceListener): data = yaml.load('\n'.join(lines), Loader=Loader) symbol._tags = data except yaml.YAMLError as exc: - click.secho(exc, fg='red') + click.secho(str(exc), fg='red') def enterEveryRule(self, ctx): log.debug('enter ' + ctx.__class__.__name__) @@ -124,6 +123,8 @@ class DomainListener(QFaceListener): name = ctx.name.text self.interface = Interface(name, self.module) self.parse_annotations(ctx, self.interface) + if ctx.extends: + self.interface._extends = ctx.extends.text contextMap[ctx] = self.interface def exitInterfaceSymbol(self, ctx: TParser.InterfaceSymbolContext): @@ -165,6 +166,9 @@ class DomainListener(QFaceListener): assert self.interface name = ctx.name.text self.operation = Operation(name, self.interface) + modifier = ctx.operationModifierSymbol() + if modifier: + 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 @@ -195,7 +199,19 @@ class DomainListener(QFaceListener): assert self.interface name = ctx.name.text self.property = Property(name, self.interface) - self.property.is_readonly = bool(ctx.isReadOnly) + modifier = ctx.propertyModifierSymbol() + + if modifier: + self.property.readonly = bool(modifier.is_readonly) + self.property.const = bool(modifier.is_const) + + if ctx.value: + try: + value = yaml.load(ctx.value.text, Loader=Loader) + self.property._value = value + except yaml.YAMLError as exc: + click.secho(exc, fg='red') + self.parse_annotations(ctx, self.property) self.parse_type(ctx, self.property.type) contextMap[ctx] = self.property @@ -207,6 +223,7 @@ class DomainListener(QFaceListener): assert self.struct name = ctx.name.text self.field = Field(name, self.struct) + self.parse_annotations(ctx, self.field) contextMap[ctx] = self.field def exitStructFieldSymbol(self, ctx: TParser.StructFieldSymbolContext): @@ -221,6 +238,7 @@ class DomainListener(QFaceListener): if ctx.intSymbol(): value = int(ctx.intSymbol().value.text, 0) self.field.value = value + self.parse_annotations(ctx, self.field) contextMap[ctx] = self.field if self.enum.is_flag: self.enumCounter <<= 1 diff --git a/qface/idl/parser/T.g4 b/qface/idl/parser/T.g4 index 4ec68c8..9cfe4e7 100644 --- a/qface/idl/parser/T.g4 +++ b/qface/idl/parser/T.g4 @@ -29,7 +29,7 @@ definitionSymbol ; interfaceSymbol - : comment=DOCCOMMENT? tagSymbol* 'interface' name=IDENTIFIER '{' interfaceMemberSymbol* '}' ';'? + : comment=DOCCOMMENT? tagSymbol* 'interface' name=IDENTIFIER ('extends' extends=IDENTIFIER)? '{' interfaceMemberSymbol* '}' ';'? ; interfaceMemberSymbol @@ -39,7 +39,11 @@ interfaceMemberSymbol ; operationSymbol - : comment=DOCCOMMENT? tagSymbol* (typeSymbol | 'void') name=IDENTIFIER '(' operationParameterSymbol* ')' ';'? + : comment=DOCCOMMENT? tagSymbol* (typeSymbol | 'void') name=IDENTIFIER '(' operationParameterSymbol* ')' operationModifierSymbol? ';'? + ; + +operationModifierSymbol + : is_const='const' ; signalSymbol @@ -48,7 +52,12 @@ signalSymbol propertySymbol - : comment=DOCCOMMENT? tagSymbol* isReadOnly='readonly'? typeSymbol name=IDENTIFIER ';'? + : comment=DOCCOMMENT? tagSymbol* propertyModifierSymbol? typeSymbol name=IDENTIFIER ';'? + ; + +propertyModifierSymbol + : is_readonly='readonly' + | is_const='const' ; operationParameterSymbol diff --git a/qface/idl/parser/T.tokens b/qface/idl/parser/T.tokens index 86bf74a..5f94603 100644 --- a/qface/idl/parser/T.tokens +++ b/qface/idl/parser/T.tokens @@ -23,38 +23,42 @@ T__21=22 T__22=23 T__23=24 T__24=25 -TAGLINE=26 -INTCONSTANT=27 -HEXCONSTANT=28 -TAGIDENTIFIER=29 -IDENTIFIER=30 -VERSION=31 -DOCCOMMENT=32 -WHITESPACE=33 -COMMENT=34 -MULTICOMM=35 +T__25=26 +T__26=27 +TAGLINE=28 +INTCONSTANT=29 +HEXCONSTANT=30 +TAGIDENTIFIER=31 +IDENTIFIER=32 +VERSION=33 +DOCCOMMENT=34 +WHITESPACE=35 +COMMENT=36 +MULTICOMM=37 'import'=1 ';'=2 'module'=3 'interface'=4 -'{'=5 -'}'=6 -'void'=7 -'('=8 -')'=9 -'signal'=10 -'readonly'=11 -','=12 -'='=13 -'bool'=14 -'int'=15 -'real'=16 -'string'=17 -'var'=18 -'list'=19 -'<'=20 -'>'=21 -'model'=22 -'struct'=23 -'enum'=24 -'flag'=25 +'extends'=5 +'{'=6 +'}'=7 +'void'=8 +'('=9 +')'=10 +'const'=11 +'signal'=12 +'readonly'=13 +','=14 +'='=15 +'bool'=16 +'int'=17 +'real'=18 +'string'=19 +'var'=20 +'list'=21 +'<'=22 +'>'=23 +'model'=24 +'struct'=25 +'enum'=26 +'flag'=27 diff --git a/qface/idl/parser/TLexer.py b/qface/idl/parser/TLexer.py index 59f1fcb..cb108c4 100644 --- a/qface/idl/parser/TLexer.py +++ b/qface/idl/parser/TLexer.py @@ -1,124 +1,133 @@ -# 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("\u0114\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("\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") buf.write("\t\23\4\24\t\24\4\25\t\25\4\26\t\26\4\27\t\27\4\30\t\30") buf.write("\4\31\t\31\4\32\t\32\4\33\t\33\4\34\t\34\4\35\t\35\4\36") - buf.write("\t\36\4\37\t\37\4 \t \4!\t!\4\"\t\"\4#\t#\4$\t$\3\2\3") - buf.write("\2\3\2\3\2\3\2\3\2\3\2\3\3\3\3\3\4\3\4\3\4\3\4\3\4\3\4") - buf.write("\3\4\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\6\3\6\3") - buf.write("\7\3\7\3\b\3\b\3\b\3\b\3\b\3\t\3\t\3\n\3\n\3\13\3\13\3") - buf.write("\13\3\13\3\13\3\13\3\13\3\f\3\f\3\f\3\f\3\f\3\f\3\f\3") - buf.write("\f\3\f\3\r\3\r\3\16\3\16\3\17\3\17\3\17\3\17\3\17\3\20") - buf.write("\3\20\3\20\3\20\3\21\3\21\3\21\3\21\3\21\3\22\3\22\3\22") - buf.write("\3\22\3\22\3\22\3\22\3\23\3\23\3\23\3\23\3\24\3\24\3\24") - buf.write("\3\24\3\24\3\25\3\25\3\26\3\26\3\27\3\27\3\27\3\27\3\27") - buf.write("\3\27\3\30\3\30\3\30\3\30\3\30\3\30\3\30\3\31\3\31\3\31") - buf.write("\3\31\3\31\3\32\3\32\3\32\3\32\3\32\3\33\3\33\7\33\u00c0") - buf.write("\n\33\f\33\16\33\u00c3\13\33\3\34\5\34\u00c6\n\34\3\34") - buf.write("\6\34\u00c9\n\34\r\34\16\34\u00ca\3\35\3\35\3\35\3\35") - buf.write("\6\35\u00d1\n\35\r\35\16\35\u00d2\3\36\3\36\3\36\7\36") - buf.write("\u00d8\n\36\f\36\16\36\u00db\13\36\3\37\3\37\7\37\u00df") - buf.write("\n\37\f\37\16\37\u00e2\13\37\3 \3 \3 \3 \3!\3!\3!\3!\3") - buf.write("!\7!\u00ed\n!\f!\16!\u00f0\13!\3!\3!\3!\3\"\6\"\u00f6") - buf.write("\n\"\r\"\16\"\u00f7\3\"\3\"\3#\3#\3#\3#\7#\u0100\n#\f") - buf.write("#\16#\u0103\13#\3#\3#\3$\3$\3$\3$\7$\u010b\n$\f$\16$\u010e") - buf.write("\13$\3$\3$\3$\3$\3$\4\u00ee\u010c\2%\3\3\5\4\7\5\t\6\13") - buf.write("\7\r\b\17\t\21\n\23\13\25\f\27\r\31\16\33\17\35\20\37") - buf.write("\21!\22#\23%\24\'\25)\26+\27-\30/\31\61\32\63\33\65\34") - buf.write("\67\359\36;\37= ?!A\"C#E$G%\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\"\"\u011d\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("\t\36\4\37\t\37\4 \t \4!\t!\4\"\t\"\4#\t#\4$\t$\4%\t%") + buf.write("\4&\t&\3\2\3\2\3\2\3\2\3\2\3\2\3\2\3\3\3\3\3\4\3\4\3\4") + buf.write("\3\4\3\4\3\4\3\4\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3") + buf.write("\5\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\7\3\7\3\b\3\b\3\t") + buf.write("\3\t\3\t\3\t\3\t\3\n\3\n\3\13\3\13\3\f\3\f\3\f\3\f\3\f") + buf.write("\3\f\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\16\3\16\3\16\3\16\3") + buf.write("\16\3\16\3\16\3\16\3\16\3\17\3\17\3\20\3\20\3\21\3\21") + buf.write("\3\21\3\21\3\21\3\22\3\22\3\22\3\22\3\23\3\23\3\23\3\23") + buf.write("\3\23\3\24\3\24\3\24\3\24\3\24\3\24\3\24\3\25\3\25\3\25") + buf.write("\3\25\3\26\3\26\3\26\3\26\3\26\3\27\3\27\3\30\3\30\3\31") + buf.write("\3\31\3\31\3\31\3\31\3\31\3\32\3\32\3\32\3\32\3\32\3\32") + buf.write("\3\32\3\33\3\33\3\33\3\33\3\33\3\34\3\34\3\34\3\34\3\34") + buf.write("\3\35\3\35\7\35\u00d2\n\35\f\35\16\35\u00d5\13\35\3\36") + buf.write("\5\36\u00d8\n\36\3\36\6\36\u00db\n\36\r\36\16\36\u00dc") + buf.write("\3\37\3\37\3\37\3\37\6\37\u00e3\n\37\r\37\16\37\u00e4") + buf.write("\3 \3 \3 \7 \u00ea\n \f \16 \u00ed\13 \3!\3!\7!\u00f1") + buf.write("\n!\f!\16!\u00f4\13!\3\"\3\"\3\"\3\"\3#\3#\3#\3#\3#\7") + buf.write("#\u00ff\n#\f#\16#\u0102\13#\3#\3#\3#\3$\6$\u0108\n$\r") + buf.write("$\16$\u0109\3$\3$\3%\3%\3%\3%\7%\u0112\n%\f%\16%\u0115") + buf.write("\13%\3%\3%\3&\3&\3&\3&\7&\u011d\n&\f&\16&\u0120\13&\3") + buf.write("&\3&\3&\3&\3&\4\u0100\u011e\2\'\3\3\5\4\7\5\t\6\13\7\r") + buf.write("\b\17\t\21\n\23\13\25\f\27\r\31\16\33\17\35\20\37\21!") + 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\"\"\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\3I\3\2\2\2\5P\3\2\2\2\7R\3\2\2\2\tY\3") - buf.write("\2\2\2\13c\3\2\2\2\re\3\2\2\2\17g\3\2\2\2\21l\3\2\2\2") - buf.write("\23n\3\2\2\2\25p\3\2\2\2\27w\3\2\2\2\31\u0080\3\2\2\2") - buf.write("\33\u0082\3\2\2\2\35\u0084\3\2\2\2\37\u0089\3\2\2\2!\u008d") - buf.write("\3\2\2\2#\u0092\3\2\2\2%\u0099\3\2\2\2\'\u009d\3\2\2\2") - buf.write(")\u00a2\3\2\2\2+\u00a4\3\2\2\2-\u00a6\3\2\2\2/\u00ac\3") - buf.write("\2\2\2\61\u00b3\3\2\2\2\63\u00b8\3\2\2\2\65\u00bd\3\2") - buf.write("\2\2\67\u00c5\3\2\2\29\u00cc\3\2\2\2;\u00d4\3\2\2\2=\u00dc") - buf.write("\3\2\2\2?\u00e3\3\2\2\2A\u00e7\3\2\2\2C\u00f5\3\2\2\2") - buf.write("E\u00fb\3\2\2\2G\u0106\3\2\2\2IJ\7k\2\2JK\7o\2\2KL\7r") - buf.write("\2\2LM\7q\2\2MN\7t\2\2NO\7v\2\2O\4\3\2\2\2PQ\7=\2\2Q\6") - buf.write("\3\2\2\2RS\7o\2\2ST\7q\2\2TU\7f\2\2UV\7w\2\2VW\7n\2\2") - buf.write("WX\7g\2\2X\b\3\2\2\2YZ\7k\2\2Z[\7p\2\2[\\\7v\2\2\\]\7") - buf.write("g\2\2]^\7t\2\2^_\7h\2\2_`\7c\2\2`a\7e\2\2ab\7g\2\2b\n") - buf.write("\3\2\2\2cd\7}\2\2d\f\3\2\2\2ef\7\177\2\2f\16\3\2\2\2g") - buf.write("h\7x\2\2hi\7q\2\2ij\7k\2\2jk\7f\2\2k\20\3\2\2\2lm\7*\2") - buf.write("\2m\22\3\2\2\2no\7+\2\2o\24\3\2\2\2pq\7u\2\2qr\7k\2\2") - buf.write("rs\7i\2\2st\7p\2\2tu\7c\2\2uv\7n\2\2v\26\3\2\2\2wx\7t") - buf.write("\2\2xy\7g\2\2yz\7c\2\2z{\7f\2\2{|\7q\2\2|}\7p\2\2}~\7") - buf.write("n\2\2~\177\7{\2\2\177\30\3\2\2\2\u0080\u0081\7.\2\2\u0081") - buf.write("\32\3\2\2\2\u0082\u0083\7?\2\2\u0083\34\3\2\2\2\u0084") - buf.write("\u0085\7d\2\2\u0085\u0086\7q\2\2\u0086\u0087\7q\2\2\u0087") - buf.write("\u0088\7n\2\2\u0088\36\3\2\2\2\u0089\u008a\7k\2\2\u008a") - buf.write("\u008b\7p\2\2\u008b\u008c\7v\2\2\u008c \3\2\2\2\u008d") - buf.write("\u008e\7t\2\2\u008e\u008f\7g\2\2\u008f\u0090\7c\2\2\u0090") - buf.write("\u0091\7n\2\2\u0091\"\3\2\2\2\u0092\u0093\7u\2\2\u0093") - buf.write("\u0094\7v\2\2\u0094\u0095\7t\2\2\u0095\u0096\7k\2\2\u0096") - buf.write("\u0097\7p\2\2\u0097\u0098\7i\2\2\u0098$\3\2\2\2\u0099") - buf.write("\u009a\7x\2\2\u009a\u009b\7c\2\2\u009b\u009c\7t\2\2\u009c") - buf.write("&\3\2\2\2\u009d\u009e\7n\2\2\u009e\u009f\7k\2\2\u009f") - buf.write("\u00a0\7u\2\2\u00a0\u00a1\7v\2\2\u00a1(\3\2\2\2\u00a2") - buf.write("\u00a3\7>\2\2\u00a3*\3\2\2\2\u00a4\u00a5\7@\2\2\u00a5") - buf.write(",\3\2\2\2\u00a6\u00a7\7o\2\2\u00a7\u00a8\7q\2\2\u00a8") - buf.write("\u00a9\7f\2\2\u00a9\u00aa\7g\2\2\u00aa\u00ab\7n\2\2\u00ab") - buf.write(".\3\2\2\2\u00ac\u00ad\7u\2\2\u00ad\u00ae\7v\2\2\u00ae") - buf.write("\u00af\7t\2\2\u00af\u00b0\7w\2\2\u00b0\u00b1\7e\2\2\u00b1") - buf.write("\u00b2\7v\2\2\u00b2\60\3\2\2\2\u00b3\u00b4\7g\2\2\u00b4") - buf.write("\u00b5\7p\2\2\u00b5\u00b6\7w\2\2\u00b6\u00b7\7o\2\2\u00b7") - buf.write("\62\3\2\2\2\u00b8\u00b9\7h\2\2\u00b9\u00ba\7n\2\2\u00ba") - buf.write("\u00bb\7c\2\2\u00bb\u00bc\7i\2\2\u00bc\64\3\2\2\2\u00bd") - buf.write("\u00c1\7B\2\2\u00be\u00c0\n\2\2\2\u00bf\u00be\3\2\2\2") - buf.write("\u00c0\u00c3\3\2\2\2\u00c1\u00bf\3\2\2\2\u00c1\u00c2\3") - buf.write("\2\2\2\u00c2\66\3\2\2\2\u00c3\u00c1\3\2\2\2\u00c4\u00c6") - buf.write("\t\3\2\2\u00c5\u00c4\3\2\2\2\u00c5\u00c6\3\2\2\2\u00c6") - buf.write("\u00c8\3\2\2\2\u00c7\u00c9\4\62;\2\u00c8\u00c7\3\2\2\2") - buf.write("\u00c9\u00ca\3\2\2\2\u00ca\u00c8\3\2\2\2\u00ca\u00cb\3") - buf.write("\2\2\2\u00cb8\3\2\2\2\u00cc\u00cd\7\62\2\2\u00cd\u00ce") - buf.write("\7z\2\2\u00ce\u00d0\3\2\2\2\u00cf\u00d1\t\4\2\2\u00d0") - buf.write("\u00cf\3\2\2\2\u00d1\u00d2\3\2\2\2\u00d2\u00d0\3\2\2\2") - buf.write("\u00d2\u00d3\3\2\2\2\u00d3:\3\2\2\2\u00d4\u00d5\7B\2\2") - buf.write("\u00d5\u00d9\t\5\2\2\u00d6\u00d8\t\6\2\2\u00d7\u00d6\3") - buf.write("\2\2\2\u00d8\u00db\3\2\2\2\u00d9\u00d7\3\2\2\2\u00d9\u00da") - buf.write("\3\2\2\2\u00da<\3\2\2\2\u00db\u00d9\3\2\2\2\u00dc\u00e0") - buf.write("\t\5\2\2\u00dd\u00df\t\6\2\2\u00de\u00dd\3\2\2\2\u00df") - buf.write("\u00e2\3\2\2\2\u00e0\u00de\3\2\2\2\u00e0\u00e1\3\2\2\2") - buf.write("\u00e1>\3\2\2\2\u00e2\u00e0\3\2\2\2\u00e3\u00e4\t\7\2") - buf.write("\2\u00e4\u00e5\7\60\2\2\u00e5\u00e6\t\7\2\2\u00e6@\3\2") - buf.write("\2\2\u00e7\u00e8\7\61\2\2\u00e8\u00e9\7,\2\2\u00e9\u00ea") - buf.write("\7,\2\2\u00ea\u00ee\3\2\2\2\u00eb\u00ed\13\2\2\2\u00ec") - buf.write("\u00eb\3\2\2\2\u00ed\u00f0\3\2\2\2\u00ee\u00ef\3\2\2\2") - buf.write("\u00ee\u00ec\3\2\2\2\u00ef\u00f1\3\2\2\2\u00f0\u00ee\3") - buf.write("\2\2\2\u00f1\u00f2\7,\2\2\u00f2\u00f3\7\61\2\2\u00f3B") - buf.write("\3\2\2\2\u00f4\u00f6\t\b\2\2\u00f5\u00f4\3\2\2\2\u00f6") - buf.write("\u00f7\3\2\2\2\u00f7\u00f5\3\2\2\2\u00f7\u00f8\3\2\2\2") - buf.write("\u00f8\u00f9\3\2\2\2\u00f9\u00fa\b\"\2\2\u00faD\3\2\2") - buf.write("\2\u00fb\u00fc\7\61\2\2\u00fc\u00fd\7\61\2\2\u00fd\u0101") - buf.write("\3\2\2\2\u00fe\u0100\n\2\2\2\u00ff\u00fe\3\2\2\2\u0100") - buf.write("\u0103\3\2\2\2\u0101\u00ff\3\2\2\2\u0101\u0102\3\2\2\2") - buf.write("\u0102\u0104\3\2\2\2\u0103\u0101\3\2\2\2\u0104\u0105\b") - buf.write("#\2\2\u0105F\3\2\2\2\u0106\u0107\7\61\2\2\u0107\u0108") - buf.write("\7,\2\2\u0108\u010c\3\2\2\2\u0109\u010b\13\2\2\2\u010a") - buf.write("\u0109\3\2\2\2\u010b\u010e\3\2\2\2\u010c\u010d\3\2\2\2") - buf.write("\u010c\u010a\3\2\2\2\u010d\u010f\3\2\2\2\u010e\u010c\3") - buf.write("\2\2\2\u010f\u0110\7,\2\2\u0110\u0111\7\61\2\2\u0111\u0112") - buf.write("\3\2\2\2\u0112\u0113\b$\2\2\u0113H\3\2\2\2\r\2\u00c1\u00c5") - buf.write("\u00ca\u00d2\u00d9\u00e0\u00ee\u00f7\u0101\u010c\3\b\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") + buf.write("\2\2\2\7V\3\2\2\2\t]\3\2\2\2\13g\3\2\2\2\ro\3\2\2\2\17") + buf.write("q\3\2\2\2\21s\3\2\2\2\23x\3\2\2\2\25z\3\2\2\2\27|\3\2") + buf.write("\2\2\31\u0082\3\2\2\2\33\u0089\3\2\2\2\35\u0092\3\2\2") + buf.write("\2\37\u0094\3\2\2\2!\u0096\3\2\2\2#\u009b\3\2\2\2%\u009f") + buf.write("\3\2\2\2\'\u00a4\3\2\2\2)\u00ab\3\2\2\2+\u00af\3\2\2\2") + buf.write("-\u00b4\3\2\2\2/\u00b6\3\2\2\2\61\u00b8\3\2\2\2\63\u00be") + buf.write("\3\2\2\2\65\u00c5\3\2\2\2\67\u00ca\3\2\2\29\u00cf\3\2") + buf.write("\2\2;\u00d7\3\2\2\2=\u00de\3\2\2\2?\u00e6\3\2\2\2A\u00ee") + buf.write("\3\2\2\2C\u00f5\3\2\2\2E\u00f9\3\2\2\2G\u0107\3\2\2\2") + buf.write("I\u010d\3\2\2\2K\u0118\3\2\2\2MN\7k\2\2NO\7o\2\2OP\7r") + buf.write("\2\2PQ\7q\2\2QR\7t\2\2RS\7v\2\2S\4\3\2\2\2TU\7=\2\2U\6") + buf.write("\3\2\2\2VW\7o\2\2WX\7q\2\2XY\7f\2\2YZ\7w\2\2Z[\7n\2\2") + buf.write("[\\\7g\2\2\\\b\3\2\2\2]^\7k\2\2^_\7p\2\2_`\7v\2\2`a\7") + buf.write("g\2\2ab\7t\2\2bc\7h\2\2cd\7c\2\2de\7e\2\2ef\7g\2\2f\n") + buf.write("\3\2\2\2gh\7g\2\2hi\7z\2\2ij\7v\2\2jk\7g\2\2kl\7p\2\2") + buf.write("lm\7f\2\2mn\7u\2\2n\f\3\2\2\2op\7}\2\2p\16\3\2\2\2qr\7") + buf.write("\177\2\2r\20\3\2\2\2st\7x\2\2tu\7q\2\2uv\7k\2\2vw\7f\2") + buf.write("\2w\22\3\2\2\2xy\7*\2\2y\24\3\2\2\2z{\7+\2\2{\26\3\2\2") + buf.write("\2|}\7e\2\2}~\7q\2\2~\177\7p\2\2\177\u0080\7u\2\2\u0080") + buf.write("\u0081\7v\2\2\u0081\30\3\2\2\2\u0082\u0083\7u\2\2\u0083") + buf.write("\u0084\7k\2\2\u0084\u0085\7i\2\2\u0085\u0086\7p\2\2\u0086") + buf.write("\u0087\7c\2\2\u0087\u0088\7n\2\2\u0088\32\3\2\2\2\u0089") + buf.write("\u008a\7t\2\2\u008a\u008b\7g\2\2\u008b\u008c\7c\2\2\u008c") + buf.write("\u008d\7f\2\2\u008d\u008e\7q\2\2\u008e\u008f\7p\2\2\u008f") + buf.write("\u0090\7n\2\2\u0090\u0091\7{\2\2\u0091\34\3\2\2\2\u0092") + buf.write("\u0093\7.\2\2\u0093\36\3\2\2\2\u0094\u0095\7?\2\2\u0095") + buf.write(" \3\2\2\2\u0096\u0097\7d\2\2\u0097\u0098\7q\2\2\u0098") + buf.write("\u0099\7q\2\2\u0099\u009a\7n\2\2\u009a\"\3\2\2\2\u009b") + buf.write("\u009c\7k\2\2\u009c\u009d\7p\2\2\u009d\u009e\7v\2\2\u009e") + buf.write("$\3\2\2\2\u009f\u00a0\7t\2\2\u00a0\u00a1\7g\2\2\u00a1") + buf.write("\u00a2\7c\2\2\u00a2\u00a3\7n\2\2\u00a3&\3\2\2\2\u00a4") + buf.write("\u00a5\7u\2\2\u00a5\u00a6\7v\2\2\u00a6\u00a7\7t\2\2\u00a7") + buf.write("\u00a8\7k\2\2\u00a8\u00a9\7p\2\2\u00a9\u00aa\7i\2\2\u00aa") + buf.write("(\3\2\2\2\u00ab\u00ac\7x\2\2\u00ac\u00ad\7c\2\2\u00ad") + buf.write("\u00ae\7t\2\2\u00ae*\3\2\2\2\u00af\u00b0\7n\2\2\u00b0") + buf.write("\u00b1\7k\2\2\u00b1\u00b2\7u\2\2\u00b2\u00b3\7v\2\2\u00b3") + buf.write(",\3\2\2\2\u00b4\u00b5\7>\2\2\u00b5.\3\2\2\2\u00b6\u00b7") + buf.write("\7@\2\2\u00b7\60\3\2\2\2\u00b8\u00b9\7o\2\2\u00b9\u00ba") + buf.write("\7q\2\2\u00ba\u00bb\7f\2\2\u00bb\u00bc\7g\2\2\u00bc\u00bd") + buf.write("\7n\2\2\u00bd\62\3\2\2\2\u00be\u00bf\7u\2\2\u00bf\u00c0") + buf.write("\7v\2\2\u00c0\u00c1\7t\2\2\u00c1\u00c2\7w\2\2\u00c2\u00c3") + buf.write("\7e\2\2\u00c3\u00c4\7v\2\2\u00c4\64\3\2\2\2\u00c5\u00c6") + buf.write("\7g\2\2\u00c6\u00c7\7p\2\2\u00c7\u00c8\7w\2\2\u00c8\u00c9") + buf.write("\7o\2\2\u00c9\66\3\2\2\2\u00ca\u00cb\7h\2\2\u00cb\u00cc") + buf.write("\7n\2\2\u00cc\u00cd\7c\2\2\u00cd\u00ce\7i\2\2\u00ce8\3") + buf.write("\2\2\2\u00cf\u00d3\7B\2\2\u00d0\u00d2\n\2\2\2\u00d1\u00d0") + buf.write("\3\2\2\2\u00d2\u00d5\3\2\2\2\u00d3\u00d1\3\2\2\2\u00d3") + buf.write("\u00d4\3\2\2\2\u00d4:\3\2\2\2\u00d5\u00d3\3\2\2\2\u00d6") + buf.write("\u00d8\t\3\2\2\u00d7\u00d6\3\2\2\2\u00d7\u00d8\3\2\2\2") + buf.write("\u00d8\u00da\3\2\2\2\u00d9\u00db\4\62;\2\u00da\u00d9\3") + buf.write("\2\2\2\u00db\u00dc\3\2\2\2\u00dc\u00da\3\2\2\2\u00dc\u00dd") + buf.write("\3\2\2\2\u00dd<\3\2\2\2\u00de\u00df\7\62\2\2\u00df\u00e0") + buf.write("\7z\2\2\u00e0\u00e2\3\2\2\2\u00e1\u00e3\t\4\2\2\u00e2") + buf.write("\u00e1\3\2\2\2\u00e3\u00e4\3\2\2\2\u00e4\u00e2\3\2\2\2") + buf.write("\u00e4\u00e5\3\2\2\2\u00e5>\3\2\2\2\u00e6\u00e7\7B\2\2") + buf.write("\u00e7\u00eb\t\5\2\2\u00e8\u00ea\t\6\2\2\u00e9\u00e8\3") + buf.write("\2\2\2\u00ea\u00ed\3\2\2\2\u00eb\u00e9\3\2\2\2\u00eb\u00ec") + buf.write("\3\2\2\2\u00ec@\3\2\2\2\u00ed\u00eb\3\2\2\2\u00ee\u00f2") + buf.write("\t\5\2\2\u00ef\u00f1\t\6\2\2\u00f0\u00ef\3\2\2\2\u00f1") + buf.write("\u00f4\3\2\2\2\u00f2\u00f0\3\2\2\2\u00f2\u00f3\3\2\2\2") + buf.write("\u00f3B\3\2\2\2\u00f4\u00f2\3\2\2\2\u00f5\u00f6\t\7\2") + buf.write("\2\u00f6\u00f7\7\60\2\2\u00f7\u00f8\t\7\2\2\u00f8D\3\2") + buf.write("\2\2\u00f9\u00fa\7\61\2\2\u00fa\u00fb\7,\2\2\u00fb\u00fc") + buf.write("\7,\2\2\u00fc\u0100\3\2\2\2\u00fd\u00ff\13\2\2\2\u00fe") + buf.write("\u00fd\3\2\2\2\u00ff\u0102\3\2\2\2\u0100\u0101\3\2\2\2") + buf.write("\u0100\u00fe\3\2\2\2\u0101\u0103\3\2\2\2\u0102\u0100\3") + buf.write("\2\2\2\u0103\u0104\7,\2\2\u0104\u0105\7\61\2\2\u0105F") + buf.write("\3\2\2\2\u0106\u0108\t\b\2\2\u0107\u0106\3\2\2\2\u0108") + buf.write("\u0109\3\2\2\2\u0109\u0107\3\2\2\2\u0109\u010a\3\2\2\2") + buf.write("\u010a\u010b\3\2\2\2\u010b\u010c\b$\2\2\u010cH\3\2\2\2") + buf.write("\u010d\u010e\7\61\2\2\u010e\u010f\7\61\2\2\u010f\u0113") + buf.write("\3\2\2\2\u0110\u0112\n\2\2\2\u0111\u0110\3\2\2\2\u0112") + buf.write("\u0115\3\2\2\2\u0113\u0111\3\2\2\2\u0113\u0114\3\2\2\2") + buf.write("\u0114\u0116\3\2\2\2\u0115\u0113\3\2\2\2\u0116\u0117\b") + buf.write("%\2\2\u0117J\3\2\2\2\u0118\u0119\7\61\2\2\u0119\u011a") + buf.write("\7,\2\2\u011a\u011e\3\2\2\2\u011b\u011d\13\2\2\2\u011c") + buf.write("\u011b\3\2\2\2\u011d\u0120\3\2\2\2\u011e\u011f\3\2\2\2") + buf.write("\u011e\u011c\3\2\2\2\u011f\u0121\3\2\2\2\u0120\u011e\3") + buf.write("\2\2\2\u0121\u0122\7,\2\2\u0122\u0123\7\61\2\2\u0123\u0124") + buf.write("\3\2\2\2\u0124\u0125\b&\2\2\u0125L\3\2\2\2\r\2\u00d3\u00d7") + buf.write("\u00dc\u00e4\u00eb\u00f2\u0100\u0109\u0113\u011e\3\b\2") buf.write("\2") return buf.getvalue() @@ -129,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 @@ -155,24 +163,28 @@ class TLexer(Lexer): T__22 = 23 T__23 = 24 T__24 = 25 - TAGLINE = 26 - INTCONSTANT = 27 - HEXCONSTANT = 28 - TAGIDENTIFIER = 29 - IDENTIFIER = 30 - VERSION = 31 - DOCCOMMENT = 32 - WHITESPACE = 33 - COMMENT = 34 - MULTICOMM = 35 + T__25 = 26 + T__26 = 27 + TAGLINE = 28 + INTCONSTANT = 29 + HEXCONSTANT = 30 + TAGIDENTIFIER = 31 + IDENTIFIER = 32 + VERSION = 33 + DOCCOMMENT = 34 + WHITESPACE = 35 + COMMENT = 36 + MULTICOMM = 37 + + channelNames = [ u"DEFAULT_TOKEN_CHANNEL", u"HIDDEN" ] modeNames = [ "DEFAULT_MODE" ] literalNames = [ "<INVALID>", - "'import'", "';'", "'module'", "'interface'", "'{'", "'}'", - "'void'", "'('", "')'", "'signal'", "'readonly'", "','", "'='", - "'bool'", "'int'", "'real'", "'string'", "'var'", "'list'", - "'<'", "'>'", "'model'", "'struct'", "'enum'", "'flag'" ] + "'import'", "';'", "'module'", "'interface'", "'extends'", "'{'", + "'}'", "'void'", "'('", "')'", "'const'", "'signal'", "'readonly'", + "','", "'='", "'bool'", "'int'", "'real'", "'string'", "'var'", + "'list'", "'<'", "'>'", "'model'", "'struct'", "'enum'", "'flag'" ] symbolicNames = [ "<INVALID>", "TAGLINE", "INTCONSTANT", "HEXCONSTANT", "TAGIDENTIFIER", "IDENTIFIER", @@ -181,15 +193,16 @@ class TLexer(Lexer): ruleNames = [ "T__0", "T__1", "T__2", "T__3", "T__4", "T__5", "T__6", "T__7", "T__8", "T__9", "T__10", "T__11", "T__12", "T__13", "T__14", "T__15", "T__16", "T__17", "T__18", "T__19", - "T__20", "T__21", "T__22", "T__23", "T__24", "TAGLINE", - "INTCONSTANT", "HEXCONSTANT", "TAGIDENTIFIER", "IDENTIFIER", - "VERSION", "DOCCOMMENT", "WHITESPACE", "COMMENT", "MULTICOMM" ] + "T__20", "T__21", "T__22", "T__23", "T__24", "T__25", + "T__26", "TAGLINE", "INTCONSTANT", "HEXCONSTANT", "TAGIDENTIFIER", + "IDENTIFIER", "VERSION", "DOCCOMMENT", "WHITESPACE", "COMMENT", + "MULTICOMM" ] 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/TLexer.tokens b/qface/idl/parser/TLexer.tokens index 86bf74a..5f94603 100644 --- a/qface/idl/parser/TLexer.tokens +++ b/qface/idl/parser/TLexer.tokens @@ -23,38 +23,42 @@ T__21=22 T__22=23 T__23=24 T__24=25 -TAGLINE=26 -INTCONSTANT=27 -HEXCONSTANT=28 -TAGIDENTIFIER=29 -IDENTIFIER=30 -VERSION=31 -DOCCOMMENT=32 -WHITESPACE=33 -COMMENT=34 -MULTICOMM=35 +T__25=26 +T__26=27 +TAGLINE=28 +INTCONSTANT=29 +HEXCONSTANT=30 +TAGIDENTIFIER=31 +IDENTIFIER=32 +VERSION=33 +DOCCOMMENT=34 +WHITESPACE=35 +COMMENT=36 +MULTICOMM=37 'import'=1 ';'=2 'module'=3 'interface'=4 -'{'=5 -'}'=6 -'void'=7 -'('=8 -')'=9 -'signal'=10 -'readonly'=11 -','=12 -'='=13 -'bool'=14 -'int'=15 -'real'=16 -'string'=17 -'var'=18 -'list'=19 -'<'=20 -'>'=21 -'model'=22 -'struct'=23 -'enum'=24 -'flag'=25 +'extends'=5 +'{'=6 +'}'=7 +'void'=8 +'('=9 +')'=10 +'const'=11 +'signal'=12 +'readonly'=13 +','=14 +'='=15 +'bool'=16 +'int'=17 +'real'=18 +'string'=19 +'var'=20 +'list'=21 +'<'=22 +'>'=23 +'model'=24 +'struct'=25 +'enum'=26 +'flag'=27 diff --git a/qface/idl/parser/TListener.py b/qface/idl/parser/TListener.py index 07d41ad..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 @@ -80,6 +80,15 @@ class TListener(ParseTreeListener): pass + # Enter a parse tree produced by TParser#operationModifierSymbol. + def enterOperationModifierSymbol(self, ctx:TParser.OperationModifierSymbolContext): + pass + + # Exit a parse tree produced by TParser#operationModifierSymbol. + def exitOperationModifierSymbol(self, ctx:TParser.OperationModifierSymbolContext): + pass + + # Enter a parse tree produced by TParser#signalSymbol. def enterSignalSymbol(self, ctx:TParser.SignalSymbolContext): pass @@ -98,6 +107,15 @@ class TListener(ParseTreeListener): pass + # Enter a parse tree produced by TParser#propertyModifierSymbol. + def enterPropertyModifierSymbol(self, ctx:TParser.PropertyModifierSymbolContext): + pass + + # Exit a parse tree produced by TParser#propertyModifierSymbol. + def exitPropertyModifierSymbol(self, ctx:TParser.PropertyModifierSymbolContext): + pass + + # Enter a parse tree produced by TParser#operationParameterSymbol. def enterOperationParameterSymbol(self, ctx:TParser.OperationParameterSymbolContext): pass diff --git a/qface/idl/parser/TParser.py b/qface/idl/parser/TParser.py index 15eadd6..b180f95 100644 --- a/qface/idl/parser/TParser.py +++ b/qface/idl/parser/TParser.py @@ -1,151 +1,163 @@ -# 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("\u0131\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("\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") buf.write("\4\24\t\24\4\25\t\25\4\26\t\26\4\27\t\27\4\30\t\30\4\31") - buf.write("\t\31\3\2\3\2\7\2\65\n\2\f\2\16\28\13\2\3\3\3\3\7\3<\n") - buf.write("\3\f\3\16\3?\13\3\3\4\3\4\3\4\3\4\5\4E\n\4\3\5\5\5H\n") - buf.write("\5\3\5\7\5K\n\5\f\5\16\5N\13\5\3\5\3\5\3\5\3\5\5\5T\n") - buf.write("\5\3\6\3\6\3\6\5\6Y\n\6\3\7\5\7\\\n\7\3\7\7\7_\n\7\f\7") - buf.write("\16\7b\13\7\3\7\3\7\3\7\3\7\7\7h\n\7\f\7\16\7k\13\7\3") - buf.write("\7\3\7\5\7o\n\7\3\b\3\b\3\b\5\bt\n\b\3\t\5\tw\n\t\3\t") - buf.write("\7\tz\n\t\f\t\16\t}\13\t\3\t\3\t\5\t\u0081\n\t\3\t\3\t") - buf.write("\3\t\7\t\u0086\n\t\f\t\16\t\u0089\13\t\3\t\3\t\5\t\u008d") - buf.write("\n\t\3\n\5\n\u0090\n\n\3\n\7\n\u0093\n\n\f\n\16\n\u0096") - buf.write("\13\n\3\n\3\n\3\n\3\n\7\n\u009c\n\n\f\n\16\n\u009f\13") - buf.write("\n\3\n\3\n\5\n\u00a3\n\n\3\13\5\13\u00a6\n\13\3\13\7\13") - buf.write("\u00a9\n\13\f\13\16\13\u00ac\13\13\3\13\5\13\u00af\n\13") - buf.write("\3\13\3\13\3\13\5\13\u00b4\n\13\3\f\3\f\3\f\5\f\u00b9") - buf.write("\n\f\3\r\3\r\3\16\3\16\3\16\5\16\u00c0\n\16\3\16\5\16") - buf.write("\u00c3\n\16\3\17\3\17\3\17\3\17\5\17\u00c9\n\17\3\20\3") - buf.write("\20\3\21\3\21\3\21\3\21\3\21\5\21\u00d2\n\21\3\22\3\22") - buf.write("\3\22\3\22\3\22\3\23\3\23\3\23\3\23\3\23\3\24\5\24\u00df") - buf.write("\n\24\3\24\7\24\u00e2\n\24\f\24\16\24\u00e5\13\24\3\24") - buf.write("\3\24\3\24\3\24\7\24\u00eb\n\24\f\24\16\24\u00ee\13\24") - buf.write("\3\24\3\24\5\24\u00f2\n\24\3\25\5\25\u00f5\n\25\3\25\7") - buf.write("\25\u00f8\n\25\f\25\16\25\u00fb\13\25\3\25\3\25\3\25\5") - buf.write("\25\u0100\n\25\3\26\5\26\u0103\n\26\3\26\7\26\u0106\n") - buf.write("\26\f\26\16\26\u0109\13\26\3\26\3\26\3\26\3\26\7\26\u010f") - buf.write("\n\26\f\26\16\26\u0112\13\26\3\26\3\26\5\26\u0116\n\26") - buf.write("\3\27\3\27\5\27\u011a\n\27\3\30\5\30\u011d\n\30\3\30\7") - buf.write("\30\u0120\n\30\f\30\16\30\u0123\13\30\3\30\3\30\3\30\5") - buf.write("\30\u0128\n\30\3\30\5\30\u012b\n\30\3\31\3\31\5\31\u012f") - buf.write("\n\31\3\31\2\2\32\2\4\6\b\n\f\16\20\22\24\26\30\32\34") - buf.write("\36 \"$&(*,.\60\2\2\u014e\2\62\3\2\2\2\49\3\2\2\2\6@\3") - buf.write("\2\2\2\bG\3\2\2\2\nX\3\2\2\2\f[\3\2\2\2\16s\3\2\2\2\20") - buf.write("v\3\2\2\2\22\u008f\3\2\2\2\24\u00a5\3\2\2\2\26\u00b5\3") - buf.write("\2\2\2\30\u00ba\3\2\2\2\32\u00bc\3\2\2\2\34\u00c8\3\2") - buf.write("\2\2\36\u00ca\3\2\2\2 \u00d1\3\2\2\2\"\u00d3\3\2\2\2$") - buf.write("\u00d8\3\2\2\2&\u00de\3\2\2\2(\u00f4\3\2\2\2*\u0102\3") - buf.write("\2\2\2,\u0119\3\2\2\2.\u011c\3\2\2\2\60\u012e\3\2\2\2") - buf.write("\62\66\5\4\3\2\63\65\5\n\6\2\64\63\3\2\2\2\658\3\2\2\2") - buf.write("\66\64\3\2\2\2\66\67\3\2\2\2\67\3\3\2\2\28\66\3\2\2\2") - buf.write("9=\5\b\5\2:<\5\6\4\2;:\3\2\2\2<?\3\2\2\2=;\3\2\2\2=>\3") - buf.write("\2\2\2>\5\3\2\2\2?=\3\2\2\2@A\7\3\2\2AB\7 \2\2BD\7!\2") - buf.write("\2CE\7\4\2\2DC\3\2\2\2DE\3\2\2\2E\7\3\2\2\2FH\7\"\2\2") - buf.write("GF\3\2\2\2GH\3\2\2\2HL\3\2\2\2IK\5\30\r\2JI\3\2\2\2KN") - buf.write("\3\2\2\2LJ\3\2\2\2LM\3\2\2\2MO\3\2\2\2NL\3\2\2\2OP\7\5") - buf.write("\2\2PQ\7 \2\2QS\7!\2\2RT\7\4\2\2SR\3\2\2\2ST\3\2\2\2T") - buf.write("\t\3\2\2\2UY\5\f\7\2VY\5&\24\2WY\5*\26\2XU\3\2\2\2XV\3") - buf.write("\2\2\2XW\3\2\2\2Y\13\3\2\2\2Z\\\7\"\2\2[Z\3\2\2\2[\\\3") - buf.write("\2\2\2\\`\3\2\2\2]_\5\30\r\2^]\3\2\2\2_b\3\2\2\2`^\3\2") - buf.write("\2\2`a\3\2\2\2ac\3\2\2\2b`\3\2\2\2cd\7\6\2\2de\7 \2\2") - buf.write("ei\7\7\2\2fh\5\16\b\2gf\3\2\2\2hk\3\2\2\2ig\3\2\2\2ij") - buf.write("\3\2\2\2jl\3\2\2\2ki\3\2\2\2ln\7\b\2\2mo\7\4\2\2nm\3\2") - buf.write("\2\2no\3\2\2\2o\r\3\2\2\2pt\5\20\t\2qt\5\24\13\2rt\5\22") - buf.write("\n\2sp\3\2\2\2sq\3\2\2\2sr\3\2\2\2t\17\3\2\2\2uw\7\"\2") - buf.write("\2vu\3\2\2\2vw\3\2\2\2w{\3\2\2\2xz\5\30\r\2yx\3\2\2\2") - buf.write("z}\3\2\2\2{y\3\2\2\2{|\3\2\2\2|\u0080\3\2\2\2}{\3\2\2") - buf.write("\2~\u0081\5\34\17\2\177\u0081\7\t\2\2\u0080~\3\2\2\2\u0080") - buf.write("\177\3\2\2\2\u0081\u0082\3\2\2\2\u0082\u0083\7 \2\2\u0083") - buf.write("\u0087\7\n\2\2\u0084\u0086\5\26\f\2\u0085\u0084\3\2\2") - buf.write("\2\u0086\u0089\3\2\2\2\u0087\u0085\3\2\2\2\u0087\u0088") - buf.write("\3\2\2\2\u0088\u008a\3\2\2\2\u0089\u0087\3\2\2\2\u008a") - buf.write("\u008c\7\13\2\2\u008b\u008d\7\4\2\2\u008c\u008b\3\2\2") - buf.write("\2\u008c\u008d\3\2\2\2\u008d\21\3\2\2\2\u008e\u0090\7") - buf.write("\"\2\2\u008f\u008e\3\2\2\2\u008f\u0090\3\2\2\2\u0090\u0094") - buf.write("\3\2\2\2\u0091\u0093\5\30\r\2\u0092\u0091\3\2\2\2\u0093") - buf.write("\u0096\3\2\2\2\u0094\u0092\3\2\2\2\u0094\u0095\3\2\2\2") - buf.write("\u0095\u0097\3\2\2\2\u0096\u0094\3\2\2\2\u0097\u0098\7") - buf.write("\f\2\2\u0098\u0099\7 \2\2\u0099\u009d\7\n\2\2\u009a\u009c") - buf.write("\5\26\f\2\u009b\u009a\3\2\2\2\u009c\u009f\3\2\2\2\u009d") - buf.write("\u009b\3\2\2\2\u009d\u009e\3\2\2\2\u009e\u00a0\3\2\2\2") - buf.write("\u009f\u009d\3\2\2\2\u00a0\u00a2\7\13\2\2\u00a1\u00a3") - buf.write("\7\4\2\2\u00a2\u00a1\3\2\2\2\u00a2\u00a3\3\2\2\2\u00a3") - buf.write("\23\3\2\2\2\u00a4\u00a6\7\"\2\2\u00a5\u00a4\3\2\2\2\u00a5") - buf.write("\u00a6\3\2\2\2\u00a6\u00aa\3\2\2\2\u00a7\u00a9\5\30\r") - buf.write("\2\u00a8\u00a7\3\2\2\2\u00a9\u00ac\3\2\2\2\u00aa\u00a8") - buf.write("\3\2\2\2\u00aa\u00ab\3\2\2\2\u00ab\u00ae\3\2\2\2\u00ac") - buf.write("\u00aa\3\2\2\2\u00ad\u00af\7\r\2\2\u00ae\u00ad\3\2\2\2") - buf.write("\u00ae\u00af\3\2\2\2\u00af\u00b0\3\2\2\2\u00b0\u00b1\5") - buf.write("\34\17\2\u00b1\u00b3\7 \2\2\u00b2\u00b4\7\4\2\2\u00b3") - buf.write("\u00b2\3\2\2\2\u00b3\u00b4\3\2\2\2\u00b4\25\3\2\2\2\u00b5") - buf.write("\u00b6\5\34\17\2\u00b6\u00b8\7 \2\2\u00b7\u00b9\7\16\2") - buf.write("\2\u00b8\u00b7\3\2\2\2\u00b8\u00b9\3\2\2\2\u00b9\27\3") - buf.write("\2\2\2\u00ba\u00bb\7\34\2\2\u00bb\31\3\2\2\2\u00bc\u00bf") - buf.write("\7 \2\2\u00bd\u00be\7\17\2\2\u00be\u00c0\7 \2\2\u00bf") - buf.write("\u00bd\3\2\2\2\u00bf\u00c0\3\2\2\2\u00c0\u00c2\3\2\2\2") - buf.write("\u00c1\u00c3\7\16\2\2\u00c2\u00c1\3\2\2\2\u00c2\u00c3") - buf.write("\3\2\2\2\u00c3\33\3\2\2\2\u00c4\u00c9\5 \21\2\u00c5\u00c9") - buf.write("\5\36\20\2\u00c6\u00c9\5\"\22\2\u00c7\u00c9\5$\23\2\u00c8") - buf.write("\u00c4\3\2\2\2\u00c8\u00c5\3\2\2\2\u00c8\u00c6\3\2\2\2") - buf.write("\u00c8\u00c7\3\2\2\2\u00c9\35\3\2\2\2\u00ca\u00cb\7 \2") - buf.write("\2\u00cb\37\3\2\2\2\u00cc\u00d2\7\20\2\2\u00cd\u00d2\7") - buf.write("\21\2\2\u00ce\u00d2\7\22\2\2\u00cf\u00d2\7\23\2\2\u00d0") - buf.write("\u00d2\7\24\2\2\u00d1\u00cc\3\2\2\2\u00d1\u00cd\3\2\2") - buf.write("\2\u00d1\u00ce\3\2\2\2\u00d1\u00cf\3\2\2\2\u00d1\u00d0") - buf.write("\3\2\2\2\u00d2!\3\2\2\2\u00d3\u00d4\7\25\2\2\u00d4\u00d5") - buf.write("\7\26\2\2\u00d5\u00d6\5\34\17\2\u00d6\u00d7\7\27\2\2\u00d7") - buf.write("#\3\2\2\2\u00d8\u00d9\7\30\2\2\u00d9\u00da\7\26\2\2\u00da") - buf.write("\u00db\5\34\17\2\u00db\u00dc\7\27\2\2\u00dc%\3\2\2\2\u00dd") - buf.write("\u00df\7\"\2\2\u00de\u00dd\3\2\2\2\u00de\u00df\3\2\2\2") - buf.write("\u00df\u00e3\3\2\2\2\u00e0\u00e2\5\30\r\2\u00e1\u00e0") - buf.write("\3\2\2\2\u00e2\u00e5\3\2\2\2\u00e3\u00e1\3\2\2\2\u00e3") - buf.write("\u00e4\3\2\2\2\u00e4\u00e6\3\2\2\2\u00e5\u00e3\3\2\2\2") - buf.write("\u00e6\u00e7\7\31\2\2\u00e7\u00e8\7 \2\2\u00e8\u00ec\7") - buf.write("\7\2\2\u00e9\u00eb\5(\25\2\u00ea\u00e9\3\2\2\2\u00eb\u00ee") - buf.write("\3\2\2\2\u00ec\u00ea\3\2\2\2\u00ec\u00ed\3\2\2\2\u00ed") - buf.write("\u00ef\3\2\2\2\u00ee\u00ec\3\2\2\2\u00ef\u00f1\7\b\2\2") - buf.write("\u00f0\u00f2\7\4\2\2\u00f1\u00f0\3\2\2\2\u00f1\u00f2\3") - buf.write("\2\2\2\u00f2\'\3\2\2\2\u00f3\u00f5\7\"\2\2\u00f4\u00f3") - buf.write("\3\2\2\2\u00f4\u00f5\3\2\2\2\u00f5\u00f9\3\2\2\2\u00f6") - buf.write("\u00f8\5\30\r\2\u00f7\u00f6\3\2\2\2\u00f8\u00fb\3\2\2") - buf.write("\2\u00f9\u00f7\3\2\2\2\u00f9\u00fa\3\2\2\2\u00fa\u00fc") - buf.write("\3\2\2\2\u00fb\u00f9\3\2\2\2\u00fc\u00fd\5\34\17\2\u00fd") - buf.write("\u00ff\7 \2\2\u00fe\u0100\7\4\2\2\u00ff\u00fe\3\2\2\2") - buf.write("\u00ff\u0100\3\2\2\2\u0100)\3\2\2\2\u0101\u0103\7\"\2") - buf.write("\2\u0102\u0101\3\2\2\2\u0102\u0103\3\2\2\2\u0103\u0107") - buf.write("\3\2\2\2\u0104\u0106\5\30\r\2\u0105\u0104\3\2\2\2\u0106") - buf.write("\u0109\3\2\2\2\u0107\u0105\3\2\2\2\u0107\u0108\3\2\2\2") - buf.write("\u0108\u010a\3\2\2\2\u0109\u0107\3\2\2\2\u010a\u010b\5") - buf.write(",\27\2\u010b\u010c\7 \2\2\u010c\u0110\7\7\2\2\u010d\u010f") - buf.write("\5.\30\2\u010e\u010d\3\2\2\2\u010f\u0112\3\2\2\2\u0110") - buf.write("\u010e\3\2\2\2\u0110\u0111\3\2\2\2\u0111\u0113\3\2\2\2") - buf.write("\u0112\u0110\3\2\2\2\u0113\u0115\7\b\2\2\u0114\u0116\7") - buf.write("\4\2\2\u0115\u0114\3\2\2\2\u0115\u0116\3\2\2\2\u0116+") - buf.write("\3\2\2\2\u0117\u011a\7\32\2\2\u0118\u011a\7\33\2\2\u0119") - buf.write("\u0117\3\2\2\2\u0119\u0118\3\2\2\2\u011a-\3\2\2\2\u011b") - buf.write("\u011d\7\"\2\2\u011c\u011b\3\2\2\2\u011c\u011d\3\2\2\2") - buf.write("\u011d\u0121\3\2\2\2\u011e\u0120\5\30\r\2\u011f\u011e") - buf.write("\3\2\2\2\u0120\u0123\3\2\2\2\u0121\u011f\3\2\2\2\u0121") - buf.write("\u0122\3\2\2\2\u0122\u0124\3\2\2\2\u0123\u0121\3\2\2\2") - buf.write("\u0124\u0127\7 \2\2\u0125\u0126\7\17\2\2\u0126\u0128\5") - buf.write("\60\31\2\u0127\u0125\3\2\2\2\u0127\u0128\3\2\2\2\u0128") - buf.write("\u012a\3\2\2\2\u0129\u012b\7\16\2\2\u012a\u0129\3\2\2") - buf.write("\2\u012a\u012b\3\2\2\2\u012b/\3\2\2\2\u012c\u012f\7\35") - buf.write("\2\2\u012d\u012f\7\36\2\2\u012e\u012c\3\2\2\2\u012e\u012d") - buf.write("\3\2\2\2\u012f\61\3\2\2\2\61\66=DGLSX[`insv{\u0080\u0087") - buf.write("\u008c\u008f\u0094\u009d\u00a2\u00a5\u00aa\u00ae\u00b3") - buf.write("\u00b8\u00bf\u00c2\u00c8\u00d1\u00de\u00e3\u00ec\u00f1") - buf.write("\u00f4\u00f9\u00ff\u0102\u0107\u0110\u0115\u0119\u011c") - buf.write("\u0121\u0127\u012a\u012e") + buf.write("\t\31\4\32\t\32\4\33\t\33\3\2\3\2\7\29\n\2\f\2\16\2<\13") + buf.write("\2\3\3\3\3\7\3@\n\3\f\3\16\3C\13\3\3\4\3\4\3\4\3\4\5\4") + buf.write("I\n\4\3\5\5\5L\n\5\3\5\7\5O\n\5\f\5\16\5R\13\5\3\5\3\5") + buf.write("\3\5\3\5\5\5X\n\5\3\6\3\6\3\6\5\6]\n\6\3\7\5\7`\n\7\3") + buf.write("\7\7\7c\n\7\f\7\16\7f\13\7\3\7\3\7\3\7\3\7\5\7l\n\7\3") + buf.write("\7\3\7\7\7p\n\7\f\7\16\7s\13\7\3\7\3\7\5\7w\n\7\3\b\3") + buf.write("\b\3\b\5\b|\n\b\3\t\5\t\177\n\t\3\t\7\t\u0082\n\t\f\t") + buf.write("\16\t\u0085\13\t\3\t\3\t\5\t\u0089\n\t\3\t\3\t\3\t\7\t") + buf.write("\u008e\n\t\f\t\16\t\u0091\13\t\3\t\3\t\5\t\u0095\n\t\3") + buf.write("\t\5\t\u0098\n\t\3\n\3\n\3\13\5\13\u009d\n\13\3\13\7\13") + buf.write("\u00a0\n\13\f\13\16\13\u00a3\13\13\3\13\3\13\3\13\3\13") + buf.write("\7\13\u00a9\n\13\f\13\16\13\u00ac\13\13\3\13\3\13\5\13") + buf.write("\u00b0\n\13\3\f\5\f\u00b3\n\f\3\f\7\f\u00b6\n\f\f\f\16") + buf.write("\f\u00b9\13\f\3\f\5\f\u00bc\n\f\3\f\3\f\3\f\5\f\u00c1") + buf.write("\n\f\3\r\3\r\5\r\u00c5\n\r\3\16\3\16\3\16\5\16\u00ca\n") + buf.write("\16\3\17\3\17\3\20\3\20\3\20\5\20\u00d1\n\20\3\20\5\20") + buf.write("\u00d4\n\20\3\21\3\21\3\21\3\21\5\21\u00da\n\21\3\22\3") + buf.write("\22\3\23\3\23\3\23\3\23\3\23\5\23\u00e3\n\23\3\24\3\24") + buf.write("\3\24\3\24\3\24\3\25\3\25\3\25\3\25\3\25\3\26\5\26\u00f0") + buf.write("\n\26\3\26\7\26\u00f3\n\26\f\26\16\26\u00f6\13\26\3\26") + buf.write("\3\26\3\26\3\26\7\26\u00fc\n\26\f\26\16\26\u00ff\13\26") + buf.write("\3\26\3\26\5\26\u0103\n\26\3\27\5\27\u0106\n\27\3\27\7") + buf.write("\27\u0109\n\27\f\27\16\27\u010c\13\27\3\27\3\27\3\27\5") + buf.write("\27\u0111\n\27\3\30\5\30\u0114\n\30\3\30\7\30\u0117\n") + buf.write("\30\f\30\16\30\u011a\13\30\3\30\3\30\3\30\3\30\7\30\u0120") + buf.write("\n\30\f\30\16\30\u0123\13\30\3\30\3\30\5\30\u0127\n\30") + buf.write("\3\31\3\31\5\31\u012b\n\31\3\32\5\32\u012e\n\32\3\32\7") + 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\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() @@ -160,10 +172,10 @@ class TParser ( Parser ): sharedContextCache = PredictionContextCache() literalNames = [ "<INVALID>", "'import'", "';'", "'module'", "'interface'", - "'{'", "'}'", "'void'", "'('", "')'", "'signal'", "'readonly'", - "','", "'='", "'bool'", "'int'", "'real'", "'string'", - "'var'", "'list'", "'<'", "'>'", "'model'", "'struct'", - "'enum'", "'flag'" ] + "'extends'", "'{'", "'}'", "'void'", "'('", "')'", + "'const'", "'signal'", "'readonly'", "','", "'='", + "'bool'", "'int'", "'real'", "'string'", "'var'", "'list'", + "'<'", "'>'", "'model'", "'struct'", "'enum'", "'flag'" ] symbolicNames = [ "<INVALID>", "<INVALID>", "<INVALID>", "<INVALID>", "<INVALID>", "<INVALID>", "<INVALID>", "<INVALID>", @@ -171,9 +183,10 @@ class TParser ( Parser ): "<INVALID>", "<INVALID>", "<INVALID>", "<INVALID>", "<INVALID>", "<INVALID>", "<INVALID>", "<INVALID>", "<INVALID>", "<INVALID>", "<INVALID>", "<INVALID>", - "<INVALID>", "<INVALID>", "TAGLINE", "INTCONSTANT", - "HEXCONSTANT", "TAGIDENTIFIER", "IDENTIFIER", "VERSION", - "DOCCOMMENT", "WHITESPACE", "COMMENT", "MULTICOMM" ] + "<INVALID>", "<INVALID>", "<INVALID>", "<INVALID>", + "TAGLINE", "INTCONSTANT", "HEXCONSTANT", "TAGIDENTIFIER", + "IDENTIFIER", "VERSION", "DOCCOMMENT", "WHITESPACE", + "COMMENT", "MULTICOMM" ] RULE_documentSymbol = 0 RULE_headerSymbol = 1 @@ -183,30 +196,32 @@ class TParser ( Parser ): RULE_interfaceSymbol = 5 RULE_interfaceMemberSymbol = 6 RULE_operationSymbol = 7 - RULE_signalSymbol = 8 - RULE_propertySymbol = 9 - RULE_operationParameterSymbol = 10 - RULE_tagSymbol = 11 - RULE_tagAttributeSymbol = 12 - RULE_typeSymbol = 13 - RULE_complexTypeSymbol = 14 - RULE_primitiveTypeSymbol = 15 - RULE_listTypeSymbol = 16 - RULE_modelTypeSymbol = 17 - RULE_structSymbol = 18 - RULE_structFieldSymbol = 19 - RULE_enumSymbol = 20 - RULE_enumTypeSymbol = 21 - RULE_enumMemberSymbol = 22 - RULE_intSymbol = 23 + RULE_operationModifierSymbol = 8 + RULE_signalSymbol = 9 + RULE_propertySymbol = 10 + RULE_propertyModifierSymbol = 11 + RULE_operationParameterSymbol = 12 + RULE_tagSymbol = 13 + RULE_tagAttributeSymbol = 14 + RULE_typeSymbol = 15 + RULE_complexTypeSymbol = 16 + RULE_primitiveTypeSymbol = 17 + RULE_listTypeSymbol = 18 + RULE_modelTypeSymbol = 19 + RULE_structSymbol = 20 + RULE_structFieldSymbol = 21 + RULE_enumSymbol = 22 + RULE_enumTypeSymbol = 23 + RULE_enumMemberSymbol = 24 + RULE_intSymbol = 25 ruleNames = [ "documentSymbol", "headerSymbol", "importSymbol", "moduleSymbol", "definitionSymbol", "interfaceSymbol", "interfaceMemberSymbol", - "operationSymbol", "signalSymbol", "propertySymbol", - "operationParameterSymbol", "tagSymbol", "tagAttributeSymbol", - "typeSymbol", "complexTypeSymbol", "primitiveTypeSymbol", - "listTypeSymbol", "modelTypeSymbol", "structSymbol", - "structFieldSymbol", "enumSymbol", "enumTypeSymbol", + "operationSymbol", "operationModifierSymbol", "signalSymbol", + "propertySymbol", "propertyModifierSymbol", "operationParameterSymbol", + "tagSymbol", "tagAttributeSymbol", "typeSymbol", "complexTypeSymbol", + "primitiveTypeSymbol", "listTypeSymbol", "modelTypeSymbol", + "structSymbol", "structFieldSymbol", "enumSymbol", "enumTypeSymbol", "enumMemberSymbol", "intSymbol" ] EOF = Token.EOF @@ -235,20 +250,22 @@ class TParser ( Parser ): T__22=23 T__23=24 T__24=25 - TAGLINE=26 - INTCONSTANT=27 - HEXCONSTANT=28 - TAGIDENTIFIER=29 - IDENTIFIER=30 - VERSION=31 - DOCCOMMENT=32 - WHITESPACE=33 - COMMENT=34 - MULTICOMM=35 - - def __init__(self, input:TokenStream): - super().__init__(input) - self.checkVersion("4.6") + T__25=26 + T__26=27 + TAGLINE=28 + INTCONSTANT=29 + HEXCONSTANT=30 + TAGIDENTIFIER=31 + IDENTIFIER=32 + VERSION=33 + DOCCOMMENT=34 + WHITESPACE=35 + COMMENT=36 + MULTICOMM=37 + + 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 @@ -298,15 +315,15 @@ class TParser ( Parser ): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 48 - self.headerSymbol() self.state = 52 + self.headerSymbol() + self.state = 56 self._errHandler.sync(self) _la = self._input.LA(1) - while (((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << TParser.T__3) | (1 << TParser.T__22) | (1 << TParser.T__23) | (1 << TParser.T__24) | (1 << TParser.TAGLINE) | (1 << TParser.DOCCOMMENT))) != 0): - self.state = 49 + while (((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << TParser.T__3) | (1 << TParser.T__24) | (1 << TParser.T__25) | (1 << TParser.T__26) | (1 << TParser.TAGLINE) | (1 << TParser.DOCCOMMENT))) != 0): + self.state = 53 self.definitionSymbol() - self.state = 54 + self.state = 58 self._errHandler.sync(self) _la = self._input.LA(1) @@ -362,15 +379,15 @@ class TParser ( Parser ): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 55 - self.moduleSymbol() self.state = 59 + self.moduleSymbol() + self.state = 63 self._errHandler.sync(self) _la = self._input.LA(1) while _la==TParser.T__0: - self.state = 56 + self.state = 60 self.importSymbol() - self.state = 61 + self.state = 65 self._errHandler.sync(self) _la = self._input.LA(1) @@ -423,17 +440,17 @@ class TParser ( Parser ): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 62 + self.state = 66 self.match(TParser.T__0) - self.state = 63 + self.state = 67 localctx.name = self.match(TParser.IDENTIFIER) - self.state = 64 + self.state = 68 localctx.version = self.match(TParser.VERSION) - self.state = 66 + self.state = 70 self._errHandler.sync(self) _la = self._input.LA(1) if _la==TParser.T__1: - self.state = 65 + self.state = 69 self.match(TParser.T__1) @@ -497,35 +514,35 @@ class TParser ( Parser ): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 69 + self.state = 73 self._errHandler.sync(self) _la = self._input.LA(1) if _la==TParser.DOCCOMMENT: - self.state = 68 + self.state = 72 localctx.comment = self.match(TParser.DOCCOMMENT) - self.state = 74 + self.state = 78 self._errHandler.sync(self) _la = self._input.LA(1) while _la==TParser.TAGLINE: - self.state = 71 + self.state = 75 self.tagSymbol() - self.state = 76 + self.state = 80 self._errHandler.sync(self) _la = self._input.LA(1) - self.state = 77 + self.state = 81 self.match(TParser.T__2) - self.state = 78 + self.state = 82 localctx.name = self.match(TParser.IDENTIFIER) - self.state = 79 + self.state = 83 localctx.version = self.match(TParser.VERSION) - self.state = 81 + self.state = 85 self._errHandler.sync(self) _la = self._input.LA(1) if _la==TParser.T__1: - self.state = 80 + self.state = 84 self.match(TParser.T__1) @@ -580,24 +597,24 @@ class TParser ( Parser ): localctx = TParser.DefinitionSymbolContext(self, self._ctx, self.state) self.enterRule(localctx, 8, self.RULE_definitionSymbol) try: - self.state = 86 + self.state = 90 self._errHandler.sync(self) la_ = self._interp.adaptivePredict(self._input,6,self._ctx) if la_ == 1: self.enterOuterAlt(localctx, 1) - self.state = 83 + self.state = 87 self.interfaceSymbol() pass elif la_ == 2: self.enterOuterAlt(localctx, 2) - self.state = 84 + self.state = 88 self.structSymbol() pass elif la_ == 3: self.enterOuterAlt(localctx, 3) - self.state = 85 + self.state = 89 self.enumSymbol() pass @@ -617,9 +634,13 @@ class TParser ( Parser ): self.parser = parser self.comment = None # Token self.name = None # Token + self.extends = None # Token - def IDENTIFIER(self): - return self.getToken(TParser.IDENTIFIER, 0) + def IDENTIFIER(self, i:int=None): + if i is None: + return self.getTokens(TParser.IDENTIFIER) + else: + return self.getToken(TParser.IDENTIFIER, i) def tagSymbol(self, i:int=None): if i is None: @@ -665,47 +686,57 @@ class TParser ( Parser ): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 89 + self.state = 93 self._errHandler.sync(self) _la = self._input.LA(1) if _la==TParser.DOCCOMMENT: - self.state = 88 + self.state = 92 localctx.comment = self.match(TParser.DOCCOMMENT) - self.state = 94 + self.state = 98 self._errHandler.sync(self) _la = self._input.LA(1) while _la==TParser.TAGLINE: - self.state = 91 + self.state = 95 self.tagSymbol() - self.state = 96 + self.state = 100 self._errHandler.sync(self) _la = self._input.LA(1) - self.state = 97 + self.state = 101 self.match(TParser.T__3) - self.state = 98 + self.state = 102 localctx.name = self.match(TParser.IDENTIFIER) - self.state = 99 - self.match(TParser.T__4) - self.state = 103 + self.state = 105 self._errHandler.sync(self) _la = self._input.LA(1) - while (((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << TParser.T__6) | (1 << TParser.T__9) | (1 << TParser.T__10) | (1 << TParser.T__13) | (1 << TParser.T__14) | (1 << TParser.T__15) | (1 << TParser.T__16) | (1 << TParser.T__17) | (1 << TParser.T__18) | (1 << TParser.T__21) | (1 << TParser.TAGLINE) | (1 << TParser.IDENTIFIER) | (1 << TParser.DOCCOMMENT))) != 0): - self.state = 100 + if _la==TParser.T__4: + self.state = 103 + self.match(TParser.T__4) + self.state = 104 + localctx.extends = self.match(TParser.IDENTIFIER) + + + self.state = 107 + self.match(TParser.T__5) + self.state = 111 + self._errHandler.sync(self) + _la = self._input.LA(1) + while (((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << TParser.T__7) | (1 << TParser.T__10) | (1 << TParser.T__11) | (1 << TParser.T__12) | (1 << TParser.T__15) | (1 << TParser.T__16) | (1 << TParser.T__17) | (1 << TParser.T__18) | (1 << TParser.T__19) | (1 << TParser.T__20) | (1 << TParser.T__23) | (1 << TParser.TAGLINE) | (1 << TParser.IDENTIFIER) | (1 << TParser.DOCCOMMENT))) != 0): + self.state = 108 self.interfaceMemberSymbol() - self.state = 105 + self.state = 113 self._errHandler.sync(self) _la = self._input.LA(1) - self.state = 106 - self.match(TParser.T__5) - self.state = 108 + self.state = 114 + self.match(TParser.T__6) + self.state = 116 self._errHandler.sync(self) _la = self._input.LA(1) if _la==TParser.T__1: - self.state = 107 + self.state = 115 self.match(TParser.T__1) @@ -760,24 +791,24 @@ class TParser ( Parser ): localctx = TParser.InterfaceMemberSymbolContext(self, self._ctx, self.state) self.enterRule(localctx, 12, self.RULE_interfaceMemberSymbol) try: - self.state = 113 + self.state = 121 self._errHandler.sync(self) - la_ = self._interp.adaptivePredict(self._input,11,self._ctx) + la_ = self._interp.adaptivePredict(self._input,12,self._ctx) if la_ == 1: self.enterOuterAlt(localctx, 1) - self.state = 110 + self.state = 118 self.operationSymbol() pass elif la_ == 2: self.enterOuterAlt(localctx, 2) - self.state = 111 + self.state = 119 self.propertySymbol() pass elif la_ == 3: self.enterOuterAlt(localctx, 3) - self.state = 112 + self.state = 120 self.signalSymbol() pass @@ -819,6 +850,10 @@ class TParser ( Parser ): return self.getTypedRuleContext(TParser.OperationParameterSymbolContext,i) + def operationModifierSymbol(self): + return self.getTypedRuleContext(TParser.OperationModifierSymbolContext,0) + + def DOCCOMMENT(self): return self.getToken(TParser.DOCCOMMENT, 0) @@ -849,59 +884,67 @@ class TParser ( Parser ): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 116 + self.state = 124 self._errHandler.sync(self) _la = self._input.LA(1) if _la==TParser.DOCCOMMENT: - self.state = 115 + self.state = 123 localctx.comment = self.match(TParser.DOCCOMMENT) - self.state = 121 + self.state = 129 self._errHandler.sync(self) _la = self._input.LA(1) while _la==TParser.TAGLINE: - self.state = 118 + self.state = 126 self.tagSymbol() - self.state = 123 + self.state = 131 self._errHandler.sync(self) _la = self._input.LA(1) - self.state = 126 + self.state = 134 self._errHandler.sync(self) token = self._input.LA(1) - if token in [TParser.T__13, TParser.T__14, TParser.T__15, TParser.T__16, TParser.T__17, TParser.T__18, TParser.T__21, TParser.IDENTIFIER]: - self.state = 124 + if token in [TParser.T__15, TParser.T__16, TParser.T__17, TParser.T__18, TParser.T__19, TParser.T__20, TParser.T__23, TParser.IDENTIFIER]: + self.state = 132 self.typeSymbol() pass - elif token in [TParser.T__6]: - self.state = 125 - self.match(TParser.T__6) + elif token in [TParser.T__7]: + self.state = 133 + self.match(TParser.T__7) pass else: raise NoViableAltException(self) - self.state = 128 + self.state = 136 localctx.name = self.match(TParser.IDENTIFIER) - self.state = 129 - self.match(TParser.T__7) - self.state = 133 + self.state = 137 + self.match(TParser.T__8) + self.state = 141 self._errHandler.sync(self) _la = self._input.LA(1) - while (((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << TParser.T__13) | (1 << TParser.T__14) | (1 << TParser.T__15) | (1 << TParser.T__16) | (1 << TParser.T__17) | (1 << TParser.T__18) | (1 << TParser.T__21) | (1 << TParser.IDENTIFIER))) != 0): - self.state = 130 + while (((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << TParser.T__15) | (1 << TParser.T__16) | (1 << TParser.T__17) | (1 << TParser.T__18) | (1 << TParser.T__19) | (1 << TParser.T__20) | (1 << TParser.T__23) | (1 << TParser.IDENTIFIER))) != 0): + self.state = 138 self.operationParameterSymbol() - self.state = 135 + self.state = 143 self._errHandler.sync(self) _la = self._input.LA(1) - self.state = 136 - self.match(TParser.T__8) - self.state = 138 + self.state = 144 + self.match(TParser.T__9) + self.state = 146 + self._errHandler.sync(self) + la_ = self._interp.adaptivePredict(self._input,17,self._ctx) + if la_ == 1: + self.state = 145 + self.operationModifierSymbol() + + + self.state = 149 self._errHandler.sync(self) _la = self._input.LA(1) if _la==TParser.T__1: - self.state = 137 + self.state = 148 self.match(TParser.T__1) @@ -913,6 +956,50 @@ class TParser ( Parser ): self.exitRule() return localctx + class OperationModifierSymbolContext(ParserRuleContext): + + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) + self.parser = parser + self.is_const = None # Token + + + def getRuleIndex(self): + return TParser.RULE_operationModifierSymbol + + def enterRule(self, listener:ParseTreeListener): + if hasattr( listener, "enterOperationModifierSymbol" ): + listener.enterOperationModifierSymbol(self) + + def exitRule(self, listener:ParseTreeListener): + if hasattr( listener, "exitOperationModifierSymbol" ): + listener.exitOperationModifierSymbol(self) + + def accept(self, visitor:ParseTreeVisitor): + if hasattr( visitor, "visitOperationModifierSymbol" ): + return visitor.visitOperationModifierSymbol(self) + else: + return visitor.visitChildren(self) + + + + + def operationModifierSymbol(self): + + localctx = TParser.OperationModifierSymbolContext(self, self._ctx, self.state) + self.enterRule(localctx, 16, self.RULE_operationModifierSymbol) + try: + self.enterOuterAlt(localctx, 1) + self.state = 151 + localctx.is_const = self.match(TParser.T__10) + except RecognitionException as re: + localctx.exception = re + self._errHandler.reportError(self, re) + self._errHandler.recover(self, re) + finally: + self.exitRule() + return localctx + class SignalSymbolContext(ParserRuleContext): def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): @@ -964,51 +1051,51 @@ class TParser ( Parser ): def signalSymbol(self): localctx = TParser.SignalSymbolContext(self, self._ctx, self.state) - self.enterRule(localctx, 16, self.RULE_signalSymbol) + self.enterRule(localctx, 18, self.RULE_signalSymbol) self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 141 + self.state = 154 self._errHandler.sync(self) _la = self._input.LA(1) if _la==TParser.DOCCOMMENT: - self.state = 140 + self.state = 153 localctx.comment = self.match(TParser.DOCCOMMENT) - self.state = 146 + self.state = 159 self._errHandler.sync(self) _la = self._input.LA(1) while _la==TParser.TAGLINE: - self.state = 143 + self.state = 156 self.tagSymbol() - self.state = 148 + self.state = 161 self._errHandler.sync(self) _la = self._input.LA(1) - self.state = 149 - self.match(TParser.T__9) - self.state = 150 + self.state = 162 + self.match(TParser.T__11) + self.state = 163 localctx.name = self.match(TParser.IDENTIFIER) - self.state = 151 - self.match(TParser.T__7) - self.state = 155 + self.state = 164 + self.match(TParser.T__8) + self.state = 168 self._errHandler.sync(self) _la = self._input.LA(1) - while (((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << TParser.T__13) | (1 << TParser.T__14) | (1 << TParser.T__15) | (1 << TParser.T__16) | (1 << TParser.T__17) | (1 << TParser.T__18) | (1 << TParser.T__21) | (1 << TParser.IDENTIFIER))) != 0): - self.state = 152 + while (((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << TParser.T__15) | (1 << TParser.T__16) | (1 << TParser.T__17) | (1 << TParser.T__18) | (1 << TParser.T__19) | (1 << TParser.T__20) | (1 << TParser.T__23) | (1 << TParser.IDENTIFIER))) != 0): + self.state = 165 self.operationParameterSymbol() - self.state = 157 + self.state = 170 self._errHandler.sync(self) _la = self._input.LA(1) - self.state = 158 - self.match(TParser.T__8) - self.state = 160 + self.state = 171 + self.match(TParser.T__9) + self.state = 173 self._errHandler.sync(self) _la = self._input.LA(1) if _la==TParser.T__1: - self.state = 159 + self.state = 172 self.match(TParser.T__1) @@ -1026,7 +1113,6 @@ class TParser ( Parser ): super().__init__(parent, invokingState) self.parser = parser self.comment = None # Token - self.isReadOnly = None # Token self.name = None # Token def typeSymbol(self): @@ -1043,6 +1129,10 @@ class TParser ( Parser ): return self.getTypedRuleContext(TParser.TagSymbolContext,i) + def propertyModifierSymbol(self): + return self.getTypedRuleContext(TParser.PropertyModifierSymbolContext,0) + + def DOCCOMMENT(self): return self.getToken(TParser.DOCCOMMENT, 0) @@ -1069,45 +1159,45 @@ class TParser ( Parser ): def propertySymbol(self): localctx = TParser.PropertySymbolContext(self, self._ctx, self.state) - self.enterRule(localctx, 18, self.RULE_propertySymbol) + self.enterRule(localctx, 20, self.RULE_propertySymbol) self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 163 + self.state = 176 self._errHandler.sync(self) _la = self._input.LA(1) if _la==TParser.DOCCOMMENT: - self.state = 162 + self.state = 175 localctx.comment = self.match(TParser.DOCCOMMENT) - self.state = 168 + self.state = 181 self._errHandler.sync(self) _la = self._input.LA(1) while _la==TParser.TAGLINE: - self.state = 165 + self.state = 178 self.tagSymbol() - self.state = 170 + self.state = 183 self._errHandler.sync(self) _la = self._input.LA(1) - self.state = 172 + self.state = 185 self._errHandler.sync(self) _la = self._input.LA(1) - if _la==TParser.T__10: - self.state = 171 - localctx.isReadOnly = self.match(TParser.T__10) + if _la==TParser.T__10 or _la==TParser.T__12: + self.state = 184 + self.propertyModifierSymbol() - self.state = 174 + self.state = 187 self.typeSymbol() - self.state = 175 + self.state = 188 localctx.name = self.match(TParser.IDENTIFIER) - self.state = 177 + self.state = 190 self._errHandler.sync(self) _la = self._input.LA(1) if _la==TParser.T__1: - self.state = 176 + self.state = 189 self.match(TParser.T__1) @@ -1119,6 +1209,64 @@ class TParser ( Parser ): self.exitRule() return localctx + class PropertyModifierSymbolContext(ParserRuleContext): + + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) + self.parser = parser + self.is_readonly = None # Token + self.is_const = None # Token + + + def getRuleIndex(self): + return TParser.RULE_propertyModifierSymbol + + def enterRule(self, listener:ParseTreeListener): + if hasattr( listener, "enterPropertyModifierSymbol" ): + listener.enterPropertyModifierSymbol(self) + + def exitRule(self, listener:ParseTreeListener): + if hasattr( listener, "exitPropertyModifierSymbol" ): + listener.exitPropertyModifierSymbol(self) + + def accept(self, visitor:ParseTreeVisitor): + if hasattr( visitor, "visitPropertyModifierSymbol" ): + return visitor.visitPropertyModifierSymbol(self) + else: + return visitor.visitChildren(self) + + + + + def propertyModifierSymbol(self): + + localctx = TParser.PropertyModifierSymbolContext(self, self._ctx, self.state) + self.enterRule(localctx, 22, self.RULE_propertyModifierSymbol) + try: + self.state = 194 + self._errHandler.sync(self) + token = self._input.LA(1) + if token in [TParser.T__12]: + self.enterOuterAlt(localctx, 1) + self.state = 192 + localctx.is_readonly = self.match(TParser.T__12) + pass + elif token in [TParser.T__10]: + self.enterOuterAlt(localctx, 2) + self.state = 193 + localctx.is_const = self.match(TParser.T__10) + pass + else: + raise NoViableAltException(self) + + except RecognitionException as re: + localctx.exception = re + self._errHandler.reportError(self, re) + self._errHandler.recover(self, re) + finally: + self.exitRule() + return localctx + class OperationParameterSymbolContext(ParserRuleContext): def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): @@ -1156,20 +1304,20 @@ class TParser ( Parser ): def operationParameterSymbol(self): localctx = TParser.OperationParameterSymbolContext(self, self._ctx, self.state) - self.enterRule(localctx, 20, self.RULE_operationParameterSymbol) + self.enterRule(localctx, 24, self.RULE_operationParameterSymbol) self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 179 + self.state = 196 self.typeSymbol() - self.state = 180 + self.state = 197 localctx.name = self.match(TParser.IDENTIFIER) - self.state = 182 + self.state = 199 self._errHandler.sync(self) _la = self._input.LA(1) - if _la==TParser.T__11: - self.state = 181 - self.match(TParser.T__11) + if _la==TParser.T__13: + self.state = 198 + self.match(TParser.T__13) except RecognitionException as re: @@ -1213,10 +1361,10 @@ class TParser ( Parser ): def tagSymbol(self): localctx = TParser.TagSymbolContext(self, self._ctx, self.state) - self.enterRule(localctx, 22, self.RULE_tagSymbol) + self.enterRule(localctx, 26, self.RULE_tagSymbol) try: self.enterOuterAlt(localctx, 1) - self.state = 184 + self.state = 201 localctx.line = self.match(TParser.TAGLINE) except RecognitionException as re: localctx.exception = re @@ -1263,28 +1411,28 @@ class TParser ( Parser ): def tagAttributeSymbol(self): localctx = TParser.TagAttributeSymbolContext(self, self._ctx, self.state) - self.enterRule(localctx, 24, self.RULE_tagAttributeSymbol) + self.enterRule(localctx, 28, self.RULE_tagAttributeSymbol) self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 186 + self.state = 203 localctx.name = self.match(TParser.IDENTIFIER) - self.state = 189 + self.state = 206 self._errHandler.sync(self) _la = self._input.LA(1) - if _la==TParser.T__12: - self.state = 187 - self.match(TParser.T__12) - self.state = 188 + if _la==TParser.T__14: + self.state = 204 + self.match(TParser.T__14) + self.state = 205 localctx.value = self.match(TParser.IDENTIFIER) - self.state = 192 + self.state = 209 self._errHandler.sync(self) _la = self._input.LA(1) - if _la==TParser.T__11: - self.state = 191 - self.match(TParser.T__11) + if _la==TParser.T__13: + self.state = 208 + self.match(TParser.T__13) except RecognitionException as re: @@ -1340,29 +1488,29 @@ class TParser ( Parser ): def typeSymbol(self): localctx = TParser.TypeSymbolContext(self, self._ctx, self.state) - self.enterRule(localctx, 26, self.RULE_typeSymbol) + self.enterRule(localctx, 30, self.RULE_typeSymbol) try: - self.state = 198 + self.state = 215 self._errHandler.sync(self) token = self._input.LA(1) - if token in [TParser.T__13, TParser.T__14, TParser.T__15, TParser.T__16, TParser.T__17]: + if token in [TParser.T__15, TParser.T__16, TParser.T__17, TParser.T__18, TParser.T__19]: self.enterOuterAlt(localctx, 1) - self.state = 194 + self.state = 211 self.primitiveTypeSymbol() pass elif token in [TParser.IDENTIFIER]: self.enterOuterAlt(localctx, 2) - self.state = 195 + self.state = 212 self.complexTypeSymbol() pass - elif token in [TParser.T__18]: + elif token in [TParser.T__20]: self.enterOuterAlt(localctx, 3) - self.state = 196 + self.state = 213 self.listTypeSymbol() pass - elif token in [TParser.T__21]: + elif token in [TParser.T__23]: self.enterOuterAlt(localctx, 4) - self.state = 197 + self.state = 214 self.modelTypeSymbol() pass else: @@ -1409,10 +1557,10 @@ class TParser ( Parser ): def complexTypeSymbol(self): localctx = TParser.ComplexTypeSymbolContext(self, self._ctx, self.state) - self.enterRule(localctx, 28, self.RULE_complexTypeSymbol) + self.enterRule(localctx, 32, self.RULE_complexTypeSymbol) try: self.enterOuterAlt(localctx, 1) - self.state = 200 + self.state = 217 localctx.name = self.match(TParser.IDENTIFIER) except RecognitionException as re: localctx.exception = re @@ -1453,35 +1601,35 @@ class TParser ( Parser ): def primitiveTypeSymbol(self): localctx = TParser.PrimitiveTypeSymbolContext(self, self._ctx, self.state) - self.enterRule(localctx, 30, self.RULE_primitiveTypeSymbol) + self.enterRule(localctx, 34, self.RULE_primitiveTypeSymbol) try: - self.state = 207 + self.state = 224 self._errHandler.sync(self) token = self._input.LA(1) - if token in [TParser.T__13]: + if token in [TParser.T__15]: self.enterOuterAlt(localctx, 1) - self.state = 202 - localctx.name = self.match(TParser.T__13) + self.state = 219 + localctx.name = self.match(TParser.T__15) pass - elif token in [TParser.T__14]: + elif token in [TParser.T__16]: self.enterOuterAlt(localctx, 2) - self.state = 203 - localctx.name = self.match(TParser.T__14) + self.state = 220 + localctx.name = self.match(TParser.T__16) pass - elif token in [TParser.T__15]: + elif token in [TParser.T__17]: self.enterOuterAlt(localctx, 3) - self.state = 204 - localctx.name = self.match(TParser.T__15) + self.state = 221 + localctx.name = self.match(TParser.T__17) pass - elif token in [TParser.T__16]: + elif token in [TParser.T__18]: self.enterOuterAlt(localctx, 4) - self.state = 205 - localctx.name = self.match(TParser.T__16) + self.state = 222 + localctx.name = self.match(TParser.T__18) pass - elif token in [TParser.T__17]: + elif token in [TParser.T__19]: self.enterOuterAlt(localctx, 5) - self.state = 206 - localctx.name = self.match(TParser.T__17) + self.state = 223 + localctx.name = self.match(TParser.T__19) pass else: raise NoViableAltException(self) @@ -1528,17 +1676,17 @@ class TParser ( Parser ): def listTypeSymbol(self): localctx = TParser.ListTypeSymbolContext(self, self._ctx, self.state) - self.enterRule(localctx, 32, self.RULE_listTypeSymbol) + self.enterRule(localctx, 36, self.RULE_listTypeSymbol) try: self.enterOuterAlt(localctx, 1) - self.state = 209 - self.match(TParser.T__18) - self.state = 210 - self.match(TParser.T__19) - self.state = 211 - localctx.valueType = self.typeSymbol() - self.state = 212 + self.state = 226 self.match(TParser.T__20) + self.state = 227 + self.match(TParser.T__21) + self.state = 228 + localctx.valueType = self.typeSymbol() + self.state = 229 + self.match(TParser.T__22) except RecognitionException as re: localctx.exception = re self._errHandler.reportError(self, re) @@ -1581,17 +1729,17 @@ class TParser ( Parser ): def modelTypeSymbol(self): localctx = TParser.ModelTypeSymbolContext(self, self._ctx, self.state) - self.enterRule(localctx, 34, self.RULE_modelTypeSymbol) + self.enterRule(localctx, 38, self.RULE_modelTypeSymbol) try: self.enterOuterAlt(localctx, 1) - self.state = 214 + self.state = 231 + self.match(TParser.T__23) + self.state = 232 self.match(TParser.T__21) - self.state = 215 - self.match(TParser.T__19) - self.state = 216 + self.state = 233 localctx.valueType = self.typeSymbol() - self.state = 217 - self.match(TParser.T__20) + self.state = 234 + self.match(TParser.T__22) except RecognitionException as re: localctx.exception = re self._errHandler.reportError(self, re) @@ -1651,51 +1799,51 @@ class TParser ( Parser ): def structSymbol(self): localctx = TParser.StructSymbolContext(self, self._ctx, self.state) - self.enterRule(localctx, 36, self.RULE_structSymbol) + self.enterRule(localctx, 40, self.RULE_structSymbol) self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 220 + self.state = 237 self._errHandler.sync(self) _la = self._input.LA(1) if _la==TParser.DOCCOMMENT: - self.state = 219 + self.state = 236 localctx.comment = self.match(TParser.DOCCOMMENT) - self.state = 225 + self.state = 242 self._errHandler.sync(self) _la = self._input.LA(1) while _la==TParser.TAGLINE: - self.state = 222 + self.state = 239 self.tagSymbol() - self.state = 227 + self.state = 244 self._errHandler.sync(self) _la = self._input.LA(1) - self.state = 228 - self.match(TParser.T__22) - self.state = 229 + self.state = 245 + self.match(TParser.T__24) + self.state = 246 localctx.name = self.match(TParser.IDENTIFIER) - self.state = 230 - self.match(TParser.T__4) - self.state = 234 + self.state = 247 + self.match(TParser.T__5) + self.state = 251 self._errHandler.sync(self) _la = self._input.LA(1) - while (((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << TParser.T__13) | (1 << TParser.T__14) | (1 << TParser.T__15) | (1 << TParser.T__16) | (1 << TParser.T__17) | (1 << TParser.T__18) | (1 << TParser.T__21) | (1 << TParser.TAGLINE) | (1 << TParser.IDENTIFIER) | (1 << TParser.DOCCOMMENT))) != 0): - self.state = 231 + while (((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << TParser.T__15) | (1 << TParser.T__16) | (1 << TParser.T__17) | (1 << TParser.T__18) | (1 << TParser.T__19) | (1 << TParser.T__20) | (1 << TParser.T__23) | (1 << TParser.TAGLINE) | (1 << TParser.IDENTIFIER) | (1 << TParser.DOCCOMMENT))) != 0): + self.state = 248 self.structFieldSymbol() - self.state = 236 + self.state = 253 self._errHandler.sync(self) _la = self._input.LA(1) - self.state = 237 - self.match(TParser.T__5) - self.state = 239 + self.state = 254 + self.match(TParser.T__6) + self.state = 256 self._errHandler.sync(self) _la = self._input.LA(1) if _la==TParser.T__1: - self.state = 238 + self.state = 255 self.match(TParser.T__1) @@ -1755,37 +1903,37 @@ class TParser ( Parser ): def structFieldSymbol(self): localctx = TParser.StructFieldSymbolContext(self, self._ctx, self.state) - self.enterRule(localctx, 38, self.RULE_structFieldSymbol) + self.enterRule(localctx, 42, self.RULE_structFieldSymbol) self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 242 + self.state = 259 self._errHandler.sync(self) _la = self._input.LA(1) if _la==TParser.DOCCOMMENT: - self.state = 241 + self.state = 258 localctx.comment = self.match(TParser.DOCCOMMENT) - self.state = 247 + self.state = 264 self._errHandler.sync(self) _la = self._input.LA(1) while _la==TParser.TAGLINE: - self.state = 244 + self.state = 261 self.tagSymbol() - self.state = 249 + self.state = 266 self._errHandler.sync(self) _la = self._input.LA(1) - self.state = 250 + self.state = 267 self.typeSymbol() - self.state = 251 + self.state = 268 localctx.name = self.match(TParser.IDENTIFIER) - self.state = 253 + self.state = 270 self._errHandler.sync(self) _la = self._input.LA(1) if _la==TParser.T__1: - self.state = 252 + self.state = 269 self.match(TParser.T__1) @@ -1852,51 +2000,51 @@ class TParser ( Parser ): def enumSymbol(self): localctx = TParser.EnumSymbolContext(self, self._ctx, self.state) - self.enterRule(localctx, 40, self.RULE_enumSymbol) + self.enterRule(localctx, 44, self.RULE_enumSymbol) self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 256 + self.state = 273 self._errHandler.sync(self) _la = self._input.LA(1) if _la==TParser.DOCCOMMENT: - self.state = 255 + self.state = 272 localctx.comment = self.match(TParser.DOCCOMMENT) - self.state = 261 + self.state = 278 self._errHandler.sync(self) _la = self._input.LA(1) while _la==TParser.TAGLINE: - self.state = 258 + self.state = 275 self.tagSymbol() - self.state = 263 + self.state = 280 self._errHandler.sync(self) _la = self._input.LA(1) - self.state = 264 + self.state = 281 self.enumTypeSymbol() - self.state = 265 + self.state = 282 localctx.name = self.match(TParser.IDENTIFIER) - self.state = 266 - self.match(TParser.T__4) - self.state = 270 + self.state = 283 + self.match(TParser.T__5) + self.state = 287 self._errHandler.sync(self) _la = self._input.LA(1) while (((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << TParser.TAGLINE) | (1 << TParser.IDENTIFIER) | (1 << TParser.DOCCOMMENT))) != 0): - self.state = 267 + self.state = 284 self.enumMemberSymbol() - self.state = 272 + self.state = 289 self._errHandler.sync(self) _la = self._input.LA(1) - self.state = 273 - self.match(TParser.T__5) - self.state = 275 + self.state = 290 + self.match(TParser.T__6) + self.state = 292 self._errHandler.sync(self) _la = self._input.LA(1) if _la==TParser.T__1: - self.state = 274 + self.state = 291 self.match(TParser.T__1) @@ -1940,20 +2088,20 @@ class TParser ( Parser ): def enumTypeSymbol(self): localctx = TParser.EnumTypeSymbolContext(self, self._ctx, self.state) - self.enterRule(localctx, 42, self.RULE_enumTypeSymbol) + self.enterRule(localctx, 46, self.RULE_enumTypeSymbol) try: - self.state = 279 + self.state = 296 self._errHandler.sync(self) token = self._input.LA(1) - if token in [TParser.T__23]: + if token in [TParser.T__25]: self.enterOuterAlt(localctx, 1) - self.state = 277 - localctx.isEnum = self.match(TParser.T__23) + self.state = 294 + localctx.isEnum = self.match(TParser.T__25) pass - elif token in [TParser.T__24]: + elif token in [TParser.T__26]: self.enterOuterAlt(localctx, 2) - self.state = 278 - localctx.isFlag = self.match(TParser.T__24) + self.state = 295 + localctx.isFlag = self.match(TParser.T__26) pass else: raise NoViableAltException(self) @@ -2014,46 +2162,46 @@ class TParser ( Parser ): def enumMemberSymbol(self): localctx = TParser.EnumMemberSymbolContext(self, self._ctx, self.state) - self.enterRule(localctx, 44, self.RULE_enumMemberSymbol) + self.enterRule(localctx, 48, self.RULE_enumMemberSymbol) self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 282 + self.state = 299 self._errHandler.sync(self) _la = self._input.LA(1) if _la==TParser.DOCCOMMENT: - self.state = 281 + self.state = 298 localctx.comment = self.match(TParser.DOCCOMMENT) - self.state = 287 + self.state = 304 self._errHandler.sync(self) _la = self._input.LA(1) while _la==TParser.TAGLINE: - self.state = 284 + self.state = 301 self.tagSymbol() - self.state = 289 + self.state = 306 self._errHandler.sync(self) _la = self._input.LA(1) - self.state = 290 + self.state = 307 localctx.name = self.match(TParser.IDENTIFIER) - self.state = 293 + self.state = 310 self._errHandler.sync(self) _la = self._input.LA(1) - if _la==TParser.T__12: - self.state = 291 - self.match(TParser.T__12) - self.state = 292 + if _la==TParser.T__14: + self.state = 308 + self.match(TParser.T__14) + self.state = 309 self.intSymbol() - self.state = 296 + self.state = 313 self._errHandler.sync(self) _la = self._input.LA(1) - if _la==TParser.T__11: - self.state = 295 - self.match(TParser.T__11) + if _la==TParser.T__13: + self.state = 312 + self.match(TParser.T__13) except RecognitionException as re: @@ -2100,19 +2248,19 @@ class TParser ( Parser ): def intSymbol(self): localctx = TParser.IntSymbolContext(self, self._ctx, self.state) - self.enterRule(localctx, 46, self.RULE_intSymbol) + self.enterRule(localctx, 50, self.RULE_intSymbol) try: - self.state = 300 + self.state = 317 self._errHandler.sync(self) token = self._input.LA(1) if token in [TParser.INTCONSTANT]: self.enterOuterAlt(localctx, 1) - self.state = 298 + self.state = 315 localctx.value = self.match(TParser.INTCONSTANT) pass elif token in [TParser.HEXCONSTANT]: self.enterOuterAlt(localctx, 2) - self.state = 299 + self.state = 316 localctx.value = self.match(TParser.HEXCONSTANT) pass else: diff --git a/qface/idl/parser/TVisitor.py b/qface/idl/parser/TVisitor.py index 537146c..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 @@ -49,6 +49,11 @@ class TVisitor(ParseTreeVisitor): return self.visitChildren(ctx) + # Visit a parse tree produced by TParser#operationModifierSymbol. + def visitOperationModifierSymbol(self, ctx:TParser.OperationModifierSymbolContext): + return self.visitChildren(ctx) + + # Visit a parse tree produced by TParser#signalSymbol. def visitSignalSymbol(self, ctx:TParser.SignalSymbolContext): return self.visitChildren(ctx) @@ -59,6 +64,11 @@ class TVisitor(ParseTreeVisitor): return self.visitChildren(ctx) + # Visit a parse tree produced by TParser#propertyModifierSymbol. + def visitPropertyModifierSymbol(self, ctx:TParser.PropertyModifierSymbolContext): + return self.visitChildren(ctx) + + # Visit a parse tree produced by TParser#operationParameterSymbol. def visitOperationParameterSymbol(self, ctx:TParser.OperationParameterSymbolContext): return self.visitChildren(ctx) diff --git a/qface/templates/qface/qtcpp.j2 b/qface/templates/qface/qtcpp.j2 new file mode 100644 index 0000000..97e1c8d --- /dev/null +++ b/qface/templates/qface/qtcpp.j2 @@ -0,0 +1,103 @@ +{%+ macro enum_decl(enum) -%} + enum {{enum}}Enum { + {% for member in enum.members %} + {{member.name}} = {{member.value}}{% if not loop.last %},{%endif%} + + {% endfor %} + }; + {% if enum.is_flag %} + Q_DECLARE_FLAGS({{enum}}Enums, {{enum}}Enum) + Q_FLAG({{enum}}Enum) + {% else %} + Q_ENUM({{enum}}Enum) + {% endif %} +{%- endmacro %} + +{% macro property(property, notifiable=True) -%} +Q_PROPERTY({{property|returnType}} {{property}} READ {{property}} {% if not property.readonly %}WRITE set{{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|parameterType }}){{ending}} +{%- endmacro %} + +{% macro property_getter_decl(property, ending=";") -%} +{{property|returnType}} {{property}}() const{{ending}} +{%- endmacro %} + +{% macro signal_decl(symbol, postfix="") -%} +void {{symbol}}{{postfix}}({{symbol|parameters}}); +{%- endmacro %} + +{% macro property_member_decl(property) -%} +{{property|returnType}} m_{{property}}; +{%- endmacro %} + +{% macro property_setter_impl(class, property, notifiable=True) -%} +/*! + \qmlproperty {{property.type}} {{class}}::{{property}} +{% with doc = property.comment|parse_doc %} + \brief {{doc.brief}} + + {{doc.description}} +{% endwith %} +*/ + +void {{class}}::set{{property|upperfirst}}({{ property|parameterType }}) +{ +{% if notifiable %} + if (m_{{property}} != {{property}}) { + m_{{property}} = {{property}}; + Q_EMIT {{property}}Changed({{property}}); + } +{% else %} + m_{{property}} = {{property}}; +{% endif %} + +} +{%- 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, ending=";") -%} + virtual {{operation|returnType}} {{operation}}({{operation|parameters}}){{ending}} +{%- 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 9129bfa..9501f25 100644 --- a/qface/watch.py +++ b/qface/watch.py @@ -16,30 +16,32 @@ class RunScriptChangeHandler(FileSystemEventHandler): self.is_running = False def on_modified(self, event): + if event.is_directory: + return self.run() def run(self): 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 -def monitor(script, src, dst): +def monitor(script, src, dst, args): """ 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) + command = ' '.join(args) + print('command: ', command) + 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') observer.schedule(event_handler, entry, recursive=True) event_handler.run() # run always once |