Coverage for gws-app/gws/spec/generator/base.py: 51%

98 statements  

« prev     ^ index     » next       coverage.py v7.8.0, created at 2025-04-17 01:37 +0200

1import os 

2import sys 

3 

4from . import util 

5 

6from gws.spec.core import * 

7 

8ATOMS = ['any', 'bool', 'bytes', 'float', 'int', 'str'] 

9 

10BUILTINS = ATOMS + ['type', 'object', 'Exception', 'dict', 'list', 'set', 'tuple'] 

11 

12BUILTIN_TYPES = [ 

13 'Any', 

14 'Callable', 

15 'ContextManager', 

16 'Dict', 

17 'Enum', 

18 'Iterable', 

19 'Iterator', 

20 'List', 

21 'Literal', 

22 'Optional', 

23 'Protocol', 

24 'Set', 

25 'Tuple', 

26 'TypeAlias', 

27 'Union', 

28 

29 # imported in TYPE_CHECKING 

30 'datetime.datetime', 

31 'osgeo', 

32 'sqlalchemy', 

33 

34 # vendor libs 

35 'gws.lib.vendor', 

36 'gws.lib.sa', 

37] 

38 

39# those star-imported in gws/__init__.py 

40GLOBAL_MODULES = [ 

41 APP_NAME + '.core.const', 

42 # APP_NAME + '.core.data', 

43 # APP_NAME + '.core.tree', 

44 # APP_NAME + '.core.types', 

45 APP_NAME + '.core.util', 

46 # APP_NAME + '.core.error', 

47 # APP_NAME + '.core' 

48] 

49 

50DEFAULT_EXT_SUPERS = { 

51 'config': APP_NAME + '.core.types.ConfigWithAccess', 

52 'props': APP_NAME + '.core.types.Props', 

53} 

54 

55# prefix for gws.plugin class names 

56PLUGIN_PREFIX = APP_NAME + '.plugin' 

57 

58# comment prefix for Variant aliases 

59VARIANT_COMMENT_PREFIX = 'variant:' 

60 

61# inline comment symbol 

62INLINE_COMMENT_SYMBOL = '#:' 

63 

64# where we are 

65SELF_DIR = os.path.dirname(__file__) 

66 

67# path to `/repository-root/app` 

68APP_DIR = os.path.abspath(SELF_DIR + '/../../..') 

69 

70EXCLUDE_PATHS = ['___', '/vendor/', 'test', 'core/ext', '__pycache__'] 

71 

72FILE_KINDS = [ 

73 ['.py', 'python'], 

74 ['/index.ts', 'ts'], 

75 ['/index.tsx', 'ts'], 

76 ['/index.css.js', 'css'], 

77 ['.theme.css.js', 'theme'], 

78 ['/strings.ini', 'strings'], 

79] 

80 

81PLUGIN_DIR = '/gws/plugin' 

82 

83SYSTEM_CHUNKS = [ 

84 [APP_NAME + '', '/js/src/gws'], 

85 [APP_NAME + '.core', '/gws/core'], 

86 [APP_NAME + '.base', '/gws/base'], 

87 [APP_NAME + '.gis', '/gws/gis'], 

88 [APP_NAME + '.lib', '/gws/lib'], 

89 [APP_NAME + '.server', '/gws/server'], 

90 [APP_NAME + '.helper', '/gws/helper'], 

91 

92] 

93 

94 

95class Data: # type: ignore 

96 def __init__(self, **kwargs): 

97 vars(self).update(kwargs) 

98 

99 def __repr__(self): 

100 return repr(vars(self)) 

101 

102 def get(self, k, default=None): 

103 return vars(self).get(k, default) 

104 

105 def __getattr__(self, item): 

106 return None 

107 

108 

109class _Logger: 

110 level = 'INFO' 

111 levels = 'ERROR', 'WARNING', 'INFO', 'DEBUG' 

112 

113 def set_level(self, level): 

114 self.level = level 

115 

116 def log(self, level, *args): 

117 if self.levels.index(level) <= self.levels.index(self.level): 

118 msg = f'[spec] {level}: ' + ' '.join(str(a) for a in args) 

119 sys.stdout.write(msg + '\n') 

120 sys.stdout.flush() 

121 

122 def error(self, *args): self.log('ERROR', *args) 

123 

124 def warning(self, *args): self.log('WARNING', *args) 

125 

126 def info(self, *args): self.log('INFO', *args) 

127 

128 def debug(self, *args): self.log('DEBUG', *args) 

129 

130 

131log = _Logger() 

132 

133 

134class Generator(Data): 

135 meta: dict 

136 types: dict[str, Type] 

137 specs = {} 

138 typescript = '' 

139 strings = {} 

140 

141 configRef = {} 

142 

143 rootDir = '' 

144 selfDir = '' 

145 outDir = '' 

146 manifestPath = '' 

147 

148 debug = False 

149 

150 chunks: list[dict] 

151 

152 def __init__(self): 

153 super().__init__() 

154 self.aliases = {} 

155 self.types = {} 

156 

157 def new_type(self, c, **kwargs): 

158 if kwargs.get('name'): 

159 t = Type(**kwargs) 

160 t.c = c 

161 t.uid = t.name 

162 return t 

163 

164 uid = c + ',' + _auto_uid(c, kwargs) 

165 if uid in self.types: 

166 return self.types[uid] 

167 

168 t = Type(**kwargs) 

169 t.c = c 

170 t.uid = uid 

171 return t 

172 

173 def dump(self, tag): 

174 if self.debug: 

175 util.write_json(self.outDir + '/' + tag + '.debug.json', self) 

176 

177 

178def _auto_uid(c, d): 

179 comma = ',' 

180 if c == C.DICT: 

181 return d['tKey'] + comma + d['tValue'] 

182 if c == C.LIST: 

183 return d['tItem'] 

184 if c == C.SET: 

185 return d['tItem'] 

186 if c == C.LITERAL: 

187 return comma.join(repr(v) for v in d['literalValues']) 

188 if c == C.OPTIONAL: 

189 return d['tTarget'] 

190 if c == C.TUPLE: 

191 return comma.join(d['tItems']) 

192 if c == C.UNION: 

193 return comma.join(sorted(d['tItems'])) 

194 if c == C.EXT: 

195 return d['extName'] 

196 if c == C.VARIANT: 

197 if 'tMembers' in d: 

198 return comma.join(sorted(d['tMembers'].values())) 

199 return comma.join(sorted(d['tItems'])) 

200 

201 return ''