10from generator
import MultitypeSortKey
11from idl_types
import IdlType, IdlNullableType, IdlUnionType, IdlArrayOrSequenceType
24 for union_id
in sorted(_unions_to_any):
25 warnings.append(
'Union type %s is mapped to \'any\'' % union_id)
35def _addTypedef(typedef):
36 _typeDefsFixup.append(typedef)
40 """ Given a type if it's a known typedef (only typedef's that aren't union)
41 are remembered for fixup. typedefs that are union type are mapped to
42 any so those we don
't need to alias. typedefs referenced in the file
43 where the typedef was defined are automatically aliased to the real type.
44 This resolves typedef where the declaration is in another IDL file.
46 for typedef
in _typeDefsFixup:
47 if typedef.id == type.id:
53_operation_suffix_map = {
54 '__getter__':
"Getter",
55 '__setter__':
"Setter",
56 '__delete__':
"Deleter",
60 """Base class for all IDL elements.
61 IDLNode may contain various child nodes, and have properties. Examples
62 of IDLNode are interfaces, interface members, function arguments,
67 """Initializes an IDLNode from a PegParser AST output."""
75 """Generates string of the form <class id extra extra ... 0x12345678>."""
77 if isinstance(extras, list):
78 extras =
' '.
join([str(e)
for e
in extras])
81 return '<%s %s 0x%x>' % (
type(self).__name__,
82 (
'%s %s' % (self.
id, extras)).strip(),
84 return '<%s %s 0x%x>' % (
type(self).__name__, extras,
hash(self))
85 except Exception
as e:
86 return "can't convert to string: %s" % e
88 def _extra_repr(self):
89 """Returns string of extra info for __repr__()."""
93 """Override default equals operation.
94 IDLNodes are equal if all their properties are equal.
"""
95 if other
is None or not isinstance(other, IDLNode):
97 return self.__dict__.
__eq__(other.__dict__)
100 """Define default hashing behavior.
101 In order to comply with a == b =>
hash(a) ==
hash(b), we recursively iterate
102 self.__dict__
and convert all objects to hashable objects.
"""
106 """Reset the id of the Node. This is typically done during a normalization
107 phase (e.g.,
"DOMWindow" ->
"Window").
"""
110 def all(self, type_filter=None):
111 """Returns a list containing this node and all it child nodes
115 type_filter -- can be used to limit the results to a specific
116 node type (e.g. IDLOperation).
119 if type_filter
is None or isinstance(self, type_filter):
122 if isinstance(v, IDLNode):
123 res.extend(v.all(type_filter))
124 elif isinstance(v, list):
126 if isinstance(item, IDLNode):
127 res.extend(item.all(type_filter))
130 def _all_subnodes(self):
131 """Accessor used by all() to find subnodes."""
132 return self.__dict__.
values()
135 """Converts the IDLNode and its children into a dictionary.
136 This method is useful mostly
for debugging
and pretty printing.
139 for (k, v)
in self.__dict__.items():
140 if v ==
None or v ==
False or v == []
or v == {}:
143 elif isinstance(v, IDLDictNode)
and not len(v):
146 elif isinstance(v, list):
150 if isinstance(sub_node, IDLNode):
152 new_v.append(sub_node.to_dict())
154 new_v.append(sub_node)
156 elif isinstance(v, IDLNode):
165 def _to_hashable(self, obj):
169 if isinstance(obj, list):
174 return tuple(new_obj)
175 elif isinstance(obj, dict):
179 for (k2, v2)
in sorted(obj.items(), key=MultitypeSortKey):
181 return frozenset(new_obj)
182 elif hasattr(obj,
'__dict__'):
185 for (k, v)
in sorted(obj.__dict__.items(), key=MultitypeSortKey):
191 def _find_all(self, ast, label, max_results=sys.maxsize):
192 """Searches the AST for tuples with a given label. The PegParser
193 output is composed of lists
and tuples, where the tuple 1st argument
194 is a label. If ast root
is a list, will search recursively inside each
198 ast -- the AST to search.
199 label -- the label to look
for.
200 res -- results are put into this list.
201 max_results -- maximum number of results.
207 if isinstance(ast, list):
210 not(isinstance(childAst, dict))
and \
211 not(isinstance(childAst, str))
and \
212 not(isinstance(childAst, tuple))
and \
213 childAst.__module__ ==
"idl_definitions":
215 if hasattr(childAst, field_name):
216 field_value = getattr(childAst, field_name)
218 if field_name ==
'idl_type':
219 field_value = getattr(field_value,
'base_type')
220 res.append(field_value)
222 sub_res = self.
_find_all(childAst, label,
223 max_results -
len(res))
225 elif isinstance(ast, tuple):
226 (nodeLabel, value) = ast
227 if nodeLabel == label:
231 elif (ast
and not (isinstance(ast, dict))
and
232 not (isinstance(ast, str))
and
233 (ast.__module__ ==
"idl_definitions" or
234 ast.__module__ ==
"idl_types")):
236 if hasattr(ast, field_name):
237 field_value = getattr(ast, field_name)
239 if label ==
'Interface' or label ==
'Enum' or label ==
"Dictionary":
240 for key
in field_value:
241 value = field_value[key]
243 elif isinstance(field_value, list):
244 for item
in field_value:
246 elif label ==
'ParentInterface' or label ==
'InterfaceType':
248 parent_idlnode = new_asts[field_value]
249 res.append(parent_idlnode.interfaces[field_value])
251 res.append(field_value)
255 def _find_first(self, ast, label):
256 """Convenience method for _find_all(..., max_results=1).
257 Returns a single element instead of a list, or None if nothing
259 res = self._find_all(ast, label, max_results=1)
264 def _has(self, ast, label):
265 """Returns true if an element with the given label is
266 in the AST by searching
for it.
"""
267 return len(self.
_find_all(ast, label, max_results=1)) == 1
270 def _convert_label_to_field(self, label):
273 'ParentInterface':
'parent',
275 'Interface':
'interfaces',
276 'Callback_Function':
'callback_functions',
277 'Callback':
'is_callback',
278 'Partial':
'is_partial',
279 'Operation':
'operations',
280 'Attribute':
'attributes',
281 'Const':
'constants',
283 'ExtAttrs':
'extended_attributes',
284 'Special':
'specials',
285 'ReturnType':
'idl_type',
286 'Argument':
'arguments',
287 'InterfaceType':
'name',
288 'ConstExpr':
'value',
289 'Static':
'is_static',
290 'ReadOnly':
'is_read_only',
291 'Optional':
'is_optional',
292 'Nullable':
'is_nullable',
293 'Enum':
'enumerations',
297 'Dictionary':
'dictionaries',
299 'Default':
'default_value',
301 result = label_field.get(label)
302 if result !=
'' and not (result):
303 print(
'FATAL ERROR: AST mapping name not found %s.' % label)
304 return result
if result
else ''
306 def _convert_all(self, ast, label, idlnode_ctor):
307 """Converts AST elements into IDLNode elements.
308 Uses _find_all to find elements with a given label
and converts
309 them into IDLNodes
with a given constructor.
311 A list of the converted nodes.
313 ast -- the ast element to start a search at.
314 label -- the element label to look
for.
315 idlnode_ctor -- a constructor function of one of the IDLNode
322 if not isinstance(found, list):
323 raise RuntimeError(
"Expected list but %s found" %
type(found))
324 for childAst
in found:
325 converted = idlnode_ctor(childAst)
326 res.append(converted)
329 def _convert_first(self, ast, label, idlnode_ctor):
330 """Like _convert_all, but only converts the first found results."""
334 return idlnode_ctor(childAst)
336 def _convert_ext_attrs(self, ast):
337 """Helper method for uniform conversion of extended attributes."""
340 def _convert_annotations(self, ast):
341 """Helper method for uniform conversion of annotations."""
344 def _convert_constants(self, ast, js_name):
345 """Helper method for uniform conversion of dictionary members."""
350 """Base class for dictionary-like IDL nodes such as extended attributes
351 and annotations. The base
class implements various dict interfaces.
"""
354 IDLNode.__init__(self,
None)
355 if ast
is not None and isinstance(ast, dict):
364 return self.
__map[key]
367 self.
__map[key] = value
373 return key
in self.
__map
378 def get(self, key, default=None):
397 """Overrides the default IDLNode.to_dict behavior.
398 The IDLDictNode members are copied into a new dictionary, and
399 IDLNode members are recursively converted into dicts
as well.
403 if isinstance(v, IDLNode):
408 def _all_subnodes(self):
414 """IDLFile is the top-level node in each IDL file. It may contain interfaces."""
416 DART_IDL =
'dart.idl'
419 IDLNode.__init__(self, ast)
422 filename_basename = os.path.basename(filename)
430 for typedefName
in ast.typedefs:
431 typedef_type = ast.typedefs[typedefName]
433 if not (isinstance(typedef_type.idl_type, IdlUnionType))
and not (
434 typedef_type.idl_type.base_type ==
'Dictionary'):
440 if len(ast.callback_functions) > 0:
441 callback_functions = self.
_convert_all(ast,
'Callback_Function',
443 for callback_function
in callback_functions:
444 for annotation
in callback_function.annotations:
445 callback = callback_function.annotations[annotation]
447 cb_interface.ext_attrs[
'Callback'] =
len(callback.arguments)
449 op.type =
IDLType(callback.idl_type)
452 if len(callback.arguments) > 0:
454 callback,
'Argument', IDLArgument)
456 cb_interface.operations = [op]
459 is_blink =
not (isinstance(
460 ast, list))
and ast.__module__ ==
'idl_definitions'
466 blink_interface = ast.interfaces.get(interface.id)
467 if filename_basename == self.
DART_IDL:
476 implement_pairs = interface_info[
'implement_pairs']
477 for implement_pair
in implement_pairs:
478 interface_name = implement_pair[0]
479 implemented_name = implement_pair[1]
481 implementor = new_asts[interface_name].interfaces.get(
484 implementor, implemented_name)
492 if 'implements_interfaces' in interface_info:
493 implements = interface_info[
'implements_interfaces']
494 if not (blink_interface.is_partial)
and len(implements) > 0:
495 implementor = new_asts[interface.id].interfaces.get(
501 for implemented_name
in implements:
503 implementor, implemented_name)
510 ast,
'ImplStmt', IDLImplementsStatement)
513 for typedefName
in ast.typedefs:
514 typedef_type = ast.typedefs[typedefName]
515 if isinstance(typedef_type.idl_type, IdlUnionType):
517 elif typedef_type.idl_type.base_type ==
'Dictionary':
523 def _createImplementsStatement(self, implementor, implemented_name):
524 implemented = new_asts[implemented_name].interfaces.get(
529 implement_statement.implementor =
IDLType(implementor)
530 implement_statement.implemented =
IDLType(implemented)
532 return implement_statement
536 """IDLModule has an id, and may contain interfaces, type defs and
537 implements statements."""
540 IDLNode.__init__(self, ast)
545 is_blink = ast.__module__ ==
'idl_definitions'
549 ast,
'TypeDef', IDLTypeDef)
560 'implements_interfaces']
563 ast,
'ImplStmt', IDLImplementsStatement)
567 """IDLExtAttrs is an IDLDictNode that stores IDL Extended Attributes.
568 Modules, interfaces, members and arguments can all own IDLExtAttrs.
"""
571 IDLDictNode.__init__(self,
None)
574 if not (isinstance(ast, list))
and ast.__module__ ==
"idl_definitions":
576 for name, value
in ast.extended_attributes.items():
578 if name ==
'NamedConstructor' or name ==
'Constructor':
579 for constructor
in ast.constructors:
580 if constructor.name ==
'NamedConstructor':
581 constructor_name = ast.extended_attributes[
584 constructor_name =
None
586 constructor_name, constructor.arguments,
True)
587 if name ==
'Constructor':
591 self[name] = func_value
592 elif name ==
'SetWrapperReferenceTo':
604 if not ext_attrs_ast:
606 for ext_attr
in self.
_find_all(ext_attrs_ast,
'ExtAttr'):
610 if name ==
'Constructor':
616 ctor_args = self.
_find_first(ext_attr,
'ExtAttrArgList')
622 func_value = self.
_find_first(value,
'ExtAttrFunctionValue')
632 def _all_subnodes(self):
639 """IDLExtAttrFunctionValue."""
641 def __init__(self, func_value_ast, arg_list_ast, is_blink=False):
642 IDLNode.__init__(self, func_value_ast)
647 for argument
in arg_list_ast:
655 """IDLType is used to describe constants, attributes and operations'
656 return and input types. IDLType matches AST labels such
as ScopedName,
657 StringType, VoidType, IntegerType, etc.
658 NOTE: AST of
None implies synthesize IDLType the id
is passed
in used by
662 global _unions_to_any
664 IDLNode.__init__(self, ast, id)
672 if isinstance(ast, list):
677 for label, childAst
in ast:
678 if label.endswith(
'Type'):
680 if type !=
'sequence':
685 return 'sequence<%s>' % findType(type_ast)
686 raise Exception(
'No type declaration found in %s' % ast)
688 self.
idid = findType(ast)
691 array_modifiers = self.
_find_first(ast,
'ArrayModifiers')
693 self.
idid += array_modifiers
694 elif isinstance(ast, tuple):
696 if label ==
'ScopedName':
700 elif isinstance(ast, str):
703 elif ast.__module__ ==
"idl_types":
704 if isinstance(ast, IdlType)
or isinstance(ast, IdlArrayOrSequenceType)
or \
705 isinstance(ast, IdlNullableType):
707 IdlNullableType)
and ast.inner_type.is_union_type:
709 if not (self.
idid in _unions_to_any):
710 _unions_to_any.append(self.
idid)
718 type_name = type_name.replace(
'unrestricted ',
'', 1)
721 type_name = type_name.replace(
'USVString',
'DOMString', 1)
722 type_name = type_name.replace(
'HTMLString',
'DOMString', 1)
726 type_name = type_name.replace(
'Function',
'any', 1)
728 self.
idid = type_name
731 if ast.is_union_type:
732 if not (self.
idid in _unions_to_any):
733 _unions_to_any.append(self.
idid)
747 print(
'>>>> __module__ %s' % ast.__module__)
748 raise SyntaxError(
'Could not parse type %s' % (ast))
750 def _label_to_type(self, label, ast):
751 if label ==
'LongLongType':
753 elif label.endswith(
'Type'):
755 label =
'%s%s' % (label[0].
lower(), label[1:-4])
758 if self.
_has(ast,
'Unsigned'):
759 label =
'unsigned %s' % label
764 """IDLNode for 'enum [id] { [string]+ }'"""
767 IDLNode.__init__(self, ast)
769 if not (isinstance(ast, list))
and ast.__module__ ==
"idl_definitions":
779 """IDLNode for 'callback [type] [id]' declarations."""
782 IDLNode.__init__(self, ast)
788 """IDLNode for 'typedef [type] [id]' declarations."""
791 IDLNode.__init__(self, ast)
797 """IDLDictionary node contains members,
798 as well
as parent references.
"""
801 IDLNode.__init__(self, ast)
804 if (typedefDictionary):
813 """IDLDictionaryMembers specialization for a list of FremontCut dictionary values."""
816 IDLDictNode.__init__(self, ast)
820 for member
in self.
_find_all(ast,
'Member'):
830 syn_op.arguments = arguments
839 result_nullable=False):
840 """ Synthesize an IDLOperation with no AST used for support of setlike."""
841 """ Arguments is a list of argument where each argument is:
842 [IDLType, argument_name, optional_boolean] """
846 syn_op.type =
IDLType(
None, result_type_name)
848 syn_op.type.nullable = result_nullable
850 for argument
in arguments:
852 arg.type = argument[0]
853 arg.optional = argument[2]
if len(argument) > 2
else False
854 syn_op.arguments.append(arg)
861 Need to create (in our database) a number of operations. This
is a new IDL
862 syntax, the implied operations
for a set now use setlike<T> where T
is a known
863 type e.g., setlike<FontFace> setlike implies these operations are generated:
865 void forEach(any callback, optional any thisArg);
866 boolean has(FontFace fontFace);
867 boolean has(FontFace fontFace);
869 if setlike
is not read-only these operations are generated:
871 FontFaceSet add(FontFace value);
872 boolean
delete(FontFace value);
877 Need to create a typedef for a function callback e.g.,
878 a setlike will need a callback that has the proper args
in FontFaceSet that
is
879 three arguments, etc.
881 typedef void FontFaceSetForEachCallback(
882 FontFace fontFace, FontFace fontFaceAgain, FontFaceSet set);
884 void forEach(FontFaceSetForEachCallback callback, [Object thisArg]);
886 callback_name = '%sForEachCallback' % interface.id
888 [[
IDLType(
None, callback_name),
'callback'],
889 [
IDLType(
None,
'any'),
'thisArg',
True]])
890 setlike_ops.append(set_op)
893 interface.id,
'boolean',
'has',
894 [[
IDLType(
None, set_like.value_type.base_type),
'arg']])
895 setlike_ops.append(set_op)
897 if not set_like.is_read_only:
900 add_result_nullable =
True
902 interface.id, interface.id,
'add',
903 [[
IDLType(
None, set_like.value_type.base_type),
'arg']],
905 setlike_ops.append(set_op)
907 interface.id,
'boolean',
'delete',
908 [[
IDLType(
None, set_like.value_type.base_type),
'arg']])
909 setlike_ops.append(set_op)
911 setlike_ops.append(set_op)
917 """IDLInterface node contains operations, attributes, constants,
918 as well
as parent references.
"""
921 IDLNode.__init__(self, ast)
936 if not (self.
_find_first(ast,
'Callback')
is None):
940 self.
ext_attrs[
'DartSupplemental'] =
None
944 if ast
is not None and ast.maplike
is not None:
949 IDLType(ast.maplike.value_type)
955 if not (id)
and ast.setlike:
958 for op
in setlike_ops:
972 """Reset the id of the Interface and corresponding the JS names."""
973 if self.
idid != new_id:
978 member.doc_js_interface_name = new_id
980 member.doc_js_interface_name = new_id
982 member.doc_js_interface_name = new_id
986 if (attribute.id == candidate.id
and
987 attribute.is_read_only == candidate.is_read_only):
993 """This IDLNode specialization is for 'Interface Child : Parent {}'
997 IDLNode.__init__(self, ast)
1003 """A base class for constants, attributes and operations."""
1005 def __init__(self, ast, doc_js_interface_name, member_id=None):
1007 IDLNode.__init__(self, ast)
1011 IDLNode.__init__(self, ast, member_id)
1029 """IDLNode specialization for 'type name(args)' declarations."""
1031 def __init__(self, ast, doc_js_interface_name, id=None):
1032 IDLMember.__init__(self, ast, doc_js_interface_name, id)
1052 if self.
idid is None:
1061 self.
idid =
'__getter__'
1063 self.
idid =
'__setter__'
1067 self.
idid =
'__delete__'
1069 raise Exception(
'Cannot handle %s: operation has no id' % ast)
1072 self.
idid in _operation_suffix_map
1075 operation_category =
'Named' if arg.type.id ==
'DOMString' else 'Indexed'
1077 'ImplementedAs',
'anonymous%s%s' %
1078 (operation_category, _operation_suffix_map[self.
idid]))
1081 return '<IDLOperation(id = %s)>' % (self.
idid)
1083 def _extra_repr(self):
1087 if self.
typetype != operation.type:
1089 return [a.type
for a
in self.
arguments] == [
1090 a.type
for a
in operation.arguments
1094 """IDLNode specialization for 'attribute type name' declarations."""
1097 IDLMember.__init__(self, ast, doc_js_interface_name)
1101 def _extra_repr(self):
1108 """IDLNode specialization for 'const type name = value' declarations."""
1111 IDLMember.__init__(self, ast, doc_js_interface_name)
1116 """IDLNode specialization for operation arguments."""
1120 IDLNode.__init__(self, ast)
1123 IDLNode.__init__(self, ast, id)
1133 if not isinstance(ast, list):
1134 if isinstance(ast.default_value,
1135 idl_definitions.IdlLiteral)
and ast.default_value:
1138 elif 'Default' in ast.extended_attributes:
1150 if 'Callback' in self.
type.id:
1154 return '<IDLArgument(type = %s, id = %s)>' % (self.
type, self.
id)
1158 """IDLNode specialization for 'const type name = value' declarations."""
1161 IDLMember.__init__(self, ast, doc_js_interface_name)
1163 self.
value = default_value.value
if default_value
else None
1167 """IDLNode specialization for 'IMPLEMENTOR implements IMPLEMENTED' declarations."""
1170 IDLNode.__init__(self, ast)
1171 if isinstance(ast, list)
or ast.__module__ !=
'idl_definitions':
1179 """IDLDictNode specialization for a list of FremontCut annotations."""
1182 IDLDictNode.__init__(self, ast)
1186 for annotation
in self.
_find_all(ast,
'Annotation'):
1193 """IDLDictNode specialization for one annotation."""
1196 IDLDictNode.__init__(self, ast)
1200 for arg
in self.
_find_all(ast,
'AnnotationArg'):
1202 value = self.
_find_first(arg,
'AnnotationArgValue')
static uint32_t hash(const SkShaderBase::GradientInfo &v)
def __init__(self, ast=None)
def __init__(self, ast=None)
def __init__(self, ast, id=None)
def __init__(self, ast, doc_js_interface_name)
def __init__(self, ast, doc_js_interface_name)
def __contains__(self, key)
def __getitem__(self, key)
def __setitem__(self, key, value)
def get(self, key, default=None)
def setdefault(self, key, value=None)
def __delitem__(self, key)
def __init__(self, ast, doc_js_interface_name)
def __init__(self, ast=None, js_name=None)
def __init__(self, ast, typedefDictionary=False)
def __init__(self, func_value_ast, arg_list_ast, is_blink=False)
def __init__(self, ast=None)
def _createImplementsStatement(self, implementor, implemented_name)
def __init__(self, ast, filename=None)
def reset_id(self, new_id)
def __init__(self, ast, id=None)
def has_attribute(self, candidate)
def __init__(self, ast, doc_js_interface_name, member_id=None)
def reset_id(self, newId)
def __init__(self, ast, id=None)
def _convert_ext_attrs(self, ast)
def _convert_first(self, ast, label, idlnode_ctor)
def _find_all(self, ast, label, max_results=sys.maxsize)
def _convert_constants(self, ast, js_name)
def _convert_annotations(self, ast)
def _has(self, ast, label)
def _find_first(self, ast, label)
def _convert_all(self, ast, label, idlnode_ctor)
def _convert_label_to_field(self, label)
def all(self, type_filter=None)
def _to_hashable(self, obj)
def SameSignatureAs(self, operation)
def __init__(self, ast, doc_js_interface_name, id=None)
def _label_to_type(self, label, ast)
def __init__(self, ast, id=None)
static void append(char **dst, size_t *count, const char *src, size_t n)
def get_interfaces_info()
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir Path to the cache directory This is different from the persistent_cache_path in embedder which is used for Skia shader cache icu native lib Path to the library file that exports the ICU data vm service The hostname IP address on which the Dart VM Service should be served If not set
const myers::Point & get(const myers::Segment &)
def print(*args, **kwargs)
def generate_operation(interface_name, result_type_name, oper_name, arguments, result_nullable=False)
def generate_callback(interface_name, result_type, arguments)
def report_unions_to_any()
def generate_setLike_operations_properties(interface, set_like)
static SkString join(const CommandLineFlags::StringArray &)