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

Side by Side Diff: lib/dom/scripts/systembase.py

Issue 10913125: Remove lib/dom directory! (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 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 #!/usr/bin/python
2 # Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
3 # for details. All rights reserved. Use of this source code is governed by a
4 # BSD-style license that can be found in the LICENSE file.
5
6 """This module provides base functionality for systems to generate
7 Dart APIs from the IDL database."""
8
9 import os
10 from generator import *
11
12 def MassagePath(path):
13 # The most robust way to emit path separators is to use / always.
14 return path.replace('\\', '/')
15
16 class System(object):
17 """A System generates all the files for one implementation.
18
19 This is a base class for all the specific systems.
20 The life-cycle of a System is:
21 - construction (__init__)
22 - (InterfaceGenerator | ProcessCallback)* # for each IDL interface
23 - GenerateLibraries
24 - Finish
25 """
26
27 def __init__(self, options):
28 self._templates = options.templates
29 self._database = options.database
30 self._emitters = options.emitters
31 self._type_registry = options.type_registry
32 self._renamer = options.renamer
33 self._output_dir = options.output_dir
34
35 def ProcessInterface(self, interface):
36 """Processes an interface that is not a callback function."""
37 pass
38
39 def ProcessCallback(self, interface, info):
40 """Processes an interface that is a callback function."""
41 pass
42
43 def GenerateLibraries(self, lib_dir):
44 pass
45
46 def Finish(self):
47 pass
48
49
50 # Helper methods used by several systems.
51
52 def _ProcessCallback(self, interface, info, file_path):
53 """Generates a typedef for the callback interface."""
54 self._dart_interface_file_paths.append(file_path)
55 code = self._emitters.FileEmitter(file_path)
56
57 code.Emit(self._templates.Load('callback.darttemplate'))
58 code.Emit('typedef $TYPE $NAME($PARAMS);\n',
59 NAME=interface.id,
60 TYPE=DartType(info.type_name),
61 PARAMS=info.ParametersImplementationDeclaration(DartType))
62
63
64 def _GenerateLibFile(self, lib_template, lib_file_path, file_paths,
65 **template_args):
66 """Generates a lib file from a template and a list of files.
67
68 Additional keyword arguments are passed to the template.
69 Typically called from self.GenerateLibraries.
70 """
71 # Load template.
72 template = self._templates.Load(lib_template)
73 # Generate the .lib file.
74 lib_file_contents = self._emitters.FileEmitter(lib_file_path)
75
76 # Emit the list of #source directives.
77 list_emitter = lib_file_contents.Emit(template, **template_args)
78 lib_file_dir = os.path.dirname(lib_file_path)
79 for path in sorted(file_paths):
80 relpath = os.path.relpath(path, lib_file_dir)
81 list_emitter.Emit("#source('$PATH');\n", PATH=MassagePath(relpath))
82
83
84 def _BaseDefines(self, interface):
85 """Returns a set of names (strings) for members defined in a base class.
86 """
87 def WalkParentChain(interface):
88 if interface.parents:
89 # Only consider primary parent, secondary parents are not on the
90 # implementation class inheritance chain.
91 parent = interface.parents[0]
92 if IsDartCollectionType(parent.type.id):
93 return
94 if self._database.HasInterface(parent.type.id):
95 parent_interface = self._database.GetInterface(parent.type.id)
96 for attr in parent_interface.attributes:
97 result.add(attr.id)
98 for op in parent_interface.operations:
99 result.add(op.id)
100 WalkParentChain(parent_interface)
101
102 result = set()
103 WalkParentChain(interface)
104 return result
105
106 class BaseGenerator(object):
107 def __init__(self, database, interface):
108 self._database = database
109 self._interface = interface
110
111 def Generate(self):
112 self.StartInterface()
113 self.AddMembers(self._interface)
114 self.AddSecondaryMembers(self._interface)
115 self.FinishInterface()
116
117 def AddMembers(self, interface):
118 for const in sorted(interface.constants, ConstantOutputOrder):
119 self.AddConstant(const)
120
121 for attr in interface.attributes:
122 if attr.type.id != 'EventListener':
123 self.AddAttribute(attr)
124
125 # The implementation should define an indexer if the interface directly
126 # extends List.
127 (element_type, requires_indexer) = ListImplementationInfo(
128 interface, self._database)
129 if element_type:
130 if requires_indexer:
131 self.AddIndexer(element_type)
132 else:
133 self.AmendIndexer(element_type)
134 # Group overloaded operations by id
135 operationsById = {}
136 for operation in interface.operations:
137 if operation.id not in operationsById:
138 operationsById[operation.id] = []
139 operationsById[operation.id].append(operation)
140
141 # Generate operations
142 for id in sorted(operationsById.keys()):
143 operations = operationsById[id]
144 info = AnalyzeOperation(interface, operations)
145 if info.IsStatic():
146 self.AddStaticOperation(info)
147 else:
148 self.AddOperation(info)
149
150 def AddSecondaryMembers(self, interface):
151 # With multiple inheritance, attributes and operations of non-first
152 # interfaces need to be added. Sometimes the attribute or operation is
153 # defined in the current interface as well as a parent. In that case we
154 # avoid making a duplicate definition and pray that the signatures match.
155 secondary_parents = self._TransitiveSecondaryParents(interface)
156 for parent_interface in secondary_parents:
157 if isinstance(parent_interface, str): # IsDartCollectionType(parent_inter face)
158 continue
159 for attr in parent_interface.attributes:
160 if not FindMatchingAttribute(interface, attr):
161 self.AddSecondaryAttribute(parent_interface, attr)
162
163 # Group overloaded operations by id
164 operationsById = {}
165 for operation in parent_interface.operations:
166 if operation.id not in operationsById:
167 operationsById[operation.id] = []
168 operationsById[operation.id].append(operation)
169
170 # Generate operations
171 for id in sorted(operationsById.keys()):
172 if not any(op.id == id for op in interface.operations):
173 operations = operationsById[id]
174 info = AnalyzeOperation(interface, operations)
175 self.AddSecondaryOperation(parent_interface, info)
176
177 def AddConstant(self, constant):
178 pass
179
180 def AddAttribute(self, attribute):
181 pass
182
183 def AddIndexer(self, element_type):
184 pass
185
186 def AmendIndexer(self, element_type):
187 pass
188
189 def AddOperation(self, info):
190 pass
191
192 def AddStaticOperation(self, info):
193 pass
194
195 def AddSecondaryAttribute(self, interface, attribute):
196 pass
197
198 def AddSecondaryOperation(self, interface, info):
199 pass
200
201 def _TransitiveSecondaryParents(self, interface):
202 """Returns a list of all non-primary parents.
203
204 The list contains the interface objects for interfaces defined in the
205 database, and the name for undefined interfaces.
206 """
207 def walk(parents):
208 for parent in parents:
209 if IsDartCollectionType(parent.type.id):
210 result.append(parent.type.id)
211 continue
212 if self._database.HasInterface(parent.type.id):
213 parent_interface = self._database.GetInterface(parent.type.id)
214 result.append(parent_interface)
215 walk(parent_interface.parents)
216
217 result = []
218 if interface.parents:
219 parent = interface.parents[0]
220 if IsPureInterface(parent.type.id):
221 walk(interface.parents)
222 else:
223 walk(interface.parents[1:])
224 return result
225
226 def _DartType(self, type_name):
227 return self._system._type_registry.DartType(type_name)
228
229
230 class GeneratorOptions(object):
231 def __init__(self, templates, database, emitters, type_registry, renamer,
232 output_dir):
233 self.templates = templates
234 self.database = database
235 self.emitters = emitters
236 self.type_registry = type_registry
237 self.renamer = renamer
238 self.output_dir = output_dir
239
240
241 def IsReadOnly(attribute):
242 return attribute.is_read_only or 'Replaceable' in attribute.ext_attrs
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698