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

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

Issue 24156003: Revert IDL compiler build flow to Perl, rename 'deprecated' (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Rebase Created 7 years, 3 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
(Empty)
1 # Copyright (C) 2013 Google Inc. All rights reserved.
2 #
3 # Redistribution and use in source and binary forms, with or without
4 # modification, are permitted provided that the following conditions are
5 # met:
6 #
7 # * Redistributions of source code must retain the above copyright
8 # notice, this list of conditions and the following disclaimer.
9 # * Redistributions in binary form must reproduce the above
10 # copyright notice, this list of conditions and the following disclaimer
11 # in the documentation and/or other materials provided with the
12 # distribution.
13 # * Neither the name of Google Inc. nor the names of its
14 # contributors may be used to endorse or promote products derived from
15 # this software without specific prior written permission.
16 #
17 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
29 """Resolve interface dependencies, producing a merged IdlDefinitions object.
30
31 This library computes interface dependencies (partial interfaces and
32 implements), reads the dependency files, and merges them to the IdlDefinitions
33 for the main IDL file, producing an IdlDefinitions object representing the
34 entire interface.
35
36 It also checks whether a file should have bindings generated, or whether
37 instead it is just a dependency.
38 """
39
40 import os.path
41
42
43 class InterfaceNotFoundError(Exception):
44 """Raised if (partial) interface not found in target IDL file."""
45 pass
46
47
48 class InvalidPartialInterfaceError(Exception):
49 """Raised if a file listed as a partial interface is not in fact so."""
50 pass
51
52
53 class InterfaceDependencyResolver:
54 def __init__(self, interface_dependencies_filename, additional_idl_filenames , reader):
55 """Inits dependency resolver.
56
57 Args:
58 interface_dependencies_filename:
59 filename of dependencies file (produced by
60 compute_dependencies.py)
61 additional_idl_filenames:
62 list of additional files, not listed in
63 interface_dependencies_file, for which bindings should
64 nonetheless be generated
65 reader:
66 IdlReader, used for reading dependency files
67 """
68 self.interface_dependencies = read_interface_dependencies_file(interface _dependencies_filename)
69 self.additional_interfaces = set()
70 for filename in additional_idl_filenames:
71 basename = os.path.basename(filename)
72 interface_name, _ = os.path.splitext(basename)
73 self.additional_interfaces.add(interface_name)
74 self.reader = reader
75
76 def resolve_dependencies(self, definitions, interface_name):
77 """Resolves dependencies, merging them into IDL definitions of main file .
78
79 Dependencies consist of 'partial interface' for the same interface as
80 in the main file, and other interfaces that this interface 'implements'.
81
82 Modifies definitions in place by adding parsed dependencies, and checks
83 whether bindings should be generated, returning bool.
84
85 Args:
86 definitions: IdlDefinitions object, modified in place
87 idl_filename: filename of main IDL file for the interface
88 Returns:
89 bool, whether bindings should be generated or not.
90 """
91 dependency_idl_filenames = self.compute_dependency_idl_files(interface_n ame)
92 if dependency_idl_filenames is None:
93 return False
94 # The Blink IDL filenaming convention is that the file
95 # <interface_name>.idl MUST contain the interface "interface_name" or
96 # exception "interface_name", unless it is a dependency (e.g.,
97 # 'partial interface Foo' can be in FooBar.idl).
98 if interface_name in definitions.exceptions:
99 # Exceptions do not have dependencies, so no merging necessary
100 return definitions
101 try:
102 target_interface = definitions.interfaces[interface_name]
103 except KeyError:
104 raise InterfaceNotFoundError('Could not find interface or exception "{0}" in {0}.idl'.format(interface_name))
105 merge_interface_dependencies(target_interface, dependency_idl_filenames, self.reader)
106
107 return definitions
108
109 def compute_dependency_idl_files(self, target_interface_name):
110 """Returns list of IDL file dependencies for a given main IDL file.
111
112 - Returns a list of IDL files on which a given IDL file depends,
113 possibly empty.
114 Dependencies consist of partial interface files and files for other
115 interfaces that the given interface implements.
116 - Returns an empty list also if the given IDL file is an additional IDL
117 file.
118 - Otherwise, return None. This happens when the given IDL file is a
119 dependency, for which we don't want to generate bindings.
120 """
121 if target_interface_name in self.interface_dependencies:
122 return self.interface_dependencies[target_interface_name]
123
124 # additional_interfaces is a list of interfaces that should not be
125 # included in DerivedSources*.cpp, and hence are not listed in the
126 # interface dependencies file, but for which we should generate .cpp
127 # and .h files.
128 if target_interface_name in self.additional_interfaces:
129 return []
130
131 return None
132
133
134 def read_interface_dependencies_file(interface_dependencies_filename):
135 """Reads the interface dependencies file, returns a dict for resolving depen dencies.
136
137 The format of the interface dependencies file is:
138
139 Document.idl P.idl
140 Event.idl
141 Window.idl Q.idl R.idl S.idl
142 ...
143
144 The above indicates that:
145 Document.idl depends on P.idl,
146 Event.idl depends on no other IDL files, and
147 Window.idl depends on Q.idl, R.idl, and S.idl.
148
149 The head entries (first IDL file on a line) are the files that should
150 have bindings generated.
151
152 An IDL file that is a dependency of another IDL file (e.g., P.idl in the
153 above example) does not have its own line in the dependency file:
154 dependencies do not have bindings generated, and do not have their
155 own dependencies.
156
157 Args:
158 interface_dependencies_filename: filename of file in above format
159 Returns:
160 dict of interface_name -> dependency_filenames
161 """
162 interface_dependencies = {}
163 with open(interface_dependencies_filename) as interface_dependencies_file:
164 for line in interface_dependencies_file:
165 idl_filename, _, dependency_filenames_string = line.partition(' ')
166 idl_basename = os.path.basename(idl_filename)
167 interface_name, _ = os.path.splitext(idl_basename)
168 dependency_filenames = dependency_filenames_string.split()
169 interface_dependencies[interface_name] = dependency_filenames
170 return interface_dependencies
171
172
173 def merge_interface_dependencies(target_interface, dependency_idl_filenames, rea der):
174 """Merge dependencies ('partial interface' and 'implements') in dependency_i dl_filenames into target_interface.
175
176 No return: modifies target_document in place.
177 """
178 # Sort so order consistent, so can compare output from run to run.
179 for dependency_idl_filename in sorted(dependency_idl_filenames):
180 dependency_interface_name, _ = os.path.splitext(os.path.basename(depende ncy_idl_filename))
181 definitions = reader.read_idl_file(dependency_idl_filename)
182
183 for dependency_interface in definitions.interfaces.itervalues():
184 # Dependency files contain either partial interfaces for
185 # the (single) target interface, in which case the interface names
186 # must agree, or interfaces that are implemented by the target
187 # interface, in which case the interface names differ.
188 if dependency_interface.is_partial and dependency_interface.name != target_interface.name:
189 raise InvalidPartialInterfaceError('%s is not a partial interfac e of %s. There maybe a bug in the the dependency generator (compute_depedencies. py).' % (dependency_idl_filename, target_interface.name))
190 if 'ImplementedAs' in dependency_interface.extended_attributes:
191 del dependency_interface.extended_attributes['ImplementedAs']
192 merge_dependency_interface(target_interface, dependency_interface, d ependency_interface_name)
193
194
195 def merge_dependency_interface(target_interface, dependency_interface, dependenc y_interface_name):
196 """Merge dependency_interface into target_interface.
197
198 No return: modifies target_interface in place.
199 """
200 def merge_lists(source_list, target_list):
201 for element in source_list:
202 # FIXME: remove check for LegacyImplementedInBaseClass when this
203 # attribute is removed
204 if 'LegacyImplementedInBaseClass' not in dependency_interface.extend ed_attributes:
205 element.extended_attributes['ImplementedBy'] = dependency_interf ace_name
206 element.extended_attributes.update(dependency_interface.extended_att ributes)
207 target_list.append(element)
208
209 merge_lists(dependency_interface.attributes, target_interface.attributes)
210 merge_lists(dependency_interface.constants, target_interface.constants)
211 merge_lists(dependency_interface.operations, target_interface.operations)
OLDNEW
« no previous file with comments | « Source/bindings/scripts/idl_validator.py ('k') | Source/bindings/scripts/unstable/blink_idl_lexer.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698