• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/python3 -i
2# Copyright 2013-2023 The Khronos Group Inc.
3# SPDX-License-Identifier: Apache-2.0
4
5from generator import OutputGenerator, enquote, write
6from scriptgenerator import ScriptOutputGenerator
7import pprint
8
9def undefquote(s):
10    if s:
11        return enquote(s)
12    else:
13        return 'undefined'
14
15class JSOutputGenerator(ScriptOutputGenerator):
16    """JSOutputGenerator - subclass of ScriptOutputGenerator.
17    Generates JavaScript data structures describing API names and
18    relationships."""
19
20    def __init__(self, *args, **kwargs):
21        self.currentDict = None
22        super().__init__(*args, **kwargs)
23
24    def beginDict(self, name):
25        """String starting definition of a named dictionary"""
26        self.currentDict = name
27        return f'exports.{name} = {{'
28
29    def endDict(self):
30        """ String ending definition of a named dictionary"""
31        return '}'
32
33    def writeDict(self, dict, name, printValues = True):
34        """Write dictionary as a JavaScript object with the given name.
35           If printValues is False, just output keys with undefined
36           values."""
37
38        write(self.beginDict(name), file=self.outFile)
39        for key in sorted(dict):
40            if printValues:
41                value = undefquote(dict[key])
42            else:
43                value = 'undefined'
44            write(f'{enquote(key)} : {value},', file=self.outFile)
45        write(self.endDict(), file=self.outFile)
46
47    def writeList(self, l, name):
48        """Write list l as a JavaScript hash with the given name"""
49
50        self.writeDict(l, name, printValues = False)
51
52    def endFile(self):
53        # Creates the inverse mapping of nonexistent APIs to their aliases.
54        super().createInverseMap()
55
56        # Print out all the dictionaries as JavaScript strings.
57        # Could just print(dict) but that is not human-readable
58        dicts = ( [ self.basetypes,     'basetypes' ],
59                  [ self.consts,        'consts' ],
60                  [ self.enums,         'enums' ],
61                  [ self.flags,         'flags' ],
62                  [ self.funcpointers,  'funcpointers' ],
63                  [ self.protos,        'protos' ],
64                  [ self.structs,       'structs' ],
65                  [ self.handles,       'handles' ],
66                  [ self.defines,       'defines' ],
67                  [ self.typeCategory,  'typeCategory' ],
68                  [ self.alias,         'alias' ],
69                  [ self.nonexistent,   'nonexistent' ],
70                )
71
72        for (dict, name) in dicts:
73            self.writeDict(dict, name)
74
75        # Dictionary containing the relationships of a type
76        # (e.g. a dictionary with each related type as keys).
77        write(self.beginDict('mapDict'), file=self.outFile)
78        for baseType in sorted(self.mapDict):
79            # Not actually including the relationships yet
80            write(f'{enquote(baseType)} : undefined,',
81                file=self.outFile)
82        write(self.endDict(), file=self.outFile)
83
84        # List of included feature names
85        self.writeList(sorted(self.features), 'features')
86
87        # Generate feature <-> interface mappings
88        for feature in self.features:
89            self.mapInterfaces(feature)
90
91        # Write out the reverse map from APIs to requiring features
92        write(self.beginDict('requiredBy'), file=self.outFile)
93        for api in sorted(self.apimap):
94            # Sort requirements by first feature in each one
95            deps = sorted(self.apimap[api], key = lambda dep: dep[0])
96            reqs = ', '.join('[{}, {}]'.format(undefquote(dep[0]), undefquote(dep[1])) for dep in deps)
97            write('{} : [{}],'.format(enquote(api), reqs), file=self.outFile)
98        write(self.endDict(), file=self.outFile)
99
100        super().endFile()
101