Beispiel #1
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 #2
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
Beispiel #3
0
 def _GenerateChoiceTypeToValue(self, cpp_namespace, type_):
   """Generates a function that serializes a choice-representing type
   into a base::Value.
   """
   c = Code()
   c.Sblock('scoped_ptr<base::Value> %s::ToValue() const {' % cpp_namespace)
   c.Append('scoped_ptr<base::Value> result;')
   for choice in type_.choices:
     choice_var = 'as_%s' % choice.unix_name
     # Enums cannot be wrapped with scoped_ptr, but the XXX_NONE enum value
     # is equal to 0.
     (c.Sblock('if (%s) {' % choice_var)
         .Append('DCHECK(!result) << "Cannot set multiple choices for %s";' %
                     type_.unix_name)
         .Cblock(self._CreateValueFromType('result.reset(%s);',
                                           choice.name,
                                           choice,
                                           choice_var,
                                           True))
       .Eblock('}')
     )
   (c.Append('DCHECK(result) << "Must set at least one choice for %s";' %
                 type_.unix_name)
     .Append('return result;')
     .Eblock('}')
   )
   return c
Beispiel #4
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 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 #6
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 nullptr;').Eblock('}').Substitute({
                     'var':
                     var,
                     'required':
                     num_required,
                     'total':
                     len(function.params),
                 }))
     return c
Beispiel #7
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.assertMultiLineEqual(
     '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())
Beispiel #8
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 #9
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 #10
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 #11
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 #12
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 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
  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
Beispiel #15
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())
Beispiel #16
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
Beispiel #17
0
 def _GenerateListValueToEnumArrayConversion(self,
                                             item_type,
                                             src_var,
                                             dst_var,
                                             failure_value,
                                             is_ptr=False):
   """Returns Code that converts a ListValue of string constants from
   |src_var| into an array of enums of |type_| in |dst_var|. On failure,
   returns |failure_value|.
   """
   c = Code()
   accessor = '.'
   if is_ptr:
     accessor = '->'
     cpp_type = self._type_helper.GetCppType(item_type, is_in_container=True)
     c.Append('%s.reset(new std::vector<%s>);' %
                  (dst_var, cpp_util.PadForGenerics(cpp_type)))
   (c.Sblock('for (const auto& it : *(%s)) {' % src_var)
     .Append('%s tmp;' % self._type_helper.GetCppType(item_type))
     .Concat(self._GenerateStringToEnumConversion(item_type,
                                                  '(it)',
                                                  'tmp',
                                                  failure_value))
     .Append('%s%spush_back(tmp);' % (dst_var, accessor))
     .Eblock('}')
   )
   return c
Beispiel #18
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
  def _GenerateEnumJsDoc(self, js_type):
    """ Given an Enum Type object, returns the Code for the enum's definition.
    """
    c = Code()
    (c.Sblock(line='/**', line_prefix=' * ')
      .Append('@enum {string}')
      .Append(self._GenerateSeeLink('type', js_type.simple_name))
      .Eblock(' */'))
    c.Append('chrome.%s.%s = {' % (self._namespace.name, js_type.name))

    def get_property_name(e):
      # Enum properties are normified to be in ALL_CAPS_STYLE.
      # Assume enum '1ring-rulesThemAll'.
      # Transform to '1ring-rules_Them_All'.
      e = re.sub(r'([a-z])([A-Z])', r'\1_\2', e)
      # Transform to '1ring_rules_Them_All'.
      e = re.sub(r'\W', '_', e)
      # Transform to '_1ring_rules_Them_All'.
      e = re.sub(r'^(\d)', r'_\1', e)
      # Transform to '_1RING_RULES_THEM_ALL'.
      return e.upper()

    c.Append('\n'.join(
        ["  %s: '%s'," % (get_property_name(v.name), v.name)
            for v in js_type.enum_values]))
    c.Append('};')
    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
  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 #22
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 #23
0
 def _GenerateFunctionResults(self, callback):
     """Generates namespace for passing a function's result back.
 """
     c = Code()
     (c.Sblock('namespace Results {').Concat(
         self._GenerateCreateCallbackArguments(callback)).Eblock('};'))
     return c
Beispiel #24
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
Beispiel #25
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 #26
0
  def _GenerateTypePopulateProperty(self, prop, src, dst):
    """Generate the code to populate a single property in a type.

    src: DictionaryValue*
    dst: Type*
    """
    c = Code()
    value_var = prop.unix_name + '_value'
    c.Append('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'))
        .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})
    return c
Beispiel #27
0
    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
  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 #29
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
Beispiel #30
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