OLD | NEW |
1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
2 # Copyright (c) 2013 Google Inc. All rights reserved. | 2 # Copyright (c) 2013 Google Inc. All rights reserved. |
3 # | 3 # |
4 # Redistribution and use in source and binary forms, with or without | 4 # Redistribution and use in source and binary forms, with or without |
5 # modification, are permitted provided that the following conditions are | 5 # modification, are permitted provided that the following conditions are |
6 # met: | 6 # met: |
7 # | 7 # |
8 # * Redistributions of source code must retain the above copyright | 8 # * Redistributions of source code must retain the above copyright |
9 # notice, this list of conditions and the following disclaimer. | 9 # notice, this list of conditions and the following disclaimer. |
10 # * Redistributions in binary form must reproduce the above | 10 # * Redistributions in binary form must reproduce the above |
(...skipping 16 matching lines...) Expand all Loading... |
27 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 27 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
28 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 28 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
29 | 29 |
30 import optparse | 30 import optparse |
31 import re | 31 import re |
32 import string | 32 import string |
33 import sys | 33 import sys |
34 | 34 |
35 template_h = string.Template("""// Code generated from InspectorInstrumentation.
idl | 35 template_h = string.Template("""// Code generated from InspectorInstrumentation.
idl |
36 | 36 |
37 #ifndef InspectorInstrumentationInl_h | 37 #ifndef ${file_name}_h |
38 #define InspectorInstrumentationInl_h | 38 #define ${file_name}_h |
| 39 |
| 40 ${includes} |
39 | 41 |
40 namespace WebCore { | 42 namespace WebCore { |
41 | 43 |
42 namespace InspectorInstrumentation { | 44 namespace InspectorInstrumentation { |
43 | 45 |
44 $impl_declarations | 46 $methods |
45 $inline_methods | |
46 } // namespace InspectorInstrumentation | 47 } // namespace InspectorInstrumentation |
47 | 48 |
48 } // namespace WebCore | 49 } // namespace WebCore |
49 | 50 |
50 #endif // !defined(InspectorInstrumentationInl_h) | 51 #endif // !defined(${file_name}_h) |
51 """) | 52 """) |
52 | 53 |
53 template_inline = string.Template(""" | 54 template_inline = string.Template(""" |
54 inline void ${name}(${params_public}) | 55 inline void ${name}(${params_public}) |
55 { ${fast_return} | 56 { ${fast_return} |
56 if (InstrumentingAgents* instrumentingAgents = ${agents_getter}) | 57 if (${condition}) |
57 ${name}Impl(${params_impl}); | 58 ${name}Impl(${params_impl}); |
58 } | 59 } |
59 """) | 60 """) |
60 | 61 |
61 template_inline_forward = string.Template(""" | 62 template_inline_forward = string.Template(""" |
62 inline void ${name}(${params_public}) | 63 inline void ${name}(${params_public}) |
63 { ${fast_return} | 64 { ${fast_return} |
64 ${name}Impl(${params_impl}); | 65 ${name}Impl(${params_impl}); |
65 } | 66 } |
66 """) | 67 """) |
67 | 68 |
68 template_inline_accepts_cookie = string.Template(""" | 69 template_inline_returns_value = string.Template(""" |
69 inline void ${name}(${params_public}) | 70 inline ${return_type} ${name}(${params_public}) |
70 { ${fast_return} | 71 { ${fast_return} |
71 if (${cookie}.isValid()) | 72 if (${condition}) |
72 ${name}Impl(${params_impl}); | 73 return ${name}Impl(${params_impl}); |
| 74 return ${default_return_value}; |
73 } | 75 } |
74 """) | 76 """) |
75 | 77 |
76 template_inline_returns_cookie = string.Template(""" | |
77 inline InspectorInstrumentationCookie ${name}(${params_public}) | |
78 { ${fast_return} | |
79 if (InstrumentingAgents* instrumentingAgents = ${agents_getter}) | |
80 return ${name}Impl(${params_impl}); | |
81 return InspectorInstrumentationCookie(); | |
82 } | |
83 """) | |
84 | |
85 | 78 |
86 template_cpp = string.Template("""// Code generated from InspectorInstrumentatio
n.idl | 79 template_cpp = string.Template("""// Code generated from InspectorInstrumentatio
n.idl |
87 | 80 |
88 #include "config.h" | 81 #include "config.h" |
89 #include "core/inspector/InspectorInstrumentation.h" | |
90 | 82 |
91 #include "core/inspector/InspectorAgent.h" | 83 ${includes} |
92 #include "core/inspector/InspectorApplicationCacheAgent.h" | |
93 #include "core/inspector/InspectorCSSAgent.h" | |
94 #include "core/inspector/InspectorCanvasAgent.h" | |
95 #include "core/inspector/InspectorConsoleAgent.h" | |
96 #include "core/inspector/InspectorConsoleInstrumentation.h" | |
97 #include "core/inspector/InspectorDOMAgent.h" | |
98 #include "core/inspector/InspectorDOMDebuggerAgent.h" | |
99 #include "core/inspector/InspectorDOMStorageAgent.h" | |
100 #include "core/inspector/InspectorDatabaseAgent.h" | |
101 #include "core/inspector/InspectorDatabaseInstrumentation.h" | |
102 #include "core/inspector/InspectorDebuggerAgent.h" | |
103 #include "core/inspector/InspectorHeapProfilerAgent.h" | |
104 #include "core/inspector/InspectorLayerTreeAgent.h" | |
105 #include "core/inspector/InspectorPageAgent.h" | |
106 #include "core/inspector/InspectorProfilerAgent.h" | |
107 #include "core/inspector/InspectorResourceAgent.h" | |
108 #include "core/inspector/InspectorTimelineAgent.h" | |
109 #include "core/inspector/InspectorWorkerAgent.h" | |
110 #include "core/inspector/InstrumentingAgents.h" | |
111 #include "core/inspector/PageDebuggerAgent.h" | |
112 #include "core/inspector/PageRuntimeAgent.h" | |
113 #include "core/inspector/WorkerRuntimeAgent.h" | |
114 | 84 |
115 namespace WebCore { | 85 namespace WebCore { |
| 86 ${extra_definitions} |
116 | 87 |
117 namespace InspectorInstrumentation { | 88 namespace InspectorInstrumentation { |
118 $out_of_line_methods | 89 $methods |
119 | 90 |
120 } // namespace InspectorInstrumentation | 91 } // namespace InspectorInstrumentation |
121 | 92 |
122 } // namespace WebCore | 93 } // namespace WebCore |
123 """) | 94 """) |
124 | 95 |
125 template_outofline = string.Template(""" | 96 template_outofline = string.Template(""" |
126 void ${name}Impl(${params_impl}) | 97 ${return_type} ${name}Impl(${params_impl}) |
127 {${agent_calls} | 98 {${impl_lines} |
128 }""") | 99 }""") |
129 | 100 |
130 template_agent_call = string.Template(""" | 101 template_agent_call = string.Template(""" |
131 if (${agent_class}* ${agent}Agent = ${agent_fetch}) | 102 if (${agent_class}* agent = ${agent_fetch}) |
132 ${agent}Agent->${name}(${params_agent});""") | 103 ${maybe_return}agent->${name}(${params_agent});""") |
133 | 104 |
134 template_timeline_agent_call = string.Template(""" | 105 template_agent_call_timeline_returns_cookie = string.Template(""" |
135 int timelineAgentId = 0; | 106 int timelineAgentId = 0; |
136 if (InspectorTimelineAgent* timelineAgent = instrumentingAgents->inspectorTi
melineAgent()) { | 107 if (InspectorTimelineAgent* agent = agents->inspectorTimelineAgent()) { |
137 if (timelineAgent->${name}(${params_agent})) | 108 if (agent->${name}(${params_agent})) |
138 timelineAgentId = timelineAgent->id(); | 109 timelineAgentId = agent->id(); |
139 }""") | 110 }""") |
140 | 111 |
141 template_outofline_returns_cookie = string.Template(""" | 112 |
142 ${return_type} ${name}Impl(${params_impl}) | 113 template_instrumenting_agents_h = string.Template("""// Code generated from Insp
ectorInstrumentation.idl |
143 {${agent_calls} | 114 |
144 return InspectorInstrumentationCookie(instrumentingAgents, ${timeline_agent_
id}); | 115 #ifndef InstrumentingAgentsInl_h |
| 116 #define InstrumentingAgentsInl_h |
| 117 |
| 118 #include <wtf/FastAllocBase.h> |
| 119 #include <wtf/Noncopyable.h> |
| 120 #include <wtf/PassRefPtr.h> |
| 121 #include <wtf/RefCounted.h> |
| 122 |
| 123 namespace WebCore { |
| 124 |
| 125 ${forward_list} |
| 126 |
| 127 class InstrumentingAgents : public RefCounted<InstrumentingAgents> { |
| 128 WTF_MAKE_NONCOPYABLE(InstrumentingAgents); |
| 129 WTF_MAKE_FAST_ALLOCATED; |
| 130 public: |
| 131 static PassRefPtr<InstrumentingAgents> create() |
| 132 { |
| 133 return adoptRef(new InstrumentingAgents()); |
| 134 } |
| 135 ~InstrumentingAgents() { } |
| 136 void reset(); |
| 137 |
| 138 ${accessor_list} |
| 139 |
| 140 private: |
| 141 InstrumentingAgents(); |
| 142 |
| 143 ${member_list} |
| 144 }; |
| 145 |
| 146 } |
| 147 |
| 148 #endif // !defined(InstrumentingAgentsInl_h) |
| 149 """) |
| 150 |
| 151 template_instrumenting_agent_accessor = string.Template(""" |
| 152 ${class_name}* ${getter_name}() const { return ${member_name}; } |
| 153 void set${class_name}(${class_name}* agent) { ${member_name} = agent; }""") |
| 154 |
| 155 template_instrumenting_agents_cpp = string.Template(""" |
| 156 InstrumentingAgents::InstrumentingAgents() |
| 157 : $init_list |
| 158 { |
| 159 } |
| 160 |
| 161 void InstrumentingAgents::reset() |
| 162 { |
| 163 $reset_list |
145 }""") | 164 }""") |
146 | 165 |
147 | 166 |
| 167 |
| 168 def match_and_consume(pattern, source): |
| 169 match = re.match(pattern, source) |
| 170 if match: |
| 171 return match, source[len(match.group(0)):].strip() |
| 172 return None, source |
| 173 |
| 174 |
148 def load_model_from_idl(source): | 175 def load_model_from_idl(source): |
149 source = re.sub("//.*\n", "", source) # Remove line comments | 176 source = re.sub("//.*", "", source) # Remove line comments |
150 source = re.sub("\n", " ", source) # Remove newlines | 177 source = re.sub("/\*(.|\n)*?\*/", "", source, re.MULTILINE) # Remove block
comments |
151 source = re.sub("/\*.*\*/", "", source) # Remove block comments | 178 source = re.sub("\]\s*?\n\s*", "] ", source) # Merge the method annotation
with the next line |
152 source = re.sub("\s\s+", " ", source) # Collapse whitespace | |
153 source = source.strip() | 179 source = source.strip() |
154 | 180 |
155 match = re.match("interface\s\w*\s?\{(.*)\}", source) | 181 model = [] |
156 if not match: | 182 |
157 sys.stderr.write("Cannot parse the file") | 183 while len(source): |
158 sys.exit(1) | 184 match, source = match_and_consume("interface\s(\w*)\s?\{([^\{]*)\}", sou
rce) |
159 lines = match.group(1) | 185 if not match: |
160 | 186 sys.stderr.write("Cannot parse %s\n" % source[:100]) |
161 methods = [] | 187 sys.exit(1) |
162 for line in map(str.strip, lines.split(";")): | 188 model.append(File(match.group(1), match.group(2))) |
163 if len(line) == 0: | 189 |
164 continue | 190 return model |
165 methods.append(Method(line)) | 191 |
166 return methods | 192 |
| 193 class File: |
| 194 def __init__(self, name, source): |
| 195 self.name = name |
| 196 self.header_name = self.name + "Inl" |
| 197 self.includes = [include_inspector_header("InspectorInstrumentation")] |
| 198 self.declarations = [] |
| 199 for line in map(str.strip, source.split("\n")): |
| 200 line = re.sub("\s{2,}", " ", line).strip() # Collapse whitespace |
| 201 if len(line) == 0: |
| 202 continue |
| 203 if line[0] == "#": |
| 204 self.includes.append(line) |
| 205 else: |
| 206 self.declarations.append(Method(line)) |
| 207 self.includes.sort() |
| 208 |
| 209 def generate(self, cpp_lines, used_agents): |
| 210 header_lines = [] |
| 211 for declaration in self.declarations: |
| 212 for agent in set(declaration.agents): |
| 213 used_agents.add(agent) |
| 214 declaration.generate_header(header_lines) |
| 215 declaration.generate_cpp(cpp_lines) |
| 216 |
| 217 return template_h.substitute(None, |
| 218 file_name=self.header_name, |
| 219 includes="\n".join(self.includes), |
| 220 methods="\n".join(header_lines)) |
167 | 221 |
168 | 222 |
169 class Method: | 223 class Method: |
170 def __init__(self, source): | 224 def __init__(self, source): |
171 match = re.match("(\[[\w|,|=|\s]*\])?\s?(\w*) (\w*)\((.*)\)", source) | 225 match = re.match("(\[[\w|,|=|\s]*\])?\s?(\w*\*?) (\w*)\((.*)\)\s?;", sou
rce) |
172 if not match: | 226 if not match: |
173 sys.stderr.write("Cannot parse %s\n" % source) | 227 sys.stderr.write("Cannot parse %s\n" % source) |
174 sys.exit(1) | 228 sys.exit(1) |
175 | 229 |
176 self.method_options = [] | 230 self.options = [] |
177 if match.group(1): | 231 if match.group(1): |
178 method_options_str = re.sub("\s", "", match.group(1)[1:-1]) | 232 options_str = re.sub("\s", "", match.group(1)[1:-1]) |
179 if len(method_options_str) != 0: | 233 if len(options_str) != 0: |
180 self.method_options = method_options_str.split(",") | 234 self.options = options_str.split(",") |
181 | 235 |
182 self.return_type = match.group(2) | 236 self.return_type = match.group(2) |
183 | 237 |
184 self.name = match.group(3) | 238 self.name = match.group(3) |
185 | 239 |
186 param_string = match.group(4) | 240 # Splitting parameters by a comma, assuming that attribute lists contain
no more than one attribute. |
187 | 241 self.params = map(Parameter, map(str.strip, match.group(4).split(","))) |
188 self.param_options = [] | 242 |
189 options_match = re.match("\[(.*)\]\s?(.*)", param_string) | 243 self.accepts_cookie = len(self.params) and self.params[0].type == "const
InspectorInstrumentationCookie&" |
190 if options_match: | 244 self.returns_cookie = self.return_type == "InspectorInstrumentationCooki
e" |
191 param_string = options_match.group(2) | 245 |
192 self.param_options = map(str.strip, options_match.group(1).split(","
)) | 246 self.returns_value = self.return_type != "void" |
193 | 247 |
194 self.params = map(Parameter, map(str.strip, param_string.split(","))) | 248 if self.return_type == "bool": |
| 249 self.default_return_value = "false" |
| 250 elif self.return_type == "String": |
| 251 self.default_return_value = "\"\"" |
| 252 else: |
| 253 self.default_return_value = self.return_type + "()" |
| 254 |
| 255 for param in self.params: |
| 256 if "DefaultReturn" in param.options: |
| 257 self.default_return_value = param.name |
| 258 |
| 259 self.params_impl = self.params |
| 260 if not self.accepts_cookie and not "Inline=Forward" in self.options: |
| 261 if not "Keep" in self.params_impl[0].options: |
| 262 self.params_impl = self.params_impl[1:] |
| 263 self.params_impl = [Parameter("InstrumentingAgents* agents")] + self
.params_impl |
| 264 self.agents_selector_class = re.match("(\w*)", self.params[0].type).
group(1) |
| 265 |
| 266 self.agents = filter(lambda option: not "=" in option, self.options) |
| 267 |
| 268 def generate_header(self, header_lines): |
| 269 if "Inline=Custom" in self.options: |
| 270 return |
| 271 |
| 272 header_lines.append("%s %sImpl(%s);" % ( |
| 273 self.return_type, self.name, ", ".join(map(Parameter.to_str_class, s
elf.params_impl)))) |
| 274 |
| 275 if "Inline=FastReturn" in self.options or "Inline=Forward" in self.optio
ns: |
| 276 fast_return = "\n FAST_RETURN_IF_NO_FRONTENDS(%s);" % self.defaul
t_return_value |
| 277 else: |
| 278 fast_return = "" |
| 279 |
| 280 for param in self.params: |
| 281 if "FastReturn" in param.options: |
| 282 fast_return += "\n if (!%s)\n return %s;" % (param.nam
e, self.default_return_value) |
| 283 |
| 284 if self.accepts_cookie: |
| 285 condition = "%s.isValid()" % self.params_impl[0].name |
| 286 template = template_inline |
| 287 elif "Inline=Forward" in self.options: |
| 288 condition = "" |
| 289 template = template_inline_forward |
| 290 else: |
| 291 condition = "InstrumentingAgents* agents = instrumentingAgentsFor%s(
%s)" % ( |
| 292 self.agents_selector_class, self.params[0].name) |
| 293 |
| 294 if self.returns_value: |
| 295 template = template_inline_returns_value |
| 296 else: |
| 297 template = template_inline |
| 298 |
| 299 header_lines.append(template.substitute( |
| 300 None, |
| 301 name=self.name, |
| 302 fast_return=fast_return, |
| 303 return_type=self.return_type, |
| 304 default_return_value=self.default_return_value, |
| 305 params_public=", ".join(map(Parameter.to_str_full, self.params)), |
| 306 params_impl=", ".join(map(Parameter.to_str_name, self.params_impl)), |
| 307 condition=condition)) |
| 308 |
| 309 def generate_cpp(self, cpp_lines): |
| 310 if len(self.agents) == 0: |
| 311 return |
| 312 |
| 313 body_lines = map(self.generate_agent_call, self.agents) |
| 314 |
| 315 if self.returns_cookie: |
| 316 if "Timeline" in self.agents: |
| 317 timeline_agent_id = "timelineAgentId" |
| 318 else: |
| 319 timeline_agent_id = "0" |
| 320 body_lines.append("\n return InspectorInstrumentationCookie(agent
s, %s);" % timeline_agent_id) |
| 321 elif self.returns_value: |
| 322 body_lines.append("\n return %s;" % self.default_return_value) |
| 323 |
| 324 cpp_lines.append(template_outofline.substitute( |
| 325 None, |
| 326 return_type=self.return_type, |
| 327 name=self.name, |
| 328 params_impl=", ".join(map(Parameter.to_str_class_and_name, self.para
ms_impl)), |
| 329 impl_lines="".join(body_lines))) |
| 330 |
| 331 def generate_agent_call(self, agent): |
| 332 agent_class, agent_getter = agent_getter_signature(agent) |
| 333 |
| 334 leading_param_name = self.params_impl[0].name |
| 335 if not self.accepts_cookie: |
| 336 agent_fetch = "%s->%s()" % (leading_param_name, agent_getter) |
| 337 elif agent == "Timeline": |
| 338 agent_fetch = "retrieveTimelineAgent(%s)" % leading_param_name |
| 339 else: |
| 340 agent_fetch = "%s.instrumentingAgents()->%s()" % (leading_param_name
, agent_getter) |
| 341 |
| 342 if agent == "Timeline" and self.returns_cookie: |
| 343 template = template_agent_call_timeline_returns_cookie |
| 344 else: |
| 345 template = template_agent_call |
| 346 |
| 347 if not self.returns_value or self.returns_cookie: |
| 348 maybe_return = "" |
| 349 else: |
| 350 maybe_return = "return " |
| 351 |
| 352 return template.substitute( |
| 353 None, |
| 354 name=self.name, |
| 355 agent_class=agent_class, |
| 356 agent_fetch=agent_fetch, |
| 357 maybe_return=maybe_return, |
| 358 params_agent=", ".join(map(Parameter.to_str_name, self.params_impl)[
1:])) |
195 | 359 |
196 | 360 |
197 class Parameter: | 361 class Parameter: |
198 def __init__(self, source): | 362 def __init__(self, source): |
| 363 self.options = [] |
| 364 match, source = match_and_consume("\[(\w*)\]", source) |
| 365 if match: |
| 366 self.options.append(match.group(1)) |
| 367 |
199 parts = map(str.strip, source.split("=")) | 368 parts = map(str.strip, source.split("=")) |
200 if len(parts) == 1: | 369 if len(parts) == 1: |
201 self.default_value = None | 370 self.default_value = None |
202 else: | 371 else: |
203 self.default_value = parts[1] | 372 self.default_value = parts[1] |
204 | 373 |
205 param_decl = parts[0] | 374 param_decl = parts[0] |
206 | 375 |
207 if re.match("(const|unsigned long) ", param_decl): | 376 if re.match("(const|unsigned long) ", param_decl): |
208 min_type_tokens = 2 | 377 min_type_tokens = 2 |
(...skipping 16 matching lines...) Expand all Loading... |
225 def to_str_class_and_name(self): | 394 def to_str_class_and_name(self): |
226 return "%s %s" % (self.type, self.name) | 395 return "%s %s" % (self.type, self.name) |
227 | 396 |
228 def to_str_class(self): | 397 def to_str_class(self): |
229 return self.type | 398 return self.type |
230 | 399 |
231 def to_str_name(self): | 400 def to_str_name(self): |
232 return self.name | 401 return self.name |
233 | 402 |
234 | 403 |
235 # This function is only needed to minimize the diff with the handwritten code. | |
236 # In fact it is sufficient to return a globally unique string. | |
237 def generate_param_name(param_type): | 404 def generate_param_name(param_type): |
238 base_name = re.match("(const |RefPtr<|PassRefPtr<)?(\w*)", param_type).group
(2) | 405 base_name = re.match("(const |PassRefPtr<)?(\w*)", param_type).group(2) |
239 | 406 return "param" + base_name |
240 custom_param_types = { | |
241 "CharacterData": "characterData", | |
242 "CSSSelector": "pseudoState", | |
243 "DocumentStyleSheetCollection": "styleSheetCollection", | |
244 "EventPath": "eventPath", | |
245 "FormData": "formData", | |
246 "InspectorCSSOMWrappers": "inspectorCSSOMWrappers", | |
247 "InstrumentingAgents": "instrumentingAgents", | |
248 "NamedFlow": "namedFlow", | |
249 "RenderObject": "renderer", | |
250 "RenderLayer": "renderLayer", | |
251 "ResourceLoader": "resourceLoader", | |
252 "PseudoElement": "pseudoElement", | |
253 "ScriptState": "scriptState"} | |
254 if base_name in custom_param_types: | |
255 return custom_param_types[base_name] | |
256 | |
257 match = re.match("(.*)([A-Z][a-z]+)", base_name) | |
258 if match: | |
259 return match.group(2).lower() # CamelCaseWord -> word | |
260 | |
261 if base_name.lower() == base_name: | |
262 return base_name + "_" | |
263 return base_name.lower() | |
264 | |
265 | |
266 # This function is only needed to minimize the diff with the handwritten code. | |
267 # In fact is is sufficient to hardcode a constant string (e.g. "agent") into the
template. | |
268 def agent_variable_name(agent): | |
269 if re.match("DOM", agent): | |
270 return re.sub("DOM", "dom", agent) | |
271 if agent.upper() == agent: | |
272 return agent.lower() | |
273 return agent[0].lower() + agent[1:] | |
274 | 407 |
275 | 408 |
276 def agent_class_name(agent): | 409 def agent_class_name(agent): |
277 custom_agent_names = ["Inspector", "PageDebugger", "PageRuntime", "WorkerRun
time"] | 410 custom_agent_names = ["Inspector", "PageDebugger", "PageRuntime", "WorkerRun
time"] |
278 if agent in custom_agent_names: | 411 if agent in custom_agent_names: |
279 return "%sAgent" % agent | 412 return "%sAgent" % agent |
280 return "Inspector%sAgent" % agent | 413 return "Inspector%sAgent" % agent |
281 | 414 |
282 | 415 |
283 def agent_getter_name(agent): | 416 def agent_getter_signature(agent): |
284 name = agent_class_name(agent) | 417 agent_class = agent_class_name(agent) |
285 return name[0].lower() + name[1:] | 418 return agent_class, agent_class[0].lower() + agent_class[1:] |
| 419 |
| 420 |
| 421 def include_header(name): |
| 422 return "#include \"%s.h\"" % name |
| 423 |
| 424 |
| 425 def include_inspector_header(name): |
| 426 return include_header("core/inspector/" + name) |
| 427 |
| 428 |
| 429 def generate_instrumenting_agents(used_agents): |
| 430 agents = list(used_agents) |
| 431 |
| 432 forward_list = [] |
| 433 accessor_list = [] |
| 434 member_list = [] |
| 435 init_list = [] |
| 436 reset_list = [] |
| 437 |
| 438 for agent in agents: |
| 439 class_name, getter_name = agent_getter_signature(agent) |
| 440 member_name = "m_" + getter_name |
| 441 |
| 442 forward_list.append("class %s;" % class_name) |
| 443 accessor_list.append(template_instrumenting_agent_accessor.substitute( |
| 444 None, |
| 445 class_name=class_name, |
| 446 getter_name=getter_name, |
| 447 member_name=member_name)) |
| 448 member_list.append(" %s* %s;" % (class_name, member_name)) |
| 449 init_list.append("%s(0)" % member_name) |
| 450 reset_list.append("%s = 0;" % member_name) |
| 451 |
| 452 forward_list.sort() |
| 453 accessor_list.sort() |
| 454 member_list.sort() |
| 455 init_list.sort() |
| 456 reset_list.sort() |
| 457 |
| 458 header_lines = template_instrumenting_agents_h.substitute( |
| 459 None, |
| 460 forward_list="\n".join(forward_list), |
| 461 accessor_list="\n".join(accessor_list), |
| 462 member_list="\n".join(member_list)) |
| 463 |
| 464 cpp_lines = template_instrumenting_agents_cpp.substitute( |
| 465 None, |
| 466 init_list="\n , ".join(init_list), |
| 467 reset_list="\n ".join(reset_list)) |
| 468 |
| 469 return header_lines, cpp_lines |
286 | 470 |
287 | 471 |
288 def generate(input_path, output_h_dir, output_cpp_dir): | 472 def generate(input_path, output_h_dir, output_cpp_dir): |
289 fin = open(input_path, "r") | 473 fin = open(input_path, "r") |
290 declarations = load_model_from_idl(fin.read()) | 474 files = load_model_from_idl(fin.read()) |
291 fin.close() | 475 fin.close() |
292 | 476 |
293 impl_declarations = [] | 477 cpp_includes = [] |
294 inline_methods = [] | 478 cpp_lines = [] |
295 out_of_line_methods = [] | 479 used_agents = set() |
| 480 for f in files: |
| 481 cpp_includes.append(include_header(f.header_name)) |
296 | 482 |
297 for declaration in declarations: | 483 fout = open(output_h_dir + "/" + f.header_name + ".h", "w") |
298 param_string_public = ", ".join(map(Parameter.to_str_full, declaration.p
arams)) | 484 fout.write(f.generate(cpp_lines, used_agents)) |
| 485 fout.close() |
299 | 486 |
300 param_list_impl_parsed = declaration.params[:] | 487 for agent in used_agents: |
| 488 cpp_includes.append(include_inspector_header(agent_class_name(agent))) |
| 489 cpp_includes.append(include_header("InstrumentingAgentsInl")) |
| 490 cpp_includes.sort() |
301 | 491 |
302 accepts_cookie = (declaration.params[0].type == "const InspectorInstrume
ntationCookie&") | 492 instrumenting_agents_header, instrumenting_agents_cpp = generate_instrumenti
ng_agents(used_agents) |
303 if not accepts_cookie and not "Inline=Forward" in declaration.method_opt
ions: | |
304 if not "Keep" in declaration.param_options: | |
305 param_list_impl_parsed = param_list_impl_parsed[1:] | |
306 param_list_impl_parsed = [Parameter("InstrumentingAgents*")] + param
_list_impl_parsed | |
307 | 493 |
308 generate_inline = not "Inline=Custom" in declaration.method_options | 494 fout = open(output_h_dir + "/" + "InstrumentingAgentsInl.h", "w") |
309 if generate_inline: | 495 fout.write(instrumenting_agents_header) |
310 impl_declarations.append("%s %sImpl(%s);" % ( | |
311 declaration.return_type, declaration.name, ", ".join(map(Paramet
er.to_str_class, param_list_impl_parsed)))) | |
312 | |
313 leading_impl_param_name = param_list_impl_parsed[0].name | |
314 param_string_impl_full = ", ".join(map(Parameter.to_str_class_and_name,
param_list_impl_parsed)) | |
315 | |
316 param_list_impl_names_only = map(Parameter.to_str_name, param_list_impl_
parsed) | |
317 param_string_impl_names_only = ", ".join(param_list_impl_names_only) | |
318 param_string_agent = ", ".join(param_list_impl_names_only[1:]) | |
319 | |
320 def is_agent_name(name): | |
321 return not "=" in name | |
322 | |
323 agents = filter(is_agent_name, declaration.method_options) | |
324 | |
325 if "Inline=FastReturn" in declaration.method_options or "Inline=Forward"
in declaration.method_options: | |
326 fast_return = "\n FAST_RETURN_IF_NO_FRONTENDS(%s());" % declarati
on.return_type | |
327 else: | |
328 fast_return = "" | |
329 | |
330 if accepts_cookie: | |
331 if generate_inline: | |
332 inline_methods.append( | |
333 template_inline_accepts_cookie.substitute( | |
334 None, | |
335 name=declaration.name, | |
336 fast_return=fast_return, | |
337 params_public=param_string_public, | |
338 params_impl=param_string_impl_names_only, | |
339 cookie=leading_impl_param_name)) | |
340 if len(agents): | |
341 agent_calls = [] | |
342 for agent in agents: | |
343 if agent == "Timeline": | |
344 agent_fetch = "retrieveTimelineAgent(%s)" % leading_impl
_param_name | |
345 else: | |
346 agent_fetch = "%s.instrumentingAgents()->%s()" % (leadin
g_impl_param_name, agent_getter_name(agent)) | |
347 agent_calls.append( | |
348 template_agent_call.substitute( | |
349 None, | |
350 name=declaration.name, | |
351 agent_fetch=agent_fetch, | |
352 params_agent=param_string_agent, | |
353 agent_class=agent_class_name(agent), | |
354 agent=agent_variable_name(agent))) | |
355 out_of_line_methods.append( | |
356 template_outofline.substitute( | |
357 None, | |
358 name=declaration.name, | |
359 params_impl=param_string_impl_full, | |
360 agent_calls="".join(agent_calls))) | |
361 else: | |
362 leading_public_param = declaration.params[0] | |
363 selector_class = re.match("(\w*)", leading_public_param.type).group(
1) | |
364 agents_getter = "instrumentingAgentsFor%s(%s)" % (selector_class, le
ading_public_param.name) | |
365 if declaration.return_type == "void": | |
366 if generate_inline: | |
367 if "Inline=Forward" in declaration.method_options: | |
368 inline_methods.append( | |
369 template_inline_forward.substitute( | |
370 None, | |
371 name=declaration.name, | |
372 fast_return=fast_return, | |
373 params_public=param_string_public, | |
374 params_impl=param_string_impl_names_only)) | |
375 else: | |
376 inline_methods.append( | |
377 template_inline.substitute( | |
378 None, | |
379 name=declaration.name, | |
380 fast_return=fast_return, | |
381 params_public=param_string_public, | |
382 params_impl=param_string_impl_names_only, | |
383 agents_getter=agents_getter)) | |
384 if len(agents): | |
385 agent_calls = [] | |
386 for agent in agents: | |
387 agent_fetch = "%s->%s()" % (leading_impl_param_name, age
nt_getter_name(agent)) | |
388 agent_call = template_agent_call.substitute( | |
389 None, | |
390 name=declaration.name, | |
391 agent_fetch=agent_fetch, | |
392 params_agent=param_string_agent, | |
393 agent_class=agent_class_name(agent), | |
394 agent=agent_variable_name(agent)) | |
395 agent_calls.append(agent_call) | |
396 out_of_line_methods.append( | |
397 template_outofline.substitute( | |
398 None, | |
399 name=declaration.name, | |
400 params_impl=param_string_impl_full, | |
401 agent_calls="".join(agent_calls))) | |
402 elif declaration.return_type == "InspectorInstrumentationCookie": | |
403 if generate_inline: | |
404 inline_methods.append( | |
405 template_inline_returns_cookie.substitute( | |
406 None, | |
407 name=declaration.name, | |
408 fast_return=fast_return, | |
409 params_public=param_string_public, | |
410 params_impl=param_string_impl_names_only, | |
411 agents_getter=agents_getter)) | |
412 | |
413 if len(agents): | |
414 timeline_agent_id = "0" | |
415 agent_calls = [] | |
416 for agent in agents: | |
417 if agent == "Timeline": | |
418 agent_call = template_timeline_agent_call.substitute
( | |
419 None, | |
420 name=declaration.name, | |
421 params_agent=param_string_agent) | |
422 timeline_agent_id = "timelineAgentId" | |
423 else: | |
424 agent_fetch = "%s->%s()" % (leading_impl_param_name,
agent_getter_name(agent)) | |
425 agent_call = template_agent_call.substitute( | |
426 None, | |
427 name=declaration.name, | |
428 agent_fetch=agent_fetch, | |
429 params_agent=param_string_agent, | |
430 agent_class=agent_class_name(agent), | |
431 agent=agent_variable_name(agent)) | |
432 agent_calls.append(agent_call) | |
433 | |
434 out_of_line_methods.append( | |
435 template_outofline_returns_cookie.substitute( | |
436 None, | |
437 return_type=declaration.return_type, | |
438 name=declaration.name, | |
439 params_impl=param_string_impl_full, | |
440 agent_calls="".join(agent_calls), | |
441 timeline_agent_id=timeline_agent_id)) | |
442 else: | |
443 sys.stderr.write("Unsupported return type %s" % declaration.retu
rn_type) | |
444 sys.exit(1) | |
445 | |
446 fout = open(output_h_dir + "/InspectorInstrumentationInl.h", "w") | |
447 fout.write(template_h.substitute(None, | |
448 impl_declarations="\n".join(impl_declaratio
ns), | |
449 inline_methods="".join(inline_methods))) | |
450 fout.close() | 496 fout.close() |
451 | 497 |
452 fout = open(output_cpp_dir + "/InspectorInstrumentationImpl.cpp", "w") | 498 fout = open(output_cpp_dir + "/InspectorInstrumentationImpl.cpp", "w") |
453 fout.write(template_cpp.substitute(None, | 499 fout.write(template_cpp.substitute(None, |
454 out_of_line_methods="\n".join(out_of_line
_methods))) | 500 includes="\n".join(cpp_includes), |
| 501 extra_definitions=instrumenting_agents_cp
p, |
| 502 methods="\n".join(cpp_lines))) |
455 fout.close() | 503 fout.close() |
456 | 504 |
457 | 505 |
458 cmdline_parser = optparse.OptionParser() | 506 cmdline_parser = optparse.OptionParser() |
459 cmdline_parser.add_option("--output_h_dir") | 507 cmdline_parser.add_option("--output_h_dir") |
460 cmdline_parser.add_option("--output_cpp_dir") | 508 cmdline_parser.add_option("--output_cpp_dir") |
461 | 509 |
462 try: | 510 try: |
463 arg_options, arg_values = cmdline_parser.parse_args() | 511 arg_options, arg_values = cmdline_parser.parse_args() |
464 if (len(arg_values) != 1): | 512 if (len(arg_values) != 1): |
465 raise Exception("Exactly one plain argument expected (found %s)" % len(a
rg_values)) | 513 raise Exception("Exactly one plain argument expected (found %s)" % len(a
rg_values)) |
466 input_path = arg_values[0] | 514 input_path = arg_values[0] |
467 output_header_dirpath = arg_options.output_h_dir | 515 output_header_dirpath = arg_options.output_h_dir |
468 output_cpp_dirpath = arg_options.output_cpp_dir | 516 output_cpp_dirpath = arg_options.output_cpp_dir |
469 if not output_header_dirpath: | 517 if not output_header_dirpath: |
470 raise Exception("Output .h directory must be specified") | 518 raise Exception("Output .h directory must be specified") |
471 if not output_cpp_dirpath: | 519 if not output_cpp_dirpath: |
472 raise Exception("Output .cpp directory must be specified") | 520 raise Exception("Output .cpp directory must be specified") |
473 except Exception: | 521 except Exception: |
474 # Work with python 2 and 3 http://docs.python.org/py3k/howto/pyporting.html | 522 # Work with python 2 and 3 http://docs.python.org/py3k/howto/pyporting.html |
475 exc = sys.exc_info()[1] | 523 exc = sys.exc_info()[1] |
476 sys.stderr.write("Failed to parse command-line arguments: %s\n\n" % exc) | 524 sys.stderr.write("Failed to parse command-line arguments: %s\n\n" % exc) |
477 sys.stderr.write("Usage: <script> InspectorInstrumentation.idl --output_h_di
r <output_header_dir> --output_cpp_dir <output_cpp_dir>\n") | 525 sys.stderr.write("Usage: <script> InspectorInstrumentation.idl --output_h_di
r <output_header_dir> --output_cpp_dir <output_cpp_dir>\n") |
478 exit(1) | 526 exit(1) |
479 | 527 |
480 generate(input_path, output_header_dirpath, output_cpp_dirpath) | 528 generate(input_path, output_header_dirpath, output_cpp_dirpath) |
OLD | NEW |