Coverage for gws-app/gws/spec/generator/base.py: 83%
99 statements
« prev ^ index » next coverage.py v7.11.0, created at 2025-10-16 22:59 +0200
« prev ^ index » next coverage.py v7.11.0, created at 2025-10-16 22:59 +0200
1from typing import Optional
2import sys
4from .. import core
5from . import util
7c = core.c
8v = core.v
9Error = core.Error
10GeneratorError = core.GeneratorError
11LoadError = core.LoadError
12ReadError = core.ReadError
13Type = core.Type
16class Data:
17 def __init__(self, **kwargs):
18 vars(self).update(kwargs)
20 def __repr__(self):
21 return repr(vars(self))
23 def get(self, k, default=None):
24 return vars(self).get(k, default)
26 def __getattr__(self, item):
27 return None
30class _Logger:
31 level = 'INFO'
32 levels = 'ERROR', 'WARNING', 'INFO', 'DEBUG'
34 def set_level(self, level):
35 self.level = level
37 def log(self, level, *args):
38 if self.levels.index(level) <= self.levels.index(self.level):
39 msg = f'[spec] {level}: ' + ' '.join(str(a) for a in args)
40 sys.stdout.write(msg + '\n')
41 sys.stdout.flush()
43 def error(self, *args):
44 self.log('ERROR', *args)
46 def warning(self, *args):
47 self.log('WARNING', *args)
49 def info(self, *args):
50 self.log('INFO', *args)
52 def debug(self, *args):
53 self.log('DEBUG', *args)
56log = _Logger()
59class Generator:
60 def __init__(self):
61 self.aliases: dict[str, str] = {}
62 self.chunks: list[core.Chunk] = []
63 self.meta: dict = {}
64 self.typeDict: dict[str, Type] = {}
65 self.serverTypes: list[Type] = []
66 self.specData: core.SpecData
67 self.configRef = {}
68 self.strings = {}
69 self.manifestPath = ''
70 self.outDir = ''
71 self.rootDir = ''
72 self.selfDir = ''
73 self.typescript = ''
74 self.debug = False
76 def add_type(self, **kwargs):
77 if kwargs.get('name'):
78 kwargs['uid'] = kwargs['name']
79 if not kwargs.get('uid'):
80 kwargs['uid'] = kwargs['c'] + ':' + _auto_uid(kwargs)
81 typ = core.make_type(kwargs)
82 self.typeDict[typ.uid] = typ
83 return typ
85 def get_type(self, uid) -> Optional[Type]:
86 return self.typeDict.get(uid)
88 def require_type(self, uid) -> Type:
89 typ = self.typeDict.get(uid)
90 if not typ:
91 raise GeneratorError(f'unknown type {uid!r}')
92 return typ
94 def dump(self, tag):
95 if self.debug:
96 util.write_json(self.outDir + '/' + tag + '.debug.json', vars(self))
99def _auto_uid(args):
100 tc = args['c']
101 if tc == c.DICT:
102 return args['tKey'] + ',' + args['tValue']
103 if tc == c.LIST:
104 return args['tItem']
105 if tc == c.SET:
106 return args['tItem']
107 if tc == c.LITERAL:
108 return _comma(repr(v) for v in args['literalValues'])
109 if tc == c.OPTIONAL:
110 return args['tTarget']
111 if tc == c.TUPLE:
112 return _comma(args['tItems'])
113 if tc == c.UNION:
114 return _comma(sorted(args['tItems']))
115 if tc == c.CALLABLE:
116 return _comma(sorted(args['tItems']))
117 if tc == c.EXT:
118 return args['extName']
119 if tc == c.VARIANT:
120 if 'tMembers' in args:
121 return _comma(sorted(args['tMembers'].values()))
122 return _comma(sorted(args['tItems']))
123 raise GeneratorError(f'auto uid for {tc!r} not implemented: {args}')
126_comma = ','.join