blob: ba095dd2871b456ec8f45df0ba2ed65efde9a83b [file] [log] [blame]
#!/usr/bin/env python3
# Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
# for details. All rights reserved. Use of this source code is governed by a
# BSD-style license that can be found in the LICENSE file.
from idlnode import *
def render(idl_node, indent_str=' '):
output = []
indent_stack = []
def begin_indent():
indent_stack.append(indent_str)
def end_indent():
indent_stack.pop()
def sort(nodes):
return sorted(nodes, key=lambda node: node.id)
def wln(node=None):
"""Writes the given node and adds a new line."""
w(node)
output.append('\n')
def wsp(node):
"""Writes the given node and adds a space if there was output."""
mark = len(output)
w(node)
if mark != len(output):
w(' ')
def w(node, list_separator=None):
"""Writes the given node.
Args:
node -- a string, IDLNode instance or a list of such.
list_separator -- if provided, and node is a list,
list_separator will be written between the list items.
"""
if node is None:
return
elif isinstance(node, str):
if output and output[-1].endswith('\n'):
# Auto-indent.
output.extend(indent_stack)
output.append(node)
elif isinstance(node, list):
for i in range(0, len(node)):
if i > 0:
w(list_separator)
w(node[i])
elif isinstance(node, IDLFile):
w(node.interfaces)
w(node.enums)
w(node.typeDefs)
elif isinstance(node, IDLModule):
wsp(node.annotations)
wsp(node.ext_attrs)
wln('module %s {' % node.id)
begin_indent()
w(node.interfaces)
w(node.enums)
w(node.typeDefs)
end_indent()
wln('};')
elif isinstance(node, IDLEnum):
w('enum %s {}' % node.id)
# TODO(antonm): emit values as well.
elif isinstance(node, IDLInterface):
if node.annotations:
wln(node.annotations)
if node.ext_attrs:
wln(node.ext_attrs)
w('interface %s' % node.id)
begin_indent()
begin_indent()
if node.parents:
wln(' :')
w(node.parents, ',\n')
wln(' {')
end_indent()
if node.constants:
wln()
wln('/* Constants */')
w(sort(node.constants))
if node.attributes:
wln()
wln('/* Attributes */')
w(sort(node.attributes))
if node.operations:
wln()
wln('/* Operations */')
w(sort(node.operations))
end_indent()
wln('};')
elif isinstance(node, IDLParentInterface):
wsp(node.annotations)
w(node.type.id)
elif isinstance(node, IDLAnnotations):
sep = ''
for (name, annotation) in sorted(node.items()):
w(sep)
sep = ' '
if annotation and len(annotation):
subRes = []
for (argName, argValue) in sorted(annotation.items()):
if argValue is None:
subRes.append(argName)
else:
subRes.append('%s=%s' % (argName, argValue))
w('@%s(%s)' % (name, ', '.join(subRes)))
else:
w('@%s' % name)
elif isinstance(node, IDLExtAttrs):
if len(node):
w('[')
i = 0
for k in sorted(node):
if i > 0:
w(', ')
w(k)
v = node[k]
if v is not None:
if isinstance(v, IDLExtAttrFunctionValue):
if v.id:
w('=')
w(v)
elif isinstance(v, list):
assert k == 'Constructor'
w(v[0])
for c in v[1:]:
w(', ')
w(k)
w(c)
else:
w('=%s' % v.__str__())
i += 1
w(']')
elif isinstance(node, IDLExtAttrFunctionValue):
if node.id:
w(node.id)
w('(')
w(node.arguments, ', ')
w(')')
elif isinstance(node, IDLAttribute):
wsp(node.annotations)
wsp(node.ext_attrs)
if node.is_read_only:
w('readonly ')
w('attribute ')
w(node.type.id)
if (node.type.nullable):
w('?')
w(' ')
w(node.id)
wln(';')
elif isinstance(node, IDLConstant):
wsp(node.annotations)
wsp(node.ext_attrs)
wln('const %s %s = %s;' % (node.type.id, node.id, node.value))
elif isinstance(node, IDLOperation):
wsp(node.annotations)
wsp(node.ext_attrs)
if node.is_static:
w('static ')
if node.specials:
w(node.specials, ' ')
w(' ')
w(node.type.id)
if (node.type.nullable):
w('?')
w(' ')
w(node.id)
w('(')
w(node.arguments, ', ')
w(')')
wln(';')
elif isinstance(node, IDLArgument):
wsp(node.ext_attrs)
if (node.optional):
w('optional ')
w(node.type.id)
if node.type.nullable:
w('?')
w(' %s' % node.id)
else:
raise TypeError("Expected str or IDLNode but %s found" % type(node))
w(idl_node)
return ''.join(output)