12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414 |
- #!/usr/bin/env python
- # Copyright (c) 2011 Google Inc. All rights reserved.
- # Copyright (c) 2012 Intel Corporation. All rights reserved.
- #
- # Redistribution and use in source and binary forms, with or without
- # modification, are permitted provided that the following conditions are
- # met:
- #
- # * Redistributions of source code must retain the above copyright
- # notice, this list of conditions and the following disclaimer.
- # * Redistributions in binary form must reproduce the above
- # copyright notice, this list of conditions and the following disclaimer
- # in the documentation and/or other materials provided with the
- # distribution.
- # * Neither the name of Google Inc. nor the names of its
- # contributors may be used to endorse or promote products derived from
- # this software without specific prior written permission.
- #
- # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- import os.path
- import sys
- import string
- import optparse
- import re
- try:
- import json
- except ImportError:
- import simplejson as json
- import CodeGeneratorInspectorStrings
- DOMAIN_DEFINE_NAME_MAP = {
- "Database": "SQL_DATABASE",
- "Debugger": "JAVASCRIPT_DEBUGGER",
- "DOMDebugger": "JAVASCRIPT_DEBUGGER",
- "FileSystem": "FILE_SYSTEM",
- "IndexedDB": "INDEXED_DATABASE",
- "Profiler": "JAVASCRIPT_DEBUGGER",
- "Worker": "WORKERS",
- }
- # Manually-filled map of type name replacements.
- TYPE_NAME_FIX_MAP = {
- "RGBA": "Rgba", # RGBA is reported to be conflicting with a define name in Windows CE.
- "": "Empty",
- }
- TYPES_WITH_RUNTIME_CAST_SET = frozenset(["Runtime.RemoteObject", "Runtime.PropertyDescriptor", "Runtime.InternalPropertyDescriptor",
- "Debugger.FunctionDetails", "Debugger.CallFrame",
- "Canvas.TraceLog", "Canvas.ResourceInfo", "Canvas.ResourceState",
- # This should be a temporary hack. TimelineEvent should be created via generated C++ API.
- "Timeline.TimelineEvent"])
- TYPES_WITH_OPEN_FIELD_LIST_SET = frozenset(["Timeline.TimelineEvent",
- # InspectorStyleSheet not only creates this property but wants to read it and modify it.
- "CSS.CSSProperty",
- # InspectorResourceAgent needs to update mime-type.
- "Network.Response"])
- EXACTLY_INT_SUPPORTED = False
- cmdline_parser = optparse.OptionParser()
- cmdline_parser.add_option("--output_h_dir")
- cmdline_parser.add_option("--output_cpp_dir")
- cmdline_parser.add_option("--write_always", action="store_true")
- try:
- arg_options, arg_values = cmdline_parser.parse_args()
- if (len(arg_values) != 1):
- raise Exception("Exactly one plain argument expected (found %s)" % len(arg_values))
- input_json_filename = arg_values[0]
- output_header_dirname = arg_options.output_h_dir
- output_cpp_dirname = arg_options.output_cpp_dir
- write_always = arg_options.write_always
- if not output_header_dirname:
- raise Exception("Output .h directory must be specified")
- if not output_cpp_dirname:
- raise Exception("Output .cpp directory must be specified")
- except Exception:
- # Work with python 2 and 3 http://docs.python.org/py3k/howto/pyporting.html
- exc = sys.exc_info()[1]
- sys.stderr.write("Failed to parse command-line arguments: %s\n\n" % exc)
- sys.stderr.write("Usage: <script> Inspector.json --output_h_dir <output_header_dir> --output_cpp_dir <output_cpp_dir> [--write_always]\n")
- exit(1)
- def dash_to_camelcase(word):
- return ''.join(x.capitalize() or '-' for x in word.split('-'))
- def fix_camel_case(name):
- refined = re.sub(r'-(\w)', lambda pat: pat.group(1).upper(), name)
- refined = to_title_case(refined)
- return re.sub(r'(?i)HTML|XML|WML|API', lambda pat: pat.group(0).upper(), refined)
- def to_title_case(name):
- return name[:1].upper() + name[1:]
- class Capitalizer:
- @staticmethod
- def lower_camel_case_to_upper(str):
- if len(str) > 0 and str[0].islower():
- str = str[0].upper() + str[1:]
- return str
- @staticmethod
- def upper_camel_case_to_lower(str):
- pos = 0
- while pos < len(str) and str[pos].isupper():
- pos += 1
- if pos == 0:
- return str
- if pos == 1:
- return str[0].lower() + str[1:]
- if pos < len(str):
- pos -= 1
- possible_abbreviation = str[0:pos]
- if possible_abbreviation not in Capitalizer.ABBREVIATION:
- raise Exception("Unknown abbreviation %s" % possible_abbreviation)
- str = possible_abbreviation.lower() + str[pos:]
- return str
- @staticmethod
- def camel_case_to_capitalized_with_underscores(str):
- if len(str) == 0:
- return str
- output = Capitalizer.split_camel_case_(str)
- return "_".join(output).upper()
- @staticmethod
- def split_camel_case_(str):
- output = []
- pos_being = 0
- pos = 1
- has_oneletter = False
- while pos < len(str):
- if str[pos].isupper():
- output.append(str[pos_being:pos].upper())
- if pos - pos_being == 1:
- has_oneletter = True
- pos_being = pos
- pos += 1
- output.append(str[pos_being:])
- if has_oneletter:
- array_pos = 0
- while array_pos < len(output) - 1:
- if len(output[array_pos]) == 1:
- array_pos_end = array_pos + 1
- while array_pos_end < len(output) and len(output[array_pos_end]) == 1:
- array_pos_end += 1
- if array_pos_end - array_pos > 1:
- possible_abbreviation = "".join(output[array_pos:array_pos_end])
- if possible_abbreviation.upper() in Capitalizer.ABBREVIATION:
- output[array_pos:array_pos_end] = [possible_abbreviation]
- else:
- array_pos = array_pos_end - 1
- array_pos += 1
- return output
- ABBREVIATION = frozenset(["XHR", "DOM", "CSS"])
- VALIDATOR_IFDEF_NAME = "!ASSERT_DISABLED"
- class DomainNameFixes:
- @classmethod
- def get_fixed_data(cls, domain_name):
- field_name_res = Capitalizer.upper_camel_case_to_lower(domain_name) + "Agent"
- class Res(object):
- skip_js_bind = domain_name in cls.skip_js_bind_domains
- agent_field_name = field_name_res
- @staticmethod
- def get_guard():
- if domain_name in DOMAIN_DEFINE_NAME_MAP:
- define_name = DOMAIN_DEFINE_NAME_MAP[domain_name]
- class Guard:
- @staticmethod
- def generate_open(output):
- output.append("#if ENABLE(%s)\n" % define_name)
- @staticmethod
- def generate_close(output):
- output.append("#endif // ENABLE(%s)\n" % define_name)
- return Guard
- return Res
- skip_js_bind_domains = set(["DOMDebugger"])
- class RawTypes(object):
- @staticmethod
- def get(json_type):
- if json_type == "boolean":
- return RawTypes.Bool
- elif json_type == "string":
- return RawTypes.String
- elif json_type == "array":
- return RawTypes.Array
- elif json_type == "object":
- return RawTypes.Object
- elif json_type == "integer":
- return RawTypes.Int
- elif json_type == "number":
- return RawTypes.Number
- elif json_type == "any":
- return RawTypes.Any
- else:
- raise Exception("Unknown type: %s" % json_type)
- # For output parameter all values are passed by pointer except RefPtr-based types.
- class OutputPassModel:
- class ByPointer:
- @staticmethod
- def get_argument_prefix():
- return "&"
- @staticmethod
- def get_parameter_type_suffix():
- return "*"
- class ByReference:
- @staticmethod
- def get_argument_prefix():
- return ""
- @staticmethod
- def get_parameter_type_suffix():
- return "&"
- class BaseType(object):
- need_internal_runtime_cast_ = False
- @classmethod
- def request_raw_internal_runtime_cast(cls):
- if not cls.need_internal_runtime_cast_:
- cls.need_internal_runtime_cast_ = True
- @classmethod
- def get_raw_validator_call_text(cls):
- return "RuntimeCastHelper::assertType<InspectorValue::Type%s>" % cls.get_validate_method_params().template_type
- class String(BaseType):
- @staticmethod
- def get_getter_name():
- return "String"
- get_setter_name = get_getter_name
- @staticmethod
- def get_c_initializer():
- return "\"\""
- @staticmethod
- def get_js_bind_type():
- return "string"
- @staticmethod
- def get_validate_method_params():
- class ValidateMethodParams:
- template_type = "String"
- return ValidateMethodParams
- @staticmethod
- def get_output_pass_model():
- return RawTypes.OutputPassModel.ByPointer
- @staticmethod
- def is_heavy_value():
- return True
- @staticmethod
- def get_array_item_raw_c_type_text():
- return "String"
- @staticmethod
- def get_raw_type_model():
- return TypeModel.String
- class Int(BaseType):
- @staticmethod
- def get_getter_name():
- return "Int"
- @staticmethod
- def get_setter_name():
- return "Number"
- @staticmethod
- def get_c_initializer():
- return "0"
- @staticmethod
- def get_js_bind_type():
- return "number"
- @classmethod
- def get_raw_validator_call_text(cls):
- return "RuntimeCastHelper::assertInt"
- @staticmethod
- def get_output_pass_model():
- return RawTypes.OutputPassModel.ByPointer
- @staticmethod
- def is_heavy_value():
- return False
- @staticmethod
- def get_array_item_raw_c_type_text():
- return "int"
- @staticmethod
- def get_raw_type_model():
- return TypeModel.Int
- class Number(BaseType):
- @staticmethod
- def get_getter_name():
- return "Double"
- @staticmethod
- def get_setter_name():
- return "Number"
- @staticmethod
- def get_c_initializer():
- return "0"
- @staticmethod
- def get_js_bind_type():
- return "number"
- @staticmethod
- def get_validate_method_params():
- class ValidateMethodParams:
- template_type = "Number"
- return ValidateMethodParams
- @staticmethod
- def get_output_pass_model():
- return RawTypes.OutputPassModel.ByPointer
- @staticmethod
- def is_heavy_value():
- return False
- @staticmethod
- def get_array_item_raw_c_type_text():
- return "double"
- @staticmethod
- def get_raw_type_model():
- return TypeModel.Number
- class Bool(BaseType):
- @staticmethod
- def get_getter_name():
- return "Boolean"
- get_setter_name = get_getter_name
- @staticmethod
- def get_c_initializer():
- return "false"
- @staticmethod
- def get_js_bind_type():
- return "boolean"
- @staticmethod
- def get_validate_method_params():
- class ValidateMethodParams:
- template_type = "Boolean"
- return ValidateMethodParams
- @staticmethod
- def get_output_pass_model():
- return RawTypes.OutputPassModel.ByPointer
- @staticmethod
- def is_heavy_value():
- return False
- @staticmethod
- def get_array_item_raw_c_type_text():
- return "bool"
- @staticmethod
- def get_raw_type_model():
- return TypeModel.Bool
- class Object(BaseType):
- @staticmethod
- def get_getter_name():
- return "Object"
- @staticmethod
- def get_setter_name():
- return "Value"
- @staticmethod
- def get_c_initializer():
- return "InspectorObject::create()"
- @staticmethod
- def get_js_bind_type():
- return "object"
- @staticmethod
- def get_output_argument_prefix():
- return ""
- @staticmethod
- def get_validate_method_params():
- class ValidateMethodParams:
- template_type = "Object"
- return ValidateMethodParams
- @staticmethod
- def get_output_pass_model():
- return RawTypes.OutputPassModel.ByReference
- @staticmethod
- def is_heavy_value():
- return True
- @staticmethod
- def get_array_item_raw_c_type_text():
- return "InspectorObject"
- @staticmethod
- def get_raw_type_model():
- return TypeModel.Object
- class Any(BaseType):
- @staticmethod
- def get_getter_name():
- return "Value"
- get_setter_name = get_getter_name
- @staticmethod
- def get_c_initializer():
- raise Exception("Unsupported")
- @staticmethod
- def get_js_bind_type():
- raise Exception("Unsupported")
- @staticmethod
- def get_raw_validator_call_text():
- return "RuntimeCastHelper::assertAny"
- @staticmethod
- def get_output_pass_model():
- return RawTypes.OutputPassModel.ByReference
- @staticmethod
- def is_heavy_value():
- return True
- @staticmethod
- def get_array_item_raw_c_type_text():
- return "InspectorValue"
- @staticmethod
- def get_raw_type_model():
- return TypeModel.Any
- class Array(BaseType):
- @staticmethod
- def get_getter_name():
- return "Array"
- @staticmethod
- def get_setter_name():
- return "Value"
- @staticmethod
- def get_c_initializer():
- return "InspectorArray::create()"
- @staticmethod
- def get_js_bind_type():
- return "object"
- @staticmethod
- def get_output_argument_prefix():
- return ""
- @staticmethod
- def get_validate_method_params():
- class ValidateMethodParams:
- template_type = "Array"
- return ValidateMethodParams
- @staticmethod
- def get_output_pass_model():
- return RawTypes.OutputPassModel.ByReference
- @staticmethod
- def is_heavy_value():
- return True
- @staticmethod
- def get_array_item_raw_c_type_text():
- return "InspectorArray"
- @staticmethod
- def get_raw_type_model():
- return TypeModel.Array
- def replace_right_shift(input_str):
- return input_str.replace(">>", "> >")
- class CommandReturnPassModel:
- class ByReference:
- def __init__(self, var_type, set_condition):
- self.var_type = var_type
- self.set_condition = set_condition
- def get_return_var_type(self):
- return self.var_type
- @staticmethod
- def get_output_argument_prefix():
- return ""
- @staticmethod
- def get_output_to_raw_expression():
- return "%s"
- def get_output_parameter_type(self):
- return self.var_type + "&"
- def get_set_return_condition(self):
- return self.set_condition
- class ByPointer:
- def __init__(self, var_type):
- self.var_type = var_type
- def get_return_var_type(self):
- return self.var_type
- @staticmethod
- def get_output_argument_prefix():
- return "&"
- @staticmethod
- def get_output_to_raw_expression():
- return "%s"
- def get_output_parameter_type(self):
- return self.var_type + "*"
- @staticmethod
- def get_set_return_condition():
- return None
- class OptOutput:
- def __init__(self, var_type):
- self.var_type = var_type
- def get_return_var_type(self):
- return "TypeBuilder::OptOutput<%s>" % self.var_type
- @staticmethod
- def get_output_argument_prefix():
- return "&"
- @staticmethod
- def get_output_to_raw_expression():
- return "%s.getValue()"
- def get_output_parameter_type(self):
- return "TypeBuilder::OptOutput<%s>*" % self.var_type
- @staticmethod
- def get_set_return_condition():
- return "%s.isAssigned()"
- class TypeModel:
- class RefPtrBased(object):
- def __init__(self, class_name):
- self.class_name = class_name
- self.optional = False
- def get_optional(self):
- result = TypeModel.RefPtrBased(self.class_name)
- result.optional = True
- return result
- def get_command_return_pass_model(self):
- if self.optional:
- set_condition = "%s"
- else:
- set_condition = None
- return CommandReturnPassModel.ByReference(replace_right_shift("RefPtr<%s>" % self.class_name), set_condition)
- def get_input_param_type_text(self):
- return replace_right_shift("PassRefPtr<%s>" % self.class_name)
- @staticmethod
- def get_event_setter_expression_pattern():
- return "%s"
- class Enum(object):
- def __init__(self, base_type_name):
- self.type_name = base_type_name + "::Enum"
- def get_optional(base_self):
- class EnumOptional:
- @classmethod
- def get_optional(cls):
- return cls
- @staticmethod
- def get_command_return_pass_model():
- return CommandReturnPassModel.OptOutput(base_self.type_name)
- @staticmethod
- def get_input_param_type_text():
- return base_self.type_name + "*"
- @staticmethod
- def get_event_setter_expression_pattern():
- raise Exception("TODO")
- return EnumOptional
- def get_command_return_pass_model(self):
- return CommandReturnPassModel.ByPointer(self.type_name)
- def get_input_param_type_text(self):
- return self.type_name
- @staticmethod
- def get_event_setter_expression_pattern():
- return "%s"
- class ValueType(object):
- def __init__(self, type_name, is_heavy):
- self.type_name = type_name
- self.is_heavy = is_heavy
- def get_optional(self):
- return self.ValueOptional(self)
- def get_command_return_pass_model(self):
- return CommandReturnPassModel.ByPointer(self.type_name)
- def get_input_param_type_text(self):
- if self.is_heavy:
- return "const %s&" % self.type_name
- else:
- return self.type_name
- def get_opt_output_type_(self):
- return self.type_name
- @staticmethod
- def get_event_setter_expression_pattern():
- return "%s"
- class ValueOptional:
- def __init__(self, base):
- self.base = base
- def get_optional(self):
- return self
- def get_command_return_pass_model(self):
- return CommandReturnPassModel.OptOutput(self.base.get_opt_output_type_())
- def get_input_param_type_text(self):
- return "const %s* const" % self.base.type_name
- @staticmethod
- def get_event_setter_expression_pattern():
- return "*%s"
- class ExactlyInt(ValueType):
- def __init__(self):
- TypeModel.ValueType.__init__(self, "int", False)
- def get_input_param_type_text(self):
- return "TypeBuilder::ExactlyInt"
- def get_opt_output_type_(self):
- return "TypeBuilder::ExactlyInt"
- @classmethod
- def init_class(cls):
- cls.Bool = cls.ValueType("bool", False)
- if EXACTLY_INT_SUPPORTED:
- cls.Int = cls.ExactlyInt()
- else:
- cls.Int = cls.ValueType("int", False)
- cls.Number = cls.ValueType("double", False)
- cls.String = cls.ValueType("String", True,)
- cls.Object = cls.RefPtrBased("InspectorObject")
- cls.Array = cls.RefPtrBased("InspectorArray")
- cls.Any = cls.RefPtrBased("InspectorValue")
- TypeModel.init_class()
- # Collection of InspectorObject class methods that are likely to be overloaded in generated class.
- # We must explicitly import all overloaded methods or they won't be available to user.
- INSPECTOR_OBJECT_SETTER_NAMES = frozenset(["setValue", "setBoolean", "setNumber", "setString", "setValue", "setObject", "setArray"])
- def fix_type_name(json_name):
- if json_name in TYPE_NAME_FIX_MAP:
- fixed = TYPE_NAME_FIX_MAP[json_name]
- class Result(object):
- class_name = fixed
- @staticmethod
- def output_comment(writer):
- writer.newline("// Type originally was named '%s'.\n" % json_name)
- else:
- class Result(object):
- class_name = json_name
- @staticmethod
- def output_comment(writer):
- pass
- return Result
- class Writer:
- def __init__(self, output, indent):
- self.output = output
- self.indent = indent
- def newline(self, str):
- if (self.indent):
- self.output.append(self.indent)
- self.output.append(str)
- def append(self, str):
- self.output.append(str)
- def newline_multiline(self, str):
- parts = str.split('\n')
- self.newline(parts[0])
- for p in parts[1:]:
- self.output.append('\n')
- if p:
- self.newline(p)
- def append_multiline(self, str):
- parts = str.split('\n')
- self.append(parts[0])
- for p in parts[1:]:
- self.output.append('\n')
- if p:
- self.newline(p)
- def get_indent(self):
- return self.indent
- def get_indented(self, additional_indent):
- return Writer(self.output, self.indent + additional_indent)
- def insert_writer(self, additional_indent):
- new_output = []
- self.output.append(new_output)
- return Writer(new_output, self.indent + additional_indent)
- class EnumConstants:
- map_ = {}
- constants_ = []
- @classmethod
- def add_constant(cls, value):
- if value in cls.map_:
- return cls.map_[value]
- else:
- pos = len(cls.map_)
- cls.map_[value] = pos
- cls.constants_.append(value)
- return pos
- @classmethod
- def get_enum_constant_code(cls):
- output = []
- for item in cls.constants_:
- output.append(" \"" + item + "\"")
- return ",\n".join(output) + "\n"
- # Typebuilder code is generated in several passes: first typedefs, then other classes.
- # Manual pass management is needed because we cannot have forward declarations for typedefs.
- class TypeBuilderPass:
- TYPEDEF = "typedef"
- MAIN = "main"
- class TypeBindings:
- @staticmethod
- def create_named_type_declaration(json_typable, context_domain_name, type_data):
- json_type = type_data.get_json_type()
- class Helper:
- is_ad_hoc = False
- full_name_prefix_for_use = "TypeBuilder::" + context_domain_name + "::"
- full_name_prefix_for_impl = "TypeBuilder::" + context_domain_name + "::"
- @staticmethod
- def write_doc(writer):
- if "description" in json_type:
- writer.newline("/* ")
- writer.append(json_type["description"])
- writer.append(" */\n")
- @staticmethod
- def add_to_forward_listener(forward_listener):
- forward_listener.add_type_data(type_data)
- fixed_type_name = fix_type_name(json_type["id"])
- return TypeBindings.create_type_declaration_(json_typable, context_domain_name, fixed_type_name, Helper)
- @staticmethod
- def create_ad_hoc_type_declaration(json_typable, context_domain_name, ad_hoc_type_context):
- class Helper:
- is_ad_hoc = True
- full_name_prefix_for_use = ad_hoc_type_context.container_relative_name_prefix
- full_name_prefix_for_impl = ad_hoc_type_context.container_full_name_prefix
- @staticmethod
- def write_doc(writer):
- pass
- @staticmethod
- def add_to_forward_listener(forward_listener):
- pass
- fixed_type_name = ad_hoc_type_context.get_type_name_fix()
- return TypeBindings.create_type_declaration_(json_typable, context_domain_name, fixed_type_name, Helper)
- @staticmethod
- def create_type_declaration_(json_typable, context_domain_name, fixed_type_name, helper):
- if json_typable["type"] == "string":
- if "enum" in json_typable:
- class EnumBinding:
- need_user_runtime_cast_ = False
- need_internal_runtime_cast_ = False
- @classmethod
- def resolve_inner(cls, resolve_context):
- pass
- @classmethod
- def request_user_runtime_cast(cls, request):
- if request:
- cls.need_user_runtime_cast_ = True
- request.acknowledge()
- @classmethod
- def request_internal_runtime_cast(cls):
- cls.need_internal_runtime_cast_ = True
- @classmethod
- def get_code_generator(enum_binding_cls):
- #FIXME: generate ad-hoc enums too once we figure out how to better implement them in C++.
- comment_out = helper.is_ad_hoc
- class CodeGenerator:
- @staticmethod
- def generate_type_builder(writer, generate_context):
- enum = json_typable["enum"]
- helper.write_doc(writer)
- enum_name = fixed_type_name.class_name
- fixed_type_name.output_comment(writer)
- writer.newline("struct ")
- writer.append(enum_name)
- writer.append(" {\n")
- writer.newline(" enum Enum {\n")
- for enum_item in enum:
- enum_pos = EnumConstants.add_constant(enum_item)
- item_c_name = enum_item.replace('-', '_')
- item_c_name = Capitalizer.lower_camel_case_to_upper(item_c_name)
- if item_c_name in TYPE_NAME_FIX_MAP:
- item_c_name = TYPE_NAME_FIX_MAP[item_c_name]
- writer.newline(" ")
- writer.append(item_c_name)
- writer.append(" = ")
- writer.append("%s" % enum_pos)
- writer.append(",\n")
- writer.newline(" };\n")
- if enum_binding_cls.need_user_runtime_cast_:
- raise Exception("Not yet implemented")
- if enum_binding_cls.need_internal_runtime_cast_:
- writer.append("#if %s\n" % VALIDATOR_IFDEF_NAME)
- writer.newline(" static void assertCorrectValue(InspectorValue* value);\n")
- writer.append("#endif // %s\n" % VALIDATOR_IFDEF_NAME)
- validator_writer = generate_context.validator_writer
- domain_fixes = DomainNameFixes.get_fixed_data(context_domain_name)
- domain_guard = domain_fixes.get_guard()
- if domain_guard:
- domain_guard.generate_open(validator_writer)
- validator_writer.newline("void %s%s::assertCorrectValue(InspectorValue* value)\n" % (helper.full_name_prefix_for_impl, enum_name))
- validator_writer.newline("{\n")
- validator_writer.newline(" WTF::String s;\n")
- validator_writer.newline(" bool cast_res = value->asString(&s);\n")
- validator_writer.newline(" ASSERT(cast_res);\n")
- if len(enum) > 0:
- condition_list = []
- for enum_item in enum:
- enum_pos = EnumConstants.add_constant(enum_item)
- condition_list.append("s == \"%s\"" % enum_item)
- validator_writer.newline(" ASSERT(%s);\n" % " || ".join(condition_list))
- validator_writer.newline("}\n")
- if domain_guard:
- domain_guard.generate_close(validator_writer)
- validator_writer.newline("\n\n")
- writer.newline("}; // struct ")
- writer.append(enum_name)
- writer.append("\n\n")
- @staticmethod
- def register_use(forward_listener):
- pass
- @staticmethod
- def get_generate_pass_id():
- return TypeBuilderPass.MAIN
- return CodeGenerator
- @classmethod
- def get_validator_call_text(cls):
- return helper.full_name_prefix_for_use + fixed_type_name.class_name + "::assertCorrectValue"
- @classmethod
- def get_array_item_c_type_text(cls):
- return helper.full_name_prefix_for_use + fixed_type_name.class_name + "::Enum"
- @staticmethod
- def get_setter_value_expression_pattern():
- return "TypeBuilder::getEnumConstantValue(%s)"
- @staticmethod
- def reduce_to_raw_type():
- return RawTypes.String
- @staticmethod
- def get_type_model():
- return TypeModel.Enum(helper.full_name_prefix_for_use + fixed_type_name.class_name)
- return EnumBinding
- else:
- if helper.is_ad_hoc:
- class PlainString:
- @classmethod
- def resolve_inner(cls, resolve_context):
- pass
- @staticmethod
- def request_user_runtime_cast(request):
- raise Exception("Unsupported")
- @staticmethod
- def request_internal_runtime_cast():
- pass
- @staticmethod
- def get_code_generator():
- return None
- @classmethod
- def get_validator_call_text(cls):
- return RawTypes.String.get_raw_validator_call_text()
- @staticmethod
- def reduce_to_raw_type():
- return RawTypes.String
- @staticmethod
- def get_type_model():
- return TypeModel.String
- @staticmethod
- def get_setter_value_expression_pattern():
- return None
- @classmethod
- def get_array_item_c_type_text(cls):
- return cls.reduce_to_raw_type().get_array_item_raw_c_type_text()
- return PlainString
- else:
- class TypedefString:
- @classmethod
- def resolve_inner(cls, resolve_context):
- pass
- @staticmethod
- def request_user_runtime_cast(request):
- raise Exception("Unsupported")
- @staticmethod
- def request_internal_runtime_cast():
- RawTypes.String.request_raw_internal_runtime_cast()
- @staticmethod
- def get_code_generator():
- class CodeGenerator:
- @staticmethod
- def generate_type_builder(writer, generate_context):
- helper.write_doc(writer)
- fixed_type_name.output_comment(writer)
- writer.newline("typedef String ")
- writer.append(fixed_type_name.class_name)
- writer.append(";\n\n")
- @staticmethod
- def register_use(forward_listener):
- pass
- @staticmethod
- def get_generate_pass_id():
- return TypeBuilderPass.TYPEDEF
- return CodeGenerator
- @classmethod
- def get_validator_call_text(cls):
- return RawTypes.String.get_raw_validator_call_text()
- @staticmethod
- def reduce_to_raw_type():
- return RawTypes.String
- @staticmethod
- def get_type_model():
- return TypeModel.ValueType("%s%s" % (helper.full_name_prefix_for_use, fixed_type_name.class_name), True)
- @staticmethod
- def get_setter_value_expression_pattern():
- return None
- @classmethod
- def get_array_item_c_type_text(cls):
- return "const %s%s&" % (helper.full_name_prefix_for_use, fixed_type_name.class_name)
- return TypedefString
- elif json_typable["type"] == "object":
- if "properties" in json_typable:
- class ClassBinding:
- resolve_data_ = None
- need_user_runtime_cast_ = False
- need_internal_runtime_cast_ = False
- @classmethod
- def resolve_inner(cls, resolve_context):
- if cls.resolve_data_:
- return
- properties = json_typable["properties"]
- main = []
- optional = []
- ad_hoc_type_list = []
- for prop in properties:
- prop_name = prop["name"]
- 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)
- binding = resolve_param_type(prop, context_domain_name, ad_hoc_type_context)
- code_generator = binding.get_code_generator()
- if code_generator:
- code_generator.register_use(resolve_context.forward_listener)
- class PropertyData:
- param_type_binding = binding
- p = prop
- if prop.get("optional"):
- optional.append(PropertyData)
- else:
- main.append(PropertyData)
- class ResolveData:
- main_properties = main
- optional_properties = optional
- ad_hoc_types = ad_hoc_type_list
- cls.resolve_data_ = ResolveData
- for ad_hoc in ad_hoc_type_list:
- ad_hoc.resolve_inner(resolve_context)
- @classmethod
- def request_user_runtime_cast(cls, request):
- if not request:
- return
- cls.need_user_runtime_cast_ = True
- request.acknowledge()
- cls.request_internal_runtime_cast()
- @classmethod
- def request_internal_runtime_cast(cls):
- if cls.need_internal_runtime_cast_:
- return
- cls.need_internal_runtime_cast_ = True
- for p in cls.resolve_data_.main_properties:
- p.param_type_binding.request_internal_runtime_cast()
- for p in cls.resolve_data_.optional_properties:
- p.param_type_binding.request_internal_runtime_cast()
- @classmethod
- def get_code_generator(class_binding_cls):
- class CodeGenerator:
- @classmethod
- def generate_type_builder(cls, writer, generate_context):
- resolve_data = class_binding_cls.resolve_data_
- helper.write_doc(writer)
- class_name = fixed_type_name.class_name
- is_open_type = (context_domain_name + "." + class_name) in TYPES_WITH_OPEN_FIELD_LIST_SET
- fixed_type_name.output_comment(writer)
- writer.newline("class ")
- writer.append(class_name)
- writer.append(" : public ")
- if is_open_type:
- writer.append("InspectorObject")
- else:
- writer.append("InspectorObjectBase")
- writer.append(" {\n")
- writer.newline("public:\n")
- ad_hoc_type_writer = writer.insert_writer(" ")
- for ad_hoc_type in resolve_data.ad_hoc_types:
- code_generator = ad_hoc_type.get_code_generator()
- if code_generator:
- code_generator.generate_type_builder(ad_hoc_type_writer, generate_context)
- writer.newline_multiline(
- """ enum {
- NoFieldsSet = 0,
- """)
- state_enum_items = []
- if len(resolve_data.main_properties) > 0:
- pos = 0
- for prop_data in resolve_data.main_properties:
- item_name = Capitalizer.lower_camel_case_to_upper(prop_data.p["name"]) + "Set"
- state_enum_items.append(item_name)
- writer.newline(" %s = 1 << %s,\n" % (item_name, pos))
- pos += 1
- all_fields_set_value = "(" + (" | ".join(state_enum_items)) + ")"
- else:
- all_fields_set_value = "0"
- writer.newline_multiline(CodeGeneratorInspectorStrings.class_binding_builder_part_1
- % (all_fields_set_value, class_name, class_name))
- pos = 0
- for prop_data in resolve_data.main_properties:
- prop_name = prop_data.p["name"]
- param_type_binding = prop_data.param_type_binding
- param_raw_type = param_type_binding.reduce_to_raw_type()
- writer.newline_multiline(CodeGeneratorInspectorStrings.class_binding_builder_part_2
- % (state_enum_items[pos],
- Capitalizer.lower_camel_case_to_upper(prop_name),
- param_type_binding.get_type_model().get_input_param_type_text(),
- state_enum_items[pos], prop_name,
- param_raw_type.get_setter_name(), prop_name,
- format_setter_value_expression(param_type_binding, "value"),
- state_enum_items[pos]))
- pos += 1
- writer.newline_multiline(CodeGeneratorInspectorStrings.class_binding_builder_part_3
- % (class_name, class_name, class_name, class_name, class_name))
- writer.newline(" /*\n")
- writer.newline(" * Synthetic constructor:\n")
- writer.newline(" * RefPtr<%s> result = %s::create()" % (class_name, class_name))
- for prop_data in resolve_data.main_properties:
- writer.append_multiline("\n * .set%s(...)" % Capitalizer.lower_camel_case_to_upper(prop_data.p["name"]))
- writer.append_multiline(";\n */\n")
- writer.newline_multiline(CodeGeneratorInspectorStrings.class_binding_builder_part_4)
- writer.newline(" typedef TypeBuilder::StructItemTraits ItemTraits;\n")
- for prop_data in resolve_data.optional_properties:
- prop_name = prop_data.p["name"]
- param_type_binding = prop_data.param_type_binding
- setter_name = "set%s" % Capitalizer.lower_camel_case_to_upper(prop_name)
- writer.append_multiline("\n void %s" % setter_name)
- writer.append("(%s value)\n" % param_type_binding.get_type_model().get_input_param_type_text())
- writer.newline(" {\n")
- writer.newline(" this->set%s(\"%s\", %s);\n"
- % (param_type_binding.reduce_to_raw_type().get_setter_name(), prop_data.p["name"],
- format_setter_value_expression(param_type_binding, "value")))
- writer.newline(" }\n")
- if setter_name in INSPECTOR_OBJECT_SETTER_NAMES:
- writer.newline(" using InspectorObjectBase::%s;\n\n" % setter_name)
- if class_binding_cls.need_user_runtime_cast_:
- writer.newline(" static PassRefPtr<%s> runtimeCast(PassRefPtr<InspectorValue> value)\n" % class_name)
- writer.newline(" {\n")
- writer.newline(" RefPtr<InspectorObject> object;\n")
- writer.newline(" bool castRes = value->asObject(&object);\n")
- writer.newline(" ASSERT_UNUSED(castRes, castRes);\n")
- writer.append("#if %s\n" % VALIDATOR_IFDEF_NAME)
- writer.newline(" assertCorrectValue(object.get());\n")
- writer.append("#endif // %s\n" % VALIDATOR_IFDEF_NAME)
- writer.newline(" COMPILE_ASSERT(sizeof(%s) == sizeof(InspectorObjectBase), type_cast_problem);\n" % class_name)
- writer.newline(" return static_cast<%s*>(static_cast<InspectorObjectBase*>(object.get()));\n" % class_name)
- writer.newline(" }\n")
- writer.append("\n")
- if class_binding_cls.need_internal_runtime_cast_:
- writer.append("#if %s\n" % VALIDATOR_IFDEF_NAME)
- writer.newline(" static void assertCorrectValue(InspectorValue* value);\n")
- writer.append("#endif // %s\n" % VALIDATOR_IFDEF_NAME)
- closed_field_set = (context_domain_name + "." + class_name) not in TYPES_WITH_OPEN_FIELD_LIST_SET
- validator_writer = generate_context.validator_writer
- domain_fixes = DomainNameFixes.get_fixed_data(context_domain_name)
- domain_guard = domain_fixes.get_guard()
- if domain_guard:
- domain_guard.generate_open(validator_writer)
- validator_writer.newline("void %s%s::assertCorrectValue(InspectorValue* value)\n" % (helper.full_name_prefix_for_impl, class_name))
- validator_writer.newline("{\n")
- validator_writer.newline(" RefPtr<InspectorObject> object;\n")
- validator_writer.newline(" bool castRes = value->asObject(&object);\n")
- validator_writer.newline(" ASSERT_UNUSED(castRes, castRes);\n")
- for prop_data in resolve_data.main_properties:
- validator_writer.newline(" {\n")
- it_name = "%sPos" % prop_data.p["name"]
- validator_writer.newline(" InspectorObject::iterator %s;\n" % it_name)
- validator_writer.newline(" %s = object->find(\"%s\");\n" % (it_name, prop_data.p["name"]))
- validator_writer.newline(" ASSERT(%s != object->end());\n" % it_name)
- validator_writer.newline(" %s(%s->value.get());\n" % (prop_data.param_type_binding.get_validator_call_text(), it_name))
- validator_writer.newline(" }\n")
- if closed_field_set:
- validator_writer.newline(" int foundPropertiesCount = %s;\n" % len(resolve_data.main_properties))
- for prop_data in resolve_data.optional_properties:
- validator_writer.newline(" {\n")
- it_name = "%sPos" % prop_data.p["name"]
- validator_writer.newline(" InspectorObject::iterator %s;\n" % it_name)
- validator_writer.newline(" %s = object->find(\"%s\");\n" % (it_name, prop_data.p["name"]))
- validator_writer.newline(" if (%s != object->end()) {\n" % it_name)
- validator_writer.newline(" %s(%s->value.get());\n" % (prop_data.param_type_binding.get_validator_call_text(), it_name))
- if closed_field_set:
- validator_writer.newline(" ++foundPropertiesCount;\n")
- validator_writer.newline(" }\n")
- validator_writer.newline(" }\n")
- if closed_field_set:
- validator_writer.newline(" if (foundPropertiesCount != object->size()) {\n")
- validator_writer.newline(" FATAL(\"Unexpected properties in object: %s\\n\", object->toJSONString().ascii().data());\n")
- validator_writer.newline(" }\n")
- validator_writer.newline("}\n")
- if domain_guard:
- domain_guard.generate_close(validator_writer)
- validator_writer.newline("\n\n")
- if is_open_type:
- cpp_writer = generate_context.cpp_writer
- writer.append("\n")
- writer.newline(" // Property names for type generated as open.\n")
- for prop_data in resolve_data.main_properties + resolve_data.optional_properties:
- prop_name = prop_data.p["name"]
- prop_field_name = Capitalizer.lower_camel_case_to_upper(prop_name)
- writer.newline(" static const char* %s;\n" % (prop_field_name))
- cpp_writer.newline("const char* %s%s::%s = \"%s\";\n" % (helper.full_name_prefix_for_impl, class_name, prop_field_name, prop_name))
- writer.newline("};\n\n")
- @staticmethod
- def generate_forward_declaration(writer):
- class_name = fixed_type_name.class_name
- writer.newline("class ")
- writer.append(class_name)
- writer.append(";\n")
- @staticmethod
- def register_use(forward_listener):
- helper.add_to_forward_listener(forward_listener)
- @staticmethod
- def get_generate_pass_id():
- return TypeBuilderPass.MAIN
- return CodeGenerator
- @staticmethod
- def get_validator_call_text():
- return helper.full_name_prefix_for_use + fixed_type_name.class_name + "::assertCorrectValue"
- @classmethod
- def get_array_item_c_type_text(cls):
- return helper.full_name_prefix_for_use + fixed_type_name.class_name
- @staticmethod
- def get_setter_value_expression_pattern():
- return None
- @staticmethod
- def reduce_to_raw_type():
- return RawTypes.Object
- @staticmethod
- def get_type_model():
- return TypeModel.RefPtrBased(helper.full_name_prefix_for_use + fixed_type_name.class_name)
- class AdHocTypeContextImpl:
- def __init__(self, property_name, class_name, resolve_context, ad_hoc_type_list, parent_full_name_prefix):
- self.property_name = property_name
- self.class_name = class_name
- self.resolve_context = resolve_context
- self.ad_hoc_type_list = ad_hoc_type_list
- self.container_full_name_prefix = parent_full_name_prefix + class_name + "::"
- self.container_relative_name_prefix = ""
- def get_type_name_fix(self):
- class NameFix:
- class_name = Capitalizer.lower_camel_case_to_upper(self.property_name)
- @staticmethod
- def output_comment(writer):
- writer.newline("// Named after property name '%s' while generating %s.\n" % (self.property_name, self.class_name))
- return NameFix
- def add_type(self, binding):
- self.ad_hoc_type_list.append(binding)
- return ClassBinding
- else:
- class PlainObjectBinding:
- @classmethod
- def resolve_inner(cls, resolve_context):
- pass
- @staticmethod
- def request_user_runtime_cast(request):
- pass
- @staticmethod
- def request_internal_runtime_cast():
- RawTypes.Object.request_raw_internal_runtime_cast()
- @staticmethod
- def get_code_generator():
- pass
- @staticmethod
- def get_validator_call_text():
- return "RuntimeCastHelper::assertType<InspectorValue::TypeObject>"
- @classmethod
- def get_array_item_c_type_text(cls):
- return cls.reduce_to_raw_type().get_array_item_raw_c_type_text()
- @staticmethod
- def get_setter_value_expression_pattern():
- return None
- @staticmethod
- def reduce_to_raw_type():
- return RawTypes.Object
- @staticmethod
- def get_type_model():
- return TypeModel.Object
- return PlainObjectBinding
- elif json_typable["type"] == "array":
- if "items" in json_typable:
- ad_hoc_types = []
- class AdHocTypeContext:
- container_full_name_prefix = "<not yet defined>"
- container_relative_name_prefix = ""
- @staticmethod
- def get_type_name_fix():
- return fixed_type_name
- @staticmethod
- def add_type(binding):
- ad_hoc_types.append(binding)
- item_binding = resolve_param_type(json_typable["items"], context_domain_name, AdHocTypeContext)
- class ArrayBinding:
- resolve_data_ = None
- need_internal_runtime_cast_ = False
- @classmethod
- def resolve_inner(cls, resolve_context):
- if cls.resolve_data_:
- return
- class ResolveData:
- item_type_binding = item_binding
- ad_hoc_type_list = ad_hoc_types
- cls.resolve_data_ = ResolveData
- for t in ad_hoc_types:
- t.resolve_inner(resolve_context)
- @classmethod
- def request_user_runtime_cast(cls, request):
- raise Exception("Not implemented yet")
- @classmethod
- def request_internal_runtime_cast(cls):
- if cls.need_internal_runtime_cast_:
- return
- cls.need_internal_runtime_cast_ = True
- cls.resolve_data_.item_type_binding.request_internal_runtime_cast()
- @classmethod
- def get_code_generator(array_binding_cls):
- class CodeGenerator:
- @staticmethod
- def generate_type_builder(writer, generate_context):
- ad_hoc_type_writer = writer
- resolve_data = array_binding_cls.resolve_data_
- for ad_hoc_type in resolve_data.ad_hoc_type_list:
- code_generator = ad_hoc_type.get_code_generator()
- if code_generator:
- code_generator.generate_type_builder(ad_hoc_type_writer, generate_context)
- @staticmethod
- def generate_forward_declaration(writer):
- pass
- @staticmethod
- def register_use(forward_listener):
- item_code_generator = item_binding.get_code_generator()
- if item_code_generator:
- item_code_generator.register_use(forward_listener)
- @staticmethod
- def get_generate_pass_id():
- return TypeBuilderPass.MAIN
- return CodeGenerator
- @classmethod
- def get_validator_call_text(cls):
- return cls.get_array_item_c_type_text() + "::assertCorrectValue"
- @classmethod
- def get_array_item_c_type_text(cls):
- return replace_right_shift("TypeBuilder::Array<%s>" % cls.resolve_data_.item_type_binding.get_array_item_c_type_text())
- @staticmethod
- def get_setter_value_expression_pattern():
- return None
- @staticmethod
- def reduce_to_raw_type():
- return RawTypes.Array
- @classmethod
- def get_type_model(cls):
- return TypeModel.RefPtrBased(cls.get_array_item_c_type_text())
- return ArrayBinding
- else:
- # Fall-through to raw type.
- pass
- raw_type = RawTypes.get(json_typable["type"])
- return RawTypeBinding(raw_type)
- class RawTypeBinding:
- def __init__(self, raw_type):
- self.raw_type_ = raw_type
- def resolve_inner(self, resolve_context):
- pass
- def request_user_runtime_cast(self, request):
- raise Exception("Unsupported")
- def request_internal_runtime_cast(self):
- self.raw_type_.request_raw_internal_runtime_cast()
- def get_code_generator(self):
- return None
- def get_validator_call_text(self):
- return self.raw_type_.get_raw_validator_call_text()
- def get_array_item_c_type_text(self):
- return self.raw_type_.get_array_item_raw_c_type_text()
- def get_setter_value_expression_pattern(self):
- return None
- def reduce_to_raw_type(self):
- return self.raw_type_
- def get_type_model(self):
- return self.raw_type_.get_raw_type_model()
- class TypeData(object):
- def __init__(self, json_type, json_domain, domain_data):
- self.json_type_ = json_type
- self.json_domain_ = json_domain
- self.domain_data_ = domain_data
- if "type" not in json_type:
- raise Exception("Unknown type")
- json_type_name = json_type["type"]
- raw_type = RawTypes.get(json_type_name)
- self.raw_type_ = raw_type
- self.binding_being_resolved_ = False
- self.binding_ = None
- def get_raw_type(self):
- return self.raw_type_
- def get_binding(self):
- if not self.binding_:
- if self.binding_being_resolved_:
- raise Error("Type %s is already being resolved" % self.json_type_["type"])
- # Resolve only lazily, because resolving one named type may require resolving some other named type.
- self.binding_being_resolved_ = True
- try:
- self.binding_ = TypeBindings.create_named_type_declaration(self.json_type_, self.json_domain_["domain"], self)
- finally:
- self.binding_being_resolved_ = False
- return self.binding_
- def get_json_type(self):
- return self.json_type_
- def get_name(self):
- return self.json_type_["id"]
- def get_domain_name(self):
- return self.json_domain_["domain"]
- class DomainData:
- def __init__(self, json_domain):
- self.json_domain = json_domain
- self.types_ = []
- def add_type(self, type_data):
- self.types_.append(type_data)
- def name(self):
- return self.json_domain["domain"]
- def types(self):
- return self.types_
- class TypeMap:
- def __init__(self, api):
- self.map_ = {}
- self.domains_ = []
- for json_domain in api["domains"]:
- domain_name = json_domain["domain"]
- domain_map = {}
- self.map_[domain_name] = domain_map
- domain_data = DomainData(json_domain)
- self.domains_.append(domain_data)
- if "types" in json_domain:
- for json_type in json_domain["types"]:
- type_name = json_type["id"]
- type_data = TypeData(json_type, json_domain, domain_data)
- domain_map[type_name] = type_data
- domain_data.add_type(type_data)
- def domains(self):
- return self.domains_
- def get(self, domain_name, type_name):
- return self.map_[domain_name][type_name]
- def resolve_param_type(json_parameter, scope_domain_name, ad_hoc_type_context):
- if "$ref" in json_parameter:
- json_ref = json_parameter["$ref"]
- type_data = get_ref_data(json_ref, scope_domain_name)
- return type_data.get_binding()
- elif "type" in json_parameter:
- result = TypeBindings.create_ad_hoc_type_declaration(json_parameter, scope_domain_name, ad_hoc_type_context)
- ad_hoc_type_context.add_type(result)
- return result
- else:
- raise Exception("Unknown type")
- def resolve_param_raw_type(json_parameter, scope_domain_name):
- if "$ref" in json_parameter:
- json_ref = json_parameter["$ref"]
- type_data = get_ref_data(json_ref, scope_domain_name)
- return type_data.get_raw_type()
- elif "type" in json_parameter:
- json_type = json_parameter["type"]
- return RawTypes.get(json_type)
- else:
- raise Exception("Unknown type")
- def get_ref_data(json_ref, scope_domain_name):
- dot_pos = json_ref.find(".")
- if dot_pos == -1:
- domain_name = scope_domain_name
- type_name = json_ref
- else:
- domain_name = json_ref[:dot_pos]
- type_name = json_ref[dot_pos + 1:]
- return type_map.get(domain_name, type_name)
- input_file = open(input_json_filename, "r")
- json_string = input_file.read()
- json_api = json.loads(json_string)
- class Templates:
- def get_this_script_path_(absolute_path):
- absolute_path = os.path.abspath(absolute_path)
- components = []
- def fill_recursive(path_part, depth):
- if depth <= 0 or path_part == '/':
- return
- fill_recursive(os.path.dirname(path_part), depth - 1)
- components.append(os.path.basename(path_part))
- # Typical path is /Source/WebCore/inspector/CodeGeneratorInspector.py
- # Let's take 4 components from the real path then.
- fill_recursive(absolute_path, 4)
- return "/".join(components)
- file_header_ = ("// File is generated by %s\n\n" % get_this_script_path_(sys.argv[0]) +
- """// Copyright (c) 2011 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- """)
- frontend_domain_class = string.Template(CodeGeneratorInspectorStrings.frontend_domain_class)
- backend_method = string.Template(CodeGeneratorInspectorStrings.backend_method)
- frontend_method = string.Template(CodeGeneratorInspectorStrings.frontend_method)
- callback_method = string.Template(CodeGeneratorInspectorStrings.callback_method)
- frontend_h = string.Template(file_header_ + CodeGeneratorInspectorStrings.frontend_h)
- backend_h = string.Template(file_header_ + CodeGeneratorInspectorStrings.backend_h)
- backend_cpp = string.Template(file_header_ + CodeGeneratorInspectorStrings.backend_cpp)
- frontend_cpp = string.Template(file_header_ + CodeGeneratorInspectorStrings.frontend_cpp)
- typebuilder_h = string.Template(file_header_ + CodeGeneratorInspectorStrings.typebuilder_h)
- typebuilder_cpp = string.Template(file_header_ + CodeGeneratorInspectorStrings.typebuilder_cpp)
- backend_js = string.Template(file_header_ + CodeGeneratorInspectorStrings.backend_js)
- param_container_access_code = CodeGeneratorInspectorStrings.param_container_access_code
- type_map = TypeMap(json_api)
- class NeedRuntimeCastRequest:
- def __init__(self):
- self.ack_ = None
- def acknowledge(self):
- self.ack_ = True
- def is_acknowledged(self):
- return self.ack_
- def resolve_all_types():
- runtime_cast_generate_requests = {}
- for type_name in TYPES_WITH_RUNTIME_CAST_SET:
- runtime_cast_generate_requests[type_name] = NeedRuntimeCastRequest()
- class ForwardListener:
- type_data_set = set()
- already_declared_set = set()
- @classmethod
- def add_type_data(cls, type_data):
- if type_data not in cls.already_declared_set:
- cls.type_data_set.add(type_data)
- class ResolveContext:
- forward_listener = ForwardListener
- for domain_data in type_map.domains():
- for type_data in domain_data.types():
- # Do not generate forwards for this type any longer.
- ForwardListener.already_declared_set.add(type_data)
- binding = type_data.get_binding()
- binding.resolve_inner(ResolveContext)
- for domain_data in type_map.domains():
- for type_data in domain_data.types():
- full_type_name = "%s.%s" % (type_data.get_domain_name(), type_data.get_name())
- request = runtime_cast_generate_requests.pop(full_type_name, None)
- binding = type_data.get_binding()
- if request:
- binding.request_user_runtime_cast(request)
- if request and not request.is_acknowledged():
- raise Exception("Failed to generate runtimeCast in " + full_type_name)
- for full_type_name in runtime_cast_generate_requests:
- raise Exception("Failed to generate runtimeCast. Type " + full_type_name + " not found")
- return ForwardListener
- global_forward_listener = resolve_all_types()
- def get_annotated_type_text(raw_type, annotated_type):
- if annotated_type != raw_type:
- return "/*%s*/ %s" % (annotated_type, raw_type)
- else:
- return raw_type
- def format_setter_value_expression(param_type_binding, value_ref):
- pattern = param_type_binding.get_setter_value_expression_pattern()
- if pattern:
- return pattern % value_ref
- else:
- return value_ref
- class Generator:
- frontend_class_field_lines = []
- frontend_domain_class_lines = []
- method_name_enum_list = []
- backend_method_declaration_list = []
- backend_method_implementation_list = []
- backend_method_name_declaration_list = []
- method_handler_list = []
- frontend_method_list = []
- backend_js_domain_initializer_list = []
- backend_virtual_setters_list = []
- backend_agent_interface_list = []
- backend_setters_list = []
- backend_constructor_init_list = []
- backend_field_list = []
- frontend_constructor_init_list = []
- type_builder_fragments = []
- type_builder_forwards = []
- validator_impl_list = []
- type_builder_impl_list = []
- @staticmethod
- def go():
- Generator.process_types(type_map)
- first_cycle_guardable_list_list = [
- Generator.backend_method_declaration_list,
- Generator.backend_method_implementation_list,
- Generator.backend_method_name_declaration_list,
- Generator.backend_agent_interface_list,
- Generator.frontend_class_field_lines,
- Generator.frontend_constructor_init_list,
- Generator.frontend_domain_class_lines,
- Generator.frontend_method_list,
- Generator.method_handler_list,
- Generator.method_name_enum_list,
- Generator.backend_constructor_init_list,
- Generator.backend_virtual_setters_list,
- Generator.backend_setters_list,
- Generator.backend_field_list]
- for json_domain in json_api["domains"]:
- domain_name = json_domain["domain"]
- domain_name_lower = domain_name.lower()
- domain_fixes = DomainNameFixes.get_fixed_data(domain_name)
- domain_guard = domain_fixes.get_guard()
- if domain_guard:
- for l in first_cycle_guardable_list_list:
- domain_guard.generate_open(l)
- agent_field_name = domain_fixes.agent_field_name
- frontend_method_declaration_lines = []
- Generator.backend_js_domain_initializer_list.append("// %s.\n" % domain_name)
- if not domain_fixes.skip_js_bind:
- Generator.backend_js_domain_initializer_list.append("InspectorBackend.register%sDispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, \"%s\");\n" % (domain_name, domain_name))
- if "types" in json_domain:
- for json_type in json_domain["types"]:
- if "type" in json_type and json_type["type"] == "string" and "enum" in json_type:
- enum_name = "%s.%s" % (domain_name, json_type["id"])
- Generator.process_enum(json_type, enum_name)
- elif json_type["type"] == "object":
- if "properties" in json_type:
- for json_property in json_type["properties"]:
- if "type" in json_property and json_property["type"] == "string" and "enum" in json_property:
- enum_name = "%s.%s%s" % (domain_name, json_type["id"], to_title_case(json_property["name"]))
- Generator.process_enum(json_property, enum_name)
- if "events" in json_domain:
- for json_event in json_domain["events"]:
- Generator.process_event(json_event, domain_name, frontend_method_declaration_lines)
- Generator.frontend_class_field_lines.append(" %s m_%s;\n" % (domain_name, domain_name_lower))
- if Generator.frontend_constructor_init_list:
- Generator.frontend_constructor_init_list.append(" , ")
- Generator.frontend_constructor_init_list.append("m_%s(inspectorFrontendChannel)\n" % domain_name_lower)
- Generator.frontend_domain_class_lines.append(Templates.frontend_domain_class.substitute(None,
- domainClassName=domain_name,
- domainFieldName=domain_name_lower,
- frontendDomainMethodDeclarations="".join(flatten_list(frontend_method_declaration_lines))))
- agent_interface_name = Capitalizer.lower_camel_case_to_upper(domain_name) + "CommandHandler"
- Generator.backend_agent_interface_list.append(" class %s {\n" % agent_interface_name)
- Generator.backend_agent_interface_list.append(" public:\n")
- if "commands" in json_domain:
- for json_command in json_domain["commands"]:
- Generator.process_command(json_command, domain_name, agent_field_name, agent_interface_name)
- Generator.backend_agent_interface_list.append("\n protected:\n")
- Generator.backend_agent_interface_list.append(" virtual ~%s() { }\n" % agent_interface_name)
- Generator.backend_agent_interface_list.append(" };\n\n")
- Generator.backend_constructor_init_list.append(" , m_%s(0)" % agent_field_name)
- Generator.backend_virtual_setters_list.append(" virtual void registerAgent(%s* %s) = 0;" % (agent_interface_name, agent_field_name))
- Generator.backend_setters_list.append(" virtual void registerAgent(%s* %s) { ASSERT(!m_%s); m_%s = %s; }" % (agent_interface_name, agent_field_name, agent_field_name, agent_field_name, agent_field_name))
- Generator.backend_field_list.append(" %s* m_%s;" % (agent_interface_name, agent_field_name))
- if domain_guard:
- for l in reversed(first_cycle_guardable_list_list):
- domain_guard.generate_close(l)
- Generator.backend_js_domain_initializer_list.append("\n")
- @staticmethod
- def process_enum(json_enum, enum_name):
- enum_members = []
- for member in json_enum["enum"]:
- enum_members.append("%s: \"%s\"" % (fix_camel_case(member), member))
- Generator.backend_js_domain_initializer_list.append("InspectorBackend.registerEnum(\"%s\", {%s});\n" % (
- enum_name, ", ".join(enum_members)))
- @staticmethod
- def process_event(json_event, domain_name, frontend_method_declaration_lines):
- event_name = json_event["name"]
- ad_hoc_type_output = []
- frontend_method_declaration_lines.append(ad_hoc_type_output)
- ad_hoc_type_writer = Writer(ad_hoc_type_output, " ")
- decl_parameter_list = []
- json_parameters = json_event.get("parameters")
- Generator.generate_send_method(json_parameters, event_name, domain_name, ad_hoc_type_writer,
- decl_parameter_list,
- Generator.EventMethodStructTemplate,
- Generator.frontend_method_list, Templates.frontend_method, {"eventName": event_name})
- backend_js_event_param_list = []
- if json_parameters:
- for parameter in json_parameters:
- parameter_name = parameter["name"]
- backend_js_event_param_list.append("\"%s\"" % parameter_name)
- frontend_method_declaration_lines.append(
- " void %s(%s);\n" % (event_name, ", ".join(decl_parameter_list)))
- Generator.backend_js_domain_initializer_list.append("InspectorBackend.registerEvent(\"%s.%s\", [%s]);\n" % (
- domain_name, event_name, ", ".join(backend_js_event_param_list)))
- class EventMethodStructTemplate:
- @staticmethod
- def append_prolog(line_list):
- line_list.append(" RefPtr<InspectorObject> paramsObject = InspectorObject::create();\n")
- @staticmethod
- def append_epilog(line_list):
- line_list.append(" jsonMessage->setObject(\"params\", paramsObject);\n")
- container_name = "paramsObject"
- @staticmethod
- def process_command(json_command, domain_name, agent_field_name, agent_interface_name):
- json_command_name = json_command["name"]
- cmd_enum_name = "k%s_%sCmd" % (domain_name, json_command["name"])
- Generator.method_name_enum_list.append(" %s," % cmd_enum_name)
- Generator.method_handler_list.append(" &InspectorBackendDispatcherImpl::%s_%s," % (domain_name, json_command_name))
- Generator.backend_method_declaration_list.append(" void %s_%s(long callId, InspectorObject* requestMessageObject);" % (domain_name, json_command_name))
- ad_hoc_type_output = []
- Generator.backend_agent_interface_list.append(ad_hoc_type_output)
- ad_hoc_type_writer = Writer(ad_hoc_type_output, " ")
- Generator.backend_agent_interface_list.append(" virtual void %s(ErrorString*" % json_command_name)
- method_in_code = ""
- method_out_code = ""
- agent_call_param_list = []
- response_cook_list = []
- request_message_param = ""
- js_parameters_text = ""
- if "parameters" in json_command:
- json_params = json_command["parameters"]
- method_in_code += Templates.param_container_access_code
- request_message_param = " requestMessageObject"
- js_param_list = []
- for json_parameter in json_params:
- json_param_name = json_parameter["name"]
- param_raw_type = resolve_param_raw_type(json_parameter, domain_name)
- getter_name = param_raw_type.get_getter_name()
- optional = json_parameter.get("optional")
- non_optional_type_model = param_raw_type.get_raw_type_model()
- if optional:
- type_model = non_optional_type_model.get_optional()
- else:
- type_model = non_optional_type_model
- if optional:
- code = (" bool %s_valueFound = false;\n"
- " %s in_%s = get%s(paramsContainerPtr, \"%s\", &%s_valueFound, protocolErrorsPtr);\n" %
- (json_param_name, non_optional_type_model.get_command_return_pass_model().get_return_var_type(), json_param_name, getter_name, json_param_name, json_param_name))
- param = ", %s_valueFound ? &in_%s : 0" % (json_param_name, json_param_name)
- # FIXME: pass optional refptr-values as PassRefPtr
- formal_param_type_pattern = "const %s*"
- else:
- code = (" %s in_%s = get%s(paramsContainerPtr, \"%s\", 0, protocolErrorsPtr);\n" %
- (non_optional_type_model.get_command_return_pass_model().get_return_var_type(), json_param_name, getter_name, json_param_name))
- param = ", in_%s" % json_param_name
- # FIXME: pass not-optional refptr-values as NonNullPassRefPtr
- if param_raw_type.is_heavy_value():
- formal_param_type_pattern = "const %s&"
- else:
- formal_param_type_pattern = "%s"
- method_in_code += code
- agent_call_param_list.append(param)
- Generator.backend_agent_interface_list.append(", %s in_%s" % (formal_param_type_pattern % non_optional_type_model.get_command_return_pass_model().get_return_var_type(), json_param_name))
- js_bind_type = param_raw_type.get_js_bind_type()
- js_param_text = "{\"name\": \"%s\", \"type\": \"%s\", \"optional\": %s}" % (
- json_param_name,
- js_bind_type,
- ("true" if ("optional" in json_parameter and json_parameter["optional"]) else "false"))
- js_param_list.append(js_param_text)
- js_parameters_text = ", ".join(js_param_list)
- response_cook_text = ""
- if json_command.get("async") == True:
- callback_name = Capitalizer.lower_camel_case_to_upper(json_command_name) + "Callback"
- callback_output = []
- callback_writer = Writer(callback_output, ad_hoc_type_writer.get_indent())
- decl_parameter_list = []
- Generator.generate_send_method(json_command.get("returns"), json_command_name, domain_name, ad_hoc_type_writer,
- decl_parameter_list,
- Generator.CallbackMethodStructTemplate,
- Generator.backend_method_implementation_list, Templates.callback_method,
- {"callbackName": callback_name, "agentName": agent_interface_name})
- callback_writer.newline("class " + callback_name + " : public CallbackBase {\n")
- callback_writer.newline("public:\n")
- callback_writer.newline(" " + callback_name + "(PassRefPtr<InspectorBackendDispatcherImpl>, int id);\n")
- callback_writer.newline(" void sendSuccess(" + ", ".join(decl_parameter_list) + ");\n")
- callback_writer.newline("};\n")
- ad_hoc_type_output.append(callback_output)
- method_out_code += " RefPtr<" + agent_interface_name + "::" + callback_name + "> callback = adoptRef(new " + agent_interface_name + "::" + callback_name + "(this, callId));\n"
- agent_call_param_list.append(", callback")
- response_cook_text += " if (!error.length()) \n"
- response_cook_text += " return;\n"
- response_cook_text += " callback->disable();\n"
- Generator.backend_agent_interface_list.append(", PassRefPtr<%s> callback" % callback_name)
- else:
- if "returns" in json_command:
- method_out_code += "\n"
- for json_return in json_command["returns"]:
- json_return_name = json_return["name"]
- optional = bool(json_return.get("optional"))
- return_type_binding = Generator.resolve_type_and_generate_ad_hoc(json_return, json_command_name, domain_name, ad_hoc_type_writer, agent_interface_name + "::")
- raw_type = return_type_binding.reduce_to_raw_type()
- setter_type = raw_type.get_setter_name()
- initializer = raw_type.get_c_initializer()
- type_model = return_type_binding.get_type_model()
- if optional:
- type_model = type_model.get_optional()
- code = " %s out_%s;\n" % (type_model.get_command_return_pass_model().get_return_var_type(), json_return_name)
- param = ", %sout_%s" % (type_model.get_command_return_pass_model().get_output_argument_prefix(), json_return_name)
- var_name = "out_%s" % json_return_name
- setter_argument = type_model.get_command_return_pass_model().get_output_to_raw_expression() % var_name
- if return_type_binding.get_setter_value_expression_pattern():
- setter_argument = return_type_binding.get_setter_value_expression_pattern() % setter_argument
- cook = " result->set%s(\"%s\", %s);\n" % (setter_type, json_return_name,
- setter_argument)
- set_condition_pattern = type_model.get_command_return_pass_model().get_set_return_condition()
- if set_condition_pattern:
- cook = (" if (%s)\n " % (set_condition_pattern % var_name)) + cook
- annotated_type = type_model.get_command_return_pass_model().get_output_parameter_type()
- param_name = "out_%s" % json_return_name
- if optional:
- param_name = "opt_" + param_name
- Generator.backend_agent_interface_list.append(", %s %s" % (annotated_type, param_name))
- response_cook_list.append(cook)
- method_out_code += code
- agent_call_param_list.append(param)
- response_cook_text = "".join(response_cook_list)
- if len(response_cook_text) != 0:
- response_cook_text = " if (!error.length()) {\n" + response_cook_text + " }"
- backend_js_reply_param_list = []
- if "returns" in json_command:
- for json_return in json_command["returns"]:
- json_return_name = json_return["name"]
- backend_js_reply_param_list.append("\"%s\"" % json_return_name)
- js_reply_list = "[%s]" % ", ".join(backend_js_reply_param_list)
- Generator.backend_method_implementation_list.append(Templates.backend_method.substitute(None,
- domainName=domain_name, methodName=json_command_name,
- agentField="m_" + agent_field_name,
- methodInCode=method_in_code,
- methodOutCode=method_out_code,
- agentCallParams="".join(agent_call_param_list),
- requestMessageObject=request_message_param,
- responseCook=response_cook_text,
- commandNameIndex=cmd_enum_name))
- Generator.backend_method_name_declaration_list.append(" \"%s.%s\"," % (domain_name, json_command_name))
- Generator.backend_js_domain_initializer_list.append("InspectorBackend.registerCommand(\"%s.%s\", [%s], %s);\n" % (domain_name, json_command_name, js_parameters_text, js_reply_list))
- Generator.backend_agent_interface_list.append(") = 0;\n")
- class CallbackMethodStructTemplate:
- @staticmethod
- def append_prolog(line_list):
- pass
- @staticmethod
- def append_epilog(line_list):
- pass
- container_name = "jsonMessage"
- # Generates common code for event sending and callback response data sending.
- @staticmethod
- def generate_send_method(parameters, event_name, domain_name, ad_hoc_type_writer, decl_parameter_list,
- method_struct_template,
- generator_method_list, method_template, template_params):
- method_line_list = []
- if parameters:
- method_struct_template.append_prolog(method_line_list)
- for json_parameter in parameters:
- parameter_name = json_parameter["name"]
- param_type_binding = Generator.resolve_type_and_generate_ad_hoc(json_parameter, event_name, domain_name, ad_hoc_type_writer, "")
- raw_type = param_type_binding.reduce_to_raw_type()
- raw_type_binding = RawTypeBinding(raw_type)
- optional = bool(json_parameter.get("optional"))
- setter_type = raw_type.get_setter_name()
- type_model = param_type_binding.get_type_model()
- raw_type_model = raw_type_binding.get_type_model()
- if optional:
- type_model = type_model.get_optional()
- raw_type_model = raw_type_model.get_optional()
- annotated_type = type_model.get_input_param_type_text()
- mode_type_binding = param_type_binding
- decl_parameter_list.append("%s %s" % (annotated_type, parameter_name))
- setter_argument = raw_type_model.get_event_setter_expression_pattern() % parameter_name
- if mode_type_binding.get_setter_value_expression_pattern():
- setter_argument = mode_type_binding.get_setter_value_expression_pattern() % setter_argument
- setter_code = " %s->set%s(\"%s\", %s);\n" % (method_struct_template.container_name, setter_type, parameter_name, setter_argument)
- if optional:
- setter_code = (" if (%s)\n " % parameter_name) + setter_code
- method_line_list.append(setter_code)
- method_struct_template.append_epilog(method_line_list)
- generator_method_list.append(method_template.substitute(None,
- domainName=domain_name,
- parameters=", ".join(decl_parameter_list),
- code="".join(method_line_list), **template_params))
- @staticmethod
- def resolve_type_and_generate_ad_hoc(json_param, method_name, domain_name, ad_hoc_type_writer, container_relative_name_prefix_param):
- param_name = json_param["name"]
- ad_hoc_type_list = []
- class AdHocTypeContext:
- container_full_name_prefix = "<not yet defined>"
- container_relative_name_prefix = container_relative_name_prefix_param
- @staticmethod
- def get_type_name_fix():
- class NameFix:
- class_name = Capitalizer.lower_camel_case_to_upper(param_name)
- @staticmethod
- def output_comment(writer):
- writer.newline("// Named after parameter '%s' while generating command/event %s.\n" % (param_name, method_name))
- return NameFix
- @staticmethod
- def add_type(binding):
- ad_hoc_type_list.append(binding)
- type_binding = resolve_param_type(json_param, domain_name, AdHocTypeContext)
- class InterfaceForwardListener:
- @staticmethod
- def add_type_data(type_data):
- pass
- class InterfaceResolveContext:
- forward_listener = InterfaceForwardListener
- for type in ad_hoc_type_list:
- type.resolve_inner(InterfaceResolveContext)
- class InterfaceGenerateContext:
- validator_writer = "not supported in InterfaceGenerateContext"
- cpp_writer = validator_writer
- for type in ad_hoc_type_list:
- generator = type.get_code_generator()
- if generator:
- generator.generate_type_builder(ad_hoc_type_writer, InterfaceGenerateContext)
- return type_binding
- @staticmethod
- def process_types(type_map):
- output = Generator.type_builder_fragments
- class GenerateContext:
- validator_writer = Writer(Generator.validator_impl_list, "")
- cpp_writer = Writer(Generator.type_builder_impl_list, "")
- def generate_all_domains_code(out, type_data_callback):
- writer = Writer(out, "")
- for domain_data in type_map.domains():
- domain_fixes = DomainNameFixes.get_fixed_data(domain_data.name())
- domain_guard = domain_fixes.get_guard()
- namespace_declared = []
- def namespace_lazy_generator():
- if not namespace_declared:
- if domain_guard:
- domain_guard.generate_open(out)
- writer.newline("namespace ")
- writer.append(domain_data.name())
- writer.append(" {\n")
- # What is a better way to change value from outer scope?
- namespace_declared.append(True)
- return writer
- for type_data in domain_data.types():
- type_data_callback(type_data, namespace_lazy_generator)
- if namespace_declared:
- writer.append("} // ")
- writer.append(domain_data.name())
- writer.append("\n\n")
- if domain_guard:
- domain_guard.generate_close(out)
- def create_type_builder_caller(generate_pass_id):
- def call_type_builder(type_data, writer_getter):
- code_generator = type_data.get_binding().get_code_generator()
- if code_generator and generate_pass_id == code_generator.get_generate_pass_id():
- writer = writer_getter()
- code_generator.generate_type_builder(writer, GenerateContext)
- return call_type_builder
- generate_all_domains_code(output, create_type_builder_caller(TypeBuilderPass.MAIN))
- Generator.type_builder_forwards.append("// Forward declarations.\n")
- def generate_forward_callback(type_data, writer_getter):
- if type_data in global_forward_listener.type_data_set:
- binding = type_data.get_binding()
- binding.get_code_generator().generate_forward_declaration(writer_getter())
- generate_all_domains_code(Generator.type_builder_forwards, generate_forward_callback)
- Generator.type_builder_forwards.append("// End of forward declarations.\n\n")
- Generator.type_builder_forwards.append("// Typedefs.\n")
- generate_all_domains_code(Generator.type_builder_forwards, create_type_builder_caller(TypeBuilderPass.TYPEDEF))
- Generator.type_builder_forwards.append("// End of typedefs.\n\n")
- def flatten_list(input):
- res = []
- def fill_recursive(l):
- for item in l:
- if isinstance(item, list):
- fill_recursive(item)
- else:
- res.append(item)
- fill_recursive(input)
- return res
- # A writer that only updates file if it actually changed to better support incremental build.
- class SmartOutput:
- def __init__(self, file_name):
- self.file_name_ = file_name
- self.output_ = ""
- def write(self, text):
- self.output_ += text
- def close(self):
- text_changed = True
- try:
- read_file = open(self.file_name_, "r")
- old_text = read_file.read()
- read_file.close()
- text_changed = old_text != self.output_
- except:
- # Ignore, just overwrite by default
- pass
- if text_changed or write_always:
- out_file = open(self.file_name_, "w")
- out_file.write(self.output_)
- out_file.close()
- Generator.go()
- backend_h_file = SmartOutput(output_header_dirname + "/InspectorBackendDispatcher.h")
- backend_cpp_file = SmartOutput(output_cpp_dirname + "/InspectorBackendDispatcher.cpp")
- frontend_h_file = SmartOutput(output_header_dirname + "/InspectorFrontend.h")
- frontend_cpp_file = SmartOutput(output_cpp_dirname + "/InspectorFrontend.cpp")
- typebuilder_h_file = SmartOutput(output_header_dirname + "/InspectorTypeBuilder.h")
- typebuilder_cpp_file = SmartOutput(output_cpp_dirname + "/InspectorTypeBuilder.cpp")
- backend_js_file = SmartOutput(output_cpp_dirname + "/InspectorBackendCommands.js")
- backend_h_file.write(Templates.backend_h.substitute(None,
- virtualSetters="\n".join(Generator.backend_virtual_setters_list),
- agentInterfaces="".join(flatten_list(Generator.backend_agent_interface_list)),
- methodNamesEnumContent="\n".join(Generator.method_name_enum_list)))
- backend_cpp_file.write(Templates.backend_cpp.substitute(None,
- constructorInit="\n".join(Generator.backend_constructor_init_list),
- setters="\n".join(Generator.backend_setters_list),
- fieldDeclarations="\n".join(Generator.backend_field_list),
- methodNameDeclarations="\n".join(Generator.backend_method_name_declaration_list),
- methods="\n".join(Generator.backend_method_implementation_list),
- methodDeclarations="\n".join(Generator.backend_method_declaration_list),
- messageHandlers="\n".join(Generator.method_handler_list)))
- frontend_h_file.write(Templates.frontend_h.substitute(None,
- fieldDeclarations="".join(Generator.frontend_class_field_lines),
- domainClassList="".join(Generator.frontend_domain_class_lines)))
- frontend_cpp_file.write(Templates.frontend_cpp.substitute(None,
- constructorInit="".join(Generator.frontend_constructor_init_list),
- methods="\n".join(Generator.frontend_method_list)))
- typebuilder_h_file.write(Templates.typebuilder_h.substitute(None,
- typeBuilders="".join(flatten_list(Generator.type_builder_fragments)),
- forwards="".join(Generator.type_builder_forwards),
- validatorIfdefName=VALIDATOR_IFDEF_NAME))
- typebuilder_cpp_file.write(Templates.typebuilder_cpp.substitute(None,
- enumConstantValues=EnumConstants.get_enum_constant_code(),
- implCode="".join(flatten_list(Generator.type_builder_impl_list)),
- validatorCode="".join(flatten_list(Generator.validator_impl_list)),
- validatorIfdefName=VALIDATOR_IFDEF_NAME))
- backend_js_file.write(Templates.backend_js.substitute(None,
- domainInitializers="".join(Generator.backend_js_domain_initializer_list)))
- backend_h_file.close()
- backend_cpp_file.close()
- frontend_h_file.close()
- frontend_cpp_file.close()
- typebuilder_h_file.close()
- typebuilder_cpp_file.close()
- backend_js_file.close()
|