Commit 606b1f11 authored by nbarth@chromium.org's avatar nbarth@chromium.org

Fix "implements in RHS file"

Recent CL broke run-bindings-tests on my machine:
Move modules-dependent IDL statements out of core by supporting 'implements' in RHS interface
https://codereview.chromium.org/270573005/

This is due to depending on order of files;
this is fixed by doing the moving/merging in a separate, global phase
(which we're already doing).

Also:
* Adds a test case.
* Fixes unaddressed nits.

R=haraken
BUG=358074

Review URL: https://codereview.chromium.org/270823002

git-svn-id: svn://svn.chromium.org/blink/trunk@173613 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent a7a88dd2
......@@ -173,11 +173,16 @@ def compute_individual_info(idl_filename):
# If not a partial interface, the basename is the interface name
interface_name, _ = os.path.splitext(os.path.basename(idl_filename))
# 'implements' statements can be included in either the file for the
# implement*ing* interface (lhs of 'implements') or implement*ed* interface
# (rhs of 'implements'). Store both for now, then merge to implement*ing*
# interface later.
left_interfaces, right_interfaces = get_implements_from_idl(idl_file_contents, interface_name)
interfaces_info[interface_name] = {
'full_path': full_path,
'implemented_as': implemented_as,
'implemented_by_interfaces': left_interfaces, # private, merged to next
'implements_interfaces': right_interfaces,
'include_path': this_include_path,
# FIXME: temporary private field, while removing old treatement of
......@@ -193,10 +198,6 @@ def compute_individual_info(idl_filename):
'referenced_interfaces': get_put_forward_interfaces_from_idl(idl_file_contents),
}
for left_interface_name in left_interfaces:
interface_info = interfaces_info[left_interface_name]
interface_info['implements_interfaces'].append(interface_name)
# Record inheritance information
inherited_extended_attributes_by_interface[interface_name] = dict(
(key, value)
......@@ -246,6 +247,15 @@ def compute_interfaces_info(idl_files):
compute_inheritance_info(interface_name)
# Compute dependencies
# Move implements info from implement*ed* interface (rhs of 'implements')
# to implement*ing* interface (lhs of 'implements').
# Note that moving an 'implements' statement between implementing and
# implemented files does not change the info (or hence cause a rebuild)!
for right_interface_name, interface_info in interfaces_info.iteritems():
for left_interface_name in interface_info['implemented_by_interfaces']:
interfaces_info[left_interface_name]['implements_interfaces'].append(right_interface_name)
del interface_info['implemented_by_interfaces']
# An IDL file's dependencies are partial interface files that extend it,
# and files for other interfaces that this interfaces implements.
for interface_name, interface_info in interfaces_info.iteritems():
......
......@@ -59,27 +59,38 @@ def get_partial_interface_name_from_idl(file_contents):
def get_implements_from_idl(file_contents, interface_name):
# Rule is: identifier-A implements identifier-B;
# http://www.w3.org/TR/WebIDL/#idl-implements-statements
# Returns two lists of interfaces that contain identifier-As and identifier-Bs.
# The 'implements' statements are supported in both identifier-A IDL and identifier-B IDL
# to avoid potential layering violation.
"""Returns lists of implementing and implemented interfaces.
Rule is: identifier-A implements identifier-B;
i.e., implement*ing* implements implement*ed*;
http://www.w3.org/TR/WebIDL/#idl-implements-statements
Returns two lists of interfaces: identifier-As and identifier-Bs.
An 'implements' statements can be present in the IDL file for either the
implementing or the implemented interface, but not other files.
"""
implements_re = (r'^\s*'
r'(\w+)\s+'
r'implements\s+'
r'(\w+)\s*'
r';')
implements_matches = re.finditer(implements_re, file_contents, re.MULTILINE)
implements_pairs = [(match.group(1), match.group(2))
for match in implements_matches]
A_interfaces = []
B_interfaces = []
for left, right in implements_pairs:
if left == interface_name:
B_interfaces.append(right)
elif right == interface_name:
A_interfaces.append(left)
return (A_interfaces, B_interfaces)
implements_pairs = [match.groups() for match in implements_matches]
foreign_implements = [pair for pair in implements_pairs
if interface_name not in pair]
if foreign_implements:
left, right = foreign_implements.pop()
raise IdlBadFilenameError(
'implements statement found in unrelated IDL file.\n'
'Statement is:\n'
' %s implements %s;\n'
'but filename is unrelated "%s.idl"' %
(left, right, interface_name))
return (
[left for left, right in implements_pairs if right == interface_name],
[right for left, right in implements_pairs if left == interface_name])
def is_callback_interface_from_idl(file_contents):
......
......@@ -37,3 +37,5 @@
attribute DOMString implements2StringAttribute;
void implements2VoidMethod();
};
TestInterface implements TestImplements2;
......@@ -72,5 +72,5 @@
};
TestInterface implements TestImplements;
TestInterface implements TestImplements2;
// TestInterface implements TestImplements2; // at implement*ed* interface
TestInterface implements TestImplements3;
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