#!/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) 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 %s %s' % (node.type.id, node.id)) if node.raises: w(' raises (%s)' % node.raises.id) else: if node.get_raises: w(' getraises (%s)' % node.get_raises.id) if 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 ') 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)