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

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: Fixed patch conflict 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
« no previous file with comments | « Source/bindings/scripts/idl_definitions.py ('k') | Source/bindings/scripts/scripts.gni » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
113 resolved_definitions = merge_interface_dependencies( 114 resolved_definitions = merge_interface_dependencies(
114 definitions, 115 definitions,
115 component, 116 component,
116 target_interface, 117 target_interface,
117 interface_info['dependencies_full_paths'], 118 interface_info['dependencies_full_paths'] +
119 interface_info['dependencies_other_component_full_paths'],
118 self.reader) 120 self.reader)
119 121
120 for referenced_interface_name in interface_info['referenced_interfaces'] : 122 for referenced_interface_name in interface_info['referenced_interfaces'] :
121 referenced_definitions = self.reader.read_idl_definitions( 123 referenced_definitions = self.reader.read_idl_definitions(
122 self.interfaces_info[referenced_interface_name]['full_path']) 124 self.interfaces_info[referenced_interface_name]['full_path'])
123 125
124 if component not in referenced_definitions: 126 for referenced_component in referenced_definitions:
125 raise Exception('This definitions: %s is defined in %s ' 127 if not is_valid_component_dependency(component, referenced_compo nent):
126 'but reference interface:%s is not defined ' 128 raise Exception('This definitions: %s is defined in %s '
127 'in %s' % (definitions.idl_name, 129 'but reference interface:%s is defined '
128 component, 130 'in %s' % (definitions.idl_name,
129 referenced_interface_name, 131 component,
130 component)) 132 referenced_interface_name,
133 referenced_component))
131 134
132 resolved_definitions[component].update(referenced_definitions[compon ent]) 135 resolved_definitions[component].update(referenced_definitions[co mponent])
136
133 return resolved_definitions 137 return resolved_definitions
134 138
135 139
136 def merge_interface_dependencies(definitions, component, target_interface, depen dency_idl_filenames, reader): 140 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. 141 """Merge dependencies ('partial interface' and 'implements') in dependency_i dl_filenames into target_interface.
138 142
139 No return: modifies target_interface in place. 143 Args:
144 definitions: IdlDefinitions object, modified in place
145 component:
146 string, describing where the above definitions are defined,
147 'core' or 'modules'. See KNOWN_COMPONENTS in utilities.py
148 target_interface: IdlInterface object, modified in place
149 dependency_idl_filenames:
150 Idl filenames which depend on the above definitions.
151 reader: IdlReader object.
152 Returns:
153 A dictionary whose key is component and value is IdlDefinitions
154 object whose dependency is resolved.
140 """ 155 """
156 resolved_definitions = {component: definitions}
141 # Sort so order consistent, so can compare output from run to run. 157 # Sort so order consistent, so can compare output from run to run.
142 for dependency_idl_filename in sorted(dependency_idl_filenames): 158 for dependency_idl_filename in sorted(dependency_idl_filenames):
143 dependency_definitions = reader.read_idl_file(dependency_idl_filename) 159 dependency_definitions = reader.read_idl_file(dependency_idl_filename)
144 # FIXME(crbug.com/358074): should not merge core definitions with 160 dependency_component = idl_filename_to_component(dependency_idl_filename )
145 # modules definitions. 161
146 dependency_interface = next(dependency_definitions.interfaces.itervalues ()) 162 dependency_interface = next(dependency_definitions.interfaces.itervalues ())
147 dependency_interface_basename, _ = os.path.splitext(os.path.basename(dep endency_idl_filename)) 163 dependency_interface_basename, _ = os.path.splitext(os.path.basename(dep endency_idl_filename))
148 164
149 transfer_extended_attributes(dependency_interface, 165 transfer_extended_attributes(dependency_interface,
150 dependency_interface_basename) 166 dependency_interface_basename)
151 definitions.update(dependency_definitions) # merges partial interfaces 167
152 if not dependency_interface.is_partial: 168 # We need to use different checkdeps here for partial interface and
169 # inheritance.
170 if dependency_interface.is_partial:
171 # Case: dependency_interface is a partial interface of
172 # target_interface.
173 # So,
174 # - A partial interface defined in modules can update
175 # the original interface defined in core.
176 # However,
177 # - A partial interface defined in core cannot update
178 # the original interface defined in modules.
179 if not is_valid_component_dependency(dependency_component, component ):
180 raise Exception('The partial interface:%s in %s cannot update '
181 'the original interface:%s in %s' % (dependency_ interface.name,
182 dependency_ component,
183 target_inte rface.name,
184 component))
185
186 if dependency_component in resolved_definitions:
187 resolved_definitions[dependency_component].update(dependency_def initions)
188 continue
189
190 dependency_interface.extended_attributes.update(target_interface.ext ended_attributes)
191 assert target_interface == definitions.interfaces[dependency_interfa ce.name]
192 dependency_interface.original_interface = target_interface
193 target_interface.partial_interfaces.append(dependency_interface)
194 resolved_definitions[dependency_component] = dependency_definitions
195 else:
196 # Case: target_interface implements dependency_interface.
197 # So,
198 # - An interface defined in modules can implement some interface
199 # defined in core.
200 # In this case, we need "NoInterfaceObject" extended attribute.
201 # However,
202 # - An interface defined in core cannot implement any interface
203 # defined in modules.
204 if not is_valid_component_dependency(component, dependency_component ):
205 raise Exception('The interface:%s in %s cannot implement '
206 'the interface:%s in %s.' % (dependency_interfac e.name,
207 dependency_componen t,
208 target_interface.na me,
209 component))
210
211 if component != dependency_component and 'NoInterfaceObject' not in dependency_interface.extended_attributes:
212 raise Exception('The interface:%s in %s cannot implement '
213 'the interface:%s in %s because of '
214 'missing NoInterfaceObject.' % (dependency_inter face.name,
215 dependency_compo nent,
216 target_interface .name,
217 component))
218
219 resolved_definitions[component].update(dependency_definitions) # me rges partial interfaces
153 # Implemented interfaces (non-partial dependencies) are also merged 220 # Implemented interfaces (non-partial dependencies) are also merged
154 # into the target interface, so Code Generator can just iterate 221 # into the target interface, so Code Generator can just iterate
155 # over one list (and not need to handle 'implements' itself). 222 # over one list (and not need to handle 'implements' itself).
156 target_interface.merge(dependency_interface) 223 target_interface.merge(dependency_interface)
157 224
158 # FIXME: Currently, this function just returns one IdlDefinitions 225 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 226
164 227
165 def transfer_extended_attributes(dependency_interface, dependency_interface_base name): 228 def transfer_extended_attributes(dependency_interface, dependency_interface_base name):
166 """Transfer extended attributes from dependency interface onto members. 229 """Transfer extended attributes from dependency interface onto members.
167 230
168 Merging consists of storing certain interface-level data in extended 231 Merging consists of storing certain interface-level data in extended
169 attributes of the *members* (because there is no separate dependency 232 attributes of the *members* (because there is no separate dependency
170 interface post-merging). 233 interface post-merging).
171 234
172 The data storing consists of: 235 The data storing consists of:
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
210 merged_extended_attributes['PartialInterfaceImplementedAs'] = ( 273 merged_extended_attributes['PartialInterfaceImplementedAs'] = (
211 dependency_interface.extended_attributes.get( 274 dependency_interface.extended_attributes.get(
212 'ImplementedAs', dependency_interface_basename)) 275 'ImplementedAs', dependency_interface_basename))
213 276
214 for attribute in dependency_interface.attributes: 277 for attribute in dependency_interface.attributes:
215 attribute.extended_attributes.update(merged_extended_attributes) 278 attribute.extended_attributes.update(merged_extended_attributes)
216 for constant in dependency_interface.constants: 279 for constant in dependency_interface.constants:
217 constant.extended_attributes.update(merged_extended_attributes) 280 constant.extended_attributes.update(merged_extended_attributes)
218 for operation in dependency_interface.operations: 281 for operation in dependency_interface.operations:
219 operation.extended_attributes.update(merged_extended_attributes) 282 operation.extended_attributes.update(merged_extended_attributes)
OLDNEW
« no previous file with comments | « Source/bindings/scripts/idl_definitions.py ('k') | Source/bindings/scripts/scripts.gni » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698