3 # Copyright 2014 The Chromium Authors. All rights reserved.
4 # Use of this source code is governed by a BSD-style license that can be
5 # found in the LICENSE file.
10 'InjectedScriptHost': 'InjectedScriptHostClass'
15 'DOMString': 'string',
17 'unsigned short': 'number',
19 'unsigned long': 'number',
35 r
'\w+' # Non IDL-specific object types.
41 # 3: nullable (optional)
42 type_expr
= r
'\b(' + r
'|'.join(idl_type_exprs
) + r
')\b(\[\])?(\?)?'
47 # 3: nullable (optional)
50 method_expr
= r
'^\s*(?:\[.+\])?\s+' + type_expr
+ r
'\s+(\w+)\s*\(([^)]*)\)\s*;\s*$'
51 method_regex
= re
.compile(method_expr
)
56 # 3: nullable (optional)
58 attribute_expr
= r
'^\s*(?:\[.+\]\s+)?(?:\breadonly\s+)?\battribute\s+' + type_expr
+ r
'\s+(\w+)\s*;'
59 attribute_regex
= re
.compile(attribute_expr
)
62 # 1: optional (optional)
65 # 4: nullable (optional)
67 arg_regex
= re
.compile(r
'\s*(?:\[[^]]+\]\s*)?(\boptional\s+)?' + type_expr
+ r
'\s+(\w+)')
69 interface_regex
= r
'\binterface\s+(\w+)'
72 /** @type {!Window} */
80 def __init__(self
, type_name
, is_array
, is_nullable
):
81 self
.type_name
= re
.sub(r
'\s+', ' ', type_name
)
82 self
.is_array
= is_array
83 self
.is_nullable
= is_nullable
86 if self
.type_name
== 'void':
91 elif self
._is
_object
_type
():
94 result
+= 'Array.<%s>' % Type(self
.type_name
, False, False).as_js_type()
96 result
+= type_map
.get(self
.type_name
, self
.type_name
)
99 def _is_object_type(self
):
100 return self
.is_array
or self
.type_name
== 'object' or not type_map
.get(self
.type_name
)
104 def __init__(self
, type, name
):
110 def __init__(self
, type, optional
, name
):
112 self
.optional
= optional
115 def as_js_param_type(self
):
116 result
= self
.type.as_js_type()
123 def __init__(self
, return_type
, name
, args
):
124 self
.return_type
= return_type
128 def js_argument_names(self
):
130 for arg
in self
.args
:
131 result
.append(arg
.name
)
132 return ', '.join(result
)
136 def __init__(self
, name
, methods
, attributes
):
138 self
.methods
= methods
139 self
.attributes
= attributes
142 def parse_args(text
):
144 for (optional
, type_name
, is_array
, is_nullable
, arg_name
) in re
.findall(arg_regex
, text
):
145 arguments
.append(Argument(Type(type_name
, is_array
, is_nullable
), optional
!= '', arg_name
))
149 def read_interface(idl
):
152 with
open(idl
, "r") as input_file
:
153 for line
in input_file
.readlines():
154 match
= re
.search(method_regex
, line
)
156 return_type
= Type(match
.group(1), match
.group(2) is not None, match
.group(3) is not None)
157 name
= match
.group(4)
158 methods
.append(Method(return_type
, name
, parse_args(match
.group(5))))
160 match
= re
.search(attribute_regex
, line
)
162 type = Type(match
.group(1), match
.group(2) is not None, match
.group(3) is not None)
163 name
= match
.group(4)
164 attributes
.append(Attribute(type, name
))
166 match
= re
.search(interface_regex
, line
)
168 interface_name
= match
.group(1)
169 return Interface(interface_name
, methods
, attributes
)
172 def generate_injected_script_externs(input_idls
, output
):
173 for idl
in input_idls
:
174 ifc
= read_interface(idl
)
175 interface_name
= interface_name_map
.get(ifc
.name
, ifc
.name
)
176 output
.write('/** @interface */\nfunction %s()\n{\n' % interface_name
)
177 for attribute
in ifc
.attributes
:
178 output
.write(' /** @type {%s} */\n' % attribute
.type.as_js_type())
179 output
.write(' this.%s;\n' % attribute
.name
)
181 for method
in ifc
.methods
:
182 output
.write('\n/**\n')
183 for arg
in method
.args
:
184 output
.write(' * @param {%s} %s\n' % (arg
.as_js_param_type(), arg
.name
))
185 return_type
= method
.return_type
.as_js_type()
187 output
.write(' * @return {%s}\n' % return_type
)
188 output
.write(' */\n')
189 output
.write('%s.prototype.%s = function(%s) {}\n' % (interface_name
, method
.name
, method
.js_argument_names()))
190 if interface_name
!= ifc
.name
:
191 output
.write('\n/** @type {!%s} */\nvar %s;\n' % (interface_name
, ifc
.name
))
193 output
.write(other_externs
)
196 def generate_injected_script_externs_to_file(input_idls
, output_name
):
197 with
open(output_name
, 'w') as output
:
198 generate_injected_script_externs(input_idls
, output
)
203 program_name
= os
.path
.basename(__file__
)
205 sys
.stderr
.write("Usage: %s IDL_1 ... IDL_N OUTPUT_FILE\n" % program_name
)
207 input_idls
= argv
[1:-1]
208 generate_injected_script_externs_to_file(input_idls
, argv
[-1])
211 if __name__
== "__main__":
213 sys
.exit(main(sys
.argv
))