Beispiel #1
0
    def Generate(self):
        """Generates a Code object with the .h for a single namespace.
    """
        c = Code()
        (c.Append(cpp_util.CHROMIUM_LICENSE).Append().Append(
            cpp_util.GENERATED_FILE_MESSAGE %
            self._namespace.source_file).Append())

        # Hack: for the purpose of gyp the header file will always be the source
        # file with its file extension replaced by '.h'. Assume so.
        output_file = os.path.splitext(self._namespace.source_file)[0] + '.h'
        ifndef_name = cpp_util.GenerateIfndefName(output_file)

        (c.Append('#ifndef %s' % ifndef_name).Append(
            '#define %s' %
            ifndef_name).Append().Append('#include <map>').Append(
                '#include <string>').Append('#include <vector>').Append().
         Append('#include "base/basictypes.h"').Append(
             '#include "base/logging.h"').Append(
                 '#include "base/memory/linked_ptr.h"').Append(
                     '#include "base/memory/scoped_ptr.h"').Append(
                         '#include "base/values.h"').Cblock(
                             self._type_helper.GenerateIncludes()).Append())

        # TODO(calamity): These forward declarations should be #includes to allow
        # $ref types from other files to be used as required params. This requires
        # some detangling of windows and tabs which will currently lead to circular
        # #includes.
        c.Cblock(self._type_helper.GenerateForwardDeclarations())

        cpp_namespace = cpp_util.GetCppNamespace(
            self._namespace.environment.namespace_pattern,
            self._namespace.unix_name)
        c.Concat(cpp_util.OpenNamespace(cpp_namespace))
        c.Append()
        if self._namespace.properties:
            (c.Append('//').Append('// Properties').Append('//').Append())
            for prop in self._namespace.properties.values():
                property_code = self._type_helper.GeneratePropertyValues(
                    prop, 'extern const %(type)s %(name)s;')
                if property_code:
                    c.Cblock(property_code)
        if self._namespace.types:
            (c.Append('//').Append('// Types').Append('//').Append().Cblock(
                self._GenerateTypes(self._FieldDependencyOrder(),
                                    is_toplevel=True,
                                    generate_typedefs=True)))
        if self._namespace.functions:
            (c.Append('//').Append('// Functions').Append('//').Append())
            for function in self._namespace.functions.values():
                c.Cblock(self._GenerateFunction(function))
        if self._namespace.events:
            (c.Append('//').Append('// Events').Append('//').Append())
            for event in self._namespace.events.values():
                c.Cblock(self._GenerateEvent(event))
        (c.Concat(cpp_util.CloseNamespace(cpp_namespace)).Append(
            '#endif  // %s' % ifndef_name).Append())
        return c
Beispiel #2
0
    def Generate(self):
        """Generates a Code object with the .cc for a single namespace.
    """
        cpp_namespace = cpp_util.GetCppNamespace(
            self._namespace.environment.namespace_pattern,
            self._namespace.unix_name)

        c = Code()
        (c.Append(cpp_util.CHROMIUM_LICENSE).Append().Append(
            cpp_util.GENERATED_FILE_MESSAGE %
            self._namespace.source_file).Append().Append(
                self._util_cc_helper.GetIncludePath()).Append(
                    '#include "base/logging.h"').Append(
                        '#include "base/strings/string_number_conversions.h"').
         Append('#include "base/strings/utf_string_conversions.h"').Append(
             '#include "%s/%s.h"' %
             (self._namespace.source_file_dir,
              self._namespace.short_filename)).Append('#include <set>').Cblock(
                  self._type_helper.GenerateIncludes(include_soft=True)
              ).Append().Append('using base::UTF8ToUTF16;').Append().Concat(
                  cpp_util.OpenNamespace(cpp_namespace)))
        if self._namespace.properties:
            (c.Append('//').Append('// Properties').Append('//').Append())
            for property in self._namespace.properties.values():
                property_code = self._type_helper.GeneratePropertyValues(
                    property,
                    'const %(type)s %(name)s = %(value)s;',
                    nodoc=True)
                if property_code:
                    c.Cblock(property_code)
        if self._namespace.types:
            (c.Append('//').Append('// Types').Append('//').Append().Cblock(
                self._GenerateTypes(None, self._namespace.types.values())))
        if self._namespace.functions:
            (c.Append('//').Append('// Functions').Append('//').Append())
        for function in self._namespace.functions.values():
            c.Cblock(self._GenerateFunction(function))
        if self._namespace.events:
            (c.Append('//').Append('// Events').Append('//').Append())
            for event in self._namespace.events.values():
                c.Cblock(self._GenerateEvent(event))
        c.Cblock(cpp_util.CloseNamespace(cpp_namespace))
        c.Append()
        return c
    def GenerateForwardDeclarations(self):
        """Returns the forward declarations for self._default_namespace.
    """
        c = Code()
        for namespace, deps in self._NamespaceTypeDependencies().iteritems():
            filtered_deps = [
                dep for dep in deps
                # Add more ways to forward declare things as necessary.
                if (not dep.hard and dep.type_.property_type in (
                    PropertyType.CHOICES, PropertyType.OBJECT))
            ]
            if not filtered_deps:
                continue

            cpp_namespace = cpp_util.GetCppNamespace(
                namespace.environment.namespace_pattern, namespace.unix_name)
            c.Concat(cpp_util.OpenNamespace(cpp_namespace))
            for dep in filtered_deps:
                c.Append('struct %s;' % dep.type_.name)
            c.Concat(cpp_util.CloseNamespace(cpp_namespace))
        return c
    def GetCppType(self, type_, is_ptr=False, is_in_container=False):
        """Translates a model.Property or model.Type into its C++ type.

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

    Use |is_ptr| if the type is optional. This will wrap the type in a
    scoped_ptr if possible (it is not possible to wrap an enum).

    Use |is_in_container| if the type is appearing in a collection, e.g. a
    std::vector or std::map. This will wrap it in the correct type with spacing.
    """
        cpp_type = None
        if type_.property_type == PropertyType.REF:
            ref_type = self._FindType(type_.ref_type)
            if ref_type is None:
                raise KeyError('Cannot find referenced type: %s' %
                               type_.ref_type)
            cpp_type = self.GetCppType(ref_type)
        elif type_.property_type == PropertyType.BOOLEAN:
            cpp_type = 'bool'
        elif type_.property_type == PropertyType.INTEGER:
            cpp_type = 'int'
        elif type_.property_type == PropertyType.INT64:
            cpp_type = 'int64'
        elif type_.property_type == PropertyType.DOUBLE:
            cpp_type = 'double'
        elif type_.property_type == PropertyType.STRING:
            cpp_type = 'std::string'
        elif type_.property_type in (PropertyType.ENUM, PropertyType.OBJECT,
                                     PropertyType.CHOICES):
            if self._default_namespace is type_.namespace:
                cpp_type = cpp_util.Classname(type_.name)
            else:
                cpp_namespace = cpp_util.GetCppNamespace(
                    type_.namespace.environment.namespace_pattern,
                    type_.namespace.unix_name)
                cpp_type = '%s::%s' % (cpp_namespace,
                                       cpp_util.Classname(type_.name))
        elif type_.property_type == PropertyType.ANY:
            cpp_type = 'base::Value'
        elif type_.property_type == PropertyType.FUNCTION:
            # Functions come into the json schema compiler as empty objects. We can
            # record these as empty DictionaryValues so that we know if the function
            # was passed in or not.
            cpp_type = 'base::DictionaryValue'
        elif type_.property_type == PropertyType.ARRAY:
            item_cpp_type = self.GetCppType(type_.item_type,
                                            is_in_container=True)
            cpp_type = 'std::vector<%s>' % cpp_util.PadForGenerics(
                item_cpp_type)
        elif type_.property_type == PropertyType.BINARY:
            cpp_type = 'std::vector<char>'
        else:
            raise NotImplementedError('Cannot get type of %s' %
                                      type_.property_type)

        # HACK: optional ENUM is represented elsewhere with a _NONE value, so it
        # never needs to be wrapped in pointer shenanigans.
        # TODO(kalman): change this - but it's an exceedingly far-reaching change.
        if not self.FollowRef(type_).property_type == PropertyType.ENUM:
            if is_in_container and (is_ptr or not self.IsCopyable(type_)):
                cpp_type = 'linked_ptr<%s>' % cpp_util.PadForGenerics(cpp_type)
            elif is_ptr:
                cpp_type = 'scoped_ptr<%s>' % cpp_util.PadForGenerics(cpp_type)

        return cpp_type
Beispiel #5
0
    def Generate(self):
        """Generates a Code object with the .h for a single namespace.
    """
        c = Code()
        (c.Append(cpp_util.CHROMIUM_LICENSE).Append().Append(
            cpp_util.GENERATED_FILE_MESSAGE %
            self._namespace.source_file).Append())

        # Hack: for the purpose of gyp the header file will always be the source
        # file with its file extension replaced by '.h'. Assume so.
        output_file = os.path.splitext(self._namespace.source_file)[0] + '.h'
        ifndef_name = cpp_util.GenerateIfndefName(output_file)

        # Hack: tabs and windows have circular references, so only generate hard
        # references for them (i.e. anything that can't be forward declared). In
        # other cases, generate soft dependencies so that they can include
        # non-optional types from other namespaces.
        include_soft = self._namespace.name not in ('tabs', 'windows')

        (c.Append('#ifndef %s' % ifndef_name).Append(
            '#define %s' % ifndef_name).Append().Append('#include <stdint.h>').
         Append().Append('#include <map>').Append('#include <memory>').Append(
             '#include <string>').Append('#include <vector>').Append().Append(
                 '#include "base/values.h"').Cblock(
                     self._type_helper.GenerateIncludes(
                         include_soft=include_soft)).Append())

        # Hack: we're not generating soft includes for tabs and windows, so we need
        # to generate forward declarations for them.
        if not include_soft:
            c.Cblock(self._type_helper.GenerateForwardDeclarations())

        cpp_namespace = cpp_util.GetCppNamespace(
            self._namespace.environment.namespace_pattern,
            self._namespace.unix_name)
        c.Concat(cpp_util.OpenNamespace(cpp_namespace))
        c.Append()
        if self._namespace.properties:
            (c.Append('//').Append('// Properties').Append('//').Append())
            for prop in self._namespace.properties.values():
                property_code = self._type_helper.GeneratePropertyValues(
                    prop, 'extern const %(type)s %(name)s;')
                if property_code:
                    c.Cblock(property_code)
        if self._namespace.types:
            (c.Append('//').Append('// Types').Append('//').Append().Cblock(
                self._GenerateTypes(self._FieldDependencyOrder(),
                                    is_toplevel=True,
                                    generate_typedefs=True)))
        if self._namespace.manifest_keys:
            c.Append('//')
            c.Append('// Manifest Keys')
            c.Append('//')
            c.Append()
            c.Cblock(self._GenerateManifestKeys())
        if self._namespace.functions:
            (c.Append('//').Append('// Functions').Append('//').Append())
            for function in self._namespace.functions.values():
                c.Cblock(self._GenerateFunction(function))
        if self._namespace.events:
            (c.Append('//').Append('// Events').Append('//').Append())
            for event in self._namespace.events.values():
                c.Cblock(self._GenerateEvent(event))
        (c.Concat(cpp_util.CloseNamespace(cpp_namespace)).Append().Append(
            '#endif  // %s' % ifndef_name).Append())
        return c