Add export annotation @exportFunction
This commit adds a new export annotation: @exportFunction. @exportFunction is to be used to declare functions that take an options object literal as their first arguments. @exportFunction is to regular functions as @exportClass is to constructors. The usage of @exportFunction is as follows: @exportFunction ol.control.defaults ol.control.DefaultsOptions ol.Collection Note: the Function#export method uses a recursive function. This is to handle nested options.
This commit is contained in:
@@ -120,6 +120,78 @@ class Class(Exportable):
|
|||||||
return '%sExport' % self.name
|
return '%sExport' % self.name
|
||||||
|
|
||||||
|
|
||||||
|
class Function(Exportable):
|
||||||
|
|
||||||
|
def __init__(self, name, object_literal, return_type, objects):
|
||||||
|
Exportable.__init__(self, name)
|
||||||
|
self.object_literal = object_literal
|
||||||
|
self.return_type = return_type
|
||||||
|
self.objects = objects
|
||||||
|
|
||||||
|
__repr__ = simplerepr
|
||||||
|
|
||||||
|
def property_object_literal(self, object_literal, prop):
|
||||||
|
prop_object_literal = None
|
||||||
|
types = object_literal.prop_types[prop].split('|')
|
||||||
|
for t in types:
|
||||||
|
if t in self.objects:
|
||||||
|
o = self.objects[t]
|
||||||
|
if isinstance(o, ObjectLiteral):
|
||||||
|
if prop_object_literal:
|
||||||
|
raise RuntimeError('Multiple "literal" types found for '
|
||||||
|
'option %s.%s: %s, %s.' %
|
||||||
|
(object_literal.name, prop,
|
||||||
|
prop_object_literal.name, o.name))
|
||||||
|
prop_object_literal = o
|
||||||
|
return prop_object_literal
|
||||||
|
|
||||||
|
def recursive_export(self, lines, prop, object_literal, local_var=None, depth=1):
|
||||||
|
indent = ' ' * depth
|
||||||
|
if not local_var:
|
||||||
|
local_var = prop.split('.')[-1]
|
||||||
|
lines.append('%s/** @type {%s} */\n' % (indent, object_literal.name))
|
||||||
|
lines.append('%svar %s =\n' % (indent, local_var))
|
||||||
|
lines.append('%s /** @type {%s} */\n' % (indent, object_literal.name))
|
||||||
|
lines.append('%s (%s);\n' % (indent, prop))
|
||||||
|
lines.append('%sif (goog.isDefAndNotNull(%s)) {\n' % (indent, prop))
|
||||||
|
for key in sorted(object_literal.prop_types.keys()):
|
||||||
|
prop_object_literal = self.property_object_literal(object_literal, key)
|
||||||
|
if prop_object_literal:
|
||||||
|
lv = self.recursive_export(lines, '%s.%s' % (prop, key),
|
||||||
|
prop_object_literal, depth=depth + 1)
|
||||||
|
lines.append('%s %s.%s =\n%s %s;\n' %
|
||||||
|
(indent, local_var, key, indent, lv))
|
||||||
|
else:
|
||||||
|
lines.append('%s %s.%s =\n%s %s.%s;\n' %
|
||||||
|
(indent, local_var, key, indent, prop, key))
|
||||||
|
lines.append('%s}\n' % (indent,))
|
||||||
|
return local_var
|
||||||
|
|
||||||
|
def export(self):
|
||||||
|
lines = []
|
||||||
|
local_var = 'arg'
|
||||||
|
lines.append('\n\n')
|
||||||
|
lines.append('/**\n')
|
||||||
|
lines.append(' * @param {%s} options Options.\n' % (self.object_literal.extern_name(),))
|
||||||
|
if self.return_type:
|
||||||
|
lines.append(' * @return {%s} Return value.\n' % (self.return_type,))
|
||||||
|
lines.append(' */\n')
|
||||||
|
lines.append('%s = function(options) {\n' % (self.export_name(),))
|
||||||
|
self.recursive_export(lines, 'options', self.object_literal,
|
||||||
|
local_var=local_var)
|
||||||
|
if self.return_type:
|
||||||
|
lines.append(' return %s(%s);\n' % (self.name, local_var))
|
||||||
|
else:
|
||||||
|
lines.append(' %s(arg);\n' % (self.name,))
|
||||||
|
lines.append('};\n')
|
||||||
|
lines.append('goog.exportSymbol(\n')
|
||||||
|
lines.append(' \'%s\',\n' % (self.name,))
|
||||||
|
lines.append(' %s);\n' % (self.export_name(),))
|
||||||
|
return ''.join(lines)
|
||||||
|
|
||||||
|
def export_name(self):
|
||||||
|
return '%sExport' % self.name
|
||||||
|
|
||||||
class ObjectLiteral(Exportable):
|
class ObjectLiteral(Exportable):
|
||||||
|
|
||||||
def __init__(self, name, objects):
|
def __init__(self, name, objects):
|
||||||
@@ -268,6 +340,22 @@ def main(argv):
|
|||||||
objects[name] = symbol
|
objects[name] = symbol
|
||||||
symbol.props.add(prop)
|
symbol.props.add(prop)
|
||||||
continue
|
continue
|
||||||
|
m = re.match(r'@exportFunction\s+(?P<name>\S+)(?:\s+(?P<object_literal_name>\S+))?(?:\s+(?P<return_type>\S+))?\Z', line)
|
||||||
|
if m:
|
||||||
|
name = m.group('name')
|
||||||
|
if name in objects:
|
||||||
|
raise RuntimeError(line) # Name already defined
|
||||||
|
object_literal_name = m.group('object_literal_name')
|
||||||
|
if object_literal_name not in objects:
|
||||||
|
raise RuntimeError(line)
|
||||||
|
object_literal = objects[object_literal_name]
|
||||||
|
if not isinstance(object_literal, ObjectLiteral):
|
||||||
|
raise RuntimeError(line)
|
||||||
|
return_type = m.group('return_type')
|
||||||
|
function = Function(name, object_literal, return_type, objects)
|
||||||
|
objects[name] = function
|
||||||
|
requires.add(name)
|
||||||
|
continue
|
||||||
m = re.match(r'@exportSymbol\s+(?P<name>\S+)(?:\s+(?P<export_as>\S+))?\Z', line)
|
m = re.match(r'@exportSymbol\s+(?P<name>\S+)(?:\s+(?P<export_as>\S+))?\Z', line)
|
||||||
if m:
|
if m:
|
||||||
name = m.group('name')
|
name = m.group('name')
|
||||||
|
|||||||
Reference in New Issue
Block a user