Commit ee0ee3d4 authored by Hitoshi Yoshida's avatar Hitoshi Yoshida Committed by Commit Bot

IDL compiler: Disable to put [Unforgeable] on interfaces or static members

In WebIDL spec, [Unforgeable] can appear on interface attributes
and interface non-static operations.
https://heycam.github.io/webidl/#Unforgeable

Now our IDL compiler does not check its use cases.
This CL makes IDL compiler to check if [Unforgeable] appears on
interfaces or static members, and stops with a warning message
if it does.


Bug: 674593
Change-Id: I6f17834eae71b3c7aa44556c3442f679091efd59
Reviewed-on: https://chromium-review.googlesource.com/1198711Reviewed-by: default avatarKenichi Ishibashi <bashi@chromium.org>
Reviewed-by: default avatarYuki Shiino <yukishiino@chromium.org>
Reviewed-by: default avatarKentaro Hara <haraken@chromium.org>
Commit-Queue: Hitoshi Yoshida <peria@chromium.org>
Cr-Commit-Position: refs/heads/master@{#587973}
parent bc09ae58
...@@ -508,12 +508,11 @@ Standard: [Unforgeable](http://heycam.github.io/webidl/#Unforgeable) ...@@ -508,12 +508,11 @@ Standard: [Unforgeable](http://heycam.github.io/webidl/#Unforgeable)
Summary: Makes interface members unconfigurable and also controls where the member is defined. Summary: Makes interface members unconfigurable and also controls where the member is defined.
Usage: Can be specified on methods, attributes or interfaces: Usage: Can be specified on interface methods or non-static interface attributes:
```webidl ```webidl
[Unforgeable] void func(); [Unforgeable] void func();
[Unforgeable] attribute DOMString str; [Unforgeable] attribute DOMString str;
[Unforgeable] interface XXX { ... };
``` ```
By default, interface members are configurable (i.e. you can modify a property descriptor corresponding to the member and also you can delete the property). `[Unforgeable]` makes the member unconfiguable so that you cannot modify or delete the property corresponding to the member. By default, interface members are configurable (i.e. you can modify a property descriptor corresponding to the member and also you can delete the property). `[Unforgeable]` makes the member unconfiguable so that you cannot modify or delete the property corresponding to the member.
......
...@@ -137,8 +137,6 @@ def get_put_forward_interfaces_from_definition(definition): ...@@ -137,8 +137,6 @@ def get_put_forward_interfaces_from_definition(definition):
def get_unforgeable_attributes_from_definition(definition): def get_unforgeable_attributes_from_definition(definition):
if 'Unforgeable' in definition.extended_attributes:
return sorted(definition.attributes)
return sorted(attribute for attribute in definition.attributes return sorted(attribute for attribute in definition.attributes
if 'Unforgeable' in attribute.extended_attributes) if 'Unforgeable' in attribute.extended_attributes)
......
...@@ -383,6 +383,9 @@ class IdlInterface(object): ...@@ -383,6 +383,9 @@ class IdlInterface(object):
raise ValueError('Value iterators (iterable<V>) must be accompanied by an indexed ' raise ValueError('Value iterators (iterable<V>) must be accompanied by an indexed '
'property getter and an integer-typed length attribute.') 'property getter and an integer-typed length attribute.')
if 'Unforgeable' in self.extended_attributes:
raise ValueError('[Unforgeable] cannot appear on interfaces.')
def accept(self, visitor): def accept(self, visitor):
visitor.visit_interface(self) visitor.visit_interface(self)
for attribute in self.attributes: for attribute in self.attributes:
...@@ -450,6 +453,9 @@ class IdlAttribute(TypedObject): ...@@ -450,6 +453,9 @@ class IdlAttribute(TypedObject):
else: else:
raise ValueError('Unrecognized node class: %s' % child_class) raise ValueError('Unrecognized node class: %s' % child_class)
if 'Unforgeable' in self.extended_attributes and self.is_static:
raise ValueError('[Unforgeable] cannot appear on static attributes.')
def accept(self, visitor): def accept(self, visitor):
visitor.visit_attribute(self) visitor.visit_attribute(self)
...@@ -575,6 +581,9 @@ class IdlOperation(TypedObject): ...@@ -575,6 +581,9 @@ class IdlOperation(TypedObject):
else: else:
raise ValueError('Unrecognized node class: %s' % child_class) raise ValueError('Unrecognized node class: %s' % child_class)
if 'Unforgeable' in self.extended_attributes and self.is_static:
raise ValueError('[Unforgeable] cannot appear on static operations.')
@classmethod @classmethod
def constructor_from_arguments_node(cls, name, arguments_node): def constructor_from_arguments_node(cls, name, arguments_node):
constructor = cls() constructor = cls()
......
...@@ -185,7 +185,7 @@ def attribute_context(interface, attribute, interfaces): ...@@ -185,7 +185,7 @@ def attribute_context(interface, attribute, interfaces):
'is_save_same_object': is_save_same_object, 'is_save_same_object': is_save_same_object,
'is_static': attribute.is_static, 'is_static': attribute.is_static,
'is_url': 'URL' in extended_attributes, 'is_url': 'URL' in extended_attributes,
'is_unforgeable': is_unforgeable(interface, attribute), 'is_unforgeable': is_unforgeable(attribute),
'on_instance': v8_utilities.on_instance(interface, attribute), 'on_instance': v8_utilities.on_instance(interface, attribute),
'on_interface': v8_utilities.on_interface(interface, attribute), 'on_interface': v8_utilities.on_interface(interface, attribute),
'on_prototype': v8_utilities.on_prototype(interface, attribute), 'on_prototype': v8_utilities.on_prototype(interface, attribute),
...@@ -579,7 +579,7 @@ def property_attributes(interface, attribute): ...@@ -579,7 +579,7 @@ def property_attributes(interface, attribute):
if ('NotEnumerable' in extended_attributes or if ('NotEnumerable' in extended_attributes or
is_constructor_attribute(attribute)): is_constructor_attribute(attribute)):
property_attributes_list.append('v8::DontEnum') property_attributes_list.append('v8::DontEnum')
if is_unforgeable(interface, attribute): if is_unforgeable(attribute):
property_attributes_list.append('v8::DontDelete') property_attributes_list.append('v8::DontDelete')
if not is_writable(attribute): if not is_writable(attribute):
property_attributes_list.append('v8::ReadOnly') property_attributes_list.append('v8::ReadOnly')
......
...@@ -220,7 +220,7 @@ def method_context(interface, method, is_visible=True): ...@@ -220,7 +220,7 @@ def method_context(interface, method, is_visible=True):
'is_per_world_bindings': 'PerWorldBindings' in extended_attributes, 'is_per_world_bindings': 'PerWorldBindings' in extended_attributes,
'is_raises_exception': is_raises_exception, 'is_raises_exception': is_raises_exception,
'is_static': is_static, 'is_static': is_static,
'is_unforgeable': is_unforgeable(interface, method), 'is_unforgeable': is_unforgeable(method),
'is_variadic': arguments and arguments[-1].is_variadic, 'is_variadic': arguments and arguments[-1].is_variadic,
'measure_as': v8_utilities.measure_as(method, interface), # [MeasureAs] 'measure_as': v8_utilities.measure_as(method, interface), # [MeasureAs]
'name': name, 'name': name,
...@@ -450,7 +450,7 @@ def property_attributes(interface, method): ...@@ -450,7 +450,7 @@ def property_attributes(interface, method):
property_attributes_list = [] property_attributes_list = []
if 'NotEnumerable' in extended_attributes: if 'NotEnumerable' in extended_attributes:
property_attributes_list.append('v8::DontEnum') property_attributes_list.append('v8::DontEnum')
if is_unforgeable(interface, method): if is_unforgeable(method):
property_attributes_list.append('v8::ReadOnly') property_attributes_list.append('v8::ReadOnly')
property_attributes_list.append('v8::DontDelete') property_attributes_list.append('v8::DontDelete')
return property_attributes_list return property_attributes_list
......
...@@ -449,10 +449,8 @@ def runtime_enabled_feature_name(definition_or_member): ...@@ -449,10 +449,8 @@ def runtime_enabled_feature_name(definition_or_member):
# [Unforgeable] # [Unforgeable]
def is_unforgeable(interface, member): def is_unforgeable(member):
return (('Unforgeable' in interface.extended_attributes or return 'Unforgeable' in member.extended_attributes
'Unforgeable' in member.extended_attributes) and
not member.is_static)
# [LegacyInterfaceTypeChecking] # [LegacyInterfaceTypeChecking]
...@@ -485,8 +483,7 @@ def on_instance(interface, member): ...@@ -485,8 +483,7 @@ def on_instance(interface, member):
if ('PrimaryGlobal' in interface.extended_attributes or if ('PrimaryGlobal' in interface.extended_attributes or
'Global' in interface.extended_attributes or 'Global' in interface.extended_attributes or
'Unforgeable' in member.extended_attributes or 'Unforgeable' in member.extended_attributes):
'Unforgeable' in interface.extended_attributes):
return True return True
return False return False
...@@ -517,8 +514,7 @@ def on_prototype(interface, member): ...@@ -517,8 +514,7 @@ def on_prototype(interface, member):
if ('PrimaryGlobal' in interface.extended_attributes or if ('PrimaryGlobal' in interface.extended_attributes or
'Global' in interface.extended_attributes or 'Global' in interface.extended_attributes or
'Unforgeable' in member.extended_attributes or 'Unforgeable' in member.extended_attributes):
'Unforgeable' in interface.extended_attributes):
return False return False
return True return True
......
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