def Render(self):
     """Returns the Code object for the body of the .cc file, which handles the
 initialization of all features."""
     c = Code()
     c.Append('%s::%s() {' % (self._provider_class, self._provider_class))
     c.Sblock()
     for k in sorted(self._features.keys()):
         c.Sblock('{')
         feature = self._features[k]
         if type(feature) is list:
             c.Append('std::vector<Feature*> features;')
             for f in feature:
                 c.Sblock('{')
                 c.Concat(f.GetCode(self._feature_class))
                 c.Append('features.push_back(feature);')
                 c.Eblock('}')
             c.Append(
                 'ComplexFeature* feature(new ComplexFeature(&features));')
             c.Append('feature->set_name("%s");' % k)
         else:
             c.Concat(feature.GetCode(self._feature_class))
         c.Append('AddFeature("%s", feature);' % k)
         c.Eblock('}')
     c.Eblock('}')
     return c
Beispiel #2
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 #3
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
 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 #5
0
 def _GenerateCreateEnumValue(self, cpp_namespace, prop):
     """Generates CreateEnumValue() that returns the |StringValue|
 representation of an enum.
 """
     c = Code()
     c.Append('// static')
     c.Sblock(
         'scoped_ptr<Value> %(cpp_namespace)s::CreateEnumValue(%(arg)s) {')
     c.Sblock('switch (%s) {' % prop.unix_name)
     if prop.optional:
         (c.Append('case %s: {' %
                   self._cpp_type_generator.GetEnumNoneValue(prop)).Append(
                       '  return scoped_ptr<Value>();').Append('}'))
     for enum_value in prop.enum_values:
         (c.Append(
             'case %s: {' %
             self._cpp_type_generator.GetEnumValue(prop, enum_value)
         ).Append(
             '  return scoped_ptr<Value>(Value::CreateStringValue("%s"));' %
             enum_value).Append('}'))
     (c.Append('default: {').Append('  return scoped_ptr<Value>();').Append(
         '}'))
     c.Eblock('}')
     c.Eblock('}')
     c.Substitute({
         'cpp_namespace':
         cpp_namespace,
         'arg':
         cpp_util.GetParameterDeclaration(
             prop, self._cpp_type_generator.GetType(prop))
     })
     return c
Beispiel #6
0
 def testComment(self):
     long_comment = ('This comment is eighty nine characters in longness, '
                     'that is, to use another word, length')
     c = Code()
     c.Comment(long_comment)
     self.assertEquals(
         '// This comment is eighty nine characters '
         'in longness, that is, to use another\n'
         '// word, length', c.Render())
     c = Code()
     c.Sblock('sblock')
     c.Comment(long_comment)
     c.Eblock('eblock')
     c.Comment(long_comment)
     self.assertEquals(
         'sblock\n'
         '  // This comment is eighty nine characters '
         'in longness, that is, to use\n'
         '  // another word, length\n'
         'eblock\n'
         '// This comment is eighty nine characters in '
         'longness, that is, to use another\n'
         '// word, length', c.Render())
     long_word = 'x' * 100
     c = Code()
     c.Comment(long_word)
     self.assertEquals('// ' + 'x' * 77 + '\n' '// ' + 'x' * 23, c.Render())
    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:
            c.Append(
                line % {
                    "type": self.GetCppType(prop.type_),
                    "name": prop.name,
                    "value": prop.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
Beispiel #8
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
  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 #10
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 #11
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
Beispiel #12
0
    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')))
            if self._cpp_type_generator.IsEnumOrEnumRef(prop):
                (c.Append('} else {').Append(
                    '%%(dst)s->%%(name)s = %s;' %
                    self._cpp_type_generator.GetEnumNoneValue(prop)))
            c.Eblock('}')
        else:
            (c.Append(
                'if (!%(src)s->GetWithoutPathExpansion("%(key)s", &%(value_var)s))'
            ).Append('  return false;').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 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._AppendInterfaceObject(c)
    c.Append()

    c.Sblock('%s.prototype = {' % self._interface)

    for function in self._namespace.functions.values():
      self._AppendFunction(c, function)

    c.TrimTrailingNewlines()
    c.Eblock('};')
    c.Append()

    for event in self._namespace.events.values():
      self._AppendEvent(c, event)

    c.TrimTrailingNewlines()

    return c
Beispiel #14
0
    def _GenerateTypeToValue(self, cpp_namespace, type_):
        """Generates a function that serializes the type into a |DictionaryValue|.

    E.g. for type "Foo" generates Foo::ToValue()
    """
        c = Code()
        (c.Sblock(
            'scoped_ptr<DictionaryValue> %s::ToValue() const {' %
            cpp_namespace).Append(
                'scoped_ptr<DictionaryValue> value(new DictionaryValue());').
         Append())
        for prop in type_.properties.values():
            if prop.type_ == PropertyType.ADDITIONAL_PROPERTIES:
                c.Append('value->MergeDictionary(&%s);' % prop.unix_name)
            else:
                if prop.optional:
                    if prop.type_ == PropertyType.ENUM:
                        c.Sblock(
                            'if (%s != %s)' %
                            (prop.unix_name,
                             self._cpp_type_generator.GetEnumNoneValue(prop)))
                    else:
                        c.Sblock('if (%s.get())' % prop.unix_name)
                c.Append('value->SetWithoutPathExpansion("%s", %s);' %
                         (prop.name,
                          self._CreateValueFromProperty(
                              prop, 'this->' + prop.unix_name)))
                if prop.optional:
                    c.Eblock()
        (c.Append().Append('return value.Pass();').Eblock('}'))
        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
Beispiel #16
0
    def Generate(self):
        """Generates a Code object for features.
    """
        c = Code()
        (c.Append(cpp_util.CHROMIUM_LICENSE).Append().Append(
            cpp_util.GENERATED_FEATURE_MESSAGE % self._source_file).Append().
         Append('#include <string>').Append().Append(
             '#include "%s.h"' % self._source_file_filename).Append().Append(
                 '#include "base/notreached.h"').Append().Concat(
                     cpp_util.OpenNamespace(self._namespace)).Append())

        # Generate the constructor.
        (c.Append('%s::%s() {' %
                  (self._class_name, self._class_name)).Sblock())
        for feature in self._feature_defs:
            c.Append('features_["%s"] = %s;' %
                     (feature.name,
                      cpp_util.FeatureNameToConstantName(feature.name)))
        (c.Eblock().Append('}').Append())

        # Generate the ToString function.
        (c.Append(
            'const char* %s::ToString('
            '%s::ID id) const {' %
            (self._class_name,
             self._class_name)).Sblock().Append('switch (id) {').Sblock())
        for feature in self._feature_defs:
            c.Append('case %s: return "%s";' %
                     (cpp_util.FeatureNameToConstantName(
                         feature.name), feature.name))
        (c.Append('case kUnknown: break;').Append('case kEnumBoundary: break;')
         .Eblock().Append('}').Append('NOTREACHED();').Append('return "";'))
        (c.Eblock().Append('}').Append())

        # Generate the FromString function.

        (c.Append(
            '%s::ID %s::FromString('
            'const std::string& id) const {' %
            (self._class_name, self._class_name)).Sblock().Append(
                'const auto& it = features_.find(id);' %
                self._class_name).Append(
                    'return (it == features_.end()) ? kUnknown : it->second;').
         Eblock().Append('}').Append().Cblock(
             cpp_util.CloseNamespace(self._namespace)))

        return c
Beispiel #17
0
  def _GenerateObjectTypeToValue(self, cpp_namespace, type_):
    """Generates a function that serializes an object-representing type
    into a base::DictionaryValue.
    """
    c = Code()
    (c.Sblock('scoped_ptr<base::DictionaryValue> %s::ToValue() const {' %
          cpp_namespace)
        .Append('scoped_ptr<base::DictionaryValue> value('
                    'new base::DictionaryValue());')
        .Append()
    )

    for prop in type_.properties.values():
      if prop.optional:
        # Optional enum values are generated with a NONE enum value.
        underlying_type = self._type_helper.FollowRef(prop.type_)
        if underlying_type.property_type == PropertyType.ENUM:
          c.Sblock('if (%s != %s) {' %
              (prop.unix_name,
               self._type_helper.GetEnumNoneValue(prop.type_)))
        else:
          c.Sblock('if (%s.get()) {' % prop.unix_name)

      # ANY is a base::Value which is abstract and cannot be a direct member, so
      # it will always be a pointer.
      is_ptr = prop.optional or prop.type_.property_type == PropertyType.ANY
      c.Append('value->SetWithoutPathExpansion("%s", %s);' % (
          prop.name,
          self._CreateValueFromType(prop.type_,
                                    'this->%s' % prop.unix_name,
                                    is_ptr=is_ptr)))

      if prop.optional:
        c.Eblock('}')

    if type_.additional_properties is not None:
      if type_.additional_properties.property_type == PropertyType.ANY:
        c.Append('value->MergeDictionary(&additional_properties);')
      else:
        # Non-copyable types will be wrapped in a linked_ptr for inclusion in
        # maps, so we need to unwrap them.
        needs_unwrap = (
            not self._type_helper.IsCopyable(type_.additional_properties))
        cpp_type = self._type_helper.GetCppType(type_.additional_properties,
                                                is_in_container=True)
        (c.Sblock('for (std::map<std::string, %s>::const_iterator it =' %
                      cpp_util.PadForGenerics(cpp_type))
          .Append('       additional_properties.begin();')
          .Append('   it != additional_properties.end(); ++it) {')
          .Append('value->SetWithoutPathExpansion(it->first, %s);' %
              self._CreateValueFromType(
                  type_.additional_properties,
                  '%sit->second' % ('*' if needs_unwrap else '')))
          .Eblock('}')
        )

    return (c.Append()
             .Append('return value.Pass();')
           .Eblock('}'))
Beispiel #18
0
  def _GenerateObjectTypeToValue(self, cpp_namespace, type_):
    """Generates a function that serializes an object-representing type
    into a base::DictionaryValue.
    """
    c = Code()
    (c.Sblock('std::unique_ptr<base::DictionaryValue> %s::ToValue() const {' %
          cpp_namespace)
        .Append('std::unique_ptr<base::DictionaryValue> to_value_result('
                    'new base::DictionaryValue());')
        .Append()
    )

    for prop in type_.properties.values():
      prop_var = 'this->%s' % prop.unix_name
      if prop.optional:
        underlying_type = self._type_helper.FollowRef(prop.type_)
        if underlying_type.property_type == PropertyType.ENUM:
          # Optional enum values are generated with a NONE enum value,
          # potentially from another namespace.
          maybe_namespace = ''
          if underlying_type.namespace != self._namespace:
            maybe_namespace = '%s::' % underlying_type.namespace.unix_name
          c.Sblock('if (%s != %s%s) {' %
              (prop_var,
               maybe_namespace,
               self._type_helper.GetEnumNoneValue(prop.type_)))
        else:
          c.Sblock('if (%s.get()) {' % prop_var)

      # ANY is a base::Value which is abstract and cannot be a direct member, so
      # it will always be a pointer.
      is_ptr = prop.optional or prop.type_.property_type == PropertyType.ANY
      c.Cblock(self._CreateValueFromType(
          'to_value_result->SetWithoutPathExpansion("%s", %%s);' % prop.name,
          prop.name,
          prop.type_,
          prop_var,
          is_ptr=is_ptr))

      if prop.optional:
        c.Eblock('}')

    if type_.additional_properties is not None:
      if type_.additional_properties.property_type == PropertyType.ANY:
        c.Append('to_value_result->MergeDictionary(&additional_properties);')
      else:
        (c.Sblock('for (const auto& it : additional_properties) {')
          .Cblock(self._CreateValueFromType(
              'to_value_result->SetWithoutPathExpansion(it.first, %s);',
              type_.additional_properties.name,
              type_.additional_properties,
              'it.second'))
          .Eblock('}')
        )

    return (c.Append()
             .Append('return to_value_result;')
           .Eblock('}'))
Beispiel #19
0
 def _GenerateEnumDeclaration(self, enum_name, type_):
     """Generate the declaration of a C++ enum.
 """
     c = Code()
     c.Sblock('enum %s {' % enum_name)
     c.Append(self._type_helper.GetEnumNoneValue(type_) + ',')
     for value in type_.enum_values:
         c.Append(self._type_helper.GetEnumValue(type_, value) + ',')
     return c.Eblock('};')
Beispiel #20
0
    def _GeneratePopulatePropertyFromValue(self,
                                           prop,
                                           value_var,
                                           dst,
                                           failure_value,
                                           check_type=True):
        """Generates code to populate a model.Property given a base::Value*. The
    existence of data inside the base::Value* is assumed so checks for existence
    should be performed before the code this generates.

    prop: the property the code is populating.
    value_var: a base::Value* that should represent |prop|.
    dst: the object with |prop| as a member.
    failure_value: the value to return if |prop| cannot be extracted from
    |value_var|
    check_type: if true, will check if |value_var| is the correct
    base::Value::Type
    """
        c = Code()
        c.Sblock('{')

        if self._IsFundamentalOrFundamentalRef(prop):
            self._GenerateFundamentalOrFundamentalRefPopulate(
                c, prop, value_var, dst)
        elif self._IsObjectOrObjectRef(prop):
            self._GenerateObjectOrObjectRefPopulate(c, prop)
        elif prop.type_ == PropertyType.FUNCTION:
            self._GenerateFunctionPopulate(c, prop)
        elif prop.type_ == PropertyType.ANY:
            self._GenerateAnyPopulate(c, prop, value_var, dst)
        elif self._IsArrayOrArrayRef(prop):
            self._GenerateArrayOrArrayRefPopulate(c, prop, dst)
        elif prop.type_ == PropertyType.CHOICES:
            self._GenerateChoicePopulate(c, prop, value_var, dst,
                                         failure_value)
        elif self._cpp_type_generator.IsEnumOrEnumRef(prop):
            self._GenerateEnumPopulate(c, prop, value_var)
        elif prop.type_ == PropertyType.BINARY:
            self._GenerateBinaryPopulate(c, prop)
        else:
            raise NotImplementedError(prop.type_)
        c.Eblock('}')
        sub = {
            'value_var': value_var,
            'name': prop.unix_name,
            'dst': dst,
            'failure_value': failure_value,
        }
        if prop.type_ not in (PropertyType.CHOICES, PropertyType.ANY):
            sub['ctype'] = self._cpp_type_generator.GetType(prop)
            sub['compiled_ctype'] = self._cpp_type_generator.GetCompiledType(
                prop)
            sub['value_type'] = cpp_util.GetValueType(
                self._cpp_type_generator.GetReferencedProperty(prop).type_)
        c.Substitute(sub)
        return c
Beispiel #21
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 #22
0
 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)
Beispiel #23
0
 def _GenerateEnumDeclaration(self, enum_name, prop, values):
     """Generate the declaration of a C++ enum for the given property and
 values.
 """
     c = Code()
     c.Sblock('enum %s {' % enum_name)
     if prop.optional:
         c.Append(self._cpp_type_generator.GetEnumNoneValue(prop) + ',')
     for value in values:
         c.Append(self._cpp_type_generator.GetEnumValue(prop, value) + ',')
     (c.Eblock('};').Append())
     return c
Beispiel #24
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
Beispiel #25
0
    def _GenerateTypeToValue(self, cpp_namespace, type_):
        """Generates a function that serializes the type into a
    |base::DictionaryValue|.

    E.g. for type "Foo" generates Foo::ToValue()
    """
        c = Code()
        (c.Sblock('scoped_ptr<base::DictionaryValue> %s::ToValue() const {' %
                  cpp_namespace).Append(
                      'scoped_ptr<base::DictionaryValue> value('
                      'new base::DictionaryValue());').Append())
        for prop in type_.properties.values():
            if prop.type_ == PropertyType.ADDITIONAL_PROPERTIES:
                c.Append('value->MergeDictionary(&%s);' % prop.unix_name)
            else:
                if prop.optional:
                    if self._cpp_type_generator.IsEnumOrEnumRef(prop):
                        c.Sblock(
                            'if (%s != %s) {' %
                            (prop.unix_name,
                             self._cpp_type_generator.GetEnumNoneValue(prop)))
                    elif prop.type_ == PropertyType.CHOICES:
                        c.Sblock(
                            'if (%s_type != %s) {' %
                            (prop.unix_name,
                             self._cpp_type_generator.GetEnumNoneValue(prop)))
                    else:
                        c.Sblock('if (%s.get()) {' % prop.unix_name)

                if prop.type_ == prop.compiled_type:
                    c.Append('value->SetWithoutPathExpansion("%s", %s);' %
                             (prop.name,
                              self._CreateValueFromProperty(
                                  prop, 'this->' + prop.unix_name)))
                else:
                    conversion_src = 'this->' + prop.unix_name
                    if prop.optional:
                        conversion_src = '*' + conversion_src
                    (c.Append('%s %s;' % (self._cpp_type_generator.GetType(
                        prop), prop.unix_name)).Append(
                            cpp_util.GenerateCompiledTypeToTypeConversion(
                                self._cpp_type_generator.GetReferencedProperty(
                                    prop), conversion_src, prop.unix_name) +
                            ';').Append(
                                'value->SetWithoutPathExpansion("%s", %s);' %
                                (prop.unix_name,
                                 self._CreateValueFromProperty(
                                     prop, prop.unix_name))))
                if prop.optional:
                    c.Eblock('}')
        (c.Append().Append('return value.Pass();').Eblock('}'))
        return c
 def _GenerateEnumDeclaration(self, enum_name, type_):
   """Generate a code object with the  declaration of a C++ enum.
   """
   c = Code()
   c.Sblock('enum %s {' % enum_name)
   c.Append(self._type_helper.GetEnumNoneValue(type_) + ',')
   for value in type_.enum_values:
     current_enum_string = self._type_helper.GetEnumValue(type_, value)
     c.Append(current_enum_string + ',')
   c.Append('%s = %s,' % (
       self._type_helper.GetEnumLastValue(type_), current_enum_string))
   c.Eblock('};')
   return c
Beispiel #27
0
 def _GenerateEvent(self, event):
     """Generates the interface for an event.
 """
     c = Code()
     c.Sblock(line='/**', line_prefix=' * ')
     if (event.description):
         c.Comment(event.description, comment_prefix='')
     c.Append('@type {!ChromeEvent}')
     c.Append(
         self._js_util.GenerateSeeLink(self._namespace.name, 'event',
                                       event.name))
     c.Eblock(' */')
     c.Append('%s: new ChromeEvent(),' % (event.name))
     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 GetCode(self, feature_type):
     c = Code()
     c.Append('std::vector<Feature*> features;')
     for f in self.feature_list:
         # Sanity check that components of complex features have no shared values
         # set.
         assert not f.shared_values
         c.Sblock('{')
         c.Concat(f.GetCode(feature_type))
         c.Append('features.push_back(feature);')
         c.Eblock('}')
     c.Append('ComplexFeature* feature(new ComplexFeature(&features));')
     c.Append('feature->set_name("%s");' % self.name)
     c.Concat(GetCodeForFeatureValues(self.shared_values))
     return c
  def _GenerateEvent(self, event):
    """Generates the code representing an event.
       For example:

       /** @type {!ChromeEvent} */
       chrome.bookmarks.onChildrenReordered;
    """
    c = Code()
    c.Sblock(line='/**', line_prefix=' * ')
    if (event.description):
      c.Comment(event.description, comment_prefix='')
    c.Append('@type {!ChromeEvent}')
    c.Append(self._GenerateSeeLink('event', event.name))
    c.Eblock(' */')
    c.Append('chrome.%s.%s;' % (self._namespace.name, event.name))
    return c