summaryrefslogtreecommitdiff
path: root/qface/idl/listener.py
diff options
context:
space:
mode:
Diffstat (limited to 'qface/idl/listener.py')
-rw-r--r--qface/idl/listener.py46
1 files changed, 39 insertions, 7 deletions
diff --git a/qface/idl/listener.py b/qface/idl/listener.py
index 34a0c64..5fafa4f 100644
--- a/qface/idl/listener.py
+++ b/qface/idl/listener.py
@@ -7,11 +7,12 @@ from .domain import *
from antlr4 import ParserRuleContext
import yaml
import click
+from .profile import get_features, EProfile, EFeature
try:
- from yaml import CLoader as Loader, CDumper as Dumper
+ from yaml import CSafeLoader as Loader, CDumper as Dumper
except ImportError:
- from yaml import Loader, Dumper
+ from yaml import SafeLoader as Loader, Dumper
log = logging.getLogger(__name__)
@@ -20,15 +21,28 @@ log = logging.getLogger(__name__)
contextMap = {}
-class DomainListener(TListener):
+class QFaceListener(TListener):
+ def __init__(self, system, profile=EProfile.FULL):
+ super().__init__()
+ click.secho('qface uses language profile: {}'.format(profile), fg='blue')
+ self.lang_features = get_features(profile)
+ self.system = system or System() # type:System
+
+ def check_support(self, feature, report=True):
+ if feature not in self.lang_features and report:
+ click.secho('Unsuported language feature: {}'.format(EFeature.IMPORT), fg='red')
+ return False
+ return True
+
+
+class DomainListener(QFaceListener):
"""The domain listener is called by the parser to fill the
domain data struture. As a result a system is passed
back"""
- def __init__(self, system):
- super(DomainListener, self).__init__()
+ def __init__(self, system, profile=EProfile.FULL):
+ super().__init__(system, profile)
contextMap.clear()
- self.system = system or System() # type:System
self.module = None # type:Module
self.interface = None # type:Interface
self.struct = None # type:Struct
@@ -63,6 +77,14 @@ class DomainListener(TListener):
type.name = 'list'
type.nested = TypeSymbol("", type)
self.parse_type(ctxSymbol, type.nested)
+ elif ctx.typeSymbol().mapTypeSymbol():
+ self.check_support(EFeature.MAPS)
+ # type:TParser.ListTypeSymbolContext
+ ctxSymbol = ctx.typeSymbol().mapTypeSymbol()
+ type.is_map = True
+ type.name = 'map'
+ type.nested = TypeSymbol("", type)
+ self.parse_type(ctxSymbol, type.nested)
elif ctx.typeSymbol().modelTypeSymbol():
# type:TParser.ModelTypeSymbolContext
ctxSymbol = ctx.typeSymbol().modelTypeSymbol()
@@ -84,7 +106,7 @@ class DomainListener(TListener):
data = yaml.load('\n'.join(lines), Loader=Loader)
symbol._tags = data
except yaml.YAMLError as exc:
- click.secho(exc, fg='red')
+ click.secho(str(exc), fg='red')
def enterEveryRule(self, ctx):
log.debug('enter ' + ctx.__class__.__name__)
@@ -186,9 +208,18 @@ class DomainListener(TListener):
name = ctx.name.text
self.property = Property(name, self.interface)
modifier = ctx.propertyModifierSymbol()
+
if modifier:
self.property.readonly = bool(modifier.is_readonly)
self.property.const = bool(modifier.is_const)
+
+ # if ctx.value:
+ # try:
+ # value = yaml.load(ctx.value.text, Loader=Loader)
+ # self.property._value = value
+ # except yaml.YAMLError as exc:
+ # click.secho(exc, fg='red')
+
self.parse_annotations(ctx, self.property)
self.parse_type(ctx, self.property.type)
contextMap[ctx] = self.property
@@ -227,6 +258,7 @@ class DomainListener(TListener):
def enterImportSymbol(self, ctx: TParser.ImportSymbolContext):
assert self.module
+ self.check_support(EFeature.IMPORT)
name = ctx.name.text
version = ctx.version.text
self.module._importMap[name] = '{0} {1}'.format(name, version)