gn-language-server/scripts/generate_builtins.py
2025-12-15 21:10:38 +09:00

67 lines
2.6 KiB
Python
Executable file

#!/usr/bin/env python3
#
# Copyright 2025 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import os
import re
import subprocess
_GN_COMMIT = '4e0818fd86bffc0b4a4b61d3295a6732ba08d715'
_SECTION_RE = re.compile(r'^## <a name="([^"]+)">[^\n]*\n\n(.*?)(?=^## |\Z)', re.DOTALL | re.MULTILINE)
_ITEM_RE = re.compile(r'^### <a name="[^"]+"></a>(\*+([^*]+)\*+[^\n]*?)&nbsp;[^\n]*\n(.*?)(?=^### |\Z)', re.DOTALL | re.MULTILINE)
_VERBATIM_RE = re.compile(r'^```$\n(.*?)^```$', re.DOTALL | re.MULTILINE)
def _ensure_gn(out_dir: str):
gn_dir = os.path.join(out_dir, 'gn')
if not os.path.exists(gn_dir):
subprocess.check_call(['git', 'clone', 'https://gn.googlesource.com/gn'], cwd=out_dir)
elif subprocess.run(['git', 'cat-file', '-t', _GN_COMMIT], stdout=subprocess.PIPE, cwd=out_dir).stdout.strip() != 'commit':
subprocess.check_call(['git', 'fetch', 'origin', 'main'], cwd=gn_dir)
subprocess.check_call(['git', 'checkout', '--quiet', _GN_COMMIT], cwd=gn_dir)
def _generate_builtins(out_dir: str):
with open(os.path.join(out_dir, 'gn/docs/reference.md')) as f:
reference = f.read()
with open(os.path.join(out_dir, 'builtins.gen.rsi'), 'w') as out:
print('// This file was generated by generate_builtins.py. DO NOT EDIT.', file=out)
print('', file=out)
print('BuiltinSymbols {', file=out)
for m in _SECTION_RE.finditer(reference):
category = m.group(1)
if category not in ('targets', 'functions', 'predefined_variables', 'target_variables'):
continue
print(f' {category}: &[', file=out)
for m in _ITEM_RE.finditer(m.group(2)):
name = m.group(2)
doc = m.group(1) + '\n' + m.group(3)
doc = _VERBATIM_RE.sub(r'```text\n\1```', doc)
print(f' BuiltinSymbol {{ name: "{name}", doc: r#"{doc}"# }},', file=out)
print(f' ],', file=out)
print('}', file=out)
def main():
os.chdir(os.path.dirname(os.path.dirname(__file__)))
out_dir = os.environ['OUT_DIR']
_ensure_gn(out_dir)
_generate_builtins(out_dir)
if __name__ == '__main__':
main()