Bug 1768060 - Add a wrapper for Cu.import return value that supports lexical variable. r=jonco,Standard8
This wrapper exposes all lexical variables in Cu.import return value, that allows us removing `this.foo = foo;` hack, in bug 1610653 patches, without affecting the not-in-tree consumer. Differential Revision: https://phabricator.services.mozilla.com/D145938
This commit is contained in:
260
js/xpconnect/loader/JSMEnvironmentProxy.cpp
Normal file
260
js/xpconnect/loader/JSMEnvironmentProxy.cpp
Normal file
@@ -0,0 +1,260 @@
|
|||||||
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
#include "JSMEnvironmentProxy.h"
|
||||||
|
|
||||||
|
#include "mozilla/Assertions.h" // MOZ_ASSERT
|
||||||
|
#include "mozilla/Maybe.h" // mozilla::Maybe
|
||||||
|
|
||||||
|
#include <stddef.h> // size_t
|
||||||
|
|
||||||
|
#include "jsapi.h" // JS_HasExtensibleLexicalEnvironment, JS_ExtensibleLexicalEnvironment
|
||||||
|
#include "js/Class.h" // JS::ObjectOpResult
|
||||||
|
#include "js/ErrorReport.h" // JS_ReportOutOfMemory
|
||||||
|
#include "js/GCVector.h" // JS::RootedVector
|
||||||
|
#include "js/Id.h" // JS::PropertyKey
|
||||||
|
#include "js/PropertyAndElement.h" // JS::IdVector, JS_HasPropertyById, JS_HasOwnPropertyById, JS_GetPropertyById, JS_Enumerate
|
||||||
|
#include "js/PropertyDescriptor.h" // JS::PropertyDescriptor, JS_GetOwnPropertyDescriptorById
|
||||||
|
#include "js/PropertyDescriptor.h" // JS::PropertyDescriptor, JS_GetOwnPropertyDescriptorById
|
||||||
|
#include "js/Proxy.h" // js::ProxyOptions, js::NewProxyObject, js::GetProxyPrivate
|
||||||
|
#include "js/RootingAPI.h" // JS::Rooted, JS::Handle, JS::MutableHandle
|
||||||
|
#include "js/TypeDecls.h" // JSContext, JSObject, JS::MutableHandleVector
|
||||||
|
#include "js/Value.h" // JS::Value, JS::UndefinedValue, JS_UNINITIALIZED_LEXICAL
|
||||||
|
#include "js/friend/ErrorMessages.h" // JSMSG_*
|
||||||
|
|
||||||
|
namespace mozilla {
|
||||||
|
namespace loader {
|
||||||
|
|
||||||
|
struct JSMEnvironmentProxyHandler : public js::BaseProxyHandler {
|
||||||
|
JSMEnvironmentProxyHandler() : BaseProxyHandler(&gFamily, false) {}
|
||||||
|
|
||||||
|
bool defineProperty(JSContext* aCx, JS::Handle<JSObject*> aProxy,
|
||||||
|
JS::Handle<JS::PropertyKey> aId,
|
||||||
|
JS::Handle<JS::PropertyDescriptor> aDesc,
|
||||||
|
JS::ObjectOpResult& aResult) const override {
|
||||||
|
return aResult.fail(JSMSG_CANT_DEFINE_PROP_OBJECT_NOT_EXTENSIBLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool getPrototype(JSContext* aCx, JS::Handle<JSObject*> aProxy,
|
||||||
|
JS::MutableHandle<JSObject*> aProtop) const override {
|
||||||
|
aProtop.set(nullptr);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool setPrototype(JSContext* aCx, JS::Handle<JSObject*> aProxy,
|
||||||
|
JS::Handle<JSObject*> aProto,
|
||||||
|
JS::ObjectOpResult& aResult) const override {
|
||||||
|
if (!aProto) {
|
||||||
|
return aResult.succeed();
|
||||||
|
}
|
||||||
|
return aResult.failCantSetProto();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool getPrototypeIfOrdinary(
|
||||||
|
JSContext* aCx, JS::Handle<JSObject*> aProxy, bool* aIsOrdinary,
|
||||||
|
JS::MutableHandle<JSObject*> aProtop) const override {
|
||||||
|
*aIsOrdinary = false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool setImmutablePrototype(JSContext* aCx, JS::Handle<JSObject*> aProxy,
|
||||||
|
bool* aSucceeded) const override {
|
||||||
|
*aSucceeded = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool preventExtensions(JSContext* aCx, JS::Handle<JSObject*> aProxy,
|
||||||
|
JS::ObjectOpResult& aResult) const override {
|
||||||
|
aResult.succeed();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isExtensible(JSContext* aCx, JS::Handle<JSObject*> aProxy,
|
||||||
|
bool* aExtensible) const override {
|
||||||
|
*aExtensible = false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool set(JSContext* aCx, JS::Handle<JSObject*> aProxy,
|
||||||
|
JS::Handle<JS::PropertyKey> aId, JS::Handle<JS::Value> aValue,
|
||||||
|
JS::Handle<JS::Value> aReceiver,
|
||||||
|
JS::ObjectOpResult& aResult) const override {
|
||||||
|
return aResult.failReadOnly();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool delete_(JSContext* aCx, JS::Handle<JSObject*> aProxy,
|
||||||
|
JS::Handle<JS::PropertyKey> aId,
|
||||||
|
JS::ObjectOpResult& aResult) const override {
|
||||||
|
return aResult.failCantDelete();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool getOwnPropertyDescriptor(
|
||||||
|
JSContext* aCx, JS::Handle<JSObject*> aProxy,
|
||||||
|
JS::Handle<JS::PropertyKey> aId,
|
||||||
|
JS::MutableHandle<mozilla::Maybe<JS::PropertyDescriptor>> aDesc)
|
||||||
|
const override;
|
||||||
|
bool has(JSContext* aCx, JS::Handle<JSObject*> aProxy,
|
||||||
|
JS::Handle<JS::PropertyKey> aId, bool* aBp) const override;
|
||||||
|
bool get(JSContext* aCx, JS::Handle<JSObject*> aProxy,
|
||||||
|
JS::Handle<JS::Value> aReceiver, JS::Handle<JS::PropertyKey> aId,
|
||||||
|
JS::MutableHandle<JS::Value> aVp) const override;
|
||||||
|
bool ownPropertyKeys(
|
||||||
|
JSContext* aCx, JS::Handle<JSObject*> aProxy,
|
||||||
|
JS::MutableHandleVector<JS::PropertyKey> aProps) const override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
static JSObject* getGlobal(JSContext* aCx, JS::Handle<JSObject*> aProxy) {
|
||||||
|
JS::Rooted<JSObject*> globalObj(aCx,
|
||||||
|
&js::GetProxyPrivate(aProxy).toObject());
|
||||||
|
return globalObj;
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
static const char gFamily;
|
||||||
|
static const JSMEnvironmentProxyHandler gHandler;
|
||||||
|
};
|
||||||
|
|
||||||
|
const JSMEnvironmentProxyHandler JSMEnvironmentProxyHandler::gHandler;
|
||||||
|
const char JSMEnvironmentProxyHandler::gFamily = 0;
|
||||||
|
|
||||||
|
JSObject* ResolveModuleObjectPropertyById(JSContext* aCx,
|
||||||
|
JS::Handle<JSObject*> aModObj,
|
||||||
|
JS::Handle<JS::PropertyKey> aId) {
|
||||||
|
if (JS_HasExtensibleLexicalEnvironment(aModObj)) {
|
||||||
|
JS::Rooted<JSObject*> lexical(aCx,
|
||||||
|
JS_ExtensibleLexicalEnvironment(aModObj));
|
||||||
|
bool found;
|
||||||
|
if (!JS_HasOwnPropertyById(aCx, lexical, aId, &found)) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
if (found) {
|
||||||
|
return lexical;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return aModObj;
|
||||||
|
}
|
||||||
|
|
||||||
|
JSObject* ResolveModuleObjectProperty(JSContext* aCx,
|
||||||
|
JS::Handle<JSObject*> aModObj,
|
||||||
|
const char* aName) {
|
||||||
|
if (JS_HasExtensibleLexicalEnvironment(aModObj)) {
|
||||||
|
RootedObject lexical(aCx, JS_ExtensibleLexicalEnvironment(aModObj));
|
||||||
|
bool found;
|
||||||
|
if (!JS_HasOwnProperty(aCx, lexical, aName, &found)) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
if (found) {
|
||||||
|
return lexical;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return aModObj;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool JSMEnvironmentProxyHandler::getOwnPropertyDescriptor(
|
||||||
|
JSContext* aCx, JS::Handle<JSObject*> aProxy,
|
||||||
|
JS::Handle<JS::PropertyKey> aId,
|
||||||
|
JS::MutableHandle<mozilla::Maybe<JS::PropertyDescriptor>> aDesc) const {
|
||||||
|
JS::Rooted<JSObject*> globalObj(aCx, getGlobal(aCx, aProxy));
|
||||||
|
JS::Rooted<JSObject*> holder(
|
||||||
|
aCx, ResolveModuleObjectPropertyById(aCx, globalObj, aId));
|
||||||
|
if (!JS_GetOwnPropertyDescriptorById(aCx, holder, aId, aDesc)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (aDesc.get().isNothing()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
JS::PropertyDescriptor& desc = *aDesc.get();
|
||||||
|
|
||||||
|
if (desc.hasValue()) {
|
||||||
|
if (desc.value().isMagic(JS_UNINITIALIZED_LEXICAL)) {
|
||||||
|
desc.setValue(JS::UndefinedValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
desc.setConfigurable(false);
|
||||||
|
desc.setEnumerable(true);
|
||||||
|
if (!desc.isAccessorDescriptor()) {
|
||||||
|
desc.setWritable(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool JSMEnvironmentProxyHandler::has(JSContext* aCx,
|
||||||
|
JS::Handle<JSObject*> aProxy,
|
||||||
|
JS::Handle<JS::PropertyKey> aId,
|
||||||
|
bool* aBp) const {
|
||||||
|
JS::Rooted<JSObject*> globalObj(aCx, getGlobal(aCx, aProxy));
|
||||||
|
JS::Rooted<JSObject*> holder(
|
||||||
|
aCx, ResolveModuleObjectPropertyById(aCx, globalObj, aId));
|
||||||
|
return JS_HasPropertyById(aCx, holder, aId, aBp);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool JSMEnvironmentProxyHandler::get(JSContext* aCx,
|
||||||
|
JS::Handle<JSObject*> aProxy,
|
||||||
|
JS::Handle<JS::Value> aReceiver,
|
||||||
|
JS::Handle<JS::PropertyKey> aId,
|
||||||
|
JS::MutableHandle<JS::Value> aVp) const {
|
||||||
|
JS::Rooted<JSObject*> globalObj(aCx, getGlobal(aCx, aProxy));
|
||||||
|
JS::Rooted<JSObject*> holder(
|
||||||
|
aCx, ResolveModuleObjectPropertyById(aCx, globalObj, aId));
|
||||||
|
if (!JS_GetPropertyById(aCx, holder, aId, aVp)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (aVp.isMagic(JS_UNINITIALIZED_LEXICAL)) {
|
||||||
|
aVp.setUndefined();
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool JSMEnvironmentProxyHandler::ownPropertyKeys(
|
||||||
|
JSContext* aCx, JS::Handle<JSObject*> aProxy,
|
||||||
|
JS::MutableHandleVector<JS::PropertyKey> aProps) const {
|
||||||
|
JS::Rooted<JSObject*> globalObj(aCx, getGlobal(aCx, aProxy));
|
||||||
|
JS::Rooted<JS::IdVector> globalIds(aCx, JS::IdVector(aCx));
|
||||||
|
if (!JS_Enumerate(aCx, globalObj, &globalIds)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t i = 0; i < globalIds.length(); i++) {
|
||||||
|
if (!aProps.append(globalIds[i])) {
|
||||||
|
JS_ReportOutOfMemory(aCx);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
JS::RootedObject lexicalEnv(aCx, JS_ExtensibleLexicalEnvironment(globalObj));
|
||||||
|
JS::Rooted<JS::IdVector> lexicalIds(aCx, JS::IdVector(aCx));
|
||||||
|
if (!JS_Enumerate(aCx, lexicalEnv, &lexicalIds)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t i = 0; i < lexicalIds.length(); i++) {
|
||||||
|
if (!aProps.append(lexicalIds[i])) {
|
||||||
|
JS_ReportOutOfMemory(aCx);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
JSObject* CreateJSMEnvironmentProxy(JSContext* aCx,
|
||||||
|
JS::Handle<JSObject*> aGlobalObj) {
|
||||||
|
js::ProxyOptions options;
|
||||||
|
options.setLazyProto(true);
|
||||||
|
|
||||||
|
JS::Rooted<JS::Value> globalVal(aCx, JS::ObjectValue(*aGlobalObj));
|
||||||
|
return NewProxyObject(aCx, &JSMEnvironmentProxyHandler::gHandler, globalVal,
|
||||||
|
nullptr, options);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace loader
|
||||||
|
} // namespace mozilla
|
||||||
31
js/xpconnect/loader/JSMEnvironmentProxy.h
Normal file
31
js/xpconnect/loader/JSMEnvironmentProxy.h
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
#ifndef mozilla_loader_JSMEnvironmentProxy_h
|
||||||
|
#define mozilla_loader_JSMEnvironmentProxy_h
|
||||||
|
|
||||||
|
#include "js/Id.h" // JS::PropertyKey
|
||||||
|
#include "js/TypeDecls.h" // JSContext, JSObject
|
||||||
|
#include "js/RootingAPI.h" // JS::Handle
|
||||||
|
|
||||||
|
namespace mozilla {
|
||||||
|
namespace loader {
|
||||||
|
|
||||||
|
JSObject* ResolveModuleObjectPropertyById(JSContext* aCx,
|
||||||
|
JS::Handle<JSObject*> aModObj,
|
||||||
|
JS::Handle<JS::PropertyKey> aId);
|
||||||
|
|
||||||
|
JSObject* ResolveModuleObjectProperty(JSContext* aCx,
|
||||||
|
JS::Handle<JSObject*> aModObj,
|
||||||
|
const char* aName);
|
||||||
|
|
||||||
|
JSObject* CreateJSMEnvironmentProxy(JSContext* aCx,
|
||||||
|
JS::Handle<JSObject*> aGlobalObj);
|
||||||
|
|
||||||
|
} // namespace loader
|
||||||
|
} // namespace mozilla
|
||||||
|
|
||||||
|
#endif // mozilla_loader_JSMEnvironmentProxy_h
|
||||||
@@ -8,6 +8,7 @@ UNIFIED_SOURCES += [
|
|||||||
"AutoMemMap.cpp",
|
"AutoMemMap.cpp",
|
||||||
"ChromeScriptLoader.cpp",
|
"ChromeScriptLoader.cpp",
|
||||||
"ComponentModuleLoader.cpp",
|
"ComponentModuleLoader.cpp",
|
||||||
|
"JSMEnvironmentProxy.cpp",
|
||||||
"ModuleEnvironmentProxy.cpp",
|
"ModuleEnvironmentProxy.cpp",
|
||||||
"mozJSLoaderUtils.cpp",
|
"mozJSLoaderUtils.cpp",
|
||||||
"mozJSSubScriptLoader.cpp",
|
"mozJSSubScriptLoader.cpp",
|
||||||
|
|||||||
@@ -49,6 +49,7 @@
|
|||||||
#include "nsReadableUtils.h"
|
#include "nsReadableUtils.h"
|
||||||
#include "nsXULAppAPI.h"
|
#include "nsXULAppAPI.h"
|
||||||
#include "WrapperFactory.h"
|
#include "WrapperFactory.h"
|
||||||
|
#include "JSMEnvironmentProxy.h"
|
||||||
#include "ModuleEnvironmentProxy.h"
|
#include "ModuleEnvironmentProxy.h"
|
||||||
|
|
||||||
#include "AutoMemMap.h"
|
#include "AutoMemMap.h"
|
||||||
@@ -344,25 +345,6 @@ mozJSComponentLoader::~mozJSComponentLoader() {
|
|||||||
|
|
||||||
StaticRefPtr<mozJSComponentLoader> mozJSComponentLoader::sSelf;
|
StaticRefPtr<mozJSComponentLoader> mozJSComponentLoader::sSelf;
|
||||||
|
|
||||||
// For terrible compatibility reasons, we need to consider both the global
|
|
||||||
// lexical environment and the global of modules when searching for exported
|
|
||||||
// symbols.
|
|
||||||
static JSObject* ResolveModuleObjectProperty(JSContext* aCx,
|
|
||||||
HandleObject aModObj,
|
|
||||||
const char* name) {
|
|
||||||
if (JS_HasExtensibleLexicalEnvironment(aModObj)) {
|
|
||||||
RootedObject lexical(aCx, JS_ExtensibleLexicalEnvironment(aModObj));
|
|
||||||
bool found;
|
|
||||||
if (!JS_HasOwnProperty(aCx, lexical, name, &found)) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
if (found) {
|
|
||||||
return lexical;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return aModObj;
|
|
||||||
}
|
|
||||||
|
|
||||||
const mozilla::Module* mozJSComponentLoader::LoadModule(FileLocation& aFile) {
|
const mozilla::Module* mozJSComponentLoader::LoadModule(FileLocation& aFile) {
|
||||||
if (!NS_IsMainThread()) {
|
if (!NS_IsMainThread()) {
|
||||||
MOZ_ASSERT(false, "Don't use JS components off the main thread");
|
MOZ_ASSERT(false, "Don't use JS components off the main thread");
|
||||||
@@ -1187,22 +1169,6 @@ nsresult mozJSComponentLoader::GetComponentLoadStack(
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static JSObject* ResolveModuleObjectPropertyById(JSContext* aCx,
|
|
||||||
HandleObject aModObj,
|
|
||||||
HandleId id) {
|
|
||||||
if (JS_HasExtensibleLexicalEnvironment(aModObj)) {
|
|
||||||
RootedObject lexical(aCx, JS_ExtensibleLexicalEnvironment(aModObj));
|
|
||||||
bool found;
|
|
||||||
if (!JS_HasOwnPropertyById(aCx, lexical, id, &found)) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
if (found) {
|
|
||||||
return lexical;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return aModObj;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsresult mozJSComponentLoader::ImportInto(const nsACString& aLocation,
|
nsresult mozJSComponentLoader::ImportInto(const nsACString& aLocation,
|
||||||
HandleObject targetObj, JSContext* cx,
|
HandleObject targetObj, JSContext* cx,
|
||||||
MutableHandleObject vp) {
|
MutableHandleObject vp) {
|
||||||
@@ -1454,7 +1420,19 @@ nsresult mozJSComponentLoader::Import(JSContext* aCx,
|
|||||||
}
|
}
|
||||||
|
|
||||||
MOZ_ASSERT(mod->obj, "Import table contains entry with no object");
|
MOZ_ASSERT(mod->obj, "Import table contains entry with no object");
|
||||||
aModuleGlobal.set(mod->obj);
|
JS::RootedObject globalProxy(aCx);
|
||||||
|
{
|
||||||
|
JSAutoRealm ar(aCx, mod->obj);
|
||||||
|
|
||||||
|
globalProxy = CreateJSMEnvironmentProxy(aCx, mod->obj);
|
||||||
|
if (!globalProxy) {
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!JS_WrapObject(aCx, &globalProxy)) {
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
aModuleGlobal.set(globalProxy);
|
||||||
|
|
||||||
JS::RootedObject exports(aCx, mod->exports);
|
JS::RootedObject exports(aCx, mod->exports);
|
||||||
if (!exports && !aIgnoreExports) {
|
if (!exports && !aIgnoreExports) {
|
||||||
|
|||||||
@@ -200,7 +200,7 @@ function testWriteProxyOps(global, expectedNames) {
|
|||||||
|
|
||||||
add_task(function test_Cu_import_not_exported_no_shim_JSM() {
|
add_task(function test_Cu_import_not_exported_no_shim_JSM() {
|
||||||
// `exports` and `global` properties for not-ESM-ified case.
|
// `exports` and `global` properties for not-ESM-ified case.
|
||||||
// Not-exported non-lexical variables should be visible in `global`.
|
// Not-exported variables should be visible in `global`.
|
||||||
|
|
||||||
const exports = {};
|
const exports = {};
|
||||||
const global = Components.utils.import(
|
const global = Components.utils.import(
|
||||||
@@ -210,25 +210,31 @@ add_task(function test_Cu_import_not_exported_no_shim_JSM() {
|
|||||||
|
|
||||||
Assert.equal(global.exportedVar, "exported var");
|
Assert.equal(global.exportedVar, "exported var");
|
||||||
Assert.equal(global.exportedFunction(), "exported function");
|
Assert.equal(global.exportedFunction(), "exported function");
|
||||||
Assert.equal(global.exportedLet, undefined);
|
Assert.equal(global.exportedLet, "exported let");
|
||||||
Assert.equal(global.exportedConst, undefined);
|
Assert.equal(global.exportedConst, "exported const");
|
||||||
Assert.equal(global.notExportedVar, "not exported var");
|
Assert.equal(global.notExportedVar, "not exported var");
|
||||||
Assert.equal(global.notExportedFunction(), "not exported function");
|
Assert.equal(global.notExportedFunction(), "not exported function");
|
||||||
Assert.equal(global.notExportedLet, undefined);
|
Assert.equal(global.notExportedLet, "not exported let");
|
||||||
Assert.equal(global.notExportedConst, undefined);
|
Assert.equal(global.notExportedConst, "not exported const");
|
||||||
|
|
||||||
const expectedNames = [
|
const expectedNames = [
|
||||||
|
"EXPORTED_SYMBOLS",
|
||||||
"exportedVar",
|
"exportedVar",
|
||||||
"exportedFunction",
|
"exportedFunction",
|
||||||
|
"exportedLet",
|
||||||
|
"exportedConst",
|
||||||
"notExportedVar",
|
"notExportedVar",
|
||||||
"notExportedFunction",
|
"notExportedFunction",
|
||||||
|
"notExportedLet",
|
||||||
|
"notExportedConst",
|
||||||
];
|
];
|
||||||
|
|
||||||
testReadProxyOps(global, expectedNames, {
|
testReadProxyOps(global, expectedNames, {
|
||||||
writable: true,
|
writable: false,
|
||||||
enumerable: true,
|
enumerable: true,
|
||||||
configurable: false,
|
configurable: false,
|
||||||
});
|
});
|
||||||
|
testWriteProxyOps(global, expectedNames);
|
||||||
|
|
||||||
Assert.equal(exports.exportedVar, "exported var");
|
Assert.equal(exports.exportedVar, "exported var");
|
||||||
Assert.equal(exports.exportedFunction(), "exported function");
|
Assert.equal(exports.exportedFunction(), "exported function");
|
||||||
@@ -252,17 +258,11 @@ add_task(function test_Cu_import_not_exported_shim() {
|
|||||||
|
|
||||||
Assert.equal(global.exportedVar, "exported var");
|
Assert.equal(global.exportedVar, "exported var");
|
||||||
Assert.equal(global.exportedFunction(), "exported function");
|
Assert.equal(global.exportedFunction(), "exported function");
|
||||||
|
|
||||||
// This is different than no-shim case.
|
|
||||||
// Lexical variables are visible in the shim's global.
|
|
||||||
Assert.equal(global.exportedLet, "exported let");
|
Assert.equal(global.exportedLet, "exported let");
|
||||||
Assert.equal(global.exportedConst, "exported const");
|
Assert.equal(global.exportedConst, "exported const");
|
||||||
|
|
||||||
Assert.equal(global.notExportedVar, "not exported var");
|
Assert.equal(global.notExportedVar, "not exported var");
|
||||||
Assert.equal(global.notExportedFunction(), "not exported function");
|
Assert.equal(global.notExportedFunction(), "not exported function");
|
||||||
|
|
||||||
// This is different than no-shim case.
|
|
||||||
// Lexical variables are visible in the shim's global.
|
|
||||||
Assert.equal(global.notExportedLet, "not exported let");
|
Assert.equal(global.notExportedLet, "not exported let");
|
||||||
Assert.equal(global.notExportedConst, "not exported const");
|
Assert.equal(global.notExportedConst, "not exported const");
|
||||||
|
|
||||||
@@ -276,6 +276,7 @@ add_task(function test_Cu_import_not_exported_shim() {
|
|||||||
"notExportedLet",
|
"notExportedLet",
|
||||||
"notExportedConst",
|
"notExportedConst",
|
||||||
];
|
];
|
||||||
|
|
||||||
testReadProxyOps(global, expectedNames, {
|
testReadProxyOps(global, expectedNames, {
|
||||||
writable: false,
|
writable: false,
|
||||||
enumerable: true,
|
enumerable: true,
|
||||||
|
|||||||
Reference in New Issue
Block a user