diff options
Diffstat (limited to 'qface')
-rw-r--r-- | qface/__about__.py | 2 | ||||
-rw-r--r-- | qface/filters.py | 28 | ||||
-rw-r--r-- | qface/generator.py | 55 | ||||
-rw-r--r-- | qface/helper/doc.py | 4 | ||||
-rw-r--r-- | qface/helper/qtcpp.py | 2 | ||||
-rw-r--r-- | qface/idl/domain.py | 2 | ||||
-rw-r--r-- | qface/idl/listener.py | 1 | ||||
-rw-r--r-- | qface/templates/__init__.py | 0 | ||||
-rw-r--r-- | qface/templates/qface/__init__.py | 0 |
9 files changed, 76 insertions, 18 deletions
diff --git a/qface/__about__.py b/qface/__about__.py index a9d62f6..0d6a726 100644 --- a/qface/__about__.py +++ b/qface/__about__.py @@ -9,7 +9,7 @@ except NameError: __title__ = "qface" __summary__ = "A generator framework based on a common modern IDL" __url__ = "https://pelagicore.github.io/qface/" -__version__ = "1.5" +__version__ = "1.6" __author__ = "JRyannel" __author_email__ = "qface-generator@googlegroups.com" __copyright__ = "2017 Pelagicore" diff --git a/qface/filters.py b/qface/filters.py index af9fc1f..c5ecab8 100644 --- a/qface/filters.py +++ b/qface/filters.py @@ -2,25 +2,29 @@ import json import hashlib -def jsonify(obj): +def jsonify(symbol): + """ returns json format for symbol """ try: # all symbols have a toJson method, try it - return json.dumps(obj.toJson(), indent=' ') + return json.dumps(symbol.toJson(), indent=' ') except AttributeError: pass - return json.dumps(obj, indent=' ') + return json.dumps(symbol, indent=' ') -def upper_first(s): - s = str(s) - return s[0].upper() + s[1:] +def upper_first(symbol): + """ uppercase first letter """ + name = str(symbol) + return name[0].upper() + name[1:] -def hash(s, hash_type='sha1'): - h = hashlib.new(hash_type) - h.update(str(s).encode('utf-8')) - return h.hexdigest() +def hash(symbol, hash_type='sha1'): + """ create a hash code from symbol """ + code = hashlib.new(hash_type) + code.update(str(symbol).encode('utf-8')) + return code.hexdigest() -def path(s): - return str(s).replace('.', '/') +def path(symbol): + """ replaces '.' with '/' """ + return str(symbol).replace('.', '/') diff --git a/qface/generator.py b/qface/generator.py index 997ace8..c2e018b 100644 --- a/qface/generator.py +++ b/qface/generator.py @@ -1,3 +1,4 @@ + # Copyright (c) Pelagicore AB 2016 from jinja2 import Environment, Template @@ -5,12 +6,13 @@ from jinja2 import FileSystemLoader, PackageLoader, ChoiceLoader from jinja2 import TemplateSyntaxError, TemplateNotFound, TemplateError from path import Path from antlr4 import FileStream, CommonTokenStream, ParseTreeWalker -from antlr4.error import DiagnosticErrorListener +from antlr4.error import DiagnosticErrorListener, ErrorListener import shelve import logging import hashlib import yaml import click +import sys from .idl.parser.TLexer import TLexer from .idl.parser.TParser import TParser @@ -43,8 +45,30 @@ def lower_first_filter(s): return s[0].lower() + s[1:] +class ReportingErrorListener(ErrorListener.ErrorListener): + def __init__(self, document): + self.document = document + + def syntaxError(self, recognizer, offendingSymbol, line, column, msg, e): + msg = '{0}:{1}:{2} {2}'.format(self.document, line, column, msg) + click.secho(msg, fg='red') + raise ValueError(msg) + + def reportAmbiguity(self, recognizer, dfa, startIndex, stopIndex, exact, ambigAlts, configs): + click.secho('ambiguity', fg='red') + + def reportAttemptingFullContext(self, recognizer, dfa, startIndex, stopIndex, conflictingAlts, configs): + click.secho('reportAttemptingFullContext', fg='red') + + def reportContextSensitivity(self, recognizer, dfa, startIndex, stopIndex, prediction, configs): + click.secho('reportContextSensitivity', fg='red') + + class Generator(object): """Manages the templates and applies your context data""" + strict = False + """ enables strict code generation """ + def __init__(self, search_path: str): loader = ChoiceLoader([ FileSystemLoader(search_path), @@ -86,18 +110,24 @@ class Generator(object): """Using a template file name it renders a template into a file given a context """ + error = False try: self._write(file_path, template, context, preserve) except TemplateSyntaxError as exc: # import pdb; pdb.set_trace() message = '{0}:{1} error: {2}'.format(exc.filename, exc.lineno, exc.message) click.secho(message, fg='red') + error = True except TemplateNotFound as exc: message = '{0} error: Template not found'.format(exc.name) click.secho(message, fg='red') + error = True except TemplateError as exc: message = 'error: {0}'.format(exc.message) click.secho(message, fg='red') + error = True + if error and Generator.strict: + sys.exit(-1) def _write(self, file_path: Path, template: str, context: dict, preserve: bool = False): path = self.destination / Path(self.apply(file_path, context)) @@ -125,9 +155,26 @@ class Generator(object): class FileSystem(object): """QFace helper functions to work with the file system""" + strict = False + """ enables strict parsing """ @staticmethod def parse_document(document: Path, system: System = None): + error = False + try: + return FileSystem._parse_document(document, system) + except FileNotFoundError as e: + click.secho('{0}: file not found'.format(document), fg='red') + error = True + except ValueError as e: + click.secho('Error parsing document {0}'.format(document)) + error = True + if error and FileSystem.strict: + sys.exit(-1) + + + @staticmethod + def _parse_document(document: Path, system: System = None): """Parses a document and returns the resulting domain system :param path: document path to parse @@ -135,19 +182,19 @@ class FileSystem(object): """ logger.debug('parse document: {0}'.format(document)) stream = FileStream(str(document), encoding='utf-8') - system = FileSystem._parse_stream(stream, system) + system = FileSystem._parse_stream(stream, system, document) FileSystem.merge_annotations(system, document.stripext() + '.yaml') return system @staticmethod - def _parse_stream(stream, system: System = None): + def _parse_stream(stream, system: System = None, document=None): logger.debug('parse stream') system = system or System() lexer = TLexer(stream) stream = CommonTokenStream(lexer) parser = TParser(stream) - parser.addErrorListener(DiagnosticErrorListener.DiagnosticErrorListener()) + parser.addErrorListener(ReportingErrorListener(document)) tree = parser.documentSymbol() walker = ParseTreeWalker() walker.walk(DomainListener(system), tree) diff --git a/qface/helper/doc.py b/qface/helper/doc.py index 0935e67..9695136 100644 --- a/qface/helper/doc.py +++ b/qface/helper/doc.py @@ -21,7 +21,7 @@ class DocObject: The documentation object passed into the template engine """ def __init__(self): - self.brief = str() + self.brief = [] self.description = [] self.see = [] self.deprecated = False @@ -78,4 +78,6 @@ def parse_doc(s): doc.add_tag(tag, value) elif tag: # append to previous matched tag doc.add_tag(tag, line) + else: # append any loose lines to description + doc.add_tag('description', line) return doc diff --git a/qface/helper/qtcpp.py b/qface/helper/qtcpp.py index 4a7178d..db959b4 100644 --- a/qface/helper/qtcpp.py +++ b/qface/helper/qtcpp.py @@ -39,6 +39,8 @@ class Filters(object): module_name = upper_first(t.reference.module.module_name) value = next(iter(t.reference.members)) return '{0}{1}Module::{2}'.format(prefix, module_name, value) + elif t.is_flag: + return '0' elif symbol.type.is_list: nested = Filters.returnType(symbol.type.nested) return 'QVariantList()'.format(nested) diff --git a/qface/idl/domain.py b/qface/idl/domain.py index b8c611f..a2e3972 100644 --- a/qface/idl/domain.py +++ b/qface/idl/domain.py @@ -125,6 +125,7 @@ class Symbol(NamedElement): self._contentMap = ChainMap() self.type = TypeSymbol('', self) + self.kind = self.__class__.__name__.lower() """ the associated type information """ @property @@ -431,6 +432,7 @@ class Operation(Symbol): def toJson(self): o = super().toJson() o['parameters'] = [s.toJson() for s in self.parameters] + o['type'] = self.type.toJson() return o diff --git a/qface/idl/listener.py b/qface/idl/listener.py index 3704444..3a36837 100644 --- a/qface/idl/listener.py +++ b/qface/idl/listener.py @@ -214,6 +214,7 @@ class DomainListener(TListener): if ctx.intSymbol(): value = int(ctx.intSymbol().value.text, 0) self.field.value = value + self.parse_annotations(ctx, self.field) contextMap[ctx] = self.field if self.enum.is_flag: self.enumCounter <<= 1 diff --git a/qface/templates/__init__.py b/qface/templates/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/qface/templates/__init__.py +++ /dev/null diff --git a/qface/templates/qface/__init__.py b/qface/templates/qface/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/qface/templates/qface/__init__.py +++ /dev/null |