OLD | NEW |
| (Empty) |
1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | |
2 // for details. All rights reserved. Use of this source code is governed by a | |
3 // BSD-style license that can be found in the LICENSE file. | |
4 | |
5 List sorted(Iterable input, [compare, key]) { | |
6 comparator(compare, key) { | |
7 if (compare == null && key == null) | |
8 return (a, b) => a.compareTo(b); | |
9 if (compare == null) | |
10 return (a, b) => key(a).compareTo(key(b)); | |
11 if (key == null) | |
12 return compare; | |
13 return (a, b) => compare(key(a), key(b)); | |
14 } | |
15 List copy = new List.from(input); | |
16 copy.sort(comparator(compare, key)); | |
17 return copy; | |
18 } | |
19 | |
20 render(idl_node, [indent_str=' ']) { | |
21 var output = ['']; | |
22 var indent_stack = []; | |
23 | |
24 indented(action) { // TODO: revert to indented(action()) { | |
25 indent_stack.add(indent_str); | |
26 action(); | |
27 indent_stack.removeLast(); | |
28 } | |
29 | |
30 sort(nodes) => sorted(nodes, key: (a) => a.id); | |
31 | |
32 var w; // For some reason mutually recursive local functions don't work. | |
33 | |
34 wln([node]) { | |
35 w(node); | |
36 output.add('\n'); | |
37 } | |
38 | |
39 w = (node, [list_separator]) { | |
40 /* | |
41 Writes the given node. | |
42 | |
43 Args: | |
44 node -- a string, IDLNode instance or a list of such. | |
45 list_separator -- if provided, and node is a list, | |
46 list_separator will be written between the list items. | |
47 */ | |
48 if (node == null) { | |
49 return; | |
50 } else if (node is String) { | |
51 if (output.last.endsWith('\n')) | |
52 output.addAll(indent_stack); | |
53 output.add(node); | |
54 } else if (node is List) { | |
55 var separator = null; | |
56 for (var element in node) { | |
57 w(separator); | |
58 separator = list_separator; | |
59 w(element); | |
60 } | |
61 } else if (node is IDLFile) { | |
62 w(node.modules); | |
63 w(node.interfaces); | |
64 } else if (node is IDLModule) { | |
65 w(node.annotations); | |
66 w(node.extAttrs); | |
67 wln('module ${node.id} {'); | |
68 indented(() { | |
69 w(node.interfaces); | |
70 w(node.typedefs); | |
71 }); | |
72 wln('};'); | |
73 } else if (node is IDLInterface) { | |
74 w(node.annotations); | |
75 w(node.extAttrs); | |
76 w('interface ${node.id}'); | |
77 indented(() { | |
78 if (!node.parents.isEmpty) { | |
79 wln(' :'); | |
80 w(node.parents, ',\n'); | |
81 } | |
82 wln(' {'); | |
83 section(list, comment) { | |
84 if (list != null && !list.isEmpty) { | |
85 wln(); | |
86 wln(comment); | |
87 w(sort(list)); | |
88 } | |
89 } | |
90 section(node.constants, '/* Constants */'); | |
91 section(node.attributes, '/* Attributes */'); | |
92 section(node.operations, '/* Operations */'); | |
93 section(node.snippets, '/* Snippets */'); | |
94 }); | |
95 wln('};'); | |
96 } else if (node is IDLParentInterface) { | |
97 w(node.annotations); | |
98 w(node.type.id); | |
99 } else if (node is IDLAnnotations) { | |
100 for (var name in sorted(node.map.keys)) { | |
101 IDLAnnotation annotation = node.map[name]; | |
102 var args = annotation.map; | |
103 if (args.isEmpty) { | |
104 w('@$name'); | |
105 } else { | |
106 var formattedArgs = []; | |
107 for (var argName in sorted(args.keys)) { | |
108 var argValue = args[argName]; | |
109 if (argValue == null) | |
110 formattedArgs.add(argName); | |
111 else | |
112 formattedArgs.add('$argName=$argValue'); | |
113 } | |
114 w('@$name(${Strings.join(formattedArgs,',')})'); | |
115 } | |
116 w(' '); | |
117 } | |
118 } else if (node is IDLExtAttrs) { | |
119 if(!node.map.isEmpty) { | |
120 w('['); | |
121 var sep = null; | |
122 for (var name in sorted(node.map.keys)) { | |
123 w(sep); | |
124 sep = ', '; | |
125 w(name); | |
126 var value = node.map[name]; | |
127 if (value != null) { | |
128 w('='); | |
129 w(value); | |
130 } | |
131 } | |
132 w('] '); | |
133 } | |
134 } else if (node is IDLAttribute) { | |
135 w(node.annotations); | |
136 w(node.extAttrs); | |
137 //if (node.isFcGetter) | |
138 // w('getter '); | |
139 //if (node.isFcSetter) | |
140 // w('setter '); | |
141 wln('attribute ${node.type.id} ${node.id};'); | |
142 } else if (node is IDLConstant) { | |
143 w(node.annotations); | |
144 w(node.extAttrs); | |
145 wln('const ${node.type.id} ${node.id} = ${node.value};'); | |
146 } else if (node is IDLSnippet) { | |
147 w(node.annotations); | |
148 wln('snippet {${node.text}};'); | |
149 } else if (node is IDLOperation) { | |
150 w(node.annotations); | |
151 w(node.extAttrs); | |
152 if (node.specials != null && !node.specials.isEmpty) { | |
153 w(node.specials, ' '); | |
154 w(' '); | |
155 } | |
156 w('${node.type.id} ${node.id}'); | |
157 w('('); | |
158 w(node.arguments, ', '); | |
159 wln(');'); | |
160 } else if (node is IDLArgument) { | |
161 w(node.extAttrs); | |
162 w('in '); | |
163 if (node.isOptional) | |
164 w('optional '); | |
165 w('${node.type.id} ${node.id}'); | |
166 } else if (node is IDLExtAttrFunctionValue) { | |
167 w(node.name); | |
168 w('('); | |
169 w(node.arguments, ', '); | |
170 w(')'); | |
171 } else if (node is IDLTypeDef) { | |
172 wln('typedef ${node.type.id} ${node.id};'); | |
173 } else { | |
174 w('// $node\n'); | |
175 } | |
176 }; | |
177 | |
178 w(idl_node); | |
179 return Strings.concatAll(output); | |
180 } | |
OLD | NEW |