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

1from . import base 

2from .base import Type 

3 

4 

5def extract(gen: base.Generator): 

6 """Extracts server specs from the types library. 

7 

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 """ 

15 

16 p = _Extractor(gen) 

17 p.run() 

18 

19 

20class _Extractor: 

21 out: dict[str, Type] = {} 

22 queue: list[str] = [] 

23 

24 def __init__(self, gen: base.Generator): 

25 self.gen = gen 

26 

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)] 

32 

33 def add(self, typ: Type, **kwargs): 

34 kwargs.setdefault('isConfig', False) 

35 

36 mod = self.gen.get_type(typ.tModule) 

37 if mod: 

38 kwargs['modName'] = mod.name 

39 kwargs['modPath'] = mod.modPath 

40 

41 vars(typ).update(kwargs) 

42 self.out[typ.uid] = typ 

43 

44 def extract(self): 

45 # config-related types 

46 self.queue = ['gws.base.application.core.Config'] 

47 self.extract_all(isConfig=True) 

48 

49 # application objects, including methods and their args/rets 

50 self.queue = ['gws.base.application.core.Object'] 

51 self.extract_all() 

52 

53 # ext objects 

54 self.queue = list(set(typ.uid for typ in self.gen.typeDict.values() if typ.extName)) 

55 self.extract_all() 

56 

57 def extract_all(self, **kwargs): 

58 while self.queue: 

59 self.extract_one(**kwargs) 

60 

61 def extract_one(self, **kwargs): 

62 typ = self.gen.require_type(self.queue.pop(0)) 

63 

64 if typ.uid in self.out or typ.c == base.c.ATOM: 

65 return 

66 

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 

72 

73 if typ.c == base.c.CLASS and typ.extName.startswith(base.v.EXT_OBJECT_PREFIX): 

74 self.add(typ, **kwargs) 

75 return 

76 

77 if typ.c == base.c.CLASS: 

78 self.add(typ, **kwargs) 

79 self.queue.extend(typ.tProperties.values()) 

80 return 

81 

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 

87 

88 if typ.c in {base.c.LIST, base.c.SET}: 

89 self.add(typ, **kwargs) 

90 self.queue.append(typ.tItem) 

91 return 

92 

93 if typ.c in {base.c.OPTIONAL, base.c.TYPE}: 

94 self.add(typ, **kwargs) 

95 self.queue.append(typ.tTarget) 

96 return 

97 

98 if typ.c in {base.c.TUPLE, base.c.UNION}: 

99 self.add(typ, **kwargs) 

100 self.queue.extend(typ.tItems) 

101 return 

102 

103 if typ.c == base.c.VARIANT: 

104 self.add(typ, **kwargs) 

105 self.queue.extend(typ.tMembers.values()) 

106 return 

107 

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 

113 

114 if typ.c == base.c.CLASS: 

115 self.add(typ, **kwargs) 

116 self.queue.extend(typ.tProperties.values()) 

117 return 

118 

119 if typ.c == base.c.ENUM: 

120 self.add(typ, **kwargs) 

121 return 

122 

123 if typ.c == base.c.LITERAL: 

124 self.add(typ, **kwargs) 

125 return 

126 

127 if typ.c == base.c.EXT: 

128 return 

129 

130 raise base.GeneratorError(f'unbound object {typ.c}: {typ.uid!r} in {typ.pos}')