def _GenerateCreateCallbackArguments(self, function): """Generates functions for passing paramaters to a callback. """ c = Code() params = function.params c.Concat(self._GeneratePropertyStructures(params)) param_lists = self._cpp_type_generator.GetAllPossibleParameterLists( params) for param_list in param_lists: declaration_list = [] for param in param_list: if param.description: c.Comment(param.description) declaration_list.append( 'const %s' % cpp_util.GetParameterDeclaration( param, self._cpp_type_generator.GetType(param))) c.Append('scoped_ptr<base::ListValue> Create(%s);' % ', '.join(declaration_list)) return c
def GenerateForwardDeclarations(self): """Returns the forward declarations for self._namespace. Use after GetRootNamespaceStart. Assumes all namespaces are relative to self._root_namespace. """ c = Code() for namespace, types in sorted( self._NamespaceTypeDependencies().items()): c.Append('namespace %s {' % namespace.name) for type_ in types: if namespace.types[type_].type_ != PropertyType.ARRAY: c.Append('struct %s;' % type_) c.Append('}') c.Concat(self.GetNamespaceStart()) for (name, type_) in self._namespace.types.items(): if not type_.functions and type_.type_ != PropertyType.ARRAY: c.Append('struct %s;' % name) c.Concat(self.GetNamespaceEnd()) return c
def _GenerateChoiceTypeToValue(self, cpp_namespace, type_): """Generates a function that serializes a choice-representing type into a base::Value. """ c = Code() c.Sblock('std::unique_ptr<base::Value> %s::ToValue() const {' % cpp_namespace) c.Append('std::unique_ptr<base::Value> result;') for choice in type_.choices: choice_var = 'as_%s' % choice.unix_name # Enums cannot be wrapped with scoped_ptr, but the XXX_NONE enum value # is equal to 0. (c.Sblock('if (%s) {' % choice_var) .Append('DCHECK(!result) << "Cannot set multiple choices for %s";' % type_.unix_name).Cblock(self._CreateValueFromType( 'result = %s;', choice.name, choice, choice_var, True)) .Eblock('}')) (c.Append('DCHECK(result) << "Must set at least one choice for %s";' % type_.unix_name).Append('return result;').Eblock('}')) return c
def GenerateIncludes(self, include_soft=False): """Returns the #include lines for self._default_namespace. """ c = Code() if self._default_namespace.manifest_keys: c.Append('#include "base/strings/string_piece.h"') # Note: It's possible that there are multiple dependencies from the same # API. Make sure to only include them once. added_paths = set() for namespace, dependencies in self._NamespaceTypeDependencies().items( ): for dependency in dependencies: if dependency.hard or include_soft: path = '%s/%s.h' % (namespace.source_file_dir, namespace.unix_name) if path not in added_paths: added_paths.add(path) c.Append('#include "%s"' % cpp_util.ToPosixPath(path)) return c
def _InitializePropertyToDefault(self, prop, dst): """Initialize a model.Property to its default value inside an object. E.g for optional enum "state", generate dst->state = STATE_NONE; dst: Type* """ c = Code() underlying_type = self._type_helper.FollowRef(prop.type_) if (underlying_type.property_type == PropertyType.ENUM and prop.optional): namespace_prefix = ('%s::' % underlying_type.namespace.unix_name if underlying_type.namespace != self._namespace else '') c.Append('%s->%s = %s%s;' % ( dst, prop.unix_name, namespace_prefix, self._type_helper.GetEnumNoneValue(prop.type_))) return c
def Generate(self): """Generates a Code object with the schema for the entire namespace. """ c = Code() (c.Append(self._GetHeader(sys.argv[0], self._namespace.name)).Append()) c.Cblock(self._GenerateNamespaceObject()) for js_type in self._namespace.types.values(): c.Cblock(self._GenerateType(js_type)) for function in self._namespace.functions.values(): c.Cblock(self._GenerateFunction(function)) for event in self._namespace.events.values(): c.Cblock(self._GenerateEvent(event)) c.TrimTrailingNewlines() return c
def Generate(self): """Generates a Code object with the schema for the entire namespace. """ c = Code() (c.Append(self._GetHeader(sys.argv[0], self._namespace.name)).Append()) self._AppendNamespaceObject(c) for js_type in self._namespace.types.values(): self._AppendType(c, js_type) for function in self._namespace.functions.values(): self._AppendFunction(c, function) for event in self._namespace.events.values(): self._AppendEvent(c, event) c.TrimTrailingNewlines() return c
def testLinePrefixes(self): c = Code() c.Sblock(line='/**', line_prefix=' * ') c.Sblock('@typedef {{') c.Append('foo: bar,') c.Sblock('baz: {') c.Append('x: y') c.Eblock('}') c.Eblock('}}') c.Eblock(line=' */') output = c.Render() self.assertMultiLineEqual( '/**\n' ' * @typedef {{\n' ' * foo: bar,\n' ' * baz: {\n' ' * x: y\n' ' * }\n' ' * }}\n' ' */', output)
def _GenerateFunctionJsDoc(self, function): """Generates the documentation for a function as a Code. Returns an empty code object if the object has no documentation. """ c = Code() c.Sblock(line='/**', line_prefix=' * ') if function.description: c.Comment(function.description, comment_prefix='') def append_field(c, tag, js_type, name, optional, description): c.Append('@%s {' % tag) c.Concat(js_type, new_line=False) if optional: c.Append('=', new_line=False) c.Append('} %s' % name, new_line=False) if description: c.Comment(' %s' % description, comment_prefix='', wrap_indent=4, new_line=False) for param in function.params: append_field(c, 'param', self._TypeToJsType(param.type_), param.name, param.optional, param.description) if function.callback: append_field(c, 'param', self._FunctionToJsFunction(function.callback), function.callback.name, function.callback.optional, function.callback.description) if function.returns: append_field(c, 'return', self._TypeToJsType(function.returns), '', False, function.returns.description) if function.deprecated: c.Append('@deprecated %s' % function.deprecated) c.Append(self._GenerateSeeLink('method', function.name)) c.Eblock(' */') return c
def Generate(self): """Generates a Code object with the .cc for a single namespace. """ cpp_namespace = cpp_util.GetCppNamespace( self._namespace.environment.namespace_pattern, self._namespace.unix_name) c = Code() (c.Append(cpp_util.CHROMIUM_LICENSE).Append().Append( cpp_util.GENERATED_FILE_MESSAGE % self._namespace.source_file). Append().Append(self._util_cc_helper.GetIncludePath()).Append( '#include "base/logging.h"').Append('#include "base/stl_util.h"'). Append('#include "base/strings/string_number_conversions.h"'). Append('#include "base/strings/utf_string_conversions.h"').Append( '#include "%s/%s.h"' % (self._namespace.source_file_dir, self._namespace.short_filename)).Append('#include <set>').Cblock( self._type_helper.GenerateIncludes(include_soft=True) ).Append().Append('using base::UTF8ToUTF16;').Append().Concat( cpp_util.OpenNamespace(cpp_namespace))) if self._namespace.properties: (c.Append('//').Append('// Properties').Append('//').Append()) for prop in self._namespace.properties.values(): property_code = self._type_helper.GeneratePropertyValues( prop, 'const %(type)s %(name)s = %(value)s;', nodoc=True) if property_code: c.Cblock(property_code) if self._namespace.types: (c.Append('//').Append('// Types').Append('//').Append().Cblock( self._GenerateTypes(None, self._namespace.types.values()))) if self._namespace.functions: (c.Append('//').Append('// Functions').Append('//').Append()) for function in self._namespace.functions.values(): c.Cblock(self._GenerateFunction(function)) if self._namespace.events: (c.Append('//').Append('// Events').Append('//').Append()) for event in self._namespace.events.values(): c.Cblock(self._GenerateEvent(event)) c.Cblock(cpp_util.CloseNamespace(cpp_namespace)) c.Append() return c
def main(): from space import Space import fill_space from pyjsparser import parse import json a = ByteCodeGenerator(Code()) s = Space() fill_space.fill_space(s, a) a.exe.space = s s.exe = a.exe con = get_file_contents('internals/esprima.js') d = parse(con + (''';JSON.stringify(exports.parse(%s), 4, 4)''' % json.dumps(con))) # d = parse(''' # function x(n) { # log(n) # return x(n+1) # } # x(0) # ''') # var v = 333333; # while (v) { # v-- # # } a.emit(d) print a.declared_vars print a.exe.tape print len(a.exe.tape) a.exe.compile() def log(this, args): print args[0] return 999 print a.exe.run(a.exe.space.GlobalObj)
def _GenerateFunctionParamsCreate(self, function): """Generate function to create an instance of Params. The generated function takes a base::ListValue of arguments. E.g for function "Bar", generate Bar::Params::Create() """ c = Code() (c.Append('// static').Sblock( 'scoped_ptr<Params> Params::Create(%s) {' % self._GenerateParams(['const base::ListValue& args']))) if self._generate_error_messages: c.Append('DCHECK(error);') (c.Concat(self._GenerateParamsCheck( function, 'args')).Append('scoped_ptr<Params> params(new Params());')) for param in function.params: c.Concat(self._InitializePropertyToDefault(param, 'params')) for i, param in enumerate(function.params): # Any failure will cause this function to return. If any argument is # incorrect or missing, those following it are not processed. Note that # for optional arguments, we allow missing arguments and proceed because # there may be other arguments following it. failure_value = 'scoped_ptr<Params>()' c.Append() value_var = param.unix_name + '_value' (c.Append('const base::Value* %(value_var)s = NULL;').Append( 'if (args.Get(%(i)s, &%(value_var)s) &&').Sblock( ' !%(value_var)s->IsType(base::Value::TYPE_NULL)) {'). Concat( self._GeneratePopulatePropertyFromValue( param, value_var, 'params', failure_value)).Eblock('}')) if not param.optional: (c.Sblock('else {').Concat( self._GenerateError('"\'%%(key)s\' is required"')).Append( 'return %s;' % failure_value).Eblock('}')) c.Substitute({'value_var': value_var, 'i': i, 'key': param.name}) (c.Append().Append('return params.Pass();').Eblock('}').Append()) return c
def _GenerateTypePopulateProperty(self, prop, src, dst): """Generate the code to populate a single property in a type. src: base::DictionaryValue* dst: Type* """ c = Code() value_var = prop.unix_name + '_value' c.Append('const base::Value* %(value_var)s = NULL;') if prop.optional: (c.Sblock( 'if (%(src)s->GetWithoutPathExpansion("%(key)s", &%(value_var)s)) {' ).Concat( self._GeneratePopulatePropertyFromValue( prop, value_var, dst, 'false'))) underlying_type = self._type_helper.FollowRef(prop.type_) if underlying_type.property_type == PropertyType.ENUM: namespace_prefix = ( '%s::' % underlying_type.namespace.unix_name if underlying_type.namespace != self._namespace else '') (c.Append('} else {').Append( '%%(dst)s->%%(name)s = %s%s;' % (namespace_prefix, self._type_helper.GetEnumNoneValue(prop.type_)))) c.Eblock('}') else: (c.Sblock( 'if (!%(src)s->GetWithoutPathExpansion("%(key)s", &%(value_var)s)) {' ).Concat(self._GenerateError('"\'%%(key)s\' is required"')).Append( 'return false;').Eblock('}').Concat( self._GeneratePopulatePropertyFromValue( prop, value_var, dst, 'false'))) c.Append() c.Substitute({ 'value_var': value_var, 'key': prop.name, 'src': src, 'dst': dst, 'name': prop.unix_name }) return c
def _GenerateStringToEnumConversion(self, type_, src_var, dst_var, failure_value): """Returns Code that converts a string type in |src_var| to an enum with type |type_| in |dst_var|. In the generated code, if |src_var| is not a valid enum name then the function will return |failure_value|. """ if type_.property_type != PropertyType.ENUM: raise TypeError(type_) c = Code() enum_as_string = '%s_as_string' % type_.unix_name cpp_type_namespace = '' if type_.namespace != self._namespace: cpp_type_namespace = '%s::' % type_.namespace.unix_name (c.Append('std::string %s;' % enum_as_string) .Sblock('if (!%s->GetAsString(&%s)) {' % (src_var, enum_as_string)) .Concat(self._GenerateError( '"\'%%(key)s\': expected string, got " + ' + self._util_cc_helper.GetValueTypeString('%%(src_var)s', True))) .Append('return %s;' % failure_value) .Eblock('}') .Append('%s = %sParse%s(%s);' % (dst_var, cpp_type_namespace, cpp_util.Classname(type_.name), enum_as_string)) .Sblock('if (%s == %s%s) {' % (dst_var, cpp_type_namespace, self._type_helper.GetEnumNoneValue(type_))) .Concat(self._GenerateError( '\"\'%%(key)s\': expected \\"' + '\\" or \\"'.join( enum_value.name for enum_value in self._type_helper.FollowRef(type_).enum_values) + '\\", got \\"" + %s + "\\""' % enum_as_string)) .Append('return %s;' % failure_value) .Eblock('}') .Substitute({'src_var': src_var, 'key': type_.name}) ) return c
def Generate(self): """Generates a Code object with the .cc for a single namespace. """ c = Code() (c.Append(cpp_util.CHROMIUM_LICENSE).Append().Append( cpp_util.GENERATED_FILE_MESSAGE % self._namespace.source_file).Append().Append( self._util_cc_helper.GetIncludePath()).Append( '#include "base/json/json_writer.h"').Append( '#include "base/logging.h"'). Append('#include "base/string_number_conversions.h"').Append( '#include "%s/%s.h"' % (self._namespace.source_file_dir, self._namespace.unix_name)).Cblock( self._type_helper.GenerateIncludes( include_soft=True)).Concat( cpp_util.OpenNamespace(self._cpp_namespace)).Cblock( self._type_helper.GetNamespaceStart())) if self._namespace.properties: (c.Append('//').Append('// Properties').Append('//').Append()) for property in self._namespace.properties.values(): property_code = self._type_helper.GeneratePropertyValues( property, 'const %(type)s %(name)s = %(value)s;', nodoc=True) if property_code: c.Cblock(property_code) if self._namespace.types: (c.Append('//').Append('// Types').Append('//').Append().Cblock( self._GenerateTypes(None, self._namespace.types.values()))) if self._namespace.functions: (c.Append('//').Append('// Functions').Append('//').Append()) for function in self._namespace.functions.values(): c.Cblock(self._GenerateFunction(function)) if self._namespace.events: (c.Append('//').Append('// Events').Append('//').Append()) for event in self._namespace.events.values(): c.Cblock(self._GenerateEvent(event)) (c.Concat(self._type_helper.GetNamespaceEnd()).Cblock( cpp_util.CloseNamespace(self._cpp_namespace))) return c
def _GenerateCreateCallbackArguments(self, function_scope, callback): """Generate all functions to create Value parameters for a callback. E.g for function "Bar", generate Bar::Results::Create E.g for event "Baz", generate Baz::Create function_scope: the function scope path, e.g. Foo::Bar for the function Foo::Bar::Baz(). callback: the Function object we are creating callback arguments for. """ c = Code() params = callback.params expanded_params = self._cpp_type_generator.ExpandParams(params) c.Concat(self._GeneratePropertyFunctions(function_scope, expanded_params)) param_lists = self._cpp_type_generator.GetAllPossibleParameterLists(params) for param_list in param_lists: (c.Sblock('scoped_ptr<base::ListValue> %(function_scope)s::' 'Create(%(declaration_list)s) {') .Append('scoped_ptr<base::ListValue> create_results(' 'new base::ListValue());') ) declaration_list = [] for param in param_list: # We treat this argument as 'required' to avoid wrapping it in a # scoped_ptr if it's optional. param_copy = param.Copy() param_copy.optional = False c.Append('create_results->Append(%s);' % self._CreateValueFromProperty(param_copy, param_copy.unix_name)) declaration_list.append("const %s" % cpp_util.GetParameterDeclaration( param_copy, self._cpp_type_generator.GetType(param_copy))) c.Append('return create_results.Pass();') c.Eblock('}') c.Substitute({ 'function_scope': function_scope, 'declaration_list': ', '.join(declaration_list) }) return c
def _GeneratePropertyFunctions(self, param_namespace, params): """Generate the functions for structures generated by a property such as CreateEnumValue for ENUMs and Populate/ToValue for Params/Results objects. """ c = Code() for param in params: if param.type_ == PropertyType.OBJECT: c.Concat(self._GenerateType( param_namespace + '::' + cpp_util.Classname(param.name), param)) c.Append() elif param.type_ == PropertyType.ARRAY: c.Concat(self._GeneratePropertyFunctions( param_namespace, [param.item_type])) elif param.type_ == PropertyType.CHOICES: c.Concat(self._GeneratePropertyFunctions( param_namespace, param.choices.values())) elif param.type_ == PropertyType.ENUM: c.Concat(self._GenerateCreateEnumValue(param_namespace, param)) c.Append() return c
def Generate(self): """Generates a Code object with the schema for the entire namespace. """ c = Code() (c.Append(self._GetHeader(sys.argv[0], self._namespace.name)).Append()) c.Cblock(self._GenerateInterfaceObject()) c.Sblock('%s.prototype = {' % self._interface) for function in self._namespace.functions.values(): c.Cblock(self._GenerateFunction(function)) for event in self._namespace.events.values(): c.Cblock(self._GenerateEvent(event)) c.TrimTrailingNewlines() c.Eblock('};') return c
def GenerateForwardDeclarations(self): """Returns the forward declarations for self._default_namespace. """ c = Code() for namespace, deps in self._NamespaceTypeDependencies().iteritems(): filtered_deps = [ dep for dep in deps # Add more ways to forward declare things as necessary. if (not dep.hard and dep.type_.property_type in ( PropertyType.CHOICES, PropertyType.OBJECT)) ] if not filtered_deps: continue cpp_namespace = cpp_util.GetCppNamespace( namespace.environment.namespace_pattern, namespace.unix_name) c.Concat(cpp_util.OpenNamespace(cpp_namespace)) for dep in filtered_deps: c.Append('struct %s;' % dep.type_.name) c.Concat(cpp_util.CloseNamespace(cpp_namespace)) return c
def _GenerateFunctionParams(self, function): """Generates the struct for passing parameters into a function. """ c = Code() if function.params: (c.Sblock('struct Params {') .Concat(self._GeneratePropertyStructures(function.params)) .Concat(self._GenerateFields(function.params)) .Append('~Params();') .Append() .Append('static scoped_ptr<Params> Create(const ListValue& args);') .Eblock() .Sblock(' private:') .Append('Params();') .Append() .Append('DISALLOW_COPY_AND_ASSIGN(Params);') .Eblock('};') ) return c
def second_pass(assembly_code, number_commands, output_name): assembly = Parser(assembly_code, number_commands) coder = Code() # Storing lines to write to .hack file in var n=[] next_avail_RAM = 16 # SECOND PASS while assembly.has_more_commands(): assembly.advance() if assembly.command_type() == 'C_COMMAND': # access to symbols symbol_c=assembly.comp() symbol_d=assembly.dest() symbol_j=assembly.jump() #convert symbols to binary e = coder.comp(symbol_c) f = coder.dest(symbol_d) g = coder.jump(symbol_j) out = '111'+ e + f + g n.append(out +'\n') elif assembly.command_type() == 'A_COMMAND': symbol = assembly.symbol() if not symbol.isdigit(): if not sym_tbl.contains(symbol): sym_tbl.add_entry(symbol, next_avail_RAM) next_avail_RAM = next_avail_RAM + 1 out = '0' + '{0:015b}'.format(sym_tbl.get_address(symbol)) else: out = '0' + "{0:015b}".format(int(symbol)) n.append(out +'\n') # writing to .hack file with open(output_name, "w") as binary_output: binary_output.writelines(n) binary_output.close()
def _GenerateInitializersAndBody(self, type_): items = [] for prop in type_.properties.values(): t = prop.type_ real_t = self._type_helper.FollowRef(t) if real_t.property_type == PropertyType.ENUM: items.append( '%s(%s)' % (prop.unix_name, self._type_helper.GetEnumNoneValue(t))) elif prop.optional: continue elif t.property_type == PropertyType.INTEGER: items.append('%s(0)' % prop.unix_name) elif t.property_type == PropertyType.DOUBLE: items.append('%s(0.0)' % prop.unix_name) elif t.property_type == PropertyType.BOOLEAN: items.append('%s(false)' % prop.unix_name) elif (t.property_type == PropertyType.ANY or t.property_type == PropertyType.ARRAY or t.property_type == PropertyType.BINARY or # mapped to std::string t.property_type == PropertyType.CHOICES or t.property_type == PropertyType.OBJECT or t.property_type == PropertyType.FUNCTION or t.property_type == PropertyType.REF or t.property_type == PropertyType.STRING): # TODO(miket): It would be nice to initialize CHOICES, but we # don't presently have the semantics to indicate which one of a set # should be the default. continue else: raise TypeError(t) if items: s = ': %s' % (', '.join(items)) else: s = '' s = s + ' {}' return Code().Append(s)
def _GeneratePropertyStructures(self, props): """Generate the structures required by a property such as OBJECT classes and enums. """ c = Code() for prop in props: if prop.type_ == PropertyType.OBJECT: c.Concat(self._GenerateType(prop)) c.Append() elif prop.type_ == PropertyType.ARRAY: c.Concat(self._GeneratePropertyStructures([prop.item_type])) c.Append() elif prop.type_ == PropertyType.CHOICES: c.Concat(self._GenerateEnumDeclaration( self._cpp_type_generator.GetChoicesEnumType(prop), prop, [choice.type_.name for choice in prop.choices.values()])) c.Concat(self._GeneratePropertyStructures(prop.choices.values())) elif prop.type_ == PropertyType.ENUM: enum_name = self._cpp_type_generator.GetCompiledType(prop) c.Concat(self._GenerateEnumDeclaration( enum_name, prop, prop.enum_values)) create_enum_value = ('scoped_ptr<base::Value> CreateEnumValue(%s %s);' % (enum_name, prop.unix_name)) enum_to_string = 'std::string ToString(%s enum_param);' % enum_name enum_from_string = ('%s From%sString(const std::string& enum_string);' % (enum_name, enum_name)) # If the property is from the UI then we're in a struct so this function # should be static. If it's from the client, then we're just in a # namespace so we can't have the static keyword. if prop.from_json: create_enum_value = 'static %s' % create_enum_value enum_to_string = 'static %s' % enum_to_string enum_from_string = 'static %s' % enum_from_string (c.Append(create_enum_value) .Append(enum_to_string) .Append(enum_from_string)) return c
def where(self, code): """Adds a $where clause to this query. The `code` argument must be an instance of (str, unicode, Code) containing a JavaScript expression. This expression will be evaluated for each object scanned. Only those objects for which the expression evaluates to *true* will be returned as results. The keyword *this* refers to the object currently being scanned. Raises TypeError if `code` is not an instance of (str, unicode). Raises InvalidOperation if this cursor has already been used. Only the last where clause applied to a cursor has any effect. :Parameters: - `code`: JavaScript expression to use as a filter """ self.__check_okay_to_chain() if not isinstance(code, Code): code = Code(code) self.__spec["$where"] = code return self
def _GenerateType(self, cpp_namespace, type_): """Generates the function definitions for a type. """ classname = cpp_util.Classname(type_.name) c = Code() if type_.functions: # Types with functions are not instantiable in C++ because they are # handled in pure Javascript and hence have no properties or # additionalProperties. if type_.properties: raise NotImplementedError('\n'.join(model.GetModelHierarchy(type_)) + '\nCannot generate both functions and properties on a type') for function in type_.functions.values(): (c.Concat( self._GenerateFunction( cpp_namespace + '::' + cpp_util.Classname(function.name), function)) .Append() ) elif type_.type_ == PropertyType.OBJECT: (c.Concat(self._GeneratePropertyFunctions( cpp_namespace, type_.properties.values())) .Sblock('%(namespace)s::%(classname)s()') .Concat(self._GenerateInitializersAndBody(type_)) .Eblock('%(namespace)s::~%(classname)s() {}') .Append() ) if type_.from_json: (c.Concat(self._GenerateTypePopulate(cpp_namespace, type_)) .Append() ) if type_.from_client: (c.Concat(self._GenerateTypeToValue(cpp_namespace, type_)) .Append() ) c.Substitute({'classname': classname, 'namespace': cpp_namespace}) return c
def _GenerateCreateEnumValue(self, cpp_namespace, prop): """Generates CreateEnumValue() that returns the base::StringValue representation of an enum. """ c = Code() (c.Append('// static').Sblock( 'scoped_ptr<base::Value> %(cpp_namespace)s::CreateEnumValue(' '%(arg)s) {').Append( 'std::string enum_temp = ToString(%s);' % prop.unix_name).Append('if (enum_temp.empty())').Append( ' return scoped_ptr<base::Value>();').Append( 'return scoped_ptr<base::Value>(' 'base::Value::CreateStringValue(enum_temp));').Eblock( '}').Substitute({ 'cpp_namespace': cpp_namespace, 'arg': cpp_util.GetParameterDeclaration( prop, self._cpp_type_generator.GetType(prop)) })) return c
def _GenerateCreateCallbackArguments(self, cpp_namespace, function_scope, callback): """Generate all functions to create Value parameters for a callback. E.g for function "Bar", generate Bar::Results::Create E.g for event "Baz", generate Baz::Create function_scope: the function scope path, e.g. Foo::Bar for the function Foo::Bar::Baz(). May be None if there is no function scope. callback: the Function object we are creating callback arguments for. """ c = Code() params = callback.params c.Concat(self._GeneratePropertyFunctions(function_scope, params)) (c.Sblock('scoped_ptr<base::ListValue> %(function_scope)s' 'Create(%(declaration_list)s) {').Append( 'scoped_ptr<base::ListValue> create_results(' 'new base::ListValue());')) declaration_list = [] for param in params: declaration_list.append( cpp_util.GetParameterDeclaration( param, self._type_helper.GetCppType(param.type_))) c.Cblock( self._CreateValueFromType('create_results->Append(%s);', param.name, param.type_, param.unix_name)) c.Append('return create_results.Pass();') c.Eblock('}') c.Substitute({ 'function_scope': ('%s::' % function_scope) if function_scope else '', 'declaration_list': ', '.join(declaration_list), 'param_names': ', '.join(param.unix_name for param in params) }) return c
def Generate(self): """Generates a Code object with the schema for the entire namespace. """ c = Code() (c.Append(LICENSE) .Append() .Append('/** @fileoverview Externs generated from namespace: %s */' % self._namespace.name) .Append()) c.Cblock(self._GenerateNamespaceObject()) for js_type in self._namespace.types.values(): c.Cblock(self._GenerateType(js_type)) for function in self._namespace.functions.values(): c.Cblock(self._GenerateFunction(function)) for event in self._namespace.events.values(): c.Cblock(self._GenerateEvent(event)) return c
def _GenerateMainClass(self): """Generates the main class for this file, which links to all functions and events. Returns a code object. """ c = Code() (c.Sblock( 'class API_%s {' % self._namespace.unix_name).Append('/*').Append( ' * API connection').Append(' */').Append('Object _jsObject;')) # Add events. if self._namespace.events: (c.Append().Append('/*').Append(' * Events').Append(' */')) for event_name in self._namespace.events: c.Append('Event_%s_%s %s;' % (self._namespace.unix_name, event_name, event_name)) # Add functions. if self._namespace.functions: (c.Append().Append('/*').Append(' * Functions').Append(' */')) for function in self._namespace.functions.values(): # Check for custom dart for this whole property. override = self._GetOverride([function.name], document_with=function) c.Cblock(override if override is not None else self. _GenerateFunction(function)) # Add the constructor. c.Sblock('API_%s(this._jsObject) {' % self._namespace.unix_name) # Add events to constructor. for event_name in self._namespace.events: c.Append("%s = new Event_%s_%s(JS('', '#.%s', this._jsObject));" % (event_name, self._namespace.unix_name, event_name, event_name)) (c.Eblock('}').Eblock('}')) return c
def _GenerateChoiceTypeToValue(self, cpp_namespace, type_): """Generates a function that serializes a choice-representing type into a base::Value. """ c = Code() c.Sblock('scoped_ptr<base::Value> %s::ToValue() const {' % cpp_namespace) c.Append('scoped_ptr<base::Value> result;') for choice in type_.choices: choice_var = 'as_%s' % choice.unix_name (c.Sblock('if (%s) {' % choice_var) .Append('DCHECK(!result) << "Cannot set multiple choices for %s";' % type_.unix_name) .Append('result.reset(%s);' % self._CreateValueFromType(choice, '*%s' % choice_var)) .Eblock('}') ) (c.Append('DCHECK(result) << "Must set at least one choice for %s";' % type_.unix_name) .Append('return result.Pass();') .Eblock('}') ) return c