12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#!/usr/bin/env python 22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)# Copyright (c) 2013 Google Inc. All rights reserved. 32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)# 42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)# Redistribution and use in source and binary forms, with or without 52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)# modification, are permitted provided that the following conditions are 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)# met: 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)# 82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)# * Redistributions of source code must retain the above copyright 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)# notice, this list of conditions and the following disclaimer. 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)# * Redistributions in binary form must reproduce the above 115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)# copyright notice, this list of conditions and the following disclaimer 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)# in the documentation and/or other materials provided with the 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)# distribution. 145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)# * Neither the name of Google Inc. nor the names of its 159ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch# contributors may be used to endorse or promote products derived from 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)# this software without specific prior written permission. 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)# 185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import optparse 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import re 325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)import string 335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)import sys 345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)template_h = string.Template("""// Code generated from InspectorInstrumentation.idl 365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#ifndef ${file_name}_h 385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#define ${file_name}_h 395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)${includes} 415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace blink { 435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)${forward_declarations} 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace InspectorInstrumentation { 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)$methods 495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} // namespace InspectorInstrumentation 505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace blink 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif // !defined(${file_name}_h) 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)""") 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)template_inline = string.Template(""" 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)inline void ${name}(${params_public}) 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles){ ${fast_return} 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (${condition}) 605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ${name}Impl(${params_impl}); 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)""") 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)template_inline_forward = string.Template(""" 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)inline void ${name}(${params_public}) 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles){ ${fast_return} 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ${name}Impl(${params_impl}); 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)""") 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)template_inline_returns_value = string.Template(""" 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)inline ${return_type} ${name}(${params_public}) 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles){ ${fast_return} 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (${condition}) 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return ${name}Impl(${params_impl}); 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return ${default_return_value}; 775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)""") 792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)template_cpp = string.Template("""// Code generated from InspectorInstrumentation.idl 825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "config.h" 845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 85a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)${includes} 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace blink { 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)${extra_definitions} 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace InspectorInstrumentation { 912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)$methods 922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace InspectorInstrumentation 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace blink 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)""") 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)template_outofline = string.Template(""" 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)${return_type} ${name}Impl(${params_impl}) 100a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles){${impl_lines} 1015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}""") 1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)template_agent_call = string.Template(""" 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (${agent_class}* agent = ${agent_fetch}) 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ${maybe_return}agent->${name}(${params_agent});""") 1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)template_agent_call_timeline_returns_cookie = string.Template(""" 1085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int timelineAgentId = 0; 1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (InspectorTimelineAgent* agent = agents->inspectorTimelineAgent()) { 1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (agent->${name}(${params_agent})) 1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) timelineAgentId = agent->id(); 1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }""") 1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)template_instrumenting_agents_h = string.Template("""// Code generated from InspectorInstrumentation.idl 1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifndef InstrumentingAgentsInl_h 1185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#define InstrumentingAgentsInl_h 1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "platform/heap/Handle.h" 1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "wtf/FastAllocBase.h" 1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "wtf/Noncopyable.h" 1235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "wtf/PassRefPtr.h" 1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "wtf/RefCounted.h" 1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace blink { 1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)${forward_list} 1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class InstrumentingAgents : public RefCountedWillBeGarbageCollectedFinalized<InstrumentingAgents> { 1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) WTF_MAKE_NONCOPYABLE(InstrumentingAgents); 1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED; 1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)public: 1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static PassRefPtrWillBeRawPtr<InstrumentingAgents> create() 1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return adoptRefWillBeNoop(new InstrumentingAgents()); 1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ~InstrumentingAgents() { } 1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void trace(Visitor*); 1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void reset(); 1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)${accessor_list} 1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)private: 1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) InstrumentingAgents(); 1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)${member_list} 1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 149a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 1505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif // !defined(InstrumentingAgentsInl_h) 1535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)""") 1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)template_instrumenting_agent_accessor = string.Template(""" 1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ${class_name}* ${getter_name}() const { return ${member_name}; } 1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void set${class_name}(${class_name}* agent) { ${member_name} = agent; }""") 1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)template_instrumenting_agents_cpp = string.Template(""" 160InstrumentingAgents::InstrumentingAgents() 161 : $init_list 162{ 163} 164 165void InstrumentingAgents::trace(Visitor* visitor) 166{ 167 $trace_list 168} 169 170void InstrumentingAgents::reset() 171{ 172 $reset_list 173}""") 174 175 176 177def match_and_consume(pattern, source): 178 match = re.match(pattern, source) 179 if match: 180 return match, source[len(match.group(0)):].strip() 181 return None, source 182 183 184def load_model_from_idl(source): 185 source = re.sub("//.*", "", source) # Remove line comments 186 source = re.sub("/\*(.|\n)*?\*/", "", source, re.MULTILINE) # Remove block comments 187 source = re.sub("\]\s*?\n\s*", "] ", source) # Merge the method annotation with the next line 188 source = source.strip() 189 190 model = [] 191 192 while len(source): 193 match, source = match_and_consume("interface\s(\w*)\s?\{([^\{]*)\}", source) 194 if not match: 195 sys.stderr.write("Cannot parse %s\n" % source[:100]) 196 sys.exit(1) 197 model.append(File(match.group(1), match.group(2))) 198 199 return model 200 201 202class File: 203 def __init__(self, name, source): 204 self.name = name 205 self.header_name = self.name + "Inl" 206 self.includes = [include_inspector_header("InspectorInstrumentation")] 207 self.forward_declarations = [] 208 self.declarations = [] 209 for line in map(str.strip, source.split("\n")): 210 line = re.sub("\s{2,}", " ", line).strip() # Collapse whitespace 211 if len(line) == 0: 212 continue 213 if line[0] == "#": 214 self.includes.append(line) 215 elif line.startswith("class "): 216 self.forward_declarations.append(line) 217 else: 218 self.declarations.append(Method(line)) 219 self.includes.sort() 220 self.forward_declarations.sort() 221 222 def generate(self, cpp_lines, used_agents): 223 header_lines = [] 224 for declaration in self.declarations: 225 for agent in set(declaration.agents): 226 used_agents.add(agent) 227 declaration.generate_header(header_lines) 228 declaration.generate_cpp(cpp_lines) 229 230 return template_h.substitute(None, 231 file_name=self.header_name, 232 includes="\n".join(self.includes), 233 forward_declarations="\n".join(self.forward_declarations), 234 methods="\n".join(header_lines)) 235 236 237class Method: 238 def __init__(self, source): 239 match = re.match("(\[[\w|,|=|\s]*\])?\s?(\w*\*?) (\w*)\((.*)\)\s?;", source) 240 if not match: 241 sys.stderr.write("Cannot parse %s\n" % source) 242 sys.exit(1) 243 244 self.options = [] 245 if match.group(1): 246 options_str = re.sub("\s", "", match.group(1)[1:-1]) 247 if len(options_str) != 0: 248 self.options = options_str.split(",") 249 250 self.return_type = match.group(2) 251 252 self.name = match.group(3) 253 254 # Splitting parameters by a comma, assuming that attribute lists contain no more than one attribute. 255 self.params = map(Parameter, map(str.strip, match.group(4).split(","))) 256 257 self.accepts_cookie = len(self.params) and self.params[0].type == "const InspectorInstrumentationCookie&" 258 self.returns_cookie = self.return_type == "InspectorInstrumentationCookie" 259 260 self.returns_value = self.return_type != "void" 261 262 if self.return_type == "bool": 263 self.default_return_value = "false" 264 elif self.return_type == "int": 265 self.default_return_value = "0" 266 elif self.return_type == "String": 267 self.default_return_value = "\"\"" 268 else: 269 self.default_return_value = self.return_type + "()" 270 271 for param in self.params: 272 if "DefaultReturn" in param.options: 273 self.default_return_value = param.name 274 275 self.params_impl = self.params 276 if not self.accepts_cookie and not "Inline=Forward" in self.options: 277 if not "Keep" in self.params_impl[0].options: 278 self.params_impl = self.params_impl[1:] 279 self.params_impl = [Parameter("InstrumentingAgents* agents")] + self.params_impl 280 281 self.agents = filter(lambda option: not "=" in option, self.options) 282 283 def generate_header(self, header_lines): 284 if "Inline=Custom" in self.options: 285 return 286 287 header_lines.append("%s %sImpl(%s);" % ( 288 self.return_type, self.name, ", ".join(map(Parameter.to_str_class, self.params_impl)))) 289 290 if "Inline=FastReturn" in self.options or "Inline=Forward" in self.options: 291 fast_return = "\n FAST_RETURN_IF_NO_FRONTENDS(%s);" % self.default_return_value 292 else: 293 fast_return = "" 294 295 for param in self.params: 296 if "FastReturn" in param.options: 297 fast_return += "\n if (!%s)\n return %s;" % (param.name, self.default_return_value) 298 299 if self.accepts_cookie: 300 condition = "%s.isValid()" % self.params_impl[0].name 301 template = template_inline 302 elif "Inline=Forward" in self.options: 303 condition = "" 304 template = template_inline_forward 305 else: 306 condition = "InstrumentingAgents* agents = instrumentingAgentsFor(%s)" % self.params[0].name 307 308 if self.returns_value: 309 template = template_inline_returns_value 310 else: 311 template = template_inline 312 313 header_lines.append(template.substitute( 314 None, 315 name=self.name, 316 fast_return=fast_return, 317 return_type=self.return_type, 318 default_return_value=self.default_return_value, 319 params_public=", ".join(map(Parameter.to_str_full, self.params)), 320 params_impl=", ".join(map(Parameter.to_str_name, self.params_impl)), 321 condition=condition)) 322 323 def generate_cpp(self, cpp_lines): 324 if len(self.agents) == 0: 325 return 326 327 body_lines = map(self.generate_ref_ptr, self.params) 328 body_lines += map(self.generate_agent_call, self.agents) 329 330 if self.returns_cookie: 331 if "Timeline" in self.agents: 332 timeline_agent_id = "timelineAgentId" 333 else: 334 timeline_agent_id = "0" 335 body_lines.append("\n return InspectorInstrumentationCookie(agents, %s);" % timeline_agent_id) 336 elif self.returns_value: 337 body_lines.append("\n return %s;" % self.default_return_value) 338 339 cpp_lines.append(template_outofline.substitute( 340 None, 341 return_type=self.return_type, 342 name=self.name, 343 params_impl=", ".join(map(Parameter.to_str_class_and_name, self.params_impl)), 344 impl_lines="".join(body_lines))) 345 346 def generate_agent_call(self, agent): 347 agent_class, agent_getter = agent_getter_signature(agent) 348 349 leading_param_name = self.params_impl[0].name 350 if not self.accepts_cookie: 351 agent_fetch = "%s->%s()" % (leading_param_name, agent_getter) 352 elif agent == "Timeline": 353 agent_fetch = "retrieveTimelineAgent(%s)" % leading_param_name 354 else: 355 agent_fetch = "%s.instrumentingAgents()->%s()" % (leading_param_name, agent_getter) 356 357 if agent == "Timeline" and self.returns_cookie: 358 template = template_agent_call_timeline_returns_cookie 359 else: 360 template = template_agent_call 361 362 if not self.returns_value or self.returns_cookie: 363 maybe_return = "" 364 else: 365 maybe_return = "return " 366 367 return template.substitute( 368 None, 369 name=self.name, 370 agent_class=agent_class, 371 agent_fetch=agent_fetch, 372 maybe_return=maybe_return, 373 params_agent=", ".join(map(Parameter.to_str_value, self.params_impl)[1:])) 374 375 def generate_ref_ptr(self, param): 376 if param.is_prp: 377 return "\n RefPtr<%s> %s = %s;" % (param.inner_type, param.value, param.name) 378 else: 379 return "" 380 381class Parameter: 382 def __init__(self, source): 383 self.options = [] 384 match, source = match_and_consume("\[(\w*)\]", source) 385 if match: 386 self.options.append(match.group(1)) 387 388 parts = map(str.strip, source.split("=")) 389 if len(parts) == 1: 390 self.default_value = None 391 else: 392 self.default_value = parts[1] 393 394 param_decl = parts[0] 395 396 if re.match("(const|unsigned long) ", param_decl): 397 min_type_tokens = 2 398 else: 399 min_type_tokens = 1 400 401 if len(param_decl.split(" ")) > min_type_tokens: 402 parts = param_decl.split(" ") 403 self.type = " ".join(parts[:-1]) 404 self.name = parts[-1] 405 else: 406 self.type = param_decl 407 self.name = generate_param_name(self.type) 408 409 if re.match("PassRefPtr<", param_decl): 410 self.is_prp = True 411 self.value = self.name 412 self.name = "prp" + self.name[0].upper() + self.name[1:] 413 self.inner_type = re.match("PassRefPtr<(.+)>", param_decl).group(1) 414 else: 415 self.is_prp = False 416 self.value = self.name 417 418 419 def to_str_full(self): 420 if self.default_value is None: 421 return self.to_str_class_and_name() 422 return "%s %s = %s" % (self.type, self.name, self.default_value) 423 424 def to_str_class_and_name(self): 425 return "%s %s" % (self.type, self.name) 426 427 def to_str_class(self): 428 return self.type 429 430 def to_str_name(self): 431 return self.name 432 433 def to_str_value(self): 434 return self.value 435 436 437def generate_param_name(param_type): 438 base_name = re.match("(const |PassRefPtr<)?(\w*)", param_type).group(2) 439 return "param" + base_name 440 441 442def agent_class_name(agent): 443 custom_agent_names = ["PageDebugger", "PageRuntime", "WorkerRuntime"] 444 if agent in custom_agent_names: 445 return "%sAgent" % agent 446 return "Inspector%sAgent" % agent 447 448 449def agent_getter_signature(agent): 450 agent_class = agent_class_name(agent) 451 return agent_class, agent_class[0].lower() + agent_class[1:] 452 453 454def include_header(name): 455 return "#include \"%s.h\"" % name 456 457 458def include_inspector_header(name): 459 return include_header("core/inspector/" + name) 460 461 462def generate_instrumenting_agents(used_agents): 463 agents = list(used_agents) 464 465 forward_list = [] 466 accessor_list = [] 467 member_list = [] 468 init_list = [] 469 trace_list = [] 470 reset_list = [] 471 472 for agent in agents: 473 class_name, getter_name = agent_getter_signature(agent) 474 member_name = "m_" + getter_name 475 476 forward_list.append("class %s;" % class_name) 477 accessor_list.append(template_instrumenting_agent_accessor.substitute( 478 None, 479 class_name=class_name, 480 getter_name=getter_name, 481 member_name=member_name)) 482 member_list.append(" RawPtrWillBeMember<%s> %s;" % (class_name, member_name)) 483 init_list.append("%s(nullptr)" % member_name) 484 trace_list.append("visitor->trace(%s);" % member_name) 485 reset_list.append("%s = nullptr;" % member_name) 486 487 forward_list.sort() 488 accessor_list.sort() 489 member_list.sort() 490 init_list.sort() 491 trace_list.sort() 492 reset_list.sort() 493 494 header_lines = template_instrumenting_agents_h.substitute( 495 None, 496 forward_list="\n".join(forward_list), 497 accessor_list="\n".join(accessor_list), 498 member_list="\n".join(member_list)) 499 500 cpp_lines = template_instrumenting_agents_cpp.substitute( 501 None, 502 init_list="\n , ".join(init_list), 503 trace_list="\n ".join(trace_list), 504 reset_list="\n ".join(reset_list)) 505 506 return header_lines, cpp_lines 507 508 509def generate(input_path, output_dir): 510 fin = open(input_path, "r") 511 files = load_model_from_idl(fin.read()) 512 fin.close() 513 514 cpp_includes = [] 515 cpp_lines = [] 516 used_agents = set() 517 for f in files: 518 cpp_includes.append(include_header(f.header_name)) 519 520 fout = open(output_dir + "/" + f.header_name + ".h", "w") 521 fout.write(f.generate(cpp_lines, used_agents)) 522 fout.close() 523 524 for agent in used_agents: 525 cpp_includes.append(include_inspector_header(agent_class_name(agent))) 526 cpp_includes.append(include_header("InstrumentingAgentsInl")) 527 cpp_includes.sort() 528 529 instrumenting_agents_header, instrumenting_agents_cpp = generate_instrumenting_agents(used_agents) 530 531 fout = open(output_dir + "/" + "InstrumentingAgentsInl.h", "w") 532 fout.write(instrumenting_agents_header) 533 fout.close() 534 535 fout = open(output_dir + "/InspectorInstrumentationImpl.cpp", "w") 536 fout.write(template_cpp.substitute(None, 537 includes="\n".join(cpp_includes), 538 extra_definitions=instrumenting_agents_cpp, 539 methods="\n".join(cpp_lines))) 540 fout.close() 541 542 543cmdline_parser = optparse.OptionParser() 544cmdline_parser.add_option("--output_dir") 545 546try: 547 arg_options, arg_values = cmdline_parser.parse_args() 548 if (len(arg_values) != 1): 549 raise Exception("Exactly one plain argument expected (found %s)" % len(arg_values)) 550 input_path = arg_values[0] 551 output_dirpath = arg_options.output_dir 552 if not output_dirpath: 553 raise Exception("Output directory must be specified") 554except Exception: 555 # Work with python 2 and 3 http://docs.python.org/py3k/howto/pyporting.html 556 exc = sys.exc_info()[1] 557 sys.stderr.write("Failed to parse command-line arguments: %s\n\n" % exc) 558 sys.stderr.write("Usage: <script> --output_dir <output_dir> InspectorInstrumentation.idl\n") 559 exit(1) 560 561generate(input_path, output_dirpath) 562