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

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

Issue 9845043: Rename client/{dom,html} to lib/{dom,html} . (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 9 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/systemnative.py ('k') | client/dom/scripts/templateloader.py » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: client/dom/scripts/systemwrapping.py
===================================================================
--- client/dom/scripts/systemwrapping.py (revision 5796)
+++ client/dom/scripts/systemwrapping.py (working copy)
@@ -1,543 +0,0 @@
-#!/usr/bin/python
-# Copyright (c) 2012, 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.
-
-"""This module provides shared functionality for the systems to generate
-wrapping binding from the IDL database."""
-
-import os
-from generator import *
-from systembase import *
-
-class WrappingImplementationSystem(System):
-
- def __init__(self, templates, database, emitters, output_dir):
- """Prepared for generating wrapping implementation.
-
- - Creates emitter for JS code.
- - Creates emitter for Dart code.
- """
- super(WrappingImplementationSystem, self).__init__(
- templates, database, emitters, output_dir)
- self._dart_wrapping_file_paths = []
-
-
- def InterfaceGenerator(self,
- interface,
- common_prefix,
- super_interface_name,
- source_filter):
- """."""
- interface_name = interface.id
- dart_wrapping_file_path = self._FilePathForDartWrappingImpl(interface_name)
-
- self._dart_wrapping_file_paths.append(dart_wrapping_file_path)
-
- dart_code = self._emitters.FileEmitter(dart_wrapping_file_path)
- dart_code.Emit(self._templates.Load('wrapping_impl.darttemplate'))
- return WrappingInterfaceGenerator(interface, super_interface_name,
- dart_code,
- self._BaseDefines(interface))
-
- def ProcessCallback(self, interface, info):
- pass
-
- def GenerateLibraries(self, lib_dir):
- # Library generated for implementation.
- self._GenerateLibFile(
- 'wrapping_dom.darttemplate',
- os.path.join(lib_dir, 'wrapping_dom.dart'),
- (self._interface_system._dart_interface_file_paths +
- self._interface_system._dart_callback_file_paths +
- # FIXME: Move the implementation to a separate library.
- self._dart_wrapping_file_paths
- ))
-
-
- def Finish(self):
- pass
-
-
- def _FilePathForDartWrappingImpl(self, interface_name):
- """Returns the file path of the Dart wrapping implementation."""
- return os.path.join(self._output_dir, 'src', 'wrapping',
- '_%sWrappingImplementation.dart' % interface_name)
-
-class WrappingInterfaceGenerator(object):
- """Generates Dart and JS implementation for one DOM IDL interface."""
-
- def __init__(self, interface, super_interface, dart_code, base_members):
- """Generates Dart and JS 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.
- 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.
- base_members: a set of names of members defined in a base class. This is
- used to avoid static member 'overriding' in the generated Dart code.
- """
- self._interface = interface
- self._super_interface = super_interface
- self._dart_code = dart_code
- self._base_members = base_members
- self._current_secondary_parent = None
-
-
- def StartInterface(self):
- interface = self._interface
- interface_name = interface.id
-
- self._class_name = self._ImplClassName(interface_name)
-
- base = self._BaseClassName(interface)
-
- (self._members_emitter,
- self._top_level_emitter) = self._dart_code.Emit(
- '\n'
- 'class $CLASS extends $BASE implements $INTERFACE {\n'
- ' $CLASS() : super() {}\n'
- '\n'
- ' static create_$CLASS() native {\n'
- ' return new $CLASS();\n'
- ' }\n'
- '$!MEMBERS'
- '\n'
- ' String get typeName() { return "$INTERFACE"; }\n'
- '}\n'
- '$!TOP_LEVEL',
- CLASS=self._class_name, BASE=base, INTERFACE=interface_name)
-
- def _ImplClassName(self, type_name):
- return '_' + type_name + 'WrappingImplementation'
-
- def _BaseClassName(self, interface):
- if not interface.parents:
- return 'DOMWrapperBase'
-
- supertype = interface.parents[0].type.id
-
- # FIXME: We're currently injecting List<..> and EventTarget as
- # supertypes in dart.idl. We should annotate/preserve as
- # 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):
- return 'DOMWrapperBase'
-
- if supertype == 'EventTarget':
- # Most implementors of EventTarget specify the EventListener operations
- # again. If the operations are not specified, try to inherit from the
- # EventTarget implementation.
- #
- # Applies to MessagePort.
- if not [op for op in interface.operations if op.id == 'addEventListener']:
- return self._ImplClassName(supertype)
- return 'DOMWrapperBase'
-
- return self._ImplClassName(supertype)
-
- def FinishInterface(self):
- """."""
- pass
-
- def AddConstant(self, constant):
- # Constants are already defined on the interface.
- pass
-
- def _MethodName(self, prefix, name):
- method_name = prefix + name
- if name in self._base_members: # Avoid illegal Dart 'static override'.
- method_name = method_name + '_' + self._interface.id
- return method_name
-
- def AddAttribute(self, getter, setter):
- if getter:
- self._AddGetter(getter)
- if setter:
- self._AddSetter(setter)
-
- def _AddGetter(self, attr):
- # FIXME: Instead of injecting the interface name into the method when it is
- # also implemented in the base class, suppress the method altogether if it
- # has the same signature. I.e., let the JS do the virtual dispatch instead.
- method_name = self._MethodName('_get_', attr.id)
- self._members_emitter.Emit(
- '\n'
- ' $TYPE get $NAME() { return $METHOD(this); }\n'
- ' static $TYPE $METHOD(var _this) native;\n',
- NAME=DartDomNameOfAttribute(attr),
- TYPE=DartType(attr.type.id),
- METHOD=method_name)
-
- def _AddSetter(self, attr):
- # FIXME: See comment on getter.
- method_name = self._MethodName('_set_', attr.id)
- self._members_emitter.Emit(
- '\n'
- ' void set $NAME($TYPE value) { $METHOD(this, value); }\n'
- ' static void $METHOD(var _this, $TYPE value) native;\n',
- NAME=DartDomNameOfAttribute(attr),
- TYPE=DartType(attr.type.id),
- METHOD=method_name)
-
- 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 _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; }
- #
- dart_element_type = DartType(element_type)
- if self._HasNativeIndexGetter(self._interface):
- self._EmitNativeIndexGetter(self._interface, dart_element_type)
- else:
- self._members_emitter.Emit(
- '\n'
- ' $TYPE operator[](int index) {\n'
- ' return item(index);\n'
- ' }\n',
- TYPE=dart_element_type)
-
- if self._HasNativeIndexSetter(self._interface):
- self._EmitNativeIndexSetter(self._interface, dart_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=dart_element_type)
-
- self._members_emitter.Emit(
- '\n'
- ' void add($TYPE value) {\n'
- ' throw new UnsupportedOperationException("Cannot add to immutable List.");\n'
- ' }\n'
- '\n'
- ' void addLast($TYPE value) {\n'
- ' throw new UnsupportedOperationException("Cannot add to immutable List.");\n'
- ' }\n'
- '\n'
- ' void addAll(Collection<$TYPE> collection) {\n'
- ' throw new UnsupportedOperationException("Cannot add to immutable List.");\n'
- ' }\n'
- '\n'
- ' void sort(int compare($TYPE a, $TYPE b)) {\n'
- ' throw new UnsupportedOperationException("Cannot sort immutable List.");\n'
- ' }\n'
- '\n'
- ' void copyFrom(List<Object> src, int srcStart, '
- 'int dstStart, int count) {\n'
- ' throw new UnsupportedOperationException("This object is immutable.");\n'
- ' }\n'
- '\n'
- ' int indexOf($TYPE element, [int start = 0]) {\n'
- ' return _Lists.indexOf(this, element, start, this.length);\n'
- ' }\n'
- '\n'
- ' int lastIndexOf($TYPE element, [int start = null]) {\n'
- ' if (start === null) start = length - 1;\n'
- ' return _Lists.lastIndexOf(this, element, start);\n'
- ' }\n'
- '\n'
- ' int clear() {\n'
- ' throw new UnsupportedOperationException("Cannot clear immutable List.");\n'
- ' }\n'
- '\n'
- ' $TYPE removeLast() {\n'
- ' throw new UnsupportedOperationException("Cannot removeLast on immutable List.");\n'
- ' }\n'
- '\n'
- ' $TYPE last() {\n'
- ' return this[length - 1];\n'
- ' }\n'
- '\n'
- ' void forEach(void f($TYPE element)) {\n'
- ' _Collections.forEach(this, f);\n'
- ' }\n'
- '\n'
- ' Collection map(f($TYPE element)) {\n'
- ' return _Collections.map(this, [], f);\n'
- ' }\n'
- '\n'
- ' Collection<$TYPE> filter(bool f($TYPE element)) {\n'
- ' return _Collections.filter(this, new List<$TYPE>(), f);\n'
- ' }\n'
- '\n'
- ' bool every(bool f($TYPE element)) {\n'
- ' return _Collections.every(this, f);\n'
- ' }\n'
- '\n'
- ' bool some(bool f($TYPE element)) {\n'
- ' return _Collections.some(this, f);\n'
- ' }\n'
- '\n'
- ' void setRange(int start, int length, List<$TYPE> from, [int startFrom]) {\n'
- ' throw new UnsupportedOperationException("Cannot setRange on immutable List.");\n'
- ' }\n'
- '\n'
- ' void removeRange(int start, int length) {\n'
- ' throw new UnsupportedOperationException("Cannot removeRange on immutable List.");\n'
- ' }\n'
- '\n'
- ' void insertRange(int start, int length, [$TYPE initialValue]) {\n'
- ' throw new UnsupportedOperationException("Cannot insertRange on immutable List.");\n'
- ' }\n'
- '\n'
- ' List<$TYPE> getRange(int start, int length) {\n'
- ' throw new NotImplementedException();\n'
- ' }\n'
- '\n'
- ' bool isEmpty() {\n'
- ' return length == 0;\n'
- ' }\n'
- '\n'
- ' Iterator<$TYPE> iterator() {\n'
- ' return new _FixedSizeListIterator<$TYPE>(this);\n'
- ' }\n',
- TYPE=dart_element_type)
-
- def _HasNativeIndexGetter(self, interface):
- return ('IndexedGetter' in interface.ext_attrs or
- 'NumericIndexedGetter' in interface.ext_attrs)
-
- def _EmitNativeIndexGetter(self, interface, dart_element_type):
- method_name = '_index'
- self._members_emitter.Emit(
- '\n'
- ' $TYPE operator[](int index) { return $METHOD(this, index); }\n'
- ' static $TYPE $METHOD(var _this, int index) native;\n',
- TYPE=dart_element_type, METHOD=method_name)
-
- def _HasNativeIndexSetter(self, interface):
- return 'CustomIndexedSetter' in interface.ext_attrs
-
- def _EmitNativeIndexSetter(self, interface, dart_element_type):
- method_name = '_set_index'
- self._members_emitter.Emit(
- '\n'
- ' void operator[]=(int index, $TYPE value) {\n'
- ' return $METHOD(this, index, value);\n'
- ' }\n'
- ' static $METHOD(_this, index, value) native;\n',
- TYPE=dart_element_type, METHOD=method_name)
-
- def AddOperation(self, info):
- """
- Arguments:
- info: An OperationInfo object.
- """
- body = self._members_emitter.Emit(
- '\n'
- ' $TYPE $NAME($PARAMS) {\n'
- '$!BODY'
- ' }\n',
- TYPE=info.type_name,
- NAME=info.name,
- PARAMS=info.ParametersImplementationDeclaration())
-
- # Process in order of ascending number of arguments to ensure missing
- # optional arguments are processed early.
- overloads = sorted(info.overloads,
- key=lambda overload: len(overload.arguments))
- self._native_version = 0
- fallthrough = self.GenerateDispatch(body, info, ' ', 0, overloads)
- if fallthrough:
- body.Emit(' throw "Incorrect number or type of arguments";\n');
-
- def GenerateSingleOperation(self, emitter, info, indent, operation):
- """Generates a call to a single operation.
-
- Arguments:
- emitter: an Emitter for the body of a block of code.
- info: the compound information about the operation and its overloads.
- indent: an indentation string for generated code.
- operation: the IDLOperation to call.
- """
- # TODO(sra): Do we need to distinguish calling with missing optional
- # arguments from passing 'null' which is represented as 'undefined'?
- def UnwrapArgExpression(name, type):
- # TODO: Type specific unwrapping.
- return '__dom_unwrap(%s)' % (name)
-
- def ArgNameAndUnwrapper(arg_info, overload_arg):
- (name, type, value) = arg_info
- return (name, UnwrapArgExpression(name, type))
-
- names_and_unwrappers = [ArgNameAndUnwrapper(info.arg_infos[i], arg)
- for (i, arg) in enumerate(operation.arguments)]
- unwrap_args = [unwrap_arg for (_, unwrap_arg) in names_and_unwrappers]
- arg_names = [name for (name, _) in names_and_unwrappers]
-
- self._native_version += 1
- native_name = self._MethodName('_', info.name)
- if self._native_version > 1:
- native_name = '%s_%s' % (native_name, self._native_version)
-
- argument_expressions = ', '.join(['this'] + arg_names)
- if info.type_name != 'void':
- emitter.Emit('$(INDENT)return $NATIVENAME($ARGS);\n',
- INDENT=indent,
- NATIVENAME=native_name,
- ARGS=argument_expressions)
- else:
- emitter.Emit('$(INDENT)$NATIVENAME($ARGS);\n'
- '$(INDENT)return;\n',
- INDENT=indent,
- NATIVENAME=native_name,
- ARGS=argument_expressions)
-
- self._members_emitter.Emit(' static $TYPE $NAME($PARAMS) native;\n',
- NAME=native_name,
- TYPE=info.type_name,
- PARAMS=', '.join(['receiver'] + arg_names) )
-
-
- def GenerateDispatch(self, emitter, info, indent, position, overloads):
- """Generates a dispatch to one of the overloads.
-
- Arguments:
- emitter: an Emitter for the body of a block of code.
- info: the compound information about the operation and its overloads.
- indent: an indentation string for generated code.
- position: the index of the parameter to dispatch on.
- overloads: a list of the remaining IDLOperations to dispatch.
-
- Returns True if the dispatch can fall through on failure, False if the code
- always dispatches.
- """
-
- def NullCheck(name):
- return '%s === null' % name
-
- def TypeCheck(name, type):
- return '%s is %s' % (name, type)
-
- def ShouldGenerateSingleOperation():
- if position == len(info.arg_infos):
- if len(overloads) > 1:
- raise Exception('Duplicate operations ' + str(overloads))
- return True
-
- # Check if we dispatch on RequiredCppParameter arguments. In this
- # case all trailing arguments must be RequiredCppParameter and there
- # is no need in dispatch.
- # TODO(antonm): better diagnositics.
- if position >= len(overloads[0].arguments):
- def IsRequiredCppParameter(arg):
- return 'RequiredCppParameter' in arg.ext_attrs
- last_overload = overloads[-1]
- if (len(last_overload.arguments) > position and
- IsRequiredCppParameter(last_overload.arguments[position])):
- for overload in overloads:
- args = overload.arguments[position:]
- if not all([IsRequiredCppParameter(arg) for arg in args]):
- raise Exception('Invalid overload for RequiredCppParameter')
- return True
-
- return False
-
- if ShouldGenerateSingleOperation():
- self.GenerateSingleOperation(emitter, info, indent, overloads[-1])
- return False
-
- # FIXME: Consider a simpler dispatch that iterates over the
- # overloads and generates an overload specific check. Revisit
- # when we move to named optional arguments.
-
- # Partition the overloads to divide and conquer on the dispatch.
- positive = []
- negative = []
- first_overload = overloads[0]
- (param_name, param_type, param_default) = info.arg_infos[position]
-
- if position < len(first_overload.arguments):
- # FIXME: This will not work if the second overload has a more
- # precise type than the first. E.g.,
- # void foo(Node x);
- # void foo(Element x);
- type = DartType(first_overload.arguments[position].type.id)
- test = TypeCheck(param_name, type)
- pred = lambda op: len(op.arguments) > position and DartType(op.arguments[position].type.id) == type
- else:
- type = None
- test = NullCheck(param_name)
- pred = lambda op: position >= len(op.arguments)
-
- for overload in overloads:
- if pred(overload):
- positive.append(overload)
- else:
- negative.append(overload)
-
- if positive and negative:
- (true_code, false_code) = emitter.Emit(
- '$(INDENT)if ($COND) {\n'
- '$!TRUE'
- '$(INDENT)} else {\n'
- '$!FALSE'
- '$(INDENT)}\n',
- COND=test, INDENT=indent)
- fallthrough1 = self.GenerateDispatch(
- true_code, info, indent + ' ', position + 1, positive)
- fallthrough2 = self.GenerateDispatch(
- false_code, info, indent + ' ', position, negative)
- return fallthrough1 or fallthrough2
-
- if negative:
- raise Exception('Internal error, must be all positive')
-
- # All overloads require the same test. Do we bother?
-
- # If the test is the same as the method's formal parameter then checked mode
- # will have done the test already. (It could be null too but we ignore that
- # case since all the overload behave the same and we don't know which types
- # in the IDL are not nullable.)
- if type == param_type:
- return self.GenerateDispatch(
- emitter, info, indent, position + 1, positive)
-
- # Otherwise the overloads have the same type but the type is a substype of
- # the method's synthesized formal parameter. e.g we have overloads f(X) and
- # f(Y), implemented by the synthesized method f(Z) where X<Z and Y<Z. The
- # dispatch has removed f(X), leaving only f(Y), but there is no guarantee
- # that Y = Z-X, so we need to check for Y.
- true_code = emitter.Emit(
- '$(INDENT)if ($COND) {\n'
- '$!TRUE'
- '$(INDENT)}\n',
- COND=test, INDENT=indent)
- self.GenerateDispatch(
- true_code, info, indent + ' ', position + 1, positive)
- return True
« no previous file with comments | « client/dom/scripts/systemnative.py ('k') | client/dom/scripts/templateloader.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698