def testIsEmpty(self): c = Code() self.assertTrue(c.IsEmpty()) c.Append('asdf') self.assertFalse(c.IsEmpty())
def _GeneratePopulateVariableFromValue(self, type_, src_var, dst_var, failure_value, is_ptr=False): """Generates code to populate a variable |dst_var| of type |type_| from a Value* at |src_var|. The Value* is assumed to be non-NULL. In the generated code, if |dst_var| fails to be populated then Populate will return |failure_value|. """ c = Code() underlying_type = self._type_helper.FollowRef(type_) if underlying_type.property_type.is_fundamental: if is_ptr: (c.Append('%(cpp_type)s temp;') .Sblock('if (!%s) {' % cpp_util.GetAsFundamentalValue( self._type_helper.FollowRef(type_), src_var, '&temp')) .Concat(self._GenerateError( '"\'%%(key)s\': expected ' + '%s, got " + %s' % ( type_.name, self._util_cc_helper.GetValueTypeString( '%%(src_var)s', True))))) c.Append('%(dst_var)s.reset();') if not self._generate_error_messages: c.Append('return %(failure_value)s;') (c.Eblock('}') .Append('else') .Append(' %(dst_var)s.reset(new %(cpp_type)s(temp));') ) else: (c.Sblock('if (!%s) {' % cpp_util.GetAsFundamentalValue( self._type_helper.FollowRef(type_), src_var, '&%s' % dst_var)) .Concat(self._GenerateError( '"\'%%(key)s\': expected ' + '%s, got " + %s' % ( type_.name, self._util_cc_helper.GetValueTypeString( '%%(src_var)s', True)))) .Append('return %(failure_value)s;') .Eblock('}') ) elif underlying_type.property_type == PropertyType.OBJECT: if is_ptr: (c.Append('const base::DictionaryValue* dictionary = NULL;') .Sblock('if (!%(src_var)s->GetAsDictionary(&dictionary)) {') .Concat(self._GenerateError( '"\'%%(key)s\': expected dictionary, got " + ' + self._util_cc_helper.GetValueTypeString('%%(src_var)s', True)))) # If an optional property fails to populate, the population can still # succeed with a warning. If no error messages are generated, this # warning is not set and we fail out instead. if not self._generate_error_messages: c.Append('return %(failure_value)s;') (c.Eblock('}') .Sblock('else {') .Append('scoped_ptr<%(cpp_type)s> temp(new %(cpp_type)s());') .Append('if (!%%(cpp_type)s::Populate(%s)) {' % self._GenerateArgs( ('*dictionary', 'temp.get()'))) .Append(' return %(failure_value)s;') ) (c.Append('}') .Append('else') .Append(' %(dst_var)s = temp.Pass();') .Eblock('}') ) else: (c.Append('const base::DictionaryValue* dictionary = NULL;') .Sblock('if (!%(src_var)s->GetAsDictionary(&dictionary)) {') .Concat(self._GenerateError( '"\'%%(key)s\': expected dictionary, got " + ' + self._util_cc_helper.GetValueTypeString('%%(src_var)s', True))) .Append('return %(failure_value)s;') .Eblock('}') .Append('if (!%%(cpp_type)s::Populate(%s)) {' % self._GenerateArgs( ('*dictionary', '&%(dst_var)s'))) .Append(' return %(failure_value)s;') .Append('}') ) elif underlying_type.property_type == PropertyType.FUNCTION: if is_ptr: c.Append('%(dst_var)s.reset(new base::DictionaryValue());') elif underlying_type.property_type == PropertyType.ANY: c.Append('%(dst_var)s.reset(%(src_var)s->DeepCopy());') elif underlying_type.property_type == PropertyType.ARRAY: # util_cc_helper deals with optional and required arrays (c.Append('const base::ListValue* list = NULL;') .Sblock('if (!%(src_var)s->GetAsList(&list)) {') .Concat(self._GenerateError( '"\'%%(key)s\': expected list, got " + ' + self._util_cc_helper.GetValueTypeString('%%(src_var)s', True))) ) if is_ptr and self._generate_error_messages: c.Append('%(dst_var)s.reset();') else: c.Append('return %(failure_value)s;') c.Eblock('}') c.Sblock('else {') item_type = self._type_helper.FollowRef(underlying_type.item_type) if item_type.property_type == PropertyType.ENUM: c.Concat(self._GenerateListValueToEnumArrayConversion( item_type, 'list', dst_var, failure_value, is_ptr=is_ptr)) else: c.Sblock('if (!%s(%s)) {' % ( self._util_cc_helper.PopulateArrayFromListFunction(is_ptr), self._GenerateArgs(('*list', '&%(dst_var)s')))) c.Concat(self._GenerateError( '"unable to populate array \'%%(parent_key)s\'"')) if is_ptr and self._generate_error_messages: c.Append('%(dst_var)s.reset();') else: c.Append('return %(failure_value)s;') c.Eblock('}') c.Eblock('}') elif underlying_type.property_type == PropertyType.CHOICES: if is_ptr: (c.Append('scoped_ptr<%(cpp_type)s> temp(new %(cpp_type)s());') .Append('if (!%%(cpp_type)s::Populate(%s))' % self._GenerateArgs( ('*%(src_var)s', 'temp.get()'))) .Append(' return %(failure_value)s;') .Append('%(dst_var)s = temp.Pass();') ) else: (c.Append('if (!%%(cpp_type)s::Populate(%s))' % self._GenerateArgs( ('*%(src_var)s', '&%(dst_var)s'))) .Append(' return %(failure_value)s;')) elif underlying_type.property_type == PropertyType.ENUM: c.Concat(self._GenerateStringToEnumConversion(underlying_type, src_var, dst_var, failure_value)) elif underlying_type.property_type == PropertyType.BINARY: (c.Append('const base::BinaryValue* binary_value = NULL;') .Sblock('if (!%(src_var)s->IsType(base::Value::TYPE_BINARY)) {') .Concat(self._GenerateError( '"\'%%(key)s\': expected binary, got " + ' + self._util_cc_helper.GetValueTypeString('%%(src_var)s', True))) ) if not self._generate_error_messages: c.Append('return %(failure_value)s;') (c.Eblock('}') .Sblock('else {') .Append(' binary_value =') .Append(' static_cast<const base::BinaryValue*>(%(src_var)s);') ) if is_ptr: (c.Append('%(dst_var)s.reset(new std::vector<char>(') .Append(' binary_value->GetBuffer(),') .Append(' binary_value->GetBuffer() + binary_value->GetSize()));') ) else: (c.Append('%(dst_var)s.assign(') .Append(' binary_value->GetBuffer(),') .Append(' binary_value->GetBuffer() + binary_value->GetSize());') ) c.Eblock('}') else: raise NotImplementedError(type_) if c.IsEmpty(): return c return Code().Sblock('{').Concat(c.Substitute({ 'cpp_type': self._type_helper.GetCppType(type_), 'src_var': src_var, 'dst_var': dst_var, 'failure_value': failure_value, 'key': type_.name, 'parent_key': type_.parent.name, })).Eblock('}')