8a883fa54d
Leaves some in parser test: pkg/front_end/parser_testcases/error_recovery/keyword_named_formal_parameter_prime.dart TEST=Refactoring, covered by existing tests. Change-Id: I7a83ef95df3cbd283878b3685b5c747bd89a1b16 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/256125 Reviewed-by: Johnni Winther <johnniwinther@google.com> Commit-Queue: Lasse Nielsen <lrn@google.com>
423 lines
7.2 KiB
Dart
423 lines
7.2 KiB
Dart
// Copyright (c) 2016, 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.
|
|
|
|
// @dart = 2.7
|
|
|
|
library jsinterop.abstract_test;
|
|
|
|
import 'package:expect/expect.dart';
|
|
import 'package:async_helper/async_helper.dart';
|
|
import 'package:compiler/src/common.dart';
|
|
import 'package:compiler/src/commandline_options.dart';
|
|
import '../helpers/memory_compiler.dart';
|
|
|
|
const List<Test> TESTS = const <Test>[
|
|
const Test('Empty js-interop class.', '''
|
|
@JS()
|
|
library test;
|
|
|
|
import 'package:js/js.dart';
|
|
|
|
@JS()
|
|
class A {}
|
|
|
|
main() => new A();
|
|
''', warnings: const []),
|
|
const Test('Js-interop class with external method.', '''
|
|
@JS()
|
|
library test;
|
|
|
|
import 'package:js/js.dart';
|
|
|
|
@JS()
|
|
class A {
|
|
external method();
|
|
}
|
|
|
|
main() => new A();
|
|
'''),
|
|
const Test(
|
|
'Js-interop class with external method with required parameters.', '''
|
|
@JS()
|
|
library test;
|
|
|
|
import 'package:js/js.dart';
|
|
|
|
@JS()
|
|
class A {
|
|
external method(a, b);
|
|
}
|
|
|
|
main() => new A();
|
|
'''),
|
|
const Test(
|
|
'Js-interop class with external method with optional parameters.', '''
|
|
@JS()
|
|
library test;
|
|
|
|
import 'package:js/js.dart';
|
|
|
|
@JS()
|
|
class A {
|
|
external method([a, b]);
|
|
}
|
|
|
|
main() => new A();
|
|
'''),
|
|
const Test(
|
|
'Js-interop class with external method with optional parameters '
|
|
'with default values.',
|
|
'''
|
|
@JS()
|
|
library test;
|
|
|
|
import 'package:js/js.dart';
|
|
|
|
@JS()
|
|
class A {
|
|
external method([a = 1, b = 2]);
|
|
}
|
|
|
|
main() => new A();
|
|
'''),
|
|
const Test('Js-interop class with static method.', '''
|
|
@JS()
|
|
library test;
|
|
|
|
import 'package:js/js.dart';
|
|
|
|
@JS()
|
|
class A {
|
|
static method() {}
|
|
}
|
|
|
|
main() => new A();
|
|
'''),
|
|
const Test('Js-interop class that extends a js-interop class.', '''
|
|
@JS()
|
|
library test;
|
|
|
|
import 'package:js/js.dart';
|
|
|
|
@JS()
|
|
abstract class A {
|
|
method();
|
|
}
|
|
|
|
@JS()
|
|
class B extends A {
|
|
external method();
|
|
}
|
|
|
|
main() => new B();
|
|
'''),
|
|
const Test(
|
|
'Js-interop class that extends a js-interop class, '
|
|
'reversed declaration order.',
|
|
'''
|
|
@JS()
|
|
library test;
|
|
|
|
import 'package:js/js.dart';
|
|
|
|
@JS()
|
|
class B extends A {
|
|
external method();
|
|
}
|
|
|
|
@JS()
|
|
abstract class A {
|
|
method();
|
|
}
|
|
|
|
main() => new B();
|
|
'''),
|
|
const Test.multi(
|
|
'Js-interop class that extends a js-interop class from a different '
|
|
'library.',
|
|
const {
|
|
'main.dart': '''
|
|
@JS()
|
|
library test;
|
|
|
|
import 'package:js/js.dart';
|
|
import 'other.dart';
|
|
|
|
@JS()
|
|
class B extends A {
|
|
external method();
|
|
}
|
|
|
|
main() => new B();
|
|
''',
|
|
'other.dart': '''
|
|
@JS()
|
|
library other;
|
|
|
|
import 'package:js/js.dart';
|
|
|
|
@JS()
|
|
abstract class A {
|
|
method();
|
|
}
|
|
'''
|
|
}),
|
|
const Test('Js-interop class that implements a regular class.', '''
|
|
@JS()
|
|
library test;
|
|
|
|
import 'package:js/js.dart';
|
|
|
|
abstract class A {
|
|
method();
|
|
}
|
|
|
|
@JS()
|
|
class B implements A {
|
|
external method();
|
|
}
|
|
|
|
main() => new B();
|
|
'''),
|
|
const Test('Js-interop class that implements a js-interop class.', '''
|
|
@JS()
|
|
library test;
|
|
|
|
import 'package:js/js.dart';
|
|
|
|
@JS()
|
|
abstract class A {
|
|
method();
|
|
}
|
|
|
|
@JS()
|
|
class B implements A {
|
|
external method();
|
|
}
|
|
|
|
main() => new B();
|
|
'''),
|
|
const Test('Js-interop class with generative constructor.', '''
|
|
@JS()
|
|
library test;
|
|
|
|
import 'package:js/js.dart';
|
|
|
|
@JS()
|
|
class A {
|
|
external A();
|
|
}
|
|
|
|
main() => new A();
|
|
'''),
|
|
const Test('Js-interop class with factory constructor.', '''
|
|
@JS()
|
|
library test;
|
|
|
|
import 'package:js/js.dart';
|
|
|
|
@JS()
|
|
class A {
|
|
factory A() => null;
|
|
}
|
|
|
|
main() => new A();
|
|
'''),
|
|
const Test('Empty anonymous js-interop class.', '''
|
|
@JS()
|
|
library test;
|
|
|
|
import 'package:js/js.dart';
|
|
|
|
@JS()
|
|
@anonymous
|
|
class A {}
|
|
|
|
main() => new A();
|
|
'''),
|
|
const Test('Anonymous js-interop class with generative constructor.', '''
|
|
@JS()
|
|
library test;
|
|
|
|
import 'package:js/js.dart';
|
|
|
|
@JS()
|
|
@anonymous
|
|
class A {
|
|
external A();
|
|
}
|
|
|
|
main() => new A();
|
|
'''),
|
|
const Test('Anonymous js-interop class with factory constructor.', '''
|
|
@JS()
|
|
library test;
|
|
|
|
import 'package:js/js.dart';
|
|
|
|
@JS()
|
|
@anonymous
|
|
class A {
|
|
factory A() => null;
|
|
}
|
|
|
|
main() => new A();
|
|
'''),
|
|
const Test(
|
|
'Anonymous js-interop class with external factory constructor.', '''
|
|
@JS()
|
|
library test;
|
|
|
|
import 'package:js/js.dart';
|
|
|
|
@JS()
|
|
@anonymous
|
|
class A {
|
|
external factory A();
|
|
}
|
|
|
|
main() => new A();
|
|
'''),
|
|
const Test('External factory constructor with named parameters.', '''
|
|
@JS()
|
|
library test;
|
|
|
|
import 'package:js/js.dart';
|
|
|
|
@JS()
|
|
@anonymous
|
|
class A {
|
|
external factory A({a, b});
|
|
}
|
|
|
|
main() => new A(a: 1);
|
|
'''),
|
|
const Test(
|
|
'External factory constructor with named parameters '
|
|
'with default parameters.',
|
|
'''
|
|
@JS()
|
|
library test;
|
|
|
|
import 'package:js/js.dart';
|
|
|
|
@JS()
|
|
@anonymous
|
|
class A {
|
|
external factory A({a: 1, b: 2});
|
|
}
|
|
|
|
main() => new A(a: 1);
|
|
'''),
|
|
const Test('Function-typed return type', '''
|
|
@JS()
|
|
library lib;
|
|
|
|
import 'package:js/js.dart';
|
|
|
|
@JS('func')
|
|
external int Function() func();
|
|
|
|
main() {
|
|
func();
|
|
}
|
|
'''),
|
|
const Test(
|
|
'Non-external field.',
|
|
'''
|
|
@JS()
|
|
library lib;
|
|
|
|
import 'package:js/js.dart';
|
|
|
|
@JS()
|
|
@anonymous
|
|
class B {
|
|
int Function() callback;
|
|
}
|
|
|
|
@JS('makeB')
|
|
external B makeB();
|
|
|
|
main() {
|
|
makeB().callback();
|
|
}
|
|
''',
|
|
// TODO(34174): Disallow js-interop fields.
|
|
/*errors: const [MessageKind.IMPLICIT_JS_INTEROP_FIELD_NOT_SUPPORTED]*/
|
|
),
|
|
];
|
|
|
|
void main(List<String> args) {
|
|
asyncTest(() async {
|
|
for (Test test in TESTS) {
|
|
bool run = true;
|
|
if (args.isNotEmpty) {
|
|
run = false;
|
|
for (String arg in args) {
|
|
if (test.name.contains(arg)) {
|
|
run = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if (run) {
|
|
await runTest(test);
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
class Test {
|
|
final String name;
|
|
final String _source;
|
|
final Map<String, String> _sources;
|
|
final List<MessageKind> errors;
|
|
final List<MessageKind> warnings;
|
|
|
|
const Test(this.name, this._source,
|
|
{this.errors = const <MessageKind>[],
|
|
this.warnings = const <MessageKind>[]})
|
|
: _sources = null;
|
|
|
|
const Test.multi(this.name, this._sources,
|
|
{this.errors = const <MessageKind>[],
|
|
this.warnings = const <MessageKind>[]})
|
|
: _source = null;
|
|
|
|
String get source => _source ?? _sources['main.dart'];
|
|
|
|
Map<String, String> get sources =>
|
|
_source != null ? {'main.dart': _source} : _sources;
|
|
}
|
|
|
|
runTest(Test test) async {
|
|
print('==${test.name}======================================================');
|
|
print(test.source);
|
|
await runTestInternal(test);
|
|
}
|
|
|
|
runTestInternal(Test test) async {
|
|
DiagnosticCollector collector = new DiagnosticCollector();
|
|
List<String> options = <String>[];
|
|
// TODO(redemption): Enable inlining.
|
|
options.add(Flags.disableInlining);
|
|
await runCompiler(
|
|
diagnosticHandler: collector,
|
|
options: options,
|
|
memorySourceFiles: test.sources);
|
|
Expect.equals(
|
|
test.errors.length, collector.errors.length, 'Unexpected error count.');
|
|
Expect.equals(test.warnings.length, collector.warnings.length,
|
|
'Unexpected warning count.');
|
|
for (int index = 0; index < test.errors.length; index++) {
|
|
Expect.equals(test.errors[index],
|
|
collector.errors.elementAt(index).messageKind, 'Unexpected error.');
|
|
}
|
|
for (int index = 0; index < test.warnings.length; index++) {
|
|
Expect.equals(test.warnings[index],
|
|
collector.warnings.elementAt(index).messageKind, 'Unexpected warning.');
|
|
}
|
|
}
|