[dart:js_interop] Use compiler-dependent global context

Fixes https://github.com/dart-lang/sdk/issues/52955

Instead of globalThis, dart2js and DDC will now use the same global
context that they did for non-static interop. dart2wasm will
continue to use globalThis.

Change-Id: Iec899fc73ed35c50cd688d9b45b980e94f101c0b
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/318520
Reviewed-by: Sigmund Cherem <sigmund@google.com>
Reviewed-by: Stephen Adams <sra@google.com>
Reviewed-by: Nicholas Shahan <nshahan@google.com>
This commit is contained in:
Srujan Gaddam 2023-08-15 20:57:17 +00:00 committed by Commit Queue
parent 8d5dfeadf6
commit 66b511fa6c
16 changed files with 141 additions and 73 deletions

View file

@ -47,6 +47,17 @@
`@staticInterop` types can subtype only `JSObject` and `JSAny` from the set of
JS types in `dart:js_interop`. Subtyping other types from `dart:js_interop`
would result in confusing type errors before, so this makes it a static error.
- **Global context of `dart:js_interop` and `@staticInterop` APIs**:
Static interop APIs will now use the same global context as non-static interop
instead of `globalThis` to avoid a greater migration. Static interop APIs,
either through `dart:js_interop` or the `@staticInterop` annotation, have used
JavaScript's `globalThis` as the global context. This is relevant to things
like external top-level members or external constructors, as this is the root
context we expect those members to reside in. Historically, this was not the
case in Dart2JS and DDC. We used either `self` or DDC's `global` in non-static
interop APIs with `package:js`. So, static interop APIs will now use one of
those global contexts. Functionally, this should matter in only a very small
number of cases, like when using older browser versions.
## 3.1.0

View file

@ -43,7 +43,7 @@ class JsUtilOptimizer extends Transformer {
final Map<Member, _InvocationBuilder?> _externalInvocationBuilders = {};
final Procedure _getPropertyTarget;
final Procedure _getPropertyTrustTypeTarget;
final Procedure _globalThisTarget;
final Procedure _globalContextTarget;
final InterfaceType _objectType;
final Procedure _setPropertyTarget;
final Procedure _setPropertyUncheckedTarget;
@ -90,8 +90,8 @@ class JsUtilOptimizer extends Transformer {
.getTopLevelProcedure('dart:js_util', 'getProperty'),
_getPropertyTrustTypeTarget = _coreTypes.index
.getTopLevelProcedure('dart:js_util', '_getPropertyTrustType'),
_globalThisTarget = _coreTypes.index
.getTopLevelProcedure('dart:js_util', 'get:globalThis'),
_globalContextTarget = _coreTypes.index.getTopLevelProcedure(
'dart:_js_helper', 'get:staticInteropGlobalContext'),
_objectType = hierarchy.coreTypes.objectNonNullableRawType,
_setPropertyTarget = _coreTypes.index
.getTopLevelProcedure('dart:js_util', 'setProperty'),
@ -152,7 +152,7 @@ class JsUtilOptimizer extends Transformer {
// constructors/factories.
var dottedPrefix = _getDottedPrefixForStaticallyResolvableMember(node);
if (dottedPrefix != null) {
var receiver = _getObjectOffGlobalThis(
var receiver = _getObjectOffGlobalContext(
node, dottedPrefix.isEmpty ? [] : dottedPrefix.split('.'));
var shouldTrustType = node.enclosingClass != null &&
hasTrustTypesAnnotation(node.enclosingClass!);
@ -166,8 +166,8 @@ class JsUtilOptimizer extends Transformer {
node, shouldTrustType, receiver);
} else if (_extensionIndex.isNonLiteralConstructor(node)) {
// Get the constructor object using the class name.
return _getExternalConstructorInvocationBuilder(
node, _getObjectOffGlobalThis(node, dottedPrefix.split('.')));
return _getExternalConstructorInvocationBuilder(node,
_getObjectOffGlobalContext(node, dottedPrefix.split('.')));
}
}
}
@ -245,11 +245,12 @@ class JsUtilOptimizer extends Transformer {
}
/// Given a list of strings, [selectors], recursively fetches the property
/// that corresponds to each string off of the `globalThis` object.
/// that corresponds to each string off of the global context.
///
/// Returns an expression that contains the nested property gets.
Expression _getObjectOffGlobalThis(Procedure node, List<String> selectors) {
Expression currentTarget = StaticGet(_globalThisTarget);
Expression _getObjectOffGlobalContext(
Procedure node, List<String> selectors) {
Expression currentTarget = StaticGet(_globalContextTarget);
for (String selector in selectors) {
currentTarget = StaticInvocation(
_getPropertyTrustTypeTarget,

View file

@ -666,6 +666,9 @@ class ProgramCompiler extends ComputeOnceConstantVisitor<js_ast.Expression>
bool _isDartForeignHelper(Library library) =>
isDartLibrary(library, '_foreign_helper');
/// True when [library] is the sdk library 'dart:js_util'.
bool _isDartJsUtil(Library library) => isDartLibrary(library, 'js_util');
@override
bool isDartLibrary(Library library, String name) {
var importUri = library.importUri;
@ -5453,8 +5456,16 @@ class ProgramCompiler extends ComputeOnceConstantVisitor<js_ast.Expression>
}
@override
js_ast.Expression visitStaticGet(StaticGet node) =>
_emitStaticGet(node.target);
js_ast.Expression visitStaticGet(StaticGet node) {
final target = node.target;
if (_isDartJsHelper(target.enclosingLibrary)) {
final name = target.name.text;
if (name == 'staticInteropGlobalContext') {
return runtimeCall('global');
}
}
return _emitStaticGet(target);
}
@override
js_ast.Expression visitStaticTearOff(StaticTearOff node) =>
@ -6395,7 +6406,7 @@ class ProgramCompiler extends ComputeOnceConstantVisitor<js_ast.Expression>
if (_isDebuggerCall(target)) {
return _emitDebuggerCall(node) as js_ast.Expression;
}
if (target.enclosingLibrary.importUri.toString() == 'dart:js_util') {
if (_isDartJsUtil(enclosingLibrary)) {
// We try and do further inlining here for the unchecked/trusted-type
// variants of js_util methods. Note that we only lower the methods that
// are used in transformations and are private. Also note that this

View file

@ -5,6 +5,7 @@ import "dart:js_interop" as js_;
import "dart:_js_annotations" as _js;
import "dart:core" as core;
import "dart:js_util" as js_2;
import "dart:_js_helper" as _js2;
import "dart:js_interop";
@ -40,10 +41,10 @@ extension type B(self::A a) {
}
external static inline-class-member method B|(self::A a) → self::B /* = self::A */;
static inline-class-member method B|_#new#tearOff(self::A a) → self::B /* = self::A */
return js_2::_callConstructorUnchecked1<self::B /* = self::A */>(js_2::_getPropertyTrustType<core::Object>(js_2::globalThis, "B"), a);
return js_2::_callConstructorUnchecked1<self::B /* = self::A */>(js_2::_getPropertyTrustType<core::Object>(_js2::staticInteropGlobalContext, "B"), a);
external static inline-class-member method B|named(core::int i) → self::B /* = self::A */;
static inline-class-member method B|_#named#tearOff(core::int i) → self::B /* = self::A */
return js_2::_callConstructorUnchecked1<self::B /* = self::A */>(js_2::_getPropertyTrustType<core::Object>(js_2::globalThis, "B"), i);
return js_2::_callConstructorUnchecked1<self::B /* = self::A */>(js_2::_getPropertyTrustType<core::Object>(_js2::staticInteropGlobalContext, "B"), i);
external static inline-class-member method B|get#field(lowered self::A #this) → self::A;
external static inline-class-member method B|set#field(lowered self::A #this, self::A #externalFieldValue) → void;
external static inline-class-member method B|method(lowered final self::B /* = self::A */ #this) → self::A;
@ -61,20 +62,20 @@ external static inline-class-member method B|staticGenericMethod<T extends self:
external static inline-class-member get B|staticGetter() → self::B /* = self::A */;
external static inline-class-member set B|staticSetter(self::B /* = self::A */ b) → void;
static method method(self::A a) → void {
self::B /* = self::A */ b1 = js_2::_callConstructorUnchecked1<self::B /* = self::A */>(js_2::_getPropertyTrustType<core::Object>(js_2::globalThis, "B"), a);
self::B /* = self::A */ b2 = js_2::_callConstructorUnchecked1<self::B /* = self::A */>(js_2::_getPropertyTrustType<core::Object>(js_2::globalThis, "B"), 0);
self::B /* = self::A */ b1 = js_2::_callConstructorUnchecked1<self::B /* = self::A */>(js_2::_getPropertyTrustType<core::Object>(_js2::staticInteropGlobalContext, "B"), a);
self::B /* = self::A */ b2 = js_2::_callConstructorUnchecked1<self::B /* = self::A */>(js_2::_getPropertyTrustType<core::Object>(_js2::staticInteropGlobalContext, "B"), 0);
a = js_2::getProperty<self::A>(b1, "field");
js_2::setProperty<self::A>(b1, "field", a);
a = js_2::_callMethodUnchecked0<self::A>(b1, "method");
b2 = js_2::callMethod<self::B /* = self::A */>(b2, "genericMethod", <dynamic>[b2]);
b1 = js_2::getProperty<self::B /* = self::A */>(b2, "getter");
js_2::setProperty<self::B /* = self::A */>(b1, "setter", b2);
a = js_2::getProperty<self::A>(js_2::_getPropertyTrustType<core::Object>(js_2::globalThis, "B"), "staticField");
js_2::setProperty<self::A>(js_2::_getPropertyTrustType<core::Object>(js_2::globalThis, "B"), "staticField", a);
a = js_2::_callMethodUnchecked0<self::A>(js_2::_getPropertyTrustType<core::Object>(js_2::globalThis, "B"), "staticMethod");
b2 = js_2::callMethod<self::B /* = self::A */>(js_2::_getPropertyTrustType<core::Object>(js_2::globalThis, "B"), "staticGenericMethod", <dynamic>[b2]);
b1 = js_2::getProperty<self::B /* = self::A */>(js_2::_getPropertyTrustType<core::Object>(js_2::globalThis, "B"), "staticGetter");
js_2::setProperty<self::B /* = self::A */>(js_2::_getPropertyTrustType<core::Object>(js_2::globalThis, "B"), "staticSetter", b2);
a = js_2::getProperty<self::A>(js_2::_getPropertyTrustType<core::Object>(_js2::staticInteropGlobalContext, "B"), "staticField");
js_2::setProperty<self::A>(js_2::_getPropertyTrustType<core::Object>(_js2::staticInteropGlobalContext, "B"), "staticField", a);
a = js_2::_callMethodUnchecked0<self::A>(js_2::_getPropertyTrustType<core::Object>(_js2::staticInteropGlobalContext, "B"), "staticMethod");
b2 = js_2::callMethod<self::B /* = self::A */>(js_2::_getPropertyTrustType<core::Object>(_js2::staticInteropGlobalContext, "B"), "staticGenericMethod", <dynamic>[b2]);
b1 = js_2::getProperty<self::B /* = self::A */>(js_2::_getPropertyTrustType<core::Object>(_js2::staticInteropGlobalContext, "B"), "staticGetter");
js_2::setProperty<self::B /* = self::A */>(js_2::_getPropertyTrustType<core::Object>(_js2::staticInteropGlobalContext, "B"), "staticSetter", b2);
}
constants {

View file

@ -5,6 +5,7 @@ import "dart:js_interop" as js_;
import "dart:_js_annotations" as _js;
import "dart:core" as core;
import "dart:js_util" as js_2;
import "dart:_js_helper" as _js2;
import "dart:js_interop";
@ -40,10 +41,10 @@ extension type B(self::A a) {
}
external static inline-class-member method B|(self::A a) → self::B /* = self::A */;
static inline-class-member method B|_#new#tearOff(self::A a) → self::B /* = self::A */
return js_2::_callConstructorUnchecked1<self::B /* = self::A */>(js_2::_getPropertyTrustType<core::Object>(js_2::globalThis, "B"), a);
return js_2::_callConstructorUnchecked1<self::B /* = self::A */>(js_2::_getPropertyTrustType<core::Object>(_js2::staticInteropGlobalContext, "B"), a);
external static inline-class-member method B|named(core::int i) → self::B /* = self::A */;
static inline-class-member method B|_#named#tearOff(core::int i) → self::B /* = self::A */
return js_2::_callConstructorUnchecked1<self::B /* = self::A */>(js_2::_getPropertyTrustType<core::Object>(js_2::globalThis, "B"), i);
return js_2::_callConstructorUnchecked1<self::B /* = self::A */>(js_2::_getPropertyTrustType<core::Object>(_js2::staticInteropGlobalContext, "B"), i);
external static inline-class-member method B|get#field(lowered self::A #this) → self::A;
external static inline-class-member method B|set#field(lowered self::A #this, self::A #externalFieldValue) → void;
external static inline-class-member method B|method(lowered final self::B /* = self::A */ #this) → self::A;
@ -61,20 +62,20 @@ external static inline-class-member method B|staticGenericMethod<T extends self:
external static inline-class-member get B|staticGetter() → self::B /* = self::A */;
external static inline-class-member set B|staticSetter(self::B /* = self::A */ b) → void;
static method method(self::A a) → void {
self::B /* = self::A */ b1 = js_2::_callConstructorUnchecked1<self::B /* = self::A */>(js_2::_getPropertyTrustType<core::Object>(js_2::globalThis, "B"), a);
self::B /* = self::A */ b2 = js_2::_callConstructorUnchecked1<self::B /* = self::A */>(js_2::_getPropertyTrustType<core::Object>(js_2::globalThis, "B"), 0);
self::B /* = self::A */ b1 = js_2::_callConstructorUnchecked1<self::B /* = self::A */>(js_2::_getPropertyTrustType<core::Object>(_js2::staticInteropGlobalContext, "B"), a);
self::B /* = self::A */ b2 = js_2::_callConstructorUnchecked1<self::B /* = self::A */>(js_2::_getPropertyTrustType<core::Object>(_js2::staticInteropGlobalContext, "B"), 0);
a = js_2::getProperty<self::A>(b1, "field");
js_2::setProperty<self::A>(b1, "field", a);
a = js_2::_callMethodUnchecked0<self::A>(b1, "method");
b2 = js_2::callMethod<self::B /* = self::A */>(b2, "genericMethod", <dynamic>[b2]);
b1 = js_2::getProperty<self::B /* = self::A */>(b2, "getter");
js_2::setProperty<self::B /* = self::A */>(b1, "setter", b2);
a = js_2::getProperty<self::A>(js_2::_getPropertyTrustType<core::Object>(js_2::globalThis, "B"), "staticField");
js_2::setProperty<self::A>(js_2::_getPropertyTrustType<core::Object>(js_2::globalThis, "B"), "staticField", a);
a = js_2::_callMethodUnchecked0<self::A>(js_2::_getPropertyTrustType<core::Object>(js_2::globalThis, "B"), "staticMethod");
b2 = js_2::callMethod<self::B /* = self::A */>(js_2::_getPropertyTrustType<core::Object>(js_2::globalThis, "B"), "staticGenericMethod", <dynamic>[b2]);
b1 = js_2::getProperty<self::B /* = self::A */>(js_2::_getPropertyTrustType<core::Object>(js_2::globalThis, "B"), "staticGetter");
js_2::setProperty<self::B /* = self::A */>(js_2::_getPropertyTrustType<core::Object>(js_2::globalThis, "B"), "staticSetter", b2);
a = js_2::getProperty<self::A>(js_2::_getPropertyTrustType<core::Object>(_js2::staticInteropGlobalContext, "B"), "staticField");
js_2::setProperty<self::A>(js_2::_getPropertyTrustType<core::Object>(_js2::staticInteropGlobalContext, "B"), "staticField", a);
a = js_2::_callMethodUnchecked0<self::A>(js_2::_getPropertyTrustType<core::Object>(_js2::staticInteropGlobalContext, "B"), "staticMethod");
b2 = js_2::callMethod<self::B /* = self::A */>(js_2::_getPropertyTrustType<core::Object>(_js2::staticInteropGlobalContext, "B"), "staticGenericMethod", <dynamic>[b2]);
b1 = js_2::getProperty<self::B /* = self::A */>(js_2::_getPropertyTrustType<core::Object>(_js2::staticInteropGlobalContext, "B"), "staticGetter");
js_2::setProperty<self::B /* = self::A */>(js_2::_getPropertyTrustType<core::Object>(_js2::staticInteropGlobalContext, "B"), "staticSetter", b2);
}
constants {

View file

@ -5,6 +5,7 @@ import "dart:js_interop" as js_;
import "dart:_js_annotations" as _js;
import "dart:core" as core;
import "dart:js_util" as js_2;
import "dart:_js_helper" as _js2;
import "dart:js_interop";
@ -40,10 +41,10 @@ extension type B(self::A a) {
}
external static inline-class-member method B|(self::A a) → self::B /* = self::A */;
static inline-class-member method B|_#new#tearOff(self::A a) → self::B /* = self::A */
return js_2::_callConstructorUnchecked1<self::B /* = self::A */>(js_2::_getPropertyTrustType<core::Object>(js_2::globalThis, "B"), a);
return js_2::_callConstructorUnchecked1<self::B /* = self::A */>(js_2::_getPropertyTrustType<core::Object>(_js2::staticInteropGlobalContext, "B"), a);
external static inline-class-member method B|named(core::int i) → self::B /* = self::A */;
static inline-class-member method B|_#named#tearOff(core::int i) → self::B /* = self::A */
return js_2::_callConstructorUnchecked1<self::B /* = self::A */>(js_2::_getPropertyTrustType<core::Object>(js_2::globalThis, "B"), i);
return js_2::_callConstructorUnchecked1<self::B /* = self::A */>(js_2::_getPropertyTrustType<core::Object>(_js2::staticInteropGlobalContext, "B"), i);
external static inline-class-member method B|get#field(lowered self::A #this) → self::A;
external static inline-class-member method B|set#field(lowered self::A #this, self::A #externalFieldValue) → void;
external static inline-class-member method B|method(lowered final self::B /* = self::A */ #this) → self::A;
@ -61,20 +62,20 @@ external static inline-class-member method B|staticGenericMethod<T extends self:
external static inline-class-member get B|staticGetter() → self::B /* = self::A */;
external static inline-class-member set B|staticSetter(self::B /* = self::A */ b) → void;
static method method(self::A a) → void {
self::B /* = self::A */ b1 = js_2::_callConstructorUnchecked1<self::B /* = self::A */>(js_2::_getPropertyTrustType<core::Object>(js_2::globalThis, "B"), a);
self::B /* = self::A */ b2 = js_2::_callConstructorUnchecked1<self::B /* = self::A */>(js_2::_getPropertyTrustType<core::Object>(js_2::globalThis, "B"), 0);
self::B /* = self::A */ b1 = js_2::_callConstructorUnchecked1<self::B /* = self::A */>(js_2::_getPropertyTrustType<core::Object>(_js2::staticInteropGlobalContext, "B"), a);
self::B /* = self::A */ b2 = js_2::_callConstructorUnchecked1<self::B /* = self::A */>(js_2::_getPropertyTrustType<core::Object>(_js2::staticInteropGlobalContext, "B"), 0);
a = js_2::getProperty<self::A>(b1, "field");
js_2::setProperty<self::A>(b1, "field", a);
a = js_2::_callMethodUnchecked0<self::A>(b1, "method");
b2 = js_2::callMethod<self::B /* = self::A */>(b2, "genericMethod", <dynamic>[b2]);
b1 = js_2::getProperty<self::B /* = self::A */>(b2, "getter");
js_2::setProperty<self::B /* = self::A */>(b1, "setter", b2);
a = js_2::getProperty<self::A>(js_2::_getPropertyTrustType<core::Object>(js_2::globalThis, "B"), "staticField");
js_2::setProperty<self::A>(js_2::_getPropertyTrustType<core::Object>(js_2::globalThis, "B"), "staticField", a);
a = js_2::_callMethodUnchecked0<self::A>(js_2::_getPropertyTrustType<core::Object>(js_2::globalThis, "B"), "staticMethod");
b2 = js_2::callMethod<self::B /* = self::A */>(js_2::_getPropertyTrustType<core::Object>(js_2::globalThis, "B"), "staticGenericMethod", <dynamic>[b2]);
b1 = js_2::getProperty<self::B /* = self::A */>(js_2::_getPropertyTrustType<core::Object>(js_2::globalThis, "B"), "staticGetter");
js_2::setProperty<self::B /* = self::A */>(js_2::_getPropertyTrustType<core::Object>(js_2::globalThis, "B"), "staticSetter", b2);
a = js_2::getProperty<self::A>(js_2::_getPropertyTrustType<core::Object>(_js2::staticInteropGlobalContext, "B"), "staticField");
js_2::setProperty<self::A>(js_2::_getPropertyTrustType<core::Object>(_js2::staticInteropGlobalContext, "B"), "staticField", a);
a = js_2::_callMethodUnchecked0<self::A>(js_2::_getPropertyTrustType<core::Object>(_js2::staticInteropGlobalContext, "B"), "staticMethod");
b2 = js_2::callMethod<self::B /* = self::A */>(js_2::_getPropertyTrustType<core::Object>(_js2::staticInteropGlobalContext, "B"), "staticGenericMethod", <dynamic>[b2]);
b1 = js_2::getProperty<self::B /* = self::A */>(js_2::_getPropertyTrustType<core::Object>(_js2::staticInteropGlobalContext, "B"), "staticGetter");
js_2::setProperty<self::B /* = self::A */>(js_2::_getPropertyTrustType<core::Object>(_js2::staticInteropGlobalContext, "B"), "staticSetter", b2);
}
constants {

View file

@ -5,6 +5,7 @@ import "dart:js_interop" as js_;
import "dart:_js_annotations" as _js;
import "dart:core" as core;
import "dart:js_util" as js_2;
import "dart:_js_helper" as _js2;
import "dart:js_interop";
@ -40,10 +41,10 @@ extension type B(self::A a) {
}
external static inline-class-member method B|(self::A a) → self::B /* = self::A */;
static inline-class-member method B|_#new#tearOff(self::A a) → self::B /* = self::A */
return js_2::_callConstructorUnchecked1<self::B /* = self::A */>(js_2::_getPropertyTrustType<core::Object>(js_2::globalThis, "B"), a);
return js_2::_callConstructorUnchecked1<self::B /* = self::A */>(js_2::_getPropertyTrustType<core::Object>(_js2::staticInteropGlobalContext, "B"), a);
external static inline-class-member method B|named(core::int i) → self::B /* = self::A */;
static inline-class-member method B|_#named#tearOff(core::int i) → self::B /* = self::A */
return js_2::_callConstructorUnchecked1<self::B /* = self::A */>(js_2::_getPropertyTrustType<core::Object>(js_2::globalThis, "B"), i);
return js_2::_callConstructorUnchecked1<self::B /* = self::A */>(js_2::_getPropertyTrustType<core::Object>(_js2::staticInteropGlobalContext, "B"), i);
external static inline-class-member method B|get#field(lowered self::A #this) → self::A;
external static inline-class-member method B|set#field(lowered self::A #this, self::A #externalFieldValue) → void;
external static inline-class-member method B|method(lowered final self::B /* = self::A */ #this) → self::A;
@ -61,20 +62,20 @@ external static inline-class-member method B|staticGenericMethod<T extends self:
external static inline-class-member get B|staticGetter() → self::B /* = self::A */;
external static inline-class-member set B|staticSetter(self::B /* = self::A */ b) → void;
static method method(self::A a) → void {
self::B /* = self::A */ b1 = js_2::_callConstructorUnchecked1<self::B /* = self::A */>(js_2::_getPropertyTrustType<core::Object>(js_2::globalThis, "B"), a);
self::B /* = self::A */ b2 = js_2::_callConstructorUnchecked1<self::B /* = self::A */>(js_2::_getPropertyTrustType<core::Object>(js_2::globalThis, "B"), 0);
self::B /* = self::A */ b1 = js_2::_callConstructorUnchecked1<self::B /* = self::A */>(js_2::_getPropertyTrustType<core::Object>(_js2::staticInteropGlobalContext, "B"), a);
self::B /* = self::A */ b2 = js_2::_callConstructorUnchecked1<self::B /* = self::A */>(js_2::_getPropertyTrustType<core::Object>(_js2::staticInteropGlobalContext, "B"), 0);
a = js_2::getProperty<self::A>(b1, "field");
js_2::setProperty<self::A>(b1, "field", a);
a = js_2::_callMethodUnchecked0<self::A>(b1, "method");
b2 = js_2::callMethod<self::B /* = self::A */>(b2, "genericMethod", <dynamic>[b2]);
b1 = js_2::getProperty<self::B /* = self::A */>(b2, "getter");
js_2::setProperty<self::B /* = self::A */>(b1, "setter", b2);
a = js_2::getProperty<self::A>(js_2::_getPropertyTrustType<core::Object>(js_2::globalThis, "B"), "staticField");
js_2::setProperty<self::A>(js_2::_getPropertyTrustType<core::Object>(js_2::globalThis, "B"), "staticField", a);
a = js_2::_callMethodUnchecked0<self::A>(js_2::_getPropertyTrustType<core::Object>(js_2::globalThis, "B"), "staticMethod");
b2 = js_2::callMethod<self::B /* = self::A */>(js_2::_getPropertyTrustType<core::Object>(js_2::globalThis, "B"), "staticGenericMethod", <dynamic>[b2]);
b1 = js_2::getProperty<self::B /* = self::A */>(js_2::_getPropertyTrustType<core::Object>(js_2::globalThis, "B"), "staticGetter");
js_2::setProperty<self::B /* = self::A */>(js_2::_getPropertyTrustType<core::Object>(js_2::globalThis, "B"), "staticSetter", b2);
a = js_2::getProperty<self::A>(js_2::_getPropertyTrustType<core::Object>(_js2::staticInteropGlobalContext, "B"), "staticField");
js_2::setProperty<self::A>(js_2::_getPropertyTrustType<core::Object>(_js2::staticInteropGlobalContext, "B"), "staticField", a);
a = js_2::_callMethodUnchecked0<self::A>(js_2::_getPropertyTrustType<core::Object>(_js2::staticInteropGlobalContext, "B"), "staticMethod");
b2 = js_2::callMethod<self::B /* = self::A */>(js_2::_getPropertyTrustType<core::Object>(_js2::staticInteropGlobalContext, "B"), "staticGenericMethod", <dynamic>[b2]);
b1 = js_2::getProperty<self::B /* = self::A */>(js_2::_getPropertyTrustType<core::Object>(_js2::staticInteropGlobalContext, "B"), "staticGetter");
js_2::setProperty<self::B /* = self::A */>(js_2::_getPropertyTrustType<core::Object>(_js2::staticInteropGlobalContext, "B"), "staticSetter", b2);
}
constants {

View file

@ -15,6 +15,7 @@ import self as sta;
import "dart:_js_annotations" as _js;
import "dart:core" as core;
import "dart:js_util" as js_;
import "dart:_js_helper" as _js2;
import "package:js/js.dart";
@ -23,9 +24,9 @@ import "package:js/js.dart";
class StaticJSClass extends core::Object {
external static factory •() → sta::StaticJSClass;
static method _#new#tearOff() → sta::StaticJSClass
return js_::_callConstructorUnchecked0<sta::StaticJSClass>(js_::_getPropertyTrustType<core::Object>(js_::globalThis, "JSClass"));
return js_::_callConstructorUnchecked0<sta::StaticJSClass>(js_::_getPropertyTrustType<core::Object>(_js2::staticInteropGlobalContext, "JSClass"));
static factory factory() → sta::StaticJSClass {
return js_::_callConstructorUnchecked0<sta::StaticJSClass>(js_::_getPropertyTrustType<core::Object>(js_::globalThis, "JSClass"));
return js_::_callConstructorUnchecked0<sta::StaticJSClass>(js_::_getPropertyTrustType<core::Object>(_js2::staticInteropGlobalContext, "JSClass"));
}
static method _#factory#tearOff() → sta::StaticJSClass
return sta::StaticJSClass::factory();

View file

@ -15,6 +15,7 @@ import self as sta;
import "dart:_js_annotations" as _js;
import "dart:core" as core;
import "dart:js_util" as js_;
import "dart:_js_helper" as _js2;
import "package:js/js.dart";
@ -23,9 +24,9 @@ import "package:js/js.dart";
class StaticJSClass extends core::Object {
external static factory •() → sta::StaticJSClass;
static method _#new#tearOff() → sta::StaticJSClass
return js_::_callConstructorUnchecked0<sta::StaticJSClass>(js_::_getPropertyTrustType<core::Object>(js_::globalThis, "JSClass"));
return js_::_callConstructorUnchecked0<sta::StaticJSClass>(js_::_getPropertyTrustType<core::Object>(_js2::staticInteropGlobalContext, "JSClass"));
static factory factory() → sta::StaticJSClass {
return js_::_callConstructorUnchecked0<sta::StaticJSClass>(js_::_getPropertyTrustType<core::Object>(js_::globalThis, "JSClass"));
return js_::_callConstructorUnchecked0<sta::StaticJSClass>(js_::_getPropertyTrustType<core::Object>(_js2::staticInteropGlobalContext, "JSClass"));
}
static method _#factory#tearOff() → sta::StaticJSClass
return sta::StaticJSClass::factory();

View file

@ -15,6 +15,7 @@ import self as sta;
import "dart:_js_annotations" as _js;
import "dart:core" as core;
import "dart:js_util" as js_;
import "dart:_js_helper" as _js2;
import "package:js/js.dart";
@ -23,9 +24,9 @@ import "package:js/js.dart";
class StaticJSClass extends core::Object {
external static factory •() → sta::StaticJSClass;
static method _#new#tearOff() → sta::StaticJSClass
return js_::_callConstructorUnchecked0<sta::StaticJSClass>(js_::_getPropertyTrustType<core::Object>(js_::globalThis, "JSClass"));
return js_::_callConstructorUnchecked0<sta::StaticJSClass>(js_::_getPropertyTrustType<core::Object>(_js2::staticInteropGlobalContext, "JSClass"));
static factory factory() → sta::StaticJSClass {
return js_::_callConstructorUnchecked0<sta::StaticJSClass>(js_::_getPropertyTrustType<core::Object>(js_::globalThis, "JSClass"));
return js_::_callConstructorUnchecked0<sta::StaticJSClass>(js_::_getPropertyTrustType<core::Object>(_js2::staticInteropGlobalContext, "JSClass"));
}
static method _#factory#tearOff() → sta::StaticJSClass
return sta::StaticJSClass::factory();

View file

@ -12,6 +12,7 @@ import self as self2;
import "dart:_js_annotations" as _js;
import "dart:core" as core;
import "dart:js_util" as js_;
import "dart:_js_helper" as _js2;
import "package:js/js.dart";
@ -20,7 +21,7 @@ import "package:js/js.dart";
class StaticJSClass extends core::Object {
external static factory •() → self2::StaticJSClass;
static method _#new#tearOff() → self2::StaticJSClass
return js_::_callConstructorUnchecked0<self2::StaticJSClass>(js_::_getPropertyTrustType<core::Object>(js_::globalThis, "JSClass"));
return js_::_callConstructorUnchecked0<self2::StaticJSClass>(js_::_getPropertyTrustType<core::Object>(_js2::staticInteropGlobalContext, "JSClass"));
static factory factory() → self2::StaticJSClass
;
static method _#factory#tearOff() → self2::StaticJSClass

View file

@ -15,6 +15,7 @@ import self as sta;
import "dart:_js_annotations" as _js;
import "dart:core" as core;
import "dart:js_util" as js_;
import "dart:_js_helper" as _js2;
import "package:js/js.dart";
@ -23,9 +24,9 @@ import "package:js/js.dart";
class StaticJSClass extends core::Object {
external static factory •() → sta::StaticJSClass;
static method _#new#tearOff() → sta::StaticJSClass
return js_::_callConstructorUnchecked0<sta::StaticJSClass>(js_::_getPropertyTrustType<core::Object>(js_::globalThis, "JSClass"));
return js_::_callConstructorUnchecked0<sta::StaticJSClass>(js_::_getPropertyTrustType<core::Object>(_js2::staticInteropGlobalContext, "JSClass"));
static factory factory() → sta::StaticJSClass {
return js_::_callConstructorUnchecked0<sta::StaticJSClass>(js_::_getPropertyTrustType<core::Object>(js_::globalThis, "JSClass"));
return js_::_callConstructorUnchecked0<sta::StaticJSClass>(js_::_getPropertyTrustType<core::Object>(_js2::staticInteropGlobalContext, "JSClass"));
}
static method _#factory#tearOff() → sta::StaticJSClass
return sta::StaticJSClass::factory();

View file

@ -17,20 +17,20 @@ library from "org-dartlang-test:///lib1.dart" as lib1 {
method instanceMethod() → sta::StaticJSClass
return sta::StaticJSClass::factory();
get instanceGetter() → sta::StaticJSClass
return dart.js_util::_callConstructorUnchecked0<sta::StaticJSClass>(dart.js_util::_getPropertyTrustType<dart.core::Object>(dart.js_util::globalThis, "JSClass"));
return dart.js_util::_callConstructorUnchecked0<sta::StaticJSClass>(dart.js_util::_getPropertyTrustType<dart.core::Object>(dart._js_helper::staticInteropGlobalContext, "JSClass"));
set instanceSetter((sta::StaticJSClass) → void f) → void {}
static method staticMethod() → sta::StaticJSClass
return sta::StaticJSClass::factory();
static get staticGetter() → sta::StaticJSClass
return dart.js_util::_callConstructorUnchecked0<sta::StaticJSClass>(dart.js_util::_getPropertyTrustType<dart.core::Object>(dart.js_util::globalThis, "JSClass"));
return dart.js_util::_callConstructorUnchecked0<sta::StaticJSClass>(dart.js_util::_getPropertyTrustType<dart.core::Object>(dart._js_helper::staticInteropGlobalContext, "JSClass"));
static set staticSetter((sta::StaticJSClass) → void f) → void {}
static method _#new#tearOff() → lib1::Class
return new lib1::Class::•();
}
static method topLevelMethod() → sta::StaticJSClass
return dart.js_util::_callConstructorUnchecked0<sta::StaticJSClass>(dart.js_util::_getPropertyTrustType<dart.core::Object>(dart.js_util::globalThis, "JSClass"));
return dart.js_util::_callConstructorUnchecked0<sta::StaticJSClass>(dart.js_util::_getPropertyTrustType<dart.core::Object>(dart._js_helper::staticInteropGlobalContext, "JSClass"));
static get topLevelGetter() → sta::StaticJSClass
return dart.js_util::_callConstructorUnchecked0<sta::StaticJSClass>(dart.js_util::_getPropertyTrustType<dart.core::Object>(dart.js_util::globalThis, "JSClass"));
return dart.js_util::_callConstructorUnchecked0<sta::StaticJSClass>(dart.js_util::_getPropertyTrustType<dart.core::Object>(dart._js_helper::staticInteropGlobalContext, "JSClass"));
static set topLevelSetter((sta::StaticJSClass) → void f) → void {}
}
@#C2
@ -43,9 +43,9 @@ library static_interop from "org-dartlang-test:///lib2.dart" as sta {
class StaticJSClass extends dart.core::Object {
external static factory •() → sta::StaticJSClass;
static method _#new#tearOff() → sta::StaticJSClass
return dart.js_util::_callConstructorUnchecked0<sta::StaticJSClass>(dart.js_util::_getPropertyTrustType<dart.core::Object>(dart.js_util::globalThis, "JSClass"));
return dart.js_util::_callConstructorUnchecked0<sta::StaticJSClass>(dart.js_util::_getPropertyTrustType<dart.core::Object>(dart._js_helper::staticInteropGlobalContext, "JSClass"));
static factory factory() → sta::StaticJSClass {
return dart.js_util::_callConstructorUnchecked0<sta::StaticJSClass>(dart.js_util::_getPropertyTrustType<dart.core::Object>(dart.js_util::globalThis, "JSClass"));
return dart.js_util::_callConstructorUnchecked0<sta::StaticJSClass>(dart.js_util::_getPropertyTrustType<dart.core::Object>(dart._js_helper::staticInteropGlobalContext, "JSClass"));
}
static method _#factory#tearOff() → sta::StaticJSClass
return sta::StaticJSClass::factory();

View file

@ -17,20 +17,20 @@ library from "org-dartlang-test:///lib1.dart" as lib1 {
method instanceMethod() → sta::StaticJSClass
return sta::StaticJSClass::factory();
get instanceGetter() → sta::StaticJSClass
return dart.js_util::_callConstructorUnchecked0<sta::StaticJSClass>(dart.js_util::_getPropertyTrustType<dart.core::Object>(dart.js_util::globalThis, "JSClass"));
return dart.js_util::_callConstructorUnchecked0<sta::StaticJSClass>(dart.js_util::_getPropertyTrustType<dart.core::Object>(dart._js_helper::staticInteropGlobalContext, "JSClass"));
set instanceSetter((sta::StaticJSClass) → void f) → void {}
static method staticMethod() → sta::StaticJSClass
return sta::StaticJSClass::factory();
static get staticGetter() → sta::StaticJSClass
return dart.js_util::_callConstructorUnchecked0<sta::StaticJSClass>(dart.js_util::_getPropertyTrustType<dart.core::Object>(dart.js_util::globalThis, "JSClass"));
return dart.js_util::_callConstructorUnchecked0<sta::StaticJSClass>(dart.js_util::_getPropertyTrustType<dart.core::Object>(dart._js_helper::staticInteropGlobalContext, "JSClass"));
static set staticSetter((sta::StaticJSClass) → void f) → void {}
static method _#new#tearOff() → lib1::Class
return new lib1::Class::•();
}
static method topLevelMethod() → sta::StaticJSClass
return dart.js_util::_callConstructorUnchecked0<sta::StaticJSClass>(dart.js_util::_getPropertyTrustType<dart.core::Object>(dart.js_util::globalThis, "JSClass"));
return dart.js_util::_callConstructorUnchecked0<sta::StaticJSClass>(dart.js_util::_getPropertyTrustType<dart.core::Object>(dart._js_helper::staticInteropGlobalContext, "JSClass"));
static get topLevelGetter() → sta::StaticJSClass
return dart.js_util::_callConstructorUnchecked0<sta::StaticJSClass>(dart.js_util::_getPropertyTrustType<dart.core::Object>(dart.js_util::globalThis, "JSClass"));
return dart.js_util::_callConstructorUnchecked0<sta::StaticJSClass>(dart.js_util::_getPropertyTrustType<dart.core::Object>(dart._js_helper::staticInteropGlobalContext, "JSClass"));
static set topLevelSetter((sta::StaticJSClass) → void f) → void {}
}
@#C2
@ -43,9 +43,9 @@ library static_interop from "org-dartlang-test:///lib2.dart" as sta {
class StaticJSClass extends dart.core::Object {
external static factory •() → sta::StaticJSClass;
static method _#new#tearOff() → sta::StaticJSClass
return dart.js_util::_callConstructorUnchecked0<sta::StaticJSClass>(dart.js_util::_getPropertyTrustType<dart.core::Object>(dart.js_util::globalThis, "JSClass"));
return dart.js_util::_callConstructorUnchecked0<sta::StaticJSClass>(dart.js_util::_getPropertyTrustType<dart.core::Object>(dart._js_helper::staticInteropGlobalContext, "JSClass"));
static factory factory() → sta::StaticJSClass {
return dart.js_util::_callConstructorUnchecked0<sta::StaticJSClass>(dart.js_util::_getPropertyTrustType<dart.core::Object>(dart.js_util::globalThis, "JSClass"));
return dart.js_util::_callConstructorUnchecked0<sta::StaticJSClass>(dart.js_util::_getPropertyTrustType<dart.core::Object>(dart._js_helper::staticInteropGlobalContext, "JSClass"));
}
static method _#factory#tearOff() → sta::StaticJSClass
return sta::StaticJSClass::factory();

View file

@ -977,3 +977,22 @@ external Object? jsObjectGetPrototypeOf(@notNull Object obj);
/// See: https://github.com/tc39/proposal-symbol-proto
@notNull
external Object jsObjectSetPrototypeOf(@notNull Object obj, Object? prototype);
/// The global context that "static interop" members use for namespaces.
///
/// For example, an interop library with no library-level `@JS` annotation and a
/// top-level external member named or renamed to 'foo' will lower a call to
/// that member as `<staticInteropGlobalContext>.foo`. The same applies for any
/// external constructors or class/extension type static members.
///
/// If the library does have a `@JS` annotation with a value, the call then gets
/// lowered to `<staticInteropGlobalContext>.<libraryJSAnnotationValue>.foo`.
///
/// To see which members get lowered with this, see the transformation in
/// `pkg/_js_interop_checks/lib/src/js_util_optimizer.dart`.
///
/// This should match the global context that non-static interop members use.
/// Note that this is external. We could implement it here, but DDC will not
/// inline the call so this will be an extra level of indirection. DDC manually
/// inlines this method in the compiler instead.
external Object get staticInteropGlobalContext;

View file

@ -3352,3 +3352,20 @@ void Function(T)? wrapZoneUnaryCallback<T>(void Function(T)? callback) {
// TODO(48585): Move this class back to the dart:_rti library when old DDC
// runtime type system has been removed.
abstract class TrustedGetRuntimeType {}
/// The global context that "static interop" members use for namespaces.
///
/// For example, an interop library with no library-level `@JS` annotation and a
/// top-level external member named or renamed to 'foo' will lower a call to
/// that member as `<staticInteropGlobalContext>.foo`. The same applies for any
/// external constructors or class/extension type static members.
///
/// If the library does have a `@JS` annotation with a value, the call then gets
/// lowered to `<staticInteropGlobalContext>.<libraryJSAnnotationValue>.foo`.
///
/// To see which members get lowered with this, see the transformation in
/// `pkg/_js_interop_checks/lib/src/js_util_optimizer.dart`.
///
/// This should match the global context that non-static interop members use.
Object get staticInteropGlobalContext =>
JS('creates:;returns:Object;depends:none;effects:none;gvn:true', 'self');