Beispiel #1
0
    def _GenerateEnumToString(self, cpp_namespace, prop, use_namespace=False):
        """Generates ToString() which gets the string representation of an enum.
    """
        c = Code()
        classname = cpp_util.Classname(
            schema_util.StripSchemaNamespace(prop.name))
        if use_namespace:
            namespace = '%s::' % cpp_namespace
        else:
            namespace = ''

        (c.Append('// static').Sblock(
            'std::string %(namespace)sToString(%(class)s enum_param) {'))
        enum_prop = self._cpp_type_generator.GetReferencedProperty(prop)
        c.Sblock('switch (enum_param) {')
        for enum_value in enum_prop.enum_values:
            c.Concat(
                self._GenerateReturnCase(
                    self._cpp_type_generator.GetEnumValue(prop, enum_value),
                    '"%s"' % enum_value))
        (c.Append('case %s:' %
                  self._cpp_type_generator.GetEnumNoneValue(prop)).Append(
                      '  return "";').Eblock('}').Append('return "";').Eblock(
                          '}').Substitute({
                              'namespace': namespace,
                              'class': classname
                          }))
        return c
  def _GenerateTypeJsDoc(self, js_type):
    """Generates the documentation for a type as a Code.

    Returns an empty code object if the object has no documentation.
    """
    c = Code()
    c.Sblock(line='/**', line_prefix=' * ')

    if js_type.description:
      for line in js_type.description.splitlines():
        c.Append(line)

    is_constructor = self._IsTypeConstructor(js_type)
    if is_constructor:
      c.Comment('@constructor', comment_prefix = ' * ', wrap_indent=4)
    else:
      c.Concat(self._GenerateTypedef(js_type.properties))

    c.Append(self._GenerateSeeLink('type', js_type.simple_name))
    c.Eblock(' */')

    var = 'var ' + js_type.simple_name
    if is_constructor: var += ' = function() {}'
    var += ';'
    c.Append(var)

    return c
  def _GenerateObjectDefinition(self, properties):
    """Given an OrderedDict of properties, returns a Code containing the
       description of an object.
    """
    if not properties: return Code()

    c = Code()
    c.Sblock('{')
    first = True
    for field, prop in properties.items():
      # Avoid trailing comma.
      # TODO(devlin): This will be unneeded, if/when
      # https://github.com/google/closure-compiler/issues/796 is fixed.
      if not first:
        c.Append(',', new_line=False)
      first = False
      js_type = self._TypeToJsType(prop.type_)
      if prop.optional:
        js_type = (Code().
                       Append('(').
                       Concat(js_type, new_line=False).
                       Append('|undefined)', new_line=False))
      c.Append('%s: ' % field, strip_right=False)
      c.Concat(js_type, new_line=False)

    c.Eblock('}')

    return c
Beispiel #4
0
  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(). 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.Append('create_results->Append(%s);' %
          self._CreateValueFromType(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
Beispiel #5
0
  def _GenerateFunctionResult(self, function):
    """Generates functions for passing a function's result back.
    """
    c = Code()

    c.Sblock('namespace Result {')
    params = function.callback.params
    if not params:
      c.Append('Value* Create();')
    else:
      c.Concat(self._GeneratePropertyStructures(params))

      # If there is a single parameter, this is straightforward. However, if
      # the callback parameter is of 'choices', this generates a Create method
      # for each choice. This works because only 1 choice can be returned at a
      # time.
      for param in self._cpp_type_generator.GetExpandedChoicesInParams(params):
        if param.description:
          c.Comment(param.description)
        if param.type_ == PropertyType.ANY:
          c.Comment("Value* Result::Create(Value*) not generated "
                    "because it's redundant.")
          continue
        c.Append('Value* Create(const %s);' % cpp_util.GetParameterDeclaration(
            param, self._cpp_type_generator.GetType(param)))
    c.Eblock('};')

    return c
Beispiel #6
0
 def _GenerateGetChoiceValue(self, cpp_namespace, prop):
     """Generates Get<Type>ChoiceValue() that returns a scoped_ptr<base::Value>
 representing the choice value.
 """
     c = Code()
     (c.Sblock(
         'scoped_ptr<base::Value> '
         '%(cpp_namespace)s::Get%(choice)sChoiceValue() const {').Sblock(
             'switch (%s_type) {' % prop.unix_name).Concat(
                 self._GenerateReturnCase(
                     self._cpp_type_generator.GetEnumNoneValue(prop),
                     'scoped_ptr<base::Value>()')))
     for choice in self._cpp_type_generator.ExpandParams([prop]):
         c.Concat(
             self._GenerateReturnCase(
                 self._cpp_type_generator.GetEnumValue(
                     prop, choice.type_.name),
                 'make_scoped_ptr<base::Value>(%s)' %
                 self._CreateValueFromProperty(choice, choice.unix_name)))
     (c.Eblock('}').Append('return scoped_ptr<base::Value>();').Eblock(
         '}').Append().Substitute({
             'cpp_namespace': cpp_namespace,
             'choice': cpp_util.Classname(prop.name)
         }))
     return c
    def GeneratePropertyValues(self, prop, line, nodoc=False):
        """Generates the Code to display all value-containing properties.
    """
        c = Code()
        if not nodoc:
            c.Comment(prop.description)

        if prop.value is not None:
            cpp_type = self.GetCppType(prop.type_)
            cpp_value = prop.value
            cpp_name = prop.name

            if cpp_type == 'std::string':
                cpp_value = '"%s"' % cpp_value
                cpp_type = 'char'
                cpp_name = '%s[]' % cpp_name
            c.Append(line % {
                "type": cpp_type,
                "name": cpp_name,
                "value": cpp_value
            })
        else:
            has_child_code = False
            c.Sblock('namespace %s {' % prop.name)
            for child_property in prop.type_.properties.values():
                child_code = self.GeneratePropertyValues(child_property,
                                                         line,
                                                         nodoc=nodoc)
                if child_code:
                    has_child_code = True
                    c.Concat(child_code)
            c.Eblock('}  // namespace %s' % prop.name)
            if not has_child_code:
                c = None
        return c
  def _FunctionToJsFunction(self, function):
    """Converts a model.Function to a JS type (i.e., function([params])...)"""
    c = Code()
    c.Append('function(')
    for i, param in enumerate(function.params):
      c.Concat(self._TypeToJsType(param.type_), new_line=False)
      if i is not len(function.params) - 1:
        c.Append(', ', new_line=False, strip_right=False)
    c.Append('):', new_line=False)

    if function.returns:
      c.Concat(self._TypeToJsType(function.returns), new_line=False)
    else:
      c.Append('void', new_line=False)

    return c
 def _TypeToJsType(self, js_type):
   """Converts a model.Type to a JS type (number, Array, etc.)"""
   if js_type.property_type in (PropertyType.INTEGER, PropertyType.DOUBLE):
     return Code().Append('number')
   if js_type.property_type is PropertyType.OBJECT:
     if js_type.properties:
       return self._GenerateObjectDefinition(js_type.properties)
     return Code().Append('Object')
   if js_type.property_type is PropertyType.ARRAY:
     return (Code().Append('!Array<').
          Concat(self._TypeToJsType(js_type.item_type), new_line=False).
          Append('>', new_line=False))
   if js_type.property_type is PropertyType.REF:
     ref_type = js_type.ref_type
     # Enums are defined as chrome.fooAPI.MyEnum, but types are defined simply
     # as MyType.
     if self._namespace.types[ref_type].property_type is PropertyType.ENUM:
       ref_type = '!chrome.%s.%s' % (self._namespace.name, ref_type)
     return Code().Append(ref_type)
   if js_type.property_type is PropertyType.CHOICES:
     c = Code()
     c.Append('(')
     for i, choice in enumerate(js_type.choices):
       c.Concat(self._TypeToJsType(choice), new_line=False)
       if i is not len(js_type.choices) - 1:
         c.Append('|', new_line=False)
     c.Append(')', new_line=False)
     return c
   if js_type.property_type is PropertyType.FUNCTION:
     return self._FunctionToJsFunction(js_type.function)
   if js_type.property_type is PropertyType.ANY:
     return Code().Append('*')
   if js_type.property_type.is_fundamental:
     return Code().Append(js_type.property_type.name)
   return Code().Append('?') # TODO(tbreisacher): Make this more specific.
Beispiel #10
0
 def _GenerateParamsCheck(self, function, var):
   """Generates a check for the correct number of arguments when creating
   Params.
   """
   c = Code()
   num_required = 0
   for param in function.params:
     if not param.optional:
       num_required += 1
   if num_required == len(function.params):
     c.Sblock('if (%(var)s.GetSize() != %(total)d) {')
   elif not num_required:
     c.Sblock('if (%(var)s.GetSize() > %(total)d) {')
   else:
     c.Sblock('if (%(var)s.GetSize() < %(required)d'
         ' || %(var)s.GetSize() > %(total)d) {')
   (c.Concat(self._GenerateError(
       '"expected %%(total)d arguments, got " '
       '+ base::IntToString(%%(var)s.GetSize())'))
     .Append('return scoped_ptr<Params>();')
     .Eblock('}')
     .Substitute({
       'var': var,
       'required': num_required,
       'total': len(function.params),
   }))
   return c
Beispiel #11
0
    def GeneratePropertyValues(self, property, line, nodoc=False):
        """Generates the Code to display all value-containing properties.
    """
        c = Code()
        if not nodoc:
            c.Comment(property.description)

        if property.value is not None:
            c.Append(
                line % {
                    "type": self.GetCppType(property.type_),
                    "name": property.name,
                    "value": property.value
                })
        else:
            has_child_code = False
            c.Sblock('namespace %s {' % property.name)
            for child_property in property.type_.properties.values():
                child_code = self.GeneratePropertyValues(child_property,
                                                         line,
                                                         nodoc=nodoc)
                if child_code:
                    has_child_code = True
                    c.Concat(child_code)
            c.Eblock('}  // namespace %s' % property.name)
            if not has_child_code:
                c = None
        return c
Beispiel #12
0
    def _FunctionToJsFunction(self, namespace_name, function):
        """Converts a model.Function to a JS type (i.e., function([params])...)"""
        c = Code()
        c.Append('function(')
        c.Concat(self._FunctionParamsToJsParams(namespace_name,
                                                function.params),
                 new_line=False)
        c.Append('): ', new_line=False, strip_right=False)

        if function.returns:
            c.Concat(self._TypeToJsType(namespace_name, function.returns),
                     new_line=False)
        else:
            c.Append('void', new_line=False)

        return c
Beispiel #13
0
    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 "%s/%s.h"' % (self._namespace.source_file_dir,
                                            self._namespace.unix_name)))
        includes = self._cpp_type_generator.GenerateIncludes()
        if not includes.IsEmpty():
            (c.Concat(includes).Append())

        (c.Append().Append('using base::Value;').Append(
            'using base::DictionaryValue;').Append('using base::ListValue;').
         Append('using base::BinaryValue;').Append(
             'using %s;' % any_helper.ANY_CLASS).Append().Concat(
                 self._cpp_type_generator.GetRootNamespaceStart()).Concat(
                     self._cpp_type_generator.GetNamespaceStart()).Append())
        if self._namespace.properties:
            (c.Append('//').Append('// Properties').Append('//').Append())
            for property in self._namespace.properties.values():
                property_code = self._cpp_type_generator.GeneratePropertyValues(
                    property,
                    'const %(type)s %(name)s = %(value)s;',
                    nodoc=True)
                if property_code:
                    c.Concat(property_code).Append()
        if self._namespace.types:
            (c.Append('//').Append('// Types').Append('//').Append())
        for type_ in self._namespace.types.values():
            (c.Concat(
                self._GenerateType(
                    schema_util.StripSchemaNamespace(type_.name),
                    type_)).Append())
        if self._namespace.functions:
            (c.Append('//').Append('// Functions').Append('//').Append())
        for function in self._namespace.functions.values():
            (c.Concat(
                self._GenerateFunction(cpp_util.Classname(function.name),
                                       function)).Append())
        (c.Concat(self._cpp_type_generator.GetNamespaceEnd()).Concat(
            self._cpp_type_generator.GetRootNamespaceEnd()).Append())
        # TODO(calamity): Events
        return c
Beispiel #14
0
 def GetCode(self, feature_type):
   """Returns the Code object for generating this feature."""
   c = Code()
   cpp_feature_class = SIMPLE_FEATURE_CPP_CLASSES[feature_type]
   c.Append('%s* feature = new %s();' % (cpp_feature_class, cpp_feature_class))
   c.Append('feature->set_name("%s");' % self.name)
   c.Concat(GetCodeForFeatureValues(self.GetAllFeatureValues()))
   return c
Beispiel #15
0
 def testSameLineAppendAndConcat(self):
     c = Code()
     c.Append('This is a line.')
     c.Append('This too.', new_line=False)
     d = Code()
     d.Append('And this.')
     c.Concat(d, new_line=False)
     self.assertEquals('This is a line.This too.And this.', c.Render())
Beispiel #16
0
  def _GenerateType(self, type_):
    """Generates a struct 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')
      c.Sblock('namespace %(classname)s {')
      for function in type_.functions.values():
        (c.Concat(self._GenerateFunction(function))
          .Append()
        )
      c.Eblock('}')
    elif type_.type_ == PropertyType.ARRAY:
      if type_.description:
        c.Comment(type_.description)
      c.Append('typedef std::vector<%(item_type)s> %(classname)s;')
      c.Substitute({'classname': classname, 'item_type':
          self._cpp_type_generator.GetType(type_.item_type,
                                           wrap_optional=True)})
    else:
      if type_.description:
        c.Comment(type_.description)
      (c.Sblock('struct %(classname)s {')
          .Append('~%(classname)s();')
          .Append('%(classname)s();')
          .Append()
          .Concat(self._GeneratePropertyStructures(type_.properties.values()))
          .Concat(self._GenerateFields(type_.properties.values()))
      )
      if type_.from_json:
        (c.Comment('Populates a %s object from a Value. Returns'
                   ' whether |out| was successfully populated.' % classname)
          .Append(
              'static bool Populate(const Value& value, %(classname)s* out);')
          .Append()
        )

      if type_.from_client:
        (c.Comment('Returns a new DictionaryValue representing the'
                   ' serialized form of this %s object. Passes '
                   'ownership to caller.' % classname)
          .Append('scoped_ptr<DictionaryValue> ToValue() const;')
        )

      (c.Eblock()
        .Sblock(' private:')
          .Append('DISALLOW_COPY_AND_ASSIGN(%(classname)s);')
        .Eblock('};')
      )
    c.Substitute({'classname': classname})
    return c
Beispiel #17
0
 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/logging.h"')
     .Append('#include "base/strings/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))
     .Append()
     .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
Beispiel #18
0
 def testCommentWithSpecialCharacters(self):
     c = Code()
     c.Comment('20% of 80%s')
     c.Substitute({})
     self.assertEquals('// 20% of 80%s', c.Render())
     d = Code()
     d.Append('90')
     d.Concat(c)
     self.assertEquals('90\n' '// 20% of 80%s', d.Render())
Beispiel #19
0
 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/Result 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.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
Beispiel #20
0
  def _GenerateType(self, type_):
    """Generates a struct for a type.
    """
    classname = cpp_util.Classname(schema_util.StripSchemaNamespace(type_.name))
    c = Code()

    if type_.functions:
      c.Sblock('namespace %(classname)s {')
      for function in type_.functions.values():
        (c.Concat(self._GenerateFunction(function))
          .Append()
        )
      c.Eblock('}')
    elif type_.type_ == PropertyType.ARRAY:
      if type_.description:
        c.Comment(type_.description)
      c.Append('typedef std::vector<%(item_type)s> %(classname)s;')
      c.Substitute({'classname': classname, 'item_type':
          self._cpp_type_generator.GetType(type_.item_type,
                                           wrap_optional=True)})
    elif type_.type_ == PropertyType.STRING:
      if type_.description:
        c.Comment(type_.description)
      c.Append('typedef std::string %(classname)s;')
      c.Substitute({'classname': classname})
    else:
      if type_.description:
        c.Comment(type_.description)
      (c.Sblock('struct %(classname)s {')
          .Append('~%(classname)s();')
          .Append('%(classname)s();')
          .Append()
          .Concat(self._GeneratePropertyStructures(type_.properties.values()))
          .Concat(self._GenerateFields(type_.properties.values()))
      )
      if type_.from_json:
        (c.Comment('Populates a %s object from a Value. Returns'
                   ' whether |out| was successfully populated.' % classname)
          .Append(
              'static bool Populate(const Value& value, %(classname)s* out);')
          .Append()
        )

      if type_.from_client:
        (c.Comment('Returns a new DictionaryValue representing the'
                   ' serialized form of this %s object. Passes '
                   'ownership to caller.' % classname)
          .Append('scoped_ptr<DictionaryValue> ToValue() const;')
        )

      (c.Eblock()
        .Sblock(' private:')
          .Append('DISALLOW_COPY_AND_ASSIGN(%(classname)s);')
        .Eblock('};')
      )
    c.Substitute({'classname': classname})
    return c
Beispiel #21
0
  def Write(self):
    """Writes the output."""
    header_file = self._out_base_filename + '.h'
    cc_file = self._out_base_filename + '.cc'

    include_file_root = self._out_root
    GEN_DIR_PREFIX = 'gen/'
    if include_file_root.startswith(GEN_DIR_PREFIX) and len(include_file_root) >= len(GEN_DIR_PREFIX):
      include_file_root = include_file_root[len(GEN_DIR_PREFIX):]
    else:
      include_file_root = ''
    if include_file_root:
      header_file_path = '%s/%s' % (include_file_root, header_file)
    else:
      header_file_path = header_file
    cc_file_path = '%s/%s' % (include_file_root, cc_file)

    substitutions = ({
        'header_file_path': header_file_path,
        'header_guard': (header_file_path.replace('/', '_').
                             replace('.', '_').upper()),
        'method_name': self._method_name,
        'source_files': str(self._source_files),
        'year': str(datetime.now().year)
    })
    if not os.path.exists(self._out_root):
      os.makedirs(self._out_root)
    # Write the .h file.
    with open(os.path.join(self._out_root, header_file), 'w') as f:
      header_file = Code()
      header_file.Append(HEADER_FILE_TEMPLATE)
      header_file.Substitute(substitutions)
      f.write(header_file.Render().strip())
    # Write the .cc file.
    with open(os.path.join(self._out_root, cc_file), 'w') as f:
      cc_file = Code()
      cc_file.Append(CC_FILE_BEGIN)
      cc_file.Substitute(substitutions)
      cc_file.Concat(self.Render())
      cc_end = Code()
      cc_end.Append(CC_FILE_END)
      cc_end.Substitute(substitutions)
      cc_file.Concat(cc_end)
      f.write(cc_file.Render().strip())
  def _GenerateTypedef(self, properties):
    """Given an OrderedDict of properties, returns a Code containing a @typedef.
    """
    if not properties: return Code()

    c = Code()
    c.Append('@typedef {')
    c.Concat(self._GenerateObjectDefinition(properties), new_line=False)
    c.Append('}', new_line=False)
    return c
Beispiel #23
0
    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:
                c.Append('struct %s;' % type_)
            c.Append('}')
        c.Concat(self.GetNamespaceStart())
        for (name, type_) in self._namespace.types.items():
            if not type_.functions:
                c.Append('struct %s;' % name)
        c.Concat(self.GetNamespaceEnd())
        return c
Beispiel #24
0
    def _GenerateFunction(self, function):
        """Generates the structs for a function.
    """
        c = Code()
        (c.Sblock('namespace %s {' % cpp_util.Classname(function.name)).Concat(
            self._GenerateFunctionParams(function)).Append())
        if function.callback:
            (c.Concat(self._GenerateFunctionResult(function)).Append())
        c.Eblock('};')

        return c
Beispiel #25
0
    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
Beispiel #26
0
    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
Beispiel #27
0
    def Generate(self):
        """Generates a Code object with the .h for a single namespace.
    """
        c = Code()
        (c.Append(cpp_util.CHROMIUM_LICENSE).Append().Append(
            cpp_util.GENERATED_FILE_MESSAGE %
            self._namespace.source_file).Append())

        ifndef_name = cpp_util.GenerateIfndefName(
            self._namespace.source_file_dir, self._target_namespace)
        (c.Append('#ifndef %s' % ifndef_name).Append(
            '#define %s' %
            ifndef_name).Append().Append('#include <string>').Append(
                '#include <vector>').Append().Append(
                    '#include "base/basictypes.h"').
         Append('#include "base/memory/linked_ptr.h"').Append(
             '#include "base/memory/scoped_ptr.h"').Append(
                 '#include "base/values.h"').Append(
                     '#include "tools/json_schema_compiler/any.h"').Append())

        c.Concat(self._cpp_type_generator.GetRootNamespaceStart())
        # TODO(calamity): These forward declarations should be #includes to allow
        # $ref types from other files to be used as required params. This requires
        # some detangling of windows and tabs which will currently lead to circular
        # #includes.
        forward_declarations = (
            self._cpp_type_generator.GenerateForwardDeclarations())
        if not forward_declarations.IsEmpty():
            (c.Append().Concat(forward_declarations).Append())

        c.Concat(self._cpp_type_generator.GetNamespaceStart())
        c.Append()
        if self._namespace.properties:
            (c.Append('//').Append('// Properties').Append('//').Append())
            for property in self._namespace.properties.values():
                property_code = self._cpp_type_generator.GeneratePropertyValues(
                    property, 'extern const %(type)s %(name)s;')
                if property_code:
                    c.Concat(property_code).Append()
        if self._namespace.types:
            (c.Append('//').Append('// Types').Append('//').Append())
            for type_ in self._FieldDependencyOrder():
                (c.Concat(self._GenerateType(type_)).Append())
        if self._namespace.functions:
            (c.Append('//').Append('// Functions').Append('//').Append())
            for function in self._namespace.functions.values():
                (c.Concat(self._GenerateFunction(function)).Append())
        if self._namespace.events:
            (c.Append('//').Append('// Events').Append('//').Append())
            for event in self._namespace.events.values():
                (c.Concat(self._GenerateEvent(event)).Append())
        (c.Concat(self._cpp_type_generator.GetNamespaceEnd()).Concat(
            self._cpp_type_generator.GetRootNamespaceEnd()).Append().Append(
                '#endif  // %s' % ifndef_name).Append())
        return c
Beispiel #28
0
 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 Render(self):
     """Returns the Code object for the body of the .cc file, which handles the
 initialization of all features."""
     c = Code()
     c.Sblock()
     for k in sorted(self._features.keys()):
         c.Sblock('{')
         feature = self._features[k]
         c.Concat(feature.GetCode(self._feature_type))
         c.Append('provider->AddFeature("%s", feature);' % k)
         c.Eblock('}')
     c.Eblock()
     return c
Beispiel #30
0
 def testConcat(self):
     b = Code()
     (b.Sblock('2').Append('2').Eblock('2'))
     c = Code()
     (c.Sblock('1').Concat(b).Append('1').Eblock('1'))
     self.assertEquals('1\n'
                       '  2\n'
                       '    2\n'
                       '  2\n'
                       '  1\n'
                       '1', c.Render())
     d = Code()
     a = Code()
     a.Concat(d)
     self.assertEquals('', a.Render())
     a.Concat(c)
     self.assertEquals('1\n'
                       '  2\n'
                       '    2\n'
                       '  2\n'
                       '  1\n'
                       '1', a.Render())