[dart:html] Migrate python scripts to python 3

Migrates syntax and semantics from python 2.7.

Major changes include:

- filters
- sorting
- print statements
- higher-order functions
- hashing and comparison

and other misc changes. go.sh consistently gives the libraries
in this and the previous commits with these changes.

Change-Id: I66365739887158d8f321015d36e556447da1bcd3
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/211542
Commit-Queue: Srujan Gaddam <srujzs@google.com>
Reviewed-by: Riley Porter <rileyporter@google.com>
This commit is contained in:
Srujan Gaddam 2021-09-08 22:10:53 +00:00 committed by commit-bot@chromium.org
parent 8cee82debb
commit f34eef5b91
22 changed files with 279 additions and 228 deletions

View file

@ -10100,10 +10100,6 @@ class Document extends Node {
@SupportedBrowser(SupportedBrowser.SAFARI) @SupportedBrowser(SupportedBrowser.SAFARI)
void _webkitExitFullscreen() native; void _webkitExitFullscreen() native;
// From NonElementParentNode
Element? getElementById(String elementId) native;
// From DocumentOrShadowRoot // From DocumentOrShadowRoot
Element? get activeElement native; Element? get activeElement native;
@ -10126,6 +10122,10 @@ class Document extends Node {
FontFaceSet? get fonts native; FontFaceSet? get fonts native;
// From NonElementParentNode
Element? getElementById(String elementId) native;
// From ParentNode // From ParentNode
@JSName('childElementCount') @JSName('childElementCount')

View file

@ -43,7 +43,7 @@ Design doc: http://www.chromium.org/developers/design-documents/idl-compiler
""" """
import os import os
import cPickle as pickle import pickle
import re import re
import sys import sys

View file

@ -34,7 +34,7 @@ Design doc: http://www.chromium.org/developers/design-documents/idl-compiler
import abc import abc
from optparse import OptionParser from optparse import OptionParser
import os import os
import cPickle as pickle import pickle
from idl_reader import IdlReader from idl_reader import IdlReader
from utilities import write_file from utilities import write_file

View file

@ -86,12 +86,11 @@ def GenerateCssTemplateFile():
# TODO(efortuna): do we also want CSSPropertyNames.in? # TODO(efortuna): do we also want CSSPropertyNames.in?
data = [d.strip() for d in data if not isCommentLine(d) and not '=' in d] data = [d.strip() for d in data if not isCommentLine(d) and not '=' in d]
browser_props = [readCssProperties(file) for file in BROWSER_PATHS] browser_props = [set(readCssProperties(file)) for file in BROWSER_PATHS]
universal_properties = reduce(lambda a, b: set(a).intersection(b), universal_properties = set.intersection(*browser_props)
browser_props)
universal_properties = universal_properties.difference(['cssText']) universal_properties = universal_properties.difference(['cssText'])
universal_properties = universal_properties.intersection( universal_properties = universal_properties.intersection(
map(camelCaseName, data)) list(map(camelCaseName, data)))
class_file = open(TEMPLATE_FILE, 'w') class_file = open(TEMPLATE_FILE, 'w')

View file

@ -72,14 +72,12 @@ class DartGenerator(object):
def LoadAuxiliary(self, auxiliary_dir): def LoadAuxiliary(self, auxiliary_dir):
def Visitor(_, dirname, names): for (dirname, _, names) in os.walk(auxiliary_dir):
for name in names: for name in names:
if name.endswith('.dart'): if name.endswith('.dart'):
name = name[0:-5] # strip off ".dart" name = name[0:-5] # strip off ".dart"
self._auxiliary_files[name] = os.path.join(dirname, name) self._auxiliary_files[name] = os.path.join(dirname, name)
os.path.walk(auxiliary_dir, Visitor, None)
def FilterMembersWithUnidentifiedTypes(self, database): def FilterMembersWithUnidentifiedTypes(self, database):
"""Removes unidentified types. """Removes unidentified types.
@ -106,10 +104,13 @@ class DartGenerator(object):
return False return False
return True return True
interface.constants = filter(IsIdentified, interface.constants) interface.constants = list(filter(IsIdentified,
interface.attributes = filter(IsIdentified, interface.attributes) interface.constants))
interface.operations = filter(IsIdentified, interface.operations) interface.attributes = list(
interface.parents = filter(IsIdentified, interface.parents) filter(IsIdentified, interface.attributes))
interface.operations = list(
filter(IsIdentified, interface.operations))
interface.parents = list(filter(IsIdentified, interface.parents))
def FilterInterfaces(self, def FilterInterfaces(self,
database, database,

View file

@ -12,7 +12,6 @@ import logging
import monitored import monitored
import os import os
import re import re
from generator import ConstantOutputOrder
from htmlrenamer import renamed_html_members, html_interface_renames from htmlrenamer import renamed_html_members, html_interface_renames
_logger = logging.getLogger('dartmetadata') _logger = logging.getLogger('dartmetadata')
@ -714,7 +713,7 @@ class DartMetadata(object):
if _monitor_type_metadata: if _monitor_type_metadata:
monitored_interfaces = {} monitored_interfaces = {}
for interface_id, interface_data in self._types.items(): for interface_id, interface_data in list(self._types.items()):
monitored_interface = interface_data.copy() monitored_interface = interface_data.copy()
monitored_interface['members'] = monitored.Dict( monitored_interface['members'] = monitored.Dict(
'dartmetadata.%s' % interface_id, interface_data['members']) 'dartmetadata.%s' % interface_id, interface_data['members'])

View file

@ -149,7 +149,7 @@ class Database(object):
def Save(self): def Save(self):
"""Saves all in-memory interfaces into files.""" """Saves all in-memory interfaces into files."""
for interface in self._all_interfaces.values(): for interface in list(self._all_interfaces.values()):
self._SaveInterfaceFile(interface) self._SaveInterfaceFile(interface)
for interface_name in self._interfaces_to_delete: for interface_name in self._interfaces_to_delete:
self._DeleteInterfaceFile(interface_name) self._DeleteInterfaceFile(interface_name)

View file

@ -51,7 +51,7 @@ class DatabaseTestCase(unittest.TestCase):
def testListInterfaces(self): def testListInterfaces(self):
db = database.Database(self._database_dir) db = database.Database(self._database_dir)
db.Load() db.Load()
self.assertEquals(self._ListInterfaces(db), ['I1']) self.assertEqual(self._ListInterfaces(db), ['I1'])
def testHasInterface(self): def testHasInterface(self):
db = database.Database(self._database_dir) db = database.Database(self._database_dir)
@ -67,7 +67,7 @@ class DatabaseTestCase(unittest.TestCase):
db.Save() db.Save()
self.assertTrue( self.assertTrue(
os.path.exists(os.path.join(self._database_dir, 'I2.idl'))) os.path.exists(os.path.join(self._database_dir, 'I2.idl')))
self.assertEquals(self._ListInterfaces(db), ['I1', 'I2']) self.assertEqual(self._ListInterfaces(db), ['I1', 'I2'])
def testDeleteInterface(self): def testDeleteInterface(self):
db = database.Database(self._database_dir) db = database.Database(self._database_dir)
@ -76,13 +76,13 @@ class DatabaseTestCase(unittest.TestCase):
db.Save() db.Save()
self.assertFalse( self.assertFalse(
os.path.exists(os.path.join(self._database_dir, 'I1.idl'))) os.path.exists(os.path.join(self._database_dir, 'I1.idl')))
self.assertEquals(self._ListInterfaces(db), []) self.assertEqual(self._ListInterfaces(db), [])
def testGetInterface(self): def testGetInterface(self):
db = database.Database(self._database_dir) db = database.Database(self._database_dir)
db.Load() db.Load()
interface = db.GetInterface('I1') interface = db.GetInterface('I1')
self.assertEquals(interface.id, 'I1') self.assertEqual(interface.id, 'I1')
if __name__ == '__main__': if __name__ == '__main__':

View file

@ -236,9 +236,9 @@ class DatabaseBuilder(object):
ext_attrs_node[ ext_attrs_node[
type_valued_attribute_name] = strip_modules(value) type_valued_attribute_name] = strip_modules(value)
map(rename_node, idl_file.all(IDLInterface)) list(map(rename_node, idl_file.all(IDLInterface)))
map(rename_node, idl_file.all(IDLType)) list(map(rename_node, idl_file.all(IDLType)))
map(rename_ext_attrs, idl_file.all(IDLExtAttrs)) list(map(rename_ext_attrs, idl_file.all(IDLExtAttrs)))
def _annotate(self, interface, import_options): def _annotate(self, interface, import_options):
"""Adds @ annotations based on the source and source_attributes """Adds @ annotations based on the source and source_attributes
@ -259,10 +259,10 @@ class DatabaseBuilder(object):
add_source_annotation(interface) add_source_annotation(interface)
map(add_source_annotation, interface.parents) list(map(add_source_annotation, interface.parents))
map(add_source_annotation, interface.constants) list(map(add_source_annotation, interface.constants))
map(add_source_annotation, interface.attributes) list(map(add_source_annotation, interface.attributes))
map(add_source_annotation, interface.operations) list(map(add_source_annotation, interface.operations))
def _sign(self, node): def _sign(self, node):
"""Computes a unique signature for the node, for merging purposed, by """Computes a unique signature for the node, for merging purposed, by
@ -480,7 +480,8 @@ class DatabaseBuilder(object):
def has_annotations(idl_node): def has_annotations(idl_node):
return len(idl_node.annotations) return len(idl_node.annotations)
old_interface.__dict__[what] = filter(has_annotations, old_list) old_interface.__dict__[what] = \
list(filter(has_annotations, old_list))
return changed return changed
@ -619,7 +620,7 @@ class DatabaseBuilder(object):
def _process_ast(self, filename, ast): def _process_ast(self, filename, ast):
if len(ast) == 1: if len(ast) == 1:
ast = ast.values()[0] ast = next(iter(ast.values()))
else: else:
print('ERROR: Processing AST: ' + os.path.basename(file_name)) print('ERROR: Processing AST: ' + os.path.basename(file_name))
new_asts[filename] = ast new_asts[filename] = ast
@ -664,8 +665,8 @@ class DatabaseBuilder(object):
(interface.id, import_options.source, (interface.id, import_options.source,
os.path.basename(idl_file.filename))) os.path.basename(idl_file.filename)))
interface.attributes = filter(enabled, interface.attributes) interface.attributes = list(filter(enabled, interface.attributes))
interface.operations = filter(enabled, interface.operations) interface.operations = list(filter(enabled, interface.operations))
self._imported_interfaces.append((interface, import_options)) self._imported_interfaces.append((interface, import_options))
# If an IDL dictionary then there is no implementsStatements. # If an IDL dictionary then there is no implementsStatements.
@ -769,15 +770,15 @@ class DatabaseBuilder(object):
if (source in idl_node.annotations and if (source in idl_node.annotations and
idl_node.annotations[source]): idl_node.annotations[source]):
annotation = idl_node.annotations[source] annotation = idl_node.annotations[source]
for name, value in annotation.items(): for name, value in list(annotation.items()):
if (name in top_level_annotation and if (name in top_level_annotation and
value == top_level_annotation[name]): value == top_level_annotation[name]):
del annotation[name] del annotation[name]
map(normalize, interface.parents) list(map(normalize, interface.parents))
map(normalize, interface.constants) list(map(normalize, interface.constants))
map(normalize, interface.attributes) list(map(normalize, interface.attributes))
map(normalize, interface.operations) list(map(normalize, interface.operations))
def map_dictionaries(self): def map_dictionaries(self):
"""Changes the type of operations/constructors arguments from an IDL """Changes the type of operations/constructors arguments from an IDL
@ -790,12 +791,12 @@ class DatabaseBuilder(object):
type_node.id = 'Dictionary' type_node.id = 'Dictionary'
def all_types(node): def all_types(node):
map(dictionary_to_map, node.all(IDLType)) list(map(dictionary_to_map, node.all(IDLType)))
for interface in self._database.GetInterfaces(): for interface in self._database.GetInterfaces():
map(all_types, interface.all(IDLExtAttrFunctionValue)) list(map(all_types, interface.all(IDLExtAttrFunctionValue)))
map(all_types, interface.attributes) list(map(all_types, interface.attributes))
map(all_types, interface.operations) list(map(all_types, interface.operations))
def fetch_constructor_data(self, options): def fetch_constructor_data(self, options):
window_interface = self._database.GetInterface('Window') window_interface = self._database.GetInterface('Window')
@ -1023,7 +1024,7 @@ Examination Complete
self._no_interfaces_used_types = [] self._no_interfaces_used_types = []
constructor_function = self._no_interface_constructor_types constructor_function = self._no_interface_constructor_types
map(constructor_function, interface.all(IDLExtAttrFunctionValue)) list(map(constructor_function, interface.all(IDLExtAttrFunctionValue)))
self._mark_usage(interface, check_dictionaries=check_dictionaries) self._mark_usage(interface, check_dictionaries=check_dictionaries)
@ -1040,7 +1041,7 @@ Examination Complete
self._no_interfaces_used_types = [] self._no_interfaces_used_types = []
used = self._no_interface_used used = self._no_interface_used
map(used, operation_attribute.all(IDLType)) list(map(used, operation_attribute.all(IDLType)))
self._remember_usage( self._remember_usage(
operation_attribute, check_dictionaries=check_dictionaries) operation_attribute, check_dictionaries=check_dictionaries)
@ -1053,14 +1054,14 @@ Examination Complete
# (IDLExtAttrFunctionValue) that have a dictionary reference. # (IDLExtAttrFunctionValue) that have a dictionary reference.
def _dictionary_constructor_types(self, node): def _dictionary_constructor_types(self, node):
self._dictionaries_used_types = [] self._dictionaries_used_types = []
map(self._dictionary_used, node.all(IDLType)) list(map(self._dictionary_used, node.all(IDLType)))
self._remember_usage(node) self._remember_usage(node)
# Iterator function for map to iterate over all constructor types # Iterator function for map to iterate over all constructor types
# (IDLExtAttrFunctionValue) that reference an interface with NoInterfaceObject. # (IDLExtAttrFunctionValue) that reference an interface with NoInterfaceObject.
def _no_interface_constructor_types(self, node): def _no_interface_constructor_types(self, node):
self._no_interfaces_used_types = [] self._no_interfaces_used_types = []
map(self._no_interface_used, node.all(IDLType)) list(map(self._no_interface_used, node.all(IDLType)))
self._remember_usage(node, check_dictionaries=False) self._remember_usage(node, check_dictionaries=False)
# Maximum width of each column. # Maximum width of each column.

View file

@ -30,7 +30,8 @@ class DatabaseBuilderTestCase(unittest.TestCase):
def _assert_content_equals(self, path, expected_content): def _assert_content_equals(self, path, expected_content):
def clean(content): def clean(content):
return ' '.join(filter(len, map(str.strip, content.split('\n')))) return ' '.join(
filter(len, list(map(str.strip, content.split('\n')))))
file_path = os.path.join(self._database_dir, path) file_path = os.path.join(self._database_dir, path)
self.assertTrue(os.path.exists(file_path)) self.assertTrue(os.path.exists(file_path))

View file

@ -18,7 +18,7 @@ class EmitterTestCase(unittest.TestCase):
pass pass
def check(self, e, expected): def check(self, e, expected):
self.assertEquals(''.join(e.Fragments()), expected) self.assertEqual(''.join(e.Fragments()), expected)
def testExample(self): def testExample(self):
e = emitter.Emitter() e = emitter.Emitter()
@ -34,7 +34,7 @@ class EmitterTestCase(unittest.TestCase):
try: try:
e = emitter.Emitter() e = emitter.Emitter()
b = e.Emit('$(A)$(!B)$(A)$(!B)') # $(!B) is duplicated b = e.Emit('$(A)$(!B)$(A)$(!B)') # $(!B) is duplicated
except RuntimeError, ex: except RuntimeError as ex:
return return
raise AssertionError('Expected error') raise AssertionError('Expected error')
@ -46,7 +46,7 @@ class EmitterTestCase(unittest.TestCase):
def testTemplate2(self): def testTemplate2(self):
e = emitter.Emitter() e = emitter.Emitter()
r = e.Emit('1$(A)2$(B)3$(A)4$(B)5', A='x', B='y') r = e.Emit('1$(A)2$(B)3$(A)4$(B)5', A='x', B='y')
self.assertEquals(None, r) self.assertEqual(None, r)
self.check(e, '1x2y3x4y5') self.check(e, '1x2y3x4y5')
def testTemplate3(self): def testTemplate3(self):
@ -128,12 +128,12 @@ class EmitterTestCase(unittest.TestCase):
e = emitter.Emitter() e = emitter.Emitter()
e.Emit('$#A(-)', A='Invalid') e.Emit('$#A(-)', A='Invalid')
e.Fragments() e.Fragments()
except RuntimeError, ex: except RuntimeError as ex:
return return
raise AssertionError('Expected error') raise AssertionError('Expected error')
def testFormat(self): def testFormat(self):
self.assertEquals(emitter.Format('$A$B', A=1, B=2), '12') self.assertEqual(emitter.Format('$A$B', A=1, B=2), '12')
if __name__ == '__main__': if __name__ == '__main__':

View file

@ -58,10 +58,10 @@ def ResolveAllTypedefs(all_interfaces):
continue continue
return True return True
interface.constants = filter(IsIdentified, interface.constants) interface.constants = list(filter(IsIdentified, interface.constants))
interface.attributes = filter(IsIdentified, interface.attributes) interface.attributes = list(filter(IsIdentified, interface.attributes))
interface.operations = filter(IsIdentified, interface.operations) interface.operations = list(filter(IsIdentified, interface.operations))
interface.parents = filter(IsIdentified, interface.parents) interface.parents = list(filter(IsIdentified, interface.parents))
def build_database(idl_files, def build_database(idl_files,
@ -193,16 +193,15 @@ def main(parallel=False, logging_level=logging.WARNING, examine_idls=False):
'WebKitGamepadList.idl', # GamepadList is the new one. 'WebKitGamepadList.idl', # GamepadList is the new one.
] ]
def visitor(arg, dir_name, names): for (dir_name, dirs, files) in os.walk(webcore_dir):
if os.path.basename(dir_name) in DIRS_TO_IGNORE: if os.path.basename(dir_name) in DIRS_TO_IGNORE:
names[:] = [] # Do not go underneath dirs[:] = [] # Do not go underneath
for name in names: else:
file_name = os.path.join(dir_name, name) for name in files:
(interface, ext) = os.path.splitext(file_name) file_name = os.path.join(dir_name, name)
if ext == '.idl' and not (name in FILES_TO_IGNORE): (interface, ext) = os.path.splitext(file_name)
idl_files.append(file_name) if ext == '.idl' and not (name in FILES_TO_IGNORE):
idl_files.append(file_name)
os.path.walk(webcore_dir, visitor, webcore_dir)
database_dir = os.path.join(current_dir, '..', 'database') database_dir = os.path.join(current_dir, '..', 'database')

View file

@ -6,14 +6,13 @@
"""Generates sdk/lib/_blink/dartium/_blink_dartium.dart file.""" """Generates sdk/lib/_blink/dartium/_blink_dartium.dart file."""
import os import os
from sets import Set from generator import AnalyzeOperation, AnalyzeConstructor, ConstantOutputOrder
from generator import AnalyzeOperation, AnalyzeConstructor
# This is list of all methods with native c++ implementations # This is list of all methods with native c++ implementations
# If performing a dartium merge, the best practice is to comment out this list, # If performing a dartium merge, the best practice is to comment out this list,
# ensure everything runs, and then uncomment this list which might possibly # ensure everything runs, and then uncomment this list which might possibly
# introduce breaking changes due to changes to these method signatures. # introduce breaking changes due to changes to these method signatures.
_js_custom_members = Set([ _js_custom_members = set([
'Document.createElement', 'Document.createElement',
'Element.id', 'Element.id',
'Element.tagName', 'Element.tagName',
@ -79,7 +78,7 @@ _js_custom_members = Set([
# Uncomment out this line to short circuited native methods and run all of # Uncomment out this line to short circuited native methods and run all of
# dart:html through JS interop except for createElement which is slightly more # dart:html through JS interop except for createElement which is slightly more
# tightly natively wired. # tightly natively wired.
# _js_custom_members = Set([]) # _js_custom_members = set()
# Expose built-in methods support by an instance that is not shown in the IDL. # Expose built-in methods support by an instance that is not shown in the IDL.
_additional_methods = { _additional_methods = {
@ -385,12 +384,6 @@ CLASS_DEFINITION_END = """}
""" """
def ConstantOutputOrder(a, b):
"""Canonical output ordering for constants."""
return (a.id > b.id) - (a.id < b.id)
def generate_parameter_entries(param_infos): def generate_parameter_entries(param_infos):
optional_default_args = 0 optional_default_args = 0
for argument in param_infos: for argument in param_infos:
@ -524,7 +517,7 @@ def _Emit_Blink_Constructors(blink_file, analyzed_constructors):
def _Process_Attributes(blink_file, interface, attributes): def _Process_Attributes(blink_file, interface, attributes):
# Emit an interface's attributes and operations. # Emit an interface's attributes and operations.
for attribute in sorted(attributes, ConstantOutputOrder): for attribute in sorted(attributes, key=ConstantOutputOrder):
name = attribute.id name = attribute.id
is_native = _Is_Native(interface.id, name) is_native = _Is_Native(interface.id, name)
if attribute.is_read_only: if attribute.is_read_only:
@ -552,7 +545,7 @@ def _Process_Operations(blink_file,
primary_interface=False): primary_interface=False):
analyzeOperations = [] analyzeOperations = []
for operation in sorted(operations, ConstantOutputOrder): for operation in sorted(operations, key=ConstantOutputOrder):
if len(analyzeOperations) == 0: if len(analyzeOperations) == 0:
analyzeOperations.append(operation) analyzeOperations.append(operation)
else: else:

View file

@ -10,6 +10,8 @@ import json
import monitored import monitored
import os import os
import re import re
from functools import cmp_to_key
from itertools import zip_longest
from htmlrenamer import custom_html_constructors, html_interface_renames, \ from htmlrenamer import custom_html_constructors, html_interface_renames, \
typed_array_renames typed_array_renames
@ -216,7 +218,7 @@ _suppressed_native_constructors = monitored.Set(
]) ])
_custom_types = monitored.Set('generator._custom_types', _custom_types = monitored.Set('generator._custom_types',
typed_array_renames.keys()) list(typed_array_renames.keys()))
def IsCustomType(interface_name): def IsCustomType(interface_name):
@ -399,6 +401,19 @@ def MatchSourceFilter(thing):
return 'WebKit' in thing.annotations or 'Dart' in thing.annotations return 'WebKit' in thing.annotations or 'Dart' in thing.annotations
# Legacy Python 2 way to sort lists. Group by type, and then sort by value.
class MultitypeSortKey:
def __init__(self, value):
self.value = value
def __lt__(self, other):
try:
return self.value < other.value
except TypeError:
return str(type(self)) < str(type(other))
class ParamInfo(object): class ParamInfo(object):
"""Holder for various information about a parameter of a Dart operation. """Holder for various information about a parameter of a Dart operation.
@ -497,7 +512,8 @@ def _BuildArguments(args, interface, constructor=False):
# Given a list of overloaded default values, choose a suitable one. # Given a list of overloaded default values, choose a suitable one.
def OverloadedDefault(args): def OverloadedDefault(args):
defaults = sorted(set(arg.default_value for arg in args)) defaults = sorted(set(arg.default_value for arg in args),
key=MultitypeSortKey)
if len(set(DartType(arg.type.id) for arg in args)) == 1: if len(set(DartType(arg.type.id) for arg in args)) == 1:
null_default = False null_default = False
for arg in args: for arg in args:
@ -509,14 +525,12 @@ def _BuildArguments(args, interface, constructor=False):
result = [] result = []
is_optional = False is_optional = False
# Process overloaded arguments across a set of overloaded operations. # Process overloaded arguments across a set of overloaded operations.
# Each tuple in args corresponds to overloaded arguments with the same name. # Each tuple in args corresponds to overloaded arguments with the same name.
for arg_tuple in map(lambda *x: x, *args): for arg_tuple in list(zip_longest(*args)):
is_optional = is_optional or any( is_optional = is_optional or any(
arg is None or IsOptional(arg) for arg in arg_tuple) arg is None or IsOptional(arg) for arg in arg_tuple)
filtered = list(filter(None, arg_tuple))
filtered = filter(None, arg_tuple)
(type_id, is_nullable) = OverloadedType(filtered) (type_id, is_nullable) = OverloadedType(filtered)
name = OverloadedName(filtered) name = OverloadedName(filtered)
(default_value, default_value_is_null) = OverloadedDefault(filtered) (default_value, default_value_is_null) = OverloadedDefault(filtered)
@ -608,9 +622,9 @@ def ConvertToFuture(info):
return 'Callback' not in type_id return 'Callback' not in type_id
# Success callback is the first argument (change if this no longer holds). # Success callback is the first argument (change if this no longer holds).
new_info.callback_args = filter(lambda x: not IsNotCallbackType(x), new_info.callback_args = list(
new_info.param_infos) filter(lambda x: not IsNotCallbackType(x), new_info.param_infos))
new_info.param_infos = filter(IsNotCallbackType, new_info.param_infos) new_info.param_infos = list(filter(IsNotCallbackType, new_info.param_infos))
new_info.type_name = 'Future' new_info.type_name = 'Future'
return new_info return new_info
@ -745,9 +759,10 @@ class OperationInfo(object):
# TODO(terry): This may have to change for dart2js for code shaking the # TODO(terry): This may have to change for dart2js for code shaking the
# return types (unions) needs to be emitted with @create # return types (unions) needs to be emitted with @create
# annotations and/or with JS('type1|type2',...) # annotations and/or with JS('type1|type2',...)
if hasattr(rename_type, if hasattr(
'im_self') and rename_type.im_self._database.HasTypeDef( rename_type,
param.type_id): '__self__') and rename_type.__self__._database.HasTypeDef(
param.type_id):
dart_type = 'dynamic' dart_type = 'dynamic'
else: else:
dart_type = rename_type( dart_type = rename_type(
@ -783,7 +798,7 @@ class OperationInfo(object):
def FormatParam(dec): def FormatParam(dec):
return dec[0] + dec[1] return dec[0] + dec[1]
argtexts = map(FormatParam, required) argtexts = list(map(FormatParam, required))
if optional: if optional:
left_bracket, right_bracket = '{}' if needs_named else '[]' left_bracket, right_bracket = '{}' if needs_named else '[]'
argtexts.append(left_bracket + argtexts.append(left_bracket +
@ -799,7 +814,7 @@ class OperationInfo(object):
""" Returns a number of required arguments in Dart declaration of """ Returns a number of required arguments in Dart declaration of
the operation. the operation.
""" """
return len(filter(lambda i: not i.is_optional, self.param_infos)) return len(list(filter(lambda i: not i.is_optional, self.param_infos)))
def ParametersAsArgumentList(self, def ParametersAsArgumentList(self,
parameter_count=None, parameter_count=None,
@ -939,11 +954,14 @@ class OperationInfo(object):
return rename_type(self.type_name) return rename_type(self.type_name)
def ConstantOutputOrder(a, b): def _ConstantOutputOrder(a, b):
"""Canonical output ordering for constants.""" """Canonical output ordering for constants."""
return (a.id > b.id) - (a.id < b.id) return (a.id > b.id) - (a.id < b.id)
ConstantOutputOrder = cmp_to_key(_ConstantOutputOrder)
def _FormatNameList(names): def _FormatNameList(names):
"""Returns JavaScript array literal expression with one name per line.""" """Returns JavaScript array literal expression with one name per line."""
#names = sorted(names) #names = sorted(names)

View file

@ -38,4 +38,4 @@ fi
# third_party IDL scripts are not compatible with python3, so use python2.7. # third_party IDL scripts are not compatible with python3, so use python2.7.
reset && \ reset && \
python2.7 ./dartdomgenerator.py --systems="$SYSTEMS" --logging=40 --update-dom-metadata --gen-interop "$ARG_OPTION" python3 ./dartdomgenerator.py --systems="$SYSTEMS" --logging=40 --update-dom-metadata --gen-interop "$ARG_OPTION"

View file

@ -37,7 +37,6 @@ _custom_factories = [
'EventSource', 'EventSource',
] ]
class HtmlDartGenerator(object): class HtmlDartGenerator(object):
def __init__(self, interface, options, dart_use_blink, logger): def __init__(self, interface, options, dart_use_blink, logger):
@ -82,10 +81,10 @@ class HtmlDartGenerator(object):
# one synthesized class (WebGL). # one synthesized class (WebGL).
self._gl_constants.extend(interface.constants) self._gl_constants.extend(interface.constants)
else: else:
for const in sorted(interface.constants, ConstantOutputOrder): for const in sorted(interface.constants, key=ConstantOutputOrder):
self.AddConstant(const) self.AddConstant(const)
for attr in sorted(interface.attributes, ConstantOutputOrder): for attr in sorted(interface.attributes, key=ConstantOutputOrder):
if attr.type.id != 'EventHandler' and attr.type.id != 'EventListener': if attr.type.id != 'EventHandler' and attr.type.id != 'EventListener':
self.AddAttribute(attr, declare_only) self.AddAttribute(attr, declare_only)
@ -132,12 +131,13 @@ class HtmlDartGenerator(object):
_logger.warn('Interface %s has duplicate parent interfaces %s - ' \ _logger.warn('Interface %s has duplicate parent interfaces %s - ' \
'ignoring duplicates. Please file a bug with the dart:html team.' % (interface.id, parent_list)) 'ignoring duplicates. Please file a bug with the dart:html team.' % (interface.id, parent_list))
for parent_interface in sorted(secondary_parents): for parent_interface in sorted(secondary_parents,
key=ConstantOutputOrder):
if isinstance(parent_interface, str): if isinstance(parent_interface, str):
continue continue
for attr in sorted(parent_interface.attributes, for attr in sorted(parent_interface.attributes,
ConstantOutputOrder): key=ConstantOutputOrder):
if not FindMatchingAttribute(interface, attr): if not FindMatchingAttribute(interface, attr):
if attr.type.id != 'EventHandler': if attr.type.id != 'EventHandler':
self.SecondaryContext(parent_interface) self.SecondaryContext(parent_interface)
@ -172,7 +172,6 @@ class HtmlDartGenerator(object):
# are pure interfaces (mixins to this interface). # are pure interfaces (mixins to this interface).
if (IsPureInterface(parent_name, self._database)): if (IsPureInterface(parent_name, self._database)):
return return
for operation in parent.operations: for operation in parent.operations:
if operation.id in operationsByName: if operation.id in operationsByName:
operations = operationsByName[operation.id] operations = operationsByName[operation.id]
@ -242,8 +241,10 @@ class HtmlDartGenerator(object):
if (operation.id in operations_by_name and if (operation.id in operations_by_name and
len(operations_by_name[operation.id]) > 1 and len( len(operations_by_name[operation.id]) > 1 and len(
filter(lambda overload: overload.startswith(operation_str), list(
renamed_overloads.keys())) == 0 and filter(
lambda overload: overload.startswith(operation_str),
renamed_overloads.keys()))) == 0 and
operation_str not in keep_overloaded_members and operation_str not in keep_overloaded_members and
operation_str not in overloaded_and_renamed and operation_str not in overloaded_and_renamed and
operation_str not in renamed_html_members and operation_str not in renamed_html_members and

View file

@ -7,6 +7,7 @@ import os
import sys import sys
import idl_definitions import idl_definitions
from generator import MultitypeSortKey
from idl_types import IdlType, IdlNullableType, IdlUnionType, IdlArrayOrSequenceType from idl_types import IdlType, IdlNullableType, IdlUnionType, IdlArrayOrSequenceType
import dependency import dependency
@ -88,12 +89,18 @@ class IDLNode(object):
"""Returns string of extra info for __repr__().""" """Returns string of extra info for __repr__()."""
return '' return ''
def __cmp__(self, other): def __eq__(self, other):
"""Override default compare operation. """Override default equals operation.
IDLNodes are equal if all their properties are equal.""" IDLNodes are equal if all their properties are equal."""
if other is None or not isinstance(other, IDLNode): if other is None or not isinstance(other, IDLNode):
return 1 return 1
return self.__dict__.__cmp__(other.__dict__) return self.__dict__.__eq__(other.__dict__)
def __hash__(self):
"""Define default hashing behavior.
In order to comply with a == b => hash(a) == hash(b), we recursively iterate
self.__dict__ and convert all objects to hashable objects."""
return self.to_hash()
def reset_id(self, newId): def reset_id(self, newId):
"""Reset the id of the Node. This is typically done during a normalization """Reset the id of the Node. This is typically done during a normalization
@ -152,7 +159,36 @@ class IDLNode(object):
res[k] = v res[k] = v
return res return res
def _find_all(self, ast, label, max_results=sys.maxint): def to_hash(self):
return hash(self._to_hashable(self))
def _to_hashable(self, obj):
# By default, lists and dicts are not hashable, and user-defined objects
# are unordered. In order to make a consistent hash for a given object,
# this converts unhashable types and sorts properties.
if isinstance(obj, list):
# Convert lists to tuples.
new_obj = []
for item in obj:
new_obj.append(self._to_hashable(item))
return tuple(new_obj)
elif isinstance(obj, dict):
# Convert dicts to frozensets of tuples.
new_obj = set()
# Sort to ensure fixed order.
for (k2, v2) in sorted(obj.items(), key=MultitypeSortKey):
new_obj.add((self._to_hashable(k2), self._to_hashable(v2)))
return frozenset(new_obj)
elif hasattr(obj, '__dict__'):
items = []
# Sort properties to ensure fixed order.
for (k, v) in sorted(obj.__dict__.items(), key=MultitypeSortKey):
items.append((k, self._to_hashable(v)))
return tuple(items)
else:
return obj
def _find_all(self, ast, label, max_results=sys.maxsize):
"""Searches the AST for tuples with a given label. The PegParser """Searches the AST for tuples with a given label. The PegParser
output is composed of lists and tuples, where the tuple 1st argument output is composed of lists and tuples, where the tuple 1st argument
is a label. If ast root is a list, will search recursively inside each is a label. If ast root is a list, will search recursively inside each
@ -452,9 +488,9 @@ class IDLFile(IDLNode):
interface_info = dependency.get_interfaces_info()[interface. interface_info = dependency.get_interfaces_info()[interface.
id] id]
implements = interface_info[ implements = []
'implements_interfaces'] if interface_info.has_key( if 'implements_interfaces' in interface_info:
'implements_interfaces') else [] implements = interface_info['implements_interfaces']
if not (blink_interface.is_partial) and len(implements) > 0: if not (blink_interface.is_partial) and len(implements) > 0:
implementor = new_asts[interface.id].interfaces.get( implementor = new_asts[interface.id].interfaces.get(
interface.id) interface.id)

View file

@ -37,7 +37,7 @@ class IDLNodeTestCase(unittest.TestCase):
ast = parser.parse(content) ast = parser.parse(content)
node = idlnode.IDLFile(ast) node = idlnode.IDLFile(ast)
actual = node.to_dict() if node else None actual = node.to_dict() if node else None
except SyntaxError, e: except SyntaxError as e:
error = e error = e
pass pass
if actual == expected: if actual == expected:

View file

@ -46,13 +46,13 @@ def _get_browser_compat_data():
if 'api' in json_dict: if 'api' in json_dict:
# Get the interface name # Get the interface name
api_dict = json_dict['api'] api_dict = json_dict['api']
interface_name = api_dict.keys()[0] interface_name = next(iter(api_dict))
return (interface_name, api_dict[interface_name]) return (interface_name, api_dict[interface_name])
elif 'html' in json_dict: elif 'html' in json_dict:
html_dict = json_dict['html'] html_dict = json_dict['html']
if 'elements' in html_dict: if 'elements' in html_dict:
elements_dict = html_dict['elements'] elements_dict = html_dict['elements']
element_name = elements_dict.keys()[0] element_name = next(iter(elements_dict))
# Convert to WebCore name # Convert to WebCore name
interface = str('HTML' + element_name + 'Element') interface = str('HTML' + element_name + 'Element')
return (interface, elements_dict[element_name]) return (interface, elements_dict[element_name])
@ -60,49 +60,12 @@ def _get_browser_compat_data():
svg_dict = json_dict['svg'] svg_dict = json_dict['svg']
if 'elements' in svg_dict: if 'elements' in svg_dict:
elements_dict = svg_dict['elements'] elements_dict = svg_dict['elements']
element_name = elements_dict.keys()[0] element_name = next(iter(elements_dict))
# Convert to WebCore name # Convert to WebCore name
interface = str('SVG' + element_name + 'Element') interface = str('SVG' + element_name + 'Element')
return (interface, elements_dict[element_name]) return (interface, elements_dict[element_name])
return (None, None) return (None, None)
def visitor(arg, dir_path, names):
def should_process_dir(dir_path):
if os.path.abspath(dir_path) == browser_compat_folder:
return True
for dir in INCLUDE_DIRS:
if dir_path.startswith(dir):
return True
return False
if should_process_dir(dir_path):
for name in names:
file_name = os.path.join(dir_path, name)
(interface_path, ext) = os.path.splitext(file_name)
if ext == '.json':
with open(file_name) as src:
json_dict = json.load(src)
interface, metadata = process_json_dict(json_dict)
if not interface is None:
# Note: interface and member names do not
# necessarily have the same capitalization as
# WebCore, so we keep them all lowercase for easier
# matching later.
interface = interface.lower()
metadata = {
member.lower(): info
for member, info in metadata.items()
}
if interface in browser_compat_data:
_unify_metadata(browser_compat_data[interface],
metadata)
else:
browser_compat_data[interface] = metadata
else:
names[:] = [] # Do not go underneath
# Attempts to unify two compatibility infos by taking the union of both, and # Attempts to unify two compatibility infos by taking the union of both, and
# for conflicting information, taking the "stricter" of the two versions. # for conflicting information, taking the "stricter" of the two versions.
# Updates `a` in place to represent the union of `a` and `b`. # Updates `a` in place to represent the union of `a` and `b`.
@ -182,7 +145,42 @@ def _get_browser_compat_data():
if not attr in a: if not attr in a:
a[attr] = b[attr] a[attr] = b[attr]
os.path.walk(browser_compat_folder, visitor, browser_compat_folder) for (dir_path, dirs, files) in os.walk(browser_compat_folder):
def should_process_dir(dir_path):
if os.path.abspath(dir_path) == browser_compat_folder:
return True
for dir in INCLUDE_DIRS:
if dir_path.startswith(dir):
return True
return False
if should_process_dir(dir_path):
for name in files:
file_name = os.path.join(dir_path, name)
(interface_path, ext) = os.path.splitext(file_name)
if ext == '.json':
with open(file_name) as src:
json_dict = json.load(src)
interface, metadata = process_json_dict(json_dict)
if not interface is None:
# Note: interface and member names do not
# necessarily have the same capitalization as
# WebCore, so we keep them all lowercase for easier
# matching later.
interface = interface.lower()
metadata = {
member.lower(): info
for member, info in metadata.items()
}
if interface in browser_compat_data:
_unify_metadata(browser_compat_data[interface],
metadata)
else:
browser_compat_data[interface] = metadata
else:
dirs[:] = [] # Do not go underneath
return browser_compat_data return browser_compat_data
@ -192,8 +190,8 @@ def _unify_versions(version_a, version_b):
# Given two valid version strings, compares parts of the version string # Given two valid version strings, compares parts of the version string
# iteratively. # iteratively.
def _greater_version(version_a, version_b): def _greater_version(version_a, version_b):
version_a_split = map(int, version_a.split('.')) version_a_split = list(map(int, version_a.split('.')))
version_b_split = map(int, version_b.split('.')) version_b_split = list(map(int, version_b.split('.')))
for i in range(min(len(version_a_split), len(version_b_split))): for i in range(min(len(version_a_split), len(version_b_split))):
if version_a_split[i] > version_b_split[i]: if version_a_split[i] > version_b_split[i]:
return version_a return version_a
@ -208,7 +206,7 @@ def _unify_versions(version_a, version_b):
return False return False
if version is True: if version is True:
return True return True
if isinstance(version, str) or isinstance(version, unicode): if isinstance(version, str):
pattern = re.compile('^([0-9]+\.)*[0-9]+$') pattern = re.compile('^([0-9]+\.)*[0-9]+$')
if not pattern.match(version): if not pattern.match(version):
# It's possible for version strings to look like '<35'. We don't # It's possible for version strings to look like '<35'. We don't

View file

@ -29,7 +29,7 @@ class MultiEmitterTestCase(unittest.TestCase):
files.append((file, ''.join(contents))) files.append((file, ''.join(contents)))
m.Flush(_Collect) m.Flush(_Collect)
self.assertEquals(expected, files) self.assertEqual(expected, files)
def testExample(self): def testExample(self):
m = multiemitter.MultiEmitter() m = multiemitter.MultiEmitter()

View file

@ -184,14 +184,14 @@ class ElementConstructorInfo(object):
info.js_name = None info.js_name = None
info.type_name = interface_name info.type_name = interface_name
# optional parameters are always nullable # optional parameters are always nullable
info.param_infos = map( info.param_infos = [
lambda tXn: ParamInfo( ParamInfo(name=tXn[1],
name=tXn[1], type_id=tXn[0],
type_id=tXn[0], is_optional=True,
is_optional=True, is_nullable=True,
is_nullable=True, default_value=None,
default_value=None, default_value_is_null=False) for tXn in self.opt_params
default_value_is_null=False), self.opt_params) ]
info.requires_named_arguments = True info.requires_named_arguments = True
info.factory_parameters = ['"%s"' % self.tag] info.factory_parameters = ['"%s"' % self.tag]
info.pure_dart_constructor = True info.pure_dart_constructor = True
@ -514,67 +514,69 @@ _js_support_checks_additional_element = [
'SVGSetElement', 'SVGSetElement',
] ]
js_support_checks = dict({ js_support_checks = dict(
'Animation': list({
"JS('bool', '!!(document.body.animate)')", 'Animation':
'AudioContext': "JS('bool', '!!(document.body.animate)')",
"JS('bool', '!!(window.AudioContext ||" 'AudioContext':
" window.webkitAudioContext)')", "JS('bool', '!!(window.AudioContext ||"
'Crypto': " window.webkitAudioContext)')",
"JS('bool', '!!(window.crypto && window.crypto.getRandomValues)')", 'Crypto':
'Database': "JS('bool', '!!(window.crypto && window.crypto.getRandomValues)')",
"JS('bool', '!!(window.openDatabase)')", 'Database':
'DOMPoint': "JS('bool', '!!(window.openDatabase)')",
"JS('bool', '!!(window.DOMPoint) || !!(window.WebKitPoint)')", 'DOMPoint':
'ApplicationCache': "JS('bool', '!!(window.DOMPoint) || !!(window.WebKitPoint)')",
"JS('bool', '!!(window.applicationCache)')", 'ApplicationCache':
'DOMFileSystem': "JS('bool', '!!(window.applicationCache)')",
"JS('bool', '!!(window.webkitRequestFileSystem)')", 'DOMFileSystem':
'FormData': "JS('bool', '!!(window.webkitRequestFileSystem)')",
"JS('bool', '!!(window.FormData)')", 'FormData':
'HashChangeEvent': "JS('bool', '!!(window.FormData)')",
"Device.isEventTypeSupported('HashChangeEvent')", 'HashChangeEvent':
'HTMLShadowElement': "Device.isEventTypeSupported('HashChangeEvent')",
ElemSupportStr('shadow'), 'HTMLShadowElement':
'HTMLTemplateElement': ElemSupportStr('shadow'),
ElemSupportStr('template'), 'HTMLTemplateElement':
'MediaStreamEvent': ElemSupportStr('template'),
"Device.isEventTypeSupported('MediaStreamEvent')", 'MediaStreamEvent':
'MediaStreamTrackEvent': "Device.isEventTypeSupported('MediaStreamEvent')",
"Device.isEventTypeSupported('MediaStreamTrackEvent')", 'MediaStreamTrackEvent':
'MediaSource': "Device.isEventTypeSupported('MediaStreamTrackEvent')",
"JS('bool', '!!(window.MediaSource)')", 'MediaSource':
'Notification': "JS('bool', '!!(window.MediaSource)')",
"JS('bool', '!!(window.Notification)')", 'Notification':
'Performance': "JS('bool', '!!(window.Notification)')",
"JS('bool', '!!(window.performance)')", 'Performance':
'SpeechRecognition': "JS('bool', '!!(window.performance)')",
"JS('bool', '!!(window.SpeechRecognition || " 'SpeechRecognition':
"window.webkitSpeechRecognition)')", "JS('bool', '!!(window.SpeechRecognition || "
'SVGExternalResourcesRequired': "window.webkitSpeechRecognition)')",
('supported(SvgElement element)', 'SVGExternalResourcesRequired':
"JS('bool', '#.externalResourcesRequired !== undefined && " ('supported(SvgElement element)',
"#.externalResourcesRequired.animVal !== undefined', " "JS('bool', '#.externalResourcesRequired !== undefined && "
"element, element)"), "#.externalResourcesRequired.animVal !== undefined', "
'SVGLangSpace': "element, element)"),
('supported(SvgElement element)', 'SVGLangSpace':
"JS('bool', '#.xmlspace !== undefined && #.xmllang !== undefined', " ('supported(SvgElement element)',
"element, element)"), "JS('bool', '#.xmlspace !== undefined && #.xmllang !== undefined', "
'TouchList': "element, element)"),
"JS('bool', '!!document.createTouchList')", 'TouchList':
'WebGLRenderingContext': "JS('bool', '!!document.createTouchList')",
"JS('bool', '!!(window.WebGLRenderingContext)')", 'WebGLRenderingContext':
'WebSocket': "JS('bool', '!!(window.WebGLRenderingContext)')",
"JS('bool', 'typeof window.WebSocket != \"undefined\"')", 'WebSocket':
'Worker': "JS('bool', 'typeof window.WebSocket != \"undefined\"')",
"JS('bool', '(typeof window.Worker != \"undefined\")')", 'Worker':
'XSLTProcessor': "JS('bool', '(typeof window.Worker != \"undefined\")')",
"JS('bool', '!!(window.XSLTProcessor)')", 'XSLTProcessor':
}.items() + dict( "JS('bool', '!!(window.XSLTProcessor)')",
(key, SvgSupportStr(_svg_element_constructors[key]) if key. }.items()) + list(
startswith('SVG') else ElemSupportStr(_html_element_constructors[key])) dict((key,
for key in _js_support_checks_basic_element_with_constructors + SvgSupportStr(_svg_element_constructors[key]) if key.startswith(
_js_support_checks_additional_element).items()) 'SVG') else ElemSupportStr(_html_element_constructors[key]))
for key in _js_support_checks_basic_element_with_constructors +
_js_support_checks_additional_element).items()))
# JavaScript element class names of elements for which createElement does not # JavaScript element class names of elements for which createElement does not
# always return exactly the right element, either because it might not be # always return exactly the right element, either because it might not be
@ -818,6 +820,9 @@ class HtmlDartInterfaceGenerator(object):
NULLABLE='?', NULLABLE='?',
NULLSAFECAST=True, NULLSAFECAST=True,
NULLASSERT='!') NULLASSERT='!')
if self._interface.doc_js_name is 'RadioNodeList':
print(self._backend.ImplementationTemplate())
print(implementation_members_emitter)
stream_getter_signatures_emitter = None stream_getter_signatures_emitter = None
element_stream_getters_emitter = None element_stream_getters_emitter = None
class_members_emitter = None class_members_emitter = None
@ -2198,7 +2203,7 @@ class Dart2JSBackend(HtmlDartGenerator):
return re.search('^@.*Returns', ann) or re.search( return re.search('^@.*Returns', ann) or re.search(
'^@.*Creates', ann) '^@.*Creates', ann)
if not filter(js_type_annotation, anns): if not list(filter(js_type_annotation, anns)):
_logger.warn('Member with wildcard native type: %s.%s' % _logger.warn('Member with wildcard native type: %s.%s' %
(self._interface.id, idl_member_name)) (self._interface.id, idl_member_name))
@ -2320,7 +2325,7 @@ class DartLibrary():
# Emit the $!TYPE_MAP # Emit the $!TYPE_MAP
if map_emitter: if map_emitter:
items = self._typeMap.items() items = list(self._typeMap.items())
items.sort() items.sort()
for (idl_name, dart_name) in items: for (idl_name, dart_name) in items:
map_emitter.Emit( map_emitter.Emit(

View file

@ -30,7 +30,7 @@ ACTUAL :
threw = False threw = False
try: try:
output_text = self._preprocess(input_text, conds) output_text = self._preprocess(input_text, conds)
except Exception, e: except Exception as e:
threw = True threw = True
if str(e).find(expected_message) == -1: if str(e).find(expected_message) == -1:
self.fail("'%s' does not contain '%s'" % (e, expected_message)) self.fail("'%s' does not contain '%s'" % (e, expected_message))