| #!/usr/bin/python3 -i |
| # Copyright 2013-2023 The Khronos Group Inc. |
| # SPDX-License-Identifier: Apache-2.0 |
| |
| from generator import OutputGenerator, enquote, write |
| from scriptgenerator import ScriptOutputGenerator |
| import pprint |
| |
| def undefquote(s): |
| if s: |
| return enquote(s) |
| else: |
| return 'undefined' |
| |
| class JSOutputGenerator(ScriptOutputGenerator): |
| """JSOutputGenerator - subclass of ScriptOutputGenerator. |
| Generates JavaScript data structures describing API names and |
| relationships.""" |
| |
| def __init__(self, *args, **kwargs): |
| self.currentDict = None |
| super().__init__(*args, **kwargs) |
| |
| def beginDict(self, name): |
| """String starting definition of a named dictionary""" |
| self.currentDict = name |
| return f'exports.{name} = {{' |
| |
| def endDict(self): |
| """ String ending definition of a named dictionary""" |
| return '}' |
| |
| def writeDict(self, dict, name, printValues = True): |
| """Write dictionary as a JavaScript object with the given name. |
| If printValues is False, just output keys with undefined |
| values.""" |
| |
| write(self.beginDict(name), file=self.outFile) |
| for key in sorted(dict): |
| if printValues: |
| value = undefquote(dict[key]) |
| else: |
| value = 'undefined' |
| write(f'{enquote(key)} : {value},', file=self.outFile) |
| write(self.endDict(), file=self.outFile) |
| |
| def writeList(self, l, name): |
| """Write list l as a JavaScript hash with the given name""" |
| |
| self.writeDict(l, name, printValues = False) |
| |
| def endFile(self): |
| # Creates the inverse mapping of nonexistent APIs to their aliases. |
| super().createInverseMap() |
| |
| # Print out all the dictionaries as JavaScript strings. |
| # Could just print(dict) but that is not human-readable |
| dicts = ( [ self.basetypes, 'basetypes' ], |
| [ self.consts, 'consts' ], |
| [ self.enums, 'enums' ], |
| [ self.flags, 'flags' ], |
| [ self.funcpointers, 'funcpointers' ], |
| [ self.protos, 'protos' ], |
| [ self.structs, 'structs' ], |
| [ self.handles, 'handles' ], |
| [ self.defines, 'defines' ], |
| [ self.typeCategory, 'typeCategory' ], |
| [ self.alias, 'alias' ], |
| [ self.nonexistent, 'nonexistent' ], |
| ) |
| |
| for (dict, name) in dicts: |
| self.writeDict(dict, name) |
| |
| # Dictionary containing the relationships of a type |
| # (e.g. a dictionary with each related type as keys). |
| write(self.beginDict('mapDict'), file=self.outFile) |
| for baseType in sorted(self.mapDict): |
| # Not actually including the relationships yet |
| write(f'{enquote(baseType)} : undefined,', |
| file=self.outFile) |
| write(self.endDict(), file=self.outFile) |
| |
| # List of included feature names |
| self.writeList(sorted(self.features), 'features') |
| |
| # Generate feature <-> interface mappings |
| for feature in self.features: |
| self.mapInterfaces(feature) |
| |
| # Write out the reverse map from APIs to requiring features |
| write(self.beginDict('requiredBy'), file=self.outFile) |
| for api in sorted(self.apimap): |
| # Sort requirements by first feature in each one |
| deps = sorted(self.apimap[api], key = lambda dep: dep[0]) |
| reqs = ', '.join('[{}, {}]'.format(undefquote(dep[0]), undefquote(dep[1])) for dep in deps) |
| write('{} : [{}],'.format(enquote(api), reqs), file=self.outFile) |
| write(self.endDict(), file=self.outFile) |
| |
| super().endFile() |