aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJuergen Bocklage-Ryannel <juergen.bocklage-ryannel@pelagicore.com>2017-03-14 12:56:40 +0100
committerJuergen Bocklage-Ryannel <juergen.bocklage-ryannel@pelagicore.com>2017-03-14 12:56:40 +0100
commit7159223d1656abfd3ea891469ae5090f481b5e81 (patch)
treed4924b1a870d5321a0c3c40e1ba20ee09dafa1cd
parent42c9a0fdf0ec3ec477dbc142551e96f62d783a80 (diff)
parent7bbb5ed1b94eeaea3073123e1845faa035d73878 (diff)
Merge branch 'release/1.1b1'1.1b1
-rw-r--r--README.md4
-rw-r--r--USAGE.md2
-rwxr-xr-xcli.py (renamed from qface-cli.py)5
-rw-r--r--docs/api.rst11
-rw-r--r--docs/grammar.rst33
-rw-r--r--docs/motivation.rst31
-rw-r--r--docs/qtcpp.rst12
-rw-r--r--examples/interfaces/echo.qface6
-rw-r--r--qface/__about__.py2
-rwxr-xr-xqface/builtin/qtcpp/qtcpp.py20
-rw-r--r--qface/builtin/qtcpp/templates/abstractinterface.cpp28
-rw-r--r--qface/builtin/qtcpp/templates/abstractinterface.h3
-rw-r--r--qface/builtin/qtcpp/templates/docs.pri32
-rw-r--r--qface/builtin/qtcpp/templates/generated.pri8
-rw-r--r--qface/builtin/qtcpp/templates/interface.cpp12
-rw-r--r--qface/builtin/qtcpp/templates/interface.h9
-rw-r--r--qface/builtin/qtcpp/templates/module.cpp26
-rw-r--r--qface/builtin/qtcpp/templates/plugin-online.qdocconf19
-rw-r--r--qface/builtin/qtcpp/templates/plugin-project.qdocconf27
-rw-r--r--qface/builtin/qtcpp/templates/plugin.pro8
-rw-r--r--qface/builtin/qtcpp/templates/plugin.qdocconf21
-rw-r--r--qface/builtin/qtcpp/templates/qmake.conf5
-rw-r--r--qface/builtin/qtcpp/templates/struct.cpp11
-rwxr-xr-x[-rw-r--r--]qface/builtin/qtqml/qtqml.py11
-rw-r--r--qface/builtin/qtqml/templates/AbstractInterface.qml23
-rw-r--r--qface/builtin/qtqml/templates/Interface.qml4
-rw-r--r--qface/builtin/qtqml/templates/InterfaceProvider.qml23
-rw-r--r--qface/builtin/qtqml/templates/private_qmldir1
-rw-r--r--qface/generator.py32
-rw-r--r--qface/helper/doc.py81
-rw-r--r--qface/idl/domain.py138
-rw-r--r--qface/idl/listener.py20
-rw-r--r--qface/idl/parser/T.g410
-rw-r--r--qface/idl/parser/T.tokens8
-rw-r--r--qface/idl/parser/TLexer.py205
-rw-r--r--qface/idl/parser/TLexer.tokens8
-rw-r--r--qface/idl/parser/TListener.py9
-rw-r--r--qface/idl/parser/TParser.py769
-rw-r--r--qface/idl/parser/TVisitor.py5
-rw-r--r--qface/shell.py16
-rw-r--r--qface/watch.py54
-rw-r--r--tests/in/com.pelagicore.ivi.climate.qface38
-rw-r--r--tests/in/com.pelagicore.ivi.tuner.qface39
-rw-r--r--tests/in/com.pelagicore.ivi.tuner.yaml2
-rw-r--r--tests/in/com.pelagicore.one.qface2
-rw-r--r--tests/in/com.pelagicore.test.qface2
-rw-r--r--tests/in/org.example.echo.qface25
-rw-r--r--tests/test_climate.py4
-rw-r--r--tests/test_comments.py55
-rw-r--r--tests/test_lookup.py10
-rw-r--r--tests/test_parser.py28
-rw-r--r--tests/test_qtcpp_helper.py4
-rw-r--r--tests/test_tags.py11
-rw-r--r--tests/test_validation.py4
54 files changed, 1337 insertions, 639 deletions
diff --git a/README.md b/README.md
index d0041d1..1760a7f 100644
--- a/README.md
+++ b/README.md
@@ -50,7 +50,7 @@ on the other side
interface Echo {
readonly Message lastMessage;
void echo(Message message);
- event void callMe();
+ signal callMe();
};
struct Message {
@@ -76,6 +76,6 @@ for module in system:
ctx = { 'interface': interface }
# use header.h template with ctx to write to a file
generator.write('{{interface|lower}}.h', 'header.h', ctx)
-```
+```
Depending on the used generator it reads the input file and runs it through the generator. The output files are written relative to the given output directory. The input can be either a file or a folder.
diff --git a/USAGE.md b/USAGE.md
index 00cf2b9..9b4a557 100644
--- a/USAGE.md
+++ b/USAGE.md
@@ -34,7 +34,7 @@ The IDL grammar is described in the grammar file (see qface/parser/idl/T.g4)
interface <identifier> {
(readonly) <type> <property>;
<type> <operation>([type name]);
- event <type> <operation>([type name]);
+ signal <signal>([type name]);
list<type> <property>;
model<type> <property>;
}
diff --git a/qface-cli.py b/cli.py
index d4a620c..9c0f4fb 100755
--- a/qface-cli.py
+++ b/cli.py
@@ -8,7 +8,6 @@ from watchdog.observers import Observer
from path import Path
import time
import os
-import sys
import yaml
import logging
import logging.config
@@ -54,7 +53,7 @@ def test_ci():
class RunTestChangeHandler(FileSystemEventHandler):
def __init__(self, clickContext):
- super(RunTestChangeHandler).__init__()
+ super().__init__()
self.clickContext = clickContext
def on_any_event(self, event):
@@ -85,7 +84,7 @@ def test_monitor(ctx):
class RunScriptChangeHandler(FileSystemEventHandler):
def __init__(self, script):
- super(RunTestChangeHandler).__init__()
+ super().__init__()
self.script = script
self.is_running = False
diff --git a/docs/api.rst b/docs/api.rst
index e200730..a9a0d16 100644
--- a/docs/api.rst
+++ b/docs/api.rst
@@ -97,14 +97,21 @@ Struct Related Classes
Base Classes
------------
-.. autoclass:: qface.idl.domain.Symbol
+.. autoclass:: qface.idl.domain.NamedElement
:members:
:show-inheritance:
-.. autoclass:: qface.idl.domain.TypedSymbol
+.. autoclass:: qface.idl.domain.Symbol
:members:
:show-inheritance:
.. autoclass:: qface.idl.domain.TypeSymbol
:members:
:show-inheritance:
+
+Utility Modules
+---------------
+
+.. autofunction:: qface.watch.monitor
+
+.. autofunction:: qface.shell.sh
diff --git a/docs/grammar.rst b/docs/grammar.rst
index f7977ce..c5acd91 100644
--- a/docs/grammar.rst
+++ b/docs/grammar.rst
@@ -12,7 +12,7 @@ QFace (Qt interface language) is an IDL to define an interface. In general it is
interface <Identifier> {
<type> <identifier>
<type> <operation>(<parameter>*)
- event <type> <event>(<parameter>*)
+ signal <signal>(<parameter>*)
}
struct <Identifier> {
@@ -40,7 +40,7 @@ Types
Types are either local and can be references simply by its name, or they are from external module in this case they need to be referenced with the fully qualified name (``module + '.' + name``). A type can be an interface, struct, enum or flag.
-A module consist of either one or more interfaces, structs and enums/flags. They can come in any number or combination. The interface is the only type which can contain operations and events. The struct is merely a container to transport structured data. An enum/flag allows the user to encode information used inside the struct or interface as datatype.
+A module consist of either one or more interfaces, structs and enums/flags. They can come in any number or combination. The interface is the only type which can contain operations and signals. The struct is merely a container to transport structured data. An enum/flag allows the user to encode information used inside the struct or interface as datatype.
The QFace does not allow to extend interfaces. It is by design kept simple.
@@ -105,7 +105,36 @@ Below is an example of a QFace file.
}
+Tags / Annotations
+==================
+Tags allows an interface author to extend the existing grammar with additional meta information, called tags, aka annotations. One or several annotations can stand in from of a module, interface, struct or enum. They are also allowed before an operation, property or signal. Everywhere where a documentation comment is allowed you can also add annotations.
+
+An annotation looks like this::
+
+ @service(port=12345)
+ interface Tuner {
+ }
+
+A annotation format is very similar to an operation signature prefixed with an `@` sign and no return value.
+
+The annotation are available later when navigating the domain model.
+
+.. note:: QFace does not specify specific annotations, but defines just the annotation format. The set of annotations supported must be defined and documented by the generator.
+
+.. rubric:: Annotation Documents
+
+QFace allows also to specify these annotations in external documents using the `YAML` syntax. For this you need to create a document with the same name as the QFace document but with the extension `.yaml`. It should have roughly the following format
+
+.. code-block:: yaml
+
+ com.pelagicore.ivi.Tuner:
+ service:
+ port: 12345
+
+On the root level should be a fully qualified name of a symbol. The symbol will be looked up and the following annotation information merged with the existing annotations form the QFace document.
+
+.. warning:: External annotation with the same name will override the QFace document annotation with the same name on the specified symbol.
diff --git a/docs/motivation.rst b/docs/motivation.rst
index f5c4b8e..fcd19ba 100644
--- a/docs/motivation.rst
+++ b/docs/motivation.rst
@@ -7,7 +7,24 @@ QFace is an attempt to establish one interface description language with an easy
The IDL
=======
-The IDL uses common API concept such as modules, interfaces, properties, structs and enums/flags. Additional it knows about lists and models. A list is an array of primitive or complex types. A model is an indicator for large data sets which are typical used vian a defined interface or via pagination.
+The IDL uses common API concept such as modules, interfaces, properties, structs and enums/flags. Additional it knows about lists and models. A list is an array of primitive or complex types. A model is an indicator for large data sets which are typical used via a defined interface or via pagination.
+
+... code-block:: js
+
+ module org.example 1.0
+
+ interface Echo {
+ string message;
+ void echo(string message);
+ signal broadcast(string message);
+ Status status;
+ }
+
+ enum Status {
+ Null, Loading, Ready, Error
+ }
+
+
The data types provided by QFace can be divided into primitive and complex types:
@@ -28,14 +45,20 @@ Complex Types
* Array
* Model
-The language as such does not provide any support for maps or dictionaries. The keys in dictionaries require a hash which can not always be guaranteed to be available.
+The language as such does not provide any support for maps or dictionaries. The reason for not providing a map container type is that keys in dictionaries requires a hash which can not always be guaranteed to be available in complex types.
+
+Why another IDL
+===============
+
+There exists many IDLs. Most of them are bound to a certain technology or library or are limited for a specific use. Only a few IDL exists which are independent from a technology. From these few which are known to the author none satisfied the requirement from the author to be Qt compatible and easy to use. Also the IDL should be easy to use and easy to be install and to be extendable. The unique mix of technologies used in QFace allows it to provide a solid stable IDL with a powerful generation framework.
+
Defining APIs
=============
-There are many opinions how to define APIs and what is the best way. The hope is if enough people use the same IDL there will be a large set of generators and at the end maybe one common way how to write your QML plugin and export the API.
+There are many opinions how to define APIs and what is the best way. The porposal of QFace is that is many project find QFace useful and use the same IDL there will be a large set of generators and at the end APIs can be compared and unified also if they will be used with different technologies.
-There are often discussions about if an interface shall be an object or better a singleton. Or if an array shall be exposed as a list or a variant list or even a QmlListProperty or always as a model. Structured data can be exposed using a QVariant or QJSValue or nowadays as a gadget or as a QObject if property notifications are required. Exposing structured data via QObject leads to memory management issues.
+Even inside on e technolgy there are often discussions about how an interface shall be coded. QFace allows the different parties to create their own generators based on the same API. Ideally at the end the knowledge how an interface shall be coded will reside in the provided generator.
Large Projects
==============
diff --git a/docs/qtcpp.rst b/docs/qtcpp.rst
index 2eb3ede..b475ffd 100644
--- a/docs/qtcpp.rst
+++ b/docs/qtcpp.rst
@@ -21,7 +21,7 @@ For example an QFace document like this
Status status;
void increaseTemperature(real step);
void decreaseTemperature(real step);
- event void error(string message);
+ signal error(string message);
}
enum Status {
@@ -68,7 +68,7 @@ Code Generation
For each module the generator creates the qmake project files, the plugin code to register the types. A module singleton which contains the enums and factory functions for creating the structures. The structure has no signals and the values are copied over.
-.. code-block:: yml
+.. code-block:: yaml
for each module:
- qmldir
@@ -79,7 +79,7 @@ For each module the generator creates the qmake project files, the plugin code t
- private/module.cpp
- for each interface:
- private/abstractinterface.h
- - private/abstractinterface.cpp
+ - private/abstractinterface.cpp
- interface.h - preserve
- interface.cpp - preserve
- for each struct:
@@ -98,11 +98,11 @@ Design Decisions
Writable properties on service objects are a cause of errors and confusion. It is very easy in the HMI stack to overwrite a binding property which writes to a service. It is better to offer a dedicated operation which does some work and triggers an operation update.
* All models generated are read only from QML
-
+
The data for a model is often stored inside another system (SQL DB, Remote, File System) and only a small subset of the data is actually in memory. Filtering, sorting or modifying the model data should be explicitly done using operations if supported by the user interface.
* Data structures are exported as gadgets
-
+
A Q_GADGET allows us to define a data structure and modify its contents. A gadget does not support signals, which means others are not notified about changes. This is the same behavior as for JS objects. Gadgets are copied from C++ to QML so there is no issue with memory management. QML has no means to create a gadget class, for this the module object contains a factory method for each structure.
* Enums are collected into one module object
@@ -122,4 +122,4 @@ Besides the interface files also the plugin and project files are preserved, as
-
+
diff --git a/examples/interfaces/echo.qface b/examples/interfaces/echo.qface
index bbde9d6..ed58685 100644
--- a/examples/interfaces/echo.qface
+++ b/examples/interfaces/echo.qface
@@ -1,14 +1,14 @@
module org.example 1.0;
-/*!
+/**
* Provide a simple echo service.
*/
interface Echo {
- /*!
+ /**
* The last echo message.
*/
string currentMessage;
- /*!
+ /**
* Returns the passed in message
*/
void echo(Message message);
diff --git a/qface/__about__.py b/qface/__about__.py
index cf715d8..6082fa1 100644
--- a/qface/__about__.py
+++ b/qface/__about__.py
@@ -9,6 +9,6 @@ except NameError:
__title__ = "qface"
__summary__ = "A generator framework based on a common modern IDL"
__uri__ = "https://pelagicore.github.io/qface/"
-__version__ = "1.0.3"
+__version__ = "1.1b1"
__author__ = "JRyannel"
__author_email__ = "qface-generator@googlegroups.com"
diff --git a/qface/builtin/qtcpp/qtcpp.py b/qface/builtin/qtcpp/qtcpp.py
index a0ee0ce..630e64a 100755
--- a/qface/builtin/qtcpp/qtcpp.py
+++ b/qface/builtin/qtcpp/qtcpp.py
@@ -9,6 +9,8 @@ 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()
@@ -25,6 +27,7 @@ def run(src, dst):
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)
@@ -38,6 +41,12 @@ def run(src, dst):
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})
@@ -52,17 +61,20 @@ def run(src, dst):
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)
- generator.write('generated/qmlvariantmodel.h', 'variantmodel.h', ctx)
- generator.write('generated/qmlvariantmodel.cpp', 'variantmodel.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):
+def app(src, dst, reload):
"""Takes several files or directories as src and generates the code
in the given dst directory."""
- run(src, dst)
+ if reload:
+ script = '{0} {1} {2}'.format(Path(__file__).abspath(), ' '.join(src), dst)
+ monitor(src, script)
+ else:
+ run(src, dst)
if __name__ == '__main__':
diff --git a/qface/builtin/qtcpp/templates/abstractinterface.cpp b/qface/builtin/qtcpp/templates/abstractinterface.cpp
index ff1ef87..3a70cb6 100644
--- a/qface/builtin/qtcpp/templates/abstractinterface.cpp
+++ b/qface/builtin/qtcpp/templates/abstractinterface.cpp
@@ -9,7 +9,15 @@
#include <QtQml>
-{{interface.comment}}
+/*!
+ \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 %}
@@ -18,11 +26,21 @@
{
}
+
{{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}}) {
@@ -39,6 +57,13 @@ void {{class}}::set{{property|upperfirst}}({{ property|parameterType }})
{% 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 %}
@@ -49,3 +74,4 @@ void {{class}}::set{{property|upperfirst}}({{ property|parameterType }})
}
{% endfor %}
+
diff --git a/qface/builtin/qtcpp/templates/abstractinterface.h b/qface/builtin/qtcpp/templates/abstractinterface.h
index c004f29..09a21a6 100644
--- a/qface/builtin/qtcpp/templates/abstractinterface.h
+++ b/qface/builtin/qtcpp/templates/abstractinterface.h
@@ -39,6 +39,9 @@ public:
{% 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 %}
diff --git a/qface/builtin/qtcpp/templates/docs.pri b/qface/builtin/qtcpp/templates/docs.pri
new file mode 100644
index 0000000..f6a3e81
--- /dev/null
+++ b/qface/builtin/qtcpp/templates/docs.pri
@@ -0,0 +1,32 @@
+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
index 4baac95..7457474 100644
--- a/qface/builtin/qtcpp/templates/generated.pri
+++ b/qface/builtin/qtcpp/templates/generated.pri
@@ -12,11 +12,11 @@ HEADERS += \
{% for interface in module.interfaces %}
$$PWD/qmlabstract{{interface|lower}}.h \
{% endfor %}
- $$PWD/qmlvariantmodel.h \
{% for struct in module.structs %}
$$PWD/qml{{struct|lower}}.h \
- $$PWD/qml{{struct|lower}}model.h {% if not loop.last %}\{% endif %}
+ $$PWD/qml{{struct|lower}}model.h \
{% endfor %}
+ $$PWD/qmlvariantmodel.h
SOURCES += \
@@ -24,10 +24,10 @@ SOURCES += \
{% for interface in module.interfaces %}
$$PWD/qmlabstract{{interface|lower}}.cpp \
{% endfor %}
- $$PWD/qmlvariantmodel.cpp \
{% for struct in module.structs %}
$$PWD/qml{{struct|lower}}.cpp \
- $$PWD/qml{{struct|lower}}model.cpp {% if not loop.last %}\{% endif %}
+ $$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
index abde3d7..cc2264a 100644
--- a/qface/builtin/qtcpp/templates/interface.cpp
+++ b/qface/builtin/qtcpp/templates/interface.cpp
@@ -1,9 +1,9 @@
{# Copyright (c) Pelagicore AB 2016 #}
{% set class = 'Qml{0}'.format(interface) %}
-/****************************************************************************
-** This is an auto-generated file.
-** Do not edit! All changes made to it will be lost.
-****************************************************************************/
+/*
+ * This is a preserved file and can be edited.
+ * All changes will not be override.
+ */
#include "{{class|lower}}.h"
@@ -21,8 +21,8 @@ QObject* {{class|lower}}_singletontype_provider(QQmlEngine*, QJSEngine*)
{
}
-{{class}}::~{{class}}()
-{
+{{class}}::~{{class}}()
+{
}
void {{class}}::registerQmlTypes(const QString& uri, int majorVersion, int minorVersion)
diff --git a/qface/builtin/qtcpp/templates/interface.h b/qface/builtin/qtcpp/templates/interface.h
index 8978be5..cc05be2 100644
--- a/qface/builtin/qtcpp/templates/interface.h
+++ b/qface/builtin/qtcpp/templates/interface.h
@@ -1,9 +1,10 @@
{# Copyright (c) Pelagicore AB 2016 #}
{% set class = 'Qml{0}'.format(interface) %}
-/****************************************************************************
-** This is an auto-generated file.
-** Do not edit! All changes made to it will be lost.
-****************************************************************************/
+/*
+ * This is a preserved file and can be edited.
+ * All changes will not be override.
+ */
+
#pragma once
diff --git a/qface/builtin/qtcpp/templates/module.cpp b/qface/builtin/qtcpp/templates/module.cpp
index 6579b2c..1289471 100644
--- a/qface/builtin/qtcpp/templates/module.cpp
+++ b/qface/builtin/qtcpp/templates/module.cpp
@@ -10,9 +10,29 @@
#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}}();
+ return new {{class}}();
}
{{class}}::{{class}}(QObject *parent)
@@ -21,6 +41,10 @@ QObject* {{class|lower}}_singletontype_provider(QQmlEngine*, QJSEngine*)
}
{% 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}}();
diff --git a/qface/builtin/qtcpp/templates/plugin-online.qdocconf b/qface/builtin/qtcpp/templates/plugin-online.qdocconf
new file mode 100644
index 0000000..771cdae
--- /dev/null
+++ b/qface/builtin/qtcpp/templates/plugin-online.qdocconf
@@ -0,0 +1,19 @@
+HTML.footer = \
+ " </div>\n" \
+ " <p class=\"copy-notice\">\n" \
+ " <acronym title=\"Copyright\">&copy;</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
new file mode 100644
index 0000000..0a846cb
--- /dev/null
+++ b/qface/builtin/qtcpp/templates/plugin-project.qdocconf
@@ -0,0 +1,27 @@
+{% 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.pro b/qface/builtin/qtcpp/templates/plugin.pro
index 00c9d6e..4984015 100644
--- a/qface/builtin/qtcpp/templates/plugin.pro
+++ b/qface/builtin/qtcpp/templates/plugin.pro
@@ -1,8 +1,7 @@
{# Copyright (c) Pelagicore AB 2016 #}
-#############################################################################
-## This is an auto-generated file.
-## Do not edit! All changes made to it will be lost.
-#############################################################################
+
+## This is a preserved file and can be edited.
+## All changes will not be override.
TEMPLATE = lib
QT += qml quick
@@ -27,6 +26,7 @@ SOURCES += \
include( generated/generated.pri )
+include( docs/docs.pri )
DISTFILES = qmldir
diff --git a/qface/builtin/qtcpp/templates/plugin.qdocconf b/qface/builtin/qtcpp/templates/plugin.qdocconf
new file mode 100644
index 0000000..a45a34b
--- /dev/null
+++ b/qface/builtin/qtcpp/templates/plugin.qdocconf
@@ -0,0 +1,21 @@
+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\">&copy;</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
new file mode 100644
index 0000000..03d3435
--- /dev/null
+++ b/qface/builtin/qtcpp/templates/qmake.conf
@@ -0,0 +1,5 @@
+SOURCE_DIR=$$PWD
+BUILD_DIR=$$shadowed($$PWD)
+QMAKEFEATURES=$$SOURCE_DIR/qmake-features
+
+VERSION = 1.0.0
diff --git a/qface/builtin/qtcpp/templates/struct.cpp b/qface/builtin/qtcpp/templates/struct.cpp
index 70dd967..9d3da67 100644
--- a/qface/builtin/qtcpp/templates/struct.cpp
+++ b/qface/builtin/qtcpp/templates/struct.cpp
@@ -37,7 +37,16 @@ public:
};
// Class
-{{struct.comment}}
+
+/*!
+ \qmltype {{struct}}
+ \inqmlmodule {{module}}
+{% with doc = struct.comment|parse_doc %}
+ \brief {{doc.brief}}
+
+ {{doc.description}}
+{% endwith %}
+*/
{{class}}::{{class}}()
: d(new {{class}}Data)
diff --git a/qface/builtin/qtqml/qtqml.py b/qface/builtin/qtqml/qtqml.py
index 224b4c2..b5ed136 100644..100755
--- a/qface/builtin/qtqml/qtqml.py
+++ b/qface/builtin/qtqml/qtqml.py
@@ -9,6 +9,7 @@ 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()
@@ -46,16 +47,20 @@ def run(src, dst):
})
generator.write('private/Abstract{{interface}}.qml', 'AbstractInterface.qml', ctx)
generator.write('{{interface}}.qml', 'Interface.qml', ctx, preserve=True)
- generator.write('private/{{interface}}Provider.qml', 'InterfaceProvider.qml', 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):
+def app(src, dst, reload):
"""Takes several files or directories as src and generates the code
in the given dst directory."""
- run(src, dst)
+ if reload:
+ script = '{0} {1} {2}'.format(Path(__file__).abspath(), ' '.join(src), dst)
+ monitor(src, script)
+ else:
+ run(src, dst)
if __name__ == '__main__':
diff --git a/qface/builtin/qtqml/templates/AbstractInterface.qml b/qface/builtin/qtqml/templates/AbstractInterface.qml
index d36aa5a..b28d6b7 100644
--- a/qface/builtin/qtqml/templates/AbstractInterface.qml
+++ b/qface/builtin/qtqml/templates/AbstractInterface.qml
@@ -6,15 +6,22 @@ import "."
{{interface.comment}}
QtObject {
id: root
- {% for property in interface.properties %}
+{% for property in interface.properties %}
{{property.comment}}
- readonly property {{property|propertyType}} {{property}} : _provider.{{property}}
- {% endfor %}
-
- {% for operation in interface.operations %}
+ {%+ if property.is_readonly %}readonly {% endif %}property {{property|propertyType}} {{property}} : {{property|defaultValue}}
+{% endfor %}
+{% for operation in interface.operations %}
{{operation.comment}}
- readonly property var {{operation}} : _provider.{{operation}}
- {% endfor %}
+ 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 %}
- property {{interface}}Provider _provider: {{interface}}Provider {}
}
diff --git a/qface/builtin/qtqml/templates/Interface.qml b/qface/builtin/qtqml/templates/Interface.qml
index dae8810..2dc9d5f 100644
--- a/qface/builtin/qtqml/templates/Interface.qml
+++ b/qface/builtin/qtqml/templates/Interface.qml
@@ -4,8 +4,4 @@ import "private"
Abstract{{interface}} {
id: root
-
- _provider : {{interface}}Provider {
- // Add your code here
- }
}
diff --git a/qface/builtin/qtqml/templates/InterfaceProvider.qml b/qface/builtin/qtqml/templates/InterfaceProvider.qml
deleted file mode 100644
index bbcaaf5..0000000
--- a/qface/builtin/qtqml/templates/InterfaceProvider.qml
+++ /dev/null
@@ -1,23 +0,0 @@
-import QtQml 2.2
-import QtQml.Models 2.2
-
-import "."
-
-QtObject {
- {% for property in interface.properties %}
- property {{property|propertyType}} {{property}} : {{property|defaultValue}}
- {% endfor %}
-
- {% for operation in interface.operations %}
- property var {{operation}} : function({{operation.parameters|join(', ')}}) {}
- {% endfor %}
-
- {% for event in interface.events %}
- signal {{event}}(
- {%- for parameter in event.parameters %}
- {{- parameter.type|propertyType }} {{ parameter.name -}}
- {% if not loop.last %}, {% endif %}
- {% endfor -%}
- )
- {% endfor %}
-}
diff --git a/qface/builtin/qtqml/templates/private_qmldir b/qface/builtin/qtqml/templates/private_qmldir
index 5cd42a6..152af67 100644
--- a/qface/builtin/qtqml/templates/private_qmldir
+++ b/qface/builtin/qtqml/templates/private_qmldir
@@ -1,5 +1,4 @@
{{module_name}}Module 1.0 {{module_name}}Module.js
{% for interface in module.interfaces %}
Abstract{{interface}} 1.0 Abstract{{interface}}.qml
-{{interface}}Provider 1.0 {{interface}}Provider.qml
{% endfor %}
diff --git a/qface/generator.py b/qface/generator.py
index 0da3613..476dc4e 100644
--- a/qface/generator.py
+++ b/qface/generator.py
@@ -7,6 +7,7 @@ from antlr4.error import DiagnosticErrorListener
import shelve
import logging
import hashlib
+import yaml
from .idl.parser.TLexer import TLexer
from .idl.parser.TParser import TParser
@@ -96,15 +97,17 @@ class FileSystem(object):
"""QFace helper functions to work with the file system"""
@staticmethod
- def parse_document(path: str, system: System = None):
+ def parse_document(document: Path, system: System = None):
"""Parses a document and returns the resulting domain system
:param path: document path to parse
:param system: system to be used (optional)
"""
- logger.debug('parse document: {0}'.format(path))
- stream = FileStream(str(path), encoding='utf-8')
- return FileSystem._parse_stream(stream, system)
+ logger.debug('parse document: {0}'.format(document))
+ stream = FileStream(str(document), encoding='utf-8')
+ system = FileSystem._parse_stream(stream, system)
+ FileSystem.merge_annoations(system, document.stripext() + '.yaml')
+ return system
@staticmethod
def _parse_stream(stream, system: System = None):
@@ -121,6 +124,24 @@ class FileSystem(object):
return system
@staticmethod
+ def merge_annoations(system: System, document: Path):
+ """Read a YAML document and for each root symbol identifier
+ updates the tag information of that symbol
+ """
+ if not document.exists():
+ return
+ meta = {}
+ try:
+ meta = yaml.load(document.text())
+ except yaml.YAMLError as exc:
+ click.echo(exc)
+ click.secho('merge tags from {0}'.format(document), fg='blue')
+ for identifier, data in meta.items():
+ symbol = system.lookup(identifier)
+ if symbol:
+ symbol.tags.update(data)
+
+ @staticmethod
def parse(input, identifier: str = None, use_cache=False, clear_cache=True, pattern="*.qface"):
"""Input can be either a file or directory or a list of files or directory.
A directory will be parsed recursively. The function returns the resulting system.
@@ -131,7 +152,7 @@ class FileSystem(object):
:param clear_cache: clears the domain cache (defaults to true)
"""
inputs = input if isinstance(input, (list, tuple)) else [input]
- logging.debug('parse input={0}'.format(inputs))
+ logger.debug('parse input={0}'.format(inputs))
identifier = 'system' if not identifier else identifier
system = System()
cache = None
@@ -150,6 +171,7 @@ class FileSystem(object):
else:
for document in path.walkfiles(pattern):
FileSystem.parse_document(document, system)
+
if use_cache:
cache[identifier] = system
return system
diff --git a/qface/helper/doc.py b/qface/helper/doc.py
new file mode 100644
index 0000000..c999227
--- /dev/null
+++ b/qface/helper/doc.py
@@ -0,0 +1,81 @@
+import re
+
+
+translate = None
+"""
+The translare function used for transalting inline tags. The
+function will be called with tag, value arguments.
+
+Example:
+
+ import qface.doc
+
+ def qdoc_translate(tag, value):
+ return '\\{0}{{{1}}}'.format(tag, value)
+
+ qface.doc.translate = qdoc_translate
+"""
+
+
+class DocObject:
+ """
+ The documentation object passed into the template engine
+ """
+ def __init__(self):
+ self.brief = str()
+ self.description = []
+ self.see = []
+ self.deprecated = False
+
+ def add_tag(self, name, value):
+ attr_type = type(getattr(self, name, None))
+ if type(value) == str:
+ value = self._replace_inline_tags(value)
+ if attr_type is bool:
+ setattr(self, name, bool(value))
+ elif attr_type is str:
+ setattr(self, name, str(value))
+ elif attr_type is list:
+ getattr(self, name).append(value)
+
+ @staticmethod
+ def _translate(name, value):
+ return '{{@{0} {1}}}'.format(name, value)
+
+ @staticmethod
+ def _call_translate(mo):
+ global translate
+ name, value = mo.group(1), mo.group(2)
+ translate = translate if translate else DocObject._translate
+ return translate(name, value)
+
+ @staticmethod
+ def _replace_inline_tags(line):
+ return re.sub(r'{@(\w+)\s+([^}]*)}', DocObject._call_translate, line)
+
+
+def parse_doc(s):
+ if not s:
+ return
+ doc = DocObject()
+ tag = None
+ s = s[3:-2] # remove '/**' and '*/'
+ for line in s.splitlines():
+ line = line.lstrip(' *') # strip a ' ' and '*' from start
+ if not line:
+ tag = None # on empty line reset the tag information
+ elif line[0] == '@':
+ line = line[1:]
+ res = line.split(maxsplit=1)
+ if len(res) == 0:
+ continue
+ tag = res[0]
+ if len(res) == 1:
+ doc.add_tag(tag, True)
+ elif len(res) == 2:
+ value = res[1]
+ doc.add_tag(tag, value)
+ elif tag: # append to previous matched tag
+ doc.add_tag(tag, line)
+ return doc
+
diff --git a/qface/idl/domain.py b/qface/idl/domain.py
index a325b55..9fc553b 100644
--- a/qface/idl/domain.py
+++ b/qface/idl/domain.py
@@ -25,6 +25,7 @@ input for the code generation templates.
'''
from collections import OrderedDict, ChainMap
+import click
import logging
log = logging.getLogger(__name__)
@@ -53,40 +54,46 @@ class System(object):
if name in self._moduleMap:
return self._moduleMap[name]
# <module>.<Symbol>
- (module_name, type_name) = self.split_typename(name)
+ (module_name, type_name, fragment_name) = self.split_typename(name)
if not module_name and type_name:
click.secho('not able to lookup symbol: {0}'.format(name), fg='red')
return None
module = self._moduleMap[module_name]
- return module.lookup(type_name)
+ return module.lookup(type_name, fragment_name)
@staticmethod
def split_typename(name):
+ parts = name.rsplit('#', 1)
+ fragment_name = None
+ module_name = None
+ type_name = None
+ if len(parts) == 2:
+ fragment_name = parts[1]
+ name = parts[0]
parts = name.rsplit('.', 1)
if len(parts) == 1:
- return ('', parts[0])
- if len(parts) == 2:
- return parts
- return ('', '')
+ type_name = parts[0]
+ elif len(parts) == 2:
+ module_name = parts[0]
+ type_name = parts[1]
+ return (module_name, type_name, fragment_name)
-class Symbol(object):
- """A symbol represents a base class for names elements"""
- def __init__(self, name: str, module: 'Module'):
+class NamedElement(object):
+ def __init__(self, name, module: 'Module'):
self.name = name
"""symbol name"""
self.module = module
"""module the symbol belongs to"""
- self.comment = ''
- """comment which appeared in QFace right before symbol"""
- self._tags = OrderedDict()
+ def __unicode__(self):
+ return self.name
+ def __str__(self):
+ return self.name
- @property
- def system(self):
- '''returns reference to system'''
- return self.module._system
+ def __repr__(self):
+ return '<{0} name={1}>'.format(type(self), self.name)
@property
def qualified_name(self):
@@ -96,14 +103,22 @@ class Symbol(object):
else:
return '{0}.{1}'.format(self.module.name, self.name)
- def __unicode__(self):
- return self.name
- def __str__(self):
- return self.name
+class Symbol(NamedElement):
+ """A symbol represents a base class for names elements"""
+ def __init__(self, name: str, module: 'Module'):
+ super().__init__(name, module)
+ self.comment = ''
+ """comment which appeared in QFace right before symbol"""
+ self._tags = OrderedDict()
- def __repr__(self):
- return '<{0} name={1}>'.format(type(self), self.name)
+ self._contentMap = ChainMap()
+ self.type = TypeSymbol('', self)
+
+ @property
+ def system(self):
+ '''returns reference to system'''
+ return self.module._system
@property
def tags(self):
@@ -125,18 +140,15 @@ class Symbol(object):
if tag in self._tags:
return self._tags[tag][name]
+ @property
+ def contents(self):
+ return self._contentMap.values()
-class TypedSymbol(Symbol):
- """A symbol which has a type, like an operation or property."""
- def __init__(self, name: str, module: 'Module'):
- super().__init__(name, module)
- self.type = TypeSymbol("", self)
- """type object of the symbol"""
-class TypeSymbol(Symbol):
+class TypeSymbol(NamedElement):
"""Defines a type in the system"""
- def __init__(self, name: str, parent: Symbol):
+ def __init__(self, name: str, parent: NamedElement):
super().__init__(name, parent.module)
log.debug('TypeSymbol()')
self.parent = parent
@@ -151,6 +163,11 @@ class TypeSymbol(Symbol):
self.__is_resolved = False
@property
+ def is_valid(self):
+ '''checks if type is a valid type'''
+ return self.is_primitive or self.is_complex
+
+ @property
def is_bool(self):
'''checks if type is primitive and bool'''
return self.is_primitive and self.name == 'bool'
@@ -216,7 +233,7 @@ class Module(Symbol):
self._interfaceMap = OrderedDict() # type: dict[str, Interface]
self._structMap = OrderedDict() # type: dict[str, Struct]
self._enumMap = OrderedDict() # type: dict[str, Enum]
- self._definitionMap = ChainMap(self._interfaceMap, self._structMap, self._enumMap)
+ self._contentMap = ChainMap(self._interfaceMap, self._structMap, self._enumMap)
self._importMap = OrderedDict() # type: dict[str, Module]
@property
@@ -242,7 +259,7 @@ class Module(Symbol):
def checkType(self, type: str):
if type.is_primitive:
return True
- (module_name, type_name) = System.split_typename(type.name)
+ (module_name, type_name, fragment_name) = System.split_typename(type.name)
if module_name and module_name not in self._importMap:
return False
return True
@@ -256,23 +273,27 @@ class Module(Symbol):
def module_name(self):
return self.name.split('.')[-1].capitalize()
- def lookup(self, name: str):
+ def lookup(self, name: str, fragment: str = None):
'''lookup a symbol by name. If symbol is not local
it will be looked up system wide'''
- if name in self._definitionMap:
- return self._definitionMap[name]
+ if name in self._contentMap:
+ symbol = self._contentMap[name]
+ if fragment:
+ return symbol._contentMap[fragment]
+ return symbol
return self.system.lookup(name)
class Interface(Symbol):
- """A interface is an object with operations, properties and events"""
+ """A interface is an object with operations, properties and signals"""
def __init__(self, name: str, module: Module):
super().__init__(name, module)
log.debug('Interface()')
self.module._interfaceMap[name] = self
self._propertyMap = OrderedDict() # type: dict[str, Property]
self._operationMap = OrderedDict() # type: dict[str, Operation]
- self._eventMap = OrderedDict() # type: dict[str, Operation]
+ self._signalMap = OrderedDict() # type: dict[str, Signal]
+ self._contentMap = ChainMap(self._propertyMap, self._operationMap, self._signalMap)
@property
def properties(self):
@@ -285,23 +306,34 @@ class Interface(Symbol):
return self._operationMap.values()
@property
- def events(self):
- '''returns ordered list of events'''
- return self._eventMap.values()
+ def signals(self):
+ '''returns ordered list of signals'''
+ return self._signalMap.values()
-class Operation(TypedSymbol):
+class Operation(Symbol):
"""An operation inside a interface"""
- def __init__(self, name: str, interface: Interface, is_event=False):
+ def __init__(self, name: str, interface: Interface):
super().__init__(name, interface.module)
log.debug('Operation()')
self.interface = interface
- self.is_event = is_event
- if is_event:
- self.interface._eventMap[name] = self
- else:
- self.interface._operationMap[name] = self
- self._parameterMap = OrderedDict() # type: dict[Parameter]
+ self.interface._operationMap[name] = self
+ self._parameterMap = self._contentMap = OrderedDict() # type: dict[Parameter]
+
+ @property
+ def parameters(self):
+ '''returns ordered list of parameters'''
+ return self._parameterMap.values()
+
+
+class Signal(Symbol):
+ """A signal inside an interface"""
+ def __init__(self, name: str, interface: Interface):
+ super().__init__(name, interface.module)
+ log.debug('Signal()')
+ self.interface = interface
+ self.interface._signalMap[name] = self
+ self._parameterMap = self._contentMap = OrderedDict() # type: dict[Parameter]
@property
def parameters(self):
@@ -309,7 +341,7 @@ class Operation(TypedSymbol):
return self._parameterMap.values()
-class Parameter(TypedSymbol):
+class Parameter(Symbol):
"""An operation parameter"""
def __init__(self, name: str, operation: Operation):
super().__init__(name, operation.module)
@@ -318,7 +350,7 @@ class Parameter(TypedSymbol):
self.operation._parameterMap[name] = self
-class Property(TypedSymbol):
+class Property(Symbol):
"""A typed property inside a interface"""
def __init__(self, name: str, interface: Interface):
super().__init__(name, interface.module)
@@ -334,7 +366,7 @@ class Struct(Symbol):
super().__init__(name, module)
log.debug('Struct()')
self.module._structMap[name] = self
- self._fieldMap = OrderedDict() # type: dict[str, Field]
+ self._fieldMap = self._contentMap = OrderedDict() # type: dict[str, Field]
@property
def fields(self):
@@ -342,7 +374,7 @@ class Struct(Symbol):
return self._fieldMap.values()
-class Field(TypedSymbol):
+class Field(Symbol):
"""A member in a struct"""
def __init__(self, name: str, struct: Struct):
super().__init__(name, struct.module)
@@ -359,7 +391,7 @@ class Enum(Symbol):
self.is_enum = True
self.is_flag = False
self.module._enumMap[name] = self
- self._memberMap = OrderedDict() # type: dict[EnumMember]
+ self._memberMap = self._contentMap = OrderedDict() # type: dict[EnumMember]
@property
def members(self):
diff --git a/qface/idl/listener.py b/qface/idl/listener.py
index 2bbad25..826f44f 100644
--- a/qface/idl/listener.py
+++ b/qface/idl/listener.py
@@ -28,11 +28,13 @@ class DomainListener(TListener):
self.enum = None # type:Enum
self.enumCounter = 0 # int
self.operation = None # type:Operation
+ self.signal = None # type:Signal
self.parameter = None # type:Parameter
self.property = None # type:Property
self.field = None # type:Field
def parse_type(self, ctx: ParserRuleContext, type: TypeSymbol):
+ assert type
if not ctx.typeSymbol():
type.is_void = True
type.name = 'void'
@@ -87,6 +89,8 @@ class DomainListener(TListener):
self.module = Module(name, self.system)
self.module.version = version
contextMap[ctx] = self.module
+ self.parse_annotations(ctx, self.module)
+
def exitModuleSymbol(self, ctx: TParser.ModuleSymbolContext):
pass
@@ -137,8 +141,7 @@ class DomainListener(TListener):
def enterOperationSymbol(self, ctx: TParser.OperationSymbolContext):
assert self.interface
name = ctx.name.text
- is_event = bool(ctx.isEvent)
- self.operation = Operation(name, self.interface, is_event)
+ self.operation = Operation(name, self.interface)
self.parse_annotations(ctx, self.operation)
self.parse_type(ctx, self.operation.type)
contextMap[ctx] = self.operation
@@ -146,9 +149,20 @@ class DomainListener(TListener):
def exitOperationSymbol(self, ctx: TParser.OperationSymbolContext):
self.operation = None
+ def enterSignalSymbol(self, ctx: TParser.SignalSymbolContext):
+ assert self.interface
+ name = ctx.name.text
+ self.signal = Signal(name, self.interface)
+ self.parse_annotations(ctx, self.operation)
+ contextMap[ctx] = self.signal
+
+ def exitSignalSymbol(self, ctx: TParser.SignalSymbolContext):
+ self.signal = None
+
def enterOperationParameterSymbol(self, ctx: TParser.OperationParameterSymbolContext):
name = ctx.name.text
- self.parameter = Parameter(name, self.operation)
+ symbol = self.operation if self.operation else self.signal
+ self.parameter = Parameter(name, symbol)
contextMap[ctx] = self.parameter
def exitOperationParameterSymbol(self, ctx: TParser.OperationParameterSymbolContext):
diff --git a/qface/idl/parser/T.g4 b/qface/idl/parser/T.g4
index 6f1e1c1..3782c91 100644
--- a/qface/idl/parser/T.g4
+++ b/qface/idl/parser/T.g4
@@ -35,12 +35,18 @@ interfaceSymbol
interfaceMemberSymbol
: operationSymbol
| propertySymbol
+ | signalSymbol
;
operationSymbol
- : comment=DOCCOMMENT? tagSymbol* isEvent='event'? (typeSymbol | 'void') name=IDENTIFIER '(' operationParameterSymbol* ')' ';'?
+ : comment=DOCCOMMENT? tagSymbol* (typeSymbol | 'void') name=IDENTIFIER '(' operationParameterSymbol* ')' ';'?
;
+signalSymbol
+ : comment=DOCCOMMENT? tagSymbol* 'signal' name=IDENTIFIER '(' operationParameterSymbol* ')' ';'?
+ ;
+
+
propertySymbol
: comment=DOCCOMMENT? tagSymbol* isReadOnly='readonly'? typeSymbol name=IDENTIFIER ';'?
;
@@ -115,7 +121,7 @@ HEXCONSTANT : '0x' ('0'..'9' | 'a'..'f' | 'A'..'F')+;
TAGIDENTIFIER : '@'[a-zA-Z_][a-zA-Z0-9_.]*;
IDENTIFIER : [a-zA-Z_][a-zA-Z0-9_.]*;
VERSION : [0-9]'.'[0-9];
-DOCCOMMENT : '/*!' .*? '*/';
+DOCCOMMENT : '/**' .*? '*/';
WHITESPACE : [ \t\r\n]+ -> skip;
COMMENT : '//' ~[\r\n]* -> skip;
MULTICOMM : '/*' .*? '*/' -> skip;
diff --git a/qface/idl/parser/T.tokens b/qface/idl/parser/T.tokens
index 4241ad3..25c2f2f 100644
--- a/qface/idl/parser/T.tokens
+++ b/qface/idl/parser/T.tokens
@@ -38,10 +38,10 @@ MULTICOMM=34
'interface'=4
'{'=5
'}'=6
-'event'=7
-'void'=8
-'('=9
-')'=10
+'void'=7
+'('=8
+')'=9
+'signal'=10
'readonly'=11
','=12
'='=13
diff --git a/qface/idl/parser/TLexer.py b/qface/idl/parser/TLexer.py
index 9feb45c..167f9ef 100644
--- a/qface/idl/parser/TLexer.py
+++ b/qface/idl/parser/TLexer.py
@@ -6,7 +6,7 @@ from io import StringIO
def serializedATN():
with StringIO() as buf:
buf.write("\3\u0430\ud6d1\u8206\uad2d\u4417\uaef1\u8d80\uaadd\2$")
- buf.write("\u010a\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("\u010b\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")
@@ -14,106 +14,107 @@ def serializedATN():
buf.write("\t\36\4\37\t\37\4 \t \4!\t!\4\"\t\"\4#\t#\3\2\3\2\3\2")
buf.write("\3\2\3\2\3\2\3\2\3\3\3\3\3\4\3\4\3\4\3\4\3\4\3\4\3\4\3")
buf.write("\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\6\3\6\3\7\3\7")
- buf.write("\3\b\3\b\3\b\3\b\3\b\3\b\3\t\3\t\3\t\3\t\3\t\3\n\3\n\3")
- buf.write("\13\3\13\3\f\3\f\3\f\3\f\3\f\3\f\3\f\3\f\3\f\3\r\3\r\3")
- buf.write("\16\3\16\3\17\3\17\3\17\3\17\3\17\3\20\3\20\3\20\3\20")
- buf.write("\3\21\3\21\3\21\3\21\3\21\3\22\3\22\3\22\3\22\3\22\3\22")
- buf.write("\3\22\3\23\3\23\3\23\3\23\3\24\3\24\3\24\3\24\3\24\3\25")
- buf.write("\3\25\3\26\3\26\3\27\3\27\3\27\3\27\3\27\3\27\3\30\3\30")
- buf.write("\3\30\3\30\3\30\3\30\3\30\3\31\3\31\3\31\3\31\3\31\3\32")
- buf.write("\3\32\3\32\3\32\3\32\3\33\5\33\u00bc\n\33\3\33\6\33\u00bf")
- buf.write("\n\33\r\33\16\33\u00c0\3\34\3\34\3\34\3\34\6\34\u00c7")
- buf.write("\n\34\r\34\16\34\u00c8\3\35\3\35\3\35\7\35\u00ce\n\35")
- buf.write("\f\35\16\35\u00d1\13\35\3\36\3\36\7\36\u00d5\n\36\f\36")
- buf.write("\16\36\u00d8\13\36\3\37\3\37\3\37\3\37\3 \3 \3 \3 \3 ")
- buf.write("\7 \u00e3\n \f \16 \u00e6\13 \3 \3 \3 \3!\6!\u00ec\n!")
- buf.write("\r!\16!\u00ed\3!\3!\3\"\3\"\3\"\3\"\7\"\u00f6\n\"\f\"")
- buf.write("\16\"\u00f9\13\"\3\"\3\"\3#\3#\3#\3#\7#\u0101\n#\f#\16")
- buf.write("#\u0104\13#\3#\3#\3#\3#\3#\4\u00e4\u0102\2$\3\3\5\4\7")
- buf.write("\5\t\6\13\7\r\b\17\t\21\n\23\13\25\f\27\r\31\16\33\17")
- buf.write("\35\20\37\21!\22#\23%\24\'\25)\26+\27-\30/\31\61\32\63")
- buf.write("\33\65\34\67\359\36;\37= ?!A\"C#E$\3\2\t\4\2--//\5\2\62")
- buf.write(";CHch\5\2C\\aac|\7\2\60\60\62;C\\aac|\3\2\62;\5\2\13\f")
- buf.write("\17\17\"\"\4\2\f\f\17\17\u0112\2\3\3\2\2\2\2\5\3\2\2\2")
- buf.write("\2\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")
- buf.write("\3\2\2\2\2\21\3\2\2\2\2\23\3\2\2\2\2\25\3\2\2\2\2\27\3")
- buf.write("\2\2\2\2\31\3\2\2\2\2\33\3\2\2\2\2\35\3\2\2\2\2\37\3\2")
- buf.write("\2\2\2!\3\2\2\2\2#\3\2\2\2\2%\3\2\2\2\2\'\3\2\2\2\2)\3")
- buf.write("\2\2\2\2+\3\2\2\2\2-\3\2\2\2\2/\3\2\2\2\2\61\3\2\2\2\2")
- buf.write("\63\3\2\2\2\2\65\3\2\2\2\2\67\3\2\2\2\29\3\2\2\2\2;\3")
- buf.write("\2\2\2\2=\3\2\2\2\2?\3\2\2\2\2A\3\2\2\2\2C\3\2\2\2\2E")
- buf.write("\3\2\2\2\3G\3\2\2\2\5N\3\2\2\2\7P\3\2\2\2\tW\3\2\2\2\13")
- buf.write("a\3\2\2\2\rc\3\2\2\2\17e\3\2\2\2\21k\3\2\2\2\23p\3\2\2")
- buf.write("\2\25r\3\2\2\2\27t\3\2\2\2\31}\3\2\2\2\33\177\3\2\2\2")
- buf.write("\35\u0081\3\2\2\2\37\u0086\3\2\2\2!\u008a\3\2\2\2#\u008f")
- buf.write("\3\2\2\2%\u0096\3\2\2\2\'\u009a\3\2\2\2)\u009f\3\2\2\2")
- buf.write("+\u00a1\3\2\2\2-\u00a3\3\2\2\2/\u00a9\3\2\2\2\61\u00b0")
- buf.write("\3\2\2\2\63\u00b5\3\2\2\2\65\u00bb\3\2\2\2\67\u00c2\3")
- buf.write("\2\2\29\u00ca\3\2\2\2;\u00d2\3\2\2\2=\u00d9\3\2\2\2?\u00dd")
- buf.write("\3\2\2\2A\u00eb\3\2\2\2C\u00f1\3\2\2\2E\u00fc\3\2\2\2")
- buf.write("GH\7k\2\2HI\7o\2\2IJ\7r\2\2JK\7q\2\2KL\7t\2\2LM\7v\2\2")
- buf.write("M\4\3\2\2\2NO\7=\2\2O\6\3\2\2\2PQ\7o\2\2QR\7q\2\2RS\7")
- buf.write("f\2\2ST\7w\2\2TU\7n\2\2UV\7g\2\2V\b\3\2\2\2WX\7k\2\2X")
- buf.write("Y\7p\2\2YZ\7v\2\2Z[\7g\2\2[\\\7t\2\2\\]\7h\2\2]^\7c\2")
- buf.write("\2^_\7e\2\2_`\7g\2\2`\n\3\2\2\2ab\7}\2\2b\f\3\2\2\2cd")
- buf.write("\7\177\2\2d\16\3\2\2\2ef\7g\2\2fg\7x\2\2gh\7g\2\2hi\7")
- buf.write("p\2\2ij\7v\2\2j\20\3\2\2\2kl\7x\2\2lm\7q\2\2mn\7k\2\2")
- buf.write("no\7f\2\2o\22\3\2\2\2pq\7*\2\2q\24\3\2\2\2rs\7+\2\2s\26")
- buf.write("\3\2\2\2tu\7t\2\2uv\7g\2\2vw\7c\2\2wx\7f\2\2xy\7q\2\2")
- buf.write("yz\7p\2\2z{\7n\2\2{|\7{\2\2|\30\3\2\2\2}~\7.\2\2~\32\3")
- buf.write("\2\2\2\177\u0080\7?\2\2\u0080\34\3\2\2\2\u0081\u0082\7")
- buf.write("d\2\2\u0082\u0083\7q\2\2\u0083\u0084\7q\2\2\u0084\u0085")
- buf.write("\7n\2\2\u0085\36\3\2\2\2\u0086\u0087\7k\2\2\u0087\u0088")
- buf.write("\7p\2\2\u0088\u0089\7v\2\2\u0089 \3\2\2\2\u008a\u008b")
- buf.write("\7t\2\2\u008b\u008c\7g\2\2\u008c\u008d\7c\2\2\u008d\u008e")
- buf.write("\7n\2\2\u008e\"\3\2\2\2\u008f\u0090\7u\2\2\u0090\u0091")
- buf.write("\7v\2\2\u0091\u0092\7t\2\2\u0092\u0093\7k\2\2\u0093\u0094")
- buf.write("\7p\2\2\u0094\u0095\7i\2\2\u0095$\3\2\2\2\u0096\u0097")
- buf.write("\7x\2\2\u0097\u0098\7c\2\2\u0098\u0099\7t\2\2\u0099&\3")
- buf.write("\2\2\2\u009a\u009b\7n\2\2\u009b\u009c\7k\2\2\u009c\u009d")
- buf.write("\7u\2\2\u009d\u009e\7v\2\2\u009e(\3\2\2\2\u009f\u00a0")
- buf.write("\7>\2\2\u00a0*\3\2\2\2\u00a1\u00a2\7@\2\2\u00a2,\3\2\2")
- buf.write("\2\u00a3\u00a4\7o\2\2\u00a4\u00a5\7q\2\2\u00a5\u00a6\7")
- buf.write("f\2\2\u00a6\u00a7\7g\2\2\u00a7\u00a8\7n\2\2\u00a8.\3\2")
- buf.write("\2\2\u00a9\u00aa\7u\2\2\u00aa\u00ab\7v\2\2\u00ab\u00ac")
- buf.write("\7t\2\2\u00ac\u00ad\7w\2\2\u00ad\u00ae\7e\2\2\u00ae\u00af")
- buf.write("\7v\2\2\u00af\60\3\2\2\2\u00b0\u00b1\7g\2\2\u00b1\u00b2")
- buf.write("\7p\2\2\u00b2\u00b3\7w\2\2\u00b3\u00b4\7o\2\2\u00b4\62")
- buf.write("\3\2\2\2\u00b5\u00b6\7h\2\2\u00b6\u00b7\7n\2\2\u00b7\u00b8")
- buf.write("\7c\2\2\u00b8\u00b9\7i\2\2\u00b9\64\3\2\2\2\u00ba\u00bc")
- buf.write("\t\2\2\2\u00bb\u00ba\3\2\2\2\u00bb\u00bc\3\2\2\2\u00bc")
- buf.write("\u00be\3\2\2\2\u00bd\u00bf\4\62;\2\u00be\u00bd\3\2\2\2")
- buf.write("\u00bf\u00c0\3\2\2\2\u00c0\u00be\3\2\2\2\u00c0\u00c1\3")
- buf.write("\2\2\2\u00c1\66\3\2\2\2\u00c2\u00c3\7\62\2\2\u00c3\u00c4")
- buf.write("\7z\2\2\u00c4\u00c6\3\2\2\2\u00c5\u00c7\t\3\2\2\u00c6")
- buf.write("\u00c5\3\2\2\2\u00c7\u00c8\3\2\2\2\u00c8\u00c6\3\2\2\2")
- buf.write("\u00c8\u00c9\3\2\2\2\u00c98\3\2\2\2\u00ca\u00cb\7B\2\2")
- buf.write("\u00cb\u00cf\t\4\2\2\u00cc\u00ce\t\5\2\2\u00cd\u00cc\3")
- buf.write("\2\2\2\u00ce\u00d1\3\2\2\2\u00cf\u00cd\3\2\2\2\u00cf\u00d0")
- buf.write("\3\2\2\2\u00d0:\3\2\2\2\u00d1\u00cf\3\2\2\2\u00d2\u00d6")
- buf.write("\t\4\2\2\u00d3\u00d5\t\5\2\2\u00d4\u00d3\3\2\2\2\u00d5")
- buf.write("\u00d8\3\2\2\2\u00d6\u00d4\3\2\2\2\u00d6\u00d7\3\2\2\2")
- buf.write("\u00d7<\3\2\2\2\u00d8\u00d6\3\2\2\2\u00d9\u00da\t\6\2")
- buf.write("\2\u00da\u00db\7\60\2\2\u00db\u00dc\t\6\2\2\u00dc>\3\2")
- buf.write("\2\2\u00dd\u00de\7\61\2\2\u00de\u00df\7,\2\2\u00df\u00e0")
- buf.write("\7#\2\2\u00e0\u00e4\3\2\2\2\u00e1\u00e3\13\2\2\2\u00e2")
- buf.write("\u00e1\3\2\2\2\u00e3\u00e6\3\2\2\2\u00e4\u00e5\3\2\2\2")
- buf.write("\u00e4\u00e2\3\2\2\2\u00e5\u00e7\3\2\2\2\u00e6\u00e4\3")
- buf.write("\2\2\2\u00e7\u00e8\7,\2\2\u00e8\u00e9\7\61\2\2\u00e9@")
- buf.write("\3\2\2\2\u00ea\u00ec\t\7\2\2\u00eb\u00ea\3\2\2\2\u00ec")
- buf.write("\u00ed\3\2\2\2\u00ed\u00eb\3\2\2\2\u00ed\u00ee\3\2\2\2")
- buf.write("\u00ee\u00ef\3\2\2\2\u00ef\u00f0\b!\2\2\u00f0B\3\2\2\2")
- buf.write("\u00f1\u00f2\7\61\2\2\u00f2\u00f3\7\61\2\2\u00f3\u00f7")
- buf.write("\3\2\2\2\u00f4\u00f6\n\b\2\2\u00f5\u00f4\3\2\2\2\u00f6")
- buf.write("\u00f9\3\2\2\2\u00f7\u00f5\3\2\2\2\u00f7\u00f8\3\2\2\2")
- buf.write("\u00f8\u00fa\3\2\2\2\u00f9\u00f7\3\2\2\2\u00fa\u00fb\b")
- buf.write("\"\2\2\u00fbD\3\2\2\2\u00fc\u00fd\7\61\2\2\u00fd\u00fe")
- buf.write("\7,\2\2\u00fe\u0102\3\2\2\2\u00ff\u0101\13\2\2\2\u0100")
- buf.write("\u00ff\3\2\2\2\u0101\u0104\3\2\2\2\u0102\u0103\3\2\2\2")
- buf.write("\u0102\u0100\3\2\2\2\u0103\u0105\3\2\2\2\u0104\u0102\3")
- buf.write("\2\2\2\u0105\u0106\7,\2\2\u0106\u0107\7\61\2\2\u0107\u0108")
- buf.write("\3\2\2\2\u0108\u0109\b#\2\2\u0109F\3\2\2\2\f\2\u00bb\u00c0")
- buf.write("\u00c8\u00cf\u00d6\u00e4\u00ed\u00f7\u0102\3\b\2\2")
+ buf.write("\3\b\3\b\3\b\3\b\3\b\3\t\3\t\3\n\3\n\3\13\3\13\3\13\3")
+ buf.write("\13\3\13\3\13\3\13\3\f\3\f\3\f\3\f\3\f\3\f\3\f\3\f\3\f")
+ buf.write("\3\r\3\r\3\16\3\16\3\17\3\17\3\17\3\17\3\17\3\20\3\20")
+ buf.write("\3\20\3\20\3\21\3\21\3\21\3\21\3\21\3\22\3\22\3\22\3\22")
+ buf.write("\3\22\3\22\3\22\3\23\3\23\3\23\3\23\3\24\3\24\3\24\3\24")
+ buf.write("\3\24\3\25\3\25\3\26\3\26\3\27\3\27\3\27\3\27\3\27\3\27")
+ buf.write("\3\30\3\30\3\30\3\30\3\30\3\30\3\30\3\31\3\31\3\31\3\31")
+ buf.write("\3\31\3\32\3\32\3\32\3\32\3\32\3\33\5\33\u00bd\n\33\3")
+ buf.write("\33\6\33\u00c0\n\33\r\33\16\33\u00c1\3\34\3\34\3\34\3")
+ buf.write("\34\6\34\u00c8\n\34\r\34\16\34\u00c9\3\35\3\35\3\35\7")
+ buf.write("\35\u00cf\n\35\f\35\16\35\u00d2\13\35\3\36\3\36\7\36\u00d6")
+ buf.write("\n\36\f\36\16\36\u00d9\13\36\3\37\3\37\3\37\3\37\3 \3")
+ buf.write(" \3 \3 \3 \7 \u00e4\n \f \16 \u00e7\13 \3 \3 \3 \3!\6")
+ buf.write("!\u00ed\n!\r!\16!\u00ee\3!\3!\3\"\3\"\3\"\3\"\7\"\u00f7")
+ buf.write("\n\"\f\"\16\"\u00fa\13\"\3\"\3\"\3#\3#\3#\3#\7#\u0102")
+ buf.write("\n#\f#\16#\u0105\13#\3#\3#\3#\3#\3#\4\u00e5\u0103\2$\3")
+ buf.write("\3\5\4\7\5\t\6\13\7\r\b\17\t\21\n\23\13\25\f\27\r\31\16")
+ buf.write("\33\17\35\20\37\21!\22#\23%\24\'\25)\26+\27-\30/\31\61")
+ buf.write("\32\63\33\65\34\67\359\36;\37= ?!A\"C#E$\3\2\t\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\"\"\4\2\f\f\17\17\u0113\2\3\3\2\2\2\2")
+ buf.write("\5\3\2\2\2\2\7\3\2\2\2\2\t\3\2\2\2\2\13\3\2\2\2\2\r\3")
+ buf.write("\2\2\2\2\17\3\2\2\2\2\21\3\2\2\2\2\23\3\2\2\2\2\25\3\2")
+ buf.write("\2\2\2\27\3\2\2\2\2\31\3\2\2\2\2\33\3\2\2\2\2\35\3\2\2")
+ buf.write("\2\2\37\3\2\2\2\2!\3\2\2\2\2#\3\2\2\2\2%\3\2\2\2\2\'\3")
+ buf.write("\2\2\2\2)\3\2\2\2\2+\3\2\2\2\2-\3\2\2\2\2/\3\2\2\2\2\61")
+ buf.write("\3\2\2\2\2\63\3\2\2\2\2\65\3\2\2\2\2\67\3\2\2\2\29\3\2")
+ buf.write("\2\2\2;\3\2\2\2\2=\3\2\2\2\2?\3\2\2\2\2A\3\2\2\2\2C\3")
+ buf.write("\2\2\2\2E\3\2\2\2\3G\3\2\2\2\5N\3\2\2\2\7P\3\2\2\2\tW")
+ buf.write("\3\2\2\2\13a\3\2\2\2\rc\3\2\2\2\17e\3\2\2\2\21j\3\2\2")
+ buf.write("\2\23l\3\2\2\2\25n\3\2\2\2\27u\3\2\2\2\31~\3\2\2\2\33")
+ buf.write("\u0080\3\2\2\2\35\u0082\3\2\2\2\37\u0087\3\2\2\2!\u008b")
+ buf.write("\3\2\2\2#\u0090\3\2\2\2%\u0097\3\2\2\2\'\u009b\3\2\2\2")
+ buf.write(")\u00a0\3\2\2\2+\u00a2\3\2\2\2-\u00a4\3\2\2\2/\u00aa\3")
+ buf.write("\2\2\2\61\u00b1\3\2\2\2\63\u00b6\3\2\2\2\65\u00bc\3\2")
+ buf.write("\2\2\67\u00c3\3\2\2\29\u00cb\3\2\2\2;\u00d3\3\2\2\2=\u00da")
+ buf.write("\3\2\2\2?\u00de\3\2\2\2A\u00ec\3\2\2\2C\u00f2\3\2\2\2")
+ buf.write("E\u00fd\3\2\2\2GH\7k\2\2HI\7o\2\2IJ\7r\2\2JK\7q\2\2KL")
+ buf.write("\7t\2\2LM\7v\2\2M\4\3\2\2\2NO\7=\2\2O\6\3\2\2\2PQ\7o\2")
+ buf.write("\2QR\7q\2\2RS\7f\2\2ST\7w\2\2TU\7n\2\2UV\7g\2\2V\b\3\2")
+ buf.write("\2\2WX\7k\2\2XY\7p\2\2YZ\7v\2\2Z[\7g\2\2[\\\7t\2\2\\]")
+ buf.write("\7h\2\2]^\7c\2\2^_\7e\2\2_`\7g\2\2`\n\3\2\2\2ab\7}\2\2")
+ buf.write("b\f\3\2\2\2cd\7\177\2\2d\16\3\2\2\2ef\7x\2\2fg\7q\2\2")
+ buf.write("gh\7k\2\2hi\7f\2\2i\20\3\2\2\2jk\7*\2\2k\22\3\2\2\2lm")
+ buf.write("\7+\2\2m\24\3\2\2\2no\7u\2\2op\7k\2\2pq\7i\2\2qr\7p\2")
+ buf.write("\2rs\7c\2\2st\7n\2\2t\26\3\2\2\2uv\7t\2\2vw\7g\2\2wx\7")
+ buf.write("c\2\2xy\7f\2\2yz\7q\2\2z{\7p\2\2{|\7n\2\2|}\7{\2\2}\30")
+ buf.write("\3\2\2\2~\177\7.\2\2\177\32\3\2\2\2\u0080\u0081\7?\2\2")
+ buf.write("\u0081\34\3\2\2\2\u0082\u0083\7d\2\2\u0083\u0084\7q\2")
+ buf.write("\2\u0084\u0085\7q\2\2\u0085\u0086\7n\2\2\u0086\36\3\2")
+ buf.write("\2\2\u0087\u0088\7k\2\2\u0088\u0089\7p\2\2\u0089\u008a")
+ buf.write("\7v\2\2\u008a \3\2\2\2\u008b\u008c\7t\2\2\u008c\u008d")
+ buf.write("\7g\2\2\u008d\u008e\7c\2\2\u008e\u008f\7n\2\2\u008f\"")
+ buf.write("\3\2\2\2\u0090\u0091\7u\2\2\u0091\u0092\7v\2\2\u0092\u0093")
+ buf.write("\7t\2\2\u0093\u0094\7k\2\2\u0094\u0095\7p\2\2\u0095\u0096")
+ buf.write("\7i\2\2\u0096$\3\2\2\2\u0097\u0098\7x\2\2\u0098\u0099")
+ buf.write("\7c\2\2\u0099\u009a\7t\2\2\u009a&\3\2\2\2\u009b\u009c")
+ buf.write("\7n\2\2\u009c\u009d\7k\2\2\u009d\u009e\7u\2\2\u009e\u009f")
+ buf.write("\7v\2\2\u009f(\3\2\2\2\u00a0\u00a1\7>\2\2\u00a1*\3\2\2")
+ buf.write("\2\u00a2\u00a3\7@\2\2\u00a3,\3\2\2\2\u00a4\u00a5\7o\2")
+ buf.write("\2\u00a5\u00a6\7q\2\2\u00a6\u00a7\7f\2\2\u00a7\u00a8\7")
+ buf.write("g\2\2\u00a8\u00a9\7n\2\2\u00a9.\3\2\2\2\u00aa\u00ab\7")
+ buf.write("u\2\2\u00ab\u00ac\7v\2\2\u00ac\u00ad\7t\2\2\u00ad\u00ae")
+ buf.write("\7w\2\2\u00ae\u00af\7e\2\2\u00af\u00b0\7v\2\2\u00b0\60")
+ buf.write("\3\2\2\2\u00b1\u00b2\7g\2\2\u00b2\u00b3\7p\2\2\u00b3\u00b4")
+ buf.write("\7w\2\2\u00b4\u00b5\7o\2\2\u00b5\62\3\2\2\2\u00b6\u00b7")
+ buf.write("\7h\2\2\u00b7\u00b8\7n\2\2\u00b8\u00b9\7c\2\2\u00b9\u00ba")
+ buf.write("\7i\2\2\u00ba\64\3\2\2\2\u00bb\u00bd\t\2\2\2\u00bc\u00bb")
+ buf.write("\3\2\2\2\u00bc\u00bd\3\2\2\2\u00bd\u00bf\3\2\2\2\u00be")
+ buf.write("\u00c0\4\62;\2\u00bf\u00be\3\2\2\2\u00c0\u00c1\3\2\2\2")
+ buf.write("\u00c1\u00bf\3\2\2\2\u00c1\u00c2\3\2\2\2\u00c2\66\3\2")
+ buf.write("\2\2\u00c3\u00c4\7\62\2\2\u00c4\u00c5\7z\2\2\u00c5\u00c7")
+ buf.write("\3\2\2\2\u00c6\u00c8\t\3\2\2\u00c7\u00c6\3\2\2\2\u00c8")
+ buf.write("\u00c9\3\2\2\2\u00c9\u00c7\3\2\2\2\u00c9\u00ca\3\2\2\2")
+ buf.write("\u00ca8\3\2\2\2\u00cb\u00cc\7B\2\2\u00cc\u00d0\t\4\2\2")
+ buf.write("\u00cd\u00cf\t\5\2\2\u00ce\u00cd\3\2\2\2\u00cf\u00d2\3")
+ buf.write("\2\2\2\u00d0\u00ce\3\2\2\2\u00d0\u00d1\3\2\2\2\u00d1:")
+ buf.write("\3\2\2\2\u00d2\u00d0\3\2\2\2\u00d3\u00d7\t\4\2\2\u00d4")
+ buf.write("\u00d6\t\5\2\2\u00d5\u00d4\3\2\2\2\u00d6\u00d9\3\2\2\2")
+ buf.write("\u00d7\u00d5\3\2\2\2\u00d7\u00d8\3\2\2\2\u00d8<\3\2\2")
+ buf.write("\2\u00d9\u00d7\3\2\2\2\u00da\u00db\t\6\2\2\u00db\u00dc")
+ buf.write("\7\60\2\2\u00dc\u00dd\t\6\2\2\u00dd>\3\2\2\2\u00de\u00df")
+ buf.write("\7\61\2\2\u00df\u00e0\7,\2\2\u00e0\u00e1\7,\2\2\u00e1")
+ buf.write("\u00e5\3\2\2\2\u00e2\u00e4\13\2\2\2\u00e3\u00e2\3\2\2")
+ buf.write("\2\u00e4\u00e7\3\2\2\2\u00e5\u00e6\3\2\2\2\u00e5\u00e3")
+ buf.write("\3\2\2\2\u00e6\u00e8\3\2\2\2\u00e7\u00e5\3\2\2\2\u00e8")
+ buf.write("\u00e9\7,\2\2\u00e9\u00ea\7\61\2\2\u00ea@\3\2\2\2\u00eb")
+ buf.write("\u00ed\t\7\2\2\u00ec\u00eb\3\2\2\2\u00ed\u00ee\3\2\2\2")
+ buf.write("\u00ee\u00ec\3\2\2\2\u00ee\u00ef\3\2\2\2\u00ef\u00f0\3")
+ buf.write("\2\2\2\u00f0\u00f1\b!\2\2\u00f1B\3\2\2\2\u00f2\u00f3\7")
+ buf.write("\61\2\2\u00f3\u00f4\7\61\2\2\u00f4\u00f8\3\2\2\2\u00f5")
+ buf.write("\u00f7\n\b\2\2\u00f6\u00f5\3\2\2\2\u00f7\u00fa\3\2\2\2")
+ buf.write("\u00f8\u00f6\3\2\2\2\u00f8\u00f9\3\2\2\2\u00f9\u00fb\3")
+ buf.write("\2\2\2\u00fa\u00f8\3\2\2\2\u00fb\u00fc\b\"\2\2\u00fcD")
+ buf.write("\3\2\2\2\u00fd\u00fe\7\61\2\2\u00fe\u00ff\7,\2\2\u00ff")
+ buf.write("\u0103\3\2\2\2\u0100\u0102\13\2\2\2\u0101\u0100\3\2\2")
+ buf.write("\2\u0102\u0105\3\2\2\2\u0103\u0104\3\2\2\2\u0103\u0101")
+ buf.write("\3\2\2\2\u0104\u0106\3\2\2\2\u0105\u0103\3\2\2\2\u0106")
+ buf.write("\u0107\7,\2\2\u0107\u0108\7\61\2\2\u0108\u0109\3\2\2\2")
+ buf.write("\u0109\u010a\b#\2\2\u010aF\3\2\2\2\f\2\u00bc\u00c1\u00c9")
+ buf.write("\u00d0\u00d7\u00e5\u00ee\u00f8\u0103\3\b\2\2")
return buf.getvalue()
@@ -163,7 +164,7 @@ class TLexer(Lexer):
literalNames = [ "<INVALID>",
"'import'", "';'", "'module'", "'interface'", "'{'", "'}'",
- "'event'", "'void'", "'('", "')'", "'readonly'", "','", "'='",
+ "'void'", "'('", "')'", "'signal'", "'readonly'", "','", "'='",
"'bool'", "'int'", "'real'", "'string'", "'var'", "'list'",
"'<'", "'>'", "'model'", "'struct'", "'enum'", "'flag'" ]
diff --git a/qface/idl/parser/TLexer.tokens b/qface/idl/parser/TLexer.tokens
index 4241ad3..25c2f2f 100644
--- a/qface/idl/parser/TLexer.tokens
+++ b/qface/idl/parser/TLexer.tokens
@@ -38,10 +38,10 @@ MULTICOMM=34
'interface'=4
'{'=5
'}'=6
-'event'=7
-'void'=8
-'('=9
-')'=10
+'void'=7
+'('=8
+')'=9
+'signal'=10
'readonly'=11
','=12
'='=13
diff --git a/qface/idl/parser/TListener.py b/qface/idl/parser/TListener.py
index b1f0969..07d41ad 100644
--- a/qface/idl/parser/TListener.py
+++ b/qface/idl/parser/TListener.py
@@ -80,6 +80,15 @@ class TListener(ParseTreeListener):
pass
+ # Enter a parse tree produced by TParser#signalSymbol.
+ def enterSignalSymbol(self, ctx:TParser.SignalSymbolContext):
+ pass
+
+ # Exit a parse tree produced by TParser#signalSymbol.
+ def exitSignalSymbol(self, ctx:TParser.SignalSymbolContext):
+ pass
+
+
# Enter a parse tree produced by TParser#propertySymbol.
def enterPropertySymbol(self, ctx:TParser.PropertySymbolContext):
pass
diff --git a/qface/idl/parser/TParser.py b/qface/idl/parser/TParser.py
index 081f381..d43a416 100644
--- a/qface/idl/parser/TParser.py
+++ b/qface/idl/parser/TParser.py
@@ -6,136 +6,149 @@ from io import StringIO
def serializedATN():
with StringIO() as buf:
buf.write("\3\u0430\ud6d1\u8206\uad2d\u4417\uaef1\u8d80\uaadd\3$")
- buf.write("\u0120\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("\u0136\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\3\2")
- buf.write("\3\2\7\2\63\n\2\f\2\16\2\66\13\2\3\3\3\3\7\3:\n\3\f\3")
- buf.write("\16\3=\13\3\3\4\3\4\3\4\3\4\5\4C\n\4\3\5\5\5F\n\5\3\5")
- buf.write("\7\5I\n\5\f\5\16\5L\13\5\3\5\3\5\3\5\3\5\5\5R\n\5\3\6")
- buf.write("\3\6\3\6\5\6W\n\6\3\7\5\7Z\n\7\3\7\7\7]\n\7\f\7\16\7`")
- buf.write("\13\7\3\7\3\7\3\7\3\7\7\7f\n\7\f\7\16\7i\13\7\3\7\3\7")
- buf.write("\5\7m\n\7\3\b\3\b\5\bq\n\b\3\t\5\tt\n\t\3\t\7\tw\n\t\f")
- buf.write("\t\16\tz\13\t\3\t\5\t}\n\t\3\t\3\t\5\t\u0081\n\t\3\t\3")
- buf.write("\t\3\t\7\t\u0086\n\t\f\t\16\t\u0089\13\t\3\t\3\t\5\t\u008d")
+ 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\5\n\u0099\n\n\3\n\3\n\3\n\5\n\u009e\n\n\3\13")
- buf.write("\3\13\3\13\5\13\u00a3\n\13\3\f\3\f\3\f\7\f\u00a8\n\f\f")
- buf.write("\f\16\f\u00ab\13\f\3\f\3\f\3\r\3\r\3\r\5\r\u00b2\n\r\3")
- buf.write("\16\3\16\3\16\3\16\5\16\u00b8\n\16\3\17\3\17\3\20\3\20")
- buf.write("\3\20\3\20\3\20\5\20\u00c1\n\20\3\21\3\21\3\21\3\21\3")
- buf.write("\21\3\22\3\22\3\22\3\22\3\22\3\23\5\23\u00ce\n\23\3\23")
- buf.write("\7\23\u00d1\n\23\f\23\16\23\u00d4\13\23\3\23\3\23\3\23")
- buf.write("\3\23\7\23\u00da\n\23\f\23\16\23\u00dd\13\23\3\23\3\23")
- buf.write("\5\23\u00e1\n\23\3\24\5\24\u00e4\n\24\3\24\7\24\u00e7")
- buf.write("\n\24\f\24\16\24\u00ea\13\24\3\24\3\24\3\24\5\24\u00ef")
- buf.write("\n\24\3\25\5\25\u00f2\n\25\3\25\7\25\u00f5\n\25\f\25\16")
- buf.write("\25\u00f8\13\25\3\25\3\25\3\25\3\25\7\25\u00fe\n\25\f")
- buf.write("\25\16\25\u0101\13\25\3\25\3\25\5\25\u0105\n\25\3\26\3")
- buf.write("\26\5\26\u0109\n\26\3\27\5\27\u010c\n\27\3\27\7\27\u010f")
- buf.write("\n\27\f\27\16\27\u0112\13\27\3\27\3\27\3\27\5\27\u0117")
- buf.write("\n\27\3\27\5\27\u011a\n\27\3\30\3\30\5\30\u011e\n\30\3")
- buf.write("\30\2\2\31\2\4\6\b\n\f\16\20\22\24\26\30\32\34\36 \"$")
- buf.write("&(*,.\2\2\u013a\2\60\3\2\2\2\4\67\3\2\2\2\6>\3\2\2\2\b")
- buf.write("E\3\2\2\2\nV\3\2\2\2\fY\3\2\2\2\16p\3\2\2\2\20s\3\2\2")
- buf.write("\2\22\u008f\3\2\2\2\24\u009f\3\2\2\2\26\u00a4\3\2\2\2")
- buf.write("\30\u00ae\3\2\2\2\32\u00b7\3\2\2\2\34\u00b9\3\2\2\2\36")
- buf.write("\u00c0\3\2\2\2 \u00c2\3\2\2\2\"\u00c7\3\2\2\2$\u00cd\3")
- buf.write("\2\2\2&\u00e3\3\2\2\2(\u00f1\3\2\2\2*\u0108\3\2\2\2,\u010b")
- buf.write("\3\2\2\2.\u011d\3\2\2\2\60\64\5\4\3\2\61\63\5\n\6\2\62")
- buf.write("\61\3\2\2\2\63\66\3\2\2\2\64\62\3\2\2\2\64\65\3\2\2\2")
- buf.write("\65\3\3\2\2\2\66\64\3\2\2\2\67;\5\b\5\28:\5\6\4\298\3")
- buf.write("\2\2\2:=\3\2\2\2;9\3\2\2\2;<\3\2\2\2<\5\3\2\2\2=;\3\2")
- buf.write("\2\2>?\7\3\2\2?@\7\37\2\2@B\7 \2\2AC\7\4\2\2BA\3\2\2\2")
- buf.write("BC\3\2\2\2C\7\3\2\2\2DF\7!\2\2ED\3\2\2\2EF\3\2\2\2FJ\3")
- buf.write("\2\2\2GI\5\26\f\2HG\3\2\2\2IL\3\2\2\2JH\3\2\2\2JK\3\2")
- buf.write("\2\2KM\3\2\2\2LJ\3\2\2\2MN\7\5\2\2NO\7\37\2\2OQ\7 \2\2")
- buf.write("PR\7\4\2\2QP\3\2\2\2QR\3\2\2\2R\t\3\2\2\2SW\5\f\7\2TW")
- buf.write("\5$\23\2UW\5(\25\2VS\3\2\2\2VT\3\2\2\2VU\3\2\2\2W\13\3")
- buf.write("\2\2\2XZ\7!\2\2YX\3\2\2\2YZ\3\2\2\2Z^\3\2\2\2[]\5\26\f")
- buf.write("\2\\[\3\2\2\2]`\3\2\2\2^\\\3\2\2\2^_\3\2\2\2_a\3\2\2\2")
- buf.write("`^\3\2\2\2ab\7\6\2\2bc\7\37\2\2cg\7\7\2\2df\5\16\b\2e")
- buf.write("d\3\2\2\2fi\3\2\2\2ge\3\2\2\2gh\3\2\2\2hj\3\2\2\2ig\3")
- buf.write("\2\2\2jl\7\b\2\2km\7\4\2\2lk\3\2\2\2lm\3\2\2\2m\r\3\2")
- buf.write("\2\2nq\5\20\t\2oq\5\22\n\2pn\3\2\2\2po\3\2\2\2q\17\3\2")
- buf.write("\2\2rt\7!\2\2sr\3\2\2\2st\3\2\2\2tx\3\2\2\2uw\5\26\f\2")
- buf.write("vu\3\2\2\2wz\3\2\2\2xv\3\2\2\2xy\3\2\2\2y|\3\2\2\2zx\3")
- buf.write("\2\2\2{}\7\t\2\2|{\3\2\2\2|}\3\2\2\2}\u0080\3\2\2\2~\u0081")
- buf.write("\5\32\16\2\177\u0081\7\n\2\2\u0080~\3\2\2\2\u0080\177")
- buf.write("\3\2\2\2\u0081\u0082\3\2\2\2\u0082\u0083\7\37\2\2\u0083")
- buf.write("\u0087\7\13\2\2\u0084\u0086\5\24\13\2\u0085\u0084\3\2")
- buf.write("\2\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\f\2\2\u008b\u008d\7\4\2\2\u008c\u008b\3\2\2\2")
- buf.write("\u008c\u008d\3\2\2\2\u008d\21\3\2\2\2\u008e\u0090\7!\2")
- buf.write("\2\u008f\u008e\3\2\2\2\u008f\u0090\3\2\2\2\u0090\u0094")
- buf.write("\3\2\2\2\u0091\u0093\5\26\f\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\u0098\3\2\2\2\u0096\u0094\3\2\2\2\u0097\u0099\7")
- buf.write("\r\2\2\u0098\u0097\3\2\2\2\u0098\u0099\3\2\2\2\u0099\u009a")
- buf.write("\3\2\2\2\u009a\u009b\5\32\16\2\u009b\u009d\7\37\2\2\u009c")
- buf.write("\u009e\7\4\2\2\u009d\u009c\3\2\2\2\u009d\u009e\3\2\2\2")
- buf.write("\u009e\23\3\2\2\2\u009f\u00a0\5\32\16\2\u00a0\u00a2\7")
- buf.write("\37\2\2\u00a1\u00a3\7\16\2\2\u00a2\u00a1\3\2\2\2\u00a2")
- buf.write("\u00a3\3\2\2\2\u00a3\25\3\2\2\2\u00a4\u00a5\7\36\2\2\u00a5")
- buf.write("\u00a9\7\13\2\2\u00a6\u00a8\5\30\r\2\u00a7\u00a6\3\2\2")
- buf.write("\2\u00a8\u00ab\3\2\2\2\u00a9\u00a7\3\2\2\2\u00a9\u00aa")
- buf.write("\3\2\2\2\u00aa\u00ac\3\2\2\2\u00ab\u00a9\3\2\2\2\u00ac")
- buf.write("\u00ad\7\f\2\2\u00ad\27\3\2\2\2\u00ae\u00b1\7\37\2\2\u00af")
- buf.write("\u00b0\7\17\2\2\u00b0\u00b2\7\37\2\2\u00b1\u00af\3\2\2")
- buf.write("\2\u00b1\u00b2\3\2\2\2\u00b2\31\3\2\2\2\u00b3\u00b8\5")
- buf.write("\36\20\2\u00b4\u00b8\5\34\17\2\u00b5\u00b8\5 \21\2\u00b6")
- buf.write("\u00b8\5\"\22\2\u00b7\u00b3\3\2\2\2\u00b7\u00b4\3\2\2")
- buf.write("\2\u00b7\u00b5\3\2\2\2\u00b7\u00b6\3\2\2\2\u00b8\33\3")
- buf.write("\2\2\2\u00b9\u00ba\7\37\2\2\u00ba\35\3\2\2\2\u00bb\u00c1")
- buf.write("\7\20\2\2\u00bc\u00c1\7\21\2\2\u00bd\u00c1\7\22\2\2\u00be")
- buf.write("\u00c1\7\23\2\2\u00bf\u00c1\7\24\2\2\u00c0\u00bb\3\2\2")
- buf.write("\2\u00c0\u00bc\3\2\2\2\u00c0\u00bd\3\2\2\2\u00c0\u00be")
- buf.write("\3\2\2\2\u00c0\u00bf\3\2\2\2\u00c1\37\3\2\2\2\u00c2\u00c3")
- buf.write("\7\25\2\2\u00c3\u00c4\7\26\2\2\u00c4\u00c5\5\32\16\2\u00c5")
- buf.write("\u00c6\7\27\2\2\u00c6!\3\2\2\2\u00c7\u00c8\7\30\2\2\u00c8")
- buf.write("\u00c9\7\26\2\2\u00c9\u00ca\5\32\16\2\u00ca\u00cb\7\27")
- buf.write("\2\2\u00cb#\3\2\2\2\u00cc\u00ce\7!\2\2\u00cd\u00cc\3\2")
- buf.write("\2\2\u00cd\u00ce\3\2\2\2\u00ce\u00d2\3\2\2\2\u00cf\u00d1")
- buf.write("\5\26\f\2\u00d0\u00cf\3\2\2\2\u00d1\u00d4\3\2\2\2\u00d2")
- buf.write("\u00d0\3\2\2\2\u00d2\u00d3\3\2\2\2\u00d3\u00d5\3\2\2\2")
- buf.write("\u00d4\u00d2\3\2\2\2\u00d5\u00d6\7\31\2\2\u00d6\u00d7")
- buf.write("\7\37\2\2\u00d7\u00db\7\7\2\2\u00d8\u00da\5&\24\2\u00d9")
- buf.write("\u00d8\3\2\2\2\u00da\u00dd\3\2\2\2\u00db\u00d9\3\2\2\2")
- buf.write("\u00db\u00dc\3\2\2\2\u00dc\u00de\3\2\2\2\u00dd\u00db\3")
- buf.write("\2\2\2\u00de\u00e0\7\b\2\2\u00df\u00e1\7\4\2\2\u00e0\u00df")
- buf.write("\3\2\2\2\u00e0\u00e1\3\2\2\2\u00e1%\3\2\2\2\u00e2\u00e4")
+ 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\r\7\r\u00be\n\r\f\r\16\r\u00c1\13\r\3\r")
+ buf.write("\3\r\3\16\3\16\3\16\5\16\u00c8\n\16\3\17\3\17\3\17\3\17")
+ buf.write("\5\17\u00ce\n\17\3\20\3\20\3\21\3\21\3\21\3\21\3\21\5")
+ buf.write("\21\u00d7\n\21\3\22\3\22\3\22\3\22\3\22\3\23\3\23\3\23")
+ buf.write("\3\23\3\23\3\24\5\24\u00e4\n\24\3\24\7\24\u00e7\n\24\f")
+ buf.write("\24\16\24\u00ea\13\24\3\24\3\24\3\24\3\24\7\24\u00f0\n")
+ buf.write("\24\f\24\16\24\u00f3\13\24\3\24\3\24\5\24\u00f7\n\24\3")
+ buf.write("\25\5\25\u00fa\n\25\3\25\7\25\u00fd\n\25\f\25\16\25\u0100")
+ buf.write("\13\25\3\25\3\25\3\25\5\25\u0105\n\25\3\26\5\26\u0108")
+ buf.write("\n\26\3\26\7\26\u010b\n\26\f\26\16\26\u010e\13\26\3\26")
+ buf.write("\3\26\3\26\3\26\7\26\u0114\n\26\f\26\16\26\u0117\13\26")
+ buf.write("\3\26\3\26\5\26\u011b\n\26\3\27\3\27\5\27\u011f\n\27\3")
+ buf.write("\30\5\30\u0122\n\30\3\30\7\30\u0125\n\30\f\30\16\30\u0128")
+ buf.write("\13\30\3\30\3\30\3\30\5\30\u012d\n\30\3\30\5\30\u0130")
+ buf.write("\n\30\3\31\3\31\5\31\u0134\n\31\3\31\2\2\32\2\4\6\b\n")
+ buf.write("\f\16\20\22\24\26\30\32\34\36 \"$&(*,.\60\2\2\u0153\2")
+ buf.write("\62\3\2\2\2\49\3\2\2\2\6@\3\2\2\2\bG\3\2\2\2\nX\3\2\2")
+ buf.write("\2\f[\3\2\2\2\16s\3\2\2\2\20v\3\2\2\2\22\u008f\3\2\2\2")
+ buf.write("\24\u00a5\3\2\2\2\26\u00b5\3\2\2\2\30\u00ba\3\2\2\2\32")
+ buf.write("\u00c4\3\2\2\2\34\u00cd\3\2\2\2\36\u00cf\3\2\2\2 \u00d6")
+ buf.write("\3\2\2\2\"\u00d8\3\2\2\2$\u00dd\3\2\2\2&\u00e3\3\2\2\2")
+ buf.write("(\u00f9\3\2\2\2*\u0107\3\2\2\2,\u011e\3\2\2\2.\u0121\3")
+ buf.write("\2\2\2\60\u0133\3\2\2\2\62\66\5\4\3\2\63\65\5\n\6\2\64")
+ buf.write("\63\3\2\2\2\658\3\2\2\2\66\64\3\2\2\2\66\67\3\2\2\2\67")
+ buf.write("\3\3\2\2\28\66\3\2\2\29=\5\b\5\2:<\5\6\4\2;:\3\2\2\2<")
+ buf.write("?\3\2\2\2=;\3\2\2\2=>\3\2\2\2>\5\3\2\2\2?=\3\2\2\2@A\7")
+ buf.write("\3\2\2AB\7\37\2\2BD\7 \2\2CE\7\4\2\2DC\3\2\2\2DE\3\2\2")
+ buf.write("\2E\7\3\2\2\2FH\7!\2\2GF\3\2\2\2GH\3\2\2\2HL\3\2\2\2I")
+ buf.write("K\5\30\r\2JI\3\2\2\2KN\3\2\2\2LJ\3\2\2\2LM\3\2\2\2MO\3")
+ buf.write("\2\2\2NL\3\2\2\2OP\7\5\2\2PQ\7\37\2\2QS\7 \2\2RT\7\4\2")
+ buf.write("\2SR\3\2\2\2ST\3\2\2\2T\t\3\2\2\2UY\5\f\7\2VY\5&\24\2")
+ buf.write("WY\5*\26\2XU\3\2\2\2XV\3\2\2\2XW\3\2\2\2Y\13\3\2\2\2Z")
+ buf.write("\\\7!\2\2[Z\3\2\2\2[\\\3\2\2\2\\`\3\2\2\2]_\5\30\r\2^")
+ buf.write("]\3\2\2\2_b\3\2\2\2`^\3\2\2\2`a\3\2\2\2ac\3\2\2\2b`\3")
+ buf.write("\2\2\2cd\7\6\2\2de\7\37\2\2ei\7\7\2\2fh\5\16\b\2gf\3\2")
+ buf.write("\2\2hk\3\2\2\2ig\3\2\2\2ij\3\2\2\2jl\3\2\2\2ki\3\2\2\2")
+ buf.write("ln\7\b\2\2mo\7\4\2\2nm\3\2\2\2no\3\2\2\2o\r\3\2\2\2pt")
+ buf.write("\5\20\t\2qt\5\24\13\2rt\5\22\n\2sp\3\2\2\2sq\3\2\2\2s")
+ buf.write("r\3\2\2\2t\17\3\2\2\2uw\7!\2\2vu\3\2\2\2vw\3\2\2\2w{\3")
+ buf.write("\2\2\2xz\5\30\r\2yx\3\2\2\2z}\3\2\2\2{y\3\2\2\2{|\3\2")
+ buf.write("\2\2|\u0080\3\2\2\2}{\3\2\2\2~\u0081\5\34\17\2\177\u0081")
+ buf.write("\7\t\2\2\u0080~\3\2\2\2\u0080\177\3\2\2\2\u0081\u0082")
+ buf.write("\3\2\2\2\u0082\u0083\7\37\2\2\u0083\u0087\7\n\2\2\u0084")
+ buf.write("\u0086\5\26\f\2\u0085\u0084\3\2\2\2\u0086\u0089\3\2\2")
+ buf.write("\2\u0087\u0085\3\2\2\2\u0087\u0088\3\2\2\2\u0088\u008a")
+ buf.write("\3\2\2\2\u0089\u0087\3\2\2\2\u008a\u008c\7\13\2\2\u008b")
+ buf.write("\u008d\7\4\2\2\u008c\u008b\3\2\2\2\u008c\u008d\3\2\2\2")
+ buf.write("\u008d\21\3\2\2\2\u008e\u0090\7!\2\2\u008f\u008e\3\2\2")
+ buf.write("\2\u008f\u0090\3\2\2\2\u0090\u0094\3\2\2\2\u0091\u0093")
+ buf.write("\5\30\r\2\u0092\u0091\3\2\2\2\u0093\u0096\3\2\2\2\u0094")
+ buf.write("\u0092\3\2\2\2\u0094\u0095\3\2\2\2\u0095\u0097\3\2\2\2")
+ buf.write("\u0096\u0094\3\2\2\2\u0097\u0098\7\f\2\2\u0098\u0099\7")
+ buf.write("\37\2\2\u0099\u009d\7\n\2\2\u009a\u009c\5\26\f\2\u009b")
+ buf.write("\u009a\3\2\2\2\u009c\u009f\3\2\2\2\u009d\u009b\3\2\2\2")
+ buf.write("\u009d\u009e\3\2\2\2\u009e\u00a0\3\2\2\2\u009f\u009d\3")
+ buf.write("\2\2\2\u00a0\u00a2\7\13\2\2\u00a1\u00a3\7\4\2\2\u00a2")
+ buf.write("\u00a1\3\2\2\2\u00a2\u00a3\3\2\2\2\u00a3\23\3\2\2\2\u00a4")
+ buf.write("\u00a6\7!\2\2\u00a5\u00a4\3\2\2\2\u00a5\u00a6\3\2\2\2")
+ buf.write("\u00a6\u00aa\3\2\2\2\u00a7\u00a9\5\30\r\2\u00a8\u00a7")
+ buf.write("\3\2\2\2\u00a9\u00ac\3\2\2\2\u00aa\u00a8\3\2\2\2\u00aa")
+ buf.write("\u00ab\3\2\2\2\u00ab\u00ae\3\2\2\2\u00ac\u00aa\3\2\2\2")
+ buf.write("\u00ad\u00af\7\r\2\2\u00ae\u00ad\3\2\2\2\u00ae\u00af\3")
+ buf.write("\2\2\2\u00af\u00b0\3\2\2\2\u00b0\u00b1\5\34\17\2\u00b1")
+ buf.write("\u00b3\7\37\2\2\u00b2\u00b4\7\4\2\2\u00b3\u00b2\3\2\2")
+ buf.write("\2\u00b3\u00b4\3\2\2\2\u00b4\25\3\2\2\2\u00b5\u00b6\5")
+ buf.write("\34\17\2\u00b6\u00b8\7\37\2\2\u00b7\u00b9\7\16\2\2\u00b8")
+ buf.write("\u00b7\3\2\2\2\u00b8\u00b9\3\2\2\2\u00b9\27\3\2\2\2\u00ba")
+ buf.write("\u00bb\7\36\2\2\u00bb\u00bf\7\n\2\2\u00bc\u00be\5\32\16")
+ buf.write("\2\u00bd\u00bc\3\2\2\2\u00be\u00c1\3\2\2\2\u00bf\u00bd")
+ buf.write("\3\2\2\2\u00bf\u00c0\3\2\2\2\u00c0\u00c2\3\2\2\2\u00c1")
+ buf.write("\u00bf\3\2\2\2\u00c2\u00c3\7\13\2\2\u00c3\31\3\2\2\2\u00c4")
+ buf.write("\u00c7\7\37\2\2\u00c5\u00c6\7\17\2\2\u00c6\u00c8\7\37")
+ buf.write("\2\2\u00c7\u00c5\3\2\2\2\u00c7\u00c8\3\2\2\2\u00c8\33")
+ buf.write("\3\2\2\2\u00c9\u00ce\5 \21\2\u00ca\u00ce\5\36\20\2\u00cb")
+ buf.write("\u00ce\5\"\22\2\u00cc\u00ce\5$\23\2\u00cd\u00c9\3\2\2")
+ buf.write("\2\u00cd\u00ca\3\2\2\2\u00cd\u00cb\3\2\2\2\u00cd\u00cc")
+ buf.write("\3\2\2\2\u00ce\35\3\2\2\2\u00cf\u00d0\7\37\2\2\u00d0\37")
+ buf.write("\3\2\2\2\u00d1\u00d7\7\20\2\2\u00d2\u00d7\7\21\2\2\u00d3")
+ buf.write("\u00d7\7\22\2\2\u00d4\u00d7\7\23\2\2\u00d5\u00d7\7\24")
+ buf.write("\2\2\u00d6\u00d1\3\2\2\2\u00d6\u00d2\3\2\2\2\u00d6\u00d3")
+ buf.write("\3\2\2\2\u00d6\u00d4\3\2\2\2\u00d6\u00d5\3\2\2\2\u00d7")
+ buf.write("!\3\2\2\2\u00d8\u00d9\7\25\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("\u00de\7\30\2\2\u00de\u00df\7\26\2\2\u00df\u00e0\5\34")
+ buf.write("\17\2\u00e0\u00e1\7\27\2\2\u00e1%\3\2\2\2\u00e2\u00e4")
buf.write("\7!\2\2\u00e3\u00e2\3\2\2\2\u00e3\u00e4\3\2\2\2\u00e4")
- buf.write("\u00e8\3\2\2\2\u00e5\u00e7\5\26\f\2\u00e6\u00e5\3\2\2")
+ buf.write("\u00e8\3\2\2\2\u00e5\u00e7\5\30\r\2\u00e6\u00e5\3\2\2")
buf.write("\2\u00e7\u00ea\3\2\2\2\u00e8\u00e6\3\2\2\2\u00e8\u00e9")
buf.write("\3\2\2\2\u00e9\u00eb\3\2\2\2\u00ea\u00e8\3\2\2\2\u00eb")
- buf.write("\u00ec\5\32\16\2\u00ec\u00ee\7\37\2\2\u00ed\u00ef\7\4")
- buf.write("\2\2\u00ee\u00ed\3\2\2\2\u00ee\u00ef\3\2\2\2\u00ef\'\3")
- buf.write("\2\2\2\u00f0\u00f2\7!\2\2\u00f1\u00f0\3\2\2\2\u00f1\u00f2")
- buf.write("\3\2\2\2\u00f2\u00f6\3\2\2\2\u00f3\u00f5\5\26\f\2\u00f4")
- buf.write("\u00f3\3\2\2\2\u00f5\u00f8\3\2\2\2\u00f6\u00f4\3\2\2\2")
- buf.write("\u00f6\u00f7\3\2\2\2\u00f7\u00f9\3\2\2\2\u00f8\u00f6\3")
- buf.write("\2\2\2\u00f9\u00fa\5*\26\2\u00fa\u00fb\7\37\2\2\u00fb")
- buf.write("\u00ff\7\7\2\2\u00fc\u00fe\5,\27\2\u00fd\u00fc\3\2\2\2")
- buf.write("\u00fe\u0101\3\2\2\2\u00ff\u00fd\3\2\2\2\u00ff\u0100\3")
- buf.write("\2\2\2\u0100\u0102\3\2\2\2\u0101\u00ff\3\2\2\2\u0102\u0104")
- buf.write("\7\b\2\2\u0103\u0105\7\4\2\2\u0104\u0103\3\2\2\2\u0104")
- buf.write("\u0105\3\2\2\2\u0105)\3\2\2\2\u0106\u0109\7\32\2\2\u0107")
- buf.write("\u0109\7\33\2\2\u0108\u0106\3\2\2\2\u0108\u0107\3\2\2")
- buf.write("\2\u0109+\3\2\2\2\u010a\u010c\7!\2\2\u010b\u010a\3\2\2")
- buf.write("\2\u010b\u010c\3\2\2\2\u010c\u0110\3\2\2\2\u010d\u010f")
- buf.write("\5\26\f\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\u0116\7\37\2\2\u0114\u0115")
- buf.write("\7\17\2\2\u0115\u0117\5.\30\2\u0116\u0114\3\2\2\2\u0116")
- buf.write("\u0117\3\2\2\2\u0117\u0119\3\2\2\2\u0118\u011a\7\16\2")
- buf.write("\2\u0119\u0118\3\2\2\2\u0119\u011a\3\2\2\2\u011a-\3\2")
- buf.write("\2\2\u011b\u011e\7\34\2\2\u011c\u011e\7\35\2\2\u011d\u011b")
- buf.write("\3\2\2\2\u011d\u011c\3\2\2\2\u011e/\3\2\2\2.\64;BEJQV")
- buf.write("Y^glpsx|\u0080\u0087\u008c\u008f\u0094\u0098\u009d\u00a2")
- buf.write("\u00a9\u00b1\u00b7\u00c0\u00cd\u00d2\u00db\u00e0\u00e3")
- buf.write("\u00e8\u00ee\u00f1\u00f6\u00ff\u0104\u0108\u010b\u0110")
- buf.write("\u0116\u0119\u011d")
+ buf.write("\u00ec\7\31\2\2\u00ec\u00ed\7\37\2\2\u00ed\u00f1\7\7\2")
+ buf.write("\2\u00ee\u00f0\5(\25\2\u00ef\u00ee\3\2\2\2\u00f0\u00f3")
+ buf.write("\3\2\2\2\u00f1\u00ef\3\2\2\2\u00f1\u00f2\3\2\2\2\u00f2")
+ buf.write("\u00f4\3\2\2\2\u00f3\u00f1\3\2\2\2\u00f4\u00f6\7\b\2\2")
+ buf.write("\u00f5\u00f7\7\4\2\2\u00f6\u00f5\3\2\2\2\u00f6\u00f7\3")
+ buf.write("\2\2\2\u00f7\'\3\2\2\2\u00f8\u00fa\7!\2\2\u00f9\u00f8")
+ buf.write("\3\2\2\2\u00f9\u00fa\3\2\2\2\u00fa\u00fe\3\2\2\2\u00fb")
+ buf.write("\u00fd\5\30\r\2\u00fc\u00fb\3\2\2\2\u00fd\u0100\3\2\2")
+ buf.write("\2\u00fe\u00fc\3\2\2\2\u00fe\u00ff\3\2\2\2\u00ff\u0101")
+ buf.write("\3\2\2\2\u0100\u00fe\3\2\2\2\u0101\u0102\5\34\17\2\u0102")
+ buf.write("\u0104\7\37\2\2\u0103\u0105\7\4\2\2\u0104\u0103\3\2\2")
+ buf.write("\2\u0104\u0105\3\2\2\2\u0105)\3\2\2\2\u0106\u0108\7!\2")
+ buf.write("\2\u0107\u0106\3\2\2\2\u0107\u0108\3\2\2\2\u0108\u010c")
+ buf.write("\3\2\2\2\u0109\u010b\5\30\r\2\u010a\u0109\3\2\2\2\u010b")
+ buf.write("\u010e\3\2\2\2\u010c\u010a\3\2\2\2\u010c\u010d\3\2\2\2")
+ buf.write("\u010d\u010f\3\2\2\2\u010e\u010c\3\2\2\2\u010f\u0110\5")
+ buf.write(",\27\2\u0110\u0111\7\37\2\2\u0111\u0115\7\7\2\2\u0112")
+ buf.write("\u0114\5.\30\2\u0113\u0112\3\2\2\2\u0114\u0117\3\2\2\2")
+ buf.write("\u0115\u0113\3\2\2\2\u0115\u0116\3\2\2\2\u0116\u0118\3")
+ buf.write("\2\2\2\u0117\u0115\3\2\2\2\u0118\u011a\7\b\2\2\u0119\u011b")
+ buf.write("\7\4\2\2\u011a\u0119\3\2\2\2\u011a\u011b\3\2\2\2\u011b")
+ buf.write("+\3\2\2\2\u011c\u011f\7\32\2\2\u011d\u011f\7\33\2\2\u011e")
+ buf.write("\u011c\3\2\2\2\u011e\u011d\3\2\2\2\u011f-\3\2\2\2\u0120")
+ buf.write("\u0122\7!\2\2\u0121\u0120\3\2\2\2\u0121\u0122\3\2\2\2")
+ buf.write("\u0122\u0126\3\2\2\2\u0123\u0125\5\30\r\2\u0124\u0123")
+ buf.write("\3\2\2\2\u0125\u0128\3\2\2\2\u0126\u0124\3\2\2\2\u0126")
+ buf.write("\u0127\3\2\2\2\u0127\u0129\3\2\2\2\u0128\u0126\3\2\2\2")
+ buf.write("\u0129\u012c\7\37\2\2\u012a\u012b\7\17\2\2\u012b\u012d")
+ buf.write("\5\60\31\2\u012c\u012a\3\2\2\2\u012c\u012d\3\2\2\2\u012d")
+ buf.write("\u012f\3\2\2\2\u012e\u0130\7\16\2\2\u012f\u012e\3\2\2")
+ buf.write("\2\u012f\u0130\3\2\2\2\u0130/\3\2\2\2\u0131\u0134\7\34")
+ buf.write("\2\2\u0132\u0134\7\35\2\2\u0133\u0131\3\2\2\2\u0133\u0132")
+ buf.write("\3\2\2\2\u0134\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\u00c7\u00cd\u00d6\u00e3\u00e8\u00f1\u00f6")
+ buf.write("\u00f9\u00fe\u0104\u0107\u010c\u0115\u011a\u011e\u0121")
+ buf.write("\u0126\u012c\u012f\u0133")
return buf.getvalue()
@@ -150,7 +163,7 @@ class TParser ( Parser ):
sharedContextCache = PredictionContextCache()
literalNames = [ "<INVALID>", "'import'", "';'", "'module'", "'interface'",
- "'{'", "'}'", "'event'", "'void'", "'('", "')'", "'readonly'",
+ "'{'", "'}'", "'void'", "'('", "')'", "'signal'", "'readonly'",
"','", "'='", "'bool'", "'int'", "'real'", "'string'",
"'var'", "'list'", "'<'", "'>'", "'model'", "'struct'",
"'enum'", "'flag'" ]
@@ -173,28 +186,30 @@ class TParser ( Parser ):
RULE_interfaceSymbol = 5
RULE_interfaceMemberSymbol = 6
RULE_operationSymbol = 7
- RULE_propertySymbol = 8
- RULE_operationParameterSymbol = 9
- RULE_tagSymbol = 10
- RULE_tagAttributeSymbol = 11
- RULE_typeSymbol = 12
- RULE_complexTypeSymbol = 13
- RULE_primitiveTypeSymbol = 14
- RULE_listTypeSymbol = 15
- RULE_modelTypeSymbol = 16
- RULE_structSymbol = 17
- RULE_structFieldSymbol = 18
- RULE_enumSymbol = 19
- RULE_enumTypeSymbol = 20
- RULE_enumMemberSymbol = 21
- RULE_intSymbol = 22
+ 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
ruleNames = [ "documentSymbol", "headerSymbol", "importSymbol", "moduleSymbol",
"definitionSymbol", "interfaceSymbol", "interfaceMemberSymbol",
- "operationSymbol", "propertySymbol", "operationParameterSymbol",
- "tagSymbol", "tagAttributeSymbol", "typeSymbol", "complexTypeSymbol",
- "primitiveTypeSymbol", "listTypeSymbol", "modelTypeSymbol",
- "structSymbol", "structFieldSymbol", "enumSymbol", "enumTypeSymbol",
+ "operationSymbol", "signalSymbol", "propertySymbol",
+ "operationParameterSymbol", "tagSymbol", "tagAttributeSymbol",
+ "typeSymbol", "complexTypeSymbol", "primitiveTypeSymbol",
+ "listTypeSymbol", "modelTypeSymbol", "structSymbol",
+ "structFieldSymbol", "enumSymbol", "enumTypeSymbol",
"enumMemberSymbol", "intSymbol" ]
EOF = Token.EOF
@@ -285,15 +300,15 @@ class TParser ( Parser ):
self._la = 0 # Token type
try:
self.enterOuterAlt(localctx, 1)
- self.state = 46
+ self.state = 48
self.headerSymbol()
- self.state = 50
+ self.state = 52
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.TAGIDENTIFIER) | (1 << TParser.DOCCOMMENT))) != 0):
- self.state = 47
+ self.state = 49
self.definitionSymbol()
- self.state = 52
+ self.state = 54
self._errHandler.sync(self)
_la = self._input.LA(1)
@@ -349,15 +364,15 @@ class TParser ( Parser ):
self._la = 0 # Token type
try:
self.enterOuterAlt(localctx, 1)
- self.state = 53
+ self.state = 55
self.moduleSymbol()
- self.state = 57
+ self.state = 59
self._errHandler.sync(self)
_la = self._input.LA(1)
while _la==TParser.T__0:
- self.state = 54
+ self.state = 56
self.importSymbol()
- self.state = 59
+ self.state = 61
self._errHandler.sync(self)
_la = self._input.LA(1)
@@ -410,17 +425,17 @@ class TParser ( Parser ):
self._la = 0 # Token type
try:
self.enterOuterAlt(localctx, 1)
- self.state = 60
+ self.state = 62
self.match(TParser.T__0)
- self.state = 61
+ self.state = 63
localctx.name = self.match(TParser.IDENTIFIER)
- self.state = 62
- localctx.version = self.match(TParser.VERSION)
self.state = 64
+ localctx.version = self.match(TParser.VERSION)
+ self.state = 66
self._errHandler.sync(self)
_la = self._input.LA(1)
if _la==TParser.T__1:
- self.state = 63
+ self.state = 65
self.match(TParser.T__1)
@@ -484,35 +499,35 @@ class TParser ( Parser ):
self._la = 0 # Token type
try:
self.enterOuterAlt(localctx, 1)
- self.state = 67
+ self.state = 69
self._errHandler.sync(self)
_la = self._input.LA(1)
if _la==TParser.DOCCOMMENT:
- self.state = 66
+ self.state = 68
localctx.comment = self.match(TParser.DOCCOMMENT)
- self.state = 72
+ self.state = 74
self._errHandler.sync(self)
_la = self._input.LA(1)
while _la==TParser.TAGIDENTIFIER:
- self.state = 69
+ self.state = 71
self.tagSymbol()
- self.state = 74
+ self.state = 76
self._errHandler.sync(self)
_la = self._input.LA(1)
- self.state = 75
+ self.state = 77
self.match(TParser.T__2)
- self.state = 76
+ self.state = 78
localctx.name = self.match(TParser.IDENTIFIER)
- self.state = 77
- localctx.version = self.match(TParser.VERSION)
self.state = 79
+ localctx.version = self.match(TParser.VERSION)
+ self.state = 81
self._errHandler.sync(self)
_la = self._input.LA(1)
if _la==TParser.T__1:
- self.state = 78
+ self.state = 80
self.match(TParser.T__1)
@@ -567,24 +582,24 @@ class TParser ( Parser ):
localctx = TParser.DefinitionSymbolContext(self, self._ctx, self.state)
self.enterRule(localctx, 8, self.RULE_definitionSymbol)
try:
- self.state = 84
+ self.state = 86
self._errHandler.sync(self)
la_ = self._interp.adaptivePredict(self._input,6,self._ctx)
if la_ == 1:
self.enterOuterAlt(localctx, 1)
- self.state = 81
+ self.state = 83
self.interfaceSymbol()
pass
elif la_ == 2:
self.enterOuterAlt(localctx, 2)
- self.state = 82
+ self.state = 84
self.structSymbol()
pass
elif la_ == 3:
self.enterOuterAlt(localctx, 3)
- self.state = 83
+ self.state = 85
self.enumSymbol()
pass
@@ -652,47 +667,47 @@ class TParser ( Parser ):
self._la = 0 # Token type
try:
self.enterOuterAlt(localctx, 1)
- self.state = 87
+ self.state = 89
self._errHandler.sync(self)
_la = self._input.LA(1)
if _la==TParser.DOCCOMMENT:
- self.state = 86
+ self.state = 88
localctx.comment = self.match(TParser.DOCCOMMENT)
- self.state = 92
+ self.state = 94
self._errHandler.sync(self)
_la = self._input.LA(1)
while _la==TParser.TAGIDENTIFIER:
- self.state = 89
+ self.state = 91
self.tagSymbol()
- self.state = 94
+ self.state = 96
self._errHandler.sync(self)
_la = self._input.LA(1)
- self.state = 95
+ self.state = 97
self.match(TParser.T__3)
- self.state = 96
+ self.state = 98
localctx.name = self.match(TParser.IDENTIFIER)
- self.state = 97
+ self.state = 99
self.match(TParser.T__4)
- self.state = 101
+ self.state = 103
self._errHandler.sync(self)
_la = self._input.LA(1)
- while (((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << TParser.T__6) | (1 << TParser.T__7) | (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.TAGIDENTIFIER) | (1 << TParser.IDENTIFIER) | (1 << TParser.DOCCOMMENT))) != 0):
- self.state = 98
+ 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.TAGIDENTIFIER) | (1 << TParser.IDENTIFIER) | (1 << TParser.DOCCOMMENT))) != 0):
+ self.state = 100
self.interfaceMemberSymbol()
- self.state = 103
+ self.state = 105
self._errHandler.sync(self)
_la = self._input.LA(1)
- self.state = 104
- self.match(TParser.T__5)
self.state = 106
+ self.match(TParser.T__5)
+ self.state = 108
self._errHandler.sync(self)
_la = self._input.LA(1)
if _la==TParser.T__1:
- self.state = 105
+ self.state = 107
self.match(TParser.T__1)
@@ -718,6 +733,10 @@ class TParser ( Parser ):
return self.getTypedRuleContext(TParser.PropertySymbolContext,0)
+ def signalSymbol(self):
+ return self.getTypedRuleContext(TParser.SignalSymbolContext,0)
+
+
def getRuleIndex(self):
return TParser.RULE_interfaceMemberSymbol
@@ -743,21 +762,27 @@ class TParser ( Parser ):
localctx = TParser.InterfaceMemberSymbolContext(self, self._ctx, self.state)
self.enterRule(localctx, 12, self.RULE_interfaceMemberSymbol)
try:
- self.state = 110
+ self.state = 113
self._errHandler.sync(self)
la_ = self._interp.adaptivePredict(self._input,11,self._ctx)
if la_ == 1:
self.enterOuterAlt(localctx, 1)
- self.state = 108
+ self.state = 110
self.operationSymbol()
pass
elif la_ == 2:
self.enterOuterAlt(localctx, 2)
- self.state = 109
+ self.state = 111
self.propertySymbol()
pass
+ elif la_ == 3:
+ self.enterOuterAlt(localctx, 3)
+ self.state = 112
+ self.signalSymbol()
+ pass
+
except RecognitionException as re:
localctx.exception = re
@@ -773,7 +798,6 @@ class TParser ( Parser ):
super().__init__(parent, invokingState)
self.parser = parser
self.comment = None # Token
- self.isEvent = None # Token
self.name = None # Token
def IDENTIFIER(self):
@@ -827,32 +851,24 @@ class TParser ( Parser ):
self._la = 0 # Token type
try:
self.enterOuterAlt(localctx, 1)
- self.state = 113
+ self.state = 116
self._errHandler.sync(self)
_la = self._input.LA(1)
if _la==TParser.DOCCOMMENT:
- self.state = 112
+ self.state = 115
localctx.comment = self.match(TParser.DOCCOMMENT)
- self.state = 118
+ self.state = 121
self._errHandler.sync(self)
_la = self._input.LA(1)
while _la==TParser.TAGIDENTIFIER:
- self.state = 115
+ self.state = 118
self.tagSymbol()
- self.state = 120
+ self.state = 123
self._errHandler.sync(self)
_la = self._input.LA(1)
- self.state = 122
- self._errHandler.sync(self)
- _la = self._input.LA(1)
- if _la==TParser.T__6:
- self.state = 121
- localctx.isEvent = self.match(TParser.T__6)
-
-
self.state = 126
self._errHandler.sync(self)
token = self._input.LA(1)
@@ -860,9 +876,9 @@ class TParser ( Parser ):
self.state = 124
self.typeSymbol()
pass
- elif token in [TParser.T__7]:
+ elif token in [TParser.T__6]:
self.state = 125
- self.match(TParser.T__7)
+ self.match(TParser.T__6)
pass
else:
raise NoViableAltException(self)
@@ -870,7 +886,7 @@ class TParser ( Parser ):
self.state = 128
localctx.name = self.match(TParser.IDENTIFIER)
self.state = 129
- self.match(TParser.T__8)
+ self.match(TParser.T__7)
self.state = 133
self._errHandler.sync(self)
_la = self._input.LA(1)
@@ -882,7 +898,7 @@ class TParser ( Parser ):
_la = self._input.LA(1)
self.state = 136
- self.match(TParser.T__9)
+ self.match(TParser.T__8)
self.state = 138
self._errHandler.sync(self)
_la = self._input.LA(1)
@@ -899,6 +915,113 @@ class TParser ( Parser ):
self.exitRule()
return localctx
+ class SignalSymbolContext(ParserRuleContext):
+
+ def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
+ super().__init__(parent, invokingState)
+ self.parser = parser
+ self.comment = None # Token
+ self.name = None # Token
+
+ def IDENTIFIER(self):
+ return self.getToken(TParser.IDENTIFIER, 0)
+
+ def tagSymbol(self, i:int=None):
+ if i is None:
+ return self.getTypedRuleContexts(TParser.TagSymbolContext)
+ else:
+ return self.getTypedRuleContext(TParser.TagSymbolContext,i)
+
+
+ def operationParameterSymbol(self, i:int=None):
+ if i is None:
+ return self.getTypedRuleContexts(TParser.OperationParameterSymbolContext)
+ else:
+ return self.getTypedRuleContext(TParser.OperationParameterSymbolContext,i)
+
+
+ def DOCCOMMENT(self):
+ return self.getToken(TParser.DOCCOMMENT, 0)
+
+ def getRuleIndex(self):
+ return TParser.RULE_signalSymbol
+
+ def enterRule(self, listener:ParseTreeListener):
+ if hasattr( listener, "enterSignalSymbol" ):
+ listener.enterSignalSymbol(self)
+
+ def exitRule(self, listener:ParseTreeListener):
+ if hasattr( listener, "exitSignalSymbol" ):
+ listener.exitSignalSymbol(self)
+
+ def accept(self, visitor:ParseTreeVisitor):
+ if hasattr( visitor, "visitSignalSymbol" ):
+ return visitor.visitSignalSymbol(self)
+ else:
+ return visitor.visitChildren(self)
+
+
+
+
+ def signalSymbol(self):
+
+ localctx = TParser.SignalSymbolContext(self, self._ctx, self.state)
+ self.enterRule(localctx, 16, self.RULE_signalSymbol)
+ self._la = 0 # Token type
+ try:
+ self.enterOuterAlt(localctx, 1)
+ self.state = 141
+ self._errHandler.sync(self)
+ _la = self._input.LA(1)
+ if _la==TParser.DOCCOMMENT:
+ self.state = 140
+ localctx.comment = self.match(TParser.DOCCOMMENT)
+
+
+ self.state = 146
+ self._errHandler.sync(self)
+ _la = self._input.LA(1)
+ while _la==TParser.TAGIDENTIFIER:
+ self.state = 143
+ self.tagSymbol()
+ self.state = 148
+ self._errHandler.sync(self)
+ _la = self._input.LA(1)
+
+ self.state = 149
+ self.match(TParser.T__9)
+ self.state = 150
+ localctx.name = self.match(TParser.IDENTIFIER)
+ self.state = 151
+ self.match(TParser.T__7)
+ self.state = 155
+ 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
+ self.operationParameterSymbol()
+ self.state = 157
+ self._errHandler.sync(self)
+ _la = self._input.LA(1)
+
+ self.state = 158
+ self.match(TParser.T__8)
+ self.state = 160
+ self._errHandler.sync(self)
+ _la = self._input.LA(1)
+ if _la==TParser.T__1:
+ self.state = 159
+ self.match(TParser.T__1)
+
+
+ except RecognitionException as re:
+ localctx.exception = re
+ self._errHandler.reportError(self, re)
+ self._errHandler.recover(self, re)
+ finally:
+ self.exitRule()
+ return localctx
+
class PropertySymbolContext(ParserRuleContext):
def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1):
@@ -948,45 +1071,45 @@ class TParser ( Parser ):
def propertySymbol(self):
localctx = TParser.PropertySymbolContext(self, self._ctx, self.state)
- self.enterRule(localctx, 16, self.RULE_propertySymbol)
+ self.enterRule(localctx, 18, self.RULE_propertySymbol)
self._la = 0 # Token type
try:
self.enterOuterAlt(localctx, 1)
- self.state = 141
+ self.state = 163
self._errHandler.sync(self)
_la = self._input.LA(1)
if _la==TParser.DOCCOMMENT:
- self.state = 140
+ self.state = 162
localctx.comment = self.match(TParser.DOCCOMMENT)
- self.state = 146
+ self.state = 168
self._errHandler.sync(self)
_la = self._input.LA(1)
while _la==TParser.TAGIDENTIFIER:
- self.state = 143
+ self.state = 165
self.tagSymbol()
- self.state = 148
+ self.state = 170
self._errHandler.sync(self)
_la = self._input.LA(1)
- self.state = 150
+ self.state = 172
self._errHandler.sync(self)
_la = self._input.LA(1)
if _la==TParser.T__10:
- self.state = 149
+ self.state = 171
localctx.isReadOnly = self.match(TParser.T__10)
- self.state = 152
+ self.state = 174
self.typeSymbol()
- self.state = 153
+ self.state = 175
localctx.name = self.match(TParser.IDENTIFIER)
- self.state = 155
+ self.state = 177
self._errHandler.sync(self)
_la = self._input.LA(1)
if _la==TParser.T__1:
- self.state = 154
+ self.state = 176
self.match(TParser.T__1)
@@ -1035,19 +1158,19 @@ class TParser ( Parser ):
def operationParameterSymbol(self):
localctx = TParser.OperationParameterSymbolContext(self, self._ctx, self.state)
- self.enterRule(localctx, 18, self.RULE_operationParameterSymbol)
+ self.enterRule(localctx, 20, self.RULE_operationParameterSymbol)
self._la = 0 # Token type
try:
self.enterOuterAlt(localctx, 1)
- self.state = 157
+ self.state = 179
self.typeSymbol()
- self.state = 158
+ self.state = 180
localctx.name = self.match(TParser.IDENTIFIER)
- self.state = 160
+ self.state = 182
self._errHandler.sync(self)
_la = self._input.LA(1)
if _la==TParser.T__11:
- self.state = 159
+ self.state = 181
self.match(TParser.T__11)
@@ -1099,26 +1222,26 @@ class TParser ( Parser ):
def tagSymbol(self):
localctx = TParser.TagSymbolContext(self, self._ctx, self.state)
- self.enterRule(localctx, 20, self.RULE_tagSymbol)
+ self.enterRule(localctx, 22, self.RULE_tagSymbol)
self._la = 0 # Token type
try:
self.enterOuterAlt(localctx, 1)
- self.state = 162
+ self.state = 184
localctx.name = self.match(TParser.TAGIDENTIFIER)
- self.state = 163
- self.match(TParser.T__8)
- self.state = 167
+ self.state = 185
+ self.match(TParser.T__7)
+ self.state = 189
self._errHandler.sync(self)
_la = self._input.LA(1)
while _la==TParser.IDENTIFIER:
- self.state = 164
+ self.state = 186
self.tagAttributeSymbol()
- self.state = 169
+ self.state = 191
self._errHandler.sync(self)
_la = self._input.LA(1)
- self.state = 170
- self.match(TParser.T__9)
+ self.state = 192
+ self.match(TParser.T__8)
except RecognitionException as re:
localctx.exception = re
self._errHandler.reportError(self, re)
@@ -1164,19 +1287,19 @@ class TParser ( Parser ):
def tagAttributeSymbol(self):
localctx = TParser.TagAttributeSymbolContext(self, self._ctx, self.state)
- self.enterRule(localctx, 22, self.RULE_tagAttributeSymbol)
+ self.enterRule(localctx, 24, self.RULE_tagAttributeSymbol)
self._la = 0 # Token type
try:
self.enterOuterAlt(localctx, 1)
- self.state = 172
+ self.state = 194
localctx.name = self.match(TParser.IDENTIFIER)
- self.state = 175
+ self.state = 197
self._errHandler.sync(self)
_la = self._input.LA(1)
if _la==TParser.T__12:
- self.state = 173
+ self.state = 195
self.match(TParser.T__12)
- self.state = 174
+ self.state = 196
localctx.value = self.match(TParser.IDENTIFIER)
@@ -1233,29 +1356,29 @@ class TParser ( Parser ):
def typeSymbol(self):
localctx = TParser.TypeSymbolContext(self, self._ctx, self.state)
- self.enterRule(localctx, 24, self.RULE_typeSymbol)
+ self.enterRule(localctx, 26, self.RULE_typeSymbol)
try:
- self.state = 181
+ self.state = 203
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]:
self.enterOuterAlt(localctx, 1)
- self.state = 177
+ self.state = 199
self.primitiveTypeSymbol()
pass
elif token in [TParser.IDENTIFIER]:
self.enterOuterAlt(localctx, 2)
- self.state = 178
+ self.state = 200
self.complexTypeSymbol()
pass
elif token in [TParser.T__18]:
self.enterOuterAlt(localctx, 3)
- self.state = 179
+ self.state = 201
self.listTypeSymbol()
pass
elif token in [TParser.T__21]:
self.enterOuterAlt(localctx, 4)
- self.state = 180
+ self.state = 202
self.modelTypeSymbol()
pass
else:
@@ -1302,10 +1425,10 @@ class TParser ( Parser ):
def complexTypeSymbol(self):
localctx = TParser.ComplexTypeSymbolContext(self, self._ctx, self.state)
- self.enterRule(localctx, 26, self.RULE_complexTypeSymbol)
+ self.enterRule(localctx, 28, self.RULE_complexTypeSymbol)
try:
self.enterOuterAlt(localctx, 1)
- self.state = 183
+ self.state = 205
localctx.name = self.match(TParser.IDENTIFIER)
except RecognitionException as re:
localctx.exception = re
@@ -1346,34 +1469,34 @@ class TParser ( Parser ):
def primitiveTypeSymbol(self):
localctx = TParser.PrimitiveTypeSymbolContext(self, self._ctx, self.state)
- self.enterRule(localctx, 28, self.RULE_primitiveTypeSymbol)
+ self.enterRule(localctx, 30, self.RULE_primitiveTypeSymbol)
try:
- self.state = 190
+ self.state = 212
self._errHandler.sync(self)
token = self._input.LA(1)
if token in [TParser.T__13]:
self.enterOuterAlt(localctx, 1)
- self.state = 185
+ self.state = 207
localctx.name = self.match(TParser.T__13)
pass
elif token in [TParser.T__14]:
self.enterOuterAlt(localctx, 2)
- self.state = 186
+ self.state = 208
localctx.name = self.match(TParser.T__14)
pass
elif token in [TParser.T__15]:
self.enterOuterAlt(localctx, 3)
- self.state = 187
+ self.state = 209
localctx.name = self.match(TParser.T__15)
pass
elif token in [TParser.T__16]:
self.enterOuterAlt(localctx, 4)
- self.state = 188
+ self.state = 210
localctx.name = self.match(TParser.T__16)
pass
elif token in [TParser.T__17]:
self.enterOuterAlt(localctx, 5)
- self.state = 189
+ self.state = 211
localctx.name = self.match(TParser.T__17)
pass
else:
@@ -1421,16 +1544,16 @@ class TParser ( Parser ):
def listTypeSymbol(self):
localctx = TParser.ListTypeSymbolContext(self, self._ctx, self.state)
- self.enterRule(localctx, 30, self.RULE_listTypeSymbol)
+ self.enterRule(localctx, 32, self.RULE_listTypeSymbol)
try:
self.enterOuterAlt(localctx, 1)
- self.state = 192
+ self.state = 214
self.match(TParser.T__18)
- self.state = 193
+ self.state = 215
self.match(TParser.T__19)
- self.state = 194
+ self.state = 216
localctx.valueType = self.typeSymbol()
- self.state = 195
+ self.state = 217
self.match(TParser.T__20)
except RecognitionException as re:
localctx.exception = re
@@ -1474,16 +1597,16 @@ class TParser ( Parser ):
def modelTypeSymbol(self):
localctx = TParser.ModelTypeSymbolContext(self, self._ctx, self.state)
- self.enterRule(localctx, 32, self.RULE_modelTypeSymbol)
+ self.enterRule(localctx, 34, self.RULE_modelTypeSymbol)
try:
self.enterOuterAlt(localctx, 1)
- self.state = 197
+ self.state = 219
self.match(TParser.T__21)
- self.state = 198
+ self.state = 220
self.match(TParser.T__19)
- self.state = 199
+ self.state = 221
localctx.valueType = self.typeSymbol()
- self.state = 200
+ self.state = 222
self.match(TParser.T__20)
except RecognitionException as re:
localctx.exception = re
@@ -1544,51 +1667,51 @@ class TParser ( Parser ):
def structSymbol(self):
localctx = TParser.StructSymbolContext(self, self._ctx, self.state)
- self.enterRule(localctx, 34, self.RULE_structSymbol)
+ self.enterRule(localctx, 36, self.RULE_structSymbol)
self._la = 0 # Token type
try:
self.enterOuterAlt(localctx, 1)
- self.state = 203
+ self.state = 225
self._errHandler.sync(self)
_la = self._input.LA(1)
if _la==TParser.DOCCOMMENT:
- self.state = 202
+ self.state = 224
localctx.comment = self.match(TParser.DOCCOMMENT)
- self.state = 208
+ self.state = 230
self._errHandler.sync(self)
_la = self._input.LA(1)
while _la==TParser.TAGIDENTIFIER:
- self.state = 205
+ self.state = 227
self.tagSymbol()
- self.state = 210
+ self.state = 232
self._errHandler.sync(self)
_la = self._input.LA(1)
- self.state = 211
+ self.state = 233
self.match(TParser.T__22)
- self.state = 212
+ self.state = 234
localctx.name = self.match(TParser.IDENTIFIER)
- self.state = 213
+ self.state = 235
self.match(TParser.T__4)
- self.state = 217
+ self.state = 239
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.TAGIDENTIFIER) | (1 << TParser.IDENTIFIER) | (1 << TParser.DOCCOMMENT))) != 0):
- self.state = 214
+ self.state = 236
self.structFieldSymbol()
- self.state = 219
+ self.state = 241
self._errHandler.sync(self)
_la = self._input.LA(1)
- self.state = 220
+ self.state = 242
self.match(TParser.T__5)
- self.state = 222
+ self.state = 244
self._errHandler.sync(self)
_la = self._input.LA(1)
if _la==TParser.T__1:
- self.state = 221
+ self.state = 243
self.match(TParser.T__1)
@@ -1648,37 +1771,37 @@ class TParser ( Parser ):
def structFieldSymbol(self):
localctx = TParser.StructFieldSymbolContext(self, self._ctx, self.state)
- self.enterRule(localctx, 36, self.RULE_structFieldSymbol)
+ self.enterRule(localctx, 38, self.RULE_structFieldSymbol)
self._la = 0 # Token type
try:
self.enterOuterAlt(localctx, 1)
- self.state = 225
+ self.state = 247
self._errHandler.sync(self)
_la = self._input.LA(1)
if _la==TParser.DOCCOMMENT:
- self.state = 224
+ self.state = 246
localctx.comment = self.match(TParser.DOCCOMMENT)
- self.state = 230
+ self.state = 252
self._errHandler.sync(self)
_la = self._input.LA(1)
while _la==TParser.TAGIDENTIFIER:
- self.state = 227
+ self.state = 249
self.tagSymbol()
- self.state = 232
+ self.state = 254
self._errHandler.sync(self)
_la = self._input.LA(1)
- self.state = 233
+ self.state = 255
self.typeSymbol()
- self.state = 234
+ self.state = 256
localctx.name = self.match(TParser.IDENTIFIER)
- self.state = 236
+ self.state = 258
self._errHandler.sync(self)
_la = self._input.LA(1)
if _la==TParser.T__1:
- self.state = 235
+ self.state = 257
self.match(TParser.T__1)
@@ -1745,51 +1868,51 @@ class TParser ( Parser ):
def enumSymbol(self):
localctx = TParser.EnumSymbolContext(self, self._ctx, self.state)
- self.enterRule(localctx, 38, self.RULE_enumSymbol)
+ self.enterRule(localctx, 40, self.RULE_enumSymbol)
self._la = 0 # Token type
try:
self.enterOuterAlt(localctx, 1)
- self.state = 239
+ self.state = 261
self._errHandler.sync(self)
_la = self._input.LA(1)
if _la==TParser.DOCCOMMENT:
- self.state = 238
+ self.state = 260
localctx.comment = self.match(TParser.DOCCOMMENT)
- self.state = 244
+ self.state = 266
self._errHandler.sync(self)
_la = self._input.LA(1)
while _la==TParser.TAGIDENTIFIER:
- self.state = 241
+ self.state = 263
self.tagSymbol()
- self.state = 246
+ self.state = 268
self._errHandler.sync(self)
_la = self._input.LA(1)
- self.state = 247
+ self.state = 269
self.enumTypeSymbol()
- self.state = 248
+ self.state = 270
localctx.name = self.match(TParser.IDENTIFIER)
- self.state = 249
+ self.state = 271
self.match(TParser.T__4)
- self.state = 253
+ self.state = 275
self._errHandler.sync(self)
_la = self._input.LA(1)
while (((_la) & ~0x3f) == 0 and ((1 << _la) & ((1 << TParser.TAGIDENTIFIER) | (1 << TParser.IDENTIFIER) | (1 << TParser.DOCCOMMENT))) != 0):
- self.state = 250
+ self.state = 272
self.enumMemberSymbol()
- self.state = 255
+ self.state = 277
self._errHandler.sync(self)
_la = self._input.LA(1)
- self.state = 256
+ self.state = 278
self.match(TParser.T__5)
- self.state = 258
+ self.state = 280
self._errHandler.sync(self)
_la = self._input.LA(1)
if _la==TParser.T__1:
- self.state = 257
+ self.state = 279
self.match(TParser.T__1)
@@ -1833,19 +1956,19 @@ class TParser ( Parser ):
def enumTypeSymbol(self):
localctx = TParser.EnumTypeSymbolContext(self, self._ctx, self.state)
- self.enterRule(localctx, 40, self.RULE_enumTypeSymbol)
+ self.enterRule(localctx, 42, self.RULE_enumTypeSymbol)
try:
- self.state = 262
+ self.state = 284
self._errHandler.sync(self)
token = self._input.LA(1)
if token in [TParser.T__23]:
self.enterOuterAlt(localctx, 1)
- self.state = 260
+ self.state = 282
localctx.isEnum = self.match(TParser.T__23)
pass
elif token in [TParser.T__24]:
self.enterOuterAlt(localctx, 2)
- self.state = 261
+ self.state = 283
localctx.isFlag = self.match(TParser.T__24)
pass
else:
@@ -1907,45 +2030,45 @@ class TParser ( Parser ):
def enumMemberSymbol(self):
localctx = TParser.EnumMemberSymbolContext(self, self._ctx, self.state)
- self.enterRule(localctx, 42, self.RULE_enumMemberSymbol)
+ self.enterRule(localctx, 44, self.RULE_enumMemberSymbol)
self._la = 0 # Token type
try:
self.enterOuterAlt(localctx, 1)
- self.state = 265
+ self.state = 287
self._errHandler.sync(self)
_la = self._input.LA(1)
if _la==TParser.DOCCOMMENT:
- self.state = 264
+ self.state = 286
localctx.comment = self.match(TParser.DOCCOMMENT)
- self.state = 270
+ self.state = 292
self._errHandler.sync(self)
_la = self._input.LA(1)
while _la==TParser.TAGIDENTIFIER:
- self.state = 267
+ self.state = 289
self.tagSymbol()
- self.state = 272
+ self.state = 294
self._errHandler.sync(self)
_la = self._input.LA(1)
- self.state = 273
+ self.state = 295
localctx.name = self.match(TParser.IDENTIFIER)
- self.state = 276
+ self.state = 298
self._errHandler.sync(self)
_la = self._input.LA(1)
if _la==TParser.T__12:
- self.state = 274
+ self.state = 296
self.match(TParser.T__12)
- self.state = 275
+ self.state = 297
self.intSymbol()
- self.state = 279
+ self.state = 301
self._errHandler.sync(self)
_la = self._input.LA(1)
if _la==TParser.T__11:
- self.state = 278
+ self.state = 300
self.match(TParser.T__11)
@@ -1993,19 +2116,19 @@ class TParser ( Parser ):
def intSymbol(self):
localctx = TParser.IntSymbolContext(self, self._ctx, self.state)
- self.enterRule(localctx, 44, self.RULE_intSymbol)
+ self.enterRule(localctx, 46, self.RULE_intSymbol)
try:
- self.state = 283
+ self.state = 305
self._errHandler.sync(self)
token = self._input.LA(1)
if token in [TParser.INTCONSTANT]:
self.enterOuterAlt(localctx, 1)
- self.state = 281
+ self.state = 303
localctx.value = self.match(TParser.INTCONSTANT)
pass
elif token in [TParser.HEXCONSTANT]:
self.enterOuterAlt(localctx, 2)
- self.state = 282
+ self.state = 304
localctx.value = self.match(TParser.HEXCONSTANT)
pass
else:
diff --git a/qface/idl/parser/TVisitor.py b/qface/idl/parser/TVisitor.py
index 64b345a..537146c 100644
--- a/qface/idl/parser/TVisitor.py
+++ b/qface/idl/parser/TVisitor.py
@@ -49,6 +49,11 @@ class TVisitor(ParseTreeVisitor):
return self.visitChildren(ctx)
+ # Visit a parse tree produced by TParser#signalSymbol.
+ def visitSignalSymbol(self, ctx:TParser.SignalSymbolContext):
+ return self.visitChildren(ctx)
+
+
# Visit a parse tree produced by TParser#propertySymbol.
def visitPropertySymbol(self, ctx:TParser.PropertySymbolContext):
return self.visitChildren(ctx)
diff --git a/qface/shell.py b/qface/shell.py
new file mode 100644
index 0000000..3d34d89
--- /dev/null
+++ b/qface/shell.py
@@ -0,0 +1,16 @@
+import click
+from subprocess import call
+
+"""
+API for interacting with the system shell
+"""
+
+
+def sh(cmd, **kwargs):
+ """
+ runs the given cmd as shell command
+ """
+ if not cmd:
+ return
+ click.echo('$ {0}'.format(cmd))
+ return call(cmd, shell=True, **kwargs)
diff --git a/qface/watch.py b/qface/watch.py
new file mode 100644
index 0000000..4a8512f
--- /dev/null
+++ b/qface/watch.py
@@ -0,0 +1,54 @@
+from watchdog.events import FileSystemEventHandler
+from watchdog.observers import Observer
+import click
+from path import Path
+import time
+from .shell import sh
+
+"""
+Provides an API to monitor the file system
+"""
+
+class RunScriptChangeHandler(FileSystemEventHandler):
+ def __init__(self, argv):
+ super().__init__()
+ self.argv = argv
+ self.is_running = False
+
+ def on_modified(self, event):
+ self.run()
+
+ def run(self):
+ if self.is_running:
+ return
+ self.is_running = True
+ # cmd = '{0} {1}'.format(sys.executable, ' '.join(self.argv))
+ sh(' '.join(self.argv), cwd=Path.getcwd())
+ self.is_running = False
+
+
+def monitor(src, argv):
+ """
+ reloads the script given by argv when src files changes
+ """
+ script = Path(argv[0]).expand().abspath()
+ src = src if isinstance(src, (list, tuple)) else [src]
+ src = [Path(entry).expand().abspath() for entry in src]
+ event_handler = RunScriptChangeHandler(argv)
+ observer = Observer()
+ path = script.dirname().expand().abspath()
+ click.secho('watch recursive: {0}'.format(path), fg='blue')
+ observer.schedule(event_handler, path, 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
+ observer.start()
+
+ try:
+ while True:
+ time.sleep(1)
+ except KeyboardInterrupt:
+ observer.stop()
+ observer.join()
diff --git a/tests/in/com.pelagicore.ivi.climate.qface b/tests/in/com.pelagicore.ivi.climate.qface
index 6414bb5..b465e8b 100644
--- a/tests/in/com.pelagicore.ivi.climate.qface
+++ b/tests/in/com.pelagicore.ivi.climate.qface
@@ -1,86 +1,86 @@
module com.pelagicore.ivi.climate 1.0;
-/*!
+/**
* The ClimateControl provides a QML interface to the climate control
* of the vehicle.
*/
interface ClimateControl {
- /*!
+ /**
* Value is true if the air conditioning is enabled.
*/
bool airConditioning;
- /*!
+ /**
* value holds the airflow directions
*/
AirflowDirections airflowDirections;
- /*!
+ /**
* value is true if the heater is enabled.
*/
bool heater;
- /*!
+ /**
* value holds the fan speed level, where the level can be between
* minimumValue(off) to maximumValue (strongest).
*/
int fanSpeedLevel;
- /*!
+ /**
* value holds the steering wheel heater level, where the level can
* be between minimumValue(off) to maximumValue (warmest).
*/
int steeringWheelHeater;
- /*!
+ /**
* value holds the target temperature of the zone expressed
* in centigrades, where the temperature can be between
* minimumValue(coolest) to maximumValue (warmest).
*/
int targetTemperature;
- /*!
+ /**
* value holds the seat cooler level, where the level can be
* between minimumValue(off) to maximumValue (coolest).
*/
int seatCooler;
- /*!
+ /**
* value holds the seat heater level, where the level can be between
* minimumValue(off) to maximumValue (warmest).
*/
int seatHeater;
- /*!
+ /**
* value holds the outside temperature of the zone expressed in
* centigrades, where the temperature can be between
* minimumValue(coolest) to maximumValue (warmest).
*/
int outsideTemperature;
- /*!
+ /**
* value is true if the zone synchronization is enabled.
*
* Which zones and properties are synchronized is controlled
* by the backend implementing it.
*/
bool zoneSynchronization;
- /*!
+ /**
* value is true if defrost is enabled. Usually that means that the fans
* are on the highest level to remove ice from the windshield.
*/
bool defrost;
- /*!
+ /**
* value holds the recirculation mode
*/
RecirculationMode recirculationMode;
- /*!
+ /**
* value is true if the recirculation is currently running.
*/
bool recirculation;
- /*!
+ /**
* value holds the sensitivity level of the recirculation
* system when the recirculationMode is set to AutoRecirculation,
* where the level can be between minimumValue(least sensitive)
* to maximumValue(most sensitive).
*/
- int recirculationSensitivityLevel;
- /*!
+ int recirculationSensitivityLevel;
+ /**
* value holds the climate mode
*/
- ClimateMode climateMode;
- /*!
+ ClimateMode climateMode;
+ /**
* value holds the intensity level of the fan when the climateMode
* is set to AutoClimate, where the level can be between
* minimumValue(least intensity) to maximumValue(most intensity).
diff --git a/tests/in/com.pelagicore.ivi.tuner.qface b/tests/in/com.pelagicore.ivi.tuner.qface
index 36fab03..765e9f5 100644
--- a/tests/in/com.pelagicore.ivi.tuner.qface
+++ b/tests/in/com.pelagicore.ivi.tuner.qface
@@ -1,42 +1,45 @@
module com.pelagicore.ivi.tuner 1.0;
-/*! Service Tuner */
+/** Service Tuner */
@service()
@interface()
interface Tuner {
- /*! property currentStation */
+ /** property currentStation */
readonly Station currentStation;
- /*! operation nextStation */
+ /** operation nextStation */
void nextStation();
- /*! operation previousStation */
+ /** operation previousStation */
void previousStation();
- /*! operation updateCurrentStation */
- void updateCurrentStation(int stationId);
+ /** operation updateCurrentStation */
+ void updateCurrentStation(int stationId);
list<int> primitiveList;
list<Station> complexList;
model<int> primitiveModel;
model<Station> complexModel;
+
+ signal scanFinished();
+ signal broadcastMessage(string message);
}
-/*! enum State */
+/** enum State */
enum State {
- /*! value State.Null */
+ /** value State.Null */
Null=0,
- /*! value State.Loading */
+ /** value State.Loading */
Loading=1,
- /*! value State.Ready */
+ /** value State.Ready */
Ready=2,
- /*! value State.Error */
+ /** value State.Error */
Error=3
}
-/*! enum Waveband */
+/** enum Waveband */
@default(value=FM)
enum Waveband {
- /*! value Waveband.FM */
+ /** value Waveband.FM */
FM=0,
- /*! value Waveband.AM */
+ /** value Waveband.AM */
AM=1
}
@@ -45,13 +48,13 @@ flag Features {
Stereo = 0x2,
}
-/*! struct Station */
+/** struct Station */
struct Station {
- /*! member stationId */
+ /** member stationId */
int stationId;
- /*! member name */
+ /** member name */
string name;
-}
+}
diff --git a/tests/in/com.pelagicore.ivi.tuner.yaml b/tests/in/com.pelagicore.ivi.tuner.yaml
new file mode 100644
index 0000000..948c50c
--- /dev/null
+++ b/tests/in/com.pelagicore.ivi.tuner.yaml
@@ -0,0 +1,2 @@
+com.pelagicore.ivi.tuner.Tuner:
+ port: 12345
diff --git a/tests/in/com.pelagicore.one.qface b/tests/in/com.pelagicore.one.qface
index 9203d29..9a4eba0 100644
--- a/tests/in/com.pelagicore.one.qface
+++ b/tests/in/com.pelagicore.one.qface
@@ -5,7 +5,7 @@ interface OneService {
list<StringStruct> messageList;
model<StringStruct> messageModel;
StringStruct echo(StringStruct message);
- event void echoMessage(StringStruct mnessage);
+ signal echoMessage(StringStruct mnessage);
}
diff --git a/tests/in/com.pelagicore.test.qface b/tests/in/com.pelagicore.test.qface
index 07ecf1f..c3b5cbf 100644
--- a/tests/in/com.pelagicore.test.qface
+++ b/tests/in/com.pelagicore.test.qface
@@ -35,7 +35,7 @@ flag Phase {
PhaseThree
}
-/*!
+/**
* The contact information
*/
struct Contact {
diff --git a/tests/in/org.example.echo.qface b/tests/in/org.example.echo.qface
new file mode 100644
index 0000000..04a93ce
--- /dev/null
+++ b/tests/in/org.example.echo.qface
@@ -0,0 +1,25 @@
+/** module */
+module org.example.echo 1.0
+
+/**
+ * @brief the brief
+ * @description the description
+ * continues {@link http://qt.io}
+ * @deprecated
+ * @see org.example.echo.Echo
+ * @see org.example
+ * @see http://qt.io
+ * @anything hello
+ */
+interface Echo {
+ /**
+ * @brief brief message
+ * @details long message
+ *
+ * @param msg the messsage
+ * @return the echo
+ */
+ string echo(string msg);
+
+}
+
diff --git a/tests/test_climate.py b/tests/test_climate.py
index b7adec6..1a2135a 100644
--- a/tests/test_climate.py
+++ b/tests/test_climate.py
@@ -1,7 +1,7 @@
from qface.generator import FileSystem
import logging
import logging.config
-from pathlib import Path
+from path import Path
# logging.config.fileConfig('logging.ini')
logging.basicConfig()
@@ -9,7 +9,7 @@ logging.basicConfig()
log = logging.getLogger(__name__)
inputPath = Path('tests/in')
-log.debug('input path folder: {0}'.format(inputPath.absolute()))
+log.debug('input path folder: {0}'.format(inputPath.abspath()))
def load_system():
diff --git a/tests/test_comments.py b/tests/test_comments.py
new file mode 100644
index 0000000..707f759
--- /dev/null
+++ b/tests/test_comments.py
@@ -0,0 +1,55 @@
+from qface.generator import FileSystem
+from qface.helper import doc
+import logging
+import logging.config
+from path import Path
+
+
+# logging.config.fileConfig('logging.ini')
+logging.basicConfig()
+
+log = logging.getLogger(__name__)
+
+inputPath = Path('tests/in')
+
+
+def qdoc_translate(name, value):
+ if not value.startswith('http'):
+ value = value.replace('.', '::')
+ return r'\{0}{{{1}}}'.format(name, value)
+
+
+# doc.DocObject.translate = translate
+
+def loadEcho():
+ path = inputPath / 'org.example.echo.qface'
+ return FileSystem.parse_document(path)
+
+
+def test_comment():
+ system = loadEcho()
+ doc.translate = None
+ module = system.lookup('org.example.echo')
+ assert module.comment == '/** module */'
+ assert module
+ interface = system.lookup('org.example.echo.Echo')
+ assert interface
+ o = doc.parse_doc(interface.comment)
+ # import pdb; pdb.set_trace()
+ assert o.brief == 'the brief'
+ assert o.description == ['the description', 'continues {@link http://qt.io}']
+ assert o.deprecated is True
+ # import pdb; pdb.set_trace()
+ assert o.see == ['org.example.echo.Echo', 'org.example', 'http://qt.io']
+
+
+def test_qdoc_translate():
+ system = loadEcho()
+ module = system.lookup('org.example.echo')
+ assert module.comment == '/** module */'
+ assert module
+ interface = system.lookup('org.example.echo.Echo')
+ assert interface
+ doc.translate = qdoc_translate
+ o = doc.parse_doc(interface.comment)
+ assert o.description == ['the description', 'continues \\link{http://qt.io}']
diff --git a/tests/test_lookup.py b/tests/test_lookup.py
index 7ff7aa5..47184c0 100644
--- a/tests/test_lookup.py
+++ b/tests/test_lookup.py
@@ -1,6 +1,6 @@
import logging
import logging.config
-from pathlib import Path
+from path import Path
from qface.generator import FileSystem
@@ -10,7 +10,7 @@ logging.basicConfig()
log = logging.getLogger(__name__)
inputPath = Path('tests/in')
-log.debug('input path folder: {0}'.format(inputPath.absolute()))
+log.debug('input path folder: {0}'.format(inputPath.abspath()))
def load_tuner():
@@ -34,3 +34,9 @@ def test_lookup():
# lookup enum
enum = system.lookup('com.pelagicore.ivi.tuner.Waveband')
assert enum is module.lookup('Waveband')
+
+ property = system.lookup('com.pelagicore.ivi.tuner.Tuner#currentStation')
+ assert property.name == 'currentStation'
+
+ operation = system.lookup('com.pelagicore.ivi.tuner.Tuner#nextStation')
+ assert operation.name == 'nextStation'
diff --git a/tests/test_parser.py b/tests/test_parser.py
index 3b36cd1..2da5e44 100644
--- a/tests/test_parser.py
+++ b/tests/test_parser.py
@@ -1,6 +1,6 @@
import logging
import logging.config
-from pathlib import Path
+from path import Path
from qface.generator import FileSystem
@@ -10,7 +10,7 @@ logging.basicConfig()
log = logging.getLogger(__name__)
inputPath = Path('tests/in')
-log.debug('input path folder: {0}'.format(inputPath.absolute()))
+log.debug('input path folder: {0}'.format(inputPath.abspath()))
def load_tuner():
@@ -41,7 +41,7 @@ def test_interface():
module = system.lookup('com.pelagicore.ivi.tuner')
interface = system.lookup('com.pelagicore.ivi.tuner.Tuner')
assert interface in module.interfaces
- assert interface.comment == '/*! Service Tuner */'
+ assert interface.comment == '/** Service Tuner */'
def test_property():
@@ -53,7 +53,23 @@ def test_property():
assert property.module == module
assert property.type.qualified_name == 'com.pelagicore.ivi.tuner.Station'
assert property.is_readonly
- assert property.comment == '/*! property currentStation */'
+ assert property.comment == '/** property currentStation */'
+
+
+def test_operation():
+ system = load_tuner()
+ interface = system.lookup('com.pelagicore.ivi.tuner.Tuner')
+ operation = interface._operationMap['nextStation']
+ assert operation
+ operation = interface._contentMap['previousStation']
+ assert operation
+
+
+def test_signals():
+ system = load_tuner()
+ interface = system.lookup('com.pelagicore.ivi.tuner.Tuner')
+ signal = interface._signalMap['scanFinished']
+ assert signal
def test_struct():
@@ -63,7 +79,7 @@ def test_struct():
assert symbol.name == 'Station'
assert symbol.module == module
assert symbol.qualified_name == 'com.pelagicore.ivi.tuner.Station'
- assert symbol.comment == '/*! struct Station */'
+ assert symbol.comment == '/** struct Station */'
def test_enum():
@@ -75,7 +91,7 @@ def test_enum():
assert symbol.name == 'Waveband'
assert symbol.module == module
assert symbol.qualified_name == 'com.pelagicore.ivi.tuner.Waveband'
- assert symbol.comment == '/*! enum Waveband */'
+ assert symbol.comment == '/** enum Waveband */'
assert symbol.is_enum
diff --git a/tests/test_qtcpp_helper.py b/tests/test_qtcpp_helper.py
index d86dfd1..8408d2e 100644
--- a/tests/test_qtcpp_helper.py
+++ b/tests/test_qtcpp_helper.py
@@ -1,6 +1,6 @@
import logging
import logging.config
-from pathlib import Path
+from path import Path
from qface.helper import qtcpp
from qface.generator import FileSystem
@@ -125,7 +125,7 @@ def test_default_value():
# check for enum
prop = interface._propertyMap['status']
answer = qtcpp.Filters.defaultValue(prop)
- assert answer == 'Status::ON'
+ assert answer == 'QmlExampleModule::ON'
# check for list of primitive
prop = interface._propertyMap['list001']
diff --git a/tests/test_tags.py b/tests/test_tags.py
index 5ff56a0..527b623 100644
--- a/tests/test_tags.py
+++ b/tests/test_tags.py
@@ -1,7 +1,7 @@
from qface.generator import FileSystem
import logging
import logging.config
-from pathlib import Path
+from path import Path
# logging.config.fileConfig('logging.ini')
logging.basicConfig()
@@ -9,7 +9,7 @@ logging.basicConfig()
log = logging.getLogger(__name__)
inputPath = Path('tests/in')
-log.debug('input path folder: {0}'.format(inputPath.absolute()))
+log.debug('input path folder: {0}'.format(inputPath.abspath()))
def loadTuner():
@@ -37,3 +37,10 @@ def test_tag():
assert enum is module.lookup('Waveband')
assert 'default' in enum.tags
assert enum.attribute('default', 'value') == 'FM'
+
+
+def test_meta_tags():
+ system = loadTuner()
+ interface = system.lookup('com.pelagicore.ivi.tuner.Tuner')
+ assert interface
+ assert 'port' in interface.tags
diff --git a/tests/test_validation.py b/tests/test_validation.py
index a420783..d742872 100644
--- a/tests/test_validation.py
+++ b/tests/test_validation.py
@@ -1,6 +1,6 @@
import logging
import logging.config
-from pathlib import Path
+from path import Path
from qface.generator import FileSystem
@@ -10,7 +10,7 @@ logging.basicConfig()
log = logging.getLogger(__name__)
inputPath = Path('tests/in')
-log.debug('input path folder: {0}'.format(inputPath.absolute()))
+log.debug('input path folder: {0}'.format(inputPath.abspath()))
def load_one():