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

Side by Side Diff: third_party/WebCore/inspector/CodeGeneratorInspector.py

Issue 12319151: WebKit IDL roll. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 9 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/env python
2 # Copyright (c) 2011 Google Inc. All rights reserved.
3 # Copyright (c) 2012 Intel Corporation. All rights reserved.
4 #
5 # Redistribution and use in source and binary forms, with or without
6 # modification, are permitted provided that the following conditions are
7 # met:
8 #
9 # * Redistributions of source code must retain the above copyright
10 # notice, this list of conditions and the following disclaimer.
11 # * Redistributions in binary form must reproduce the above
12 # copyright notice, this list of conditions and the following disclaimer
13 # in the documentation and/or other materials provided with the
14 # distribution.
15 # * Neither the name of Google Inc. nor the names of its
16 # contributors may be used to endorse or promote products derived from
17 # this software without specific prior written permission.
18 #
19 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
31 import os.path
32 import sys
33 import string
34 import optparse
35 try:
36 import json
37 except ImportError:
38 import simplejson as json
39
40 import CodeGeneratorInspectorStrings
41
42
43 DOMAIN_DEFINE_NAME_MAP = {
44 "Database": "SQL_DATABASE",
45 "Debugger": "JAVASCRIPT_DEBUGGER",
46 "DOMDebugger": "JAVASCRIPT_DEBUGGER",
47 "FileSystem": "FILE_SYSTEM",
48 "IndexedDB": "INDEXED_DATABASE",
49 "Profiler": "JAVASCRIPT_DEBUGGER",
50 "Worker": "WORKERS",
51 }
52
53
54 # Manually-filled map of type name replacements.
55 TYPE_NAME_FIX_MAP = {
56 "RGBA": "Rgba", # RGBA is reported to be conflicting with a define name in Windows CE.
57 "": "Empty",
58 }
59
60
61 TYPES_WITH_RUNTIME_CAST_SET = frozenset(["Runtime.RemoteObject", "Runtime.Proper tyDescriptor", "Runtime.InternalPropertyDescriptor",
62 "Debugger.FunctionDetails", "Debugger.C allFrame",
63 "Canvas.TraceLog", "Canvas.ResourceInfo ", "Canvas.ResourceState",
64 # This should be a temporary hack. Time lineEvent should be created via generated C++ API.
65 "Timeline.TimelineEvent"])
66
67 TYPES_WITH_OPEN_FIELD_LIST_SET = frozenset(["Timeline.TimelineEvent",
68 # InspectorStyleSheet not only creat es this property but wants to read it and modify it.
69 "CSS.CSSProperty",
70 # InspectorResourceAgent needs to up date mime-type.
71 "Network.Response"])
72
73 EXACTLY_INT_SUPPORTED = False
74
75 cmdline_parser = optparse.OptionParser()
76 cmdline_parser.add_option("--output_h_dir")
77 cmdline_parser.add_option("--output_cpp_dir")
78
79 try:
80 arg_options, arg_values = cmdline_parser.parse_args()
81 if (len(arg_values) != 1):
82 raise Exception("Exactly one plain argument expected (found %s)" % len(a rg_values))
83 input_json_filename = arg_values[0]
84 output_header_dirname = arg_options.output_h_dir
85 output_cpp_dirname = arg_options.output_cpp_dir
86 if not output_header_dirname:
87 raise Exception("Output .h directory must be specified")
88 if not output_cpp_dirname:
89 raise Exception("Output .cpp directory must be specified")
90 except Exception:
91 # Work with python 2 and 3 http://docs.python.org/py3k/howto/pyporting.html
92 exc = sys.exc_info()[1]
93 sys.stderr.write("Failed to parse command-line arguments: %s\n\n" % exc)
94 sys.stderr.write("Usage: <script> Inspector.json --output_h_dir <output_head er_dir> --output_cpp_dir <output_cpp_dir>\n")
95 exit(1)
96
97
98 def dash_to_camelcase(word):
99 return ''.join(x.capitalize() or '-' for x in word.split('-'))
100
101
102 class Capitalizer:
103 @staticmethod
104 def lower_camel_case_to_upper(str):
105 if len(str) > 0 and str[0].islower():
106 str = str[0].upper() + str[1:]
107 return str
108
109 @staticmethod
110 def upper_camel_case_to_lower(str):
111 pos = 0
112 while pos < len(str) and str[pos].isupper():
113 pos += 1
114 if pos == 0:
115 return str
116 if pos == 1:
117 return str[0].lower() + str[1:]
118 if pos < len(str):
119 pos -= 1
120 possible_abbreviation = str[0:pos]
121 if possible_abbreviation not in Capitalizer.ABBREVIATION:
122 raise Exception("Unknown abbreviation %s" % possible_abbreviation)
123 str = possible_abbreviation.lower() + str[pos:]
124 return str
125
126 @staticmethod
127 def camel_case_to_capitalized_with_underscores(str):
128 if len(str) == 0:
129 return str
130 output = Capitalizer.split_camel_case_(str)
131 return "_".join(output).upper()
132
133 @staticmethod
134 def split_camel_case_(str):
135 output = []
136 pos_being = 0
137 pos = 1
138 has_oneletter = False
139 while pos < len(str):
140 if str[pos].isupper():
141 output.append(str[pos_being:pos].upper())
142 if pos - pos_being == 1:
143 has_oneletter = True
144 pos_being = pos
145 pos += 1
146 output.append(str[pos_being:])
147 if has_oneletter:
148 array_pos = 0
149 while array_pos < len(output) - 1:
150 if len(output[array_pos]) == 1:
151 array_pos_end = array_pos + 1
152 while array_pos_end < len(output) and len(output[array_pos_e nd]) == 1:
153 array_pos_end += 1
154 if array_pos_end - array_pos > 1:
155 possible_abbreviation = "".join(output[array_pos:array_p os_end])
156 if possible_abbreviation.upper() in Capitalizer.ABBREVIA TION:
157 output[array_pos:array_pos_end] = [possible_abbrevia tion]
158 else:
159 array_pos = array_pos_end - 1
160 array_pos += 1
161 return output
162
163 ABBREVIATION = frozenset(["XHR", "DOM", "CSS"])
164
165 VALIDATOR_IFDEF_NAME = "!ASSERT_DISABLED"
166
167
168 class DomainNameFixes:
169 @classmethod
170 def get_fixed_data(cls, domain_name):
171 field_name_res = Capitalizer.upper_camel_case_to_lower(domain_name) + "A gent"
172
173 class Res(object):
174 skip_js_bind = domain_name in cls.skip_js_bind_domains
175 agent_field_name = field_name_res
176
177 @staticmethod
178 def get_guard():
179 if domain_name in DOMAIN_DEFINE_NAME_MAP:
180 define_name = DOMAIN_DEFINE_NAME_MAP[domain_name]
181
182 class Guard:
183 @staticmethod
184 def generate_open(output):
185 output.append("#if ENABLE(%s)\n" % define_name)
186
187 @staticmethod
188 def generate_close(output):
189 output.append("#endif // ENABLE(%s)\n" % define_name )
190
191 return Guard
192
193 return Res
194
195 skip_js_bind_domains = set(["DOMDebugger"])
196
197
198 class RawTypes(object):
199 @staticmethod
200 def get(json_type):
201 if json_type == "boolean":
202 return RawTypes.Bool
203 elif json_type == "string":
204 return RawTypes.String
205 elif json_type == "array":
206 return RawTypes.Array
207 elif json_type == "object":
208 return RawTypes.Object
209 elif json_type == "integer":
210 return RawTypes.Int
211 elif json_type == "number":
212 return RawTypes.Number
213 elif json_type == "any":
214 return RawTypes.Any
215 else:
216 raise Exception("Unknown type: %s" % json_type)
217
218 # For output parameter all values are passed by pointer except RefPtr-based types.
219 class OutputPassModel:
220 class ByPointer:
221 @staticmethod
222 def get_argument_prefix():
223 return "&"
224
225 @staticmethod
226 def get_parameter_type_suffix():
227 return "*"
228
229 class ByReference:
230 @staticmethod
231 def get_argument_prefix():
232 return ""
233
234 @staticmethod
235 def get_parameter_type_suffix():
236 return "&"
237
238 class BaseType(object):
239 need_internal_runtime_cast_ = False
240
241 @classmethod
242 def request_raw_internal_runtime_cast(cls):
243 if not cls.need_internal_runtime_cast_:
244 cls.need_internal_runtime_cast_ = True
245
246 @classmethod
247 def get_raw_validator_call_text(cls):
248 return "RuntimeCastHelper::assertType<InspectorValue::Type%s>" % cls .get_validate_method_params().template_type
249
250 class String(BaseType):
251 @staticmethod
252 def get_getter_name():
253 return "String"
254
255 get_setter_name = get_getter_name
256
257 @staticmethod
258 def get_c_initializer():
259 return "\"\""
260
261 @staticmethod
262 def get_js_bind_type():
263 return "string"
264
265 @staticmethod
266 def get_validate_method_params():
267 class ValidateMethodParams:
268 template_type = "String"
269 return ValidateMethodParams
270
271 @staticmethod
272 def get_output_pass_model():
273 return RawTypes.OutputPassModel.ByPointer
274
275 @staticmethod
276 def is_heavy_value():
277 return True
278
279 @staticmethod
280 def get_array_item_raw_c_type_text():
281 return "String"
282
283 @staticmethod
284 def get_raw_type_model():
285 return TypeModel.String
286
287 class Int(BaseType):
288 @staticmethod
289 def get_getter_name():
290 return "Int"
291
292 @staticmethod
293 def get_setter_name():
294 return "Number"
295
296 @staticmethod
297 def get_c_initializer():
298 return "0"
299
300 @staticmethod
301 def get_js_bind_type():
302 return "number"
303
304 @classmethod
305 def get_raw_validator_call_text(cls):
306 return "RuntimeCastHelper::assertInt"
307
308 @staticmethod
309 def get_output_pass_model():
310 return RawTypes.OutputPassModel.ByPointer
311
312 @staticmethod
313 def is_heavy_value():
314 return False
315
316 @staticmethod
317 def get_array_item_raw_c_type_text():
318 return "int"
319
320 @staticmethod
321 def get_raw_type_model():
322 return TypeModel.Int
323
324 class Number(BaseType):
325 @staticmethod
326 def get_getter_name():
327 return "Double"
328
329 @staticmethod
330 def get_setter_name():
331 return "Number"
332
333 @staticmethod
334 def get_c_initializer():
335 return "0"
336
337 @staticmethod
338 def get_js_bind_type():
339 return "number"
340
341 @staticmethod
342 def get_validate_method_params():
343 class ValidateMethodParams:
344 template_type = "Number"
345 return ValidateMethodParams
346
347 @staticmethod
348 def get_output_pass_model():
349 return RawTypes.OutputPassModel.ByPointer
350
351 @staticmethod
352 def is_heavy_value():
353 return False
354
355 @staticmethod
356 def get_array_item_raw_c_type_text():
357 return "double"
358
359 @staticmethod
360 def get_raw_type_model():
361 return TypeModel.Number
362
363 class Bool(BaseType):
364 @staticmethod
365 def get_getter_name():
366 return "Boolean"
367
368 get_setter_name = get_getter_name
369
370 @staticmethod
371 def get_c_initializer():
372 return "false"
373
374 @staticmethod
375 def get_js_bind_type():
376 return "boolean"
377
378 @staticmethod
379 def get_validate_method_params():
380 class ValidateMethodParams:
381 template_type = "Boolean"
382 return ValidateMethodParams
383
384 @staticmethod
385 def get_output_pass_model():
386 return RawTypes.OutputPassModel.ByPointer
387
388 @staticmethod
389 def is_heavy_value():
390 return False
391
392 @staticmethod
393 def get_array_item_raw_c_type_text():
394 return "bool"
395
396 @staticmethod
397 def get_raw_type_model():
398 return TypeModel.Bool
399
400 class Object(BaseType):
401 @staticmethod
402 def get_getter_name():
403 return "Object"
404
405 @staticmethod
406 def get_setter_name():
407 return "Value"
408
409 @staticmethod
410 def get_c_initializer():
411 return "InspectorObject::create()"
412
413 @staticmethod
414 def get_js_bind_type():
415 return "object"
416
417 @staticmethod
418 def get_output_argument_prefix():
419 return ""
420
421 @staticmethod
422 def get_validate_method_params():
423 class ValidateMethodParams:
424 template_type = "Object"
425 return ValidateMethodParams
426
427 @staticmethod
428 def get_output_pass_model():
429 return RawTypes.OutputPassModel.ByReference
430
431 @staticmethod
432 def is_heavy_value():
433 return True
434
435 @staticmethod
436 def get_array_item_raw_c_type_text():
437 return "InspectorObject"
438
439 @staticmethod
440 def get_raw_type_model():
441 return TypeModel.Object
442
443 class Any(BaseType):
444 @staticmethod
445 def get_getter_name():
446 return "Value"
447
448 get_setter_name = get_getter_name
449
450 @staticmethod
451 def get_c_initializer():
452 raise Exception("Unsupported")
453
454 @staticmethod
455 def get_js_bind_type():
456 raise Exception("Unsupported")
457
458 @staticmethod
459 def get_raw_validator_call_text():
460 return "RuntimeCastHelper::assertAny"
461
462 @staticmethod
463 def get_output_pass_model():
464 return RawTypes.OutputPassModel.ByReference
465
466 @staticmethod
467 def is_heavy_value():
468 return True
469
470 @staticmethod
471 def get_array_item_raw_c_type_text():
472 return "InspectorValue"
473
474 @staticmethod
475 def get_raw_type_model():
476 return TypeModel.Any
477
478 class Array(BaseType):
479 @staticmethod
480 def get_getter_name():
481 return "Array"
482
483 @staticmethod
484 def get_setter_name():
485 return "Value"
486
487 @staticmethod
488 def get_c_initializer():
489 return "InspectorArray::create()"
490
491 @staticmethod
492 def get_js_bind_type():
493 return "object"
494
495 @staticmethod
496 def get_output_argument_prefix():
497 return ""
498
499 @staticmethod
500 def get_validate_method_params():
501 class ValidateMethodParams:
502 template_type = "Array"
503 return ValidateMethodParams
504
505 @staticmethod
506 def get_output_pass_model():
507 return RawTypes.OutputPassModel.ByReference
508
509 @staticmethod
510 def is_heavy_value():
511 return True
512
513 @staticmethod
514 def get_array_item_raw_c_type_text():
515 return "InspectorArray"
516
517 @staticmethod
518 def get_raw_type_model():
519 return TypeModel.Array
520
521
522 def replace_right_shift(input_str):
523 return input_str.replace(">>", "> >")
524
525
526 class CommandReturnPassModel:
527 class ByReference:
528 def __init__(self, var_type, set_condition):
529 self.var_type = var_type
530 self.set_condition = set_condition
531
532 def get_return_var_type(self):
533 return self.var_type
534
535 @staticmethod
536 def get_output_argument_prefix():
537 return ""
538
539 @staticmethod
540 def get_output_to_raw_expression():
541 return "%s"
542
543 def get_output_parameter_type(self):
544 return self.var_type + "&"
545
546 def get_set_return_condition(self):
547 return self.set_condition
548
549 class ByPointer:
550 def __init__(self, var_type):
551 self.var_type = var_type
552
553 def get_return_var_type(self):
554 return self.var_type
555
556 @staticmethod
557 def get_output_argument_prefix():
558 return "&"
559
560 @staticmethod
561 def get_output_to_raw_expression():
562 return "%s"
563
564 def get_output_parameter_type(self):
565 return self.var_type + "*"
566
567 @staticmethod
568 def get_set_return_condition():
569 return None
570
571 class OptOutput:
572 def __init__(self, var_type):
573 self.var_type = var_type
574
575 def get_return_var_type(self):
576 return "TypeBuilder::OptOutput<%s>" % self.var_type
577
578 @staticmethod
579 def get_output_argument_prefix():
580 return "&"
581
582 @staticmethod
583 def get_output_to_raw_expression():
584 return "%s.getValue()"
585
586 def get_output_parameter_type(self):
587 return "TypeBuilder::OptOutput<%s>*" % self.var_type
588
589 @staticmethod
590 def get_set_return_condition():
591 return "%s.isAssigned()"
592
593
594 class TypeModel:
595 class RefPtrBased(object):
596 def __init__(self, class_name):
597 self.class_name = class_name
598 self.optional = False
599
600 def get_optional(self):
601 result = TypeModel.RefPtrBased(self.class_name)
602 result.optional = True
603 return result
604
605 def get_command_return_pass_model(self):
606 if self.optional:
607 set_condition = "%s"
608 else:
609 set_condition = None
610 return CommandReturnPassModel.ByReference(replace_right_shift("RefPt r<%s>" % self.class_name), set_condition)
611
612 def get_input_param_type_text(self):
613 return replace_right_shift("PassRefPtr<%s>" % self.class_name)
614
615 @staticmethod
616 def get_event_setter_expression_pattern():
617 return "%s"
618
619 class Enum(object):
620 def __init__(self, base_type_name):
621 self.type_name = base_type_name + "::Enum"
622
623 def get_optional(base_self):
624 class EnumOptional:
625 @classmethod
626 def get_optional(cls):
627 return cls
628
629 @staticmethod
630 def get_command_return_pass_model():
631 return CommandReturnPassModel.OptOutput(base_self.type_name)
632
633 @staticmethod
634 def get_input_param_type_text():
635 return base_self.type_name + "*"
636
637 @staticmethod
638 def get_event_setter_expression_pattern():
639 raise Exception("TODO")
640 return EnumOptional
641
642 def get_command_return_pass_model(self):
643 return CommandReturnPassModel.ByPointer(self.type_name)
644
645 def get_input_param_type_text(self):
646 return self.type_name
647
648 @staticmethod
649 def get_event_setter_expression_pattern():
650 return "%s"
651
652 class ValueType(object):
653 def __init__(self, type_name, is_heavy):
654 self.type_name = type_name
655 self.is_heavy = is_heavy
656
657 def get_optional(self):
658 return self.ValueOptional(self)
659
660 def get_command_return_pass_model(self):
661 return CommandReturnPassModel.ByPointer(self.type_name)
662
663 def get_input_param_type_text(self):
664 if self.is_heavy:
665 return "const %s&" % self.type_name
666 else:
667 return self.type_name
668
669 def get_opt_output_type_(self):
670 return self.type_name
671
672 @staticmethod
673 def get_event_setter_expression_pattern():
674 return "%s"
675
676 class ValueOptional:
677 def __init__(self, base):
678 self.base = base
679
680 def get_optional(self):
681 return self
682
683 def get_command_return_pass_model(self):
684 return CommandReturnPassModel.OptOutput(self.base.get_opt_output _type_())
685
686 def get_input_param_type_text(self):
687 return "const %s* const" % self.base.type_name
688
689 @staticmethod
690 def get_event_setter_expression_pattern():
691 return "*%s"
692
693 class ExactlyInt(ValueType):
694 def __init__(self):
695 TypeModel.ValueType.__init__(self, "int", False)
696
697 def get_input_param_type_text(self):
698 return "TypeBuilder::ExactlyInt"
699
700 def get_opt_output_type_(self):
701 return "TypeBuilder::ExactlyInt"
702
703 @classmethod
704 def init_class(cls):
705 cls.Bool = cls.ValueType("bool", False)
706 if EXACTLY_INT_SUPPORTED:
707 cls.Int = cls.ExactlyInt()
708 else:
709 cls.Int = cls.ValueType("int", False)
710 cls.Number = cls.ValueType("double", False)
711 cls.String = cls.ValueType("String", True,)
712 cls.Object = cls.RefPtrBased("InspectorObject")
713 cls.Array = cls.RefPtrBased("InspectorArray")
714 cls.Any = cls.RefPtrBased("InspectorValue")
715
716 TypeModel.init_class()
717
718
719 # Collection of InspectorObject class methods that are likely to be overloaded i n generated class.
720 # We must explicitly import all overloaded methods or they won't be available to user.
721 INSPECTOR_OBJECT_SETTER_NAMES = frozenset(["setValue", "setBoolean", "setNumber" , "setString", "setValue", "setObject", "setArray"])
722
723
724 def fix_type_name(json_name):
725 if json_name in TYPE_NAME_FIX_MAP:
726 fixed = TYPE_NAME_FIX_MAP[json_name]
727
728 class Result(object):
729 class_name = fixed
730
731 @staticmethod
732 def output_comment(writer):
733 writer.newline("// Type originally was named '%s'.\n" % json_nam e)
734 else:
735
736 class Result(object):
737 class_name = json_name
738
739 @staticmethod
740 def output_comment(writer):
741 pass
742
743 return Result
744
745
746 class Writer:
747 def __init__(self, output, indent):
748 self.output = output
749 self.indent = indent
750
751 def newline(self, str):
752 if (self.indent):
753 self.output.append(self.indent)
754 self.output.append(str)
755
756 def append(self, str):
757 self.output.append(str)
758
759 def newline_multiline(self, str):
760 parts = str.split('\n')
761 self.newline(parts[0])
762 for p in parts[1:]:
763 self.output.append('\n')
764 if p:
765 self.newline(p)
766
767 def append_multiline(self, str):
768 parts = str.split('\n')
769 self.append(parts[0])
770 for p in parts[1:]:
771 self.output.append('\n')
772 if p:
773 self.newline(p)
774
775 def get_indent(self):
776 return self.indent
777
778 def get_indented(self, additional_indent):
779 return Writer(self.output, self.indent + additional_indent)
780
781 def insert_writer(self, additional_indent):
782 new_output = []
783 self.output.append(new_output)
784 return Writer(new_output, self.indent + additional_indent)
785
786
787 class EnumConstants:
788 map_ = {}
789 constants_ = []
790
791 @classmethod
792 def add_constant(cls, value):
793 if value in cls.map_:
794 return cls.map_[value]
795 else:
796 pos = len(cls.map_)
797 cls.map_[value] = pos
798 cls.constants_.append(value)
799 return pos
800
801 @classmethod
802 def get_enum_constant_code(cls):
803 output = []
804 for item in cls.constants_:
805 output.append(" \"" + item + "\"")
806 return ",\n".join(output) + "\n"
807
808
809 # Typebuilder code is generated in several passes: first typedefs, then other cl asses.
810 # Manual pass management is needed because we cannot have forward declarations f or typedefs.
811 class TypeBuilderPass:
812 TYPEDEF = "typedef"
813 MAIN = "main"
814
815
816 class TypeBindings:
817 @staticmethod
818 def create_named_type_declaration(json_typable, context_domain_name, type_da ta):
819 json_type = type_data.get_json_type()
820
821 class Helper:
822 is_ad_hoc = False
823 full_name_prefix_for_use = "TypeBuilder::" + context_domain_name + " ::"
824 full_name_prefix_for_impl = "TypeBuilder::" + context_domain_name + "::"
825
826 @staticmethod
827 def write_doc(writer):
828 if "description" in json_type:
829 writer.newline("/* ")
830 writer.append(json_type["description"])
831 writer.append(" */\n")
832
833 @staticmethod
834 def add_to_forward_listener(forward_listener):
835 forward_listener.add_type_data(type_data)
836
837
838 fixed_type_name = fix_type_name(json_type["id"])
839 return TypeBindings.create_type_declaration_(json_typable, context_domai n_name, fixed_type_name, Helper)
840
841 @staticmethod
842 def create_ad_hoc_type_declaration(json_typable, context_domain_name, ad_hoc _type_context):
843 class Helper:
844 is_ad_hoc = True
845 full_name_prefix_for_use = ad_hoc_type_context.container_relative_na me_prefix
846 full_name_prefix_for_impl = ad_hoc_type_context.container_full_name_ prefix
847
848 @staticmethod
849 def write_doc(writer):
850 pass
851
852 @staticmethod
853 def add_to_forward_listener(forward_listener):
854 pass
855 fixed_type_name = ad_hoc_type_context.get_type_name_fix()
856 return TypeBindings.create_type_declaration_(json_typable, context_domai n_name, fixed_type_name, Helper)
857
858 @staticmethod
859 def create_type_declaration_(json_typable, context_domain_name, fixed_type_n ame, helper):
860 if json_typable["type"] == "string":
861 if "enum" in json_typable:
862
863 class EnumBinding:
864 need_user_runtime_cast_ = False
865 need_internal_runtime_cast_ = False
866
867 @classmethod
868 def resolve_inner(cls, resolve_context):
869 pass
870
871 @classmethod
872 def request_user_runtime_cast(cls, request):
873 if request:
874 cls.need_user_runtime_cast_ = True
875 request.acknowledge()
876
877 @classmethod
878 def request_internal_runtime_cast(cls):
879 cls.need_internal_runtime_cast_ = True
880
881 @classmethod
882 def get_code_generator(enum_binding_cls):
883 #FIXME: generate ad-hoc enums too once we figure out how to better implement them in C++.
884 comment_out = helper.is_ad_hoc
885
886 class CodeGenerator:
887 @staticmethod
888 def generate_type_builder(writer, generate_context):
889 enum = json_typable["enum"]
890 helper.write_doc(writer)
891 enum_name = fixed_type_name.class_name
892 fixed_type_name.output_comment(writer)
893 writer.newline("struct ")
894 writer.append(enum_name)
895 writer.append(" {\n")
896 writer.newline(" enum Enum {\n")
897 for enum_item in enum:
898 enum_pos = EnumConstants.add_constant(enum_i tem)
899
900 item_c_name = enum_item.replace('-', '_')
901 item_c_name = Capitalizer.lower_camel_case_t o_upper(item_c_name)
902 if item_c_name in TYPE_NAME_FIX_MAP:
903 item_c_name = TYPE_NAME_FIX_MAP[item_c_n ame]
904 writer.newline(" ")
905 writer.append(item_c_name)
906 writer.append(" = ")
907 writer.append("%s" % enum_pos)
908 writer.append(",\n")
909 writer.newline(" };\n")
910 if enum_binding_cls.need_user_runtime_cast_:
911 raise Exception("Not yet implemented")
912
913 if enum_binding_cls.need_internal_runtime_cast_:
914 writer.append("#if %s\n" % VALIDATOR_IFDEF_N AME)
915 writer.newline(" static void assertCorrec tValue(InspectorValue* value);\n")
916 writer.append("#endif // %s\n" % VALIDATOR_ IFDEF_NAME)
917
918 validator_writer = generate_context.validato r_writer
919
920 domain_fixes = DomainNameFixes.get_fixed_dat a(context_domain_name)
921 domain_guard = domain_fixes.get_guard()
922 if domain_guard:
923 domain_guard.generate_open(validator_wri ter)
924
925 validator_writer.newline("void %s%s::assertC orrectValue(InspectorValue* value)\n" % (helper.full_name_prefix_for_impl, enum_ name))
926 validator_writer.newline("{\n")
927 validator_writer.newline(" WTF::String s; \n")
928 validator_writer.newline(" bool cast_res = value->asString(&s);\n")
929 validator_writer.newline(" ASSERT(cast_re s);\n")
930 if len(enum) > 0:
931 condition_list = []
932 for enum_item in enum:
933 enum_pos = EnumConstants.add_constan t(enum_item)
934 condition_list.append("s == \"%s\"" % enum_item)
935 validator_writer.newline(" ASSERT(%s) ;\n" % " || ".join(condition_list))
936 validator_writer.newline("}\n")
937
938 if domain_guard:
939 domain_guard.generate_close(validator_wr iter)
940
941 validator_writer.newline("\n\n")
942
943 writer.newline("}; // struct ")
944 writer.append(enum_name)
945 writer.append("\n\n")
946
947 @staticmethod
948 def register_use(forward_listener):
949 pass
950
951 @staticmethod
952 def get_generate_pass_id():
953 return TypeBuilderPass.MAIN
954
955 return CodeGenerator
956
957 @classmethod
958 def get_validator_call_text(cls):
959 return helper.full_name_prefix_for_use + fixed_type_name .class_name + "::assertCorrectValue"
960
961 @classmethod
962 def get_array_item_c_type_text(cls):
963 return helper.full_name_prefix_for_use + fixed_type_name .class_name + "::Enum"
964
965 @staticmethod
966 def get_setter_value_expression_pattern():
967 return "TypeBuilder::getEnumConstantValue(%s)"
968
969 @staticmethod
970 def reduce_to_raw_type():
971 return RawTypes.String
972
973 @staticmethod
974 def get_type_model():
975 return TypeModel.Enum(helper.full_name_prefix_for_use + fixed_type_name.class_name)
976
977 return EnumBinding
978 else:
979 if helper.is_ad_hoc:
980
981 class PlainString:
982 @classmethod
983 def resolve_inner(cls, resolve_context):
984 pass
985
986 @staticmethod
987 def request_user_runtime_cast(request):
988 raise Exception("Unsupported")
989
990 @staticmethod
991 def request_internal_runtime_cast():
992 pass
993
994 @staticmethod
995 def get_code_generator():
996 return None
997
998 @classmethod
999 def get_validator_call_text(cls):
1000 return RawTypes.String.get_raw_validator_call_text()
1001
1002 @staticmethod
1003 def reduce_to_raw_type():
1004 return RawTypes.String
1005
1006 @staticmethod
1007 def get_type_model():
1008 return TypeModel.String
1009
1010 @staticmethod
1011 def get_setter_value_expression_pattern():
1012 return None
1013
1014 @classmethod
1015 def get_array_item_c_type_text(cls):
1016 return cls.reduce_to_raw_type().get_array_item_raw_c _type_text()
1017
1018 return PlainString
1019
1020 else:
1021
1022 class TypedefString:
1023 @classmethod
1024 def resolve_inner(cls, resolve_context):
1025 pass
1026
1027 @staticmethod
1028 def request_user_runtime_cast(request):
1029 raise Exception("Unsupported")
1030
1031 @staticmethod
1032 def request_internal_runtime_cast():
1033 RawTypes.String.request_raw_internal_runtime_cast()
1034
1035 @staticmethod
1036 def get_code_generator():
1037 class CodeGenerator:
1038 @staticmethod
1039 def generate_type_builder(writer, generate_conte xt):
1040 helper.write_doc(writer)
1041 fixed_type_name.output_comment(writer)
1042 writer.newline("typedef String ")
1043 writer.append(fixed_type_name.class_name)
1044 writer.append(";\n\n")
1045
1046 @staticmethod
1047 def register_use(forward_listener):
1048 pass
1049
1050 @staticmethod
1051 def get_generate_pass_id():
1052 return TypeBuilderPass.TYPEDEF
1053
1054 return CodeGenerator
1055
1056 @classmethod
1057 def get_validator_call_text(cls):
1058 return RawTypes.String.get_raw_validator_call_text()
1059
1060 @staticmethod
1061 def reduce_to_raw_type():
1062 return RawTypes.String
1063
1064 @staticmethod
1065 def get_type_model():
1066 return TypeModel.ValueType("%s%s" % (helper.full_nam e_prefix_for_use, fixed_type_name.class_name), True)
1067
1068 @staticmethod
1069 def get_setter_value_expression_pattern():
1070 return None
1071
1072 @classmethod
1073 def get_array_item_c_type_text(cls):
1074 return "const %s%s&" % (helper.full_name_prefix_for_ use, fixed_type_name.class_name)
1075
1076 return TypedefString
1077
1078 elif json_typable["type"] == "object":
1079 if "properties" in json_typable:
1080
1081 class ClassBinding:
1082 resolve_data_ = None
1083 need_user_runtime_cast_ = False
1084 need_internal_runtime_cast_ = False
1085
1086 @classmethod
1087 def resolve_inner(cls, resolve_context):
1088 if cls.resolve_data_:
1089 return
1090
1091 properties = json_typable["properties"]
1092 main = []
1093 optional = []
1094
1095 ad_hoc_type_list = []
1096
1097 for prop in properties:
1098 prop_name = prop["name"]
1099 ad_hoc_type_context = cls.AdHocTypeContextImpl(prop_ name, fixed_type_name.class_name, resolve_context, ad_hoc_type_list, helper.full _name_prefix_for_impl)
1100 binding = resolve_param_type(prop, context_domain_na me, ad_hoc_type_context)
1101
1102 code_generator = binding.get_code_generator()
1103 if code_generator:
1104 code_generator.register_use(resolve_context.forw ard_listener)
1105
1106 class PropertyData:
1107 param_type_binding = binding
1108 p = prop
1109
1110 if prop.get("optional"):
1111 optional.append(PropertyData)
1112 else:
1113 main.append(PropertyData)
1114
1115 class ResolveData:
1116 main_properties = main
1117 optional_properties = optional
1118 ad_hoc_types = ad_hoc_type_list
1119
1120 cls.resolve_data_ = ResolveData
1121
1122 for ad_hoc in ad_hoc_type_list:
1123 ad_hoc.resolve_inner(resolve_context)
1124
1125 @classmethod
1126 def request_user_runtime_cast(cls, request):
1127 if not request:
1128 return
1129 cls.need_user_runtime_cast_ = True
1130 request.acknowledge()
1131 cls.request_internal_runtime_cast()
1132
1133 @classmethod
1134 def request_internal_runtime_cast(cls):
1135 if cls.need_internal_runtime_cast_:
1136 return
1137 cls.need_internal_runtime_cast_ = True
1138 for p in cls.resolve_data_.main_properties:
1139 p.param_type_binding.request_internal_runtime_cast()
1140 for p in cls.resolve_data_.optional_properties:
1141 p.param_type_binding.request_internal_runtime_cast()
1142
1143 @classmethod
1144 def get_code_generator(class_binding_cls):
1145 class CodeGenerator:
1146 @classmethod
1147 def generate_type_builder(cls, writer, generate_cont ext):
1148 resolve_data = class_binding_cls.resolve_data_
1149 helper.write_doc(writer)
1150 class_name = fixed_type_name.class_name
1151
1152 is_open_type = (context_domain_name + "." + clas s_name) in TYPES_WITH_OPEN_FIELD_LIST_SET
1153
1154 fixed_type_name.output_comment(writer)
1155 writer.newline("class ")
1156 writer.append(class_name)
1157 writer.append(" : public ")
1158 if is_open_type:
1159 writer.append("InspectorObject")
1160 else:
1161 writer.append("InspectorObjectBase")
1162 writer.append(" {\n")
1163 writer.newline("public:\n")
1164 ad_hoc_type_writer = writer.insert_writer(" " )
1165
1166 for ad_hoc_type in resolve_data.ad_hoc_types:
1167 code_generator = ad_hoc_type.get_code_genera tor()
1168 if code_generator:
1169 code_generator.generate_type_builder(ad_ hoc_type_writer, generate_context)
1170
1171 writer.newline_multiline(
1172 """ enum {
1173 NoFieldsSet = 0,
1174 """)
1175
1176 state_enum_items = []
1177 if len(resolve_data.main_properties) > 0:
1178 pos = 0
1179 for prop_data in resolve_data.main_propertie s:
1180 item_name = Capitalizer.lower_camel_case _to_upper(prop_data.p["name"]) + "Set"
1181 state_enum_items.append(item_name)
1182 writer.newline(" %s = 1 << %s,\n" % (item_name, pos))
1183 pos += 1
1184 all_fields_set_value = "(" + (" | ".join(sta te_enum_items)) + ")"
1185 else:
1186 all_fields_set_value = "0"
1187
1188 writer.newline_multiline(CodeGeneratorInspectorS trings.class_binding_builder_part_1
1189 % (all_fields_set_value , class_name, class_name))
1190
1191 pos = 0
1192 for prop_data in resolve_data.main_properties:
1193 prop_name = prop_data.p["name"]
1194
1195 param_type_binding = prop_data.param_type_bi nding
1196 param_raw_type = param_type_binding.reduce_t o_raw_type()
1197
1198 writer.newline_multiline(CodeGeneratorInspec torStrings.class_binding_builder_part_2
1199 % (state_enum_items[pos],
1200 Capitalizer.lower_camel_case_to_upper (prop_name),
1201 param_type_binding.get_type_model().g et_input_param_type_text(),
1202 state_enum_items[pos], prop_name,
1203 param_raw_type.get_setter_name(), pro p_name,
1204 format_setter_value_expression(param_ type_binding, "value"),
1205 state_enum_items[pos]))
1206
1207 pos += 1
1208
1209 writer.newline_multiline(CodeGeneratorInspectorS trings.class_binding_builder_part_3
1210 % (class_name, class_na me, class_name, class_name, class_name))
1211
1212 writer.newline(" /*\n")
1213 writer.newline(" * Synthetic constructor:\n" )
1214 writer.newline(" * RefPtr<%s> result = %s::c reate()" % (class_name, class_name))
1215 for prop_data in resolve_data.main_properties:
1216 writer.append_multiline("\n * .set%s (...)" % Capitalizer.lower_camel_case_to_upper(prop_data.p["name"]))
1217 writer.append_multiline(";\n */\n")
1218
1219 writer.newline_multiline(CodeGeneratorInspectorS trings.class_binding_builder_part_4)
1220
1221 writer.newline(" typedef TypeBuilder::StructI temTraits ItemTraits;\n")
1222
1223 for prop_data in resolve_data.optional_propertie s:
1224 prop_name = prop_data.p["name"]
1225 param_type_binding = prop_data.param_type_bi nding
1226 setter_name = "set%s" % Capitalizer.lower_ca mel_case_to_upper(prop_name)
1227
1228 writer.append_multiline("\n void %s" % se tter_name)
1229 writer.append("(%s value)\n" % param_type_bi nding.get_type_model().get_input_param_type_text())
1230 writer.newline(" {\n")
1231 writer.newline(" this->set%s(\"%s\", %s);\n"
1232 % (param_type_binding.reduce_to_raw_type ().get_setter_name(), prop_data.p["name"],
1233 format_setter_value_expression(param_ type_binding, "value")))
1234 writer.newline(" }\n")
1235
1236
1237 if setter_name in INSPECTOR_OBJECT_SETTER_NA MES:
1238 writer.newline(" using InspectorObjec tBase::%s;\n\n" % setter_name)
1239
1240 if class_binding_cls.need_user_runtime_cast_:
1241 writer.newline(" static PassRefPtr<%s> ru ntimeCast(PassRefPtr<InspectorValue> value)\n" % class_name)
1242 writer.newline(" {\n")
1243 writer.newline(" RefPtr<InspectorObje ct> object;\n")
1244 writer.newline(" bool castRes = value ->asObject(&object);\n")
1245 writer.newline(" ASSERT_UNUSED(castRe s, castRes);\n")
1246 writer.append("#if %s\n" % VALIDATOR_IFDEF_N AME)
1247 writer.newline(" assertCorrectValue(o bject.get());\n")
1248 writer.append("#endif // %s\n" % VALIDATOR_ IFDEF_NAME)
1249 writer.newline(" COMPILE_ASSERT(sizeo f(%s) == sizeof(InspectorObjectBase), type_cast_problem);\n" % class_name)
1250 writer.newline(" return static_cast<% s*>(static_cast<InspectorObjectBase*>(object.get()));\n" % class_name)
1251 writer.newline(" }\n")
1252 writer.append("\n")
1253
1254 if class_binding_cls.need_internal_runtime_cast_ :
1255 writer.append("#if %s\n" % VALIDATOR_IFDEF_N AME)
1256 writer.newline(" static void assertCorrec tValue(InspectorValue* value);\n")
1257 writer.append("#endif // %s\n" % VALIDATOR_ IFDEF_NAME)
1258
1259 closed_field_set = (context_domain_name + ". " + class_name) not in TYPES_WITH_OPEN_FIELD_LIST_SET
1260
1261 validator_writer = generate_context.validato r_writer
1262
1263 domain_fixes = DomainNameFixes.get_fixed_dat a(context_domain_name)
1264 domain_guard = domain_fixes.get_guard()
1265 if domain_guard:
1266 domain_guard.generate_open(validator_wri ter)
1267
1268 validator_writer.newline("void %s%s::assertC orrectValue(InspectorValue* value)\n" % (helper.full_name_prefix_for_impl, class _name))
1269 validator_writer.newline("{\n")
1270 validator_writer.newline(" RefPtr<Inspect orObject> object;\n")
1271 validator_writer.newline(" bool castRes = value->asObject(&object);\n")
1272 validator_writer.newline(" ASSERT_UNUSED( castRes, castRes);\n")
1273 for prop_data in resolve_data.main_propertie s:
1274 validator_writer.newline(" {\n")
1275 it_name = "%sPos" % prop_data.p["name"]
1276 validator_writer.newline(" Inspec torObject::iterator %s;\n" % it_name)
1277 validator_writer.newline(" %s = o bject->find(\"%s\");\n" % (it_name, prop_data.p["name"]))
1278 validator_writer.newline(" ASSERT (%s != object->end());\n" % it_name)
1279 validator_writer.newline(" %s(%s- >value.get());\n" % (prop_data.param_type_binding.get_validator_call_text(), it_ name))
1280 validator_writer.newline(" }\n")
1281
1282 if closed_field_set:
1283 validator_writer.newline(" int foundP ropertiesCount = %s;\n" % len(resolve_data.main_properties))
1284
1285 for prop_data in resolve_data.optional_prope rties:
1286 validator_writer.newline(" {\n")
1287 it_name = "%sPos" % prop_data.p["name"]
1288 validator_writer.newline(" Inspec torObject::iterator %s;\n" % it_name)
1289 validator_writer.newline(" %s = o bject->find(\"%s\");\n" % (it_name, prop_data.p["name"]))
1290 validator_writer.newline(" if (%s != object->end()) {\n" % it_name)
1291 validator_writer.newline(" %s (%s->value.get());\n" % (prop_data.param_type_binding.get_validator_call_text(), it_name))
1292 if closed_field_set:
1293 validator_writer.newline(" ++foundPropertiesCount;\n")
1294 validator_writer.newline(" }\n")
1295 validator_writer.newline(" }\n")
1296
1297 if closed_field_set:
1298 validator_writer.newline(" if (foundP ropertiesCount != object->size()) {\n")
1299 validator_writer.newline(" FATAL(\" Unexpected properties in object: %s\\n\", object->toJSONString().ascii().data()) ;\n")
1300 validator_writer.newline(" }\n")
1301 validator_writer.newline("}\n")
1302
1303 if domain_guard:
1304 domain_guard.generate_close(validator_wr iter)
1305
1306 validator_writer.newline("\n\n")
1307
1308 if is_open_type:
1309 cpp_writer = generate_context.cpp_writer
1310 writer.append("\n")
1311 writer.newline(" // Property names for ty pe generated as open.\n")
1312 for prop_data in resolve_data.main_propertie s + resolve_data.optional_properties:
1313 prop_name = prop_data.p["name"]
1314 prop_field_name = Capitalizer.lower_came l_case_to_upper(prop_name)
1315 writer.newline(" static const char* % s;\n" % (prop_field_name))
1316 cpp_writer.newline("const char* %s%s::%s = \"%s\";\n" % (helper.full_name_prefix_for_impl, class_name, prop_field_name, prop_name))
1317
1318
1319 writer.newline("};\n\n")
1320
1321 @staticmethod
1322 def generate_forward_declaration(writer):
1323 class_name = fixed_type_name.class_name
1324 writer.newline("class ")
1325 writer.append(class_name)
1326 writer.append(";\n")
1327
1328 @staticmethod
1329 def register_use(forward_listener):
1330 helper.add_to_forward_listener(forward_listener)
1331
1332 @staticmethod
1333 def get_generate_pass_id():
1334 return TypeBuilderPass.MAIN
1335
1336 return CodeGenerator
1337
1338 @staticmethod
1339 def get_validator_call_text():
1340 return helper.full_name_prefix_for_use + fixed_type_name .class_name + "::assertCorrectValue"
1341
1342 @classmethod
1343 def get_array_item_c_type_text(cls):
1344 return helper.full_name_prefix_for_use + fixed_type_name .class_name
1345
1346 @staticmethod
1347 def get_setter_value_expression_pattern():
1348 return None
1349
1350 @staticmethod
1351 def reduce_to_raw_type():
1352 return RawTypes.Object
1353
1354 @staticmethod
1355 def get_type_model():
1356 return TypeModel.RefPtrBased(helper.full_name_prefix_for _use + fixed_type_name.class_name)
1357
1358 class AdHocTypeContextImpl:
1359 def __init__(self, property_name, class_name, resolve_co ntext, ad_hoc_type_list, parent_full_name_prefix):
1360 self.property_name = property_name
1361 self.class_name = class_name
1362 self.resolve_context = resolve_context
1363 self.ad_hoc_type_list = ad_hoc_type_list
1364 self.container_full_name_prefix = parent_full_name_p refix + class_name + "::"
1365 self.container_relative_name_prefix = ""
1366
1367 def get_type_name_fix(self):
1368 class NameFix:
1369 class_name = Capitalizer.lower_camel_case_to_upp er(self.property_name)
1370
1371 @staticmethod
1372 def output_comment(writer):
1373 writer.newline("// Named after property name '%s' while generating %s.\n" % (self.property_name, self.class_name))
1374
1375 return NameFix
1376
1377 def add_type(self, binding):
1378 self.ad_hoc_type_list.append(binding)
1379
1380 return ClassBinding
1381 else:
1382
1383 class PlainObjectBinding:
1384 @classmethod
1385 def resolve_inner(cls, resolve_context):
1386 pass
1387
1388 @staticmethod
1389 def request_user_runtime_cast(request):
1390 pass
1391
1392 @staticmethod
1393 def request_internal_runtime_cast():
1394 RawTypes.Object.request_raw_internal_runtime_cast()
1395
1396 @staticmethod
1397 def get_code_generator():
1398 pass
1399
1400 @staticmethod
1401 def get_validator_call_text():
1402 return "RuntimeCastHelper::assertType<InspectorValue::Ty peObject>"
1403
1404 @classmethod
1405 def get_array_item_c_type_text(cls):
1406 return cls.reduce_to_raw_type().get_array_item_raw_c_typ e_text()
1407
1408 @staticmethod
1409 def get_setter_value_expression_pattern():
1410 return None
1411
1412 @staticmethod
1413 def reduce_to_raw_type():
1414 return RawTypes.Object
1415
1416 @staticmethod
1417 def get_type_model():
1418 return TypeModel.Object
1419
1420 return PlainObjectBinding
1421 elif json_typable["type"] == "array":
1422 if "items" in json_typable:
1423
1424 ad_hoc_types = []
1425
1426 class AdHocTypeContext:
1427 container_full_name_prefix = "<not yet defined>"
1428 container_relative_name_prefix = ""
1429
1430 @staticmethod
1431 def get_type_name_fix():
1432 return fixed_type_name
1433
1434 @staticmethod
1435 def add_type(binding):
1436 ad_hoc_types.append(binding)
1437
1438 item_binding = resolve_param_type(json_typable["items"], context _domain_name, AdHocTypeContext)
1439
1440 class ArrayBinding:
1441 resolve_data_ = None
1442 need_internal_runtime_cast_ = False
1443
1444 @classmethod
1445 def resolve_inner(cls, resolve_context):
1446 if cls.resolve_data_:
1447 return
1448
1449 class ResolveData:
1450 item_type_binding = item_binding
1451 ad_hoc_type_list = ad_hoc_types
1452
1453 cls.resolve_data_ = ResolveData
1454
1455 for t in ad_hoc_types:
1456 t.resolve_inner(resolve_context)
1457
1458 @classmethod
1459 def request_user_runtime_cast(cls, request):
1460 raise Exception("Not implemented yet")
1461
1462 @classmethod
1463 def request_internal_runtime_cast(cls):
1464 if cls.need_internal_runtime_cast_:
1465 return
1466 cls.need_internal_runtime_cast_ = True
1467 cls.resolve_data_.item_type_binding.request_internal_run time_cast()
1468
1469 @classmethod
1470 def get_code_generator(array_binding_cls):
1471
1472 class CodeGenerator:
1473 @staticmethod
1474 def generate_type_builder(writer, generate_context):
1475 ad_hoc_type_writer = writer
1476
1477 resolve_data = array_binding_cls.resolve_data_
1478
1479 for ad_hoc_type in resolve_data.ad_hoc_type_list :
1480 code_generator = ad_hoc_type.get_code_genera tor()
1481 if code_generator:
1482 code_generator.generate_type_builder(ad_ hoc_type_writer, generate_context)
1483
1484 @staticmethod
1485 def generate_forward_declaration(writer):
1486 pass
1487
1488 @staticmethod
1489 def register_use(forward_listener):
1490 item_code_generator = item_binding.get_code_gene rator()
1491 if item_code_generator:
1492 item_code_generator.register_use(forward_lis tener)
1493
1494 @staticmethod
1495 def get_generate_pass_id():
1496 return TypeBuilderPass.MAIN
1497
1498 return CodeGenerator
1499
1500 @classmethod
1501 def get_validator_call_text(cls):
1502 return cls.get_array_item_c_type_text() + "::assertCorre ctValue"
1503
1504 @classmethod
1505 def get_array_item_c_type_text(cls):
1506 return replace_right_shift("TypeBuilder::Array<%s>" % cl s.resolve_data_.item_type_binding.get_array_item_c_type_text())
1507
1508 @staticmethod
1509 def get_setter_value_expression_pattern():
1510 return None
1511
1512 @staticmethod
1513 def reduce_to_raw_type():
1514 return RawTypes.Array
1515
1516 @classmethod
1517 def get_type_model(cls):
1518 return TypeModel.RefPtrBased(cls.get_array_item_c_type_t ext())
1519
1520 return ArrayBinding
1521 else:
1522 # Fall-through to raw type.
1523 pass
1524
1525 raw_type = RawTypes.get(json_typable["type"])
1526
1527 return RawTypeBinding(raw_type)
1528
1529
1530 class RawTypeBinding:
1531 def __init__(self, raw_type):
1532 self.raw_type_ = raw_type
1533
1534 def resolve_inner(self, resolve_context):
1535 pass
1536
1537 def request_user_runtime_cast(self, request):
1538 raise Exception("Unsupported")
1539
1540 def request_internal_runtime_cast(self):
1541 self.raw_type_.request_raw_internal_runtime_cast()
1542
1543 def get_code_generator(self):
1544 return None
1545
1546 def get_validator_call_text(self):
1547 return self.raw_type_.get_raw_validator_call_text()
1548
1549 def get_array_item_c_type_text(self):
1550 return self.raw_type_.get_array_item_raw_c_type_text()
1551
1552 def get_setter_value_expression_pattern(self):
1553 return None
1554
1555 def reduce_to_raw_type(self):
1556 return self.raw_type_
1557
1558 def get_type_model(self):
1559 return self.raw_type_.get_raw_type_model()
1560
1561
1562 class TypeData(object):
1563 def __init__(self, json_type, json_domain, domain_data):
1564 self.json_type_ = json_type
1565 self.json_domain_ = json_domain
1566 self.domain_data_ = domain_data
1567
1568 if "type" not in json_type:
1569 raise Exception("Unknown type")
1570
1571 json_type_name = json_type["type"]
1572 raw_type = RawTypes.get(json_type_name)
1573 self.raw_type_ = raw_type
1574 self.binding_being_resolved_ = False
1575 self.binding_ = None
1576
1577 def get_raw_type(self):
1578 return self.raw_type_
1579
1580 def get_binding(self):
1581 if not self.binding_:
1582 if self.binding_being_resolved_:
1583 raise Error("Type %s is already being resolved" % self.json_type _["type"])
1584 # Resolve only lazily, because resolving one named type may require resolving some other named type.
1585 self.binding_being_resolved_ = True
1586 try:
1587 self.binding_ = TypeBindings.create_named_type_declaration(self. json_type_, self.json_domain_["domain"], self)
1588 finally:
1589 self.binding_being_resolved_ = False
1590
1591 return self.binding_
1592
1593 def get_json_type(self):
1594 return self.json_type_
1595
1596 def get_name(self):
1597 return self.json_type_["id"]
1598
1599 def get_domain_name(self):
1600 return self.json_domain_["domain"]
1601
1602
1603 class DomainData:
1604 def __init__(self, json_domain):
1605 self.json_domain = json_domain
1606 self.types_ = []
1607
1608 def add_type(self, type_data):
1609 self.types_.append(type_data)
1610
1611 def name(self):
1612 return self.json_domain["domain"]
1613
1614 def types(self):
1615 return self.types_
1616
1617
1618 class TypeMap:
1619 def __init__(self, api):
1620 self.map_ = {}
1621 self.domains_ = []
1622 for json_domain in api["domains"]:
1623 domain_name = json_domain["domain"]
1624
1625 domain_map = {}
1626 self.map_[domain_name] = domain_map
1627
1628 domain_data = DomainData(json_domain)
1629 self.domains_.append(domain_data)
1630
1631 if "types" in json_domain:
1632 for json_type in json_domain["types"]:
1633 type_name = json_type["id"]
1634 type_data = TypeData(json_type, json_domain, domain_data)
1635 domain_map[type_name] = type_data
1636 domain_data.add_type(type_data)
1637
1638 def domains(self):
1639 return self.domains_
1640
1641 def get(self, domain_name, type_name):
1642 return self.map_[domain_name][type_name]
1643
1644
1645 def resolve_param_type(json_parameter, scope_domain_name, ad_hoc_type_context):
1646 if "$ref" in json_parameter:
1647 json_ref = json_parameter["$ref"]
1648 type_data = get_ref_data(json_ref, scope_domain_name)
1649 return type_data.get_binding()
1650 elif "type" in json_parameter:
1651 result = TypeBindings.create_ad_hoc_type_declaration(json_parameter, sco pe_domain_name, ad_hoc_type_context)
1652 ad_hoc_type_context.add_type(result)
1653 return result
1654 else:
1655 raise Exception("Unknown type")
1656
1657 def resolve_param_raw_type(json_parameter, scope_domain_name):
1658 if "$ref" in json_parameter:
1659 json_ref = json_parameter["$ref"]
1660 type_data = get_ref_data(json_ref, scope_domain_name)
1661 return type_data.get_raw_type()
1662 elif "type" in json_parameter:
1663 json_type = json_parameter["type"]
1664 return RawTypes.get(json_type)
1665 else:
1666 raise Exception("Unknown type")
1667
1668
1669 def get_ref_data(json_ref, scope_domain_name):
1670 dot_pos = json_ref.find(".")
1671 if dot_pos == -1:
1672 domain_name = scope_domain_name
1673 type_name = json_ref
1674 else:
1675 domain_name = json_ref[:dot_pos]
1676 type_name = json_ref[dot_pos + 1:]
1677
1678 return type_map.get(domain_name, type_name)
1679
1680
1681 input_file = open(input_json_filename, "r")
1682 json_string = input_file.read()
1683 json_api = json.loads(json_string)
1684
1685
1686 class Templates:
1687 def get_this_script_path_(absolute_path):
1688 absolute_path = os.path.abspath(absolute_path)
1689 components = []
1690
1691 def fill_recursive(path_part, depth):
1692 if depth <= 0 or path_part == '/':
1693 return
1694 fill_recursive(os.path.dirname(path_part), depth - 1)
1695 components.append(os.path.basename(path_part))
1696
1697 # Typical path is /Source/WebCore/inspector/CodeGeneratorInspector.py
1698 # Let's take 4 components from the real path then.
1699 fill_recursive(absolute_path, 4)
1700
1701 return "/".join(components)
1702
1703 file_header_ = ("// File is generated by %s\n\n" % get_this_script_path_(sys .argv[0]) +
1704 """// Copyright (c) 2011 The Chromium Authors. All rights reserved.
1705 // Use of this source code is governed by a BSD-style license that can be
1706 // found in the LICENSE file.
1707 """)
1708
1709 frontend_domain_class = string.Template(CodeGeneratorInspectorStrings.fronte nd_domain_class)
1710 backend_method = string.Template(CodeGeneratorInspectorStrings.backend_metho d)
1711 frontend_method = string.Template(CodeGeneratorInspectorStrings.frontend_met hod)
1712 callback_method = string.Template(CodeGeneratorInspectorStrings.callback_met hod)
1713 frontend_h = string.Template(file_header_ + CodeGeneratorInspectorStrings.fr ontend_h)
1714 backend_h = string.Template(file_header_ + CodeGeneratorInspectorStrings.bac kend_h)
1715 backend_cpp = string.Template(file_header_ + CodeGeneratorInspectorStrings.b ackend_cpp)
1716 frontend_cpp = string.Template(file_header_ + CodeGeneratorInspectorStrings. frontend_cpp)
1717 typebuilder_h = string.Template(file_header_ + CodeGeneratorInspectorStrings .typebuilder_h)
1718 typebuilder_cpp = string.Template(file_header_ + CodeGeneratorInspectorStrin gs.typebuilder_cpp)
1719 backend_js = string.Template(file_header_ + CodeGeneratorInspectorStrings.ba ckend_js)
1720 param_container_access_code = CodeGeneratorInspectorStrings.param_container_ access_code
1721
1722
1723
1724
1725
1726 type_map = TypeMap(json_api)
1727
1728
1729 class NeedRuntimeCastRequest:
1730 def __init__(self):
1731 self.ack_ = None
1732
1733 def acknowledge(self):
1734 self.ack_ = True
1735
1736 def is_acknowledged(self):
1737 return self.ack_
1738
1739
1740 def resolve_all_types():
1741 runtime_cast_generate_requests = {}
1742 for type_name in TYPES_WITH_RUNTIME_CAST_SET:
1743 runtime_cast_generate_requests[type_name] = NeedRuntimeCastRequest()
1744
1745 class ForwardListener:
1746 type_data_set = set()
1747 already_declared_set = set()
1748
1749 @classmethod
1750 def add_type_data(cls, type_data):
1751 if type_data not in cls.already_declared_set:
1752 cls.type_data_set.add(type_data)
1753
1754 class ResolveContext:
1755 forward_listener = ForwardListener
1756
1757 for domain_data in type_map.domains():
1758 for type_data in domain_data.types():
1759 # Do not generate forwards for this type any longer.
1760 ForwardListener.already_declared_set.add(type_data)
1761
1762 binding = type_data.get_binding()
1763 binding.resolve_inner(ResolveContext)
1764
1765 for domain_data in type_map.domains():
1766 for type_data in domain_data.types():
1767 full_type_name = "%s.%s" % (type_data.get_domain_name(), type_data.g et_name())
1768 request = runtime_cast_generate_requests.pop(full_type_name, None)
1769 binding = type_data.get_binding()
1770 if request:
1771 binding.request_user_runtime_cast(request)
1772
1773 if request and not request.is_acknowledged():
1774 raise Exception("Failed to generate runtimeCast in " + full_type _name)
1775
1776 for full_type_name in runtime_cast_generate_requests:
1777 raise Exception("Failed to generate runtimeCast. Type " + full_type_name + " not found")
1778
1779 return ForwardListener
1780
1781
1782 global_forward_listener = resolve_all_types()
1783
1784
1785 def get_annotated_type_text(raw_type, annotated_type):
1786 if annotated_type != raw_type:
1787 return "/*%s*/ %s" % (annotated_type, raw_type)
1788 else:
1789 return raw_type
1790
1791
1792 def format_setter_value_expression(param_type_binding, value_ref):
1793 pattern = param_type_binding.get_setter_value_expression_pattern()
1794 if pattern:
1795 return pattern % value_ref
1796 else:
1797 return value_ref
1798
1799 class Generator:
1800 frontend_class_field_lines = []
1801 frontend_domain_class_lines = []
1802
1803 method_name_enum_list = []
1804 backend_method_declaration_list = []
1805 backend_method_implementation_list = []
1806 backend_method_name_declaration_list = []
1807 method_handler_list = []
1808 frontend_method_list = []
1809 backend_js_domain_initializer_list = []
1810
1811 backend_virtual_setters_list = []
1812 backend_agent_interface_list = []
1813 backend_setters_list = []
1814 backend_constructor_init_list = []
1815 backend_field_list = []
1816 frontend_constructor_init_list = []
1817 type_builder_fragments = []
1818 type_builder_forwards = []
1819 validator_impl_list = []
1820 type_builder_impl_list = []
1821
1822
1823 @staticmethod
1824 def go():
1825 Generator.process_types(type_map)
1826
1827 first_cycle_guardable_list_list = [
1828 Generator.backend_method_declaration_list,
1829 Generator.backend_method_implementation_list,
1830 Generator.backend_method_name_declaration_list,
1831 Generator.backend_agent_interface_list,
1832 Generator.frontend_class_field_lines,
1833 Generator.frontend_constructor_init_list,
1834 Generator.frontend_domain_class_lines,
1835 Generator.frontend_method_list,
1836 Generator.method_handler_list,
1837 Generator.method_name_enum_list,
1838 Generator.backend_constructor_init_list,
1839 Generator.backend_virtual_setters_list,
1840 Generator.backend_setters_list,
1841 Generator.backend_field_list]
1842
1843 for json_domain in json_api["domains"]:
1844 domain_name = json_domain["domain"]
1845 domain_name_lower = domain_name.lower()
1846
1847 domain_fixes = DomainNameFixes.get_fixed_data(domain_name)
1848
1849 domain_guard = domain_fixes.get_guard()
1850
1851 if domain_guard:
1852 for l in first_cycle_guardable_list_list:
1853 domain_guard.generate_open(l)
1854
1855 agent_field_name = domain_fixes.agent_field_name
1856
1857 frontend_method_declaration_lines = []
1858
1859 Generator.backend_js_domain_initializer_list.append("// %s.\n" % dom ain_name)
1860
1861 if not domain_fixes.skip_js_bind:
1862 Generator.backend_js_domain_initializer_list.append("InspectorBa ckend.register%sDispatcher = InspectorBackend.registerDomainDispatcher.bind(Insp ectorBackend, \"%s\");\n" % (domain_name, domain_name))
1863
1864 if "events" in json_domain:
1865 for json_event in json_domain["events"]:
1866 Generator.process_event(json_event, domain_name, frontend_me thod_declaration_lines)
1867
1868 Generator.frontend_class_field_lines.append(" %s m_%s;\n" % (doma in_name, domain_name_lower))
1869 if Generator.frontend_constructor_init_list:
1870 Generator.frontend_constructor_init_list.append(" , ")
1871 Generator.frontend_constructor_init_list.append("m_%s(inspectorFront endChannel)\n" % domain_name_lower)
1872 Generator.frontend_domain_class_lines.append(Templates.frontend_doma in_class.substitute(None,
1873 domainClassName=domain_name,
1874 domainFieldName=domain_name_lower,
1875 frontendDomainMethodDeclarations="".join(flatten_list(frontend_m ethod_declaration_lines))))
1876
1877 agent_interface_name = Capitalizer.lower_camel_case_to_upper(domain_ name) + "CommandHandler"
1878 Generator.backend_agent_interface_list.append(" class %s {\n" % a gent_interface_name)
1879 Generator.backend_agent_interface_list.append(" public:\n")
1880 if "commands" in json_domain:
1881 for json_command in json_domain["commands"]:
1882 Generator.process_command(json_command, domain_name, agent_f ield_name, agent_interface_name)
1883 Generator.backend_agent_interface_list.append("\n protected:\n")
1884 Generator.backend_agent_interface_list.append(" virtual ~%s() { }\n" % agent_interface_name)
1885 Generator.backend_agent_interface_list.append(" };\n\n")
1886
1887 Generator.backend_constructor_init_list.append(" , m_%s(0)" % agent_field_name)
1888 Generator.backend_virtual_setters_list.append(" virtual void regi sterAgent(%s* %s) = 0;" % (agent_interface_name, agent_field_name))
1889 Generator.backend_setters_list.append(" virtual void registerAgen t(%s* %s) { ASSERT(!m_%s); m_%s = %s; }" % (agent_interface_name, agent_field_na me, agent_field_name, agent_field_name, agent_field_name))
1890 Generator.backend_field_list.append(" %s* m_%s;" % (agent_interfa ce_name, agent_field_name))
1891
1892 if domain_guard:
1893 for l in reversed(first_cycle_guardable_list_list):
1894 domain_guard.generate_close(l)
1895 Generator.backend_js_domain_initializer_list.append("\n")
1896
1897 @staticmethod
1898 def process_event(json_event, domain_name, frontend_method_declaration_lines ):
1899 event_name = json_event["name"]
1900
1901 ad_hoc_type_output = []
1902 frontend_method_declaration_lines.append(ad_hoc_type_output)
1903 ad_hoc_type_writer = Writer(ad_hoc_type_output, " ")
1904
1905 decl_parameter_list = []
1906
1907 json_parameters = json_event.get("parameters")
1908 Generator.generate_send_method(json_parameters, event_name, domain_name, ad_hoc_type_writer,
1909 decl_parameter_list,
1910 Generator.EventMethodStructTemplate,
1911 Generator.frontend_method_list, Templates .frontend_method, {"eventName": event_name})
1912
1913 backend_js_event_param_list = []
1914 if json_parameters:
1915 for parameter in json_parameters:
1916 parameter_name = parameter["name"]
1917 backend_js_event_param_list.append("\"%s\"" % parameter_name)
1918
1919 frontend_method_declaration_lines.append(
1920 " void %s(%s);\n" % (event_name, ", ".join(decl_parameter_lis t)))
1921
1922 Generator.backend_js_domain_initializer_list.append("InspectorBackend.re gisterEvent(\"%s.%s\", [%s]);\n" % (
1923 domain_name, event_name, ", ".join(backend_js_event_param_list)))
1924
1925 class EventMethodStructTemplate:
1926 @staticmethod
1927 def append_prolog(line_list):
1928 line_list.append(" RefPtr<InspectorObject> paramsObject = Inspect orObject::create();\n")
1929
1930 @staticmethod
1931 def append_epilog(line_list):
1932 line_list.append(" jsonMessage->setObject(\"params\", paramsObjec t);\n")
1933
1934 container_name = "paramsObject"
1935
1936 @staticmethod
1937 def process_command(json_command, domain_name, agent_field_name, agent_inter face_name):
1938 json_command_name = json_command["name"]
1939
1940 cmd_enum_name = "k%s_%sCmd" % (domain_name, json_command["name"])
1941
1942 Generator.method_name_enum_list.append(" %s," % cmd_enum_name)
1943 Generator.method_handler_list.append(" &InspectorBackendDispa tcherImpl::%s_%s," % (domain_name, json_command_name))
1944 Generator.backend_method_declaration_list.append(" void %s_%s(long ca llId, InspectorObject* requestMessageObject);" % (domain_name, json_command_name ))
1945
1946 ad_hoc_type_output = []
1947 Generator.backend_agent_interface_list.append(ad_hoc_type_output)
1948 ad_hoc_type_writer = Writer(ad_hoc_type_output, " ")
1949
1950 Generator.backend_agent_interface_list.append(" virtual void %s(E rrorString*" % json_command_name)
1951
1952 method_in_code = ""
1953 method_out_code = ""
1954 agent_call_param_list = []
1955 response_cook_list = []
1956 request_message_param = ""
1957 js_parameters_text = ""
1958 if "parameters" in json_command:
1959 json_params = json_command["parameters"]
1960 method_in_code += Templates.param_container_access_code
1961 request_message_param = " requestMessageObject"
1962 js_param_list = []
1963
1964 for json_parameter in json_params:
1965 json_param_name = json_parameter["name"]
1966 param_raw_type = resolve_param_raw_type(json_parameter, domain_n ame)
1967
1968 getter_name = param_raw_type.get_getter_name()
1969
1970 optional = json_parameter.get("optional")
1971
1972 non_optional_type_model = param_raw_type.get_raw_type_model()
1973 if optional:
1974 type_model = non_optional_type_model.get_optional()
1975 else:
1976 type_model = non_optional_type_model
1977
1978 if optional:
1979 code = (" bool %s_valueFound = false;\n"
1980 " %s in_%s = get%s(paramsContainerPtr, \"%s\", &% s_valueFound, protocolErrorsPtr);\n" %
1981 (json_param_name, non_optional_type_model.get_command _return_pass_model().get_return_var_type(), json_param_name, getter_name, json_p aram_name, json_param_name))
1982 param = ", %s_valueFound ? &in_%s : 0" % (json_param_name, j son_param_name)
1983 # FIXME: pass optional refptr-values as PassRefPtr
1984 formal_param_type_pattern = "const %s*"
1985 else:
1986 code = (" %s in_%s = get%s(paramsContainerPtr, \"%s\", 0, protocolErrorsPtr);\n" %
1987 (non_optional_type_model.get_command_return_pass_mod el().get_return_var_type(), json_param_name, getter_name, json_param_name))
1988 param = ", in_%s" % json_param_name
1989 # FIXME: pass not-optional refptr-values as NonNullPassRefPt r
1990 if param_raw_type.is_heavy_value():
1991 formal_param_type_pattern = "const %s&"
1992 else:
1993 formal_param_type_pattern = "%s"
1994
1995 method_in_code += code
1996 agent_call_param_list.append(param)
1997 Generator.backend_agent_interface_list.append(", %s in_%s" % (fo rmal_param_type_pattern % non_optional_type_model.get_command_return_pass_model( ).get_return_var_type(), json_param_name))
1998
1999 js_bind_type = param_raw_type.get_js_bind_type()
2000 js_param_text = "{\"name\": \"%s\", \"type\": \"%s\", \"optional \": %s}" % (
2001 json_param_name,
2002 js_bind_type,
2003 ("true" if ("optional" in json_parameter and json_parameter[ "optional"]) else "false"))
2004
2005 js_param_list.append(js_param_text)
2006
2007 js_parameters_text = ", ".join(js_param_list)
2008
2009 response_cook_text = ""
2010 if json_command.get("async") == True:
2011 callback_name = Capitalizer.lower_camel_case_to_upper(json_command_n ame) + "Callback"
2012
2013 callback_output = []
2014 callback_writer = Writer(callback_output, ad_hoc_type_writer.get_ind ent())
2015
2016 decl_parameter_list = []
2017 Generator.generate_send_method(json_command.get("returns"), json_com mand_name, domain_name, ad_hoc_type_writer,
2018 decl_parameter_list,
2019 Generator.CallbackMethodStructTemplat e,
2020 Generator.backend_method_implementati on_list, Templates.callback_method,
2021 {"callbackName": callback_name, "agen tName": agent_interface_name})
2022
2023 callback_writer.newline("class " + callback_name + " : public Callba ckBase {\n")
2024 callback_writer.newline("public:\n")
2025 callback_writer.newline(" " + callback_name + "(PassRefPtr<Inspec torBackendDispatcherImpl>, int id);\n")
2026 callback_writer.newline(" void sendSuccess(" + ", ".join(decl_par ameter_list) + ");\n")
2027 callback_writer.newline("};\n")
2028
2029 ad_hoc_type_output.append(callback_output)
2030
2031 method_out_code += " RefPtr<" + agent_interface_name + "::" + cal lback_name + "> callback = adoptRef(new " + agent_interface_name + "::" + callba ck_name + "(this, callId));\n"
2032 agent_call_param_list.append(", callback")
2033 response_cook_text += " if (!error.length()) \n"
2034 response_cook_text += " return;\n"
2035 response_cook_text += " callback->disable();\n"
2036 Generator.backend_agent_interface_list.append(", PassRefPtr<%s> call back" % callback_name)
2037 else:
2038 if "returns" in json_command:
2039 method_out_code += "\n"
2040 for json_return in json_command["returns"]:
2041
2042 json_return_name = json_return["name"]
2043
2044 optional = bool(json_return.get("optional"))
2045
2046 return_type_binding = Generator.resolve_type_and_generate_ad _hoc(json_return, json_command_name, domain_name, ad_hoc_type_writer, agent_inte rface_name + "::")
2047
2048 raw_type = return_type_binding.reduce_to_raw_type()
2049 setter_type = raw_type.get_setter_name()
2050 initializer = raw_type.get_c_initializer()
2051
2052 type_model = return_type_binding.get_type_model()
2053 if optional:
2054 type_model = type_model.get_optional()
2055
2056 code = " %s out_%s;\n" % (type_model.get_command_return_p ass_model().get_return_var_type(), json_return_name)
2057 param = ", %sout_%s" % (type_model.get_command_return_pass_m odel().get_output_argument_prefix(), json_return_name)
2058 var_name = "out_%s" % json_return_name
2059 setter_argument = type_model.get_command_return_pass_model() .get_output_to_raw_expression() % var_name
2060 if return_type_binding.get_setter_value_expression_pattern() :
2061 setter_argument = return_type_binding.get_setter_value_e xpression_pattern() % setter_argument
2062
2063 cook = " result->set%s(\"%s\", %s);\n" % (setter_ type, json_return_name,
2064 setter_ argument)
2065
2066 set_condition_pattern = type_model.get_command_return_pass_m odel().get_set_return_condition()
2067 if set_condition_pattern:
2068 cook = (" if (%s)\n " % (set_condition_pat tern % var_name)) + cook
2069 annotated_type = type_model.get_command_return_pass_model(). get_output_parameter_type()
2070
2071 param_name = "out_%s" % json_return_name
2072 if optional:
2073 param_name = "opt_" + param_name
2074
2075 Generator.backend_agent_interface_list.append(", %s %s" % (a nnotated_type, param_name))
2076 response_cook_list.append(cook)
2077
2078 method_out_code += code
2079 agent_call_param_list.append(param)
2080
2081 response_cook_text = "".join(response_cook_list)
2082
2083 if len(response_cook_text) != 0:
2084 response_cook_text = " if (!error.length()) {\n" + re sponse_cook_text + " }"
2085
2086 backend_js_reply_param_list = []
2087 if "returns" in json_command:
2088 for json_return in json_command["returns"]:
2089 json_return_name = json_return["name"]
2090 backend_js_reply_param_list.append("\"%s\"" % json_return_name)
2091
2092 js_reply_list = "[%s]" % ", ".join(backend_js_reply_param_list)
2093
2094 Generator.backend_method_implementation_list.append(Templates.backend_me thod.substitute(None,
2095 domainName=domain_name, methodName=json_command_name,
2096 agentField="m_" + agent_field_name,
2097 methodInCode=method_in_code,
2098 methodOutCode=method_out_code,
2099 agentCallParams="".join(agent_call_param_list),
2100 requestMessageObject=request_message_param,
2101 responseCook=response_cook_text,
2102 commandNameIndex=cmd_enum_name))
2103 Generator.backend_method_name_declaration_list.append(" \"%s.%s\"," % (domain_name, json_command_name))
2104
2105 Generator.backend_js_domain_initializer_list.append("InspectorBackend.re gisterCommand(\"%s.%s\", [%s], %s);\n" % (domain_name, json_command_name, js_par ameters_text, js_reply_list))
2106 Generator.backend_agent_interface_list.append(") = 0;\n")
2107
2108 class CallbackMethodStructTemplate:
2109 @staticmethod
2110 def append_prolog(line_list):
2111 pass
2112
2113 @staticmethod
2114 def append_epilog(line_list):
2115 pass
2116
2117 container_name = "jsonMessage"
2118
2119 # Generates common code for event sending and callback response data sending .
2120 @staticmethod
2121 def generate_send_method(parameters, event_name, domain_name, ad_hoc_type_wr iter, decl_parameter_list,
2122 method_struct_template,
2123 generator_method_list, method_template, template_pa rams):
2124 method_line_list = []
2125 if parameters:
2126 method_struct_template.append_prolog(method_line_list)
2127 for json_parameter in parameters:
2128 parameter_name = json_parameter["name"]
2129
2130 param_type_binding = Generator.resolve_type_and_generate_ad_hoc( json_parameter, event_name, domain_name, ad_hoc_type_writer, "")
2131
2132 raw_type = param_type_binding.reduce_to_raw_type()
2133 raw_type_binding = RawTypeBinding(raw_type)
2134
2135 optional = bool(json_parameter.get("optional"))
2136
2137 setter_type = raw_type.get_setter_name()
2138
2139 type_model = param_type_binding.get_type_model()
2140 raw_type_model = raw_type_binding.get_type_model()
2141 if optional:
2142 type_model = type_model.get_optional()
2143 raw_type_model = raw_type_model.get_optional()
2144
2145 annotated_type = type_model.get_input_param_type_text()
2146 mode_type_binding = param_type_binding
2147
2148 decl_parameter_list.append("%s %s" % (annotated_type, parameter_ name))
2149
2150 setter_argument = raw_type_model.get_event_setter_expression_pat tern() % parameter_name
2151 if mode_type_binding.get_setter_value_expression_pattern():
2152 setter_argument = mode_type_binding.get_setter_value_express ion_pattern() % setter_argument
2153
2154 setter_code = " %s->set%s(\"%s\", %s);\n" % (method_struct_te mplate.container_name, setter_type, parameter_name, setter_argument)
2155 if optional:
2156 setter_code = (" if (%s)\n " % parameter_name) + sette r_code
2157 method_line_list.append(setter_code)
2158
2159 method_struct_template.append_epilog(method_line_list)
2160
2161 generator_method_list.append(method_template.substitute(None,
2162 domainName=domain_name,
2163 parameters=", ".join(decl_parameter_list),
2164 code="".join(method_line_list), **template_params))
2165
2166 @staticmethod
2167 def resolve_type_and_generate_ad_hoc(json_param, method_name, domain_name, a d_hoc_type_writer, container_relative_name_prefix_param):
2168 param_name = json_param["name"]
2169 ad_hoc_type_list = []
2170
2171 class AdHocTypeContext:
2172 container_full_name_prefix = "<not yet defined>"
2173 container_relative_name_prefix = container_relative_name_prefix_para m
2174
2175 @staticmethod
2176 def get_type_name_fix():
2177 class NameFix:
2178 class_name = Capitalizer.lower_camel_case_to_upper(param_nam e)
2179
2180 @staticmethod
2181 def output_comment(writer):
2182 writer.newline("// Named after parameter '%s' while gene rating command/event %s.\n" % (param_name, method_name))
2183
2184 return NameFix
2185
2186 @staticmethod
2187 def add_type(binding):
2188 ad_hoc_type_list.append(binding)
2189
2190 type_binding = resolve_param_type(json_param, domain_name, AdHocTypeCont ext)
2191
2192 class InterfaceForwardListener:
2193 @staticmethod
2194 def add_type_data(type_data):
2195 pass
2196
2197 class InterfaceResolveContext:
2198 forward_listener = InterfaceForwardListener
2199
2200 for type in ad_hoc_type_list:
2201 type.resolve_inner(InterfaceResolveContext)
2202
2203 class InterfaceGenerateContext:
2204 validator_writer = "not supported in InterfaceGenerateContext"
2205 cpp_writer = validator_writer
2206
2207 for type in ad_hoc_type_list:
2208 generator = type.get_code_generator()
2209 if generator:
2210 generator.generate_type_builder(ad_hoc_type_writer, InterfaceGen erateContext)
2211
2212 return type_binding
2213
2214 @staticmethod
2215 def process_types(type_map):
2216 output = Generator.type_builder_fragments
2217
2218 class GenerateContext:
2219 validator_writer = Writer(Generator.validator_impl_list, "")
2220 cpp_writer = Writer(Generator.type_builder_impl_list, "")
2221
2222 def generate_all_domains_code(out, type_data_callback):
2223 writer = Writer(out, "")
2224 for domain_data in type_map.domains():
2225 domain_fixes = DomainNameFixes.get_fixed_data(domain_data.name() )
2226 domain_guard = domain_fixes.get_guard()
2227
2228 namespace_declared = []
2229
2230 def namespace_lazy_generator():
2231 if not namespace_declared:
2232 if domain_guard:
2233 domain_guard.generate_open(out)
2234 writer.newline("namespace ")
2235 writer.append(domain_data.name())
2236 writer.append(" {\n")
2237 # What is a better way to change value from outer scope?
2238 namespace_declared.append(True)
2239 return writer
2240
2241 for type_data in domain_data.types():
2242 type_data_callback(type_data, namespace_lazy_generator)
2243
2244 if namespace_declared:
2245 writer.append("} // ")
2246 writer.append(domain_data.name())
2247 writer.append("\n\n")
2248
2249 if domain_guard:
2250 domain_guard.generate_close(out)
2251
2252 def create_type_builder_caller(generate_pass_id):
2253 def call_type_builder(type_data, writer_getter):
2254 code_generator = type_data.get_binding().get_code_generator()
2255 if code_generator and generate_pass_id == code_generator.get_gen erate_pass_id():
2256 writer = writer_getter()
2257
2258 code_generator.generate_type_builder(writer, GenerateContext )
2259 return call_type_builder
2260
2261 generate_all_domains_code(output, create_type_builder_caller(TypeBuilder Pass.MAIN))
2262
2263 Generator.type_builder_forwards.append("// Forward declarations.\n")
2264
2265 def generate_forward_callback(type_data, writer_getter):
2266 if type_data in global_forward_listener.type_data_set:
2267 binding = type_data.get_binding()
2268 binding.get_code_generator().generate_forward_declaration(writer _getter())
2269 generate_all_domains_code(Generator.type_builder_forwards, generate_forw ard_callback)
2270
2271 Generator.type_builder_forwards.append("// End of forward declarations.\ n\n")
2272
2273 Generator.type_builder_forwards.append("// Typedefs.\n")
2274
2275 generate_all_domains_code(Generator.type_builder_forwards, create_type_b uilder_caller(TypeBuilderPass.TYPEDEF))
2276
2277 Generator.type_builder_forwards.append("// End of typedefs.\n\n")
2278
2279
2280 def flatten_list(input):
2281 res = []
2282
2283 def fill_recursive(l):
2284 for item in l:
2285 if isinstance(item, list):
2286 fill_recursive(item)
2287 else:
2288 res.append(item)
2289 fill_recursive(input)
2290 return res
2291
2292
2293 # A writer that only updates file if it actually changed to better support incre mental build.
2294 class SmartOutput:
2295 def __init__(self, file_name):
2296 self.file_name_ = file_name
2297 self.output_ = ""
2298
2299 def write(self, text):
2300 self.output_ += text
2301
2302 def close(self):
2303 text_changed = True
2304
2305 try:
2306 read_file = open(self.file_name_, "r")
2307 old_text = read_file.read()
2308 read_file.close()
2309 text_changed = old_text != self.output_
2310 except:
2311 # Ignore, just overwrite by default
2312 pass
2313
2314 if text_changed:
2315 out_file = open(self.file_name_, "w")
2316 out_file.write(self.output_)
2317 out_file.close()
2318
2319
2320 Generator.go()
2321
2322 backend_h_file = SmartOutput(output_header_dirname + "/InspectorBackendDispatche r.h")
2323 backend_cpp_file = SmartOutput(output_cpp_dirname + "/InspectorBackendDispatcher .cpp")
2324
2325 frontend_h_file = SmartOutput(output_header_dirname + "/InspectorFrontend.h")
2326 frontend_cpp_file = SmartOutput(output_cpp_dirname + "/InspectorFrontend.cpp")
2327
2328 typebuilder_h_file = SmartOutput(output_header_dirname + "/InspectorTypeBuilder. h")
2329 typebuilder_cpp_file = SmartOutput(output_cpp_dirname + "/InspectorTypeBuilder.c pp")
2330
2331 backend_js_file = SmartOutput(output_cpp_dirname + "/InspectorBackendCommands.js ")
2332
2333
2334 backend_h_file.write(Templates.backend_h.substitute(None,
2335 virtualSetters="\n".join(Generator.backend_virtual_setters_list),
2336 agentInterfaces="".join(flatten_list(Generator.backend_agent_interface_list) ),
2337 methodNamesEnumContent="\n".join(Generator.method_name_enum_list)))
2338
2339 backend_cpp_file.write(Templates.backend_cpp.substitute(None,
2340 constructorInit="\n".join(Generator.backend_constructor_init_list),
2341 setters="\n".join(Generator.backend_setters_list),
2342 fieldDeclarations="\n".join(Generator.backend_field_list),
2343 methodNameDeclarations="\n".join(Generator.backend_method_name_declaration_l ist),
2344 methods="\n".join(Generator.backend_method_implementation_list),
2345 methodDeclarations="\n".join(Generator.backend_method_declaration_list),
2346 messageHandlers="\n".join(Generator.method_handler_list)))
2347
2348 frontend_h_file.write(Templates.frontend_h.substitute(None,
2349 fieldDeclarations="".join(Generator.frontend_class_field_lines),
2350 domainClassList="".join(Generator.frontend_domain_class_lines)))
2351
2352 frontend_cpp_file.write(Templates.frontend_cpp.substitute(None,
2353 constructorInit="".join(Generator.frontend_constructor_init_list),
2354 methods="\n".join(Generator.frontend_method_list)))
2355
2356 typebuilder_h_file.write(Templates.typebuilder_h.substitute(None,
2357 typeBuilders="".join(flatten_list(Generator.type_builder_fragments)),
2358 forwards="".join(Generator.type_builder_forwards),
2359 validatorIfdefName=VALIDATOR_IFDEF_NAME))
2360
2361 typebuilder_cpp_file.write(Templates.typebuilder_cpp.substitute(None,
2362 enumConstantValues=EnumConstants.get_enum_constant_code(),
2363 implCode="".join(flatten_list(Generator.type_builder_impl_list)),
2364 validatorCode="".join(flatten_list(Generator.validator_impl_list)),
2365 validatorIfdefName=VALIDATOR_IFDEF_NAME))
2366
2367 backend_js_file.write(Templates.backend_js.substitute(None,
2368 domainInitializers="".join(Generator.backend_js_domain_initializer_list)))
2369
2370 backend_h_file.close()
2371 backend_cpp_file.close()
2372
2373 frontend_h_file.close()
2374 frontend_cpp_file.close()
2375
2376 typebuilder_h_file.close()
2377 typebuilder_cpp_file.close()
2378
2379 backend_js_file.close()
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698