mirror of
https://github.com/dart-lang/sdk
synced 2024-10-06 13:08:01 +00:00
[dart:js_interop] Re-enable type checks on external APIs
External APIs when using dart:js_interop should only allow primitives, JS types, and other static interop types. This was previously checked in a more restrictive mode called "strict mode" but is not checked everywhere where dart:js_interop APIs exist. Change-Id: Ic82a3ec0bf6062c25d7f8933e503820a21bc191f Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/316867 Reviewed-by: Sigmund Cherem <sigmund@google.com> Commit-Queue: Srujan Gaddam <srujzs@google.com>
This commit is contained in:
parent
cf5336c244
commit
2a669c571f
|
@ -96,7 +96,7 @@ constraint][language version] lower bound to 3.2 or greater (`sdk: '^3.2.0'`).
|
|||
|
||||
#### `dart:js_interop`
|
||||
|
||||
- **JSNumber.toDart and Object.toJS**:
|
||||
- **Breaking Change on JSNumber.toDart and Object.toJS**:
|
||||
`JSNumber.toDart` is removed in favor of `toDartDouble` and `toDartInt` to
|
||||
make the type explicit. `Object.toJS` is also removed in favor of
|
||||
`Object.toJSBox`. Previously, this function would allow Dart objects to flow
|
||||
|
@ -128,6 +128,11 @@ constraint][language version] lower bound to 3.2 or greater (`sdk: '^3.2.0'`).
|
|||
number of cases, like when using older browser versions. `dart:js_interop`'s
|
||||
`globalJSObject` is also renamed to `globalContext` and returns the global
|
||||
context used in the lowerings.
|
||||
- **Breaking Change on Types of `dart:js_interop` External APIs**:
|
||||
External JS interop APIs when using `dart:js_interop` are restricted to a set
|
||||
of allowed types. Namely, this include the primitive types like `String`, JS
|
||||
types from `dart:js_interop`, and other static interop types (either through
|
||||
`@staticInterop` or extension types).
|
||||
|
||||
### Tools
|
||||
|
||||
|
|
|
@ -48,7 +48,7 @@ import 'package:front_end/src/fasta/fasta_codes.dart'
|
|||
show
|
||||
templateJsInteropExtensionTypeNotInterop,
|
||||
templateJsInteropFunctionToJSRequiresStaticType,
|
||||
templateJsInteropStrictModeViolation;
|
||||
templateJsInteropStaticInteropExternalTypeViolation;
|
||||
|
||||
import 'package:kernel/class_hierarchy.dart';
|
||||
import 'package:kernel/core_types.dart';
|
||||
|
@ -73,18 +73,12 @@ class JsInteropChecks extends RecursiveVisitor {
|
|||
bool _classHasJSAnnotation = false;
|
||||
bool _classHasAnonymousAnnotation = false;
|
||||
bool _classHasStaticInteropAnnotation = false;
|
||||
final _checkDisallowedInterop = false;
|
||||
bool _inTearoff = false;
|
||||
bool _libraryHasDartJSInteropAnnotation = false;
|
||||
bool _libraryHasJSAnnotation = false;
|
||||
bool _libraryIsGlobalNamespace = false;
|
||||
|
||||
// TODO(joshualitt): Today strict mode is just for testing, but we should find
|
||||
// a way to expose this to users who want strict mode guarantees.
|
||||
bool _enforceStrictMode = false;
|
||||
|
||||
/// If [enableStrictMode] is true, then static interop methods must use JS
|
||||
/// types.
|
||||
final bool enableStrictMode;
|
||||
final ExportChecker exportChecker;
|
||||
final bool isDart2Wasm;
|
||||
|
||||
|
@ -144,7 +138,7 @@ class JsInteropChecks extends RecursiveVisitor {
|
|||
|
||||
JsInteropChecks(this._coreTypes, ClassHierarchy hierarchy, this._reporter,
|
||||
this._nativeClasses,
|
||||
{this.isDart2Wasm = false, this.enableStrictMode = false})
|
||||
{this.isDart2Wasm = false})
|
||||
: exportChecker = ExportChecker(_reporter, _coreTypes.objectClass),
|
||||
_functionToJSTarget = _coreTypes.index.getTopLevelProcedure(
|
||||
'dart:js_interop', 'FunctionToJSExportedDartFunction|get#toJS'),
|
||||
|
@ -303,11 +297,11 @@ class JsInteropChecks extends RecursiveVisitor {
|
|||
_libraryHasJSAnnotation =
|
||||
_libraryHasDartJSInteropAnnotation || hasJSInteropAnnotation(node);
|
||||
_libraryIsGlobalNamespace = _isLibraryGlobalNamespace(node);
|
||||
_enforceStrictMode = _shouldEnforceStrictMode(node);
|
||||
|
||||
if (_enforceStrictMode && !node.importUri.isScheme('dart')) {
|
||||
_checkDisallowedLibrariesInStrictMode(node);
|
||||
}
|
||||
// TODO(srujzs): Should we still keep around this check? Currently, it's
|
||||
// unused since we allow the old interop on dart2wasm, but we should
|
||||
// disallow them eventually.
|
||||
if (_checkDisallowedInterop) _checkDisallowedLibrariesForDart2Wasm(node);
|
||||
|
||||
super.visitLibrary(node);
|
||||
exportChecker.visitLibrary(node);
|
||||
|
@ -364,18 +358,6 @@ class JsInteropChecks extends RecursiveVisitor {
|
|||
report(messageJsInteropInvalidStaticClassMemberName);
|
||||
}
|
||||
|
||||
// In strict mode, check all types are JS types.
|
||||
if (enableStrictMode) {
|
||||
final function = node.function;
|
||||
_reportProcedureIfNotJSType(function.returnType, node);
|
||||
for (final parameter in function.positionalParameters) {
|
||||
_reportProcedureIfNotJSType(parameter.type, node);
|
||||
}
|
||||
for (final parameter in function.namedParameters) {
|
||||
_reportProcedureIfNotJSType(parameter.type, node);
|
||||
}
|
||||
}
|
||||
|
||||
if (_classHasStaticInteropAnnotation ||
|
||||
node.isExtensionTypeMember ||
|
||||
node.isExtensionMember ||
|
||||
|
@ -403,8 +385,16 @@ class JsInteropChecks extends RecursiveVisitor {
|
|||
if (annotatable == null ||
|
||||
((hasDartJSInteropAnnotation(annotatable) ||
|
||||
annotatable is ExtensionTypeDeclaration))) {
|
||||
// Only restrict type parameters for dart:js_interop.
|
||||
// Checks for dart:js_interop APIs only.
|
||||
_checkStaticInteropMemberUsesValidTypeParameters(node);
|
||||
final function = node.function;
|
||||
_reportProcedureIfNotAllowedType(function.returnType, node);
|
||||
for (final parameter in function.positionalParameters) {
|
||||
_reportProcedureIfNotAllowedType(parameter.type, node);
|
||||
}
|
||||
for (final parameter in function.namedParameters) {
|
||||
_reportProcedureIfNotAllowedType(parameter.type, node);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -530,14 +520,7 @@ class JsInteropChecks extends RecursiveVisitor {
|
|||
|
||||
// JS interop library checks
|
||||
|
||||
/// Determine if [node] enforces strict mode checking. This is currently only
|
||||
/// enabled for testing.
|
||||
bool _shouldEnforceStrictMode(Library node) {
|
||||
return node.fileUri.toString().contains(RegExp(
|
||||
r'(?<!generated_)tests/lib/js/static_interop_test/strict_mode_test.dart'));
|
||||
}
|
||||
|
||||
void _checkDisallowedLibrariesInStrictMode(Library node) {
|
||||
void _checkDisallowedLibrariesForDart2Wasm(Library node) {
|
||||
for (final dependency in node.dependencies) {
|
||||
final dependencyUriString = dependency.targetLibrary.importUri.toString();
|
||||
if (_disallowedLibrariesInStrictMode.contains(dependencyUriString)) {
|
||||
|
@ -735,9 +718,9 @@ class JsInteropChecks extends RecursiveVisitor {
|
|||
node.name.text.length,
|
||||
node.location?.file);
|
||||
} else {
|
||||
_reportStaticInvocationIfNotJSType(functionType.returnType, node);
|
||||
_reportStaticInvocationIfNotAllowedType(functionType.returnType, node);
|
||||
for (final parameter in functionType.positionalParameters) {
|
||||
_reportStaticInvocationIfNotJSType(parameter, node);
|
||||
_reportStaticInvocationIfNotAllowedType(parameter, node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -946,8 +929,7 @@ class JsInteropChecks extends RecursiveVisitor {
|
|||
return false;
|
||||
}
|
||||
|
||||
void _reportIfNotJSType(
|
||||
DartType type, TreeNode node, Name name, Uri? fileUri) {
|
||||
bool _isAllowedExternalType(DartType type) {
|
||||
// TODO(joshualitt): We allow only JS types on external JS interop APIs with
|
||||
// two exceptions: `void` and `Null`. Both of these exceptions exist largely
|
||||
// to support passing Dart functions to JS as callbacks. Furthermore, both
|
||||
|
@ -955,28 +937,54 @@ class JsInteropChecks extends RecursiveVisitor {
|
|||
// said, for completeness, we may restrict these two types someday, and
|
||||
// provide JS types equivalents, but likely only if we have implicit
|
||||
// conversions between Dart types and JS types.
|
||||
if (_enforceStrictMode &&
|
||||
!(type is VoidType ||
|
||||
type is NullType ||
|
||||
(type is InterfaceType &&
|
||||
hasStaticInteropAnnotation(type.classNode)) ||
|
||||
(type is ExtensionType &&
|
||||
_extensionIndex
|
||||
.isInteropExtensionType(type.extensionTypeDeclaration)))) {
|
||||
|
||||
// Type parameter types are checked elsewhere.
|
||||
if (type is VoidType || type is NullType || type is TypeParameterType) {
|
||||
return true;
|
||||
}
|
||||
if (type is InterfaceType) {
|
||||
final cls = type.classNode;
|
||||
if (cls == _coreTypes.boolClass ||
|
||||
cls == _coreTypes.numClass ||
|
||||
cls == _coreTypes.doubleClass ||
|
||||
cls == _coreTypes.intClass ||
|
||||
cls == _coreTypes.stringClass) {
|
||||
return true;
|
||||
}
|
||||
if (hasStaticInteropAnnotation(cls)) return true;
|
||||
}
|
||||
if (type is ExtensionType) {
|
||||
if (_extensionIndex
|
||||
.isInteropExtensionType(type.extensionTypeDeclaration)) {
|
||||
return true;
|
||||
}
|
||||
// Extension types where the representation type is allowed are okay.
|
||||
// TODO(srujzs): Once the CFE pre-computes the concrete type, don't
|
||||
// recurse.
|
||||
return _isAllowedExternalType(type.typeErasure);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void _reportIfNotAllowedExternalType(
|
||||
DartType type, TreeNode node, Name name, Uri? fileUri) {
|
||||
if (!_isAllowedExternalType(type)) {
|
||||
_reporter.report(
|
||||
templateJsInteropStrictModeViolation.withArguments(type, true),
|
||||
templateJsInteropStaticInteropExternalTypeViolation.withArguments(
|
||||
type, true),
|
||||
node.fileOffset,
|
||||
name.text.length,
|
||||
fileUri);
|
||||
}
|
||||
}
|
||||
|
||||
void _reportProcedureIfNotJSType(DartType type, Procedure node) =>
|
||||
_reportIfNotJSType(type, node, node.name, node.fileUri);
|
||||
void _reportProcedureIfNotAllowedType(DartType type, Procedure node) =>
|
||||
_reportIfNotAllowedExternalType(type, node, node.name, node.fileUri);
|
||||
|
||||
void _reportStaticInvocationIfNotJSType(
|
||||
void _reportStaticInvocationIfNotAllowedType(
|
||||
DartType type, StaticInvocation node) =>
|
||||
_reportIfNotJSType(type, node, node.name, node.location?.file);
|
||||
_reportIfNotAllowedExternalType(
|
||||
type, node, node.name, node.location?.file);
|
||||
}
|
||||
|
||||
/// Visitor used to check that all usages of type parameter types of an external
|
||||
|
|
|
@ -166,7 +166,7 @@ class WasmTarget extends Target {
|
|||
diagnosticReporter as DiagnosticReporter<Message, LocatedMessage>);
|
||||
final jsInteropChecks = JsInteropChecks(
|
||||
coreTypes, hierarchy, jsInteropReporter, _nativeClasses!,
|
||||
isDart2Wasm: true, enableStrictMode: true);
|
||||
isDart2Wasm: true);
|
||||
// Process and validate first before doing anything with exports.
|
||||
for (Library library in interopDependentLibraries) {
|
||||
jsInteropChecks.visitLibrary(library);
|
||||
|
|
|
@ -4108,6 +4108,38 @@ Message _withArgumentsJsInteropFunctionToJSRequiresStaticType(
|
|||
arguments: {'type': _type});
|
||||
}
|
||||
|
||||
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
|
||||
const Template<Message Function(DartType _type, bool isNonNullableByDefault)>
|
||||
templateJsInteropStaticInteropExternalTypeViolation = const Template<
|
||||
Message Function(DartType _type, bool isNonNullableByDefault)>(
|
||||
"JsInteropStaticInteropExternalTypeViolation",
|
||||
problemMessageTemplate:
|
||||
r"""Type '#type' is not a valid type for external `dart:js_interop` APIs. The only valid types are: @staticInterop types, JS types from `dart:js_interop`, void, bool, num, double, int, String, and any extension type that erases to one of these types.""",
|
||||
correctionMessageTemplate: r"""Use one of the valid types instead.""",
|
||||
withArguments:
|
||||
_withArgumentsJsInteropStaticInteropExternalTypeViolation);
|
||||
|
||||
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
|
||||
const Code<Message Function(DartType _type, bool isNonNullableByDefault)>
|
||||
codeJsInteropStaticInteropExternalTypeViolation =
|
||||
const Code<Message Function(DartType _type, bool isNonNullableByDefault)>(
|
||||
"JsInteropStaticInteropExternalTypeViolation",
|
||||
);
|
||||
|
||||
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
|
||||
Message _withArgumentsJsInteropStaticInteropExternalTypeViolation(
|
||||
DartType _type, bool isNonNullableByDefault) {
|
||||
TypeLabeler labeler = new TypeLabeler(isNonNullableByDefault);
|
||||
List<Object> typeParts = labeler.labelType(_type);
|
||||
String type = typeParts.join();
|
||||
return new Message(codeJsInteropStaticInteropExternalTypeViolation,
|
||||
problemMessage:
|
||||
"""Type '${type}' is not a valid type for external `dart:js_interop` APIs. The only valid types are: @staticInterop types, JS types from `dart:js_interop`, void, bool, num, double, int, String, and any extension type that erases to one of these types.""" +
|
||||
labeler.originMessages,
|
||||
correctionMessage: """Use one of the valid types instead.""",
|
||||
arguments: {'type': _type});
|
||||
}
|
||||
|
||||
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
|
||||
const Template<Message Function(DartType _type, bool isNonNullableByDefault)>
|
||||
templateJsInteropStaticInteropMockNotStaticInteropType = const Template<
|
||||
|
@ -4173,37 +4205,6 @@ Message _withArgumentsJsInteropStaticInteropMockTypeParametersNotAllowed(
|
|||
arguments: {'type': _type});
|
||||
}
|
||||
|
||||
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
|
||||
const Template<Message Function(DartType _type, bool isNonNullableByDefault)>
|
||||
templateJsInteropStrictModeViolation = const Template<
|
||||
Message Function(DartType _type, bool isNonNullableByDefault)>(
|
||||
"JsInteropStrictModeViolation",
|
||||
problemMessageTemplate:
|
||||
r"""JS interop requires JS types when strict mode is enabled, but Type '#type' is not a type or subtype of a type from `dart:js_interop`.""",
|
||||
correctionMessageTemplate: r"""Use a JS type instead.""",
|
||||
withArguments: _withArgumentsJsInteropStrictModeViolation);
|
||||
|
||||
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
|
||||
const Code<Message Function(DartType _type, bool isNonNullableByDefault)>
|
||||
codeJsInteropStrictModeViolation =
|
||||
const Code<Message Function(DartType _type, bool isNonNullableByDefault)>(
|
||||
"JsInteropStrictModeViolation",
|
||||
);
|
||||
|
||||
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
|
||||
Message _withArgumentsJsInteropStrictModeViolation(
|
||||
DartType _type, bool isNonNullableByDefault) {
|
||||
TypeLabeler labeler = new TypeLabeler(isNonNullableByDefault);
|
||||
List<Object> typeParts = labeler.labelType(_type);
|
||||
String type = typeParts.join();
|
||||
return new Message(codeJsInteropStrictModeViolation,
|
||||
problemMessage:
|
||||
"""JS interop requires JS types when strict mode is enabled, but Type '${type}' is not a type or subtype of a type from `dart:js_interop`.""" +
|
||||
labeler.originMessages,
|
||||
correctionMessage: """Use a JS type instead.""",
|
||||
arguments: {'type': _type});
|
||||
}
|
||||
|
||||
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
|
||||
const Template<
|
||||
Message Function(
|
||||
|
|
|
@ -624,6 +624,8 @@ JsInteropObjectLiteralConstructorPositionalParameters/analyzerCode: Fail # Web c
|
|||
JsInteropObjectLiteralConstructorPositionalParameters/example: Fail # Web compiler specific
|
||||
JsInteropStaticInteropExternalMemberWithInvalidTypeParameters/analyzerCode: Fail # Web compiler specific
|
||||
JsInteropStaticInteropExternalMemberWithInvalidTypeParameters/example: Fail # Web compiler specific
|
||||
JsInteropStaticInteropExternalTypeViolation/analyzerCode: Fail # Web compiler specific
|
||||
JsInteropStaticInteropExternalTypeViolation/example: Fail # Web compiler specific
|
||||
JsInteropStaticInteropGenerativeConstructor/analyzerCode: Fail # Web compiler specific
|
||||
JsInteropStaticInteropGenerativeConstructor/example: Fail # Web compiler specific
|
||||
JsInteropStaticInteropMockMissingGetterOrSetter/analyzerCode: Fail # Web compiler specific
|
||||
|
@ -654,8 +656,6 @@ JsInteropStaticInteropWithNonStaticSupertype/analyzerCode: Fail # Web compiler s
|
|||
JsInteropStaticInteropWithNonStaticSupertype/example: Fail # Web compiler specific
|
||||
JsInteropFunctionToJSRequiresStaticType/analyzerCode: Fail # Web compiler specific
|
||||
JsInteropFunctionToJSRequiresStaticType/example: Fail # Web compiler specific
|
||||
JsInteropStrictModeViolation/analyzerCode: Fail # Web compiler specific
|
||||
JsInteropStrictModeViolation/example: Fail # Web compiler specific
|
||||
JsInteropStrictModeForbiddenLibrary/analyzerCode: Fail # Web compiler specific
|
||||
JsInteropStrictModeForbiddenLibrary/example: Fail # Web compiler specific
|
||||
LanguageVersionInvalidInDotPackages/analyzerCode: Fail
|
||||
|
|
|
@ -5669,6 +5669,10 @@ JsInteropStaticInteropExternalMemberWithInvalidTypeParameters:
|
|||
problemMessage: "External static interop members can only use type parameters that extend either a static interop type or one of the 'dart:js_interop' types."
|
||||
correctionMessage: "Try adding a valid bound to the type parameters used in this member."
|
||||
|
||||
JsInteropStaticInteropExternalTypeViolation:
|
||||
problemMessage: "Type '#type' is not a valid type for external `dart:js_interop` APIs. The only valid types are: @staticInterop types, JS types from `dart:js_interop`, void, bool, num, double, int, String, and any extension type that erases to one of these types."
|
||||
correctionMessage: "Use one of the valid types instead."
|
||||
|
||||
JsInteropStaticInteropGenerativeConstructor:
|
||||
problemMessage: "`@staticInterop` classes should not contain any generative constructors."
|
||||
correctionMessage: "Use factory constructors instead."
|
||||
|
@ -5726,10 +5730,6 @@ JsInteropStaticInteropWithNonStaticSupertype:
|
|||
problemMessage: "JS interop class '#name' has an `@staticInterop` annotation, but has supertype '#name2', which does not."
|
||||
correctionMessage: "Try marking the supertype as a static interop class using `@staticInterop`."
|
||||
|
||||
JsInteropStrictModeViolation:
|
||||
problemMessage: "JS interop requires JS types when strict mode is enabled, but Type '#type' is not a type or subtype of a type from `dart:js_interop`."
|
||||
correctionMessage: "Use a JS type instead."
|
||||
|
||||
JsInteropStrictModeForbiddenLibrary:
|
||||
problemMessage: "Library '#name' is forbidden when strict mode is enabled."
|
||||
correctionMessage: "Remove the import of a forbidden library."
|
||||
|
|
|
@ -15,6 +15,7 @@ abispecificintegermapping
|
|||
adjusting
|
||||
annotate
|
||||
api
|
||||
apis
|
||||
argument(s)
|
||||
assigning
|
||||
augment
|
||||
|
|
|
@ -12,13 +12,15 @@ import 'dart:js_interop';
|
|||
|
||||
import 'package:expect/expect.dart';
|
||||
import 'package:expect/minitest.dart';
|
||||
// To test non-JS types for @staticInterop.
|
||||
import 'package:js/js.dart' as pkgJs;
|
||||
import 'package:js/js_util.dart' as js_util;
|
||||
|
||||
@JS()
|
||||
external void eval(String code);
|
||||
|
||||
@JS()
|
||||
@staticInterop
|
||||
@pkgJs.JS()
|
||||
@pkgJs.staticInterop
|
||||
class Foo<T extends JSAny?, U extends Nested> {
|
||||
external factory Foo(int a);
|
||||
}
|
||||
|
@ -64,8 +66,8 @@ extension FooExt<T extends JSAny?, U extends Nested> on Foo<T, U> {
|
|||
external R combineNestedGeneric<R extends Nested>(R a, [R b]);
|
||||
}
|
||||
|
||||
@JS('module.Bar')
|
||||
@staticInterop
|
||||
@pkgJs.JS('module.Bar')
|
||||
@pkgJs.staticInterop
|
||||
class Bar {
|
||||
external factory Bar(int a);
|
||||
}
|
||||
|
|
|
@ -22,6 +22,8 @@ external T invalidTopLevel<T>(T t);
|
|||
|
||||
typedef Typedef<T> = T Function();
|
||||
|
||||
extension type JSList<T>._(JSAny? _) {}
|
||||
|
||||
@JS()
|
||||
@staticInterop
|
||||
class Uninstantiated<W, X extends Instantiated?> {
|
||||
|
@ -68,12 +70,11 @@ extension UninstantiatedExtension<T, U extends JSAny?, V extends Instantiated>
|
|||
external void consumeV(V v);
|
||||
|
||||
// Test type parameters in a nested type context.
|
||||
Set<Typedef<T>> get getNestedTDart => throw UnimplementedError();
|
||||
external Set<Typedef<T>> get getNestedT;
|
||||
// ^
|
||||
// [web] External static interop members can only use type parameters that extend either a static interop type or one of the 'dart:js_interop' types.
|
||||
external Set<Typedef<U>> get getNestedU;
|
||||
external Set<Typedef<V>> get getNestedV;
|
||||
JSList<Typedef<T>> get getNestedTDart => throw UnimplementedError();
|
||||
// No error as JSList is an interop extension type.
|
||||
external JSList<Typedef<T>> get getNestedT;
|
||||
external JSList<Typedef<U>> get getNestedU;
|
||||
external JSList<Typedef<V>> get getNestedV;
|
||||
|
||||
// Test type parameters that are declared by the member.
|
||||
W returnWDart<W>() => throw UnimplementedError();
|
||||
|
@ -126,12 +127,11 @@ extension type UninstantiatedExtensionType<T, U extends JSAny?,
|
|||
external void consumeV(V v);
|
||||
|
||||
// Test type parameters in a nested type context.
|
||||
Set<Typedef<T>> get getNestedTDart => throw UnimplementedError();
|
||||
external Set<Typedef<T>> get getNestedT;
|
||||
// ^
|
||||
// [web] External static interop members can only use type parameters that extend either a static interop type or one of the 'dart:js_interop' types.
|
||||
external Set<Typedef<U>> get getNestedU;
|
||||
external Set<Typedef<V>> get getNestedV;
|
||||
JSList<Typedef<T>> get getNestedTDart => throw UnimplementedError();
|
||||
// No error as JSList is an interop extension type.
|
||||
external JSList<Typedef<T>> get getNestedT;
|
||||
external JSList<Typedef<U>> get getNestedU;
|
||||
external JSList<Typedef<V>> get getNestedV;
|
||||
|
||||
// Test type parameters that are declared by the member.
|
||||
W returnWDart<W>() => throw UnimplementedError();
|
||||
|
@ -178,25 +178,25 @@ extension PkgJsExtension<T> on PkgJs<T> {
|
|||
@JS()
|
||||
@staticInterop
|
||||
class Instantiated {
|
||||
external factory Instantiated(List<JSNumber> list);
|
||||
external factory Instantiated(JSList<JSNumber> list);
|
||||
}
|
||||
|
||||
extension InstantiatedExtension on Instantiated {
|
||||
external List<Instantiated> fieldList;
|
||||
external List<Instantiated> get getList;
|
||||
external set setList(List<Instantiated> list);
|
||||
external List<Instantiated> returnList();
|
||||
external void consumeList(List<Instantiated> list);
|
||||
external JSList<int> fieldList;
|
||||
external JSList<int> get getList;
|
||||
external set setList(JSList<int> list);
|
||||
external JSList<int> returnList();
|
||||
external void consumeList(JSList<int> list);
|
||||
}
|
||||
|
||||
extension type InstantiatedExtensionType._(JSObject _) {
|
||||
// Test generic types where all the type parameters are instantiated.
|
||||
external InstantiatedExtensionType(List<JSNumber> list);
|
||||
external List<InstantiatedExtensionType> fieldList;
|
||||
external List<InstantiatedExtensionType> get getList;
|
||||
external set setList(List<InstantiatedExtensionType> list);
|
||||
external List<InstantiatedExtensionType> returnList();
|
||||
external void consumeList(List<InstantiatedExtensionType> list);
|
||||
external InstantiatedExtensionType(JSList<int> list);
|
||||
external JSList<int> fieldList;
|
||||
external JSList<int> get getList;
|
||||
external set setList(JSList<int> list);
|
||||
external JSList<int> returnList();
|
||||
external void consumeList(JSList<int> list);
|
||||
}
|
||||
|
||||
void main() {}
|
||||
|
|
|
@ -10,7 +10,7 @@ import 'dart:js_interop';
|
|||
import 'package:expect/minitest.dart';
|
||||
|
||||
@JS()
|
||||
external dynamic eval(String code);
|
||||
external void eval(String code);
|
||||
|
||||
@JS()
|
||||
@staticInterop
|
||||
|
|
|
@ -11,7 +11,7 @@ import 'package:expect/minitest.dart';
|
|||
import 'package:js/js.dart' show trustTypes;
|
||||
|
||||
@JS()
|
||||
external dynamic eval(String code);
|
||||
external void eval(String code);
|
||||
|
||||
@JS('ExternalStatic')
|
||||
@staticInterop
|
||||
|
|
|
@ -12,7 +12,7 @@ import 'dart:js_interop';
|
|||
import 'package:expect/minitest.dart';
|
||||
|
||||
@JS()
|
||||
external dynamic eval(String code);
|
||||
external void eval(String code);
|
||||
|
||||
extension type ExtensionType._(JSObject _) {
|
||||
external ExtensionType();
|
||||
|
|
|
@ -13,7 +13,7 @@ import 'package:expect/expect.dart';
|
|||
import 'package:expect/minitest.dart';
|
||||
|
||||
@JS()
|
||||
external dynamic eval(String code);
|
||||
external void eval(String code);
|
||||
|
||||
extension type External<T extends JSAny?, U extends Nested>._(JSObject _) {
|
||||
external External();
|
||||
|
|
|
@ -13,7 +13,7 @@ import 'dart:js_util' as js_util;
|
|||
import 'package:expect/minitest.dart';
|
||||
|
||||
@JS()
|
||||
external dynamic eval(String code);
|
||||
external void eval(String code);
|
||||
|
||||
@JS()
|
||||
extension type ExternalStatic._(JSObject obj) {
|
||||
|
|
|
@ -13,7 +13,7 @@ import 'dart:js_util' as js_util;
|
|||
import 'package:expect/minitest.dart';
|
||||
|
||||
@JS()
|
||||
external dynamic eval(String code);
|
||||
external void eval(String code);
|
||||
|
||||
@JS('library3.ExternalStatic')
|
||||
extension type ExternalStatic._(JSObject obj) {
|
||||
|
|
|
@ -10,7 +10,7 @@ library js_array_test;
|
|||
import 'dart:js_interop';
|
||||
|
||||
@JS()
|
||||
external dynamic eval(String code);
|
||||
external void eval(String code);
|
||||
|
||||
// dart:js_interop top-levels do return-type checks so if the call to these
|
||||
// getters succeed, it's enough to know they can be interoperable.
|
||||
|
|
|
@ -12,10 +12,10 @@ import 'dart:js_interop';
|
|||
import 'package:expect/minitest.dart';
|
||||
|
||||
@JS()
|
||||
external dynamic eval(String code);
|
||||
external void eval(String code);
|
||||
|
||||
@JS()
|
||||
external Object get obj;
|
||||
external JSAny get obj;
|
||||
|
||||
void main() {
|
||||
eval('''
|
||||
|
|
|
@ -10,7 +10,7 @@ library native_error_test;
|
|||
import 'dart:js_interop';
|
||||
|
||||
@JS()
|
||||
external dynamic eval(String code);
|
||||
external void eval(String code);
|
||||
|
||||
// dart:js_interop top-levels do return-type checks so if the call to these
|
||||
// getters succeed, it's enough to know they can be interoperable.
|
||||
|
|
|
@ -16,60 +16,60 @@ class StaticInterop {}
|
|||
extension _ on StaticInterop {
|
||||
// https://dart.dev/guides/language/language-tour#_operators for the list of
|
||||
// operators allowed by the language.
|
||||
external void operator <(_);
|
||||
external void operator <(JSAny _);
|
||||
// ^
|
||||
// [web] JS interop classes do not support operator methods, with the exception of '[]' and '[]=' using static interop.
|
||||
external void operator >(_);
|
||||
external void operator >(JSAny _);
|
||||
// ^
|
||||
// [web] JS interop classes do not support operator methods, with the exception of '[]' and '[]=' using static interop.
|
||||
external void operator <=(_);
|
||||
external void operator <=(JSAny _);
|
||||
// ^
|
||||
// [web] JS interop classes do not support operator methods, with the exception of '[]' and '[]=' using static interop.
|
||||
external void operator >=(_);
|
||||
external void operator >=(JSAny _);
|
||||
// ^
|
||||
// [web] JS interop classes do not support operator methods, with the exception of '[]' and '[]=' using static interop.
|
||||
external void operator -(_);
|
||||
external void operator -(JSAny _);
|
||||
// ^
|
||||
// [web] JS interop classes do not support operator methods, with the exception of '[]' and '[]=' using static interop.
|
||||
external void operator +(_);
|
||||
external void operator +(JSAny _);
|
||||
// ^
|
||||
// [web] JS interop classes do not support operator methods, with the exception of '[]' and '[]=' using static interop.
|
||||
external void operator /(_);
|
||||
external void operator /(JSAny _);
|
||||
// ^
|
||||
// [web] JS interop classes do not support operator methods, with the exception of '[]' and '[]=' using static interop.
|
||||
external void operator ~/(_);
|
||||
external void operator ~/(JSAny _);
|
||||
// ^
|
||||
// [web] JS interop classes do not support operator methods, with the exception of '[]' and '[]=' using static interop.
|
||||
external void operator *(_);
|
||||
external void operator *(JSAny _);
|
||||
// ^
|
||||
// [web] JS interop classes do not support operator methods, with the exception of '[]' and '[]=' using static interop.
|
||||
external void operator %(_);
|
||||
external void operator %(JSAny _);
|
||||
// ^
|
||||
// [web] JS interop classes do not support operator methods, with the exception of '[]' and '[]=' using static interop.
|
||||
external void operator |(_);
|
||||
external void operator |(JSAny _);
|
||||
// ^
|
||||
// [web] JS interop classes do not support operator methods, with the exception of '[]' and '[]=' using static interop.
|
||||
external void operator ^(_);
|
||||
external void operator ^(JSAny _);
|
||||
// ^
|
||||
// [web] JS interop classes do not support operator methods, with the exception of '[]' and '[]=' using static interop.
|
||||
external void operator &(_);
|
||||
external void operator &(JSAny _);
|
||||
// ^
|
||||
// [web] JS interop classes do not support operator methods, with the exception of '[]' and '[]=' using static interop.
|
||||
external void operator <<(_);
|
||||
external void operator <<(JSAny _);
|
||||
// ^
|
||||
// [web] JS interop classes do not support operator methods, with the exception of '[]' and '[]=' using static interop.
|
||||
external void operator >>(_);
|
||||
external void operator >>(JSAny _);
|
||||
// ^
|
||||
// [web] JS interop classes do not support operator methods, with the exception of '[]' and '[]=' using static interop.
|
||||
external void operator >>>(_);
|
||||
external void operator >>>(JSAny _);
|
||||
// ^
|
||||
// [web] JS interop classes do not support operator methods, with the exception of '[]' and '[]=' using static interop.
|
||||
@JS('rename')
|
||||
external void operator [](_);
|
||||
external void operator [](JSAny _);
|
||||
// ^
|
||||
// [web] JS interop operator methods cannot be renamed using the '@JS' annotation.
|
||||
@JS('rename')
|
||||
external void operator []=(_, __);
|
||||
external void operator []=(JSAny _, JSAny __);
|
||||
// ^
|
||||
// [web] JS interop operator methods cannot be renamed using the '@JS' annotation.
|
||||
external void operator ~();
|
||||
|
@ -81,60 +81,60 @@ extension _ on StaticInterop {
|
|||
|
||||
@JS()
|
||||
extension type ExtensionType(JSObject _) {
|
||||
external void operator <(_);
|
||||
external void operator <(JSAny _);
|
||||
// ^
|
||||
// [web] JS interop classes do not support operator methods, with the exception of '[]' and '[]=' using static interop.
|
||||
external void operator >(_);
|
||||
external void operator >(JSAny _);
|
||||
// ^
|
||||
// [web] JS interop classes do not support operator methods, with the exception of '[]' and '[]=' using static interop.
|
||||
external void operator <=(_);
|
||||
external void operator <=(JSAny _);
|
||||
// ^
|
||||
// [web] JS interop classes do not support operator methods, with the exception of '[]' and '[]=' using static interop.
|
||||
external void operator >=(_);
|
||||
external void operator >=(JSAny _);
|
||||
// ^
|
||||
// [web] JS interop classes do not support operator methods, with the exception of '[]' and '[]=' using static interop.
|
||||
external void operator -(_);
|
||||
external void operator -(JSAny _);
|
||||
// ^
|
||||
// [web] JS interop classes do not support operator methods, with the exception of '[]' and '[]=' using static interop.
|
||||
external void operator +(_);
|
||||
external void operator +(JSAny _);
|
||||
// ^
|
||||
// [web] JS interop classes do not support operator methods, with the exception of '[]' and '[]=' using static interop.
|
||||
external void operator /(_);
|
||||
external void operator /(JSAny _);
|
||||
// ^
|
||||
// [web] JS interop classes do not support operator methods, with the exception of '[]' and '[]=' using static interop.
|
||||
external void operator ~/(_);
|
||||
external void operator ~/(JSAny _);
|
||||
// ^
|
||||
// [web] JS interop classes do not support operator methods, with the exception of '[]' and '[]=' using static interop.
|
||||
external void operator *(_);
|
||||
external void operator *(JSAny _);
|
||||
// ^
|
||||
// [web] JS interop classes do not support operator methods, with the exception of '[]' and '[]=' using static interop.
|
||||
external void operator %(_);
|
||||
external void operator %(JSAny _);
|
||||
// ^
|
||||
// [web] JS interop classes do not support operator methods, with the exception of '[]' and '[]=' using static interop.
|
||||
external void operator |(_);
|
||||
external void operator |(JSAny _);
|
||||
// ^
|
||||
// [web] JS interop classes do not support operator methods, with the exception of '[]' and '[]=' using static interop.
|
||||
external void operator ^(_);
|
||||
external void operator ^(JSAny _);
|
||||
// ^
|
||||
// [web] JS interop classes do not support operator methods, with the exception of '[]' and '[]=' using static interop.
|
||||
external void operator &(_);
|
||||
external void operator &(JSAny _);
|
||||
// ^
|
||||
// [web] JS interop classes do not support operator methods, with the exception of '[]' and '[]=' using static interop.
|
||||
external void operator <<(_);
|
||||
external void operator <<(JSAny _);
|
||||
// ^
|
||||
// [web] JS interop classes do not support operator methods, with the exception of '[]' and '[]=' using static interop.
|
||||
external void operator >>(_);
|
||||
external void operator >>(JSAny _);
|
||||
// ^
|
||||
// [web] JS interop classes do not support operator methods, with the exception of '[]' and '[]=' using static interop.
|
||||
external void operator >>>(_);
|
||||
external void operator >>>(JSAny _);
|
||||
// ^
|
||||
// [web] JS interop classes do not support operator methods, with the exception of '[]' and '[]=' using static interop.
|
||||
@JS('rename')
|
||||
external void operator [](_);
|
||||
external void operator [](JSAny _);
|
||||
// ^
|
||||
// [web] JS interop operator methods cannot be renamed using the '@JS' annotation.
|
||||
@JS('rename')
|
||||
external void operator []=(_, __);
|
||||
external void operator []=(JSAny _, JSAny __);
|
||||
// ^
|
||||
// [web] JS interop operator methods cannot be renamed using the '@JS' annotation.
|
||||
external void operator ~();
|
||||
|
|
|
@ -8,74 +8,49 @@
|
|||
library strict_mode_test;
|
||||
|
||||
import 'dart:js_interop';
|
||||
/**/ import 'dart:js';
|
||||
// ^
|
||||
// [web] Library 'dart:js' is forbidden when strict mode is enabled.
|
||||
|
||||
/**/ import 'dart:js_util';
|
||||
// ^
|
||||
// [web] Library 'dart:js_util' is forbidden when strict mode is enabled.
|
||||
import 'dart:js';
|
||||
import 'dart:js_util';
|
||||
|
||||
@JS()
|
||||
@staticInterop
|
||||
class JSClass {
|
||||
external factory JSClass(List<int> baz);
|
||||
// ^
|
||||
// [web] JS interop requires JS types when strict mode is enabled, but Type 'List<int>' is not a type or subtype of a type from `dart:js_interop`.
|
||||
// [web] Type 'List<int>' is not a valid type for external `dart:js_interop` APIs. The only valid types are: @staticInterop types, JS types from `dart:js_interop`, void, bool, num, double, int, String, and any extension type that erases to one of these types.
|
||||
|
||||
external factory JSClass.other(Object blu);
|
||||
// ^
|
||||
// [web] JS interop requires JS types when strict mode is enabled, but Type 'Object' is not a type or subtype of a type from `dart:js_interop`.
|
||||
// [web] Type 'Object' is not a valid type for external `dart:js_interop` APIs. The only valid types are: @staticInterop types, JS types from `dart:js_interop`, void, bool, num, double, int, String, and any extension type that erases to one of these types.
|
||||
|
||||
external static int foo();
|
||||
// ^
|
||||
// [web] JS interop requires JS types when strict mode is enabled, but Type 'int' is not a type or subtype of a type from `dart:js_interop`.
|
||||
|
||||
external static JSClass foo1(String bar);
|
||||
external static dynamic foo();
|
||||
// ^
|
||||
// [web] JS interop requires JS types when strict mode is enabled, but Type 'String' is not a type or subtype of a type from `dart:js_interop`.
|
||||
// [web] Type 'dynamic' is not a valid type for external `dart:js_interop` APIs. The only valid types are: @staticInterop types, JS types from `dart:js_interop`, void, bool, num, double, int, String, and any extension type that erases to one of these types.
|
||||
|
||||
external static Function foo2();
|
||||
// ^
|
||||
// [web] JS interop requires JS types when strict mode is enabled, but Type 'Function' is not a type or subtype of a type from `dart:js_interop`.
|
||||
external static Function get fooGet;
|
||||
// ^
|
||||
// [web] Type 'Function' is not a valid type for external `dart:js_interop` APIs. The only valid types are: @staticInterop types, JS types from `dart:js_interop`, void, bool, num, double, int, String, and any extension type that erases to one of these types.
|
||||
|
||||
external static JSClass foo3(void Function() bar);
|
||||
// ^
|
||||
// [web] JS interop requires JS types when strict mode is enabled, but Type 'void Function()' is not a type or subtype of a type from `dart:js_interop`.
|
||||
|
||||
external static double get fooGet;
|
||||
// ^
|
||||
// [web] JS interop requires JS types when strict mode is enabled, but Type 'double' is not a type or subtype of a type from `dart:js_interop`.
|
||||
|
||||
external static set fooSet(String bar);
|
||||
external static set fooSet(void Function() bar);
|
||||
// ^
|
||||
// [web] JS interop requires JS types when strict mode is enabled, but Type 'String' is not a type or subtype of a type from `dart:js_interop`.
|
||||
// [web] Type 'void Function()' is not a valid type for external `dart:js_interop` APIs. The only valid types are: @staticInterop types, JS types from `dart:js_interop`, void, bool, num, double, int, String, and any extension type that erases to one of these types.
|
||||
}
|
||||
|
||||
extension JSClassExtension on JSClass {
|
||||
external dynamic extFoo();
|
||||
// ^
|
||||
// [web] JS interop requires JS types when strict mode is enabled, but Type 'dynamic' is not a type or subtype of a type from `dart:js_interop`.
|
||||
// [web] Type 'dynamic' is not a valid type for external `dart:js_interop` APIs. The only valid types are: @staticInterop types, JS types from `dart:js_interop`, void, bool, num, double, int, String, and any extension type that erases to one of these types.
|
||||
|
||||
external JSClass extFoo2(List<Object?> bar);
|
||||
// ^
|
||||
// [web] JS interop requires JS types when strict mode is enabled, but Type 'List<Object?>' is not a type or subtype of a type from `dart:js_interop`.
|
||||
// [web] Type 'List<Object?>' is not a valid type for external `dart:js_interop` APIs. The only valid types are: @staticInterop types, JS types from `dart:js_interop`, void, bool, num, double, int, String, and any extension type that erases to one of these types.
|
||||
|
||||
external Function extFoo3(JSClass bar);
|
||||
// ^
|
||||
// [web] JS interop requires JS types when strict mode is enabled, but Type 'Function' is not a type or subtype of a type from `dart:js_interop`.
|
||||
external Function get extFooGet;
|
||||
// ^
|
||||
// [web] Type 'Function' is not a valid type for external `dart:js_interop` APIs. The only valid types are: @staticInterop types, JS types from `dart:js_interop`, void, bool, num, double, int, String, and any extension type that erases to one of these types.
|
||||
|
||||
external JSClass extFoo4(void Function() bar);
|
||||
// ^
|
||||
// [web] JS interop requires JS types when strict mode is enabled, but Type 'void Function()' is not a type or subtype of a type from `dart:js_interop`.
|
||||
|
||||
external double get extFooGet;
|
||||
// ^
|
||||
// [web] JS interop requires JS types when strict mode is enabled, but Type 'double' is not a type or subtype of a type from `dart:js_interop`.
|
||||
|
||||
external set extFooSet(String bar);
|
||||
external set extFooSet(void Function() bar);
|
||||
// ^
|
||||
// [web] JS interop requires JS types when strict mode is enabled, but Type 'String' is not a type or subtype of a type from `dart:js_interop`.
|
||||
// [web] Type 'void Function()' is not a valid type for external `dart:js_interop` APIs. The only valid types are: @staticInterop types, JS types from `dart:js_interop`, void, bool, num, double, int, String, and any extension type that erases to one of these types.
|
||||
}
|
||||
|
||||
@JS()
|
||||
|
@ -92,12 +67,16 @@ external void useStaticInteropExtensionType(ExtensionType foo);
|
|||
|
||||
void main() {
|
||||
jsFunctionTest(((double foo) => 4.0.toJS).toJS);
|
||||
// ^
|
||||
// [web] JS interop requires JS types when strict mode is enabled, but Type 'double' is not a type or subtype of a type from `dart:js_interop`.
|
||||
|
||||
jsFunctionTest(((JSNumber foo) => 4.0).toJS);
|
||||
// ^
|
||||
// [web] JS interop requires JS types when strict mode is enabled, but Type 'double' is not a type or subtype of a type from `dart:js_interop`.
|
||||
|
||||
jsFunctionTest(((List foo) => 4.0).toJS);
|
||||
// ^
|
||||
// [web] Type 'List<dynamic>' is not a valid type for external `dart:js_interop` APIs. The only valid types are: @staticInterop types, JS types from `dart:js_interop`, void, bool, num, double, int, String, and any extension type that erases to one of these types.
|
||||
|
||||
jsFunctionTest(((JSNumber foo) => () {}).toJS);
|
||||
// ^
|
||||
// [web] Type 'Null Function()' is not a valid type for external `dart:js_interop` APIs. The only valid types are: @staticInterop types, JS types from `dart:js_interop`, void, bool, num, double, int, String, and any extension type that erases to one of these types.
|
||||
|
||||
jsFunctionTest(((((JSNumber foo) => 4.0) as dynamic) as Function).toJS);
|
||||
// ^
|
||||
|
|
|
@ -22,7 +22,7 @@ external int get getter;
|
|||
// ^
|
||||
// [web] Only JS interop members may be 'external'.
|
||||
|
||||
external set setter(_);
|
||||
external set setter(int _);
|
||||
// ^
|
||||
// [web] Only JS interop members may be 'external'.
|
||||
|
||||
|
@ -40,7 +40,7 @@ external int annotatedFinalField;
|
|||
external int get annotatedGetter;
|
||||
|
||||
@JS()
|
||||
external set annotatedSetter(_);
|
||||
external set annotatedSetter(int _);
|
||||
|
||||
@JS()
|
||||
external int annotatedMethod();
|
||||
|
|
|
@ -11,7 +11,7 @@ library typed_data_test;
|
|||
import 'dart:js_interop';
|
||||
|
||||
@JS()
|
||||
external dynamic eval(String code);
|
||||
external void eval(String code);
|
||||
|
||||
// dart:js_interop top-levels do return-type checks so if the call to these
|
||||
// getters succeed, it's enough to know they can be interoperable.
|
||||
|
|
|
@ -14,13 +14,15 @@ import 'dart:js_interop';
|
|||
|
||||
import 'package:expect/expect.dart';
|
||||
import 'package:expect/minitest.dart';
|
||||
// To test non-JS types for @staticInterop.
|
||||
import 'package:js/js.dart' as pkgJs;
|
||||
import 'package:js/js_util.dart' as js_util;
|
||||
|
||||
@JS()
|
||||
external void eval(String code);
|
||||
|
||||
@JS()
|
||||
@staticInterop
|
||||
@pkgJs.JS()
|
||||
@pkgJs.staticInterop
|
||||
class Foo<T extends JSAny, U extends Nested> {
|
||||
external factory Foo(int a);
|
||||
}
|
||||
|
@ -66,8 +68,8 @@ extension FooExt<T extends JSAny, U extends Nested> on Foo<T, U> {
|
|||
external R combineNestedGeneric<R extends Nested>(R a, [R b]);
|
||||
}
|
||||
|
||||
@JS('module.Bar')
|
||||
@staticInterop
|
||||
@pkgJs.JS('module.Bar')
|
||||
@pkgJs.staticInterop
|
||||
class Bar {
|
||||
external factory Bar(int a);
|
||||
}
|
||||
|
|
|
@ -20,6 +20,10 @@ external T invalidTopLevel<T>(T t);
|
|||
|
||||
typedef Typedef<T> = T Function();
|
||||
|
||||
@JS()
|
||||
@staticInterop
|
||||
class JSList<T> {}
|
||||
|
||||
@JS()
|
||||
@staticInterop
|
||||
class Uninstantiated<W, X extends Instantiated> {
|
||||
|
@ -66,12 +70,11 @@ extension UninstantiatedExtension<T, U extends JSAny, V extends Instantiated>
|
|||
external void consumeV(V v);
|
||||
|
||||
// Test type parameters in a nested type context.
|
||||
Set<Typedef<T>> get getNestedTDart => throw UnimplementedError();
|
||||
external Set<Typedef<T>> get getNestedT;
|
||||
// ^
|
||||
// [web] External static interop members can only use type parameters that extend either a static interop type or one of the 'dart:js_interop' types.
|
||||
external Set<Typedef<U>> get getNestedU;
|
||||
external Set<Typedef<V>> get getNestedV;
|
||||
JSList<Typedef<T>> get getNestedTDart => throw UnimplementedError();
|
||||
// No error as JSList is an interop type.
|
||||
external JSList<Typedef<T>> get getNestedT;
|
||||
external JSList<Typedef<U>> get getNestedU;
|
||||
external JSList<Typedef<V>> get getNestedV;
|
||||
|
||||
// Test type parameters that are declared by the member.
|
||||
W returnWDart<W>() => throw UnimplementedError();
|
||||
|
@ -109,15 +112,15 @@ extension PkgJsExtension<T> on PkgJs<T> {
|
|||
@JS()
|
||||
@staticInterop
|
||||
class Instantiated {
|
||||
external factory Instantiated(List<JSNumber> list);
|
||||
external factory Instantiated(JSList<JSNumber> list);
|
||||
}
|
||||
|
||||
extension InstantiatedExtension on Instantiated {
|
||||
external List<Instantiated> fieldList;
|
||||
external List<Instantiated> get getList;
|
||||
external set setList(List<Instantiated> list);
|
||||
external List<Instantiated> returnList();
|
||||
external void consumeList(List<Instantiated> list);
|
||||
external JSList<int> fieldList;
|
||||
external JSList<int> get getList;
|
||||
external set setList(JSList<int> list);
|
||||
external JSList<int> returnList();
|
||||
external void consumeList(JSList<int> list);
|
||||
}
|
||||
|
||||
void main() {}
|
||||
|
|
|
@ -11,7 +11,7 @@ import 'package:expect/minitest.dart';
|
|||
import 'package:js/js.dart' show staticInterop;
|
||||
|
||||
@JS()
|
||||
external dynamic eval(String code);
|
||||
external void eval(String code);
|
||||
|
||||
@JS()
|
||||
@staticInterop
|
||||
|
|
|
@ -11,7 +11,7 @@ import 'package:expect/minitest.dart';
|
|||
import 'package:js/js.dart' show trustTypes, staticInterop;
|
||||
|
||||
@JS()
|
||||
external dynamic eval(String code);
|
||||
external void eval(String code);
|
||||
|
||||
@JS('ExternalStatic')
|
||||
@staticInterop
|
||||
|
|
Loading…
Reference in a new issue