Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(163)

Unified Diff: client/dom/scripts/dartgenerator.py

Issue 9403004: Wrapperless dart:html generator (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Final version to check in. changes generator script but doesn't check in an active version of the … Created 8 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « client/dom/scripts/dartdomgenerator.py ('k') | client/dom/scripts/dartgenerator_test.py » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: client/dom/scripts/dartgenerator.py
diff --git a/client/dom/scripts/dartgenerator.py b/client/dom/scripts/dartgenerator.py
index e267c905996abb0c91c02932c43c029da3c663ef..338678abb5204db3585638d62f4e4489d11e2cc7 100755
--- a/client/dom/scripts/dartgenerator.py
+++ b/client/dom/scripts/dartgenerator.py
@@ -12,133 +12,14 @@ import multiemitter
import os
import re
import shutil
+from generator import *
+from systembase import *
+from systemfrog import *
+from systemhtml import *
+from systeminterface import *
_logger = logging.getLogger('dartgenerator')
-# IDL->Dart primitive types conversion.
-_idl_to_dart_type_conversions = {
- 'any': 'Object',
- 'any[]': 'List',
- 'custom': 'Dynamic',
- 'boolean': 'bool',
- 'DOMObject': 'Object',
- 'DOMString': 'String',
- 'DOMStringList': 'List<String>',
- 'DOMTimeStamp': 'int',
- 'Date': 'Date',
- # Map to num to enable callers to pass in Dart int, rational
- # types. Our implementations will need to convert these to
- # doubles or floats as needed.
- 'double': 'num',
- 'float': 'num',
- 'int': 'int',
- # Map to extra precision - int is a bignum in Dart.
- 'long': 'int',
- 'long long': 'int',
- 'object': 'Object',
- # Map to extra precision - int is a bignum in Dart.
- 'short': 'int',
- 'string': 'String',
- 'void': 'void',
- 'Array': 'List',
- 'sequence': 'List',
- # TODO(sra): Come up with some meaningful name so that where this appears in
- # the documentation, the user is made aware that only a limited subset of
- # serializable types are actually permitted.
- 'SerializedScriptValue': 'Dynamic',
- # TODO(vsm): Automatically recognize types defined in src.
- 'TimeoutHandler': 'TimeoutHandler',
- 'RequestAnimationFrameCallback': 'RequestAnimationFrameCallback',
-
- # TODO(sra): Flags is really a dictionary: {create:bool, exclusive:bool}
- # http://dev.w3.org/2009/dap/file-system/file-dir-sys.html#the-flags-interface
- 'WebKitFlags': 'Object',
- }
-
-_dart_to_idl_type_conversions = dict((v,k) for k, v in
- _idl_to_dart_type_conversions.iteritems())
-
-
-#
-# Identifiers that are used in the IDL than need to be treated specially because
-# *some* JavaScript processors forbid them as properties.
-#
-_javascript_keywords = ['delete', 'continue']
-
-#
-# Interface version of the DOM needs to delegate typed array constructors to a
-# factory provider.
-#
-_interface_factories = {
- 'Float32Array': '_TypedArrayFactoryProvider',
- 'Float64Array': '_TypedArrayFactoryProvider',
- 'Int8Array': '_TypedArrayFactoryProvider',
- 'Int16Array': '_TypedArrayFactoryProvider',
- 'Int32Array': '_TypedArrayFactoryProvider',
- 'Uint8Array': '_TypedArrayFactoryProvider',
- 'Uint16Array': '_TypedArrayFactoryProvider',
- 'Uint32Array': '_TypedArrayFactoryProvider',
- 'Uint8ClampedArray': '_TypedArrayFactoryProvider',
-}
-
-#
-# Custom methods that must be implemented by hand.
-#
-_custom_methods = set([
- ('DOMWindow', 'setInterval'),
- ('DOMWindow', 'setTimeout'),
- ('WorkerContext', 'setInterval'),
- ('WorkerContext', 'setTimeout'),
- ('CanvasRenderingContext2D', 'setFillStyle'),
- ('CanvasRenderingContext2D', 'setStrokeStyle'),
- ('CanvasRenderingContext2D', 'setFillStyle'),
- ])
-
-#
-# Custom getters that must be implemented by hand.
-#
-_custom_getters = set([
- ('DOMWindow', 'localStorage'),
- ])
-
-#
-# Custom native specs for the Frog dom.
-#
-_frog_dom_custom_native_specs = {
- # Decorate the singleton Console object, if present (workers do not have a
- # console).
- 'Console': "=(typeof console == 'undefined' ? {} : console)",
-
- # DOMWindow aliased with global scope.
- 'DOMWindow': '@*DOMWindow',
-}
-
-#
-# Simple method substitution when one method had different names on different
-# browsers, but are otherwise identical. The alternates are tried in order and
-# the first one defined is used.
-#
-# This can be probably be removed when Chrome renames initWebKitWheelEvent to
-# initWheelEvent.
-#
-_alternate_methods = {
- ('WheelEvent', 'initWheelEvent'): ['initWebKitWheelEvent', 'initWheelEvent']
-}
-
-
-def _MatchSourceFilter(filter, thing):
- if not filter:
- return True
- else:
- return any(token in thing.annotations for token in filter)
-
-def _IsDartListType(type):
- return type == 'List' or type.startswith('List<')
-
-def _IsDartCollectionType(type):
- return _IsDartListType(type)
-
-
class DartGenerator(object):
"""Utilities to generate Dart APIs and corresponding JavaScript."""
@@ -162,12 +43,8 @@ class DartGenerator(object):
def _StripModules(self, type_name):
return type_name.split('::')[-1]
- def _IsPrimitiveType(self, type_name):
- return (self._ConvertPrimitiveType(type_name) is not None or
- type_name in _dart_to_idl_type_conversions)
-
def _IsCompoundType(self, database, type_name):
- if self._IsPrimitiveType(type_name):
+ if IsPrimitiveType(type_name):
return True
striped_type_name = self._StripModules(type_name)
@@ -186,15 +63,6 @@ class DartGenerator(object):
def _IsDartType(self, type_name):
return '.' in type_name
- def _ConvertPrimitiveType(self, type_name):
- if type_name.startswith('unsigned '):
- type_name = type_name[len('unsigned '):]
-
- if type_name in _idl_to_dart_type_conversions:
- # Primitive type conversion
- return _idl_to_dart_type_conversions[type_name]
- return None
-
def LoadAuxiliary(self):
def Visitor(_, dirname, names):
for name in names:
@@ -203,7 +71,7 @@ class DartGenerator(object):
self._auxiliary_files[name] = os.path.join(dirname, name)
os.path.walk(self._auxiliary_dir, Visitor, None)
- def RenameTypes(self, database, conversion_table=None):
+ def RenameTypes(self, database, conversion_table, rename_javascript_binding_names):
"""Renames interfaces using the given conversion table.
References through all interfaces will be renamed as well.
@@ -215,18 +83,23 @@ class DartGenerator(object):
if conversion_table is None:
conversion_table = {}
-
+
# Rename interfaces:
for old_name, new_name in conversion_table.items():
if database.HasInterface(old_name):
- _logger.info('renaming interface %s to %s' %
- (old_name, new_name))
+ _logger.info('renaming interface %s to %s' % (old_name, new_name))
interface = database.GetInterface(old_name)
database.DeleteInterface(old_name)
if not database.HasInterface(new_name):
interface.id = new_name
database.AddInterface(interface)
-
+ else:
+ new_interface = database.GetInterface(new_name)
+ new_interface.merge(interface)
+
+ interface.javascript_binding_name = (old_name if rename_javascript_binding_names
+ else new_name)
+
# Fix references:
for interface in database.GetInterfaces():
for idl_type in interface.all(idlnode.IDLType):
@@ -265,8 +138,8 @@ class DartGenerator(object):
def ConvertType(interface, type_name):
"""Helper method for converting a type name to the proper
Dart name"""
- if self._IsPrimitiveType(type_name):
- return self._ConvertPrimitiveType(type_name)
+ if IsPrimitiveType(type_name):
+ return ConvertPrimitiveType(type_name)
if self._IsDartType(type_name):
# This is for when dart qualified names are explicitly
@@ -355,7 +228,7 @@ class DartGenerator(object):
def Generate(self, database, output_dir,
module_source_preference=[], source_filter=None,
super_database=None, common_prefix=None, super_map={},
- lib_dir=None, systems=[]):
+ html_map={}, lib_dir=None, systems=[]):
"""Generates Dart and JS files for the loaded interfaces.
Args:
@@ -373,7 +246,7 @@ class DartGenerator(object):
lib_file_path -- filename for generated .lib file, None if not required.
lib_template -- template file in this directory for generated lib file.
"""
-
+
self._emitters = multiemitter.MultiEmitter()
self._database = database
self._output_dir = output_dir
@@ -383,15 +256,16 @@ class DartGenerator(object):
self._systems = []
# TODO(jmesserly): only create these if needed
- interface_system = InterfacesSystem(
- TemplateLoader(self._template_dir, ['dom/interface', 'dom', '']),
- self._database, self._emitters, self._output_dir)
- self._systems.append(interface_system)
-
- html_interface_system = HtmlInterfacesSystem(
- TemplateLoader(self._template_dir, ['html/interface', 'html', '']),
- self._database, self._emitters, self._output_dir)
- self._systems.append(html_interface_system)
+ if ('htmlfrog' in systems) or ('htmldartium' in systems):
+ html_interface_system = HtmlInterfacesSystem(
+ TemplateLoader(self._template_dir, ['html/interface', 'html', '']),
+ self._database, self._emitters, self._output_dir, self)
+ self._systems.append(html_interface_system)
+ else:
+ interface_system = InterfacesSystem(
+ TemplateLoader(self._template_dir, ['dom/interface', 'dom', '']),
+ self._database, self._emitters, self._output_dir)
+ self._systems.append(interface_system)
if 'native' in systems:
native_system = NativeImplementationSystem(
@@ -432,7 +306,7 @@ class DartGenerator(object):
if 'htmlfrog' in systems:
html_system = HtmlFrogSystem(
TemplateLoader(self._template_dir, ['html/frog', 'html', '']),
- self._database, self._emitters, self._output_dir)
+ self._database, self._emitters, self._output_dir, self)
html_system._interface_system = html_interface_system
self._systems.append(html_system)
@@ -440,7 +314,7 @@ class DartGenerator(object):
if 'htmldartium' in systems:
html_system = HtmlDartiumSystem(
TemplateLoader(self._template_dir, ['html/dartium', 'html', '']),
- self._database, self._emitters, self._output_dir)
+ self._database, self._emitters, self._output_dir, self)
html_system._interface_system = html_interface_system
self._systems.append(html_system)
@@ -448,7 +322,7 @@ class DartGenerator(object):
# Collect interfaces
interfaces = []
for interface in database.GetInterfaces():
- if not _MatchSourceFilter(source_filter, interface):
+ if not MatchSourceFilter(source_filter, interface):
# Skip this interface since it's not present in the required source
_logger.info('Omitting interface - %s' % interface.id)
continue
@@ -478,7 +352,7 @@ class DartGenerator(object):
interface_name, auxiliary_file))
continue
- info = _RecognizeCallback(interface)
+ info = RecognizeCallback(interface)
if info:
for system in self._systems:
system.ProcessCallback(interface, info)
@@ -506,7 +380,7 @@ class DartGenerator(object):
return
seen.add(interface.id)
for parent in interface.parents:
- if _IsDartCollectionType(parent.type.id):
+ if IsDartCollectionType(parent.type.id):
continue
if self._database.HasInterface(parent.type.id):
parent_interface = self._database.GetInterface(parent.type.id)
@@ -544,8 +418,9 @@ class DartGenerator(object):
for generator in generators:
generator.AddAttribute(getter, setter)
- events = _PairUpAttributes([attr for attr in interface.attributes
+ events = set([attr for attr in interface.attributes
if self._IsEventAttribute(interface, attr)])
+
if events:
for generator in generators:
generator.AddEventAttributes(events)
@@ -556,7 +431,6 @@ class DartGenerator(object):
if element_type:
for generator in generators:
generator.AddIndexer(element_type)
-
# Group overloaded operations by id
operationsById = {}
for operation in interface.operations:
@@ -567,7 +441,7 @@ class DartGenerator(object):
# Generate operations
for id in sorted(operationsById.keys()):
operations = operationsById[id]
- info = _AnalyzeOperation(interface, operations)
+ info = AnalyzeOperation(interface, operations)
for generator in generators:
generator.AddOperation(info)
@@ -577,10 +451,10 @@ class DartGenerator(object):
# avoid making a duplicate definition and pray that the signatures match.
for parent_interface in self._TransitiveSecondaryParents(interface):
- if isinstance(parent_interface, str): # _IsDartCollectionType(parent_interface)
+ if isinstance(parent_interface, str): # IsDartCollectionType(parent_interface)
continue
attributes = [attr for attr in parent_interface.attributes
- if not _FindMatchingAttribute(interface, attr)]
+ if not FindMatchingAttribute(interface, attr)]
for (getter, setter) in _PairUpAttributes(attributes):
for generator in generators:
generator.AddSecondaryAttribute(parent_interface, getter, setter)
@@ -596,7 +470,7 @@ class DartGenerator(object):
for id in sorted(operationsById.keys()):
if not any(op.id == id for op in interface.operations):
operations = operationsById[id]
- info = _AnalyzeOperation(interface, operations)
+ info = AnalyzeOperation(interface, operations)
for generator in generators:
generator.AddSecondaryOperation(parent_interface, info)
@@ -607,10 +481,8 @@ class DartGenerator(object):
def _IsEventAttribute(self, interface, attr):
# Remove EventListener attributes like 'onclick' when addEventListener
# is available.
- if attr.type.id == 'EventListener':
- if 'EventTarget' in self._AllImplementedInterfaces(interface):
- return True
- return False
+ return (attr.type.id == 'EventListener' and
+ 'EventTarget' in self._AllImplementedInterfaces(interface))
def _TransitiveSecondaryParents(self, interface):
"""Returns a list of all non-primary parents.
@@ -620,7 +492,7 @@ class DartGenerator(object):
"""
def walk(parents):
for parent in parents:
- if _IsDartCollectionType(parent.type.id):
+ if IsDartCollectionType(parent.type.id):
result.append(parent.type.id)
continue
if self._database.HasInterface(parent.type.id):
@@ -683,18 +555,6 @@ class DartGenerator(object):
"""
return self._inheritance_closure[interface.id]
-
-def _RecognizeCallback(interface):
- """Returns the info for the callback method if the interface smells like a
- callback.
- """
- if 'Callback' not in interface.ext_attrs: return None
- handlers = [op for op in interface.operations if op.id == 'handleEvent']
- if not handlers: return None
- if not (handlers == interface.operations): return None
- return _AnalyzeOperation(interface, handlers)
-
-
def _PairUpAttributes(attributes):
"""Returns a list of (getter, setter) pairs sorted by name.
@@ -710,186 +570,6 @@ def _PairUpAttributes(attributes):
setters[attr.id] = attr
return [(getters.get(id), setters.get(id)) for id in names]
-
-def _FindMatchingAttribute(interface, attr1):
- matches = [attr2 for attr2 in interface.attributes
- if attr1.id == attr2.id
- and attr1.is_fc_getter == attr2.is_fc_getter
- and attr1.is_fc_setter == attr2.is_fc_setter]
- if matches:
- assert len(matches) == 1
- return matches[0]
- return None
-
-
-def _AnalyzeOperation(interface, operations):
- """Makes operation calling convention decision for a set of overloads.
-
- Returns: An OperationInfo object.
- """
-
- # Zip together arguments from each overload by position, then convert
- # to a dart argument.
-
- # Given a list of overloaded arguments, choose a suitable name.
- def OverloadedName(args):
- return '_OR_'.join(sorted(set(arg.id for arg in args)))
-
- # Given a list of overloaded arguments, choose a suitable type.
- def OverloadedType(args):
- typeIds = sorted(set(arg.type.id for arg in args))
- if len(typeIds) == 1:
- return typeIds[0]
- else:
- return TypeName(typeIds, interface)
-
- # Given a list of overloaded arguments, render a dart argument.
- def DartArg(args):
- filtered = filter(None, args)
- optional = any(not arg or arg.is_optional for arg in args)
- type = OverloadedType(filtered)
- name = OverloadedName(filtered)
- if optional:
- return (name, type, 'null')
- else:
- return (name, type, None)
-
- args = map(lambda *args: DartArg(args),
- *(op.arguments for op in operations))
-
- info = OperationInfo()
- info.overloads = operations
- info.declared_name = operations[0].id
- info.name = operations[0].ext_attrs.get('DartName', info.declared_name)
- info.js_name = info.declared_name
- info.type_name = operations[0].type.id # TODO: widen.
- info.arg_infos = args
- return info
-
-
-class OperationInfo(object):
- """Holder for various derived information from a set of overloaded operations.
-
- Attributes:
- overloads: A list of IDL operation overloads with the same name.
- name: A string, the simple name of the operation.
- type_name: A string, the name of the return type of the operation.
- arg_infos: A list of (name, type, default_value) tuples.
- default_value is None for mandatory arguments.
- """
-
- def ParametersInterfaceDeclaration(self):
- """Returns a formatted string declaring the parameters for the interface."""
- return self._FormatArgs(self.arg_infos, True)
-
- def ParametersImplementationDeclaration(self, rename_type=None):
- """Returns a formatted string declaring the parameters for the
- implementation.
-
- Args:
- rename_type: A function that allows the types to be renamed.
- """
- args = self.arg_infos
- if rename_type:
- args = [(name, rename_type(type), default)
- for (name, type, default) in args]
- return self._FormatArgs(args, False)
-
-
- def _FormatArgs(self, args, is_interface):
- def FormatArg(arg_info):
- """Returns an argument declaration fragment for an argument info tuple."""
- (name, type, default) = arg_info
- if default:
- return '%s %s = %s' % (type, name, default)
- else:
- return '%s %s' % (type, name)
-
- required = []
- optional = []
- for (name, type, default) in args:
- if default:
- if is_interface:
- optional.append((name, type, None)) # Default values illegal.
- else:
- optional.append((name, type, default))
- else:
- if optional:
- raise Exception('Optional arguments cannot precede required ones: '
- + str(args))
- required.append((name, type, None))
- argtexts = map(FormatArg, required)
- if optional:
- argtexts.append('[' + ', '.join(map(FormatArg, optional)) + ']')
- return ', '.join(argtexts)
-
-
-def MaybeListElementTypeName(type_name):
- """Returns the List element type T from string of form "List<T>", or None."""
- match = re.match(r'List<(\w*)>$', type_name)
- if match:
- return match.group(1)
- return None
-
-def MaybeListElementType(interface):
- """Returns the List element type T, or None in interface does not implement
- List<T>.
- """
- for parent in interface.parents:
- element_type = MaybeListElementTypeName(parent.type.id)
- if element_type:
- return element_type
- return None
-
-def MaybeTypedArrayElementType(interface):
- """Returns the typed array element type, or None in interface is not a
- TypedArray.
- """
- # Typed arrays implement ArrayBufferView and List<T>.
- for parent in interface.parents:
- if parent.type.id == 'ArrayBufferView':
- return MaybeListElementType(interface)
- if parent.type.id == 'Uint8Array':
- return 'int'
- return None
-
-
-def AttributeOutputOrder(a, b):
- """Canonical output ordering for attributes."""
- # Getters before setters:
- if a.id < b.id: return -1
- if a.id > b.id: return 1
- if a.is_fc_setter < b.is_fc_setter: return -1
- if a.is_fc_setter > b.is_fc_setter: return 1
- return 0
-
-def ConstantOutputOrder(a, b):
- """Canonical output ordering for constants."""
- if a.id < b.id: return -1
- if a.id > b.id: return 1
- return 0
-
-
-def _FormatNameList(names):
- """Returns JavaScript array literal expression with one name per line."""
- #names = sorted(names)
- if len(names) <= 1:
- expression_string = str(names) # e.g. ['length']
- else:
- expression_string = ',\n '.join(str(names).split(','))
- expression_string = expression_string.replace('[', '[\n ')
- return expression_string
-
-
-def IndentText(text, indent):
- """Format lines of text with indent."""
- def FormatLine(line):
- if line.strip():
- return '%s%s\n' % (indent, line)
- else:
- return '\n'
- return ''.join(FormatLine(line) for line in text.split('\n'))
-
# ------------------------------------------------------------------------------
class TemplateLoader(object):
@@ -928,190 +608,6 @@ class TemplateLoader(object):
raise Exception("Could not find template '%s' on %s / %s" % (
name, self._root, self._subpaths))
-
-# ------------------------------------------------------------------------------
-
-class System(object):
- """Generates all the files for one implementation."""
-
- def __init__(self, templates, database, emitters, output_dir):
- self._templates = templates
- self._database = database
- self._emitters = emitters
- self._output_dir = output_dir
- self._dart_callback_file_paths = []
-
- def InterfaceGenerator(self,
- interface,
- common_prefix,
- super_interface_name,
- source_filter):
- """Returns an interface generator for |interface|."""
- return None
-
- def ProcessCallback(self, interface, info):
- pass
-
- def GenerateLibraries(self, lib_dir):
- pass
-
- def Finish(self):
- pass
-
-
- def _ProcessCallback(self, interface, info, file_path):
- """Generates a typedef for the callback interface."""
- self._dart_callback_file_paths.append(file_path)
- code = self._emitters.FileEmitter(file_path)
-
- code.Emit(self._templates.Load('callback.darttemplate'))
- code.Emit('typedef $TYPE $NAME($PARAMS);\n',
- NAME=interface.id,
- TYPE=info.type_name,
- PARAMS=info.ParametersImplementationDeclaration())
-
- def _GenerateLibFile(self, lib_template, lib_file_path, file_paths,
- **template_args):
- """Generates a lib file from a template and a list of files.
-
- Additional keyword arguments are passed to the template.
- """
- # Load template.
- template = self._templates.Load(lib_template)
- # Generate the .lib file.
- lib_file_contents = self._emitters.FileEmitter(lib_file_path)
-
- # Emit the list of #source directives.
- list_emitter = lib_file_contents.Emit(template, **template_args)
- lib_file_dir = os.path.dirname(lib_file_path)
- for path in sorted(file_paths):
- relpath = os.path.relpath(path, lib_file_dir)
- list_emitter.Emit("#source('$PATH');\n", PATH=relpath)
-
-
- def _BaseDefines(self, interface):
- """Returns a set of names (strings) for members defined in a base class.
- """
- def WalkParentChain(interface):
- if interface.parents:
- # Only consider primary parent, secondary parents are not on the
- # implementation class inheritance chain.
- parent = interface.parents[0]
- if _IsDartCollectionType(parent.type.id):
- return
- if self._database.HasInterface(parent.type.id):
- parent_interface = self._database.GetInterface(parent.type.id)
- for attr in parent_interface.attributes:
- result.add(attr.id)
- for op in parent_interface.operations:
- result.add(op.id)
- WalkParentChain(parent_interface)
-
- result = set()
- WalkParentChain(interface)
- return result;
-
-
-# ------------------------------------------------------------------------------
-
-class InterfacesSystem(System):
-
- def __init__(self, templates, database, emitters, output_dir):
- super(InterfacesSystem, self).__init__(
- templates, database, emitters, output_dir)
- self._dart_interface_file_paths = []
-
-
- def InterfaceGenerator(self,
- interface,
- common_prefix,
- super_interface_name,
- source_filter):
- """."""
- interface_name = interface.id
- dart_interface_file_path = self._FilePathForDartInterface(interface_name)
-
- self._dart_interface_file_paths.append(dart_interface_file_path)
-
- dart_interface_code = self._emitters.FileEmitter(dart_interface_file_path)
-
- template_file = 'interface_%s.darttemplate' % interface_name
- template = self._templates.TryLoad(template_file)
- if not template:
- template = self._templates.Load('interface.darttemplate')
-
- return DartInterfaceGenerator(
- interface, dart_interface_code,
- template,
- common_prefix, super_interface_name,
- source_filter)
-
- def ProcessCallback(self, interface, info):
- """Generates a typedef for the callback interface."""
- interface_name = interface.id
- file_path = self._FilePathForDartInterface(interface_name)
- self._ProcessCallback(interface, info, file_path)
-
- def GenerateLibraries(self, lib_dir):
- pass
-
-
- def _FilePathForDartInterface(self, interface_name):
- """Returns the file path of the Dart interface definition."""
- return os.path.join(self._output_dir, 'src', 'interface',
- '%s.dart' % interface_name)
-
-
-# ------------------------------------------------------------------------------
-
-class HtmlInterfacesSystem(System):
-
- def __init__(self, templates, database, emitters, output_dir):
- super(HtmlInterfacesSystem, self).__init__(
- templates, database, emitters, output_dir)
- self._dart_interface_file_paths = []
-
- def InterfaceGenerator(self,
- interface,
- common_prefix,
- super_interface_name,
- source_filter):
- """."""
- interface_name = interface.id
- dart_interface_file_path = self._FilePathForDartInterface(interface_name)
-
- self._dart_interface_file_paths.append(dart_interface_file_path)
-
- dart_interface_code = self._emitters.FileEmitter(dart_interface_file_path)
-
- template_file = 'interface_%s.darttemplate' % interface_name
- template = self._templates.TryLoad(template_file)
- if not template:
- template = self._templates.Load('interface.darttemplate')
-
- return HtmlDartInterfaceGenerator(
- interface, dart_interface_code,
- template,
- common_prefix, super_interface_name,
- source_filter)
-
- def ProcessCallback(self, interface, info):
- """Generates a typedef for the callback interface."""
- interface_name = interface.id
- file_path = self._FilePathForDartInterface(interface_name)
- self._ProcessCallback(interface, info, file_path)
-
- def GenerateLibraries(self, lib_dir):
- pass
-
-
- def _FilePathForDartInterface(self, interface_name):
- """Returns the file path of the Dart interface definition."""
- # TODO(jmesserly): is this the right path
- return os.path.join(self._output_dir, 'html', 'interface',
- '%s.dart' % interface_name)
-
-
# ------------------------------------------------------------------------------
class DummyImplementationSystem(System):
@@ -1204,270 +700,6 @@ class WrappingImplementationSystem(System):
# ------------------------------------------------------------------------------
-class FrogSystem(System):
-
- def __init__(self, templates, database, emitters, output_dir):
- super(FrogSystem, self).__init__(
- templates, database, emitters, output_dir)
- self._dart_frog_file_paths = []
-
- def InterfaceGenerator(self,
- interface,
- common_prefix,
- super_interface_name,
- source_filter):
- """."""
- dart_frog_file_path = self._FilePathForFrogImpl(interface.id)
- self._dart_frog_file_paths.append(dart_frog_file_path)
-
- template_file = 'impl_%s.darttemplate' % interface.id
- template = self._templates.TryLoad(template_file)
- if not template:
- template = self._templates.Load('frog_impl.darttemplate')
-
- dart_code = self._emitters.FileEmitter(dart_frog_file_path)
- return FrogInterfaceGenerator(self, interface, template,
- super_interface_name, dart_code)
-
- def GenerateLibraries(self, lib_dir):
- self._GenerateLibFile(
- 'frog_dom.darttemplate',
- os.path.join(lib_dir, 'dom_frog.dart'),
- (self._interface_system._dart_interface_file_paths +
- self._interface_system._dart_callback_file_paths +
- self._dart_frog_file_paths))
-
- def Finish(self):
- pass
-
- def _FilePathForFrogImpl(self, interface_name):
- """Returns the file path of the Frog implementation."""
- return os.path.join(self._output_dir, 'src', 'frog',
- '%s.dart' % interface_name)
-
-
-# ------------------------------------------------------------------------------
-
-class HtmlFrogSystem(System):
-
- def __init__(self, templates, database, emitters, output_dir):
- super(HtmlFrogSystem, self).__init__(
- templates, database, emitters, output_dir)
- self._dart_frog_file_paths = []
-
- def InterfaceGenerator(self,
- interface,
- common_prefix,
- super_interface_name,
- source_filter):
- """."""
- dart_frog_file_path = self._FilePathForFrogImpl(interface.id)
- self._dart_frog_file_paths.append(dart_frog_file_path)
-
- template_file = 'impl_%s.darttemplate' % interface.id
- template = self._templates.TryLoad(template_file)
- if not template:
- template = self._templates.Load('frog_impl.darttemplate')
-
- dart_code = self._emitters.FileEmitter(dart_frog_file_path)
- return HtmlFrogInterfaceGenerator(self, interface, template,
- super_interface_name, dart_code)
-
- def GenerateLibraries(self, lib_dir):
- self._GenerateLibFile(
- 'html_frog.darttemplate',
- os.path.join(lib_dir, 'html_frog.dart'),
- (self._interface_system._dart_interface_file_paths +
- self._interface_system._dart_callback_file_paths +
- self._dart_frog_file_paths))
-
- def Finish(self):
- pass
-
- def _FilePathForFrogImpl(self, interface_name):
- """Returns the file path of the Frog implementation."""
- # TODO(jmesserly): is this the right path
- return os.path.join(self._output_dir, 'html', 'frog',
- '%s.dart' % interface_name)
-
-# ------------------------------------------------------------------------------
-
-class DartInterfaceGenerator(object):
- """Generates Dart Interface definition for one DOM IDL interface."""
-
- def __init__(self, interface, emitter, template,
- common_prefix, super_interface, source_filter):
- """Generates Dart code for the given interface.
-
- Args:
- interface -- an IDLInterface instance. It is assumed that all types have
- been converted to Dart types (e.g. int, String), unless they are in the
- same package as the interface.
- common_prefix -- the prefix for the common library, if any.
- super_interface -- the name of the common interface that this interface
- implements, if any.
- source_filter -- if specified, rewrites the names of any superinterfaces
- that are not from these sources to use the common prefix.
- """
- self._interface = interface
- self._emitter = emitter
- self._template = template
- self._common_prefix = common_prefix
- self._super_interface = super_interface
- self._source_filter = source_filter
-
-
- def StartInterface(self):
- if self._super_interface:
- typename = self._super_interface
- else:
- typename = self._interface.id
-
- # TODO(vsm): Add appropriate package / namespace syntax.
- (extends_emitter,
- self._members_emitter,
- self._top_level_emitter) = self._emitter.Emit(
- self._template + '$!TOP_LEVEL',
- ID=typename)
-
- extends = []
- suppressed_extends = []
-
- for parent in self._interface.parents:
- # TODO(vsm): Remove source_filter.
- if _MatchSourceFilter(self._source_filter, parent):
- # Parent is a DOM type.
- extends.append(parent.type.id)
- elif '<' in parent.type.id:
- # Parent is a Dart collection type.
- # TODO(vsm): Make this check more robust.
- extends.append(parent.type.id)
- else:
- suppressed_extends.append('%s.%s' %
- (self._common_prefix, parent.type.id))
-
- comment = ' extends'
- if extends:
- extends_emitter.Emit(' extends $SUPERS', SUPERS=', '.join(extends))
- comment = ','
- if suppressed_extends:
- extends_emitter.Emit(' /*$COMMENT $SUPERS */',
- COMMENT=comment,
- SUPERS=', '.join(suppressed_extends))
-
- if typename in _interface_factories:
- extends_emitter.Emit(' default $F', F=_interface_factories[typename])
-
- element_type = MaybeTypedArrayElementType(self._interface)
- if element_type:
- self._members_emitter.Emit(
- '\n'
- ' $CTOR(int length);\n'
- '\n'
- ' $CTOR.fromList(List<$TYPE> list);\n'
- '\n'
- ' $CTOR.fromBuffer(ArrayBuffer buffer);\n',
- CTOR=self._interface.id,
- TYPE=element_type)
-
-
- def FinishInterface(self):
- # TODO(vsm): Use typedef if / when that is supported in Dart.
- # Define variant as subtype.
- if (self._super_interface and
- self._interface.id is not self._super_interface):
- consts_emitter = self._top_level_emitter.Emit(
- '\n'
- 'interface $NAME extends $BASE {\n'
- '$!CONSTS'
- '}\n',
- NAME=self._interface.id,
- BASE=self._super_interface)
- for const in sorted(self._interface.constants, ConstantOutputOrder):
- self._EmitConstant(consts_emitter, const)
-
- def AddConstant(self, constant):
- if (not self._super_interface or
- self._interface.id is self._super_interface):
- self._EmitConstant(self._members_emitter, constant)
-
- def _EmitConstant(self, emitter, constant):
- emitter.Emit('\n static final $TYPE $NAME = $VALUE;\n',
- NAME=constant.id,
- TYPE=constant.type.id,
- VALUE=constant.value)
-
- def AddAttribute(self, getter, setter):
- if getter and setter and getter.type.id == setter.type.id:
- self._members_emitter.Emit('\n $TYPE $NAME;\n',
- NAME=getter.id, TYPE=getter.type.id);
- return
- if getter and not setter:
- self._members_emitter.Emit('\n final $TYPE $NAME;\n',
- NAME=getter.id, TYPE=getter.type.id);
- return
- raise Exception('Unexpected getter/setter combination %s %s' %
- (getter, setter))
-
- def AddIndexer(self, element_type):
- # Interface inherits all operations from List<element_type>.
- pass
-
- def AddOperation(self, info):
- """
- Arguments:
- operations - contains the overloads, one or more operations with the same
- name.
- """
- self._members_emitter.Emit('\n'
- ' $TYPE $NAME($PARAMS);\n',
- TYPE=info.type_name,
- NAME=info.name,
- PARAMS=info.ParametersInterfaceDeclaration())
-
- # Interfaces get secondary members directly via the superinterfaces.
- def AddSecondaryAttribute(self, interface, getter, setter):
- pass
-
- def AddSecondaryOperation(self, interface, attr):
- pass
-
- def AddEventAttributes(self, event_attrs):
- pass
-
-# Given a sorted sequence of type identifiers, return an appropriate type
-# name
-def TypeName(typeIds, interface):
- # Dynamically type this field for now.
- return 'var'
-
-# ------------------------------------------------------------------------------
-
-# TODO(jmesserly): inheritance is probably not the right way to factor this long
-# term, but it makes merging better for now.
-class HtmlDartInterfaceGenerator(DartInterfaceGenerator):
- """Generates Dart Interface definition for one DOM IDL interface."""
-
- def __init__(self, interface, emitter, template,
- common_prefix, super_interface, source_filter):
- super(HtmlDartInterfaceGenerator, self).__init__(interface,
- emitter, template, common_prefix, super_interface, source_filter)
-
- def AddEventAttributes(self, event_attrs):
- events_interface = self._interface.id + 'Events'
- self._members_emitter.Emit('\n $TYPE get on();\n',
- TYPE=events_interface)
- events_members = self._emitter.Emit(
- '\ninterface $INTERFACE {\n$!MEMBERS}\n',
- INTERFACE=events_interface)
-
- for getter, setter in event_attrs:
- event = getter or setter
- events_members.Emit('\n EventListenerList get $NAME();\n', NAME=event.id)
-
-
-# ------------------------------------------------------------------------------
-
class DummyInterfaceGenerator(object):
"""Generates nothing."""
@@ -1569,7 +801,7 @@ class WrappingInterfaceGenerator(object):
# attributes instead. For now, this hack lets the interfaces
# inherit, but not the classes.
# List methods are injected in AddIndexer.
- if _IsDartListType(supertype) or _IsDartCollectionType(supertype):
+ if IsDartListType(supertype) or IsDartCollectionType(supertype):
return 'DOMWrapperBase'
if supertype == 'EventTarget':
@@ -1961,323 +1193,6 @@ class WrappingInterfaceGenerator(object):
true_code, info, indent + ' ', position + 1, positive)
return True
-
-# ------------------------------------------------------------------------------
-
-class FrogInterfaceGenerator(object):
- """Generates a Frog class for a DOM IDL interface."""
-
- def __init__(self, system, interface, template, super_interface, dart_code):
- """Generates Dart code for the given interface.
-
- Args:
-
- interface: an IDLInterface instance. It is assumed that all types have
- been converted to Dart types (e.g. int, String), unless they are in
- the same package as the interface.
- template: A string template.
- super_interface: A string or None, the name of the common interface that
- this interface implements, if any.
- dart_code: an Emitter for the file containing the Dart implementation
- class.
- """
- self._system = system
- self._interface = interface
- self._template = template
- self._super_interface = super_interface
- self._dart_code = dart_code
- self._current_secondary_parent = None
-
-
- def StartInterface(self):
- interface = self._interface
- interface_name = interface.id
-
- self._class_name = self._ImplClassName(interface_name)
-
- base = None
- if interface.parents:
- supertype = interface.parents[0].type.id
- if _IsDartCollectionType(supertype):
- # List methods are injected in AddIndexer.
- pass
- else:
- base = self._ImplClassName(supertype)
-
- if interface_name in _frog_dom_custom_native_specs:
- native_spec = _frog_dom_custom_native_specs[interface_name]
- else:
- # Make the class 'hidden' so it is dynamically patched at runtime. This
- # is useful not only for browser compat, but to allow code that links
- # against dart:dom to load in a worker isolate.
- native_spec = '*' + interface_name
-
- if base:
- extends = ' extends ' + base
- elif native_spec[0] == '=':
- # The implementation is a singleton with no prototype.
- extends = ''
- else:
- extends = ' extends _DOMTypeJs'
-
- # TODO: Include all implemented interfaces, including other Lists.
- implements = [interface_name]
- element_type = MaybeTypedArrayElementType(self._interface)
- if element_type:
- implements.append('List<' + element_type + '>')
-
- self._members_emitter = self._dart_code.Emit(
- self._template,
- #class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC {
- #$!MEMBERS
- #}
- CLASSNAME=self._class_name,
- EXTENDS=extends,
- IMPLEMENTS=' implements ' + ', '.join(implements),
- NATIVESPEC=' native "' + native_spec + '"')
-
- element_type = MaybeTypedArrayElementType(interface)
- if element_type:
- self.AddTypedArrayConstructors(element_type)
-
-
- def FinishInterface(self):
- """."""
- pass
-
- def _ImplClassName(self, type_name):
- return '_' + type_name + 'Js'
-
- def _NarrowToImplementationType(self, type_name):
- # TODO(sra): Move into the 'system' and cache the result.
- if type_name == 'EventListener':
- # Callbacks are typedef functions so don't have a class.
- return type_name
- if self._system._database.HasInterface(type_name):
- interface = self._system._database.GetInterface(type_name)
- if _RecognizeCallback(interface):
- # Callbacks are typedef functions so don't have a class.
- return type_name
- else:
- return self._ImplClassName(type_name)
- return type_name
-
- def _NarrowInputType(self, type_name):
- return self._NarrowToImplementationType(type_name)
-
- def _NarrowOutputType(self, type_name):
- return self._NarrowToImplementationType(type_name)
-
- def AddConstant(self, constant):
- # Since we are currently generating native classes without interfaces,
- # generate the constants as part of the class. This will need to go away
- # if we revert back to generating interfaces.
- self._members_emitter.Emit('\n static final $TYPE $NAME = $VALUE;\n',
- NAME=constant.id,
- TYPE=constant.type.id,
- VALUE=constant.value)
-
- pass
-
- def AddAttribute(self, getter, setter):
- output_type = getter and self._NarrowOutputType(getter.type.id)
- input_type = setter and self._NarrowInputType(setter.type.id)
-
- # If the (getter, setter) pair is shadowing, we can't generate a shadowing
- # field (Issue 1633).
- (super_getter, super_getter_interface) = self._FindShadowedAttribute(getter)
- (super_setter, super_setter_interface) = self._FindShadowedAttribute(setter)
- if super_getter or super_setter:
- if getter and not setter and super_getter and not super_setter:
- if getter.type.id == super_getter.type.id:
- # Compatible getter, use the superclass property. This works because
- # JavaScript will do its own dynamic dispatch.
- self._members_emitter.Emit(
- '\n'
- ' // Use implementation from $SUPER.\n'
- ' // final $TYPE $NAME;\n',
- SUPER=super_getter_interface.id,
- NAME=getter.id, TYPE=output_type)
- return
-
- self._members_emitter.Emit('\n // Shadowing definition.')
- self._AddAttributeUsingProperties(getter, setter)
- return
-
- if getter and setter and input_type == output_type:
- self._members_emitter.Emit(
- '\n $TYPE $NAME;\n',
- NAME=getter.id, TYPE=output_type)
- return
- if getter and not setter:
- self._members_emitter.Emit(
- '\n final $TYPE $NAME;\n',
- NAME=getter.id, TYPE=output_type)
- return
- self._AddAttributeUsingProperties(getter, setter)
-
- def _AddAttributeUsingProperties(self, getter, setter):
- if getter:
- self._AddGetter(getter)
- if setter:
- self._AddSetter(setter)
-
- def _AddGetter(self, attr):
- # TODO(sra): Remove native body when Issue 829 fixed.
- self._members_emitter.Emit(
- '\n $TYPE get $NAME() native "return this.$NAME;";\n',
- NAME=attr.id, TYPE=self._NarrowOutputType(attr.type.id))
-
- def _AddSetter(self, attr):
- # TODO(sra): Remove native body when Issue 829 fixed.
- self._members_emitter.Emit(
- ' void set $NAME($TYPE value) native "this.$NAME = value;";\n',
- NAME=attr.id, TYPE=self._NarrowInputType(attr.type.id))
-
- def _FindShadowedAttribute(self, attr):
- """Returns (attribute, superinterface) or (None, None)."""
- def FindInParent(interface):
- """Returns matching attribute in parent, or None."""
- if interface.parents:
- parent = interface.parents[0]
- if _IsDartCollectionType(parent.type.id):
- return (None, None)
- if self._system._database.HasInterface(parent.type.id):
- parent_interface = self._system._database.GetInterface(parent.type.id)
- attr2 = _FindMatchingAttribute(parent_interface, attr)
- if attr2:
- return (attr2, parent_interface)
- return FindInParent(parent_interface)
- return (None, None)
-
- return FindInParent(self._interface) if attr else (None, None)
-
-
- def AddSecondaryAttribute(self, interface, getter, setter):
- self._SecondaryContext(interface)
- self.AddAttribute(getter, setter)
-
- def AddSecondaryOperation(self, interface, info):
- self._SecondaryContext(interface)
- self.AddOperation(info)
-
- def AddEventAttributes(self, event_attrs):
- pass
-
- def _SecondaryContext(self, interface):
- if interface is not self._current_secondary_parent:
- self._current_secondary_parent = interface
- self._members_emitter.Emit('\n // From $WHERE\n', WHERE=interface.id)
-
- def AddIndexer(self, element_type):
- """Adds all the methods required to complete implementation of List."""
- # We would like to simply inherit the implementation of everything except
- # get length(), [], and maybe []=. It is possible to extend from a base
- # array implementation class only when there is no other implementation
- # inheritance. There might be no implementation inheritance other than
- # DOMBaseWrapper for many classes, but there might be some where the
- # array-ness is introduced by a non-root interface:
- #
- # interface Y extends X, List<T> ...
- #
- # In the non-root case we have to choose between:
- #
- # class YImpl extends XImpl { add List<T> methods; }
- #
- # and
- #
- # class YImpl extends ListBase<T> { copies of transitive XImpl methods; }
- #
- self._members_emitter.Emit(
- '\n'
- ' $TYPE operator[](int index) native "return this[index];";\n',
- TYPE=self._NarrowOutputType(element_type))
-
- if 'CustomIndexedSetter' in self._interface.ext_attrs:
- self._members_emitter.Emit(
- '\n'
- ' void operator[]=(int index, $TYPE value) native "this[index] = value";\n',
- TYPE=self._NarrowInputType(element_type))
- else:
- self._members_emitter.Emit(
- '\n'
- ' void operator[]=(int index, $TYPE value) {\n'
- ' throw new UnsupportedOperationException("Cannot assign element of immutable List.");\n'
- ' }\n',
- TYPE=self._NarrowInputType(element_type))
-
- # TODO(sra): Use separate mixins for mutable implementations of List<T>.
- # TODO(sra): Use separate mixins for typed array implementations of List<T>.
- template_file = 'immutable_list_mixin.darttemplate'
- template = self._system._templates.Load(template_file)
- self._members_emitter.Emit(template, E=element_type)
-
-
- def AddTypedArrayConstructors(self, element_type):
- self._members_emitter.Emit(
- '\n'
- ' factory $CTOR(int length) => _construct_$CTOR(length);\n'
- '\n'
- ' factory $CTOR.fromList(List<$TYPE> list) => _construct_$CTOR(list);\n'
- '\n'
- ' factory $CTOR.fromBuffer(ArrayBuffer buffer) => _construct_$CTOR(buffer);\n'
- '\n'
- ' static _construct_$CTOR(arg) native \'return new $CTOR(arg);\';\n',
- CTOR=self._interface.id,
- TYPE=element_type)
-
-
- def AddOperation(self, info):
- """
- Arguments:
- info: An OperationInfo object.
- """
- # TODO(vsm): Handle overloads.
- self._members_emitter.Emit(
- '\n'
- ' $TYPE $NAME($PARAMS) native;\n',
- TYPE=self._NarrowOutputType(info.type_name),
- NAME=info.name,
- PARAMS=info.ParametersImplementationDeclaration(
- lambda type_name: self._NarrowInputType(type_name)))
-
-
-# ------------------------------------------------------------------------------
-
-# TODO(jmesserly): inheritance is probably not the right way to factor this long
-# term, but it makes merging better for now.
-class HtmlFrogInterfaceGenerator(FrogInterfaceGenerator):
- """Generates a Frog class for the dart:html library from a DOM IDL
- interface.
- """
-
- def __init__(self, system, interface, template, super_interface, dart_code):
- super(HtmlFrogInterfaceGenerator, self).__init__(
- system, interface, template, super_interface, dart_code)
-
- def AddEventAttributes(self, event_attrs):
- events_class = self._interface.id + 'EventsImpl'
- events_interface = self._interface.id + 'Events'
- self._members_emitter.Emit('\n $TYPE get on() =>\n new $TYPE(this);\n',
- TYPE=events_class)
-
- events_members = self._dart_code.Emit(
- '\n'
- 'class $CLASSNAME extends EventsImplementation '
- 'implements $INTERFACE {\n'
- ' $CLASSNAME(_ptr) : super._wrap(_ptr);\n'
- '$!MEMBERS}\n',
- CLASSNAME=events_class,
- INTERFACE=events_interface)
-
- for getter, setter in event_attrs:
- event = getter or setter
- events_members.Emit(
- "\n"
- "EventListenerList get $NAME() => _get('$NAME');\n",
- NAME=event.id)
-
-
# ------------------------------------------------------------------------------
class IDLTypeInfo(object):
« no previous file with comments | « client/dom/scripts/dartdomgenerator.py ('k') | client/dom/scripts/dartgenerator_test.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698