Commit 5f595574 authored by Yuki Shiino's avatar Yuki Shiino Committed by Commit Bot

IDL compiler: Refactor ExtendedAttributes

As a preparation to introduce identity operator to
ExtendedAttributes, refactors ExtendedAttributes
giving it immutability.

Bug: 839389
Change-Id: Ia985e9fc09ec0647ea819fe373a2482bd5473dfb
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1724434
Commit-Queue: Yuki Shiino <yukishiino@chromium.org>
Reviewed-by: default avatarHitoshi Yoshida <peria@chromium.org>
Cr-Commit-Position: refs/heads/master@{#682592}
parent 1bc6e59d
...@@ -5,58 +5,61 @@ ...@@ -5,58 +5,61 @@
# This file defines some classes to implement extended attributes # This file defines some classes to implement extended attributes
# https://heycam.github.io/webidl/#idl-extended-attributes # https://heycam.github.io/webidl/#idl-extended-attributes
from itertools import groupby import itertools
class ExtendedAttribute(object): class ExtendedAttribute(object):
"""ExtendedAttribute represents an exnteded attribute that
is described in either of following formats as spec defines.
a. [Key]
b. [Key=Value]
c. [Key=(Value1,Value2,...)]
d. [Key(ValueL1 ValueR1, ValueL2 ValueR2,...)]
e. [Key=Name(ValueL1 ValueR1, ValueL2 ValueR2,...)]
""" """
_FORM_NO_ARGS = 'NoArgs' # for (a) Represents a single extended attribute.
_FORM_IDENT = 'Ident' # for (b) https://heycam.github.io/webidl/#dfn-extended-attribute
_FORM_IDENT_LIST = 'IdentList' # for (c) """
_FORM_ARG_LIST = 'ArgList' # for (d)
_FORM_NAMED_ARG_LIST = 'NamedArgList' # for (e) # [Key]
_FORM_NO_ARGS = 'NoArgs'
# [Key=Value]
_FORM_IDENT = 'Ident'
# [Key=(Value1, Value2, ...)]
_FORM_IDENT_LIST = 'IdentList'
# [Key(Value1L Value1R, Value2L Value2R, ...)]
_FORM_ARG_LIST = 'ArgList'
# [Key=Name(Value1L Value1R, Value2L Value2R, ...)]
_FORM_NAMED_ARG_LIST = 'NamedArgList'
def __init__(self, key, values=None, arguments=None, name=None): def __init__(self, key, values=None, arguments=None, name=None):
assert isinstance(key, str) assert isinstance(key, str)
# |values| can be either of None, a single string, or a list. assert values is None or isinstance(values, str) or (isinstance(
assert values is None or isinstance(values, (str, tuple, list)) values,
# |arguments| can be either of None or a list of pairs of strings. (list, tuple)) and all(isinstance(value, str) for value in values))
assert arguments is None or isinstance(arguments, (tuple, list)) assert arguments is None or (isinstance(
arguments, (list, tuple)) and all(
isinstance(left, str) and isinstance(right, str)
for left, right in arguments))
assert name is None or isinstance(name, str)
self._format = None self._format = None
self._key = key self._key = key
self._values = values self._values = None
self._arguments = arguments self._arguments = None
self._name = name self._name = name
if name is not None: if name is not None:
self._format = self._FORM_NAMED_ARG_LIST self._format = self._FORM_NAMED_ARG_LIST
if values is not None or arguments is None: if values is not None or arguments is None:
raise ValueError('Unknown format for ExtendedAttribute') raise ValueError('Unknown format for ExtendedAttribute')
self._arguments = tuple(arguments)
elif arguments is not None: elif arguments is not None:
assert all(
isinstance(arg, (tuple, list)) and len(arg) == 2
and isinstance(arg[0], str) and isinstance(arg[1], str)
for arg in arguments)
self._format = self._FORM_ARG_LIST self._format = self._FORM_ARG_LIST
if values is not None: if values is not None:
raise ValueError('Unknown format for ExtendedAttribute') raise ValueError('Unknown format for ExtendedAttribute')
self._arguments = tuple(arguments)
elif values is None: elif values is None:
self._format = self._FORM_NO_ARGS self._format = self._FORM_NO_ARGS
elif isinstance(values, (tuple, list)):
self._format = self._FORM_IDENT_LIST
self._values = tuple(values)
elif isinstance(values, str): elif isinstance(values, str):
self._format = self._FORM_IDENT self._format = self._FORM_IDENT
self._values = values
else: else:
raise ValueError('Unknown format for ExtendedAttribute') self._format = self._FORM_IDENT_LIST
self._values = tuple(values)
def make_copy(self): def make_copy(self):
return ExtendedAttribute( return ExtendedAttribute(
...@@ -83,30 +86,24 @@ class ExtendedAttribute(object): ...@@ -83,30 +86,24 @@ class ExtendedAttribute(object):
@property @property
def key(self): def key(self):
"""
Returns the key.
@return str
"""
return self._key return self._key
@property @property
def value(self): def value(self):
""" """
Returns the value for the format Ident. Returns None for the format Returns the value for format Ident. Returns None for format NoArgs.
NoArgs. Raises an error otherwise. Raises an error otherwise.
@return str
""" """
if self._format in (self._FORM_NO_ARGS, self._FORM_IDENT): if self._format in (self._FORM_NO_ARGS, self._FORM_IDENT):
return self._values return self._values
raise ValueError('"{}" does not have a single value.'.format( raise ValueError('[{}] does not have a single value.'.format(
str(self))) self.syntactic_form))
@property @property
def values(self): def values(self):
""" """
Returns a list of values for formats Ident and IdentList. Returns an Returns a list of values for format Ident and IdentList. Returns an
empty list for the format NorArgs. Raises an error otherwise. empty list for format NorArgs. Raises an error otherwise.
@return tuple(str)
""" """
if self._format == self._FORM_NO_ARGS: if self._format == self._FORM_NO_ARGS:
return () return ()
...@@ -114,28 +111,29 @@ class ExtendedAttribute(object): ...@@ -114,28 +111,29 @@ class ExtendedAttribute(object):
return (self._values, ) return (self._values, )
if self._format == self._FORM_IDENT_LIST: if self._format == self._FORM_IDENT_LIST:
return self._values return self._values
raise ValueError('"{}" does not have values.'.format(str(self))) raise ValueError('[{}] does not have a value.'.format(
self.syntactic_form))
@property @property
def arguments(self): def arguments(self):
""" """
Returns a tuple of value pairs for formats ArgList and NamedArgList. Returns a list of value pairs for format ArgList and NamedArgList.
Raises an error otherwise. Raises an error otherwise.
@return tuple(Argument)
""" """
if self._format in (self._FORM_ARG_LIST, self._FORM_NAMED_ARG_LIST): if self._format in (self._FORM_ARG_LIST, self._FORM_NAMED_ARG_LIST):
return self._arguments return self._arguments
raise ValueError('"{}" does not have arguments.'.format(str(self))) raise ValueError('[{}] does not have an argument.'.format(
self.syntactic_form))
@property @property
def name(self): def name(self):
""" """
Returns |Name| for the format NamedArgList. Raises an error otherwise. Returns |Name| for format NamedArgList. Raises an error otherwise.
@return str
""" """
if self._format == self._FORM_NAMED_ARG_LIST: if self._format == self._FORM_NAMED_ARG_LIST:
return self._name return self._name
raise ValueError('"{}" does not have a name.'.format(str(self))) raise ValueError('[{}] does not have a name.'.format(
self.syntactic_form))
class ExtendedAttributes(object): class ExtendedAttributes(object):
...@@ -145,7 +143,7 @@ class ExtendedAttributes(object): ...@@ -145,7 +143,7 @@ class ExtendedAttributes(object):
For an IDL fragment For an IDL fragment
[A, A=(foo, bar), B=baz] [A, A=(foo, bar), B=baz]
the generated ExtendedAttributes instance will be like an ExtendedAttributes instance will be like
{ {
'A': (ExtendedAttribute('A'), ExtendedAttribute('A', values=('foo', 'bar'))), 'A': (ExtendedAttribute('A'), ExtendedAttribute('A', values=('foo', 'bar'))),
'B': (ExtendedAttribute('B', value='baz')), 'B': (ExtendedAttribute('B', value='baz')),
...@@ -159,26 +157,21 @@ class ExtendedAttributes(object): ...@@ -159,26 +157,21 @@ class ExtendedAttributes(object):
for attr in attributes)) for attr in attributes))
attributes = sorted(attributes or [], key=lambda x: x.key) attributes = sorted(attributes or [], key=lambda x: x.key)
self._attributes = { self._attributes = {
k: tuple(v) key: tuple(attrs)
for k, v in groupby(attributes, key=lambda x: x.key) for key, attrs in itertools.groupby(
attributes, key=lambda x: x.key)
} }
def __bool__(self): def __bool__(self):
return bool(self._attributes) return bool(self._attributes)
def __contains__(self, key): def __contains__(self, key):
""" """Returns True if this has an extended attribute with the |key|."""
Returns True if this has an extended attribute with the |key|.
@param str key
@return bool
"""
return key in self._attributes return key in self._attributes
def __iter__(self): def __iter__(self):
""" """Yields all ExtendedAttribute instances."""
Yields all ExtendedAttribute instances. for attrs in self._attributes.itervalues():
"""
for attrs in self._attributes.values():
for attr in attrs: for attr in attrs:
yield attr yield attr
...@@ -198,11 +191,8 @@ class ExtendedAttributes(object): ...@@ -198,11 +191,8 @@ class ExtendedAttributes(object):
def get(self, key): def get(self, key):
""" """
Returns an exnteded attribute whose key is |key|. Returns an exnteded attribute whose key is |key|, or None if not found.
If |self| has no such elements, returns None, If there are multiple extended attributes with |key|, raises an error.
and if |self| has multiple elements, raises an error.
@param str key
@return ExtendedAttriute?
""" """
values = self.get_list_of(key) values = self.get_list_of(key)
if len(values) == 0: if len(values) == 0:
...@@ -215,13 +205,6 @@ class ExtendedAttributes(object): ...@@ -215,13 +205,6 @@ class ExtendedAttributes(object):
def get_list_of(self, key): def get_list_of(self, key):
""" """
Returns a list of extended attributes whose keys are |identifier|. Returns a list of extended attributes whose keys are |key|.
@param str key
@return tuple(ExtendedAttribute)
""" """
return self._attributes.get(key, ()) return self._attributes.get(key, ())
def append(self, extended_attribute):
assert isinstance(extended_attribute, ExtendedAttribute)
key = extended_attribute.key
self._attributes[key] = self.get_list_of(key) + (extended_attribute, )
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment