示例#1
0
  def _GenerateType(self, cpp_namespace, type_):
    """Generates the function definitions for a type.
    """
    classname = cpp_util.Classname(schema_util.StripSchemaNamespace(type_.name))
    c = Code()

    if type_.functions:
      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 ToPpapiType(self, type_, array=False, optional=False):
        """Returns a string containing the name of the Pepper C type for |type_|.

    If array is True, returns the name of an array of |type_|. If optional is
    True, returns the name of an optional |type_|. If both array and optional
    are True, returns the name of an optional array of |type_|.
    """
        if isinstance(type_, model.Function) or type_.property_type in (
                model.PropertyType.OBJECT, model.PropertyType.ENUM):
            return self._FormatPpapiTypeName(
                array,
                optional,
                '_'.join(
                    cpp_util.Classname(s)
                    for s in self._NameComponents(type_)),
                namespace=cpp_util.Classname(self._namespace.name))
        elif type_.property_type == model.PropertyType.REF:
            return self.ToPpapiType(self._namespace.types[type_.ref_type],
                                    optional=optional,
                                    array=array)
        elif type_.property_type == model.PropertyType.ARRAY:
            return self.ToPpapiType(type_.item_type,
                                    array=True,
                                    optional=optional)
        elif type_.property_type == model.PropertyType.STRING and not array:
            return 'PP_Var'
        elif array or optional:
            if type_.property_type in self._PPAPI_COMPOUND_PRIMITIVE_TYPE_MAP:
                return self._FormatPpapiTypeName(
                    array, optional, self._PPAPI_COMPOUND_PRIMITIVE_TYPE_MAP[
                        type_.property_type], '')
        return self._PPAPI_PRIMITIVE_TYPE_MAP.get(type_.property_type,
                                                  'PP_Var')
示例#3
0
    def GetType(self, prop, pad_for_generics=False, wrap_optional=False):
        """Translates a model.Property into its C++ type.

    If REF types from different namespaces are referenced, will resolve
    using self._type_namespaces.

    Use pad_for_generics when using as a generic to avoid operator ambiguity.

    Use wrap_optional to wrap the type in a scoped_ptr<T> if the Property is
    optional.
    """
        cpp_type = None
        if prop.type_ == PropertyType.REF:
            dependency_namespace = self._ResolveTypeNamespace(prop.ref_type)
            if not dependency_namespace:
                raise KeyError('Cannot find referenced type: %s' %
                               prop.ref_type)
            if self._namespace != dependency_namespace:
                cpp_type = '%s::%s' % (
                    self._cpp_namespaces[dependency_namespace], prop.ref_type)
            else:
                cpp_type = prop.ref_type
        elif prop.type_ == PropertyType.BOOLEAN:
            cpp_type = 'bool'
        elif prop.type_ == PropertyType.INTEGER:
            cpp_type = 'int'
        elif prop.type_ == PropertyType.DOUBLE:
            cpp_type = 'double'
        elif prop.type_ == PropertyType.STRING:
            cpp_type = 'std::string'
        elif prop.type_ == PropertyType.ENUM:
            cpp_type = cpp_util.Classname(prop.name)
        elif prop.type_ == PropertyType.ADDITIONAL_PROPERTIES:
            cpp_type = 'base::DictionaryValue'
        elif prop.type_ == PropertyType.ANY:
            cpp_type = any_helper.ANY_CLASS
        elif prop.type_ == PropertyType.OBJECT:
            cpp_type = cpp_util.Classname(prop.name)
        elif prop.type_ == PropertyType.ARRAY:
            if prop.item_type.type_ in (PropertyType.REF, PropertyType.ANY,
                                        PropertyType.OBJECT):
                cpp_type = 'std::vector<linked_ptr<%s> > '
            else:
                cpp_type = 'std::vector<%s> '
            cpp_type = cpp_type % self.GetType(prop.item_type,
                                               pad_for_generics=True)
        elif prop.type_ == PropertyType.BINARY:
            cpp_type = 'base::BinaryValue'
        else:
            raise NotImplementedError(prop.type_)

        # Enums aren't wrapped because C++ won't allow it. Optional enums have a
        # NONE value generated instead.
        if wrap_optional and prop.optional and prop.type_ != PropertyType.ENUM:
            cpp_type = 'scoped_ptr<%s> ' % cpp_type
        if pad_for_generics:
            return cpp_type
        return cpp_type.strip()
示例#4
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().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())
        if self._namespace.events:
            (c.Append('//').Append('// Events').Append('//').Append())
        for event in self._namespace.events.values():
            (c.Concat(
                self._GenerateCreateCallbackArguments(
                    cpp_util.Classname(event.name),
                    event,
                    generate_to_json=True)).Append())
        (c.Concat(self._cpp_type_generator.GetNamespaceEnd()).Concat(
            self._cpp_type_generator.GetRootNamespaceEnd()).Append())
        return c
示例#5
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
示例#6
0
    def _GenerateFunction(self, function):
        """Generates the definitions for function structs.
    """
        c = Code()

        # TODO(kalman): use function.unix_name not Classname.
        function_namespace = cpp_util.Classname(function.name)
        (c.Append('namespace %s {' % function_namespace).Append())

        # Params::Populate function
        if function.params:
            c.Concat(self._GeneratePropertyFunctions('Params',
                                                     function.params))
            (c.Append('Params::Params() {}').Append(
                'Params::~Params() {}').Append().Cblock(
                    self._GenerateFunctionParamsCreate(function)))

        # Results::Create function
        if function.callback:
            c.Concat(
                self._GenerateCreateCallbackArguments('Results',
                                                      function.callback))

        c.Append('}  // namespace %s' % function_namespace)
        return c
示例#7
0
    def _GenerateEnumFromString(self,
                                cpp_namespace,
                                prop,
                                use_namespace=False):
        """Generates FromClassNameString() which gets an enum from its string
    representation.
    """
        c = Code()
        classname = cpp_util.Classname(
            schema_util.StripSchemaNamespace(prop.name))
        if use_namespace:
            namespace = '%s::' % cpp_namespace
        else:
            namespace = ''

        (c.Append('// static').Sblock('%(namespace)s%(class)s'
                                      ' %(namespace)sFrom%(class)sString('
                                      'const std::string& enum_string) {'))
        enum_prop = self._cpp_type_generator.GetReferencedProperty(prop)
        for i, enum_value in enumerate(
                self._cpp_type_generator.GetReferencedProperty(
                    prop).enum_values):
            # This is broken up into all ifs with no else ifs because we get
            # "fatal error C1061: compiler limit : blocks nested too deeply"
            # on Windows.
            (c.Append('if (enum_string == "%s")' % enum_value).Append(
                '  return %s;' %
                self._cpp_type_generator.GetEnumValue(prop, enum_value)))
        (c.Append('return %s;' %
                  self._cpp_type_generator.GetEnumNoneValue(prop)).Eblock(
                      '}').Substitute({
                          'namespace': namespace,
                          'class': classname
                      }))
        return c
示例#8
0
    def _ShowCompiledFile(self, parsed_url, head, body):
        """Show the compiled version of a json file given the path to the compiled
    file.
    """

        api_model = model.Model()

        request_path = self._GetRequestPath(parsed_url)
        (file_root, file_ext) = os.path.splitext(request_path)
        (filedir, filename) = os.path.split(file_root)
        json_file_path = os.path.normpath(file_root + '.json')

        try:
            # Get main json file
            api_defs = json_schema.Load(json_file_path)
            namespace = api_model.AddNamespace(api_defs[0], json_file_path)
            type_generator = cpp_type_generator.CppTypeGenerator(
                'previewserver::api', namespace, namespace.unix_name)

            # Get json file depedencies
            for dependency in api_defs[0].get('dependencies', []):
                json_file_path = os.path.join(filedir, dependency + '.json')
                api_defs = json_schema.Load(json_file_path)
                referenced_namespace = api_model.AddNamespace(
                    api_defs[0], json_file_path)
                if referenced_namespace:
                    type_generator.AddNamespace(
                        referenced_namespace,
                        cpp_util.Classname(referenced_namespace.name).lower())

            # Generate code
            if file_ext == '.h':
                cpp_code = (h_generator.HGenerator(
                    namespace, type_generator).Generate().Render())
            elif file_ext == '.cc':
                cpp_code = (cc_generator.CCGenerator(
                    namespace, type_generator).Generate().Render())
            else:
                self.send_error(404, "File not found: %s" % request_path)
                return

            # Do highlighting on the generated code
            (highlighter_param,
             style_param) = self._GetHighlighterParams(parsed_url)
            head.Append('<style>' +
                        self.server.highlighters[highlighter_param].GetCSS(
                            style_param) + '</style>')
            body.Append(
                self.server.highlighters[highlighter_param].GetCodeElement(
                    cpp_code, style_param))
        except IOError:
            self.send_error(404, "File not found: %s" % request_path)
            return
        except (TypeError, KeyError, AttributeError, AssertionError,
                NotImplementedError) as error:
            body.Append('<pre>')
            body.Append('compiler error: ' + str(error))
            body.Append('Check server log for more details')
            body.Append('</pre>')
            raise
示例#9
0
    def _GenerateTypePopulate(self, cpp_namespace, type_):
        """Generates the function for populating a type given a pointer to it.

    E.g for type "Foo", generates Foo::Populate()
    """
        classname = cpp_util.Classname(type_.name)
        c = Code()
        (c.Append('// static').Sblock('bool %(namespace)s::Populate'
                                      '(const Value& value, %(name)s* out) {').
         Append('if (!value.IsType(Value::TYPE_DICTIONARY))').Append(
             '  return false;').Append(
                 'const DictionaryValue* dict = '
                 'static_cast<const DictionaryValue*>(&value);').Append())
        for prop in type_.properties.values():
            c.Concat(self._InitializePropertyToDefault(prop, 'out'))
        for prop in type_.properties.values():
            if prop.type_ == PropertyType.ADDITIONAL_PROPERTIES:
                c.Append('out->additional_properties.MergeDictionary(dict);')
                # remove all keys that are actual properties
                for cur_prop in type_.properties.values():
                    if prop != cur_prop:
                        c.Append('out->additional_properties'
                                 '.RemoveWithoutPathExpansion("%s", NULL);' %
                                 cur_prop.name)
                c.Append()
            else:
                c.Concat(
                    self._GenerateTypePopulateProperty(prop, 'dict', 'out'))
        (c.Append('return true;').Eblock('}'))
        c.Substitute({'namespace': cpp_namespace, 'name': classname})
        return c
示例#10
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/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()))
             if param.from_client:
                 c.Concat(
                     self._GenerateGetChoiceValue(param_namespace, param))
         elif param.type_ == PropertyType.ENUM:
             (c.Concat(self._GenerateCreateEnumValue(
                 param_namespace, param)).Append().Concat(
                     self._GenerateEnumFromString(
                         param_namespace, param,
                         use_namespace=True)).Append().Concat(
                             self._GenerateEnumToString(
                                 param_namespace, param,
                                 use_namespace=True)).Append())
     return c
示例#11
0
    def GetEnumValue(self, prop, enum_value):
        """Gets the enum value of the given model.Property of the given type.

    e.g VAR_STRING
    """
        return '%s_%s' % (prop.unix_name.upper(),
                          cpp_util.Classname(enum_value.upper()))
示例#12
0
  def _GenerateEnumToString(self, cpp_namespace, type_):
    """Generates ToString() which gets the string representation of an enum.
    """
    c = Code()
    classname = cpp_util.Classname(schema_util.StripNamespace(type_.name))

    if cpp_namespace is not None:
      c.Append('// static')
    maybe_namespace = '' if cpp_namespace is None else '%s::' % cpp_namespace

    c.Sblock('std::string %sToString(%s enum_param) {' %
                 (maybe_namespace, classname))
    c.Sblock('switch (enum_param) {')
    for enum_value in self._type_helper.FollowRef(type_).enum_values:
      name = enum_value.name
      if 'camel_case_enum_to_string' in self._namespace.compiler_options:
        name = enum_value.CamelName()
      (c.Append('case %s: ' % self._type_helper.GetEnumValue(type_, enum_value))
        .Append('  return "%s";' % name))
    (c.Append('case %s:' % self._type_helper.GetEnumNoneValue(type_))
      .Append('  return "";')
      .Eblock('}')
      .Append('NOTREACHED();')
      .Append('return "";')
      .Eblock('}')
    )
    return c
示例#13
0
    def Generate(self):
        """Generates a code.Code object with the .cc for a single namespace.
    """
        c = code.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.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 %s;' % any_helper.ANY_CLASS).Append().Concat(
             self._cpp_type_generator.GetRootNamespaceStart()).Concat(
                 self._cpp_type_generator.GetNamespaceStart()).Append())
        if self._namespace.types:
            (c.Append('//').Append('// Types').Append('//').Append())
        for type_ in self._namespace.types.values():
            (c.Concat(self._GenerateType(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
  def _ShowCompiledFile(self, parsed_url, head, body):
    """Show the compiled version of a json or idl file given the path to the
    compiled file.
    """
    api_model = model.Model()

    request_path = self._GetRequestPath(parsed_url)
    (file_root, file_ext) = os.path.splitext(request_path)
    (filedir, filename) = os.path.split(file_root)

    try:
      # Get main file.
      (api_def, file_path) = self._LoadModel(filedir, filename)
      namespace = api_model.AddNamespace(api_def, file_path)
      type_generator = cpp_type_generator.CppTypeGenerator(
           api_model,
           schema_loader.SchemaLoader(filedir),
           namespace)

      # Get the model's dependencies.
      for dependency in api_def.get('dependencies', []):
        # Dependencies can contain : in which case they don't refer to APIs,
        # rather, permissions or manifest keys.
        if ':' in dependency:
          continue
        (api_def, file_path) = self._LoadModel(filedir, dependency)
        referenced_namespace = api_model.AddNamespace(api_def, file_path)
        if referenced_namespace:
          type_generator.AddNamespace(referenced_namespace,
              cpp_util.Classname(referenced_namespace.name).lower())

      # Generate code
      cpp_namespace = 'generated_api_schemas'
      if file_ext == '.h':
        cpp_code = (h_generator.HGenerator(type_generator, cpp_namespace)
            .Generate(namespace).Render())
      elif file_ext == '.cc':
        cpp_code = (cc_generator.CCGenerator(type_generator, cpp_namespace)
            .Generate(namespace).Render())
      else:
        self.send_error(404, "File not found: %s" % request_path)
        return

      # Do highlighting on the generated code
      (highlighter_param, style_param) = self._GetHighlighterParams(parsed_url)
      head.Append('<style>' +
          self.server.highlighters[highlighter_param].GetCSS(style_param) +
          '</style>')
      body.Append(self.server.highlighters[highlighter_param]
          .GetCodeElement(cpp_code, style_param))
    except IOError:
      self.send_error(404, "File not found: %s" % request_path)
      return
    except (TypeError, KeyError, AttributeError,
        AssertionError, NotImplementedError) as error:
      body.Append('<pre>')
      body.Append('compiler error: %s' % error)
      body.Append('Check server log for more details')
      body.Append('</pre>')
      raise
示例#15
0
 def _GenerateEvent(self, event):
     """Generates the namespaces for an event.
 """
     c = Code()
     (c.Sblock('namespace %s {' % cpp_util.Classname(event.name)).Concat(
         self._GenerateCreateCallbackArguments(event)).Eblock('};'))
     return c
示例#16
0
  def _GenerateFunction(self, function):
    """Generates the definitions for function structs.
    """
    c = Code()

    # TODO(kalman): use function.unix_name not Classname.
    function_namespace = cpp_util.Classname(function.name)
    # Windows has a #define for SendMessage, so to avoid any issues, we need
    # to not use the name.
    if function_namespace == 'SendMessage':
      function_namespace = 'PassMessage'
    (c.Append('namespace %s {' % function_namespace)
      .Append()
    )

    # Params::Populate function
    if function.params:
      c.Concat(self._GeneratePropertyFunctions('Params', function.params))
      (c.Append('Params::Params() {}')
        .Append('Params::~Params() {}')
        .Append()
        .Cblock(self._GenerateFunctionParamsCreate(function))
      )

    # Results::Create function
    if function.callback:
      c.Concat(self._GenerateCreateCallbackArguments('Results',
                                                     function.callback))

    c.Append('}  // namespace %s' % function_namespace)
    return c
示例#17
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
示例#18
0
  def _GenerateEnumFromString(self, cpp_namespace, type_):
    """Generates FromClassNameString() which gets an enum from its string
    representation.
    """
    c = Code()
    classname = cpp_util.Classname(schema_util.StripNamespace(type_.name))

    if cpp_namespace is not None:
      c.Append('// static')
    maybe_namespace = '' if cpp_namespace is None else '%s::' % cpp_namespace

    c.Sblock('%s%s %sParse%s(const std::string& enum_string) {' %
                 (maybe_namespace, classname, maybe_namespace, classname))
    for _, enum_value in enumerate(
          self._type_helper.FollowRef(type_).enum_values):
      # This is broken up into all ifs with no else ifs because we get
      # "fatal error C1061: compiler limit : blocks nested too deeply"
      # on Windows.
      (c.Append('if (enum_string == "%s")' % enum_value.name)
        .Append('  return %s;' %
            self._type_helper.GetEnumValue(type_, enum_value)))
    (c.Append('return %s;' % self._type_helper.GetEnumNoneValue(type_))
      .Eblock('}')
    )
    return c
示例#19
0
 def _GenerateEvent(self, event):
     # TODO(kalman): use event.unix_name not Classname.
     c = Code()
     event_namespace = cpp_util.Classname(event.name)
     (c.Append('namespace %s {' % event_namespace).Append().Cblock(
         self._GenerateCreateCallbackArguments(None, event)).Append(
             '}  // namespace %s' % event_namespace))
     return c
示例#20
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
示例#21
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
示例#22
0
    def _CreateValueFromProperty(self, prop, var):
        """Creates a base::Value given a property. Generated code passes ownership
    to caller.

    var: variable or variable*

    E.g for std::string, generate base::Value::CreateStringValue(var)
    """
        if prop.type_ == PropertyType.CHOICES:
            return 'Get%sChoiceValue().release()' % cpp_util.Classname(
                prop.name)
        elif self._IsObjectOrObjectRef(prop):
            if prop.optional:
                return '%s->ToValue().release()' % var
            else:
                return '%s.ToValue().release()' % var
        elif prop.type_ == PropertyType.ANY:
            return '%s.DeepCopy()' % self._any_helper.GetValue(prop, var)
        elif prop.type_ == PropertyType.ADDITIONAL_PROPERTIES:
            return '%s.DeepCopy()' % var
        elif prop.type_ == PropertyType.FUNCTION:
            if prop.optional:
                vardot = var + '->'
            else:
                vardot = var + '.'
            return '%sDeepCopy()' % vardot
        elif self._cpp_type_generator.IsEnumOrEnumRef(prop):
            return 'base::Value::CreateStringValue(ToString(%s))' % var
        elif prop.type_ == PropertyType.BINARY:
            if prop.optional:
                vardot = var + '->'
            else:
                vardot = var + '.'
            return (
                'base::BinaryValue::CreateWithCopiedBuffer(%sdata(), %ssize())'
                % (vardot, vardot))
        elif self._IsArrayOrArrayRef(prop):
            return '%s.release()' % self._util_cc_helper.CreateValueFromArray(
                self._cpp_type_generator.GetReferencedProperty(prop), var,
                prop.optional)
        elif self._IsFundamentalOrFundamentalRef(prop):
            # If prop.type != prop.compiled_type, then no asterisk is necessary
            # because the target is a local variable and not a dereferenced scoped
            # pointer. The asterisk is instead prepended to conversion_src around line
            # 273.
            if prop.optional and prop.type_ == prop.compiled_type:
                var = '*' + var
            prop = self._cpp_type_generator.GetReferencedProperty(prop)
            return {
                PropertyType.STRING: 'base::Value::CreateStringValue(%s)',
                PropertyType.BOOLEAN: 'base::Value::CreateBooleanValue(%s)',
                PropertyType.INTEGER: 'base::Value::CreateIntegerValue(%s)',
                PropertyType.DOUBLE: 'base::Value::CreateDoubleValue(%s)',
            }[prop.type_] % var
        else:
            raise NotImplementedError('Conversion of %s to base::Value not '
                                      'implemented' % repr(prop.type_))
示例#23
0
 def _GenerateEvent(self, event):
     """Generates the namespaces for an event.
 """
     c = Code()
     # TODO(kalman): use event.unix_name not Classname.
     event_namespace = cpp_util.Classname(event.name)
     (c.Append('namespace %s {' % event_namespace).Append().Concat(
         self._GenerateCreateCallbackArguments(event)).Eblock(
             '}  // namespace %s' % event_namespace))
     return c
示例#24
0
    def _GenerateType(self, cpp_namespace, type_):
        """Generates the function definitions for a type.
    """
        classname = cpp_util.Classname(schema_util.StripNamespace(type_.name))
        c = Code()

        if type_.functions:
            # Wrap functions within types in the type's namespace.
            (c.Append('namespace %s {' % classname).Append())
            for function in type_.functions.values():
                c.Cblock(self._GenerateFunction(function))
            c.Append('}  // namespace %s' % classname)
        elif type_.property_type == PropertyType.ARRAY:
            c.Cblock(self._GenerateType(cpp_namespace, type_.item_type))
        elif type_.property_type in (PropertyType.CHOICES,
                                     PropertyType.OBJECT):
            if cpp_namespace is None:
                classname_in_namespace = classname
            else:
                classname_in_namespace = '%s::%s' % (cpp_namespace, classname)

            if type_.property_type == PropertyType.OBJECT:
                c.Cblock(
                    self._GeneratePropertyFunctions(classname_in_namespace,
                                                    type_.properties.values()))
            else:
                c.Cblock(
                    self._GenerateTypes(classname_in_namespace, type_.choices))

            (c.Append('%s::%s()' % (classname_in_namespace, classname)).Cblock(
                self._GenerateInitializersAndBody(type_)).Append(
                    '%s::~%s() {}' % (classname_in_namespace, classname)))
            # Note: we use 'rhs' because some API objects have a member 'other'.
            (c.Append('%s::%s(%s&& rhs)' %
                      (classname_in_namespace, classname, classname)).Cblock(
                          self._GenerateMoveCtor(type_)).Append(
                              '%s& %s::operator=(%s&& rhs)' %
                              (classname_in_namespace, classname_in_namespace,
                               classname)).Cblock(
                                   self._GenerateMoveAssignOperator(type_)))
            if type_.origin.from_json:
                c.Cblock(
                    self._GenerateTypePopulate(classname_in_namespace, type_))
                if cpp_namespace is None:  # only generate for top-level types
                    c.Cblock(
                        self._GenerateTypeFromValue(classname_in_namespace,
                                                    type_))
            if type_.origin.from_client:
                c.Cblock(
                    self._GenerateTypeToValue(classname_in_namespace, type_))
        elif type_.property_type == PropertyType.ENUM:
            (c.Cblock(self._GenerateEnumToString(cpp_namespace, type_)).Cblock(
                self._GenerateEnumFromString(cpp_namespace, type_)))

        return c
示例#25
0
    def _GenerateFunction(self, function):
        """Generates the structs for a function.
    """
        c = code.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
示例#26
0
 def _GenerateEvent(self, event):
     """Generates the namespaces for an event.
 """
     c = Code()
     # TODO(kalman): use event.unix_name not Classname.
     event_namespace = cpp_util.Classname(event.name)
     (c.Append('namespace %s {' % event_namespace).Append().Concat(
         self._GenerateEventNameConstant(event)).Concat(
             self._GenerateAsyncResponseArguments(event.params)).Append(
                 '}  // namespace %s' % event_namespace))
     return c
示例#27
0
    def GetEnumValue(self, type_, enum_value):
        """Gets the enum value of the given model.Property of the given type.

    e.g VAR_STRING
    """
        value = '%s_%s' % (self.FollowRef(type_).unix_name.upper(),
                           cpp_util.Classname(enum_value.upper()))
        # To avoid collisions with built-in OS_* preprocessor definitions, we add a
        # trailing slash to enum names that start with OS_.
        if value.startswith("OS_"):
            value += "_"
        return value
示例#28
0
    def _GenerateTypePopulate(self, cpp_namespace, type_):
        """Generates the function for populating a type given a pointer to it.

    E.g for type "Foo", generates Foo::Populate()
    """
        classname = cpp_util.Classname(schema_util.StripNamespace(type_.name))
        c = Code()
        (c.Append('// static').Append('bool %(namespace)s::Populate(').Sblock(
            '    const base::Value& value, %(name)s* out) {'))
        if type_.property_type == PropertyType.CHOICES:
            for choice in type_.choices:
                value_type = cpp_util.GetValueType(
                    self._type_helper.FollowRef(choice))
                (c.Sblock('if (value.IsType(%s)) {' % value_type).Concat(
                    self._GeneratePopulateVariableFromValue(
                        choice,
                        '(&value)',
                        'out->as_%s' % choice.unix_name,
                        'false',
                        is_ptr=True)).Append('return true;').Eblock('}'))
            c.Append('return false;')
        elif type_.property_type == PropertyType.OBJECT:
            (c.Append('if (!value.IsType(base::Value::TYPE_DICTIONARY))').
             Append('  return false;'))
            if type_.properties or type_.additional_properties is not None:
                c.Append('const base::DictionaryValue* dict = '
                         'static_cast<const base::DictionaryValue*>(&value);')
            for prop in type_.properties.values():
                c.Concat(self._InitializePropertyToDefault(prop, 'out'))
            for prop in type_.properties.values():
                c.Concat(
                    self._GenerateTypePopulateProperty(prop, 'dict', 'out'))
            if type_.additional_properties is not None:
                if type_.additional_properties.property_type == PropertyType.ANY:
                    c.Append(
                        'out->additional_properties.MergeDictionary(dict);')
                else:
                    cpp_type = self._type_helper.GetCppType(
                        type_.additional_properties, is_in_container=True)
                    (c.Append('for (base::DictionaryValue::Iterator it(*dict);'
                              ).Sblock('     !it.IsAtEnd(); it.Advance()) {').
                     Append('%s tmp;' % cpp_type).Concat(
                         self._GeneratePopulateVariableFromValue(
                             type_.additional_properties, '(&it.value())',
                             'tmp', 'false')).Append(
                                 'out->additional_properties[it.key()] = tmp;'
                             ).Eblock('}'))
            c.Append('return true;')
        (c.Eblock('}').Substitute({
            'namespace': cpp_namespace,
            'name': classname
        }))
        return c
示例#29
0
 def _GenerateTypeFromValue(self, cpp_namespace, type_):
     classname = cpp_util.Classname(schema_util.StripNamespace(type_.name))
     c = Code()
     (c.Append('// static').Append(
         'scoped_ptr<%s> %s::FromValue(const base::Value& value) {' %
         (classname, cpp_namespace)).Append(
             '  scoped_ptr<%s> out(new %s());' %
             (classname, classname)).Append(
                 '  if (!Populate(value, out.get()))').Append(
                     '    return scoped_ptr<%s>();' %
                     classname).Append('  return out.Pass();').Append('}'))
     return c
示例#30
0
 def _GenerateFunction(self, function):
     """Generates the namespaces and structs for a function.
 """
     c = Code()
     # TODO(kalman): Use function.unix_name not Classname here.
     function_namespace = cpp_util.Classname(function.name)
     (c.Append('namespace %s {' % function_namespace).Append().Cblock(
         self._GenerateFunctionParams(function)))
     if function.callback:
         c.Cblock(self._GenerateFunctionResults(function.callback))
     c.Append('}  // namespace %s' % function_namespace)
     return c