Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 #!/usr/bin/python | 1 #!/usr/bin/python |
| 2 # Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 2 # Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file |
| 3 # for details. All rights reserved. Use of this source code is governed by a | 3 # for details. All rights reserved. Use of this source code is governed by a |
| 4 # BSD-style license that can be found in the LICENSE file. | 4 # BSD-style license that can be found in the LICENSE file. |
| 5 | 5 |
| 6 """This module generates Dart APIs from the IDL database.""" | 6 """This module generates Dart APIs from the IDL database.""" |
| 7 | 7 |
| 8 import emitter | 8 import emitter |
| 9 import idlnode | 9 import idlnode |
| 10 import logging | 10 import logging |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 94 ]) | 94 ]) |
| 95 | 95 |
| 96 # | 96 # |
| 97 # Custom getters that must be implemented by hand. | 97 # Custom getters that must be implemented by hand. |
| 98 # | 98 # |
| 99 _custom_getters = set([ | 99 _custom_getters = set([ |
| 100 ('DOMWindow', 'localStorage'), | 100 ('DOMWindow', 'localStorage'), |
| 101 ]) | 101 ]) |
| 102 | 102 |
| 103 # | 103 # |
| 104 # Publically visible types common across all supported browsers. | |
| 105 # | |
| 106 _BROWSER_SHARED_TYPES = [ | |
| 107 'Attr', | |
| 108 'CDATASection', | |
| 109 'CSSFontFaceRule', | |
| 110 'CSSImportRule', | |
| 111 'CSSMediaRule', | |
| 112 'CSSPageRule', | |
| 113 'CSSRule', | |
| 114 'CSSRuleList', | |
| 115 'CSSStyleDeclaration', | |
| 116 'CSSStyleRule', | |
| 117 'CSSStyleSheet', | |
| 118 'CanvasRenderingContext2D', | |
| 119 'CharacterData', | |
| 120 'ClientRect', | |
| 121 'ClientRectList', | |
| 122 'Comment', | |
| 123 'DOMException', | |
| 124 'DOMImplementation', | |
| 125 'DOMParser', | |
| 126 'Document', | |
| 127 'DocumentFragment', | |
| 128 'DocumentType', | |
| 129 'Element', | |
| 130 'Event', | |
| 131 'EventException', | |
| 132 'HTMLAnchorElement', | |
| 133 'HTMLAppletElement', | |
| 134 'HTMLAreaElement', | |
| 135 'HTMLAudioElement', | |
| 136 'HTMLBRElement', | |
| 137 'HTMLBaseElement', | |
| 138 'HTMLBodyElement', | |
| 139 'HTMLButtonElement', | |
| 140 'HTMLCanvasElement', | |
| 141 'HTMLCollection', | |
| 142 'HTMLDListElement', | |
| 143 'HTMLDirectoryElement', | |
| 144 'HTMLDivElement', | |
| 145 'HTMLElement', | |
| 146 'HTMLEmbedElement', | |
| 147 'HTMLFieldSetElement', | |
| 148 'HTMLFontElement', | |
| 149 'HTMLFormElement', | |
| 150 'HTMLFrameElement', | |
| 151 'HTMLFrameSetElement', | |
| 152 'HTMLHRElement', | |
| 153 'HTMLHeadElement', | |
| 154 'HTMLHeadingElement', | |
| 155 'HTMLHtmlElement', | |
| 156 'HTMLIFrameElement', | |
| 157 'HTMLImageElement', | |
| 158 'HTMLInputElement', | |
| 159 'HTMLLIElement', | |
| 160 'HTMLLabelElement', | |
| 161 'HTMLLegendElement', | |
| 162 'HTMLLinkElement', | |
| 163 'HTMLMapElement', | |
| 164 'HTMLMediaElement', | |
| 165 'HTMLMenuElement', | |
| 166 'HTMLMetaElement', | |
| 167 'HTMLModElement', | |
| 168 'HTMLOListElement', | |
| 169 'HTMLObjectElement', | |
| 170 'HTMLOptGroupElement', | |
| 171 'HTMLOptionElement', | |
| 172 'HTMLParagraphElement', | |
| 173 'HTMLParamElement', | |
| 174 'HTMLPreElement', | |
| 175 'HTMLQuoteElement', | |
| 176 'HTMLScriptElement', | |
| 177 'HTMLSelectElement', | |
| 178 'HTMLStyleElement', | |
| 179 'HTMLTableCaptionElement', | |
| 180 'HTMLTableCellElement', | |
| 181 'HTMLTableColElement', | |
| 182 'HTMLTableElement', | |
| 183 'HTMLTableRowElement', | |
| 184 'HTMLTableSectionElement', | |
| 185 'HTMLTextAreaElement', | |
| 186 'HTMLTitleElement', | |
| 187 'HTMLUListElement', | |
| 188 'HTMLVideoElement', | |
| 189 'KeyboardEvent', | |
| 190 'MediaError', | |
| 191 'MediaList', | |
| 192 'MessageEvent', | |
| 193 'MouseEvent', | |
| 194 'MutationEvent', | |
| 195 'NamedNodeMap', | |
| 196 'Node', | |
| 197 'NodeFilter', | |
| 198 'NodeList', | |
| 199 'ProcessingInstruction', | |
| 200 'Range', | |
| 201 'RangeException', | |
| 202 'SVGAElement', | |
| 203 'SVGAngle', | |
| 204 'SVGAnimatedAngle', | |
| 205 'SVGAnimatedBoolean', | |
| 206 'SVGAnimatedEnumeration', | |
| 207 'SVGAnimatedInteger', | |
| 208 'SVGAnimatedLength', | |
| 209 'SVGAnimatedLengthList', | |
| 210 'SVGAnimatedNumber', | |
| 211 'SVGAnimatedNumberList', | |
| 212 'SVGAnimatedPreserveAspectRatio', | |
| 213 'SVGAnimatedRect', | |
| 214 'SVGAnimatedString', | |
| 215 'SVGAnimatedTransformList', | |
| 216 'SVGCircleElement', | |
| 217 'SVGClipPathElement', | |
| 218 'SVGDefsElement', | |
| 219 'SVGDescElement', | |
| 220 'SVGElement', | |
| 221 'SVGEllipseElement', | |
| 222 'SVGException', | |
| 223 'SVGGElement', | |
| 224 'SVGGradientElement', | |
| 225 'SVGImageElement', | |
| 226 'SVGLength', | |
| 227 'SVGLengthList', | |
| 228 'SVGLineElement', | |
| 229 'SVGLinearGradientElement', | |
| 230 'SVGMarkerElement', | |
| 231 'SVGMaskElement', | |
| 232 'SVGMatrix', | |
| 233 'SVGMetadataElement', | |
| 234 'SVGNumber', | |
| 235 'SVGNumberList', | |
| 236 'SVGPathElement', | |
| 237 'SVGPathSeg', | |
| 238 'SVGPathSegArcAbs', | |
| 239 'SVGPathSegArcRel', | |
| 240 'SVGPathSegClosePath', | |
| 241 'SVGPathSegCurvetoCubicAbs', | |
| 242 'SVGPathSegCurvetoCubicRel', | |
| 243 'SVGPathSegCurvetoCubicSmoothAbs', | |
| 244 'SVGPathSegCurvetoCubicSmoothRel', | |
| 245 'SVGPathSegCurvetoQuadraticAbs', | |
| 246 'SVGPathSegCurvetoQuadraticRel', | |
| 247 'SVGPathSegCurvetoQuadraticSmoothAbs', | |
| 248 'SVGPathSegCurvetoQuadraticSmoothRel', | |
| 249 'SVGPathSegLinetoAbs', | |
| 250 'SVGPathSegLinetoHorizontalAbs', | |
| 251 'SVGPathSegLinetoHorizontalRel', | |
| 252 'SVGPathSegLinetoRel', | |
| 253 'SVGPathSegLinetoVerticalAbs', | |
| 254 'SVGPathSegLinetoVerticalRel', | |
| 255 'SVGPathSegList', | |
| 256 'SVGPathSegMovetoAbs', | |
| 257 'SVGPathSegMovetoRel', | |
| 258 'SVGPatternElement', | |
| 259 'SVGPoint', | |
| 260 'SVGPointList', | |
| 261 'SVGPolygonElement', | |
| 262 'SVGPolylineElement', | |
| 263 'SVGPreserveAspectRatio', | |
| 264 'SVGRadialGradientElement', | |
| 265 'SVGRect', | |
| 266 'SVGRectElement', | |
| 267 'SVGSVGElement', | |
| 268 'SVGScriptElement', | |
| 269 'SVGStopElement', | |
| 270 'SVGStyleElement', | |
| 271 'SVGSwitchElement', | |
| 272 'SVGSymbolElement', | |
| 273 'SVGTSpanElement', | |
| 274 'SVGTextContentElement', | |
| 275 'SVGTextElement', | |
| 276 'SVGTextPathElement', | |
| 277 'SVGTextPositioningElement', | |
| 278 'SVGTitleElement', | |
| 279 'SVGTransform', | |
| 280 'SVGTransformList', | |
| 281 'SVGUnitTypes', | |
| 282 'SVGUseElement', | |
| 283 'SVGZoomEvent', | |
| 284 'Storage', | |
| 285 'StorageEvent', | |
| 286 'StyleSheet', | |
| 287 'StyleSheetList', | |
| 288 'Text', | |
| 289 'TextMetrics', | |
| 290 'UIEvent', | |
| 291 'XMLHttpRequest', | |
| 292 'XMLSerializer', | |
| 293 ] | |
| 294 | |
| 295 # | |
| 104 # Simple method substitution when one method had different names on different | 296 # Simple method substitution when one method had different names on different |
| 105 # browsers, but are otherwise identical. The alternates are tried in order and | 297 # browsers, but are otherwise identical. The alternates are tried in order and |
| 106 # the first one defined is used. | 298 # the first one defined is used. |
| 107 # | 299 # |
| 108 # This can be probably be removed when Chrome renames initWebKitWheelEvent to | 300 # This can be probably be removed when Chrome renames initWebKitWheelEvent to |
| 109 # initWheelEvent. | 301 # initWheelEvent. |
| 110 # | 302 # |
| 111 _alternate_methods = { | 303 _alternate_methods = { |
| 112 ('WheelEvent', 'initWheelEvent'): ['initWebKitWheelEvent', 'initWheelEvent'] | 304 ('WheelEvent', 'initWheelEvent'): ['initWebKitWheelEvent', 'initWheelEvent'] |
| 113 } | 305 } |
| (...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 356 """ | 548 """ |
| 357 | 549 |
| 358 self._emitters = multiemitter.MultiEmitter() | 550 self._emitters = multiemitter.MultiEmitter() |
| 359 self._database = database | 551 self._database = database |
| 360 self._output_dir = output_dir | 552 self._output_dir = output_dir |
| 361 self._dart_callback_file_paths = [] | 553 self._dart_callback_file_paths = [] |
| 362 | 554 |
| 363 self._StartGenerateInterfaceLibrary() | 555 self._StartGenerateInterfaceLibrary() |
| 364 self._StartGenerateJavaScriptMonkeyImpl(database, output_dir) | 556 self._StartGenerateJavaScriptMonkeyImpl(database, output_dir) |
| 365 self._StartGenerateWrappingImpl(output_dir) | 557 self._StartGenerateWrappingImpl(output_dir) |
| 366 self._StartGenerateFrogImpl(output_dir) | 558 self._StartGenerateFrogImpl(database, output_dir) |
| 367 | 559 |
| 368 # Render all interfaces into Dart and save them in files. | 560 # Render all interfaces into Dart and save them in files. |
| 369 dart_file_paths = [] | 561 dart_file_paths = [] |
| 370 processed_interfaces = [] | 562 processed_interfaces = [] |
| 371 for interface in database.GetInterfaces(): | 563 for interface in database.GetInterfaces(): |
| 372 | 564 |
| 373 super_interface = None | 565 super_interface = None |
| 374 super_name = interface.id | 566 super_name = interface.id |
| 375 | 567 |
| 376 if not _MatchSourceFilter(source_filter, interface): | 568 if not _MatchSourceFilter(source_filter, interface): |
| (...skipping 435 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 812 result.add(attr.id) | 1004 result.add(attr.id) |
| 813 for op in parent_interface.operations: | 1005 for op in parent_interface.operations: |
| 814 result.add(op.id) | 1006 result.add(op.id) |
| 815 WalkParentChain(parent_interface) | 1007 WalkParentChain(parent_interface) |
| 816 | 1008 |
| 817 result = set() | 1009 result = set() |
| 818 WalkParentChain(interface) | 1010 WalkParentChain(interface) |
| 819 return result; | 1011 return result; |
| 820 | 1012 |
| 821 | 1013 |
| 822 def _StartGenerateFrogImpl(self, output_dir): | 1014 def _StartGenerateFrogImpl(self, database, output_dir): |
|
Emily Fortuna
2011/12/06 18:19:35
Why pass database around if we can access it as se
sra1
2011/12/06 19:25:30
Good point. Other code does this, so I'm copying
| |
| 823 """Prepared for generating frog implementation. | 1015 """Prepared for generating frog implementation. |
| 824 | |
| 825 - Creates emitter for Dart code. | |
| 826 """ | 1016 """ |
| 827 pass | 1017 self._interface_names_with_subtypes = set() |
| 828 | 1018 for interface in database.GetInterfaces(): |
| 1019 for parent in interface.parents: | |
| 1020 self._interface_names_with_subtypes.add(parent.type.id) | |
| 829 | 1021 |
| 830 def _MakeFrogImplInterfaceGenerator(self, | 1022 def _MakeFrogImplInterfaceGenerator(self, |
| 831 interface, | 1023 interface, |
| 832 common_prefix, | 1024 common_prefix, |
| 833 super_interface_name, | 1025 super_interface_name, |
| 834 source_filter): | 1026 source_filter): |
| 835 """.""" | 1027 """.""" |
| 836 interface_name = interface.id | 1028 interface_name = interface.id |
| 837 dart_frog_file_path = self.FilePathForFrogImpl(interface_name) | 1029 dart_frog_file_path = self.FilePathForFrogImpl(interface_name) |
| 838 | 1030 |
| 839 self._dart_frog_file_paths.append(dart_frog_file_path) | 1031 self._dart_frog_file_paths.append(dart_frog_file_path) |
| 840 | 1032 |
| 841 dart_code = self._emitters.FileEmitter(dart_frog_file_path) | 1033 dart_code = self._emitters.FileEmitter(dart_frog_file_path) |
| 842 dart_code.Emit( | 1034 dart_code.Emit( |
| 843 ''.join(open('template_frog_impl.darttemplate').readlines())) | 1035 ''.join(open('template_frog_impl.darttemplate').readlines())) |
| 844 return FrogInterfaceGenerator(interface, super_interface_name, | 1036 return FrogInterfaceGenerator(interface, super_interface_name, |
| 1037 self._interface_names_with_subtypes, | |
| 845 dart_code) | 1038 dart_code) |
| 846 | 1039 |
| 847 | 1040 |
| 848 def _StartGenerateJavaScriptMonkeyImpl(self, database, output_dir): | 1041 def _StartGenerateJavaScriptMonkeyImpl(self, database, output_dir): |
| 849 """Generate a JavaScript implementation that is coherent with | 1042 """Generate a JavaScript implementation that is coherent with |
| 850 generated Dart APIs. | 1043 generated Dart APIs. |
| 851 """ | 1044 """ |
| 852 self._ComputeInheritanceClosure(database) | 1045 self._ComputeInheritanceClosure(database) |
| 853 js_file_name = os.path.join(output_dir, 'monkey_dom.js') | 1046 js_file_name = os.path.join(output_dir, 'monkey_dom.js') |
| 854 code = self._emitters.FileEmitter(js_file_name) | 1047 code = self._emitters.FileEmitter(js_file_name) |
| (...skipping 1150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2005 self.AddSetter(attr) | 2198 self.AddSetter(attr) |
| 2006 | 2199 |
| 2007 def AddSecondaryOperation(self, interface, info): | 2200 def AddSecondaryOperation(self, interface, info): |
| 2008 self.AddOperation(info) | 2201 self.AddOperation(info) |
| 2009 | 2202 |
| 2010 # ------------------------------------------------------------------------------ | 2203 # ------------------------------------------------------------------------------ |
| 2011 | 2204 |
| 2012 class FrogInterfaceGenerator(object): | 2205 class FrogInterfaceGenerator(object): |
| 2013 """Generates a Frog class for a DOM IDL interface.""" | 2206 """Generates a Frog class for a DOM IDL interface.""" |
| 2014 | 2207 |
| 2015 def __init__(self, interface, super_interface, dart_code): | 2208 def __init__(self, interface, super_interface, interfaces_with_subtypes, |
| 2209 dart_code): | |
| 2016 """Generates Dart code for the given interface. | 2210 """Generates Dart code for the given interface. |
| 2017 | 2211 |
| 2018 Args: | 2212 Args: |
| 2019 | 2213 |
| 2020 interface: an IDLInterface instance. It is assumed that all types have | 2214 interface: an IDLInterface instance. It is assumed that all types have |
| 2021 been converted to Dart types (e.g. int, String), unless they are in | 2215 been converted to Dart types (e.g. int, String), unless they are in |
| 2022 the same package as the interface. | 2216 the same package as the interface. |
| 2023 super_interface: A string or None, the name of the common interface that | 2217 super_interface: A string or None, the name of the common interface that |
| 2024 this interface implements, if any. | 2218 this interface implements, if any. |
| 2219 interfaces_with_subtypes: A set of strings names of interfaces that have | |
| 2220 at least one subtype. | |
| 2025 dart_code: an Emitter for the file containing the Dart implementation | 2221 dart_code: an Emitter for the file containing the Dart implementation |
| 2026 class. | 2222 class. |
| 2027 """ | 2223 """ |
| 2028 self._interface = interface | 2224 self._interface = interface |
| 2029 self._super_interface = super_interface | 2225 self._super_interface = super_interface |
| 2226 self._interfaces_with_subtypes = interfaces_with_subtypes | |
| 2030 self._dart_code = dart_code | 2227 self._dart_code = dart_code |
| 2031 self._current_secondary_parent = None | 2228 self._current_secondary_parent = None |
| 2032 | 2229 |
| 2033 | 2230 |
| 2034 def StartInterface(self): | 2231 def StartInterface(self): |
| 2035 interface = self._interface | 2232 interface = self._interface |
| 2036 interface_name = interface.id | 2233 interface_name = interface.id |
| 2037 | 2234 |
| 2038 self._class_name = self._ImplClassName(interface_name) | 2235 self._class_name = self._ImplClassName(interface_name) |
| 2039 | 2236 |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 2065 extends = " extends " + base | 2262 extends = " extends " + base |
| 2066 else: | 2263 else: |
| 2067 extends = "" | 2264 extends = "" |
| 2068 | 2265 |
| 2069 if interface_name in _constructable_types.keys(): | 2266 if interface_name in _constructable_types.keys(): |
| 2070 parameters = _constructable_types[interface_name] | 2267 parameters = _constructable_types[interface_name] |
| 2071 constructor = ' %s(%s) native;\n\n' % (interface_name, parameters) | 2268 constructor = ' %s(%s) native;\n\n' % (interface_name, parameters) |
| 2072 else: | 2269 else: |
| 2073 constructor = '' | 2270 constructor = '' |
| 2074 | 2271 |
| 2272 # Is the type's constructor accessible from the global scope? If so, we can | |
| 2273 # directly patch the prototype. We don't really want to do this yet because | |
| 2274 # the dynamic patching mechanism is tricky and we want to test it a lot. | |
| 2275 # But patching is currently broken on FireFox for non-leaf types, so 'hide' | |
| 2276 # only the leaf types. | |
| 2277 is_hidden = interface_name not in _BROWSER_SHARED_TYPES | |
| 2278 if interface_name not in self._interfaces_with_subtypes: | |
| 2279 is_hidden = True | |
| 2280 | |
| 2075 # Compiler needs to know window is aliased with global scope. | 2281 # Compiler needs to know window is aliased with global scope. |
| 2076 global_marker = '@' if interface_name == 'DOMWindow' else '' | 2282 global_marker = '@' if interface_name == 'DOMWindow' else '' |
| 2077 | 2283 |
| 2078 (self._members_emitter, self._base_emitter) = self._dart_code.Emit( | 2284 (self._members_emitter, self._base_emitter) = self._dart_code.Emit( |
| 2079 '\n' | 2285 '\n' |
| 2080 'class $CLASS$BASE native "$SPLAT*$CLASS" {\n' | 2286 'class $CLASS$BASE native "$SPLAT$HIDDEN$CLASS" {\n' |
| 2081 '$CONSTRUCTOR$!MEMBERS' | 2287 '$CONSTRUCTOR$!MEMBERS' |
| 2082 '$!ADDITIONS' | 2288 '$!ADDITIONS' |
| 2083 '}\n', | 2289 '}\n', |
| 2084 CLASS=self._class_name, BASE=extends, | 2290 CLASS=self._class_name, BASE=extends, |
| 2085 INTERFACE=interface_name, CONSTRUCTOR=constructor, | 2291 INTERFACE=interface_name, CONSTRUCTOR=constructor, |
| 2086 SPLAT=global_marker) | 2292 SPLAT=global_marker, |
| 2293 HIDDEN='*' if is_hidden else '') | |
| 2087 | 2294 |
| 2088 if not base: | 2295 if not base: |
| 2089 # Emit shared base functionality here as we have no common base type. | 2296 # Emit shared base functionality here as we have no common base type. |
| 2090 self._base_emitter.Emit( | 2297 self._base_emitter.Emit( |
| 2091 '\n' | 2298 '\n' |
| 2092 ' var dartObjectLocalStorage;\n' | 2299 ' var dartObjectLocalStorage;\n' |
| 2093 '\n' | 2300 '\n' |
| 2094 ' String get typeName() native;\n') | 2301 ' String get typeName() native;\n') |
| 2095 | 2302 |
| 2096 def _ImplClassName(self, type_name): | 2303 def _ImplClassName(self, type_name): |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2169 Arguments: | 2376 Arguments: |
| 2170 info: An OperationInfo object. | 2377 info: An OperationInfo object. |
| 2171 """ | 2378 """ |
| 2172 # TODO(vsm): Handle overloads. | 2379 # TODO(vsm): Handle overloads. |
| 2173 self._members_emitter.Emit( | 2380 self._members_emitter.Emit( |
| 2174 '\n' | 2381 '\n' |
| 2175 ' $TYPE $NAME($ARGS) native;\n', | 2382 ' $TYPE $NAME($ARGS) native;\n', |
| 2176 TYPE=info.type_name, | 2383 TYPE=info.type_name, |
| 2177 NAME=info.name, | 2384 NAME=info.name, |
| 2178 ARGS=info.arg_implementation_declaration) | 2385 ARGS=info.arg_implementation_declaration) |
| OLD | NEW |