From 2ece284f3b9c7ad25694a8fb225422c4505cc9a9 Mon Sep 17 00:00:00 2001 From: Juergen Bocklage-Ryannel Date: Sat, 11 Feb 2017 22:10:06 +0100 Subject: Added simple shell command to be used. Can be used to call a shell command after reloading the generator --- qface/shell.py | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 qface/shell.py diff --git a/qface/shell.py b/qface/shell.py new file mode 100644 index 0000000..5496923 --- /dev/null +++ b/qface/shell.py @@ -0,0 +1,9 @@ +import click +from subprocess import call + + +def sh(cmd, **kwargs): + if not cmd: + return + click.echo('$ {0}'.format(cmd)) + return call(cmd, shell=True, **kwargs) -- cgit v1.2.1 From 7941521f9d079e50af1c00e44f4a36212ff0dab5 Mon Sep 17 00:00:00 2001 From: Juergen Bocklage-Ryannel Date: Sat, 11 Feb 2017 22:11:30 +0100 Subject: Allows now to pass in the command line as array of arguments (args) for the script to be called on FS change --- qface/watch.py | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/qface/watch.py b/qface/watch.py index ca3ec73..18fe5f9 100644 --- a/qface/watch.py +++ b/qface/watch.py @@ -1,21 +1,15 @@ from watchdog.events import FileSystemEventHandler from watchdog.observers import Observer import click -from subprocess import call from path import Path import time -import sys - - -def sh(cmd, all=False, **kwargs): - click.secho('$ {0}'.format(cmd), fg='green') - return call(cmd, shell=True, **kwargs) +from .shell import sh class RunScriptChangeHandler(FileSystemEventHandler): - def __init__(self, script): + def __init__(self, argv): super().__init__() - self.script = script + self.argv = argv self.is_running = False def on_modified(self, event): @@ -25,19 +19,19 @@ class RunScriptChangeHandler(FileSystemEventHandler): if self.is_running: return self.is_running = True - cmd = '{0} {1}'.format(sys.executable, self.script) - sh(cmd, cwd=Path.getcwd()) + # cmd = '{0} {1}'.format(sys.executable, ' '.join(self.argv)) + sh(' '.join(self.argv), cwd=Path.getcwd()) self.is_running = False -def monitor(src, script): +def monitor(src, argv): """ reloads the script when src files changes """ - script = Path(script).expand().abspath() + 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(script) + event_handler = RunScriptChangeHandler(argv) observer = Observer() path = script.dirname().expand().abspath() click.secho('watch recursive: {0}'.format(path), fg='blue') -- cgit v1.2.1 From b47657af5ef6fa87f850fcd48b106be4ecffaced Mon Sep 17 00:00:00 2001 From: Juergen Bocklage-Ryannel Date: Sat, 11 Feb 2017 22:27:01 +0100 Subject: =?UTF-8?q?Introduced=20the=20NamedElement=20base=20class=20for=20?= =?UTF-8?q?the=20domain=20and=20removed=20the=20TypedSymbol.=20This=20make?= =?UTF-8?q?s=20the=20architecture=20simpler=20and=20less=20confusing=20whe?= =?UTF-8?q?n=20the=20Type=20was=20a=20Symbol.=20Additonally=20introduced?= =?UTF-8?q?=20the=20contents=20property=20which=20shall=20generalize=20the?= =?UTF-8?q?=20=E2=80=9Cchildren=E2=80=9D=20of=20a=20symbol,=20e.g.=20param?= =?UTF-8?q?eters=20of=20an=20operation.=20This=20shall=20help=20to=20write?= =?UTF-8?q?=20more=20reusable=20template=20helper=20functions.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- qface/idl/domain.py | 84 ++++++++++++++++++++++++++++----------------------- qface/idl/listener.py | 1 + tests/test_parser.py | 2 +- 3 files changed, 48 insertions(+), 39 deletions(-) diff --git a/qface/idl/domain.py b/qface/idl/domain.py index 1a8ca98..9fc553b 100644 --- a/qface/idl/domain.py +++ b/qface/idl/domain.py @@ -79,23 +79,21 @@ class System(object): 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() - self._definitionMap = ChainMap() + def __unicode__(self): + return self.name - @property - def system(self): - '''returns reference to system''' - return self.module._system + def __str__(self): + return self.name + + def __repr__(self): + return '<{0} name={1}>'.format(type(self), self.name) @property def qualified_name(self): @@ -105,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): @@ -134,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 @@ -159,6 +162,11 @@ class TypeSymbol(Symbol): self.__reference = None 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''' @@ -225,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 @@ -268,10 +276,10 @@ class Module(Symbol): 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: - symbol = self._definitionMap[name] + if name in self._contentMap: + symbol = self._contentMap[name] if fragment: - return symbol._definitionMap[fragment] + return symbol._contentMap[fragment] return symbol return self.system.lookup(name) @@ -285,7 +293,7 @@ class Interface(Symbol): self._propertyMap = OrderedDict() # type: dict[str, Property] self._operationMap = OrderedDict() # type: dict[str, Operation] self._signalMap = OrderedDict() # type: dict[str, Signal] - self._definitionMap = ChainMap(self._propertyMap, self._operationMap, self._signalMap) + self._contentMap = ChainMap(self._propertyMap, self._operationMap, self._signalMap) @property def properties(self): @@ -303,14 +311,14 @@ class Interface(Symbol): return self._signalMap.values() -class Operation(TypedSymbol): +class Operation(Symbol): """An operation inside a interface""" def __init__(self, name: str, interface: Interface): super().__init__(name, interface.module) log.debug('Operation()') self.interface = interface self.interface._operationMap[name] = self - self._parameterMap = OrderedDict() # type: dict[Parameter] + self._parameterMap = self._contentMap = OrderedDict() # type: dict[Parameter] @property def parameters(self): @@ -325,7 +333,7 @@ class Signal(Symbol): log.debug('Signal()') self.interface = interface self.interface._signalMap[name] = self - self._parameterMap = OrderedDict() # type: dict[Parameter] + self._parameterMap = self._contentMap = OrderedDict() # type: dict[Parameter] @property def parameters(self): @@ -333,7 +341,7 @@ class Signal(Symbol): 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) @@ -342,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) @@ -358,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): @@ -366,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) @@ -383,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 925e908..826f44f 100644 --- a/qface/idl/listener.py +++ b/qface/idl/listener.py @@ -34,6 +34,7 @@ class DomainListener(TListener): 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' diff --git a/tests/test_parser.py b/tests/test_parser.py index 8357632..2da5e44 100644 --- a/tests/test_parser.py +++ b/tests/test_parser.py @@ -61,7 +61,7 @@ def test_operation(): interface = system.lookup('com.pelagicore.ivi.tuner.Tuner') operation = interface._operationMap['nextStation'] assert operation - operation = interface._definitionMap['previousStation'] + operation = interface._contentMap['previousStation'] assert operation -- cgit v1.2.1 From a41d19e8bdc9e12c7f1f637f6e2923d5abbd3909 Mon Sep 17 00:00:00 2001 From: Juergen Bocklage-Ryannel Date: Sun, 12 Feb 2017 09:16:12 +0100 Subject: Updated the documentation for the new watch and shell module --- docs/api.rst | 11 +++++++++-- docs/qtcpp.rst | 2 +- qface/shell.py | 7 +++++++ qface/watch.py | 5 ++++- 4 files changed, 21 insertions(+), 4 deletions(-) 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/qtcpp.rst b/docs/qtcpp.rst index 5178eac..b475ffd 100644 --- a/docs/qtcpp.rst +++ b/docs/qtcpp.rst @@ -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 diff --git a/qface/shell.py b/qface/shell.py index 5496923..3d34d89 100644 --- a/qface/shell.py +++ b/qface/shell.py @@ -1,8 +1,15 @@ 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)) diff --git a/qface/watch.py b/qface/watch.py index 18fe5f9..4a8512f 100644 --- a/qface/watch.py +++ b/qface/watch.py @@ -5,6 +5,9 @@ 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): @@ -26,7 +29,7 @@ class RunScriptChangeHandler(FileSystemEventHandler): def monitor(src, argv): """ - reloads the script when src files changes + 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] -- cgit v1.2.1