Switch the downloads API over to IDL/json_schema_compiler

Modify ppapi/generators/idl_parser.py to
0: not require a file-level comment (but generate the same parse tree structure),
1: actually support ext_attrs (modifiers) for dictionaries, and
2: support [ext_attr=(symbols|values)].

Modify json_schema_compiler to
0: use "base::Value" and any_helper.ANY_CLASS instead of Value and Any in order to support ArrayBuffers named |value| or |any|,
1: actually test that namespaces and dictionaries are sorted correctly,
2: fix HGenerator._FieldDependencyOrder(),
3: support [inline_doc] on dictionaries and enums,
4: support descriptions on enums,
5: support documentation_permissions_required,
6: support [legalValues=(values...)].

Review URL: https://chromiumcodereview.appspot.com/10639020

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@146201 0039d316-1c4b-4281-b951-d872f2087c98
parent df66ed60
...@@ -46,296 +46,162 @@ extern const char kNotImplementedError[]; ...@@ -46,296 +46,162 @@ extern const char kNotImplementedError[];
} // namespace download_extension_errors } // namespace download_extension_errors
class DownloadsFunctionInterface {
public:
enum DownloadsFunctionName {
DOWNLOADS_FUNCTION_DOWNLOAD = 0,
DOWNLOADS_FUNCTION_SEARCH = 1,
DOWNLOADS_FUNCTION_PAUSE = 2,
DOWNLOADS_FUNCTION_RESUME = 3,
DOWNLOADS_FUNCTION_CANCEL = 4,
DOWNLOADS_FUNCTION_ERASE = 5,
DOWNLOADS_FUNCTION_SET_DESTINATION = 6,
DOWNLOADS_FUNCTION_ACCEPT_DANGER = 7,
DOWNLOADS_FUNCTION_SHOW = 8,
DOWNLOADS_FUNCTION_DRAG = 9,
DOWNLOADS_FUNCTION_GET_FILE_ICON = 10,
// Insert new values here, not at the beginning.
DOWNLOADS_FUNCTION_LAST
};
protected:
virtual ~DownloadsFunctionInterface() {}
// Return true if args_ is well-formed, otherwise set error_ and return false.
virtual bool ParseArgs() = 0;
// Implementation-specific logic. "Do the thing that you do." Should return
// true if the call succeeded and false otherwise.
virtual bool RunInternal() = 0;
// Which subclass is this.
virtual DownloadsFunctionName function() const = 0;
// Wrap ParseArgs(), RunInternal().
static bool RunImplImpl(DownloadsFunctionInterface* pimpl);
};
class SyncDownloadsFunction : public SyncExtensionFunction,
public DownloadsFunctionInterface {
protected:
explicit SyncDownloadsFunction(DownloadsFunctionName function);
virtual ~SyncDownloadsFunction();
// ExtensionFunction:
virtual bool RunImpl() OVERRIDE;
// DownloadsFunctionInterface:
virtual DownloadsFunctionName function() const OVERRIDE;
content::DownloadItem* GetActiveItem(int download_id);
private:
DownloadsFunctionName function_;
DISALLOW_COPY_AND_ASSIGN(SyncDownloadsFunction);
};
class AsyncDownloadsFunction : public AsyncExtensionFunction, class DownloadsDownloadFunction : public AsyncExtensionFunction {
public DownloadsFunctionInterface {
protected:
explicit AsyncDownloadsFunction(DownloadsFunctionName function);
virtual ~AsyncDownloadsFunction();
// ExtensionFunction:
virtual bool RunImpl() OVERRIDE;
// DownloadsFunctionInterface:
virtual DownloadsFunctionName function() const OVERRIDE;
content::DownloadItem* GetActiveItem(int download_id);
private:
DownloadsFunctionName function_;
DISALLOW_COPY_AND_ASSIGN(AsyncDownloadsFunction);
};
class DownloadsDownloadFunction : public AsyncDownloadsFunction {
public: public:
DECLARE_EXTENSION_FUNCTION_NAME("downloads.download"); DECLARE_EXTENSION_FUNCTION_NAME("downloads.download");
DownloadsDownloadFunction(); DownloadsDownloadFunction();
virtual bool RunImpl() OVERRIDE;
protected: protected:
virtual ~DownloadsDownloadFunction(); virtual ~DownloadsDownloadFunction();
// DownloadsFunctionInterface:
virtual bool ParseArgs() OVERRIDE;
virtual bool RunInternal() OVERRIDE;
private: private:
struct IOData {
public:
IOData();
~IOData();
GURL url;
string16 filename;
bool save_as;
base::ListValue* extra_headers;
std::string method;
std::string post_body;
content::ResourceDispatcherHost* rdh;
content::ResourceContext* resource_context;
int render_process_host_id;
int render_view_host_routing_id;
};
void BeginDownloadOnIOThread();
void OnStarted(content::DownloadId dl_id, net::Error error); void OnStarted(content::DownloadId dl_id, net::Error error);
scoped_ptr<IOData> iodata_;
DISALLOW_COPY_AND_ASSIGN(DownloadsDownloadFunction); DISALLOW_COPY_AND_ASSIGN(DownloadsDownloadFunction);
}; };
class DownloadsSearchFunction : public SyncDownloadsFunction { class DownloadsSearchFunction : public SyncExtensionFunction {
public: public:
DECLARE_EXTENSION_FUNCTION_NAME("downloads.search"); DECLARE_EXTENSION_FUNCTION_NAME("downloads.search");
DownloadsSearchFunction(); DownloadsSearchFunction();
virtual bool RunImpl() OVERRIDE;
protected: protected:
virtual ~DownloadsSearchFunction(); virtual ~DownloadsSearchFunction();
// DownloadsFunctionInterface:
virtual bool ParseArgs() OVERRIDE;
virtual bool RunInternal() OVERRIDE;
private: private:
bool ParseOrderBy(const base::Value& order_by_value);
scoped_ptr<DownloadQuery> query_;
int get_id_;
bool has_get_id_;
DISALLOW_COPY_AND_ASSIGN(DownloadsSearchFunction); DISALLOW_COPY_AND_ASSIGN(DownloadsSearchFunction);
}; };
class DownloadsPauseFunction : public SyncDownloadsFunction { class DownloadsPauseFunction : public SyncExtensionFunction {
public: public:
DECLARE_EXTENSION_FUNCTION_NAME("downloads.pause"); DECLARE_EXTENSION_FUNCTION_NAME("downloads.pause");
DownloadsPauseFunction(); DownloadsPauseFunction();
virtual bool RunImpl() OVERRIDE;
protected: protected:
virtual ~DownloadsPauseFunction(); virtual ~DownloadsPauseFunction();
// DownloadsFunctionInterface:
virtual bool ParseArgs() OVERRIDE;
virtual bool RunInternal() OVERRIDE;
private: private:
int download_id_;
DISALLOW_COPY_AND_ASSIGN(DownloadsPauseFunction); DISALLOW_COPY_AND_ASSIGN(DownloadsPauseFunction);
}; };
class DownloadsResumeFunction : public SyncDownloadsFunction { class DownloadsResumeFunction : public SyncExtensionFunction {
public: public:
DECLARE_EXTENSION_FUNCTION_NAME("downloads.resume"); DECLARE_EXTENSION_FUNCTION_NAME("downloads.resume");
DownloadsResumeFunction(); DownloadsResumeFunction();
virtual bool RunImpl() OVERRIDE;
protected: protected:
virtual ~DownloadsResumeFunction(); virtual ~DownloadsResumeFunction();
// DownloadsFunctionInterface:
virtual bool ParseArgs() OVERRIDE;
virtual bool RunInternal() OVERRIDE;
private: private:
int download_id_;
DISALLOW_COPY_AND_ASSIGN(DownloadsResumeFunction); DISALLOW_COPY_AND_ASSIGN(DownloadsResumeFunction);
}; };
class DownloadsCancelFunction : public SyncDownloadsFunction { class DownloadsCancelFunction : public SyncExtensionFunction {
public: public:
DECLARE_EXTENSION_FUNCTION_NAME("downloads.cancel"); DECLARE_EXTENSION_FUNCTION_NAME("downloads.cancel");
DownloadsCancelFunction(); DownloadsCancelFunction();
virtual bool RunImpl() OVERRIDE;
protected: protected:
virtual ~DownloadsCancelFunction(); virtual ~DownloadsCancelFunction();
// DownloadsFunctionInterface:
virtual bool ParseArgs() OVERRIDE;
virtual bool RunInternal() OVERRIDE;
private: private:
int download_id_;
DISALLOW_COPY_AND_ASSIGN(DownloadsCancelFunction); DISALLOW_COPY_AND_ASSIGN(DownloadsCancelFunction);
}; };
class DownloadsEraseFunction : public AsyncDownloadsFunction { class DownloadsEraseFunction : public AsyncExtensionFunction {
public: public:
DECLARE_EXTENSION_FUNCTION_NAME("downloads.erase"); DECLARE_EXTENSION_FUNCTION_NAME("downloads.erase");
DownloadsEraseFunction(); DownloadsEraseFunction();
virtual bool RunImpl() OVERRIDE;
protected: protected:
virtual ~DownloadsEraseFunction(); virtual ~DownloadsEraseFunction();
// DownloadsFunctionInterface:
virtual bool ParseArgs() OVERRIDE;
virtual bool RunInternal() OVERRIDE;
private: private:
DISALLOW_COPY_AND_ASSIGN(DownloadsEraseFunction); DISALLOW_COPY_AND_ASSIGN(DownloadsEraseFunction);
}; };
class DownloadsSetDestinationFunction : public AsyncDownloadsFunction { class DownloadsSetDestinationFunction : public AsyncExtensionFunction {
public: public:
DECLARE_EXTENSION_FUNCTION_NAME("downloads.setDestination"); DECLARE_EXTENSION_FUNCTION_NAME("downloads.setDestination");
DownloadsSetDestinationFunction(); DownloadsSetDestinationFunction();
virtual bool RunImpl() OVERRIDE;
protected: protected:
virtual ~DownloadsSetDestinationFunction(); virtual ~DownloadsSetDestinationFunction();
// DownloadsFunctionInterface:
virtual bool ParseArgs() OVERRIDE;
virtual bool RunInternal() OVERRIDE;
private: private:
DISALLOW_COPY_AND_ASSIGN(DownloadsSetDestinationFunction); DISALLOW_COPY_AND_ASSIGN(DownloadsSetDestinationFunction);
}; };
class DownloadsAcceptDangerFunction : public AsyncDownloadsFunction { class DownloadsAcceptDangerFunction : public AsyncExtensionFunction {
public: public:
DECLARE_EXTENSION_FUNCTION_NAME("downloads.acceptDanger"); DECLARE_EXTENSION_FUNCTION_NAME("downloads.acceptDanger");
DownloadsAcceptDangerFunction(); DownloadsAcceptDangerFunction();
virtual bool RunImpl() OVERRIDE;
protected: protected:
virtual ~DownloadsAcceptDangerFunction(); virtual ~DownloadsAcceptDangerFunction();
// DownloadsFunctionInterface:
virtual bool ParseArgs() OVERRIDE;
virtual bool RunInternal() OVERRIDE;
private: private:
DISALLOW_COPY_AND_ASSIGN(DownloadsAcceptDangerFunction); DISALLOW_COPY_AND_ASSIGN(DownloadsAcceptDangerFunction);
}; };
class DownloadsShowFunction : public AsyncDownloadsFunction { class DownloadsShowFunction : public AsyncExtensionFunction {
public: public:
DECLARE_EXTENSION_FUNCTION_NAME("downloads.show"); DECLARE_EXTENSION_FUNCTION_NAME("downloads.show");
DownloadsShowFunction(); DownloadsShowFunction();
virtual bool RunImpl() OVERRIDE;
protected: protected:
virtual ~DownloadsShowFunction(); virtual ~DownloadsShowFunction();
// DownloadsFunctionInterface:
virtual bool ParseArgs() OVERRIDE;
virtual bool RunInternal() OVERRIDE;
private: private:
DISALLOW_COPY_AND_ASSIGN(DownloadsShowFunction); DISALLOW_COPY_AND_ASSIGN(DownloadsShowFunction);
}; };
class DownloadsDragFunction : public AsyncDownloadsFunction { class DownloadsOpenFunction : public AsyncExtensionFunction {
public: public:
DECLARE_EXTENSION_FUNCTION_NAME("downloads.drag"); DECLARE_EXTENSION_FUNCTION_NAME("downloads.open");
DownloadsOpenFunction();
virtual bool RunImpl() OVERRIDE;
protected:
virtual ~DownloadsOpenFunction();
private:
DISALLOW_COPY_AND_ASSIGN(DownloadsOpenFunction);
};
class DownloadsDragFunction : public AsyncExtensionFunction {
public:
DECLARE_EXTENSION_FUNCTION_NAME("downloads.drag");
DownloadsDragFunction(); DownloadsDragFunction();
virtual bool RunImpl() OVERRIDE;
protected: protected:
virtual ~DownloadsDragFunction(); virtual ~DownloadsDragFunction();
// DownloadsFunctionInterface:
virtual bool ParseArgs() OVERRIDE;
virtual bool RunInternal() OVERRIDE;
private: private:
DISALLOW_COPY_AND_ASSIGN(DownloadsDragFunction); DISALLOW_COPY_AND_ASSIGN(DownloadsDragFunction);
}; };
class DownloadsGetFileIconFunction : public AsyncDownloadsFunction { class DownloadsGetFileIconFunction : public AsyncExtensionFunction {
public: public:
DECLARE_EXTENSION_FUNCTION_NAME("downloads.getFileIcon"); DECLARE_EXTENSION_FUNCTION_NAME("downloads.getFileIcon");
DownloadsGetFileIconFunction(); DownloadsGetFileIconFunction();
virtual bool RunImpl() OVERRIDE;
void SetIconExtractorForTesting(DownloadFileIconExtractor* extractor); void SetIconExtractorForTesting(DownloadFileIconExtractor* extractor);
protected: protected:
virtual ~DownloadsGetFileIconFunction(); virtual ~DownloadsGetFileIconFunction();
// DownloadsFunctionInterface:
virtual bool ParseArgs() OVERRIDE;
virtual bool RunInternal() OVERRIDE;
private: private:
void OnIconURLExtracted(const std::string& url); void OnIconURLExtracted(const std::string& url);
FilePath path_; FilePath path_;
......
...@@ -13,7 +13,6 @@ ...@@ -13,7 +13,6 @@
#include "chrome/browser/extensions/api/context_menu/context_menu_api.h" #include "chrome/browser/extensions/api/context_menu/context_menu_api.h"
#include "chrome/browser/extensions/api/cookies/cookies_api.h" #include "chrome/browser/extensions/api/cookies/cookies_api.h"
#include "chrome/browser/extensions/api/declarative/declarative_api.h" #include "chrome/browser/extensions/api/declarative/declarative_api.h"
#include "chrome/browser/extensions/api/downloads/downloads_api.h"
#include "chrome/browser/extensions/api/extension_action/extension_browser_actions_api.h" #include "chrome/browser/extensions/api/extension_action/extension_browser_actions_api.h"
#include "chrome/browser/extensions/api/extension_action/extension_page_actions_api.h" #include "chrome/browser/extensions/api/extension_action/extension_page_actions_api.h"
#include "chrome/browser/extensions/api/extension_action/extension_script_badge_api.h" #include "chrome/browser/extensions/api/extension_action/extension_script_badge_api.h"
...@@ -451,19 +450,6 @@ void ExtensionFunctionRegistry::ResetFunctions() { ...@@ -451,19 +450,6 @@ void ExtensionFunctionRegistry::ResetFunctions() {
RegisterFunction<RemovePermissionsFunction>(); RegisterFunction<RemovePermissionsFunction>();
RegisterFunction<RequestPermissionsFunction>(); RegisterFunction<RequestPermissionsFunction>();
// Downloads
RegisterFunction<DownloadsDownloadFunction>();
RegisterFunction<DownloadsSearchFunction>();
RegisterFunction<DownloadsPauseFunction>();
RegisterFunction<DownloadsResumeFunction>();
RegisterFunction<DownloadsCancelFunction>();
RegisterFunction<DownloadsEraseFunction>();
RegisterFunction<DownloadsSetDestinationFunction>();
RegisterFunction<DownloadsAcceptDangerFunction>();
RegisterFunction<DownloadsShowFunction>();
RegisterFunction<DownloadsDragFunction>();
RegisterFunction<DownloadsGetFileIconFunction>();
// PageCapture // PageCapture
RegisterFunction<PageCaptureSaveAsMHTMLFunction>(); RegisterFunction<PageCaptureSaveAsMHTMLFunction>();
......
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
'idl_schema_files': [ 'idl_schema_files': [
'alarms.idl', 'alarms.idl',
'app_window.idl', 'app_window.idl',
'downloads.idl',
'experimental_bluetooth.idl', 'experimental_bluetooth.idl',
'experimental_discovery.idl', 'experimental_discovery.idl',
'experimental_dns.idl', 'experimental_dns.idl',
......
This diff is collapsed.
This diff is collapsed.
...@@ -365,8 +365,6 @@ void ExtensionAPI::InitDefaultConfiguration() { ...@@ -365,8 +365,6 @@ void ExtensionAPI::InitDefaultConfiguration() {
IDR_EXTENSION_API_JSON_DECLARATIVE_WEBREQUEST)); IDR_EXTENSION_API_JSON_DECLARATIVE_WEBREQUEST));
RegisterSchema("devtools", ReadFromResource( RegisterSchema("devtools", ReadFromResource(
IDR_EXTENSION_API_JSON_DEVTOOLS)); IDR_EXTENSION_API_JSON_DEVTOOLS));
RegisterSchema("downloads", ReadFromResource(
IDR_EXTENSION_API_JSON_DOWNLOADS));
RegisterSchema("events", ReadFromResource( RegisterSchema("events", ReadFromResource(
IDR_EXTENSION_API_JSON_EVENTS)); IDR_EXTENSION_API_JSON_EVENTS));
RegisterSchema("experimental.accessibility", ReadFromResource( RegisterSchema("experimental.accessibility", ReadFromResource(
......
...@@ -83,13 +83,13 @@ def parse_idl_file(path): ...@@ -83,13 +83,13 @@ def parse_idl_file(path):
api_def = idl_schema.Load(path) api_def = idl_schema.Load(path)
for namespace_def in api_def: for namespace_def in api_def:
namespace_dot = namespace_def['namespace'] + '.' namespace_dot = namespace_def['namespace'] + '.'
types = dict((type_['id'], type_) inline_types = dict((type_['id'], type_)
for type_ in namespace_def.get('types', []) for type_ in namespace_def.get('types', [])
if type_) if type_ and type_.get('inline_doc', False))
def SubstituteInlineDoc(prop): def SubstituteInlineDoc(prop):
prop_ref_type = prop.get('$ref', '') prop_ref_type = prop.get('$ref', '')
type_obj = types.get(namespace_dot + prop_ref_type, type_obj = inline_types.get(namespace_dot + prop_ref_type,
types.get(prop_ref_type, {})) inline_types.get(prop_ref_type, {}))
if not type_obj: if not type_obj:
return return
if 'properties' in type_obj: if 'properties' in type_obj:
...@@ -113,8 +113,6 @@ def parse_idl_file(path): ...@@ -113,8 +113,6 @@ def parse_idl_file(path):
if (prop.get('type', '') == 'array' and if (prop.get('type', '') == 'array' and
prop.get('items', {}).get('$ref', '').startswith(namespace_dot)): prop.get('items', {}).get('$ref', '').startswith(namespace_dot)):
prop['items']['$ref'] = prop['items']['$ref'][len(namespace_dot):] prop['items']['$ref'] = prop['items']['$ref'][len(namespace_dot):]
if prop.get('inline_doc', False):
del prop['inline_doc']
SubstituteInlineDoc(prop) SubstituteInlineDoc(prop)
if 'items' in prop: if 'items' in prop:
SubstituteInlineDoc(prop['items']) SubstituteInlineDoc(prop['items'])
...@@ -124,6 +122,9 @@ def parse_idl_file(path): ...@@ -124,6 +122,9 @@ def parse_idl_file(path):
type_['id'] = type_['id'][len(namespace_dot):] type_['id'] = type_['id'][len(namespace_dot):]
for prop in type_.get('properties', {}).values(): for prop in type_.get('properties', {}).values():
FixReferences(prop) FixReferences(prop)
if type_.get('inline_doc', False):
del type_['inline_doc']
type_['nodoc'] = True
for func in namespace_def.get('functions', []): for func in namespace_def.get('functions', []):
for param in func.get('parameters', []): for param in func.get('parameters', []):
FixReferences(param) FixReferences(param)
......
...@@ -150,7 +150,6 @@ ...@@ -150,7 +150,6 @@
"chrome.experimental.discovery.clearAllSuggestions": "experimental.discovery.html#method-clearAllSuggestions", "chrome.experimental.discovery.clearAllSuggestions": "experimental.discovery.html#method-clearAllSuggestions",
"chrome.experimental.discovery.removeSuggestion": "experimental.discovery.html#method-removeSuggestion", "chrome.experimental.discovery.removeSuggestion": "experimental.discovery.html#method-removeSuggestion",
"chrome.experimental.discovery.suggest": "experimental.discovery.html#method-suggest", "chrome.experimental.discovery.suggest": "experimental.discovery.html#method-suggest",
"chrome.experimental.dns.resolve": "experimental.dns.html#method-resolve",
"chrome.experimental.fontSettings.clearDefaultFixedFontSize": "experimental.fontSettings.html#method-clearDefaultFixedFontSize", "chrome.experimental.fontSettings.clearDefaultFixedFontSize": "experimental.fontSettings.html#method-clearDefaultFixedFontSize",
"chrome.experimental.fontSettings.clearDefaultFontSize": "experimental.fontSettings.html#method-clearDefaultFontSize", "chrome.experimental.fontSettings.clearDefaultFontSize": "experimental.fontSettings.html#method-clearDefaultFontSize",
"chrome.experimental.fontSettings.clearFont": "experimental.fontSettings.html#method-clearFont", "chrome.experimental.fontSettings.clearFont": "experimental.fontSettings.html#method-clearFont",
...@@ -170,10 +169,6 @@ ...@@ -170,10 +169,6 @@
"chrome.experimental.fontSettings.setMinimumFontSize": "experimental.fontSettings.html#method-setMinimumFontSize", "chrome.experimental.fontSettings.setMinimumFontSize": "experimental.fontSettings.html#method-setMinimumFontSize",
"chrome.experimental.identity.getAuthToken": "experimental.identity.html#method-getAuthToken", "chrome.experimental.identity.getAuthToken": "experimental.identity.html#method-getAuthToken",
"chrome.experimental.identity.launchWebAuthFlow": "experimental.identity.html#method-launchWebAuthFlow", "chrome.experimental.identity.launchWebAuthFlow": "experimental.identity.html#method-launchWebAuthFlow",
"chrome.experimental.idltest.getArrayBuffer": "experimental.idltest.html#method-getArrayBuffer",
"chrome.experimental.idltest.nocompileFunc": "experimental.idltest.html#method-nocompileFunc",
"chrome.experimental.idltest.sendArrayBuffer": "experimental.idltest.html#method-sendArrayBuffer",
"chrome.experimental.idltest.sendArrayBufferView": "experimental.idltest.html#method-sendArrayBufferView",
"chrome.experimental.infobars.show": "experimental.infobars.html#method-show", "chrome.experimental.infobars.show": "experimental.infobars.html#method-show",
"chrome.experimental.keybinding.onCommand": "experimental.keybinding.html#event-onCommand", "chrome.experimental.keybinding.onCommand": "experimental.keybinding.html#event-onCommand",
"chrome.experimental.mediaGalleries.assembleMediaFile": "experimental.mediaGalleries.html#method-assembleMediaFile", "chrome.experimental.mediaGalleries.assembleMediaFile": "experimental.mediaGalleries.html#method-assembleMediaFile",
......
...@@ -26,7 +26,6 @@ ...@@ -26,7 +26,6 @@
<include name="IDR_EXTENSION_API_JSON_EXPERIMENTAL_ACCESSIBILITY" file="extensions\api\experimental_accessibility.json" type="BINDATA" /> <include name="IDR_EXTENSION_API_JSON_EXPERIMENTAL_ACCESSIBILITY" file="extensions\api\experimental_accessibility.json" type="BINDATA" />
<include name="IDR_EXTENSION_API_JSON_EXPERIMENTAL_APP" file="extensions\api\experimental_app.json" type="BINDATA" /> <include name="IDR_EXTENSION_API_JSON_EXPERIMENTAL_APP" file="extensions\api\experimental_app.json" type="BINDATA" />
<include name="IDR_EXTENSION_API_JSON_EXPERIMENTAL_BOOKMARKMANAGER" file="extensions\api\experimental_bookmark_manager.json" type="BINDATA" /> <include name="IDR_EXTENSION_API_JSON_EXPERIMENTAL_BOOKMARKMANAGER" file="extensions\api\experimental_bookmark_manager.json" type="BINDATA" />
<include name="IDR_EXTENSION_API_JSON_DOWNLOADS" file="extensions\api\downloads.json" type="BINDATA" />
<include name="IDR_EXTENSION_API_JSON_EXPERIMENTAL_FONTSSETTINGS" file="extensions\api\experimental_font_settings.json" type="BINDATA" /> <include name="IDR_EXTENSION_API_JSON_EXPERIMENTAL_FONTSSETTINGS" file="extensions\api\experimental_font_settings.json" type="BINDATA" />
<include name="IDR_EXTENSION_API_JSON_EXPERIMENTAL_IDENTITY" file="extensions\api\experimental_identity.json" type="BINDATA" /> <include name="IDR_EXTENSION_API_JSON_EXPERIMENTAL_IDENTITY" file="extensions\api\experimental_identity.json" type="BINDATA" />
<include name="IDR_EXTENSION_API_JSON_EXPERIMENTAL_INFOBARS" file="extensions\api\experimental_infobars.json" type="BINDATA" /> <include name="IDR_EXTENSION_API_JSON_EXPERIMENTAL_INFOBARS" file="extensions\api\experimental_infobars.json" type="BINDATA" />
......
...@@ -221,6 +221,15 @@ class IDLParser(IDLLexer): ...@@ -221,6 +221,15 @@ class IDLParser(IDLLexer):
p[0] = ListFromConcat(Copyright, Filedoc, p[3], p[4]) p[0] = ListFromConcat(Copyright, Filedoc, p[3], p[4])
if self.parse_debug: DumpReduction('top', p) if self.parse_debug: DumpReduction('top', p)
def p_top_short(self, p):
"""top : COMMENT ext_attr_block top_list"""
Copyright = self.BuildComment('Copyright', p, 1)
Filedoc = IDLNode('Comment', self.lexobj.filename, p.lineno(2)-1,
p.lexpos(2)-1, [self.BuildAttribute('NAME', ''),
self.BuildAttribute('FORM', 'cc')])
p[0] = ListFromConcat(Copyright, Filedoc, p[2], p[3])
if self.parse_debug: DumpReduction('top', p)
# Build a list of top level items. # Build a list of top level items.
def p_top_list(self, p): def p_top_list(self, p):
"""top_list : callback_decl top_list """top_list : callback_decl top_list
...@@ -289,11 +298,11 @@ class IDLParser(IDLLexer): ...@@ -289,11 +298,11 @@ class IDLParser(IDLLexer):
# #
# Dictionary # Dictionary
# #
# A dictionary contains is a named list of optional and required members. # A dictionary is a named list of optional and required members.
# #
def p_dictionary_block(self, p): def p_dictionary_block(self, p):
"""dictionary_block : modifiers DICTIONARY SYMBOL '{' struct_list '}' ';'""" """dictionary_block : modifiers DICTIONARY SYMBOL '{' struct_list '}' ';'"""
p[0] = self.BuildNamed('Dictionary', p, 3, ListFromConcat(p[5])) p[0] = self.BuildNamed('Dictionary', p, 3, ListFromConcat(p[1], p[5]))
# #
# Callback # Callback
...@@ -370,6 +379,29 @@ class IDLParser(IDLLexer): ...@@ -370,6 +379,29 @@ class IDLParser(IDLLexer):
p[0] = ListFromConcat(self.BuildAttribute(p[1], 'True'), p[2]) p[0] = ListFromConcat(self.BuildAttribute(p[1], 'True'), p[2])
if self.parse_debug: DumpReduction('ext_attribute_list', p) if self.parse_debug: DumpReduction('ext_attribute_list', p)
def p_ext_attr_list_values(self, p):
"""ext_attr_list : SYMBOL '=' '(' values ')' ext_attr_cont
| SYMBOL '=' '(' symbols ')' ext_attr_cont"""
p[0] = ListFromConcat(self.BuildAttribute(p[1], p[4]), p[6])
def p_values(self, p):
"""values : value values_cont"""
p[0] = ListFromConcat(p[1], p[2])
def p_symbols(self, p):
"""symbols : SYMBOL symbols_cont"""
p[0] = ListFromConcat(p[1], p[2])
def p_symbols_cont(self, p):
"""symbols_cont : ',' SYMBOL symbols_cont
| """
if len(p) > 1: p[0] = ListFromConcat(p[2], p[3])
def p_values_cont(self, p):
"""values_cont : ',' value values_cont
| """
if len(p) > 1: p[0] = ListFromConcat(p[2], p[3])
def p_ext_attr_cont(self, p): def p_ext_attr_cont(self, p):
"""ext_attr_cont : ',' ext_attr_list """ext_attr_cont : ',' ext_attr_list
|""" |"""
...@@ -555,7 +587,7 @@ class IDLParser(IDLLexer): ...@@ -555,7 +587,7 @@ class IDLParser(IDLLexer):
def p_param_item(self, p): def p_param_item(self, p):
"""param_item : modifiers optional SYMBOL arrays identifier""" """param_item : modifiers optional SYMBOL arrays identifier"""
typeref = self.BuildAttribute('TYPEREF', p[3]) typeref = self.BuildAttribute('TYPEREF', p[3])
children = ListFromConcat(p[1],p[2], typeref, p[4]) children = ListFromConcat(p[1], p[2], typeref, p[4])
p[0] = self.BuildNamed('Param', p, 5, children) p[0] = self.BuildNamed('Param', p, 5, children)
if self.parse_debug: DumpReduction('param_item', p) if self.parse_debug: DumpReduction('param_item', p)
......
This diff is collapsed.
...@@ -7,7 +7,6 @@ from model import PropertyType ...@@ -7,7 +7,6 @@ from model import PropertyType
import any_helper import any_helper
import cpp_util import cpp_util
import schema_util import schema_util
import string
class CppTypeGenerator(object): class CppTypeGenerator(object):
"""Manages the types of properties and provides utilities for getting the """Manages the types of properties and provides utilities for getting the
...@@ -191,8 +190,9 @@ class CppTypeGenerator(object): ...@@ -191,8 +190,9 @@ class CppTypeGenerator(object):
c.Append('typedef std::string %s;' % type_name) c.Append('typedef std::string %s;' % type_name)
elif namespace.types[type_].type_ == PropertyType.ARRAY: elif namespace.types[type_].type_ == PropertyType.ARRAY:
c.Append('typedef std::vector<%(item_type)s> %(name)s;') c.Append('typedef std::vector<%(item_type)s> %(name)s;')
c.Substitute({'name': type_name, 'item_type': c.Substitute({
self.GetType(namespace.types[type_].item_type, 'name': type_name,
'item_type': self.GetType(namespace.types[type_].item_type,
wrap_optional=True)}) wrap_optional=True)})
else: else:
c.Append('struct %s;' % type_name) c.Append('struct %s;' % type_name)
......
...@@ -59,12 +59,14 @@ class CppTypeGeneratorTest(unittest.TestCase): ...@@ -59,12 +59,14 @@ class CppTypeGeneratorTest(unittest.TestCase):
def testGenerateIncludesAndForwardDeclarationsMultipleTypes(self): def testGenerateIncludesAndForwardDeclarationsMultipleTypes(self):
m = model.Model() m = model.Model()
self.tabs_json[0]['types'].append(self.permissions_json[0]['types'][0]) self.tabs_json[0]['types'].append(self.permissions_json[0]['types'][0])
tabs_namespace = m.AddNamespace(self.tabs_json[0],
'path/to/tabs.json')
self.windows_json[0]['functions'].append( self.windows_json[0]['functions'].append(
self.permissions_json[0]['functions'][1]) self.permissions_json[0]['functions'][1])
# Insert 'windows' before 'tabs' in order to test that they are sorted
# properly.
windows = m.AddNamespace(self.windows_json[0], windows = m.AddNamespace(self.windows_json[0],
'path/to/windows.json') 'path/to/windows.json')
tabs_namespace = m.AddNamespace(self.tabs_json[0],
'path/to/tabs.json')
manager = CppTypeGenerator('', windows, self.windows.unix_name) manager = CppTypeGenerator('', windows, self.windows.unix_name)
manager.AddNamespace(tabs_namespace, self.tabs.unix_name) manager.AddNamespace(tabs_namespace, self.tabs.unix_name)
self.assertEquals('#include "path/to/tabs.h"', self.assertEquals('#include "path/to/tabs.h"',
...@@ -81,16 +83,18 @@ class CppTypeGeneratorTest(unittest.TestCase): ...@@ -81,16 +83,18 @@ class CppTypeGeneratorTest(unittest.TestCase):
def testGenerateIncludesAndForwardDeclarationsDependencies(self): def testGenerateIncludesAndForwardDeclarationsDependencies(self):
m = model.Model() m = model.Model()
browser_action_namespace = m.AddNamespace(self.browser_action_json[0], # Insert 'font_settings' before 'browser_action' in order to test that
'path/to/browser_action.json') # CppTypeGenerator sorts them properly.
font_settings_namespace = m.AddNamespace(self.font_settings_json[0], font_settings_namespace = m.AddNamespace(self.font_settings_json[0],
'path/to/font_settings.json') 'path/to/font_settings.json')
browser_action_namespace = m.AddNamespace(self.browser_action_json[0],
'path/to/browser_action.json')
manager = CppTypeGenerator('', self.dependency_tester, manager = CppTypeGenerator('', self.dependency_tester,
self.dependency_tester.unix_name) self.dependency_tester.unix_name)
manager.AddNamespace(browser_action_namespace,
self.browser_action.unix_name)
manager.AddNamespace(font_settings_namespace, manager.AddNamespace(font_settings_namespace,
self.font_settings.unix_name) self.font_settings.unix_name)
manager.AddNamespace(browser_action_namespace,
self.browser_action.unix_name)
self.assertEquals('#include "path/to/browser_action.h"\n' self.assertEquals('#include "path/to/browser_action.h"\n'
'#include "path/to/font_settings.h"', '#include "path/to/font_settings.h"',
manager.GenerateIncludes().Render()) manager.GenerateIncludes().Render())
......
...@@ -5,8 +5,6 @@ ...@@ -5,8 +5,6 @@
from code import Code from code import Code
from model import PropertyType from model import PropertyType
import cpp_util import cpp_util
import model
import os
import schema_util import schema_util
class HGenerator(object): class HGenerator(object):
...@@ -110,7 +108,8 @@ class HGenerator(object): ...@@ -110,7 +108,8 @@ class HGenerator(object):
raise ValueError("Illegal circular dependency via cycle " + raise ValueError("Illegal circular dependency via cycle " +
", ".join(map(lambda x: x.name, path + [type_]))) ", ".join(map(lambda x: x.name, path + [type_])))
for prop in type_.properties.values(): for prop in type_.properties.values():
if not prop.optional and prop.type_ == PropertyType.REF: if (prop.type_ == PropertyType.REF and
schema_util.GetNamespace(prop.ref_type) == self._namespace.name):
ExpandType(path + [type_], self._namespace.types[prop.ref_type]) ExpandType(path + [type_], self._namespace.types[prop.ref_type])
if not type_ in dependency_order: if not type_ in dependency_order:
dependency_order.append(type_) dependency_order.append(type_)
...@@ -177,7 +176,6 @@ class HGenerator(object): ...@@ -177,7 +176,6 @@ class HGenerator(object):
if type_.description: if type_.description:
c.Comment(type_.description) c.Comment(type_.description)
c.Append('typedef std::string %(classname)s;') c.Append('typedef std::string %(classname)s;')
c.Substitute({'classname': classname})
else: else:
if type_.description: if type_.description:
c.Comment(type_.description) c.Comment(type_.description)
...@@ -189,18 +187,18 @@ class HGenerator(object): ...@@ -189,18 +187,18 @@ class HGenerator(object):
.Concat(self._GenerateFields(type_.properties.values())) .Concat(self._GenerateFields(type_.properties.values()))
) )
if type_.from_json: if type_.from_json:
(c.Comment('Populates a %s object from a Value. Returns' (c.Comment('Populates a %s object from a base::Value. Returns'
' whether |out| was successfully populated.' % classname) ' whether |out| was successfully populated.' % classname)
.Append( .Append('static bool Populate(const base::Value& value, '
'static bool Populate(const Value& value, %(classname)s* out);') '%(classname)s* out);')
.Append() .Append()
) )
if type_.from_client: if type_.from_client:
(c.Comment('Returns a new DictionaryValue representing the' (c.Comment('Returns a new base::DictionaryValue representing the'
' serialized form of this %s object. Passes ' ' serialized form of this %s object. Passes '
'ownership to caller.' % classname) 'ownership to caller.' % classname)
.Append('scoped_ptr<DictionaryValue> ToValue() const;') .Append('scoped_ptr<base::DictionaryValue> ToValue() const;')
) )
(c.Eblock() (c.Eblock()
...@@ -238,7 +236,8 @@ class HGenerator(object): ...@@ -238,7 +236,8 @@ class HGenerator(object):
.Concat(self._GenerateFields(function.params)) .Concat(self._GenerateFields(function.params))
.Append('~Params();') .Append('~Params();')
.Append() .Append()
.Append('static scoped_ptr<Params> Create(const ListValue& args);') .Append('static scoped_ptr<Params> Create('
'const base::ListValue& args);')
.Eblock() .Eblock()
.Sblock(' private:') .Sblock(' private:')
.Append('Params();') .Append('Params();')
...@@ -273,7 +272,7 @@ class HGenerator(object): ...@@ -273,7 +272,7 @@ class HGenerator(object):
enum_name, enum_name,
prop, prop,
prop.enum_values)) prop.enum_values))
c.Append('static scoped_ptr<Value> CreateEnumValue(%s %s);' % c.Append('static scoped_ptr<base::Value> CreateEnumValue(%s %s);' %
(enum_name, prop.unix_name)) (enum_name, prop.unix_name))
return c return c
...@@ -285,7 +284,7 @@ class HGenerator(object): ...@@ -285,7 +284,7 @@ class HGenerator(object):
c.Sblock('namespace Result {') c.Sblock('namespace Result {')
params = function.callback.params params = function.callback.params
if not params: if not params:
c.Append('Value* Create();') c.Append('base::Value* Create();')
else: else:
c.Concat(self._GeneratePropertyStructures(params)) c.Concat(self._GeneratePropertyStructures(params))
...@@ -297,10 +296,11 @@ class HGenerator(object): ...@@ -297,10 +296,11 @@ class HGenerator(object):
if param.description: if param.description:
c.Comment(param.description) c.Comment(param.description)
if param.type_ == PropertyType.ANY: if param.type_ == PropertyType.ANY:
c.Comment("Value* Result::Create(Value*) not generated " c.Comment("base::Value* Result::Create(base::Value*) not generated "
"because it's redundant.") "because it's redundant.")
continue continue
c.Append('Value* Create(const %s);' % cpp_util.GetParameterDeclaration( c.Append('base::Value* Create(const %s);' %
cpp_util.GetParameterDeclaration(
param, self._cpp_type_generator.GetType(param))) param, self._cpp_type_generator.GetType(param)))
c.Eblock('};') c.Eblock('};')
......
...@@ -55,7 +55,7 @@ def ProcessComment(comment): ...@@ -55,7 +55,7 @@ def ProcessComment(comment):
# Escape double quotes. # Escape double quotes.
comment = comment.replace('"', '\\"'); comment = comment.replace('"', '\\"');
# Find all the parameter comments of the form "|name|: comment". # Find all the parameter comments of the form '|name|: comment'.
parameter_starts = list(re.finditer(r'\n *\|([^|]*)\| *: *', comment)) parameter_starts = list(re.finditer(r'\n *\|([^|]*)\| *: *', comment))
# Get the parent comment (everything before the first parameter comment. # Get the parent comment (everything before the first parameter comment.
...@@ -104,9 +104,9 @@ class Param(object): ...@@ -104,9 +104,9 @@ class Param(object):
self.node = param_node self.node = param_node
def process(self, callbacks): def process(self, callbacks):
return Typeref(self.node.GetProperty( 'TYPEREF'), return Typeref(self.node.GetProperty('TYPEREF'),
self.node, self.node,
{ 'name': self.node.GetName() }).process(callbacks) {'name': self.node.GetName()}).process(callbacks)
class Dictionary(object): class Dictionary(object):
''' '''
...@@ -122,30 +122,12 @@ class Dictionary(object): ...@@ -122,30 +122,12 @@ class Dictionary(object):
if node.cls == 'Member': if node.cls == 'Member':
k, v = Member(node).process(callbacks) k, v = Member(node).process(callbacks)
properties[k] = v properties[k] = v
return { 'id': self.node.GetName(), result = {'id': self.node.GetName(),
'properties': properties, 'properties': properties,
'type': 'object' } 'type': 'object'}
if self.node.GetProperty('inline_doc'):
class Enum(object): result['inline_doc'] = True
''' return result
Given an IDL Enum node, converts into a Python dictionary that the JSON
schema compiler expects to see.
'''
def __init__(self, enum_node):
self.node = enum_node
def process(self, callbacks):
enum = []
for node in self.node.children:
if node.cls == 'EnumItem':
name = node.GetName()
enum.append(name)
else:
sys.exit("Did not process %s %s" % (node.cls, node))
return { "id" : self.node.GetName(),
'enum': enum,
'type': 'string' }
class Member(object): class Member(object):
...@@ -169,8 +151,7 @@ class Member(object): ...@@ -169,8 +151,7 @@ class Member(object):
if node.cls == 'Comment': if node.cls == 'Comment':
(parent_comment, parameter_comments) = ProcessComment(node.GetName()) (parent_comment, parameter_comments) = ProcessComment(node.GetName())
properties['description'] = parent_comment properties['description'] = parent_comment
for node in self.node.children: elif node.cls == 'Callspec':
if node.cls == 'Callspec':
is_function = True is_function = True
name, parameters = Callspec(node, parameter_comments).process(callbacks) name, parameters = Callspec(node, parameter_comments).process(callbacks)
properties['parameters'] = parameters properties['parameters'] = parameters
...@@ -180,6 +161,13 @@ class Member(object): ...@@ -180,6 +161,13 @@ class Member(object):
else: else:
properties = Typeref(self.node.GetProperty('TYPEREF'), properties = Typeref(self.node.GetProperty('TYPEREF'),
self.node, properties).process(callbacks) self.node, properties).process(callbacks)
enum_values = self.node.GetProperty('legalValues')
if enum_values:
if properties['type'] == 'integer':
enum_values = map(int, enum_values)
elif properties['type'] == 'double':
enum_values = map(float, enum_values)
properties['enum'] = enum_values
return name, properties return name, properties
class Typeref(object): class Typeref(object):
...@@ -240,42 +228,70 @@ class Typeref(object): ...@@ -240,42 +228,70 @@ class Typeref(object):
return result return result
class Enum(object):
'''
Given an IDL Enum node, converts into a Python dictionary that the JSON
schema compiler expects to see.
'''
def __init__(self, enum_node):
self.node = enum_node
self.description = ''
def process(self, callbacks):
enum = []
for node in self.node.children:
if node.cls == 'EnumItem':
enum.append(node.GetName())
elif node.cls == 'Comment':
self.description = ProcessComment(node.GetName())[0]
else:
sys.exit('Did not process %s %s' % (node.cls, node))
result = {'id' : self.node.GetName(),
'description': self.description,
'type': 'string',
'enum': enum}
if self.node.GetProperty('inline_doc'):
result['inline_doc'] = True
return result
class Namespace(object): class Namespace(object):
''' '''
Given an IDLNode representing an IDL namespace, converts into a Python Given an IDLNode representing an IDL namespace, converts into a Python
dictionary that the JSON schema compiler expects to see. dictionary that the JSON schema compiler expects to see.
''' '''
def __init__(self, namespace_node, nodoc=False): def __init__(self, namespace_node, nodoc=False, permissions=None):
self.namespace = namespace_node self.namespace = namespace_node
self.nodoc = nodoc self.nodoc = nodoc
self.events = [] self.events = []
self.functions = [] self.functions = []
self.types = [] self.types = []
self.callbacks = {} self.callbacks = {}
self.permissions = permissions or []
def process(self): def process(self):
for node in self.namespace.children: for node in self.namespace.children:
cls = node.cls if node.cls == 'Dictionary':
if cls == "Dictionary":
self.types.append(Dictionary(node).process(self.callbacks)) self.types.append(Dictionary(node).process(self.callbacks))
elif cls == "Callback": elif node.cls == 'Callback':
k, v = Member(node).process(self.callbacks) k, v = Member(node).process(self.callbacks)
self.callbacks[k] = v self.callbacks[k] = v
elif cls == "Interface" and node.GetName() == "Functions": elif node.cls == 'Interface' and node.GetName() == 'Functions':
self.functions = self.process_interface(node) self.functions = self.process_interface(node)
elif cls == "Interface" and node.GetName() == "Events": elif node.cls == 'Interface' and node.GetName() == 'Events':
self.events = self.process_interface(node) self.events = self.process_interface(node)
elif cls == "Enum": elif node.cls == 'Enum':
self.types.append(Enum(node).process(self.callbacks)) self.types.append(Enum(node).process(self.callbacks))
else: else:
sys.exit("Did not process %s %s" % (node.cls, node)) sys.exit('Did not process %s %s' % (node.cls, node))
return {'namespace': self.namespace.GetName(),
return { 'events': self.events, 'nodoc': self.nodoc,
'functions': self.functions, 'documentation_permissions_required': self.permissions,
'types': self.types, 'types': self.types,
'namespace': self.namespace.GetName(), 'functions': self.functions,
'nodoc': self.nodoc } 'events': self.events}
def process_interface(self, node): def process_interface(self, node):
members = [] members = []
...@@ -296,23 +312,25 @@ class IDLSchema(object): ...@@ -296,23 +312,25 @@ class IDLSchema(object):
def process(self): def process(self):
namespaces = [] namespaces = []
for node in self.idl:
nodoc = False nodoc = False
cls = node.cls permissions = None
if cls == 'Namespace': for node in self.idl:
namespace = Namespace(node, nodoc) if node.cls == 'Namespace':
namespace = Namespace(node, nodoc, permissions)
namespaces.append(namespace.process()) namespaces.append(namespace.process())
elif cls == 'Copyright': elif node.cls == 'Copyright':
continue continue
elif cls == 'Comment': elif node.cls == 'Comment':
continue continue
elif cls == 'ExtAttribute': elif node.cls == 'ExtAttribute':
if node.name == 'nodoc': if node.name == 'nodoc':
nodoc = bool(node.value) nodoc = bool(node.value)
elif node.name == 'permissions':
permission = node.value.split(',')
else: else:
continue continue
else: else:
sys.exit("Did not process %s %s" % (node.cls, node)) sys.exit('Did not process %s %s' % (node.cls, node))
schema_util.PrefixSchemasWithNamespace(namespaces) schema_util.PrefixSchemasWithNamespace(namespaces)
return namespaces return namespaces
......
...@@ -56,11 +56,18 @@ class IdlSchemaTest(unittest.TestCase): ...@@ -56,11 +56,18 @@ class IdlSchemaTest(unittest.TestCase):
'parameters':[{'type':'integer', 'name':'x'}]}}] 'parameters':[{'type':'integer', 'name':'x'}]}}]
self.assertEquals(expected, getParams(schema, 'whatever')) self.assertEquals(expected, getParams(schema, 'whatever'))
def testLegalValues(self):
self.assertEquals({
'x': {'name': 'x', 'type': 'integer', 'enum': [1,2],
'description': 'This comment tests \\\"double-quotes\\\".'},
'y': {'name': 'y', 'type': 'string'}},
getType(self.idl_basics, 'idl_basics.MyType1')['properties'])
def testEnum(self): def testEnum(self):
schema = self.idl_basics schema = self.idl_basics
expected = {'enum': ['name1', 'name2'], expected = {'enum': ['name1', 'name2'], 'description': 'Enum description',
'type': 'string', 'id': 'idl_basics.EnumType'} 'type': 'string', 'id': 'idl_basics.EnumType'}
self.assertEquals(expected, getType(schema, 'idl_basics.EnumType')) self.assertEquals(expected, getType(schema, expected['id']))
expected = [{'name':'type', '$ref':'idl_basics.EnumType'}, expected = [{'name':'type', '$ref':'idl_basics.EnumType'},
{'type':'function', 'name':'Callback5', {'type':'function', 'name':'Callback5',
......
...@@ -193,7 +193,9 @@ class Property(object): ...@@ -193,7 +193,9 @@ class Property(object):
elif '$ref' in json: elif '$ref' in json:
self.ref_type = json['$ref'] self.ref_type = json['$ref']
self.type_ = PropertyType.REF self.type_ = PropertyType.REF
elif 'enum' in json: elif 'enum' in json and json.get('type') == 'string':
# Non-string enums (as in the case of [legalValues=(1,2)]) should fall
# through to the next elif.
self.enum_values = [] self.enum_values = []
for value in json['enum']: for value in json['enum']:
self.enum_values.append(value) self.enum_values.append(value)
......
...@@ -4,6 +4,10 @@ ...@@ -4,6 +4,10 @@
"""Utilies for the processing of schema python structures. """Utilies for the processing of schema python structures.
""" """
def GetNamespace(ref_type):
if '.' in ref_type:
return ref_type[:ref_type.rindex('.')]
def StripSchemaNamespace(s): def StripSchemaNamespace(s):
last_dot = s.rfind('.') last_dot = s.rfind('.')
if not last_dot == -1: if not last_dot == -1:
......
...@@ -5,13 +5,15 @@ ...@@ -5,13 +5,15 @@
// Tests a variety of basic API definition features. // Tests a variety of basic API definition features.
namespace idl_basics { namespace idl_basics {
// Enum description
enum EnumType { enum EnumType {
name1, name1,
name2 name2
}; };
dictionary MyType1 { dictionary MyType1 {
long x; // This comment tests "double-quotes". // This comment tests "double-quotes".
[legalValues=(1,2)] long x;
DOMString y; DOMString y;
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment