mirror of
https://github.com/dart-lang/sdk
synced 2024-10-06 15:29:45 +00:00
[pkg:js] Refactor createStaticInteropMock tests to account for new changes
Change-Id: I4de0c94bf1f00336432d61b174703fde9476545a Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/262863 Reviewed-by: Riley Porter <rileyporter@google.com> Reviewed-by: Sigmund Cherem <sigmund@google.com> Commit-Queue: Srujan Gaddam <srujzs@google.com>
This commit is contained in:
parent
8c62ad7596
commit
dbb793a330
|
@ -3,176 +3,102 @@
|
|||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
// Test that `createStaticInteropMock` checks for extension member conflicts.
|
||||
// We should only require users to implement one of these conflicts (or a
|
||||
// getter/setter pair).
|
||||
|
||||
import 'package:js/js.dart';
|
||||
import 'package:js/js_util.dart';
|
||||
|
||||
class EmptyDart {}
|
||||
|
||||
@JS()
|
||||
@staticInterop
|
||||
class Method {}
|
||||
class SameKindConflict {}
|
||||
|
||||
extension on Method {
|
||||
external void member();
|
||||
extension E1 on SameKindConflict {
|
||||
external int get getter;
|
||||
external set setter(int val);
|
||||
external int method();
|
||||
}
|
||||
|
||||
@JS()
|
||||
@staticInterop
|
||||
class Getter {}
|
||||
|
||||
extension NamedExtension on Getter {
|
||||
external int get member;
|
||||
extension E2 on SameKindConflict {
|
||||
external String get getter;
|
||||
external set setter(int val);
|
||||
external String method();
|
||||
}
|
||||
|
||||
@JS()
|
||||
@staticInterop
|
||||
class Field {}
|
||||
|
||||
extension on Field {
|
||||
external final String member;
|
||||
@JSExport()
|
||||
class DartSameKindConflict {
|
||||
String getter = '';
|
||||
set setter(int val) => throw '';
|
||||
String method() => throw '';
|
||||
}
|
||||
|
||||
@JS()
|
||||
@staticInterop
|
||||
class ExtendsImplementsConflict extends Method implements Getter {}
|
||||
|
||||
@JS()
|
||||
@staticInterop
|
||||
class ImplementsConflict implements Method, Getter {}
|
||||
|
||||
@JS()
|
||||
@staticInterop
|
||||
class ManyConflicts extends Method implements Getter, Field {}
|
||||
|
||||
@JS()
|
||||
@staticInterop
|
||||
class Override implements Method {}
|
||||
|
||||
extension on Override {
|
||||
external int member();
|
||||
@JSExport()
|
||||
class IncorrectDartSameKindConflict {
|
||||
bool getter = true;
|
||||
set setter(bool val) => throw '';
|
||||
bool method() => throw '';
|
||||
}
|
||||
|
||||
@JS()
|
||||
@staticInterop
|
||||
class OverrideOneConflictButNotAll implements Override, Getter {}
|
||||
|
||||
@JS()
|
||||
@staticInterop
|
||||
class ConflictThroughInheritance implements OverrideOneConflictButNotAll {}
|
||||
|
||||
@JS()
|
||||
@staticInterop
|
||||
class ResolveThroughOverride implements ConflictThroughInheritance {}
|
||||
|
||||
extension on ResolveThroughOverride {
|
||||
external int member;
|
||||
}
|
||||
|
||||
class ResolveThroughOverrideDart {
|
||||
int member = throw '';
|
||||
}
|
||||
|
||||
@JS()
|
||||
@staticInterop
|
||||
class Setter {}
|
||||
|
||||
extension on Setter {
|
||||
external set member(int val);
|
||||
}
|
||||
|
||||
@JS()
|
||||
@staticInterop
|
||||
class NoConflictDueToSubtype implements Override, Method {}
|
||||
|
||||
class NoConflictDueToSubtypeDart {
|
||||
int member() => throw '';
|
||||
}
|
||||
|
||||
@JS()
|
||||
@staticInterop
|
||||
class GetterSetterConflict implements Setter, Getter {}
|
||||
|
||||
@JS()
|
||||
@staticInterop
|
||||
class GetterSetterSameExtension {}
|
||||
|
||||
extension on GetterSetterSameExtension {
|
||||
external int get member;
|
||||
external set member(int val);
|
||||
}
|
||||
|
||||
class GetterSetterSameExtensionDart extends ResolveThroughOverrideDart {}
|
||||
|
||||
@JS()
|
||||
@staticInterop
|
||||
class GetterSetterMethodConflict implements GetterSetterSameExtension, Method {}
|
||||
|
||||
@JS()
|
||||
@staticInterop
|
||||
class NonExternal {}
|
||||
|
||||
extension on NonExternal {
|
||||
int get member => throw '';
|
||||
}
|
||||
|
||||
@JS()
|
||||
@staticInterop
|
||||
class ExternalNonExternal implements NonExternal, GetterSetterSameExtension {}
|
||||
|
||||
class ExternalNonExternalDart extends ResolveThroughOverrideDart {}
|
||||
|
||||
void main() {
|
||||
// Test name conflicts between extended and implemented members.
|
||||
createStaticInteropMock<ExtendsImplementsConflict, EmptyDart>(
|
||||
void testSameKindConflict() {
|
||||
// No error as one of the extension members are implemented for each export
|
||||
// name.
|
||||
createStaticInteropMock<SameKindConflict, DartSameKindConflict>(
|
||||
DartSameKindConflict());
|
||||
// Error as none of them are implemented for each export name.
|
||||
createStaticInteropMock<SameKindConflict, IncorrectDartSameKindConflict>(
|
||||
//^
|
||||
// [web] External extension member with name 'member' is defined in the following extensions and none are more specific: 'Getter.NamedExtension', 'Method.unnamed'.
|
||||
EmptyDart());
|
||||
// Test name conflicts between implemented members.
|
||||
createStaticInteropMock<ImplementsConflict, EmptyDart>(EmptyDart());
|
||||
//^
|
||||
// [web] External extension member with name 'member' is defined in the following extensions and none are more specific: 'Getter.NamedExtension', 'Method.unnamed'.
|
||||
|
||||
// Test multiple name conflicts.
|
||||
createStaticInteropMock<ManyConflicts, EmptyDart>(EmptyDart());
|
||||
//^
|
||||
// [web] External extension member with name 'member' is defined in the following extensions and none are more specific: 'Field.unnamed', 'Getter.NamedExtension', 'Method.unnamed'.
|
||||
|
||||
// Test name conflicts where one definition is overridden, but there is still
|
||||
// a name conflict between the other two.
|
||||
createStaticInteropMock<OverrideOneConflictButNotAll, EmptyDart>(
|
||||
//^
|
||||
// [web] External extension member with name 'member' is defined in the following extensions and none are more specific: 'Getter.NamedExtension', 'Override.unnamed'.
|
||||
EmptyDart());
|
||||
// Test case where if we inherit a class with a conflict, the conflict still
|
||||
// exists.
|
||||
createStaticInteropMock<ConflictThroughInheritance, EmptyDart>(
|
||||
//^
|
||||
// [web] External extension member with name 'member' is defined in the following extensions and none are more specific: 'Getter.NamedExtension', 'Override.unnamed'.
|
||||
EmptyDart());
|
||||
// Test case where name conflicts are resolved using derived class.
|
||||
createStaticInteropMock<ResolveThroughOverride, ResolveThroughOverrideDart>(
|
||||
ResolveThroughOverrideDart());
|
||||
// Test case where you inherit two classes with the same member name but they
|
||||
// have a subtype relation, so there is no conflict.
|
||||
createStaticInteropMock<NoConflictDueToSubtype, NoConflictDueToSubtypeDart>(
|
||||
NoConflictDueToSubtypeDart());
|
||||
// Test conflict where getter and setter collide when they are in different
|
||||
// extensions.
|
||||
createStaticInteropMock<GetterSetterConflict, EmptyDart>(EmptyDart());
|
||||
//^
|
||||
// [web] External extension member with name 'member' is defined in the following extensions and none are more specific: 'Getter.NamedExtension', 'Setter.unnamed'.
|
||||
|
||||
// Test no conflict where getter and setter are on the same extension.
|
||||
createStaticInteropMock<GetterSetterSameExtension,
|
||||
GetterSetterSameExtensionDart>(GetterSetterSameExtensionDart());
|
||||
// Test conflict where getter and setter are in one extension, but there is
|
||||
// a conflict with another extension.
|
||||
createStaticInteropMock<GetterSetterMethodConflict, EmptyDart>(EmptyDart());
|
||||
//^
|
||||
// [web] External extension member with name 'member' is defined in the following extensions and none are more specific: 'GetterSetterSameExtension.unnamed', 'Method.unnamed'.
|
||||
|
||||
// Test no conflict between external and non-external members.
|
||||
createStaticInteropMock<ExternalNonExternal, ExternalNonExternalDart>(
|
||||
ExternalNonExternalDart());
|
||||
// [web] Dart class 'IncorrectDartSameKindConflict' does not have any members that implement any of the following extension member(s) with export name 'getter': E1.getter (FunctionType(int Function())), E2.getter (FunctionType(String Function())).
|
||||
// [web] Dart class 'IncorrectDartSameKindConflict' does not have any members that implement any of the following extension member(s) with export name 'method': E1.method (FunctionType(int Function())), E2.method (FunctionType(String Function())).
|
||||
// [web] Dart class 'IncorrectDartSameKindConflict' does not have any members that implement any of the following extension member(s) with export name 'setter': E1.setter= (FunctionType(void Function(int))), E2.setter= (FunctionType(void Function(int))).
|
||||
IncorrectDartSameKindConflict());
|
||||
}
|
||||
|
||||
@JS()
|
||||
@staticInterop
|
||||
class DifferentKindConflict {}
|
||||
|
||||
extension E3 on DifferentKindConflict {
|
||||
external int getSet;
|
||||
@JS('getSet')
|
||||
external void method();
|
||||
}
|
||||
|
||||
@JSExport()
|
||||
class ImplementGetter {
|
||||
int get getSet => throw '';
|
||||
}
|
||||
|
||||
@JSExport()
|
||||
class ImplementSetter {
|
||||
set getSet(int val) => throw '';
|
||||
}
|
||||
|
||||
@JSExport()
|
||||
class ImplementBoth {
|
||||
int getSet = 0;
|
||||
}
|
||||
|
||||
@JSExport()
|
||||
class ImplementMethod {
|
||||
void getSet() {}
|
||||
}
|
||||
|
||||
void testDifferentKindConflict() {
|
||||
// Missing setter error.
|
||||
createStaticInteropMock<DifferentKindConflict, ImplementGetter>(
|
||||
//^
|
||||
// [web] Dart class 'ImplementGetter' has a getter, but does not have a setter to implement any of the following extension member(s) with export name 'getSet': E3.getSet= (FunctionType(void Function(int))).
|
||||
ImplementGetter());
|
||||
// Missing getter error.
|
||||
createStaticInteropMock<DifferentKindConflict, ImplementSetter>(
|
||||
//^
|
||||
// [web] Dart class 'ImplementSetter' has a setter, but does not have a getter to implement any of the following extension member(s) with export name 'getSet': E3.getSet (FunctionType(int Function())).
|
||||
ImplementSetter());
|
||||
// No error as both getter and setter are there, and we've satisfied an export
|
||||
// for `getSet`.
|
||||
createStaticInteropMock<DifferentKindConflict, ImplementBoth>(
|
||||
ImplementBoth());
|
||||
// No error as we've satisfied an export for `getSet`.
|
||||
createStaticInteropMock<DifferentKindConflict, ImplementMethod>(
|
||||
ImplementMethod());
|
||||
}
|
||||
|
|
|
@ -23,10 +23,11 @@ extension on Methods {
|
|||
external int optionalAdd(int a, int b, [int c = 0, int? d]);
|
||||
}
|
||||
|
||||
@JSExport()
|
||||
class MethodsDart {
|
||||
int add(int a, int b) => a + b;
|
||||
int nonExternal() => 1;
|
||||
int rename() => 1;
|
||||
int _rename() => 1;
|
||||
int optionalAdd(int a, int b, [int? c, int? d]) =>
|
||||
a + b + (c ?? 0) + (d ?? 0);
|
||||
}
|
||||
|
@ -44,11 +45,12 @@ extension on Fields {
|
|||
external final int renamedFinalField;
|
||||
}
|
||||
|
||||
@JSExport()
|
||||
class FieldsDart {
|
||||
int field = 1;
|
||||
int finalField = 1;
|
||||
int renamedField = 1;
|
||||
final int renamedFinalField = 1;
|
||||
int _renamedField = 1;
|
||||
final int _renamedFinalField = 1;
|
||||
}
|
||||
|
||||
@JS()
|
||||
|
@ -72,12 +74,13 @@ extension on GetSet {
|
|||
external set differentNameSameRenameSet(int val);
|
||||
}
|
||||
|
||||
@JSExport()
|
||||
class GetSetDart {
|
||||
int getSet = 1;
|
||||
int renamedGetSet = 1;
|
||||
int sameNameDifferentRename = 1;
|
||||
int differentNameSameRenameGet = 1;
|
||||
int differentNameSameRenameSet = 1;
|
||||
int _renamedGetSet = 1;
|
||||
int _sameNameDifferentRenameGet = 1;
|
||||
int _sameNameDifferentRenameSet = 1;
|
||||
int _differentNameSameRename = 1;
|
||||
}
|
||||
|
||||
void test([Object? proto]) {
|
||||
|
@ -99,11 +102,11 @@ void test([Object? proto]) {
|
|||
jsFields.field = 2;
|
||||
jsFields.renamedField = 2;
|
||||
expect(dartFields.field, 2);
|
||||
expect(dartFields.renamedField, 2);
|
||||
expect(dartFields._renamedField, 2);
|
||||
// Modify the Dart mock and check for updates in the JS mock.
|
||||
dartFields.field = 3;
|
||||
dartFields.finalField = 3;
|
||||
dartFields.renamedField = 3;
|
||||
dartFields._renamedField = 3;
|
||||
expect(jsFields.field, 3);
|
||||
expect(jsFields.finalField, 3);
|
||||
expect(jsFields.renamedField, 3);
|
||||
|
@ -119,17 +122,17 @@ void test([Object? proto]) {
|
|||
jsGetSet.sameNameDifferentRename = 2;
|
||||
jsGetSet.differentNameSameRenameSet = 2;
|
||||
expect(dartGetSet.getSet, 2);
|
||||
expect(dartGetSet.renamedGetSet, 2);
|
||||
expect(dartGetSet.sameNameDifferentRename, 2);
|
||||
expect(dartGetSet.differentNameSameRenameGet, 1);
|
||||
expect(dartGetSet.differentNameSameRenameSet, 2);
|
||||
expect(dartGetSet._renamedGetSet, 2);
|
||||
expect(dartGetSet._sameNameDifferentRenameGet, 1);
|
||||
expect(dartGetSet._sameNameDifferentRenameSet, 2);
|
||||
expect(dartGetSet._differentNameSameRename, 2);
|
||||
// Modify the Dart mock and check for updates in the JS mock.
|
||||
dartGetSet.getSet = 3;
|
||||
dartGetSet.renamedGetSet = 3;
|
||||
dartGetSet.sameNameDifferentRename = 3;
|
||||
dartGetSet._renamedGetSet = 3;
|
||||
// Use different values to disambiguate.
|
||||
dartGetSet.differentNameSameRenameGet = 3;
|
||||
dartGetSet.differentNameSameRenameSet = 4;
|
||||
dartGetSet._sameNameDifferentRenameGet = 3;
|
||||
dartGetSet._sameNameDifferentRenameSet = 4;
|
||||
dartGetSet._differentNameSameRename = 3;
|
||||
expect(jsGetSet.getSet, 3);
|
||||
expect(jsGetSet.renamedGetSet, 3);
|
||||
expect(jsGetSet.sameNameDifferentRename, 3);
|
||||
|
|
|
@ -24,26 +24,29 @@ class StaticInterop {
|
|||
external factory StaticInterop();
|
||||
}
|
||||
|
||||
class Dart {}
|
||||
@JSExport()
|
||||
class Dart {
|
||||
int _unused = 0;
|
||||
}
|
||||
|
||||
void main() {
|
||||
createStaticInteropMock<StaticInterop, Dart>(Dart());
|
||||
createStaticInteropMock<Dart, StaticInterop>(StaticInterop());
|
||||
//^
|
||||
// [web] First type argument 'Dart' is not a `@staticInterop` type.
|
||||
// [web] Second type argument 'StaticInterop' is not a Dart interface type.
|
||||
// [web] Type argument 'Dart' needs to be a `@staticInterop` type.
|
||||
// [web] Type argument 'StaticInterop' needs to be a non-JS interop type.
|
||||
createStaticInteropMock<Dart, Js>(Js());
|
||||
//^
|
||||
// [web] First type argument 'Dart' is not a `@staticInterop` type.
|
||||
// [web] Second type argument 'Js' is not a Dart interface type.
|
||||
// [web] Type argument 'Dart' needs to be a `@staticInterop` type.
|
||||
// [web] Type argument 'Js' needs to be a non-JS interop type.
|
||||
createStaticInteropMock<Dart, Anonymous>(Anonymous());
|
||||
//^
|
||||
// [web] First type argument 'Dart' is not a `@staticInterop` type.
|
||||
// [web] Second type argument 'Anonymous' is not a Dart interface type.
|
||||
// [web] Type argument 'Anonymous' needs to be a non-JS interop type.
|
||||
// [web] Type argument 'Dart' needs to be a `@staticInterop` type.
|
||||
createStaticInteropMock<StaticInterop, void Function()>(() {});
|
||||
//^
|
||||
// [web] Second type argument 'void Function()' is not a Dart interface type.
|
||||
// [web] Type argument 'void Function()' needs to be an interface type.
|
||||
createStaticInteropMock(Dart());
|
||||
//^
|
||||
// [web] First type argument 'dynamic' is not a `@staticInterop` type.
|
||||
// [web] Type argument 'Object' needs to be a `@staticInterop` type.
|
||||
}
|
||||
|
|
|
@ -2,9 +2,8 @@
|
|||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
// Basic inheritance test where @staticInterop class inherits extension methods
|
||||
// which are then defined in the Dart class' inheritance chain, with some
|
||||
// overrides.
|
||||
// Test that @staticInterop extension methods are collected from all extensions,
|
||||
// including inheritance.
|
||||
|
||||
import 'package:expect/minitest.dart';
|
||||
import 'package:js/js.dart';
|
||||
|
@ -18,8 +17,8 @@ extension on Extends {
|
|||
external int extendsMethod(int val);
|
||||
external int extendsField;
|
||||
external final int extendsFinalField;
|
||||
external int get getSet;
|
||||
external set getSet(int val);
|
||||
external int get extendsGetSet;
|
||||
external set extendsGetSet(int val);
|
||||
}
|
||||
|
||||
@JS()
|
||||
|
@ -27,15 +26,12 @@ extension on Extends {
|
|||
class Implements {}
|
||||
|
||||
extension on Implements {
|
||||
@JS('_implementsMethod')
|
||||
external int implementsMethod(int val);
|
||||
@JS('_implementsField')
|
||||
external int implementsField;
|
||||
@JS('_implementsFinalField')
|
||||
external final int implementsFinalField;
|
||||
@JS('_implementsGetter')
|
||||
@JS('implementsGetSet')
|
||||
external int get implementsGetter;
|
||||
@JS('_implementsSetter')
|
||||
@JS('implementsGetSet')
|
||||
external set implementsSetter(int val);
|
||||
}
|
||||
|
||||
|
@ -47,43 +43,59 @@ extension on Inheritance {
|
|||
external int method(int val);
|
||||
external int field;
|
||||
external final int finalField;
|
||||
// Overrides
|
||||
external int get getSet;
|
||||
external set getSet(int val);
|
||||
}
|
||||
|
||||
extension on Inheritance {
|
||||
external int method2(int val);
|
||||
external int field2;
|
||||
external final int finalField2;
|
||||
external int get getSet2;
|
||||
external set getSet2(int val);
|
||||
}
|
||||
|
||||
@JSExport()
|
||||
class ExtendsDart {
|
||||
int extendsMethod(int val) => val;
|
||||
int extendsField = 0;
|
||||
final int extendsFinalField = 0;
|
||||
int getSet = 0;
|
||||
int extendsGetSet = 0;
|
||||
}
|
||||
|
||||
@JSExport()
|
||||
class ImplementsMixin {
|
||||
int implementsMethod(int val) => val;
|
||||
int implementsField = 1;
|
||||
final int implementsFinalField = 1;
|
||||
int _implementsGetSet = 1;
|
||||
int get implementsGetter => _implementsGetSet;
|
||||
set implementsSetter(int val) => _implementsGetSet = val;
|
||||
int implementsGetSet = 1;
|
||||
}
|
||||
|
||||
@JSExport()
|
||||
class InheritanceDart extends ExtendsDart with ImplementsMixin {
|
||||
int method(int val) => val;
|
||||
int field = 2;
|
||||
final int finalField = 2;
|
||||
@override
|
||||
int getSet = 2;
|
||||
int method2(int val) => val;
|
||||
int field2 = 2;
|
||||
final int finalField2 = 2;
|
||||
int getSet2 = 2;
|
||||
}
|
||||
|
||||
void main() {
|
||||
var dartMock = InheritanceDart();
|
||||
var jsMock = createStaticInteropMock<Inheritance, InheritanceDart>(dartMock);
|
||||
|
||||
expect(jsMock.extendsMethod(0), 0);
|
||||
expect(jsMock.extendsField, 0);
|
||||
jsMock.extendsField = 1;
|
||||
expect(jsMock.extendsField, 1);
|
||||
expect(jsMock.extendsFinalField, 0);
|
||||
expect(jsMock.extendsGetSet, 0);
|
||||
// Dart mock uses a field for this getter and setter, so it should change.
|
||||
jsMock.extendsGetSet = 1;
|
||||
expect(jsMock.extendsGetSet, 1);
|
||||
|
||||
expect(jsMock.implementsMethod(1), 1);
|
||||
expect(jsMock.implementsField, 1);
|
||||
|
@ -92,7 +104,6 @@ void main() {
|
|||
expect(jsMock.implementsFinalField, 1);
|
||||
expect(jsMock.implementsGetter, 1);
|
||||
jsMock.implementsSetter = 2;
|
||||
// Dart mock uses a field for this getter and setter, so it should change.
|
||||
expect(jsMock.implementsGetter, 2);
|
||||
|
||||
expect(jsMock.method(2), 2);
|
||||
|
@ -103,4 +114,13 @@ void main() {
|
|||
expect(jsMock.getSet, 2);
|
||||
jsMock.getSet = 3;
|
||||
expect(jsMock.getSet, 3);
|
||||
|
||||
expect(jsMock.method2(2), 2);
|
||||
expect(jsMock.field2, 2);
|
||||
jsMock.field2 = 3;
|
||||
expect(jsMock.field2, 3);
|
||||
expect(jsMock.finalField2, 2);
|
||||
expect(jsMock.getSet2, 2);
|
||||
jsMock.getSet2 = 3;
|
||||
expect(jsMock.getSet2, 3);
|
||||
}
|
||||
|
|
|
@ -1,183 +0,0 @@
|
|||
// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
// Test that `createStaticInteropMock` checks that there aren't any missing
|
||||
// overrides.
|
||||
|
||||
import 'package:js/js.dart';
|
||||
import 'package:js/js_util.dart';
|
||||
|
||||
@JS()
|
||||
@staticInterop
|
||||
class StaticInterop {}
|
||||
|
||||
extension on StaticInterop {
|
||||
external int field;
|
||||
external final int finalField;
|
||||
external int get getSet;
|
||||
external set getSet(int val);
|
||||
external void method();
|
||||
|
||||
// We should ignore the non-external members for determining overrides.
|
||||
int get nonExternalGetSet => throw '';
|
||||
set nonExternalGetSet(int val) => throw '';
|
||||
void nonExternalMethod() => throw '';
|
||||
}
|
||||
|
||||
class CorrectDart {
|
||||
int field = throw '';
|
||||
final int finalField = throw '';
|
||||
int get getSet => throw '';
|
||||
set getSet(int val) => throw '';
|
||||
void method() => throw '';
|
||||
}
|
||||
|
||||
class DartStatic {
|
||||
static int field = throw '';
|
||||
final int finalField = throw '';
|
||||
int get getSet => throw '';
|
||||
set getSet(int val) => throw '';
|
||||
void method() => throw '';
|
||||
}
|
||||
|
||||
class DartUsingExtensions {
|
||||
int field = throw '';
|
||||
final int finalField = throw '';
|
||||
int get getSet => throw '';
|
||||
set getSet(int val) => throw '';
|
||||
}
|
||||
|
||||
extension on DartUsingExtensions {
|
||||
void method() => throw '';
|
||||
}
|
||||
|
||||
class DartFactory {
|
||||
DartFactory();
|
||||
factory DartFactory.finalField() => DartFactory();
|
||||
int field = throw '';
|
||||
int get getSet => throw '';
|
||||
set getSet(int val) => throw '';
|
||||
void method() => throw '';
|
||||
}
|
||||
|
||||
class DartFinal {
|
||||
final int field = throw '';
|
||||
final int finalField = throw '';
|
||||
int get getSet => throw '';
|
||||
set getSet(int val) => throw '';
|
||||
void method() => throw '';
|
||||
}
|
||||
|
||||
class DartNoGet {
|
||||
int field = throw '';
|
||||
final int finalField = throw '';
|
||||
set getSet(int val) => throw '';
|
||||
void method() => throw '';
|
||||
}
|
||||
|
||||
class DartNoSet {
|
||||
int field = throw '';
|
||||
final int finalField = throw '';
|
||||
int get getSet => throw '';
|
||||
void method() => throw '';
|
||||
}
|
||||
|
||||
class DartNoMembers {}
|
||||
|
||||
void main() {
|
||||
createStaticInteropMock<StaticInterop, CorrectDart>(CorrectDart());
|
||||
// Static members do not qualify as an override.
|
||||
createStaticInteropMock<StaticInterop, DartStatic>(
|
||||
//^
|
||||
// [web] `@staticInterop` class 'StaticInterop' has external extension member 'field', but Dart class 'DartStatic' does not have an overriding instance member.
|
||||
// [web] `@staticInterop` class 'StaticInterop' has external extension member 'field=', but Dart class 'DartStatic' does not have an overriding instance member.
|
||||
DartStatic());
|
||||
// Extension members do not qualify as an override.
|
||||
createStaticInteropMock<StaticInterop, DartUsingExtensions>(
|
||||
//^
|
||||
// [web] `@staticInterop` class 'StaticInterop' has external extension member 'method', but Dart class 'DartUsingExtensions' does not have an overriding instance member.
|
||||
DartUsingExtensions());
|
||||
// Factory members with the same name do not qualify as an override.
|
||||
createStaticInteropMock<StaticInterop, DartFactory>(
|
||||
//^
|
||||
// [web] `@staticInterop` class 'StaticInterop' has external extension member 'finalField', but Dart class 'DartFactory' does not have an overriding instance member.
|
||||
DartFactory());
|
||||
// Final fields can not override a setter.
|
||||
createStaticInteropMock<StaticInterop, DartFinal>(DartFinal());
|
||||
//^
|
||||
// [web] `@staticInterop` class 'StaticInterop' has external extension member 'field=', but Dart class 'DartFinal' does not have an overriding instance member.
|
||||
createStaticInteropMock<StaticInterop, DartNoGet>(DartNoGet());
|
||||
//^
|
||||
// [web] `@staticInterop` class 'StaticInterop' has external extension member 'getSet', but Dart class 'DartNoGet' does not have an overriding instance member.
|
||||
|
||||
// Test that getters are treated differently from setters even though they
|
||||
// share the same name.
|
||||
createStaticInteropMock<StaticInterop, DartNoSet>(DartNoSet());
|
||||
//^
|
||||
// [web] `@staticInterop` class 'StaticInterop' has external extension member 'getSet=', but Dart class 'DartNoSet' does not have an overriding instance member.
|
||||
|
||||
// Test multiple missing members.
|
||||
createStaticInteropMock<StaticInterop, DartNoMembers>(
|
||||
//^
|
||||
// [web] `@staticInterop` class 'StaticInterop' has external extension member 'field', but Dart class 'DartNoMembers' does not have an overriding instance member.
|
||||
// [web] `@staticInterop` class 'StaticInterop' has external extension member 'field=', but Dart class 'DartNoMembers' does not have an overriding instance member.
|
||||
// [web] `@staticInterop` class 'StaticInterop' has external extension member 'finalField', but Dart class 'DartNoMembers' does not have an overriding instance member.
|
||||
// [web] `@staticInterop` class 'StaticInterop' has external extension member 'getSet', but Dart class 'DartNoMembers' does not have an overriding instance member.
|
||||
// [web] `@staticInterop` class 'StaticInterop' has external extension member 'getSet=', but Dart class 'DartNoMembers' does not have an overriding instance member.
|
||||
// [web] `@staticInterop` class 'StaticInterop' has external extension member 'method', but Dart class 'DartNoMembers' does not have an overriding instance member.
|
||||
DartNoMembers());
|
||||
|
||||
testUsingInheritanceAndMixins();
|
||||
}
|
||||
|
||||
// The following should classes should not contain any override errors, as they
|
||||
// have all the necessary members.
|
||||
class DartWithInheritance extends DartNoSet {
|
||||
set getSet(int val) => throw '';
|
||||
}
|
||||
|
||||
class DartWithMixins with CorrectDart {}
|
||||
|
||||
mixin MixinSet {
|
||||
set getSet(int val) => throw '';
|
||||
}
|
||||
|
||||
class DartWithMixinsAndInheritance extends DartNoSet with MixinSet {}
|
||||
|
||||
@JS()
|
||||
@staticInterop
|
||||
class BaseStaticInterop {}
|
||||
|
||||
extension on BaseStaticInterop {
|
||||
external void baseMethod();
|
||||
}
|
||||
|
||||
@JS()
|
||||
@staticInterop
|
||||
class StaticInteropWithInheritance extends BaseStaticInterop
|
||||
implements StaticInterop {}
|
||||
|
||||
class DartImplementingInteropInheritance extends DartWithMixinsAndInheritance {
|
||||
void baseMethod() => throw '';
|
||||
}
|
||||
|
||||
void testUsingInheritanceAndMixins() {
|
||||
// Test where Dart class implements using inherited members.
|
||||
createStaticInteropMock<StaticInterop, DartWithInheritance>(
|
||||
DartWithInheritance());
|
||||
// Test where Dart class implements using mixed-in members.
|
||||
createStaticInteropMock<StaticInterop, DartWithMixins>(DartWithMixins());
|
||||
// Test where Dart class implements using inherited and mixed-in members.
|
||||
createStaticInteropMock<StaticInterop, DartWithMixinsAndInheritance>(
|
||||
DartWithMixinsAndInheritance());
|
||||
// Missing inherited method, expect an error.
|
||||
createStaticInteropMock<
|
||||
//^
|
||||
// [web] `@staticInterop` class 'StaticInteropWithInheritance' has external extension member 'baseMethod', but Dart class 'DartWithMixinsAndInheritance' does not have an overriding instance member.
|
||||
StaticInteropWithInheritance,
|
||||
DartWithMixinsAndInheritance>(DartWithMixinsAndInheritance());
|
||||
// Added missing method, should pass.
|
||||
createStaticInteropMock<StaticInteropWithInheritance,
|
||||
DartImplementingInteropInheritance>(DartImplementingInteropInheritance());
|
||||
}
|
|
@ -24,6 +24,7 @@ extension on StaticInterop {
|
|||
external set getSet(int? val);
|
||||
}
|
||||
|
||||
@JSExport()
|
||||
class Dart {
|
||||
int? method(int? val) => throw '';
|
||||
int? field = throw '';
|
||||
|
@ -34,6 +35,7 @@ class Dart {
|
|||
|
||||
// Have the mock class implement the class interface you defined to mock the
|
||||
// @staticInterop interface.
|
||||
@JSExport()
|
||||
class DartMock extends Mock implements Dart {}
|
||||
|
||||
void main() {
|
||||
|
|
|
@ -26,7 +26,10 @@ external Object get windowType;
|
|||
@staticInterop
|
||||
class JSWindow {}
|
||||
|
||||
class DartWindow {}
|
||||
@JSExport()
|
||||
class DartWindow {
|
||||
int _unused = 0;
|
||||
}
|
||||
|
||||
void main() {
|
||||
// Test that everything still works the same.
|
||||
|
|
|
@ -2,11 +2,67 @@
|
|||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
// Test that `createStaticInteropMock` checks that overrides are subtypes.
|
||||
// Test that `createStaticInteropMock` checks that overrides exist and are
|
||||
// subtypes.
|
||||
|
||||
import 'package:js/js.dart';
|
||||
import 'package:js/js_util.dart';
|
||||
|
||||
@JS()
|
||||
@staticInterop
|
||||
class StaticInterop {}
|
||||
|
||||
extension on StaticInterop {
|
||||
external int field;
|
||||
external final int finalField;
|
||||
external int get getSet1;
|
||||
external set getSet1(int val);
|
||||
external int get getSet2;
|
||||
external set getSet2(int val);
|
||||
external void method();
|
||||
}
|
||||
|
||||
@JSExport()
|
||||
class CorrectDart {
|
||||
int field = throw '';
|
||||
final int finalField = throw '';
|
||||
int get getSet1 => throw '';
|
||||
set getSet1(int val) => throw '';
|
||||
int get getSet2 => throw '';
|
||||
set getSet2(int val) => throw '';
|
||||
void method() => throw '';
|
||||
}
|
||||
|
||||
@JSExport()
|
||||
class IncorrectDart {
|
||||
IncorrectDart();
|
||||
// Factories do not count.
|
||||
factory IncorrectDart.method() => IncorrectDart();
|
||||
// Setter is not implemented.
|
||||
final int field = throw '';
|
||||
// Static members do not count.
|
||||
static final int finalField = throw '';
|
||||
// Getter is not implemented.
|
||||
set getSet1(int val) => throw '';
|
||||
int get getSet2 => throw '';
|
||||
}
|
||||
|
||||
extension on IncorrectDart {
|
||||
// Extension members do not count.
|
||||
set getSet2(int val) => throw '';
|
||||
}
|
||||
|
||||
void testMissingOverrides() {
|
||||
createStaticInteropMock<StaticInterop, CorrectDart>(CorrectDart());
|
||||
createStaticInteropMock<StaticInterop, IncorrectDart>(IncorrectDart());
|
||||
//^
|
||||
// [web] Dart class 'IncorrectDart' does not have any members that implement any of the following extension member(s) with export name 'finalField': <unnamed>.finalField (FunctionType(int Function())).
|
||||
// [web] Dart class 'IncorrectDart' does not have any members that implement any of the following extension member(s) with export name 'method': <unnamed>.method (FunctionType(void Function())).
|
||||
// [web] Dart class 'IncorrectDart' has a getter, but does not have a setter to implement any of the following extension member(s) with export name 'field': <unnamed>.field= (FunctionType(void Function(int))).
|
||||
// [web] Dart class 'IncorrectDart' has a getter, but does not have a setter to implement any of the following extension member(s) with export name 'getSet2': <unnamed>.getSet2= (FunctionType(void Function(int))).
|
||||
// [web] Dart class 'IncorrectDart' has a setter, but does not have a getter to implement any of the following extension member(s) with export name 'getSet1': <unnamed>.getSet1 (FunctionType(int Function())).
|
||||
}
|
||||
|
||||
// Set up a simple type hierarchy.
|
||||
class A {
|
||||
const A();
|
||||
|
@ -27,38 +83,61 @@ class SimpleInterop {}
|
|||
extension SimpleInteropExtension on SimpleInterop {
|
||||
external B field;
|
||||
external final B finalField;
|
||||
external B get getSetNum;
|
||||
external set getSetInt(B val);
|
||||
external B get getSet;
|
||||
external set getSet(B val);
|
||||
external B method(B b);
|
||||
}
|
||||
|
||||
// Implement using the exact same types.
|
||||
@JSExport()
|
||||
class SimpleDart {
|
||||
B field = throw '';
|
||||
final B finalField = throw '';
|
||||
B get getSetNum => throw '';
|
||||
set getSetInt(B val) => throw '';
|
||||
B get getSet => throw '';
|
||||
set getSet(B val) => throw '';
|
||||
B method(B b) => throw '';
|
||||
}
|
||||
|
||||
void testExactTypes() {
|
||||
createStaticInteropMock<SimpleInterop, SimpleDart>(SimpleDart());
|
||||
}
|
||||
|
||||
// Implement using subtypes.
|
||||
@JSExport()
|
||||
class SubtypeSimpleDart {
|
||||
B field = throw '';
|
||||
final C finalField = throw '';
|
||||
C get getSetNum => throw '';
|
||||
set getSetInt(A val) => throw '';
|
||||
C get getSet => throw '';
|
||||
set getSet(A val) => throw '';
|
||||
C method(A a) => throw '';
|
||||
}
|
||||
|
||||
void testSimpleSubtyping() {
|
||||
createStaticInteropMock<SimpleInterop, SubtypeSimpleDart>(
|
||||
SubtypeSimpleDart());
|
||||
}
|
||||
|
||||
// Implement using supertypes (which shouldn't work).
|
||||
@JSExport()
|
||||
class SupertypeSimpleDart {
|
||||
A field = throw '';
|
||||
final A finalField = throw '';
|
||||
A get getSetNum => throw '';
|
||||
set getSetInt(C val) => throw '';
|
||||
// Getter must be subtype of setter, so only the setter should be an error.
|
||||
C get getSet => throw '';
|
||||
set getSet(C val) => throw '';
|
||||
A method(C c) => throw '';
|
||||
}
|
||||
|
||||
void testIncorrectSimpleSubtyping() {
|
||||
createStaticInteropMock<SimpleInterop, SupertypeSimpleDart>(
|
||||
//^
|
||||
// [web] Dart class 'SupertypeSimpleDart' does not have any members that implement any of the following extension member(s) with export name 'finalField': SimpleInteropExtension.finalField (FunctionType(B Function())).
|
||||
// [web] Dart class 'SupertypeSimpleDart' does not have any members that implement any of the following extension member(s) with export name 'method': SimpleInteropExtension.method (FunctionType(B Function(B))).
|
||||
// [web] Dart class 'SupertypeSimpleDart' has a getter, but does not have a setter to implement any of the following extension member(s) with export name 'getSet': SimpleInteropExtension.getSet= (FunctionType(void Function(B))).
|
||||
// [web] Dart class 'SupertypeSimpleDart' has a setter, but does not have a getter to implement any of the following extension member(s) with export name 'field': SimpleInteropExtension.field (FunctionType(B Function())).
|
||||
SupertypeSimpleDart());
|
||||
}
|
||||
|
||||
@JS()
|
||||
@staticInterop
|
||||
class ComplexAndOptionalInteropMethods {}
|
||||
|
@ -70,12 +149,19 @@ extension ComplexAndOptionalInteropMethodsExtension
|
|||
external B optionalSubtype(B b, [B b2 = const B()]);
|
||||
}
|
||||
|
||||
@JSExport()
|
||||
class ComplexAndOptionalDart {
|
||||
C Function(A _) nestedTypes(List<B> arg1, Map<Set<B>, B> arg2) => throw '';
|
||||
B optional(B b, [B? b2]) => throw '';
|
||||
C optionalSubtype(A a, [A? a2]) => throw '';
|
||||
}
|
||||
|
||||
void testComplexSubtyping() {
|
||||
createStaticInteropMock<ComplexAndOptionalInteropMethods,
|
||||
ComplexAndOptionalDart>(ComplexAndOptionalDart());
|
||||
}
|
||||
|
||||
@JSExport()
|
||||
class IncorrectComplexAndOptionalDart {
|
||||
// List type is wrong.
|
||||
B Function(B _) nestedTypes(List<List<B>> arg1, Map<Set<B>, B> arg2) =>
|
||||
|
@ -86,25 +172,25 @@ class IncorrectComplexAndOptionalDart {
|
|||
B optionalSubtype(B b, [C c = const C()]) => throw '';
|
||||
}
|
||||
|
||||
void main() {
|
||||
createStaticInteropMock<SimpleInterop, SimpleDart>(SimpleDart());
|
||||
createStaticInteropMock<SimpleInterop, SubtypeSimpleDart>(
|
||||
SubtypeSimpleDart());
|
||||
createStaticInteropMock<SimpleInterop, SupertypeSimpleDart>(
|
||||
//^
|
||||
// [web] Dart class member 'SupertypeSimpleDart.field' with type 'A Function()' is not a subtype of `@staticInterop` external extension member 'SimpleInterop.field' with type 'B Function()'.
|
||||
// [web] Dart class member 'SupertypeSimpleDart.finalField' with type 'A Function()' is not a subtype of `@staticInterop` external extension member 'SimpleInterop.finalField' with type 'B Function()'.
|
||||
// [web] Dart class member 'SupertypeSimpleDart.getSetInt=' with type 'void Function(C)' is not a subtype of `@staticInterop` external extension member 'SimpleInterop.getSetInt=' with type 'void Function(B)'.
|
||||
// [web] Dart class member 'SupertypeSimpleDart.getSetNum' with type 'A Function()' is not a subtype of `@staticInterop` external extension member 'SimpleInterop.getSetNum' with type 'B Function()'.
|
||||
// [web] Dart class member 'SupertypeSimpleDart.method' with type 'A Function(C)' is not a subtype of `@staticInterop` external extension member 'SimpleInterop.method' with type 'B Function(B)'.
|
||||
SupertypeSimpleDart());
|
||||
createStaticInteropMock<ComplexAndOptionalInteropMethods,
|
||||
ComplexAndOptionalDart>(ComplexAndOptionalDart());
|
||||
void testIncorrectComplexSubtyping() {
|
||||
createStaticInteropMock<
|
||||
//^
|
||||
// [web] Dart class member 'IncorrectComplexAndOptionalDart.nestedTypes' with type 'B Function(B) Function(List<List<B>>, Map<Set<B>, B>)' is not a subtype of `@staticInterop` external extension member 'ComplexAndOptionalInteropMethods.nestedTypes' with type 'B Function(B) Function(List<B>, Map<Set<B>, B>)'.
|
||||
// [web] Dart class member 'IncorrectComplexAndOptionalDart.optional' with type 'B Function(B, B?)' is not a subtype of `@staticInterop` external extension member 'ComplexAndOptionalInteropMethods.optional' with type 'B Function(B, [B?])'.
|
||||
// [web] Dart class member 'IncorrectComplexAndOptionalDart.optionalSubtype' with type 'B Function(B, [C])' is not a subtype of `@staticInterop` external extension member 'ComplexAndOptionalInteropMethods.optionalSubtype' with type 'B Function(B, [B])'.
|
||||
// [web] Dart class 'IncorrectComplexAndOptionalDart' does not have any members that implement any of the following extension member(s) with export name 'nestedTypes': ComplexAndOptionalInteropMethodsExtension.nestedTypes (FunctionType(B Function(B) Function(List<B>, Map<Set<B>, B>))).
|
||||
// [web] Dart class 'IncorrectComplexAndOptionalDart' does not have any members that implement any of the following extension member(s) with export name 'optional': ComplexAndOptionalInteropMethodsExtension.optional (FunctionType(B Function(B, [B?]))).
|
||||
// [web] Dart class 'IncorrectComplexAndOptionalDart' does not have any members that implement any of the following extension member(s) with export name 'optionalSubtype': ComplexAndOptionalInteropMethodsExtension.optionalSubtype (FunctionType(B Function(B, [B]))).
|
||||
ComplexAndOptionalInteropMethods,
|
||||
IncorrectComplexAndOptionalDart>(IncorrectComplexAndOptionalDart());
|
||||
}
|
||||
|
||||
void testSubtyping() {
|
||||
testExactTypes();
|
||||
testSimpleSubtyping();
|
||||
testIncorrectSimpleSubtyping();
|
||||
testComplexSubtyping();
|
||||
testIncorrectComplexSubtyping();
|
||||
}
|
||||
|
||||
void main() {
|
||||
testMissingOverrides();
|
||||
testSubtyping();
|
||||
}
|
||||
|
|
|
@ -3,176 +3,102 @@
|
|||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
// Test that `createStaticInteropMock` checks for extension member conflicts.
|
||||
// We should only require users to implement one of these conflicts (or a
|
||||
// getter/setter pair).
|
||||
|
||||
import 'package:js/js.dart';
|
||||
import 'package:js/js_util.dart';
|
||||
|
||||
class EmptyDart {}
|
||||
|
||||
@JS()
|
||||
@staticInterop
|
||||
class Method {}
|
||||
class SameKindConflict {}
|
||||
|
||||
extension on Method {
|
||||
external void member();
|
||||
extension E1 on SameKindConflict {
|
||||
external int get getter;
|
||||
external set setter(int val);
|
||||
external int method();
|
||||
}
|
||||
|
||||
@JS()
|
||||
@staticInterop
|
||||
class Getter {}
|
||||
|
||||
extension NamedExtension on Getter {
|
||||
external int get member;
|
||||
extension E2 on SameKindConflict {
|
||||
external String get getter;
|
||||
external set setter(int val);
|
||||
external String method();
|
||||
}
|
||||
|
||||
@JS()
|
||||
@staticInterop
|
||||
class Field {}
|
||||
|
||||
extension on Field {
|
||||
external final String member;
|
||||
@JSExport()
|
||||
class DartSameKindConflict {
|
||||
String getter = '';
|
||||
set setter(int val) => throw '';
|
||||
String method() => throw '';
|
||||
}
|
||||
|
||||
@JS()
|
||||
@staticInterop
|
||||
class ExtendsImplementsConflict extends Method implements Getter {}
|
||||
|
||||
@JS()
|
||||
@staticInterop
|
||||
class ImplementsConflict implements Method, Getter {}
|
||||
|
||||
@JS()
|
||||
@staticInterop
|
||||
class ManyConflicts extends Method implements Getter, Field {}
|
||||
|
||||
@JS()
|
||||
@staticInterop
|
||||
class Override implements Method {}
|
||||
|
||||
extension on Override {
|
||||
external int member();
|
||||
@JSExport()
|
||||
class IncorrectDartSameKindConflict {
|
||||
bool getter = true;
|
||||
set setter(bool val) => throw '';
|
||||
bool method() => throw '';
|
||||
}
|
||||
|
||||
@JS()
|
||||
@staticInterop
|
||||
class OverrideOneConflictButNotAll implements Override, Getter {}
|
||||
|
||||
@JS()
|
||||
@staticInterop
|
||||
class ConflictThroughInheritance implements OverrideOneConflictButNotAll {}
|
||||
|
||||
@JS()
|
||||
@staticInterop
|
||||
class ResolveThroughOverride implements ConflictThroughInheritance {}
|
||||
|
||||
extension on ResolveThroughOverride {
|
||||
external int member;
|
||||
}
|
||||
|
||||
class ResolveThroughOverrideDart {
|
||||
int member = throw '';
|
||||
}
|
||||
|
||||
@JS()
|
||||
@staticInterop
|
||||
class Setter {}
|
||||
|
||||
extension on Setter {
|
||||
external set member(int val);
|
||||
}
|
||||
|
||||
@JS()
|
||||
@staticInterop
|
||||
class NoConflictDueToSubtype implements Override, Method {}
|
||||
|
||||
class NoConflictDueToSubtypeDart {
|
||||
int member() => throw '';
|
||||
}
|
||||
|
||||
@JS()
|
||||
@staticInterop
|
||||
class GetterSetterConflict implements Setter, Getter {}
|
||||
|
||||
@JS()
|
||||
@staticInterop
|
||||
class GetterSetterSameExtension {}
|
||||
|
||||
extension on GetterSetterSameExtension {
|
||||
external int get member;
|
||||
external set member(int val);
|
||||
}
|
||||
|
||||
class GetterSetterSameExtensionDart extends ResolveThroughOverrideDart {}
|
||||
|
||||
@JS()
|
||||
@staticInterop
|
||||
class GetterSetterMethodConflict implements GetterSetterSameExtension, Method {}
|
||||
|
||||
@JS()
|
||||
@staticInterop
|
||||
class NonExternal {}
|
||||
|
||||
extension on NonExternal {
|
||||
int get member => throw '';
|
||||
}
|
||||
|
||||
@JS()
|
||||
@staticInterop
|
||||
class ExternalNonExternal implements NonExternal, GetterSetterSameExtension {}
|
||||
|
||||
class ExternalNonExternalDart extends ResolveThroughOverrideDart {}
|
||||
|
||||
void main() {
|
||||
// Test name conflicts between extended and implemented members.
|
||||
createStaticInteropMock<ExtendsImplementsConflict, EmptyDart>(
|
||||
void testSameKindConflict() {
|
||||
// No error as one of the extension members are implemented for each export
|
||||
// name.
|
||||
createStaticInteropMock<SameKindConflict, DartSameKindConflict>(
|
||||
DartSameKindConflict());
|
||||
// Error as none of them are implemented for each export name.
|
||||
createStaticInteropMock<SameKindConflict, IncorrectDartSameKindConflict>(
|
||||
//^
|
||||
// [web] External extension member with name 'member' is defined in the following extensions and none are more specific: 'Getter.NamedExtension', 'Method.unnamed'.
|
||||
EmptyDart());
|
||||
// Test name conflicts between implemented members.
|
||||
createStaticInteropMock<ImplementsConflict, EmptyDart>(EmptyDart());
|
||||
//^
|
||||
// [web] External extension member with name 'member' is defined in the following extensions and none are more specific: 'Getter.NamedExtension', 'Method.unnamed'.
|
||||
|
||||
// Test multiple name conflicts.
|
||||
createStaticInteropMock<ManyConflicts, EmptyDart>(EmptyDart());
|
||||
//^
|
||||
// [web] External extension member with name 'member' is defined in the following extensions and none are more specific: 'Field.unnamed', 'Getter.NamedExtension', 'Method.unnamed'.
|
||||
|
||||
// Test name conflicts where one definition is overridden, but there is still
|
||||
// a name conflict between the other two.
|
||||
createStaticInteropMock<OverrideOneConflictButNotAll, EmptyDart>(
|
||||
//^
|
||||
// [web] External extension member with name 'member' is defined in the following extensions and none are more specific: 'Getter.NamedExtension', 'Override.unnamed'.
|
||||
EmptyDart());
|
||||
// Test case where if we inherit a class with a conflict, the conflict still
|
||||
// exists.
|
||||
createStaticInteropMock<ConflictThroughInheritance, EmptyDart>(
|
||||
//^
|
||||
// [web] External extension member with name 'member' is defined in the following extensions and none are more specific: 'Getter.NamedExtension', 'Override.unnamed'.
|
||||
EmptyDart());
|
||||
// Test case where name conflicts are resolved using derived class.
|
||||
createStaticInteropMock<ResolveThroughOverride, ResolveThroughOverrideDart>(
|
||||
ResolveThroughOverrideDart());
|
||||
// Test case where you inherit two classes with the same member name but they
|
||||
// have a subtype relation, so there is no conflict.
|
||||
createStaticInteropMock<NoConflictDueToSubtype, NoConflictDueToSubtypeDart>(
|
||||
NoConflictDueToSubtypeDart());
|
||||
// Test conflict where getter and setter collide when they are in different
|
||||
// extensions.
|
||||
createStaticInteropMock<GetterSetterConflict, EmptyDart>(EmptyDart());
|
||||
//^
|
||||
// [web] External extension member with name 'member' is defined in the following extensions and none are more specific: 'Getter.NamedExtension', 'Setter.unnamed'.
|
||||
|
||||
// Test no conflict where getter and setter are on the same extension.
|
||||
createStaticInteropMock<GetterSetterSameExtension,
|
||||
GetterSetterSameExtensionDart>(GetterSetterSameExtensionDart());
|
||||
// Test conflict where getter and setter are in one extension, but there is
|
||||
// a conflict with another extension.
|
||||
createStaticInteropMock<GetterSetterMethodConflict, EmptyDart>(EmptyDart());
|
||||
//^
|
||||
// [web] External extension member with name 'member' is defined in the following extensions and none are more specific: 'GetterSetterSameExtension.unnamed', 'Method.unnamed'.
|
||||
|
||||
// Test no conflict between external and non-external members.
|
||||
createStaticInteropMock<ExternalNonExternal, ExternalNonExternalDart>(
|
||||
ExternalNonExternalDart());
|
||||
// [web] Dart class 'IncorrectDartSameKindConflict' does not have any members that implement any of the following extension member(s) with export name 'getter': E1.getter (FunctionType(int Function())), E2.getter (FunctionType(String Function())).
|
||||
// [web] Dart class 'IncorrectDartSameKindConflict' does not have any members that implement any of the following extension member(s) with export name 'method': E1.method (FunctionType(int Function())), E2.method (FunctionType(String Function())).
|
||||
// [web] Dart class 'IncorrectDartSameKindConflict' does not have any members that implement any of the following extension member(s) with export name 'setter': E1.setter= (FunctionType(void Function(int))), E2.setter= (FunctionType(void Function(int))).
|
||||
IncorrectDartSameKindConflict());
|
||||
}
|
||||
|
||||
@JS()
|
||||
@staticInterop
|
||||
class DifferentKindConflict {}
|
||||
|
||||
extension E3 on DifferentKindConflict {
|
||||
external int getSet;
|
||||
@JS('getSet')
|
||||
external void method();
|
||||
}
|
||||
|
||||
@JSExport()
|
||||
class ImplementGetter {
|
||||
int get getSet => throw '';
|
||||
}
|
||||
|
||||
@JSExport()
|
||||
class ImplementSetter {
|
||||
set getSet(int val) => throw '';
|
||||
}
|
||||
|
||||
@JSExport()
|
||||
class ImplementBoth {
|
||||
int getSet = 0;
|
||||
}
|
||||
|
||||
@JSExport()
|
||||
class ImplementMethod {
|
||||
void getSet() {}
|
||||
}
|
||||
|
||||
void testDifferentKindConflict() {
|
||||
// Missing setter error.
|
||||
createStaticInteropMock<DifferentKindConflict, ImplementGetter>(
|
||||
//^
|
||||
// [web] Dart class 'ImplementGetter' has a getter, but does not have a setter to implement any of the following extension member(s) with export name 'getSet': E3.getSet= (FunctionType(void Function(int))).
|
||||
ImplementGetter());
|
||||
// Missing getter error.
|
||||
createStaticInteropMock<DifferentKindConflict, ImplementSetter>(
|
||||
//^
|
||||
// [web] Dart class 'ImplementSetter' has a setter, but does not have a getter to implement any of the following extension member(s) with export name 'getSet': E3.getSet (FunctionType(int Function())).
|
||||
ImplementSetter());
|
||||
// No error as both getter and setter are there, and we've satisfied an export
|
||||
// for `getSet`.
|
||||
createStaticInteropMock<DifferentKindConflict, ImplementBoth>(
|
||||
ImplementBoth());
|
||||
// No error as we've satisfied an export for `getSet`.
|
||||
createStaticInteropMock<DifferentKindConflict, ImplementMethod>(
|
||||
ImplementMethod());
|
||||
}
|
||||
|
|
|
@ -23,10 +23,11 @@ extension on Methods {
|
|||
external int optionalAdd(int a, int b, [int c = 0, int? d]);
|
||||
}
|
||||
|
||||
@JSExport()
|
||||
class MethodsDart {
|
||||
int add(int a, int b) => a + b;
|
||||
int nonExternal() => 1;
|
||||
int rename() => 1;
|
||||
int _rename() => 1;
|
||||
int optionalAdd(int a, int b, [int? c, int? d]) =>
|
||||
a + b + (c ?? 0) + (d ?? 0);
|
||||
}
|
||||
|
@ -44,11 +45,12 @@ extension on Fields {
|
|||
external final int renamedFinalField;
|
||||
}
|
||||
|
||||
@JSExport()
|
||||
class FieldsDart {
|
||||
int field = 1;
|
||||
int finalField = 1;
|
||||
int renamedField = 1;
|
||||
final int renamedFinalField = 1;
|
||||
int _renamedField = 1;
|
||||
final int _renamedFinalField = 1;
|
||||
}
|
||||
|
||||
@JS()
|
||||
|
@ -72,12 +74,13 @@ extension on GetSet {
|
|||
external set differentNameSameRenameSet(int val);
|
||||
}
|
||||
|
||||
@JSExport()
|
||||
class GetSetDart {
|
||||
int getSet = 1;
|
||||
int renamedGetSet = 1;
|
||||
int sameNameDifferentRename = 1;
|
||||
int differentNameSameRenameGet = 1;
|
||||
int differentNameSameRenameSet = 1;
|
||||
int _renamedGetSet = 1;
|
||||
int _sameNameDifferentRenameGet = 1;
|
||||
int _sameNameDifferentRenameSet = 1;
|
||||
int _differentNameSameRename = 1;
|
||||
}
|
||||
|
||||
void test([Object? proto]) {
|
||||
|
@ -99,11 +102,11 @@ void test([Object? proto]) {
|
|||
jsFields.field = 2;
|
||||
jsFields.renamedField = 2;
|
||||
expect(dartFields.field, 2);
|
||||
expect(dartFields.renamedField, 2);
|
||||
expect(dartFields._renamedField, 2);
|
||||
// Modify the Dart mock and check for updates in the JS mock.
|
||||
dartFields.field = 3;
|
||||
dartFields.finalField = 3;
|
||||
dartFields.renamedField = 3;
|
||||
dartFields._renamedField = 3;
|
||||
expect(jsFields.field, 3);
|
||||
expect(jsFields.finalField, 3);
|
||||
expect(jsFields.renamedField, 3);
|
||||
|
@ -119,17 +122,17 @@ void test([Object? proto]) {
|
|||
jsGetSet.sameNameDifferentRename = 2;
|
||||
jsGetSet.differentNameSameRenameSet = 2;
|
||||
expect(dartGetSet.getSet, 2);
|
||||
expect(dartGetSet.renamedGetSet, 2);
|
||||
expect(dartGetSet.sameNameDifferentRename, 2);
|
||||
expect(dartGetSet.differentNameSameRenameGet, 1);
|
||||
expect(dartGetSet.differentNameSameRenameSet, 2);
|
||||
expect(dartGetSet._renamedGetSet, 2);
|
||||
expect(dartGetSet._sameNameDifferentRenameGet, 1);
|
||||
expect(dartGetSet._sameNameDifferentRenameSet, 2);
|
||||
expect(dartGetSet._differentNameSameRename, 2);
|
||||
// Modify the Dart mock and check for updates in the JS mock.
|
||||
dartGetSet.getSet = 3;
|
||||
dartGetSet.renamedGetSet = 3;
|
||||
dartGetSet.sameNameDifferentRename = 3;
|
||||
dartGetSet._renamedGetSet = 3;
|
||||
// Use different values to disambiguate.
|
||||
dartGetSet.differentNameSameRenameGet = 3;
|
||||
dartGetSet.differentNameSameRenameSet = 4;
|
||||
dartGetSet._sameNameDifferentRenameGet = 3;
|
||||
dartGetSet._sameNameDifferentRenameSet = 4;
|
||||
dartGetSet._differentNameSameRename = 3;
|
||||
expect(jsGetSet.getSet, 3);
|
||||
expect(jsGetSet.renamedGetSet, 3);
|
||||
expect(jsGetSet.sameNameDifferentRename, 3);
|
||||
|
|
|
@ -24,26 +24,29 @@ class StaticInterop {
|
|||
external factory StaticInterop();
|
||||
}
|
||||
|
||||
class Dart {}
|
||||
@JSExport()
|
||||
class Dart {
|
||||
int _unused = 0;
|
||||
}
|
||||
|
||||
void main() {
|
||||
createStaticInteropMock<StaticInterop, Dart>(Dart());
|
||||
createStaticInteropMock<Dart, StaticInterop>(StaticInterop());
|
||||
//^
|
||||
// [web] First type argument 'Dart' is not a `@staticInterop` type.
|
||||
// [web] Second type argument 'StaticInterop' is not a Dart interface type.
|
||||
// [web] Type argument 'Dart' needs to be a `@staticInterop` type.
|
||||
// [web] Type argument 'StaticInterop' needs to be a non-JS interop type.
|
||||
createStaticInteropMock<Dart, Js>(Js());
|
||||
//^
|
||||
// [web] First type argument 'Dart' is not a `@staticInterop` type.
|
||||
// [web] Second type argument 'Js' is not a Dart interface type.
|
||||
// [web] Type argument 'Dart' needs to be a `@staticInterop` type.
|
||||
// [web] Type argument 'Js' needs to be a non-JS interop type.
|
||||
createStaticInteropMock<Dart, Anonymous>(Anonymous());
|
||||
//^
|
||||
// [web] First type argument 'Dart' is not a `@staticInterop` type.
|
||||
// [web] Second type argument 'Anonymous' is not a Dart interface type.
|
||||
// [web] Type argument 'Anonymous' needs to be a non-JS interop type.
|
||||
// [web] Type argument 'Dart' needs to be a `@staticInterop` type.
|
||||
createStaticInteropMock<StaticInterop, void Function()>(() {});
|
||||
//^
|
||||
// [web] Second type argument 'void Function()' is not a Dart interface type.
|
||||
// [web] Type argument 'void Function()' needs to be an interface type.
|
||||
createStaticInteropMock(Dart());
|
||||
//^
|
||||
// [web] First type argument 'dynamic' is not a `@staticInterop` type.
|
||||
// [web] Type argument 'Object' needs to be a `@staticInterop` type.
|
||||
}
|
||||
|
|
|
@ -2,9 +2,8 @@
|
|||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
// Basic inheritance test where @staticInterop class inherits extension methods
|
||||
// which are then defined in the Dart class' inheritance chain, with some
|
||||
// overrides.
|
||||
// Test that @staticInterop extension methods are collected from all extensions,
|
||||
// including inheritance.
|
||||
|
||||
import 'package:expect/minitest.dart';
|
||||
import 'package:js/js.dart';
|
||||
|
@ -18,8 +17,8 @@ extension on Extends {
|
|||
external int extendsMethod(int val);
|
||||
external int extendsField;
|
||||
external final int extendsFinalField;
|
||||
external int get getSet;
|
||||
external set getSet(int val);
|
||||
external int get extendsGetSet;
|
||||
external set extendsGetSet(int val);
|
||||
}
|
||||
|
||||
@JS()
|
||||
|
@ -27,15 +26,12 @@ extension on Extends {
|
|||
class Implements {}
|
||||
|
||||
extension on Implements {
|
||||
@JS('_implementsMethod')
|
||||
external int implementsMethod(int val);
|
||||
@JS('_implementsField')
|
||||
external int implementsField;
|
||||
@JS('_implementsFinalField')
|
||||
external final int implementsFinalField;
|
||||
@JS('_implementsGetter')
|
||||
@JS('implementsGetSet')
|
||||
external int get implementsGetter;
|
||||
@JS('_implementsSetter')
|
||||
@JS('implementsGetSet')
|
||||
external set implementsSetter(int val);
|
||||
}
|
||||
|
||||
|
@ -47,43 +43,59 @@ extension on Inheritance {
|
|||
external int method(int val);
|
||||
external int field;
|
||||
external final int finalField;
|
||||
// Overrides
|
||||
external int get getSet;
|
||||
external set getSet(int val);
|
||||
}
|
||||
|
||||
extension on Inheritance {
|
||||
external int method2(int val);
|
||||
external int field2;
|
||||
external final int finalField2;
|
||||
external int get getSet2;
|
||||
external set getSet2(int val);
|
||||
}
|
||||
|
||||
@JSExport()
|
||||
class ExtendsDart {
|
||||
int extendsMethod(int val) => val;
|
||||
int extendsField = 0;
|
||||
final int extendsFinalField = 0;
|
||||
int getSet = 0;
|
||||
int extendsGetSet = 0;
|
||||
}
|
||||
|
||||
@JSExport()
|
||||
class ImplementsMixin {
|
||||
int implementsMethod(int val) => val;
|
||||
int implementsField = 1;
|
||||
final int implementsFinalField = 1;
|
||||
int _implementsGetSet = 1;
|
||||
int get implementsGetter => _implementsGetSet;
|
||||
set implementsSetter(int val) => _implementsGetSet = val;
|
||||
int implementsGetSet = 1;
|
||||
}
|
||||
|
||||
@JSExport()
|
||||
class InheritanceDart extends ExtendsDart with ImplementsMixin {
|
||||
int method(int val) => val;
|
||||
int field = 2;
|
||||
final int finalField = 2;
|
||||
@override
|
||||
int getSet = 2;
|
||||
int method2(int val) => val;
|
||||
int field2 = 2;
|
||||
final int finalField2 = 2;
|
||||
int getSet2 = 2;
|
||||
}
|
||||
|
||||
void main() {
|
||||
var dartMock = InheritanceDart();
|
||||
var jsMock = createStaticInteropMock<Inheritance, InheritanceDart>(dartMock);
|
||||
|
||||
expect(jsMock.extendsMethod(0), 0);
|
||||
expect(jsMock.extendsField, 0);
|
||||
jsMock.extendsField = 1;
|
||||
expect(jsMock.extendsField, 1);
|
||||
expect(jsMock.extendsFinalField, 0);
|
||||
expect(jsMock.extendsGetSet, 0);
|
||||
// Dart mock uses a field for this getter and setter, so it should change.
|
||||
jsMock.extendsGetSet = 1;
|
||||
expect(jsMock.extendsGetSet, 1);
|
||||
|
||||
expect(jsMock.implementsMethod(1), 1);
|
||||
expect(jsMock.implementsField, 1);
|
||||
|
@ -92,7 +104,6 @@ void main() {
|
|||
expect(jsMock.implementsFinalField, 1);
|
||||
expect(jsMock.implementsGetter, 1);
|
||||
jsMock.implementsSetter = 2;
|
||||
// Dart mock uses a field for this getter and setter, so it should change.
|
||||
expect(jsMock.implementsGetter, 2);
|
||||
|
||||
expect(jsMock.method(2), 2);
|
||||
|
@ -103,4 +114,13 @@ void main() {
|
|||
expect(jsMock.getSet, 2);
|
||||
jsMock.getSet = 3;
|
||||
expect(jsMock.getSet, 3);
|
||||
|
||||
expect(jsMock.method2(2), 2);
|
||||
expect(jsMock.field2, 2);
|
||||
jsMock.field2 = 3;
|
||||
expect(jsMock.field2, 3);
|
||||
expect(jsMock.finalField2, 2);
|
||||
expect(jsMock.getSet2, 2);
|
||||
jsMock.getSet2 = 3;
|
||||
expect(jsMock.getSet2, 3);
|
||||
}
|
||||
|
|
|
@ -1,183 +0,0 @@
|
|||
// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
// Test that `createStaticInteropMock` checks that there aren't any missing
|
||||
// overrides.
|
||||
|
||||
import 'package:js/js.dart';
|
||||
import 'package:js/js_util.dart';
|
||||
|
||||
@JS()
|
||||
@staticInterop
|
||||
class StaticInterop {}
|
||||
|
||||
extension on StaticInterop {
|
||||
external int field;
|
||||
external final int finalField;
|
||||
external int get getSet;
|
||||
external set getSet(int val);
|
||||
external void method();
|
||||
|
||||
// We should ignore the non-external members for determining overrides.
|
||||
int get nonExternalGetSet => throw '';
|
||||
set nonExternalGetSet(int val) => throw '';
|
||||
void nonExternalMethod() => throw '';
|
||||
}
|
||||
|
||||
class CorrectDart {
|
||||
int field = throw '';
|
||||
final int finalField = throw '';
|
||||
int get getSet => throw '';
|
||||
set getSet(int val) => throw '';
|
||||
void method() => throw '';
|
||||
}
|
||||
|
||||
class DartStatic {
|
||||
static int field = throw '';
|
||||
final int finalField = throw '';
|
||||
int get getSet => throw '';
|
||||
set getSet(int val) => throw '';
|
||||
void method() => throw '';
|
||||
}
|
||||
|
||||
class DartUsingExtensions {
|
||||
int field = throw '';
|
||||
final int finalField = throw '';
|
||||
int get getSet => throw '';
|
||||
set getSet(int val) => throw '';
|
||||
}
|
||||
|
||||
extension on DartUsingExtensions {
|
||||
void method() => throw '';
|
||||
}
|
||||
|
||||
class DartFactory {
|
||||
DartFactory();
|
||||
factory DartFactory.finalField() => DartFactory();
|
||||
int field = throw '';
|
||||
int get getSet => throw '';
|
||||
set getSet(int val) => throw '';
|
||||
void method() => throw '';
|
||||
}
|
||||
|
||||
class DartFinal {
|
||||
final int field = throw '';
|
||||
final int finalField = throw '';
|
||||
int get getSet => throw '';
|
||||
set getSet(int val) => throw '';
|
||||
void method() => throw '';
|
||||
}
|
||||
|
||||
class DartNoGet {
|
||||
int field = throw '';
|
||||
final int finalField = throw '';
|
||||
set getSet(int val) => throw '';
|
||||
void method() => throw '';
|
||||
}
|
||||
|
||||
class DartNoSet {
|
||||
int field = throw '';
|
||||
final int finalField = throw '';
|
||||
int get getSet => throw '';
|
||||
void method() => throw '';
|
||||
}
|
||||
|
||||
class DartNoMembers {}
|
||||
|
||||
void main() {
|
||||
createStaticInteropMock<StaticInterop, CorrectDart>(CorrectDart());
|
||||
// Static members do not qualify as an override.
|
||||
createStaticInteropMock<StaticInterop, DartStatic>(
|
||||
//^
|
||||
// [web] `@staticInterop` class 'StaticInterop' has external extension member 'field', but Dart class 'DartStatic' does not have an overriding instance member.
|
||||
// [web] `@staticInterop` class 'StaticInterop' has external extension member 'field=', but Dart class 'DartStatic' does not have an overriding instance member.
|
||||
DartStatic());
|
||||
// Extension members do not qualify as an override.
|
||||
createStaticInteropMock<StaticInterop, DartUsingExtensions>(
|
||||
//^
|
||||
// [web] `@staticInterop` class 'StaticInterop' has external extension member 'method', but Dart class 'DartUsingExtensions' does not have an overriding instance member.
|
||||
DartUsingExtensions());
|
||||
// Factory members with the same name do not qualify as an override.
|
||||
createStaticInteropMock<StaticInterop, DartFactory>(
|
||||
//^
|
||||
// [web] `@staticInterop` class 'StaticInterop' has external extension member 'finalField', but Dart class 'DartFactory' does not have an overriding instance member.
|
||||
DartFactory());
|
||||
// Final fields can not override a setter.
|
||||
createStaticInteropMock<StaticInterop, DartFinal>(DartFinal());
|
||||
//^
|
||||
// [web] `@staticInterop` class 'StaticInterop' has external extension member 'field=', but Dart class 'DartFinal' does not have an overriding instance member.
|
||||
createStaticInteropMock<StaticInterop, DartNoGet>(DartNoGet());
|
||||
//^
|
||||
// [web] `@staticInterop` class 'StaticInterop' has external extension member 'getSet', but Dart class 'DartNoGet' does not have an overriding instance member.
|
||||
|
||||
// Test that getters are treated differently from setters even though they
|
||||
// share the same name.
|
||||
createStaticInteropMock<StaticInterop, DartNoSet>(DartNoSet());
|
||||
//^
|
||||
// [web] `@staticInterop` class 'StaticInterop' has external extension member 'getSet=', but Dart class 'DartNoSet' does not have an overriding instance member.
|
||||
|
||||
// Test multiple missing members.
|
||||
createStaticInteropMock<StaticInterop, DartNoMembers>(
|
||||
//^
|
||||
// [web] `@staticInterop` class 'StaticInterop' has external extension member 'field', but Dart class 'DartNoMembers' does not have an overriding instance member.
|
||||
// [web] `@staticInterop` class 'StaticInterop' has external extension member 'field=', but Dart class 'DartNoMembers' does not have an overriding instance member.
|
||||
// [web] `@staticInterop` class 'StaticInterop' has external extension member 'finalField', but Dart class 'DartNoMembers' does not have an overriding instance member.
|
||||
// [web] `@staticInterop` class 'StaticInterop' has external extension member 'getSet', but Dart class 'DartNoMembers' does not have an overriding instance member.
|
||||
// [web] `@staticInterop` class 'StaticInterop' has external extension member 'getSet=', but Dart class 'DartNoMembers' does not have an overriding instance member.
|
||||
// [web] `@staticInterop` class 'StaticInterop' has external extension member 'method', but Dart class 'DartNoMembers' does not have an overriding instance member.
|
||||
DartNoMembers());
|
||||
|
||||
testUsingInheritanceAndMixins();
|
||||
}
|
||||
|
||||
// The following should classes should not contain any override errors, as they
|
||||
// have all the necessary members.
|
||||
class DartWithInheritance extends DartNoSet {
|
||||
set getSet(int val) => throw '';
|
||||
}
|
||||
|
||||
class DartWithMixins with CorrectDart {}
|
||||
|
||||
mixin MixinSet {
|
||||
set getSet(int val) => throw '';
|
||||
}
|
||||
|
||||
class DartWithMixinsAndInheritance extends DartNoSet with MixinSet {}
|
||||
|
||||
@JS()
|
||||
@staticInterop
|
||||
class BaseStaticInterop {}
|
||||
|
||||
extension on BaseStaticInterop {
|
||||
external void baseMethod();
|
||||
}
|
||||
|
||||
@JS()
|
||||
@staticInterop
|
||||
class StaticInteropWithInheritance extends BaseStaticInterop
|
||||
implements StaticInterop {}
|
||||
|
||||
class DartImplementingInteropInheritance extends DartWithMixinsAndInheritance {
|
||||
void baseMethod() => throw '';
|
||||
}
|
||||
|
||||
void testUsingInheritanceAndMixins() {
|
||||
// Test where Dart class implements using inherited members.
|
||||
createStaticInteropMock<StaticInterop, DartWithInheritance>(
|
||||
DartWithInheritance());
|
||||
// Test where Dart class implements using mixed-in members.
|
||||
createStaticInteropMock<StaticInterop, DartWithMixins>(DartWithMixins());
|
||||
// Test where Dart class implements using inherited and mixed-in members.
|
||||
createStaticInteropMock<StaticInterop, DartWithMixinsAndInheritance>(
|
||||
DartWithMixinsAndInheritance());
|
||||
// Missing inherited method, expect an error.
|
||||
createStaticInteropMock<
|
||||
//^
|
||||
// [web] `@staticInterop` class 'StaticInteropWithInheritance' has external extension member 'baseMethod', but Dart class 'DartWithMixinsAndInheritance' does not have an overriding instance member.
|
||||
StaticInteropWithInheritance,
|
||||
DartWithMixinsAndInheritance>(DartWithMixinsAndInheritance());
|
||||
// Added missing method, should pass.
|
||||
createStaticInteropMock<StaticInteropWithInheritance,
|
||||
DartImplementingInteropInheritance>(DartImplementingInteropInheritance());
|
||||
}
|
|
@ -24,6 +24,7 @@ extension on StaticInterop {
|
|||
external set getSet(int? val);
|
||||
}
|
||||
|
||||
@JSExport()
|
||||
class Dart {
|
||||
int? method(int? val) => throw '';
|
||||
int? field = throw '';
|
||||
|
@ -34,6 +35,7 @@ class Dart {
|
|||
|
||||
// Have the mock class implement the class interface you defined to mock the
|
||||
// @staticInterop interface.
|
||||
@JSExport()
|
||||
class DartMock extends Mock implements Dart {}
|
||||
|
||||
void main() {
|
||||
|
|
|
@ -26,7 +26,10 @@ external Object get windowType;
|
|||
@staticInterop
|
||||
class JSWindow {}
|
||||
|
||||
class DartWindow {}
|
||||
@JSExport()
|
||||
class DartWindow {
|
||||
int _unused = 0;
|
||||
}
|
||||
|
||||
void main() {
|
||||
// Test that everything still works the same.
|
||||
|
|
|
@ -2,11 +2,67 @@
|
|||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
// Test that `createStaticInteropMock` checks that overrides are subtypes.
|
||||
// Test that `createStaticInteropMock` checks that overrides exist and are
|
||||
// subtypes.
|
||||
|
||||
import 'package:js/js.dart';
|
||||
import 'package:js/js_util.dart';
|
||||
|
||||
@JS()
|
||||
@staticInterop
|
||||
class StaticInterop {}
|
||||
|
||||
extension on StaticInterop {
|
||||
external int field;
|
||||
external final int finalField;
|
||||
external int get getSet1;
|
||||
external set getSet1(int val);
|
||||
external int get getSet2;
|
||||
external set getSet2(int val);
|
||||
external void method();
|
||||
}
|
||||
|
||||
@JSExport()
|
||||
class CorrectDart {
|
||||
int field = throw '';
|
||||
final int finalField = throw '';
|
||||
int get getSet1 => throw '';
|
||||
set getSet1(int val) => throw '';
|
||||
int get getSet2 => throw '';
|
||||
set getSet2(int val) => throw '';
|
||||
void method() => throw '';
|
||||
}
|
||||
|
||||
@JSExport()
|
||||
class IncorrectDart {
|
||||
IncorrectDart();
|
||||
// Factories do not count.
|
||||
factory IncorrectDart.method() => IncorrectDart();
|
||||
// Setter is not implemented.
|
||||
final int field = throw '';
|
||||
// Static members do not count.
|
||||
static final int finalField = throw '';
|
||||
// Getter is not implemented.
|
||||
set getSet1(int val) => throw '';
|
||||
int get getSet2 => throw '';
|
||||
}
|
||||
|
||||
extension on IncorrectDart {
|
||||
// Extension members do not count.
|
||||
set getSet2(int val) => throw '';
|
||||
}
|
||||
|
||||
void testMissingOverrides() {
|
||||
createStaticInteropMock<StaticInterop, CorrectDart>(CorrectDart());
|
||||
createStaticInteropMock<StaticInterop, IncorrectDart>(IncorrectDart());
|
||||
//^
|
||||
// [web] Dart class 'IncorrectDart' does not have any members that implement any of the following extension member(s) with export name 'finalField': <unnamed>.finalField (FunctionType(int Function())).
|
||||
// [web] Dart class 'IncorrectDart' does not have any members that implement any of the following extension member(s) with export name 'method': <unnamed>.method (FunctionType(void Function())).
|
||||
// [web] Dart class 'IncorrectDart' has a getter, but does not have a setter to implement any of the following extension member(s) with export name 'field': <unnamed>.field= (FunctionType(void Function(int))).
|
||||
// [web] Dart class 'IncorrectDart' has a getter, but does not have a setter to implement any of the following extension member(s) with export name 'getSet2': <unnamed>.getSet2= (FunctionType(void Function(int))).
|
||||
// [web] Dart class 'IncorrectDart' has a setter, but does not have a getter to implement any of the following extension member(s) with export name 'getSet1': <unnamed>.getSet1 (FunctionType(int Function())).
|
||||
}
|
||||
|
||||
// Set up a simple type hierarchy.
|
||||
class A {
|
||||
const A();
|
||||
|
@ -27,38 +83,61 @@ class SimpleInterop {}
|
|||
extension SimpleInteropExtension on SimpleInterop {
|
||||
external B field;
|
||||
external final B finalField;
|
||||
external B get getSetNum;
|
||||
external set getSetInt(B val);
|
||||
external B get getSet;
|
||||
external set getSet(B val);
|
||||
external B method(B b);
|
||||
}
|
||||
|
||||
// Implement using the exact same types.
|
||||
@JSExport()
|
||||
class SimpleDart {
|
||||
B field = throw '';
|
||||
final B finalField = throw '';
|
||||
B get getSetNum => throw '';
|
||||
set getSetInt(B val) => throw '';
|
||||
B get getSet => throw '';
|
||||
set getSet(B val) => throw '';
|
||||
B method(B b) => throw '';
|
||||
}
|
||||
|
||||
void testExactTypes() {
|
||||
createStaticInteropMock<SimpleInterop, SimpleDart>(SimpleDart());
|
||||
}
|
||||
|
||||
// Implement using subtypes.
|
||||
@JSExport()
|
||||
class SubtypeSimpleDart {
|
||||
B field = throw '';
|
||||
final C finalField = throw '';
|
||||
C get getSetNum => throw '';
|
||||
set getSetInt(A val) => throw '';
|
||||
C get getSet => throw '';
|
||||
set getSet(A val) => throw '';
|
||||
C method(A a) => throw '';
|
||||
}
|
||||
|
||||
void testSimpleSubtyping() {
|
||||
createStaticInteropMock<SimpleInterop, SubtypeSimpleDart>(
|
||||
SubtypeSimpleDart());
|
||||
}
|
||||
|
||||
// Implement using supertypes (which shouldn't work).
|
||||
@JSExport()
|
||||
class SupertypeSimpleDart {
|
||||
A field = throw '';
|
||||
final A finalField = throw '';
|
||||
A get getSetNum => throw '';
|
||||
set getSetInt(C val) => throw '';
|
||||
// Getter must be subtype of setter, so only the setter should be an error.
|
||||
C get getSet => throw '';
|
||||
set getSet(C val) => throw '';
|
||||
A method(C c) => throw '';
|
||||
}
|
||||
|
||||
void testIncorrectSimpleSubtyping() {
|
||||
createStaticInteropMock<SimpleInterop, SupertypeSimpleDart>(
|
||||
//^
|
||||
// [web] Dart class 'SupertypeSimpleDart' does not have any members that implement any of the following extension member(s) with export name 'finalField': SimpleInteropExtension.finalField (FunctionType(B Function())).
|
||||
// [web] Dart class 'SupertypeSimpleDart' does not have any members that implement any of the following extension member(s) with export name 'method': SimpleInteropExtension.method (FunctionType(B Function(B))).
|
||||
// [web] Dart class 'SupertypeSimpleDart' has a getter, but does not have a setter to implement any of the following extension member(s) with export name 'getSet': SimpleInteropExtension.getSet= (FunctionType(void Function(B))).
|
||||
// [web] Dart class 'SupertypeSimpleDart' has a setter, but does not have a getter to implement any of the following extension member(s) with export name 'field': SimpleInteropExtension.field (FunctionType(B Function())).
|
||||
SupertypeSimpleDart());
|
||||
}
|
||||
|
||||
@JS()
|
||||
@staticInterop
|
||||
class ComplexAndOptionalInteropMethods {}
|
||||
|
@ -70,12 +149,19 @@ extension ComplexAndOptionalInteropMethodsExtension
|
|||
external B optionalSubtype(B b, [B b2 = const B()]);
|
||||
}
|
||||
|
||||
@JSExport()
|
||||
class ComplexAndOptionalDart {
|
||||
C Function(A _) nestedTypes(List<B> arg1, Map<Set<B>, B> arg2) => throw '';
|
||||
B optional(B b, [B? b2]) => throw '';
|
||||
C optionalSubtype(A a, [A? a2]) => throw '';
|
||||
}
|
||||
|
||||
void testComplexSubtyping() {
|
||||
createStaticInteropMock<ComplexAndOptionalInteropMethods,
|
||||
ComplexAndOptionalDart>(ComplexAndOptionalDart());
|
||||
}
|
||||
|
||||
@JSExport()
|
||||
class IncorrectComplexAndOptionalDart {
|
||||
// List type is wrong.
|
||||
B Function(B _) nestedTypes(List<List<B>> arg1, Map<Set<B>, B> arg2) =>
|
||||
|
@ -86,25 +172,25 @@ class IncorrectComplexAndOptionalDart {
|
|||
B optionalSubtype(B b, [C c = const C()]) => throw '';
|
||||
}
|
||||
|
||||
void main() {
|
||||
createStaticInteropMock<SimpleInterop, SimpleDart>(SimpleDart());
|
||||
createStaticInteropMock<SimpleInterop, SubtypeSimpleDart>(
|
||||
SubtypeSimpleDart());
|
||||
createStaticInteropMock<SimpleInterop, SupertypeSimpleDart>(
|
||||
//^
|
||||
// [web] Dart class member 'SupertypeSimpleDart.field' with type 'A Function()' is not a subtype of `@staticInterop` external extension member 'SimpleInterop.field' with type 'B Function()'.
|
||||
// [web] Dart class member 'SupertypeSimpleDart.finalField' with type 'A Function()' is not a subtype of `@staticInterop` external extension member 'SimpleInterop.finalField' with type 'B Function()'.
|
||||
// [web] Dart class member 'SupertypeSimpleDart.getSetInt=' with type 'void Function(C)' is not a subtype of `@staticInterop` external extension member 'SimpleInterop.getSetInt=' with type 'void Function(B)'.
|
||||
// [web] Dart class member 'SupertypeSimpleDart.getSetNum' with type 'A Function()' is not a subtype of `@staticInterop` external extension member 'SimpleInterop.getSetNum' with type 'B Function()'.
|
||||
// [web] Dart class member 'SupertypeSimpleDart.method' with type 'A Function(C)' is not a subtype of `@staticInterop` external extension member 'SimpleInterop.method' with type 'B Function(B)'.
|
||||
SupertypeSimpleDart());
|
||||
createStaticInteropMock<ComplexAndOptionalInteropMethods,
|
||||
ComplexAndOptionalDart>(ComplexAndOptionalDart());
|
||||
void testIncorrectComplexSubtyping() {
|
||||
createStaticInteropMock<
|
||||
//^
|
||||
// [web] Dart class member 'IncorrectComplexAndOptionalDart.nestedTypes' with type 'B Function(B) Function(List<List<B>>, Map<Set<B>, B>)' is not a subtype of `@staticInterop` external extension member 'ComplexAndOptionalInteropMethods.nestedTypes' with type 'B Function(B) Function(List<B>, Map<Set<B>, B>)'.
|
||||
// [web] Dart class member 'IncorrectComplexAndOptionalDart.optional' with type 'B Function(B, B?)' is not a subtype of `@staticInterop` external extension member 'ComplexAndOptionalInteropMethods.optional' with type 'B Function(B, [B?])'.
|
||||
// [web] Dart class member 'IncorrectComplexAndOptionalDart.optionalSubtype' with type 'B Function(B, [C])' is not a subtype of `@staticInterop` external extension member 'ComplexAndOptionalInteropMethods.optionalSubtype' with type 'B Function(B, [B])'.
|
||||
// [web] Dart class 'IncorrectComplexAndOptionalDart' does not have any members that implement any of the following extension member(s) with export name 'nestedTypes': ComplexAndOptionalInteropMethodsExtension.nestedTypes (FunctionType(B Function(B) Function(List<B>, Map<Set<B>, B>))).
|
||||
// [web] Dart class 'IncorrectComplexAndOptionalDart' does not have any members that implement any of the following extension member(s) with export name 'optional': ComplexAndOptionalInteropMethodsExtension.optional (FunctionType(B Function(B, [B?]))).
|
||||
// [web] Dart class 'IncorrectComplexAndOptionalDart' does not have any members that implement any of the following extension member(s) with export name 'optionalSubtype': ComplexAndOptionalInteropMethodsExtension.optionalSubtype (FunctionType(B Function(B, [B]))).
|
||||
ComplexAndOptionalInteropMethods,
|
||||
IncorrectComplexAndOptionalDart>(IncorrectComplexAndOptionalDart());
|
||||
}
|
||||
|
||||
void testSubtyping() {
|
||||
testExactTypes();
|
||||
testSimpleSubtyping();
|
||||
testIncorrectSimpleSubtyping();
|
||||
testComplexSubtyping();
|
||||
testIncorrectComplexSubtyping();
|
||||
}
|
||||
|
||||
void main() {
|
||||
testMissingOverrides();
|
||||
testSubtyping();
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue