diff options
23 files changed, 221 insertions, 141 deletions
diff --git a/chrome/browser/extensions/api/app_window/app_window_apitest.cc b/chrome/browser/extensions/api/app_window/app_window_apitest.cc index 7701a5c..69ebde6 100644 --- a/chrome/browser/extensions/api/app_window/app_window_apitest.cc +++ b/chrome/browser/extensions/api/app_window/app_window_apitest.cc @@ -142,4 +142,9 @@ IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest, WindowsApiAlwaysOnTop) { << message_; } +IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest, WindowsApiGet) { + EXPECT_TRUE(RunPlatformAppTest("platform_apps/windows_api_get")) + << message_; +} + } // namespace extensions diff --git a/chrome/chrome_renderer.gypi b/chrome/chrome_renderer.gypi index aca68e0..ae6c3c1 100644 --- a/chrome/chrome_renderer.gypi +++ b/chrome/chrome_renderer.gypi @@ -92,8 +92,6 @@ 'renderer/extensions/dom_activity_logger.h', 'renderer/extensions/event_bindings.cc', 'renderer/extensions/event_bindings.h', - 'renderer/extensions/extension_custom_bindings.cc', - 'renderer/extensions/extension_custom_bindings.h', 'renderer/extensions/extension_groups.h', 'renderer/extensions/extension_helper.cc', 'renderer/extensions/extension_helper.h', @@ -434,7 +432,6 @@ 'renderer/extensions/chrome_v8_extension.cc', 'renderer/extensions/chrome_v8_extension_handler.cc', 'renderer/extensions/context_menus_custom_bindings.cc', - 'renderer/extensions/extension_custom_bindings.cc', 'renderer/extensions/file_browser_handler_custom_bindings.cc', 'renderer/extensions/page_actions_custom_bindings.cc', 'renderer/extensions/render_view_observer_natives.cc', diff --git a/chrome/common/extensions/api/app_window.idl b/chrome/common/extensions/api/app_window.idl index e2ccc39..bd307e8 100644 --- a/chrome/common/extensions/api/app_window.idl +++ b/chrome/common/extensions/api/app_window.idl @@ -222,6 +222,9 @@ namespace app.window { // The JavaScript 'window' object for the created child. [instanceOf=Window] object contentWindow; + + // The id the window was created with. + DOMString id; }; interface Functions { @@ -253,6 +256,13 @@ namespace app.window { // otherWindow.chrome.app.window.current(). [nocompile] static AppWindow current(); [nocompile, nodoc] static void initializeAppWindow(object state); + + // Gets an array of all currently created app windows. + [nocompile] static AppWindow[] getAll(); + + // Gets an $ref:AppWindow with the given id. If no window with the given id + // exists null is returned. + [nocompile] static AppWindow get(DOMString id); }; interface Events { diff --git a/chrome/renderer/extensions/dispatcher.cc b/chrome/renderer/extensions/dispatcher.cc index 404bb42..ea5ca21 100644 --- a/chrome/renderer/extensions/dispatcher.cc +++ b/chrome/renderer/extensions/dispatcher.cc @@ -41,7 +41,6 @@ #include "chrome/renderer/extensions/document_custom_bindings.h" #include "chrome/renderer/extensions/dom_activity_logger.h" #include "chrome/renderer/extensions/event_bindings.h" -#include "chrome/renderer/extensions/extension_custom_bindings.h" #include "chrome/renderer/extensions/extension_groups.h" #include "chrome/renderer/extensions/extension_helper.h" #include "chrome/renderer/extensions/feedback_private_custom_bindings.h" @@ -905,9 +904,6 @@ void Dispatcher::RegisterNativeHandlers(ModuleSystem* module_system, module_system->RegisterNativeHandler("document_natives", scoped_ptr<NativeHandler>( new DocumentCustomBindings(this, context))); - module_system->RegisterNativeHandler("extension", - scoped_ptr<NativeHandler>( - new ExtensionCustomBindings(this, context))); module_system->RegisterNativeHandler("sync_file_system", scoped_ptr<NativeHandler>( new SyncFileSystemCustomBindings(this, context))); diff --git a/chrome/renderer/extensions/extension_custom_bindings.cc b/chrome/renderer/extensions/extension_custom_bindings.cc deleted file mode 100644 index 743c900..0000000 --- a/chrome/renderer/extensions/extension_custom_bindings.cc +++ /dev/null @@ -1,95 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/renderer/extensions/extension_custom_bindings.h" - -#include <string> - -#include "base/bind.h" -#include "base/strings/string_util.h" -#include "chrome/common/extensions/extension.h" -#include "chrome/common/url_constants.h" -#include "chrome/renderer/extensions/dispatcher.h" -#include "chrome/renderer/extensions/extension_helper.h" -#include "content/public/renderer/render_view.h" -#include "content/public/renderer/v8_value_converter.h" -#include "extensions/common/view_type.h" -#include "grit/renderer_resources.h" -#include "third_party/WebKit/public/web/WebFrame.h" -#include "third_party/WebKit/public/web/WebView.h" -#include "v8/include/v8.h" - -namespace extensions { - -namespace { - -} // namespace - -ExtensionCustomBindings::ExtensionCustomBindings(Dispatcher* dispatcher, - ChromeV8Context* context) - : ChromeV8Extension(dispatcher, context) { - RouteFunction("GetExtensionViews", - base::Bind(&ExtensionCustomBindings::GetExtensionViews, - base::Unretained(this))); -} - -void ExtensionCustomBindings::GetExtensionViews( - const v8::FunctionCallbackInfo<v8::Value>& args) { - if (args.Length() != 2) - return; - - if (!args[0]->IsInt32() || !args[1]->IsString()) - return; - - // |browser_window_id| == extension_misc::kUnknownWindowId means getting - // views attached to any browser window. - int browser_window_id = args[0]->Int32Value(); - - std::string view_type_string = *v8::String::Utf8Value(args[1]->ToString()); - StringToUpperASCII(&view_type_string); - // |view_type| == VIEW_TYPE_INVALID means getting any type of - // views. - ViewType view_type = VIEW_TYPE_INVALID; - if (view_type_string == kViewTypeBackgroundPage) { - view_type = VIEW_TYPE_EXTENSION_BACKGROUND_PAGE; - } else if (view_type_string == kViewTypeInfobar) { - view_type = VIEW_TYPE_EXTENSION_INFOBAR; - } else if (view_type_string == kViewTypeNotification) { - view_type = VIEW_TYPE_NOTIFICATION; - } else if (view_type_string == kViewTypeTabContents) { - view_type = VIEW_TYPE_TAB_CONTENTS; - } else if (view_type_string == kViewTypePopup) { - view_type = VIEW_TYPE_EXTENSION_POPUP; - } else if (view_type_string == kViewTypeExtensionDialog) { - view_type = VIEW_TYPE_EXTENSION_DIALOG; - } else if (view_type_string == kViewTypeAppShell) { - view_type = VIEW_TYPE_APP_SHELL; - } else if (view_type_string == kViewTypePanel) { - view_type = VIEW_TYPE_PANEL; - } else if (view_type_string != kViewTypeAll) { - return; - } - - const Extension* extension = GetExtensionForRenderView(); - if (!extension) - return; - - std::vector<content::RenderView*> views = ExtensionHelper::GetExtensionViews( - extension->id(), browser_window_id, view_type); - v8::Local<v8::Array> v8_views = v8::Array::New(); - int v8_index = 0; - for (size_t i = 0; i < views.size(); ++i) { - v8::Local<v8::Context> context = - views[i]->GetWebView()->mainFrame()->mainWorldScriptContext(); - if (!context.IsEmpty()) { - v8::Local<v8::Value> window = context->Global(); - DCHECK(!window.IsEmpty()); - v8_views->Set(v8::Integer::New(v8_index++), window); - } - } - - args.GetReturnValue().Set(v8_views); -} - -} // namespace extensions diff --git a/chrome/renderer/extensions/extension_custom_bindings.h b/chrome/renderer/extensions/extension_custom_bindings.h deleted file mode 100644 index 9889d35..0000000 --- a/chrome/renderer/extensions/extension_custom_bindings.h +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_RENDERER_EXTENSIONS_EXTENSION_CUSTOM_BINDINGS_H_ -#define CHROME_RENDERER_EXTENSIONS_EXTENSION_CUSTOM_BINDINGS_H_ - -#include "chrome/renderer/extensions/chrome_v8_extension.h" - -namespace extensions { -class Dispatcher; - -// Implements custom bindings for the extension API. -class ExtensionCustomBindings : public ChromeV8Extension { - public: - explicit ExtensionCustomBindings(Dispatcher* dispatcher, - ChromeV8Context* context); - - private: - void GetExtensionViews(const v8::FunctionCallbackInfo<v8::Value>& args); -}; - -} // namespace extensions - -#endif // CHROME_RENDERER_EXTENSIONS_EXTENSION_CUSTOM_BINDINGS_H_ diff --git a/chrome/renderer/extensions/runtime_custom_bindings.cc b/chrome/renderer/extensions/runtime_custom_bindings.cc index e10423a..fba7355 100644 --- a/chrome/renderer/extensions/runtime_custom_bindings.cc +++ b/chrome/renderer/extensions/runtime_custom_bindings.cc @@ -12,6 +12,7 @@ #include "chrome/renderer/extensions/api_activity_logger.h" #include "chrome/renderer/extensions/chrome_v8_context.h" #include "chrome/renderer/extensions/dispatcher.h" +#include "chrome/renderer/extensions/extension_helper.h" #include "content/public/renderer/render_view.h" #include "content/public/renderer/v8_value_converter.h" #include "extensions/common/features/feature.h" @@ -37,6 +38,9 @@ RuntimeCustomBindings::RuntimeCustomBindings(Dispatcher* dispatcher, RouteFunction("OpenChannelToNativeApp", base::Bind(&RuntimeCustomBindings::OpenChannelToNativeApp, base::Unretained(this))); + RouteFunction("GetExtensionViews", + base::Bind(&RuntimeCustomBindings::GetExtensionViews, + base::Unretained(this))); } RuntimeCustomBindings::~RuntimeCustomBindings() {} @@ -112,4 +116,62 @@ void RuntimeCustomBindings::GetManifest( context()->v8_context())); } +void RuntimeCustomBindings::GetExtensionViews( + const v8::FunctionCallbackInfo<v8::Value>& args) { + if (args.Length() != 2) + return; + + if (!args[0]->IsInt32() || !args[1]->IsString()) + return; + + // |browser_window_id| == extension_misc::kUnknownWindowId means getting + // all views for the current extension. + int browser_window_id = args[0]->Int32Value(); + + std::string view_type_string = *v8::String::Utf8Value(args[1]->ToString()); + StringToUpperASCII(&view_type_string); + // |view_type| == VIEW_TYPE_INVALID means getting any type of + // views. + ViewType view_type = VIEW_TYPE_INVALID; + if (view_type_string == kViewTypeBackgroundPage) { + view_type = VIEW_TYPE_EXTENSION_BACKGROUND_PAGE; + } else if (view_type_string == kViewTypeInfobar) { + view_type = VIEW_TYPE_EXTENSION_INFOBAR; + } else if (view_type_string == kViewTypeNotification) { + view_type = VIEW_TYPE_NOTIFICATION; + } else if (view_type_string == kViewTypeTabContents) { + view_type = VIEW_TYPE_TAB_CONTENTS; + } else if (view_type_string == kViewTypePopup) { + view_type = VIEW_TYPE_EXTENSION_POPUP; + } else if (view_type_string == kViewTypeExtensionDialog) { + view_type = VIEW_TYPE_EXTENSION_DIALOG; + } else if (view_type_string == kViewTypeAppShell) { + view_type = VIEW_TYPE_APP_SHELL; + } else if (view_type_string == kViewTypePanel) { + view_type = VIEW_TYPE_PANEL; + } else if (view_type_string != kViewTypeAll) { + return; + } + + std::string extension_id = context()->GetExtensionID(); + if (extension_id.empty()) + return; + + std::vector<content::RenderView*> views = ExtensionHelper::GetExtensionViews( + extension_id, browser_window_id, view_type); + v8::Local<v8::Array> v8_views = v8::Array::New(); + int v8_index = 0; + for (size_t i = 0; i < views.size(); ++i) { + v8::Local<v8::Context> context = + views[i]->GetWebView()->mainFrame()->mainWorldScriptContext(); + if (!context.IsEmpty()) { + v8::Local<v8::Value> window = context->Global(); + DCHECK(!window.IsEmpty()); + v8_views->Set(v8::Integer::New(v8_index++), window); + } + } + + args.GetReturnValue().Set(v8_views); +} + } // namespace extensions diff --git a/chrome/renderer/extensions/runtime_custom_bindings.h b/chrome/renderer/extensions/runtime_custom_bindings.h index c1c2dac..3200eb5 100644 --- a/chrome/renderer/extensions/runtime_custom_bindings.h +++ b/chrome/renderer/extensions/runtime_custom_bindings.h @@ -29,6 +29,7 @@ class RuntimeCustomBindings : public ChromeV8Extension { private: void GetManifest(const v8::FunctionCallbackInfo<v8::Value>& args); + void GetExtensionViews(const v8::FunctionCallbackInfo<v8::Value>& args); }; } // namespace extensions diff --git a/chrome/renderer/extensions/safe_builtins.cc b/chrome/renderer/extensions/safe_builtins.cc index 010eb64..de2352f 100644 --- a/chrome/renderer/extensions/safe_builtins.cc +++ b/chrome/renderer/extensions/safe_builtins.cc @@ -70,7 +70,8 @@ const char kScript[] = "saveBuiltin(Function,\n" " ['apply', 'bind', 'call']);\n" "saveBuiltin(Array,\n" - " ['concat', 'forEach', 'join', 'push', 'slice', 'splice']);\n" + " ['concat', 'forEach', 'join', 'push', 'slice', 'splice',\n" + " 'map', 'filter']);\n" "saveBuiltin(String,\n" " ['slice', 'split']);\n" "saveBuiltin(RegExp,\n" diff --git a/chrome/renderer/resources/extensions/app_window_custom_bindings.js b/chrome/renderer/resources/extensions/app_window_custom_bindings.js index a060f11..f80970b 100644 --- a/chrome/renderer/resources/extensions/app_window_custom_bindings.js +++ b/chrome/renderer/resources/extensions/app_window_custom_bindings.js @@ -5,6 +5,7 @@ // Custom binding for the app_window API. var appWindowNatives = requireNative('app_window_natives'); +var runtimeNatives = requireNative('runtime'); var Binding = require('binding').Binding; var Event = require('event_bindings').Event; var forEach = require('utils').forEach; @@ -82,6 +83,20 @@ appWindow.registerCustomHook(function(bindingsAPI) { return currentAppWindow; }); + apiFunctions.setHandleRequest('getAll', function() { + var views = runtimeNatives.GetExtensionViews(-1, 'SHELL'); + return $Array.map(views, function(win) { + return win.chrome.app.window.current(); + }); + }); + + apiFunctions.setHandleRequest('get', function(id) { + var windows = $Array.filter(chrome.app.window.getAll(), function(win) { + return win.id == id; + }); + return windows.length > 0 ? windows[0] : null; + }); + // This is an internal function, but needs to be bound with setHandleRequest // because it is called from a different JS context. apiFunctions.setHandleRequest('initializeAppWindow', function(params) { diff --git a/chrome/renderer/resources/extensions/browser_action_custom_bindings.js b/chrome/renderer/resources/extensions/browser_action_custom_bindings.js index 9bec48b..60ac0c3 100644 --- a/chrome/renderer/resources/extensions/browser_action_custom_bindings.js +++ b/chrome/renderer/resources/extensions/browser_action_custom_bindings.js @@ -7,7 +7,7 @@ var binding = require('binding').Binding.create('browserAction'); var setIcon = require('setIcon').setIcon; -var getExtensionViews = requireNative('extension').GetExtensionViews; +var getExtensionViews = requireNative('runtime').GetExtensionViews; binding.registerCustomHook(function(bindingsAPI) { var apiFunctions = bindingsAPI.apiFunctions; diff --git a/chrome/renderer/resources/extensions/extension_custom_bindings.js b/chrome/renderer/resources/extensions/extension_custom_bindings.js index 08991485..b28fabd 100644 --- a/chrome/renderer/resources/extensions/extension_custom_bindings.js +++ b/chrome/renderer/resources/extensions/extension_custom_bindings.js @@ -6,10 +6,9 @@ var binding = require('binding').Binding.create('extension'); -var extensionNatives = requireNative('extension'); -var GetExtensionViews = extensionNatives.GetExtensionViews; var messaging = require('messaging'); var runtimeNatives = requireNative('runtime'); +var GetExtensionViews = runtimeNatives.GetExtensionViews; var OpenChannelToExtension = runtimeNatives.OpenChannelToExtension; var OpenChannelToNativeApp = runtimeNatives.OpenChannelToNativeApp; var chrome = requireNative('chrome').GetChrome(); diff --git a/chrome/renderer/resources/extensions/file_system_custom_bindings.js b/chrome/renderer/resources/extensions/file_system_custom_bindings.js index 6fdf89d..edd4b33 100644 --- a/chrome/renderer/resources/extensions/file_system_custom_bindings.js +++ b/chrome/renderer/resources/extensions/file_system_custom_bindings.js @@ -12,7 +12,7 @@ var lastError = require('lastError'); var sendRequest = require('sendRequest').sendRequest; var GetModuleSystem = requireNative('v8_context').GetModuleSystem; // TODO(sammc): Don't require extension. See http://crbug.com/235689. -var GetExtensionViews = requireNative('extension').GetExtensionViews; +var GetExtensionViews = requireNative('runtime').GetExtensionViews; // Fallback to using the current window if no background page is running. var backgroundPage = GetExtensionViews(-1, 'BACKGROUND')[0] || window; diff --git a/chrome/renderer/resources/extensions/runtime_custom_bindings.js b/chrome/renderer/resources/extensions/runtime_custom_bindings.js index ae1fa95..add47cc 100644 --- a/chrome/renderer/resources/extensions/runtime_custom_bindings.js +++ b/chrome/renderer/resources/extensions/runtime_custom_bindings.js @@ -6,7 +6,6 @@ var binding = require('binding').Binding.create('runtime'); -var extensionNatives = requireNative('extension'); var messaging = require('messaging'); var runtimeNatives = requireNative('runtime'); var unloadEvent = require('unload_event'); @@ -22,7 +21,7 @@ if (contextType == 'BLESSED_EXTENSION' || if (manifest.app && manifest.app.background) { // Get the background page if one exists. Otherwise, default to the current // window. - backgroundPage = extensionNatives.GetExtensionViews(-1, 'BACKGROUND')[0]; + backgroundPage = runtimeNatives.GetExtensionViews(-1, 'BACKGROUND')[0]; if (backgroundPage) { var GetModuleSystem = requireNative('v8_context').GetModuleSystem; backgroundRequire = GetModuleSystem(backgroundPage).require; @@ -193,7 +192,7 @@ binding.registerCustomHook(function(binding, id, contextType) { apiFunctions.setCustomCallback('getBackgroundPage', function(name, request, response) { if (request.callback) { - var bg = extensionNatives.GetExtensionViews(-1, 'BACKGROUND')[0] || null; + var bg = runtimeNatives.GetExtensionViews(-1, 'BACKGROUND')[0] || null; request.callback(bg); } request.callback = null; diff --git a/chrome/test/base/chrome_render_view_test.cc b/chrome/test/base/chrome_render_view_test.cc index 4f15553..4cf279c 100644 --- a/chrome/test/base/chrome_render_view_test.cc +++ b/chrome/test/base/chrome_render_view_test.cc @@ -11,7 +11,6 @@ #include "chrome/renderer/extensions/chrome_v8_extension.h" #include "chrome/renderer/extensions/dispatcher.h" #include "chrome/renderer/extensions/event_bindings.h" -#include "chrome/renderer/extensions/extension_custom_bindings.h" #include "chrome/renderer/spellchecker/spellcheck.h" #include "components/autofill/content/renderer/autofill_agent.h" #include "components/autofill/content/renderer/password_autofill_agent.h" @@ -32,7 +31,6 @@ #include "ui/base/gtk/event_synthesis_gtk.h" #endif -using extensions::ExtensionCustomBindings; using blink::WebFrame; using blink::WebInputEvent; using blink::WebMouseEvent; diff --git a/chrome/test/data/extensions/platform_apps/windows_api_get/background.js b/chrome/test/data/extensions/platform_apps/windows_api_get/background.js new file mode 100644 index 0000000..6f584a5 --- /dev/null +++ b/chrome/test/data/extensions/platform_apps/windows_api_get/background.js @@ -0,0 +1,75 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +function compareId(a, b) { + return a.id > b.id; +} + +chrome.app.runtime.onLaunched.addListener(function() { + chrome.test.runTests([ + + function testGetAllNoWindows() { + chrome.test.assertEq({}, chrome.app.window.getAll()); + chrome.test.succeed(); + }, + + function testGetAllOneWindow() { + chrome.app.window.create('index.html', {id: 'win1'}, function(win) { + win.contentWindow.addEventListener('load', function() { + chrome.test.assertEq([win], chrome.app.window.getAll()); + win.onClosed.addListener(function() { + chrome.test.succeed(); + }); + win.close(); + }); + }); + }, + + function testGetAllMultipleWindows() { + chrome.app.window.create('index.html', {id: 'win1'}, function(win1) { + win1.contentWindow.addEventListener('load', function() { + chrome.app.window.create('index.html', {id: 'win2'}, function(win2) { + win2.contentWindow.addEventListener('load', function() { + var windows = chrome.app.window.getAll().sort(compareId); + chrome.test.assertEq([win1, win2], windows); + win2.onClosed.addListener(function() { + chrome.test.succeed(); + }); + win1.onClosed.addListener(function() { + win2.close(); + }); + win1.close(); + }); + }); + }); + }); + }, + + function testGetNoWindows() { + chrome.test.assertEq(null, chrome.app.window.get('')); + chrome.test.succeed(); + }, + + function testGet() { + chrome.app.window.create('index.html', {id: 'win1'}, function(win1) { + win1.contentWindow.addEventListener('load', function() { + chrome.app.window.create('index.html', {id: 'win2'}, function(win2) { + win2.contentWindow.addEventListener('load', function() { + chrome.test.assertEq(win1, chrome.app.window.get('win1')); + chrome.test.assertEq(win2, chrome.app.window.get('win2')); + chrome.test.assertEq(null, chrome.app.window.get('win3')); + win2.onClosed.addListener(function() { + chrome.test.succeed(); + }); + win1.onClosed.addListener(function() { + win2.close(); + }); + win1.close(); + }); + }); + }); + }); + } + ]); +}); diff --git a/chrome/test/data/extensions/platform_apps/windows_api_get/index.html b/chrome/test/data/extensions/platform_apps/windows_api_get/index.html new file mode 100644 index 0000000..c341a40 --- /dev/null +++ b/chrome/test/data/extensions/platform_apps/windows_api_get/index.html @@ -0,0 +1 @@ +<!-- empty --> diff --git a/chrome/test/data/extensions/platform_apps/windows_api_get/manifest.json b/chrome/test/data/extensions/platform_apps/windows_api_get/manifest.json new file mode 100644 index 0000000..bbd3a80 --- /dev/null +++ b/chrome/test/data/extensions/platform_apps/windows_api_get/manifest.json @@ -0,0 +1,10 @@ +{ + "name": "Windows API - get/getAll", + "version": "1", + "manifest_version": 2, + "app": { + "background": { + "scripts": ["background.js"] + } + } +} diff --git a/ppapi/generators/idl_parser.py b/ppapi/generators/idl_parser.py index 40751e3..2c526fb 100755 --- a/ppapi/generators/idl_parser.py +++ b/ppapi/generators/idl_parser.py @@ -732,10 +732,10 @@ class IDLParser(IDLLexer): if self.parse_debug: DumpReduction('attribute', p) def p_member_function(self, p): - """member_function : modifiers static SYMBOL SYMBOL param_list""" + """member_function : modifiers static SYMBOL arrays SYMBOL param_list""" typeref = self.BuildAttribute('TYPEREF', p[3]) - children = ListFromConcat(p[1], p[2], typeref, p[5]) - p[0] = self.BuildNamed('Member', p, 4, children) + children = ListFromConcat(p[1], p[2], typeref, p[4], p[6]) + p[0] = self.BuildNamed('Member', p, 5, children) if self.parse_debug: DumpReduction('function', p) def p_static(self, p): diff --git a/ppapi/generators/test_parser/interface.idl b/ppapi/generators/test_parser/interface.idl index 6b52402..712027a 100644 --- a/ppapi/generators/test_parser/interface.idl +++ b/ppapi/generators/test_parser/interface.idl @@ -27,6 +27,9 @@ interface Interface1 { [out] PP_Size size, /* OK Param(is_always_opaque) */ [out] PP_Bool is_always_opaque); + + /* OK Member(ReturnArray) */ + PP_Resource[] ReturnArray(); }; diff --git a/tools/json_schema_compiler/idl_schema.py b/tools/json_schema_compiler/idl_schema.py index c8c1c8a..b056603 100644 --- a/tools/json_schema_compiler/idl_schema.py +++ b/tools/json_schema_compiler/idl_schema.py @@ -100,7 +100,7 @@ class Callspec(object): return_type = None if self.node.GetProperty('TYPEREF') not in ('void', None): return_type = Typeref(self.node.GetProperty('TYPEREF'), - self.node, + self.node.parent, {'name': self.node.GetName()}).process(callbacks) # The IDL parser doesn't allow specifying return types as optional. # Instead we infer any object return values to be optional. diff --git a/tools/json_schema_compiler/idl_schema_test.py b/tools/json_schema_compiler/idl_schema_test.py index ca9b6e0..212efdc 100755 --- a/tools/json_schema_compiler/idl_schema_test.py +++ b/tools/json_schema_compiler/idl_schema_test.py @@ -18,6 +18,11 @@ def getParams(schema, name): return function['parameters'] +def getReturns(schema, name): + function = getFunction(schema, name) + return function['returns'] + + def getType(schema, id): for item in schema['types']: if item['id'] == id: @@ -110,6 +115,23 @@ class IdlSchemaTest(unittest.TestCase): self.assertTrue(idl_basics['internal']) self.assertFalse(idl_basics['nodoc']) + def testReturnTypes(self): + schema = self.idl_basics + self.assertEquals({'name': 'function19', 'type': 'integer'}, + getReturns(schema, 'function19')) + self.assertEquals({'name': 'function20', '$ref': 'MyType1', + 'optional': True}, + getReturns(schema, 'function20')) + self.assertEquals({'name': 'function21', 'type': 'array', + 'items': {'$ref': 'MyType1'}}, + getReturns(schema, 'function21')) + self.assertEquals({'name': 'function22', '$ref': 'EnumType', + 'optional': True}, + getReturns(schema, 'function22')) + self.assertEquals({'name': 'function23', 'type': 'array', + 'items': {'$ref': 'EnumType'}}, + getReturns(schema, 'function23')) + def testChromeOSPlatformsNamespace(self): schema = idl_schema.Load('test/idl_namespace_chromeos.idl')[0] self.assertEquals('idl_namespace_chromeos', schema['namespace']) diff --git a/tools/json_schema_compiler/test/idl_basics.idl b/tools/json_schema_compiler/test/idl_basics.idl index 05b09c5..c6f9920 100644 --- a/tools/json_schema_compiler/test/idl_basics.idl +++ b/tools/json_schema_compiler/test/idl_basics.idl @@ -80,6 +80,12 @@ static void function17(Callback7 cb); // |cb|: Override callback comment. static void function18(Callback7 cb); + + static long function19(); + static MyType1 function20(); + static MyType1[] function21(); + static EnumType function22(); + static EnumType[] function23(); }; interface Events { |