Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(265)

Side by Side Diff: Source/bindings/scripts/interface_dependency_resolver.py

Issue 618373003: [bindings] partial interfaces should not violate componentization (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 # Copyright (C) 2013 Google Inc. All rights reserved. 1 # Copyright (C) 2013 Google Inc. All rights reserved.
2 # 2 #
3 # Redistribution and use in source and binary forms, with or without 3 # Redistribution and use in source and binary forms, with or without
4 # modification, are permitted provided that the following conditions are 4 # modification, are permitted provided that the following conditions are
5 # met: 5 # met:
6 # 6 #
7 # * Redistributions of source code must retain the above copyright 7 # * Redistributions of source code must retain the above copyright
8 # notice, this list of conditions and the following disclaimer. 8 # notice, this list of conditions and the following disclaimer.
9 # * Redistributions in binary form must reproduce the above 9 # * Redistributions in binary form must reproduce the above
10 # copyright notice, this list of conditions and the following disclaimer 10 # copyright notice, this list of conditions and the following disclaimer
(...skipping 19 matching lines...) Expand all
30 30
31 This library computes interface dependencies (partial interfaces and 31 This library computes interface dependencies (partial interfaces and
32 implements), reads the dependency files, and merges them to the IdlDefinitions 32 implements), reads the dependency files, and merges them to the IdlDefinitions
33 for the main IDL file, producing an IdlDefinitions object representing the 33 for the main IDL file, producing an IdlDefinitions object representing the
34 entire interface. 34 entire interface.
35 35
36 Design doc: http://www.chromium.org/developers/design-documents/idl-compiler#TOC -Dependency-resolution 36 Design doc: http://www.chromium.org/developers/design-documents/idl-compiler#TOC -Dependency-resolution
37 """ 37 """
38 38
39 import os.path 39 import os.path
40 from utilities import idl_filename_to_component, is_valid_component_dependency
40 41
41 # The following extended attributes can be applied to a dependency interface, 42 # The following extended attributes can be applied to a dependency interface,
42 # and are then applied to the individual members when merging. 43 # and are then applied to the individual members when merging.
43 # Note that this moves the extended attribute from the interface to the member, 44 # Note that this moves the extended attribute from the interface to the member,
44 # which changes the semantics and yields different code than the same extended 45 # which changes the semantics and yields different code than the same extended
45 # attribute on the main interface. 46 # attribute on the main interface.
46 DEPENDENCY_EXTENDED_ATTRIBUTES = set([ 47 DEPENDENCY_EXTENDED_ATTRIBUTES = set([
47 'Conditional', 48 'Conditional',
48 'PerContextEnabled', 49 'PerContextEnabled',
49 'RuntimeEnabled', 50 'RuntimeEnabled',
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
103 'have a dictionary.' % definitions.idl_name) 104 'have a dictionary.' % definitions.idl_name)
104 105
105 target_interface = next(definitions.interfaces.itervalues()) 106 target_interface = next(definitions.interfaces.itervalues())
106 interface_name = target_interface.name 107 interface_name = target_interface.name
107 interface_info = self.interfaces_info[interface_name] 108 interface_info = self.interfaces_info[interface_name]
108 109
109 if 'inherited_extended_attributes' in interface_info: 110 if 'inherited_extended_attributes' in interface_info:
110 target_interface.extended_attributes.update( 111 target_interface.extended_attributes.update(
111 interface_info['inherited_extended_attributes']) 112 interface_info['inherited_extended_attributes'])
112 113
114 # FIXME: new method for partial interface dependencies full paths?
113 resolved_definitions = merge_interface_dependencies( 115 resolved_definitions = merge_interface_dependencies(
114 definitions, 116 definitions,
115 component, 117 component,
116 target_interface, 118 target_interface,
117 interface_info['dependencies_full_paths'], 119 interface_info['dependencies_full_paths'] +
120 interface_info['partial_interface_dependencies_full_paths'],
118 self.reader) 121 self.reader)
119 122
120 for referenced_interface_name in interface_info['referenced_interfaces'] : 123 for referenced_interface_name in interface_info['referenced_interfaces'] :
121 referenced_definitions = self.reader.read_idl_definitions( 124 referenced_definitions = self.reader.read_idl_definitions(
122 self.interfaces_info[referenced_interface_name]['full_path']) 125 self.interfaces_info[referenced_interface_name]['full_path'])
123 126
124 if component not in referenced_definitions: 127 for referenced_component in referenced_definitions:
haraken 2014/10/16 04:24:08 I'd rename all "referenced" to "dependent", but yo
tasak 2014/10/17 07:38:17 I will do this in a follow-up.
125 raise Exception('This definitions: %s is defined in %s ' 128 if not is_valid_component_dependency(component, referenced_compo nent):
126 'but reference interface:%s is not defined ' 129 raise Exception('This definitions: %s is defined in %s '
127 'in %s' % (definitions.idl_name, 130 'but reference interface:%s is defined '
128 component, 131 'in %s' % (definitions.idl_name,
129 referenced_interface_name, 132 component,
130 component)) 133 referenced_interface_name,
134 referenced_component))
131 135
132 resolved_definitions[component].update(referenced_definitions[compon ent]) 136 resolved_definitions[component].update(referenced_definitions[co mponent])
137
133 return resolved_definitions 138 return resolved_definitions
134 139
135 140
136 def merge_interface_dependencies(definitions, component, target_interface, depen dency_idl_filenames, reader): 141 def merge_interface_dependencies(definitions, component, target_interface, depen dency_idl_filenames, reader):
137 """Merge dependencies ('partial interface' and 'implements') in dependency_i dl_filenames into target_interface. 142 """Merge dependencies ('partial interface' and 'implements') in dependency_i dl_filenames into target_interface.
138 143
139 No return: modifies target_interface in place. 144 Args:
145 definitions: IdlDefinitions object, modified in place
146 component:
147 string, describing where the above definitions are defined,
148 'core' or 'modules'. See KNOWN_COMPONENTS in utilities.py
149 target_interface: IdlInterface object, modified in place
150 dependency_idl_filenames:
151 Idl filenames which depend on the above definitions.
152 reader: IdlReader object.
153 Returns:
154 A dictionary whose key is component and value is IdlDefinitions
155 object whose dependency is resolved.
140 """ 156 """
157 resolved_definitions = {component: definitions}
141 # Sort so order consistent, so can compare output from run to run. 158 # Sort so order consistent, so can compare output from run to run.
142 for dependency_idl_filename in sorted(dependency_idl_filenames): 159 for dependency_idl_filename in sorted(dependency_idl_filenames):
143 dependency_definitions = reader.read_idl_file(dependency_idl_filename) 160 dependency_definitions = reader.read_idl_file(dependency_idl_filename)
144 # FIXME(crbug.com/358074): should not merge core definitions with 161 dependency_component = idl_filename_to_component(dependency_idl_filename )
145 # modules definitions. 162
146 dependency_interface = next(dependency_definitions.interfaces.itervalues ()) 163 dependency_interface = next(dependency_definitions.interfaces.itervalues ())
147 dependency_interface_basename, _ = os.path.splitext(os.path.basename(dep endency_idl_filename)) 164 dependency_interface_basename, _ = os.path.splitext(os.path.basename(dep endency_idl_filename))
148 165
149 transfer_extended_attributes(dependency_interface, 166 transfer_extended_attributes(dependency_interface,
150 dependency_interface_basename) 167 dependency_interface_basename)
151 definitions.update(dependency_definitions) # merges partial interfaces 168
152 if not dependency_interface.is_partial: 169 # We need to use different checkdeps here for partial interface and
170 # inheritance.
171 if dependency_interface.is_partial:
172 # Case: dependency_interface is a partial interface of
173 # target_interface.
174 # So,
175 # - A partial interface defined in modules can update
176 # the original interface defined in core.
177 # However,
178 # - A partial interface defined in core cannot update
179 # the original interface defined in modules.
180 if not is_valid_component_dependency(dependency_component, component ):
181 raise Exception('The partial interface:%s in %s cannot update '
182 'the original interface:%s in %s' % (dependency_ interface.name,
183 dependency_ component,
184 target_inte rface.name,
185 component))
186
187 if dependency_component in resolved_definitions:
188 resolved_definitions[dependency_component].update(dependency_def initions)
189 continue
190
191 dependency_interface.extended_attributes.update(target_interface.ext ended_attributes)
192 assert target_interface == definitions.interfaces[dependency_interfa ce.name]
193 dependency_interface.original_interface = target_interface
194 target_interface.partial_interfaces.append(dependency_interface)
195 resolved_definitions[dependency_component] = dependency_definitions
196 else:
197 # Case: target_interface implements dependency_interface.
198 # So,
199 # - An interface defined in modules can implement some interface
200 # defined in core.
201 # In this case, we need "NoInterfaceObject" extended attribute.
202 # However,
203 # - An interface defined in core cannot implement any interface
204 # defined in modules.
205 if not is_valid_component_dependency(component, dependency_component ):
206 raise Exception('The interface:%s in %s cannot implement '
207 'the interface:%s in %s.' % (dependency_interfac e.name,
208 dependency_componen t,
209 target_interface.na me,
210 component))
211
212 if component != dependency_component:
213 if 'NoInterfaceObject' not in dependency_interface.extended_attr ibutes:
haraken 2014/10/16 04:24:08 You can merge the two if branches.
tasak 2014/10/17 07:38:17 Done.
214 raise Exception('The interface:%s in %s cannot implement '
215 'the interface:%s in %s because of '
216 'missing NoInterfaceObject.' % (dependency_i nterface.name,
217 dependency_c omponent,
218 target_inter face.name,
219 component))
220
221 resolved_definitions[component].update(dependency_definitions) # me rges partial interfaces
153 # Implemented interfaces (non-partial dependencies) are also merged 222 # Implemented interfaces (non-partial dependencies) are also merged
154 # into the target interface, so Code Generator can just iterate 223 # into the target interface, so Code Generator can just iterate
155 # over one list (and not need to handle 'implements' itself). 224 # over one list (and not need to handle 'implements' itself).
156 target_interface.merge(dependency_interface) 225 target_interface.merge(dependency_interface)
157 226
158 # FIXME: Currently, this function just returns one IdlDefinitions 227 return resolved_definitions
159 # instance. However, for partial interface modularization, we need to
160 # make this function return multiple definitions, i.e.
161 # { 'core': ..., 'modules': ... }.
162 return {component: definitions}
163 228
164 229
165 def transfer_extended_attributes(dependency_interface, dependency_interface_base name): 230 def transfer_extended_attributes(dependency_interface, dependency_interface_base name):
166 """Transfer extended attributes from dependency interface onto members. 231 """Transfer extended attributes from dependency interface onto members.
167 232
168 Merging consists of storing certain interface-level data in extended 233 Merging consists of storing certain interface-level data in extended
169 attributes of the *members* (because there is no separate dependency 234 attributes of the *members* (because there is no separate dependency
170 interface post-merging). 235 interface post-merging).
171 236
172 The data storing consists of: 237 The data storing consists of:
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
210 merged_extended_attributes['PartialInterfaceImplementedAs'] = ( 275 merged_extended_attributes['PartialInterfaceImplementedAs'] = (
211 dependency_interface.extended_attributes.get( 276 dependency_interface.extended_attributes.get(
212 'ImplementedAs', dependency_interface_basename)) 277 'ImplementedAs', dependency_interface_basename))
213 278
214 for attribute in dependency_interface.attributes: 279 for attribute in dependency_interface.attributes:
215 attribute.extended_attributes.update(merged_extended_attributes) 280 attribute.extended_attributes.update(merged_extended_attributes)
216 for constant in dependency_interface.constants: 281 for constant in dependency_interface.constants:
217 constant.extended_attributes.update(merged_extended_attributes) 282 constant.extended_attributes.update(merged_extended_attributes)
218 for operation in dependency_interface.operations: 283 for operation in dependency_interface.operations:
219 operation.extended_attributes.update(merged_extended_attributes) 284 operation.extended_attributes.update(merged_extended_attributes)
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698