-
-
Notifications
You must be signed in to change notification settings - Fork 44
/
Copy pathapiwriter.py
140 lines (127 loc) · 4.25 KB
/
apiwriter.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
"""
Writes the parts of the API that are simple: flags, enums, structs.
"""
import re
from codegen.utils import print, format_code, to_snake_case
from codegen.idlparser import get_idl_parser
from codegen.files import file_cache
ref_pattern = re.compile(r"\W((GPU|flags\.|enums\.|structs\.)\w+?)\W", re.MULTILINE)
def resolve_crossrefs(text):
# Similar code as in docs/conf.py
text += " "
i2 = 0
while True:
m = ref_pattern.search(text, i2)
if not m:
break
i1, i2 = m.start(1), m.end(1)
prefix = m.group(2)
ref_indicator = ":obj:" if prefix.lower() == prefix else ":class:"
name = m.group(1)
if name.startswith("structs."):
link = name.split(".")[1]
else:
link = "wgpu." + name
insertion = f"{ref_indicator}`{name} <{link}>`"
text = text[:i1] + insertion + text[i2:]
i2 += len(insertion) - len(name)
return text.rstrip()
def write_flags():
# Get preamble
pylines = []
for line in file_cache.read("flags.py").splitlines():
pylines.append(line)
if "AUTOGENERATED" in line:
pylines += ["", ""]
break
# Prepare
idl = get_idl_parser()
n = len(idl.flags)
# List'm
pylines.append(f"# There are {n} flags\n")
pylines.append("__all__ = [")
for name in idl.flags.keys():
pylines.append(f' "{name}",')
pylines.append("]\n\n")
# The flags definitions
for name, d in idl.flags.items():
# Generate Code
pylines.append(f"class {name}(Flags):\n")
for key, val in d.items():
pylines.append(f" {key} = {val!r}") # note: can add docs using "#: "
pylines.append("\n")
# Write
code = format_code("\n".join(pylines))
file_cache.write("flags.py", code)
print(f"Wrote {n} flags to flags.py")
def write_enums():
# Get preamble
pylines = []
for line in file_cache.read("enums.py").splitlines():
pylines.append(line)
if "AUTOGENERATED" in line:
pylines += ["", ""]
break
# Prepare
idl = get_idl_parser()
n = len(idl.enums)
# List'm
pylines.append(f"# There are {n} enums\n")
pylines.append("__all__ = [")
for name in idl.enums.keys():
pylines.append(f' "{name}",')
pylines.append("]\n\n")
for name, d in idl.enums.items():
# Generate Code
pylines.append(f"class {name}(Enum):\n")
for key, val in d.items():
pylines.append(f' {key} = "{val}"') # note: can add docs using "#: "
pylines.append("\n")
# Write
code = format_code("\n".join(pylines))
file_cache.write("enums.py", code)
print(f"Wrote {n} enums to enums.py")
def write_structs():
# Get preamble
pylines = []
for line in file_cache.read("structs.py").splitlines():
pylines.append(line)
if "AUTOGENERATED" in line:
pylines += ["", ""]
break
# Prepare
idl = get_idl_parser()
n = len(idl.structs)
ignore = ["ImageCopyTextureTagged"]
pylines.append(f"# There are {n} structs\n")
# List'm
pylines.append("__all__ = [")
for name in idl.structs.keys():
if name not in ignore:
pylines.append(f' "{name}",')
pylines.append("]\n\n")
for name, d in idl.structs.items():
if name in ignore:
continue
# Object-docstring as a comment
for field in d.values():
tp = idl.resolve_type(field.typename).strip("'")
if field.default:
pylines.append(
resolve_crossrefs(f"#: * {field.name} :: {tp} = {field.default}")
)
else:
pylines.append(resolve_crossrefs(f"#: * {field.name} :: {tp}"))
# Generate Code
pylines.append(f'{name} = Struct(\n "{name}",')
for field in d.values():
key = to_snake_case(field.name)
val = idl.resolve_type(field.typename)
if not val.startswith(("'", '"')):
val = f"'{val}'"
pylines.append(f" {key}={val},")
pylines.append(")\n")
# Write
code = format_code("\n".join(pylines))
file_cache.write("structs.py", code)
print(f"Wrote {n} structs to structs.py")