mirror of
https://github.com/github/codeql.git
synced 2025-12-17 17:23:36 +01:00
105 lines
3.2 KiB
Python
105 lines
3.2 KiB
Python
'''Tool for generating the dbscheme from the relation tree described in
|
|
'master.py' and the part scheme in dbscheme.template'''
|
|
|
|
|
|
|
|
from semmle.util import fprintf
|
|
from semmle import util
|
|
from semmle.python import master
|
|
|
|
import sys
|
|
import os.path
|
|
|
|
|
|
def write(nodes, out):
|
|
nodes = set(nodes)
|
|
#Emit in sorted order to reduce diffs.
|
|
sorted_nodes = sorted(nodes, key = lambda n: n.__name__)
|
|
fprintf(out, '\n')
|
|
for n in sorted_nodes:
|
|
if n.layout:
|
|
fprintf(out, '\n')
|
|
for name, f_t, offset, _, _, _ in n.layout:
|
|
fprintf(out, '/* <Field> %s.%s = %s, %s */\n',
|
|
n.ql_name(), name, offset, f_t.__name__)
|
|
if n.parents:
|
|
fprintf(out, '/* <Parent> %s = %s */\n',
|
|
n.ql_name(), n.parents.ql_name())
|
|
parents = set()
|
|
for n in sorted_nodes:
|
|
if n.is_sub_type() or n.is_union_type():
|
|
continue
|
|
fprintf(out, u'%s(', n.relation_name())
|
|
if n.__name__ == "bool":
|
|
fields = []
|
|
else:
|
|
fields = [ n.db_key('id') ]
|
|
if n.is_case_type():
|
|
fields.append('int kind: int ref')
|
|
if n.parents:
|
|
parents.add(n.parents)
|
|
if n.unique_parent:
|
|
fields.append('unique int parent : %s ref' % n.parents.db_name())
|
|
else:
|
|
fields.append('int parent : %s ref' % n.parents.db_name())
|
|
fields.append('int idx : int ref')
|
|
fprintf(out, ',\n '.join(fields))
|
|
fprintf(out, ');\n\n')
|
|
nodes = nodes | parents
|
|
sorted_nodes = sorted(nodes, key = lambda n: n.__name__)
|
|
for n in sorted_nodes:
|
|
if n.is_case_type():
|
|
fprintf(out, 'case %s.kind of\n ', n.db_name())
|
|
subtypes = sorted(n.subclasses, key = lambda x : x.index)
|
|
body = '\n| '.join(['%s = %s' % (s.index, s.db_name())
|
|
for s in subtypes])
|
|
fprintf(out, '%s;\n\n' % body)
|
|
for n in sorted_nodes:
|
|
if n.is_union_type():
|
|
fprintf(out, '%s = ', n.db_name())
|
|
body = ' | '.join(sorted([item.db_name() for item in n.types]))
|
|
fprintf(out, '%s;\n\n' % body)
|
|
|
|
HEADER = '''/*
|
|
* This dbscheme is auto-generated by '%s'.
|
|
* WARNING: Any modifications to this file will be lost.
|
|
* Relations can be changed by modifying master.py or
|
|
* by adding rules to dbscheme.template
|
|
*/
|
|
|
|
'''
|
|
|
|
AUTO_GEN_END = '''
|
|
/*
|
|
* End of auto-generated part
|
|
*/
|
|
|
|
'''
|
|
|
|
def main():
|
|
run(master)
|
|
|
|
def run(nodes_module):
|
|
use_file = len(sys.argv) > 1
|
|
if use_file:
|
|
out = open(sys.argv[1], 'w', encoding='utf-8')
|
|
else:
|
|
out = sys.stdout
|
|
try:
|
|
nodes = nodes_module.all_nodes()
|
|
this_dir, _ = os.path.split(sys.argv[0])
|
|
with open(os.path.join(this_dir, 'dbscheme.template')) as template_file:
|
|
t0, t1 = template_file.read().split('$AST_SCHEME$')
|
|
out.write(HEADER % '/'.join(__file__.split(os.path.sep)[-2:]))
|
|
out.write(t0)
|
|
out.write(util.AUTO_GEN_STRING)
|
|
write(nodes.values(), out)
|
|
out.write(AUTO_GEN_END)
|
|
out.write(t1)
|
|
finally:
|
|
if use_file:
|
|
out.close()
|
|
|
|
if __name__ == '__main__':
|
|
main()
|