This rather large commit refactors the build system to solve a number of problems: - Object literal types are now declared in just one place - There are no more circular dependencies - There is no need for concealed subclasses in build-standalone mode When building in standalone mode, you need to include the source in build/src/external. This declares object literal types as externs so that their properties are not renamed. When building with the application, you need to include the source in build/src/internal. This declares object literal types as typedefs so that their properties can be renamed and removed. Note also that ol.MapOptions has been merged into ol.Map, with some renaming.
100 lines
3.1 KiB
Python
Executable File
100 lines
3.1 KiB
Python
Executable File
#!/usr/bin/env python
|
|
|
|
import fileinput
|
|
from operator import attrgetter
|
|
from optparse import OptionParser
|
|
import re
|
|
import sys
|
|
|
|
|
|
class Type(object):
|
|
|
|
def __init__(self, name, members=None):
|
|
self.name = name
|
|
self.namespace = '.'.join(self.name.split('.')[:-1]) or None
|
|
self.members = members or {}
|
|
|
|
def extern(self):
|
|
lines = []
|
|
lines.append('/**\n')
|
|
lines.append(' * @interface\n')
|
|
lines.append(' */\n')
|
|
lines.append('%s = function() {};\n' % (self.name,))
|
|
for key in sorted(self.members.keys()):
|
|
lines.append('\n')
|
|
lines.append('\n')
|
|
lines.append('/**\n')
|
|
lines.append(' * @type {%s}\n' % (self.members[key],))
|
|
lines.append(' */\n')
|
|
lines.append('%s.prototype.%s;\n' % (self.name, key))
|
|
return ''.join(lines)
|
|
|
|
def provide(self):
|
|
return 'goog.provide(\'%sType\');\n' % (self.name,)
|
|
|
|
def typedef(self):
|
|
lines = []
|
|
lines.append('/**\n')
|
|
for i, key in enumerate(sorted(self.members.keys())):
|
|
prefix = ' * @typedef {{' if i == 0 else ' * '
|
|
suffix = '}}' if i == len(self.members) - 1 else ','
|
|
type = self.members[key]
|
|
if '|' in type:
|
|
type = '(%s)' % (type,)
|
|
lines.append('%s%s: %s%s\n' % (prefix, key, type, suffix))
|
|
lines.append(' */\n')
|
|
lines.append('%s;\n' % (self.name,))
|
|
return ''.join(lines)
|
|
|
|
|
|
def main(argv):
|
|
|
|
option_parser = OptionParser()
|
|
option_parser.add_option('--externs', action='store_true')
|
|
option_parser.add_option('--typedef', action='store_true')
|
|
options, args = option_parser.parse_args(argv[1:])
|
|
|
|
types = []
|
|
for arg in args:
|
|
for line in open(arg):
|
|
line = line.strip()
|
|
if not line:
|
|
continue
|
|
m = re.match('@externtype\s*(?P<name>\S+)\Z', line)
|
|
if m:
|
|
type = Type(m.group('name'))
|
|
types.append(type)
|
|
continue
|
|
m = re.match('(?P<key>\S+):\s+(?P<value>\S+)', line)
|
|
if m:
|
|
type.members[m.group('key')] = m.group('value')
|
|
continue
|
|
raise RuntimeError(line)
|
|
types = sorted(types, key=attrgetter('name'))
|
|
|
|
if options.externs:
|
|
sys.stdout.write('/**\n')
|
|
sys.stdout.write(' * @externs\n')
|
|
sys.stdout.write(' */\n')
|
|
namespaces = sorted(set(filter(None, (type.namespace for type in types))))
|
|
for namespace in namespaces:
|
|
sys.stdout.write('\n\n')
|
|
sys.stdout.write('/**\n')
|
|
sys.stdout.write(' * @type {Object}\n')
|
|
sys.stdout.write(' */\n')
|
|
sys.stdout.write('var %s;\n' % (namespace,))
|
|
for type in types:
|
|
sys.stdout.write('\n\n\n')
|
|
sys.stdout.write(type.extern())
|
|
|
|
if options.typedef:
|
|
for type in types:
|
|
sys.stdout.write(type.provide())
|
|
for type in types:
|
|
sys.stdout.write('\n\n')
|
|
sys.stdout.write(type.typedef())
|
|
|
|
|
|
if __name__ == '__main__':
|
|
sys.exit(main(sys.argv))
|