|  | #!/usr/bin/python | 
|  | # 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.modules) | 
|  | w(node.interfaces) | 
|  | elif isinstance(node, IDLModule): | 
|  | wsp(node.annotations) | 
|  | wsp(node.ext_attrs) | 
|  | wln('module %s {' % node.id) | 
|  | begin_indent() | 
|  | w(node.interfaces) | 
|  | w(node.typeDefs) | 
|  | end_indent() | 
|  | wln('};') | 
|  | 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) | 
|  | 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_fc_getter: | 
|  | w('getter ') | 
|  | if node.is_fc_setter: | 
|  | w('setter ') | 
|  | w('attribute %s %s' % (node.type.id, node.id)) | 
|  | if node.raises: | 
|  | w(' raises (%s)' % node.raises.id) | 
|  | elif node.is_fc_getter and node.get_raises: | 
|  | w(' getraises (%s)' % node.get_raises.id) | 
|  | elif node.is_fc_setter and node.set_raises: | 
|  | w(' setraises (%s)' % node.set_raises.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('%s ' % node.type.id) | 
|  | w(node.id) | 
|  | w('(') | 
|  | w(node.arguments, ', ') | 
|  | w(')') | 
|  | if node.raises: | 
|  | w(' raises (%s)' % node.raises.id) | 
|  | wln(';') | 
|  | elif isinstance(node, IDLArgument): | 
|  | wsp(node.ext_attrs) | 
|  | w('in ') | 
|  | if node.is_optional: | 
|  | w('optional ') | 
|  | w('%s %s' % (node.type.id, node.id)) | 
|  | else: | 
|  | raise TypeError("Expected str or IDLNode but %s found" % | 
|  | type(node)) | 
|  |  | 
|  | w(idl_node) | 
|  | return ''.join(output) |