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
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
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