diff options
author | cduvall@chromium.org <cduvall@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-09-25 01:00:41 +0000 |
---|---|---|
committer | cduvall@chromium.org <cduvall@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-09-25 01:00:41 +0000 |
commit | 0ba7b4f2a2295978d3747573ef0332f7e410889b (patch) | |
tree | 93769dd77f84c9463e1a8ad8a6dff5be850f895e | |
parent | dd5d7cc6a98df018e0018cd23b72a1b6287be0c4 (diff) | |
download | chromium_src-0ba7b4f2a2295978d3747573ef0332f7e410889b.zip chromium_src-0ba7b4f2a2295978d3747573ef0332f7e410889b.tar.gz chromium_src-0ba7b4f2a2295978d3747573ef0332f7e410889b.tar.bz2 |
Extensions Docs Server: Enum values do not show up if enum is a type
If an enumerated string is a type, the possible values were not shown.
BUG=146301
Review URL: https://chromiumcodereview.appspot.com/10907151
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@158475 0039d316-1c4b-4281-b951-d872f2087c98
22 files changed, 255 insertions, 204 deletions
diff --git a/chrome/browser/extensions/api/context_menu/context_menu_api.cc b/chrome/browser/extensions/api/context_menu/context_menu_api.cc index a87a349..102d5ee 100644 --- a/chrome/browser/extensions/api/context_menu/context_menu_api.cc +++ b/chrome/browser/extensions/api/context_menu/context_menu_api.cc @@ -75,6 +75,8 @@ extensions::MenuItem::ContextList GetContexts( case PropertyWithEnumT::CONTEXTS_ELEMENT_FRAME: contexts.Add(extensions::MenuItem::FRAME); break; + case PropertyWithEnumT::CONTEXTS_ELEMENT_NONE: + NOTREACHED(); } } return contexts; @@ -243,6 +245,8 @@ bool UpdateContextMenuFunction::RunImpl() { case Update::Params::ID_INTEGER: item_id.uid = *params->id_integer; break; + case Update::Params::ID_NONE: + NOTREACHED(); } ExtensionService* service = profile()->GetExtensionService(); @@ -344,6 +348,9 @@ bool RemoveContextMenuFunction::RunImpl() { break; case Remove::Params::MENU_ITEM_ID_INTEGER: id.uid = *params->menu_item_id_integer; + break; + case Remove::Params::MENU_ITEM_ID_NONE: + NOTREACHED(); } MenuItem* item = manager->GetItemById(id); diff --git a/chrome/browser/extensions/api/downloads/downloads_api.cc b/chrome/browser/extensions/api/downloads/downloads_api.cc index e4cc721..f2394a1 100644 --- a/chrome/browser/extensions/api/downloads/downloads_api.cc +++ b/chrome/browser/extensions/api/downloads/downloads_api.cc @@ -431,18 +431,21 @@ void RunDownloadQuery( } query_out.Limit(*query_in.limit.get()); } - if (query_in.state.get()) { - DownloadItem::DownloadState state = StateEnumFromString( - *query_in.state.get()); + std::string state_string = + extensions::api::downloads::ToString(query_in.state); + if (!state_string.empty()) { + DownloadItem::DownloadState state = StateEnumFromString(state_string); if (state == DownloadItem::MAX_DOWNLOAD_STATE) { *error = download_extension_errors::kInvalidStateError; return; } query_out.AddFilter(state); } - if (query_in.danger.get()) { - content::DownloadDangerType danger_type = - DangerEnumFromString(*query_in.danger.get()); + std::string danger_string = + extensions::api::downloads::ToString(query_in.danger); + if (!danger_string.empty()) { + content::DownloadDangerType danger_type = DangerEnumFromString( + danger_string); if (danger_type == content::DOWNLOAD_DANGER_TYPE_MAX) { *error = download_extension_errors::kInvalidDangerTypeError; return; @@ -624,8 +627,10 @@ bool DownloadsDownloadFunction::RunImpl() { } } - if (options.method.get()) - download_params->set_method(*options.method.get()); + std::string method_string = + extensions::api::downloads::ToString(options.method); + if (!method_string.empty()) + download_params->set_method(method_string); if (options.body.get()) download_params->set_post_body(*options.body.get()); download_params->set_callback(base::Bind( diff --git a/chrome/browser/extensions/api/downloads/downloads_api_unittest.cc b/chrome/browser/extensions/api/downloads/downloads_api_unittest.cc index aee109d..aef64d6 100644 --- a/chrome/browser/extensions/api/downloads/downloads_api_unittest.cc +++ b/chrome/browser/extensions/api/downloads/downloads_api_unittest.cc @@ -1207,14 +1207,6 @@ IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, EXPECT_STREQ(download_extension_errors::kInvalidFilterError, error.c_str()); error = RunFunctionAndReturnError( - new DownloadsSearchFunction(), "[{\"danger\": \"goat\"}]"); - EXPECT_STREQ(download_extension_errors::kInvalidDangerTypeError, - error.c_str()); - error = RunFunctionAndReturnError( - new DownloadsSearchFunction(), "[{\"state\": \"goat\"}]"); - EXPECT_STREQ(download_extension_errors::kInvalidStateError, - error.c_str()); - error = RunFunctionAndReturnError( new DownloadsSearchFunction(), "[{\"orderBy\": \"goat\"}]"); EXPECT_STREQ(download_extension_errors::kInvalidOrderByError, error.c_str()); diff --git a/chrome/browser/extensions/api/font_settings/font_settings_api.cc b/chrome/browser/extensions/api/font_settings/font_settings_api.cc index 729f7b6..4abe3df 100644 --- a/chrome/browser/extensions/api/font_settings/font_settings_api.cc +++ b/chrome/browser/extensions/api/font_settings/font_settings_api.cc @@ -59,11 +59,15 @@ const char kWebKitFontPrefPrefix[] = "webkit.webprefs.fonts."; // Gets the font name preference path for |generic_family| and |script|. If // |script| is NULL, uses prefs::kWebKitCommonScript. -std::string GetFontNamePrefPath(const std::string& generic_family, - const std::string* script) { +std::string GetFontNamePrefPath(fonts::GenericFamily generic_family_enum, + fonts::ScriptCode script_enum) { + std::string script = fonts::ToString(script_enum); + if (script.empty()) + script = prefs::kWebKitCommonScript; + std::string generic_family = fonts::ToString(generic_family_enum); return StringPrintf(kWebKitFontPrefFormat, generic_family.c_str(), - script ? script->c_str() : prefs::kWebKitCommonScript); + script.c_str()); } // Extracts the generic family and script from font name pref path |pref_path|. @@ -251,7 +255,7 @@ bool ClearFontFunction::RunImpl() { EXTENSION_FUNCTION_VALIDATE(params.get()); std::string pref_path = GetFontNamePrefPath(params->details.generic_family, - params->details.script.get()); + params->details.script); // Ensure |pref_path| really is for a registered per-script font pref. EXTENSION_FUNCTION_VALIDATE( @@ -270,7 +274,8 @@ bool GetFontFunction::RunImpl() { EXTENSION_FUNCTION_VALIDATE(params.get()); std::string pref_path = GetFontNamePrefPath(params->details.generic_family, - params->details.script.get()); + params->details.script); + PrefService* prefs = profile_->GetPrefs(); const PrefService::Preference* pref = prefs->FindPreference(pref_path.c_str()); @@ -307,7 +312,8 @@ bool SetFontFunction::RunImpl() { EXTENSION_FUNCTION_VALIDATE(params.get()); std::string pref_path = GetFontNamePrefPath(params->details.generic_family, - params->details.script.get()); + params->details.script); + // Ensure |pref_path| really is for a registered font pref. EXTENSION_FUNCTION_VALIDATE( profile_->GetPrefs()->FindPreference(pref_path.c_str())); diff --git a/chrome/browser/extensions/api/media_galleries/media_galleries_api.cc b/chrome/browser/extensions/api/media_galleries/media_galleries_api.cc index 648c9d6..1430964 100644 --- a/chrome/browser/extensions/api/media_galleries/media_galleries_api.cc +++ b/chrome/browser/extensions/api/media_galleries/media_galleries_api.cc @@ -73,24 +73,34 @@ bool MediaGalleriesGetMediaFileSystemsFunction::RunImpl() { scoped_ptr<GetMediaFileSystems::Params> params( GetMediaFileSystems::Params::Create(*args_)); EXTENSION_FUNCTION_VALIDATE(params.get()); - MediaGalleries::GetMediaFileSystemsInteractivity interactive = "no"; - if (params->details.get() && params->details->interactive.get()) - interactive = *params->details->interactive; - - if (interactive == "yes") { - ShowDialog(); - return true; - } else if (interactive == "if_needed") { - MediaFileSystemRegistry::GetInstance()->GetMediaFileSystemsForExtension( - render_view_host(), GetExtension(), base::Bind( - &MediaGalleriesGetMediaFileSystemsFunction::ShowDialogIfNoGalleries, - this)); - return true; - } else if (interactive == "no") { - GetAndReturnGalleries(); - return true; + MediaGalleries::GetMediaFileSystemsInteractivity interactive = + MediaGalleries::MEDIA_GALLERIES_GET_MEDIA_FILE_SYSTEMS_INTERACTIVITY_NO; + if (params->details.get() && params->details->interactive != MediaGalleries:: + MEDIA_GALLERIES_GET_MEDIA_FILE_SYSTEMS_INTERACTIVITY_NONE) { + interactive = params->details->interactive; } + switch (interactive) { + case MediaGalleries:: + MEDIA_GALLERIES_GET_MEDIA_FILE_SYSTEMS_INTERACTIVITY_YES: + ShowDialog(); + return true; + case MediaGalleries:: + MEDIA_GALLERIES_GET_MEDIA_FILE_SYSTEMS_INTERACTIVITY_IF_NEEDED: + MediaFileSystemRegistry::GetInstance()->GetMediaFileSystemsForExtension( + render_view_host(), GetExtension(), base::Bind( + &MediaGalleriesGetMediaFileSystemsFunction:: + ShowDialogIfNoGalleries, + this)); + return true; + case MediaGalleries:: + MEDIA_GALLERIES_GET_MEDIA_FILE_SYSTEMS_INTERACTIVITY_NO: + GetAndReturnGalleries(); + return true; + case MediaGalleries:: + MEDIA_GALLERIES_GET_MEDIA_FILE_SYSTEMS_INTERACTIVITY_NONE: + NOTREACHED(); + } error_ = kInvalidInteractive; return false; } diff --git a/chrome/browser/extensions/api/rtc_private/rtc_private_api.cc b/chrome/browser/extensions/api/rtc_private/rtc_private_api.cc index 57c07a5..ada236f 100644 --- a/chrome/browser/extensions/api/rtc_private/rtc_private_api.cc +++ b/chrome/browser/extensions/api/rtc_private/rtc_private_api.cc @@ -46,27 +46,20 @@ const char kNameIntentField[] = "name"; const char kPhoneIntentField[] = "phone"; const char kEmailIntentField[] = "email"; -// Returns string representation of intent action. -const char* GetLaunchAction(RtcPrivateEventRouter::LaunchAction action) { - const char* action_str = kActivateAction; +// Returns the ActionType of intent action. +api::rtc_private::ActionType GetLaunchAction( + RtcPrivateEventRouter::LaunchAction action) { switch (action) { case RtcPrivateEventRouter::LAUNCH_ACTIVATE: - action_str = kActivateAction; - break; + return api::rtc_private::RTC_PRIVATE_ACTION_TYPE_NONE; case RtcPrivateEventRouter::LAUNCH_CHAT: - action_str = kChatAction; - break; + return api::rtc_private::RTC_PRIVATE_ACTION_TYPE_CHAT; case RtcPrivateEventRouter::LAUNCH_VOICE: - action_str = kVoiceAction; - break; + return api::rtc_private::RTC_PRIVATE_ACTION_TYPE_VOICE; case RtcPrivateEventRouter::LAUNCH_VIDEO: - action_str = kVideoAction; - break; - default: - NOTREACHED() << "Unknown action " << action; - break; + return api::rtc_private::RTC_PRIVATE_ACTION_TYPE_VIDEO; } - return action_str; + return api::rtc_private::RTC_PRIVATE_ACTION_TYPE_NONE; } // Creates JSON payload string for contact web intent data. diff --git a/chrome/browser/extensions/api/socket/socket_api.cc b/chrome/browser/extensions/api/socket/socket_api.cc index ce400e5..c4d1637 100644 --- a/chrome/browser/extensions/api/socket/socket_api.cc +++ b/chrome/browser/extensions/api/socket/socket_api.cc @@ -28,9 +28,6 @@ const char kBytesWrittenKey[] = "bytesWritten"; const char kDataKey[] = "data"; const char kResultCodeKey[] = "resultCode"; const char kSocketIdKey[] = "socketId"; -const char kTCPOption[] = "tcp"; -const char kUDPOption[] = "udp"; -const char kUnknown[] = "unknown"; const char kSocketNotFoundError[] = "Socket not found"; const char kSocketTypeInvalidError[] = "Socket type is not supported"; @@ -120,14 +117,18 @@ bool SocketCreateFunction::Prepare() { params_ = api::socket::Create::Params::Create(*args_); EXTENSION_FUNCTION_VALIDATE(params_.get()); - if (params_->type == kTCPOption) { - socket_type_ = kSocketTypeTCP; - } else if (params_->type == kUDPOption) { - socket_type_ = kSocketTypeUDP; - } else { - error_ = kSocketTypeInvalidError; - return false; + switch (params_->type) { + case extensions::api::socket::SOCKET_SOCKET_TYPE_TCP: + socket_type_ = kSocketTypeTCP; + break; + case extensions::api::socket::SOCKET_SOCKET_TYPE_UDP: + socket_type_ = kSocketTypeUDP; + break; + case extensions::api::socket::SOCKET_SOCKET_TYPE_NONE: + NOTREACHED(); + break; } + if (params_->options.get()) { scoped_ptr<DictionaryValue> options = params_->options->ToValue(); src_id_ = ExtractSrcId(options.get()); @@ -534,18 +535,10 @@ void SocketGetInfoFunction::Work() { if (socket) { // This represents what we know about the socket, and does not call through // to the system. - switch (socket->GetSocketType()) { - case Socket::TYPE_TCP: - info.socket_type = kTCPOption; - break; - case Socket::TYPE_UDP: - info.socket_type = kUDPOption; - break; - default: - NOTREACHED() << "Unknown socket type."; - info.socket_type = kUnknown; - break; - } + if (socket->GetSocketType() == Socket::TYPE_TCP) + info.socket_type = extensions::api::socket::SOCKET_SOCKET_TYPE_TCP; + else + info.socket_type = extensions::api::socket::SOCKET_SOCKET_TYPE_UDP; info.connected = socket->IsConnected(); // Grab the peer address as known by the OS. This and the call below will diff --git a/chrome/browser/extensions/api/socket/socket_api_unittest.cc b/chrome/browser/extensions/api/socket/socket_api_unittest.cc index 008e07b..ff1466c 100644 --- a/chrome/browser/extensions/api/socket/socket_api_unittest.cc +++ b/chrome/browser/extensions/api/socket/socket_api_unittest.cc @@ -74,11 +74,6 @@ TEST_F(SocketUnitTest, Create) { new SocketCreateFunction(), "[\"tcp\"]")); ASSERT_TRUE(result.get()); } - { - std::string error = RunFunctionAndReturnError( - new SocketCreateFunction(), "[\"nonexistent-socket-type\"]"); - ASSERT_FALSE(error.empty()) << "Expected error. Got nothing instead."; - } } } // namespace extensions diff --git a/chrome/browser/extensions/api/socket/socket_apitest.cc b/chrome/browser/extensions/api/socket/socket_apitest.cc index af02f634..29414d1 100644 --- a/chrome/browser/extensions/api/socket/socket_apitest.cc +++ b/chrome/browser/extensions/api/socket/socket_apitest.cc @@ -93,22 +93,6 @@ IN_PROC_BROWSER_TEST_F(SocketApiTest, SocketTCPCreateGood) { ASSERT_TRUE(socketId > 0); } -IN_PROC_BROWSER_TEST_F(SocketApiTest, SocketCreateBad) { - scoped_refptr<extensions::SocketCreateFunction> socket_create_function( - new extensions::SocketCreateFunction()); - scoped_refptr<Extension> empty_extension(utils::CreateEmptyExtension()); - - socket_create_function->set_extension(empty_extension.get()); - socket_create_function->set_has_callback(true); - - // TODO(miket): this test currently passes only because of artificial code - // that doesn't run in production. Fix this when we're able to. - utils::RunFunctionAndReturnError( - socket_create_function, - "[\"xxxx\"]", - browser(), utils::NONE); -} - IN_PROC_BROWSER_TEST_F(SocketApiTest, GetNetworkList) { scoped_refptr<extensions::SocketGetNetworkListFunction> socket_function( new extensions::SocketGetNetworkListFunction()); diff --git a/chrome/browser/extensions/api/system_info_storage/storage_info_provider_mac.cc b/chrome/browser/extensions/api/system_info_storage/storage_info_provider_mac.cc index 53537d7..2ae4589 100644 --- a/chrome/browser/extensions/api/system_info_storage/storage_info_provider_mac.cc +++ b/chrome/browser/extensions/api/system_info_storage/storage_info_provider_mac.cc @@ -79,7 +79,8 @@ bool StorageInfoProviderMac::QueryUnitInfo(const std::string& id, type = dev_path_to_type_map_[volume_dev].empty() ? systeminfo::kStorageTypeUnknown : dev_path_to_type_map_[volume_dev]; } - info->type = type; + info->type = + api::experimental_system_info_storage::FromStorageUnitTypeString(type); // TODO(joshuagl): we're reporting different values than Disk Utility. // Is there an alternative API to get this information that doesn't use // statfs? NSFileManager's attributesOfFileSystemForPath uses statfs. diff --git a/chrome/browser/extensions/api/system_info_storage/storage_info_provider_win.cc b/chrome/browser/extensions/api/system_info_storage/storage_info_provider_win.cc index e3c721d..83c347f 100644 --- a/chrome/browser/extensions/api/system_info_storage/storage_info_provider_win.cc +++ b/chrome/browser/extensions/api/system_info_storage/storage_info_provider_win.cc @@ -83,7 +83,8 @@ bool StorageInfoProviderWin::QueryUnitInfo(const std::string& id, if (GetDiskFreeSpaceEx(drive.c_str(), NULL, &total_bytes, &free_bytes)) { info->id = id; - info->type = type; + info->type = + api::experimental_system_info_storage::FromStorageUnitTypeString(type); info->capacity = static_cast<double>(total_bytes.QuadPart); info->available_capacity = static_cast<double>(free_bytes.QuadPart); return true; diff --git a/chrome/browser/extensions/api/system_info_storage/system_info_storage_apitest.cc b/chrome/browser/extensions/api/system_info_storage/system_info_storage_apitest.cc index 3f7e77a..3231c3d 100644 --- a/chrome/browser/extensions/api/system_info_storage/system_info_storage_apitest.cc +++ b/chrome/browser/extensions/api/system_info_storage/system_info_storage_apitest.cc @@ -32,7 +32,8 @@ class MockStorageInfoProvider : public StorageInfoProvider { linked_ptr<StorageUnitInfo> unit(new StorageUnitInfo()); unit->id = "0xbeaf"; - unit->type = systeminfo::kStorageTypeUnknown; + unit->type = api::experimental_system_info_storage:: + EXPERIMENTAL_SYSTEM_INFO_STORAGE_STORAGE_UNIT_TYPE_UNKNOWN; unit->capacity = 4098; unit->available_capacity = 1024; diff --git a/tools/json_schema_compiler/cc_generator.py b/tools/json_schema_compiler/cc_generator.py index f01479a..2e42998 100644 --- a/tools/json_schema_compiler/cc_generator.py +++ b/tools/json_schema_compiler/cc_generator.py @@ -109,27 +109,27 @@ class CCGenerator(object): self._GenerateFunction( cpp_namespace + '::' + cpp_util.Classname(function.name), function)) - .Append() - ) + .Append()) elif type_.type_ == PropertyType.OBJECT: (c.Concat(self._GeneratePropertyFunctions( cpp_namespace, type_.properties.values())) .Sblock('%(namespace)s::%(classname)s()') .Concat(self._GenerateInitializersAndBody(type_)) .Eblock('%(namespace)s::~%(classname)s() {}') - .Append() - ) + .Append()) if type_.from_json: (c.Concat(self._GenerateTypePopulate(cpp_namespace, type_)) - .Append() - ) + .Append()) if type_.from_client: (c.Concat(self._GenerateTypeToValue(cpp_namespace, type_)) - .Append() - ) + .Append()) elif self._cpp_type_generator.IsEnumOrEnumRef(type_): - c.Concat(self._GenerateCreateEnumTypeValue(cpp_namespace, type_)) - c.Append() + (c.Concat(self._GenerateCreateEnumTypeValue(cpp_namespace, type_)) + .Append() + .Concat(self._GenerateEnumFromString(cpp_namespace, type_)) + .Append() + .Concat(self._GenerateEnumToString(cpp_namespace, type_)) + .Append()) c.Substitute({'classname': classname, 'namespace': cpp_namespace}) return c @@ -220,12 +220,14 @@ class CCGenerator(object): c.Append('const base::Value* %(value_var)s = NULL;') if prop.optional: (c.Sblock( - 'if (%(src)s->GetWithoutPathExpansion("%(key)s", &%(value_var)s)) {' - ) + 'if (%(src)s->GetWithoutPathExpansion("%(key)s", &%(value_var)s)) {') .Concat(self._GeneratePopulatePropertyFromValue( - prop, value_var, dst, 'false')) - .Eblock('}') - ) + 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))') @@ -234,7 +236,13 @@ class CCGenerator(object): prop, value_var, dst, 'false')) ) c.Append() - c.Substitute({'value_var': value_var, 'key': prop.name, 'src': src}) + c.Substitute({ + 'value_var': value_var, + 'key': prop.name, + 'src': src, + 'dst': dst, + 'name': prop.unix_name + }) return c def _GenerateTypeToValue(self, cpp_namespace, type_): @@ -343,7 +351,7 @@ class CCGenerator(object): vardot = var + '.' return '%sDeepCopy()' % vardot elif self._cpp_type_generator.IsEnumOrEnumRef(prop): - return 'CreateEnumValue(%s).release()' % var + return 'base::Value::CreateStringValue(ToString(%s))' % var elif prop.type_ == PropertyType.BINARY: if prop.optional: vardot = var + '->' @@ -648,11 +656,7 @@ class CCGenerator(object): c.Append('%(dst)s->%(name)s' + accessor + 'push_back(enum_temp);') c.Eblock('}') - def _GenerateStringToEnumConversion(self, - c, - prop, - value_var, - enum_temp): + def _GenerateStringToEnumConversion(self, c, prop, value_var, enum_temp): """Appends code that converts a string to an enum. Leaves failure_value unsubstituted. @@ -661,23 +665,16 @@ class CCGenerator(object): value_var: the string value that is being converted. enum_temp: the name used to store the temporary enum value. """ - (c.Append('%s %s;' % (self._cpp_type_generator.GetCompiledType(prop), - enum_temp)) - .Append('std::string enum_as_string;') + (c.Append('std::string enum_as_string;') .Append('if (!%s->GetAsString(&enum_as_string))' % value_var) .Append(' return %(failure_value)s;') - ) - for i, enum_value in enumerate( - self._cpp_type_generator.GetReferencedProperty(prop).enum_values): - (c.Append( - ('if' if i == 0 else 'else if') + - '(enum_as_string == "%s")' % enum_value) - .Append(' ' + enum_temp + ' = %s;' % ( - self._cpp_type_generator.GetEnumValue(prop, enum_value))) - ) - (c.Append('else') - .Append(' return %(failure_value)s;') - ) + .Append('%(type)s %(enum)s = From%(type)sString(enum_as_string);' % { + 'type': self._cpp_type_generator.GetCompiledType(prop), + 'enum': enum_temp + }) + .Append('if (%s == %s)' % + (enum_temp, self._cpp_type_generator.GetEnumNoneValue(prop))) + .Append(' return %(failure_value)s;')) def _GeneratePropertyFunctions(self, param_namespace, params): """Generate the functions for structures generated by a property such as @@ -699,8 +696,16 @@ class CCGenerator(object): if param.from_client: c.Concat(self._GenerateGetChoiceValue(param_namespace, param)) elif param.type_ == PropertyType.ENUM: - c.Concat(self._GenerateCreateEnumValue(param_namespace, param)) - c.Append() + (c.Concat(self._GenerateCreateEnumValue(param_namespace, param)) + .Append() + .Concat(self._GenerateEnumFromString(param_namespace, + param, + use_namespace=True)) + .Append() + .Concat(self._GenerateEnumToString(param_namespace, + param, + use_namespace=True)) + .Append()) return c def _GenerateGetChoiceValue(self, cpp_namespace, prop): @@ -711,18 +716,15 @@ class CCGenerator(object): (c.Sblock('scoped_ptr<base::Value> ' '%(cpp_namespace)s::Get%(choice)sChoiceValue() const {') .Sblock('switch (%s_type) {' % prop.unix_name) - ) - if prop.optional: - c.Concat(self._GenerateReturnCase( + .Concat(self._GenerateReturnCase( self._cpp_type_generator.GetEnumNoneValue(prop), - 'scoped_ptr<base::Value>()')) + '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('NOTREACHED();') .Append('return scoped_ptr<base::Value>();') .Eblock('}') .Append() @@ -739,21 +741,76 @@ class CCGenerator(object): """ c = Code() classname = cpp_util.Classname(schema_util.StripSchemaNamespace(prop.name)) - c.Sblock('scoped_ptr<base::Value> CreateEnumValue(%s %s) {' % ( - classname, classname.lower())) - c.Sblock('switch (%s) {' % classname.lower()) + (c.Sblock('scoped_ptr<base::Value> CreateEnumValue(%s %s) {' % + (classname, classname.lower())) + .Append('std::string enum_temp = ToString(%s);' % classname.lower()) + .Append('if (enum_temp.empty())') + .Append(' return scoped_ptr<base::Value>();') + .Append('return scoped_ptr<base::Value>(' + 'base::Value::CreateStringValue(enum_temp));') + .Eblock('}')) + return c + + 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( - '%s_%s' % (classname.upper(), enum_value.upper()), - 'scoped_ptr<base::Value>(base::Value::CreateStringValue("%s"))' % - enum_value)) - (c.Eblock('}') - .Append('NOTREACHED();') - .Append('return scoped_ptr<base::Value>();') + 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 + + def _GenerateEnumFromString(self, cpp_namespace, prop, use_namespace=False): + """Generates FromClassNameString() which gets an enum from its string + representation. + """ + c = Code() + classname = cpp_util.Classname(schema_util.StripSchemaNamespace(prop.name)) + if use_namespace: + namespace = '%s::' % cpp_namespace + else: + namespace = '' + + (c.Append('// static') + .Sblock('%(namespace)s%(class)s' + ' %(namespace)sFrom%(class)sString(' + 'const std::string& enum_string) {')) + enum_prop = self._cpp_type_generator.GetReferencedProperty(prop) + for i, enum_value in enumerate( + self._cpp_type_generator.GetReferencedProperty(prop).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) + .Append(' return %s;' % + self._cpp_type_generator.GetEnumValue(prop, enum_value))) + (c.Append('return %s;' % + self._cpp_type_generator.GetEnumNoneValue(prop)) + .Eblock('}') + .Substitute({ + 'namespace': namespace, + 'class': classname + })) return c # TODO(chebert): This is basically the same as GenerateCreateEnumTypeValue(). @@ -764,29 +821,20 @@ class CCGenerator(object): representation of an enum. """ c = Code() - c.Append('// static') - c.Sblock('scoped_ptr<base::Value> %(cpp_namespace)s::CreateEnumValue(' + (c.Append('// static') + .Sblock('scoped_ptr<base::Value> %(cpp_namespace)s::CreateEnumValue(' '%(arg)s) {') - c.Sblock('switch (%s) {' % prop.unix_name) - if prop.optional: - c.Concat(self._GenerateReturnCase( - self._cpp_type_generator.GetEnumNoneValue(prop), - 'scoped_ptr<base::Value>()')) - for enum_value in prop.enum_values: - c.Concat(self._GenerateReturnCase( - self._cpp_type_generator.GetEnumValue(prop, enum_value), - 'scoped_ptr<base::Value>(base::Value::CreateStringValue("%s"))' % - enum_value)) - (c.Eblock('}') - .Append('NOTREACHED();') - .Append('return scoped_ptr<base::Value>();') + .Append('std::string enum_temp = ToString(%s);' % prop.unix_name) + .Append('if (enum_temp.empty())') + .Append(' return scoped_ptr<base::Value>();') + .Append('return scoped_ptr<base::Value>(' + 'base::Value::CreateStringValue(enum_temp));') .Eblock('}') .Substitute({ 'cpp_namespace': cpp_namespace, 'arg': cpp_util.GetParameterDeclaration( prop, self._cpp_type_generator.GetType(prop)) - }) - ) + })) return c def _GenerateReturnCase(self, case_value, return_value): diff --git a/tools/json_schema_compiler/cpp_type_generator.py b/tools/json_schema_compiler/cpp_type_generator.py index 95329c3..deade36 100644 --- a/tools/json_schema_compiler/cpp_type_generator.py +++ b/tools/json_schema_compiler/cpp_type_generator.py @@ -6,6 +6,7 @@ from code import Code from model import PropertyType import any_helper import cpp_util +import operator import schema_util class CppTypeGenerator(object): @@ -98,20 +99,15 @@ class CppTypeGenerator(object): """Gets the enum value in the given model.Property indicating no value has been set. """ - prop_name = prop.unix_name - if (self.IsEnumRef(prop)): - prop_name = self.GetCompiledType(prop).upper() - return '%s_NONE' % prop_name.upper() + return '%s_NONE' % self.GetReferencedProperty(prop).unix_name.upper() def GetEnumValue(self, prop, enum_value): """Gets the enum value of the given model.Property of the given type. e.g VAR_STRING """ - prop_name = prop.unix_name.upper() - if (self.IsEnumRef(prop)): - prop_name = self.GetCompiledType(prop).upper() - return '%s_%s' % (prop_name, cpp_util.Classname(enum_value.upper())) + return '%s_%s' % (self.GetReferencedProperty(prop).unix_name.upper(), + cpp_util.Classname(enum_value.upper())) def GetChoicesEnumType(self, prop): """Gets the type of the enum for the given model.Property. @@ -209,7 +205,7 @@ class CppTypeGenerator(object): c = Code() namespace_type_dependencies = self._NamespaceTypeDependencies() for namespace in sorted(namespace_type_dependencies.keys(), - key=lambda ns: ns.name): + key=operator.attrgetter('name')): c.Append('namespace %s {' % namespace.name) for type_ in sorted(namespace_type_dependencies[namespace], key=schema_util.StripSchemaNamespace): @@ -222,7 +218,8 @@ class CppTypeGenerator(object): 'name': type_name, 'item_type': self.GetType(namespace.types[type_].item_type, wrap_optional=True)}) - else: + # Enums cannot be forward declared. + elif namespace.types[type_].type_ != PropertyType.ENUM: c.Append('struct %s;' % type_name) c.Append('}') c.Concat(self.GetNamespaceStart()) diff --git a/tools/json_schema_compiler/cpp_type_generator_test.py b/tools/json_schema_compiler/cpp_type_generator_test.py index decf1e9..4bfa507 100755 --- a/tools/json_schema_compiler/cpp_type_generator_test.py +++ b/tools/json_schema_compiler/cpp_type_generator_test.py @@ -120,7 +120,7 @@ class CppTypeGeneratorTest(unittest.TestCase): 'typedef std::vector<int> ColorArray;\n' '}\n' 'namespace fontSettings {\n' - 'typedef std::string ScriptCode;\n' + 'typedef std::string FakeStringType;\n' '}\n' 'namespace dependency_tester {\n' '} // dependency_tester', @@ -154,7 +154,8 @@ class CppTypeGeneratorTest(unittest.TestCase): self.font_settings.unix_name) self.assertEquals( 'std::string', - manager.GetType(self.font_settings.types['fontSettings.ScriptCode'])) + manager.GetType( + self.font_settings.types['fontSettings.FakeStringType'])) def testArrayAsType(self): manager = CppTypeGenerator('', self.browser_action, diff --git a/tools/json_schema_compiler/h_generator.py b/tools/json_schema_compiler/h_generator.py index c1df7ba..05a0241 100644 --- a/tools/json_schema_compiler/h_generator.py +++ b/tools/json_schema_compiler/h_generator.py @@ -135,8 +135,7 @@ class HGenerator(object): """ c = Code() c.Sblock('enum %s {' % enum_name) - if prop.optional: - c.Append(self._cpp_type_generator.GetEnumNoneValue(prop) + ',') + c.Append(self._cpp_type_generator.GetEnumNoneValue(prop) + ',') for value in values: c.Append(self._cpp_type_generator.GetEnumValue(prop, value) + ',') (c.Eblock('};') @@ -193,12 +192,16 @@ class HGenerator(object): if type_.description: c.Comment(type_.description) c.Sblock('enum %(classname)s {') + c.Append('%s,' % self._cpp_type_generator.GetEnumNoneValue(type_)) for value in type_.enum_values: - c.Append('%s_%s,' % (classname.upper(), value.upper())) + c.Append('%s,' % self._cpp_type_generator.GetEnumValue(type_, value)) (c.Eblock('};') .Append() .Append('scoped_ptr<base::Value> CreateEnumValue(%s %s);' % (classname, classname.lower())) + .Append('std::string ToString(%s enum_param);' % classname) + .Append('%s From%sString(const std::string& enum_string);' % + (classname, classname)) ) else: if type_.description: @@ -312,12 +315,19 @@ class HGenerator(object): prop.enum_values)) create_enum_value = ('scoped_ptr<base::Value> CreateEnumValue(%s %s);' % (enum_name, prop.unix_name)) + enum_to_string = 'std::string ToString(%s enum_param);' % enum_name + enum_from_string = ('%s From%sString(const std::string& enum_string);' % + (enum_name, enum_name)) # If the property is from the UI then we're in a struct so this function # should be static. If it's from the client, then we're just in a # namespace so we can't have the static keyword. if prop.from_json: - create_enum_value = 'static ' + create_enum_value - c.Append(create_enum_value) + create_enum_value = 'static %s' % create_enum_value + enum_to_string = 'static %s' % enum_to_string + enum_from_string = 'static %s' % enum_from_string + (c.Append(create_enum_value) + .Append(enum_to_string) + .Append(enum_from_string)) return c def _GeneratePrivatePropertyStructures(self, props): diff --git a/tools/json_schema_compiler/model.py b/tools/json_schema_compiler/model.py index 29c54a0..38a70ac 100644 --- a/tools/json_schema_compiler/model.py +++ b/tools/json_schema_compiler/model.py @@ -79,13 +79,13 @@ class Type(object): self.item_type = Property(self, name + "Element", json['items'], from_json=True, from_client=True) - elif json.get('type') == 'string': - self.type_ = PropertyType.STRING elif 'enum' in json: self.enum_values = [] for value in json['enum']: self.enum_values.append(value) self.type_ = PropertyType.ENUM + elif json.get('type') == 'string': + self.type_ = PropertyType.STRING else: if not ( 'properties' in json or @@ -95,6 +95,7 @@ class Type(object): raise ParseException(self, name + " has no properties or functions") self.type_ = PropertyType.OBJECT self.name = name + self.unix_name = UnixName(self.name) self.description = json.get('description') self.from_json = True self.from_client = True diff --git a/tools/json_schema_compiler/test/dependency_tester.json b/tools/json_schema_compiler/test/dependency_tester.json index aec4c15..15ff4ac 100644 --- a/tools/json_schema_compiler/test/dependency_tester.json +++ b/tools/json_schema_compiler/test/dependency_tester.json @@ -21,7 +21,7 @@ "$ref": "browserAction.ColorArray" }, "scriptCode": { - "$ref": "fontSettings.ScriptCode" + "$ref": "fontSettings.FakeStringType" } } } diff --git a/tools/json_schema_compiler/test/enums.json b/tools/json_schema_compiler/test/enums.json index 48c2c980..a0bea46 100644 --- a/tools/json_schema_compiler/test/enums.json +++ b/tools/json_schema_compiler/test/enums.json @@ -4,7 +4,7 @@ "types": [ { "id": "Enumeration", - "enum": ["none", "one", "two", "three"] + "enum": ["one", "two", "three"] }, { "id": "EnumType", diff --git a/tools/json_schema_compiler/test/enums_unittest.cc b/tools/json_schema_compiler/test/enums_unittest.cc index b9fec70..4604694 100644 --- a/tools/json_schema_compiler/test/enums_unittest.cc +++ b/tools/json_schema_compiler/test/enums_unittest.cc @@ -33,10 +33,10 @@ TEST(JsonSchemaCompilerEnumsTest, EnumsAsTypes) { scoped_ptr<TakesEnumAsType::Params> params( TakesEnumAsType::Params::Create(args)); ASSERT_TRUE(params.get()); - EXPECT_EQ(ENUMERATION_ONE, params->enumeration); + EXPECT_EQ(ENUMS_ENUMERATION_ONE, params->enumeration); EXPECT_TRUE(args.Equals(ReturnsEnumAsType::Results::Create( - ENUMERATION_ONE).get())); + ENUMS_ENUMERATION_ONE).get())); } { HasEnumeration enumeration; diff --git a/tools/json_schema_compiler/test/font_settings.json b/tools/json_schema_compiler/test/font_settings.json index be68083..0326aca 100644 --- a/tools/json_schema_compiler/test/font_settings.json +++ b/tools/json_schema_compiler/test/font_settings.json @@ -22,14 +22,9 @@ } }, { - "id": "ScriptCode", + "id": "FakeStringType", "type": "string", - "enum": [ "Arab", "Armn", "Beng", "Cans", "Cher", "Cyrl", "Deva", "Ethi", "Geor", - "Grek", "Gujr", "Guru", "Hang", "Hans", "Hant", "Hebr", "Hrkt", "Knda", - "Khmr", "Laoo", "Mlym", "Mong", "Mymr", "Orya", "Sinh", "Taml", "Telu", - "Thaa", "Thai", "Tibt", "Yiii" - ], - "description": "An ISO 15924 script code." + "description": "Used to test a string type." }, { "id": "GenericFamily", @@ -54,7 +49,7 @@ "type": "object", "properties": { "script": { - "$ref": "ScriptCode", + "$ref": "FakeStringType", "description": "The script for which the font should be cleared. If omitted, the global script font setting is cleared.", "optional": true }, @@ -81,7 +76,7 @@ "type": "object", "properties": { "script": { - "$ref": "ScriptCode", + "$ref": "FakeStringType", "description": "The script for which the font should be retrieved. If omitted, the font for the global script is retrieved.", "optional": true }, @@ -119,7 +114,7 @@ "type": "object", "properties": { "script": { - "$ref": "ScriptCode", + "$ref": "FakeStringType", "description": "The script code which the font should be set. If omitted, the font for the global script is set.", "optional": true }, @@ -454,7 +449,7 @@ "properties": { "fontName": { "type": "string" }, "script": { - "$ref": "ScriptCode", + "$ref": "FakeStringType", "description": "The script code for which the font setting has changed. If omitted, the global script font setting has changed.", "optional": true }, diff --git a/tools/json_schema_compiler/util.h b/tools/json_schema_compiler/util.h index 509b0dc..6943590 100644 --- a/tools/json_schema_compiler/util.h +++ b/tools/json_schema_compiler/util.h @@ -44,6 +44,17 @@ bool GetItemFromList(const ListValue& from, int index, linked_ptr<T>* out) { return true; } +// This is used for getting an enum out of a ListValue, which will happen if an +// array of enums is a parameter to a function. +template<class T> +bool GetItemFromList(const ListValue& from, int index, T* out) { + int value; + if (!from.GetInteger(index, &value)) + return false; + *out = static_cast<T>(value); + return true; +} + // Populates |out| with |list|. Returns false if there is no list at the // specified key or if the list has anything other than |T|. template <class T> |