Coverage for gws-app/gws/spec/generator/extractor.py: 95%
88 statements
« prev ^ index » next coverage.py v7.15.4, created at 2026-08-24 12:46 +0200
« prev ^ index » next coverage.py v7.15.4, created at 2026-08-24 12:46 +0200
1from . import base
2from .base import Type
5def extract(gen: base.Generator):
6 """Extracts server specs from the types library.
8 For the server, we need
9 - all gws.ext.object.xxx, but not their properties (too many)
10 - all gws.ext.config.xxx and gws.ext.properties.xxx
11 - their properties, recursively
12 - command methods (gws.ext.command.xxx)
13 - their args and rets, recursively
14 """
16 p = _Extractor(gen)
17 p.run()
20class _Extractor:
21 out: dict[str, Type] = {}
22 queue: list[str] = []
24 def __init__(self, gen: base.Generator):
25 self.gen = gen
27 def run(self):
28 self.out = {}
29 self.queue = []
30 self.extract()
31 self.gen.serverTypes = [self.out[uid] for uid in sorted(self.out)]
33 def add(self, typ: Type, **kwargs):
34 kwargs.setdefault('isConfig', False)
36 mod = self.gen.get_type(typ.tModule)
37 if mod:
38 kwargs['modName'] = mod.name
39 kwargs['modPath'] = mod.modPath
41 vars(typ).update(kwargs)
42 self.out[typ.uid] = typ
44 def extract(self):
45 # config-related types
46 self.queue = ['gws.base.application.core.Config']
47 self.extract_all(isConfig=True)
49 # application objects, including methods and their args/rets
50 self.queue = ['gws.base.application.core.Object']
51 self.extract_all()
53 # ext objects
54 self.queue = list(set(typ.uid for typ in self.gen.typeDict.values() if typ.extName))
55 self.extract_all()
57 def extract_all(self, **kwargs):
58 while self.queue:
59 self.extract_one(**kwargs)
61 def extract_one(self, **kwargs):
62 typ = self.gen.require_type(self.queue.pop(0))
64 if typ.uid in self.out or typ.c == base.c.ATOM:
65 return
67 if typ.c == base.c.METHOD and typ.extName.startswith(base.v.EXT_COMMAND_PREFIX):
68 self.add(typ, **kwargs)
69 self.queue.append(typ.tOwner)
70 self.queue.append(typ.tArg)
71 return
73 if typ.c == base.c.CLASS and typ.extName.startswith(base.v.EXT_OBJECT_PREFIX):
74 self.add(typ, **kwargs)
75 return
77 if typ.c == base.c.CLASS:
78 self.add(typ, **kwargs)
79 self.queue.extend(typ.tProperties.values())
80 return
82 if typ.c == base.c.DICT:
83 self.add(typ, **kwargs)
84 self.queue.append(typ.tKey)
85 self.queue.append(typ.tValue)
86 return
88 if typ.c in {base.c.LIST, base.c.SET}:
89 self.add(typ, **kwargs)
90 self.queue.append(typ.tItem)
91 return
93 if typ.c in {base.c.OPTIONAL, base.c.TYPE}:
94 self.add(typ, **kwargs)
95 self.queue.append(typ.tTarget)
96 return
98 if typ.c in {base.c.TUPLE, base.c.UNION}:
99 self.add(typ, **kwargs)
100 self.queue.extend(typ.tItems)
101 return
103 if typ.c == base.c.VARIANT:
104 self.add(typ, **kwargs)
105 self.queue.extend(typ.tMembers.values())
106 return
108 if typ.c == base.c.PROPERTY:
109 self.add(typ, **kwargs)
110 self.queue.append(typ.tValue)
111 self.queue.append(typ.tOwner)
112 return
114 if typ.c == base.c.CLASS:
115 self.add(typ, **kwargs)
116 self.queue.extend(typ.tProperties.values())
117 return
119 if typ.c == base.c.ENUM:
120 self.add(typ, **kwargs)
121 return
123 if typ.c == base.c.LITERAL:
124 self.add(typ, **kwargs)
125 return
127 if typ.c == base.c.EXT:
128 return
130 raise base.GeneratorError(f'unbound object {typ.c}: {typ.uid!r} in {typ.pos}')