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

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

Issue 15801003: IDL parser rewrite in Python (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Final (rebased). Created 7 years, 5 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 17 matching lines...) Expand all
28 28
29 """Resolve interface dependencies, producing a merged IdlDefinitions object. 29 """Resolve interface dependencies, producing a merged IdlDefinitions object.
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 It also checks whether a file should have bindings generated, or whether 36 It also checks whether a file should have bindings generated, or whether
37 instead it is just a dependency. 37 instead it is just a dependency.
38
39 FIXME: Currently a stub, as part of landing the parser incrementally.
40 Just computes dependencies, and should always return None, indicating
41 bindings should not be generated.
42 Does not read IDL files or merge IdlDefinitions yet.
43 """ 38 """
44 39
45 import os.path 40 import os.path
46 41
42 import idl_reader
47 43
48 def merge_interface_dependencies(idl_definitions, idl_filename, interface_depend encies_filename, additional_idl_filenames):
49 """Merges dependencies into an existing IDL document.
50 44
51 Modifies idl_definitions in place by adding parsed dependencies, and checks 45 class InterfaceNotFoundError(Exception):
46 """Raised if (partial) interface not found in target IDL file."""
47 pass
48
49
50 class InvalidPartialInterfaceError(Exception):
51 """Raised if a file listed as a partial interface is not in fact so."""
52 pass
53
54
55 def resolve_dependencies(definitions, idl_filename, interface_dependencies_filen ame, additional_idl_filenames, verbose=False):
56 """Resolves dependencies, merging them into IDL definitions of main file.
57
58 Dependencies consist of 'partial interface' for the same interface as in the
59 main file, and other interfaces that this interface 'implements'.
60
61 Modifies definitions in place by adding parsed dependencies, and checks
52 whether bindings should be generated, returning bool. 62 whether bindings should be generated, returning bool.
53 63
54 FIXME: stub: parser not implemented yet
55
56 Arguments: 64 Arguments:
57 idl_definitions: IdlDefinitions object, modified in place 65 definitions: IdlDefinitions object, modified in place
58 idl_filename: filename of main IDL file for the interface 66 idl_filename: filename of main IDL file for the interface
59 interface_dependencies_file: filename of dependencies file (produced by compute_dependencies.py) 67 interface_dependencies_file: filename of dependencies file (produced by compute_dependencies.py)
60 additional_idl_files: list of additional files, not listed in interface_ dependencies_file, for which bindings should nonetheless be generated 68 additional_idl_files: list of additional files, not listed in interface_ dependencies_file, for which bindings should nonetheless be generated
61 Returns: 69 Returns:
62 bool, whether bindings should be generated or not. 70 bool, whether bindings should be generated or not.
63 """ 71 """
64 basename = os.path.basename(idl_filename) 72 basename = os.path.basename(idl_filename)
65 interface_name, _ = os.path.splitext(basename) 73 interface_name, _ = os.path.splitext(basename)
66 74
67 dependency_idl_filenames = compute_dependency_idl_files(basename, interface_ dependencies_filename, additional_idl_filenames) 75 dependency_idl_filenames = compute_dependency_idl_files(basename, interface_ dependencies_filename, additional_idl_filenames)
68 if dependency_idl_filenames is None: 76 if dependency_idl_filenames is None:
69 return False 77 return False
70 # FIXME: currently dependency_idl_files *must* be None (indicating that 78 # The Blink IDL filenaming convention is that the file <interface_name>.idl
71 # dummy .cpp and .h files should be generated), as actual parser not 79 # MUST contain the interface "interface_name" or exception "interface_name".
72 # present yet. 80 if interface_name in definitions.exceptions:
73 raise RuntimeError('Stub: parser not implemented yet') 81 # Exceptions do not have dependencies, so no merging necessary
82 return definitions
83 try:
84 target_interface = definitions.interfaces[interface_name]
85 except KeyError:
86 raise InterfaceNotFoundError('Could not find interface or exception "%s" in %s' % (interface_name, basename))
87 merge_interface_dependencies(target_interface, idl_filename, dependency_idl_ filenames, verbose=verbose)
88
89 return definitions
74 90
75 91
76 def compute_dependency_idl_files(target_idl_basename, interface_dependencies_fil ename, additional_idl_filenames): 92 def compute_dependency_idl_files(target_idl_basename, interface_dependencies_fil ename, additional_idl_filenames):
77 """Returns list of IDL file dependencies for a given main IDL file. 93 """Returns list of IDL file dependencies for a given main IDL file.
78 94
79 - Returns a list of IDL files on which a given IDL file depends, 95 - Returns a list of IDL files on which a given IDL file depends,
80 possibly empty. 96 possibly empty.
81 Dependencies consist of partial interface files and files for other 97 Dependencies consist of partial interface files and files for other
82 interfaces that the given interface implements. 98 interfaces that the given interface implements.
83 - Returns an empty list also if the given IDL file is an additional IDL 99 - Returns an empty list also if the given IDL file is an additional IDL
84 file. 100 file.
85 - Otherwise, return None. This happens when the given IDL file is a 101 - Otherwise, return None. This happens when the given IDL file is a
86 dependency, for which we don't want to generate bindings. 102 dependency, for which we don't want to generate bindings.
87 """ 103 """
88 if interface_dependencies_filename is None:
89 return []
90
91 # The format of the interface dependencies file is: 104 # The format of the interface dependencies file is:
92 # 105 #
93 # Document.idl P.idl 106 # Document.idl P.idl
94 # Event.idl 107 # Event.idl
95 # Window.idl Q.idl R.idl S.idl 108 # Window.idl Q.idl R.idl S.idl
96 # ... 109 # ...
97 # 110 #
98 # The above indicates that: 111 # The above indicates that:
99 # Document.idl depends on P.idl, 112 # Document.idl depends on P.idl,
100 # Event.idl depends on no other IDL files, and 113 # Event.idl depends on no other IDL files, and
(...skipping 13 matching lines...) Expand all
114 return dependency_filenames.split() 127 return dependency_filenames.split()
115 128
116 # additional_idl_files is a list of IDL files which should not be included 129 # additional_idl_files is a list of IDL files which should not be included
117 # in DerivedSources*.cpp, and hence are not listed in the interface 130 # in DerivedSources*.cpp, and hence are not listed in the interface
118 # dependencies file, but for which we should generate .cpp and .h files. 131 # dependencies file, but for which we should generate .cpp and .h files.
119 additional_idl_basenames = set(map(os.path.basename, additional_idl_filename s)) 132 additional_idl_basenames = set(map(os.path.basename, additional_idl_filename s))
120 if target_idl_basename in additional_idl_basenames: 133 if target_idl_basename in additional_idl_basenames:
121 return [] 134 return []
122 135
123 return None 136 return None
137
138
139 def merge_interface_dependencies(target_interface, idl_filename, dependency_idl_ filenames, verbose=False):
140 """Merge dependencies ('partial interface' and 'implements') in dependency_i dl_filenames into target_interface.
141
142 No return: modifies target_document in place.
143 """
144 # Sort so order consistent, so can compare output from run to run.
145 for dependency_idl_filename in sorted(dependency_idl_filenames):
146 dependency_interface_name, _ = os.path.splitext(os.path.basename(depende ncy_idl_filename))
147 definitions = idl_reader.read_idl_file(dependency_idl_filename, verbose= verbose)
148
149 for dependency_interface in definitions.interfaces.itervalues():
150 # Dependency files contain either partial interfaces for
151 # the (single) target interface, in which case the interface names
152 # must agree, or interfaces that are implemented by the target
153 # interface, in which case the interface names differ.
154 if dependency_interface.is_partial and dependency_interface.name != target_interface.name:
155 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, idl_filename))
156 if 'ImplementedAs' in dependency_interface.extended_attributes:
157 del dependency_interface.extended_attributes['ImplementedAs']
158 merge_dependency_interface(target_interface, dependency_interface, d ependency_interface_name)
159
160
161 def merge_dependency_interface(target_interface, dependency_interface, dependenc y_interface_name):
162 """Merge dependency_interface into target_interface.
163
164 No return: modifies target_interface in place.
165 """
166 def merge_lists(source_list, target_list):
167 for element in source_list:
168 if dependency_interface.is_partial:
169 element.extended_attributes['ImplementedBy'] = dependency_interf ace_name
170 element.extended_attributes.update(dependency_interface.extended_att ributes)
171 target_list.append(element)
172
173 merge_lists(dependency_interface.attributes, target_interface.attributes)
174 merge_lists(dependency_interface.constants, target_interface.constants)
175 merge_lists(dependency_interface.operations, target_interface.operations)
OLDNEW
« Source/bindings/derived_sources.gyp ('K') | « Source/bindings/scripts/idl_validator.py ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698