diff --git a/.gitattributes b/.gitattributes index dd987892fa1..207c1a293c8 100644 --- a/.gitattributes +++ b/.gitattributes @@ -30,6 +30,12 @@ tests/lib_2/mirrors/method_mirror_source_line_ending_lf.dart -text tests/lib_2/mirrors/method_mirror_source_line_ending_test.dart -text tests/lib_2/mirrors/method_mirror_source_other.dart -text tests/lib_2/mirrors/method_mirror_source_test.dart -text +tests/lib/mirrors/method_mirror_source_line_ending_cr.dart -text +tests/lib/mirrors/method_mirror_source_line_ending_crlf.dart -text +tests/lib/mirrors/method_mirror_source_line_ending_lf.dart -text +tests/lib/mirrors/method_mirror_source_line_ending_test.dart -text +tests/lib/mirrors/method_mirror_source_other.dart -text +tests/lib/mirrors/method_mirror_source_test.dart -text # Files to leave alone and not diff. *.png binary diff --git a/tests/lib/mirrors/abstract_class_test.dart b/tests/lib/mirrors/abstract_class_test.dart new file mode 100644 index 00000000000..8cd4fae93f7 --- /dev/null +++ b/tests/lib/mirrors/abstract_class_test.dart @@ -0,0 +1,174 @@ +// Copyright (c) 2014, 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. + +library test.abstract_class_test; + +import 'dart:mirrors'; +import 'package:expect/expect.dart'; + +void main() { + testSimple(); + testFunctionType(); + testFakeFunction(); + testGeneric(); + testAnonMixinApplication(); + testNamedMixinApplication(); +} + +abstract class Foo { + foo(); +} + +class Bar extends Foo { + foo() {} +} + +testSimple() { + Expect.isTrue(reflectClass(Foo).isAbstract); + Expect.isFalse(reflectClass(Bar).isAbstract); + Expect.isTrue(reflect(new Bar()).type.superclass.isAbstract); + Expect.isFalse(reflect(new Bar()).type.isAbstract); +} + +void baz() {} + +testFunctionType() { + Expect.isFalse(reflect(baz).type.isAbstract); +} + +abstract class FunctionFoo implements Function { + call(); +} + +class FunctionBar extends FunctionFoo { + call() {} +} + +testFakeFunction() { + Expect.isTrue(reflectClass(FunctionFoo).isAbstract); + Expect.isFalse(reflectClass(FunctionBar).isAbstract); + Expect.isTrue(reflect(new FunctionBar()).type.superclass.isAbstract); + Expect.isFalse(reflect(new FunctionBar()).type.isAbstract); +} + +abstract class GenericFoo { + T genericFoo(); +} + +class GenericBar extends GenericFoo { + T genericFoo() {} +} + +testGeneric() { + // Unbound. + Expect.isTrue(reflectClass(GenericFoo).isAbstract); + Expect.isFalse(reflectClass(GenericBar).isAbstract); + // Bound. + Expect.isTrue(reflect(new GenericBar()).type.superclass.isAbstract); + Expect.isFalse(reflect(new GenericBar()).type.isAbstract); +} + +class S {} + +abstract class M { + mixinFoo(); +} + +abstract class MA extends S with M {} + +class SubMA extends MA { + mixinFoo() {} +} + +class ConcreteMA extends S with M { + mixinFoo() {} +} + +class M2 { + mixin2Foo() {} +} + +abstract class MA2 extends S with M2 { + mixinBar(); +} + +class SubMA2 extends MA2 { + mixinBar() {} +} + +class ConcreteMA2 extends S with M2 { + mixin2Foo() {} +} + +testAnonMixinApplication() { + // Application is abstract. + { + // Mixin is abstract. + Expect.isFalse(reflectClass(SubMA).isAbstract); + Expect.isTrue(reflectClass(SubMA).superclass.isAbstract); + Expect.isTrue(reflectClass(SubMA).superclass.superclass.isAbstract); + Expect.isTrue(reflectClass(MA).isAbstract); + Expect.isTrue(reflectClass(MA).superclass.isAbstract); + + // Mixin is concrete. + Expect.isFalse(reflectClass(SubMA2).isAbstract); + Expect.isTrue(reflectClass(SubMA2).superclass.isAbstract); + Expect.isTrue(reflectClass(SubMA2).superclass.superclass.isAbstract); + Expect.isTrue(reflectClass(MA2).isAbstract); + Expect.isTrue(reflectClass(MA2).superclass.isAbstract); + } + + // Application is concrete. + { + // Mixin is abstract. + Expect.isFalse(reflectClass(ConcreteMA).isAbstract); + Expect.isTrue(reflectClass(ConcreteMA).superclass.isAbstract); + Expect.isFalse(reflectClass(ConcreteMA).superclass.superclass.isAbstract); + + // Mixin is concrete. + Expect.isFalse(reflectClass(ConcreteMA2).isAbstract); + Expect.isTrue(reflectClass(ConcreteMA2).superclass.isAbstract); + Expect.isFalse(reflectClass(ConcreteMA2).superclass.superclass.isAbstract); + } +} + +abstract class NamedMA = S with M; + +class SubNamedMA extends NamedMA { + mixinFoo() {} +} + +abstract class NamedMA2 = S with M2; + +class SubNamedMA2 extends NamedMA2 { + mixinFoo() {} +} + +class ConcreteNamedMA2 = S with M2; + +testNamedMixinApplication() { + // Application is abstract. + { + // Mixin is abstract. + Expect.isFalse(reflectClass(SubNamedMA).isAbstract); + Expect.isTrue(reflectClass(SubNamedMA).superclass.isAbstract); + Expect.isFalse(reflectClass(SubNamedMA).superclass.superclass.isAbstract); + Expect.isTrue(reflectClass(NamedMA).isAbstract); + Expect.isFalse(reflectClass(NamedMA).superclass.isAbstract); + + // Mixin is concrete. + Expect.isFalse(reflectClass(SubNamedMA2).isAbstract); + Expect.isTrue(reflectClass(SubNamedMA2).superclass.isAbstract); + Expect.isFalse(reflectClass(SubNamedMA2).superclass.superclass.isAbstract); + Expect.isTrue(reflectClass(NamedMA2).isAbstract); + Expect.isFalse(reflectClass(NamedMA2).superclass.isAbstract); + } + + // Application is concrete. + { + // Mixin is concrete. + Expect.isFalse(reflectClass(ConcreteNamedMA2).isAbstract); + Expect.isFalse(reflectClass(ConcreteNamedMA2).superclass.isAbstract); + } +} diff --git a/tests/lib/mirrors/abstract_test.dart b/tests/lib/mirrors/abstract_test.dart new file mode 100644 index 00000000000..aad20b2b0db --- /dev/null +++ b/tests/lib/mirrors/abstract_test.dart @@ -0,0 +1,18 @@ +// Copyright (c) 2013, 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 abstract classes are retained. + +library test.abstract_test; + +import 'dart:mirrors'; + +import 'stringify.dart'; + +abstract class Foo {} + +void main() { + expect( + 'Class(s(Foo) in s(test.abstract_test), top-level)', reflectClass(Foo)); +} diff --git a/tests/lib/mirrors/accessor_cache_overflow_test.dart b/tests/lib/mirrors/accessor_cache_overflow_test.dart new file mode 100644 index 00000000000..5703ea1b124 --- /dev/null +++ b/tests/lib/mirrors/accessor_cache_overflow_test.dart @@ -0,0 +1,308 @@ +// Copyright (c) 2014, 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. + +// This test runs invokes getField and setField enough times to get cached +// closures generated and with enough different field names to trip the path +// that flushes the closure cache. + +library test.hot_get_field; + +import 'dart:mirrors'; +import 'package:expect/expect.dart'; + +const int optimizationThreshold = 20; + +main() { + var digits = [ + '0', + '1', + '2', + '3', + '4', + '5', + '6', + '7', + '8', + '9', + 'A', + 'B', + 'C', + 'D', + 'E', + 'F' + ]; + var symbols = new List(); + for (var high in digits) { + for (var low in digits) { + symbols.add(MirrorSystem.getSymbol("v$high$low")); + } + } + + var im = reflect(new C()); + for (var i = 0; i < optimizationThreshold * 2; i++) { + for (var fieldName in symbols) { + im.getField(fieldName); + im.setField(fieldName, 'foo'); + } + } +} + +class C { + var v00; + var v01; + var v02; + var v03; + var v04; + var v05; + var v06; + var v07; + var v08; + var v09; + var v0A; + var v0B; + var v0C; + var v0D; + var v0E; + var v0F; + var v10; + var v11; + var v12; + var v13; + var v14; + var v15; + var v16; + var v17; + var v18; + var v19; + var v1A; + var v1B; + var v1C; + var v1D; + var v1E; + var v1F; + var v20; + var v21; + var v22; + var v23; + var v24; + var v25; + var v26; + var v27; + var v28; + var v29; + var v2A; + var v2B; + var v2C; + var v2D; + var v2E; + var v2F; + var v30; + var v31; + var v32; + var v33; + var v34; + var v35; + var v36; + var v37; + var v38; + var v39; + var v3A; + var v3B; + var v3C; + var v3D; + var v3E; + var v3F; + var v40; + var v41; + var v42; + var v43; + var v44; + var v45; + var v46; + var v47; + var v48; + var v49; + var v4A; + var v4B; + var v4C; + var v4D; + var v4E; + var v4F; + var v50; + var v51; + var v52; + var v53; + var v54; + var v55; + var v56; + var v57; + var v58; + var v59; + var v5A; + var v5B; + var v5C; + var v5D; + var v5E; + var v5F; + var v60; + var v61; + var v62; + var v63; + var v64; + var v65; + var v66; + var v67; + var v68; + var v69; + var v6A; + var v6B; + var v6C; + var v6D; + var v6E; + var v6F; + var v70; + var v71; + var v72; + var v73; + var v74; + var v75; + var v76; + var v77; + var v78; + var v79; + var v7A; + var v7B; + var v7C; + var v7D; + var v7E; + var v7F; + var v80; + var v81; + var v82; + var v83; + var v84; + var v85; + var v86; + var v87; + var v88; + var v89; + var v8A; + var v8B; + var v8C; + var v8D; + var v8E; + var v8F; + var v90; + var v91; + var v92; + var v93; + var v94; + var v95; + var v96; + var v97; + var v98; + var v99; + var v9A; + var v9B; + var v9C; + var v9D; + var v9E; + var v9F; + var vA0; + var vA1; + var vA2; + var vA3; + var vA4; + var vA5; + var vA6; + var vA7; + var vA8; + var vA9; + var vAA; + var vAB; + var vAC; + var vAD; + var vAE; + var vAF; + var vB0; + var vB1; + var vB2; + var vB3; + var vB4; + var vB5; + var vB6; + var vB7; + var vB8; + var vB9; + var vBA; + var vBB; + var vBC; + var vBD; + var vBE; + var vBF; + var vC0; + var vC1; + var vC2; + var vC3; + var vC4; + var vC5; + var vC6; + var vC7; + var vC8; + var vC9; + var vCA; + var vCB; + var vCC; + var vCD; + var vCE; + var vCF; + var vD0; + var vD1; + var vD2; + var vD3; + var vD4; + var vD5; + var vD6; + var vD7; + var vD8; + var vD9; + var vDA; + var vDB; + var vDC; + var vDD; + var vDE; + var vDF; + var vE0; + var vE1; + var vE2; + var vE3; + var vE4; + var vE5; + var vE6; + var vE7; + var vE8; + var vE9; + var vEA; + var vEB; + var vEC; + var vED; + var vEE; + var vEF; + var vF0; + var vF1; + var vF2; + var vF3; + var vF4; + var vF5; + var vF6; + var vF7; + var vF8; + var vF9; + var vFA; + var vFB; + var vFC; + var vFD; + var vFE; + var vFF; +} diff --git a/tests/lib/mirrors/apply3_test.dart b/tests/lib/mirrors/apply3_test.dart new file mode 100644 index 00000000000..d96fa0d264e --- /dev/null +++ b/tests/lib/mirrors/apply3_test.dart @@ -0,0 +1,69 @@ +// Copyright (c) 2013, 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 [Function.apply] on user-defined classes that implement [noSuchMethod]. + +import "package:expect/expect.dart"; +import 'dart:mirrors'; + +class F { + call([p1]) => "call"; + noSuchMethod(Invocation invocation) => "NSM"; +} + +class G { + call() => '42'; + noSuchMethod(Invocation invocation) => invocation; +} + +class H { + call(required, {a}) => required + a; +} + +main() { + Expect.equals('call', Function.apply(new F(), [])); + Expect.equals('call', Function.apply(new F(), [1])); + Expect.equals('NSM', Function.apply(new F(), [1, 2])); + Expect.equals('NSM', Function.apply(new F(), [1, 2, 3])); + + var symbol = const Symbol('a'); + var requiredParameters = [1]; + var optionalParameters = new Map()..[symbol] = 42; + Invocation i = + Function.apply(new G(), requiredParameters, optionalParameters); + + Expect.equals(const Symbol('call'), i.memberName); + Expect.listEquals(requiredParameters, i.positionalArguments); + Expect.mapEquals(optionalParameters, i.namedArguments); + Expect.isTrue(i.isMethod); + Expect.isFalse(i.isGetter); + Expect.isFalse(i.isSetter); + Expect.isFalse(i.isAccessor); + + // Check that changing the passed list and map for parameters does + // not affect [i]. + requiredParameters[0] = 42; + optionalParameters[symbol] = 12; + Expect.listEquals([1], i.positionalArguments); + Expect.mapEquals(new Map()..[symbol] = 42, i.namedArguments); + + // Check that using [i] for invocation yields the same [Invocation] + // object. + var mirror = reflect(new G()); + Invocation other = mirror.delegate(i); + Expect.equals(i.memberName, other.memberName); + Expect.listEquals(i.positionalArguments, other.positionalArguments); + Expect.mapEquals(i.namedArguments, other.namedArguments); + Expect.equals(i.isMethod, other.isMethod); + Expect.equals(i.isGetter, other.isGetter); + Expect.equals(i.isSetter, other.isSetter); + Expect.equals(i.isAccessor, other.isAccessor); + + // Test that [i] can be used to hit an existing method. + Expect.equals(43, new H().call(1, a: 42)); + Expect.equals(43, Function.apply(new H(), [1], new Map()..[symbol] = 42)); + mirror = reflect(new H()); + Expect.equals(43, mirror.delegate(i)); + Expect.equals(43, mirror.delegate(other)); +} diff --git a/tests/lib/mirrors/array_tracing2_test.dart b/tests/lib/mirrors/array_tracing2_test.dart new file mode 100644 index 00000000000..39411a10b77 --- /dev/null +++ b/tests/lib/mirrors/array_tracing2_test.dart @@ -0,0 +1,19 @@ +// Copyright (c) 2013, 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. + +import 'dart:mirrors'; + +class A { + var field; +} + +main() { + var a = new A(); + var mirror = reflect(a); + var array = [42]; + a.field = array; + var field = mirror.getField(#field); + field.invoke(#clear, []); + if (array.length == 1) throw 'Test failed'; +} diff --git a/tests/lib/mirrors/array_tracing3_test.dart b/tests/lib/mirrors/array_tracing3_test.dart new file mode 100644 index 00000000000..092feacdc82 --- /dev/null +++ b/tests/lib/mirrors/array_tracing3_test.dart @@ -0,0 +1,19 @@ +// Copyright (c) 2013, 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. + +import 'dart:mirrors'; + +class A { + static var field; +} + +main() { + MirrorSystem mirrors = currentMirrorSystem(); + ClassMirror a = reflectClass(A); + var array = [42]; + A.field = array; + var field = a.getField(#field); + field.invoke(#clear, []); + if (array.length == 1) throw 'Test failed'; +} diff --git a/tests/lib/mirrors/array_tracing_test.dart b/tests/lib/mirrors/array_tracing_test.dart new file mode 100644 index 00000000000..092feacdc82 --- /dev/null +++ b/tests/lib/mirrors/array_tracing_test.dart @@ -0,0 +1,19 @@ +// Copyright (c) 2013, 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. + +import 'dart:mirrors'; + +class A { + static var field; +} + +main() { + MirrorSystem mirrors = currentMirrorSystem(); + ClassMirror a = reflectClass(A); + var array = [42]; + A.field = array; + var field = a.getField(#field); + field.invoke(#clear, []); + if (array.length == 1) throw 'Test failed'; +} diff --git a/tests/lib/mirrors/bad_argument_types_test.dart b/tests/lib/mirrors/bad_argument_types_test.dart new file mode 100644 index 00000000000..a6d129f52b5 --- /dev/null +++ b/tests/lib/mirrors/bad_argument_types_test.dart @@ -0,0 +1,157 @@ +// Copyright (c) 2018, 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. + +import 'dart:io'; +import 'dart:mirrors'; + +import 'package:expect/expect.dart'; + +int foobar = 1; + +set foobaz(int x) { + foobar = x; +} + +void foo(Map m) { + print(m); + print(m['bar']); +} + +void bar(T a) { + print(a); +} + +class Foo { + Map bork; + static Map bark; + static set woof(Map x) { + bark = x; + } + + Foo(Map m) { + print(m); + } + + Foo.a(); + + static void baz(Map m, {String bar}) { + print('baz'); + print(m['bar']); + print(bar); + } + + void bar(Map m) { + print('bar'); + print(m.runtimeType); + } +} + +class FooBar { + T bar; + FooBar(this.bar) { + print(bar); + } + + set barz(T x) { + bar = x; + } + + factory FooBar.baz(T bar) { + print(bar); + return FooBar(bar); + } + + void foobar(T a, S b) { + print(a); + print(b); + } +} + +void badClassStaticInvoke() { + Map map = Map(); + map['bar'] = 'Hello world!'; + final cm = reflectClass(Foo); + Expect.throwsTypeError(() => cm.invoke(#baz, [ + map + ], { + #bar: {'boo': 'bah'} + })); +} + +void badStaticInvoke() { + final im = reflect(foo) as ClosureMirror; + Expect.throwsTypeError(() => im.apply(['Hello world!'])); +} + +void badInstanceInvoke() { + final fooCls = Foo.a(); + final im = reflect(fooCls); + Expect.throwsTypeError(() => im.invoke(#bar, ['Hello World!'])); +} + +void badConstructorInvoke() { + final cm = reflectClass(Foo); + Expect.throwsTypeError(() => cm.newInstance(Symbol(''), ['Hello World!'])); +} + +void badSetterInvoke() { + final fooCls = Foo.a(); + final im = reflect(fooCls); + Expect.throwsTypeError(() => im.setField(#bork, 'Hello World!')); +} + +void badStaticSetterInvoke() { + final cm = reflectClass(Foo); + Expect.throwsTypeError(() => cm.setField(#bark, 'Hello World!')); + Expect.throwsTypeError(() => cm.setField(#woof, 'Hello World!')); +} + +void badGenericConstructorInvoke() { + final cm = reflectType(FooBar, [int]) as ClassMirror; + Expect.throwsTypeError(() => cm.newInstance(Symbol(''), ['Hello World!'])); +} + +void badGenericClassStaticInvoke() { + final cm = reflectType(FooBar, [int]) as ClassMirror; + final im = cm.newInstance(Symbol(''), [1]); + Expect.throwsTypeError(() => im.invoke(#foobar, ['Hello', 'World'])); +} + +void badGenericFactoryInvoke() { + final cm = reflectType(FooBar, [int]) as ClassMirror; + Expect.throwsTypeError(() => cm.newInstance(Symbol('baz'), ['Hello World!'])); +} + +void badGenericStaticInvoke() { + final im = reflect(bar) as ClosureMirror; + Expect.throwsTypeError(() => im.apply(['Hello world!'])); +} + +void badGenericSetterInvoke() { + final cm = reflectType(FooBar, [int]) as ClassMirror; + final im = cm.newInstance(Symbol(''), [0]); + Expect.throwsTypeError(() => im.setField(#bar, 'Hello world!')); + Expect.throwsTypeError(() => im.setField(#barz, 'Hello world!')); +} + +void badLibrarySetterInvoke() { + final lm = currentMirrorSystem().findLibrary(Symbol('')); + Expect.throwsTypeError(() => lm.setField(#foobar, 'Foobaz')); + Expect.throwsTypeError(() => lm.setField(#foobaz, 'Foobaz')); +} + +void main() { + badClassStaticInvoke(); + badStaticInvoke(); + badInstanceInvoke(); + badConstructorInvoke(); + badSetterInvoke(); + badStaticSetterInvoke(); + badGenericConstructorInvoke(); + badGenericClassStaticInvoke(); + badGenericFactoryInvoke(); + badGenericStaticInvoke(); + badGenericSetterInvoke(); + badLibrarySetterInvoke(); +} diff --git a/tests/lib/mirrors/basic_types_in_dart_core_test.dart b/tests/lib/mirrors/basic_types_in_dart_core_test.dart new file mode 100644 index 00000000000..50e9203b2b8 --- /dev/null +++ b/tests/lib/mirrors/basic_types_in_dart_core_test.dart @@ -0,0 +1,52 @@ +// Copyright (c) 2013, 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. + +library test.basic_types_in_dart_core; + +import 'dart:mirrors'; +import 'package:expect/expect.dart'; + +main() { + LibraryMirror dartcore = currentMirrorSystem().findLibrary(#dart.core); + ClassMirror cm; + TypeMirror tm; + + cm = dartcore.declarations[#int] as ClassMirror; + Expect.equals(reflectClass(int), cm); + Expect.equals(#int, cm.simpleName); + + cm = dartcore.declarations[#double] as ClassMirror; + Expect.equals(reflectClass(double), cm); + Expect.equals(#double, cm.simpleName); + + cm = dartcore.declarations[#num] as ClassMirror; + Expect.equals(reflectClass(num), cm); + Expect.equals(#num, cm.simpleName); + + cm = dartcore.declarations[#bool] as ClassMirror; + Expect.equals(reflectClass(bool), cm); + Expect.equals(#bool, cm.simpleName); + + cm = dartcore.declarations[#String] as ClassMirror; + Expect.equals(reflectClass(String), cm); + Expect.equals(#String, cm.simpleName); + + cm = dartcore.declarations[#List] as ClassMirror; + Expect.equals(reflectClass(List), cm); + Expect.equals(#List, cm.simpleName); + + cm = dartcore.declarations[#Null] as ClassMirror; + Expect.equals(reflectClass(Null), cm); + Expect.equals(#Null, cm.simpleName); + + cm = dartcore.declarations[#Object] as ClassMirror; + Expect.equals(reflectClass(Object), cm); + Expect.equals(#Object, cm.simpleName); + + tm = dartcore.declarations[#dynamic] as TypeMirror; + Expect.isNull(tm); + + tm = dartcore.declarations[const Symbol('void')] as TypeMirror; + Expect.isNull(tm); +} diff --git a/tests/lib/mirrors/circular_factory_redirection_test.dart b/tests/lib/mirrors/circular_factory_redirection_test.dart new file mode 100644 index 00000000000..560ed6e79d1 --- /dev/null +++ b/tests/lib/mirrors/circular_factory_redirection_test.dart @@ -0,0 +1,39 @@ +// Copyright (c) 2013, 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. + +import "dart:mirrors"; +import "package:expect/expect.dart"; + +class A { + A(); + A.circular() = B.circular; // //# 01: compile-time error + const A.circular2() = B.circular2; // //# 02: compile-time error +} + +class B { + B(); + B.circular() = C.circular; // //# 01: continued + const B.circular2() = C.circular2; // //# 02: continued +} + +class C { + C(); + C.circular() = A.circular; // //# 01: continued + const C.circular2() = A.circular2; // //# 02: continued +} + +main() { + ClassMirror cm = reflectClass(A); + + new A.circular(); // //# 01: continued + new A.circular2(); // //# 02: continued + + Expect.throwsNoSuchMethodError( + () => cm.newInstance(#circular, []), + 'Should disallow circular redirection (non-const)'); + + Expect.throwsNoSuchMethodError( + () => cm.newInstance(#circular2, []), + 'Should disallow circular redirection (const)'); +} diff --git a/tests/lib/mirrors/class_declarations_test.dart b/tests/lib/mirrors/class_declarations_test.dart new file mode 100644 index 00000000000..f0a121cdbbb --- /dev/null +++ b/tests/lib/mirrors/class_declarations_test.dart @@ -0,0 +1,368 @@ +// Copyright (c) 2013, 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. + +library test.declarations_test; + +import 'dart:mirrors'; +import 'package:expect/expect.dart'; + +import 'stringify.dart'; +import 'declarations_model.dart' as declarations_model; + +Set inheritedDeclarations(ClassMirror cm) { + var decls = new Set(); + while (cm != null) { + decls.addAll(cm.declarations.values); + cm = cm.superclass; + } + return decls; +} + +main() { + ClassMirror cm = reflectClass(declarations_model.Class); + + Expect.setEquals([ + 'Variable(s(_instanceVariable) in s(Class), private)', + 'Variable(s(_staticVariable) in s(Class), private, static)', + 'Variable(s(instanceVariable) in s(Class))', + 'Variable(s(staticVariable) in s(Class), static)' + ], cm.declarations.values.where((dm) => dm is VariableMirror).map(stringify), + 'variables'); + + Expect.setEquals( + [ + 'Method(s(_instanceGetter) in s(Class), private, getter)', + 'Method(s(_staticGetter) in s(Class), private, static, getter)', + 'Method(s(instanceGetter) in s(Class), getter)', + 'Method(s(staticGetter) in s(Class), static, getter)' + ], + cm.declarations.values + .where((dm) => dm is MethodMirror && dm.isGetter) + .map(stringify), + 'getters'); + + Expect.setEquals( + [ + 'Method(s(_instanceSetter=) in s(Class), private, setter)', + 'Method(s(_staticSetter=) in s(Class), private, static, setter)', + 'Method(s(instanceSetter=) in s(Class), setter)', + 'Method(s(staticSetter=) in s(Class), static, setter)' + ], + cm.declarations.values + .where((dm) => dm is MethodMirror && dm.isSetter) + .map(stringify), + 'setters'); + + // dart2js stops testing here. + return; //# 01: ok + + Expect.setEquals( + [ + 'Method(s(+) in s(Class))', + 'Method(s(_instanceMethod) in s(Class), private)', + 'Method(s(_staticMethod) in s(Class), private, static)', + 'Method(s(abstractMethod) in s(Class), abstract)', + 'Method(s(instanceMethod) in s(Class))', + 'Method(s(staticMethod) in s(Class), static)' + ], + cm.declarations.values + .where((dm) => dm is MethodMirror && dm.isRegularMethod) + .map(stringify), + 'regular methods'); + + Expect.setEquals( + [ + 'Method(s(Class._generativeConstructor) in s(Class), private, constructor)', + 'Method(s(Class._normalFactory) in s(Class), private, static, constructor)', + 'Method(s(Class._redirectingConstructor)' + ' in s(Class), private, constructor)', + 'Method(s(Class._redirectingFactory)' + ' in s(Class), private, static, constructor)', + 'Method(s(Class.generativeConstructor) in s(Class), constructor)', + 'Method(s(Class.normalFactory) in s(Class), static, constructor)', + 'Method(s(Class.redirectingConstructor) in s(Class), constructor)', + 'Method(s(Class.redirectingFactory) in s(Class), static, constructor)' + ], + cm.declarations.values + .where((dm) => dm is MethodMirror && dm.isConstructor) + .map(stringify), + 'constructors and factories'); + + Expect.setEquals( + [ + 'Method(s(Class._normalFactory) in s(Class), private, static, constructor)', + 'Method(s(Class._redirectingFactory)' + ' in s(Class), private, static, constructor)', + 'Method(s(Class.normalFactory) in s(Class), static, constructor)', + 'Method(s(Class.redirectingFactory) in s(Class), static, constructor)', + 'Method(s(_staticGetter) in s(Class), private, static, getter)', + 'Method(s(_staticMethod) in s(Class), private, static)', + 'Method(s(_staticSetter=) in s(Class), private, static, setter)', + 'Variable(s(_staticVariable) in s(Class), private, static)', + 'Method(s(staticGetter) in s(Class), static, getter)', + 'Method(s(staticMethod) in s(Class), static)', + 'Method(s(staticSetter=) in s(Class), static, setter)', + 'Variable(s(staticVariable) in s(Class), static)' + ], + cm.declarations.values + .where((dm) => (dm as dynamic).isStatic) + .map(stringify), + 'statics'); + + Expect.setEquals( + [ + 'Method(s(+) in s(Class))', + 'TypeVariable(s(C) in s(Class),' + ' upperBound = Class(s(Object) in s(dart.core), top-level))', + 'Method(s(Class._generativeConstructor) in s(Class), private, constructor)', + 'Method(s(Class._redirectingConstructor)' + ' in s(Class), private, constructor)', + 'Method(s(Class.generativeConstructor) in s(Class), constructor)', + 'Method(s(Class.redirectingConstructor) in s(Class), constructor)', + 'Method(s(_instanceGetter) in s(Class), private, getter)', + 'Method(s(_instanceMethod) in s(Class), private)', + 'Method(s(_instanceSetter=) in s(Class), private, setter)', + 'Variable(s(_instanceVariable) in s(Class), private)', + 'Method(s(abstractMethod) in s(Class), abstract)', + 'Method(s(instanceGetter) in s(Class), getter)', + 'Method(s(instanceMethod) in s(Class))', + 'Method(s(instanceSetter=) in s(Class), setter)', + 'Variable(s(instanceVariable) in s(Class))' + ], + cm.declarations.values + .where((dm) => !(dm as dynamic).isStatic) + .map(stringify), + 'non-statics'); + + Expect.setEquals( + [ + 'Method(s(+) in s(Class))', + 'TypeVariable(s(C) in s(Class),' + ' upperBound = Class(s(Object) in s(dart.core), top-level))', + 'Method(s(Class.generativeConstructor) in s(Class), constructor)', + 'Method(s(Class.normalFactory) in s(Class), static, constructor)', + 'Method(s(Class.redirectingConstructor) in s(Class), constructor)', + 'Method(s(Class.redirectingFactory) in s(Class), static, constructor)', + 'Method(s(abstractMethod) in s(Class), abstract)', + 'Method(s(instanceGetter) in s(Class), getter)', + 'Method(s(instanceMethod) in s(Class))', + 'Method(s(instanceSetter=) in s(Class), setter)', + 'Variable(s(instanceVariable) in s(Class))', + 'Method(s(staticGetter) in s(Class), static, getter)', + 'Method(s(staticMethod) in s(Class), static)', + 'Method(s(staticSetter=) in s(Class), static, setter)', + 'Variable(s(staticVariable) in s(Class), static)' + ], + cm.declarations.values + .where((dm) => !(dm as dynamic).isPrivate) + .map(stringify), + 'public'); + + Expect.setEquals([ + 'Method(s(*) in s(Mixin))', + 'Method(s(+) in s(Class))', + 'Method(s(-) in s(Superclass))', + 'Method(s(==) in s(Object))', + 'TypeVariable(s(C) in s(Class),' + ' upperBound = Class(s(Object) in s(dart.core), top-level))', + 'Method(s(Class.generativeConstructor) in s(Class), constructor)', + 'Method(s(Class.normalFactory) in s(Class), static, constructor)', + 'Method(s(Class.redirectingConstructor) in s(Class), constructor)', + 'Method(s(Class.redirectingFactory) in s(Class), static, constructor)', + 'Method(s(Object) in s(Object), constructor)', + 'TypeVariable(s(S) in s(Superclass),' + ' upperBound = Class(s(Object) in s(dart.core), top-level))', + 'Method(s(Superclass.inheritedGenerativeConstructor)' + ' in s(Superclass), constructor)', + 'Method(s(Superclass.inheritedNormalFactory)' + ' in s(Superclass), static, constructor)', + 'Method(s(Superclass.inheritedRedirectingConstructor)' + ' in s(Superclass), constructor)', + 'Method(s(Superclass.inheritedRedirectingFactory)' + ' in s(Superclass), static, constructor)', + 'Method(s(abstractMethod) in s(Class), abstract)', + 'Method(s(hashCode) in s(Object), getter)', + 'Method(s(inheritedInstanceGetter) in s(Superclass), getter)', + 'Method(s(inheritedInstanceMethod) in s(Superclass))', + 'Method(s(inheritedInstanceSetter=) in s(Superclass), setter)', + 'Variable(s(inheritedInstanceVariable) in s(Superclass))', + 'Method(s(inheritedStaticGetter) in s(Superclass), static, getter)', + 'Method(s(inheritedStaticMethod) in s(Superclass), static)', + 'Method(s(inheritedStaticSetter=) in s(Superclass), static, setter)', + 'Variable(s(inheritedStaticVariable) in s(Superclass), static)', + 'Method(s(instanceGetter) in s(Class), getter)', + 'Method(s(instanceMethod) in s(Class))', + 'Method(s(instanceSetter=) in s(Class), setter)', + 'Variable(s(instanceVariable) in s(Class))', + 'Method(s(mixinInstanceGetter) in s(Mixin), getter)', + 'Method(s(mixinInstanceMethod) in s(Mixin))', + 'Method(s(mixinInstanceSetter=) in s(Mixin), setter)', + 'Variable(s(mixinInstanceVariable) in s(Mixin))', + 'Method(s(noSuchMethod) in s(Object))', + 'Method(s(runtimeType) in s(Object), getter)', + 'Method(s(staticGetter) in s(Class), static, getter)', + 'Method(s(staticMethod) in s(Class), static)', + 'Method(s(staticSetter=) in s(Class), static, setter)', + 'Variable(s(staticVariable) in s(Class), static)', + 'Method(s(test.declarations_model.Superclass' + ' with test.declarations_model.Mixin.inheritedGenerativeConstructor)' + ' in s(test.declarations_model.Superclass' + ' with test.declarations_model.Mixin), constructor)', + 'Method(s(test.declarations_model.Superclass' + ' with test.declarations_model.Mixin.inheritedRedirectingConstructor)' + ' in s(test.declarations_model.Superclass' + ' with test.declarations_model.Mixin), constructor)', + 'Method(s(toString) in s(Object))', + 'Variable(s(mixinStaticVariable) in s(Mixin), static)', + 'Method(s(mixinStaticGetter) in s(Mixin), static, getter)', + 'Method(s(mixinStaticSetter=) in s(Mixin), static, setter)', + 'Method(s(mixinStaticMethod) in s(Mixin), static)' + ], inheritedDeclarations(cm).where((dm) => !dm.isPrivate).map(stringify), + 'transitive public'); + // The public members of Object should be the same in all implementations, so + // we don't exclude Object here. + + Expect.setEquals([ + 'Method(s(+) in s(Class))', + 'TypeVariable(s(C) in s(Class),' + ' upperBound = Class(s(Object) in s(dart.core), top-level))', + 'Method(s(Class._generativeConstructor) in s(Class), private, constructor)', + 'Method(s(Class._normalFactory) in s(Class), private, static, constructor)', + 'Method(s(Class._redirectingConstructor)' + ' in s(Class), private, constructor)', + 'Method(s(Class._redirectingFactory)' + ' in s(Class), private, static, constructor)', + 'Method(s(Class.generativeConstructor) in s(Class), constructor)', + 'Method(s(Class.normalFactory) in s(Class), static, constructor)', + 'Method(s(Class.redirectingConstructor) in s(Class), constructor)', + 'Method(s(Class.redirectingFactory) in s(Class), static, constructor)', + 'Method(s(_instanceGetter) in s(Class), private, getter)', + 'Method(s(_instanceMethod) in s(Class), private)', + 'Method(s(_instanceSetter=) in s(Class), private, setter)', + 'Variable(s(_instanceVariable) in s(Class), private)', + 'Method(s(_staticGetter) in s(Class), private, static, getter)', + 'Method(s(_staticMethod) in s(Class), private, static)', + 'Method(s(_staticSetter=) in s(Class), private, static, setter)', + 'Variable(s(_staticVariable) in s(Class), private, static)', + 'Method(s(abstractMethod) in s(Class), abstract)', + 'Method(s(instanceGetter) in s(Class), getter)', + 'Method(s(instanceMethod) in s(Class))', + 'Method(s(instanceSetter=) in s(Class), setter)', + 'Variable(s(instanceVariable) in s(Class))', + 'Method(s(staticGetter) in s(Class), static, getter)', + 'Method(s(staticMethod) in s(Class), static)', + 'Method(s(staticSetter=) in s(Class), static, setter)', + 'Variable(s(staticVariable) in s(Class), static)' + ], cm.declarations.values.map(stringify), 'declarations'); + + Expect.setEquals( + [ + 'Method(s(*) in s(Mixin))', + 'Method(s(+) in s(Class))', + 'Method(s(-) in s(Superclass))', + 'TypeVariable(s(C) in s(Class),' + ' upperBound = Class(s(Object) in s(dart.core), top-level))', + 'Method(s(Class._generativeConstructor) in s(Class), private, constructor)', + 'Method(s(Class._normalFactory) in s(Class), private, static, constructor)', + 'Method(s(Class._redirectingConstructor)' + ' in s(Class), private, constructor)', + 'Method(s(Class._redirectingFactory)' + ' in s(Class), private, static, constructor)', + 'Method(s(Class.generativeConstructor) in s(Class), constructor)', + 'Method(s(Class.normalFactory) in s(Class), static, constructor)', + 'Method(s(Class.redirectingConstructor) in s(Class), constructor)', + 'Method(s(Class.redirectingFactory) in s(Class), static, constructor)', + 'TypeVariable(s(S) in s(Superclass),' + ' upperBound = Class(s(Object) in s(dart.core), top-level))', + 'Method(s(Superclass._inheritedGenerativeConstructor)' + ' in s(Superclass), private, constructor)', + 'Method(s(Superclass._inheritedNormalFactory)' + ' in s(Superclass), private, static, constructor)', + 'Method(s(Superclass._inheritedRedirectingConstructor)' + ' in s(Superclass), private, constructor)', + 'Method(s(Superclass._inheritedRedirectingFactory)' + ' in s(Superclass), private, static, constructor)', + 'Method(s(Superclass.inheritedGenerativeConstructor)' + ' in s(Superclass), constructor)', + 'Method(s(Superclass.inheritedNormalFactory)' + ' in s(Superclass), static, constructor)', + 'Method(s(Superclass.inheritedRedirectingConstructor)' + ' in s(Superclass), constructor)', + 'Method(s(Superclass.inheritedRedirectingFactory)' + ' in s(Superclass), static, constructor)', + 'Method(s(_inheritedInstanceGetter) in s(Superclass), private, getter)', + 'Method(s(_inheritedInstanceMethod) in s(Superclass), private)', + 'Method(s(_inheritedInstanceSetter=) in s(Superclass), private, setter)', + 'Variable(s(_inheritedInstanceVariable) in s(Superclass), private)', + 'Method(s(_inheritedStaticGetter)' + ' in s(Superclass), private, static, getter)', + 'Method(s(_inheritedStaticMethod) in s(Superclass), private, static)', + 'Method(s(_inheritedStaticSetter=)' + ' in s(Superclass), private, static, setter)', + 'Variable(s(_inheritedStaticVariable) in s(Superclass), private, static)', + 'Method(s(_instanceGetter) in s(Class), private, getter)', + 'Method(s(_instanceMethod) in s(Class), private)', + 'Method(s(_instanceSetter=) in s(Class), private, setter)', + 'Variable(s(_instanceVariable) in s(Class), private)', + 'Method(s(_mixinInstanceGetter) in s(Mixin), private, getter)', + 'Method(s(_mixinInstanceMethod) in s(Mixin), private)', + 'Method(s(_mixinInstanceSetter=) in s(Mixin), private, setter)', + 'Variable(s(_mixinInstanceVariable) in s(Mixin), private)', + 'Method(s(_staticGetter) in s(Class), private, static, getter)', + 'Method(s(_staticMethod) in s(Class), private, static)', + 'Method(s(_staticSetter=) in s(Class), private, static, setter)', + 'Variable(s(_staticVariable) in s(Class), private, static)', + 'Method(s(abstractMethod) in s(Class), abstract)', + 'Method(s(inheritedInstanceGetter) in s(Superclass), getter)', + 'Method(s(inheritedInstanceMethod) in s(Superclass))', + 'Method(s(inheritedInstanceSetter=) in s(Superclass), setter)', + 'Variable(s(inheritedInstanceVariable) in s(Superclass))', + 'Method(s(inheritedStaticGetter) in s(Superclass), static, getter)', + 'Method(s(inheritedStaticMethod) in s(Superclass), static)', + 'Method(s(inheritedStaticSetter=) in s(Superclass), static, setter)', + 'Variable(s(inheritedStaticVariable) in s(Superclass), static)', + 'Method(s(instanceGetter) in s(Class), getter)', + 'Method(s(instanceMethod) in s(Class))', + 'Method(s(instanceSetter=) in s(Class), setter)', + 'Variable(s(instanceVariable) in s(Class))', + 'Method(s(mixinInstanceGetter) in s(Mixin), getter)', + 'Method(s(mixinInstanceMethod) in s(Mixin))', + 'Method(s(mixinInstanceSetter=) in s(Mixin), setter)', + 'Variable(s(mixinInstanceVariable) in s(Mixin))', + 'Method(s(staticGetter) in s(Class), static, getter)', + 'Method(s(staticMethod) in s(Class), static)', + 'Method(s(staticSetter=) in s(Class), static, setter)', + 'Variable(s(staticVariable) in s(Class), static)', + 'Method(s(test.declarations_model.Superclass' + ' with test.declarations_model.Mixin._inheritedGenerativeConstructor)' + ' in s(test.declarations_model.Superclass' + ' with test.declarations_model.Mixin), private, constructor)', + 'Method(s(test.declarations_model.Superclass' + ' with test.declarations_model.Mixin._inheritedRedirectingConstructor)' + ' in s(test.declarations_model.Superclass' + ' with test.declarations_model.Mixin), private, constructor)', + 'Method(s(test.declarations_model.Superclass' + ' with test.declarations_model.Mixin.inheritedGenerativeConstructor)' + ' in s(test.declarations_model.Superclass' + ' with test.declarations_model.Mixin), constructor)', + 'Method(s(test.declarations_model.Superclass' + ' with test.declarations_model.Mixin.inheritedRedirectingConstructor)' + ' in s(test.declarations_model.Superclass' + ' with test.declarations_model.Mixin), constructor)', + 'Variable(s(mixinStaticVariable) in s(Mixin), static)', + 'Variable(s(_mixinStaticVariable) in s(Mixin), private, static)', + 'Method(s(mixinStaticGetter) in s(Mixin), static, getter)', + 'Method(s(mixinStaticSetter=) in s(Mixin), static, setter)', + 'Method(s(mixinStaticMethod) in s(Mixin), static)', + 'Method(s(_mixinStaticGetter) in s(Mixin), private, static, getter)', + 'Method(s(_mixinStaticSetter=) in s(Mixin), private, static, setter)', + 'Method(s(_mixinStaticMethod) in s(Mixin), private, static)' + ], + inheritedDeclarations(cm) + .difference(reflectClass(Object).declarations.values.toSet()) + .map(stringify), + 'transitive less Object'); + // The private members of Object may vary across implementations, so we + // exclude the declarations of Object in this test case. +} diff --git a/tests/lib/mirrors/class_mirror_location_other.dart b/tests/lib/mirrors/class_mirror_location_other.dart new file mode 100644 index 00000000000..eb94d21d6ce --- /dev/null +++ b/tests/lib/mirrors/class_mirror_location_other.dart @@ -0,0 +1,11 @@ +// Copyright (c) 2015, 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. + +part of test.class_location; + +class ClassInOtherFile {} + + class SpaceIndentedInOtherFile {} + + class TabIndentedInOtherFile {} diff --git a/tests/lib/mirrors/class_mirror_location_test.dart b/tests/lib/mirrors/class_mirror_location_test.dart new file mode 100644 index 00000000000..3132b0da138 --- /dev/null +++ b/tests/lib/mirrors/class_mirror_location_test.dart @@ -0,0 +1,69 @@ +// Copyright (c) 2015, 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. +library test.class_location; + +import "dart:mirrors"; +import "package:expect/expect.dart"; + +part 'class_mirror_location_other.dart'; + +class ClassInMainFile {} + class SpaceIndentedInMainFile {} + class TabIndentedInMainFile {} + +abstract class AbstractClass {} +typedef bool Predicate(num n); + +class M {} +class S {} +class MA extends S with M {} +class MA2 = S with M; + +const metadata = 'metadata'; + +@metadata +class WithMetadata {} + +enum Enum { RED, GREEN, BLUE } + +@metadata +enum AnnotatedEnum { SALT, PEPPER } + +// We only check for a suffix of the uri because the test might be run from +// any number of absolute paths. +expectLocation( + DeclarationMirror mirror, String uriSuffix, int line, int column) { + final location = mirror.location; + final uri = location.sourceUri; + Expect.isTrue( + uri.toString().endsWith(uriSuffix), "Expected suffix $uriSuffix in $uri"); + Expect.equals(line, location.line, "line"); + Expect.equals(column, location.column, "column"); +} + +main() { + String mainSuffix = 'class_mirror_location_test.dart'; + String otherSuffix = 'class_mirror_location_other.dart'; + + // This file. + expectLocation(reflectClass(ClassInMainFile), mainSuffix, 12, 1); + expectLocation(reflectClass(SpaceIndentedInMainFile), mainSuffix, 13, 3); + expectLocation(reflectClass(TabIndentedInMainFile), mainSuffix, 14, 2); + expectLocation(reflectClass(AbstractClass), mainSuffix, 16, 1); + expectLocation(reflectType(Predicate), mainSuffix, 17, 1); + expectLocation(reflectClass(MA), mainSuffix, 21, 1); + expectLocation(reflectClass(MA2), mainSuffix, 22, 1); + expectLocation(reflectClass(WithMetadata), mainSuffix, 26, 1); + expectLocation(reflectClass(Enum), mainSuffix, 29, 1); + expectLocation(reflectClass(AnnotatedEnum), mainSuffix, 31, 1); + + // Another part. + expectLocation(reflectClass(ClassInOtherFile), otherSuffix, 7, 1); + expectLocation(reflectClass(SpaceIndentedInOtherFile), otherSuffix, 9, 3); + expectLocation(reflectClass(TabIndentedInOtherFile), otherSuffix, 11, 2); + + // Synthetic classes. + Expect.isNull(reflectClass(MA).superclass.location); + Expect.isNull((reflect(main) as ClosureMirror).type.location); +} diff --git a/tests/lib/mirrors/class_mirror_type_variables_data.dart b/tests/lib/mirrors/class_mirror_type_variables_data.dart new file mode 100644 index 00000000000..00902415901 --- /dev/null +++ b/tests/lib/mirrors/class_mirror_type_variables_data.dart @@ -0,0 +1,25 @@ +// Copyright (c) 2013, 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. + +library class_mirror_type_variables_data; + +class NoTypeParams {} + +class A {} + +class B> {} + +class C> {} + +class D { + R foo(R r) => r; + S bar(S s) => s; + T baz(T t) => t; +} + +class Helper {} + +class E>> {} + +class F>> {} diff --git a/tests/lib/mirrors/class_mirror_type_variables_expect.dart b/tests/lib/mirrors/class_mirror_type_variables_expect.dart new file mode 100644 index 00000000000..adee190a9cb --- /dev/null +++ b/tests/lib/mirrors/class_mirror_type_variables_expect.dart @@ -0,0 +1,130 @@ +// Copyright (c) 2013, 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 expectations for 'class_mirror_type_variables_data.dart'. + +library class_mirror_type_variables_expect; + +import "dart:mirrors"; + +import "package:expect/expect.dart"; + +/// The interface of [Env] is shared between the runtime and the source mirrors +/// test. +abstract class Env { + ClassMirror getA(); + ClassMirror getB(); + ClassMirror getC(); + ClassMirror getD(); + ClassMirror getE(); + ClassMirror getF(); + ClassMirror getNoTypeParams(); + ClassMirror getObject(); + ClassMirror getString(); + ClassMirror getHelperOfString(); +} + +void test(Env env) { + testNoTypeParams(env); + testA(env); + testBAndC(env); + testD(env); + testE(env); + testF(env); +} + +testNoTypeParams(Env env) { + ClassMirror cm = env.getNoTypeParams(); + Expect.equals(cm.typeVariables.length, 0); +} + +void testA(Env env) { + ClassMirror a = env.getA(); + Expect.equals(2, a.typeVariables.length); + + TypeVariableMirror aT = a.typeVariables[0]; + TypeVariableMirror aS = a.typeVariables[1]; + ClassMirror aTBound = aT.upperBound as ClassMirror; + ClassMirror aSBound = aS.upperBound as ClassMirror; + + Expect.isTrue(aTBound.isOriginalDeclaration); + Expect.isTrue(aSBound.isOriginalDeclaration); + + Expect.equals(env.getObject(), aTBound); + Expect.equals(env.getString(), aSBound); +} + +void testBAndC(Env env) { + ClassMirror b = env.getB(); + ClassMirror c = env.getC(); + + Expect.equals(1, b.typeVariables.length); + Expect.equals(1, c.typeVariables.length); + + TypeVariableMirror bZ = b.typeVariables[0]; + TypeVariableMirror cZ = c.typeVariables[0]; + ClassMirror bZBound = bZ.upperBound as ClassMirror; + ClassMirror cZBound = cZ.upperBound as ClassMirror; + + Expect.isFalse(bZBound.isOriginalDeclaration); + Expect.isFalse(cZBound.isOriginalDeclaration); + + Expect.notEquals(bZBound, cZBound); + Expect.equals(b, bZBound.originalDeclaration); + Expect.equals(b, cZBound.originalDeclaration); + + TypeMirror bZBoundTypeArgument = bZBound.typeArguments.single; + TypeMirror cZBoundTypeArgument = cZBound.typeArguments.single; + TypeVariableMirror bZBoundTypeVariable = bZBound.typeVariables.single; + TypeVariableMirror cZBoundTypeVariable = cZBound.typeVariables.single; + + Expect.equals(b, bZ.owner); + Expect.equals(c, cZ.owner); + Expect.equals(b, bZBoundTypeVariable.owner); + Expect.equals(b, cZBoundTypeVariable.owner); + Expect.equals(b, bZBoundTypeArgument.owner); + Expect.equals(c, cZBoundTypeArgument.owner); + + Expect.notEquals(bZ, cZ); + Expect.equals(bZ, bZBoundTypeArgument); + Expect.equals(cZ, cZBoundTypeArgument); + Expect.equals(bZ, bZBoundTypeVariable); + Expect.equals(bZ, cZBoundTypeVariable); +} + +testD(Env env) { + ClassMirror cm = env.getD(); + Expect.equals(3, cm.typeVariables.length); + var values = cm.typeVariables; + values.forEach((e) { + Expect.equals(true, e is TypeVariableMirror); + }); + Expect.equals(#R, values.elementAt(0).simpleName); + Expect.equals(#S, values.elementAt(1).simpleName); + Expect.equals(#T, values.elementAt(2).simpleName); +} + +void testE(Env env) { + ClassMirror e = env.getE(); + TypeVariableMirror eR = e.typeVariables.single; + ClassMirror mapRAndHelperOfString = eR.upperBound as ClassMirror; + + Expect.isFalse(mapRAndHelperOfString.isOriginalDeclaration); + Expect.equals(eR, mapRAndHelperOfString.typeArguments.first); + Expect.equals( + env.getHelperOfString(), mapRAndHelperOfString.typeArguments.last); +} + +void testF(Env env) { + ClassMirror f = env.getF(); + TypeVariableMirror fZ = f.typeVariables[0]; + ClassMirror fZBound = fZ.upperBound as ClassMirror; + ClassMirror fZBoundTypeArgument = fZBound.typeArguments.single as ClassMirror; + + Expect.equals(1, f.typeVariables.length); + Expect.isFalse(fZBound.isOriginalDeclaration); + Expect.isFalse(fZBoundTypeArgument.isOriginalDeclaration); + Expect.equals(f, fZBoundTypeArgument.originalDeclaration); + Expect.equals(fZ, fZBoundTypeArgument.typeArguments.single); +} diff --git a/tests/lib/mirrors/class_mirror_type_variables_test.dart b/tests/lib/mirrors/class_mirror_type_variables_test.dart new file mode 100644 index 00000000000..8918de7bbbd --- /dev/null +++ b/tests/lib/mirrors/class_mirror_type_variables_test.dart @@ -0,0 +1,27 @@ +// Copyright (c) 2013, 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. + +import "dart:mirrors"; + +import "package:expect/expect.dart"; + +import "class_mirror_type_variables_data.dart"; +import "class_mirror_type_variables_expect.dart"; + +class RuntimeEnv implements Env { + ClassMirror getA() => reflectClass(A); + ClassMirror getB() => reflectClass(B); + ClassMirror getC() => reflectClass(C); + ClassMirror getD() => reflectClass(D); + ClassMirror getE() => reflectClass(E); + ClassMirror getF() => reflectClass(F); + ClassMirror getNoTypeParams() => reflectClass(NoTypeParams); + ClassMirror getObject() => reflectClass(Object); + ClassMirror getString() => reflectClass(String); + ClassMirror getHelperOfString() => reflect(new Helper()).type; +} + +main() { + test(new RuntimeEnv()); +} diff --git a/tests/lib/mirrors/closure_mirror_import1.dart b/tests/lib/mirrors/closure_mirror_import1.dart new file mode 100644 index 00000000000..c0e41daab02 --- /dev/null +++ b/tests/lib/mirrors/closure_mirror_import1.dart @@ -0,0 +1,17 @@ +// Copyright (c) 2013, 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. + +library closure_mirror_import1; + +export "closure_mirror_import2.dart" show firstGlobalVariableInImport2; + +var globalVariableInImport1 = "globalVariableInImport1"; + +globalFunctionInImport1() => "globalFunctionInImport1"; + +class StaticClass { + static var staticField = "staticField"; + + static staticFunctionInStaticClass() => "staticFunctionInStaticClass"; +} diff --git a/tests/lib/mirrors/closure_mirror_import2.dart b/tests/lib/mirrors/closure_mirror_import2.dart new file mode 100644 index 00000000000..9d09d365ee2 --- /dev/null +++ b/tests/lib/mirrors/closure_mirror_import2.dart @@ -0,0 +1,8 @@ +// Copyright (c) 2013, 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. + +library closure_mirror_import2; + +var firstGlobalVariableInImport2 = "firstGlobalVariableInImport2"; +var secondGlobalVariableInImport2 = "secondGlobalVariableInImport2"; diff --git a/tests/lib/mirrors/closures_test.dart b/tests/lib/mirrors/closures_test.dart new file mode 100644 index 00000000000..a1e2e93de6c --- /dev/null +++ b/tests/lib/mirrors/closures_test.dart @@ -0,0 +1,28 @@ +// Copyright (c) 2013, 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. + +import 'dart:mirrors'; +import 'package:expect/expect.dart'; +import 'stringify.dart'; + +testIntercepted() { + var instance = []; + var closureMirror = reflect(instance.toString) as ClosureMirror; + var methodMirror = closureMirror.function; + Expect.equals(#toString, methodMirror.simpleName); + Expect.equals('[]', closureMirror.apply([]).reflectee); +} + +testNonIntercepted() { + var closure = new Map().containsKey; + var closureMirror = reflect(closure) as ClosureMirror; + var methodMirror = closureMirror.function; + Expect.equals(#containsKey, methodMirror.simpleName); + Expect.isFalse(closureMirror.apply([7]).reflectee); +} + +main() { + testIntercepted(); + testNonIntercepted(); +} diff --git a/tests/lib/mirrors/closurization_equivalence_test.dart b/tests/lib/mirrors/closurization_equivalence_test.dart new file mode 100644 index 00000000000..e1cdbed550b --- /dev/null +++ b/tests/lib/mirrors/closurization_equivalence_test.dart @@ -0,0 +1,25 @@ +// Copyright (c) 2015, 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. + +import 'dart:mirrors'; +import 'package:expect/expect.dart'; + +topLevelMethod() {} + +class C { + static staticMethod() {} + instanceMethod() {} +} + +main() { + LibraryMirror thisLibrary = reflectClass(C).owner as LibraryMirror; + Expect.equals(thisLibrary.declarations[#topLevelMethod], + (reflect(topLevelMethod) as ClosureMirror).function, "topLevel"); + + Expect.equals(reflectClass(C).declarations[#staticMethod], + (reflect(C.staticMethod) as ClosureMirror).function, "static"); + + Expect.equals(reflectClass(C).declarations[#instanceMethod], + (reflect(new C().instanceMethod) as ClosureMirror).function, "instance"); +} diff --git a/tests/lib/mirrors/const_evaluation_test.dart b/tests/lib/mirrors/const_evaluation_test.dart new file mode 100644 index 00000000000..be271334d12 --- /dev/null +++ b/tests/lib/mirrors/const_evaluation_test.dart @@ -0,0 +1,21 @@ +// Copyright (c) 2014, 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. + +// Check that compile-time evaluation of constants is consistent with runtime +// evaluation. + +import 'dart:mirrors'; +import 'package:expect/expect.dart'; + +const top_const = identical(-0.0, 0); + +@top_const +class C {} + +void main() { + var local_var = identical(-0.0, 0); + var metadata = reflectClass(C).metadata[0].reflectee; + Expect.equals(top_const, metadata); + Expect.equals(local_var, metadata); +} diff --git a/tests/lib/mirrors/constructor_kinds_test.dart b/tests/lib/mirrors/constructor_kinds_test.dart new file mode 100644 index 00000000000..185e7d0b87c --- /dev/null +++ b/tests/lib/mirrors/constructor_kinds_test.dart @@ -0,0 +1,112 @@ +// Copyright (c) 2013, 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. + +library test.constructor_kinds_test; + +import 'dart:mirrors'; +import 'package:expect/expect.dart'; + +class ClassWithDefaultConstructor {} + +class Class { + Class.generativeConstructor(); + Class.redirectingGenerativeConstructor() : this.generativeConstructor(); + factory Class.factoryConstructor() => new Class.generativeConstructor(); + factory Class.redirectingFactoryConstructor() = Class.factoryConstructor; + + const Class.constGenerativeConstructor(); + const Class.constRedirectingGenerativeConstructor() + : this.constGenerativeConstructor(); + // Not legal. + // const factory Class.constFactoryConstructor() => ... + const factory Class.constRedirectingFactoryConstructor() = + Class.constGenerativeConstructor; +} + +main() { + ClassMirror cm; + MethodMirror mm; + + // Multitest with and without constructor calls. On the VM, we want to check + // that constructor properties are correctly set even if the constructor + // hasn't been fully compiled. On dart2js, we want to check that constructors + // are retain even if there are no base-level calls. + new ClassWithDefaultConstructor(); // //# 01: ok + new Class.generativeConstructor(); // //# 01: ok + new Class.redirectingGenerativeConstructor(); // //# 01: ok + new Class.factoryConstructor(); // //# 01: ok + new Class.redirectingFactoryConstructor(); // //# 01: ok + const Class.constGenerativeConstructor(); // //# 01: ok + const Class.constRedirectingGenerativeConstructor(); // //# 01: ok + const Class.constRedirectingFactoryConstructor(); // //# 01: ok + + cm = reflectClass(ClassWithDefaultConstructor); + mm = cm.declarations.values + .where((d) => d is MethodMirror && d.isConstructor) + .single as MethodMirror; + Expect.isTrue(mm.isConstructor); + Expect.isTrue(mm.isGenerativeConstructor); + Expect.isFalse(mm.isFactoryConstructor); + Expect.isFalse(mm.isRedirectingConstructor); + Expect.isFalse(mm.isConstConstructor); + + cm = reflectClass(Class); + + mm = cm.declarations[#Class.generativeConstructor] as MethodMirror; + Expect.isTrue(mm.isConstructor); + Expect.isTrue(mm.isGenerativeConstructor); + Expect.isFalse(mm.isFactoryConstructor); + Expect.isFalse(mm.isRedirectingConstructor); + Expect.isFalse(mm.isConstConstructor); + + mm = cm.declarations[#Class.redirectingGenerativeConstructor] as MethodMirror; + Expect.isTrue(mm.isConstructor); + Expect.isTrue(mm.isGenerativeConstructor); + Expect.isFalse(mm.isFactoryConstructor); + Expect.isTrue(mm.isRedirectingConstructor); + Expect.isFalse(mm.isConstConstructor); + + mm = cm.declarations[#Class.factoryConstructor] as MethodMirror; + Expect.isTrue(mm.isConstructor); + Expect.isFalse(mm.isGenerativeConstructor); + Expect.isTrue(mm.isFactoryConstructor); + Expect.isFalse(mm.isRedirectingConstructor); + Expect.isFalse(mm.isConstConstructor); + + mm = cm.declarations[#Class.redirectingFactoryConstructor] as MethodMirror; + Expect.isTrue(mm.isConstructor); + Expect.isFalse(mm.isGenerativeConstructor); + Expect.isTrue(mm.isFactoryConstructor); + Expect.isTrue(mm.isRedirectingConstructor); + Expect.isFalse(mm.isConstConstructor); + + mm = cm.declarations[#Class.constGenerativeConstructor] as MethodMirror; + Expect.isTrue(mm.isConstructor); + Expect.isTrue(mm.isGenerativeConstructor); + Expect.isFalse(mm.isFactoryConstructor); + Expect.isFalse(mm.isRedirectingConstructor); + Expect.isTrue(mm.isConstConstructor); + + mm = cm.declarations[#Class.constRedirectingGenerativeConstructor] as MethodMirror; + Expect.isTrue(mm.isConstructor); + Expect.isTrue(mm.isGenerativeConstructor); + Expect.isFalse(mm.isFactoryConstructor); + Expect.isTrue(mm.isRedirectingConstructor); + Expect.isTrue(mm.isConstConstructor); + + // Not legal. + // mm = cm.declarations[#Class.constFactoryConstructor] as MethodMirror; + // Expect.isTrue(mm.isConstructor); + // Expect.isFalse(mm.isGenerativeConstructor); + // Expect.isTrue(mm.isFactoryConstructor); + // Expect.isFalse(mm.isRedirectingConstructor); + // Expect.isTrue(mm.isConstConstructor); + + mm = cm.declarations[#Class.constRedirectingFactoryConstructor] as MethodMirror; + Expect.isTrue(mm.isConstructor); + Expect.isFalse(mm.isGenerativeConstructor); + Expect.isTrue(mm.isFactoryConstructor); + Expect.isTrue(mm.isRedirectingConstructor); + Expect.isTrue(mm.isConstConstructor); +} diff --git a/tests/lib/mirrors/constructor_optional_args_test.dart b/tests/lib/mirrors/constructor_optional_args_test.dart new file mode 100644 index 00000000000..5592fd2f434 --- /dev/null +++ b/tests/lib/mirrors/constructor_optional_args_test.dart @@ -0,0 +1,62 @@ +// 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. + +library test.constructor_test; + +import 'dart:mirrors'; +import 'package:expect/expect.dart'; + +class A { + factory A([x, y]) = B; + factory A.more([x, y]) = B.more; + factory A.oneMore(x, [y]) = B.more; +} + +class B implements A { + final _x, _y, _z; + + B([x = 'x', y = 'y']) + : _x = x, + _y = y, + _z = null; + + B.more([x = 'x', y = 'y', z = 'z']) + : _x = x, + _y = y, + _z = z; + + toString() => 'B(x=$_x, y=$_y, z=$_z)'; +} + +main() { + var d1 = new A(1); + Expect.equals('B(x=1, y=y, z=null)', '$d1', 'direct 1'); + + var d2 = new A.more(1); + Expect.equals('B(x=1, y=y, z=z)', '$d2', 'direct 2'); + + ClassMirror cm = reflectClass(A); + + var v1 = cm.newInstance(Symbol.empty, []).reflectee; + var v2 = cm.newInstance(Symbol.empty, [1]).reflectee; + var v3 = cm.newInstance(Symbol.empty, [2, 3]).reflectee; + + Expect.equals('B(x=x, y=y, z=null)', '$v1', 'unnamed 1'); + Expect.equals('B(x=1, y=y, z=null)', '$v2', 'unnamed 2'); + Expect.equals('B(x=2, y=3, z=null)', '$v3', 'unnamed 3'); + + var m1 = cm.newInstance(const Symbol('more'), []).reflectee; + var m2 = cm.newInstance(const Symbol('more'), [1]).reflectee; + var m3 = cm.newInstance(const Symbol('more'), [2, 3]).reflectee; + + Expect.equals('B(x=x, y=y, z=z)', '$m1', 'more 1'); + Expect.equals('B(x=1, y=y, z=z)', '$m2', 'more 2'); + Expect.equals('B(x=2, y=3, z=z)', '$m3', 'more 3'); + + var o1 = cm.newInstance(const Symbol('oneMore'), [1]).reflectee; + var o2 = cm.newInstance(const Symbol('oneMore'), [2, 3]).reflectee; + + Expect.equals('B(x=1, y=y, z=z)', '$o1', 'oneMore one arg'); + Expect.equals('B(x=2, y=3, z=z)', '$o2', 'oneMore two args'); +} diff --git a/tests/lib/mirrors/constructor_private_name_test.dart b/tests/lib/mirrors/constructor_private_name_test.dart new file mode 100644 index 00000000000..c0db651a9f7 --- /dev/null +++ b/tests/lib/mirrors/constructor_private_name_test.dart @@ -0,0 +1,31 @@ +// Copyright (c) 2013, 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. + +library test.constructors_test; + +// Regression test for C1 bug. + +import 'dart:mirrors'; + +import 'package:expect/expect.dart'; + +class Foo { + Foo._private(); +} + +class _Foo { + _Foo._private(); +} + +main() { + ClassMirror fooMirror = reflectClass(Foo); + Symbol constructorName = + (fooMirror.declarations[#Foo._private] as MethodMirror).constructorName; + fooMirror.newInstance(constructorName, []); + + ClassMirror _fooMirror = reflectClass(_Foo); + constructorName = + (_fooMirror.declarations[#_Foo._private] as MethodMirror).constructorName; + _fooMirror.newInstance(constructorName, []); +} diff --git a/tests/lib/mirrors/constructors_test.dart b/tests/lib/mirrors/constructors_test.dart new file mode 100644 index 00000000000..9bdbc7fb9ae --- /dev/null +++ b/tests/lib/mirrors/constructors_test.dart @@ -0,0 +1,73 @@ +// Copyright (c) 2013, 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. + +library test.constructors_test; + +import 'dart:mirrors'; + +import 'package:expect/expect.dart'; + +import 'stringify.dart'; + +constructorsOf(ClassMirror cm) { + var result = new Map(); + cm.declarations.forEach((k, v) { + if (v is MethodMirror && v.isConstructor) result[k] = v; + }); + return result; +} + +class Foo {} + +class Bar { + Bar(); +} + +class Baz { + Baz.named(); +} + +class Biz { + Biz(); + Biz.named(); +} + +main() { + ClassMirror fooMirror = reflectClass(Foo); + Map fooConstructors = constructorsOf(fooMirror); + ClassMirror barMirror = reflectClass(Bar); + Map barConstructors = constructorsOf(barMirror); + ClassMirror bazMirror = reflectClass(Baz); + Map bazConstructors = constructorsOf(bazMirror); + ClassMirror bizMirror = reflectClass(Biz); + Map bizConstructors = constructorsOf(bizMirror); + + expect('{Foo: Method(s(Foo) in s(Foo), constructor)}', fooConstructors); + expect('{Bar: Method(s(Bar) in s(Bar), constructor)}', barConstructors); + expect('{Baz.named: Method(s(Baz.named) in s(Baz), constructor)}', + bazConstructors); + expect( + '{Biz: Method(s(Biz) in s(Biz), constructor),' + ' Biz.named: Method(s(Biz.named) in s(Biz), constructor)}', + bizConstructors); + print(bizConstructors); + + expect('[]', fooConstructors.values.single.parameters); + expect('[]', barConstructors.values.single.parameters); + expect('[]', bazConstructors.values.single.parameters); + for (var constructor in bizConstructors.values) { + expect('[]', constructor.parameters); + } + + expect( + '[s()]', fooConstructors.values.map((m) => m.constructorName).toList()); + expect( + '[s()]', barConstructors.values.map((m) => m.constructorName).toList()); + expect('[s(named)]', + bazConstructors.values.map((m) => m.constructorName).toList()); + expect( + '[s(), s(named)]', + bizConstructors.values.map((m) => m.constructorName).toList() + ..sort(compareSymbols)); +} diff --git a/tests/lib/mirrors/dart2js_mirrors_test.dart b/tests/lib/mirrors/dart2js_mirrors_test.dart new file mode 100644 index 00000000000..65c32e3ffa4 --- /dev/null +++ b/tests/lib/mirrors/dart2js_mirrors_test.dart @@ -0,0 +1,13 @@ +// Copyright (c) 2013, 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. + +// This test should be removed when dart2js can pass all mirror tests. +// TODO(ahe): Remove this test. + +import 'mirrors_test.dart' as test; + +main() { + test.isDart2js = true; + test.main(); +} diff --git a/tests/lib/mirrors/declarations_model.dart b/tests/lib/mirrors/declarations_model.dart new file mode 100644 index 00000000000..f25523f1e76 --- /dev/null +++ b/tests/lib/mirrors/declarations_model.dart @@ -0,0 +1,166 @@ +// Copyright (c) 2013, 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. + +library test.declarations_model; + +var libraryVariable; +get libraryGetter => null; +set librarySetter(x) => x; +libraryMethod() => null; + +var _libraryVariable; +get _libraryGetter => null; +set _librarySetter(x) => x; +_libraryMethod() => null; + +typedef bool Predicate(dynamic); + +abstract class Interface { + operator /(x) => null; + + var interfaceInstanceVariable; + get interfaceInstanceGetter; + set interfaceInstanceSetter(x); + interfaceInstanceMethod(); + + var _interfaceInstanceVariable; + get _interfaceInstanceGetter; + set _interfaceInstanceSetter(x); + _interfaceInstanceMethod(); + + static var interfaceStaticVariable; + static get interfaceStaticGetter => null; + static set interfaceStaticSetter(x) => x; + static interfaceStaticMethod() => null; + + static var _interfaceStaticVariable; + static get _interfaceStaticGetter => null; + static set _interfaceStaticSetter(x) => x; + static _interfaceStaticMethod() => null; +} + +class Mixin { + operator *(x) => null; + + var mixinInstanceVariable; + get mixinInstanceGetter => null; + set mixinInstanceSetter(x) => x; + mixinInstanceMethod() => null; + + var _mixinInstanceVariable; + get _mixinInstanceGetter => null; + set _mixinInstanceSetter(x) => x; + _mixinInstanceMethod() => null; + + static var mixinStaticVariable; + static get mixinStaticGetter => null; + static set mixinStaticSetter(x) => x; + static mixinStaticMethod() => null; + + static var _mixinStaticVariable; + static get _mixinStaticGetter => null; + static set _mixinStaticSetter(x) => x; + static _mixinStaticMethod() => null; +} + +class Superclass { + operator -(x) => null; + + var inheritedInstanceVariable; + get inheritedInstanceGetter => null; + set inheritedInstanceSetter(x) => x; + inheritedInstanceMethod() => null; + + var _inheritedInstanceVariable; + get _inheritedInstanceGetter => null; + set _inheritedInstanceSetter(x) => x; + _inheritedInstanceMethod() => null; + + static var inheritedStaticVariable; + static get inheritedStaticGetter => null; + static set inheritedStaticSetter(x) => x; + static inheritedStaticMethod() => null; + + static var _inheritedStaticVariable; + static get _inheritedStaticGetter => null; + static set _inheritedStaticSetter(x) => x; + static _inheritedStaticMethod() => null; + + Superclass.inheritedGenerativeConstructor(this.inheritedInstanceVariable); + Superclass.inheritedRedirectingConstructor(x) + : this.inheritedGenerativeConstructor(x * 2); + factory Superclass.inheritedNormalFactory(y) => + new Superclass.inheritedRedirectingConstructor(y * 3); + factory Superclass.inheritedRedirectingFactory(z) = + Superclass.inheritedNormalFactory; + + Superclass._inheritedGenerativeConstructor(this._inheritedInstanceVariable); + Superclass._inheritedRedirectingConstructor(x) + : this._inheritedGenerativeConstructor(x * 2); + factory Superclass._inheritedNormalFactory(y) => + new Superclass._inheritedRedirectingConstructor(y * 3); + factory Superclass._inheritedRedirectingFactory(z) = + Superclass._inheritedNormalFactory; +} + +abstract class Class extends Superclass + with Mixin + implements Interface { + operator +(x) => null; + + abstractMethod(); + + var instanceVariable; + get instanceGetter => null; + set instanceSetter(x) => x; + instanceMethod() => null; + + var _instanceVariable; + get _instanceGetter => null; + set _instanceSetter(x) => x; + _instanceMethod() => null; + + static var staticVariable; + static get staticGetter => null; + static set staticSetter(x) => x; + static staticMethod() => null; + + static var _staticVariable; + static get _staticGetter => null; + static set _staticSetter(x) => x; + static _staticMethod() => null; + + Class.generativeConstructor(this.instanceVariable) + : super.inheritedGenerativeConstructor(0); + Class.redirectingConstructor(x) : this.generativeConstructor(x * 2); + factory Class.normalFactory(y) => new ConcreteClass(y * 3); + factory Class.redirectingFactory(z) = Class.normalFactory; + + Class._generativeConstructor(this._instanceVariable) + : super._inheritedGenerativeConstructor(0); + Class._redirectingConstructor(x) : this._generativeConstructor(x * 2); + factory Class._normalFactory(y) => new ConcreteClass(y * 3); + factory Class._redirectingFactory(z) = Class._normalFactory; +} + +// This is just here as a target of Class's factories to appease the analyzer. +class ConcreteClass extends Class { + abstractMethod() {} + + operator /(x) => null; + + var interfaceInstanceVariable; + get interfaceInstanceGetter => null; + set interfaceInstanceSetter(x) => null; + interfaceInstanceMethod() => null; + + var _interfaceInstanceVariable; + get _interfaceInstanceGetter => null; + set _interfaceInstanceSetter(x) => null; + _interfaceInstanceMethod() => null; + + ConcreteClass(x) : super.generativeConstructor(x); +} + +class _PrivateClass {} diff --git a/tests/lib/mirrors/declarations_model_easier.dart b/tests/lib/mirrors/declarations_model_easier.dart new file mode 100644 index 00000000000..665b691ec33 --- /dev/null +++ b/tests/lib/mirrors/declarations_model_easier.dart @@ -0,0 +1,84 @@ +// Copyright (c) 2013, 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. + +library test.declarations_model; + +var libraryVariable; +get libraryGetter => null; +set librarySetter(x) => x; +libraryMethod() => null; + +typedef bool Predicate(dynamic); + +abstract class Interface { + operator /(x) => null; + + var interfaceInstanceVariable; + get interfaceInstanceGetter; + set interfaceInstanceSetter(x); + interfaceInstanceMethod(); + + static var interfaceStaticVariable; + static get interfaceStaticGetter => null; + static set interfaceStaticSetter(x) => x; + static interfaceStaticMethod() => null; +} + +class Superclass { + operator -(x) => null; + + var inheritedInstanceVariable; + get inheritedInstanceGetter => null; + set inheritedInstanceSetter(x) => x; + inheritedInstanceMethod() => null; + + static var inheritedStaticVariable; + static get inheritedStaticGetter => null; + static set inheritedStaticSetter(x) => x; + static inheritedStaticMethod() => null; + + Superclass.inheritedGenerativeConstructor(this.inheritedInstanceVariable); + Superclass.inheritedRedirectingConstructor(x) + : this.inheritedGenerativeConstructor(x * 2); + factory Superclass.inheritedNormalFactory(y) => + new Superclass.inheritedRedirectingConstructor(y * 3); + factory Superclass.inheritedRedirectingFactory(z) = + Superclass.inheritedNormalFactory; +} + +abstract class Class extends Superclass implements Interface { + operator +(x) => null; + + abstractMethod(); + + var instanceVariable; + get instanceGetter => null; + set instanceSetter(x) => x; + instanceMethod() => null; + + static var staticVariable; + static get staticGetter => null; + static set staticSetter(x) => x; + static staticMethod() => null; + + Class.generativeConstructor(this.instanceVariable) + : super.inheritedGenerativeConstructor(0); + Class.redirectingConstructor(x) : this.generativeConstructor(x * 2); + factory Class.normalFactory(y) => new ConcreteClass(y * 3); + factory Class.redirectingFactory(z) = Class.normalFactory; +} + +// This is just here as a target of Class's factories to appease the analyzer. +class ConcreteClass extends Class { + abstractMethod() {} + + operator /(x) => null; + + var interfaceInstanceVariable; + get interfaceInstanceGetter => null; + set interfaceInstanceSetter(x) => null; + interfaceInstanceMethod() => null; + + ConcreteClass(x) : super.generativeConstructor(x); +} diff --git a/tests/lib/mirrors/declarations_type_test.dart b/tests/lib/mirrors/declarations_type_test.dart new file mode 100644 index 00000000000..836ce852c9c --- /dev/null +++ b/tests/lib/mirrors/declarations_type_test.dart @@ -0,0 +1,35 @@ +// Copyright (c) 2014, 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. + +// Regression test for Issue 14972. + +library test.declarations_type; + +import 'dart:mirrors'; +import 'package:expect/expect.dart'; + +class C {} + +main() { + var classDeclarations = reflectClass(C).declarations; + Expect.isTrue(classDeclarations is Map); + Expect.isTrue(classDeclarations.values is Iterable); + Expect.isTrue(classDeclarations.values.where((x) => true) + is Iterable); + Expect.isFalse(classDeclarations is Map); + Expect.isFalse(classDeclarations.values is Iterable); + Expect.isFalse( + classDeclarations.values.where((x) => true) is Iterable); + + var libraryDeclarations = + (reflectClass(C).owner as LibraryMirror).declarations; + Expect.isTrue(libraryDeclarations is Map); + Expect.isTrue(libraryDeclarations.values is Iterable); + Expect.isTrue(libraryDeclarations.values.where((x) => true) + is Iterable); + Expect.isFalse(libraryDeclarations is Map); + Expect.isFalse(libraryDeclarations.values is Iterable); + Expect.isFalse( + libraryDeclarations.values.where((x) => true) is Iterable); +} diff --git a/tests/lib/mirrors/deferred_constraints_constants_lib.dart b/tests/lib/mirrors/deferred_constraints_constants_lib.dart new file mode 100644 index 00000000000..cdeec47f791 --- /dev/null +++ b/tests/lib/mirrors/deferred_constraints_constants_lib.dart @@ -0,0 +1,17 @@ +// Copyright (c) 2014, 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. + +class C { + static int staticMethod() => 42; +} + +class G {} + +class Const { + const Const(); + const Const.namedConstructor(); + static const instance = const Const(); +} + +const constantInstance = const Const(); diff --git a/tests/lib/mirrors/deferred_constraints_constants_test.dart b/tests/lib/mirrors/deferred_constraints_constants_test.dart new file mode 100644 index 00000000000..053bb816f53 --- /dev/null +++ b/tests/lib/mirrors/deferred_constraints_constants_test.dart @@ -0,0 +1,70 @@ +// Copyright (c) 2014, 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. + +import 'package:expect/expect.dart'; +import 'package:async_helper/async_helper.dart'; +import 'dart:mirrors'; + +import "deferred_constraints_constants_lib.dart" deferred as lib; + +const myConst1 = + lib.constantInstance; //# reference1: compile-time error + /* // //# reference1: continued + 499; + */ // //# reference1: continued +const myConst2 = + lib.Const.instance; //# reference2: compile-time error + /* // //# reference2: continued + 499; + */ // //# reference2: continued + +void f1( + {a: + const lib.Const() //# default_argument1: compile-time error + /* // //# default_argument1: continued + 499 + */ // //# default_argument1: continued + }) {} + +void f2( + {a: + lib.constantInstance //# default_argument2: compile-time error + /* // //# default_argument2: continued + 499 + */ // //# default_argument2: continued + }) {} + +@lib.Const() //# metadata1: compile-time error +class H1 {} + +@lib.Const.instance //# metadata2: compile-time error +class H2 {} + +@lib.Const.namedConstructor() //# metadata3: compile-time error +class H3 {} + +void main() { + var a1 = myConst1; + var a2 = myConst2; + + asyncStart(); + lib.loadLibrary().then((_) { + var instance = lib.constantInstance; + var c1 = const lib.Const(); //# constructor1: compile-time error + var c2 = const lib.Const.namedConstructor(); //# constructor2: compile-time error + f1(); + f2(); + var constInstance = lib.constantInstance; //# reference_after_load: ok + var h1 = new H1(); + var h2 = new H2(); + var h3 = new H3(); + + // Need to access the metadata to trigger the expected compilation error. + reflectClass(H1).metadata; //# metadata1: continued + reflectClass(H2).metadata; //# metadata2: continued + reflectClass(H3).metadata; //# metadata3: continued + + asyncEnd(); + }); +} diff --git a/tests/lib/mirrors/deferred_mirrors_metadata_lib.dart b/tests/lib/mirrors/deferred_mirrors_metadata_lib.dart new file mode 100644 index 00000000000..80b43b9afae --- /dev/null +++ b/tests/lib/mirrors/deferred_mirrors_metadata_lib.dart @@ -0,0 +1,31 @@ +library lib; + +import "deferred_mirrors_metadata_test.dart"; +import "dart:mirrors"; + +class H { + const H(); +} + +class F { + @H() + int f = 0; +} + +@C() +class E { + @D() + dynamic f; +} + +String foo() { + String c = reflectClass(E).metadata[0].invoke(#toString, []).reflectee; + String d = reflectClass(E) + .declarations[#f] + .metadata[0] + .invoke(#toString, []).reflectee; + InstanceMirror i = currentMirrorSystem().findLibrary(#main).metadata[0]; + String a = i.invoke(#toString, []).reflectee; + String b = i.getField(#b).invoke(#toString, []).reflectee; + return a + b + c + d; +} diff --git a/tests/lib/mirrors/deferred_mirrors_metadata_test.dart b/tests/lib/mirrors/deferred_mirrors_metadata_test.dart new file mode 100644 index 00000000000..02b007d531d --- /dev/null +++ b/tests/lib/mirrors/deferred_mirrors_metadata_test.dart @@ -0,0 +1,45 @@ +// Copyright (c) 2014, 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. + +@A(const B()) +library main; + +@B() +import 'package:async_helper/async_helper.dart'; +import 'package:expect/expect.dart'; + +import "dart:math"; + +import 'deferred_mirrors_metadata_lib.dart' deferred as lib1; + +class A { + final B b; + const A(this.b); + String toString() => "A"; +} + +class B { + const B(); + String toString() => "B"; +} + +class C { + const C(); + String toString() => "C"; +} + +class D { + const D(); + String toString() => "D"; +} + +void main() { + asyncStart(); + lib1.loadLibrary().then((_) { + Expect.equals("ABCD", lib1.foo()); + new C(); + new D(); + asyncEnd(); + }); +} diff --git a/tests/lib/mirrors/deferred_mirrors_metatarget_lib.dart b/tests/lib/mirrors/deferred_mirrors_metatarget_lib.dart new file mode 100644 index 00000000000..e48c4ccd74d --- /dev/null +++ b/tests/lib/mirrors/deferred_mirrors_metatarget_lib.dart @@ -0,0 +1,22 @@ +// Copyright (c) 2014, 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. + +library lib; + +import "dart:mirrors"; + +class MetaTarget { + const MetaTarget(); +} + +@MetaTarget() +class A { + String toString() => "A"; +} + +String foo() { + final a = + currentMirrorSystem().findLibrary(#lib).declarations[#A] as ClassMirror; + return a.newInstance(Symbol.empty, []).invoke(#toString, []).reflectee; +} diff --git a/tests/lib/mirrors/deferred_mirrors_metatarget_test.dart b/tests/lib/mirrors/deferred_mirrors_metatarget_test.dart new file mode 100644 index 00000000000..f0091c8f328 --- /dev/null +++ b/tests/lib/mirrors/deferred_mirrors_metatarget_test.dart @@ -0,0 +1,18 @@ +// Copyright (c) 2014, 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 metaTargets can be reached via the mirrorSystem. + +import 'package:async_helper/async_helper.dart'; +import 'package:expect/expect.dart'; + +import "deferred_mirrors_metatarget_lib.dart" deferred as lib; + +void main() { + asyncStart(); + lib.loadLibrary().then((_) { + Expect.equals("A", lib.foo()); + asyncEnd(); + }); +} diff --git a/tests/lib/mirrors/deferred_mirrors_update_lib.dart b/tests/lib/mirrors/deferred_mirrors_update_lib.dart new file mode 100644 index 00000000000..02b1f3bd76c --- /dev/null +++ b/tests/lib/mirrors/deferred_mirrors_update_lib.dart @@ -0,0 +1,10 @@ +library lib; + +import "dart:mirrors"; + +class C {} + +foo() { + var a = new C(); + print(reflectClass(C).owner); +} diff --git a/tests/lib/mirrors/deferred_mirrors_update_test.dart b/tests/lib/mirrors/deferred_mirrors_update_test.dart new file mode 100644 index 00000000000..bf1fbbc5426 --- /dev/null +++ b/tests/lib/mirrors/deferred_mirrors_update_test.dart @@ -0,0 +1,16 @@ +library main; + +// Test that the library-mirrors are updated after loading a deferred library. + +import "dart:mirrors"; + +import "deferred_mirrors_update_lib.dart" deferred as l; + +class D {} + +void main() { + print(reflectClass(D).owner); + l.loadLibrary().then((_) { + l.foo(); + }); +} diff --git a/tests/lib/mirrors/deferred_type_other.dart b/tests/lib/mirrors/deferred_type_other.dart new file mode 100644 index 00000000000..58e7417e9d9 --- /dev/null +++ b/tests/lib/mirrors/deferred_type_other.dart @@ -0,0 +1,7 @@ +// Copyright (c) 2015, 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. + +library deferred_type_other; + +class DeferredType {} diff --git a/tests/lib/mirrors/deferred_type_test.dart b/tests/lib/mirrors/deferred_type_test.dart new file mode 100644 index 00000000000..338680df302 --- /dev/null +++ b/tests/lib/mirrors/deferred_type_test.dart @@ -0,0 +1,18 @@ +// Copyright (c) 2015, 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. + +library deferred_type; + +import 'dart:mirrors'; +import 'package:expect/expect.dart'; +import 'package:async_helper/async_helper.dart'; + +import 'deferred_type_other.dart' deferred as other; + +bad(other.DeferredType x) {} + +main() { + print((reflect(bad) as ClosureMirror).function.parameters[0].type); + throw "Should have died sooner. other.DeferredType is not loaded"; +} diff --git a/tests/lib/mirrors/delegate_call_through_getter_test.dart b/tests/lib/mirrors/delegate_call_through_getter_test.dart new file mode 100644 index 00000000000..85040aef902 --- /dev/null +++ b/tests/lib/mirrors/delegate_call_through_getter_test.dart @@ -0,0 +1,46 @@ +// Copyright (c) 2013, 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. + +library test.invoke_call_through_getter; + +import 'dart:mirrors'; + +import 'package:expect/expect.dart'; + +class FakeFunctionCall { + call(x, y) => '1 $x $y'; +} + +class FakeFunctionNSM { + noSuchMethod(msg) => msg.positionalArguments.join(', '); +} + +class C { + get fakeFunctionCall => new FakeFunctionCall(); + get fakeFunctionNSM => new FakeFunctionNSM(); + get closure => (x, y) => '2 $this $x $y'; + get closureOpt => (x, y, [z, w]) => '3 $this $x $y $z $w'; + get closureNamed => (x, y, {z, w}) => '4 $this $x $y $z $w'; + get notAClosure => 'Not a closure'; + noSuchMethod(msg) => 'DNU'; + + toString() => 'C'; +} + +class Forwarder { + dynamic noSuchMethod(Invocation msg) => reflect(new C()).delegate(msg); +} + +main() { + dynamic f = new Forwarder(); + + Expect.equals('1 5 6', f.fakeFunctionCall(5, 6)); + Expect.equals('7, 8', f.fakeFunctionNSM(7, 8)); + Expect.equals('2 C 9 10', f.closure(9, 10)); + Expect.equals('3 C 11 12 13 null', f.closureOpt(11, 12, 13)); + Expect.equals('4 C 14 15 null 16', f.closureNamed(14, 15, w: 16)); + Expect.equals('DNU', f.doesNotExist(17, 18)); + Expect.throwsNoSuchMethodError(() => f.closure('wrong arity')); + Expect.throwsNoSuchMethodError(() => f.notAClosure()); +} diff --git a/tests/lib/mirrors/delegate_class_test.dart b/tests/lib/mirrors/delegate_class_test.dart new file mode 100644 index 00000000000..83ee8f079d3 --- /dev/null +++ b/tests/lib/mirrors/delegate_class_test.dart @@ -0,0 +1,50 @@ +// Copyright (c) 2015, 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. + +library test.delegate_class; + +import 'dart:mirrors'; + +import 'package:expect/expect.dart'; + +class C { + static method(a, b, c) => "$a-$b-$c"; + static methodWithNamed(a, {b: 'B', c}) => "$a-$b-$c"; + static methodWithOpt(a, [b, c = 'C']) => "$a-$b-$c"; + static get getter => 'g'; + static set setter(x) { + field = x * 2; + } + + static var field; +} + +class Proxy { + var targetMirror; + Proxy(this.targetMirror); + noSuchMethod(invocation) => targetMirror.delegate(invocation); +} + +main() { + dynamic proxy = new Proxy(reflectClass(C)); + var result; + + Expect.equals('X-Y-Z', proxy.method('X', 'Y', 'Z')); + + Expect.equals('X-B-null', proxy.methodWithNamed('X')); + Expect.equals('X-Y-null', proxy.methodWithNamed('X', b: 'Y')); + Expect.equals('X-Y-Z', proxy.methodWithNamed('X', b: 'Y', c: 'Z')); + + Expect.equals('X-null-C', proxy.methodWithOpt('X')); + Expect.equals('X-Y-C', proxy.methodWithOpt('X', 'Y')); + Expect.equals('X-Y-Z', proxy.methodWithOpt('X', 'Y', 'Z')); + + Expect.equals('g', proxy.getter); + + Expect.equals(5, proxy.setter = 5); + Expect.equals(10, proxy.field); + + Expect.equals(5, proxy.field = 5); + Expect.equals(5, proxy.field); +} diff --git a/tests/lib/mirrors/delegate_function_invocation_test.dart b/tests/lib/mirrors/delegate_function_invocation_test.dart new file mode 100644 index 00000000000..5fe88f4bfb1 --- /dev/null +++ b/tests/lib/mirrors/delegate_function_invocation_test.dart @@ -0,0 +1,56 @@ +// Copyright (c) 2014, 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. + +library test.delgate_function_invocation; + +import 'dart:mirrors'; + +import 'package:expect/expect.dart'; + +class Proxy { + var targetMirror; + Proxy(target) : this.targetMirror = reflect(target); + noSuchMethod(invocation) => targetMirror.delegate(invocation); +} + +testClosure() { + dynamic proxy = new Proxy(() => 42); + Expect.equals(42, proxy()); + Expect.equals(42, proxy.call()); +} + +class FakeFunction { + call() => 43; +} + +testFakeFunction() { + dynamic proxy = new Proxy(new FakeFunction()); + Expect.equals(43, proxy()); + Expect.equals(43, proxy.call()); +} + +topLevelFunction() => 44; + +testTopLevelTearOff() { + dynamic proxy = new Proxy(topLevelFunction); + Expect.equals(44, proxy()); + Expect.equals(44, proxy.call()); +} + +class C { + method() => 45; +} + +testInstanceTearOff() { + dynamic proxy = new Proxy(new C().method); + Expect.equals(45, proxy()); + Expect.equals(45, proxy.call()); +} + +main() { + testClosure(); + testFakeFunction(); + testTopLevelTearOff(); + testInstanceTearOff(); +} diff --git a/tests/lib/mirrors/delegate_library_test.dart b/tests/lib/mirrors/delegate_library_test.dart new file mode 100644 index 00000000000..a4cf43224d5 --- /dev/null +++ b/tests/lib/mirrors/delegate_library_test.dart @@ -0,0 +1,48 @@ +// Copyright (c) 2015, 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. + +library test.delegate_library; + +import 'dart:mirrors'; + +import 'package:expect/expect.dart'; + +method(a, b, c) => "$a-$b-$c"; +methodWithNamed(a, {b: 'B', c}) => "$a-$b-$c"; +methodWithOpt(a, [b, c = 'C']) => "$a-$b-$c"; +get getter => 'g'; +set setter(x) { + field = x * 2; +} + +var field; + +class Proxy { + var targetMirror; + Proxy(this.targetMirror); + noSuchMethod(invocation) => targetMirror.delegate(invocation); +} + +main() { + dynamic proxy = new Proxy(reflectClass(Proxy).owner); + var result; + + Expect.equals('X-Y-Z', proxy.method('X', 'Y', 'Z')); + + Expect.equals('X-B-null', proxy.methodWithNamed('X')); + Expect.equals('X-Y-null', proxy.methodWithNamed('X', b: 'Y')); + Expect.equals('X-Y-Z', proxy.methodWithNamed('X', b: 'Y', c: 'Z')); + + Expect.equals('X-null-C', proxy.methodWithOpt('X')); + Expect.equals('X-Y-C', proxy.methodWithOpt('X', 'Y')); + Expect.equals('X-Y-Z', proxy.methodWithOpt('X', 'Y', 'Z')); + + Expect.equals('g', proxy.getter); + + Expect.equals(5, proxy.setter = 5); + Expect.equals(10, proxy.field); + + Expect.equals(5, proxy.field = 5); + Expect.equals(5, proxy.field); +} diff --git a/tests/lib/mirrors/delegate_test.dart b/tests/lib/mirrors/delegate_test.dart new file mode 100644 index 00000000000..4c63f28392d --- /dev/null +++ b/tests/lib/mirrors/delegate_test.dart @@ -0,0 +1,51 @@ +// Copyright (c) 2013, 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. + +library test.invoke_named_test; + +import 'dart:mirrors'; + +import 'package:expect/expect.dart'; + +class C { + method(a, b, c) => "$a-$b-$c"; + methodWithNamed(a, {b: 'B', c}) => "$a-$b-$c"; + methodWithOpt(a, [b, c = 'C']) => "$a-$b-$c"; + get getter => 'g'; + set setter(x) { + field = x * 2; + } + + var field; +} + +class Proxy { + var targetMirror; + Proxy(target) : this.targetMirror = reflect(target); + noSuchMethod(invocation) => targetMirror.delegate(invocation); +} + +main() { + var c = new C(); + dynamic proxy = new Proxy(c); + var result; + + Expect.equals('X-Y-Z', proxy.method('X', 'Y', 'Z')); + + Expect.equals('X-B-null', proxy.methodWithNamed('X')); + Expect.equals('X-Y-null', proxy.methodWithNamed('X', b: 'Y')); + Expect.equals('X-Y-Z', proxy.methodWithNamed('X', b: 'Y', c: 'Z')); + + Expect.equals('X-null-C', proxy.methodWithOpt('X')); + Expect.equals('X-Y-C', proxy.methodWithOpt('X', 'Y')); + Expect.equals('X-Y-Z', proxy.methodWithOpt('X', 'Y', 'Z')); + + Expect.equals('g', proxy.getter); + + Expect.equals(5, proxy.setter = 5); + Expect.equals(10, proxy.field); + + Expect.equals(5, proxy.field = 5); + Expect.equals(5, proxy.field); +} diff --git a/tests/lib/mirrors/disable_tree_shaking_test.dart b/tests/lib/mirrors/disable_tree_shaking_test.dart new file mode 100644 index 00000000000..b34f3523b5a --- /dev/null +++ b/tests/lib/mirrors/disable_tree_shaking_test.dart @@ -0,0 +1,23 @@ +// Copyright (c) 2013, 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. + +// Ensure that reflection works on methods that would otherwise be +// tree-shaken away. + +import "dart:mirrors"; + +class Foo { + Foo(); + foo() => 42; +} + +main() { + // Do NOT instantiate Foo. + var m = reflectClass(Foo); + var instanceMirror = m.newInstance(new Symbol(''), []); + var result = instanceMirror.invoke(new Symbol('foo'), []).reflectee; + if (result != 42) { + throw 'Expected 42, but got $result'; + } +} diff --git a/tests/lib/mirrors/dynamic_load_error.dart b/tests/lib/mirrors/dynamic_load_error.dart new file mode 100644 index 00000000000..f75aaf93f3a --- /dev/null +++ b/tests/lib/mirrors/dynamic_load_error.dart @@ -0,0 +1,6 @@ +// Copyright (c) 2018, 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. + +// A top-level parse error: +import import import import diff --git a/tests/lib/mirrors/dynamic_load_success.dart b/tests/lib/mirrors/dynamic_load_success.dart new file mode 100644 index 00000000000..1645a923e76 --- /dev/null +++ b/tests/lib/mirrors/dynamic_load_success.dart @@ -0,0 +1,9 @@ +// Copyright (c) 2018, 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. + +library dynamic_load_success; + +int _counter = 0; + +advanceCounter() => ++_counter; diff --git a/tests/lib/mirrors/dynamic_load_test.dart b/tests/lib/mirrors/dynamic_load_test.dart new file mode 100644 index 00000000000..dddb1ac23dd --- /dev/null +++ b/tests/lib/mirrors/dynamic_load_test.dart @@ -0,0 +1,83 @@ +// Copyright (c) 2018, 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. + +import 'dart:async'; +import 'dart:mirrors'; + +import 'package:expect/expect.dart'; + +main() async { + IsolateMirror isolate = currentMirrorSystem().isolate; + print(isolate); + + LibraryMirror success = + await isolate.loadUri(Uri.parse("dynamic_load_success.dart")); + print(success); + InstanceMirror result = success.invoke(#advanceCounter, []); + print(result); + Expect.equals(1, result.reflectee); + result = success.invoke(#advanceCounter, []); + print(result); + Expect.equals(2, result.reflectee); + + LibraryMirror success2 = + await isolate.loadUri(Uri.parse("dynamic_load_success.dart")); + print(success2); + Expect.equals(success, success2); + result = success2.invoke(#advanceCounter, []); + print(result); + Expect.equals(3, result.reflectee); // Same library, same state. + + LibraryMirror math = await isolate.loadUri(Uri.parse("dart:math")); + result = math.invoke(#max, [3, 4]); + print(result); + Expect.equals(4, result.reflectee); + + Future bad_load = isolate.loadUri(Uri.parse("DOES_NOT_EXIST")); + var error; + try { + await bad_load; + } catch (e) { + error = e; + } + print(error); + Expect.isTrue(error.toString().contains("Cannot open file") || + error.toString().contains("file not found") || + error.toString().contains("No such file or directory") || + error.toString().contains("The system cannot find the file specified")); + Expect.isTrue(error.toString().contains("DOES_NOT_EXIST")); + + Future bad_load2 = isolate.loadUri(Uri.parse("dart:_builtin")); + var error2; + try { + await bad_load2; + } catch (e) { + error2 = e; + } + print(error2); + Expect.isTrue(error2.toString().contains("Cannot load")); + Expect.isTrue(error2.toString().contains("dart:_builtin")); + + // Check error is not sticky. + LibraryMirror success3 = + await isolate.loadUri(Uri.parse("dynamic_load_success.dart")); + print(success3); + Expect.equals(success, success3); + result = success3.invoke(#advanceCounter, []); + print(result); + Expect.equals(4, result.reflectee); // Same library, same state. + + Future bad_load3 = + isolate.loadUri(Uri.parse("dynamic_load_error.dart")); + var error3; + try { + await bad_load3; + } catch (e) { + error3 = e; + } + print(error3); + Expect.isTrue(error3.toString().contains("library url expected") || + error3.toString().contains("Error: Expected a String")); + Expect.isTrue(error3.toString().contains("dynamic_load_error.dart")); +} diff --git a/tests/lib/mirrors/empty.dart b/tests/lib/mirrors/empty.dart new file mode 100644 index 00000000000..e2f6f5e97a2 --- /dev/null +++ b/tests/lib/mirrors/empty.dart @@ -0,0 +1,6 @@ +// Copyright (c) 2015, 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. + +// This library has no functions. +library empty; diff --git a/tests/lib/mirrors/empty_test.dart b/tests/lib/mirrors/empty_test.dart new file mode 100644 index 00000000000..9e776344832 --- /dev/null +++ b/tests/lib/mirrors/empty_test.dart @@ -0,0 +1,11 @@ +// Copyright (c) 2015, 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. + +import 'dart:mirrors'; +import 'empty.dart'; + +main() { + var empty = currentMirrorSystem().findLibrary(#empty); + print(empty.location); // Used to crash VM. +} diff --git a/tests/lib/mirrors/enum_mirror_test.dart b/tests/lib/mirrors/enum_mirror_test.dart new file mode 100644 index 00000000000..00de84b8f44 --- /dev/null +++ b/tests/lib/mirrors/enum_mirror_test.dart @@ -0,0 +1,15 @@ +// Copyright (c) 2014, 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. + +import 'dart:mirrors'; + +import 'package:expect/expect.dart'; + +enum Foo { BAR, BAZ } + +main() { + Expect.equals('Foo.BAR', Foo.BAR.toString()); + var name = reflect(Foo.BAR).invoke(#toString, []).reflectee; + Expect.equals('Foo.BAR', name); +} diff --git a/tests/lib/mirrors/enum_test.dart b/tests/lib/mirrors/enum_test.dart new file mode 100644 index 00000000000..318bfe63711 --- /dev/null +++ b/tests/lib/mirrors/enum_test.dart @@ -0,0 +1,65 @@ +// Copyright (c) 2015, 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. + +library test.enums; + +import 'dart:mirrors'; +import 'package:expect/expect.dart'; +import 'stringify.dart'; + +class C {} + +enum Suite { CLUBS, DIAMONDS, SPADES, HEARTS } + +main() { + Expect.isFalse(reflectClass(C).isEnum); + + Expect.isTrue(reflectClass(Suite).isEnum); + Expect.isFalse(reflectClass(Suite).isAbstract); + Expect.equals( + 0, + reflectClass(Suite) + .declarations + .values + .where((d) => d is MethodMirror && d.isConstructor) + .length); + + Expect.equals( + reflectClass(Suite), + (reflectClass(C).owner as LibraryMirror).declarations[#Suite], + "found in library"); + + Expect.equals(reflectClass(Suite), reflect(Suite.CLUBS).type); + + Expect.equals(0, reflect(Suite.CLUBS).getField(#index).reflectee); + Expect.equals(1, reflect(Suite.DIAMONDS).getField(#index).reflectee); + Expect.equals(2, reflect(Suite.SPADES).getField(#index).reflectee); + Expect.equals(3, reflect(Suite.HEARTS).getField(#index).reflectee); + + Expect.equals( + "Suite.CLUBS", reflect(Suite.CLUBS).invoke(#toString, []).reflectee); + Expect.equals("Suite.DIAMONDS", + reflect(Suite.DIAMONDS).invoke(#toString, []).reflectee); + Expect.equals( + "Suite.SPADES", reflect(Suite.SPADES).invoke(#toString, []).reflectee); + Expect.equals( + "Suite.HEARTS", reflect(Suite.HEARTS).invoke(#toString, []).reflectee); + + Expect.setEquals( + [ + 'Variable(s(index) in s(Suite), final)', + 'Variable(s(CLUBS) in s(Suite), static, final)', + 'Variable(s(DIAMONDS) in s(Suite), static, final)', + 'Variable(s(SPADES) in s(Suite), static, final)', + 'Variable(s(HEARTS) in s(Suite), static, final)', + 'Variable(s(values) in s(Suite), static, final)', + 'Method(s(hashCode) in s(Suite), getter)', + 'Method(s(toString) in s(Suite))' + ], + reflectClass(Suite) + .declarations + .values + .where((d) => !d.isPrivate) + .map(stringify)); +} diff --git a/tests/lib/mirrors/equality_test.dart b/tests/lib/mirrors/equality_test.dart new file mode 100644 index 00000000000..0fa6fb421d1 --- /dev/null +++ b/tests/lib/mirrors/equality_test.dart @@ -0,0 +1,159 @@ +// Copyright (c) 2013, 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. + +// This tests uses the multi-test "ok" feature: +// none: Trimmed behaviour. Passing on the VM. +// 01: Trimmed version for dart2js. +// 02: Full version passing in the VM. +// +// TODO(rmacnak,ahe): Remove multi-test when VM and dart2js are on par. + +library test.class_equality_test; + +import 'dart:mirrors'; + +import 'package:expect/expect.dart'; + +class A {} + +class B extends A {} + +class BadEqualityHash { + int count = 0; + bool operator ==(other) => true; + int get hashCode => count++; +} + +typedef bool Predicate(Object o); +Predicate somePredicate = (Object o) => false; + +checkEquality(List> equivalenceClasses) { + for (var equivalenceClass in equivalenceClasses) { + equivalenceClass.forEach((name, member) { + equivalenceClass.forEach((otherName, otherMember) { + // Reflexivity, symmetry and transitivity. + Expect.equals(member, otherMember, "$name == $otherName"); + Expect.equals(member.hashCode, otherMember.hashCode, + "$name.hashCode == $otherName.hashCode"); + }); + for (var otherEquivalenceClass in equivalenceClasses) { + if (otherEquivalenceClass == equivalenceClass) continue; + otherEquivalenceClass.forEach((otherName, otherMember) { + Expect.notEquals( + member, otherMember, "$name != $otherName"); // Exclusion. + // Hash codes may or may not be equal. + }); + } + }); + } +} + +void subroutine() {} + +main() { + LibraryMirror thisLibrary = currentMirrorSystem() + .findLibrary(const Symbol('test.class_equality_test')); + + var o1 = new Object(); + var o2 = new Object(); + + var badEqualityHash1 = new BadEqualityHash(); + var badEqualityHash2 = new BadEqualityHash(); + + checkEquality(>[ + {'reflect(o1)': reflect(o1), 'reflect(o1), again': reflect(o1)}, + {'reflect(o2)': reflect(o2), 'reflect(o2), again': reflect(o2)}, + { + 'reflect(badEqualityHash1)': reflect(badEqualityHash1), + 'reflect(badEqualityHash1), again': reflect(badEqualityHash1) + }, + { + 'reflect(badEqualityHash2)': reflect(badEqualityHash2), + 'reflect(badEqualityHash2), again': reflect(badEqualityHash2) + }, + {'reflect(true)': reflect(true), 'reflect(true), again': reflect(true)}, + {'reflect(false)': reflect(false), 'reflect(false), again': reflect(false)}, + {'reflect(null)': reflect(null), 'reflect(null), again': reflect(null)}, + { + 'reflect(3.5+4.5)': reflect(3.5 + 4.5), + 'reflect(6.5+1.5)': reflect(6.5 + 1.5) + }, + {'reflect(3+4)': reflect(3 + 4), 'reflect(6+1)': reflect(6 + 1)}, + {'reflect("foo")': reflect("foo"), 'reflect("foo"), again': reflect("foo")}, + { + 'currentMirrorSystem().voidType': currentMirrorSystem().voidType, + 'thisLibrary.declarations[#subroutine].returnType': + (thisLibrary.declarations[#subroutine] as MethodMirror).returnType + }, + { + 'currentMirrorSystem().dynamicType': currentMirrorSystem().dynamicType, + 'thisLibrary.declarations[#main].returnType': + (thisLibrary.declarations[#main] as MethodMirror).returnType + }, + { + 'reflectClass(A)': reflectClass(A), + 'thisLibrary.declarations[#A]': thisLibrary.declarations[#A], + 'reflect(new A()).type.originalDeclaration': + reflect(new A()).type.originalDeclaration + }, + { + 'reflectClass(B).superclass': reflectClass(B).superclass, + 'reflect(new A()).type': reflect(new A()).type + }, + { + 'reflectClass(B)': reflectClass(B), + 'thisLibrary.declarations[#B]': thisLibrary.declarations[#B], + 'reflect(new B()).type': reflect(new B()).type + }, + { + 'reflectClass(BadEqualityHash).declarations[#==]': + reflectClass(BadEqualityHash).declarations[#==], + 'reflect(new BadEqualityHash()).type.declarations[#==]': + reflect(new BadEqualityHash()).type.declarations[#==] + }, + { + 'reflectClass(BadEqualityHash).declarations[#==].parameters[0]': + (reflectClass(BadEqualityHash).declarations[#==] as MethodMirror) + .parameters[0], + 'reflect(new BadEqualityHash()).type.declarations[#==].parameters[0]': + (reflect(new BadEqualityHash()).type.declarations[#==] + as MethodMirror) + .parameters[0] + }, + { + 'reflectClass(BadEqualityHash).declarations[#count]': + reflectClass(BadEqualityHash).declarations[#count], + 'reflect(new BadEqualityHash()).type.declarations[#count]': + reflect(new BadEqualityHash()).type.declarations[#count] + }, + { + 'reflectType(Predicate)': reflectType(Predicate), + 'thisLibrary.declarations[#somePredicate].type': + (thisLibrary.declarations[#somePredicate] as VariableMirror).type + }, + { + 'reflectType(Predicate).referent': + (reflectType(Predicate) as TypedefMirror).referent, + 'thisLibrary.declarations[#somePredicate].type.referent': + ((thisLibrary.declarations[#somePredicate] as VariableMirror).type + as TypedefMirror) + .referent + }, + { + 'reflectClass(A).typeVariables.single': + reflectClass(A).typeVariables.single, + 'reflect(new A()).type.originalDeclaration.typeVariables.single': + reflect(new A()).type.originalDeclaration.typeVariables.single + }, + {'currentMirrorSystem()': currentMirrorSystem()}, + {'currentMirrorSystem().isolate': currentMirrorSystem().isolate}, + { + 'thisLibrary': thisLibrary, + 'reflectClass(A).owner': reflectClass(A).owner, + 'reflectClass(B).owner': reflectClass(B).owner, + 'reflect(new A()).type.owner': reflect(new A()).type.owner, + 'reflect(new B()).type.owner': reflect(new B()).type.owner + }, + ]); +} diff --git a/tests/lib/mirrors/fake_function_with_call_test.dart b/tests/lib/mirrors/fake_function_with_call_test.dart new file mode 100644 index 00000000000..43522bcc8c5 --- /dev/null +++ b/tests/lib/mirrors/fake_function_with_call_test.dart @@ -0,0 +1,48 @@ +// Copyright (c) 2013, 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. + +import "dart:mirrors"; + +import "package:expect/expect.dart"; + +membersOf(ClassMirror cm) { + var result = new Map(); + cm.declarations.forEach((k, v) { + if (v is MethodMirror && !v.isConstructor) result[k] = v; + if (v is VariableMirror) result[k] = v; + }); + return result; +} + +class WannabeFunction { + int call(int a, int b) => a + b; + method(x) => x * x; +} + +main() { + Expect.isTrue(new WannabeFunction() is Function); + + ClosureMirror cm = reflect(new WannabeFunction()) as ClosureMirror; + Expect.equals(7, cm.invoke(#call, [3, 4]).reflectee); + Expect.throwsNoSuchMethodError(() => cm.invoke(#call, [3]), "Wrong arity"); + Expect.equals(49, cm.invoke(#method, [7]).reflectee); + Expect.throwsNoSuchMethodError(() => cm.invoke(#method, [3, 4]), + "Wrong arity"); + Expect.equals(7, cm.apply([3, 4]).reflectee); + Expect.throwsNoSuchMethodError(() => cm.apply([3]), "Wrong arity"); + + MethodMirror mm = cm.function; + Expect.equals(#call, mm.simpleName); + Expect.equals(reflectClass(WannabeFunction), mm.owner); + Expect.isTrue(mm.isRegularMethod); + Expect.equals(#int, mm.returnType.simpleName); + Expect.equals(#int, mm.parameters[0].type.simpleName); + Expect.equals(#int, mm.parameters[1].type.simpleName); + + ClassMirror km = cm.type; + Expect.equals(reflectClass(WannabeFunction), km); + Expect.equals(#WannabeFunction, km.simpleName); + Expect.equals(mm.hashCode, km.declarations[#call].hashCode); + Expect.setEquals([#call, #method], membersOf(km).keys); +} diff --git a/tests/lib/mirrors/fake_function_without_call_test.dart b/tests/lib/mirrors/fake_function_without_call_test.dart new file mode 100644 index 00000000000..3d80c03b0cf --- /dev/null +++ b/tests/lib/mirrors/fake_function_without_call_test.dart @@ -0,0 +1,39 @@ +// Copyright (c) 2013, 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. + +import "dart:mirrors"; + +import "package:expect/expect.dart"; + +class MultiArityFunction implements Function { + noSuchMethod(Invocation msg) { + if (msg.memberName != #call) return super.noSuchMethod(msg); + return msg.positionalArguments.join(","); + } +} + +main() { + dynamic f = new MultiArityFunction(); + + Expect.isTrue(f is Function); + Expect.equals('a', f('a')); + Expect.equals('a,b', f('a', 'b')); + Expect.equals('a,b,c', f('a', 'b', 'c')); + Expect.equals('a', Function.apply(f, ['a'])); + Expect.equals('a,b', Function.apply(f, ['a', 'b'])); + Expect.equals('a,b,c', Function.apply(f, ['a', 'b', 'c'])); + Expect.throwsNoSuchMethodError(() => f.foo('a', 'b', 'c')); + + ClosureMirror cm = reflect(f) as ClosureMirror; + Expect.isTrue(cm is ClosureMirror); + Expect.equals('a', cm.apply(['a']).reflectee); + Expect.equals('a,b', cm.apply(['a', 'b']).reflectee); + Expect.equals('a,b,c', cm.apply(['a', 'b', 'c']).reflectee); + + MethodMirror mm = cm.function; + Expect.isNull(mm); + + ClassMirror km = cm.type; + Expect.equals(reflectClass(MultiArityFunction), km); +} diff --git a/tests/lib/mirrors/field_metadata2_test.dart b/tests/lib/mirrors/field_metadata2_test.dart new file mode 100644 index 00000000000..60e1b6c7181 --- /dev/null +++ b/tests/lib/mirrors/field_metadata2_test.dart @@ -0,0 +1,28 @@ +// compile options: --emit-metadata +// Copyright (c) 2017, 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. + +// Run essentially the same test, but with emit-metadata compile option, +// which allows us to reflect on the fields. +import 'dart:mirrors'; +import 'package:expect/expect.dart'; + +import 'field_metadata_test.dart' as field_metadata_test; +import 'field_metadata_test.dart' show Foo, Bar; + +void main() { + // Make sure the other test still works. + field_metadata_test.main(); + + // Check that we can now reflect on the annotations. + dynamic f = new Foo(); + var members = reflect(f).type.declarations; + var x = members[#x] as VariableMirror; + var bar = x.metadata.first.reflectee as Bar; + Expect.equals(bar.name, 'bar'); + + var y = members[#y] as VariableMirror; + var baz = y.metadata.first.reflectee as Bar; + Expect.equals(baz.name, 'baz'); +} diff --git a/tests/lib/mirrors/field_metadata_test.dart b/tests/lib/mirrors/field_metadata_test.dart new file mode 100644 index 00000000000..3abc991bd7c --- /dev/null +++ b/tests/lib/mirrors/field_metadata_test.dart @@ -0,0 +1,41 @@ +// Copyright (c) 2017, 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. + +import 'dart:mirrors'; +import 'package:expect/expect.dart'; + +class Bar { + final String name; + + const Bar(this.name); +} + +class Foo { + @Bar('bar') + int x = 40; + + @Bar('baz') + final String y = 'hi'; + + @Bar('foo') + void set z(int val) { + x = val; + } +} + +void main() { + dynamic f = new Foo(); + f.x += 2; + Expect.equals(f.x, 42); + Expect.equals(f.y, 'hi'); + + f.z = 0; + Expect.equals(f.x, 0); + + var members = reflect(f).type.declarations; + var x = members[#x] as VariableMirror; + var y = members[#y] as VariableMirror; + Expect.equals(x.type.simpleName, #int); + Expect.equals(y.type.simpleName, #String); +} diff --git a/tests/lib/mirrors/field_type_test.dart b/tests/lib/mirrors/field_type_test.dart new file mode 100644 index 00000000000..9b2356b12ce --- /dev/null +++ b/tests/lib/mirrors/field_type_test.dart @@ -0,0 +1,85 @@ +// Copyright (c) 2013, 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. + +library field_test; + +import 'dart:mirrors'; +import "package:expect/expect.dart"; + +String toplevelVariable = ""; + +class C { + final int i; + const C(this.i); +} + +class A { + static int staticField = 0; + @C(42) + @C(44) + String field = ""; + var dynamicTypeField; + T typeVariableField; + H parameterizedTypeField; +} + +class H {} + +testOriginalDeclaration() { + ClassMirror a = reflectClass(A); + VariableMirror staticField = a.declarations[#staticField] as VariableMirror; + VariableMirror field = a.declarations[#field] as VariableMirror; + VariableMirror dynamicTypeField = + a.declarations[#dynamicTypeField] as VariableMirror; + VariableMirror typeVariableField = + a.declarations[#typeVariableField] as VariableMirror; + VariableMirror parameterizedTypeField = + a.declarations[#parameterizedTypeField] as VariableMirror; + + Expect.equals(reflectType(int), staticField.type); + Expect.equals(reflectClass(String), field.type); + Expect.equals(reflectType(dynamic), dynamicTypeField.type); + Expect.equals(a.typeVariables.single, typeVariableField.type); + Expect.equals(reflect(new H()).type, parameterizedTypeField.type); + + Expect.equals(2, field.metadata.length); + Expect.equals(reflect(const C(42)), field.metadata.first); + Expect.equals(reflect(const C(44)), field.metadata.last); +} + +testInstance() { + ClassMirror aOfString = reflect(new A()).type; + VariableMirror staticField = + aOfString.declarations[#staticField] as VariableMirror; + VariableMirror field = aOfString.declarations[#field] as VariableMirror; + VariableMirror dynamicTypeField = + aOfString.declarations[#dynamicTypeField] as VariableMirror; + VariableMirror typeVariableField = + aOfString.declarations[#typeVariableField] as VariableMirror; + VariableMirror parameterizedTypeField = + aOfString.declarations[#parameterizedTypeField] as VariableMirror; + + Expect.equals(reflectType(int), staticField.type); + Expect.equals(reflectClass(String), field.type); + Expect.equals(reflectType(dynamic), dynamicTypeField.type); + Expect.equals(reflectClass(String), typeVariableField.type); + Expect.equals(reflect(new H()).type, parameterizedTypeField.type); + + Expect.equals(2, field.metadata.length); + Expect.equals(reflect(const C(42)), field.metadata.first); + Expect.equals(reflect(const C(44)), field.metadata.last); +} + +testTopLevel() { + LibraryMirror currentLibrary = currentMirrorSystem().findLibrary(#field_test); + VariableMirror topLevel = + currentLibrary.declarations[#toplevelVariable] as VariableMirror; + Expect.equals(reflectClass(String), topLevel.type); +} + +main() { + testOriginalDeclaration(); + testInstance(); + testTopLevel(); +} diff --git a/tests/lib/mirrors/function_apply_mirrors_lib.dart b/tests/lib/mirrors/function_apply_mirrors_lib.dart new file mode 100644 index 00000000000..3c4c510b52d --- /dev/null +++ b/tests/lib/mirrors/function_apply_mirrors_lib.dart @@ -0,0 +1,9 @@ +// Copyright (c) 2015, 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. + +library function_apply_mirrors_lib; + +import "dart:mirrors"; + +bar() => reflect(499).reflectee; diff --git a/tests/lib/mirrors/function_apply_mirrors_test.dart b/tests/lib/mirrors/function_apply_mirrors_test.dart new file mode 100644 index 00000000000..81d3b9ebaaa --- /dev/null +++ b/tests/lib/mirrors/function_apply_mirrors_test.dart @@ -0,0 +1,21 @@ +// Copyright (c) 2015, 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. + +// Only 'lib' imports mirrors. +// Function.apply is resolved, before it is known that mirrors are used. +// Dart2js has different implementations of Function.apply for different +// emitters (like --fast-startup). Dart2js must not switch the resolved +// Function.apply when it discovers the use of mirrors. +// In particular it must not switch from the fast-startup emitter to the full +// emitter without updating the Function.apply reference. +import 'function_apply_mirrors_lib.dart' as lib; + +import "package:expect/expect.dart"; + +int foo({x: 499, y: 42}) => x + y; + +main() { + Expect.equals(709, Function.apply(foo, [], {#y: 210})); + Expect.equals(499, lib.bar()); +} diff --git a/tests/lib/mirrors/function_apply_test.dart b/tests/lib/mirrors/function_apply_test.dart new file mode 100644 index 00000000000..206d08bc880 --- /dev/null +++ b/tests/lib/mirrors/function_apply_test.dart @@ -0,0 +1,39 @@ +// Copyright (c) 2017, 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. + +library lib; + +import "dart:mirrors"; + +import "package:expect/expect.dart"; + +class A { + call(int x) => 123 + x; + bar(int y) => 321 + y; +} + +foo(int y) => 456 + y; + +main() { + // Static function. + ClosureMirror f1 = reflect(foo) as ClosureMirror; + Expect.equals(1456, f1.apply([1000]).reflectee); + + // Local declaration. + chomp(int z) => z + 42; + ClosureMirror f2 = reflect(chomp) as ClosureMirror; + Expect.equals(1042, f2.apply([1000]).reflectee); + + // Local expression. + ClosureMirror f3 = reflect((u) => u + 987) as ClosureMirror; + Expect.equals(1987, f3.apply([1000]).reflectee); + + // Instance property extraction. + ClosureMirror f4 = reflect(new A().bar) as ClosureMirror; + Expect.equals(1321, f4.apply([1000]).reflectee); + + // Instance implementing Function via call method. + ClosureMirror f5 = reflect(new A()) as ClosureMirror; + Expect.equals(1123, f5.apply([1000]).reflectee); +} diff --git a/tests/lib/mirrors/function_type_mirror_test.dart b/tests/lib/mirrors/function_type_mirror_test.dart new file mode 100644 index 00000000000..3b2a5955df9 --- /dev/null +++ b/tests/lib/mirrors/function_type_mirror_test.dart @@ -0,0 +1,23 @@ +// Copyright (c) 2013, 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. + +import "dart:mirrors"; + +import "package:expect/expect.dart"; + +typedef void FooFunction(int a, double b); + +bar(int a) {} + +main() { + TypedefMirror tm = reflectType(FooFunction) as TypedefMirror; + FunctionTypeMirror ftm = tm.referent; + Expect.equals(const Symbol('void'), ftm.returnType.simpleName); + Expect.equals(#int, ftm.parameters[0].type.simpleName); + Expect.equals(#double, ftm.parameters[1].type.simpleName); + ClosureMirror cm = reflect(bar) as ClosureMirror; + ftm = cm.type as FunctionTypeMirror; + Expect.equals(#dynamic, ftm.returnType.simpleName); + Expect.equals(#int, ftm.parameters[0].type.simpleName); +} diff --git a/tests/lib/mirrors/generic_bounded_by_type_parameter_test.dart b/tests/lib/mirrors/generic_bounded_by_type_parameter_test.dart new file mode 100644 index 00000000000..894b464285f --- /dev/null +++ b/tests/lib/mirrors/generic_bounded_by_type_parameter_test.dart @@ -0,0 +1,66 @@ +// Copyright (c) 2013, 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. + +library test.generic_bounded_by_type_parameter; + +import 'dart:mirrors'; + +import 'package:expect/expect.dart'; + +import 'generics_helper.dart'; + +class Super {} + +class Fixed extends Super {} + +class Generic extends Super {} //# 02: compile-time error + +main() { + ClassMirror superDecl = reflectClass(Super); + ClassMirror superOfNumAndInt = reflectClass(Fixed).superclass; + ClassMirror genericDecl = reflectClass(Generic); // //# 02: continued + ClassMirror superOfXAndY = genericDecl.superclass; // //# 02: continued + ClassMirror genericOfNumAndDouble = reflect(new Generic()).type; // //# 02: continued + ClassMirror superOfNumAndDouble = genericOfNumAndDouble.superclass; // //# 02: continued + + ClassMirror genericOfNumAndBool = reflect(new Generic()).type; // //# 02: compile-time error + ClassMirror superOfNumAndBool = genericOfNumAndBool.superclass; // //# 02: continued + Expect.isFalse(genericOfNumAndBool.isOriginalDeclaration); // //# 02: continued + Expect.isFalse(superOfNumAndBool.isOriginalDeclaration); // //# 02: continued + typeParameters(genericOfNumAndBool, [#X, #Y]); // //# 02: continued + typeParameters(superOfNumAndBool, [#T, #R]); // //# 02: continued + typeArguments(genericOfNumAndBool, [reflectClass(num), reflectClass(bool)]); // //# 02: continued + typeArguments(superOfNumAndBool, [reflectClass(num), reflectClass(bool)]); // //# 02: continued + + Expect.isTrue(superDecl.isOriginalDeclaration); + Expect.isFalse(superOfNumAndInt.isOriginalDeclaration); + Expect.isTrue(genericDecl.isOriginalDeclaration); // //# 02: continued + Expect.isFalse(superOfXAndY.isOriginalDeclaration); // //# 02: continued + Expect.isFalse(genericOfNumAndDouble.isOriginalDeclaration); // //# 02: continued + Expect.isFalse(superOfNumAndDouble.isOriginalDeclaration); // //# 02: continued + + TypeVariableMirror tFromSuper = superDecl.typeVariables[0]; + TypeVariableMirror rFromSuper = superDecl.typeVariables[1]; + TypeVariableMirror xFromGeneric = genericDecl.typeVariables[0]; // //# 02: continued + TypeVariableMirror yFromGeneric = genericDecl.typeVariables[1]; // //# 02: continued + + Expect.equals(reflectClass(Object), tFromSuper.upperBound); + Expect.equals(tFromSuper, rFromSuper.upperBound); + Expect.equals(reflectClass(Object), xFromGeneric.upperBound); // //# 02: continued + Expect.equals(reflectClass(Object), yFromGeneric.upperBound); // //# 02: continued + + typeParameters(superDecl, [#T, #R]); + typeParameters(superOfNumAndInt, [#T, #R]); + typeParameters(genericDecl, [#X, #Y]); // //# 02: continued + typeParameters(superOfXAndY, [#T, #R]); // //# 02: continued + typeParameters(genericOfNumAndDouble, [#X, #Y]); // //# 02: continued + typeParameters(superOfNumAndDouble, [#T, #R]); // //# 02: continued + + typeArguments(superDecl, []); + typeArguments(superOfNumAndInt, [reflectClass(num), reflectClass(int)]); + typeArguments(genericDecl, []); // //# 02: continued + typeArguments(superOfXAndY, [xFromGeneric, yFromGeneric]); // //# 02: continued + typeArguments(genericOfNumAndDouble, [reflectClass(num), reflectClass(double)]); // //# 02: continued + typeArguments(superOfNumAndDouble, [reflectClass(num), reflectClass(double)]); // //# 02: continued +} diff --git a/tests/lib/mirrors/generic_bounded_test.dart b/tests/lib/mirrors/generic_bounded_test.dart new file mode 100644 index 00000000000..83d5a8161ed --- /dev/null +++ b/tests/lib/mirrors/generic_bounded_test.dart @@ -0,0 +1,67 @@ +// Copyright (c) 2013, 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. + +library test.generic_bounded; + +import 'dart:mirrors'; + +import 'package:expect/expect.dart'; + +import 'generics_helper.dart'; + +class Super {} + +class Fixed extends Super {} +class Generic extends Super {} // //# 02: compile-time error +class Malbounded extends Super {} //# 01: compile-time error + +main() { + ClassMirror superDecl = reflectClass(Super); + ClassMirror superOfInt = reflectClass(Fixed).superclass; + ClassMirror genericDecl = reflectClass(Generic); // //# 02: continued + ClassMirror superOfR = genericDecl.superclass; // //# 02: continued + ClassMirror genericOfDouble = reflect(new Generic()).type; // //# 02: continued + ClassMirror superOfDouble = genericOfDouble.superclass; // //# 02: continued + ClassMirror genericOfBool = reflect(new Generic()).type; // //# 02: compile-time error + ClassMirror superOfBool = genericOfBool.superclass; // //# 02: continued + Expect.isFalse(genericOfBool.isOriginalDeclaration); // //# 02: continued + Expect.isFalse(superOfBool.isOriginalDeclaration); // //# 02: continued + typeParameters(genericOfBool, [#R]); // //# 02: continued + typeParameters(superOfBool, [#T]); // //# 02: continued + typeArguments(genericOfBool, [reflectClass(bool)]); // //# 02: continued + typeArguments(superOfBool, [reflectClass(bool)]); // //# 02: continued + + ClassMirror superOfString = reflectClass(Malbounded).superclass; // //# 01: continued + + Expect.isTrue(superDecl.isOriginalDeclaration); + Expect.isFalse(superOfInt.isOriginalDeclaration); + Expect.isTrue(genericDecl.isOriginalDeclaration); // //# 02: continued + Expect.isFalse(superOfR.isOriginalDeclaration); // //# 02: continued + Expect.isFalse(genericOfDouble.isOriginalDeclaration); // //# 02: continued + Expect.isFalse(superOfDouble.isOriginalDeclaration); // //# 02: continued + + Expect.isFalse(superOfString.isOriginalDeclaration); // //# 01: continued + + TypeVariableMirror tFromSuper = superDecl.typeVariables.single; + TypeVariableMirror rFromGeneric = genericDecl.typeVariables.single; // //# 02: continued + + Expect.equals(reflectClass(num), tFromSuper.upperBound); + Expect.equals(reflectClass(Object), rFromGeneric.upperBound); // //# 02: continued + + typeParameters(superDecl, [#T]); + typeParameters(superOfInt, [#T]); + typeParameters(genericDecl, [#R]); // //# 02: continued + typeParameters(superOfR, [#T]); // //# 02: continued + typeParameters(genericOfDouble, [#R]); // //# 02: continued + typeParameters(superOfDouble, [#T]); // //# 02: continued + typeParameters(superOfString, [#T]); // //# 01: continued + + typeArguments(superDecl, []); + typeArguments(superOfInt, [reflectClass(int)]); + typeArguments(genericDecl, []); // //# 02: continued + typeArguments(superOfR, [rFromGeneric]); // //# 02: continued + typeArguments(genericOfDouble, [reflectClass(double)]); // //# 02: continued + typeArguments(superOfDouble, [reflectClass(double)]); // //# 02: continued + typeArguments(superOfString, [reflectClass(String)]); // //# 01: continued +} diff --git a/tests/lib/mirrors/generic_class_declaration_test.dart b/tests/lib/mirrors/generic_class_declaration_test.dart new file mode 100644 index 00000000000..79ebee19e86 --- /dev/null +++ b/tests/lib/mirrors/generic_class_declaration_test.dart @@ -0,0 +1,94 @@ +// Copyright (c) 2013, 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. + +import 'dart:mirrors'; +import 'package:expect/expect.dart'; + +import 'stringify.dart'; + +class A { + var instanceVariable; + get instanceGetter => null; + set instanceSetter(x) => x; + instanceMethod() => null; + + var _instanceVariable; + get _instanceGetter => null; + set _instanceSetter(x) => x; + _instanceMethod() => null; + + static var staticVariable; + static get staticGetter => null; + static set staticSetter(x) => x; + static staticMethod() => null; + + static var _staticVariable; + static get _staticGetter => null; + static set _staticSetter(x) => x; + static _staticMethod() => null; +} + +main() { + ClassMirror cm = reflect(new A()).type; + Expect.setEquals([ + 'Variable(s(_instanceVariable) in s(A), private)', + 'Variable(s(_staticVariable) in s(A), private, static)', + 'Variable(s(instanceVariable) in s(A))', + 'Variable(s(staticVariable) in s(A), static)' + ], cm.declarations.values.where((dm) => dm is VariableMirror).map(stringify), + 'variables'); + + Expect.setEquals( + [ + 'Method(s(_instanceGetter) in s(A), private, getter)', + 'Method(s(_staticGetter) in s(A), private, static, getter)', + 'Method(s(instanceGetter) in s(A), getter)', + 'Method(s(staticGetter) in s(A), static, getter)' + ], + cm.declarations.values + .where((dm) => dm is MethodMirror && dm.isGetter) + .map(stringify), + 'getters'); + + Expect.setEquals( + [ + 'Method(s(_instanceSetter=) in s(A), private, setter)', + 'Method(s(_staticSetter=) in s(A), private, static, setter)', + 'Method(s(instanceSetter=) in s(A), setter)', + 'Method(s(staticSetter=) in s(A), static, setter)' + ], + cm.declarations.values + .where((dm) => dm is MethodMirror && dm.isSetter) + .map(stringify), + 'setters'); + + Expect.setEquals( + [ + 'Method(s(_instanceMethod) in s(A), private)', + 'Method(s(_staticMethod) in s(A), private, static)', + 'Method(s(instanceMethod) in s(A))', + 'Method(s(staticMethod) in s(A), static)' + ], + cm.declarations.values + .where((dm) => dm is MethodMirror && dm.isRegularMethod) + .map(stringify), + 'methods'); + + Expect.setEquals( + ['Method(s(A) in s(A), constructor)'], + cm.declarations.values + .where((dm) => dm is MethodMirror && dm.isConstructor) + .map(stringify), + 'constructors'); + + Expect.setEquals( + [ + 'TypeVariable(s(T) in s(A), upperBound = Class(s(Object) in ' + 's(dart.core), top-level))' + ], + cm.declarations.values + .where((dm) => dm is TypeVariableMirror) + .map(stringify), + 'type variables'); +} diff --git a/tests/lib/mirrors/generic_f_bounded_mixin_application_test.dart b/tests/lib/mirrors/generic_f_bounded_mixin_application_test.dart new file mode 100644 index 00000000000..5df9521d44e --- /dev/null +++ b/tests/lib/mirrors/generic_f_bounded_mixin_application_test.dart @@ -0,0 +1,122 @@ +// Copyright (c) 2013, 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. + +library test.generic_f_bounded; + +import 'dart:mirrors'; + +import 'package:expect/expect.dart'; + +import 'generics_helper.dart'; + +class Collection {} + +class Serializable {} + +class OrderedCollection extends Collection + with Serializable> {} + +class AbstractOrderedCollection = Collection + with Serializable>; + +class CustomOrderedCollection extends AbstractOrderedCollection {} + +class OrderedIntegerCollection extends OrderedCollection {} + +class CustomOrderedIntegerCollection extends CustomOrderedCollection {} + +class Serializer> {} + +class CollectionSerializer extends Serializer {} + +class OrderedCollectionSerializer extends Serializer {} + +main() { + ClassMirror collectionDecl = reflectClass(Collection); + ClassMirror serializableDecl = reflectClass(Serializable); + ClassMirror orderedCollectionDecl = reflectClass(OrderedCollection); + ClassMirror abstractOrderedCollectionDecl = + reflectClass(AbstractOrderedCollection); + ClassMirror customOrderedCollectionDecl = + reflectClass(CustomOrderedCollection); + ClassMirror orderedIntegerCollection = reflectClass(OrderedIntegerCollection); + ClassMirror customOrderedIntegerCollection = + reflectClass(CustomOrderedIntegerCollection); + ClassMirror serializerDecl = reflectClass(Serializer); + ClassMirror collectionSerializerDecl = reflectClass(CollectionSerializer); + ClassMirror orderedCollectionSerializerDecl = + reflectClass(OrderedCollectionSerializer); + + ClassMirror orderedCollectionOfInt = orderedIntegerCollection.superclass; + ClassMirror customOrderedCollectionOfInt = + customOrderedIntegerCollection.superclass; + ClassMirror serializerOfCollection = collectionSerializerDecl.superclass; + ClassMirror serializerOfOrderedCollection = + orderedCollectionSerializerDecl.superclass; + ClassMirror collectionOfDynamic = reflect(new Collection()).type; + ClassMirror orderedCollectionOfDynamic = + reflect(new OrderedCollection()).type; + ClassMirror collectionWithSerializableOfOrderedCollection = + orderedCollectionDecl.superclass; + + Expect.isTrue(collectionDecl.isOriginalDeclaration); + Expect.isTrue(serializableDecl.isOriginalDeclaration); + Expect.isTrue(orderedCollectionDecl.isOriginalDeclaration); + Expect.isTrue(abstractOrderedCollectionDecl.isOriginalDeclaration); + Expect.isTrue(customOrderedCollectionDecl.isOriginalDeclaration); + Expect.isTrue(orderedIntegerCollection.isOriginalDeclaration); + Expect.isTrue(customOrderedIntegerCollection.isOriginalDeclaration); + Expect.isTrue(serializerDecl.isOriginalDeclaration); + Expect.isTrue(collectionSerializerDecl.isOriginalDeclaration); + Expect.isTrue(orderedCollectionSerializerDecl.isOriginalDeclaration); + + Expect.isFalse(orderedCollectionOfInt.isOriginalDeclaration); + Expect.isFalse(customOrderedCollectionOfInt.isOriginalDeclaration); + Expect.isFalse(serializerOfCollection.isOriginalDeclaration); + Expect.isFalse(serializerOfOrderedCollection.isOriginalDeclaration); + Expect.isFalse(collectionOfDynamic.isOriginalDeclaration); + Expect.isFalse( + collectionWithSerializableOfOrderedCollection.isOriginalDeclaration); + + TypeVariableMirror rFromSerializer = serializerDecl.typeVariables.single; + ClassMirror serializableOfR = rFromSerializer.upperBound as ClassMirror; + Expect.isFalse(serializableOfR.isOriginalDeclaration); + Expect.equals(serializableDecl, serializableOfR.originalDeclaration); + Expect.equals(rFromSerializer, serializableOfR.typeArguments.single); + + typeParameters(collectionDecl, [#C]); + typeParameters(serializableDecl, [#S]); + typeParameters(orderedCollectionDecl, [#V]); + typeParameters(abstractOrderedCollectionDecl, [#W]); + typeParameters(customOrderedCollectionDecl, [#Z]); + typeParameters(orderedIntegerCollection, []); + typeParameters(customOrderedIntegerCollection, []); + typeParameters(serializerDecl, [#R]); + typeParameters(collectionSerializerDecl, []); + typeParameters(orderedCollectionSerializerDecl, []); + + typeParameters(orderedCollectionOfInt, [#V]); + typeParameters(customOrderedCollectionOfInt, [#Z]); + typeParameters(serializerOfCollection, [#R]); + typeParameters(serializerOfOrderedCollection, [#R]); + typeParameters(collectionOfDynamic, [#C]); + typeParameters(collectionWithSerializableOfOrderedCollection, []); + + typeArguments(collectionDecl, []); + typeArguments(serializableDecl, []); + typeArguments(orderedCollectionDecl, []); + typeArguments(abstractOrderedCollectionDecl, []); + typeArguments(customOrderedCollectionDecl, []); + typeArguments(orderedIntegerCollection, []); + typeArguments(customOrderedIntegerCollection, []); + typeArguments(serializerDecl, []); + typeArguments(collectionSerializerDecl, []); + typeArguments(orderedCollectionSerializerDecl, []); + + typeArguments(orderedCollectionOfInt, [reflectClass(int)]); + typeArguments(customOrderedCollectionOfInt, [reflectClass(int)]); + typeArguments(serializerOfCollection, [collectionOfDynamic]); + typeArguments(serializerOfOrderedCollection, [orderedCollectionOfDynamic]); + typeArguments(collectionWithSerializableOfOrderedCollection, []); +} diff --git a/tests/lib/mirrors/generic_f_bounded_test.dart b/tests/lib/mirrors/generic_f_bounded_test.dart new file mode 100644 index 00000000000..1ddf7e44875 --- /dev/null +++ b/tests/lib/mirrors/generic_f_bounded_test.dart @@ -0,0 +1,61 @@ +// Copyright (c) 2013, 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. + +library test.generic_f_bounded; + +import 'dart:mirrors'; + +import 'package:expect/expect.dart'; + +import 'generics_helper.dart'; + +class Magnitude {} + +class Real extends Magnitude {} + +class Sorter> {} + +class RealSorter extends Sorter {} + +main() { + ClassMirror magnitudeDecl = reflectClass(Magnitude); + ClassMirror realDecl = reflectClass(Real); + ClassMirror sorterDecl = reflectClass(Sorter); + ClassMirror realSorterDecl = reflectClass(RealSorter); + ClassMirror magnitudeOfReal = realDecl.superclass; + ClassMirror sorterOfReal = realSorterDecl.superclass; + + Expect.isTrue(magnitudeDecl.isOriginalDeclaration); + Expect.isTrue(realDecl.isOriginalDeclaration); + Expect.isTrue(sorterDecl.isOriginalDeclaration); + Expect.isTrue(realSorterDecl.isOriginalDeclaration); + Expect.isFalse(magnitudeOfReal.isOriginalDeclaration); + Expect.isFalse(sorterOfReal.isOriginalDeclaration); + + TypeVariableMirror tFromMagnitude = magnitudeDecl.typeVariables.single; + TypeVariableMirror rFromSorter = sorterDecl.typeVariables.single; + + Expect.equals(reflectClass(Object), tFromMagnitude.upperBound); + + ClassMirror magnitudeOfR = rFromSorter.upperBound; + Expect.isFalse(magnitudeOfR.isOriginalDeclaration); + Expect.equals(magnitudeDecl, magnitudeOfR.originalDeclaration); + Expect.equals(rFromSorter, magnitudeOfR.typeArguments.single); + + typeParameters(magnitudeDecl, [#T]); + typeParameters(realDecl, []); + typeParameters(sorterDecl, [#R]); + typeParameters(realSorterDecl, []); + typeParameters(magnitudeOfReal, [#T]); + typeParameters(sorterOfReal, [#R]); + typeParameters(magnitudeOfR, [#T]); + + typeArguments(magnitudeDecl, []); + typeArguments(realDecl, []); + typeArguments(sorterDecl, []); + typeArguments(realSorterDecl, []); + typeArguments(magnitudeOfReal, [realDecl]); //# 01: ok + typeArguments(sorterOfReal, [realDecl]); //# 01: ok + typeArguments(magnitudeOfR, [rFromSorter]); +} diff --git a/tests/lib/mirrors/generic_function_typedef_test.dart b/tests/lib/mirrors/generic_function_typedef_test.dart new file mode 100644 index 00000000000..6b0d44bc484 --- /dev/null +++ b/tests/lib/mirrors/generic_function_typedef_test.dart @@ -0,0 +1,128 @@ +// Copyright (c) 2013, 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. + +library test.generic_function_typedef; + +import 'dart:mirrors'; + +import 'package:expect/expect.dart'; + +import 'generics_helper.dart'; + +typedef bool NonGenericPredicate(num n); +typedef bool GenericPredicate(T t); +typedef S GenericTransform(S s); + +class C { + GenericPredicate predicateOfNum; + GenericTransform transformOfString; + GenericTransform transformOfR; +} + +reflectTypeDeclaration(t) => reflectType(t).originalDeclaration; + +main() { + TypeMirror dynamicMirror = currentMirrorSystem().dynamicType; + + TypedefMirror predicateOfNum = + (reflectClass(C).declarations[#predicateOfNum] as VariableMirror).type + as TypedefMirror; + TypedefMirror transformOfString = + (reflectClass(C).declarations[#transformOfString] as VariableMirror).type + as TypedefMirror; + TypedefMirror transformOfR = + (reflectClass(C).declarations[#transformOfR] as VariableMirror).type + as TypedefMirror; + TypedefMirror transformOfDouble = (reflect(new C()) + .type + .declarations[#transformOfR] as VariableMirror) + .type as TypedefMirror; + + TypeVariableMirror tFromGenericPredicate = + reflectTypeDeclaration(GenericPredicate).typeVariables[0]; + TypeVariableMirror sFromGenericTransform = + reflectTypeDeclaration(GenericTransform).typeVariables[0]; + TypeVariableMirror rFromC = reflectClass(C).typeVariables[0]; + + // Typedefs. + typeParameters(reflectTypeDeclaration(NonGenericPredicate), []); + typeParameters(reflectTypeDeclaration(GenericPredicate), [#T]); + typeParameters(reflectTypeDeclaration(GenericTransform), [#S]); + typeParameters(predicateOfNum, [#T]); + typeParameters(transformOfString, [#S]); + typeParameters(transformOfR, [#S]); + typeParameters(transformOfDouble, [#S]); + + typeArguments(reflectTypeDeclaration(NonGenericPredicate), []); + typeArguments(reflectTypeDeclaration(GenericPredicate), []); + typeArguments(reflectTypeDeclaration(GenericTransform), []); + typeArguments(predicateOfNum, [reflectClass(num)]); + typeArguments(transformOfString, [reflectClass(String)]); + typeArguments(transformOfR, [rFromC]); + typeArguments(transformOfDouble, [reflectClass(double)]); + + Expect.isTrue( + reflectTypeDeclaration(NonGenericPredicate).isOriginalDeclaration); + Expect.isTrue(reflectTypeDeclaration(GenericPredicate).isOriginalDeclaration); + Expect.isTrue(reflectTypeDeclaration(GenericTransform).isOriginalDeclaration); + Expect.isFalse(predicateOfNum.isOriginalDeclaration); + Expect.isFalse(transformOfString.isOriginalDeclaration); + Expect.isFalse(transformOfR.isOriginalDeclaration); + Expect.isFalse(transformOfDouble.isOriginalDeclaration); + + // Function types. + typeParameters(reflectTypeDeclaration(NonGenericPredicate).referent, []); + typeParameters(reflectTypeDeclaration(GenericPredicate).referent, []); + typeParameters(reflectTypeDeclaration(GenericTransform).referent, []); + typeParameters(predicateOfNum.referent, []); + typeParameters(transformOfString.referent, []); + typeParameters(transformOfR.referent, []); + typeParameters(transformOfDouble.referent, []); + + typeArguments(reflectTypeDeclaration(NonGenericPredicate).referent, []); + typeArguments(reflectTypeDeclaration(GenericPredicate).referent, []); + typeArguments(reflectTypeDeclaration(GenericTransform).referent, []); + typeArguments(predicateOfNum.referent, []); + typeArguments(transformOfString.referent, []); + typeArguments(transformOfR.referent, []); + typeArguments(transformOfDouble.referent, []); + + // Function types are always non-generic. Only the typedef is generic. + Expect.isTrue(reflectTypeDeclaration(NonGenericPredicate) + .referent + .isOriginalDeclaration); + Expect.isTrue( + reflectTypeDeclaration(GenericPredicate).referent.isOriginalDeclaration); + Expect.isTrue( + reflectTypeDeclaration(GenericTransform).referent.isOriginalDeclaration); + Expect.isTrue(predicateOfNum.referent.isOriginalDeclaration); + Expect.isTrue(transformOfString.referent.isOriginalDeclaration); + Expect.isTrue(transformOfR.referent.isOriginalDeclaration); + Expect.isTrue(transformOfDouble.referent.isOriginalDeclaration); + + Expect.equals(reflectClass(num), + reflectTypeDeclaration(NonGenericPredicate).referent.parameters[0].type); + Expect.equals(tFromGenericPredicate, + reflectTypeDeclaration(GenericPredicate).referent.parameters[0].type); + Expect.equals(sFromGenericTransform, + reflectTypeDeclaration(GenericTransform).referent.parameters[0].type); + + Expect.equals(reflectClass(num), predicateOfNum.referent.parameters[0].type); + Expect.equals( + reflectClass(String), transformOfString.referent.parameters[0].type); + Expect.equals(rFromC, transformOfR.referent.parameters[0].type); + Expect.equals( + reflectClass(double), transformOfDouble.referent.parameters[0].type); + + Expect.equals(reflectClass(bool), + reflectTypeDeclaration(NonGenericPredicate).referent.returnType); + Expect.equals(reflectClass(bool), + reflectTypeDeclaration(GenericPredicate).referent.returnType); + Expect.equals(sFromGenericTransform, + reflectTypeDeclaration(GenericTransform).referent.returnType); + Expect.equals(reflectClass(bool), predicateOfNum.referent.returnType); + Expect.equals(reflectClass(String), transformOfString.referent.returnType); + Expect.equals(rFromC, transformOfR.referent.returnType); + Expect.equals(reflectClass(double), transformOfDouble.referent.returnType); +} diff --git a/tests/lib/mirrors/generic_interface_test.dart b/tests/lib/mirrors/generic_interface_test.dart new file mode 100644 index 00000000000..8b38a3b4bac --- /dev/null +++ b/tests/lib/mirrors/generic_interface_test.dart @@ -0,0 +1,123 @@ +// Copyright (c) 2013, 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. + +library test.generic_bounded; + +import 'dart:mirrors'; + +import 'package:expect/expect.dart'; + +import 'generics_helper.dart'; + +class Interface {} + +class Bounded {} + +class Fixed implements Interface {} + +class Generic implements Interface {} + +class Bienbounded implements Bounded {} + +class Malbounded implements Bounded {} // //# 01: compile-time error +class FBounded implements Interface {} + +class Mixin {} + +class FixedMixinApplication = Object with Mixin implements Interface; +class GenericMixinApplication = Object with Mixin implements Interface; + +class FixedClass extends Object with Mixin implements Interface {} + +class GenericClass extends Object with Mixin implements Interface {} + +main() { + TypeMirror dynamicMirror = currentMirrorSystem().dynamicType; + + ClassMirror interfaceDecl = reflectClass(Interface); + ClassMirror boundedDecl = reflectClass(Bounded); + + ClassMirror interfaceOfInt = reflectClass(Fixed).superinterfaces.single; + ClassMirror interfaceOfR = reflectClass(Generic).superinterfaces.single; + ClassMirror interfaceOfBool = + reflect(new Generic()).type.superinterfaces.single; + + ClassMirror boundedOfInt = reflectClass(Bienbounded).superinterfaces.single; + ClassMirror boundedOfString = reflectClass(Malbounded).superinterfaces.single; // //# 01: continued + ClassMirror interfaceOfFBounded = + reflectClass(FBounded).superinterfaces.single; + + ClassMirror interfaceOfInt2 = + reflectClass(FixedMixinApplication).superinterfaces.single; + ClassMirror interfaceOfX = + reflectClass(GenericMixinApplication).superinterfaces.single; + ClassMirror interfaceOfDouble = reflect(new GenericMixinApplication()) + .type + .superinterfaces + .single; + ClassMirror interfaceOfInt3 = reflectClass(FixedClass).superinterfaces.single; + ClassMirror interfaceOfY = reflectClass(GenericClass).superinterfaces.single; + ClassMirror interfaceOfDouble2 = + reflect(new GenericClass()).type.superinterfaces.single; + + Expect.isTrue(interfaceDecl.isOriginalDeclaration); + Expect.isTrue(boundedDecl.isOriginalDeclaration); + + Expect.isFalse(interfaceOfInt.isOriginalDeclaration); + Expect.isFalse(interfaceOfR.isOriginalDeclaration); + Expect.isFalse(interfaceOfBool.isOriginalDeclaration); + Expect.isFalse(boundedOfInt.isOriginalDeclaration); + Expect.isFalse(boundedOfString.isOriginalDeclaration); // //# 01: continued + Expect.isFalse(interfaceOfFBounded.isOriginalDeclaration); + Expect.isFalse(interfaceOfInt2.isOriginalDeclaration); + Expect.isFalse(interfaceOfX.isOriginalDeclaration); + Expect.isFalse(interfaceOfDouble.isOriginalDeclaration); + Expect.isFalse(interfaceOfInt3.isOriginalDeclaration); + Expect.isFalse(interfaceOfY.isOriginalDeclaration); + Expect.isFalse(interfaceOfDouble2.isOriginalDeclaration); + + TypeVariableMirror tFromInterface = interfaceDecl.typeVariables.single; + TypeVariableMirror sFromBounded = boundedDecl.typeVariables.single; + TypeVariableMirror rFromGeneric = reflectClass(Generic).typeVariables.single; + TypeVariableMirror xFromGenericMixinApplication = + reflectClass(GenericMixinApplication).typeVariables.single; + TypeVariableMirror yFromGenericClass = + reflectClass(GenericClass).typeVariables.single; + + Expect.equals(reflectClass(Object), tFromInterface.upperBound); + Expect.equals(reflectClass(num), sFromBounded.upperBound); + Expect.equals(reflectClass(Object), rFromGeneric.upperBound); + Expect.equals(reflectClass(Object), xFromGenericMixinApplication.upperBound); + Expect.equals(reflectClass(Object), yFromGenericClass.upperBound); + + typeParameters(interfaceDecl, [#T]); + typeParameters(boundedDecl, [#S]); + typeParameters(interfaceOfInt, [#T]); + typeParameters(interfaceOfR, [#T]); + typeParameters(interfaceOfBool, [#T]); + typeParameters(boundedOfInt, [#S]); + typeParameters(boundedOfString, [#S]); // //# 01: continued + typeParameters(interfaceOfFBounded, [#T]); + typeParameters(interfaceOfInt2, [#T]); + typeParameters(interfaceOfX, [#T]); + typeParameters(interfaceOfDouble, [#T]); + typeParameters(interfaceOfInt3, [#T]); + typeParameters(interfaceOfY, [#T]); + typeParameters(interfaceOfDouble2, [#T]); + + typeArguments(interfaceDecl, []); + typeArguments(boundedDecl, []); + typeArguments(interfaceOfInt, [reflectClass(int)]); + typeArguments(interfaceOfR, [rFromGeneric]); + typeArguments(interfaceOfBool, [reflectClass(bool)]); + typeArguments(boundedOfInt, [reflectClass(int)]); + typeArguments(boundedOfString, [reflectClass(String)]); // //# 01: continued + typeArguments(interfaceOfFBounded, [reflectClass(FBounded)]); + typeArguments(interfaceOfInt2, [reflectClass(int)]); + typeArguments(interfaceOfX, [xFromGenericMixinApplication]); + typeArguments(interfaceOfDouble, [reflectClass(double)]); + typeArguments(interfaceOfInt3, [reflectClass(int)]); + typeArguments(interfaceOfY, [yFromGenericClass]); + typeArguments(interfaceOfDouble2, [reflectClass(double)]); +} diff --git a/tests/lib/mirrors/generic_list_test.dart b/tests/lib/mirrors/generic_list_test.dart new file mode 100644 index 00000000000..79d5e94b345 --- /dev/null +++ b/tests/lib/mirrors/generic_list_test.dart @@ -0,0 +1,21 @@ +// Copyright (c) 2013, 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. + +library test.superclass; + +import 'dart:mirrors'; +import 'package:expect/expect.dart'; + +class Foo { + List makeList() { + if (new DateTime.now().millisecondsSinceEpoch == 42) return []; + return new List(); + } +} + +main() { + List list = new Foo().makeList(); + var cls = reflectClass(list.runtimeType); + Expect.isNotNull(cls, 'Failed to reflect on MyClass.'); +} diff --git a/tests/lib/mirrors/generic_local_function_test.dart b/tests/lib/mirrors/generic_local_function_test.dart new file mode 100644 index 00000000000..bc56f291140 --- /dev/null +++ b/tests/lib/mirrors/generic_local_function_test.dart @@ -0,0 +1,40 @@ +// Copyright (c) 2013, 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. + +library test.generic_function_typedef; + +import 'dart:mirrors'; + +import 'package:expect/expect.dart'; + +import 'generics_helper.dart'; + +class C { + makeClosure1() { + T closure1(T t) {} + return closure1; + } + + makeClosure2() { + enclosing() { + T closure2(T t) {} + return closure2; + } + + ; + return enclosing(); + } +} + +main() { + ClosureMirror closure1 = + reflect(new C().makeClosure1()) as ClosureMirror; + Expect.equals(reflectClass(String), closure1.function.returnType); + Expect.equals(reflectClass(String), closure1.function.parameters[0].type); + + ClosureMirror closure2 = + reflect(new C().makeClosure2()) as ClosureMirror; + Expect.equals(reflectClass(String), closure2.function.returnType); + Expect.equals(reflectClass(String), closure2.function.parameters[0].type); +} diff --git a/tests/lib/mirrors/generic_method_test.dart b/tests/lib/mirrors/generic_method_test.dart new file mode 100644 index 00000000000..fb82bbfb799 --- /dev/null +++ b/tests/lib/mirrors/generic_method_test.dart @@ -0,0 +1,15 @@ +// Copyright (c) 2017, 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. + +import 'dart:mirrors'; +import 'package:expect/expect.dart'; + +class Foo { + T bar() => null; +} + +void main() { + var type = reflectClass(Foo); + Expect.isTrue(type.declarations.keys.contains(#bar)); +} diff --git a/tests/lib/mirrors/generic_mixin_applications_test.dart b/tests/lib/mirrors/generic_mixin_applications_test.dart new file mode 100644 index 00000000000..8a9fec7b764 --- /dev/null +++ b/tests/lib/mirrors/generic_mixin_applications_test.dart @@ -0,0 +1,105 @@ +// Copyright (c) 2013, 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. + +library test.generic_mixin_applications; + +import 'dart:mirrors'; + +import 'package:expect/expect.dart'; + +import 'generics_helper.dart'; + +class Super {} + +class Mixin {} + +class Nixim {} + +class NonGenericMixinApplication1 = Super with Mixin; +class NonGenericMixinApplication2 = Super with Mixin; + +class GenericMixinApplication1 = Super with Mixin; +class GenericMixinApplication2 = Super with Mixin; + +class NonGenericClass1 extends Super with Mixin {} + +class NonGenericClass2 extends Super with Mixin {} + +class GenericClass1 extends Super with Mixin {} + +class GenericClass2 extends Super with Mixin {} + +class GenericMultipleMixins extends Super with Mixin, Nixim {} + +main() { + TypeMirror dynamicMirror = currentMirrorSystem().dynamicType; + + // Declarations. + typeParameters(reflectClass(NonGenericMixinApplication1), []); + typeParameters(reflectClass(NonGenericMixinApplication2), []); + typeParameters(reflectClass(GenericMixinApplication1), [#MA]); + typeParameters(reflectClass(GenericMixinApplication2), [#MA]); + typeParameters(reflectClass(NonGenericClass1), []); + typeParameters(reflectClass(NonGenericClass2), []); + typeParameters(reflectClass(GenericClass1), [#C]); + typeParameters(reflectClass(GenericClass2), [#C]); + typeParameters(reflectClass(GenericMultipleMixins), [#A, #B, #C]); + // Anonymous mixin applications have no type parameters or type arguments. + typeParameters(reflectClass(NonGenericClass1).superclass, []); + typeParameters(reflectClass(NonGenericClass2).superclass, []); + typeParameters(reflectClass(GenericClass1).superclass, []); + typeParameters(reflectClass(GenericClass2).superclass, []); + + typeArguments(reflectClass(NonGenericMixinApplication1), []); + typeArguments(reflectClass(NonGenericMixinApplication2), []); + typeArguments(reflectClass(GenericMixinApplication1), []); + typeArguments(reflectClass(GenericMixinApplication2), []); + typeArguments(reflectClass(NonGenericClass1), []); + typeArguments(reflectClass(NonGenericClass2), []); + typeArguments(reflectClass(GenericClass1), []); + typeArguments(reflectClass(GenericClass2), []); + typeArguments(reflectClass(GenericMultipleMixins), []); + // Anonymous mixin applications have no type parameters or type arguments. + typeArguments( + reflectClass(NonGenericClass1).superclass.originalDeclaration, []); + typeArguments( + reflectClass(NonGenericClass2).superclass.originalDeclaration, []); + typeArguments(reflectClass(GenericClass1).superclass.originalDeclaration, []); + typeArguments(reflectClass(GenericClass2).superclass.originalDeclaration, []); + + // Instantiations. + typeParameters(reflect(new NonGenericMixinApplication1()).type, []); + typeParameters(reflect(new NonGenericMixinApplication2()).type, []); + typeParameters(reflect(new GenericMixinApplication1()).type, [#MA]); + typeParameters(reflect(new GenericMixinApplication2()).type, [#MA]); + typeParameters(reflect(new NonGenericClass1()).type, []); + typeParameters(reflect(new NonGenericClass2()).type, []); + typeParameters(reflect(new GenericClass1()).type, [#C]); + typeParameters(reflect(new GenericClass2()).type, [#C]); + typeParameters(reflect(new GenericMultipleMixins()).type, + [#A, #B, #C]); + // Anonymous mixin applications have no type parameters or type arguments. + typeParameters(reflect(new NonGenericClass1()).type.superclass, []); + typeParameters(reflect(new NonGenericClass2()).type.superclass, []); + typeParameters(reflect(new GenericClass1()).type.superclass, []); + typeParameters(reflect(new GenericClass2()).type.superclass, []); + + typeArguments(reflect(new NonGenericMixinApplication1()).type, []); + typeArguments(reflect(new NonGenericMixinApplication2()).type, []); + typeArguments( + reflect(new GenericMixinApplication1()).type, [reflectClass(bool)]); + typeArguments( + reflect(new GenericMixinApplication2()).type, [reflectClass(bool)]); + typeArguments(reflect(new NonGenericClass1()).type, []); + typeArguments(reflect(new NonGenericClass2()).type, []); + typeArguments(reflect(new GenericClass1()).type, [reflectClass(bool)]); + typeArguments(reflect(new GenericClass2()).type, [reflectClass(bool)]); + typeArguments(reflect(new GenericMultipleMixins()).type, + [reflectClass(bool), reflectClass(String), reflectClass(int)]); + // Anonymous mixin applications have no type parameters or type arguments. + typeArguments(reflect(new NonGenericClass1()).type.superclass, []); + typeArguments(reflect(new NonGenericClass2()).type.superclass, []); + typeArguments(reflect(new GenericClass1()).type.superclass, []); + typeArguments(reflect(new GenericClass2()).type.superclass, []); +} diff --git a/tests/lib/mirrors/generic_mixin_test.dart b/tests/lib/mirrors/generic_mixin_test.dart new file mode 100644 index 00000000000..480b110337b --- /dev/null +++ b/tests/lib/mirrors/generic_mixin_test.dart @@ -0,0 +1,182 @@ +// Copyright (c) 2013, 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. + +library test.generic_mixin; + +import 'dart:mirrors'; + +import 'package:expect/expect.dart'; + +import 'generics_helper.dart'; + +class Super {} + +class Mixin {} + +class Nixim {} + +class NonGenericMixinApplication1 = Super with Mixin; +class NonGenericMixinApplication2 = Super with Mixin; + +class GenericMixinApplication1 = Super with Mixin; +class GenericMixinApplication2 = Super with Mixin; + +class NonGenericClass1 extends Super with Mixin {} + +class NonGenericClass2 extends Super with Mixin {} + +class GenericClass1 extends Super with Mixin {} + +class GenericClass2 extends Super with Mixin {} + +class GenericMultipleMixins extends Super with Mixin, Nixim {} + +main() { + TypeMirror dynamicMirror = currentMirrorSystem().dynamicType; + + typeParameters(reflectClass(NonGenericMixinApplication1).mixin, [#M]); + typeParameters(reflectClass(NonGenericMixinApplication2).mixin, [#M]); + typeParameters(reflectClass(GenericMixinApplication1).mixin, [#M]); + typeParameters(reflectClass(GenericMixinApplication2).mixin, [#M]); + typeParameters(reflectClass(NonGenericClass1).mixin, []); + typeParameters(reflectClass(NonGenericClass2).mixin, []); + typeParameters(reflectClass(GenericClass1).mixin, [#C]); + typeParameters(reflectClass(GenericClass2).mixin, [#C]); + typeParameters(reflectClass(NonGenericClass1).superclass.mixin, [#M]); + typeParameters(reflectClass(NonGenericClass2).superclass.mixin, [#M]); + typeParameters(reflectClass(GenericClass1).superclass.mixin, [#M]); + typeParameters(reflectClass(GenericClass2).superclass.mixin, [#M]); + typeParameters(reflectClass(GenericMultipleMixins).mixin, [#A, #B, #C]); + typeParameters(reflectClass(GenericMultipleMixins).superclass.mixin, [#N]); + typeParameters( + reflectClass(GenericMultipleMixins).superclass.superclass.mixin, [#M]); + typeParameters( + reflectClass(GenericMultipleMixins) + .superclass + .superclass + .superclass + .mixin, + [#S]); + + typeArguments( + reflectClass(NonGenericMixinApplication1).mixin, [dynamicMirror]); + typeArguments( + reflectClass(NonGenericMixinApplication2).mixin, [reflectClass(String)]); + typeArguments(reflectClass(GenericMixinApplication1).mixin, + [reflectClass(GenericMixinApplication1).typeVariables.single]); + typeArguments( + reflectClass(GenericMixinApplication2).mixin, [reflectClass(String)]); + typeArguments(reflectClass(NonGenericClass1).mixin, []); + typeArguments(reflectClass(NonGenericClass2).mixin, []); + typeArguments(reflectClass(GenericClass1).mixin, []); + typeArguments(reflectClass(GenericClass2).mixin, []); + typeArguments( + reflectClass(NonGenericClass1).superclass.mixin, [dynamicMirror]); + typeArguments( + reflectClass(NonGenericClass2).superclass.mixin, [reflectClass(String)]); + typeArguments(reflectClass(GenericClass1).superclass.mixin, + [reflectClass(GenericClass1).typeVariables.single]); + typeArguments( + reflectClass(GenericClass2).superclass.mixin, [reflectClass(String)]); + typeArguments(reflectClass(GenericMultipleMixins).mixin, []); + typeArguments(reflectClass(GenericMultipleMixins).superclass.mixin, + [reflectClass(GenericMultipleMixins).typeVariables[2]]); + typeArguments(reflectClass(GenericMultipleMixins).superclass.superclass.mixin, + [reflectClass(GenericMultipleMixins).typeVariables[1]]); + typeArguments( + reflectClass(GenericMultipleMixins) + .superclass + .superclass + .superclass + .mixin, + [reflectClass(GenericMultipleMixins).typeVariables[0]]); + + typeParameters(reflect(new NonGenericMixinApplication1()).type.mixin, [#M]); + typeParameters(reflect(new NonGenericMixinApplication2()).type.mixin, [#M]); + typeParameters( + reflect(new GenericMixinApplication1()).type.mixin, [#M]); + typeParameters( + reflect(new GenericMixinApplication2()).type.mixin, [#M]); + typeParameters(reflect(new NonGenericClass1()).type.mixin, []); + typeParameters(reflect(new NonGenericClass2()).type.mixin, []); + typeParameters(reflect(new GenericClass1()).type.mixin, [#C]); + typeParameters(reflect(new GenericClass2()).type.mixin, [#C]); + typeParameters(reflect(new NonGenericClass1()).type.superclass.mixin, [#M]); + typeParameters(reflect(new NonGenericClass2()).type.superclass.mixin, [#M]); + typeParameters( + reflect(new GenericClass1()).type.superclass.mixin, [#M]); + typeParameters( + reflect(new GenericClass2()).type.superclass.mixin, [#M]); + typeParameters( + reflect(new GenericMultipleMixins()).type.mixin, + [#A, #B, #C]); + typeParameters( + reflect(new GenericMultipleMixins()) + .type + .superclass + .mixin, + [#N]); + typeParameters( + reflect(new GenericMultipleMixins()) + .type + .superclass + .superclass + .mixin, + [#M]); + typeParameters( + reflect(new GenericMultipleMixins()) + .type + .superclass + .superclass + .superclass + .mixin, + [#S]); + + typeArguments( + reflect(new NonGenericMixinApplication1()).type.mixin, [dynamicMirror]); + typeArguments(reflect(new NonGenericMixinApplication2()).type.mixin, + [reflectClass(String)]); + typeArguments(reflect(new GenericMixinApplication1()).type.mixin, + [reflectClass(bool)]); + typeArguments(reflect(new GenericMixinApplication2()).type.mixin, + [reflectClass(String)]); + typeArguments(reflect(new NonGenericClass1()).type.mixin, []); + typeArguments(reflect(new NonGenericClass2()).type.mixin, []); + typeArguments( + reflect(new GenericClass1()).type.mixin, [reflectClass(bool)]); + typeArguments( + reflect(new GenericClass2()).type.mixin, [reflectClass(bool)]); + typeArguments( + reflect(new NonGenericClass1()).type.superclass.mixin, [dynamicMirror]); + typeArguments(reflect(new NonGenericClass2()).type.superclass.mixin, + [reflectClass(String)]); + typeArguments(reflect(new GenericClass1()).type.superclass.mixin, + [reflectClass(bool)]); + typeArguments(reflect(new GenericClass2()).type.superclass.mixin, + [reflectClass(String)]); + typeArguments( + reflect(new GenericMultipleMixins()).type.mixin, + [reflectClass(bool), reflectClass(String), reflectClass(int)]); + typeArguments( + reflect(new GenericMultipleMixins()) + .type + .superclass + .mixin, + [reflectClass(int)]); + typeArguments( + reflect(new GenericMultipleMixins()) + .type + .superclass + .superclass + .mixin, + [reflectClass(String)]); + typeArguments( + reflect(new GenericMultipleMixins()) + .type + .superclass + .superclass + .superclass + .mixin, + [reflectClass(bool)]); +} diff --git a/tests/lib/mirrors/generic_superclass_test.dart b/tests/lib/mirrors/generic_superclass_test.dart new file mode 100644 index 00000000000..9c4ea678a43 --- /dev/null +++ b/tests/lib/mirrors/generic_superclass_test.dart @@ -0,0 +1,129 @@ +// Copyright (c) 2013, 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. + +import 'package:expect/expect.dart'; +import 'dart:mirrors'; + +class A {} + +class B extends A {} + +class C extends A {} + +class D extends A {} + +class E extends G> {} + +class F implements A {} + +class FF implements G> {} + +class G {} + +class H {} + +class U {} + +class R {} + +void testOriginals() { + ClassMirror a = reflectClass(A); + ClassMirror b = reflectClass(B); + ClassMirror c = reflectClass(C); + ClassMirror d = reflectClass(D); + ClassMirror e = reflectClass(E); + ClassMirror f = reflectClass(F); + ClassMirror ff = reflectClass(FF); + ClassMirror superA = a.superclass; + ClassMirror superB = b.superclass; + ClassMirror superC = c.superclass; + ClassMirror superD = d.superclass; + ClassMirror superE = e.superclass; + ClassMirror superInterfaceF = f.superinterfaces[0]; + ClassMirror superInterfaceFF = ff.superinterfaces[0]; + + TypeVariableMirror aT = a.typeVariables[0]; + TypeVariableMirror dT = d.typeVariables[0]; + TypeVariableMirror eX = e.typeVariables[0]; + TypeVariableMirror eY = e.typeVariables[1]; + TypeVariableMirror fX = f.typeVariables[0]; + TypeVariableMirror feX = ff.typeVariables[0]; + TypeVariableMirror feY = ff.typeVariables[1]; + + Expect.isTrue(superA.isOriginalDeclaration); + Expect.isFalse(superB.isOriginalDeclaration); + Expect.isFalse(superC.isOriginalDeclaration); + Expect.isFalse(superD.isOriginalDeclaration); + Expect.isFalse(superE.isOriginalDeclaration); + Expect.isFalse(superInterfaceF.isOriginalDeclaration); + Expect.isFalse(superInterfaceFF.isOriginalDeclaration); + + Expect.equals(reflectClass(Object), superA); + Expect.equals(reflect(new A()).type, superB); + Expect.equals(reflect(new A()).type, superC); //# 01: ok + Expect.equals(reflect(new U()).type, superB.typeArguments[0]); + Expect.equals(reflect(new C()).type, superC.typeArguments[0]); //# 01: ok + Expect.equals(dT, superD.typeArguments[0]); + Expect.equals(eY, superE.typeArguments[0].typeArguments[0]); + Expect.equals(feY, superInterfaceFF.typeArguments[0].typeArguments[0]); + Expect.equals(fX, superInterfaceF.typeArguments[0]); +} + +void testInstances() { + ClassMirror a = reflect(new A()).type; + ClassMirror b = reflect(new B()).type; + ClassMirror c = reflect(new C()).type; + ClassMirror d = reflect(new D()).type; + ClassMirror e = reflect(new E()).type; + ClassMirror e0 = reflect(new E>()).type; + ClassMirror ff = reflect(new FF()).type; + ClassMirror f = reflect(new F()).type; + ClassMirror u = reflect(new U()).type; + ClassMirror r = reflect(new R()).type; + ClassMirror hr = reflect(new H()).type; + + ClassMirror superA = a.superclass; + ClassMirror superB = b.superclass; + ClassMirror superC = c.superclass; + ClassMirror superD = d.superclass; + ClassMirror superE = e.superclass; + ClassMirror superE0 = e0.superclass; + ClassMirror superInterfaceF = f.superinterfaces[0]; + ClassMirror superInterfaceFF = ff.superinterfaces[0]; + + Expect.isTrue(superA.isOriginalDeclaration); + Expect.isFalse(superB.isOriginalDeclaration); + Expect.isFalse(superC.isOriginalDeclaration); + Expect.isFalse(superD.isOriginalDeclaration); + Expect.isFalse(superE.isOriginalDeclaration); + Expect.isFalse(superE0.isOriginalDeclaration); + Expect.isFalse(superInterfaceF.isOriginalDeclaration); + Expect.isFalse(superInterfaceFF.isOriginalDeclaration); + + Expect.equals(reflectClass(Object), superA); + Expect.equals(reflect(new A()).type, superB); + Expect.equals(reflect(new A()).type, superC); //# 01: ok + Expect.equals(reflect(new A()).type, superD); + Expect.equals(reflect(new G>()).type, superE); + Expect.equals(reflect(new G>>()).type, superE0); + Expect.equals(reflect(new G>()).type, superInterfaceFF); + Expect.equals(u, superB.typeArguments[0]); + Expect.equals(reflect(new C()).type, superC.typeArguments[0]); //# 01: ok + Expect.equals(u, superD.typeArguments[0]); + Expect.equals(r, superE.typeArguments[0].typeArguments[0]); + Expect.equals(hr, superE0.typeArguments[0].typeArguments[0]); + Expect.equals(r, superInterfaceFF.typeArguments[0].typeArguments[0]); + Expect.equals(u, superInterfaceF.typeArguments[0]); +} + +void testObject() { + ClassMirror object = reflectClass(Object); + Expect.equals(null, object.superclass); +} + +main() { + testOriginals(); + testInstances(); + testObject(); +} diff --git a/tests/lib/mirrors/generic_type_mirror_test.dart b/tests/lib/mirrors/generic_type_mirror_test.dart new file mode 100644 index 00000000000..97603d5afcd --- /dev/null +++ b/tests/lib/mirrors/generic_type_mirror_test.dart @@ -0,0 +1,92 @@ +// Copyright (c) 2013, 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. + +import "dart:mirrors"; +import "package:expect/expect.dart"; + +class Foo { + V field; + V get bar => field; + set bar(V v) {} + W m() {} + V n() {} + H p() {} + o(W w) {} +} + +class H {} + +class Bar {} + +class Baz {} + +void testInstance() { + ClassMirror foo = reflect((new Foo())).type; + ClassMirror bar = reflect(new Bar()).type; + ClassMirror baz = reflect(new Baz()).type; + ClassMirror hOfBaz = reflect(new H()).type; + VariableMirror field = foo.declarations[#field] as VariableMirror; + MethodMirror getter = foo.declarations[#bar] as MethodMirror; + MethodMirror setter = foo.declarations[const Symbol('bar=')] as MethodMirror; + MethodMirror m = foo.declarations[#m] as MethodMirror; + MethodMirror n = foo.declarations[#n] as MethodMirror; + MethodMirror o = foo.declarations[#o] as MethodMirror; + MethodMirror p = foo.declarations[#p] as MethodMirror; + + Expect.equals(foo, field.owner); + Expect.equals(foo, getter.owner); + Expect.equals(foo, setter.owner); + Expect.equals(foo, m.owner); + Expect.equals(foo, n.owner); + Expect.equals(foo, o.owner); + Expect.equals(foo, p.owner); + + Expect.equals(baz, field.type); + Expect.equals(baz, getter.returnType); + Expect.equals(bar, m.returnType); + Expect.equals(baz, n.returnType); + Expect.equals(bar, o.parameters.single.type); + Expect.equals(hOfBaz, p.returnType); + Expect.equals(1, p.returnType.typeArguments.length); + Expect.equals(baz, p.returnType.typeArguments[0]); + + Expect.equals(baz, setter.parameters.single.type); +} + +void testOriginalDeclaration() { + ClassMirror foo = reflectClass(Foo); + + VariableMirror field = foo.declarations[#field] as VariableMirror; + MethodMirror getter = foo.declarations[#bar] as MethodMirror; + MethodMirror setter = foo.declarations[const Symbol('bar=')] as MethodMirror; + MethodMirror m = foo.declarations[#m] as MethodMirror; + MethodMirror n = foo.declarations[#n] as MethodMirror; + MethodMirror o = foo.declarations[#o] as MethodMirror; + MethodMirror p = foo.declarations[#p] as MethodMirror; + TypeVariableMirror w = foo.typeVariables[0] as TypeVariableMirror; + TypeVariableMirror v = foo.typeVariables[1] as TypeVariableMirror; + + Expect.equals(foo, field.owner); + Expect.equals(foo, getter.owner); + Expect.equals(foo, setter.owner); + Expect.equals(foo, m.owner); + Expect.equals(foo, n.owner); + Expect.equals(foo, o.owner); + Expect.equals(foo, p.owner); + + Expect.equals(v, field.type); + Expect.equals(v, getter.returnType); + Expect.equals(w, m.returnType); + Expect.equals(v, n.returnType); + Expect.equals(w, o.parameters.single.type); + Expect.equals(1, p.returnType.typeArguments.length); + Expect.equals(v, p.returnType.typeArguments[0]); + + Expect.equals(v, setter.parameters.single.type); +} + +main() { + testInstance(); + testOriginalDeclaration(); +} diff --git a/tests/lib/mirrors/generics_double_substitution_test.dart b/tests/lib/mirrors/generics_double_substitution_test.dart new file mode 100644 index 00000000000..a44fb3a7fd7 --- /dev/null +++ b/tests/lib/mirrors/generics_double_substitution_test.dart @@ -0,0 +1,36 @@ +// Copyright (c) 2013, 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. + +library test.generics_double_substitution; + +import 'dart:mirrors'; + +import 'package:expect/expect.dart'; + +class A {} + +class B {} + +class C extends B> { + A field; + A returnType() => new A(); + parameterType(A param) {} +} + +main() { + ClassMirror cOfString = reflect(new C()).type; + ClassMirror aOfString = reflect(new A()).type; + + VariableMirror field = cOfString.declarations[#field] as VariableMirror; + Expect.equals(aOfString, field.type); + + MethodMirror returnType = cOfString.declarations[#returnType] as MethodMirror; + Expect.equals(aOfString, returnType.returnType); + + MethodMirror parameterType = cOfString.declarations[#parameterType] as MethodMirror; + Expect.equals(aOfString, parameterType.parameters.single.type); + + ClassMirror typeArgOfSuperclass = cOfString.superclass.typeArguments.single as ClassMirror; + Expect.equals(aOfString, typeArgOfSuperclass); //# 01: ok +} diff --git a/tests/lib/mirrors/generics_dynamic_test.dart b/tests/lib/mirrors/generics_dynamic_test.dart new file mode 100644 index 00000000000..40c82d60c39 --- /dev/null +++ b/tests/lib/mirrors/generics_dynamic_test.dart @@ -0,0 +1,69 @@ +// Copyright (c) 2013, 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. + +import 'dart:mirrors'; +import 'package:expect/expect.dart'; + +class A {} + +class B extends A implements C { + A m(A a) {} + A field; +} + +class C {} + +class D extends A {} + +main() { + ClassMirror aDecl = reflectClass(A); + ClassMirror bDecl = reflectClass(B); + ClassMirror cDecl = reflectClass(C); + TypeMirror aInstance = reflect(new A()).type; + TypeMirror aInstanceDynamic = reflect(new A()).type; + TypeMirror dInstance = reflect(new D()).type; + TypeMirror cInstance = reflect(new C()).type; + TypeMirror cNestedInstance = reflect(new C()).type; + TypeMirror cTypeArgument = cNestedInstance.typeArguments.first; + TypeMirror superA = bDecl.superclass; + TypeMirror superC = bDecl.superinterfaces.single; + MethodMirror m = bDecl.declarations[#m] as MethodMirror; + VariableMirror field = bDecl.declarations[#field] as VariableMirror; + TypeMirror returnTypeA = m.returnType; + TypeMirror parameterTypeA = m.parameters.first.type; + TypeMirror fieldTypeA = field.type; + TypeMirror upperBoundA = bDecl.typeVariables.single.upperBound; + TypeMirror dynamicMirror = currentMirrorSystem().dynamicType; + + Expect.isTrue(aDecl.isOriginalDeclaration); + Expect.isTrue(reflect(dInstance).type.isOriginalDeclaration); + Expect.isFalse(aInstance.isOriginalDeclaration); + Expect.isFalse(aInstanceDynamic.isOriginalDeclaration); + Expect.isFalse(superA.isOriginalDeclaration); + Expect.isFalse(superC.isOriginalDeclaration); + Expect.isFalse(returnTypeA.isOriginalDeclaration); + Expect.isFalse(parameterTypeA.isOriginalDeclaration); + Expect.isFalse(fieldTypeA.isOriginalDeclaration); + Expect.isFalse(upperBoundA.isOriginalDeclaration); + Expect.isFalse(cInstance.isOriginalDeclaration); + Expect.isFalse(cNestedInstance.isOriginalDeclaration); + Expect.isFalse(cTypeArgument.isOriginalDeclaration); + + Expect.isTrue(aDecl.typeArguments.isEmpty); + Expect.isTrue(dInstance.typeArguments.isEmpty); + Expect.equals(dynamicMirror, aInstance.typeArguments.single); + Expect.equals(dynamicMirror, aInstanceDynamic.typeArguments.single); + Expect.equals(dynamicMirror, superA.typeArguments.single); + Expect.equals(dynamicMirror, superC.typeArguments.first); + Expect.equals(dynamicMirror, superC.typeArguments.last); + Expect.equals(dynamicMirror, returnTypeA.typeArguments.single); + Expect.equals(dynamicMirror, parameterTypeA.typeArguments.single); + Expect.equals(dynamicMirror, fieldTypeA.typeArguments.single); + Expect.equals(dynamicMirror, upperBoundA.typeArguments.single); + Expect.equals(dynamicMirror, cInstance.typeArguments.first); + Expect.equals(dynamicMirror, cInstance.typeArguments.last); + Expect.equals(dynamicMirror, cNestedInstance.typeArguments.last); + Expect.equals(dynamicMirror, cTypeArgument.typeArguments.first); + Expect.equals(dynamicMirror, cTypeArgument.typeArguments.last); +} diff --git a/tests/lib/mirrors/generics_helper.dart b/tests/lib/mirrors/generics_helper.dart new file mode 100644 index 00000000000..da10962e44d --- /dev/null +++ b/tests/lib/mirrors/generics_helper.dart @@ -0,0 +1,16 @@ +// Copyright (c) 2013, 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. + +library generics_helper; + +import 'package:expect/expect.dart'; + +typeParameters(mirror, parameterNames) { + Expect.listEquals( + parameterNames, mirror.typeVariables.map((v) => v.simpleName).toList()); +} + +typeArguments(mirror, argumentMirrors) { + Expect.listEquals(argumentMirrors, mirror.typeArguments); +} diff --git a/tests/lib/mirrors/generics_special_types_test.dart b/tests/lib/mirrors/generics_special_types_test.dart new file mode 100644 index 00000000000..49f72ecee05 --- /dev/null +++ b/tests/lib/mirrors/generics_special_types_test.dart @@ -0,0 +1,29 @@ +// Copyright (c) 2013, 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. + +library test.generics_special_types; + +import 'dart:mirrors'; +import 'package:expect/expect.dart'; + +main() { + TypeMirror dynamicMirror = currentMirrorSystem().dynamicType; + Expect.isTrue(dynamicMirror.isOriginalDeclaration); + Expect.equals(dynamicMirror, dynamicMirror.originalDeclaration); + Expect.listEquals([], dynamicMirror.typeVariables); + Expect.listEquals([], dynamicMirror.typeArguments); + + TypeMirror voidMirror = currentMirrorSystem().voidType; + Expect.isTrue(voidMirror.isOriginalDeclaration); + Expect.equals(voidMirror, voidMirror.originalDeclaration); + Expect.listEquals([], voidMirror.typeVariables); + Expect.listEquals([], voidMirror.typeArguments); + + TypeMirror dynamicMirror2 = reflectType(dynamic); + Expect.equals(dynamicMirror, dynamicMirror2); + Expect.isTrue(dynamicMirror2.isOriginalDeclaration); + Expect.equals(dynamicMirror2, dynamicMirror2.originalDeclaration); + Expect.listEquals([], dynamicMirror2.typeVariables); + Expect.listEquals([], dynamicMirror2.typeArguments); +} diff --git a/tests/lib/mirrors/generics_substitution_test.dart b/tests/lib/mirrors/generics_substitution_test.dart new file mode 100644 index 00000000000..b078c1a031f --- /dev/null +++ b/tests/lib/mirrors/generics_substitution_test.dart @@ -0,0 +1,55 @@ +// Copyright (c) 2013, 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. + +library test.generics_substitution; + +import 'dart:mirrors'; +import 'package:expect/expect.dart'; + +class SuperGeneric { + R r; + s(S s) {} +} + +class Generic extends SuperGeneric { + T t() => throw "does-not-return"; // +} + +main() { + ClassMirror genericDecl = reflectClass(Generic); + ClassMirror genericOfString = reflect(new Generic()).type; + ClassMirror superGenericDecl = reflectClass(SuperGeneric); + ClassMirror superOfTAndInt = genericDecl.superclass; + ClassMirror superOfStringAndInt = genericOfString.superclass; + + Expect.isTrue(genericDecl.isOriginalDeclaration); + Expect.isFalse(genericOfString.isOriginalDeclaration); + Expect.isTrue(superGenericDecl.isOriginalDeclaration); + Expect.isFalse(superOfTAndInt.isOriginalDeclaration); + Expect.isFalse(superOfStringAndInt.isOriginalDeclaration); + + Symbol r(ClassMirror cm) => + (cm.declarations[#r] as VariableMirror).type.simpleName; + Symbol s(ClassMirror cm) => + (cm.declarations[#s] as MethodMirror).parameters[0].type.simpleName; + Symbol t(ClassMirror cm) => + (cm.declarations[#t] as MethodMirror).returnType.simpleName; + + Expect.equals(#T, r(genericDecl.superclass)); + Expect.equals(#int, s(genericDecl.superclass)); + Expect.equals(#T, t(genericDecl)); + + Expect.equals(#String, r(genericOfString.superclass)); + Expect.equals(#int, s(genericOfString.superclass)); + Expect.equals(#String, t(genericOfString)); + + Expect.equals(#R, r(superGenericDecl)); + Expect.equals(#S, s(superGenericDecl)); + + Expect.equals(#T, r(superOfTAndInt)); + Expect.equals(#int, s(superOfTAndInt)); + + Expect.equals(#String, r(superOfStringAndInt)); + Expect.equals(#int, s(superOfStringAndInt)); +} diff --git a/tests/lib/mirrors/generics_test.dart b/tests/lib/mirrors/generics_test.dart new file mode 100644 index 00000000000..fface13201c --- /dev/null +++ b/tests/lib/mirrors/generics_test.dart @@ -0,0 +1,165 @@ +// Copyright (c) 2013, 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. + +library test.type_arguments_test; + +import 'dart:mirrors'; + +import 'package:expect/expect.dart'; +import 'generics_helper.dart'; + +class A {} + +class Z {} + +class B extends A {} + +class C + extends A //# 01: compile-time error +{} + +class D extends A {} + +class E extends A {} + +class F extends A {} + +class G {} + +class H {} + +class I extends G {} + +main() { + // Declarations. + typeParameters(reflectClass(A), [#T]); + typeParameters(reflectClass(G), []); + typeParameters(reflectClass(B), []); + typeParameters(reflectClass(C), []); + typeParameters(reflectClass(D), []); + typeParameters(reflectClass(E), [#S]); + typeParameters(reflectClass(F), [#R]); + typeParameters(reflectClass(G), []); + typeParameters(reflectClass(H), [#A, #B, #C]); + typeParameters(reflectClass(I), []); + + typeArguments(reflectClass(A), []); + typeArguments(reflectClass(B), []); + typeArguments(reflectClass(C), []); + typeArguments(reflectClass(D), []); + typeArguments(reflectClass(E), []); + typeArguments(reflectClass(F), []); + typeArguments(reflectClass(G), []); + typeArguments(reflectClass(H), []); + typeArguments(reflectClass(I), []); + + Expect.isTrue(reflectClass(A).isOriginalDeclaration); + Expect.isTrue(reflectClass(B).isOriginalDeclaration); + Expect.isTrue(reflectClass(C).isOriginalDeclaration); + Expect.isTrue(reflectClass(D).isOriginalDeclaration); + Expect.isTrue(reflectClass(E).isOriginalDeclaration); + Expect.isTrue(reflectClass(F).isOriginalDeclaration); + Expect.isTrue(reflectClass(G).isOriginalDeclaration); + Expect.isTrue(reflectClass(H).isOriginalDeclaration); + Expect.isTrue(reflectClass(I).isOriginalDeclaration); + + Expect.equals(reflectClass(A), reflectClass(A).originalDeclaration); + Expect.equals(reflectClass(B), reflectClass(B).originalDeclaration); + Expect.equals(reflectClass(C), reflectClass(C).originalDeclaration); + Expect.equals(reflectClass(D), reflectClass(D).originalDeclaration); + Expect.equals(reflectClass(E), reflectClass(E).originalDeclaration); + Expect.equals(reflectClass(F), reflectClass(F).originalDeclaration); + Expect.equals(reflectClass(G), reflectClass(G).originalDeclaration); + Expect.equals(reflectClass(H), reflectClass(H).originalDeclaration); + Expect.equals(reflectClass(I), reflectClass(I).originalDeclaration); + + // Instantiations. + typeParameters(reflect(new A()).type, [#T]); + typeParameters(reflect(new B()).type, []); + typeParameters(reflect(new C()).type, []); + typeParameters(reflect(new D()).type, []); + typeParameters(reflect(new E()).type, [#S]); + typeParameters(reflect(new F()).type, [#R]); + typeParameters(reflect(new G()).type, []); + typeParameters(reflect(new H()).type, [#A, #B, #C]); + typeParameters(reflect(new I()).type, []); + + var numMirror = reflectClass(num); + var dynamicMirror = currentMirrorSystem().dynamicType; + typeArguments(reflect(new A()).type, [numMirror]); + typeArguments(reflect(new A()).type, [dynamicMirror]); + typeArguments(reflect(new A()).type, [dynamicMirror]); + typeArguments(reflect(new B()).type, []); + typeArguments(reflect(new C()).type, []); + typeArguments(reflect(new D()).type, []); + typeArguments(reflect(new E()).type, [numMirror]); + typeArguments(reflect(new E()).type, [dynamicMirror]); + typeArguments(reflect(new E()).type, [dynamicMirror]); + typeArguments(reflect(new F()).type, [numMirror]); + typeArguments(reflect(new F()).type, [dynamicMirror]); + typeArguments(reflect(new F()).type, [dynamicMirror]); + typeArguments(reflect(new G()).type, []); + typeArguments(reflect(new H()).type, + [dynamicMirror, numMirror, dynamicMirror]); + typeArguments(reflect(new I()).type, []); + + Expect.isFalse(reflect(new A()).type.isOriginalDeclaration); + Expect.isTrue(reflect(new B()).type.isOriginalDeclaration); + Expect.isTrue(reflect(new C()).type.isOriginalDeclaration); + Expect.isTrue(reflect(new D()).type.isOriginalDeclaration); + Expect.isFalse(reflect(new E()).type.isOriginalDeclaration); + Expect.isFalse(reflect(new F()).type.isOriginalDeclaration); + Expect.isTrue(reflect(new G()).type.isOriginalDeclaration); + Expect.isFalse(reflect(new H()).type.isOriginalDeclaration); + Expect.isTrue(reflect(new I()).type.isOriginalDeclaration); + + Expect.equals( + reflectClass(A), reflect(new A()).type.originalDeclaration); + Expect.equals(reflectClass(B), reflect(new B()).type.originalDeclaration); + Expect.equals(reflectClass(C), reflect(new C()).type.originalDeclaration); + Expect.equals(reflectClass(D), reflect(new D()).type.originalDeclaration); + Expect.equals( + reflectClass(E), reflect(new E()).type.originalDeclaration); + Expect.equals( + reflectClass(F), reflect(new F()).type.originalDeclaration); + Expect.equals(reflectClass(G), reflect(new G()).type.originalDeclaration); + Expect.equals(reflectClass(H), reflect(new H()).type.originalDeclaration); + Expect.equals(reflectClass(I), reflect(new I()).type.originalDeclaration); + + Expect.notEquals(reflect(new A()).type, + reflect(new A()).type.originalDeclaration); + Expect.equals( + reflect(new B()).type, reflect(new B()).type.originalDeclaration); + Expect.equals( + reflect(new C()).type, reflect(new C()).type.originalDeclaration); + Expect.equals( + reflect(new D()).type, reflect(new D()).type.originalDeclaration); + Expect.notEquals(reflect(new E()).type, + reflect(new E()).type.originalDeclaration); + Expect.notEquals(reflect(new F()).type, + reflect(new F()).type.originalDeclaration); + Expect.equals( + reflect(new G()).type, reflect(new G()).type.originalDeclaration); + Expect.notEquals( + reflect(new H()).type, reflect(new H()).type.originalDeclaration); + Expect.equals( + reflect(new I()).type, reflect(new I()).type.originalDeclaration); + + // Library members are all uninstantiated generics or non-generics. + currentMirrorSystem().libraries.values.forEach((libraryMirror) { + libraryMirror.declarations.values.forEach((declaration) { + if (declaration is ClassMirror) { + Expect.isTrue(declaration.isOriginalDeclaration); + Expect.equals(declaration, declaration.originalDeclaration); + } + }); + }); + + Expect.equals(reflectClass(A).typeVariables[0].owner, reflectClass(A)); + Expect.equals(reflectClass(Z).typeVariables[0].owner, reflectClass(Z)); + Expect.notEquals( + reflectClass(A).typeVariables[0], reflectClass(Z).typeVariables[0]); + Expect.equals( + reflectClass(A).typeVariables[0], reflectClass(A).typeVariables[0]); +} diff --git a/tests/lib/mirrors/get_field_cache_test.dart b/tests/lib/mirrors/get_field_cache_test.dart new file mode 100644 index 00000000000..60c57f5d56a --- /dev/null +++ b/tests/lib/mirrors/get_field_cache_test.dart @@ -0,0 +1,35 @@ +// Copyright (c) 2014, 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. + +import 'dart:mirrors'; + +import 'package:expect/expect.dart'; + +class A { + toString() => "A"; +} + +class B { + int x = 99; + toString() => "B"; +} + +void main() { + var a = new A(); + var am = reflect(a); + for (int i = 0; i < 10; i++) { + // Adds a probe function on the symbol. + am.getField(#toString); + } + var b = new B(); + var bm = reflect(b); + for (int i = 0; i < 10; i++) { + // Adds a field-cache on the mirror. + bm.getField(#x); + } + // There is a cache now, but the cache should not contain 'toString' from + // JavaScript's Object.prototype. + var toString = bm.getField(#toString).reflectee; + Expect.equals("B", toString()); +} diff --git a/tests/lib/mirrors/get_field_static_test.dart b/tests/lib/mirrors/get_field_static_test.dart new file mode 100644 index 00000000000..60edc9209f3 --- /dev/null +++ b/tests/lib/mirrors/get_field_static_test.dart @@ -0,0 +1,30 @@ +// Copyright (c) 2014, 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. + +import 'dart:mirrors'; + +import 'package:expect/expect.dart'; + +class A { + static foo(y, [x]) => y; + static get bar => 499; + static operator$foo([optional = 499]) => optional; + static var x = 42; + static final y = "toto"; + static const z = true; +} + +main() { + var cm = reflectClass(A); + var closure = cm.getField(#foo).reflectee; + Expect.equals("b", closure("b")); + + closure = cm.getField(#operator$foo).reflectee; + Expect.equals(499, closure()); + + Expect.equals(499, cm.getField(#bar).reflectee); + Expect.equals(42, cm.getField(#x).reflectee); + Expect.equals("toto", cm.getField(#y).reflectee); // //# 00: ok + Expect.equals(true, cm.getField(#z).reflectee); // //# 00: ok +} diff --git a/tests/lib/mirrors/get_field_test.dart b/tests/lib/mirrors/get_field_test.dart new file mode 100644 index 00000000000..d2a2d1c8fe3 --- /dev/null +++ b/tests/lib/mirrors/get_field_test.dart @@ -0,0 +1,24 @@ +// Copyright (c) 2013, 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. + +import 'dart:mirrors'; + +import 'package:expect/expect.dart'; + +class A { + foo(y, [x]) => y; + operator +(other) => null; + get bar => 499; + operator$foo([optional = 499]) => optional; +} + +main() { + // We are using `getField` to tear off `foo`. We must make sure that all + // stub methods are installed. + var closure = reflect(new A()).getField(#foo).reflectee; + Expect.equals("b", closure("b")); + + closure = reflect(new A()).getField(#operator$foo).reflectee; + Expect.equals(499, closure()); +} diff --git a/tests/lib/mirrors/get_symbol_name_no_such_method_test.dart b/tests/lib/mirrors/get_symbol_name_no_such_method_test.dart new file mode 100644 index 00000000000..854dc589c9f --- /dev/null +++ b/tests/lib/mirrors/get_symbol_name_no_such_method_test.dart @@ -0,0 +1,35 @@ +// Copyright (c) 2013, 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 MirrorSystem.getName works correctly on symbols returned from +/// Invocation.memberName. This is especially relevant when minifying. + +import 'dart:mirrors' show MirrorSystem; + +class Foo { + String noSuchMethod(Invocation invocation) { + return MirrorSystem.getName(invocation.memberName); + } +} + +expect(expected, actual) { + if (expected != actual) { + throw 'Expected: "$expected", but got "$actual"'; + } +} + +main() { + dynamic foo = new Foo(); + expect('foo', foo.foo); + expect('foo', foo.foo()); + expect('foo', foo.foo(null)); + expect('foo', foo.foo(null, null)); + expect('foo', foo.foo(a: null, b: null)); + + expect('baz', foo.baz); + expect('baz', foo.baz()); + expect('baz', foo.baz(null)); + expect('baz', foo.baz(null, null)); + expect('baz', foo.baz(a: null, b: null)); +} diff --git a/tests/lib/mirrors/get_symbol_name_test.dart b/tests/lib/mirrors/get_symbol_name_test.dart new file mode 100644 index 00000000000..68b3cb176a7 --- /dev/null +++ b/tests/lib/mirrors/get_symbol_name_test.dart @@ -0,0 +1,16 @@ +// Copyright (c) 2013, 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. + +import 'dart:mirrors' show MirrorSystem; + +expect(expected, actual) { + if (expected != actual) { + throw 'Expected: "$expected", but got "$actual"'; + } +} + +main() { + expect('fisk', MirrorSystem.getName(const Symbol('fisk'))); + expect('fisk', MirrorSystem.getName(new Symbol('fisk'))); +} diff --git a/tests/lib/mirrors/globalized_closures2_test.dart b/tests/lib/mirrors/globalized_closures2_test.dart new file mode 100644 index 00000000000..d4927c997c4 --- /dev/null +++ b/tests/lib/mirrors/globalized_closures2_test.dart @@ -0,0 +1,37 @@ +// Copyright (c) 2014, 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. + +// Dart2js crashed on this example. It globalized both closures and created +// top-level classes for closures (here the globalized_closure{2}). There was a +// name-clash (both being named "main_closure") which led to a crash. + +library main; + +import 'dart:mirrors'; + +import 'package:expect/expect.dart'; + +confuse(x) { + if (new DateTime.now().millisecondsSinceEpoch == 42) { + return confuse(() => print(42)); + } + return x; +} + +main() { + var globalized_closure = confuse(() => 499); + var globalized_closure2 = confuse(() => 99); + globalized_closure(); + globalized_closure2(); + final ms = currentMirrorSystem(); + var lib = ms.findLibrary(#main); + var collectedParents = []; + var classes = lib.declarations.values; + for (var c in classes) { + if (c is ClassMirror && c.superclass != null) { + collectedParents.add(MirrorSystem.getName(c.superclass.simpleName)); + } + } + Expect.isTrue(collectedParents.isEmpty); // //# 00: ok +} diff --git a/tests/lib/mirrors/globalized_closures_test.dart b/tests/lib/mirrors/globalized_closures_test.dart new file mode 100644 index 00000000000..93b0bf0d1af --- /dev/null +++ b/tests/lib/mirrors/globalized_closures_test.dart @@ -0,0 +1,36 @@ +// Copyright (c) 2014, 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. + +// Dart2js crashed on this example. It globalized closures and created +// top-level classes for closures (here the globalized_closure). There was a +// name-clash with the global "main_closure" class which led to a crash. + +library main; + +import 'dart:mirrors'; + +import 'package:expect/expect.dart'; + +class main_closure {} + +confuse(x) { + if (new DateTime.now().millisecondsSinceEpoch == 42) return confuse(() => 42); + return x; +} + +main() { + new main_closure(); + var globalized_closure = confuse(() => 499); + globalized_closure(); + final ms = currentMirrorSystem(); + var lib = ms.findLibrary(#main); + var collectedParents = []; + var classes = lib.declarations.values; + for (var c in classes) { + if (c is ClassMirror && c.superclass != null) { + collectedParents.add(MirrorSystem.getName(c.superclass.simpleName)); + } + } + Expect.listEquals(["Object"], collectedParents); // //# 00: ok +} diff --git a/tests/lib/mirrors/hierarchy_invariants_test.dart b/tests/lib/mirrors/hierarchy_invariants_test.dart new file mode 100644 index 00000000000..2ff3dc846c0 --- /dev/null +++ b/tests/lib/mirrors/hierarchy_invariants_test.dart @@ -0,0 +1,42 @@ +// Copyright (c) 2013, 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. + +library test.hierarchy_invariants_test; + +import 'dart:mirrors'; + +import 'package:expect/expect.dart'; + +isAnonymousMixinApplication(classMirror) { + return MirrorSystem.getName(classMirror.simpleName).contains(' with '); +} + +checkClass(classMirror) { + Expect.isTrue(classMirror.simpleName is Symbol); + Expect.notEquals(null, classMirror.owner); + Expect.isTrue(classMirror.owner is LibraryMirror); + if (!isAnonymousMixinApplication(classMirror)) { + Expect.equals(classMirror.originalDeclaration, + classMirror.owner.declarations[classMirror.simpleName]); + } else { + Expect.isNull(classMirror.owner.declarations[classMirror.simpleName]); + } + Expect.isTrue(classMirror.superinterfaces is List); + if (classMirror.superclass == null) { + Expect.isTrue((reflectClass(Object) == classMirror) || + (classMirror.toString() == "ClassMirror on 'FutureOr'")); + } else { + checkClass(classMirror.superclass); + } +} + +checkLibrary(libraryMirror) { + libraryMirror.declarations.values + .where((d) => d is ClassMirror) + .forEach(checkClass); +} + +main() { + currentMirrorSystem().libraries.values.forEach(checkLibrary); +} diff --git a/tests/lib/mirrors/hot_get_field_test.dart b/tests/lib/mirrors/hot_get_field_test.dart new file mode 100644 index 00000000000..65cf2818ac4 --- /dev/null +++ b/tests/lib/mirrors/hot_get_field_test.dart @@ -0,0 +1,67 @@ +// Copyright (c) 2014, 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. + +library test.hot_get_field; + +import 'dart:mirrors'; +import 'package:expect/expect.dart'; + +class C { + var field; + var _field; + operator +(other) => field + other; +} + +const int optimizationThreshold = 20; + +testPublic() { + var c = new C(); + var im = reflect(c); + + for (int i = 0; i < (2 * optimizationThreshold); i++) { + c.field = i; + Expect.equals(i, im.getField(#field).reflectee); + } +} + +testPrivate() { + var c = new C(); + var im = reflect(c); + + for (int i = 0; i < (2 * optimizationThreshold); i++) { + c._field = i; + Expect.equals(i, im.getField(#_field).reflectee); + } +} + +testPrivateWrongLibrary() { + var c = new C(); + var im = reflect(c); + var selector = MirrorSystem.getSymbol( + '_field', reflectClass(Mirror).owner as LibraryMirror); + + for (int i = 0; i < (2 * optimizationThreshold); i++) { + Expect.throwsNoSuchMethodError(() => im.getField(selector)); + } +} + +testOperator() { + var plus = const Symbol("+"); + var c = new C(); + var im = reflect(c); + + for (int i = 0; i < (2 * optimizationThreshold); i++) { + c.field = i; + var closurizedPlus = im.getField(plus).reflectee; + Expect.isTrue(closurizedPlus is Function); + Expect.equals(2 * i, closurizedPlus(i)); + } +} + +main() { + testPublic(); + testPrivate(); + testPrivateWrongLibrary(); + testOperator(); +} diff --git a/tests/lib/mirrors/hot_set_field_test.dart b/tests/lib/mirrors/hot_set_field_test.dart new file mode 100644 index 00000000000..cd084d30722 --- /dev/null +++ b/tests/lib/mirrors/hot_set_field_test.dart @@ -0,0 +1,52 @@ +// Copyright (c) 2014, 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. + +library test.hot_set_field; + +import 'dart:mirrors'; +import 'package:expect/expect.dart'; + +class C { + var field; + var _field; +} + +const int optimizationThreshold = 20; + +testPublic() { + var c = new C(); + var im = reflect(c); + + for (int i = 0; i < (2 * optimizationThreshold); i++) { + im.setField(#field, i); + Expect.equals(i, c.field); + } +} + +testPrivate() { + var c = new C(); + var im = reflect(c); + + for (int i = 0; i < (2 * optimizationThreshold); i++) { + im.setField(#_field, i); + Expect.equals(i, c._field); + } +} + +testPrivateWrongLibrary() { + var c = new C(); + var im = reflect(c); + var selector = MirrorSystem.getSymbol( + '_field', reflectClass(Mirror).owner as LibraryMirror); + + for (int i = 0; i < (2 * optimizationThreshold); i++) { + Expect.throwsNoSuchMethodError(() => im.setField(selector, i)); + } +} + +main() { + testPublic(); + testPrivate(); + testPrivateWrongLibrary(); +} diff --git a/tests/lib/mirrors/immutable_collections_test.dart b/tests/lib/mirrors/immutable_collections_test.dart new file mode 100644 index 00000000000..ed2f3af1b6a --- /dev/null +++ b/tests/lib/mirrors/immutable_collections_test.dart @@ -0,0 +1,81 @@ +// Copyright (c) 2013, 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. + +library test.immutable_collections; + +import 'dart:mirrors'; +import 'package:expect/expect.dart'; + +bool someException(e) => e is Exception || e is Error; + +checkList(dynamic l, String reason) { + Expect.throws(() => l[0] = 'value', someException, reason); + Expect.throws(() => l.add('value'), someException, reason); + Expect.throws(() => l.clear(), someException, reason); +} + +checkMap(Map m, String reason) { + Expect.throws(() => m[#key] = 'value', someException, reason); + checkList(m.keys, '$reason keys'); + checkList(m.values, '$reason values'); +} + +checkVariable(VariableMirror vm) { + checkList(vm.metadata, 'VariableMirror.metadata'); +} + +checkTypeVariable(TypeVariableMirror tvm) { + checkList(tvm.metadata, 'TypeVariableMirror.metadata'); +} + +checkParameter(ParameterMirror pm) { + checkList(pm.metadata, 'ParameterMirror.metadata'); +} + +checkMethod(MethodMirror mm) { + checkList(mm.parameters, 'MethodMirror.parameters'); + checkList(mm.metadata, 'MethodMirror.metadata'); + + mm.parameters.forEach(checkParameter); +} + +checkClass(ClassMirror cm) { + checkMap(cm.declarations, 'ClassMirror.declarations'); + checkMap(cm.instanceMembers, 'ClassMirror.instanceMembers'); + checkMap(cm.staticMembers, 'ClassMirror.staticMembers'); + checkList(cm.metadata, 'ClassMirror.metadata'); + checkList(cm.superinterfaces, 'ClassMirror.superinterfaces'); + checkList(cm.typeArguments, 'ClassMirror.typeArguments'); + checkList(cm.typeVariables, 'ClassMirror.typeVariables'); + + cm.declarations.values.forEach(checkDeclaration); + cm.instanceMembers.values.forEach(checkDeclaration); + cm.staticMembers.values.forEach(checkDeclaration); + cm.typeVariables.forEach(checkTypeVariable); +} + +checkType(TypeMirror tm) { + checkList(tm.metadata, 'TypeMirror.metadata'); +} + +checkDeclaration(DeclarationMirror dm) { + if (dm is MethodMirror) checkMethod(dm); + if (dm is ClassMirror) checkClass(dm); + if (dm is TypeMirror) checkType(dm); + if (dm is VariableMirror) checkVariable(dm); + if (dm is TypeVariableMirror) checkTypeVariable(dm); +} + +checkLibrary(LibraryMirror lm) { + checkMap(lm.declarations, 'LibraryMirror.declarations'); + checkList(lm.metadata, 'LibraryMirror.metadata'); + + lm.declarations.values.forEach(checkDeclaration); +} + +main() { + currentMirrorSystem().libraries.values.forEach(checkLibrary); + checkType(currentMirrorSystem().voidType); + checkType(currentMirrorSystem().dynamicType); +} diff --git a/tests/lib/mirrors/inference_and_no_such_method_test.dart b/tests/lib/mirrors/inference_and_no_such_method_test.dart new file mode 100644 index 00000000000..79dd63560d6 --- /dev/null +++ b/tests/lib/mirrors/inference_and_no_such_method_test.dart @@ -0,0 +1,26 @@ +// Copyright (c) 2013, 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. + +// Regression test for dart2js that did type inferencing on parameters +// whose type may change at runtime due to an invocation through +// [InstanceMirror.delegate]. + +import 'dart:mirrors'; +import 'package:expect/expect.dart'; + +class A { + noSuchMethod(im) { + reflect(new B()).delegate(im); + } +} + +class B { + foo(a) => a + 42; +} + +main() { + Expect.equals(42, new B().foo(0)); + dynamic a = new A(); + Expect.throwsTypeError(() => a.foo('foo')); +} diff --git a/tests/lib/mirrors/inherit_field_test.dart b/tests/lib/mirrors/inherit_field_test.dart new file mode 100644 index 00000000000..d8590ed81ef --- /dev/null +++ b/tests/lib/mirrors/inherit_field_test.dart @@ -0,0 +1,23 @@ +// Copyright (c) 2013, 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 inherited fields. + +library test.inherit_field_test; + +import 'dart:mirrors'; + +import 'stringify.dart'; + +class Foo { + var field; +} + +class Bar extends Foo {} + +void main() { + expect( + 'Variable(s(field) in s(Foo))', reflectClass(Foo).declarations[#field]); + expect('', reflectClass(Bar).declarations[#field]); +} diff --git a/tests/lib/mirrors/inherited_metadata_test.dart b/tests/lib/mirrors/inherited_metadata_test.dart new file mode 100644 index 00000000000..87a2b4299e9 --- /dev/null +++ b/tests/lib/mirrors/inherited_metadata_test.dart @@ -0,0 +1,44 @@ +// Copyright (c) 2014, 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. + +library test.mirrors; + +import 'dart:mirrors'; + +import 'package:expect/expect.dart'; + +class RemoteClass { + final String name; + const RemoteClass([this.name = "default"]); +} + +class A {} + +@RemoteClass("ASF") +class B extends A {} + +class C extends B {} + +void main() { + bool foundB = false; + + MirrorSystem mirrorSystem = currentMirrorSystem(); + mirrorSystem.libraries.forEach((lk, l) { + l.declarations.forEach((dk, d) { + if (d is ClassMirror) { + d.metadata.forEach((md) { + InstanceMirror metadata = md as InstanceMirror; + // Metadata must not be inherited. + if (metadata.type == reflectClass(RemoteClass)) { + Expect.isFalse(foundB); + Expect.equals(#B, d.simpleName); + foundB = true; + } + }); + } + }); + }); + + Expect.isTrue(foundB); +} diff --git a/tests/lib/mirrors/initializing_formals_test.dart b/tests/lib/mirrors/initializing_formals_test.dart new file mode 100644 index 00000000000..8cc4af1f345 --- /dev/null +++ b/tests/lib/mirrors/initializing_formals_test.dart @@ -0,0 +1,159 @@ +// Copyright (c) 2013, 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. + +library test.initializing_formals; + +import 'dart:mirrors'; +import 'package:expect/expect.dart'; + +class Class { + num numField = 0; + bool boolField = false; + String stringField = ""; + T tField; + dynamic _privateField; + + Class.nongeneric(this.numField); + Class.named({this.boolField = false}); + Class.optPos([this.stringField = 'default']); + Class.generic(this.tField); + Class.private(this._privateField); + + Class.explicitType(num this.numField); + Class.withVar(var this.numField); + Class.withSubtype(int this.numField); +} + +class Constant { + final num value; + const Constant(this.value); + const Constant.marked(final this.value); +} + +main() { + MethodMirror mm; + ParameterMirror pm; + + mm = reflectClass(Class).declarations[#Class.nongeneric] as MethodMirror; + pm = mm.parameters.single; + Expect.equals(#numField, pm.simpleName); + Expect.equals(reflectClass(num), pm.type); + Expect.isFalse(pm.isNamed); // //# 01: ok + Expect.isFalse(pm.isFinal); // //# 01: ok + Expect.isFalse(pm.isOptional); // //# 01: ok + Expect.isFalse(pm.hasDefaultValue); // //# 01: ok + Expect.isFalse(pm.isPrivate); + Expect.isFalse(pm.isStatic); + Expect.isFalse(pm.isTopLevel); + + mm = reflectClass(Class).declarations[#Class.named] as MethodMirror; + pm = mm.parameters.single; + Expect.equals(#boolField, pm.simpleName); + Expect.equals(reflectClass(bool), pm.type); + Expect.isTrue(pm.isNamed); // //# 01: ok + Expect.isFalse(pm.isFinal); // //# 01: ok + Expect.isTrue(pm.isOptional); // //# 01: ok + Expect.isTrue(pm.hasDefaultValue); // //# 01: ok + Expect.equals(false, pm.defaultValue.reflectee); // //# 01: ok + Expect.isFalse(pm.isPrivate); + Expect.isFalse(pm.isStatic); + Expect.isFalse(pm.isTopLevel); + + mm = reflectClass(Class).declarations[#Class.optPos] as MethodMirror; + pm = mm.parameters.single; + Expect.equals(#stringField, pm.simpleName); + Expect.equals(reflectClass(String), pm.type); + Expect.isFalse(pm.isNamed); // //# 01: ok + Expect.isFalse(pm.isFinal); // //# 01: ok + Expect.isTrue(pm.isOptional); // //# 01: ok + Expect.isTrue(pm.hasDefaultValue); // //# 01: ok + Expect.equals('default', pm.defaultValue.reflectee); // //# 01: ok + Expect.isFalse(pm.isPrivate); + Expect.isFalse(pm.isStatic); + Expect.isFalse(pm.isTopLevel); + + mm = reflectClass(Class).declarations[#Class.generic] as MethodMirror; + pm = mm.parameters.single; + Expect.equals(#tField, pm.simpleName); + Expect.equals(reflectClass(Class).typeVariables.single, pm.type); + Expect.isFalse(pm.isNamed); // //# 01: ok + Expect.isFalse(pm.isFinal); // //# 01: ok + Expect.isFalse(pm.isOptional); // //# 01: ok + Expect.isFalse(pm.hasDefaultValue); // //# 01: ok + Expect.isFalse(pm.isPrivate); + Expect.isFalse(pm.isStatic); + Expect.isFalse(pm.isTopLevel); + + mm = reflectClass(Class).declarations[#Class.private] as MethodMirror; + pm = mm.parameters.single; + Expect.equals(#_privateField, pm.simpleName); // //# 03: ok + Expect.equals(currentMirrorSystem().dynamicType, pm.type); + Expect.isFalse(pm.isNamed); // //# 01: ok + Expect.isFalse(pm.isFinal); // //# 01: ok + Expect.isFalse(pm.isOptional); // //# 01: ok + Expect.isFalse(pm.hasDefaultValue); // //# 01: ok + Expect.isTrue(pm.isPrivate); + Expect.isFalse(pm.isStatic); + Expect.isFalse(pm.isTopLevel); + + mm = reflectClass(Class).declarations[#Class.explicitType] as MethodMirror; + pm = mm.parameters.single; + Expect.equals(#numField, pm.simpleName); + Expect.equals(reflectClass(num), pm.type); + Expect.isFalse(pm.isNamed); // //# 01: ok + Expect.isFalse(pm.isFinal); // //# 01: ok + Expect.isFalse(pm.isOptional); // //# 01: ok + Expect.isFalse(pm.hasDefaultValue); // //# 01: ok + Expect.isFalse(pm.isPrivate); + Expect.isFalse(pm.isStatic); + Expect.isFalse(pm.isTopLevel); + + mm = reflectClass(Class).declarations[#Class.withVar] as MethodMirror; + pm = mm.parameters.single; + Expect.equals(#numField, pm.simpleName); + Expect.equals(reflectClass(num), pm.type); + Expect.isFalse(pm.isNamed); // //# 01: ok + Expect.isFalse(pm.isFinal); // //# 01: ok + Expect.isFalse(pm.isOptional); // //# 01: ok + Expect.isFalse(pm.hasDefaultValue); // //# 01: ok + Expect.isFalse(pm.isPrivate); + Expect.isFalse(pm.isStatic); + Expect.isFalse(pm.isTopLevel); + + mm = reflectClass(Class).declarations[#Class.withSubtype] as MethodMirror; + pm = mm.parameters.single; + Expect.equals(#numField, pm.simpleName); + Expect.equals(reflectClass(int), pm.type); + Expect.isFalse(pm.isNamed); // //# 01: ok + Expect.isFalse(pm.isFinal); // //# 01: ok + Expect.isFalse(pm.isOptional); // //# 01: ok + Expect.isFalse(pm.hasDefaultValue); // //# 01: ok + Expect.isFalse(pm.isPrivate); + Expect.isFalse(pm.isStatic); + Expect.isFalse(pm.isTopLevel); + + mm = reflectClass(Constant).declarations[#Constant] as MethodMirror; + pm = mm.parameters.single; + Expect.equals(#value, pm.simpleName); + Expect.equals(reflectClass(num), pm.type); + Expect.isFalse(pm.isNamed); // //# 01: ok + Expect.isFalse(pm.isFinal); // N.B. // //# 01: ok + Expect.isFalse(pm.isOptional); // //# 01: ok + Expect.isFalse(pm.hasDefaultValue); // //# 01: ok + Expect.isFalse(pm.isPrivate); + Expect.isFalse(pm.isStatic); + Expect.isFalse(pm.isTopLevel); + + mm = reflectClass(Constant).declarations[#Constant.marked] as MethodMirror; + pm = mm.parameters.single; + Expect.equals(#value, pm.simpleName); + Expect.equals(reflectClass(num), pm.type); + Expect.isFalse(pm.isNamed); // //# 01: ok + Expect.isTrue(pm.isFinal); // N.B. // //# 01: ok + Expect.isFalse(pm.isOptional); // //# 01: ok + Expect.isFalse(pm.hasDefaultValue); // //# 01: ok + Expect.isFalse(pm.isPrivate); + Expect.isFalse(pm.isStatic); + Expect.isFalse(pm.isTopLevel); +} diff --git a/tests/lib/mirrors/instance_creation_in_function_annotation_test.dart b/tests/lib/mirrors/instance_creation_in_function_annotation_test.dart new file mode 100644 index 00000000000..bfdd69cd16b --- /dev/null +++ b/tests/lib/mirrors/instance_creation_in_function_annotation_test.dart @@ -0,0 +1,29 @@ +// Copyright (c) 2015, 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. + +// Verify that instance creation expressions inside function +// annotations are properly handled. See dartbug.com/23354 + +import 'dart:mirrors'; +import 'package:expect/expect.dart'; + +class C { + final String s; + const C(this.s); +} + +class D { + final C c; + const D(this.c); +} + +@D(const C('foo')) +f() {} + +main() { + ClosureMirror closureMirror = reflect(f) as ClosureMirror; + List metadata = closureMirror.function.metadata; + Expect.equals(1, metadata.length); + Expect.equals(metadata[0].reflectee.c.s, 'foo'); +} diff --git a/tests/lib/mirrors/instance_members_easier_test.dart b/tests/lib/mirrors/instance_members_easier_test.dart new file mode 100644 index 00000000000..4a9fe66afea --- /dev/null +++ b/tests/lib/mirrors/instance_members_easier_test.dart @@ -0,0 +1,91 @@ +// Copyright (c) 2013, 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. + +library test.instance_members; + +import 'dart:mirrors'; +import 'package:expect/expect.dart'; + +import 'declarations_model_easier.dart' as declarations_model; + +selectKeys(map, predicate) { + return map.keys.where((key) => predicate(map[key])); +} + +class EasierSuperclass { + shuper() {} + static staticShuper() {} +} + +class EasierMixin { + mixin() {} + static staticMixin() {} +} + +class EasierMixinApplication extends EasierSuperclass with EasierMixin { + application() {} + static staticApplication() {} +} + +class Derived extends EasierMixinApplication { + derived() {} + static staticDerived() {} +} + +main() { + ClassMirror cm = reflectClass(declarations_model.Class); + + Expect.setEquals([ + #+, + #instanceVariable, + const Symbol('instanceVariable='), + #instanceGetter, + const Symbol('instanceSetter='), + #instanceMethod, + #-, + #inheritedInstanceVariable, + const Symbol('inheritedInstanceVariable='), + #inheritedInstanceGetter, + const Symbol('inheritedInstanceSetter='), + #inheritedInstanceMethod, + #hashCode, + #runtimeType, + #==, + #noSuchMethod, + #toString + ], selectKeys(cm.instanceMembers, (dm) => !dm.isPrivate)); + // Filter out private to avoid implementation-specific members of Object. + + Expect.setEquals([ + #instanceVariable, + const Symbol('instanceVariable='), + #inheritedInstanceVariable, + const Symbol('inheritedInstanceVariable=') + ], selectKeys(cm.instanceMembers, (dm) => !dm.isPrivate && dm.isSynthetic)); + + cm = reflectClass(Derived); + Expect.setEquals([ + #derived, + #shuper, + #mixin, + #application, + #hashCode, + #runtimeType, + #==, + #noSuchMethod, + #toString + ], selectKeys(cm.instanceMembers, (dm) => !dm.isPrivate)); + + cm = reflectClass(EasierMixinApplication); + Expect.setEquals([ + #shuper, + #mixin, + #application, + #hashCode, + #runtimeType, + #==, + #noSuchMethod, + #toString + ], selectKeys(cm.instanceMembers, (dm) => !dm.isPrivate)); +} diff --git a/tests/lib/mirrors/instance_members_test.dart b/tests/lib/mirrors/instance_members_test.dart new file mode 100644 index 00000000000..4bbf79f0dd5 --- /dev/null +++ b/tests/lib/mirrors/instance_members_test.dart @@ -0,0 +1,54 @@ +// Copyright (c) 2013, 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. + +library test.instance_members; + +import 'dart:mirrors'; +import 'package:expect/expect.dart'; + +import 'declarations_model.dart' as declarations_model; + +selectKeys(map, predicate) { + return map.keys.where((key) => predicate(map[key])); +} + +main() { + ClassMirror cm = reflectClass(declarations_model.Class); + + Expect.setEquals([ + #+, + #instanceVariable, + const Symbol('instanceVariable='), + #instanceGetter, + const Symbol('instanceSetter='), + #instanceMethod, + #-, + #inheritedInstanceVariable, + const Symbol('inheritedInstanceVariable='), + #inheritedInstanceGetter, + const Symbol('inheritedInstanceSetter='), + #inheritedInstanceMethod, + #*, + #mixinInstanceVariable, + const Symbol('mixinInstanceVariable='), + #mixinInstanceGetter, + const Symbol('mixinInstanceSetter='), + #mixinInstanceMethod, + #hashCode, + #runtimeType, + #==, + #noSuchMethod, + #toString + ], selectKeys(cm.instanceMembers, (dm) => !dm.isPrivate)); + // Filter out private to avoid implementation-specific members of Object. + + Expect.setEquals([ + #instanceVariable, + const Symbol('instanceVariable='), + #inheritedInstanceVariable, + const Symbol('inheritedInstanceVariable='), + #mixinInstanceVariable, + const Symbol('mixinInstanceVariable=') + ], selectKeys(cm.instanceMembers, (dm) => !dm.isPrivate && dm.isSynthetic)); +} diff --git a/tests/lib/mirrors/instance_members_unimplemented_interface_test.dart b/tests/lib/mirrors/instance_members_unimplemented_interface_test.dart new file mode 100644 index 00000000000..5c264105505 --- /dev/null +++ b/tests/lib/mirrors/instance_members_unimplemented_interface_test.dart @@ -0,0 +1,27 @@ +// Copyright (c) 2013, 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. + +library test.instance_members_unimplemented_interface; + +import 'dart:mirrors'; +import 'package:expect/expect.dart'; + +class I { + implementMe() {} +} + +abstract class C implements I {} + +selectKeys(Map map, bool predicate(V)) { + return map.keys.where((key) => predicate(map[key])); +} + +main() { + ClassMirror cm = reflectClass(C); + + // N.B.: Does not include #implementMe. + Expect.setEquals([#hashCode, #runtimeType, #==, #noSuchMethod, #toString], + selectKeys(cm.instanceMembers, (dm) => !dm.isPrivate)); + // Filter out private to avoid implementation-specific members of Object. +} diff --git a/tests/lib/mirrors/instance_members_with_override_test.dart b/tests/lib/mirrors/instance_members_with_override_test.dart new file mode 100644 index 00000000000..9cefc0b22c8 --- /dev/null +++ b/tests/lib/mirrors/instance_members_with_override_test.dart @@ -0,0 +1,89 @@ +// Copyright (c) 2013, 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. + +library test.instance_members_with_override; + +import 'dart:mirrors'; +import 'package:expect/expect.dart'; +import 'package:meta/meta.dart' show virtual; + +class S { + @virtual + var field; + @virtual + final finalField = 0; + method() {} + get getter {} + set setter(x) {} + notOverridden() {} +} + +abstract class C extends S { + var field; + final finalField = 0; + method() {} + get getter {} + set setter(x) {} + /* abstract */ notOverridden(); +} + +selectKeys(map, predicate) { + return map.keys.where((key) => predicate(map[key])); +} + +main() { + ClassMirror sMirror = reflectClass(S); + ClassMirror cMirror = reflectClass(C); + + Expect.setEquals([ + #field, + const Symbol('field='), + #finalField, + #method, + #getter, + const Symbol('setter='), + #notOverridden, + #hashCode, + #runtimeType, + #==, + #noSuchMethod, + #toString + ], selectKeys(sMirror.instanceMembers, (dm) => !dm.isPrivate)); + // Filter out private to avoid implementation-specific members of Object. + + Expect.equals(sMirror, sMirror.instanceMembers[#field].owner); + Expect.equals(sMirror, sMirror.instanceMembers[const Symbol('field=')].owner); + Expect.equals(sMirror, sMirror.instanceMembers[#finalField].owner); + Expect.equals(sMirror, sMirror.instanceMembers[#method].owner); + Expect.equals(sMirror, sMirror.instanceMembers[#getter].owner); + Expect.equals( + sMirror, sMirror.instanceMembers[const Symbol('setter=')].owner); + + Expect.setEquals([ + #field, + const Symbol('field='), + #finalField, + #method, + #getter, + const Symbol('setter='), + #notOverridden, + #hashCode, + #runtimeType, + #==, + #noSuchMethod, + #toString + ], selectKeys(cMirror.instanceMembers, (dm) => !dm.isPrivate)); + // Filter out private to avoid implementation-specific members of Object. + + Expect.equals(cMirror, cMirror.instanceMembers[#field].owner); + Expect.equals(cMirror, cMirror.instanceMembers[const Symbol('field=')].owner); + Expect.equals(cMirror, cMirror.instanceMembers[#finalField].owner); + Expect.equals(cMirror, cMirror.instanceMembers[#method].owner); + Expect.equals(cMirror, cMirror.instanceMembers[#getter].owner); + Expect.equals( + cMirror, cMirror.instanceMembers[const Symbol('setter=')].owner); + + Expect.equals(sMirror, sMirror.instanceMembers[#notOverridden].owner); + Expect.equals(sMirror, cMirror.instanceMembers[#notOverridden].owner); +} diff --git a/tests/lib/mirrors/instantiate_abstract_class_test.dart b/tests/lib/mirrors/instantiate_abstract_class_test.dart new file mode 100644 index 00000000000..057b40bad5a --- /dev/null +++ b/tests/lib/mirrors/instantiate_abstract_class_test.dart @@ -0,0 +1,46 @@ +// Copyright (c) 2013, 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. + +library test.instantiate_abstract_class; + +import 'dart:mirrors'; +import 'package:expect/expect.dart'; + +assertInstanitationErrorOnGenerativeConstructors(classMirror) { + classMirror.declarations.values.forEach((decl) { + if (decl is! MethodMirror) return; + if (!decl.isGenerativeConstructor) return; + var args = new List(decl.parameters.length); + Expect.throws( + () => classMirror.newInstance(decl.constructorName, args), + (e) => e is AbstractClassInstantiationError, + '${decl.qualifiedName} should have failed'); + }); +} + +runFactoryConstructors(classMirror) { + classMirror.declarations.values.forEach((decl) { + if (decl is! MethodMirror) return; + if (!decl.isFactoryConstructor) return; + var args = new List(decl.parameters.length); + classMirror.newInstance(decl.constructorName, args); // Should not throw. + }); +} + +abstract class AbstractClass { + AbstractClass(); + AbstractClass.named(); + factory AbstractClass.named2() => new ConcreteClass(); +} + +class ConcreteClass implements AbstractClass {} + +main() { + assertInstanitationErrorOnGenerativeConstructors(reflectType(num)); + assertInstanitationErrorOnGenerativeConstructors(reflectType(double)); + assertInstanitationErrorOnGenerativeConstructors(reflectType(StackTrace)); + + assertInstanitationErrorOnGenerativeConstructors(reflectType(AbstractClass)); + runFactoryConstructors(reflectType(AbstractClass)); +} diff --git a/tests/lib/mirrors/intercepted_cache_test.dart b/tests/lib/mirrors/intercepted_cache_test.dart new file mode 100644 index 00000000000..b38881c6164 --- /dev/null +++ b/tests/lib/mirrors/intercepted_cache_test.dart @@ -0,0 +1,22 @@ +// Copyright (c) 2013, 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. + +// This is a test for a problem in how dart2js cached InstanceMirror.invoke, +// etc. The test is using getField, as invoke, setField, and getField all share +// the same caching. + +import 'dart:mirrors'; + +import 'package:expect/expect.dart'; + +class Foo { + Foo(this.length); + int length; +} + +main() { + Expect.equals(1, reflect(new Foo(1)).getField(#length).reflectee); + Expect.equals(2, reflect(new Foo(2)).getField(#length).reflectee); + Expect.equals(0, reflect([]).getField(#length).reflectee); +} diff --git a/tests/lib/mirrors/intercepted_class_test.dart b/tests/lib/mirrors/intercepted_class_test.dart new file mode 100644 index 00000000000..57a7737478f --- /dev/null +++ b/tests/lib/mirrors/intercepted_class_test.dart @@ -0,0 +1,35 @@ +// Copyright (c) 2013, 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. + +// Ensure that classes handled specially by dart2js can be reflected on. + +library test.intercepted_class_test; + +import 'dart:mirrors'; + +import 'stringify.dart' show stringify, expect; + +checkClassMirrorMethods(ClassMirror cls) { + var variables = new Map(); + cls.declarations.forEach((Symbol key, DeclarationMirror value) { + if (value is VariableMirror && !value.isStatic && !value.isPrivate) { + variables[key] = value; + } + }); + expect('{}', variables); +} + +checkClassMirror(ClassMirror cls, String name) { + expect('s($name)', cls.simpleName); + checkClassMirrorMethods(cls); +} + +main() { + checkClassMirror(reflectClass(String), 'String'); + checkClassMirror(reflectClass(int), 'int'); + checkClassMirror(reflectClass(double), 'double'); + checkClassMirror(reflectClass(num), 'num'); + checkClassMirror(reflectClass(bool), 'bool'); + checkClassMirror(reflectClass(List), 'List'); +} diff --git a/tests/lib/mirrors/intercepted_object_test.dart b/tests/lib/mirrors/intercepted_object_test.dart new file mode 100644 index 00000000000..ccbffa52990 --- /dev/null +++ b/tests/lib/mirrors/intercepted_object_test.dart @@ -0,0 +1,64 @@ +// Copyright (c) 2013, 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. + +// Ensure that objects handled specially by dart2js can be reflected on. + +library test.intercepted_object_test; + +import 'dart:mirrors'; + +import 'stringify.dart' show stringify, expect; + +import 'intercepted_class_test.dart' show checkClassMirrorMethods; + +checkImplements(object, String name) { + ClassMirror cls = reflect(object).type; + checkClassMirrorMethods(cls); + + // The VM implements List via a mixin, so check for that. + if (cls.superinterfaces.isEmpty && object is List) { + cls = cls.superclass.superclass.mixin; + } + + // The VM implements String through an intermediate abstract + // class. + if (cls.superinterfaces.isEmpty && object is String) { + cls = cls.superclass; + } + + // The VM implements int through an intermediate abstract + // class. + if (object is int && + stringify(cls.superclass.simpleName) == 's(_IntegerImplementation)') { + cls = cls.superclass; + } + + List superinterfaces = cls.superinterfaces; + String symName = 's($name)'; + for (ClassMirror superinterface in superinterfaces) { + print(superinterface.simpleName); + if (symName == stringify(superinterface.simpleName)) { + checkClassMirrorMethods(superinterface); + return; + } + } + + // A class implements itself, even if not explicitly declared. + if (symName == stringify(cls.simpleName)) { + checkClassMirrorMethods(cls); + return; + } + + // TODO(floitsch): use correct fail + expect(name, "super interface not found"); +} + +main() { + checkImplements('', 'String'); + checkImplements(1, 'int'); + checkImplements(1.5, 'double'); + checkImplements(true, 'bool'); + checkImplements(false, 'bool'); + checkImplements([], 'List'); +} diff --git a/tests/lib/mirrors/intercepted_superclass_test.dart b/tests/lib/mirrors/intercepted_superclass_test.dart new file mode 100644 index 00000000000..a7f48581865 --- /dev/null +++ b/tests/lib/mirrors/intercepted_superclass_test.dart @@ -0,0 +1,29 @@ +// Copyright (c) 2013, 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. + +library test.intercepted_superclass_test; + +import 'dart:mirrors'; +import 'package:expect/expect.dart'; + +check(ClassMirror cm) { + Expect.isTrue(cm is ClassMirror); + Expect.isNotNull(cm); +} + +main() { + check(reflect('').type.superclass); + check(reflect(1).type.superclass); + check(reflect(1.5).type.superclass); + check(reflect(true).type.superclass); + check(reflect(false).type.superclass); + check(reflect([]).type.superclass); + + check(reflectClass(String).superclass); + check(reflectClass(int).superclass); + check(reflectClass(double).superclass); + check(reflectClass(num).superclass); + check(reflectClass(bool).superclass); + check(reflectClass(List).superclass); +} diff --git a/tests/lib/mirrors/invocation_cache_test.dart b/tests/lib/mirrors/invocation_cache_test.dart new file mode 100644 index 00000000000..f8ec29cf2f4 --- /dev/null +++ b/tests/lib/mirrors/invocation_cache_test.dart @@ -0,0 +1,18 @@ +// Copyright (c) 2014, 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. + +import 'dart:mirrors'; + +import 'package:expect/expect.dart'; + +class A { + toString() => "A"; +} + +main() { + // The invocation cache must not find the 'toString' from JavaScript's + // Object.prototype. + var toString = reflect(new A()).getField(#toString).reflectee; + Expect.equals("A", Function.apply(toString, [], {})); +} diff --git a/tests/lib/mirrors/invocation_fuzz_test.dart b/tests/lib/mirrors/invocation_fuzz_test.dart new file mode 100644 index 00000000000..61124a89e04 --- /dev/null +++ b/tests/lib/mirrors/invocation_fuzz_test.dart @@ -0,0 +1,187 @@ +// Copyright (c) 2014, 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. + +// This test reflectively enumerates all the methods in the system and tries to +// invoke them with various basic values (nulls, ints, etc). This may result in +// Dart exceptions or hangs, but should never result in crashes or JavaScript +// exceptions. + +library test.invoke_natives; + +import 'dart:mirrors'; +import 'dart:async'; +import 'dart:io'; + +// Methods to be skipped, by qualified name. +var blacklist = [ + // Don't recurse on this test. + 'test.invoke_natives', + + // Don't exit the test pre-maturely. + 'dart.io.exit', + + // Don't change the exit code, which may fool the test harness. + 'dart.io.exitCode', + + // Don't kill random other processes. + 'dart.io.Process.killPid', + + // Don't break into the debugger. + 'dart.developer.debugger', + + // Don't run blocking io calls. + 'dart.io.sleep', + new RegExp(r".*Sync$"), + + // Don't call private methods in dart.async as they may circumvent the zoned + // error handling below. + new RegExp(r"^dart\.async\._.*$"), +]; + +bool isBlacklisted(Symbol qualifiedSymbol) { + var qualifiedString = MirrorSystem.getName(qualifiedSymbol); + for (var pattern in blacklist) { + if (qualifiedString.contains(pattern)) { + print('Skipping $qualifiedString'); + return true; + } + } + return false; +} + +class Task { + dynamic name; + dynamic action; +} + +var queue = new List(); + +checkMethod(MethodMirror m, ObjectMirror target, [origin]) { + if (isBlacklisted(m.qualifiedName)) return; + + var task = new Task(); + task.name = '${MirrorSystem.getName(m.qualifiedName)} from $origin'; + + if (m.isRegularMethod) { + task.action = () => target.invoke( + m.simpleName, new List.filled(m.parameters.length, fuzzArgument)); + } else if (m.isGetter) { + task.action = () => target.getField(m.simpleName); + } else if (m.isSetter) { + task.action = () => target.setField(m.simpleName, null); + } else if (m.isConstructor) { + return; + } else { + throw "Unexpected method kind"; + } + + queue.add(task); +} + +checkInstance(instanceMirror, origin) { + ClassMirror klass = instanceMirror.type; + while (klass != null) { + instanceMirror.type.declarations.values + .where((d) => d is MethodMirror && !d.isStatic) + .forEach((m) => checkMethod(m, instanceMirror, origin)); + klass = klass.superclass; + } +} + +checkClass(classMirror) { + classMirror.declarations.values + .where((d) => d is MethodMirror && d.isStatic) + .forEach((m) => checkMethod(m, classMirror)); + + classMirror.declarations.values + .where((d) => d is MethodMirror && d.isConstructor) + .forEach((m) { + if (isBlacklisted(m.qualifiedName)) return; + var task = new Task(); + task.name = MirrorSystem.getName(m.qualifiedName); + + task.action = () { + var instance = classMirror.newInstance(m.constructorName, + new List.filled(m.parameters.length, fuzzArgument)); + checkInstance(instance, task.name); + }; + queue.add(task); + }); +} + +checkLibrary(libraryMirror) { + print(libraryMirror.simpleName); + if (isBlacklisted(libraryMirror.qualifiedName)) return; + + libraryMirror.declarations.values + .where((d) => d is ClassMirror) + .forEach(checkClass); + + libraryMirror.declarations.values + .where((d) => d is MethodMirror) + .forEach((m) => checkMethod(m, libraryMirror)); +} + +var testZone; + +doOneTask() { + if (queue.length == 0) { + print('Done'); + // Forcibly exit as we likely opened sockets and timers during the fuzzing. + exit(0); + } + + var task = queue.removeLast(); + print(task.name); + try { + task.action(); + } catch (e) {} + + // Register the next task in a timer callback so as to yield to async code + // scheduled in the current task. This isn't necessary for the test itself, + // but is helpful when trying to figure out which function is responsible for + // a crash. + testZone.createTimer(Duration.zero, doOneTask); +} + +var fuzzArgument; + +main() { + fuzzArgument = null; + fuzzArgument = 1; // //# smi: ok + fuzzArgument = false; // //# false: ok + fuzzArgument = 'string'; // //# string: ok + fuzzArgument = new List(0); // //# emptyarray: ok + + print('Fuzzing with $fuzzArgument'); + + currentMirrorSystem().libraries.values.forEach(checkLibrary); + + var valueObjects = [ + true, + false, + null, + [], + {}, + dynamic, + 0, + 0xEFFFFFF, + 0xFFFFFFFF, + 0xFFFFFFFFFFFFFFFF, + 3.14159, + "foo", + 'blåbærgrød', + 'Îñţérñåţîöñåļîžåţîờñ', + "\u{1D11E}", + #symbol + ]; + valueObjects.forEach((v) => checkInstance(reflect(v), 'value object')); + + void uncaughtErrorHandler(self, parent, zone, error, stack) {} + + var zoneSpec = + new ZoneSpecification(handleUncaughtError: uncaughtErrorHandler); + testZone = Zone.current.fork(specification: zoneSpec); + testZone.createTimer(Duration.zero, doOneTask); +} diff --git a/tests/lib/mirrors/invocation_mirror_invoke_on2_test.dart b/tests/lib/mirrors/invocation_mirror_invoke_on2_test.dart new file mode 100644 index 00000000000..a7a6d756f28 --- /dev/null +++ b/tests/lib/mirrors/invocation_mirror_invoke_on2_test.dart @@ -0,0 +1,81 @@ +// Copyright (c) 2013, 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. + +import "dart:mirrors" show reflect; +import "package:expect/expect.dart"; + +class Proxy { + final proxied; + Proxy(this.proxied); + noSuchMethod(mirror) => reflect(proxied).delegate(mirror); +} + +main() { + testList(); + testString(); + testInt(); + testDouble(); +} + +testList() { + dynamic list = []; + dynamic proxy = new Proxy(list); + + Expect.isTrue(proxy.isEmpty); + Expect.isTrue(list.isEmpty); + + proxy.add(42); + + Expect.isFalse(proxy.isEmpty); + Expect.equals(1, proxy.length); + Expect.equals(42, proxy[0]); + + Expect.isFalse(list.isEmpty); + Expect.equals(1, list.length); + Expect.equals(42, list[0]); + + proxy.add(87); + + Expect.equals(2, proxy.length); + Expect.equals(87, proxy[1]); + + Expect.equals(2, list.length); + Expect.equals(87, list[1]); + + Expect.throwsNoSuchMethodError(() => proxy.funky()); + Expect.throwsNoSuchMethodError(() => list.funky()); +} + +testString() { + dynamic string = "funky"; + dynamic proxy = new Proxy(string); + + Expect.equals(string.codeUnitAt(0), proxy.codeUnitAt(0)); + Expect.equals(string.length, proxy.length); + + Expect.throwsNoSuchMethodError(() => proxy.funky()); + Expect.throwsNoSuchMethodError(() => string.funky()); +} + +testInt() { + dynamic number = 42; + dynamic proxy = new Proxy(number); + + Expect.equals(number + 87, proxy + 87); + Expect.equals(number.toDouble(), proxy.toDouble()); + + Expect.throwsNoSuchMethodError(() => proxy.funky()); + Expect.throwsNoSuchMethodError(() => number.funky()); +} + +testDouble() { + dynamic number = 42.99; + dynamic proxy = new Proxy(number); + + Expect.equals(number + 87, proxy + 87); + Expect.equals(number.toInt(), proxy.toInt()); + + Expect.throwsNoSuchMethodError(() => proxy.funky()); + Expect.throwsNoSuchMethodError(() => number.funky()); +} diff --git a/tests/lib/mirrors/invocation_mirror_invoke_on_test.dart b/tests/lib/mirrors/invocation_mirror_invoke_on_test.dart new file mode 100644 index 00000000000..c1151a303c2 --- /dev/null +++ b/tests/lib/mirrors/invocation_mirror_invoke_on_test.dart @@ -0,0 +1,41 @@ +// Copyright (c) 2012, 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. + +import "dart:mirrors" show reflect; +import "package:expect/expect.dart"; + +// Testing InstanceMirror.delegate method; test of issue 7227. + +var reachedSetX = 0; +var reachedGetX = 0; +var reachedM = 0; + +class A { + set x(val) { + reachedSetX = val; + } + + get x { + reachedGetX = 1; + } + + m() { + reachedM = 1; + } +} + +class B { + final a = new A(); + noSuchMethod(mirror) => reflect(a).delegate(mirror); +} + +main() { + dynamic b = new B(); + b.x = 10; + Expect.equals(10, reachedSetX); + b.x; + Expect.equals(1, reachedGetX); + b.m(); + Expect.equals(1, reachedM); +} diff --git a/tests/lib/mirrors/invoke_call_on_closure_test.dart b/tests/lib/mirrors/invoke_call_on_closure_test.dart new file mode 100644 index 00000000000..bb08c379a34 --- /dev/null +++ b/tests/lib/mirrors/invoke_call_on_closure_test.dart @@ -0,0 +1,63 @@ +// Copyright (c) 2014, 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. + +library test.invoke_call_on_closure; + +import 'dart:mirrors'; + +import 'package:expect/expect.dart'; + +class FakeFunctionCall { + call(x, y) => '1 $x $y'; +} + +class FakeFunctionNSM { + noSuchMethod(msg) => msg.positionalArguments.join(', '); +} + +class C { + get fakeFunctionCall => new FakeFunctionCall(); + get fakeFunctionNSM => new FakeFunctionNSM(); + get closure => (x, y) => '2 $this $x $y'; + get closureOpt => (x, y, [z, w]) => '3 $this $x $y $z $w'; + get closureNamed => (x, y, {z, w}) => '4 $this $x $y $z $w'; + tearOff(x, y) => '22 $this $x $y'; + tearOffOpt(x, y, [z, w]) => '33 $this $x $y $z $w'; + tearOffNamed(x, y, {z, w}) => '44 $this $x $y $z $w'; + + noSuchMethod(msg) => 'DNU'; + + toString() => 'C'; +} + +main() { + var c = new C(); + InstanceMirror im; + + im = reflect(c.fakeFunctionCall); + Expect.equals('1 5 6', im.invoke(#call, [5, 6]).reflectee); + + im = reflect(c.fakeFunctionNSM); + Expect.equals('7, 8', im.invoke(#call, [7, 8]).reflectee); + + im = reflect(c.closure); + Expect.equals('2 C 9 10', im.invoke(#call, [9, 10]).reflectee); + + im = reflect(c.closureOpt); + Expect.equals('3 C 11 12 13 null', im.invoke(#call, [11, 12, 13]).reflectee); + + im = reflect(c.closureNamed); + Expect.equals( + '4 C 14 15 null 16', im.invoke(#call, [14, 15], {#w: 16}).reflectee); + + im = reflect(c.tearOff); + Expect.equals('22 C 9 10', im.invoke(#call, [9, 10]).reflectee); + + im = reflect(c.tearOffOpt); + Expect.equals('33 C 11 12 13 null', im.invoke(#call, [11, 12, 13]).reflectee); + + im = reflect(c.tearOffNamed); + Expect.equals( + '44 C 14 15 null 16', im.invoke(#call, [14, 15], {#w: 16}).reflectee); +} diff --git a/tests/lib/mirrors/invoke_call_through_getter_previously_accessed_test.dart b/tests/lib/mirrors/invoke_call_through_getter_previously_accessed_test.dart new file mode 100644 index 00000000000..f1bbc5be3e4 --- /dev/null +++ b/tests/lib/mirrors/invoke_call_through_getter_previously_accessed_test.dart @@ -0,0 +1,127 @@ +// Copyright (c) 2013, 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. + +library test.invoke_call_through_getter; + +import 'dart:mirrors'; + +import 'package:expect/expect.dart'; + +class FakeFunctionCall { + call(x, y) => '1 $x $y'; +} + +class FakeFunctionNSM { + noSuchMethod(msg) => msg.positionalArguments.join(', '); +} + +class C { + get fakeFunctionCall => new FakeFunctionCall(); + get fakeFunctionNSM => new FakeFunctionNSM(); + get closure => (x, y) => '2 $this $x $y'; + get closureOpt => (x, y, [z, w]) => '3 $this $x $y $z $w'; + get closureNamed => (x, y, {z, w}) => '4 $this $x $y $z $w'; + get notAClosure => 'Not a closure'; + noSuchMethod(msg) => 'DNU'; + + toString() => 'C'; +} + +testInstanceBase() { + dynamic c = new C(); + + Expect.equals('1 5 6', c.fakeFunctionCall(5, 6)); + Expect.equals('7, 8', c.fakeFunctionNSM(7, 8)); + Expect.equals('2 C 9 10', c.closure(9, 10)); + Expect.equals('3 C 11 12 13 null', c.closureOpt(11, 12, 13)); + Expect.equals('4 C 14 15 null 16', c.closureNamed(14, 15, w: 16)); + Expect.equals('DNU', c.doesNotExist(17, 18)); + Expect.throwsNoSuchMethodError(() => c.closure('wrong arity')); + Expect.throwsNoSuchMethodError(() => c.notAClosure()); +} + +testInstanceReflective() { + InstanceMirror im = reflect(new C()); + + Expect.equals('1 5 6', im.invoke(#fakeFunctionCall, [5, 6]).reflectee); + Expect.equals('7, 8', im.invoke(#fakeFunctionNSM, [7, 8]).reflectee); + Expect.equals('2 C 9 10', im.invoke(#closure, [9, 10]).reflectee); + Expect.equals( + '3 C 11 12 13 null', im.invoke(#closureOpt, [11, 12, 13]).reflectee); + Expect.equals('4 C 14 15 null 16', // //# named: ok + im.invoke(#closureNamed, [14, 15], {#w: 16}).reflectee); // //# named: continued + Expect.equals('DNU', im.invoke(#doesNotExist, [17, 18]).reflectee); + Expect.throwsNoSuchMethodError(() => im.invoke(#closure, ['wrong arity'])); + Expect.throwsNoSuchMethodError(() => im.invoke(#notAClosure, [])); +} + +class D { + static get fakeFunctionCall => new FakeFunctionCall(); + static get fakeFunctionNSM => new FakeFunctionNSM(); + static get closure => (x, y) => '2 $x $y'; + static get closureOpt => (x, y, [z, w]) => '3 $x $y $z $w'; + static get closureNamed => (x, y, {z, w}) => '4 $x $y $z $w'; + static get notAClosure => 'Not a closure'; +} + +testClassBase() { + Expect.equals('1 5 6', D.fakeFunctionCall(5, 6)); + Expect.equals('7, 8', D.fakeFunctionNSM(7, 8)); + Expect.equals('2 9 10', D.closure(9, 10)); + Expect.equals('3 11 12 13 null', D.closureOpt(11, 12, 13)); + Expect.equals('4 14 15 null 16', D.closureNamed(14, 15, w: 16)); + Expect.throwsNoSuchMethodError(() => D.closure('wrong arity')); +} + +testClassReflective() { + ClassMirror cm = reflectClass(D); + + Expect.equals('1 5 6', cm.invoke(#fakeFunctionCall, [5, 6]).reflectee); + Expect.equals('7, 8', cm.invoke(#fakeFunctionNSM, [7, 8]).reflectee); + Expect.equals('2 9 10', cm.invoke(#closure, [9, 10]).reflectee); + Expect.equals( + '3 11 12 13 null', cm.invoke(#closureOpt, [11, 12, 13]).reflectee); + Expect.equals('4 14 15 null 16', // //# named: continued + cm.invoke(#closureNamed, [14, 15], {#w: 16}).reflectee); // //# named: continued + Expect.throwsNoSuchMethodError(() => cm.invoke(#closure, ['wrong arity'])); +} + +get fakeFunctionCall => new FakeFunctionCall(); +get fakeFunctionNSM => new FakeFunctionNSM(); +get closure => (x, y) => '2 $x $y'; +get closureOpt => (x, y, [z, w]) => '3 $x $y $z $w'; +get closureNamed => (x, y, {z, w}) => '4 $x $y $z $w'; +get notAClosure => 'Not a closure'; + +testLibraryBase() { + Expect.equals('1 5 6', fakeFunctionCall(5, 6)); + Expect.equals('7, 8', fakeFunctionNSM(7, 8)); + Expect.equals('2 9 10', closure(9, 10)); + Expect.equals('3 11 12 13 null', closureOpt(11, 12, 13)); + Expect.equals('4 14 15 null 16', closureNamed(14, 15, w: 16)); + Expect.throwsNoSuchMethodError(() => closure('wrong arity')); +} + +testLibraryReflective() { + LibraryMirror lm = reflectClass(D).owner as LibraryMirror; + + Expect.equals('1 5 6', lm.invoke(#fakeFunctionCall, [5, 6]).reflectee); + Expect.equals('7, 8', lm.invoke(#fakeFunctionNSM, [7, 8]).reflectee); + Expect.equals('2 9 10', lm.invoke(#closure, [9, 10]).reflectee); + Expect.equals( + '3 11 12 13 null', lm.invoke(#closureOpt, [11, 12, 13]).reflectee); + Expect.equals('4 14 15 null 16', // //# named: continued + lm.invoke(#closureNamed, [14, 15], {#w: 16}).reflectee); // //# named: continued + Expect.throwsNoSuchMethodError(() => lm.invoke(#closure, ['wrong arity'])); +} + +main() { + // Access the getters/closures at the base level in this variant. + testInstanceBase(); + testInstanceReflective(); + testClassBase(); + testClassReflective(); + testLibraryBase(); + testLibraryReflective(); +} diff --git a/tests/lib/mirrors/invoke_call_through_getter_test.dart b/tests/lib/mirrors/invoke_call_through_getter_test.dart new file mode 100644 index 00000000000..57ff6ddb545 --- /dev/null +++ b/tests/lib/mirrors/invoke_call_through_getter_test.dart @@ -0,0 +1,127 @@ +// Copyright (c) 2013, 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. + +library test.invoke_call_through_getter; + +import 'dart:mirrors'; + +import 'package:expect/expect.dart'; + +class FakeFunctionCall { + call(x, y) => '1 $x $y'; +} + +class FakeFunctionNSM { + noSuchMethod(msg) => msg.positionalArguments.join(', '); +} + +class C { + get fakeFunctionCall => new FakeFunctionCall(); + get fakeFunctionNSM => new FakeFunctionNSM(); + get closure => (x, y) => '2 $this $x $y'; + get closureOpt => (x, y, [z, w]) => '3 $this $x $y $z $w'; + get closureNamed => (x, y, {z, w}) => '4 $this $x $y $z $w'; + get notAClosure => 'Not a closure'; + noSuchMethod(msg) => 'DNU'; + + toString() => 'C'; +} + +testInstanceBase() { + dynamic c = new C(); + + Expect.equals('1 5 6', c.fakeFunctionCall(5, 6)); + Expect.equals('7, 8', c.fakeFunctionNSM(7, 8)); + Expect.equals('2 C 9 10', c.closure(9, 10)); + Expect.equals('3 C 11 12 13 null', c.closureOpt(11, 12, 13)); + Expect.equals('4 C 14 15 null 16', c.closureNamed(14, 15, w: 16)); + Expect.equals('DNU', c.doesNotExist(17, 18)); + Expect.throwsNoSuchMethodError(() => c.closure('wrong arity')); + Expect.throwsNoSuchMethodError(() => c.notAClosure()); +} + +testInstanceReflective() { + InstanceMirror im = reflect(new C()); + + Expect.equals('1 5 6', im.invoke(#fakeFunctionCall, [5, 6]).reflectee); + Expect.equals('7, 8', im.invoke(#fakeFunctionNSM, [7, 8]).reflectee); + Expect.equals('2 C 9 10', im.invoke(#closure, [9, 10]).reflectee); + Expect.equals( + '3 C 11 12 13 null', im.invoke(#closureOpt, [11, 12, 13]).reflectee); + Expect.equals('4 C 14 15 null 16', // //# named: ok + im.invoke(#closureNamed, [14, 15], {#w: 16}).reflectee); // //# named: continued + Expect.equals('DNU', im.invoke(#doesNotExist, [17, 18]).reflectee); + Expect.throwsNoSuchMethodError(() => im.invoke(#closure, ['wrong arity'])); + Expect.throwsNoSuchMethodError(() => im.invoke(#notAClosure, [])); +} + +class D { + static get fakeFunctionCall => new FakeFunctionCall(); + static get fakeFunctionNSM => new FakeFunctionNSM(); + static get closure => (x, y) => '2 $x $y'; + static get closureOpt => (x, y, [z, w]) => '3 $x $y $z $w'; + static get closureNamed => (x, y, {z, w}) => '4 $x $y $z $w'; + static get notAClosure => 'Not a closure'; +} + +testClassBase() { + Expect.equals('1 5 6', D.fakeFunctionCall(5, 6)); + Expect.equals('7, 8', D.fakeFunctionNSM(7, 8)); + Expect.equals('2 9 10', D.closure(9, 10)); + Expect.equals('3 11 12 13 null', D.closureOpt(11, 12, 13)); + Expect.equals('4 14 15 null 16', D.closureNamed(14, 15, w: 16)); + Expect.throwsNoSuchMethodError(() => D.closure('wrong arity')); +} + +testClassReflective() { + ClassMirror cm = reflectClass(D); + + Expect.equals('1 5 6', cm.invoke(#fakeFunctionCall, [5, 6]).reflectee); + Expect.equals('7, 8', cm.invoke(#fakeFunctionNSM, [7, 8]).reflectee); + Expect.equals('2 9 10', cm.invoke(#closure, [9, 10]).reflectee); + Expect.equals( + '3 11 12 13 null', cm.invoke(#closureOpt, [11, 12, 13]).reflectee); + Expect.equals('4 14 15 null 16', // //# named: continued + cm.invoke(#closureNamed, [14, 15], {#w: 16}).reflectee); // //# named: continued + Expect.throwsNoSuchMethodError(() => cm.invoke(#closure, ['wrong arity'])); +} + +get fakeFunctionCall => new FakeFunctionCall(); +get fakeFunctionNSM => new FakeFunctionNSM(); +get closure => (x, y) => '2 $x $y'; +get closureOpt => (x, y, [z, w]) => '3 $x $y $z $w'; +get closureNamed => (x, y, {z, w}) => '4 $x $y $z $w'; +get notAClosure => 'Not a closure'; + +testLibraryBase() { + Expect.equals('1 5 6', fakeFunctionCall(5, 6)); + Expect.equals('7, 8', fakeFunctionNSM(7, 8)); + Expect.equals('2 9 10', closure(9, 10)); + Expect.equals('3 11 12 13 null', closureOpt(11, 12, 13)); + Expect.equals('4 14 15 null 16', closureNamed(14, 15, w: 16)); + Expect.throwsNoSuchMethodError(() => closure('wrong arity')); +} + +testLibraryReflective() { + LibraryMirror lm = reflectClass(D).owner as LibraryMirror; + + Expect.equals('1 5 6', lm.invoke(#fakeFunctionCall, [5, 6]).reflectee); + Expect.equals('7, 8', lm.invoke(#fakeFunctionNSM, [7, 8]).reflectee); + Expect.equals('2 9 10', lm.invoke(#closure, [9, 10]).reflectee); + Expect.equals( + '3 11 12 13 null', lm.invoke(#closureOpt, [11, 12, 13]).reflectee); + Expect.equals('4 14 15 null 16', // //# named: continued + lm.invoke(#closureNamed, [14, 15], {#w: 16}).reflectee); // //# named: continued + Expect.throwsNoSuchMethodError(() => lm.invoke(#closure, ['wrong arity'])); +} + +main() { + // Do not access the getters/closures at the base level in this variant. + //testInstanceBase(); + testInstanceReflective(); + //testClassBase(); + testClassReflective(); + //testLibraryBase(); + testLibraryReflective(); +} diff --git a/tests/lib/mirrors/invoke_call_through_implicit_getter_previously_accessed_test.dart b/tests/lib/mirrors/invoke_call_through_implicit_getter_previously_accessed_test.dart new file mode 100644 index 00000000000..2504ea6c983 --- /dev/null +++ b/tests/lib/mirrors/invoke_call_through_implicit_getter_previously_accessed_test.dart @@ -0,0 +1,130 @@ +// Copyright (c) 2014, 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. + +library test.invoke_call_through_implicit_getter; + +import 'dart:mirrors'; + +import 'package:expect/expect.dart'; + +class FakeFunctionCall { + call(x, y) => '1 $x $y'; +} + +class FakeFunctionNSM { + noSuchMethod(msg) => msg.positionalArguments.join(', '); +} + +class C { + var fakeFunctionCall = new FakeFunctionCall(); + var fakeFunctionNSM = new FakeFunctionNSM(); + var closure; // = (x, y) => '2 $this $x $y'; + var closureOpt; // = (x, y, [z, w]) => '3 $this $x $y $z $w'; + var closureNamed; // = (x, y, {z, w}) => '4 $this $x $y $z $w'; + var notAClosure = 'Not a closure'; + noSuchMethod(msg) => 'DNU'; + + C() { + closure = (x, y) => '2 $this $x $y'; + closureOpt = (x, y, [z, w]) => '3 $this $x $y $z $w'; + closureNamed = (x, y, {z, w}) => '4 $this $x $y $z $w'; + } + + toString() => 'C'; +} + +testInstanceBase() { + dynamic c = new C(); + + Expect.equals('1 5 6', c.fakeFunctionCall(5, 6)); + Expect.equals('7, 8', c.fakeFunctionNSM(7, 8)); + Expect.equals('2 C 9 10', c.closure(9, 10)); + Expect.equals('3 C 11 12 13 null', c.closureOpt(11, 12, 13)); + Expect.equals('4 C 14 15 null 16', c.closureNamed(14, 15, w: 16)); + Expect.equals('DNU', c.doesNotExist(17, 18)); + Expect.throwsNoSuchMethodError(() => c.closure('wrong arity')); + Expect.throwsNoSuchMethodError(() => c.notAClosure()); +} + +testInstanceReflective() { + InstanceMirror im = reflect(new C()); + + Expect.equals('1 5 6', im.invoke(#fakeFunctionCall, [5, 6]).reflectee); + Expect.equals('7, 8', im.invoke(#fakeFunctionNSM, [7, 8]).reflectee); + Expect.equals('2 C 9 10', im.invoke(#closure, [9, 10]).reflectee); + Expect.equals( + '3 C 11 12 13 null', im.invoke(#closureOpt, [11, 12, 13]).reflectee); + Expect.equals('4 C 14 15 null 16', // //# named: ok + im.invoke(#closureNamed, [14, 15], {#w: 16}).reflectee); // //# named: continued + Expect.equals('DNU', im.invoke(#doesNotExist, [17, 18]).reflectee); + Expect.throwsNoSuchMethodError(() => im.invoke(#closure, ['wrong arity'])); + Expect.throwsNoSuchMethodError(() => im.invoke(#notAClosure, [])); +} + +class D { + static dynamic fakeFunctionCall = new FakeFunctionCall(); + static dynamic fakeFunctionNSM = new FakeFunctionNSM(); + static var closure = (x, y) => '2 $x $y'; + static var closureOpt = (x, y, [z, w]) => '3 $x $y $z $w'; + static var closureNamed = (x, y, {z, w}) => '4 $x $y $z $w'; + static var notAClosure = 'Not a closure'; +} + +testClassBase() { + Expect.equals('1 5 6', D.fakeFunctionCall(5, 6)); + Expect.equals('7, 8', D.fakeFunctionNSM(7, 8)); + Expect.equals('2 9 10', D.closure(9, 10)); + Expect.equals('3 11 12 13 null', D.closureOpt(11, 12, 13)); + Expect.equals('4 14 15 null 16', D.closureNamed(14, 15, w: 16)); +} + +testClassReflective() { + ClassMirror cm = reflectClass(D); + + Expect.equals('1 5 6', cm.invoke(#fakeFunctionCall, [5, 6]).reflectee); + Expect.equals('7, 8', cm.invoke(#fakeFunctionNSM, [7, 8]).reflectee); + Expect.equals('2 9 10', cm.invoke(#closure, [9, 10]).reflectee); + Expect.equals( + '3 11 12 13 null', cm.invoke(#closureOpt, [11, 12, 13]).reflectee); + Expect.equals('4 14 15 null 16', // //# named: continued + cm.invoke(#closureNamed, [14, 15], {#w: 16}).reflectee); // //# named: continued + Expect.throwsNoSuchMethodError(() => cm.invoke(#closure, ['wrong arity'])); +} + +var fakeFunctionCall = new FakeFunctionCall(); +dynamic fakeFunctionNSM = new FakeFunctionNSM(); +var closure = (x, y) => '2 $x $y'; +var closureOpt = (x, y, [z, w]) => '3 $x $y $z $w'; +var closureNamed = (x, y, {z, w}) => '4 $x $y $z $w'; +var notAClosure = 'Not a closure'; + +testLibraryBase() { + Expect.equals('1 5 6', fakeFunctionCall(5, 6)); + Expect.equals('7, 8', fakeFunctionNSM(7, 8)); + Expect.equals('2 9 10', closure(9, 10)); + Expect.equals('3 11 12 13 null', closureOpt(11, 12, 13)); + Expect.equals('4 14 15 null 16', closureNamed(14, 15, w: 16)); +} + +testLibraryReflective() { + LibraryMirror lm = reflectClass(D).owner as LibraryMirror; + + Expect.equals('1 5 6', lm.invoke(#fakeFunctionCall, [5, 6]).reflectee); + Expect.equals('7, 8', lm.invoke(#fakeFunctionNSM, [7, 8]).reflectee); + Expect.equals('2 9 10', lm.invoke(#closure, [9, 10]).reflectee); + Expect.equals( + '3 11 12 13 null', lm.invoke(#closureOpt, [11, 12, 13]).reflectee); + Expect.equals('4 14 15 null 16', // //# named: continued + lm.invoke(#closureNamed, [14, 15], {#w: 16}).reflectee); // //# named: continued + Expect.throwsNoSuchMethodError(() => lm.invoke(#closure, ['wrong arity'])); +} + +main() { + testInstanceBase(); + testInstanceReflective(); + testClassBase(); + testClassReflective(); + testLibraryBase(); + testLibraryReflective(); +} diff --git a/tests/lib/mirrors/invoke_call_through_implicit_getter_test.dart b/tests/lib/mirrors/invoke_call_through_implicit_getter_test.dart new file mode 100644 index 00000000000..fd0b481a53a --- /dev/null +++ b/tests/lib/mirrors/invoke_call_through_implicit_getter_test.dart @@ -0,0 +1,130 @@ +// Copyright (c) 2014, 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. + +library test.invoke_call_through_implicit_getter; + +import 'dart:mirrors'; + +import 'package:expect/expect.dart'; + +class FakeFunctionCall { + call(x, y) => '1 $x $y'; +} + +class FakeFunctionNSM { + noSuchMethod(msg) => msg.positionalArguments.join(', '); +} + +class C { + dynamic fakeFunctionCall = new FakeFunctionCall(); + dynamic fakeFunctionNSM = new FakeFunctionNSM(); + var closure; // = (x, y) => '2 $this $x $y'; + var closureOpt; // = (x, y, [z, w]) => '3 $this $x $y $z $w'; + var closureNamed; // = (x, y, {z, w}) => '4 $this $x $y $z $w'; + dynamic notAClosure = 'Not a closure'; + noSuchMethod(msg) => 'DNU'; + + C() { + closure = (x, y) => '2 $this $x $y'; + closureOpt = (x, y, [z, w]) => '3 $this $x $y $z $w'; + closureNamed = (x, y, {z, w}) => '4 $this $x $y $z $w'; + } + + toString() => 'C'; +} + +testInstanceBase() { + dynamic c = new C(); + + Expect.equals('1 5 6', c.fakeFunctionCall(5, 6)); + Expect.equals('7, 8', c.fakeFunctionNSM(7, 8)); + Expect.equals('2 C 9 10', c.closure(9, 10)); + Expect.equals('3 C 11 12 13 null', c.closureOpt(11, 12, 13)); + Expect.equals('4 C 14 15 null 16', c.closureNamed(14, 15, w: 16)); + Expect.equals('DNU', c.doesNotExist(17, 18)); + Expect.throwsNoSuchMethodError(() => c.notAClosure()); +} + +testInstanceReflective() { + InstanceMirror im = reflect(new C()); + + Expect.equals('1 5 6', im.invoke(#fakeFunctionCall, [5, 6]).reflectee); + Expect.equals('7, 8', im.invoke(#fakeFunctionNSM, [7, 8]).reflectee); + Expect.equals('2 C 9 10', im.invoke(#closure, [9, 10]).reflectee); + Expect.equals( + '3 C 11 12 13 null', im.invoke(#closureOpt, [11, 12, 13]).reflectee); + Expect.equals('4 C 14 15 null 16', + im.invoke(#closureNamed, [14, 15], {#w: 16}).reflectee); + Expect.equals('DNU', im.invoke(#doesNotExist, [17, 18]).reflectee); + Expect.throwsNoSuchMethodError(() => im.invoke(#closure, ['wrong arity'])); + Expect.throwsNoSuchMethodError(() => im.invoke(#notAClosure, [])); +} + +class D { + static dynamic fakeFunctionCall = new FakeFunctionCall(); + static dynamic fakeFunctionNSM = new FakeFunctionNSM(); + static var closure = (x, y) => '2 $x $y'; + static var closureOpt = (x, y, [z, w]) => '3 $x $y $z $w'; + static var closureNamed = (x, y, {z, w}) => '4 $x $y $z $w'; + static var notAClosure = 'Not a closure'; +} + +testClassBase() { + Expect.equals('1 5 6', D.fakeFunctionCall(5, 6)); + Expect.equals('7, 8', D.fakeFunctionNSM(7, 8)); + Expect.equals('2 9 10', D.closure(9, 10)); + Expect.equals('3 11 12 13 null', D.closureOpt(11, 12, 13)); + Expect.equals('4 14 15 null 16', D.closureNamed(14, 15, w: 16)); +} + +testClassReflective() { + ClassMirror cm = reflectClass(D); + + Expect.equals('1 5 6', cm.invoke(#fakeFunctionCall, [5, 6]).reflectee); + Expect.equals('7, 8', cm.invoke(#fakeFunctionNSM, [7, 8]).reflectee); + Expect.equals('2 9 10', cm.invoke(#closure, [9, 10]).reflectee); + Expect.equals( + '3 11 12 13 null', cm.invoke(#closureOpt, [11, 12, 13]).reflectee); + Expect.equals('4 14 15 null 16', + cm.invoke(#closureNamed, [14, 15], {#w: 16}).reflectee); + Expect.throwsNoSuchMethodError(() => cm.invoke(#closure, ['wrong arity'])); +} + +var fakeFunctionCall = new FakeFunctionCall(); +dynamic fakeFunctionNSM = new FakeFunctionNSM(); +var closure = (x, y) => '2 $x $y'; +var closureOpt = (x, y, [z, w]) => '3 $x $y $z $w'; +var closureNamed = (x, y, {z, w}) => '4 $x $y $z $w'; +var notAClosure = 'Not a closure'; + +testLibraryBase() { + Expect.equals('1 5 6', fakeFunctionCall(5, 6)); + Expect.equals('7, 8', fakeFunctionNSM(7, 8)); + Expect.equals('2 9 10', closure(9, 10)); + Expect.equals('3 11 12 13 null', closureOpt(11, 12, 13)); + Expect.equals('4 14 15 null 16', closureNamed(14, 15, w: 16)); +} + +testLibraryReflective() { + LibraryMirror lm = reflectClass(D).owner as LibraryMirror; + + Expect.equals('1 5 6', lm.invoke(#fakeFunctionCall, [5, 6]).reflectee); + Expect.equals('7, 8', lm.invoke(#fakeFunctionNSM, [7, 8]).reflectee); + Expect.equals('2 9 10', lm.invoke(#closure, [9, 10]).reflectee); + Expect.equals( + '3 11 12 13 null', lm.invoke(#closureOpt, [11, 12, 13]).reflectee); + Expect.equals('4 14 15 null 16', + lm.invoke(#closureNamed, [14, 15], {#w: 16}).reflectee); + Expect.throwsNoSuchMethodError(() => lm.invoke(#closure, ['wrong arity'])); +} + +main() { + // Do not access the getters/closures at the base level in this variant. + //testInstanceBase(); + testInstanceReflective(); + //testClassBase(); + testClassReflective(); + //testLibraryBase(); + testLibraryReflective(); +} diff --git a/tests/lib/mirrors/invoke_closurization2_test.dart b/tests/lib/mirrors/invoke_closurization2_test.dart new file mode 100644 index 00000000000..2e1833031d9 --- /dev/null +++ b/tests/lib/mirrors/invoke_closurization2_test.dart @@ -0,0 +1,129 @@ +// Copyright (c) 2014, 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. + +library test.invoke_closurization_test; + +import 'dart:mirrors'; + +import 'package:expect/expect.dart'; + +class A { + foo() => "foo"; + bar([x]) => "bar-$x"; + gee({named}) => "gee-$named"; + + // Methods that must be intercepted. + + // Tear-offs we will also get without mirrors. + codeUnitAt(x) => "codeUnitAt-$x"; + toUpperCase() => "toUpperCase"; + // indexOf takes an optional argument in String. + indexOf(x) => "indexOf-$x"; + // lastIndexOf matches signature from String. + lastIndexOf(x, [y]) => "lastIndexOf-$x,$y"; + // splitMapJoin matches signature from String. + splitMapJoin(x, {onMatch, onNonMatch}) => + "splitMapJoin-$x,$onMatch,$onNonMatch"; + // Same name as intercepted, but with named argument. + trim({named}) => "trim-$named"; + + // Tear-offs we will not call directly. + endsWith(x) => "endsWith-$x"; + toLowerCase() => "toLowerCase"; + // matchAsPrefix matches signature from String. + matchAsPrefix(x, [y = 0]) => "matchAsPrefix-$x,$y"; + // Matches signature from List + toList({growable: true}) => "toList-$growable"; + // Same name as intercepted, but with named argument. + toSet({named}) => "toSet-$named"; +} + +// The recursive call makes inlining difficult. +// The use of DateTime.now makes the result unpredictable. +confuse(x) { + if (new DateTime.now().millisecondsSinceEpoch == 42) { + return confuse(new DateTime.now().millisecondsSinceEpoch); + } + return x; +} + +main() { + var list = ["foo", new List(), new A()]; + + getAMirror() => reflect(list[confuse(2)]); + + // Tear-off without mirrors. + var f = confuse(getAMirror().reflectee.codeUnitAt); + Expect.equals("codeUnitAt-42", f(42)); + f = confuse(getAMirror().reflectee.toUpperCase); + Expect.equals("toUpperCase", f()); + f = confuse(getAMirror().reflectee.indexOf); + Expect.equals("indexOf-499", f(499)); + f = confuse(getAMirror().reflectee.lastIndexOf); + Expect.equals("lastIndexOf-FOO,BAR", f("FOO", "BAR")); + f = confuse(getAMirror().reflectee.splitMapJoin); + Expect.equals("splitMapJoin-1,2,3", f(1, onMatch: 2, onNonMatch: 3)); + f = confuse(getAMirror().reflectee.trim); + Expect.equals("trim-true", f(named: true)); + + // Now the same thing through mirrors. + f = getAMirror().getField(#codeUnitAt).reflectee; + Expect.equals("codeUnitAt-42", f(42)); + f = getAMirror().getField(#toUpperCase).reflectee; + Expect.equals("toUpperCase", f()); + f = getAMirror().getField(#indexOf).reflectee; + Expect.equals("indexOf-499", f(499)); + f = getAMirror().getField(#lastIndexOf).reflectee; + Expect.equals("lastIndexOf-FOO,BAR", f("FOO", "BAR")); + f = getAMirror().getField(#splitMapJoin).reflectee; + Expect.equals("splitMapJoin-1,2,3", f(1, onMatch: 2, onNonMatch: 3)); + f = getAMirror().getField(#trim).reflectee; + Expect.equals("trim-true", f(named: true)); + + // Now the same thing through mirrors and mirror-invocation. + f = getAMirror().getField(#codeUnitAt); + Expect.equals("codeUnitAt-42", f.invoke(#call, [42], {}).reflectee); + f = getAMirror().getField(#toUpperCase); + Expect.equals("toUpperCase", f.invoke(#call, [], {}).reflectee); + f = getAMirror().getField(#indexOf); + Expect.equals("indexOf-499", f.invoke(#call, [499], {}).reflectee); + f = getAMirror().getField(#lastIndexOf); + Expect.equals( + "lastIndexOf-FOO,BAR", f.invoke(#call, ["FOO", "BAR"]).reflectee); + f = getAMirror().getField(#splitMapJoin); + Expect.equals("splitMapJoin-1,2,3", + f.invoke(#call, [1], {#onMatch: 2, #onNonMatch: 3}).reflectee); + f = getAMirror().getField(#trim); + Expect.equals("trim-true", f.invoke(#call, [], {#named: true}).reflectee); + + // Tear-offs only through mirrors. (No direct selector in the code). + // -------- + + f = getAMirror().getField(#endsWith).reflectee; + Expect.equals("endsWith-42", f(42)); + f = getAMirror().getField(#toLowerCase).reflectee; + Expect.equals("toLowerCase", f()); + f = getAMirror().getField(#indexOf).reflectee; + Expect.equals("indexOf-499", f(499)); + f = getAMirror().getField(#matchAsPrefix).reflectee; + Expect.equals("matchAsPrefix-FOO,BAR", f("FOO", "BAR")); + f = getAMirror().getField(#toList).reflectee; + Expect.equals("toList-1", f(growable: 1)); + f = getAMirror().getField(#toSet).reflectee; + Expect.equals("toSet-true", f(named: true)); + + f = getAMirror().getField(#endsWith); + Expect.equals("endsWith-42", f.invoke(#call, [42], {}).reflectee); + f = getAMirror().getField(#toLowerCase); + Expect.equals("toLowerCase", f.invoke(#call, [], {}).reflectee); + f = getAMirror().getField(#indexOf); + Expect.equals("indexOf-499", f.invoke(#call, [499], {}).reflectee); + f = getAMirror().getField(#matchAsPrefix); + Expect.equals( + "matchAsPrefix-FOO,BAR", f.invoke(#call, ["FOO", "BAR"]).reflectee); + f = getAMirror().getField(#toList); + Expect.equals("toList-1", f.invoke(#call, [], {#growable: 1}).reflectee); + f = getAMirror().getField(#toSet); + Expect.equals("toSet-true", f.invoke(#call, [], {#named: true}).reflectee); +} diff --git a/tests/lib/mirrors/invoke_closurization_test.dart b/tests/lib/mirrors/invoke_closurization_test.dart new file mode 100644 index 00000000000..aa079136532 --- /dev/null +++ b/tests/lib/mirrors/invoke_closurization_test.dart @@ -0,0 +1,40 @@ +// Copyright (c) 2013, 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. + +library test.invoke_closurization_test; + +import 'dart:mirrors'; + +import 'package:expect/expect.dart'; + +class C { + instanceMethod(x, y, z) => '$x+$y+$z'; + static staticFunction(x, y, z) => '$x-$y-$z'; +} + +libraryFunction(x, y, z) => '$x:$y:$z'; + +testSync() { + var result; + + C c = new C(); + InstanceMirror im = reflect(c); + result = im.getField(#instanceMethod); + Expect.isTrue(result.reflectee is Function, "Should be closure"); + Expect.equals("A+B+C", result.reflectee('A', 'B', 'C')); + + ClassMirror cm = reflectClass(C); + result = cm.getField(#staticFunction); + Expect.isTrue(result.reflectee is Function, "Should be closure"); + Expect.equals("A-B-C", result.reflectee('A', 'B', 'C')); + + LibraryMirror lm = cm.owner as LibraryMirror; + result = lm.getField(#libraryFunction); + Expect.isTrue(result.reflectee is Function, "Should be closure"); + Expect.equals("A:B:C", result.reflectee('A', 'B', 'C')); +} + +main() { + testSync(); +} diff --git a/tests/lib/mirrors/invoke_import_test.dart b/tests/lib/mirrors/invoke_import_test.dart new file mode 100644 index 00000000000..7b41c551cc7 --- /dev/null +++ b/tests/lib/mirrors/invoke_import_test.dart @@ -0,0 +1,35 @@ +// Copyright (c) 2013, 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. + +library test.invoke_import_test; + +import 'dart:mirrors'; +import 'package:expect/expect.dart'; + +import 'other_library.dart'; + +main() { + LibraryMirror thisLibrary = + currentMirrorSystem().findLibrary(#test.invoke_import_test); + + Expect.throwsNoSuchMethodError( + () => thisLibrary.invoke(#topLevelMethod, []), + 'Should not invoke imported method #topLevelMethod'); + + Expect.throwsNoSuchMethodError( + () => thisLibrary.getField(#topLevelGetter), + 'Should not invoke imported getter #topLevelGetter'); + + Expect.throwsNoSuchMethodError( + () => thisLibrary.getField(#topLevelField), + 'Should not invoke imported field #topLevelField'); + + Expect.throwsNoSuchMethodError( + () => thisLibrary.setField(#topLevelSetter, 23), + 'Should not invoke imported setter #topLevelSetter'); + + Expect.throwsNoSuchMethodError( + () => thisLibrary.setField(#topLevelField, 23), + 'Should not invoke imported field #topLevelField'); +} diff --git a/tests/lib/mirrors/invoke_named_test.dart b/tests/lib/mirrors/invoke_named_test.dart new file mode 100644 index 00000000000..04d547bc3ca --- /dev/null +++ b/tests/lib/mirrors/invoke_named_test.dart @@ -0,0 +1,288 @@ +// Copyright (c) 2013, 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. + +library test.invoke_named_test; + +import 'dart:mirrors'; + +import 'dart:async' show Future; + +import 'package:expect/expect.dart'; +import 'invoke_test.dart'; + +// TODO(ahe): Remove this variable (http://dartbug.com/12863). +bool isDart2js = false; + +class C { + a(a, {b: 'B', c}) => "$a-$b-$c"; + b({a: 'A', b, c}) => "$a-$b-$c"; + c(a, [b, c = 'C']) => "$a-$b-$c"; + d([a, b = 'B', c = 'C']) => "$a-$b-$c"; + e(a, b, c) => "$a-$b-$c"; +} + +class D { + static a(a, {b: 'B', c}) => "$a-$b-$c"; + static b({a: 'A', b, c}) => "$a-$b-$c"; + static c(a, [b, c = 'C']) => "$a-$b-$c"; + static d([a, b = 'B', c = 'C']) => "$a-$b-$c"; + static e(a, b, c) => "$a-$b-$c"; +} + +class E { + var field; + E(a, {b: 'B', c}) : this.field = "$a-$b-$c"; + E.b({a: 'A', b, c}) : this.field = "$a-$b-$c"; + E.c(a, [b, c = 'C']) : this.field = "$a-$b-$c"; + E.d([a, b = 'B', c = 'C']) : this.field = "$a-$b-$c"; + E.e(a, b, c) : this.field = "$a-$b-$c"; +} + +a(a, {b: 'B', c}) => "$a-$b-$c"; +b({a: 'A', b, c}) => "$a-$b-$c"; +c(a, [b, c = 'C']) => "$a-$b-$c"; +d([a, b = 'B', c = 'C']) => "$a-$b-$c"; +e(a, b, c) => "$a-$b-$c"; + +testSyncInvoke(ObjectMirror om) { + InstanceMirror result; + + result = om.invoke(const Symbol('a'), ['X']); + Expect.equals('X-B-null', result.reflectee); + result = om.invoke(const Symbol('a'), ['X'], {const Symbol('b'): 'Y'}); + Expect.equals('X-Y-null', result.reflectee); + result = om.invoke(const Symbol('a'), ['X'], + {const Symbol('c'): 'Z', const Symbol('b'): 'Y'}); + Expect.equals('X-Y-Z', result.reflectee); + Expect.throwsNoSuchMethodError(() => om.invoke(const Symbol('a'), []), + 'Insufficient positional arguments'); + Expect.throwsNoSuchMethodError(() => om.invoke(const Symbol('a'), ['X', 'Y']), + 'Extra positional arguments'); + Expect.throwsNoSuchMethodError( + () => om.invoke(const Symbol('a'), ['X'], {const Symbol('undef'): 'Y'}), + 'Unmatched named argument'); + + result = om.invoke(const Symbol('b'), []); + Expect.equals('A-null-null', result.reflectee); + result = om.invoke(const Symbol('b'), [], {const Symbol('a'): 'X'}); + Expect.equals('X-null-null', result.reflectee); + result = om.invoke(const Symbol('b'), [], + {const Symbol('b'): 'Y', const Symbol('c'): 'Z', const Symbol('a'): 'X'}); + Expect.equals('X-Y-Z', result.reflectee); + Expect.throwsNoSuchMethodError( + () => om.invoke(const Symbol('b'), ['X']), 'Extra positional arguments'); + Expect.throwsNoSuchMethodError( + () => om.invoke(const Symbol('b'), ['X'], {const Symbol('undef'): 'Y'}), + 'Unmatched named argument'); + + result = om.invoke(const Symbol('c'), ['X']); + Expect.equals('X-null-C', result.reflectee); + result = om.invoke(const Symbol('c'), ['X', 'Y']); + Expect.equals('X-Y-C', result.reflectee); + result = om.invoke(const Symbol('c'), ['X', 'Y', 'Z']); + Expect.equals('X-Y-Z', result.reflectee); + Expect.throwsNoSuchMethodError(() => om.invoke(const Symbol('c'), []), + 'Insufficient positional arguments'); + Expect.throwsNoSuchMethodError( + () => om.invoke(const Symbol('c'), ['X', 'Y', 'Z', 'W']), + 'Extra positional arguments'); + Expect.throwsNoSuchMethodError( + () => om.invoke(const Symbol('c'), ['X'], {const Symbol('undef'): 'Y'}), + 'Unmatched named argument'); + + result = om.invoke(const Symbol('d'), []); + Expect.equals('null-B-C', result.reflectee); + result = om.invoke(const Symbol('d'), ['X']); + Expect.equals('X-B-C', result.reflectee); + result = om.invoke(const Symbol('d'), ['X', 'Y']); + Expect.equals('X-Y-C', result.reflectee); + result = om.invoke(const Symbol('d'), ['X', 'Y', 'Z']); + Expect.equals('X-Y-Z', result.reflectee); + Expect.throwsNoSuchMethodError( + () => om.invoke(const Symbol('d'), ['X', 'Y', 'Z', 'W']), + 'Extra positional arguments'); + Expect.throwsNoSuchMethodError( + () => om.invoke(const Symbol('d'), ['X'], {const Symbol('undef'): 'Y'}), + 'Unmatched named argument'); + + result = om.invoke(const Symbol('e'), ['X', 'Y', 'Z']); + Expect.equals('X-Y-Z', result.reflectee); + Expect.throwsNoSuchMethodError(() => om.invoke(const Symbol('e'), ['X']), + 'Insufficient positional arguments'); + Expect.throwsNoSuchMethodError( + () => om.invoke(const Symbol('e'), ['X', 'Y', 'Z', 'W']), + 'Extra positional arguments'); + Expect.throwsNoSuchMethodError( + () => om.invoke(const Symbol('e'), ['X'], {const Symbol('undef'): 'Y'}), + 'Unmatched named argument'); +} + +testSyncNewInstance() { + ClassMirror cm = reflectClass(E); + InstanceMirror result; + + result = cm.newInstance(Symbol.empty, ['X']); + Expect.equals('X-B-null', result.reflectee.field); + result = cm.newInstance(Symbol.empty, ['X'], {const Symbol('b'): 'Y'}); + Expect.equals('X-Y-null', result.reflectee.field); + result = cm.newInstance( + Symbol.empty, ['X'], {const Symbol('c'): 'Z', const Symbol('b'): 'Y'}); + Expect.equals('X-Y-Z', result.reflectee.field); + Expect.throwsNoSuchMethodError(() => cm.newInstance(Symbol.empty, []), + 'Insufficient positional arguments'); + Expect.throwsNoSuchMethodError(() => cm.newInstance(Symbol.empty, ['X', 'Y']), + 'Extra positional arguments'); + Expect.throwsNoSuchMethodError( + () => cm.newInstance(Symbol.empty, ['X'], {const Symbol('undef'): 'Y'}), + 'Unmatched named argument'); + + result = cm.newInstance(const Symbol('b'), []); + Expect.equals('A-null-null', result.reflectee.field); + result = cm.newInstance(const Symbol('b'), [], {const Symbol('a'): 'X'}); + Expect.equals('X-null-null', result.reflectee.field); + result = cm.newInstance(const Symbol('b'), [], + {const Symbol('b'): 'Y', const Symbol('c'): 'Z', const Symbol('a'): 'X'}); + Expect.equals('X-Y-Z', result.reflectee.field); + Expect.throwsNoSuchMethodError(() => cm.newInstance(const Symbol('b'), ['X']), + 'Extra positional arguments'); + Expect.throwsNoSuchMethodError( + () => cm + .newInstance(const Symbol('b'), ['X'], {const Symbol('undef'): 'Y'}), + 'Unmatched named argument'); + + result = cm.newInstance(const Symbol('c'), ['X']); + Expect.equals('X-null-C', result.reflectee.field); + result = cm.newInstance(const Symbol('c'), ['X', 'Y']); + Expect.equals('X-Y-C', result.reflectee.field); + result = cm.newInstance(const Symbol('c'), ['X', 'Y', 'Z']); + Expect.equals('X-Y-Z', result.reflectee.field); + Expect.throwsNoSuchMethodError(() => cm.newInstance(const Symbol('c'), []), + 'Insufficient positional arguments'); + Expect.throwsNoSuchMethodError( + () => cm.newInstance(const Symbol('c'), ['X', 'Y', 'Z', 'W']), + 'Extra positional arguments'); + Expect.throwsNoSuchMethodError( + () => cm + .newInstance(const Symbol('c'), ['X'], {const Symbol('undef'): 'Y'}), + 'Unmatched named argument'); + + result = cm.newInstance(const Symbol('d'), []); + Expect.equals('null-B-C', result.reflectee.field); + result = cm.newInstance(const Symbol('d'), ['X']); + Expect.equals('X-B-C', result.reflectee.field); + result = cm.newInstance(const Symbol('d'), ['X', 'Y']); + Expect.equals('X-Y-C', result.reflectee.field); + result = cm.newInstance(const Symbol('d'), ['X', 'Y', 'Z']); + Expect.equals('X-Y-Z', result.reflectee.field); + Expect.throwsNoSuchMethodError( + () => cm.newInstance(const Symbol('d'), ['X', 'Y', 'Z', 'W']), + 'Extra positional arguments'); + Expect.throwsNoSuchMethodError( + () => cm + .newInstance(const Symbol('d'), ['X'], {const Symbol('undef'): 'Y'}), + 'Unmatched named argument'); + + result = cm.newInstance(const Symbol('e'), ['X', 'Y', 'Z']); + Expect.equals('X-Y-Z', result.reflectee.field); + Expect.throwsNoSuchMethodError(() => cm.newInstance(const Symbol('e'), ['X']), + 'Insufficient positional arguments'); + Expect.throwsNoSuchMethodError( + () => cm.newInstance(const Symbol('e'), ['X', 'Y', 'Z', 'W']), + 'Extra positional arguments'); + Expect.throwsNoSuchMethodError( + () => cm + .newInstance(const Symbol('e'), ['X'], {const Symbol('undef'): 'Y'}), + 'Unmatched named argument'); +} + +testSyncApply() { + ClosureMirror cm; + InstanceMirror result; + + cm = reflect(a) as ClosureMirror; + result = cm.apply(['X']); + Expect.equals('X-B-null', result.reflectee); + result = cm.apply(['X'], {const Symbol('b'): 'Y'}); + Expect.equals('X-Y-null', result.reflectee); + result = cm.apply(['X'], {const Symbol('c'): 'Z', const Symbol('b'): 'Y'}); + Expect.equals('X-Y-Z', result.reflectee); + Expect.throwsNoSuchMethodError( + () => cm.apply([]), 'Insufficient positional arguments'); + Expect.throwsNoSuchMethodError( + () => cm.apply(['X', 'Y']), 'Extra positional arguments'); + Expect.throwsNoSuchMethodError( + () => cm.apply(['X'], {const Symbol('undef'): 'Y'}), + 'Unmatched named argument'); + + cm = reflect(b) as ClosureMirror; + result = cm.apply([]); + Expect.equals('A-null-null', result.reflectee); + result = cm.apply([], {const Symbol('a'): 'X'}); + Expect.equals('X-null-null', result.reflectee); + result = cm.apply([], + {const Symbol('b'): 'Y', const Symbol('c'): 'Z', const Symbol('a'): 'X'}); + Expect.equals('X-Y-Z', result.reflectee); + Expect.throwsNoSuchMethodError( + () => cm.apply(['X']), 'Extra positional arguments'); + Expect.throwsNoSuchMethodError( + () => cm.apply(['X'], {const Symbol('undef'): 'Y'}), + 'Unmatched named argument'); + + cm = reflect(c) as ClosureMirror; + result = cm.apply(['X']); + Expect.equals('X-null-C', result.reflectee); + result = cm.apply(['X', 'Y']); + Expect.equals('X-Y-C', result.reflectee); + result = cm.apply(['X', 'Y', 'Z']); + Expect.equals('X-Y-Z', result.reflectee); + Expect.throwsNoSuchMethodError( + () => cm.apply([]), 'Insufficient positional arguments'); + Expect.throwsNoSuchMethodError( + () => cm.apply(['X', 'Y', 'Z', 'W']), 'Extra positional arguments'); + Expect.throwsNoSuchMethodError( + () => cm.apply(['X'], {const Symbol('undef'): 'Y'}), + 'Unmatched named argument'); + + cm = reflect(d) as ClosureMirror; + result = cm.apply([]); + Expect.equals('null-B-C', result.reflectee); + result = cm.apply(['X']); + Expect.equals('X-B-C', result.reflectee); + result = cm.apply(['X', 'Y']); + Expect.equals('X-Y-C', result.reflectee); + result = cm.apply(['X', 'Y', 'Z']); + Expect.equals('X-Y-Z', result.reflectee); + Expect.throwsNoSuchMethodError( + () => cm.apply(['X', 'Y', 'Z', 'W']), 'Extra positional arguments'); + Expect.throwsNoSuchMethodError( + () => cm.apply(['X'], {const Symbol('undef'): 'Y'}), + 'Unmatched named argument'); + + cm = reflect(e) as ClosureMirror; + result = cm.apply(['X', 'Y', 'Z']); + Expect.equals('X-Y-Z', result.reflectee); + Expect.throwsNoSuchMethodError( + () => cm.apply(['X']), 'Insufficient positional arguments'); + Expect.throwsNoSuchMethodError( + () => cm.apply(['X', 'Y', 'Z', 'W']), 'Extra positional arguments'); + Expect.throwsNoSuchMethodError( + () => cm.apply(['X'], {const Symbol('undef'): 'Y'}), + 'Unmatched named argument'); +} + +main() { + isDart2js = true; //# 01: ok + + testSyncInvoke(reflect(new C())); // InstanceMirror + + if (isDart2js) return; + + testSyncInvoke(reflectClass(D)); // ClassMirror + LibraryMirror lib = reflectClass(D).owner as LibraryMirror; + testSyncInvoke(lib); // LibraryMirror + + testSyncNewInstance(); + + testSyncApply(); +} diff --git a/tests/lib/mirrors/invoke_natives_malicious_test.dart b/tests/lib/mirrors/invoke_natives_malicious_test.dart new file mode 100644 index 00000000000..43ccb5da9c8 --- /dev/null +++ b/tests/lib/mirrors/invoke_natives_malicious_test.dart @@ -0,0 +1,28 @@ +// Copyright (c) 2014, 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. + +library test.invoke_natives; + +import 'dart:mirrors'; +import 'package:expect/expect.dart'; + +test(name, action) { + print(name); + Expect.throws(action, (e) => true, name); + print("done"); +} + +main() { + LibraryMirror dartcore = reflectClass(Object).owner as LibraryMirror; + + test('List_copyFromObjectArray', () { + var receiver = new List(3); + var selector = MirrorSystem.getSymbol('_copyFromObjectArray', dartcore); + var src = new List(3); + var srcStart = 10; + var dstStart = 10; + var count = 10; + reflect(receiver).invoke(selector, [src, srcStart, dstStart, count]); + }); +} diff --git a/tests/lib/mirrors/invoke_private_test.dart b/tests/lib/mirrors/invoke_private_test.dart new file mode 100644 index 00000000000..753dd9e5c46 --- /dev/null +++ b/tests/lib/mirrors/invoke_private_test.dart @@ -0,0 +1,83 @@ +// Copyright (c) 2013, 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. + +library test.invoke_private_test; + +import 'dart:mirrors'; + +import 'package:expect/expect.dart'; + +class C { + var _field; + C() : this._field = 'default'; + C._named(this._field); + + get _getter => 'get $_field'; + set _setter(v) => _field = 'set $v'; + _method(x, y, z) => '$x+$y+$z'; + + static var _staticField = 'initial'; + static get _staticGetter => 'sget $_staticField'; + static set _staticSetter(v) => _staticField = 'sset $v'; + static _staticFunction(x, y) => "($x,$y)"; +} + +var _libraryField = 'a priori'; +get _libraryGetter => 'lget $_libraryField'; +set _librarySetter(v) => _libraryField = 'lset $v'; +_libraryFunction(x, y) => '$x$y'; + +main() { + var result; + + // InstanceMirror. + C c = new C(); + InstanceMirror im = reflect(c); + result = im.invoke(#_method, [2, 4, 8]); + Expect.equals('2+4+8', result.reflectee); + + result = im.getField(#_getter); + Expect.equals('get default', result.reflectee); + result = im.getField(#_field); + Expect.equals('default', result.reflectee); + + im.setField(#_setter, 'foo'); + Expect.equals('set foo', c._field); + im.setField(#_field, 'bar'); + Expect.equals('bar', c._field); + + // ClassMirror. + ClassMirror cm = reflectClass(C); + result = cm.invoke(#_staticFunction, [3, 4]); + Expect.equals('(3,4)', result.reflectee); + + result = cm.getField(#_staticGetter); + Expect.equals('sget initial', result.reflectee); + result = cm.getField(#_staticField); + Expect.equals('initial', result.reflectee); + + cm.setField(#_staticSetter, 'sfoo'); + Expect.equals('sset sfoo', C._staticField); + cm.setField(#_staticField, 'sbar'); + Expect.equals('sbar', C._staticField); + + result = cm.newInstance(#_named, ['my value']); + Expect.isTrue(result.reflectee is C); + Expect.equals('my value', result.reflectee._field); + + // LibraryMirror. + LibraryMirror lm = cm.owner as LibraryMirror; + result = lm.invoke(#_libraryFunction, [':', ')']); + Expect.equals(':)', result.reflectee); + + result = lm.getField(#_libraryGetter); + Expect.equals('lget a priori', result.reflectee); + result = lm.getField(#_libraryField); + Expect.equals('a priori', result.reflectee); + + lm.setField(#_librarySetter, 'lfoo'); + Expect.equals('lset lfoo', _libraryField); + lm.setField(#_libraryField, 'lbar'); + Expect.equals('lbar', _libraryField); +} diff --git a/tests/lib/mirrors/invoke_private_wrong_library_test.dart b/tests/lib/mirrors/invoke_private_wrong_library_test.dart new file mode 100644 index 00000000000..f0ded320c6d --- /dev/null +++ b/tests/lib/mirrors/invoke_private_wrong_library_test.dart @@ -0,0 +1,40 @@ +// Copyright (c) 2013, 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. + +library test.invoke_test; + +import 'dart:mirrors'; + +import 'package:expect/expect.dart'; +import "package:async_helper/async_helper.dart"; + +import 'invoke_private_test.dart' show C; + +main() { + var result; + + C c = new C(); + InstanceMirror im = reflect(c); + Expect.throwsNoSuchMethodError(() => im.invoke(#_method, [2, 4, 8])); + Expect.throwsNoSuchMethodError(() => im.getField(#_getter)); + Expect.throwsNoSuchMethodError(() => im.getField(#_field)); + Expect.throwsNoSuchMethodError(() => im.setField(#_setter, 'foo')); + Expect.throwsNoSuchMethodError(() => im.setField(#_field, 'bar')); + + ClassMirror cm = reflectClass(C); + Expect.throwsNoSuchMethodError(() => cm.invoke(#_staticFunction, [3, 4])); + Expect.throwsNoSuchMethodError(() => cm.getField(#_staticGetter)); + Expect.throwsNoSuchMethodError(() => cm.getField(#_staticField)); + Expect.throwsNoSuchMethodError(() => cm.setField(#_staticSetter, 'sfoo')); + Expect.throwsNoSuchMethodError(() => cm.setField(#_staticField, 'sbar')); + Expect.throwsNoSuchMethodError(() => cm.newInstance(#_named, ['my value'])); + + LibraryMirror lm = cm.owner as LibraryMirror; + Expect.throwsNoSuchMethodError( + () => lm.invoke(#_libraryFunction, [':', ')'])); + Expect.throwsNoSuchMethodError(() => lm.getField(#_libraryGetter)); + Expect.throwsNoSuchMethodError(() => lm.getField(#_libraryField)); + Expect.throwsNoSuchMethodError(() => lm.setField(#_librarySetter, 'lfoo')); + Expect.throwsNoSuchMethodError(() => lm.setField(#_libraryField, 'lbar')); +} diff --git a/tests/lib/mirrors/invoke_test.dart b/tests/lib/mirrors/invoke_test.dart new file mode 100644 index 00000000000..fd5215fd6ec --- /dev/null +++ b/tests/lib/mirrors/invoke_test.dart @@ -0,0 +1,145 @@ +// Copyright (c) 2013, 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. + +library test.invoke_test; + +import 'dart:mirrors'; + +import 'dart:async' show Future; + +import 'package:expect/expect.dart'; + +class C { + var field; + C() : this.field = 'default'; + C.named(this.field); + + get getter => 'get $field'; + set setter(v) => field = 'set $v'; + method(x, y, z) => '$x+$y+$z'; + toString() => 'a C'; + + noSuchMethod(invocation) => 'DNU'; + + static var staticField = 'initial'; + static get staticGetter => 'sget $staticField'; + static set staticSetter(v) => staticField = 'sset $v'; + static staticFunction(x, y) => "($x,$y)"; +} + +var libraryField = 'a priori'; +get libraryGetter => 'lget $libraryField'; +set librarySetter(v) => libraryField = 'lset $v'; +libraryFunction(x, y) => '$x$y'; + +testSync() { + var result; + + // InstanceMirror invoke + C c = new C(); + InstanceMirror im = reflect(c); + result = im.invoke(const Symbol('method'), [2, 4, 8]); + Expect.equals('2+4+8', result.reflectee); + result = im.invoke(const Symbol('doesntExist'), [2, 4, 8]); + Expect.equals('DNU', result.reflectee); + result = im.invoke(const Symbol('method'), [2, 4]); // Wrong arity. + Expect.equals('DNU', result.reflectee); + + // InstanceMirror invokeGetter + result = im.getField(const Symbol('getter')); + Expect.equals('get default', result.reflectee); + result = im.getField(const Symbol('field')); + Expect.equals('default', result.reflectee); + result = im.getField(const Symbol('doesntExist')); + Expect.equals('DNU', result.reflectee); + + // InstanceMirror invokeSetter + result = im.setField(const Symbol('setter'), 'foo'); + Expect.equals('foo', result.reflectee); + Expect.equals('set foo', c.field); + Expect.equals('set foo', im.getField(const Symbol('field')).reflectee); + result = im.setField(const Symbol('field'), 'bar'); + Expect.equals('bar', result.reflectee); + Expect.equals('bar', c.field); + Expect.equals('bar', im.getField(const Symbol('field')).reflectee); + result = im.setField(const Symbol('doesntExist'), 'bar'); + Expect.equals('bar', result.reflectee); + + // ClassMirror invoke + ClassMirror cm = reflectClass(C); + result = cm.invoke(const Symbol('staticFunction'), [3, 4]); + Expect.equals('(3,4)', result.reflectee); + Expect.throwsNoSuchMethodError( + () => cm.invoke(const Symbol('doesntExist'), [3, 4]), 'Not defined'); + Expect.throwsNoSuchMethodError( + () => cm.invoke(const Symbol('staticFunction'), [3]), 'Wrong arity'); + + // ClassMirror invokeGetter + result = cm.getField(const Symbol('staticGetter')); + Expect.equals('sget initial', result.reflectee); + result = cm.getField(const Symbol('staticField')); + Expect.equals('initial', result.reflectee); + Expect.throwsNoSuchMethodError( + () => cm.getField(const Symbol('doesntExist')), 'Not defined'); + + // ClassMirror invokeSetter + result = cm.setField(const Symbol('staticSetter'), 'sfoo'); + Expect.equals('sfoo', result.reflectee); + Expect.equals('sset sfoo', C.staticField); + Expect.equals( + 'sset sfoo', cm.getField(const Symbol('staticField')).reflectee); + result = cm.setField(const Symbol('staticField'), 'sbar'); + Expect.equals('sbar', result.reflectee); + Expect.equals('sbar', C.staticField); + Expect.equals('sbar', cm.getField(const Symbol('staticField')).reflectee); + Expect.throwsNoSuchMethodError( + () => cm.setField(const Symbol('doesntExist'), 'sbar'), 'Not defined'); + + // ClassMirror invokeConstructor + result = cm.newInstance(Symbol.empty, []); + Expect.isTrue(result.reflectee is C); + Expect.equals('default', result.reflectee.field); + result = cm.newInstance(const Symbol('named'), ['my value']); + Expect.isTrue(result.reflectee is C); + Expect.equals('my value', result.reflectee.field); + Expect.throwsNoSuchMethodError( + () => cm.newInstance(const Symbol('doesntExist'), ['my value']), + 'Not defined'); + Expect.throwsNoSuchMethodError( + () => cm.newInstance(const Symbol('named'), []), 'Wrong arity'); + + // LibraryMirror invoke + LibraryMirror lm = cm.owner as LibraryMirror; + result = lm.invoke(const Symbol('libraryFunction'), [':', ')']); + Expect.equals(':)', result.reflectee); + Expect.throwsNoSuchMethodError( + () => lm.invoke(const Symbol('doesntExist'), [':', ')']), 'Not defined'); + Expect.throwsNoSuchMethodError( + () => lm.invoke(const Symbol('libraryFunction'), [':']), 'Wrong arity'); + + // LibraryMirror invokeGetter + result = lm.getField(const Symbol('libraryGetter')); + Expect.equals('lget a priori', result.reflectee); + result = lm.getField(const Symbol('libraryField')); + Expect.equals('a priori', result.reflectee); + Expect.throwsNoSuchMethodError( + () => lm.getField(const Symbol('doesntExist')), 'Not defined'); + + // LibraryMirror invokeSetter + result = lm.setField(const Symbol('librarySetter'), 'lfoo'); + Expect.equals('lfoo', result.reflectee); + Expect.equals('lset lfoo', libraryField); + Expect.equals( + 'lset lfoo', lm.getField(const Symbol('libraryField')).reflectee); + result = lm.setField(const Symbol('libraryField'), 'lbar'); + Expect.equals('lbar', result.reflectee); + Expect.equals('lbar', libraryField); + Expect.equals('lbar', lm.getField(const Symbol('libraryField')).reflectee); + Expect.throwsNoSuchMethodError( + () => lm.setField(const Symbol('doesntExist'), 'lbar'), 'Not defined'); +} + +main() { + testSync(); +} diff --git a/tests/lib/mirrors/invoke_throws_test.dart b/tests/lib/mirrors/invoke_throws_test.dart new file mode 100644 index 00000000000..59f5b2f7383 --- /dev/null +++ b/tests/lib/mirrors/invoke_throws_test.dart @@ -0,0 +1,87 @@ +// Copyright (c) 2013, 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. + +library test.invoke_throws_test; + +import 'dart:mirrors'; + +import 'package:expect/expect.dart'; + +class MyException {} + +class Class { + Class.noException(); + Class.generative() { + throw new MyException(); + } + Class.redirecting() : this.generative(); + factory Class.faktory() { + throw new MyException(); + } + factory Class.redirectingFactory() = Class.faktory; + + get getter { + throw new MyException(); + } + + set setter(v) { + throw new MyException(); + } + + method() { + throw new MyException(); + } + + noSuchMethod(invocation) { + throw new MyException(); + } + + static get staticGetter { + throw new MyException(); + } + + static set staticSetter(v) { + throw new MyException(); + } + + static staticFunction() { + throw new MyException(); + } +} + +get libraryGetter { + throw new MyException(); +} + +set librarySetter(v) { + throw new MyException(); +} + +libraryFunction() { + throw new MyException(); +} + +bool isMyException(e) => e is MyException; + +main() { + InstanceMirror im = reflect(new Class.noException()); + Expect.throws(() => im.getField(#getter), isMyException); + Expect.throws(() => im.setField(#setter, ['arg']), isMyException); + Expect.throws(() => im.invoke(#method, []), isMyException); + Expect.throws(() => im.invoke(#triggerNoSuchMethod, []), isMyException); + + ClassMirror cm = reflectClass(Class); + Expect.throws(() => cm.getField(#staticGetter), isMyException); + Expect.throws(() => cm.setField(#staticSetter, ['arg']), isMyException); + Expect.throws(() => cm.invoke(#staticFunction, []), isMyException); + Expect.throws(() => cm.newInstance(#generative, []), isMyException); + Expect.throws(() => cm.newInstance(#redirecting, []), isMyException); + Expect.throws(() => cm.newInstance(#faktory, []), isMyException); + Expect.throws(() => cm.newInstance(#redirectingFactory, []), isMyException); + + LibraryMirror lm = reflectClass(Class).owner as LibraryMirror; + Expect.throws(() => lm.getField(#libraryGetter), isMyException); + Expect.throws(() => lm.setField(#librarySetter, ['arg']), isMyException); + Expect.throws(() => lm.invoke(#libraryFunction, []), isMyException); +} diff --git a/tests/lib/mirrors/io_html_mutual_exclusion_test.dart b/tests/lib/mirrors/io_html_mutual_exclusion_test.dart new file mode 100644 index 00000000000..087b8a63c95 --- /dev/null +++ b/tests/lib/mirrors/io_html_mutual_exclusion_test.dart @@ -0,0 +1,17 @@ +// Copyright (c) 2015, 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. + +library test.io_html_mutual_exclusion; + +import 'dart:mirrors'; + +main() { + var libraries = currentMirrorSystem().libraries; + bool has_io = libraries[Uri.parse('dart:io')] != null; + bool has_html = libraries[Uri.parse('dart:html')] != null; + + if (has_io && has_html) { + throw "No embedder should have both dart:io and dart:html accessible"; + } +} diff --git a/tests/lib/mirrors/is_odd_test.dart b/tests/lib/mirrors/is_odd_test.dart new file mode 100644 index 00000000000..0dc1655c824 --- /dev/null +++ b/tests/lib/mirrors/is_odd_test.dart @@ -0,0 +1,16 @@ +// Copyright (c) 2013, 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 otherwise unused intercepted methods are reified correctly. This +/// was a bug in dart2js. +library test.is_odd_test; + +import 'dart:mirrors'; + +import 'package:expect/expect.dart'; + +main() { + Expect.isTrue(reflect(1).getField(#isOdd).reflectee); + Expect.isFalse(reflect(2).getField(#isOdd).reflectee); +} diff --git a/tests/lib/mirrors/issue21079_test.dart b/tests/lib/mirrors/issue21079_test.dart new file mode 100644 index 00000000000..c376df0fad5 --- /dev/null +++ b/tests/lib/mirrors/issue21079_test.dart @@ -0,0 +1,20 @@ +// Copyright (c) 2013, 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. + +// Regression test case for http://dartbug.com/21079 +import 'dart:mirrors'; +import 'dart:isolate'; +import "package:expect/expect.dart"; + +void main() { + Expect.isTrue(reflectClass(MyException).superclass.reflectedType == + IsolateSpawnException); + + Expect.isTrue(reflectClass(IsolateSpawnException).reflectedType == + IsolateSpawnException); +} + +class MyException extends IsolateSpawnException { + MyException() : super("Test") {} +} diff --git a/tests/lib/mirrors/lazy_static_test.dart b/tests/lib/mirrors/lazy_static_test.dart new file mode 100644 index 00000000000..65ac90929d9 --- /dev/null +++ b/tests/lib/mirrors/lazy_static_test.dart @@ -0,0 +1,33 @@ +// Copyright (c) 2013, 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 static members. + +import 'dart:mirrors'; + +import 'package:expect/expect.dart'; + +import 'stringify.dart'; + +class Foo { + static dynamic hello = { + 'a': 'b', + 'c': 'd', + }; +} + +void main() { + expect('Variable(s(hello) in s(Foo), static)', + reflectClass(Foo).declarations[#hello]); + var reflectee = reflectClass(Foo).getField(#hello).reflectee; + Expect.stringEquals('a, c', reflectee.keys.join(', ')); + // Call the lazy getter twice as different things probably happen in the + // underlying implementation. + reflectee = reflectClass(Foo).getField(#hello).reflectee; + Expect.stringEquals('a, c', reflectee.keys.join(', ')); + var value = 'fisk'; + Foo.hello = value; + reflectee = reflectClass(Foo).getField(#hello).reflectee; + Expect.identical(value, reflectee); +} diff --git a/tests/lib/mirrors/libraries_test.dart b/tests/lib/mirrors/libraries_test.dart new file mode 100644 index 00000000000..43566567602 --- /dev/null +++ b/tests/lib/mirrors/libraries_test.dart @@ -0,0 +1,35 @@ +// Copyright (c) 2013, 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. + +library test.libraries_test; + +import 'dart:mirrors'; + +import 'package:expect/expect.dart'; + +main() { + MirrorSystem mirrors = currentMirrorSystem(); + Expect.isNotNull(mirrors, 'mirrors is null'); + + Map libraries = mirrors.libraries; + Expect.isNotNull(libraries, 'libraries is null'); + + Expect.isTrue(libraries.isNotEmpty); + LibraryMirror mirrorsLibrary = libraries[Uri.parse('dart:mirrors')]; + if (mirrorsLibrary == null) { + // In minified mode we don't preserve the URIs. + mirrorsLibrary = libraries.values + .firstWhere((LibraryMirror lm) => lm.simpleName == #dart.mirrors); + Uri uri = mirrorsLibrary.uri; + Expect.equals("https", uri.scheme); + Expect.equals("dartlang.org", uri.host); + Expect.equals("/dart2js-stripped-uri", uri.path); + } + + ClassMirror cls = mirrorsLibrary.declarations[#LibraryMirror] as ClassMirror; + Expect.isNotNull(cls, 'cls is null'); + + Expect.equals(#dart.mirrors.LibraryMirror, cls.qualifiedName); + Expect.equals(reflectClass(LibraryMirror), cls); +} diff --git a/tests/lib/mirrors/library_declarations_test.dart b/tests/lib/mirrors/library_declarations_test.dart new file mode 100644 index 00000000000..80cd982c8ed --- /dev/null +++ b/tests/lib/mirrors/library_declarations_test.dart @@ -0,0 +1,129 @@ +// Copyright (c) 2013, 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. + +library test.library_declarations_test; + +import 'dart:mirrors'; +import 'package:expect/expect.dart'; + +import 'stringify.dart'; +import 'declarations_model.dart' as declarations_model; + +main() { + LibraryMirror lm = + currentMirrorSystem().findLibrary(#test.declarations_model); + + Expect.setEquals([ + 'Variable(s(_libraryVariable)' + ' in s(test.declarations_model), private, top-level, static)', + 'Variable(s(libraryVariable)' + ' in s(test.declarations_model), top-level, static)' + ], lm.declarations.values.where((dm) => dm is VariableMirror).map(stringify), + 'variables'); + + // dart2js stops testing here. + return; // //# 01: ok + + Expect.setEquals( + [ + 'Method(s(_libraryGetter)' + ' in s(test.declarations_model), private, top-level, static, getter)', + 'Method(s(libraryGetter)' + ' in s(test.declarations_model), top-level, static, getter)' + ], + lm.declarations.values + .where((dm) => dm is MethodMirror && dm.isGetter) + .map(stringify), + 'getters'); + + Expect.setEquals( + [ + 'Method(s(_librarySetter=)' + ' in s(test.declarations_model), private, top-level, static, setter)', + 'Method(s(librarySetter=)' + ' in s(test.declarations_model), top-level, static, setter)' + ], + lm.declarations.values + .where((dm) => dm is MethodMirror && dm.isSetter) + .map(stringify), + 'setters'); + + Expect.setEquals( + [ + 'Method(s(_libraryMethod)' + ' in s(test.declarations_model), private, top-level, static)', + 'Method(s(libraryMethod)' + ' in s(test.declarations_model), top-level, static)' + ], + lm.declarations.values + .where((dm) => dm is MethodMirror && dm.isRegularMethod) + .map(stringify), + 'regular methods'); + + Expect.setEquals([ + 'Class(s(Class) in s(test.declarations_model), top-level)', + 'Class(s(ConcreteClass) in s(test.declarations_model), top-level)', + 'Class(s(Interface) in s(test.declarations_model), top-level)', + 'Class(s(Mixin) in s(test.declarations_model), top-level)', + 'Class(s(Superclass) in s(test.declarations_model), top-level)', + 'Class(s(_PrivateClass)' + ' in s(test.declarations_model), private, top-level)' + ], lm.declarations.values.where((dm) => dm is ClassMirror).map(stringify), + 'classes'); + + Expect.setEquals([ + 'Class(s(Class) in s(test.declarations_model), top-level)', + 'Class(s(ConcreteClass) in s(test.declarations_model), top-level)', + 'Class(s(Interface) in s(test.declarations_model), top-level)', + 'Class(s(Mixin) in s(test.declarations_model), top-level)', + 'Type(s(Predicate) in s(test.declarations_model), top-level)', + 'Class(s(Superclass) in s(test.declarations_model), top-level)', + 'Class(s(_PrivateClass)' + ' in s(test.declarations_model), private, top-level)' + ], lm.declarations.values.where((dm) => dm is TypeMirror).map(stringify), + 'types'); + + Expect.setEquals([ + 'Class(s(Class) in s(test.declarations_model), top-level)', + 'Class(s(ConcreteClass) in s(test.declarations_model), top-level)', + 'Class(s(Interface) in s(test.declarations_model), top-level)', + 'Class(s(Mixin) in s(test.declarations_model), top-level)', + 'Type(s(Predicate) in s(test.declarations_model), top-level)', + 'Class(s(Superclass) in s(test.declarations_model), top-level)', + 'Method(s(libraryGetter)' + ' in s(test.declarations_model), top-level, static, getter)', + 'Method(s(libraryMethod)' + ' in s(test.declarations_model), top-level, static)', + 'Method(s(librarySetter=)' + ' in s(test.declarations_model), top-level, static, setter)', + 'Variable(s(libraryVariable)' + ' in s(test.declarations_model), top-level, static)' + ], lm.declarations.values.where((dm) => !dm.isPrivate).map(stringify), + 'public'); + + Expect.setEquals([ + 'Class(s(Class) in s(test.declarations_model), top-level)', + 'Class(s(ConcreteClass) in s(test.declarations_model), top-level)', + 'Class(s(Interface) in s(test.declarations_model), top-level)', + 'Class(s(Mixin) in s(test.declarations_model), top-level)', + 'Type(s(Predicate) in s(test.declarations_model), top-level)', + 'Class(s(Superclass) in s(test.declarations_model), top-level)', + 'Class(s(_PrivateClass) in s(test.declarations_model), private, top-level)', + 'Method(s(_libraryGetter)' + ' in s(test.declarations_model), private, top-level, static, getter)', + 'Method(s(_libraryMethod)' + ' in s(test.declarations_model), private, top-level, static)', + 'Method(s(_librarySetter=)' + ' in s(test.declarations_model), private, top-level, static, setter)', + 'Variable(s(_libraryVariable)' + ' in s(test.declarations_model), private, top-level, static)', + 'Method(s(libraryGetter)' + ' in s(test.declarations_model), top-level, static, getter)', + 'Method(s(libraryMethod) in s(test.declarations_model), top-level, static)', + 'Method(s(librarySetter=)' + ' in s(test.declarations_model), top-level, static, setter)', + 'Variable(s(libraryVariable)' + ' in s(test.declarations_model), top-level, static)' + ], lm.declarations.values.map(stringify), 'all declarations'); +} diff --git a/tests/lib/mirrors/library_enumeration_deferred_loading_test.dart b/tests/lib/mirrors/library_enumeration_deferred_loading_test.dart new file mode 100644 index 00000000000..7783b74e9c7 --- /dev/null +++ b/tests/lib/mirrors/library_enumeration_deferred_loading_test.dart @@ -0,0 +1,26 @@ +// Copyright (c) 2015, 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. + +library library_enumeration_deferred_loading; + +import 'dart:mirrors'; +import 'package:expect/expect.dart'; +import 'package:async_helper/async_helper.dart'; + +import 'other_library.dart' deferred as other; + +main() { + var ms = currentMirrorSystem(); + Expect.throws(() => ms.findLibrary(#test.other_library), (e) => true, + "should not be loaded yet"); + + asyncStart(); + other.loadLibrary().then((_) { + asyncEnd(); + LibraryMirror otherMirror = ms.findLibrary(#test.other_library); + Expect.isNotNull(otherMirror); + Expect.equals(#test.other_library, otherMirror.simpleName); + Expect.equals(42, other.topLevelMethod()); + }); +} diff --git a/tests/lib/mirrors/library_exports_hidden.dart b/tests/lib/mirrors/library_exports_hidden.dart new file mode 100644 index 00000000000..c1ea0813f74 --- /dev/null +++ b/tests/lib/mirrors/library_exports_hidden.dart @@ -0,0 +1,10 @@ +// Copyright (c) 2014, 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. + +library library_exports_hidden; + +export 'library_imports_a.dart' hide somethingFromA, somethingFromBoth; +export 'library_imports_b.dart' hide somethingFromB; + +var somethingFromHidden; diff --git a/tests/lib/mirrors/library_exports_hidden_test.dart b/tests/lib/mirrors/library_exports_hidden_test.dart new file mode 100644 index 00000000000..e69fef4e431 --- /dev/null +++ b/tests/lib/mirrors/library_exports_hidden_test.dart @@ -0,0 +1,34 @@ +// Copyright (c) 2014, 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. + +library test.library_exports_hidden; + +import 'dart:mirrors'; +import 'package:expect/expect.dart'; +import 'stringify.dart'; + +import 'library_exports_hidden.dart'; + +test(MirrorSystem mirrors) { + LibraryMirror hidden = mirrors.findLibrary(#library_exports_hidden); + LibraryMirror a = mirrors.findLibrary(#library_imports_a); + LibraryMirror b = mirrors.findLibrary(#library_imports_b); + LibraryMirror core = mirrors.findLibrary(#dart.core); + + Expect.setEquals( + [a, b, core], hidden.libraryDependencies.map((dep) => dep.targetLibrary)); + + Expect.stringEquals( + 'import dart.core\n' + 'export library_imports_a\n' + ' hide somethingFromA\n' + ' hide somethingFromBoth\n' + 'export library_imports_b\n' + ' hide somethingFromB\n', + stringifyDependencies(hidden)); +} + +main() { + test(currentMirrorSystem()); +} diff --git a/tests/lib/mirrors/library_exports_shown.dart b/tests/lib/mirrors/library_exports_shown.dart new file mode 100644 index 00000000000..524ab4c1b28 --- /dev/null +++ b/tests/lib/mirrors/library_exports_shown.dart @@ -0,0 +1,10 @@ +// Copyright (c) 2014, 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. + +library library_exports_shown; + +export 'library_imports_a.dart' show somethingFromA, somethingFromBoth; +export 'library_imports_b.dart' show somethingFromB; + +var somethingFromShown; diff --git a/tests/lib/mirrors/library_exports_shown_test.dart b/tests/lib/mirrors/library_exports_shown_test.dart new file mode 100644 index 00000000000..003de2fce05 --- /dev/null +++ b/tests/lib/mirrors/library_exports_shown_test.dart @@ -0,0 +1,35 @@ +// Copyright (c) 2014, 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. + +library test.library_exports_shown; + +import 'dart:mirrors'; +import 'package:expect/expect.dart'; +import 'stringify.dart'; + +import 'library_exports_shown.dart'; + +test(MirrorSystem mirrors) { + LibraryMirror shown = mirrors.findLibrary(#library_exports_shown); + LibraryMirror a = mirrors.findLibrary(#library_imports_a); + LibraryMirror b = mirrors.findLibrary(#library_imports_b); + + LibraryMirror core = mirrors.findLibrary(#dart.core); + + Expect.setEquals( + [a, b, core], shown.libraryDependencies.map((dep) => dep.targetLibrary)); + + Expect.stringEquals( + 'import dart.core\n' + 'export library_imports_a\n' + ' show somethingFromA\n' + ' show somethingFromBoth\n' + 'export library_imports_b\n' + ' show somethingFromB\n', + stringifyDependencies(shown)); +} + +main() { + test(currentMirrorSystem()); +} diff --git a/tests/lib/mirrors/library_import_deferred_loading_test.dart b/tests/lib/mirrors/library_import_deferred_loading_test.dart new file mode 100644 index 00000000000..9b228273a42 --- /dev/null +++ b/tests/lib/mirrors/library_import_deferred_loading_test.dart @@ -0,0 +1,28 @@ +// Copyright (c) 2015, 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. + +library library_loading_deferred_loading; + +import 'dart:mirrors'; +import 'package:expect/expect.dart'; +import 'stringify.dart'; +import 'package:async_helper/async_helper.dart'; + +import 'other_library.dart' deferred as other; + +main() { + var ms = currentMirrorSystem(); + LibraryMirror thisLibrary = ms.findLibrary(#library_loading_deferred_loading); + LibraryDependencyMirror dep = + thisLibrary.libraryDependencies.singleWhere((d) => d.prefix == #other); + Expect.isNull(dep.targetLibrary, "should not be loaded yet"); + + asyncStart(); + other.loadLibrary().then((_) { + asyncEnd(); + Expect.isNotNull(dep.targetLibrary); + Expect.equals(#test.other_library, dep.targetLibrary.simpleName); + Expect.equals(42, other.topLevelMethod()); + }); +} diff --git a/tests/lib/mirrors/library_imports_a.dart b/tests/lib/mirrors/library_imports_a.dart new file mode 100644 index 00000000000..afdc329c609 --- /dev/null +++ b/tests/lib/mirrors/library_imports_a.dart @@ -0,0 +1,8 @@ +// Copyright (c) 2014, 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. + +library library_imports_a; + +var somethingFromA; +var somethingFromBoth; diff --git a/tests/lib/mirrors/library_imports_b.dart b/tests/lib/mirrors/library_imports_b.dart new file mode 100644 index 00000000000..493f3239ae4 --- /dev/null +++ b/tests/lib/mirrors/library_imports_b.dart @@ -0,0 +1,8 @@ +// Copyright (c) 2014, 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. + +library library_imports_b; + +var somethingFromB; +var somethingFromBoth; diff --git a/tests/lib/mirrors/library_imports_bad_metadata_test.dart b/tests/lib/mirrors/library_imports_bad_metadata_test.dart new file mode 100644 index 00000000000..43d873bab70 --- /dev/null +++ b/tests/lib/mirrors/library_imports_bad_metadata_test.dart @@ -0,0 +1,18 @@ +// Copyright (c) 2014, 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. + +library test.library_imports_bad_metadata; + +@undefined // //# 01: compile-time error +import 'dart:mirrors'; +import 'package:expect/expect.dart'; + +main() { + LibraryMirror thisLibrary = + currentMirrorSystem().findLibrary(#test.library_imports_bad_metadata); + + thisLibrary.libraryDependencies.forEach((dep) { + Expect.listEquals([], dep.metadata); + }); +} diff --git a/tests/lib/mirrors/library_imports_deferred_test.dart b/tests/lib/mirrors/library_imports_deferred_test.dart new file mode 100644 index 00000000000..ab2668da781 --- /dev/null +++ b/tests/lib/mirrors/library_imports_deferred_test.dart @@ -0,0 +1,44 @@ +// Copyright (c) 2015, 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. + +library test.library_imports_deferred; + +import 'dart:mirrors'; +import 'package:expect/expect.dart'; +import 'stringify.dart'; + +import 'dart:collection' as eagercollection; +import 'dart:collection' deferred as lazycollection; + +test(MirrorSystem mirrors) { + LibraryMirror thisLibrary = + mirrors.findLibrary(#test.library_imports_deferred); + LibraryMirror collection = mirrors.findLibrary(#dart.collection); + + var importsOfCollection = thisLibrary.libraryDependencies + .where((dep) => dep.targetLibrary == collection) + .toList(); + Expect.equals(2, importsOfCollection.length); + Expect.notEquals(importsOfCollection[0].isDeferred, + importsOfCollection[1].isDeferred); // One deferred, one not. + + // Only collection is defer-imported. + LibraryDependencyMirror dep = + thisLibrary.libraryDependencies.singleWhere((dep) => dep.isDeferred); + Expect.equals(collection, dep.targetLibrary); + + Expect.stringEquals( + 'import dart.collection as eagercollection\n' + 'import dart.collection deferred as lazycollection\n' + ' hide loadLibrary\n' + 'import dart.core\n' + 'import dart.mirrors\n' + 'import expect\n' + 'import test.stringify\n', + stringifyDependencies(thisLibrary)); +} + +main() { + test(currentMirrorSystem()); +} diff --git a/tests/lib/mirrors/library_imports_hidden.dart b/tests/lib/mirrors/library_imports_hidden.dart new file mode 100644 index 00000000000..deccc64ad16 --- /dev/null +++ b/tests/lib/mirrors/library_imports_hidden.dart @@ -0,0 +1,10 @@ +// Copyright (c) 2014, 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. + +library library_imports_hidden; + +import 'library_imports_a.dart' hide somethingFromA, somethingFromBoth; +import 'library_imports_b.dart' hide somethingFromB; + +var somethingFromHidden; diff --git a/tests/lib/mirrors/library_imports_hidden_test.dart b/tests/lib/mirrors/library_imports_hidden_test.dart new file mode 100644 index 00000000000..edc19e077aa --- /dev/null +++ b/tests/lib/mirrors/library_imports_hidden_test.dart @@ -0,0 +1,34 @@ +// Copyright (c) 2014, 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. + +library test.library_imports_hidden; + +import 'dart:mirrors'; +import 'package:expect/expect.dart'; +import 'stringify.dart'; + +import 'library_imports_hidden.dart'; + +test(MirrorSystem mirrors) { + LibraryMirror hidden = mirrors.findLibrary(#library_imports_hidden); + LibraryMirror a = mirrors.findLibrary(#library_imports_a); + LibraryMirror b = mirrors.findLibrary(#library_imports_b); + LibraryMirror core = mirrors.findLibrary(#dart.core); + + Expect.setEquals( + [a, b, core], hidden.libraryDependencies.map((dep) => dep.targetLibrary)); + + Expect.stringEquals( + 'import dart.core\n' + 'import library_imports_a\n' + ' hide somethingFromA\n' + ' hide somethingFromBoth\n' + 'import library_imports_b\n' + ' hide somethingFromB\n', + stringifyDependencies(hidden)); +} + +main() { + test(currentMirrorSystem()); +} diff --git a/tests/lib/mirrors/library_imports_metadata.dart b/tests/lib/mirrors/library_imports_metadata.dart new file mode 100644 index 00000000000..15e0403b1a6 --- /dev/null +++ b/tests/lib/mirrors/library_imports_metadata.dart @@ -0,0 +1,18 @@ +// Copyright (c) 2014, 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. + +library library_imports_metadata; + +@m1 +import 'dart:mirrors' as mirrors; + +@m2 +@m3 +import 'dart:collection'; + +import 'dart:async'; + +const m1 = const Object(); +const m2 = const Object(); +const m3 = const Object(); diff --git a/tests/lib/mirrors/library_imports_metadata_test.dart b/tests/lib/mirrors/library_imports_metadata_test.dart new file mode 100644 index 00000000000..ab1c15d66a2 --- /dev/null +++ b/tests/lib/mirrors/library_imports_metadata_test.dart @@ -0,0 +1,56 @@ +// Copyright (c) 2014, 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. + +library test.library_imports; + +import 'dart:mirrors'; +import 'package:expect/expect.dart'; +import 'stringify.dart'; + +import 'library_imports_metadata.dart'; + +main() { + LibraryMirror lib = + currentMirrorSystem().findLibrary(#library_imports_metadata); + + LibraryMirror core = currentMirrorSystem().findLibrary(#dart.core); + LibraryMirror mirrors = currentMirrorSystem().findLibrary(#dart.mirrors); + LibraryMirror collection = + currentMirrorSystem().findLibrary(#dart.collection); + LibraryMirror async = currentMirrorSystem().findLibrary(#dart.async); + + Expect.setEquals([core, mirrors, collection, async], + lib.libraryDependencies.map((dep) => dep.targetLibrary)); + + Expect.stringEquals( + 'import dart.async\n' + 'import dart.collection\n' + 'import dart.core\n' + 'import dart.mirrors as mirrors\n', + stringifyDependencies(lib)); + + Expect.listEquals( + [].map(reflect).toList(), + lib.libraryDependencies + .singleWhere((dep) => dep.targetLibrary == core) + .metadata); + + Expect.listEquals( + [m1].map(reflect).toList(), + lib.libraryDependencies + .singleWhere((dep) => dep.targetLibrary == mirrors) + .metadata); + + Expect.listEquals( + [m2, m3].map(reflect).toList(), + lib.libraryDependencies + .singleWhere((dep) => dep.targetLibrary == collection) + .metadata); + + Expect.listEquals( + [].map(reflect).toList(), + lib.libraryDependencies + .singleWhere((dep) => dep.targetLibrary == async) + .metadata); +} diff --git a/tests/lib/mirrors/library_imports_prefixed.dart b/tests/lib/mirrors/library_imports_prefixed.dart new file mode 100644 index 00000000000..ad50f424766 --- /dev/null +++ b/tests/lib/mirrors/library_imports_prefixed.dart @@ -0,0 +1,10 @@ +// Copyright (c) 2014, 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. + +library library_imports_prefixed; + +import 'library_imports_a.dart' as prefixa; +import 'library_imports_b.dart' as prefixb; + +var somethingFromPrefixed; diff --git a/tests/lib/mirrors/library_imports_prefixed_show_hide.dart b/tests/lib/mirrors/library_imports_prefixed_show_hide.dart new file mode 100644 index 00000000000..ea7c71fa93f --- /dev/null +++ b/tests/lib/mirrors/library_imports_prefixed_show_hide.dart @@ -0,0 +1,10 @@ +// Copyright (c) 2014, 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. + +library library_imports_prefixed_show_hide; + +import 'library_imports_a.dart' as prefixa show somethingFromA; +import 'library_imports_b.dart' as prefixb hide somethingFromB; + +var somethingFromPrefixed; diff --git a/tests/lib/mirrors/library_imports_prefixed_show_hide_test.dart b/tests/lib/mirrors/library_imports_prefixed_show_hide_test.dart new file mode 100644 index 00000000000..a4089c0c81e --- /dev/null +++ b/tests/lib/mirrors/library_imports_prefixed_show_hide_test.dart @@ -0,0 +1,34 @@ +// Copyright (c) 2014, 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. + +library test.library_imports_prefixed_show_hide; + +import 'dart:mirrors'; +import 'package:expect/expect.dart'; +import 'stringify.dart'; + +import 'library_imports_prefixed_show_hide.dart'; + +test(MirrorSystem mirrors) { + LibraryMirror prefixed_show_hide = + mirrors.findLibrary(#library_imports_prefixed_show_hide); + LibraryMirror a = mirrors.findLibrary(#library_imports_a); + LibraryMirror b = mirrors.findLibrary(#library_imports_b); + LibraryMirror core = mirrors.findLibrary(#dart.core); + + Expect.setEquals([a, b, core], + prefixed_show_hide.libraryDependencies.map((dep) => dep.targetLibrary)); + + Expect.stringEquals( + 'import dart.core\n' + 'import library_imports_a as prefixa\n' + ' show somethingFromA\n' + 'import library_imports_b as prefixb\n' + ' hide somethingFromB\n', + stringifyDependencies(prefixed_show_hide)); +} + +main() { + test(currentMirrorSystem()); +} diff --git a/tests/lib/mirrors/library_imports_prefixed_test.dart b/tests/lib/mirrors/library_imports_prefixed_test.dart new file mode 100644 index 00000000000..7915fae49ed --- /dev/null +++ b/tests/lib/mirrors/library_imports_prefixed_test.dart @@ -0,0 +1,31 @@ +// Copyright (c) 2014, 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. + +library test.library_imports_prefixed; + +import 'dart:mirrors'; +import 'package:expect/expect.dart'; +import 'stringify.dart'; + +import 'library_imports_prefixed.dart'; + +test(MirrorSystem mirrors) { + LibraryMirror prefixed = mirrors.findLibrary(#library_imports_prefixed); + LibraryMirror a = mirrors.findLibrary(#library_imports_a); + LibraryMirror b = mirrors.findLibrary(#library_imports_b); + LibraryMirror core = mirrors.findLibrary(#dart.core); + + Expect.setEquals([a, b, core], + prefixed.libraryDependencies.map((dep) => dep.targetLibrary)); + + Expect.stringEquals( + 'import dart.core\n' + 'import library_imports_a as prefixa\n' + 'import library_imports_b as prefixb\n', + stringifyDependencies(prefixed)); +} + +main() { + test(currentMirrorSystem()); +} diff --git a/tests/lib/mirrors/library_imports_shown.dart b/tests/lib/mirrors/library_imports_shown.dart new file mode 100644 index 00000000000..6790902e695 --- /dev/null +++ b/tests/lib/mirrors/library_imports_shown.dart @@ -0,0 +1,10 @@ +// Copyright (c) 2014, 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. + +library library_imports_shown; + +import 'library_imports_a.dart' show somethingFromA, somethingFromBoth; +import 'library_imports_b.dart' show somethingFromB; + +var somethingFromShown; diff --git a/tests/lib/mirrors/library_imports_shown_test.dart b/tests/lib/mirrors/library_imports_shown_test.dart new file mode 100644 index 00000000000..44086e21f8b --- /dev/null +++ b/tests/lib/mirrors/library_imports_shown_test.dart @@ -0,0 +1,34 @@ +// Copyright (c) 2014, 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. + +library test.library_imports_shown; + +import 'dart:mirrors'; +import 'package:expect/expect.dart'; +import 'stringify.dart'; + +import 'library_imports_shown.dart'; + +test(MirrorSystem mirrors) { + LibraryMirror shown = mirrors.findLibrary(#library_imports_shown); + LibraryMirror a = mirrors.findLibrary(#library_imports_a); + LibraryMirror b = mirrors.findLibrary(#library_imports_b); + LibraryMirror core = mirrors.findLibrary(#dart.core); + + Expect.setEquals( + [a, b, core], shown.libraryDependencies.map((dep) => dep.targetLibrary)); + + Expect.stringEquals( + 'import dart.core\n' + 'import library_imports_a\n' + ' show somethingFromA\n' + ' show somethingFromBoth\n' + 'import library_imports_b\n' + ' show somethingFromB\n', + stringifyDependencies(shown)); +} + +main() { + test(currentMirrorSystem()); +} diff --git a/tests/lib/mirrors/library_metadata2_lib1.dart b/tests/lib/mirrors/library_metadata2_lib1.dart new file mode 100644 index 00000000000..75149b362cf --- /dev/null +++ b/tests/lib/mirrors/library_metadata2_lib1.dart @@ -0,0 +1,10 @@ +// Copyright (c) 2013, 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. + +@MyConst() +library lib1; + +class MyConst { + const MyConst(); +} diff --git a/tests/lib/mirrors/library_metadata2_lib2.dart b/tests/lib/mirrors/library_metadata2_lib2.dart new file mode 100644 index 00000000000..b8a447f07f4 --- /dev/null +++ b/tests/lib/mirrors/library_metadata2_lib2.dart @@ -0,0 +1,6 @@ +// Copyright (c) 2013, 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. + +@MyConst() +library lib2; diff --git a/tests/lib/mirrors/library_metadata2_test.dart b/tests/lib/mirrors/library_metadata2_test.dart new file mode 100644 index 00000000000..b6fc2d9ba1a --- /dev/null +++ b/tests/lib/mirrors/library_metadata2_test.dart @@ -0,0 +1,16 @@ +// Copyright (c) 2013, 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. + +import 'dart:mirrors'; + +import 'library_metadata2_lib1.dart'; + +import 'library_metadata2_lib2.dart'; //# 01: compile-time error + +void main() { + for (var library in currentMirrorSystem().libraries.values) { + print(library.metadata); // Processing @MyConst() in lib2 results in a + // delayed compilation error here. + } +} diff --git a/tests/lib/mirrors/library_metadata_test.dart b/tests/lib/mirrors/library_metadata_test.dart new file mode 100644 index 00000000000..2a85166806c --- /dev/null +++ b/tests/lib/mirrors/library_metadata_test.dart @@ -0,0 +1,18 @@ +// Copyright (c) 2013, 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. + +@string +@symbol +library test.library_metadata_test; + +import 'dart:mirrors'; + +import 'metadata_test.dart'; + +main() { + MirrorSystem mirrors = currentMirrorSystem(); + checkMetadata( + mirrors.findLibrary(#test.library_metadata_test), [string, symbol]); + checkMetadata(mirrors.findLibrary(#test.metadata_test), []); +} diff --git a/tests/lib/mirrors/library_metatarget_test.dart b/tests/lib/mirrors/library_metatarget_test.dart new file mode 100644 index 00000000000..6800bab91b6 --- /dev/null +++ b/tests/lib/mirrors/library_metatarget_test.dart @@ -0,0 +1,16 @@ +// Copyright (c) 2013, 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. + +// Regression test for the combined use of metatargets and library tags. + +library topLib; + +import 'library_metatarget_test_lib.dart'; +import 'library_metatarget_test_annotations_lib.dart'; + +import 'dart:mirrors'; + +void main() { + print(new A()); +} diff --git a/tests/lib/mirrors/library_metatarget_test_annotations_lib.dart b/tests/lib/mirrors/library_metatarget_test_annotations_lib.dart new file mode 100644 index 00000000000..9464fa7f1da --- /dev/null +++ b/tests/lib/mirrors/library_metatarget_test_annotations_lib.dart @@ -0,0 +1,19 @@ +// Copyright (c) 2013, 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. + +// Regression test for the combined use of metatargets and library tags. + +library annotations; + +class UsedOnlyOnLibrary { + const UsedOnlyOnLibrary(); +} + +const usedOnlyOnLibrary = const UsedOnlyOnLibrary(); + +class Reflectable { + const Reflectable(); +} + +const Reflectable reflectable = const Reflectable(); diff --git a/tests/lib/mirrors/library_metatarget_test_lib.dart b/tests/lib/mirrors/library_metatarget_test_lib.dart new file mode 100644 index 00000000000..f8126c17478 --- /dev/null +++ b/tests/lib/mirrors/library_metatarget_test_lib.dart @@ -0,0 +1,16 @@ +// Copyright (c) 2013, 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. + +// Regression test for the combined use of metatargets and library tags. + +@usedOnlyOnLibrary +library subLib; + +import 'library_metatarget_test_annotations_lib.dart'; + +class A { + @reflectable + var reflectableField = 1; + var nonreflectableField = 2; +} diff --git a/tests/lib/mirrors/library_uri_io_test.dart b/tests/lib/mirrors/library_uri_io_test.dart new file mode 100644 index 00000000000..84008438487 --- /dev/null +++ b/tests/lib/mirrors/library_uri_io_test.dart @@ -0,0 +1,29 @@ +// Copyright (c) 2013, 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 library uri for a library read as a file. + +library MirrorsTest; + +import 'dart:io'; +import 'dart:mirrors'; + +import 'package:async_helper/async_minitest.dart'; + +class Class {} + +testLibraryUri(var value, Uri expectedUri) { + var valueMirror = reflect(value); + ClassMirror valueClass = valueMirror.type; + LibraryMirror valueLibrary = valueClass.owner as LibraryMirror; + expect(valueLibrary.uri, equals(expectedUri)); +} + +main() { + var mirrors = currentMirrorSystem(); + test("Test current library uri", () { + Uri uri = Uri.base.resolveUri(Platform.script); + testLibraryUri(new Class(), uri); + }); +} diff --git a/tests/lib/mirrors/library_uri_package_test.dart b/tests/lib/mirrors/library_uri_package_test.dart new file mode 100644 index 00000000000..01160054cab --- /dev/null +++ b/tests/lib/mirrors/library_uri_package_test.dart @@ -0,0 +1,31 @@ +// Copyright (c) 2011, 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 library uri for a library read as a package . + +library MirrorsTest; + +import 'dart:mirrors'; +import 'package:args/args.dart'; +import 'package:async_helper/async_minitest.dart'; + +testLibraryUri(var value, Uri expectedUri) { + var valueMirror = reflect(value); + ClassMirror valueClass = valueMirror.type; + LibraryMirror valueLibrary = valueClass.owner as LibraryMirror; + Uri uri = valueLibrary.uri; + if (uri.scheme != "https" || + uri.host != "dartlang.org" || + uri.path != "/dart2js-stripped-uri") { + expect(uri, equals(expectedUri)); + } +} + +main() { + var mirrors = currentMirrorSystem(); + test("Test package library uri", () { + testLibraryUri( + new ArgParser(), Uri.parse('package:args/src/arg_parser.dart')); + }); +} diff --git a/tests/lib/mirrors/library_with_annotated_declaration.dart b/tests/lib/mirrors/library_with_annotated_declaration.dart new file mode 100644 index 00000000000..07a498ba2cc --- /dev/null +++ b/tests/lib/mirrors/library_with_annotated_declaration.dart @@ -0,0 +1,10 @@ +// Copyright (c) 2015, 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. + +@metadata +library library_with_annotated_declaration; + +const metadata = 'metadata'; + +class ClassInLibraryWithAnnotatedDeclaration {} diff --git a/tests/lib/mirrors/library_without_declaration.dart b/tests/lib/mirrors/library_without_declaration.dart new file mode 100644 index 00000000000..d9e1fe4a20f --- /dev/null +++ b/tests/lib/mirrors/library_without_declaration.dart @@ -0,0 +1,7 @@ +// Copyright (c) 2015, 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. + +// NO LIBRARY DECLARATION + +class ClassInLibraryWithoutDeclaration {} diff --git a/tests/lib/mirrors/list_constructor_test.dart b/tests/lib/mirrors/list_constructor_test.dart new file mode 100644 index 00000000000..16f3c45b889 --- /dev/null +++ b/tests/lib/mirrors/list_constructor_test.dart @@ -0,0 +1,30 @@ +// Copyright (c) 2013, 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. + +import "package:expect/expect.dart"; + +import 'dart:mirrors'; + +main() { + var cls = reflectClass(List); + Expect.throwsArgumentError(() => cls.newInstance(Symbol.empty, [null])); + + var list = cls.newInstance(Symbol.empty, [42]).reflectee; + // Check that the list is fixed. + Expect.equals(42, list.length); + Expect.throwsUnsupportedError(() => list.add(2)); + list[0] = 1; + Expect.equals(1, list[0]); + + testGrowableList(); //# 01: ok +} + +testGrowableList() { + var cls = reflectClass(List); + var list = cls.newInstance(Symbol.empty, []).reflectee; + // Check that the list is growable. + Expect.equals(0, list.length); + list.add(42); + Expect.equals(1, list.length); +} diff --git a/tests/lib/mirrors/load_library_test.dart b/tests/lib/mirrors/load_library_test.dart new file mode 100644 index 00000000000..a43d3f24aff --- /dev/null +++ b/tests/lib/mirrors/load_library_test.dart @@ -0,0 +1,27 @@ +// Copyright (c) 2015, 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. + +library load_library; + +import 'dart:mirrors'; +import 'package:expect/expect.dart'; +import 'package:async_helper/async_helper.dart'; + +import 'other_library.dart' deferred as other; + +main() { + var ms = currentMirrorSystem(); + LibraryMirror thisLibrary = ms.findLibrary(#load_library); + var dep = + thisLibrary.libraryDependencies.singleWhere((d) => d.prefix == #other); + Expect.isNull(dep.targetLibrary, "should not be loaded yet"); + + asyncStart(); + dep.loadLibrary().then((_) { + asyncEnd(); + Expect.isNotNull(dep.targetLibrary); + Expect.equals(#test.other_library, dep.targetLibrary.simpleName); + Expect.equals(42, other.topLevelMethod()); + }); +} diff --git a/tests/lib/mirrors/local_function_is_static_test.dart b/tests/lib/mirrors/local_function_is_static_test.dart new file mode 100644 index 00000000000..131fb757507 --- /dev/null +++ b/tests/lib/mirrors/local_function_is_static_test.dart @@ -0,0 +1,44 @@ +// Copyright (c) 2014, 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. + +library test.local_function_is_static; + +import 'dart:mirrors'; +import 'package:expect/expect.dart'; + +topLevel() => 1; +topLevelLocal() => () => 2; + +class C { + static klass() => 3; + static klassLocal() => () => 4; + instance() => 5; + instanceLocal() => () => 6; +} + +main() { + var f = topLevel; + Expect.equals(1, f()); + Expect.isTrue((reflect(f) as ClosureMirror).function.isStatic); + + f = topLevelLocal(); + Expect.equals(2, f()); + Expect.isTrue((reflect(f) as ClosureMirror).function.isStatic); + + f = C.klass; + Expect.equals(3, f()); + Expect.isTrue((reflect(f) as ClosureMirror).function.isStatic); + + f = C.klassLocal(); + Expect.equals(4, f()); + Expect.isTrue((reflect(f) as ClosureMirror).function.isStatic); + + f = new C().instance; + Expect.equals(5, f()); + Expect.isFalse((reflect(f) as ClosureMirror).function.isStatic); + + f = new C().instanceLocal(); + Expect.equals(6, f()); + Expect.isFalse((reflect(f) as ClosureMirror).function.isStatic); +} diff --git a/tests/lib/mirrors/local_isolate_test.dart b/tests/lib/mirrors/local_isolate_test.dart new file mode 100644 index 00000000000..e619812368e --- /dev/null +++ b/tests/lib/mirrors/local_isolate_test.dart @@ -0,0 +1,21 @@ +// Copyright (c) 2013, 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 the local IsolateMirror. + +library test.local_isolate_test; + +import 'dart:mirrors'; + +import 'package:expect/expect.dart'; + +class Foo {} + +void main() { + LibraryMirror rootLibrary = reflectClass(Foo).owner as LibraryMirror; + IsolateMirror isolate = currentMirrorSystem().isolate; + Expect.isTrue(isolate.debugName is String); + Expect.isTrue(isolate.isCurrent); + Expect.equals(rootLibrary, isolate.rootLibrary); +} diff --git a/tests/lib/mirrors/metadata_allowed_values_import.dart b/tests/lib/mirrors/metadata_allowed_values_import.dart new file mode 100644 index 00000000000..67df4e21ab2 --- /dev/null +++ b/tests/lib/mirrors/metadata_allowed_values_import.dart @@ -0,0 +1,9 @@ +// Copyright (c) 2013, 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. + +class Imported { + const Imported(); + const Imported.named(); + static const CONSTANT = 0; +} diff --git a/tests/lib/mirrors/metadata_allowed_values_test.dart b/tests/lib/mirrors/metadata_allowed_values_test.dart new file mode 100644 index 00000000000..32047304613 --- /dev/null +++ b/tests/lib/mirrors/metadata_allowed_values_test.dart @@ -0,0 +1,224 @@ +// Copyright (c) 2013, 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. + +library test.metadata_allowed_values; + +import 'dart:mirrors'; +import 'package:expect/expect.dart'; + +import 'metadata_allowed_values_import.dart'; // Unprefixed. +import 'metadata_allowed_values_import.dart' as prefix; + +@A // //# 01: compile-time error +class A {} + +@B.CONSTANT +class B { + static const CONSTANT = 3; +} + +@C(3) +class C { + final field; + const C(this.field); +} + +@D.named(4) +class D { + final field; + const D.named(this.field); +} + +@E.NOT_CONSTANT // //# 02: compile-time error +class E { + static var NOT_CONSTANT = 3; +} + +@F(6) // //# 03: compile-time error +class F { + final field; + F(this.field); +} + +@G.named(4) // //# 04: compile-time error +class G { + final field; + G.named(this.field); +} + +@H() // //# 05: compile-time error +class H { + const H(); +} + +@I[0] // //# 06: compile-time error +class I {} + +@this.toString // //# 07: compile-time error +class J {} + +@super.toString // //# 08: compile-time error +class K {} + +@L.func() // //# 09: compile-time error +class L { + static func() => 6; +} + +@Imported // //# 10: compile-time error +class M {} + +@Imported() +class N {} + +@Imported.named() +class O {} + +@Imported.CONSTANT +class P {} + +@prefix.Imported // //# 11: compile-time error +class Q {} + +@prefix.Imported() +class R {} + +@prefix.Imported.named() +class S {} + +@prefix.Imported.CONSTANT +class T {} + +@U..toString() // //# 12: compile-time error +class U {} + +@V.tearOff // //# 13: compile-time error +class V { + static tearOff() {} +} + +topLevelTearOff() => 4; + +@topLevelTearOff // //# 14: compile-time error +class W {} + +@TypeParameter // //# 15: compile-time error +class X {} + +@TypeParameter.member // //# 16: compile-time error +class Y {} + +@1 // //# 17: compile-time error +class Z {} + +@3.14 // //# 18: compile-time error +class AA {} + +@'string' // //# 19: compile-time error +class BB {} + +@#symbol // //# 20: compile-time error +class CC {} + +@['element'] // //# 21: compile-time error +class DD {} + +@{'key': 'value'} // //# 22: compile-time error +class EE {} + +@true // //# 23: compile-time error +class FF {} + +@false // //# 24: compile-time error +class GG {} + +@null // //# 25: compile-time error +class HH {} + +const a = const [1, 2, 3]; + +@a +class II {} + +@a[0] // //# 26: compile-time error +class JJ {} + +@kk // //# 27: compile-time error +class KK { + const KK(); +} + +get kk => const KK(); + +@LL(() => 42) // //# 28: compile-time error +class LL { + final field; + const LL(this.field); +} + +@MM((x) => 42) // //# 29: compile-time error +class MM { + final field; + const MM(this.field); +} + +@NN(() {}) // //# 30: compile-time error +class NN { + final field; + const NN(this.field); +} + +@OO(() { () {} }) // //# 31: compile-time error +class OO { + final field; + const OO(this.field); +} + +checkMetadata(DeclarationMirror mirror, List expectedMetadata) { + Expect.listEquals(expectedMetadata.map(reflect).toList(), mirror.metadata); +} + +main() { + reflectClass(A).metadata; + checkMetadata(reflectClass(B), [B.CONSTANT]); + checkMetadata(reflectClass(C), [const C(3)]); + checkMetadata(reflectClass(D), [const D.named(4)]); + reflectClass(E).metadata; + reflectClass(F).metadata; + reflectClass(G).metadata; + reflectClass(H).metadata; + reflectClass(I).metadata; + reflectClass(J).metadata; + reflectClass(K).metadata; + reflectClass(L).metadata; + reflectClass(M).metadata; + checkMetadata(reflectClass(N), [const Imported()]); + checkMetadata(reflectClass(O), [const Imported.named()]); + checkMetadata(reflectClass(P), [Imported.CONSTANT]); + reflectClass(Q).metadata; + checkMetadata(reflectClass(R), [const prefix.Imported()]); + checkMetadata(reflectClass(S), [const prefix.Imported.named()]); + checkMetadata(reflectClass(T), [prefix.Imported.CONSTANT]); + reflectClass(U).metadata; + reflectClass(V).metadata; + reflectClass(W).metadata; + reflectClass(X).metadata; + reflectClass(Y).metadata; + reflectClass(Z).metadata; + reflectClass(AA).metadata; + reflectClass(BB).metadata; + reflectClass(CC).metadata; + reflectClass(DD).metadata; + reflectClass(EE).metadata; + reflectClass(FF).metadata; + reflectClass(GG).metadata; + reflectClass(HH).metadata; + reflectClass(II).metadata; + reflectClass(JJ).metadata; + reflectClass(KK).metadata; + reflectClass(LL).metadata; + reflectClass(MM).metadata; + reflectClass(NN).metadata; + reflectClass(OO).metadata; +} diff --git a/tests/lib/mirrors/metadata_class_mirror_test.dart b/tests/lib/mirrors/metadata_class_mirror_test.dart new file mode 100644 index 00000000000..9dab02494e7 --- /dev/null +++ b/tests/lib/mirrors/metadata_class_mirror_test.dart @@ -0,0 +1,22 @@ +// Copyright (c) 2014, 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. + +// Regression test for http://dartbug.com/19173 + +library lib; + +import 'dart:mirrors'; + +class A { + const A(); +} + +@deprecated +const A anA = const A(); + +main() { + ClassMirror typeMirror = reflectType(A) as ClassMirror; + var decs = typeMirror.declarations; + print(decs.length); +} diff --git a/tests/lib/mirrors/metadata_const_map_test.dart b/tests/lib/mirrors/metadata_const_map_test.dart new file mode 100644 index 00000000000..dcf8376e59f --- /dev/null +++ b/tests/lib/mirrors/metadata_const_map_test.dart @@ -0,0 +1,22 @@ +// Copyright (c) 2014, 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. + +// Regression test for issue 20776. Tests that the needed classes for the +// constant map in the metadata are generated. + +library lib; + +import 'dart:mirrors'; + +class C { + final x; + const C(this.x); +} + +@C(const {'foo': 'bar'}) +class A {} + +main() { + print(reflectClass(A).metadata); +} diff --git a/tests/lib/mirrors/metadata_constructed_constant_test.dart b/tests/lib/mirrors/metadata_constructed_constant_test.dart new file mode 100644 index 00000000000..16746a02c11 --- /dev/null +++ b/tests/lib/mirrors/metadata_constructed_constant_test.dart @@ -0,0 +1,27 @@ +// compile options: --emit-metadata +// Copyright (c) 2013, 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. + +library test.metadata_constructed_constant_test; + +import 'dart:mirrors'; + +import 'package:expect/expect.dart'; + +class ConstructedConstant { + final value; + const ConstructedConstant(this.value); + toString() => 'ConstructedConstant($value)'; +} + +class Foo { + @ConstructedConstant(StateError) + m() {} +} + +main() { + var m = reflectClass(Foo).declarations[#m] as MethodMirror; + var value = m.metadata.single.reflectee; + Expect.stringEquals('ConstructedConstant($StateError)', '$value'); +} diff --git a/tests/lib/mirrors/metadata_constructor_arguments_test.dart b/tests/lib/mirrors/metadata_constructor_arguments_test.dart new file mode 100644 index 00000000000..bc459e911ae --- /dev/null +++ b/tests/lib/mirrors/metadata_constructor_arguments_test.dart @@ -0,0 +1,73 @@ +// compile options: --emit-metadata +// Copyright (c) 2013, 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. + +// Regression test for Issue 13817. + +library test.metadata_constructor_arguments; + +import 'dart:mirrors'; +import 'package:expect/expect.dart'; + +class Tag { + final name; + const Tag({named}) : this.name = named; +} + +@Tag(named: undefined) // //# 01: compile-time error +class A {} + +@Tag(named: 'valid') +class B {} + +@Tag(named: C.STATIC_FIELD) +class C { + static const STATIC_FIELD = 3; +} + +@Tag(named: D.instanceMethod()) // //# 02: compile-time error +class D { + instanceMethod() {} +} + +@Tag(named: instanceField) // //# 03: compile-time error +class E { + var instanceField; +} + +@Tag(named: F.nonConstStaticField) // //# 04: compile-time error +class F { + static var nonConstStaticField = 6; +} + +@Tag(named: instanceMethod) // //# 05: compile-time error +class G { + instanceMethod() {} +} + +@Tag(named: this) // //# 06: compile-time error +class H { + instanceMethod() {} +} + +@Tag(named: super) // //# 07: compile-time error +class I { + instanceMethod() {} +} + +checkMetadata(DeclarationMirror mirror, List expectedMetadata) { + Expect.listEquals(expectedMetadata.map(reflect).toList(), mirror.metadata); +} + +main() { + reflectClass(A).metadata; + checkMetadata(reflectClass(B), [const Tag(named: 'valid')]); + checkMetadata(reflectClass(C), [const Tag(named: C.STATIC_FIELD)]); + reflectClass(D).metadata; + reflectClass(E).metadata; + reflectClass(F).metadata; + reflectClass(G).metadata; + reflectClass(H).metadata; + reflectClass(I).metadata; +} diff --git a/tests/lib/mirrors/metadata_nested_constructor_call_test.dart b/tests/lib/mirrors/metadata_nested_constructor_call_test.dart new file mode 100644 index 00000000000..d2edccc8b2c --- /dev/null +++ b/tests/lib/mirrors/metadata_nested_constructor_call_test.dart @@ -0,0 +1,86 @@ +// compile options: --emit-metadata +// Copyright (c) 2014, 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. + +// Regression test for Issue 17141. + +library test.metadata_nested_constructor_call; + +import 'dart:mirrors'; +import 'package:expect/expect.dart'; + +class Box { + final contents; + const Box([this.contents]); +} + +class MutableBox { + var contents; + MutableBox([this.contents]); // Not const. +} + +@Box() +class A {} + +@Box(const Box()) +class B {} + +@Box(const Box(const Box())) +class C {} + +@Box(const Box(const MutableBox())) // //# 01: compile-time error +class D {} + +@Box(const MutableBox(const Box())) // //# 02: compile-time error +class E {} + +@Box(Box()) +class F {} + +@Box(Box(const Box())) +class G {} + +@Box(Box(const MutableBox())) // //# 05: compile-time error +class H {} + +@Box(MutableBox(const Box())) // //# 06: compile-time error +class I {} + +final closure = () => 42; + +@Box(closure()) // //# 07: compile-time error +class J {} + +@Box(closure) // //# 08: compile-time error +class K {} + +function() => 42; + +@Box(function()) // //# 09: compile-time error +class L {} + +// N.B. This is legal, but @function is not (tested by metadata_allowed_values). +@Box(function) +class M {} + +checkMetadata(DeclarationMirror mirror, List expectedMetadata) { + Expect.listEquals(expectedMetadata.map(reflect).toList(), mirror.metadata); +} + +main() { + closure(); + checkMetadata(reflectClass(A), [const Box()]); + checkMetadata(reflectClass(B), [const Box(const Box())]); + checkMetadata(reflectClass(C), [const Box(const Box(const Box()))]); + reflectClass(D).metadata; + reflectClass(E).metadata; + reflectClass(F).metadata; + reflectClass(G).metadata; + reflectClass(H).metadata; + reflectClass(I).metadata; + reflectClass(J).metadata; + reflectClass(K).metadata; + reflectClass(L).metadata; + reflectClass(M).metadata; +} diff --git a/tests/lib/mirrors/metadata_scope_test.dart b/tests/lib/mirrors/metadata_scope_test.dart new file mode 100644 index 00000000000..521dee6563a --- /dev/null +++ b/tests/lib/mirrors/metadata_scope_test.dart @@ -0,0 +1,63 @@ +// Copyright (c) 2014, 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. + +library test.metadata_scope; + +import 'dart:mirrors'; +import 'package:expect/expect.dart'; + +class Annotation { + final contents; + const Annotation(this.contents); + toString() => "Annotation($contents)"; +} + +// Note there is no compile-time constant 'foo' in scope. In particular, A.foo +// is not in scope here. +@Annotation(foo) // //# 01: compile-time error +class A<@Annotation(foo) T> { + @Annotation(foo) + static foo() {} + + @Annotation(foo) + static bar() {} +} + +@Annotation(B.foo) +class B<@Annotation(B.foo) T> { + @Annotation(B.foo) + static foo() {} + + @Annotation(B.foo) + static bar() {} +} + +baz() {} + +// Note the top-level function baz is in scope here, not C.baz. +@Annotation(baz) +class C<@Annotation(baz) T> { + @Annotation(baz) + static baz() {} +} + +checkMetadata(DeclarationMirror mirror, List expectedMetadata) { + Expect.listEquals(expectedMetadata.map(reflect).toList(), mirror.metadata); +} + +main() { + reflectClass(A).metadata; + checkMetadata(reflectClass(A).declarations[#T], [const Annotation(A.foo)]); + checkMetadata(reflectClass(A).declarations[#foo], [const Annotation(A.foo)]); + checkMetadata(reflectClass(A).declarations[#bar], [const Annotation(A.foo)]); + checkMetadata(reflectClass(B), [const Annotation(B.foo)]); + checkMetadata(reflectClass(B).declarations[#T], [const Annotation(B.foo)]); + checkMetadata(reflectClass(B).declarations[#foo], [const Annotation(B.foo)]); + checkMetadata(reflectClass(B).declarations[#bar], [const Annotation(B.foo)]); + // The top-level function baz, not C.baz. + checkMetadata(reflectClass(C), [const Annotation(baz)]); + // C.baz, not the top-level function baz. + checkMetadata(reflectClass(C).declarations[#T], [const Annotation(C.baz)]); + checkMetadata(reflectClass(C).declarations[#baz], [const Annotation(C.baz)]); +} diff --git a/tests/lib/mirrors/metadata_symbol_literal_test.dart b/tests/lib/mirrors/metadata_symbol_literal_test.dart new file mode 100644 index 00000000000..129d4cd8f1a --- /dev/null +++ b/tests/lib/mirrors/metadata_symbol_literal_test.dart @@ -0,0 +1,22 @@ +// Copyright (c) 2018, 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. + +import 'dart:mirrors'; +import 'package:expect/expect.dart'; + +class T { + const T(this.symbol); + final Symbol symbol; +} + +class U { + @T(#x) + int field; +} + +main() { + final field = reflectClass(U).declarations[#field] as VariableMirror; + final metadata = field.metadata; + Expect.identical((metadata.first.reflectee as T).symbol, const Symbol('x')); +} diff --git a/tests/lib/mirrors/metadata_test.dart b/tests/lib/mirrors/metadata_test.dart new file mode 100644 index 00000000000..d574bc1376b --- /dev/null +++ b/tests/lib/mirrors/metadata_test.dart @@ -0,0 +1,78 @@ +// Copyright (c) 2013, 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. + +library test.metadata_test; + +import 'dart:mirrors'; + +const string = 'a metadata string'; + +const symbol = const Symbol('symbol'); + +const hest = 'hest'; + +@symbol +@string +class MyClass { + @hest + @hest + @symbol + var x; + var y; + + @string + @symbol + @string + myMethod() => 1; + myOtherMethod() => 2; +} + +checkMetadata(DeclarationMirror mirror, List expectedMetadata) { + List metadata = mirror.metadata.map((m) => m.reflectee).toList(); + if (metadata == null) { + throw 'Null metadata on $mirror'; + } + int expectedLength = expectedMetadata.length; + int actualLength = metadata.length; + if (expectedLength != actualLength) { + throw 'Expected length = $expectedLength, but got length = $actualLength.'; + } + for (int i = 0; i < expectedLength; i++) { + if (metadata[i] != expectedMetadata[i]) { + throw '${metadata[i]} is not "${expectedMetadata[i]}"' + ' in $mirror at index $i'; + } + } + print(metadata); +} + +@symbol +@string +@symbol +main() { + if (MirrorSystem.getName(symbol) != 'symbol') { + // This happened in dart2js due to how early library metadata is + // computed. + throw 'Bad constant: $symbol'; + } + + MirrorSystem mirrors = currentMirrorSystem(); + ClassMirror myClassMirror = reflectClass(MyClass); + checkMetadata(myClassMirror, [symbol, string]); + LibraryMirror lib = mirrors.findLibrary(#test.metadata_test); + MethodMirror function = lib.declarations[#main] as MethodMirror; + checkMetadata(function, [symbol, string, symbol]); + MethodMirror method = myClassMirror.declarations[#myMethod] as MethodMirror; + checkMetadata(method, [string, symbol, string]); + method = myClassMirror.declarations[#myOtherMethod] as MethodMirror; + checkMetadata(method, []); + + VariableMirror xMirror = myClassMirror.declarations[#x] as VariableMirror; + checkMetadata(xMirror, [hest, hest, symbol]); + + VariableMirror yMirror = myClassMirror.declarations[#y] as VariableMirror; + checkMetadata(yMirror, []); + + // TODO(ahe): Test local functions. +} diff --git a/tests/lib/mirrors/metadata_type_literal_test.dart b/tests/lib/mirrors/metadata_type_literal_test.dart new file mode 100644 index 00000000000..4d567a68e75 --- /dev/null +++ b/tests/lib/mirrors/metadata_type_literal_test.dart @@ -0,0 +1,24 @@ +// Copyright (c) 2018, 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. + +import 'dart:mirrors'; +import 'package:expect/expect.dart'; + +class Foo {} + +class Annotation { + final Object bindings; + const Annotation(this.bindings); +} + +@Annotation(Foo) +class Annotated {} + +main(List args) { + ClassMirror mirror = reflectType(Annotated) as ClassMirror; + Expect.equals("ClassMirror on 'Annotated'", mirror.toString()); + + var bindings = mirror.metadata[0].reflectee.bindings; + Expect.equals('Foo', bindings.toString()); +} diff --git a/tests/lib/mirrors/method_mirror_extension_test.dart b/tests/lib/mirrors/method_mirror_extension_test.dart new file mode 100644 index 00000000000..2d68474512c --- /dev/null +++ b/tests/lib/mirrors/method_mirror_extension_test.dart @@ -0,0 +1,126 @@ +// Copyright (c) 2019, 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. + +// SharedOptions=--enable-experiment=extension-methods + +library lib; + +import "dart:mirrors"; + +import "package:expect/expect.dart"; + +class C { + static int tracefunc() { + try { + throw "producing a stack trace"; + } catch (e, s) { + print(s); + } + return 10; + } +} + +extension ext on C { + func() { + try { + throw "producing a stack trace"; + } catch (e, s) { + print(s); + } + } + + get prop { + try { + throw "producing a stack trace"; + } catch (e, s) { + print(s); + } + } + + set prop(value) { + try { + throw "producing a stack trace"; + } catch (e, s) { + print(s); + } + } + + operator +(val) { + try { + throw "producing a stack trace"; + } catch (e, s) { + print(s); + } + } + + operator -(val) { + try { + throw "producing a stack trace"; + } catch (e, s) { + print(s); + } + } + + static int sfld = C.tracefunc(); + static sfunc() { + try { + throw "producing a stack trace"; + } catch (e, s) { + print(s); + } + } + + static get sprop { + try { + throw "producing a stack trace"; + } catch (e, s) { + print(s); + } + } + + static set sprop(value) { + try { + throw "producing a stack trace"; + } catch (e, s) { + print(s); + } + } +} + +checkExtensionKind(closure, kind, name) { + var closureMirror = reflect(closure) as ClosureMirror; + var methodMirror = closureMirror.function; + Expect.isTrue(methodMirror.simpleName.toString().contains(name)); + Expect.equals(kind, methodMirror.isExtensionMember, "isExtension"); +} + +void testExtension(sym, mirror) { + if (mirror is MethodMirror) { + var methodMirror = mirror as MethodMirror; + if (MirrorSystem.getName(sym).startsWith('ext', 0)) { + Expect.equals(true, methodMirror.isExtensionMember, "isExtension"); + Expect.isTrue(methodMirror.simpleName.toString().contains('ext.')); + } else { + Expect.equals(false, methodMirror.isExtensionMember, "isExtension"); + } + } else if (mirror is VariableMirror) { + var variableMirror = mirror as VariableMirror; + if (MirrorSystem.getName(sym).startsWith('ext', 0)) { + Expect.equals(true, variableMirror.isExtensionMember, "isExtension"); + } else { + Expect.equals(false, variableMirror.isExtensionMember, "isExtension"); + } + } +} + +main() { + checkExtensionKind(C.tracefunc, false, 'tracefunc'); + + C c = new C(); + checkExtensionKind(c.func, true, 'ext.func'); + checkExtensionKind(ext.sfunc, true, 'ext.sfunc'); + + var libraryMirror = reflectClass(C).owner as LibraryMirror; + libraryMirror.declarations.forEach(testExtension); +} diff --git a/tests/lib/mirrors/method_mirror_location_other.dart b/tests/lib/mirrors/method_mirror_location_other.dart new file mode 100644 index 00000000000..1747eb9342f --- /dev/null +++ b/tests/lib/mirrors/method_mirror_location_other.dart @@ -0,0 +1,17 @@ +// Copyright (c) 2014, 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. + +part of test.method_location; + +class ClassInOtherFile { + ClassInOtherFile(); + + method() {} +} + +topLevelInOtherFile() {} + + spaceIdentedInOtherFile() {} + + tabIdentedInOtherFile() {} diff --git a/tests/lib/mirrors/method_mirror_location_test.dart b/tests/lib/mirrors/method_mirror_location_test.dart new file mode 100644 index 00000000000..426d3f2c99f --- /dev/null +++ b/tests/lib/mirrors/method_mirror_location_test.dart @@ -0,0 +1,77 @@ +// Copyright (c) 2014, 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. + +library test.method_location; + +import "dart:mirrors"; +import "package:expect/expect.dart"; + +part 'method_mirror_location_other.dart'; + +// We only check for a suffix of the uri because the test might be run from +// any number of absolute paths. +expectLocation(Mirror mirror, String uriSuffix, int line, int column) { + MethodMirror methodMirror; + if (mirror is ClosureMirror) { + methodMirror = mirror.function; + } else { + methodMirror = mirror as MethodMirror; + } + Expect.isTrue(methodMirror is MethodMirror); + final location = methodMirror.location; + final uri = location.sourceUri; + Expect.isTrue(uri.toString().endsWith(uriSuffix), "Expected suffix $uriSuffix in $uri"); + Expect.equals(line, location.line, "line"); + Expect.equals(column, location.column, "column"); +} + +class ClassInMainFile { + + ClassInMainFile(); + + method() {} +} + +void topLevelInMainFile() {} + spaceIdentedInMainFile() {} + tabIdentedInMainFile() {} + +class HasImplicitConstructor {} + +typedef bool Predicate(num n); + +main() { + localFunction(x) { + return x; + } + + String mainSuffix = 'method_mirror_location_test.dart'; + String otherSuffix = 'method_mirror_location_other.dart'; + + // This file. + expectLocation(reflectClass(ClassInMainFile).declarations[#ClassInMainFile], + mainSuffix, 31, 3); + expectLocation( + reflectClass(ClassInMainFile).declarations[#method], mainSuffix, 33, 3); + expectLocation(reflect(topLevelInMainFile), mainSuffix, 36, 1); + expectLocation(reflect(spaceIdentedInMainFile), mainSuffix, 37, 3); + expectLocation(reflect(tabIdentedInMainFile), mainSuffix, 38, 2); + expectLocation(reflect(localFunction), mainSuffix, 45, 3); + + // Another part. + expectLocation(reflectClass(ClassInOtherFile).declarations[#ClassInOtherFile], + otherSuffix, 8, 3); + expectLocation( + reflectClass(ClassInOtherFile).declarations[#method], otherSuffix, 10, 3); + expectLocation(reflect(topLevelInOtherFile), otherSuffix, 13, 1); + expectLocation(reflect(spaceIdentedInOtherFile), otherSuffix, 15, 3); + expectLocation(reflect(tabIdentedInOtherFile), otherSuffix, 17, 2); + + // Synthetic methods. + Expect.isNull(reflectClass(HasImplicitConstructor) + .declarations[#HasImplicitConstructor] + .location); + Expect.isNull( + (reflectType(Predicate) as TypedefMirror).referent.callMethod.location); +} diff --git a/tests/lib/mirrors/method_mirror_name_test.dart b/tests/lib/mirrors/method_mirror_name_test.dart new file mode 100644 index 00000000000..c428da72f3b --- /dev/null +++ b/tests/lib/mirrors/method_mirror_name_test.dart @@ -0,0 +1,19 @@ +// Copyright (c) 2013, 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. + +library lib; + +import "dart:mirrors"; + +import "package:expect/expect.dart"; +import "stringify.dart"; + +doNothing42() {} + +main() { + // Regression test for http://www.dartbug.com/6335 + var closureMirror = reflect(doNothing42) as ClosureMirror; + Expect.equals( + stringifySymbol(closureMirror.function.simpleName), "s(doNothing42)"); +} diff --git a/tests/lib/mirrors/method_mirror_properties_test.dart b/tests/lib/mirrors/method_mirror_properties_test.dart new file mode 100644 index 00000000000..d2262f16edf --- /dev/null +++ b/tests/lib/mirrors/method_mirror_properties_test.dart @@ -0,0 +1,79 @@ +// Copyright (c) 2013, 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. + +library lib; + +import "dart:mirrors"; + +import "package:expect/expect.dart"; + +doNothing42() {} + +int _x = 5; +int get topGetter => _x; +void set topSetter(x) { + _x = x; +} + +abstract class AbstractC { + AbstractC(); + + void bar(); + get priv; + set priv(value); +} + +abstract class C extends AbstractC { + static foo() {} + + C(); + C.other(); + C.other2() : this.other(); + + var _priv; + get priv => _priv; + set priv(value) => _priv = value; +} + +checkKinds(method, kinds) { + Expect.equals(kinds[0], method.isStatic, "isStatic"); + Expect.equals(kinds[1], method.isAbstract, "isAbstract"); + Expect.equals(kinds[2], method.isGetter, "isGetter"); + Expect.equals(kinds[3], method.isSetter, "isSetter"); + Expect.equals(kinds[4], method.isConstructor, "isConstructor"); + Expect.equals(false, method.isExtensionMember, "isExtension"); +} + +main() { + // Top level functions should be static. + var closureMirror = reflect(doNothing42) as ClosureMirror; + checkKinds(closureMirror.function, [true, false, false, false, false]); + var libraryMirror = reflectClass(C).owner as LibraryMirror; + checkKinds(libraryMirror.declarations[#topGetter], + [true, false, true, false, false]); + checkKinds(libraryMirror.declarations[const Symbol("topSetter=")], + [true, false, false, true, false]); + var classMirror; + classMirror = reflectClass(C); + checkKinds( + classMirror.declarations[#foo], [true, false, false, false, false]); + checkKinds( + classMirror.declarations[#priv], [false, false, true, false, false]); + checkKinds(classMirror.declarations[const Symbol("priv=")], + [false, false, false, true, false]); + checkKinds(classMirror.declarations[#C], [false, false, false, false, true]); + checkKinds( + classMirror.declarations[#C.other], [false, false, false, false, true]); + checkKinds( + classMirror.declarations[#C.other2], [false, false, false, false, true]); + classMirror = reflectClass(AbstractC); + checkKinds( + classMirror.declarations[#AbstractC], [false, false, false, false, true]); + checkKinds( + classMirror.declarations[#bar], [false, true, false, false, false]); + checkKinds( + classMirror.declarations[#priv], [false, true, true, false, false]); + checkKinds(classMirror.declarations[const Symbol("priv=")], + [false, true, false, true, false]); +} diff --git a/tests/lib/mirrors/method_mirror_returntype_test.dart b/tests/lib/mirrors/method_mirror_returntype_test.dart new file mode 100644 index 00000000000..83b5f891080 --- /dev/null +++ b/tests/lib/mirrors/method_mirror_returntype_test.dart @@ -0,0 +1,51 @@ +// Copyright (c) 2013, 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. + +library lib; + +import "dart:mirrors"; + +import "package:expect/expect.dart"; + +void voidFunc() {} + +dynamicFunc1() {} + +dynamic dynamicFunc2() {} + +int intFunc() => 0; + +class C { + E getE(E v) => v; +} + +main() { + MethodMirror mm; + + mm = (reflect(intFunc) as ClosureMirror).function; + Expect.equals(true, mm.returnType is TypeMirror); + Expect.equals(#int, mm.returnType.simpleName); + Expect.equals(true, mm.returnType.owner is LibraryMirror); + + mm = (reflect(dynamicFunc1) as ClosureMirror).function; + Expect.equals(true, mm.returnType is TypeMirror); + Expect.equals(#dynamic, mm.returnType.simpleName); + + mm = (reflect(dynamicFunc2) as ClosureMirror).function; + Expect.equals(true, mm.returnType is TypeMirror); + Expect.equals(#dynamic, mm.returnType.simpleName); + + mm = (reflect(voidFunc) as ClosureMirror).function; + Expect.equals(true, mm.returnType is TypeMirror); + Expect.equals(const Symbol("void"), mm.returnType.simpleName); + + ClassMirror cm = reflectClass(C); + mm = cm.declarations[#getE] as MethodMirror; + Expect.equals(true, mm.returnType is TypeMirror); + // The spec for this is ambiguous and needs to be updated before it is clear + // what has to be returned. + //Expect.equals("E", _n(mm.returnType.simpleName)); + Expect.equals(true, mm.owner is ClassMirror); + Expect.equals(#C, mm.owner.simpleName); +} diff --git a/tests/lib/mirrors/method_mirror_source_line_ending_cr.dart b/tests/lib/mirrors/method_mirror_source_line_ending_cr.dart new file mode 100755 index 00000000000..45533d47348 --- /dev/null +++ b/tests/lib/mirrors/method_mirror_source_line_ending_cr.dart @@ -0,0 +1 @@ +// Copyright (c) 2014, 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. // Note: This test relies on CR line endings in the source file. library line_endings.cr; oneLineCR(x) => x; multiLineCR(y) { return y + 1; } b (){ } diff --git a/tests/lib/mirrors/method_mirror_source_line_ending_crlf.dart b/tests/lib/mirrors/method_mirror_source_line_ending_crlf.dart new file mode 100755 index 00000000000..d93615cd83b --- /dev/null +++ b/tests/lib/mirrors/method_mirror_source_line_ending_crlf.dart @@ -0,0 +1,15 @@ +// Copyright (c) 2014, 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. + +// Note: This test relies on CRLF line endings in the source file. + +library line_endings.crlf; + +oneLineCRLF(x) => x; +multiLineCRLF(y) { + return y + 1; +} +c +(){ +} diff --git a/tests/lib/mirrors/method_mirror_source_line_ending_lf.dart b/tests/lib/mirrors/method_mirror_source_line_ending_lf.dart new file mode 100755 index 00000000000..b805a757a5d --- /dev/null +++ b/tests/lib/mirrors/method_mirror_source_line_ending_lf.dart @@ -0,0 +1,15 @@ +// Copyright (c) 2014, 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. + +// Note: This test relies on LF line endings in the source file. + +library line_endings.lf; + +oneLineLF(x) => x; +multiLineLF(y) { + return y + 1; +} +a +(){ +} diff --git a/tests/lib/mirrors/method_mirror_source_line_ending_test.dart b/tests/lib/mirrors/method_mirror_source_line_ending_test.dart new file mode 100644 index 00000000000..4e4e8a4ba2f --- /dev/null +++ b/tests/lib/mirrors/method_mirror_source_line_ending_test.dart @@ -0,0 +1,34 @@ +// Copyright (c) 2014, 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. + +// Note: These tests rely on specific line endings in the source files. + +import "dart:mirrors"; +import "package:expect/expect.dart"; + +import "method_mirror_source_line_ending_lf.dart"; +import "method_mirror_source_line_ending_cr.dart"; +import "method_mirror_source_line_ending_crlf.dart"; + +main() { + String sourceOf(Function f) => (reflect(f) as ClosureMirror).function.source; + + // Source does not cross line breaks. + Expect.stringEquals('oneLineLF(x) => x;', sourceOf(oneLineLF)); + Expect.stringEquals('oneLineCR(x) => x;', sourceOf(oneLineCR)); + Expect.stringEquals('oneLineCRLF(x) => x;', sourceOf(oneLineCRLF)); + + // Source includes line breaks. + Expect.stringEquals( + 'multiLineLF(y) {\n return y + 1;\n}', sourceOf(multiLineLF)); + Expect.stringEquals( + 'multiLineCR(y) {\r return y + 1;\r}', sourceOf(multiLineCR)); + Expect.stringEquals( + 'multiLineCRLF(y) {\r\n return y + 1;\r\n}', sourceOf(multiLineCRLF)); + + // First and last characters separated from middle by line breaks. + Expect.stringEquals('a\n(){\n}', sourceOf(a)); + Expect.stringEquals('b\r(){\r}', sourceOf(b)); + Expect.stringEquals('c\r\n(){\r\n}', sourceOf(c)); +} diff --git a/tests/lib/mirrors/method_mirror_source_other.dart b/tests/lib/mirrors/method_mirror_source_other.dart new file mode 100644 index 00000000000..37151b62d18 --- /dev/null +++ b/tests/lib/mirrors/method_mirror_source_other.dart @@ -0,0 +1,8 @@ +main() { + print("Blah"); +} +// This function must be on the first line. + +class SomethingInOther {} + +// Note: This test relies on LF line endings in the source file. diff --git a/tests/lib/mirrors/method_mirror_source_test.dart b/tests/lib/mirrors/method_mirror_source_test.dart new file mode 100644 index 00000000000..dbfbf5cdd92 --- /dev/null +++ b/tests/lib/mirrors/method_mirror_source_test.dart @@ -0,0 +1,110 @@ +// Copyright (c) 2013, 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. + +// Note: This test relies on LF line endings in the source file. + +import "dart:mirrors"; +import "package:expect/expect.dart"; +import "method_mirror_source_other.dart"; + +expectSource(Mirror mirror, String source) { + MethodMirror methodMirror; + if (mirror is ClosureMirror) { + methodMirror = mirror.function; + } else { + methodMirror = mirror as MethodMirror; + } + Expect.isTrue(methodMirror is MethodMirror); + Expect.equals(source, methodMirror.source); +} + +foo1() {} +doSomething(e) => e; + +int get x => 42; +set x(value) { } + +class S {} + +class C extends S { + + var _x; + var _y; + + C(this._x, y) + : _y = y, + super(); + + factory C.other(num z) {} + factory C.other2() {} + factory C.other3() = C.other2; + + static dynamic foo() { + // Happy foo. + } + + // Some comment. + + void bar() { /* Not so happy bar. */ } + + num get someX => + 181; + + set someX(v) { + // Discard this one. + } +} + + +main() { + // Top-level members + LibraryMirror lib = reflectClass(C).owner as LibraryMirror; + expectSource(lib.declarations[#foo1], + "foo1() {}"); + expectSource(lib.declarations[#x], + "int get x => 42;"); + expectSource(lib.declarations[const Symbol("x=")], + "set x(value) { }"); + + // Class members + ClassMirror cm = reflectClass(C); + expectSource(cm.declarations[#foo], + "static dynamic foo() {\n" + " // Happy foo.\n" + " }"); + expectSource(cm.declarations[#bar], + "void bar() { /* Not so happy bar. */ }"); + expectSource(cm.declarations[#someX], + "num get someX =>\n" + " 181;"); + expectSource(cm.declarations[const Symbol("someX=")], + "set someX(v) {\n" + " // Discard this one.\n" + " }"); + expectSource(cm.declarations[#C], + "C(this._x, y)\n" + " : _y = y,\n" + " super();"); + expectSource(cm.declarations[#C.other], + "factory C.other(num z) {}"); + expectSource(cm.declarations[#C.other3], + "factory C.other3() = C.other2;"); + + // Closures + expectSource(reflect((){}), "(){}"); + expectSource(reflect((x,y,z) { return x*y*z; }), "(x,y,z) { return x*y*z; }"); + expectSource(reflect((e) => doSomething(e)), "(e) => doSomething(e)"); + + namedClosure(x,y,z) => 1; + var a = () {}; + expectSource(reflect(namedClosure), "namedClosure(x,y,z) => 1;"); + expectSource(reflect(a), "() {}"); + + // Function at first line. + LibraryMirror otherLib = reflectClass(SomethingInOther).owner as LibraryMirror; + expectSource(otherLib.declarations[#main], +"""main() { + print("Blah"); +}"""); +} diff --git a/tests/lib/mirrors/mirror_in_static_init_test.dart b/tests/lib/mirrors/mirror_in_static_init_test.dart new file mode 100644 index 00000000000..4de3ef6c4b7 --- /dev/null +++ b/tests/lib/mirrors/mirror_in_static_init_test.dart @@ -0,0 +1,29 @@ +// Copyright (c) 2015, 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. + +// Error in class finalization triggered via mirror in a static initializer. +// Simply check that we do not crash. +// This is a regression test for the VM. + +library mirror_in_static_init_test; + +import 'dart:mirrors'; + +// This class is only loaded during initialization of `staticField`. +abstract class C { + int _a; + // This is a syntax error on purpose. + C([this._a: 0]); //# 01: compile-time error +} + +final int staticField = () { + var lib = currentMirrorSystem().findLibrary(#mirror_in_static_init_test); + var c = lib.declarations[#C] as ClassMirror; + var lst = new List.from(c.declarations.values); + return 42; +}(); + +main() { + return staticField; +} diff --git a/tests/lib/mirrors/mirrors_nsm_mismatch_test.dart b/tests/lib/mirrors/mirrors_nsm_mismatch_test.dart new file mode 100644 index 00000000000..2a3637bbdbe --- /dev/null +++ b/tests/lib/mirrors/mirrors_nsm_mismatch_test.dart @@ -0,0 +1,52 @@ +// Copyright (c) 2015, 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. + +library test.mirrors_nsm_mismatch; + +import 'dart:mirrors'; +import 'mirrors_nsm_test.dart'; + +topLevelMethod({missing}) {} + +class C { + C.constructor({missing}); + factory C.redirecting({missing}) = C.constructor; + static staticMethod({missing}) {} + instanceMethod({missing}) {} +} + +main() { + var mirrors = currentMirrorSystem(); + var libMirror = mirrors.findLibrary(#test.mirrors_nsm_mismatch); + expectMatchingErrors(() => libMirror.invoke(#topLevelMethod, [], {#extra: 1}), + () => topLevelMethod(extra: 1)); + expectMatchingErrors(() => libMirror.invoke(#topLevelMethod, ['positional']), + () => topLevelMethod('positional')); + + var classMirror = reflectClass(C); + expectMatchingErrors( + () => classMirror.newInstance(#constructor, [], {#extra: 1}), + () => new C.constructor(extra: 1)); + expectMatchingErrors( + () => classMirror.newInstance(#redirecting, [], {#extra: 1}), + () => new C.redirecting(extra: 1)); + expectMatchingErrors(() => classMirror.invoke(#staticMethod, [], {#extra: 1}), + () => C.staticMethod(extra: 1)); + expectMatchingErrors( + () => classMirror.newInstance(#constructor, ['positional']), + () => new C.constructor('positional')); + expectMatchingErrors( + () => classMirror.newInstance(#redirecting, ['positional']), + () => new C.redirecting('positional')); + expectMatchingErrors(() => classMirror.invoke(#staticMethod, ['positional']), + () => C.staticMethod('positional')); + + var instanceMirror = reflect(new C.constructor()); + expectMatchingErrors( + () => instanceMirror.invoke(#instanceMethod, [], {#extra: 1}), + () => instanceMirror.reflectee.instanceMethod(extra: 1)); + expectMatchingErrors( + () => instanceMirror.invoke(#instanceMethod, ['positional']), + () => instanceMirror.reflectee.instanceMethod('positional')); +} diff --git a/tests/lib/mirrors/mirrors_nsm_test.dart b/tests/lib/mirrors/mirrors_nsm_test.dart new file mode 100644 index 00000000000..d7a772947ae --- /dev/null +++ b/tests/lib/mirrors/mirrors_nsm_test.dart @@ -0,0 +1,115 @@ +// Copyright (c) 2011, 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. + +library MirrorsTest; + +import 'dart:mirrors'; +import 'package:expect/expect.dart'; + +bool isNSMContainingFieldName(e, String fieldName, bool isSetter) { + if (e is! NoSuchMethodError) return false; + String needle = fieldName; + if (isSetter) needle += "="; + return "$e".contains(needle) && !"$e".contains(needle + "="); +} + +final finalTopLevel = 0; + +class A { + final finalInstance = 0; + static final finalStatic = 0; +} + +class B { + B(a, b); + factory B.fac(a, b) => new B(a, b); +} + +testMessageContents() { + var mirrors = currentMirrorSystem(); + var libMirror = mirrors.findLibrary(#MirrorsTest); + Expect.throws(() => libMirror.invoke(#foo, []), + (e) => isNSMContainingFieldName(e, "foo", false)); + Expect.throws(() => libMirror.getField(#foo), + (e) => isNSMContainingFieldName(e, "foo", false)); + Expect.throws(() => libMirror.setField(#foo, null), + (e) => isNSMContainingFieldName(e, "foo", true)); + Expect.throws(() => libMirror.setField(#finalTopLevel, null), + (e) => isNSMContainingFieldName(e, "finalTopLevel", true)); + + var classMirror = reflectClass(A); + Expect.throws(() => classMirror.invoke(#foo, []), + (e) => isNSMContainingFieldName(e, "foo", false)); + Expect.throws(() => classMirror.getField(#foo), + (e) => isNSMContainingFieldName(e, "foo", false)); + Expect.throws(() => classMirror.setField(#foo, null), + (e) => isNSMContainingFieldName(e, "foo", true)); + Expect.throws(() => classMirror.setField(#finalStatic, null), + (e) => isNSMContainingFieldName(e, "finalStatic", true)); + + var instanceMirror = reflect(new A()); + Expect.throws(() => instanceMirror.invoke(#foo, []), + (e) => isNSMContainingFieldName(e, "foo", false)); + Expect.throws(() => instanceMirror.getField(#foo), + (e) => isNSMContainingFieldName(e, "foo", false)); + Expect.throws(() => instanceMirror.setField(#foo, null), + (e) => isNSMContainingFieldName(e, "foo", true)); + Expect.throws(() => instanceMirror.setField(#finalInstance, null), + (e) => isNSMContainingFieldName(e, "finalInstance", true)); +} + +expectMatchingErrors(reflectiveAction, baseAction) { + var reflectiveError, baseError; + try { + reflectiveAction(); + } catch (e) { + reflectiveError = e; + } + + try { + baseAction(); + } catch (e) { + baseError = e; + } + + if (baseError.toString() != reflectiveError.toString()) { + print("\n==Base==\n $baseError"); + print("\n==Reflective==\n $reflectiveError"); + throw "Expected matching errors"; + } +} + +testMatchingMessages() { + var mirrors = currentMirrorSystem(); + var libMirror = mirrors.findLibrary(#MirrorsTest); + expectMatchingErrors(() => libMirror.invoke(#foo, []), () => foo()); + expectMatchingErrors(() => libMirror.getField(#foo), () => foo); + expectMatchingErrors(() => libMirror.setField(#foo, null), () => foo = null); + expectMatchingErrors(() => libMirror.setField(#finalTopLevel, null), + () => finalTopLevel = null); + + var classMirror = reflectClass(A); + expectMatchingErrors(() => classMirror.invoke(#foo, []), () => A.foo()); + expectMatchingErrors(() => classMirror.getField(#foo), () => A.foo); + expectMatchingErrors( + () => classMirror.setField(#foo, null), () => A.foo = null); + expectMatchingErrors(() => classMirror.setField(#finalStatic, null), + () => A.finalStatic = null); + expectMatchingErrors(() => classMirror.newInstance(#constructor, [1, 2, 3]), + () => new A.constructor(1, 2, 3)); + + var instanceMirror = reflect(new A()); + expectMatchingErrors( + () => instanceMirror.invoke(#foo, []), () => new A().foo()); + expectMatchingErrors(() => instanceMirror.getField(#foo), () => new A().foo); + expectMatchingErrors( + () => instanceMirror.setField(#foo, null), () => new A().foo = null); + expectMatchingErrors(() => instanceMirror.setField(#finalInstance, null), + () => new A().finalInstance = null); +} + +main() { + testMessageContents(); + testMatchingMessages(); //# dart2js: ok +} diff --git a/tests/lib/mirrors/mirrors_reader.dart b/tests/lib/mirrors/mirrors_reader.dart new file mode 100644 index 00000000000..b8a5faaad56 --- /dev/null +++ b/tests/lib/mirrors/mirrors_reader.dart @@ -0,0 +1,260 @@ +// Copyright (c) 2014, 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 LICESNE file. + +library mirrors.reader; + +import 'dart:mirrors'; +import 'mirrors_visitor.dart'; + +class ReadError { + final String tag; + final exception; + final StackTrace stackTrace; + + ReadError(this.tag, this.exception, this.stackTrace); +} + +class MirrorsReader extends MirrorsVisitor { + /// Produce verbose output. + final bool verbose; + + /// Include stack trace in the error report. + final bool includeStackTrace; + + bool fatalError = false; + Set visited = new Set(); + Set declarations = new Set(); + Set instantiations = new Set(); + List errors = []; + List queue = []; + + MirrorsReader({this.verbose: false, this.includeStackTrace: false}); + + void checkMirrorSystem(MirrorSystem mirrorSystem) { + visitMirrorSystem(mirrorSystem); + if (!errors.isEmpty) { + Set errorMessages = new Set(); + for (ReadError error in errors) { + String text = 'Mirrors read error: ${error.tag}=${error.exception}'; + if (includeStackTrace) { + text = '$text\n${error.stackTrace}'; + } + if (errorMessages.add(text)) { + print(text); + } + } + throw 'Unexpected errors occurred reading mirrors.'; + } + } + + // Skip mirrors so that each mirror is only visited once. + bool skipMirror(Mirror mirror) { + if (fatalError) return true; + if (mirror is TypeMirror) { + if (mirror.isOriginalDeclaration) { + // Visit the declaration once. + return !declarations.add(mirror); + } else { + // Visit only one instantiation. + return !instantiations.add(mirror.originalDeclaration); + } + } + return !visited.add(mirror); + } + + reportError(var receiver, String tag, var exception, StackTrace stackTrace) { + String errorTag = '${receiver.runtimeType}.$tag'; + errors.add(new ReadError(errorTag, exception, stackTrace)); + } + + visitUnsupported(var receiver, String tag, UnsupportedError exception, + StackTrace stackTrace) { + if (verbose) print('visitUnsupported:$receiver.$tag:$exception'); + if (!expectUnsupported(receiver, tag, exception) && + !allowUnsupported(receiver, tag, exception)) { + reportError(receiver, tag, exception, stackTrace); + } + } + + /// Override to specify that access is expected to be unsupported. + bool expectUnsupported( + var receiver, String tag, UnsupportedError exception) => + false; + + /// Override to allow unsupported access. + bool allowUnsupported(var receiver, String tag, UnsupportedError exception) => + false; + + /// Evaluates the function [f]. Subclasses can override this to handle + /// specific exceptions. + dynamic evaluate(dynamic f) => f(); + + visit(var receiver, String tag, var value) { + if (value is Function) { + try { + var result = evaluate(value); + if (expectUnsupported(receiver, tag, null)) { + reportError(receiver, tag, 'Expected UnsupportedError.', null); + } + return visit(receiver, tag, result); + } on UnsupportedError catch (e, s) { + visitUnsupported(receiver, tag, e, s); + } on OutOfMemoryError catch (e, s) { + reportError(receiver, tag, e, s); + fatalError = true; + } on StackOverflowError catch (e, s) { + reportError(receiver, tag, e, s); + fatalError = true; + } catch (e, s) { + reportError(receiver, tag, e, s); + } + } else { + if (value is Mirror) { + if (!skipMirror(value)) { + if (verbose) print('visit:$receiver.$tag=$value'); + bool drain = queue.isEmpty; + queue.add(value); + if (drain) { + while (!queue.isEmpty) { + visitMirror(queue.removeLast()); + } + } + } + } else if (value is MirrorSystem) { + visitMirrorSystem(value); + } else if (value is SourceLocation) { + visitSourceLocation(value); + } else if (value is Iterable) { + // TODO(johnniwinther): Merge with `immutable_collections_test.dart`. + value.forEach((e) { + visit(receiver, tag, e); + }); + } else if (value is Map) { + value.forEach((k, v) { + visit(receiver, tag, k); + visit(receiver, tag, v); + }); + } + } + return value; + } + + visitMirrorSystem(MirrorSystem mirrorSystem) { + visit(mirrorSystem, 'dynamicType', () => mirrorSystem.dynamicType); + visit(mirrorSystem, 'voidType', () => mirrorSystem.voidType); + visit(mirrorSystem, 'libraries', () => mirrorSystem.libraries); + } + + visitClassMirror(ClassMirror mirror) { + super.visitClassMirror(mirror); + visit(mirror, 'declarations', () => mirror.declarations); + bool hasReflectedType = + visit(mirror, 'hasReflectedType', () => mirror.hasReflectedType); + visit(mirror, 'instanceMembers', () => mirror.instanceMembers); + visit(mirror, 'mixin', () => mirror.mixin); + if (hasReflectedType) { + visit(mirror, 'reflectedType', () => mirror.reflectedType); + } + visit(mirror, 'staticMembers', () => mirror.staticMembers); + visit(mirror, 'superclass', () => mirror.superclass); + visit(mirror, 'superinterfaces', () => mirror.superinterfaces); + } + + visitDeclarationMirror(DeclarationMirror mirror) { + super.visitDeclarationMirror(mirror); + visit(mirror, 'isPrivate', () => mirror.isPrivate); + visit(mirror, 'isTopLevel', () => mirror.isTopLevel); + visit(mirror, 'location', () => mirror.location); + visit(mirror, 'metadata', () => mirror.metadata); + visit(mirror, 'owner', () => mirror.owner); + visit(mirror, 'qualifiedName', () => mirror.qualifiedName); + visit(mirror, 'simpleName', () => mirror.simpleName); + } + + visitFunctionTypeMirror(FunctionTypeMirror mirror) { + super.visitFunctionTypeMirror(mirror); + visit(mirror, 'callMethod', () => mirror.callMethod); + visit(mirror, 'parameters', () => mirror.parameters); + visit(mirror, 'returnType', () => mirror.returnType); + } + + visitInstanceMirror(InstanceMirror mirror) { + super.visitInstanceMirror(mirror); + bool hasReflectee = + visit(mirror, 'hasReflectee', () => mirror.hasReflectee); + if (hasReflectee) { + visit(mirror, 'reflectee', () => mirror.reflectee); + } + visit(mirror, 'type', () => mirror.type); + } + + visitLibraryMirror(LibraryMirror mirror) { + super.visitLibraryMirror(mirror); + visit(mirror, 'declarations', () => mirror.declarations); + visit(mirror, 'uri', () => mirror.uri); + } + + visitMethodMirror(MethodMirror mirror) { + super.visitMethodMirror(mirror); + visit(mirror, 'constructorName', () => mirror.constructorName); + visit(mirror, 'isAbstract', () => mirror.isAbstract); + visit(mirror, 'isConstConstructor', () => mirror.isConstConstructor); + visit(mirror, 'isConstructor', () => mirror.isConstructor); + visit(mirror, 'isFactoryConstructor', () => mirror.isFactoryConstructor); + visit(mirror, 'isGenerativeConstructor', + () => mirror.isGenerativeConstructor); + visit(mirror, 'isGetter', () => mirror.isGetter); + visit(mirror, 'isOperator', () => mirror.isOperator); + visit(mirror, 'isRedirectingConstructor', + () => mirror.isRedirectingConstructor); + visit(mirror, 'isRegularMethod', () => mirror.isRegularMethod); + visit(mirror, 'isSetter', () => mirror.isSetter); + visit(mirror, 'isStatic', () => mirror.isStatic); + visit(mirror, 'isSynthetic', () => mirror.isSynthetic); + visit(mirror, 'parameters', () => mirror.parameters); + visit(mirror, 'returnType', () => mirror.returnType); + visit(mirror, 'source', () => mirror.source); + } + + visitParameterMirror(ParameterMirror mirror) { + super.visitParameterMirror(mirror); + bool hasDefaultValue = + visit(mirror, 'hasDefaultValue', () => mirror.hasDefaultValue); + if (hasDefaultValue) { + visit(mirror, 'defaultValue', () => mirror.defaultValue); + } + visit(mirror, 'isNamed', () => mirror.isNamed); + visit(mirror, 'isOptional', () => mirror.isOptional); + visit(mirror, 'type', () => mirror.type); + } + + visitSourceLocation(SourceLocation location) {} + + visitTypedefMirror(TypedefMirror mirror) { + super.visitTypedefMirror(mirror); + visit(mirror, 'referent', () => mirror.referent); + } + + visitTypeMirror(TypeMirror mirror) { + super.visitTypeMirror(mirror); + visit(mirror, 'isOriginalDeclaration', () => mirror.isOriginalDeclaration); + visit(mirror, 'originalDeclaration', () => mirror.originalDeclaration); + visit(mirror, 'typeArguments', () => mirror.typeArguments); + visit(mirror, 'typeVariables', () => mirror.typeVariables); + } + + visitTypeVariableMirror(TypeVariableMirror mirror) { + super.visitTypeVariableMirror(mirror); + visit(mirror, 'upperBound', () => mirror.upperBound); + visit(mirror, 'isStatic', () => mirror.isStatic); + } + + visitVariableMirror(VariableMirror mirror) { + super.visitVariableMirror(mirror); + visit(mirror, 'isConst', () => mirror.isConst); + visit(mirror, 'isFinal', () => mirror.isFinal); + visit(mirror, 'isStatic', () => mirror.isStatic); + visit(mirror, 'type', () => mirror.type); + } +} diff --git a/tests/lib/mirrors/mirrors_reader_test.dart b/tests/lib/mirrors/mirrors_reader_test.dart new file mode 100644 index 00000000000..81154d65bcc --- /dev/null +++ b/tests/lib/mirrors/mirrors_reader_test.dart @@ -0,0 +1,70 @@ +// Copyright (c) 2014, 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 everything reachable from a [MirrorSystem] can be accessed. + +library test.mirrors.reader; + +import 'dart:mirrors'; +import 'package:expect/expect.dart'; +import 'mirrors_reader.dart'; + +class RuntimeMirrorsReader extends MirrorsReader { + final MirrorSystem mirrorSystem; + final String mirrorSystemType; + + RuntimeMirrorsReader(MirrorSystem mirrorSystem, + {bool verbose: false, bool includeStackTrace: false}) + : this.mirrorSystem = mirrorSystem, + this.mirrorSystemType = '${mirrorSystem.runtimeType}', + super(verbose: verbose, includeStackTrace: includeStackTrace); + + visitLibraryMirror(LibraryMirror mirror) { + super.visitLibraryMirror(mirror); + Expect.equals(mirror, mirrorSystem.libraries[mirror.uri]); + } + + visitClassMirror(ClassMirror mirror) { + super.visitClassMirror(mirror); + Expect.isNotNull(mirror.owner); + } + + bool allowUnsupported(var receiver, String tag, UnsupportedError exception) { + if (mirrorSystemType == '_MirrorSystem') { + // VM mirror system. + if (tag.endsWith('location')) { + return receiver is ParameterMirror; + } + } else if (mirrorSystemType == 'JsMirrorSystem') { + // Dart2js runtime mirror system. + if (tag.endsWith('.metadata')) { + return true; // Issue 10905. + } + } + return false; + } + + bool expectUnsupported(var receiver, String tag, UnsupportedError exception) { + // [DeclarationMirror.location] is intentionally not supported in runtime + // mirrors. + + if (mirrorSystemType == '_MirrorSystem') { + // VM mirror system. + } else if (mirrorSystemType == 'JsMirrorSystem') { + // Dart2js runtime mirror system. + if (receiver is DeclarationMirror && tag == 'location') { + return true; + } + } + return false; + } +} + +void main([List arguments = const []]) { + MirrorSystem mirrors = currentMirrorSystem(); + MirrorsReader reader = new RuntimeMirrorsReader(mirrors, + verbose: arguments.contains('-v'), + includeStackTrace: arguments.contains('-s')); + reader.checkMirrorSystem(mirrors); +} diff --git a/tests/lib/mirrors/mirrors_resolve_fields_test.dart b/tests/lib/mirrors/mirrors_resolve_fields_test.dart new file mode 100644 index 00000000000..b914dda7701 --- /dev/null +++ b/tests/lib/mirrors/mirrors_resolve_fields_test.dart @@ -0,0 +1,25 @@ +// Copyright (c) 2013, 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. + +// Regression test for dart2js that used to not resolve instance +// fields when a class is only instantiated through mirrors. + +library lib; + +import "package:expect/expect.dart"; + +import 'dart:mirrors'; + +class A { + static const int _STATE_INITIAL = 0; + int _state = _STATE_INITIAL; + A(); +} + +main() { + var mirrors = currentMirrorSystem(); + var classMirror = reflectClass(A); + var instanceMirror = classMirror.newInstance(Symbol.empty, []); + Expect.equals(A._STATE_INITIAL, instanceMirror.reflectee._state); +} diff --git a/tests/lib/mirrors/mirrors_test.dart b/tests/lib/mirrors/mirrors_test.dart new file mode 100644 index 00000000000..1d8a20427df --- /dev/null +++ b/tests/lib/mirrors/mirrors_test.dart @@ -0,0 +1,247 @@ +// Copyright (c) 2011, 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. + +library MirrorsTest; + +import 'dart:mirrors'; + +import '../../light_unittest.dart'; + +bool isDart2js = false; // TODO(ahe): Remove this field. + +var topLevelField; +u(a, b, c) => {"a": a, "b": b, "c": c}; +_v(a, b) => a + b; + +class Class { + Class() { + this.field = "default value"; + } + Class.withInitialValue(this.field); + var field; + + Class.generative(this.field); + Class.redirecting(y) : this.generative(y * 2); + factory Class.faktory(y) => new Class.withInitialValue(y * 3); + factory Class.redirectingFactory(y) = Class.faktory; + + m(a, b, c) => {"a": a, "b": b, "c": c}; + _n(a, b) => a + b; + noSuchMethod(invocation) => "DNU"; + + static var staticField; + static s(a, b, c) => {"a": a, "b": b, "c": c}; + static _t(a, b) => a + b; +} + +typedef Typedef(); + +testInvoke(mirrors) { + var instance = new Class(); + var instMirror = reflect(instance); + + expect(instMirror.invoke(#m, ['A', 'B', instance]).reflectee, + equals({"a": 'A', "b": 'B', "c": instance})); + expect(instMirror.invoke(#notDefined, []).reflectee, equals("DNU")); + expect(instMirror.invoke(#m, []).reflectee, equals("DNU")); // Wrong arity. + + var classMirror = instMirror.type; + expect(classMirror.invoke(#s, ['A', 'B', instance]).reflectee, + equals({"a": 'A', "b": 'B', "c": instance})); + expect(() => classMirror.invoke(#notDefined, []).reflectee, throws); + expect(() => classMirror.invoke(#s, []).reflectee, throws); // Wrong arity. + + var libMirror = classMirror.owner as LibraryMirror; + expect(libMirror.invoke(#u, ['A', 'B', instance]).reflectee, + equals({"a": 'A', "b": 'B', "c": instance})); + expect(() => libMirror.invoke(#notDefined, []).reflectee, throws); + expect(() => libMirror.invoke(#u, []).reflectee, throws); // Wrong arity. +} + +/// In dart2js, lists, numbers, and other objects are treated special +/// and their methods are invoked through a techique called interceptors. +testIntercepted(mirrors) { + { + var instance = 1; + var instMirror = reflect(instance); + + expect(instMirror.invoke(#toString, []).reflectee, equals('1')); + } + + var instance = []; + var instMirror = reflect(instance); + instMirror.setField(#length, 44); + var resultMirror = instMirror.getField(#length); + expect(resultMirror.reflectee, equals(44)); + expect(instance.length, equals(44)); + + expect( + instMirror.invoke(#toString, []).reflectee, + equals('[null, null, null, null, null, null, null, null, null, null,' + ' null, null, null, null, null, null, null, null, null, null,' + ' null, null, null, null, null, null, null, null, null, null,' + ' null, null, null, null, null, null, null, null, null, null,' + ' null, null, null, null]')); +} + +testFieldAccess(mirrors) { + var instance = new Class(); + + var libMirror = mirrors.findLibrary(#MirrorsTest); + var classMirror = libMirror.declarations[#Class]; + var instMirror = reflect(instance); + var fieldMirror = classMirror.declarations[#field]; + var future; + + expect(fieldMirror is VariableMirror, isTrue); + expect(fieldMirror.type, equals(mirrors.dynamicType)); + + libMirror.setField(#topLevelField, [91]); + expect(libMirror.getField(#topLevelField).reflectee, equals([91])); + expect(topLevelField, equals([91])); +} + +testClosureMirrors(mirrors) { + // TODO(ahe): Test optional parameters (named or not). + var closure = (x, y, z) { + return x + y + z; + }; + + var mirror = reflect(closure) as ClosureMirror; + + var funcMirror = (mirror.function) as MethodMirror; + expect(funcMirror.parameters.length, equals(3)); + + expect(mirror.apply([7, 8, 9]).reflectee, equals(24)); +} + +testInvokeConstructor(mirrors) { + var classMirror = reflectClass(Class); + + var instanceMirror = classMirror.newInstance(Symbol.empty, []); + expect(instanceMirror.reflectee is Class, equals(true)); + expect(instanceMirror.reflectee.field, equals("default value")); + + instanceMirror = classMirror.newInstance(#withInitialValue, [45]); + expect(instanceMirror.reflectee is Class, equals(true)); + expect(instanceMirror.reflectee.field, equals(45)); + + instanceMirror = classMirror.newInstance(#generative, [7]); + expect(instanceMirror.reflectee is Class, equals(true)); + expect(instanceMirror.reflectee.field, equals(7)); + + instanceMirror = classMirror.newInstance(#redirecting, [8]); + expect(instanceMirror.reflectee is Class, equals(true)); + expect(instanceMirror.reflectee.field, equals(16)); + + instanceMirror = classMirror.newInstance(#faktory, [9]); + expect(instanceMirror.reflectee is Class, equals(true)); + expect(instanceMirror.reflectee.field, equals(27)); + + instanceMirror = classMirror.newInstance(#redirectingFactory, [10]); + expect(instanceMirror.reflectee is Class, equals(true)); + expect(instanceMirror.reflectee.field, equals(30)); +} + +testReflectClass(mirrors) { + var classMirror = reflectClass(Class); + expect(classMirror is ClassMirror, equals(true)); + var symbolClassMirror = reflectClass(Symbol); + var symbolMirror = + symbolClassMirror.newInstance(Symbol.empty, ['withInitialValue']); + var objectMirror = classMirror.newInstance(symbolMirror.reflectee, [1234]); + expect(objectMirror.reflectee is Class, equals(true)); + expect(objectMirror.reflectee.field, equals(1234)); +} + +testNames(mirrors) { + var libMirror = mirrors.findLibrary(#MirrorsTest); + var classMirror = libMirror.declarations[#Class]; + var typedefMirror = libMirror.declarations[#Typedef]; + var methodMirror = libMirror.declarations[#testNames]; + var variableMirror = classMirror.declarations[#field]; + + expect(libMirror.simpleName, equals(#MirrorsTest)); + expect(libMirror.qualifiedName, equals(#MirrorsTest)); + + expect(classMirror.simpleName, equals(#Class)); + expect(classMirror.qualifiedName, equals(#MirrorsTest.Class)); + + TypeVariableMirror typeVariable = classMirror.typeVariables.single; + expect(typeVariable.simpleName, equals(#T)); + expect( + typeVariable.qualifiedName, equals(const Symbol('MirrorsTest.Class.T'))); + + if (!isDart2js) { + // TODO(ahe): Implement this in dart2js. + expect(typedefMirror.simpleName, equals(#Typedef)); + expect(typedefMirror.qualifiedName, + equals(const Symbol('MirrorsTest.Typedef'))); + + var typedefMirrorDeNovo = reflectType(Typedef); + expect(typedefMirrorDeNovo.simpleName, equals(#Typedef)); + expect(typedefMirrorDeNovo.qualifiedName, + equals(const Symbol('MirrorsTest.Typedef'))); + } + + expect(methodMirror.simpleName, equals(#testNames)); + expect(methodMirror.qualifiedName, + equals(const Symbol('MirrorsTest.testNames'))); + + expect(variableMirror.simpleName, equals(#field)); + expect(variableMirror.qualifiedName, + equals(const Symbol('MirrorsTest.Class.field'))); +} + +testLibraryUri(var value, bool check(Uri uri)) { + var valueMirror = reflect(value); + ClassMirror valueClass = valueMirror.type; + LibraryMirror valueLibrary = valueClass.owner as LibraryMirror; + Uri uri = valueLibrary.uri; + if (uri.scheme != "https" || + uri.host != "dartlang.org" || + uri.path != "/dart2js-stripped-uri") { + expect(check(uri), isTrue); + } +} + +main() { + var mirrors = currentMirrorSystem(); + test("Test reflective method invocation", () { + testInvoke(mirrors); + }); + test('Test intercepted objects', () { + testIntercepted(mirrors); + }); + test("Test field access", () { + testFieldAccess(mirrors); + }); + test("Test closure mirrors", () { + testClosureMirrors(mirrors); + }); + test("Test invoke constructor", () { + testInvokeConstructor(mirrors); + }); + test("Test current library uri", () { + testLibraryUri( + new Class(), + // TODO(floitsch): change this to "/mirrors_test.dart" when + // dart2js_mirrors_test.dart has been removed. + (Uri uri) => uri.path.endsWith('mirrors_test.dart')); + }); + test("Test dart library uri", () { + testLibraryUri("test", (Uri uri) { + if (uri == Uri.parse('dart:core')) return true; + // TODO(floitsch): do we want to fake the interceptors to + // be in dart:core? + return (uri == Uri.parse('dart:_interceptors')); + }); + }); + test("Test simple and qualifiedName", () { + testNames(mirrors); + }); + test("Test reflect type", () { + testReflectClass(mirrors); + }); +} diff --git a/tests/lib/mirrors/mirrors_visitor.dart b/tests/lib/mirrors/mirrors_visitor.dart new file mode 100644 index 00000000000..a78b7ec1208 --- /dev/null +++ b/tests/lib/mirrors/mirrors_visitor.dart @@ -0,0 +1,88 @@ +// Copyright (c) 2014, 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. + +library mirrors.visitor; + +import 'dart:mirrors'; + +abstract class MirrorsVisitor { + visitMirror(Mirror mirror) { + if (mirror == null) return; + + if (mirror is FunctionTypeMirror) { + visitFunctionTypeMirror(mirror); + } else if (mirror is ClassMirror) { + visitClassMirror(mirror); + } else if (mirror is TypedefMirror) { + visitTypedefMirror(mirror); + } else if (mirror is TypeVariableMirror) { + visitTypeVariableMirror(mirror); + } else if (mirror is TypeMirror) { + visitTypeMirror(mirror); + } else if (mirror is ParameterMirror) { + visitParameterMirror(mirror); + } else if (mirror is VariableMirror) { + visitVariableMirror(mirror); + } else if (mirror is MethodMirror) { + visitMethodMirror(mirror); + } else if (mirror is LibraryMirror) { + visitLibraryMirror(mirror); + } else if (mirror is InstanceMirror) { + visitInstanceMirror(mirror); + } else if (mirror is ObjectMirror) { + visitObjectMirror(mirror); + } else if (mirror is DeclarationMirror) { + visitDeclarationMirror(mirror); + } else { + throw new StateError( + 'Unexpected mirror kind ${mirror.runtimeType}: $mirror'); + } + } + + visitClassMirror(ClassMirror mirror) { + visitObjectMirror(mirror); + visitTypeMirror(mirror); + } + + visitDeclarationMirror(DeclarationMirror mirror) {} + + visitFunctionTypeMirror(FunctionTypeMirror mirror) { + visitClassMirror(mirror); + } + + visitInstanceMirror(InstanceMirror mirror) { + visitObjectMirror(mirror); + } + + visitLibraryMirror(LibraryMirror mirror) { + visitObjectMirror(mirror); + visitDeclarationMirror(mirror); + } + + visitMethodMirror(MethodMirror mirror) { + visitDeclarationMirror(mirror); + } + + visitObjectMirror(ObjectMirror mirror) {} + + visitParameterMirror(ParameterMirror mirror) { + visitVariableMirror(mirror); + } + + visitTypedefMirror(TypedefMirror mirror) { + visitTypeMirror(mirror); + } + + visitTypeMirror(TypeMirror mirror) { + visitDeclarationMirror(mirror); + } + + visitTypeVariableMirror(TypeVariableMirror mirror) { + visitTypeMirror(mirror); + } + + visitVariableMirror(VariableMirror mirror) { + visitDeclarationMirror(mirror); + } +} diff --git a/tests/lib/mirrors/mixin_application_test.dart b/tests/lib/mirrors/mixin_application_test.dart new file mode 100644 index 00000000000..2f616475f6a --- /dev/null +++ b/tests/lib/mirrors/mixin_application_test.dart @@ -0,0 +1,332 @@ +// Copyright (c) 2013, 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. + +// This test uses the multi-test "ok" feature to create two positive tests from +// one file. One of these tests fail on dart2js, but pass on the VM, or vice +// versa. +// TODO(ahe): When both implementations agree, remove the multi-test parts. + +library test.mixin_application_test; + +import 'dart:mirrors'; + +import 'package:expect/expect.dart'; + +import 'model.dart'; +import 'stringify.dart'; + +class Mixin { + int i = 0; + m() {} +} + +class Mixin2 { + int i2 = 0; + m2() {} +} + +class MixinApplication = C with Mixin; +class MixinApplicationA = C with Mixin, Mixin2; + +class UnusedMixinApplication = C with Mixin; + +class Subclass extends C with Mixin { + f() {} +} + +class Subclass2 extends MixinApplication { + g() {} +} + +class SubclassA extends C with Mixin, Mixin2 { + fa() {} +} + +class Subclass2A extends MixinApplicationA { + ga() {} +} + +membersOf(ClassMirror cm) { + var result = new Map(); + cm.declarations.forEach((k, v) { + if (v is MethodMirror && !v.isConstructor) result[k] = v; + if (v is VariableMirror) result[k] = v; + }); + return result; +} + +constructorsOf(ClassMirror cm) { + var result = new Map(); + cm.declarations.forEach((k, v) { + if (v is MethodMirror && v.isConstructor) result[k] = v; + }); + return result; +} + +checkClass(Type type, List expectedSuperclasses) { + int i = 0; + for (ClassMirror cls = reflectClass(type); + cls != null; + cls = cls.superclass) { + expect(expectedSuperclasses[i++], cls); + } + Expect.equals(i, expectedSuperclasses.length, '$type'); +} + +expectSame(ClassMirror a, ClassMirror b) { + Expect.equals(a, b); + expect(stringify(a), b); + expect(stringify(b), a); +} + +testMixin() { + checkClass(Mixin, [ + 'Class(s(Mixin) in s(test.mixin_application_test), top-level)', + 'Class(s(Object) in s(dart.core), top-level)', + ]); + + expect( + '{i: Variable(s(i) in s(Mixin)),' + ' m: Method(s(m) in s(Mixin))}', + membersOf(reflectClass(Mixin))); + + expect('{Mixin: Method(s(Mixin) in s(Mixin), constructor)}', + constructorsOf(reflectClass(Mixin))); +} + +testMixin2() { + checkClass(Mixin2, [ + 'Class(s(Mixin2) in s(test.mixin_application_test), top-level)', + 'Class(s(Object) in s(dart.core), top-level)', + ]); + + expect( + '{i2: Variable(s(i2) in s(Mixin2)),' + ' m2: Method(s(m2) in s(Mixin2))}', + membersOf(reflectClass(Mixin2))); + + expect('{Mixin2: Method(s(Mixin2) in s(Mixin2), constructor)}', + constructorsOf(reflectClass(Mixin2))); +} + +testMixinApplication() { + checkClass(MixinApplication, [ + 'Class(s(MixinApplication) in s(test.mixin_application_test), top-level)', + 'Class(s(C) in s(test.model), top-level)', + 'Class(s(B) in s(test.model), top-level)', + 'Class(s(A) in s(test.model), top-level)', + 'Class(s(Object) in s(dart.core), top-level)', + ]); + + String owner = 'Mixin'; + expect( + '{i: Variable(s(i) in s($owner)),' + ' m: Method(s(m) in s($owner))}', + membersOf(reflectClass(MixinApplication))); + + expect( + '{MixinApplication: Method(s(MixinApplication) in s(MixinApplication),' + ' constructor)}', + constructorsOf(reflectClass(MixinApplication))); + + expectSame(reflectClass(C), reflectClass(MixinApplication).superclass); +} + +testMixinApplicationA() { + String owner = ' in s(test.mixin_application_test)'; + checkClass(MixinApplicationA, [ + 'Class(s(MixinApplicationA)' + ' in s(test.mixin_application_test), top-level)', + 'Class(s(test.model.C with test.mixin_application_test.Mixin)' + '$owner, top-level)', + 'Class(s(C) in s(test.model), top-level)', + 'Class(s(B) in s(test.model), top-level)', + 'Class(s(A) in s(test.model), top-level)', + 'Class(s(Object) in s(dart.core), top-level)', + ]); + + owner = 'Mixin2'; + expect( + '{i2: Variable(s(i2) in s($owner)),' + ' m2: Method(s(m2) in s($owner))}', + membersOf(reflectClass(MixinApplicationA))); + + expect( + '{MixinApplicationA: Method(s(MixinApplicationA) in s(MixinApplicationA),' + ' constructor)}', + constructorsOf(reflectClass(MixinApplicationA))); + + expect( + '{i: Variable(s(i) in s(Mixin)),' + ' m: Method(s(m) in s(Mixin))}', + membersOf(reflectClass(MixinApplicationA).superclass)); + + String name = 'test.model.C with test.mixin_application_test.Mixin'; + expect( + '{$name:' + ' Method(s($name)' + ' in s($name), constructor)}', + constructorsOf(reflectClass(MixinApplicationA).superclass)); + + expectSame( + reflectClass(C), reflectClass(MixinApplicationA).superclass.superclass); +} + +testUnusedMixinApplication() { + checkClass(UnusedMixinApplication, [ + 'Class(s(UnusedMixinApplication) in s(test.mixin_application_test),' + ' top-level)', + 'Class(s(C) in s(test.model), top-level)', + 'Class(s(B) in s(test.model), top-level)', + 'Class(s(A) in s(test.model), top-level)', + 'Class(s(Object) in s(dart.core), top-level)', + ]); + + String owner = 'Mixin'; + expect( + '{i: Variable(s(i) in s($owner)),' + ' m: Method(s(m) in s($owner))}', + membersOf(reflectClass(UnusedMixinApplication))); + + expect( + '{UnusedMixinApplication: Method(s(UnusedMixinApplication)' + ' in s(UnusedMixinApplication), constructor)}', + constructorsOf(reflectClass(UnusedMixinApplication))); + + expectSame(reflectClass(C), reflectClass(UnusedMixinApplication).superclass); +} + +testSubclass() { + String owner = ' in s(test.mixin_application_test)'; + checkClass(Subclass, [ + 'Class(s(Subclass) in s(test.mixin_application_test), top-level)', + 'Class(s(test.model.C with test.mixin_application_test.Mixin)' + '$owner, top-level)', + 'Class(s(C) in s(test.model), top-level)', + 'Class(s(B) in s(test.model), top-level)', + 'Class(s(A) in s(test.model), top-level)', + 'Class(s(Object) in s(dart.core), top-level)', + ]); + + expect('{f: Method(s(f) in s(Subclass))}', membersOf(reflectClass(Subclass))); + + expect('{Subclass: Method(s(Subclass) in s(Subclass), constructor)}', + constructorsOf(reflectClass(Subclass))); + + expect( + '{i: Variable(s(i) in s(Mixin)),' + ' m: Method(s(m) in s(Mixin))}', + membersOf(reflectClass(Subclass).superclass)); + + String name = 'test.model.C with test.mixin_application_test.Mixin'; + expect( + '{$name:' + ' Method(s($name)' + ' in s($name), constructor)}', + constructorsOf(reflectClass(Subclass).superclass)); + + expectSame(reflectClass(C), reflectClass(Subclass).superclass.superclass); +} + +testSubclass2() { + checkClass(Subclass2, [ + 'Class(s(Subclass2) in s(test.mixin_application_test), top-level)', + 'Class(s(MixinApplication) in s(test.mixin_application_test), top-level)', + 'Class(s(C) in s(test.model), top-level)', + 'Class(s(B) in s(test.model), top-level)', + 'Class(s(A) in s(test.model), top-level)', + 'Class(s(Object) in s(dart.core), top-level)', + ]); + + expect( + '{g: Method(s(g) in s(Subclass2))}', membersOf(reflectClass(Subclass2))); + + expect('{Subclass2: Method(s(Subclass2) in s(Subclass2), constructor)}', + constructorsOf(reflectClass(Subclass2))); + + expectSame( + reflectClass(MixinApplication), reflectClass(Subclass2).superclass); +} + +testSubclassA() { + String owner = ' in s(test.mixin_application_test)'; + checkClass(SubclassA, [ + 'Class(s(SubclassA) in s(test.mixin_application_test), top-level)', + 'Class(s(test.model.C with test.mixin_application_test.Mixin,' + ' test.mixin_application_test.Mixin2)$owner, top-level)', + 'Class(s(test.model.C with test.mixin_application_test.Mixin)$owner,' + ' top-level)', + 'Class(s(C) in s(test.model), top-level)', + 'Class(s(B) in s(test.model), top-level)', + 'Class(s(A) in s(test.model), top-level)', + 'Class(s(Object) in s(dart.core), top-level)', + ]); + + expect('{fa: Method(s(fa) in s(SubclassA))}', + membersOf(reflectClass(SubclassA))); + + expect('{SubclassA: Method(s(SubclassA) in s(SubclassA), constructor)}', + constructorsOf(reflectClass(SubclassA))); + + expect( + '{i2: Variable(s(i2) in s(Mixin2)),' + ' m2: Method(s(m2) in s(Mixin2))}', + membersOf(reflectClass(SubclassA).superclass)); + + String name = 'test.model.C with test.mixin_application_test.Mixin,' + ' test.mixin_application_test.Mixin2'; + expect('{$name: Method(s($name) in s($name), constructor)}', + constructorsOf(reflectClass(SubclassA).superclass)); + + expect( + '{i: Variable(s(i) in s(Mixin)),' + ' m: Method(s(m) in s(Mixin))}', + membersOf(reflectClass(SubclassA).superclass.superclass)); + + name = 'test.model.C with test.mixin_application_test.Mixin'; + expect( + '{$name:' + ' Method(s($name)' + ' in s($name), constructor)}', + constructorsOf(reflectClass(SubclassA).superclass.superclass)); + + expectSame(reflectClass(C), + reflectClass(SubclassA).superclass.superclass.superclass); +} + +testSubclass2A() { + String owner = ' in s(test.mixin_application_test)'; + checkClass(Subclass2A, [ + 'Class(s(Subclass2A) in s(test.mixin_application_test), top-level)', + 'Class(s(MixinApplicationA) in s(test.mixin_application_test),' + ' top-level)', + 'Class(s(test.model.C with test.mixin_application_test.Mixin)$owner,' + ' top-level)', + 'Class(s(C) in s(test.model), top-level)', + 'Class(s(B) in s(test.model), top-level)', + 'Class(s(A) in s(test.model), top-level)', + 'Class(s(Object) in s(dart.core), top-level)', + ]); + + expect('{ga: Method(s(ga) in s(Subclass2A))}', + membersOf(reflectClass(Subclass2A))); + + expect('{Subclass2A: Method(s(Subclass2A) in s(Subclass2A), constructor)}', + constructorsOf(reflectClass(Subclass2A))); + + expectSame( + reflectClass(MixinApplicationA), reflectClass(Subclass2A).superclass); +} + +main() { + testMixin(); + testMixin2(); + testMixinApplication(); + testMixinApplicationA(); + testUnusedMixinApplication(); + testSubclass(); + testSubclass2(); + testSubclassA(); + testSubclass2A(); +} diff --git a/tests/lib/mirrors/mixin_members_test.dart b/tests/lib/mirrors/mixin_members_test.dart new file mode 100644 index 00000000000..ae6db71b442 --- /dev/null +++ b/tests/lib/mirrors/mixin_members_test.dart @@ -0,0 +1,70 @@ +// Copyright (c) 2013, 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. + +library mixin_members_test; + +import "dart:mirrors"; + +import "package:expect/expect.dart"; + +import 'stringify.dart'; + +abstract class Fooer { + foo1(); +} + +class S implements Fooer { + foo1() {} + foo2() {} +} + +class M1 { + bar1() {} + bar2() {} +} + +class M2 { + baz1() {} + baz2() {} +} + +class C extends S with M1, M2 {} + +membersOf(ClassMirror cm) { + var result = new Map(); + cm.declarations.forEach((k, v) { + if (v is MethodMirror && !v.isConstructor) result[k] = v; + if (v is VariableMirror) result[k] = v; + }); + return result; +} + +main() { + ClassMirror cm = reflectClass(C); + ClassMirror sM1M2 = cm.superclass; + ClassMirror sM1 = sM1M2.superclass; + ClassMirror s = sM1.superclass; + expect('{}', membersOf(cm)); + expect( + '[s(baz1), s(baz2)]', + // TODO(ahe): Shouldn't have to sort. + sort(membersOf(sM1M2).keys), + '(S with M1, M2).members'); + expect('[s(M2)]', simpleNames(sM1M2.superinterfaces), + '(S with M1, M2).superinterfaces'); + expect( + '[s(bar1), s(bar2)]', + // TODO(ahe): Shouldn't have to sort. + sort(membersOf(sM1).keys), + '(S with M1).members'); + expect('[s(M1)]', simpleNames(sM1.superinterfaces), + '(S with M1).superinterfaces'); + expect( + '[s(foo1), s(foo2)]', + // TODO(ahe): Shouldn't have to sort. + sort(membersOf(s).keys), + 's.members'); + expect('[s(Fooer)]', simpleNames(s.superinterfaces), 's.superinterfaces'); + Expect.equals(s, reflectClass(S)); +} diff --git a/tests/lib/mirrors/mixin_simple_test.dart b/tests/lib/mirrors/mixin_simple_test.dart new file mode 100644 index 00000000000..f9f0915cd0f --- /dev/null +++ b/tests/lib/mirrors/mixin_simple_test.dart @@ -0,0 +1,43 @@ +// 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. + +library test.mixin; + +import 'dart:mirrors'; + +import 'package:expect/expect.dart'; + +class Super {} + +class Mixin {} + +class Mixin2 {} + +class Class extends Super with Mixin {} + +class MultipleMixins extends Class with Mixin2 {} + +main() { + Expect.equals(reflectClass(Class), reflectClass(Class).mixin); + Expect.equals(reflectClass(Mixin), reflectClass(Class).superclass.mixin); + Expect.equals( + reflectClass(Super), reflectClass(Class).superclass.superclass.mixin); + + Expect.equals( + reflectClass(MultipleMixins), reflectClass(MultipleMixins).mixin); + Expect.equals( + reflectClass(Mixin2), reflectClass(MultipleMixins).superclass.mixin); + Expect.equals(reflectClass(Class), + reflectClass(MultipleMixins).superclass.superclass.mixin); + Expect.equals(reflectClass(Mixin), + reflectClass(MultipleMixins).superclass.superclass.superclass.mixin); + Expect.equals( + reflectClass(Super), + reflectClass(MultipleMixins) + .superclass + .superclass + .superclass + .superclass + .mixin); +} diff --git a/tests/lib/mirrors/mixin_test.dart b/tests/lib/mirrors/mixin_test.dart new file mode 100644 index 00000000000..d55d5eb073c --- /dev/null +++ b/tests/lib/mirrors/mixin_test.dart @@ -0,0 +1,51 @@ +// Copyright (c) 2013, 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. + +library test.mixin; + +import 'dart:mirrors'; + +import 'package:expect/expect.dart'; + +class Super {} + +class Mixin {} + +class Mixin2 {} + +class Mixin3 {} + +class MixinApplication = Super with Mixin; + +class Class extends Super with Mixin {} + +class MultipleMixins extends Super with Mixin, Mixin2, Mixin3 {} + +main() { + Expect.equals(reflectClass(Mixin), reflectClass(MixinApplication).mixin); + Expect.equals( + reflectClass(Super), reflectClass(MixinApplication).superclass.mixin); + + Expect.equals(reflectClass(Class), reflectClass(Class).mixin); + Expect.equals(reflectClass(Mixin), reflectClass(Class).superclass.mixin); + Expect.equals( + reflectClass(Super), reflectClass(Class).superclass.superclass.mixin); + + Expect.equals( + reflectClass(MultipleMixins), reflectClass(MultipleMixins).mixin); + Expect.equals( + reflectClass(Mixin3), reflectClass(MultipleMixins).superclass.mixin); + Expect.equals(reflectClass(Mixin2), + reflectClass(MultipleMixins).superclass.superclass.mixin); + Expect.equals(reflectClass(Mixin), + reflectClass(MultipleMixins).superclass.superclass.superclass.mixin); + Expect.equals( + reflectClass(Super), + reflectClass(MultipleMixins) + .superclass + .superclass + .superclass + .superclass + .mixin); +} diff --git a/tests/lib/mirrors/model.dart b/tests/lib/mirrors/model.dart new file mode 100644 index 00000000000..508cbf2e2f2 --- /dev/null +++ b/tests/lib/mirrors/model.dart @@ -0,0 +1,49 @@ +// Copyright (c) 2013, 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. + +library test.model; + +var accessorA; + +var accessorB; + +var accessorC; + +var fieldC; + +class A { + var field; + instanceMethod(x) => 'A:instanceMethod($x)'; + get accessor => 'A:get accessor'; + set accessor(x) { + accessorA = x; + } + + aMethod() => 'aMethod'; +} + +class B extends A { + get field => 'B:get field'; + instanceMethod(x) => 'B:instanceMethod($x)'; + get accessor => 'B:get accessor'; + set accessor(x) { + accessorB = x; + } + + bMethod() => 'bMethod'; +} + +class C extends B { + set field(x) { + fieldC = x; + } + + instanceMethod(x) => 'C:instanceMethod($x)'; + get accessor => 'C:get accessor'; + set accessor(x) { + accessorC = x; + } + + cMethod() => 'cMethod'; +} diff --git a/tests/lib/mirrors/model_test.dart b/tests/lib/mirrors/model_test.dart new file mode 100644 index 00000000000..1e249010236 --- /dev/null +++ b/tests/lib/mirrors/model_test.dart @@ -0,0 +1,55 @@ +// Copyright (c) 2013, 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. + +library test.model_test; + +import 'package:expect/expect.dart'; + +import 'model.dart'; + +main() { + dynamic a = new A(); + dynamic b = new B(); + dynamic c = new C(); + + Expect.isNull(a.field); + Expect.equals('B:get field', b.field); + Expect.equals('B:get field', c.field); + + a.field = 42; + b.field = 87; + c.field = 89; + Expect.equals(42, a.field); + Expect.equals('B:get field', b.field); + Expect.equals('B:get field', c.field); + Expect.equals(89, fieldC); + + Expect.equals('A:instanceMethod(7)', a.instanceMethod(7)); + Expect.equals('B:instanceMethod(9)', b.instanceMethod(9)); + Expect.equals('C:instanceMethod(13)', c.instanceMethod(13)); + + Expect.equals('A:get accessor', a.accessor); + Expect.equals('B:get accessor', b.accessor); + Expect.equals('C:get accessor', c.accessor); + + a.accessor = 'foo'; + b.accessor = 'bar'; + c.accessor = 'baz'; + + Expect.equals('foo', accessorA); + Expect.equals('bar', accessorB); + Expect.equals('baz', accessorC); + + Expect.equals('aMethod', a.aMethod()); + Expect.equals('aMethod', b.aMethod()); + Expect.equals('aMethod', c.aMethod()); + + Expect.throwsNoSuchMethodError(() => a.bMethod()); + Expect.equals('bMethod', b.bMethod()); + Expect.equals('bMethod', c.bMethod()); + + Expect.throwsNoSuchMethodError(() => a.cMethod()); + Expect.throwsNoSuchMethodError(() => b.cMethod()); + Expect.equals('cMethod', c.cMethod()); +} diff --git a/tests/lib/mirrors/new_instance_optional_arguments_test.dart b/tests/lib/mirrors/new_instance_optional_arguments_test.dart new file mode 100644 index 00000000000..3d50f040472 --- /dev/null +++ b/tests/lib/mirrors/new_instance_optional_arguments_test.dart @@ -0,0 +1,126 @@ +// Copyright (c) 2014, 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. + +library mirror_test; + +import 'dart:mirrors'; + +import 'package:expect/expect.dart'; + +class A { + var req1, opt1, opt2; + A.a0([opt1]) : this.opt1 = opt1; + A.b0([opt1, opt2]) + : this.opt1 = opt1, + this.opt2 = opt2; + A.c0([opt1 = 499]) : this.opt1 = opt1; + A.d0([opt1 = 499, opt2 = 42]) + : this.opt1 = opt1, + this.opt2 = opt2; + A.a1(req1, [opt1]) + : this.req1 = req1, + this.opt1 = opt1; + A.b1(req1, [opt1, opt2]) + : this.req1 = req1, + this.opt1 = opt1, + this.opt2 = opt2; + A.c1(req1, [opt1 = 499]) + : this.req1 = req1, + this.opt1 = opt1; + A.d1(req1, [opt1 = 499, opt2 = 42]) + : this.req1 = req1, + this.opt1 = opt1, + this.opt2 = opt2; +} + +main() { + ClassMirror cm = reflectClass(A); + + var o; + o = cm.newInstance(#a0, []).reflectee; + Expect.equals(null, o.req1); + Expect.equals(null, o.opt1); + Expect.equals(null, o.opt2); + o = cm.newInstance(#b0, []).reflectee; + Expect.equals(null, o.req1); + Expect.equals(null, o.opt1); + Expect.equals(null, o.opt2); + o = cm.newInstance(#c0, []).reflectee; + Expect.equals(null, o.req1); + Expect.equals(499, o.opt1); + Expect.equals(null, o.opt2); + o = cm.newInstance(#d0, []).reflectee; + Expect.equals(null, o.req1); + Expect.equals(499, o.opt1); + Expect.equals(42, o.opt2); + + o = cm.newInstance(#a0, [77]).reflectee; + Expect.equals(null, o.req1); + Expect.equals(77, o.opt1); + Expect.equals(null, o.opt2); + o = cm.newInstance(#b0, [77]).reflectee; + Expect.equals(null, o.req1); + Expect.equals(77, o.opt1); + Expect.equals(null, o.opt2); + o = cm.newInstance(#c0, [77]).reflectee; + Expect.equals(null, o.req1); + Expect.equals(77, o.opt1); + Expect.equals(null, o.opt2); + o = cm.newInstance(#d0, [77]).reflectee; + Expect.equals(null, o.req1); + Expect.equals(77, o.opt1); + Expect.equals(42, o.opt2); + + o = cm.newInstance(#b0, [77, 11]).reflectee; + Expect.equals(null, o.req1); + Expect.equals(77, o.opt1); + Expect.equals(11, o.opt2); + o = cm.newInstance(#d0, [77, 11]).reflectee; + Expect.equals(null, o.req1); + Expect.equals(77, o.opt1); + Expect.equals(11, o.opt2); + + o = cm.newInstance(#a1, [123]).reflectee; + Expect.equals(123, o.req1); + Expect.equals(null, o.opt1); + Expect.equals(null, o.opt2); + o = cm.newInstance(#b1, [123]).reflectee; + Expect.equals(123, o.req1); + Expect.equals(null, o.opt1); + Expect.equals(null, o.opt2); + o = cm.newInstance(#c1, [123]).reflectee; + Expect.equals(123, o.req1); + Expect.equals(499, o.opt1); + Expect.equals(null, o.opt2); + o = cm.newInstance(#d1, [123]).reflectee; + Expect.equals(123, o.req1); + Expect.equals(499, o.opt1); + Expect.equals(42, o.opt2); + + o = cm.newInstance(#a1, [123, 77]).reflectee; + Expect.equals(123, o.req1); + Expect.equals(77, o.opt1); + Expect.equals(null, o.opt2); + o = cm.newInstance(#b1, [123, 77]).reflectee; + Expect.equals(123, o.req1); + Expect.equals(77, o.opt1); + Expect.equals(null, o.opt2); + o = cm.newInstance(#c1, [123, 77]).reflectee; + Expect.equals(123, o.req1); + Expect.equals(77, o.opt1); + Expect.equals(null, o.opt2); + o = cm.newInstance(#d1, [123, 77]).reflectee; + Expect.equals(123, o.req1); + Expect.equals(77, o.opt1); + Expect.equals(42, o.opt2); + + o = cm.newInstance(#b1, [123, 77, 11]).reflectee; + Expect.equals(123, o.req1); + Expect.equals(77, o.opt1); + Expect.equals(11, o.opt2); + o = cm.newInstance(#d1, [123, 77, 11]).reflectee; + Expect.equals(123, o.req1); + Expect.equals(77, o.opt1); + Expect.equals(11, o.opt2); +} diff --git a/tests/lib/mirrors/new_instance_with_type_arguments_test.dart b/tests/lib/mirrors/new_instance_with_type_arguments_test.dart new file mode 100644 index 00000000000..cf0ee6dd0f0 --- /dev/null +++ b/tests/lib/mirrors/new_instance_with_type_arguments_test.dart @@ -0,0 +1,60 @@ +// Copyright (c) 2013, 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. + +library test.new_instance_with_type_arguments_test; + +import 'dart:mirrors'; + +import 'package:expect/expect.dart'; + +class A { + Type get t => T; +} + +class B extends A {} + +class C extends A { + Type get s => S; +} + +main() { + ClassMirror cmA = reflectClass(A); + ClassMirror cmB = reflectClass(B); + ClassMirror cmC = reflectClass(C); + + dynamic a_int = new A(); + dynamic a_dynamic = new A(); + dynamic b = new B(); + dynamic c_string = new C(); + dynamic c_dynamic = new C(); + + Expect.equals(int, a_int.t); + Expect.equals(dynamic, a_dynamic.t); + Expect.equals(int, b.t); + Expect.equals(num, c_string.t); + Expect.equals(num, c_dynamic.t); + + Expect.equals(String, c_string.s); + Expect.equals(dynamic, c_dynamic.s); + + dynamic reflective_a_int = + cmB.superclass.newInstance(Symbol.empty, []).reflectee; + dynamic reflective_a_dynamic = cmA.newInstance(Symbol.empty, []).reflectee; + dynamic reflective_b = cmB.newInstance(Symbol.empty, []).reflectee; + dynamic reflective_c_dynamic = cmC.newInstance(Symbol.empty, []).reflectee; + + Expect.equals(int, reflective_a_int.t); + Expect.equals(dynamic, reflective_a_dynamic.t); + Expect.equals(int, reflective_b.t); + Expect.equals(num, c_string.t); + Expect.equals(num, reflective_c_dynamic.t); + + Expect.equals(String, c_string.s); + Expect.equals(dynamic, reflective_c_dynamic.s); + + Expect.equals(a_int.runtimeType, reflective_a_int.runtimeType); + Expect.equals(a_dynamic.runtimeType, reflective_a_dynamic.runtimeType); + Expect.equals(b.runtimeType, reflective_b.runtimeType); + Expect.equals(c_dynamic.runtimeType, reflective_c_dynamic.runtimeType); +} diff --git a/tests/lib/mirrors/no_metadata_test.dart b/tests/lib/mirrors/no_metadata_test.dart new file mode 100644 index 00000000000..642dd83634d --- /dev/null +++ b/tests/lib/mirrors/no_metadata_test.dart @@ -0,0 +1,13 @@ +// Copyright (c) 2013, 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. + +import 'dart:mirrors'; + +import 'stringify.dart'; + +class Foo {} + +main() { + expect('[]', reflectClass(Foo).metadata); +} diff --git a/tests/lib/mirrors/null2_test.dart b/tests/lib/mirrors/null2_test.dart new file mode 100644 index 00000000000..4c5590d398f --- /dev/null +++ b/tests/lib/mirrors/null2_test.dart @@ -0,0 +1,16 @@ +// Copyright (c) 2013, 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. + +library test.null_test; + +import 'dart:mirrors'; + +import 'package:expect/expect.dart'; + +main() { + InstanceMirror nullMirror = reflect(null); + for (int i = 0; i < 10; i++) { + Expect.isTrue(nullMirror.getField(#hashCode).reflectee is int); + } +} diff --git a/tests/lib/mirrors/null_test.dart b/tests/lib/mirrors/null_test.dart new file mode 100644 index 00000000000..f0e154ea849 --- /dev/null +++ b/tests/lib/mirrors/null_test.dart @@ -0,0 +1,71 @@ +// Copyright (c) 2013, 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. + +// VMOptions=--optimization-counter-threshold=5 + +import "dart:mirrors"; +import "package:expect/expect.dart"; + +void main() { + for (int i = 0; i < 10; i++) { + test(); + } +} + +void test() { + ClassMirror cm = reflectClass(Null); + + InstanceMirror im1 = reflect(null); + Expect.equals(cm, im1.type); + Expect.isTrue(im1.invoke(const Symbol("=="), [null]).reflectee); + Expect.isFalse(im1.invoke(const Symbol("=="), [42]).reflectee); + + var obj = confuse(null); // Null value that isn't known at compile-time. + InstanceMirror im2 = reflect(obj); + Expect.equals(cm, im2.type); + Expect.isTrue(im2.invoke(const Symbol("=="), [null]).reflectee); + Expect.isFalse(im2.invoke(const Symbol("=="), [42]).reflectee); + + InstanceMirror nullMirror = reflect(null); + Expect.isTrue(nullMirror.getField(#hashCode).reflectee is int); + Expect.equals(null.hashCode, nullMirror.getField(#hashCode).reflectee); + Expect.equals('Null', nullMirror.getField(#runtimeType).reflectee.toString()); + Expect.isTrue(nullMirror.invoke(#==, [null]).reflectee); + Expect.isFalse(nullMirror.invoke(#==, [new Object()]).reflectee); + Expect.equals('null', nullMirror.invoke(#toString, []).reflectee); + Expect.throwsNoSuchMethodError( + () => nullMirror.invoke(#notDefined, []), 'noSuchMethod'); + + ClassMirror NullMirror = nullMirror.type; + Expect.equals(reflectClass(Null), NullMirror); + Expect.equals(#Null, NullMirror.simpleName); + Expect.equals(#Object, NullMirror.superclass.simpleName); + Expect.equals(null, NullMirror.superclass.superclass); + Expect.listEquals([], NullMirror.superinterfaces); + Map libraries = currentMirrorSystem().libraries; + LibraryMirror coreLibrary = libraries[Uri.parse('dart:core')]; + if (coreLibrary == null) { + // In minified mode we don't preserve the URIs. + coreLibrary = libraries.values + .firstWhere((LibraryMirror lm) => lm.simpleName == #dart.core); + Uri uri = coreLibrary.uri; + Expect.equals("https", uri.scheme); + Expect.equals("dartlang.org", uri.host); + Expect.equals("/dart2js-stripped-uri", uri.path); + } + Expect.equals(coreLibrary, NullMirror.owner); +} + +// Magic incantation to avoid the compiler recognizing the constant values +// at compile time. If the result is computed at compile time, the dynamic code +// will not be tested. +confuse(x) { + try { + if (new DateTime.now().millisecondsSinceEpoch == 42) x = 42; + throw [x]; + } catch (e) { + return e[0]; + } + return 42; +} diff --git a/tests/lib/mirrors/operator_test.dart b/tests/lib/mirrors/operator_test.dart new file mode 100644 index 00000000000..a7fafbcb223 --- /dev/null +++ b/tests/lib/mirrors/operator_test.dart @@ -0,0 +1,140 @@ +// Copyright (c) 2013, 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 operators. +library test.operator_test; + +import 'dart:mirrors'; + +import 'package:expect/expect.dart'; + +import 'stringify.dart'; + +class Foo { + Foo operator ~() {} + Foo operator -() {} + + bool operator ==(a) {} + Foo operator [](int a) {} + Foo operator *(Foo a) {} + Foo operator /(Foo a) {} + Foo operator %(Foo a) {} + Foo operator ~/(Foo a) {} + Foo operator +(Foo a) {} + Foo operator <<(Foo a) {} + Foo operator >>(Foo a) {} + Foo operator >=(Foo a) {} + Foo operator >(Foo a) {} + Foo operator <=(Foo a) {} + Foo operator <(Foo a) {} + Foo operator &(Foo a) {} + Foo operator ^(Foo a) {} + Foo operator |(Foo a) {} + Foo operator -(Foo a) {} + + // TODO(ahe): use void when dart2js reifies that type. + operator []=(int a, Foo b) {} +} + +void main() { + ClassMirror cls = reflectClass(Foo); + var operators = new Map(); + var operatorParameters = new Map(); + var returnTypes = new Map(); + for (var method in cls.declarations.values) { + if (method is MethodMirror) { + if (!method.isConstructor) { + Expect.isTrue(method.isRegularMethod); + Expect.isTrue(method.isOperator); + Expect.isFalse(method.isGetter); + Expect.isFalse(method.isSetter); + Expect.isFalse(method.isAbstract); + operators[method.simpleName] = method; + operatorParameters[method.simpleName] = method.parameters; + returnTypes[method.simpleName] = method.returnType; + } + } + } + expect(OPERATORS, operators); + expect(PARAMETERS, operatorParameters); + expect(RETURN_TYPES, returnTypes); +} + +const String OPERATORS = '{' + '%: Method(s(%) in s(Foo)), ' + '&: Method(s(&) in s(Foo)), ' + '*: Method(s(*) in s(Foo)), ' + '+: Method(s(+) in s(Foo)), ' + '-: Method(s(-) in s(Foo)), ' + '/: Method(s(/) in s(Foo)), ' + '<: Method(s(<) in s(Foo)), ' + '<<: Method(s(<<) in s(Foo)), ' + '<=: Method(s(<=) in s(Foo)), ' + '==: Method(s(==) in s(Foo)), ' + '>: Method(s(>) in s(Foo)), ' + '>=: Method(s(>=) in s(Foo)), ' + '>>: Method(s(>>) in s(Foo)), ' + '[]: Method(s([]) in s(Foo)), ' + '[]=: Method(s([]=) in s(Foo)), ' + '^: Method(s(^) in s(Foo)), ' + 'unary-: Method(s(unary-) in s(Foo)), ' + '|: Method(s(|) in s(Foo)), ' + '~: Method(s(~) in s(Foo)), ' + '~/: Method(s(~/) in s(Foo))' + '}'; + +const String DYNAMIC = 'Type(s(dynamic), top-level)'; + +const String FOO = 'Class(s(Foo) in s(test.operator_test), top-level)'; + +const String INT = 'Class(s(int) in s(dart.core), top-level)'; + +const String BOOL = 'Class(s(bool) in s(dart.core), top-level)'; + +const String PARAMETERS = '{' + '%: [Parameter(s(a) in s(%), type = $FOO)], ' + '&: [Parameter(s(a) in s(&), type = $FOO)], ' + '*: [Parameter(s(a) in s(*), type = $FOO)], ' + '+: [Parameter(s(a) in s(+), type = $FOO)], ' + '-: [Parameter(s(a) in s(-), type = $FOO)], ' + '/: [Parameter(s(a) in s(/), type = $FOO)], ' + '<: [Parameter(s(a) in s(<), type = $FOO)], ' + '<<: [Parameter(s(a) in s(<<), type = $FOO)], ' + '<=: [Parameter(s(a) in s(<=), type = $FOO)], ' + '==: [Parameter(s(a) in s(==), type = $DYNAMIC)], ' + '>: [Parameter(s(a) in s(>), type = $FOO)], ' + '>=: [Parameter(s(a) in s(>=), type = $FOO)], ' + '>>: [Parameter(s(a) in s(>>), type = $FOO)], ' + '[]: [Parameter(s(a) in s([]), type = $INT)], ' + '[]=: [Parameter(s(a) in s([]=), type = $INT), ' + 'Parameter(s(b) in s([]=), type = $FOO)], ' + '^: [Parameter(s(a) in s(^), type = $FOO)], ' + 'unary-: [], ' + '|: [Parameter(s(a) in s(|), type = $FOO)], ' + '~: [], ' + '~/: [Parameter(s(a) in s(~/), type = $FOO)]' + '}'; + +const String RETURN_TYPES = '{' + '%: $FOO, ' + '&: $FOO, ' + '*: $FOO, ' + '+: $FOO, ' + '-: $FOO, ' + '/: $FOO, ' + '<: $FOO, ' + '<<: $FOO, ' + '<=: $FOO, ' + '==: $BOOL, ' + '>: $FOO, ' + '>=: $FOO, ' + '>>: $FOO, ' + '[]: $FOO, ' + '[]=: $DYNAMIC, ' + '^: $FOO, ' + 'unary-: $FOO, ' + '|: $FOO, ' + '~: $FOO, ' + '~/: $FOO' + '}'; diff --git a/tests/lib/mirrors/optional_parameters_test.dart b/tests/lib/mirrors/optional_parameters_test.dart new file mode 100644 index 00000000000..10515dd8b9a --- /dev/null +++ b/tests/lib/mirrors/optional_parameters_test.dart @@ -0,0 +1,29 @@ +// Copyright (c) 2015, 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. + +// Regression test for http://dartbug.com/22987. +// Ensure that functions whose signature only differs in optionality of +// parameters are reflected correctly. + +library optional_parameter_test; + +import "dart:mirrors"; +import 'package:expect/expect.dart'; + +class A { + foo(int x) => x; +} + +class B { + foo([int x = -1]) => x + 1; +} + +main() { + var x = {}; + x["A"] = reflect(new A()); + x["B"] = reflect(new B()); + + Expect.equals(1, x["A"].invoke(#foo, [1]).reflectee); + Expect.equals(2, x["B"].invoke(#foo, [1]).reflectee); +} diff --git a/tests/lib/mirrors/other_declarations_location_test.dart b/tests/lib/mirrors/other_declarations_location_test.dart new file mode 100644 index 00000000000..cbd0b9d6c05 --- /dev/null +++ b/tests/lib/mirrors/other_declarations_location_test.dart @@ -0,0 +1,57 @@ +// Copyright (c) 2015, 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. + +library test.declarations_location; + +import "dart:mirrors"; +import "package:expect/expect.dart"; +import "library_without_declaration.dart"; +import "library_with_annotated_declaration.dart"; + +const metadata = 'metadata'; + +class C { + var a; + final b = 2; + static var c; + static final d = 4; + @metadata + var e; + List f; +} + +// We only check for a suffix of the uri because the test might be run from +// any number of absolute paths. +expectLocation( + DeclarationMirror mirror, String uriSuffix, int line, int column) { + SourceLocation location = mirror.location; + Uri uri = location.sourceUri; + Expect.isTrue( + uri.toString().endsWith(uriSuffix), "Expected suffix $uriSuffix in $uri"); + Expect.equals(line, location.line, "line"); + Expect.equals(column, location.column, "column"); +} + +main() { + String mainSuffix = 'other_declarations_location_test.dart'; + + // Fields. + expectLocation(reflectClass(C).declarations[#a], mainSuffix, 15, 7); + expectLocation(reflectClass(C).declarations[#b], mainSuffix, 16, 9); + expectLocation(reflectClass(C).declarations[#c], mainSuffix, 17, 14); + expectLocation(reflectClass(C).declarations[#d], mainSuffix, 18, 16); + expectLocation(reflectClass(C).declarations[#e], mainSuffix, 20, 7); + expectLocation(reflectClass(C).declarations[#f], mainSuffix, 21, 11); + + // Type variables. + expectLocation(reflectClass(C).declarations[#S], mainSuffix, 14, 9); + expectLocation(reflectClass(C).declarations[#T], mainSuffix, 14, 12); + + // Libraries. + expectLocation(reflectClass(C).owner, mainSuffix, 5, 1); + expectLocation(reflectClass(ClassInLibraryWithoutDeclaration).owner, + "library_without_declaration.dart", 1, 1); + expectLocation(reflectClass(ClassInLibraryWithAnnotatedDeclaration).owner, + "library_with_annotated_declaration.dart", 5, 1); +} diff --git a/tests/lib/mirrors/other_library.dart b/tests/lib/mirrors/other_library.dart new file mode 100644 index 00000000000..c1e908f4a8d --- /dev/null +++ b/tests/lib/mirrors/other_library.dart @@ -0,0 +1,15 @@ +// Copyright (c) 2013, 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. + +library test.other_library; + +topLevelMethod() => 42; +get topLevelGetter => 42; +set topLevelSetter(x) => 42; +var topLevelField = 42; + +_topLevelMethod() => 42; +get _topLevelGetter => 42; +set _topLevelSetter(x) => 42; +var _topLevelField = 42; diff --git a/tests/lib/mirrors/parameter_abstract_test.dart b/tests/lib/mirrors/parameter_abstract_test.dart new file mode 100644 index 00000000000..cf2bd25ce81 --- /dev/null +++ b/tests/lib/mirrors/parameter_abstract_test.dart @@ -0,0 +1,32 @@ +// Copyright (c) 2019, 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. + +import 'dart:mirrors'; + +import 'package:expect/expect.dart'; +import 'stringify.dart'; + +const X = 'X'; +const Y = 'Y'; +const Z = 'Z'; + +abstract class C { + foo1({@X int x: 1, @Y int y: 2, @Z int z: 3}); +} + +main() { + ClassMirror cm = reflectClass(C); + + MethodMirror foo1 = cm.declarations[#foo1] as MethodMirror; + expect('Method(s(foo1) in s(C), abstract)', foo1); + expect( + 'Parameter(s(x) in s(foo1), optional, named, type = Class(s(int) in s(dart.core), top-level))', + foo1.parameters[0]); + expect( + 'Parameter(s(y) in s(foo1), optional, named, type = Class(s(int) in s(dart.core), top-level))', + foo1.parameters[1]); + expect( + 'Parameter(s(z) in s(foo1), optional, named, type = Class(s(int) in s(dart.core), top-level))', + foo1.parameters[2]); +} diff --git a/tests/lib/mirrors/parameter_annotation_mirror_test.dart b/tests/lib/mirrors/parameter_annotation_mirror_test.dart new file mode 100644 index 00000000000..ff4aaa6b4ae --- /dev/null +++ b/tests/lib/mirrors/parameter_annotation_mirror_test.dart @@ -0,0 +1,64 @@ +// Copyright (c) 2014, 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. + +import "dart:mirrors"; + +import 'package:expect/expect.dart'; + +class ParameterAnnotation { + final String value; + const ParameterAnnotation(this.value); +} + +class Foo { + Foo(@ParameterAnnotation("vogel") p) {} + Foo.named(@ParameterAnnotation("hamster") p) {} + Foo.named2( + @ParameterAnnotation("hamster") p, @ParameterAnnotation("wurm") p2) {} + + f1(@ParameterAnnotation("hest") p) {} + f2(@ParameterAnnotation("hest") @ParameterAnnotation("fisk") p) {} + f3(a, @ParameterAnnotation("fugl") p) {} + f4(@ParameterAnnotation("fisk") a, {@ParameterAnnotation("hval") p}) {} + f5(@ParameterAnnotation("fisk") a, [@ParameterAnnotation("hval") p]) {} + f6({@ParameterAnnotation("fisk") z, @ParameterAnnotation("hval") p}) {} + + set s1(@ParameterAnnotation("cheval") p) {} +} + +expectAnnotations( + Type type, Symbol method, int parameterIndex, List expectedValues) { + MethodMirror mirror = reflectClass(type).declarations[method] as MethodMirror; + ParameterMirror parameter = mirror.parameters[parameterIndex]; + List annotations = parameter.metadata; + Expect.equals(annotations.length, expectedValues.length, + "wrong number of parameter annotations"); + for (int i = 0; i < annotations.length; i++) { + Expect.equals( + expectedValues[i], + annotations[i].reflectee.value, + "annotation #$i of parameter #$parameterIndex " + "of $type.$method."); + } +} + +main() { + expectAnnotations(Foo, #Foo, 0, ["vogel"]); + expectAnnotations(Foo, #Foo.named, 0, ["hamster"]); + expectAnnotations(Foo, #Foo.named2, 0, ["hamster"]); + expectAnnotations(Foo, #Foo.named2, 1, ["wurm"]); + + expectAnnotations(Foo, #f1, 0, ["hest"]); + expectAnnotations(Foo, #f2, 0, ["hest", "fisk"]); + expectAnnotations(Foo, #f3, 0, []); + expectAnnotations(Foo, #f3, 1, ["fugl"]); + expectAnnotations(Foo, #f4, 0, ["fisk"]); + expectAnnotations(Foo, #f4, 1, ["hval"]); + expectAnnotations(Foo, #f5, 0, ["fisk"]); + expectAnnotations(Foo, #f5, 1, ["hval"]); + expectAnnotations(Foo, #f6, 0, ["fisk"]); + expectAnnotations(Foo, #f6, 1, ["hval"]); + + expectAnnotations(Foo, const Symbol('s1='), 0, ["cheval"]); +} diff --git a/tests/lib/mirrors/parameter_is_const_test.dart b/tests/lib/mirrors/parameter_is_const_test.dart new file mode 100644 index 00000000000..c2739e5848a --- /dev/null +++ b/tests/lib/mirrors/parameter_is_const_test.dart @@ -0,0 +1,20 @@ +// Copyright (c) 2013, 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. + +library test.parameter_is_const; + +import 'dart:mirrors'; + +import 'package:expect/expect.dart'; + +class Class { + foo( + const //# 01: compile-time error + param) {} +} + +main() { + MethodMirror mm = reflectClass(Class).declarations[#foo] as MethodMirror; + Expect.isFalse(mm.parameters.single.isConst); +} diff --git a/tests/lib/mirrors/parameter_metadata_test.dart b/tests/lib/mirrors/parameter_metadata_test.dart new file mode 100644 index 00000000000..f87598391bf --- /dev/null +++ b/tests/lib/mirrors/parameter_metadata_test.dart @@ -0,0 +1,63 @@ +// Copyright (c) 2013, 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. + +library test.parameter_metadata_test; + +import 'dart:mirrors'; + +import 'metadata_test.dart'; + +const m1 = 'm1'; +const m2 = #m2; +const m3 = const CustomAnnotation(3); + +class CustomAnnotation { + final value; + const CustomAnnotation(this.value); + toString() => 'CustomAnnotation($value)'; +} + +class B { + B.foo(int x) {} + factory B.bar(@m3 @m2 int z, x) {} + + baz(@m1 final int x, @m2 int y, @m3 final int z) {} + qux(int x, [@m3 @m2 @m1 int y = 3 + 1]) {} + quux(int x, {String str: "foo"}) {} + corge({@m1 int x: 3 * 17, @m2 String str: "bar"}) {} + + set x(@m2 final value) {} +} + +main() { + ClassMirror cm = reflectClass(B); + MethodMirror mm; + + mm = cm.declarations[#B.foo] as MethodMirror; + checkMetadata(mm.parameters[0], []); + + mm = cm.declarations[#B.bar] as MethodMirror; + checkMetadata(mm.parameters[0], [m3, m2]); + checkMetadata(mm.parameters[1], []); + + mm = cm.declarations[#baz] as MethodMirror; + checkMetadata(mm.parameters[0], [m1]); + checkMetadata(mm.parameters[1], [m2]); + checkMetadata(mm.parameters[2], [m3]); + + mm = cm.declarations[#qux] as MethodMirror; + checkMetadata(mm.parameters[0], []); + checkMetadata(mm.parameters[1], [m3, m2, m1]); + + mm = cm.declarations[#quux] as MethodMirror; + checkMetadata(mm.parameters[0], []); + checkMetadata(mm.parameters[1], []); + + mm = cm.declarations[#corge] as MethodMirror; + checkMetadata(mm.parameters[0], [m1]); + checkMetadata(mm.parameters[1], [m2]); + + mm = cm.declarations[const Symbol('x=')] as MethodMirror; + checkMetadata(mm.parameters[0], [m2]); +} diff --git a/tests/lib/mirrors/parameter_of_mixin_app_constructor_test.dart b/tests/lib/mirrors/parameter_of_mixin_app_constructor_test.dart new file mode 100644 index 00000000000..014db1e775e --- /dev/null +++ b/tests/lib/mirrors/parameter_of_mixin_app_constructor_test.dart @@ -0,0 +1,107 @@ +// Copyright (c) 2014, 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. + +library test.parameter_of_mixin_app_constructor; + +import 'dart:mirrors'; +import 'stringify.dart'; + +class MapView { + final _map; + MapView(map) : this._map = map; +} + +abstract class UnmodifiableMapMixin { + someFunctionality() {} +} + +class UnmodifiableMapView1 extends MapView with UnmodifiableMapMixin { + UnmodifiableMapView1(map1) : super(map1); +} + +class UnmodifiableMapView2 = MapView with UnmodifiableMapMixin; + +class S { + S(int p1, String p2); +} + +class M1 {} + +class M2 {} + +class M3 {} + +class MorePlumbing = S with M1, M2, M3; + +soleConstructorOf(ClassMirror cm) { + return cm.declarations.values + .where((dm) => dm is MethodMirror && dm.isConstructor) + .single; +} + +main() { + ClassMirror umv1 = reflectClass(UnmodifiableMapView1); + expect( + '[Parameter(s(map1) in s(UnmodifiableMapView1),' + ' type = Type(s(dynamic), top-level))]', + soleConstructorOf(umv1).parameters); + expect( + '[Parameter(s(map) in s(test.parameter_of_mixin_app_constructor.MapView' + ' with test.parameter_of_mixin_app_constructor.UnmodifiableMapMixin),' + ' final, type = Type(s(dynamic), top-level))]', + soleConstructorOf(umv1.superclass).parameters); + expect( + '[Parameter(s(map) in s(MapView),' + ' type = Type(s(dynamic), top-level))]', + soleConstructorOf(umv1.superclass.superclass).parameters); + expect('[]', + soleConstructorOf(umv1.superclass.superclass.superclass).parameters); + + ClassMirror umv2 = reflectClass(UnmodifiableMapView2); + expect( + '[Parameter(s(map) in s(UnmodifiableMapView2),' + ' final, type = Type(s(dynamic), top-level))]', + soleConstructorOf(umv2).parameters); + expect( + '[Parameter(s(map) in s(MapView),' + ' type = Type(s(dynamic), top-level))]', + soleConstructorOf(umv2.superclass).parameters); + expect('[]', soleConstructorOf(umv2.superclass.superclass).parameters); + + ClassMirror mp = reflectClass(MorePlumbing); + expect( + '[Parameter(s(p1) in s(MorePlumbing),' + ' final, type = Type(s(dynamic), top-level)),' + ' Parameter(s(p2) in s(MorePlumbing),' + ' final, type = Type(s(dynamic), top-level))]', + soleConstructorOf(mp).parameters); + expect( + '[Parameter(s(p1) in s(test.parameter_of_mixin_app_constructor.S' + ' with test.parameter_of_mixin_app_constructor.M1,' + ' test.parameter_of_mixin_app_constructor.M2),' + ' final, type = Type(s(dynamic), top-level)),' + ' Parameter(s(p2) in s(test.parameter_of_mixin_app_constructor.S' + ' with test.parameter_of_mixin_app_constructor.M1,' + ' test.parameter_of_mixin_app_constructor.M2),' + ' final, type = Type(s(dynamic), top-level))]', + soleConstructorOf(mp.superclass).parameters); + expect( + '[Parameter(s(p1) in s(test.parameter_of_mixin_app_constructor.S' + ' with test.parameter_of_mixin_app_constructor.M1),' + ' final, type = Type(s(dynamic), top-level)),' + ' Parameter(s(p2) in s(test.parameter_of_mixin_app_constructor.S' + ' with test.parameter_of_mixin_app_constructor.M1),' + ' final, type = Type(s(dynamic), top-level))]', + soleConstructorOf(mp.superclass.superclass).parameters); + expect( + '[Parameter(s(p1) in s(S),' + ' type = Class(s(int) in s(dart.core), top-level)),' + ' Parameter(s(p2) in s(S),' + ' type = Class(s(String) in s(dart.core), top-level))]', + soleConstructorOf(mp.superclass.superclass.superclass).parameters); + expect( + '[]', + soleConstructorOf(mp.superclass.superclass.superclass.superclass) + .parameters); +} diff --git a/tests/lib/mirrors/parameter_optional_order_test.dart b/tests/lib/mirrors/parameter_optional_order_test.dart new file mode 100644 index 00000000000..a2fa3d487c1 --- /dev/null +++ b/tests/lib/mirrors/parameter_optional_order_test.dart @@ -0,0 +1,107 @@ +// Copyright (c) 2019, 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. + +import 'dart:mirrors'; + +import 'package:expect/expect.dart'; +import 'stringify.dart'; + +const X = 'X'; +const Y = 'Y'; +const Z = 'Z'; + +class C { + positional1(u, v, w, [@X int x = 1, @Y int y = 2, @Z int z = 3]) {} + positional2(u, v, w, [@Y int y = 1, @Z int z = 2, @X int x = 3]) {} + positional3(u, v, w, [@Z int z = 1, @X int x = 2, @Y int y = 3]) {} + + named1(u, v, w, {@X int x: 1, @Y int y: 2, @Z int z: 3}) {} + named2(u, v, w, {@Y int y: 1, @Z int z: 2, @X int x: 3}) {} + named3(u, v, w, {@Z int z: 1, @X int x: 2, @Y int y: 3}) {} +} + +testPositional() { + ClassMirror cm = reflectClass(C); + + MethodMirror positional1 = cm.declarations[#positional1] as MethodMirror; + expect('Method(s(positional1) in s(C))', positional1); + expect( + 'Parameter(s(x) in s(positional1), optional, value = Instance(value = 1), type = Class(s(int) in s(dart.core), top-level))', + positional1.parameters[3]); + expect( + 'Parameter(s(y) in s(positional1), optional, value = Instance(value = 2), type = Class(s(int) in s(dart.core), top-level))', + positional1.parameters[4]); + expect( + 'Parameter(s(z) in s(positional1), optional, value = Instance(value = 3), type = Class(s(int) in s(dart.core), top-level))', + positional1.parameters[5]); + + MethodMirror positional2 = cm.declarations[#positional2] as MethodMirror; + expect('Method(s(positional2) in s(C))', positional2); + expect( + 'Parameter(s(y) in s(positional2), optional, value = Instance(value = 1), type = Class(s(int) in s(dart.core), top-level))', + positional2.parameters[3]); + expect( + 'Parameter(s(z) in s(positional2), optional, value = Instance(value = 2), type = Class(s(int) in s(dart.core), top-level))', + positional2.parameters[4]); + expect( + 'Parameter(s(x) in s(positional2), optional, value = Instance(value = 3), type = Class(s(int) in s(dart.core), top-level))', + positional2.parameters[5]); + + MethodMirror positional3 = cm.declarations[#positional3] as MethodMirror; + expect('Method(s(positional3) in s(C))', positional3); + expect( + 'Parameter(s(z) in s(positional3), optional, value = Instance(value = 1), type = Class(s(int) in s(dart.core), top-level))', + positional3.parameters[3]); + expect( + 'Parameter(s(x) in s(positional3), optional, value = Instance(value = 2), type = Class(s(int) in s(dart.core), top-level))', + positional3.parameters[4]); + expect( + 'Parameter(s(y) in s(positional3), optional, value = Instance(value = 3), type = Class(s(int) in s(dart.core), top-level))', + positional3.parameters[5]); +} + +testNamed() { + ClassMirror cm = reflectClass(C); + + MethodMirror named1 = cm.declarations[#named1] as MethodMirror; + expect('Method(s(named1) in s(C))', named1); + expect( + 'Parameter(s(x) in s(named1), optional, named, value = Instance(value = 1), type = Class(s(int) in s(dart.core), top-level))', + named1.parameters[3]); + expect( + 'Parameter(s(y) in s(named1), optional, named, value = Instance(value = 2), type = Class(s(int) in s(dart.core), top-level))', + named1.parameters[4]); + expect( + 'Parameter(s(z) in s(named1), optional, named, value = Instance(value = 3), type = Class(s(int) in s(dart.core), top-level))', + named1.parameters[5]); + + MethodMirror named2 = cm.declarations[#named2] as MethodMirror; + expect('Method(s(named2) in s(C))', named2); + expect( + 'Parameter(s(y) in s(named2), optional, named, value = Instance(value = 1), type = Class(s(int) in s(dart.core), top-level))', + named2.parameters[3]); + expect( + 'Parameter(s(z) in s(named2), optional, named, value = Instance(value = 2), type = Class(s(int) in s(dart.core), top-level))', + named2.parameters[4]); + expect( + 'Parameter(s(x) in s(named2), optional, named, value = Instance(value = 3), type = Class(s(int) in s(dart.core), top-level))', + named2.parameters[5]); + + MethodMirror named3 = cm.declarations[#named3] as MethodMirror; + expect('Method(s(named3) in s(C))', named3); + expect( + 'Parameter(s(z) in s(named3), optional, named, value = Instance(value = 1), type = Class(s(int) in s(dart.core), top-level))', + named3.parameters[3]); + expect( + 'Parameter(s(x) in s(named3), optional, named, value = Instance(value = 2), type = Class(s(int) in s(dart.core), top-level))', + named3.parameters[4]); + expect( + 'Parameter(s(y) in s(named3), optional, named, value = Instance(value = 3), type = Class(s(int) in s(dart.core), top-level))', + named3.parameters[5]); +} + +main() { + testPositional(); + testNamed(); +} diff --git a/tests/lib/mirrors/parameter_test.dart b/tests/lib/mirrors/parameter_test.dart new file mode 100644 index 00000000000..d09671149dd --- /dev/null +++ b/tests/lib/mirrors/parameter_test.dart @@ -0,0 +1,203 @@ +// Copyright (c) 2013, 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. + +// This tests uses the multi-test "ok" feature: +// none: Desired behaviour, passing on the VM. +// 01: Trimmed version for dart2js. +// +// TODO(rmacnak,ahe): Remove multi-test when VM and dart2js are on par. + +/** Test of [ParameterMirror]. */ +library test.parameter_test; + +import 'dart:mirrors'; + +import 'package:expect/expect.dart'; +import 'stringify.dart'; + +class B { + B(); + B.foo(int x); + B.bar(int z, x); + + // TODO(6490): Currently only supported by the VM. + B.baz(final int x, int y, final int z); + B.qux(int x, [int y = 3 + 1]); + B.quux(int x, {String str: "foo"}); + B.corge({int x: 3 * 17, String str: "bar"}); + + var _x; + get x => _x; + set x(final value) { + _x = value; + } + + grault([int x = 0]) {} + garply({int y = 0}) {} + waldo(int z) {} +} + +class C { + // TODO(6490): Currently only supported by the VM. + foo(int a, S b) => b; + bar(S a, T b, num c) {} +} + +main() { + ClassMirror cm = reflectClass(B); + var constructors = new Map(); + cm.declarations.forEach((k, v) { + if (v is MethodMirror && v.isConstructor) constructors[k] = v; + }); + + List constructorKeys = [ + #B, + #B.bar, + #B.baz, + #B.foo, + #B.quux, + #B.qux, + #B.corge + ]; + Expect.setEquals(constructorKeys, constructors.keys); + + MethodMirror unnamedConstructor = constructors[#B] as MethodMirror; + expect('Method(s(B) in s(B), constructor)', unnamedConstructor); + expect('[]', unnamedConstructor.parameters); + expect('Class(s(B) in s(test.parameter_test), top-level)', + unnamedConstructor.returnType); + + MethodMirror fooConstructor = constructors[#B.foo] as MethodMirror; + expect('Method(s(B.foo) in s(B), constructor)', fooConstructor); + expect( + '[Parameter(s(x) in s(B.foo),' + ' type = Class(s(int) in s(dart.core), top-level))]', + fooConstructor.parameters); + expect('Class(s(B) in s(test.parameter_test), top-level)', + fooConstructor.returnType); + + MethodMirror barConstructor = constructors[#B.bar] as MethodMirror; + expect('Method(s(B.bar) in s(B), constructor)', barConstructor); + expect( + '[Parameter(s(z) in s(B.bar),' + ' type = Class(s(int) in s(dart.core), top-level)), ' + 'Parameter(s(x) in s(B.bar),' + ' type = Type(s(dynamic), top-level))]', + barConstructor.parameters); + expect('Class(s(B) in s(test.parameter_test), top-level)', + barConstructor.returnType); + + // dart2js stops testing here. + return; // //# 01: ok + + MethodMirror bazConstructor = constructors[#B.baz] as MethodMirror; + expect('Method(s(B.baz) in s(B), constructor)', bazConstructor); + expect( + '[Parameter(s(x) in s(B.baz), final,' + ' type = Class(s(int) in s(dart.core), top-level)), ' + 'Parameter(s(y) in s(B.baz),' + ' type = Class(s(int) in s(dart.core), top-level)), ' + 'Parameter(s(z) in s(B.baz), final,' + ' type = Class(s(int) in s(dart.core), top-level))]', + bazConstructor.parameters); + expect('Class(s(B) in s(test.parameter_test), top-level)', + bazConstructor.returnType); + + MethodMirror quxConstructor = constructors[#B.qux] as MethodMirror; + expect('Method(s(B.qux) in s(B), constructor)', quxConstructor); + expect( + '[Parameter(s(x) in s(B.qux),' + ' type = Class(s(int) in s(dart.core), top-level)), ' + 'Parameter(s(y) in s(B.qux), optional,' + ' value = Instance(value = 4),' + ' type = Class(s(int) in s(dart.core), top-level))]', + quxConstructor.parameters); + expect('Class(s(B) in s(test.parameter_test), top-level)', + quxConstructor.returnType); + + MethodMirror quuxConstructor = constructors[#B.quux] as MethodMirror; + expect('Method(s(B.quux) in s(B), constructor)', quuxConstructor); + expect( + '[Parameter(s(x) in s(B.quux),' + ' type = Class(s(int) in s(dart.core), top-level)), ' + 'Parameter(s(str) in s(B.quux), optional, named,' + ' value = Instance(value = foo),' + ' type = Class(s(String) in s(dart.core), top-level))]', + quuxConstructor.parameters); + expect('Class(s(B) in s(test.parameter_test), top-level)', + quuxConstructor.returnType); + + MethodMirror corgeConstructor = constructors[#B.corge] as MethodMirror; + expect('Method(s(B.corge) in s(B), constructor)', corgeConstructor); + expect( + '[Parameter(s(x) in s(B.corge), optional, named,' + ' value = Instance(value = 51),' + ' type = Class(s(int) in s(dart.core), top-level)), ' + 'Parameter(s(str) in s(B.corge), optional, named,' + ' value = Instance(value = bar),' + ' type = Class(s(String) in s(dart.core), top-level))]', + corgeConstructor.parameters); + expect('Class(s(B) in s(test.parameter_test), top-level)', + corgeConstructor.returnType); + + MethodMirror xGetter = cm.declarations[#x] as MethodMirror; + expect('Method(s(x) in s(B), getter)', xGetter); + expect('[]', xGetter.parameters); + + MethodMirror xSetter = cm.declarations[const Symbol('x=')] as MethodMirror; + expect('Method(s(x=) in s(B), setter)', xSetter); + expect( + '[Parameter(s(value) in s(x=), final,' + ' type = Type(s(dynamic), top-level))]', + xSetter.parameters); + + MethodMirror grault = cm.declarations[#grault] as MethodMirror; + expect('Method(s(grault) in s(B))', grault); + expect( + '[Parameter(s(x) in s(grault), optional, value = Instance(value = 0),' + ' type = Class(s(int) in s(dart.core), top-level))]', + grault.parameters); + expect('Instance(value = 0)', grault.parameters[0].defaultValue); + + MethodMirror garply = cm.declarations[#garply] as MethodMirror; + expect('Method(s(garply) in s(B))', garply); + expect( + '[Parameter(s(y) in s(garply), optional, named, value = Instance(value = 0),' + ' type = Class(s(int) in s(dart.core), top-level))]', + garply.parameters); + expect('Instance(value = 0)', garply.parameters[0].defaultValue); + + MethodMirror waldo = cm.declarations[#waldo] as MethodMirror; + expect('Method(s(waldo) in s(B))', waldo); + expect( + '[Parameter(s(z) in s(waldo),' + ' type = Class(s(int) in s(dart.core), top-level))]', + waldo.parameters); + expect('', waldo.parameters[0].defaultValue); + + cm = reflectClass(C); + + MethodMirror fooInC = cm.declarations[#foo] as MethodMirror; + expect('Method(s(foo) in s(C))', fooInC); + expect( + '[Parameter(s(a) in s(foo),' + ' type = Class(s(int) in s(dart.core), top-level)), ' + 'Parameter(s(b) in s(foo),' + ' type = TypeVariable(s(S) in s(C),' + ' upperBound = Class(s(int) in s(dart.core), top-level)))]', + fooInC.parameters); + + MethodMirror barInC = cm.declarations[#bar] as MethodMirror; + expect('Method(s(bar) in s(C))', barInC); + expect( + '[Parameter(s(a) in s(bar),' + ' type = TypeVariable(s(S) in s(C),' + ' upperBound = Class(s(int) in s(dart.core), top-level))), ' + 'Parameter(s(b) in s(bar),' + ' type = TypeVariable(s(T) in s(C),' + ' upperBound = Class(s(Object) in s(dart.core), top-level))), ' + 'Parameter(s(c) in s(bar),' + ' type = Class(s(num) in s(dart.core), top-level))]', + barInC.parameters); +} diff --git a/tests/lib/mirrors/private_class_field_other.dart b/tests/lib/mirrors/private_class_field_other.dart new file mode 100644 index 00000000000..1a303547a61 --- /dev/null +++ b/tests/lib/mirrors/private_class_field_other.dart @@ -0,0 +1,9 @@ +// 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. + +class C { + static var _privateField = 42; +} + +get privateFieldSymbolInOther => #_privateField; diff --git a/tests/lib/mirrors/private_class_field_test.dart b/tests/lib/mirrors/private_class_field_test.dart new file mode 100644 index 00000000000..ae963e87f34 --- /dev/null +++ b/tests/lib/mirrors/private_class_field_test.dart @@ -0,0 +1,19 @@ +// 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. + +// Test a private field name doesn't match the equivalent private name from +// another library. + +import 'dart:mirrors'; +import 'package:expect/expect.dart'; + +import 'private_class_field_other.dart'; + +void main() { + var classMirror = reflectClass(C); + // The symbol is private w/r/t the wrong library. + Expect.throwsNoSuchMethodError(() => classMirror.getField(#_privateField)); + + Expect.equals(42, classMirror.getField(privateFieldSymbolInOther).reflectee); +} diff --git a/tests/lib/mirrors/private_field_helper.dart b/tests/lib/mirrors/private_field_helper.dart new file mode 100644 index 00000000000..df4636edd0e --- /dev/null +++ b/tests/lib/mirrors/private_field_helper.dart @@ -0,0 +1,17 @@ +// 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. + +library test.mixin; + +import 'dart:mirrors'; + +import 'package:expect/expect.dart'; + +class Bar { + String _field = "hello"; + String get field => _field; +} + +var privateSymbol2 = #_field; +var publicSymbol2 = #field; diff --git a/tests/lib/mirrors/private_field_test.dart b/tests/lib/mirrors/private_field_test.dart new file mode 100644 index 00000000000..ae830a9b1e6 --- /dev/null +++ b/tests/lib/mirrors/private_field_test.dart @@ -0,0 +1,36 @@ +// 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. + +library test.mixin; + +import 'dart:mirrors'; + +import 'package:expect/expect.dart'; + +import 'private_field_helper.dart'; + +class Foo extends Bar { + int _field = 42; + + static int _staticField = 99; +} + +var privateSymbol = #_field; +var publicSymbol = #field; + +main() { + Expect.equals(publicSymbol, publicSymbol2); + Expect.notEquals(privateSymbol, privateSymbol2); + + var foo = new Foo(); + var m = reflect(foo); + m.setField(privateSymbol, 38); + Expect.equals(38, foo._field); + m.setField(privateSymbol2, "world"); + Expect.equals("world", foo.field); + Expect.equals("world", m.getField(publicSymbol).reflectee); + + var type = reflectClass(Foo); + Expect.equals(99, type.getField(#_staticField).reflectee); +} diff --git a/tests/lib/mirrors/private_symbol_mangling_lib.dart b/tests/lib/mirrors/private_symbol_mangling_lib.dart new file mode 100644 index 00000000000..8d9c93bb0bd --- /dev/null +++ b/tests/lib/mirrors/private_symbol_mangling_lib.dart @@ -0,0 +1,14 @@ +// Copyright (c) 2014, 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. + +library other; + +var _privateGlobalField = 3; + +_privateGlobalMethod() => 11; + +class C2 { + var _privateField = 1; + _privateMethod() => 3; +} diff --git a/tests/lib/mirrors/private_symbol_mangling_test.dart b/tests/lib/mirrors/private_symbol_mangling_test.dart new file mode 100644 index 00000000000..826d06c8b83 --- /dev/null +++ b/tests/lib/mirrors/private_symbol_mangling_test.dart @@ -0,0 +1,70 @@ +// Copyright (c) 2014, 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. + +library main; + +import 'dart:mirrors'; +import 'package:expect/expect.dart'; +import 'private_symbol_mangling_lib.dart'; + +var _privateGlobalField = 1; + +_privateGlobalMethod() => 9; + +class C1 { + var _privateField = 0; + _privateMethod() => 2; +} + +getPrivateGlobalFieldValue(LibraryMirror lib) { + for (Symbol symbol in lib.declarations.keys) { + DeclarationMirror decl = lib.declarations[symbol]; + if (decl is VariableMirror && decl.isPrivate) { + return lib.getField(symbol).reflectee; + } + } +} + +getPrivateFieldValue(InstanceMirror cls) { + for (Symbol symbol in cls.type.declarations.keys) { + DeclarationMirror decl = cls.type.declarations[symbol]; + if (decl is VariableMirror && decl.isPrivate) { + return cls.getField(symbol).reflectee; + } + } +} + +getPrivateGlobalMethodValue(LibraryMirror lib) { + for (Symbol symbol in lib.declarations.keys) { + DeclarationMirror decl = lib.declarations[symbol]; + if (decl is MethodMirror && decl.isRegularMethod && decl.isPrivate) { + return lib.invoke(symbol, []).reflectee; + } + } +} + +getPrivateMethodValue(InstanceMirror cls) { + for (Symbol symbol in cls.type.declarations.keys) { + DeclarationMirror decl = cls.type.declarations[symbol]; + if (decl is MethodMirror && decl.isRegularMethod && decl.isPrivate) { + return cls.invoke(symbol, []).reflectee; + } + } +} + +main() { + LibraryMirror libmain = currentMirrorSystem().findLibrary(#main); + LibraryMirror libother = currentMirrorSystem().findLibrary(#other); + Expect.equals(1, getPrivateGlobalFieldValue(libmain)); + Expect.equals(3, getPrivateGlobalFieldValue(libother)); + Expect.equals(9, getPrivateGlobalMethodValue(libmain)); + Expect.equals(11, getPrivateGlobalMethodValue(libother)); + + var c1 = reflect(new C1()); + var c2 = reflect(new C2()); + Expect.equals(0, getPrivateFieldValue(c1)); + Expect.equals(1, getPrivateFieldValue(c2)); + Expect.equals(2, getPrivateMethodValue(c1)); + Expect.equals(3, getPrivateMethodValue(c2)); +} diff --git a/tests/lib/mirrors/private_symbol_test.dart b/tests/lib/mirrors/private_symbol_test.dart new file mode 100644 index 00000000000..b6e74af866e --- /dev/null +++ b/tests/lib/mirrors/private_symbol_test.dart @@ -0,0 +1,123 @@ +// Copyright (c) 2013, 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. + +library test; + +import 'dart:mirrors'; +import 'package:expect/expect.dart'; + +typedef int _F(int i); + +class _C<_T> { + get g {} + set s(x) {} + m(_p) {} + get _g {} + set _s(x) {} + _m() {} +} + +main() { + // Test private symbols are distinct across libraries, and the same within a + // library when created multiple ways. Test the string can be properly + // extracted. + LibraryMirror libcore = currentMirrorSystem().findLibrary(#dart.core); + LibraryMirror libmath = currentMirrorSystem().findLibrary(#dart.math); + LibraryMirror libtest = currentMirrorSystem().findLibrary(#test); + + Symbol corefoo = MirrorSystem.getSymbol('foo', libcore); + Symbol mathfoo = MirrorSystem.getSymbol('foo', libmath); + Symbol testfoo = MirrorSystem.getSymbol('foo', libtest); + Symbol nullfoo1 = MirrorSystem.getSymbol('foo'); + Symbol nullfoo2 = MirrorSystem.getSymbol('foo', null); + + Expect.equals(corefoo, mathfoo); + Expect.equals(mathfoo, testfoo); + Expect.equals(testfoo, corefoo); + Expect.equals(nullfoo1, corefoo); + Expect.equals(nullfoo2, corefoo); + + Expect.equals('foo', MirrorSystem.getName(corefoo)); + Expect.equals('foo', MirrorSystem.getName(mathfoo)); + Expect.equals('foo', MirrorSystem.getName(testfoo)); + Expect.equals('foo', MirrorSystem.getName(#foo)); + Expect.equals('foo', MirrorSystem.getName(nullfoo1)); + Expect.equals('foo', MirrorSystem.getName(nullfoo2)); + + Symbol core_foo = MirrorSystem.getSymbol('_foo', libcore); + Symbol math_foo = MirrorSystem.getSymbol('_foo', libmath); + Symbol test_foo = MirrorSystem.getSymbol('_foo', libtest); + + Expect.equals('_foo', MirrorSystem.getName(core_foo)); + Expect.equals('_foo', MirrorSystem.getName(math_foo)); + Expect.equals('_foo', MirrorSystem.getName(test_foo)); + Expect.equals('_foo', MirrorSystem.getName(#_foo)); + + Expect.notEquals(core_foo, math_foo); + Expect.notEquals(math_foo, test_foo); + Expect.notEquals(test_foo, core_foo); + + Expect.notEquals(corefoo, core_foo); + Expect.notEquals(mathfoo, math_foo); + Expect.notEquals(testfoo, test_foo); + + Expect.equals(test_foo, #_foo); + + // Test interactions with the manglings for getters and setters, etc. + ClassMirror cm = reflectClass(_C); + Expect.equals(#_C, cm.simpleName); + Expect.equals('_C', MirrorSystem.getName(cm.simpleName)); + + MethodMirror mm = cm.declarations[#g] as MethodMirror; + Expect.isNotNull(mm); + Expect.isTrue(mm.isGetter); + Expect.equals(#g, mm.simpleName); + Expect.equals('g', MirrorSystem.getName(mm.simpleName)); + + mm = cm.declarations[const Symbol('s=')] as MethodMirror; + Expect.isNotNull(mm); + Expect.isTrue(mm.isSetter); + Expect.equals(const Symbol('s='), mm.simpleName); + Expect.equals('s=', MirrorSystem.getName(mm.simpleName)); + + mm = cm.declarations[#m] as MethodMirror; + Expect.isNotNull(mm); + Expect.isTrue(mm.isRegularMethod); + Expect.equals(#m, mm.simpleName); + Expect.equals('m', MirrorSystem.getName(mm.simpleName)); + + mm = cm.declarations[#_g] as MethodMirror; + Expect.isNotNull(mm); + Expect.isTrue(mm.isGetter); + Expect.equals(#_g, mm.simpleName); + Expect.equals('_g', MirrorSystem.getName(mm.simpleName)); + + mm = cm.declarations[MirrorSystem.getSymbol('_s=', libtest)] as MethodMirror; + Expect.isNotNull(mm); + Expect.isTrue(mm.isSetter); + Expect.equals(MirrorSystem.getSymbol('_s=', libtest), mm.simpleName); + Expect.equals('_s=', MirrorSystem.getName(mm.simpleName)); + + mm = cm.declarations[#_m] as MethodMirror; + Expect.isNotNull(mm); + Expect.isTrue(mm.isRegularMethod); + Expect.equals(#_m, mm.simpleName); + Expect.equals('_m', MirrorSystem.getName(mm.simpleName)); + + TypeVariableMirror tvm = cm.typeVariables[0]; + Expect.isNotNull(tvm); + Expect.equals(#_T, tvm.simpleName); + Expect.equals('_T', MirrorSystem.getName(tvm.simpleName)); + + TypedefMirror tdm = reflectType(_F) as TypedefMirror; + Expect.equals(#_F, tdm.simpleName); + Expect.equals('_F', MirrorSystem.getName(tdm.simpleName)); + + ParameterMirror pm = (cm.declarations[#m] as MethodMirror).parameters[0]; + Expect.equals(#_p, pm.simpleName); + Expect.equals('_p', MirrorSystem.getName(pm.simpleName)); + + // Private symbol without a library. + Expect.throwsArgumentError(() => MirrorSystem.getSymbol('_private')); +} diff --git a/tests/lib/mirrors/private_types_test.dart b/tests/lib/mirrors/private_types_test.dart new file mode 100644 index 00000000000..4d908e38b0f --- /dev/null +++ b/tests/lib/mirrors/private_types_test.dart @@ -0,0 +1,32 @@ +// Copyright (c) 2014, 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. + +library test.private_types; + +import 'dart:mirrors'; +import 'package:expect/expect.dart'; + +typedef int _F(int i); + +class _C<_T> {} + +typedef int F(int i); + +class C {} + +main() { + Expect.isTrue(reflectType(_F).isPrivate); + Expect.isFalse((reflectType(_F) as TypedefMirror).referent.isPrivate); + Expect.isTrue(reflectType(_C).isPrivate); + Expect.isTrue(reflectClass(_C).typeVariables.single.isPrivate); + + Expect.isFalse(reflectType(F).isPrivate); + Expect.isFalse((reflectType(F) as TypedefMirror).referent.isPrivate); + Expect.isFalse(reflectType(C).isPrivate); + Expect.isFalse(reflectClass(C).typeVariables.single.isPrivate); + + Expect.isFalse(reflectType(dynamic).isPrivate); + Expect.isFalse(currentMirrorSystem().dynamicType.isPrivate); + Expect.isFalse(currentMirrorSystem().voidType.isPrivate); +} diff --git a/tests/lib/mirrors/proxy_type_test.dart b/tests/lib/mirrors/proxy_type_test.dart new file mode 100644 index 00000000000..986ded7be75 --- /dev/null +++ b/tests/lib/mirrors/proxy_type_test.dart @@ -0,0 +1,83 @@ +// Copyright (c) 2013, 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. + +library test.proxy_type; + +import 'dart:mirrors'; +import 'package:expect/expect.dart'; + +// This test is much longer that is strictly necessary to test +// InstanceMirror.type in the face of a reflectee overriding runtimeType, but +// shows a case where one might have legimate reason to override runtimeType. +// See section 2.2 in Mark Miller's Robust Composition: Towards a Unified +// Approach to Access Control and Concurrency Control. + +class Alice { + Bob bob = new Bob(); + Carol carol = new Carol(); + sayFooUnattenuated() { + bob.foo(carol); + } + + sayFooAttenuated() { + bool enabled = true; + bool gate() => enabled; + bob.foo(new CarolCaretaker(carol, gate)); + enabled = false; // Attenuate a capability + } + + sayBar() { + bob.bar(); + } +} + +class Bob { + Carol savedCarol; + foo(Carol carol) { + savedCarol = carol; // Store a capability + carol.foo(); + } + + bar() { + savedCarol.foo(); + } +} + +class Carol { + foo() => 'c'; +} + +typedef bool Gate(); + +class CarolCaretaker implements Carol { + final Carol _carol; + final Gate _gate; + CarolCaretaker(this._carol, this._gate); + + foo() { + if (!_gate()) throw new NoSuchMethodError(this, #foo, [], {}); + return _carol.foo(); + } + + Type get runtimeType => Carol; +} + +main() { + Alice alice1 = new Alice(); + alice1.sayFooUnattenuated(); + alice1.sayBar(); // Bob still has authority to use Carol + + Alice alice2 = new Alice(); + alice2.sayFooAttenuated(); + Expect.throwsNoSuchMethodError(() => alice2.sayBar(), + 'Authority should have been attenuated'); + + // At the base level, a caretaker for a Carol masquerades as a Carol. + CarolCaretaker caretaker = new CarolCaretaker(new Carol(), () => true); + Expect.isTrue(caretaker is Carol); + Expect.equals(Carol, caretaker.runtimeType); + + // At the reflective level, the caretaker is distinguishable. + Expect.equals(reflectClass(CarolCaretaker), reflect(caretaker).type); +} diff --git a/tests/lib/mirrors/raw_type_test.dart b/tests/lib/mirrors/raw_type_test.dart new file mode 100644 index 00000000000..3bd49821049 --- /dev/null +++ b/tests/lib/mirrors/raw_type_test.dart @@ -0,0 +1,20 @@ +// Copyright (c) 2013, 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. + +import 'dart:mirrors'; + +import 'package:expect/expect.dart'; + +class Foo {} + +class Bar extends Foo {} + +main() { + var fooType = reflectType(Foo); + var fooDeclaration = fooType.originalDeclaration; + var barSupertype = reflect(new Bar()).type.superclass; + var barSuperclass = barSupertype.originalDeclaration; + Expect.equals(fooDeclaration, barSuperclass, 'declarations'); + Expect.equals(fooType, barSupertype, 'types'); //# 01: ok +} diff --git a/tests/lib/mirrors/redirecting_factory_different_type_test.dart b/tests/lib/mirrors/redirecting_factory_different_type_test.dart new file mode 100644 index 00000000000..cb23a9b211c --- /dev/null +++ b/tests/lib/mirrors/redirecting_factory_different_type_test.dart @@ -0,0 +1,33 @@ +// Copyright (c) 2013, 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. + +library mirror_test; + +import 'dart:mirrors'; + +import 'package:expect/expect.dart'; + +class A { + factory A( + String //# 01: compile-time error + var //# 02: compile-time error + int //# none: ok + x) = B; + A._(); +} + +class B extends A { + var x; + B(int x) + : this.x = x, + super._(); +} + +main() { + var cm = reflectClass(A); + // The type-annotation in A's constructor must be ignored. + var b = cm.newInstance(Symbol.empty, [499]).reflectee; + Expect.equals(499, b.x); + Expect.throwsTypeError(() => cm.newInstance(Symbol.empty, ["str"])); +} diff --git a/tests/lib/mirrors/redirecting_factory_reflection_test.dart b/tests/lib/mirrors/redirecting_factory_reflection_test.dart new file mode 100644 index 00000000000..cf5d60b332f --- /dev/null +++ b/tests/lib/mirrors/redirecting_factory_reflection_test.dart @@ -0,0 +1,24 @@ +// Copyright (c) 2015, 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. + +import 'dart:mirrors'; +import 'package:expect/expect.dart'; + +abstract class A { + get t; + factory A() = B>; +} + +class B implements A { + final t; + B() : t = Y; +} + +main() { + ClassMirror m = reflectClass(A); + var i = m.newInstance(Symbol.empty, []).reflectee; + var s = i.t.toString(); + Expect.isTrue(s == 'A' || s == 'A', + 'mirrors should create the correct reified generic type'); +} diff --git a/tests/lib/mirrors/redirecting_factory_test.dart b/tests/lib/mirrors/redirecting_factory_test.dart new file mode 100644 index 00000000000..2f5e47a8da4 --- /dev/null +++ b/tests/lib/mirrors/redirecting_factory_test.dart @@ -0,0 +1,120 @@ +// Copyright (c) 2013, 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. + +import "dart:mirrors"; +import "package:expect/expect.dart"; +import "stringify.dart"; + +class Class { + final field; + Class(this.field); + + factory Class.factoryNoOptional(a, b) => new Class(a - b); + factory Class.redirectingFactoryNoOptional(a, b) = Class.factoryNoOptional; + + factory Class.factoryUnnamedOptional(a, [b = 42]) => new Class(a - b); + factory Class.redirectingFactoryUnnamedOptional(a, [b]) = + Class.factoryUnnamedOptional; + + factory Class.factoryNamedOptional(a, {b: 42}) { + return new Class(a - b); + } + + factory Class.redirectingFactoryNamedOptional(a, {b}) = + Class.factoryNamedOptional; + + factory Class.factoryMoreNamedOptional(a, {b: 0, c: 2}) { + return new Class(a - b - c); + } + + factory Class.redirectingFactoryMoreNamedOptional(a, {b}) = + Class.factoryMoreNamedOptional; + + factory Class.factoryMoreUnnamedOptional(a, [b = 0, c = 2]) { + return new Class(a - b - c); + } + + factory Class.redirectingFactoryMoreUnnamedOptional(a, [b]) = + Class.factoryMoreUnnamedOptional; + + factory Class.redirectingFactoryStringIntTypeParameters(a, b) = Class // + //# 03: compile-time error + .factoryNoOptional; + + factory Class.redirectingFactoryStringTypeParameters(a, b) = Class // + //# 02: compile-time error + .factoryNoOptional; + + factory Class.redirectingFactoryTypeParameters(a, b) = + Class.factoryNoOptional; + + factory Class.redirectingFactoryReversedTypeParameters(a, b) = Class // + //# 04: compile-time error + .factoryNoOptional; +} + +main() { + var classMirror = reflectClass(Class); + + var instanceMirror = classMirror.newInstance(Symbol.empty, [2]); + Expect.equals(2, instanceMirror.reflectee.field); + + instanceMirror = + classMirror.newInstance(#redirectingFactoryNoOptional, [8, 6]); + Expect.equals(2, instanceMirror.reflectee.field); + + instanceMirror = + classMirror.newInstance(#redirectingFactoryUnnamedOptional, [43, 1]); + Expect.equals(42, instanceMirror.reflectee.field); + + instanceMirror = + classMirror.newInstance(#redirectingFactoryMoreUnnamedOptional, [43, 1]); + Expect.equals(40, instanceMirror.reflectee.field); + + instanceMirror = classMirror + .newInstance(#redirectingFactoryStringIntTypeParameters, [43, 1]); + Expect.equals(42, instanceMirror.reflectee.field); + Expect.isTrue(instanceMirror.reflectee is Class); + Expect.isFalse(instanceMirror.reflectee is Class); + + instanceMirror = + classMirror.newInstance(#redirectingFactoryStringTypeParameters, [43, 1]); + Expect.equals(42, instanceMirror.reflectee.field); + Expect.isTrue(instanceMirror.reflectee is Class); + Expect.isTrue(instanceMirror.reflectee is Class); + Expect.isTrue(instanceMirror.reflectee is Class); + + bool isDart2js = false; + isDart2js = true; //# 01: ok + if (isDart2js) return; + + instanceMirror = + classMirror.newInstance(#redirectingFactoryUnnamedOptional, [43]); + Expect.equals(1, instanceMirror.reflectee.field); + + instanceMirror = + classMirror.newInstance(#redirectingFactoryNamedOptional, [43]); + Expect.equals(1, instanceMirror.reflectee.field); + + instanceMirror = classMirror.newInstance( + #redirectingFactoryNamedOptional, [43], new Map()..[#b] = 1); + Expect.equals(42, instanceMirror.reflectee.field); + + instanceMirror = classMirror.newInstance( + #redirectingFactoryMoreNamedOptional, [43], new Map()..[#b] = 1); + Expect.equals(40, instanceMirror.reflectee.field); + + classMirror = reflect(new Class(42)).type; + instanceMirror = + classMirror.newInstance(#redirectingFactoryTypeParameters, [43, 1]); + Expect.equals(42, instanceMirror.reflectee.field); + Expect.isTrue(instanceMirror.reflectee is Class); + Expect.isFalse(instanceMirror.reflectee is Class); + + instanceMirror = classMirror + .newInstance(#redirectingFactoryReversedTypeParameters, [43, 1]); + Expect.equals(42, instanceMirror.reflectee.field); + Expect.isTrue(instanceMirror.reflectee is Class); + Expect.isFalse(instanceMirror.reflectee is Class); +} diff --git a/tests/lib/mirrors/reflect_class_test.dart b/tests/lib/mirrors/reflect_class_test.dart new file mode 100644 index 00000000000..ca0b94de8e8 --- /dev/null +++ b/tests/lib/mirrors/reflect_class_test.dart @@ -0,0 +1,16 @@ +// Copyright (c) 2013, 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. + +import "dart:mirrors"; + +import "package:expect/expect.dart"; + +typedef void FooFunction(int a, double b); + +main() { + Expect.throwsArgumentError(() => reflectClass(dynamic)); + Expect.throwsArgumentError(() => reflectClass(1)); //# 01: compile-time error + Expect.throwsArgumentError(() => reflectClass("string")); //# 02: compile-time error + Expect.throwsArgumentError(() => reflectClass(FooFunction)); +} diff --git a/tests/lib/mirrors/reflect_model_test.dart b/tests/lib/mirrors/reflect_model_test.dart new file mode 100644 index 00000000000..416f041b099 --- /dev/null +++ b/tests/lib/mirrors/reflect_model_test.dart @@ -0,0 +1,142 @@ +// Copyright (c) 2013, 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. + +library test.reflect_model_test; + +import 'dart:mirrors'; + +import 'package:expect/expect.dart'; + +import 'model.dart'; +import 'stringify.dart'; + +variablesOf(ClassMirror cm) { + var result = new Map(); + cm.declarations.forEach((k, v) { + if (v is VariableMirror) result[k] = v; + }); + return result; +} + +gettersOf(ClassMirror cm) { + var result = new Map(); + cm.declarations.forEach((k, v) { + if (v is MethodMirror && v.isGetter) result[k] = v; + }); + return result; +} + +settersOf(ClassMirror cm) { + var result = new Map(); + cm.declarations.forEach((k, v) { + if (v is MethodMirror && v.isSetter) result[k] = v; + }); + return result; +} + +methodsOf(ClassMirror cm) { + var result = new Map(); + cm.declarations.forEach((k, v) { + if (v is MethodMirror && v.isRegularMethod) result[k] = v; + }); + return result; +} + +main() { + var unnamed = new Symbol(''); + var field = new Symbol('field'); + var instanceMethod = new Symbol('instanceMethod'); + var accessor = new Symbol('accessor'); + var aMethod = new Symbol('aMethod'); + var bMethod = new Symbol('bMethod'); + var cMethod = new Symbol('cMethod'); + + var aClass = reflectClass(A); + var bClass = reflectClass(B); + var cClass = reflectClass(C); + var a = aClass.newInstance(unnamed, []); + var b = bClass.newInstance(unnamed, []); + var c = cClass.newInstance(unnamed, []); + + expect('{field: Variable(s(field) in s(A))}', variablesOf(aClass)); + expect('{}', variablesOf(bClass)); + expect('{}', variablesOf(cClass)); + + Expect.isNull(a.getField(field).reflectee); + Expect.equals('B:get field', b.getField(field).reflectee); + Expect.equals('B:get field', c.getField(field).reflectee); + + Expect.equals(42, a.setField(field, 42).reflectee); + Expect.equals(87, b.setField(field, 87).reflectee); + Expect.equals(89, c.setField(field, 89).reflectee); + + Expect.equals(42, a.getField(field).reflectee); + Expect.equals('B:get field', b.getField(field).reflectee); + Expect.equals('B:get field', c.getField(field).reflectee); + Expect.equals(89, fieldC); + + expect( + '{accessor: Method(s(accessor) in s(A), getter)' + '}', + gettersOf(aClass)); + expect( + '{accessor: Method(s(accessor) in s(B), getter)' + ', field: Method(s(field) in s(B), getter)}', + gettersOf(bClass)); + expect('{accessor: Method(s(accessor) in s(C), getter)}', gettersOf(cClass)); + + expect( + '{accessor=: Method(s(accessor=) in s(A), setter)' + '}', + settersOf(aClass)); + expect( + '{accessor=: Method(s(accessor=) in s(B), setter)}', settersOf(bClass)); + expect( + '{accessor=: Method(s(accessor=) in s(C), setter)' + ', field=: Method(s(field=) in s(C), setter)}', + settersOf(cClass)); + + Expect.equals('A:instanceMethod(7)', a.invoke(instanceMethod, [7]).reflectee); + Expect.equals('B:instanceMethod(9)', b.invoke(instanceMethod, [9]).reflectee); + Expect.equals( + 'C:instanceMethod(13)', c.invoke(instanceMethod, [13]).reflectee); + + expect( + '{aMethod: Method(s(aMethod) in s(A))' + ', instanceMethod: Method(s(instanceMethod) in s(A))}', + methodsOf(aClass)); + + expect( + '{bMethod: Method(s(bMethod) in s(B))' + ', instanceMethod: Method(s(instanceMethod) in s(B))}', + methodsOf(bClass)); + expect( + '{cMethod: Method(s(cMethod) in s(C))' + ', instanceMethod: Method(s(instanceMethod) in s(C))}', + methodsOf(cClass)); + + Expect.equals('A:get accessor', a.getField(accessor).reflectee); + Expect.equals('B:get accessor', b.getField(accessor).reflectee); + Expect.equals('C:get accessor', c.getField(accessor).reflectee); + + Expect.equals('foo', a.setField(accessor, 'foo').reflectee); + Expect.equals('bar', b.setField(accessor, 'bar').reflectee); + Expect.equals('baz', c.setField(accessor, 'baz').reflectee); + + Expect.equals('foo', accessorA); + Expect.equals('bar', accessorB); + Expect.equals('baz', accessorC); + + Expect.equals('aMethod', a.invoke(aMethod, []).reflectee); + Expect.equals('aMethod', b.invoke(aMethod, []).reflectee); + Expect.equals('aMethod', c.invoke(aMethod, []).reflectee); + + Expect.throwsNoSuchMethodError(() => a.invoke(bMethod, [])); + Expect.equals('bMethod', b.invoke(bMethod, []).reflectee); + Expect.equals('bMethod', c.invoke(bMethod, []).reflectee); + + Expect.throwsNoSuchMethodError(() => a.invoke(cMethod, [])); + Expect.throwsNoSuchMethodError(() => b.invoke(cMethod, [])); + Expect.equals('cMethod', c.invoke(cMethod, []).reflectee); +} diff --git a/tests/lib/mirrors/reflect_runtime_type_test.dart b/tests/lib/mirrors/reflect_runtime_type_test.dart new file mode 100644 index 00000000000..a5e96b67aa1 --- /dev/null +++ b/tests/lib/mirrors/reflect_runtime_type_test.dart @@ -0,0 +1,24 @@ +// Copyright (c) 2013, 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. + +// A simple test that ensure that reflection works on runtime types of +// instantiated classes. + +import "dart:mirrors"; + +class Foo { + int a = 0; +} + +main() { + var m = reflectClass(new Foo().runtimeType); + var field = publicFields(m).single; + if (MirrorSystem.getName(field.simpleName) != 'a') { + throw 'Expected "a", but got "${MirrorSystem.getName(field.simpleName)}"'; + } + print(field); +} + +publicFields(ClassMirror mirror) => mirror.declarations.values + .where((x) => x is VariableMirror && !(x.isPrivate || x.isStatic)); diff --git a/tests/lib/mirrors/reflect_two_classes_test.dart b/tests/lib/mirrors/reflect_two_classes_test.dart new file mode 100644 index 00000000000..65f103beb67 --- /dev/null +++ b/tests/lib/mirrors/reflect_two_classes_test.dart @@ -0,0 +1,35 @@ +// Copyright (c) 2015, 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. + +// This is a regression test for http://dartbug.com/23054 + +library index; + +import 'dart:mirrors'; + +import 'package:expect/expect.dart'; + +main() { + var bar = new Bar(); + var barMirror = reflect(bar); + Expect.equals(42, barMirror.getField(#bar).reflectee, "bar field"); + Expect.equals(42, barMirror.invoke(#getBar, []).reflectee, "getBar Method"); + + var foo = new Foo(); + var fooMirror = reflect(foo); + Expect.equals(9, fooMirror.getField(#foo).reflectee, "foo field"); + Expect.equals(9, fooMirror.invoke(#getFoo, []).reflectee, "getFoo Method"); +} + +class Bar { + int bar = 42; + + int getBar() => bar; +} + +class Foo { + int foo = 9; + + int getFoo() => foo; +} diff --git a/tests/lib/mirrors/reflect_uninstantiated_class_test.dart b/tests/lib/mirrors/reflect_uninstantiated_class_test.dart new file mode 100644 index 00000000000..bfbdadb3c41 --- /dev/null +++ b/tests/lib/mirrors/reflect_uninstantiated_class_test.dart @@ -0,0 +1,24 @@ +// Copyright (c) 2013, 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. + +// A simple test that ensure that reflection works on uninstantiated classes. + +import "dart:mirrors"; + +class Foo { + int a = 0; +} + +main() { + // Do NOT instantiate Foo. + var m = reflectClass(Foo); + var field = publicFields(m).single; + if (MirrorSystem.getName(field.simpleName) != 'a') { + throw 'Expected "a", but got "${MirrorSystem.getName(field.simpleName)}"'; + } + print(field); +} + +publicFields(ClassMirror mirror) => mirror.declarations.values + .where((x) => x is VariableMirror && !(x.isPrivate || x.isStatic)); diff --git a/tests/lib/mirrors/reflected_type_classes_test.dart b/tests/lib/mirrors/reflected_type_classes_test.dart new file mode 100644 index 00000000000..bdc828c3665 --- /dev/null +++ b/tests/lib/mirrors/reflected_type_classes_test.dart @@ -0,0 +1,62 @@ +// Copyright (c) 2014, 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. + +library test.reflected_type_classes; + +import 'dart:mirrors'; + +import 'reflected_type_helper.dart'; + +class A {} + +class B extends A {} + +class C extends A {} // //# 01: compile-time error +class D extends A {} + +class E extends A {} + +class F extends A {} + +class G {} + +class H {} + +main() { + // Declarations. + expectReflectedType(reflectClass(A), null); + expectReflectedType(reflectClass(B), B); + expectReflectedType(reflectClass(C), C); // //# 01: continued + expectReflectedType(reflectClass(D), D); + expectReflectedType(reflectClass(E), null); + expectReflectedType(reflectClass(F), null); + expectReflectedType(reflectClass(G), G); + expectReflectedType(reflectClass(H), null); + + // Instantiations. + expectReflectedType(reflect(new A()).type, new A().runtimeType); + expectReflectedType(reflect(new B()).type, new B().runtimeType); + expectReflectedType(reflect(new C()).type, new C().runtimeType); // //# 01: continued + expectReflectedType(reflect(new D()).type, new D().runtimeType); + expectReflectedType(reflect(new E()).type, new E().runtimeType); + expectReflectedType(reflect(new F()).type, new F().runtimeType); + expectReflectedType(reflect(new G()).type, new G().runtimeType); + expectReflectedType(reflect(new H()).type, new H().runtimeType); + + expectReflectedType(reflect(new A()).type, new A().runtimeType); + expectReflectedType(reflect(new B()).type.superclass, // //# 02: compile-time error + new A().runtimeType); // //# 02: continued + expectReflectedType(reflect(new C()).type.superclass, // //# 01: continued + new A().runtimeType); // //# 01: continued + expectReflectedType(reflect(new D()).type.superclass, // //# 03: compile-time error + new A().runtimeType); // //# 03: continued + expectReflectedType(reflect(new E()).type, new E().runtimeType); + expectReflectedType( + reflect(new E()).type.superclass, new A().runtimeType); + expectReflectedType( + reflect(new F()).type.superclass, new A().runtimeType); + expectReflectedType(reflect(new F()).type, new F().runtimeType); + expectReflectedType( + reflect(new H()).type, new H().runtimeType); +} diff --git a/tests/lib/mirrors/reflected_type_function_type_test.dart b/tests/lib/mirrors/reflected_type_function_type_test.dart new file mode 100644 index 00000000000..53132a3a282 --- /dev/null +++ b/tests/lib/mirrors/reflected_type_function_type_test.dart @@ -0,0 +1,23 @@ +// Copyright (c) 2014, 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. + +library test.reflected_type_function_types; + +import 'dart:mirrors'; + +import 'reflected_type_helper.dart'; + +typedef bool Predicate(num n); + +bool somePredicate(num n) => n < 0; + +main() { + FunctionTypeMirror numToBool1 = + reflect(somePredicate).type as FunctionTypeMirror; + FunctionTypeMirror numToBool2 = + (reflectType(Predicate) as TypedefMirror).referent; + + expectReflectedType(numToBool1, somePredicate.runtimeType); + expectReflectedType(numToBool2, Predicate); +} diff --git a/tests/lib/mirrors/reflected_type_generics_test.dart b/tests/lib/mirrors/reflected_type_generics_test.dart new file mode 100644 index 00000000000..4e84300690e --- /dev/null +++ b/tests/lib/mirrors/reflected_type_generics_test.dart @@ -0,0 +1,99 @@ +// 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. + +library test.reflected_type_generics_test; + +import 'dart:mirrors'; + +import 'package:expect/expect.dart'; + +import 'reflected_type_helper.dart'; + +class A {} + +class P {} + +class B extends A

{} + +class C {} + +class D extends A {} + +class E extends C {} + +class F {} + +typedef bool Predicate(T arg); + +class FBounded> {} + +class Helper { + Type get param => T; +} + +class Mixin {} + +class Composite extends Object with Mixin {} + +main() { + // "Happy" paths: + expectReflectedType(reflectType(A, [P]), new A

().runtimeType); + expectReflectedType(reflectType(C, [B, P]), new C().runtimeType); + expectReflectedType(reflectType(D, [P]), new D

().runtimeType); + expectReflectedType(reflectType(E, [P]), new E

().runtimeType); + expectReflectedType( + reflectType(FBounded, [new FBounded().runtimeType]), new FBounded>().runtimeType); + + var predicateHelper = new Helper>(); + expectReflectedType(reflectType(Predicate, [P]), predicateHelper.param); //# 01: ok + var composite = new Composite(); + expectReflectedType(reflectType(Composite, [P, int]), composite.runtimeType); + + // Edge cases: + Expect.throws( + () => reflectType(P, []), + (e) => e is ArgumentError && e.invalidValue is List, + "Should throw an ArgumentError if reflecting not a generic class with " + "empty list of type arguments"); + Expect.throws( // //# 03: ok + () => reflectType(P, [B]), // //# 03: continued + (e) => e is Error, // //# 03: continued + "Should throw an ArgumentError if reflecting not a generic class with " //# 03: continued + "some type arguments"); // //# 03: continued + Expect.throws( + () => reflectType(A, []), + (e) => e is ArgumentError && e.invalidValue is List, + "Should throw an ArgumentError if type argument list is empty for a " + "generic class"); + Expect.throws( // //# 04: ok + () => reflectType(A, [P, B]), // //# 04: continued + (e) => e is ArgumentError && e.invalidValue is List, // //# 04: continued + "Should throw an ArgumentError if number of type arguments is not " // //# 04: continued + "correct"); // //# 04: continued + Expect.throws(() => reflectType(B, [P]), (e) => e is Error, // //# 05: ok + "Should throw an ArgumentError for non-generic class extending " // //# 05: continued + "generic one"); // //# 05: continued +/* Expect.throws( + () => reflectType(A, ["non-type"]), + (e) => e is ArgumentError && e.invalidValue is List, + "Should throw an ArgumentError when any of type arguments is not a + Type");*/ + Expect.throws( // //# 06: ok + () => reflectType(A, [P, B]), // //# 06: continued + (e) => e is ArgumentError && e.invalidValue is List, // //# 06: continued + "Should throw an ArgumentError if number of type arguments is not correct " //# 06: continued + "for generic extending another generic"); // //# 06: continued + Expect.throws( + () => reflectType(reflectType(F).typeVariables[0].reflectedType, [int])); + Expect.throws(() => reflectType(FBounded, [int])); //# 02: ok + var boundedType = + reflectType(FBounded).typeVariables[0].upperBound.reflectedType; + Expect.throws(() => reflectType(boundedType, [int])); //# 02: ok + Expect.throws(() => reflectType(Composite, [int, int])); //# 02: ok + + // Instantiation of a generic class preserves type information: + ClassMirror m = reflectType(A, [P]) as ClassMirror; + var instance = m.newInstance(Symbol.empty, []).reflectee; + Expect.equals(new A

().runtimeType, instance.runtimeType); +} diff --git a/tests/lib/mirrors/reflected_type_helper.dart b/tests/lib/mirrors/reflected_type_helper.dart new file mode 100644 index 00000000000..fb7bf93ec4a --- /dev/null +++ b/tests/lib/mirrors/reflected_type_helper.dart @@ -0,0 +1,19 @@ +// Copyright (c) 2014, 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. + +library test.reflected_type_helper; + +import 'dart:mirrors'; +import 'package:expect/expect.dart'; + +expectReflectedType(TypeMirror typeMirror, Type expectedType) { + if (expectedType == null) { + Expect.isFalse(typeMirror.hasReflectedType); + Expect.throwsUnsupportedError(() => typeMirror.reflectedType, + "Should not have a reflected type"); + } else { + Expect.isTrue(typeMirror.hasReflectedType); + Expect.equals(expectedType, typeMirror.reflectedType); + } +} diff --git a/tests/lib/mirrors/reflected_type_special_types_test.dart b/tests/lib/mirrors/reflected_type_special_types_test.dart new file mode 100644 index 00000000000..4fe726124fc --- /dev/null +++ b/tests/lib/mirrors/reflected_type_special_types_test.dart @@ -0,0 +1,19 @@ +// Copyright (c) 2014, 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. + +library test.reflected_type_special_types; + +import 'dart:mirrors'; + +import 'reflected_type_helper.dart'; + +main() { + TypeMirror dynamicMirror = currentMirrorSystem().dynamicType; + TypeMirror dynamicMirror2 = reflectType(dynamic); + TypeMirror voidMirror = currentMirrorSystem().voidType; + + expectReflectedType(dynamicMirror, dynamic); + expectReflectedType(dynamicMirror2, dynamic); + expectReflectedType(voidMirror, null); +} diff --git a/tests/lib/mirrors/reflected_type_test.dart b/tests/lib/mirrors/reflected_type_test.dart new file mode 100644 index 00000000000..4b07e43ce11 --- /dev/null +++ b/tests/lib/mirrors/reflected_type_test.dart @@ -0,0 +1,83 @@ +// Copyright (c) 2013, 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. + +library test.reflected_type_test; + +import 'dart:mirrors'; + +import 'package:expect/expect.dart'; + +class A {} + +class B extends A {} + +class C extends A {} // //# 01: compile-time error +class D extends A {} + +class E extends A {} + +class F extends A {} + +class G {} + +class H {} + +expectReflectedType(classMirror, expectedType) { + if (expectedType == null) { + Expect.isFalse(classMirror.hasReflectedType, + "$classMirror should not have a reflected type"); + Expect.throwsUnsupportedError(() => classMirror.reflectedType); + } else { + Expect.isTrue(classMirror.hasReflectedType, + "$classMirror should have a reflected type"); + Expect.equals(expectedType, classMirror.reflectedType); + } +} + +main() { + // Basic non-generic types, including intercepted types. + expectReflectedType(reflectClass(Object), Object); + expectReflectedType(reflectClass(String), String); + expectReflectedType(reflectClass(int), int); + expectReflectedType(reflectClass(num), num); + expectReflectedType(reflectClass(double), double); + expectReflectedType(reflectClass(bool), bool); + expectReflectedType(reflectClass(Null), Null); + + // Declarations. + expectReflectedType(reflectClass(A), null); + expectReflectedType(reflectClass(B), B); + expectReflectedType(reflectClass(C), C); // //# 01: continued + expectReflectedType(reflectClass(D), D); + expectReflectedType(reflectClass(E), null); + expectReflectedType(reflectClass(F), null); + expectReflectedType(reflectClass(G), G); + expectReflectedType(reflectClass(H), null); + + // Instantiations. + expectReflectedType(reflect(new A()).type, new A().runtimeType); + expectReflectedType(reflect(new B()).type, new B().runtimeType); + expectReflectedType(reflect(new C()).type, new C().runtimeType); // //# 01: continued + expectReflectedType(reflect(new D()).type, new D().runtimeType); + expectReflectedType(reflect(new E()).type, new E().runtimeType); + expectReflectedType(reflect(new F()).type, new F().runtimeType); + expectReflectedType(reflect(new G()).type, new G().runtimeType); + expectReflectedType(reflect(new H()).type, new H().runtimeType); + + expectReflectedType(reflect(new A()).type, new A().runtimeType); + expectReflectedType(reflect(new B()).type.superclass, // //# 02: compile-time error + new A().runtimeType); // //# 02: continued + expectReflectedType(reflect(new C()).type.superclass, // //# 01: continued + new A().runtimeType); // //# 01: continued + expectReflectedType(reflect(new D()).type.superclass, // //# 03: compile-time error + new A().runtimeType); // //# 03: continued + expectReflectedType(reflect(new E()).type, new E().runtimeType); + expectReflectedType( + reflect(new E()).type.superclass, new A().runtimeType); + expectReflectedType( + reflect(new F()).type.superclass, new A().runtimeType); + expectReflectedType(reflect(new F()).type, new F().runtimeType); + expectReflectedType( + reflect(new H()).type, new H().runtimeType); +} diff --git a/tests/lib/mirrors/reflected_type_typedefs_test.dart b/tests/lib/mirrors/reflected_type_typedefs_test.dart new file mode 100644 index 00000000000..03673d7d04e --- /dev/null +++ b/tests/lib/mirrors/reflected_type_typedefs_test.dart @@ -0,0 +1,28 @@ +// Copyright (c) 2014, 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. + +library test.reflected_type_typedefs; + +import 'dart:mirrors'; + +import 'reflected_type_helper.dart'; + +typedef bool NonGenericPredicate(num n); +typedef bool GenericPredicate(T t); +typedef S GenericTransform(S s); + +main() { + final nonGenericPredicate = reflectType(NonGenericPredicate) as TypedefMirror; + final predicateOfDynamic = reflectType(GenericPredicate) as TypedefMirror; + final transformOfDynamic = reflectType(GenericTransform) as TypedefMirror; + + final predicateDecl = predicateOfDynamic.originalDeclaration as TypedefMirror; + final transformDecl = transformOfDynamic.originalDeclaration as TypedefMirror; + + expectReflectedType(nonGenericPredicate, NonGenericPredicate); + expectReflectedType(predicateOfDynamic, GenericPredicate); + expectReflectedType(transformOfDynamic, GenericTransform); + expectReflectedType(predicateDecl, null); + expectReflectedType(transformDecl, null); +} diff --git a/tests/lib/mirrors/reflected_type_typevars_test.dart b/tests/lib/mirrors/reflected_type_typevars_test.dart new file mode 100644 index 00000000000..a43c0557a28 --- /dev/null +++ b/tests/lib/mirrors/reflected_type_typevars_test.dart @@ -0,0 +1,21 @@ +// Copyright (c) 2014, 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. + +library test.reflected_type_type_variables; + +import 'dart:mirrors'; + +import 'reflected_type_helper.dart'; + +class Class {} + +typedef bool Predicate(S t); + +main() { + TypeVariableMirror tFromClass = reflectClass(Class).typeVariables[0]; + TypeVariableMirror sFromPredicate = reflectType(Predicate).typeVariables[0]; + + expectReflectedType(tFromClass, null); + expectReflectedType(sFromPredicate, null); +} diff --git a/tests/lib/mirrors/reflectively_instantiate_uninstantiated_class_test.dart b/tests/lib/mirrors/reflectively_instantiate_uninstantiated_class_test.dart new file mode 100644 index 00000000000..63cbb9938c3 --- /dev/null +++ b/tests/lib/mirrors/reflectively_instantiate_uninstantiated_class_test.dart @@ -0,0 +1,28 @@ +// Copyright (c) 2013, 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. + +// Ensure that otherwise uninstantiated classes can be instantiated +// reflectively. + +import "dart:mirrors"; + +class Foo { + int a = 0; +} + +main() { + // Do NOT instantiate Foo. + var m = reflectClass(Foo); + var instance = m.newInstance(Symbol.empty, []); + print(instance); + bool threw = false; + try { + m.newInstance(#noSuchConstructor, []); + throw 'Expected an exception'; + } on NoSuchMethodError catch (e) { + print(e); + threw = true; + } + if (!threw) throw 'Expected a NoSuchMethodError'; +} diff --git a/tests/lib/mirrors/regress_13462_0_test.dart b/tests/lib/mirrors/regress_13462_0_test.dart new file mode 100644 index 00000000000..b87bf1f24d7 --- /dev/null +++ b/tests/lib/mirrors/regress_13462_0_test.dart @@ -0,0 +1,9 @@ +// Copyright (c) 2013, 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. + +import 'dart:mirrors'; + +main() { + print(MirrorSystem.getName(#foo)); +} diff --git a/tests/lib/mirrors/regress_13462_1_test.dart b/tests/lib/mirrors/regress_13462_1_test.dart new file mode 100644 index 00000000000..bffdd033426 --- /dev/null +++ b/tests/lib/mirrors/regress_13462_1_test.dart @@ -0,0 +1,10 @@ +// Copyright (c) 2013, 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. + +import 'dart:mirrors'; + +main() { + var name = MirrorSystem.getName(#foo); + if (name != 'foo') throw 'Wrong name: $name != foo'; +} diff --git a/tests/lib/mirrors/regress_14304_test.dart b/tests/lib/mirrors/regress_14304_test.dart new file mode 100644 index 00000000000..293fcea281b --- /dev/null +++ b/tests/lib/mirrors/regress_14304_test.dart @@ -0,0 +1,20 @@ +// Copyright (c) 2013, 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. + +// Regression test for Issue 14304. + +import "dart:mirrors"; +import "package:expect/expect.dart"; + +class A { + T m() {} +} + +main() { + ClassMirror a = reflectClass(A); + TypeVariableMirror t = a.typeVariables[0]; + MethodMirror m = a.declarations[#m] as MethodMirror; + + Expect.equals(t, m.returnType); +} diff --git a/tests/lib/mirrors/regress_16321_test.dart b/tests/lib/mirrors/regress_16321_test.dart new file mode 100644 index 00000000000..6ccf0b28ffe --- /dev/null +++ b/tests/lib/mirrors/regress_16321_test.dart @@ -0,0 +1,21 @@ +// Copyright (c) 2014, 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. + +// Regression test for Issue 16321. +// (Type errors in metadata crashed the VM in checked mode). + +import "dart:mirrors"; + +class TypedBox { + final List contents; + const TypedBox(this.contents); +} + +@TypedBox('foo') //# 01: compile-time error +@TypedBox(const ['foo']) +class C {} + +main() { + reflectClass(C).metadata; +} diff --git a/tests/lib/mirrors/regress_18535_test.dart b/tests/lib/mirrors/regress_18535_test.dart new file mode 100644 index 00000000000..2abb964005a --- /dev/null +++ b/tests/lib/mirrors/regress_18535_test.dart @@ -0,0 +1,12 @@ +// Copyright (c) 2014, 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. + +// Regression test for issue 18535. + +import 'dart:mirrors'; +import 'package:collection/collection.dart'; + +void main() { + print(currentMirrorSystem().libraries); +} diff --git a/tests/lib/mirrors/regress_19731_test.dart b/tests/lib/mirrors/regress_19731_test.dart new file mode 100644 index 00000000000..358098e7265 --- /dev/null +++ b/tests/lib/mirrors/regress_19731_test.dart @@ -0,0 +1,39 @@ +// Copyright (c) 2014, 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. + +@metadata +library regress_19731; + +import 'dart:mirrors'; +import 'package:expect/expect.dart'; + +@metadata +const metadata = const Object(); + +class OneField { + @metadata + var onlyClassField; + + @metadata + method() {} +} + +@metadata +method() {} + +main() { + dynamic classMirror = reflectType(OneField); + var classFieldNames = classMirror.declarations.values + .where((v) => v is VariableMirror) + .map((v) => v.simpleName) + .toList(); + Expect.setEquals([#onlyClassField], classFieldNames); + + dynamic libraryMirror = classMirror.owner; + var libraryFieldNames = libraryMirror.declarations.values + .where((v) => v is VariableMirror) + .map((v) => v.simpleName) + .toList(); + Expect.setEquals([#metadata], libraryFieldNames); +} diff --git a/tests/lib/mirrors/regress_26187_test.dart b/tests/lib/mirrors/regress_26187_test.dart new file mode 100644 index 00000000000..6c381c78dfd --- /dev/null +++ b/tests/lib/mirrors/regress_26187_test.dart @@ -0,0 +1,29 @@ +// 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. + +import 'dart:mirrors'; +import 'package:expect/expect.dart'; + +class A { + const A(); +} + +class B { + const B(); +} + +typedef void f(@A() int, String); + +typedef void g(@B() int, String); + +main() { + ParameterMirror fParamMirror = + (reflectType(f) as TypedefMirror).referent.parameters[0]; + ParameterMirror gParamMirror = + (reflectType(g) as TypedefMirror).referent.parameters[0]; + Expect.equals( + '.A', MirrorSystem.getName(fParamMirror.metadata[0].type.qualifiedName)); + Expect.equals( + '.B', MirrorSystem.getName(gParamMirror.metadata[0].type.qualifiedName)); +} diff --git a/tests/lib/mirrors/regress_28255_test.dart b/tests/lib/mirrors/regress_28255_test.dart new file mode 100644 index 00000000000..b127045030f --- /dev/null +++ b/tests/lib/mirrors/regress_28255_test.dart @@ -0,0 +1,23 @@ +// Copyright (c) 2017, 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. + +// Regression test for issue 28255 + +import 'dart:mirrors'; +import 'package:expect/expect.dart'; + +class Class { + noSuchMethod(i) => true; + + foo() { + dynamic o = this; + Expect.isFalse(o.bar is Null); + Expect.isTrue(o.bar != null); + Expect.equals(true.runtimeType, o.bar.runtimeType); + } +} + +main() { + reflectClass(Class).newInstance(Symbol.empty, []).reflectee.foo(); +} diff --git a/tests/lib/mirrors/regress_33259_test.dart b/tests/lib/mirrors/regress_33259_test.dart new file mode 100644 index 00000000000..af2b4ebcd72 --- /dev/null +++ b/tests/lib/mirrors/regress_33259_test.dart @@ -0,0 +1,26 @@ +// Copyright (c) 2018, 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. + +// Regression test for http://dartbug.com/33259. + +import 'dart:mirrors'; +import 'package:expect/expect.dart'; + +void main() { + final foo = reflectClass(Thing).declarations[#foo] as VariableMirror; + Expect.isTrue(foo.metadata[0].reflectee is Sub); +} + +class Thing { + @Sub() + String foo = "initialized"; +} + +class Base { + const Base(); +} + +class Sub extends Base { + const Sub(); +} diff --git a/tests/lib/mirrors/regress_34982_test.dart b/tests/lib/mirrors/regress_34982_test.dart new file mode 100644 index 00000000000..f86df29cb45 --- /dev/null +++ b/tests/lib/mirrors/regress_34982_test.dart @@ -0,0 +1,27 @@ +// Copyright (c) 2019, 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. + +// Regression test for http://dartbug.com/34982 +import 'dart:mirrors'; +import 'package:expect/expect.dart'; + +abstract class A { + int c(); +} + +class B implements A { + dynamic noSuchMethod(Invocation invocation) {} +} + +void main() { + MethodMirror method1 = reflectClass(B).declarations[#c] as MethodMirror; + Expect.isTrue(method1.isSynthetic); + + MethodMirror method2 = + reflectClass(B).declarations[#noSuchMethod] as MethodMirror; + Expect.isFalse(method2.isSynthetic); + + MethodMirror method3 = reflectClass(A).declarations[#c] as MethodMirror; + Expect.isFalse(method3.isSynthetic); +} diff --git a/tests/lib/mirrors/regress_38035_test.dart b/tests/lib/mirrors/regress_38035_test.dart new file mode 100644 index 00000000000..4e6c25a17db --- /dev/null +++ b/tests/lib/mirrors/regress_38035_test.dart @@ -0,0 +1,19 @@ +// Copyright (c) 2019, 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. + +// Regression test for https://github.com/dart-lang/sdk/issues/38035. +// +// Verifies that static tear-off has correct information about argument types. + +import 'package:expect/expect.dart'; +import 'dart:mirrors'; + +class A { + static bool _defaultCheck([dynamic e]) => true; +} + +main() { + Expect.equals('([dynamic]) -> dart.core.bool', + MirrorSystem.getName(reflect(A._defaultCheck).type.simpleName)); +} diff --git a/tests/lib/mirrors/relation_assignable_test.dart b/tests/lib/mirrors/relation_assignable_test.dart new file mode 100644 index 00000000000..da4c13d7170 --- /dev/null +++ b/tests/lib/mirrors/relation_assignable_test.dart @@ -0,0 +1,328 @@ +// Copyright (c) 2014, 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. + +library test.relation_assignable; + +import "dart:mirrors"; + +import "package:expect/expect.dart"; + +class Superclass {} + +class Subclass1 extends Superclass {} + +class Subclass2 extends Superclass {} + +typedef bool NumberPredicate(num x); +typedef bool IntegerPredicate(int x); +typedef bool DoublePredicate(double x); + +typedef num NumberGenerator(); +typedef int IntegerGenerator(); +typedef double DoubleGenerator(); + +class A {} + +class B extends A {} + +class C {} + +test(MirrorSystem mirrors) { + LibraryMirror coreLibrary = mirrors.findLibrary(#dart.core); + LibraryMirror thisLibrary = mirrors.findLibrary(#test.relation_assignable); + + // Classes. + TypeMirror Super = thisLibrary.declarations[#Superclass] as TypeMirror; + TypeMirror Sub1 = thisLibrary.declarations[#Subclass1] as TypeMirror; + TypeMirror Sub2 = thisLibrary.declarations[#Subclass2] as TypeMirror; + TypeMirror Obj = coreLibrary.declarations[#Object] as TypeMirror; + TypeMirror Nul = coreLibrary.declarations[#Null] as TypeMirror; + + Expect.isTrue(Obj.isAssignableTo(Obj)); + Expect.isTrue(Super.isAssignableTo(Super)); + Expect.isTrue(Sub1.isAssignableTo(Sub1)); + Expect.isTrue(Sub2.isAssignableTo(Sub2)); + Expect.isTrue(Nul.isAssignableTo(Nul)); + + Expect.isTrue(Sub1.isAssignableTo(Super)); + Expect.isTrue(Super.isAssignableTo(Sub1)); + + Expect.isTrue(Sub2.isAssignableTo(Super)); + Expect.isTrue(Super.isAssignableTo(Sub2)); + + Expect.isFalse(Sub2.isAssignableTo(Sub1)); + Expect.isFalse(Sub1.isAssignableTo(Sub2)); + + Expect.isTrue(Sub1.isAssignableTo(Obj)); + Expect.isTrue(Obj.isAssignableTo(Sub1)); + + Expect.isTrue(Sub2.isAssignableTo(Obj)); + Expect.isTrue(Obj.isAssignableTo(Sub2)); + + Expect.isTrue(Super.isAssignableTo(Obj)); + Expect.isTrue(Obj.isAssignableTo(Super)); + + Expect.isTrue(Nul.isAssignableTo(Obj)); + Expect.isTrue(Obj.isAssignableTo(Nul)); + Expect.isTrue(Nul.isAssignableTo(Super)); // Null type is bottom type. + Expect.isTrue(Super.isAssignableTo(Nul)); + + // Function typedef - argument type. + TypeMirror Func = coreLibrary.declarations[#Function] as TypeMirror; + TypedefMirror NumPred = + thisLibrary.declarations[#NumberPredicate] as TypedefMirror; + TypedefMirror IntPred = + thisLibrary.declarations[#IntegerPredicate] as TypedefMirror; + TypedefMirror DubPred = + thisLibrary.declarations[#DoublePredicate] as TypedefMirror; + + Expect.isTrue(Func.isAssignableTo(Func)); + Expect.isTrue(NumPred.isAssignableTo(NumPred)); + Expect.isTrue(IntPred.isAssignableTo(IntPred)); + Expect.isTrue(DubPred.isAssignableTo(DubPred)); + + Expect.isTrue(NumPred.isAssignableTo(Func)); + Expect.isTrue(NumPred.isAssignableTo(IntPred)); + Expect.isTrue(NumPred.isAssignableTo(DubPred)); + + Expect.isTrue(IntPred.isAssignableTo(Func)); + Expect.isTrue(IntPred.isAssignableTo(NumPred)); + Expect.isFalse(IntPred.isAssignableTo(DubPred)); + + Expect.isTrue(DubPred.isAssignableTo(Func)); + Expect.isTrue(DubPred.isAssignableTo(NumPred)); + Expect.isFalse(DubPred.isAssignableTo(IntPred)); + + Expect.isTrue(Func.isAssignableTo(Obj)); + Expect.isTrue(NumPred.isAssignableTo(Obj)); + Expect.isTrue(IntPred.isAssignableTo(Obj)); + Expect.isTrue(DubPred.isAssignableTo(Obj)); + Expect.isTrue(Obj.isAssignableTo(Func)); + Expect.isTrue(Obj.isAssignableTo(NumPred)); + Expect.isTrue(Obj.isAssignableTo(IntPred)); + Expect.isTrue(Obj.isAssignableTo(DubPred)); + + // Function typedef - return type. + TypedefMirror NumGen = + thisLibrary.declarations[#NumberGenerator] as TypedefMirror; + TypedefMirror IntGen = + thisLibrary.declarations[#IntegerGenerator] as TypedefMirror; + TypedefMirror DubGen = + thisLibrary.declarations[#DoubleGenerator] as TypedefMirror; + + Expect.isTrue(NumGen.isAssignableTo(NumGen)); + Expect.isTrue(IntGen.isAssignableTo(IntGen)); + Expect.isTrue(DubGen.isAssignableTo(DubGen)); + + Expect.isTrue(NumGen.isAssignableTo(Func)); + Expect.isTrue(NumGen.isAssignableTo(IntGen)); + Expect.isTrue(NumGen.isAssignableTo(DubGen)); + + Expect.isTrue(IntGen.isAssignableTo(Func)); + Expect.isTrue(IntGen.isAssignableTo(NumGen)); + Expect.isFalse(IntGen.isAssignableTo(DubGen)); + + Expect.isTrue(DubGen.isAssignableTo(Func)); + Expect.isTrue(DubGen.isAssignableTo(NumGen)); + Expect.isFalse(DubGen.isAssignableTo(IntGen)); + + Expect.isTrue(Func.isAssignableTo(Obj)); + Expect.isTrue(NumGen.isAssignableTo(Obj)); + Expect.isTrue(IntGen.isAssignableTo(Obj)); + Expect.isTrue(DubGen.isAssignableTo(Obj)); + Expect.isTrue(Obj.isAssignableTo(Func)); + Expect.isTrue(Obj.isAssignableTo(NumGen)); + Expect.isTrue(Obj.isAssignableTo(IntGen)); + Expect.isTrue(Obj.isAssignableTo(DubGen)); + + // Function - argument type. + TypeMirror NumPredRef = NumPred.referent; + TypeMirror IntPredRef = IntPred.referent; + TypeMirror DubPredRef = DubPred.referent; + + Expect.isTrue(Func.isAssignableTo(Func)); + Expect.isTrue(NumPredRef.isAssignableTo(NumPredRef)); + Expect.isTrue(IntPredRef.isAssignableTo(IntPredRef)); + Expect.isTrue(DubPredRef.isAssignableTo(DubPredRef)); + + Expect.isTrue(NumPredRef.isAssignableTo(Func)); + Expect.isTrue(NumPredRef.isAssignableTo(IntPredRef)); + Expect.isTrue(NumPredRef.isAssignableTo(DubPredRef)); + + Expect.isTrue(IntPredRef.isAssignableTo(Func)); + Expect.isTrue(IntPredRef.isAssignableTo(NumPredRef)); + Expect.isFalse(IntPredRef.isAssignableTo(DubPredRef)); + + Expect.isTrue(DubPredRef.isAssignableTo(Func)); + Expect.isTrue(DubPredRef.isAssignableTo(NumPredRef)); + Expect.isFalse(DubPredRef.isAssignableTo(IntPredRef)); + + Expect.isTrue(Func.isAssignableTo(Obj)); + Expect.isTrue(NumPredRef.isAssignableTo(Obj)); + Expect.isTrue(IntPredRef.isAssignableTo(Obj)); + Expect.isTrue(DubPredRef.isAssignableTo(Obj)); + Expect.isTrue(Obj.isAssignableTo(Func)); + Expect.isTrue(Obj.isAssignableTo(NumPredRef)); + Expect.isTrue(Obj.isAssignableTo(IntPredRef)); + Expect.isTrue(Obj.isAssignableTo(DubPredRef)); + + // Function - return type. + TypeMirror NumGenRef = NumGen.referent; + TypeMirror IntGenRef = IntGen.referent; + TypeMirror DubGenRef = DubGen.referent; + + Expect.isTrue(NumGenRef.isAssignableTo(NumGenRef)); + Expect.isTrue(IntGenRef.isAssignableTo(IntGenRef)); + Expect.isTrue(DubGenRef.isAssignableTo(DubGenRef)); + + Expect.isTrue(NumGenRef.isAssignableTo(Func)); + Expect.isTrue(NumGenRef.isAssignableTo(IntGenRef)); + Expect.isTrue(NumGenRef.isAssignableTo(DubGenRef)); + + Expect.isTrue(IntGenRef.isAssignableTo(Func)); + Expect.isTrue(IntGenRef.isAssignableTo(NumGenRef)); + Expect.isFalse(IntGenRef.isAssignableTo(DubGenRef)); + + Expect.isTrue(DubGenRef.isAssignableTo(Func)); + Expect.isTrue(DubGenRef.isAssignableTo(NumGenRef)); + Expect.isFalse(DubGenRef.isAssignableTo(IntGenRef)); + + Expect.isTrue(Func.isAssignableTo(Obj)); + Expect.isTrue(NumGenRef.isAssignableTo(Obj)); + Expect.isTrue(IntGenRef.isAssignableTo(Obj)); + Expect.isTrue(DubGenRef.isAssignableTo(Obj)); + Expect.isTrue(Obj.isAssignableTo(Func)); + Expect.isTrue(Obj.isAssignableTo(NumGenRef)); + Expect.isTrue(Obj.isAssignableTo(IntGenRef)); + Expect.isTrue(Obj.isAssignableTo(DubGenRef)); + + // Function typedef / function. + Expect.isTrue(NumPred.isAssignableTo(NumPredRef)); + Expect.isTrue(IntPred.isAssignableTo(IntPredRef)); + Expect.isTrue(DubPred.isAssignableTo(DubPredRef)); + Expect.isTrue(NumPredRef.isAssignableTo(NumPred)); + Expect.isTrue(IntPredRef.isAssignableTo(IntPred)); + Expect.isTrue(DubPredRef.isAssignableTo(DubPred)); + + // Function typedef / function. + Expect.isTrue(NumGen.isAssignableTo(NumGenRef)); + Expect.isTrue(IntGen.isAssignableTo(IntGenRef)); + Expect.isTrue(DubGen.isAssignableTo(DubGenRef)); + Expect.isTrue(NumGenRef.isAssignableTo(NumGen)); + Expect.isTrue(IntGenRef.isAssignableTo(IntGen)); + Expect.isTrue(DubGenRef.isAssignableTo(DubGen)); + + // Type variable. + TypeMirror TFromA = + (thisLibrary.declarations[#A] as ClassMirror).typeVariables.single; + TypeMirror TFromB = + (thisLibrary.declarations[#B] as ClassMirror).typeVariables.single; + TypeMirror TFromC = + (thisLibrary.declarations[#C] as ClassMirror).typeVariables.single; + + Expect.isTrue(TFromA.isAssignableTo(TFromA)); + Expect.isTrue(TFromB.isAssignableTo(TFromB)); + Expect.isTrue(TFromC.isAssignableTo(TFromC)); + + Expect.isFalse(TFromA.isAssignableTo(TFromB)); + Expect.isFalse(TFromA.isAssignableTo(TFromC)); + Expect.isFalse(TFromB.isAssignableTo(TFromA)); + Expect.isFalse(TFromB.isAssignableTo(TFromC)); + Expect.isFalse(TFromC.isAssignableTo(TFromA)); + Expect.isFalse(TFromC.isAssignableTo(TFromB)); + + TypeMirror Num = coreLibrary.declarations[#num] as TypeMirror; + Expect.isTrue(TFromC.isAssignableTo(Num)); + Expect.isTrue(Num.isAssignableTo(TFromC)); + + // dynamic & void. + TypeMirror Dynamic = mirrors.dynamicType; + Expect.isTrue(Dynamic.isAssignableTo(Dynamic)); + Expect.isTrue(Obj.isAssignableTo(Dynamic)); + Expect.isTrue(Super.isAssignableTo(Dynamic)); + Expect.isTrue(Sub1.isAssignableTo(Dynamic)); + Expect.isTrue(Sub2.isAssignableTo(Dynamic)); + Expect.isTrue(NumPred.isAssignableTo(Dynamic)); + Expect.isTrue(IntPred.isAssignableTo(Dynamic)); + Expect.isTrue(DubPred.isAssignableTo(Dynamic)); + Expect.isTrue(NumPredRef.isAssignableTo(Dynamic)); + Expect.isTrue(IntPredRef.isAssignableTo(Dynamic)); + Expect.isTrue(DubPredRef.isAssignableTo(Dynamic)); + Expect.isTrue(NumGen.isAssignableTo(Dynamic)); + Expect.isTrue(IntGen.isAssignableTo(Dynamic)); + Expect.isTrue(DubGen.isAssignableTo(Dynamic)); + Expect.isTrue(NumGenRef.isAssignableTo(Dynamic)); + Expect.isTrue(IntGenRef.isAssignableTo(Dynamic)); + Expect.isTrue(DubGenRef.isAssignableTo(Dynamic)); + Expect.isTrue(TFromA.isAssignableTo(Dynamic)); + Expect.isTrue(TFromB.isAssignableTo(Dynamic)); + Expect.isTrue(TFromC.isAssignableTo(Dynamic)); + Expect.isTrue(Dynamic.isAssignableTo(Obj)); + Expect.isTrue(Dynamic.isAssignableTo(Super)); + Expect.isTrue(Dynamic.isAssignableTo(Sub1)); + Expect.isTrue(Dynamic.isAssignableTo(Sub2)); + Expect.isTrue(Dynamic.isAssignableTo(NumPred)); + Expect.isTrue(Dynamic.isAssignableTo(IntPred)); + Expect.isTrue(Dynamic.isAssignableTo(DubPred)); + Expect.isTrue(Dynamic.isAssignableTo(NumPredRef)); + Expect.isTrue(Dynamic.isAssignableTo(IntPredRef)); + Expect.isTrue(Dynamic.isAssignableTo(DubPredRef)); + Expect.isTrue(Dynamic.isAssignableTo(NumGen)); + Expect.isTrue(Dynamic.isAssignableTo(IntGen)); + Expect.isTrue(Dynamic.isAssignableTo(DubGen)); + Expect.isTrue(Dynamic.isAssignableTo(NumGenRef)); + Expect.isTrue(Dynamic.isAssignableTo(IntGenRef)); + Expect.isTrue(Dynamic.isAssignableTo(DubGenRef)); + Expect.isTrue(Dynamic.isAssignableTo(TFromA)); + Expect.isTrue(Dynamic.isAssignableTo(TFromB)); + Expect.isTrue(Dynamic.isAssignableTo(TFromC)); + + TypeMirror Void = mirrors.voidType; + Expect.isTrue(Void.isAssignableTo(Void)); + Expect.isFalse(Obj.isAssignableTo(Void)); + Expect.isFalse(Super.isAssignableTo(Void)); + Expect.isFalse(Sub1.isAssignableTo(Void)); + Expect.isFalse(Sub2.isAssignableTo(Void)); + Expect.isFalse(NumPred.isAssignableTo(Void)); + Expect.isFalse(IntPred.isAssignableTo(Void)); + Expect.isFalse(DubPred.isAssignableTo(Void)); + Expect.isFalse(NumPredRef.isAssignableTo(Void)); + Expect.isFalse(IntPredRef.isAssignableTo(Void)); + Expect.isFalse(DubPredRef.isAssignableTo(Void)); + Expect.isFalse(NumGen.isAssignableTo(Void)); + Expect.isFalse(IntGen.isAssignableTo(Void)); + Expect.isFalse(DubGen.isAssignableTo(Void)); + Expect.isFalse(NumGenRef.isAssignableTo(Void)); + Expect.isFalse(IntGenRef.isAssignableTo(Void)); + Expect.isFalse(DubGenRef.isAssignableTo(Void)); + Expect.isFalse(TFromA.isAssignableTo(Void)); + Expect.isFalse(TFromB.isAssignableTo(Void)); + Expect.isFalse(TFromC.isAssignableTo(Void)); + Expect.isFalse(Void.isAssignableTo(Obj)); + Expect.isFalse(Void.isAssignableTo(Super)); + Expect.isFalse(Void.isAssignableTo(Sub1)); + Expect.isFalse(Void.isAssignableTo(Sub2)); + Expect.isFalse(Void.isAssignableTo(NumPred)); + Expect.isFalse(Void.isAssignableTo(IntPred)); + Expect.isFalse(Void.isAssignableTo(DubPred)); + Expect.isFalse(Void.isAssignableTo(NumPredRef)); + Expect.isFalse(Void.isAssignableTo(IntPredRef)); + Expect.isFalse(Void.isAssignableTo(DubPredRef)); + Expect.isFalse(Void.isAssignableTo(NumGen)); + Expect.isFalse(Void.isAssignableTo(IntGen)); + Expect.isFalse(Void.isAssignableTo(DubGen)); + Expect.isFalse(Void.isAssignableTo(NumGenRef)); + Expect.isFalse(Void.isAssignableTo(IntGenRef)); + Expect.isFalse(Void.isAssignableTo(DubGenRef)); + Expect.isFalse(Void.isAssignableTo(TFromA)); + Expect.isFalse(Void.isAssignableTo(TFromB)); + Expect.isFalse(Void.isAssignableTo(TFromC)); + + Expect.isTrue(Dynamic.isAssignableTo(Void)); + Expect.isTrue(Void.isAssignableTo(Dynamic)); +} + +main() { + test(currentMirrorSystem()); +} diff --git a/tests/lib/mirrors/relation_subclass_test.dart b/tests/lib/mirrors/relation_subclass_test.dart new file mode 100644 index 00000000000..7e83931b8d5 --- /dev/null +++ b/tests/lib/mirrors/relation_subclass_test.dart @@ -0,0 +1,118 @@ +// Copyright (c) 2014, 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. + +library test.relation_subclass; + +import "dart:mirrors"; + +import "package:expect/expect.dart"; + +class Superclass {} + +class Subclass1 extends Superclass {} + +class Subclass2 extends Superclass {} + +typedef bool NumberPredicate(num x); +typedef bool IntegerPredicate(int x); +typedef bool DoublePredicate(double x); + +typedef num NumberGenerator(); +typedef int IntegerGenerator(); +typedef double DoubleGenerator(); + +test(MirrorSystem mirrors) { + LibraryMirror coreLibrary = mirrors.findLibrary(#dart.core); + LibraryMirror thisLibrary = mirrors.findLibrary(#test.relation_subclass); + + ClassMirror Super = thisLibrary.declarations[#Superclass] as ClassMirror; + ClassMirror Sub1 = thisLibrary.declarations[#Subclass1] as ClassMirror; + ClassMirror Sub2 = thisLibrary.declarations[#Subclass2] as ClassMirror; + ClassMirror Obj = coreLibrary.declarations[#Object] as ClassMirror; + ClassMirror Nul = coreLibrary.declarations[#Null] as ClassMirror; + + Expect.isTrue(Obj.isSubclassOf(Obj)); + Expect.isTrue(Super.isSubclassOf(Super)); + Expect.isTrue(Sub1.isSubclassOf(Sub1)); + Expect.isTrue(Sub2.isSubclassOf(Sub2)); + Expect.isTrue(Nul.isSubclassOf(Nul)); + + Expect.isTrue(Sub1.isSubclassOf(Super)); + Expect.isFalse(Super.isSubclassOf(Sub1)); + + Expect.isTrue(Sub2.isSubclassOf(Super)); + Expect.isFalse(Super.isSubclassOf(Sub2)); + + Expect.isFalse(Sub2.isSubclassOf(Sub1)); + Expect.isFalse(Sub1.isSubclassOf(Sub2)); + + Expect.isTrue(Sub1.isSubclassOf(Obj)); + Expect.isFalse(Obj.isSubclassOf(Sub1)); + + Expect.isTrue(Sub2.isSubclassOf(Obj)); + Expect.isFalse(Obj.isSubclassOf(Sub2)); + + Expect.isTrue(Super.isSubclassOf(Obj)); + Expect.isFalse(Obj.isSubclassOf(Super)); + + Expect.isTrue(Nul.isSubclassOf(Obj)); + Expect.isFalse(Obj.isSubclassOf(Nul)); + Expect.isFalse(Nul.isSubclassOf(Super)); + Expect.isFalse(Super.isSubclassOf(Nul)); + + ClassMirror Func = coreLibrary.declarations[#Function] as ClassMirror; + Expect.isTrue(Func.isSubclassOf(Obj)); + Expect.isFalse(Obj.isSubclassOf(Func)); + + // Function typedef. + dynamic NumPred = thisLibrary.declarations[#NumberPredicate]; + dynamic IntPred = thisLibrary.declarations[#IntegerPredicate]; + dynamic DubPred = thisLibrary.declarations[#DoublePredicate]; + dynamic NumGen = thisLibrary.declarations[#NumberGenerator]; + dynamic IntGen = thisLibrary.declarations[#IntegerGenerator]; + dynamic DubGen = thisLibrary.declarations[#DoubleGenerator]; + + isArgumentOrTypeError(e) => e is ArgumentError || e is TypeError; + Expect.throws(() => Func.isSubclassOf(NumPred), isArgumentOrTypeError); + Expect.throws(() => Func.isSubclassOf(IntPred), isArgumentOrTypeError); + Expect.throws(() => Func.isSubclassOf(DubPred), isArgumentOrTypeError); + Expect.throws(() => Func.isSubclassOf(NumGen), isArgumentOrTypeError); + Expect.throws(() => Func.isSubclassOf(IntGen), isArgumentOrTypeError); + Expect.throws(() => Func.isSubclassOf(DubGen), isArgumentOrTypeError); + + Expect.throwsNoSuchMethodError(() => NumPred.isSubclassOf(Func)); + Expect.throwsNoSuchMethodError(() => IntPred.isSubclassOf(Func)); + Expect.throwsNoSuchMethodError(() => DubPred.isSubclassOf(Func)); + Expect.throwsNoSuchMethodError(() => NumGen.isSubclassOf(Func)); + Expect.throwsNoSuchMethodError(() => IntGen.isSubclassOf(Func)); + Expect.throwsNoSuchMethodError(() => DubGen.isSubclassOf(Func)); + + // Function type. + TypeMirror NumPredRef = (NumPred as TypedefMirror).referent; + TypeMirror IntPredRef = (IntPred as TypedefMirror).referent; + TypeMirror DubPredRef = (DubPred as TypedefMirror).referent; + TypeMirror NumGenRef = (NumGen as TypedefMirror).referent; + TypeMirror IntGenRef = (IntGen as TypedefMirror).referent; + TypeMirror DubGenRef = (DubGen as TypedefMirror).referent; + + Expect.isFalse(Func.isSubclassOf(NumPredRef)); + Expect.isFalse(Func.isSubclassOf(IntPredRef)); + Expect.isFalse(Func.isSubclassOf(DubPredRef)); + Expect.isFalse(Func.isSubclassOf(NumGenRef)); + Expect.isFalse(Func.isSubclassOf(IntGenRef)); + Expect.isFalse(Func.isSubclassOf(DubGenRef)); + + // The spec doesn't require these to be either value, only that they implement + // Function. + // NumPredRef.isSubclassOf(Func); + // IntPredRef.isSubclassOf(Func); + // DubPredRef.isSubclassOf(Func); + // NumGenRef.isSubclassOf(Func); + // IntGenRef.isSubclassOf(Func); + // DubGenRef.isSubclassOf(Func); +} + +main() { + test(currentMirrorSystem()); +} diff --git a/tests/lib/mirrors/relation_subtype_test.dart b/tests/lib/mirrors/relation_subtype_test.dart new file mode 100644 index 00000000000..a9d165a045a --- /dev/null +++ b/tests/lib/mirrors/relation_subtype_test.dart @@ -0,0 +1,312 @@ +// Copyright (c) 2014, 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. + +library test.relation_subtype; + +import "dart:mirrors"; + +import "package:expect/expect.dart"; + +class Superclass {} + +class Subclass1 extends Superclass {} + +class Subclass2 extends Superclass {} + +typedef bool NumberPredicate(num x); +typedef bool IntegerPredicate(int x); +typedef bool DoublePredicate(double x); + +typedef num NumberGenerator(); +typedef int IntegerGenerator(); +typedef double DoubleGenerator(); + +class A {} + +class B extends A {} + +class C {} + +test(MirrorSystem mirrors) { + LibraryMirror coreLibrary = mirrors.findLibrary(#dart.core); + LibraryMirror thisLibrary = mirrors.findLibrary(#test.relation_subtype); + + // Classes. + final Super = thisLibrary.declarations[#Superclass] as ClassMirror; + final Sub1 = thisLibrary.declarations[#Subclass1] as ClassMirror; + final Sub2 = thisLibrary.declarations[#Subclass2] as ClassMirror; + final Obj = coreLibrary.declarations[#Object] as ClassMirror; + final Nul = coreLibrary.declarations[#Null] as ClassMirror; + + Expect.isTrue(Obj.isSubtypeOf(Obj)); + Expect.isTrue(Super.isSubtypeOf(Super)); + Expect.isTrue(Sub1.isSubtypeOf(Sub1)); + Expect.isTrue(Sub2.isSubtypeOf(Sub2)); + Expect.isTrue(Nul.isSubtypeOf(Nul)); + + Expect.isTrue(Sub1.isSubtypeOf(Super)); + Expect.isFalse(Super.isSubtypeOf(Sub1)); + + Expect.isTrue(Sub2.isSubtypeOf(Super)); + Expect.isFalse(Super.isSubtypeOf(Sub2)); + + Expect.isFalse(Sub2.isSubtypeOf(Sub1)); + Expect.isFalse(Sub1.isSubtypeOf(Sub2)); + + Expect.isTrue(Sub1.isSubtypeOf(Obj)); + Expect.isFalse(Obj.isSubtypeOf(Sub1)); + + Expect.isTrue(Sub2.isSubtypeOf(Obj)); + Expect.isFalse(Obj.isSubtypeOf(Sub2)); + + Expect.isTrue(Super.isSubtypeOf(Obj)); + Expect.isFalse(Obj.isSubtypeOf(Super)); + + Expect.isTrue(Nul.isSubtypeOf(Obj)); + Expect.isFalse(Obj.isSubtypeOf(Nul)); + Expect.isTrue(Nul.isSubtypeOf(Super)); // Null type is bottom type. + Expect.isFalse(Super.isSubtypeOf(Nul)); + + // Function typedef - argument type. + TypeMirror Func = coreLibrary.declarations[#Function] as TypeMirror; + TypedefMirror NumPred = + thisLibrary.declarations[#NumberPredicate] as TypedefMirror; + TypedefMirror IntPred = + thisLibrary.declarations[#IntegerPredicate] as TypedefMirror; + TypedefMirror DubPred = + thisLibrary.declarations[#DoublePredicate] as TypedefMirror; + + Expect.isTrue(Func.isSubtypeOf(Func)); + Expect.isTrue(NumPred.isSubtypeOf(NumPred)); + Expect.isTrue(IntPred.isSubtypeOf(IntPred)); + Expect.isTrue(DubPred.isSubtypeOf(DubPred)); + + Expect.isTrue(NumPred.isSubtypeOf(Func)); + Expect.isTrue(NumPred.isSubtypeOf(IntPred)); + Expect.isTrue(NumPred.isSubtypeOf(DubPred)); + + Expect.isTrue(IntPred.isSubtypeOf(Func)); + Expect.isTrue(IntPred.isSubtypeOf(NumPred)); + Expect.isFalse(IntPred.isSubtypeOf(DubPred)); + + Expect.isTrue(DubPred.isSubtypeOf(Func)); + Expect.isTrue(DubPred.isSubtypeOf(NumPred)); + Expect.isFalse(DubPred.isSubtypeOf(IntPred)); + + Expect.isTrue(Func.isSubtypeOf(Obj)); + Expect.isTrue(NumPred.isSubtypeOf(Obj)); + Expect.isTrue(IntPred.isSubtypeOf(Obj)); + Expect.isTrue(DubPred.isSubtypeOf(Obj)); + + // Function typedef - return type. + TypedefMirror NumGen = + thisLibrary.declarations[#NumberGenerator] as TypedefMirror; + TypedefMirror IntGen = + thisLibrary.declarations[#IntegerGenerator] as TypedefMirror; + TypedefMirror DubGen = + thisLibrary.declarations[#DoubleGenerator] as TypedefMirror; + + Expect.isTrue(NumGen.isSubtypeOf(NumGen)); + Expect.isTrue(IntGen.isSubtypeOf(IntGen)); + Expect.isTrue(DubGen.isSubtypeOf(DubGen)); + + Expect.isTrue(NumGen.isSubtypeOf(Func)); + Expect.isTrue(NumGen.isSubtypeOf(IntGen)); + Expect.isTrue(NumGen.isSubtypeOf(DubGen)); + + Expect.isTrue(IntGen.isSubtypeOf(Func)); + Expect.isTrue(IntGen.isSubtypeOf(NumGen)); + Expect.isFalse(IntGen.isSubtypeOf(DubGen)); + + Expect.isTrue(DubGen.isSubtypeOf(Func)); + Expect.isTrue(DubGen.isSubtypeOf(NumGen)); + Expect.isFalse(DubGen.isSubtypeOf(IntGen)); + + Expect.isTrue(Func.isSubtypeOf(Obj)); + Expect.isTrue(NumGen.isSubtypeOf(Obj)); + Expect.isTrue(IntGen.isSubtypeOf(Obj)); + Expect.isTrue(DubGen.isSubtypeOf(Obj)); + + // Function - argument type. + TypeMirror NumPredRef = NumPred.referent; + TypeMirror IntPredRef = IntPred.referent; + TypeMirror DubPredRef = DubPred.referent; + + Expect.isTrue(Func.isSubtypeOf(Func)); + Expect.isTrue(NumPredRef.isSubtypeOf(NumPredRef)); + Expect.isTrue(IntPredRef.isSubtypeOf(IntPredRef)); + Expect.isTrue(DubPredRef.isSubtypeOf(DubPredRef)); + + Expect.isTrue(NumPredRef.isSubtypeOf(Func)); + Expect.isTrue(NumPredRef.isSubtypeOf(IntPredRef)); + Expect.isTrue(NumPredRef.isSubtypeOf(DubPredRef)); + + Expect.isTrue(IntPredRef.isSubtypeOf(Func)); + Expect.isTrue(IntPredRef.isSubtypeOf(NumPredRef)); + Expect.isFalse(IntPredRef.isSubtypeOf(DubPredRef)); + + Expect.isTrue(DubPredRef.isSubtypeOf(Func)); + Expect.isTrue(DubPredRef.isSubtypeOf(NumPredRef)); + Expect.isFalse(DubPredRef.isSubtypeOf(IntPredRef)); + + Expect.isTrue(Func.isSubtypeOf(Obj)); + Expect.isTrue(NumPredRef.isSubtypeOf(Obj)); + Expect.isTrue(IntPredRef.isSubtypeOf(Obj)); + Expect.isTrue(DubPredRef.isSubtypeOf(Obj)); + + // Function - return type. + TypeMirror NumGenRef = NumGen.referent; + TypeMirror IntGenRef = IntGen.referent; + TypeMirror DubGenRef = DubGen.referent; + + Expect.isTrue(NumGenRef.isSubtypeOf(NumGenRef)); + Expect.isTrue(IntGenRef.isSubtypeOf(IntGenRef)); + Expect.isTrue(DubGenRef.isSubtypeOf(DubGenRef)); + + Expect.isTrue(NumGenRef.isSubtypeOf(Func)); + Expect.isTrue(NumGenRef.isSubtypeOf(IntGenRef)); + Expect.isTrue(NumGenRef.isSubtypeOf(DubGenRef)); + + Expect.isTrue(IntGenRef.isSubtypeOf(Func)); + Expect.isTrue(IntGenRef.isSubtypeOf(NumGenRef)); + Expect.isFalse(IntGenRef.isSubtypeOf(DubGenRef)); + + Expect.isTrue(DubGenRef.isSubtypeOf(Func)); + Expect.isTrue(DubGenRef.isSubtypeOf(NumGenRef)); + Expect.isFalse(DubGenRef.isSubtypeOf(IntGenRef)); + + Expect.isTrue(Func.isSubtypeOf(Obj)); + Expect.isTrue(NumGenRef.isSubtypeOf(Obj)); + Expect.isTrue(IntGenRef.isSubtypeOf(Obj)); + Expect.isTrue(DubGenRef.isSubtypeOf(Obj)); + + // Function typedef / function. + Expect.isTrue(NumPred.isSubtypeOf(NumPredRef)); + Expect.isTrue(IntPred.isSubtypeOf(IntPredRef)); + Expect.isTrue(DubPred.isSubtypeOf(DubPredRef)); + Expect.isTrue(NumPredRef.isSubtypeOf(NumPred)); + Expect.isTrue(IntPredRef.isSubtypeOf(IntPred)); + Expect.isTrue(DubPredRef.isSubtypeOf(DubPred)); + + // Function typedef / function. + Expect.isTrue(NumGen.isSubtypeOf(NumGenRef)); + Expect.isTrue(IntGen.isSubtypeOf(IntGenRef)); + Expect.isTrue(DubGen.isSubtypeOf(DubGenRef)); + Expect.isTrue(NumGenRef.isSubtypeOf(NumGen)); + Expect.isTrue(IntGenRef.isSubtypeOf(IntGen)); + Expect.isTrue(DubGenRef.isSubtypeOf(DubGen)); + + // Type variable. + TypeMirror TFromA = + (thisLibrary.declarations[#A] as ClassMirror).typeVariables.single; + TypeMirror TFromB = + (thisLibrary.declarations[#B] as ClassMirror).typeVariables.single; + TypeMirror TFromC = + (thisLibrary.declarations[#C] as ClassMirror).typeVariables.single; + + Expect.isTrue(TFromA.isSubtypeOf(TFromA)); + Expect.isTrue(TFromB.isSubtypeOf(TFromB)); + Expect.isTrue(TFromC.isSubtypeOf(TFromC)); + + Expect.isFalse(TFromA.isSubtypeOf(TFromB)); + Expect.isFalse(TFromA.isSubtypeOf(TFromC)); + Expect.isFalse(TFromB.isSubtypeOf(TFromA)); + Expect.isFalse(TFromB.isSubtypeOf(TFromC)); + Expect.isFalse(TFromC.isSubtypeOf(TFromA)); + Expect.isFalse(TFromC.isSubtypeOf(TFromB)); + + TypeMirror Num = coreLibrary.declarations[#num] as TypeMirror; + Expect.isTrue(TFromC.isSubtypeOf(Num)); + Expect.isFalse(Num.isSubtypeOf(TFromC)); + + // dynamic & void. + TypeMirror Dynamic = mirrors.dynamicType; + Expect.isTrue(Dynamic.isSubtypeOf(Dynamic)); + Expect.isTrue(Obj.isSubtypeOf(Dynamic)); + Expect.isTrue(Super.isSubtypeOf(Dynamic)); + Expect.isTrue(Sub1.isSubtypeOf(Dynamic)); + Expect.isTrue(Sub2.isSubtypeOf(Dynamic)); + Expect.isTrue(NumPred.isSubtypeOf(Dynamic)); + Expect.isTrue(IntPred.isSubtypeOf(Dynamic)); + Expect.isTrue(DubPred.isSubtypeOf(Dynamic)); + Expect.isTrue(NumPredRef.isSubtypeOf(Dynamic)); + Expect.isTrue(IntPredRef.isSubtypeOf(Dynamic)); + Expect.isTrue(DubPredRef.isSubtypeOf(Dynamic)); + Expect.isTrue(NumGen.isSubtypeOf(Dynamic)); + Expect.isTrue(IntGen.isSubtypeOf(Dynamic)); + Expect.isTrue(DubGen.isSubtypeOf(Dynamic)); + Expect.isTrue(NumGenRef.isSubtypeOf(Dynamic)); + Expect.isTrue(IntGenRef.isSubtypeOf(Dynamic)); + Expect.isTrue(DubGenRef.isSubtypeOf(Dynamic)); + Expect.isTrue(TFromA.isSubtypeOf(Dynamic)); + Expect.isTrue(TFromB.isSubtypeOf(Dynamic)); + Expect.isTrue(TFromC.isSubtypeOf(Dynamic)); + Expect.isTrue(Dynamic.isSubtypeOf(Obj)); + Expect.isTrue(Dynamic.isSubtypeOf(Super)); + Expect.isTrue(Dynamic.isSubtypeOf(Sub1)); + Expect.isTrue(Dynamic.isSubtypeOf(Sub2)); + Expect.isTrue(Dynamic.isSubtypeOf(NumPred)); + Expect.isTrue(Dynamic.isSubtypeOf(IntPred)); + Expect.isTrue(Dynamic.isSubtypeOf(DubPred)); + Expect.isTrue(Dynamic.isSubtypeOf(NumPredRef)); + Expect.isTrue(Dynamic.isSubtypeOf(IntPredRef)); + Expect.isTrue(Dynamic.isSubtypeOf(DubPredRef)); + Expect.isTrue(Dynamic.isSubtypeOf(NumGen)); + Expect.isTrue(Dynamic.isSubtypeOf(IntGen)); + Expect.isTrue(Dynamic.isSubtypeOf(DubGen)); + Expect.isTrue(Dynamic.isSubtypeOf(NumGenRef)); + Expect.isTrue(Dynamic.isSubtypeOf(IntGenRef)); + Expect.isTrue(Dynamic.isSubtypeOf(DubGenRef)); + Expect.isTrue(Dynamic.isSubtypeOf(TFromA)); + Expect.isTrue(Dynamic.isSubtypeOf(TFromB)); + Expect.isTrue(Dynamic.isSubtypeOf(TFromC)); + + TypeMirror Void = mirrors.voidType; + Expect.isTrue(Void.isSubtypeOf(Void)); + Expect.isFalse(Obj.isSubtypeOf(Void)); + Expect.isFalse(Super.isSubtypeOf(Void)); + Expect.isFalse(Sub1.isSubtypeOf(Void)); + Expect.isFalse(Sub2.isSubtypeOf(Void)); + Expect.isFalse(NumPred.isSubtypeOf(Void)); + Expect.isFalse(IntPred.isSubtypeOf(Void)); + Expect.isFalse(DubPred.isSubtypeOf(Void)); + Expect.isFalse(NumPredRef.isSubtypeOf(Void)); + Expect.isFalse(IntPredRef.isSubtypeOf(Void)); + Expect.isFalse(DubPredRef.isSubtypeOf(Void)); + Expect.isFalse(NumGen.isSubtypeOf(Void)); + Expect.isFalse(IntGen.isSubtypeOf(Void)); + Expect.isFalse(DubGen.isSubtypeOf(Void)); + Expect.isFalse(NumGenRef.isSubtypeOf(Void)); + Expect.isFalse(IntGenRef.isSubtypeOf(Void)); + Expect.isFalse(DubGenRef.isSubtypeOf(Void)); + Expect.isFalse(TFromA.isSubtypeOf(Void)); + Expect.isFalse(TFromB.isSubtypeOf(Void)); + Expect.isFalse(TFromC.isSubtypeOf(Void)); + Expect.isFalse(Void.isSubtypeOf(Obj)); + Expect.isFalse(Void.isSubtypeOf(Super)); + Expect.isFalse(Void.isSubtypeOf(Sub1)); + Expect.isFalse(Void.isSubtypeOf(Sub2)); + Expect.isFalse(Void.isSubtypeOf(NumPred)); + Expect.isFalse(Void.isSubtypeOf(IntPred)); + Expect.isFalse(Void.isSubtypeOf(DubPred)); + Expect.isFalse(Void.isSubtypeOf(NumPredRef)); + Expect.isFalse(Void.isSubtypeOf(IntPredRef)); + Expect.isFalse(Void.isSubtypeOf(DubPredRef)); + Expect.isFalse(Void.isSubtypeOf(NumGen)); + Expect.isFalse(Void.isSubtypeOf(IntGen)); + Expect.isFalse(Void.isSubtypeOf(DubGen)); + Expect.isFalse(Void.isSubtypeOf(NumGenRef)); + Expect.isFalse(Void.isSubtypeOf(IntGenRef)); + Expect.isFalse(Void.isSubtypeOf(DubGenRef)); + Expect.isFalse(Void.isSubtypeOf(TFromA)); + Expect.isFalse(Void.isSubtypeOf(TFromB)); + Expect.isFalse(Void.isSubtypeOf(TFromC)); + + Expect.isTrue(Dynamic.isSubtypeOf(Void)); + Expect.isTrue(Void.isSubtypeOf(Dynamic)); +} + +main() { + test(currentMirrorSystem()); +} diff --git a/tests/lib/mirrors/repeated_private_anon_mixin_app1.dart b/tests/lib/mirrors/repeated_private_anon_mixin_app1.dart new file mode 100644 index 00000000000..377cd51367b --- /dev/null +++ b/tests/lib/mirrors/repeated_private_anon_mixin_app1.dart @@ -0,0 +1,15 @@ +// Copyright (c) 2013, 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. + +library lib1; + +class _S {} + +class _M {} + +class _M2 {} + +class MA extends _S with _M {} + +class MA2 extends _S with _M, _M2 {} diff --git a/tests/lib/mirrors/repeated_private_anon_mixin_app2.dart b/tests/lib/mirrors/repeated_private_anon_mixin_app2.dart new file mode 100644 index 00000000000..36f9d8cacca --- /dev/null +++ b/tests/lib/mirrors/repeated_private_anon_mixin_app2.dart @@ -0,0 +1,15 @@ +// Copyright (c) 2013, 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. + +library lib2; + +class _S {} + +class _M {} + +class _M2 {} + +class MA extends _S with _M {} + +class MA2 extends _S with _M, _M2 {} diff --git a/tests/lib/mirrors/repeated_private_anon_mixin_app_test.dart b/tests/lib/mirrors/repeated_private_anon_mixin_app_test.dart new file mode 100644 index 00000000000..7a7a5adcaa6 --- /dev/null +++ b/tests/lib/mirrors/repeated_private_anon_mixin_app_test.dart @@ -0,0 +1,40 @@ +// Copyright (c) 2013, 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. + +library test.repeated_private_anon_mixin_app; + +// Regression test for symbol mangling. + +import 'dart:mirrors'; +import 'package:expect/expect.dart'; + +import 'repeated_private_anon_mixin_app1.dart' as lib1; +import 'repeated_private_anon_mixin_app2.dart' as lib2; + +testMA() { + Symbol name1 = reflectClass(lib1.MA).superclass.simpleName; + Symbol name2 = reflectClass(lib2.MA).superclass.simpleName; + + Expect.equals('lib._S with lib._M', MirrorSystem.getName(name1)); + Expect.equals('lib._S with lib._M', MirrorSystem.getName(name2)); + + Expect.notEquals(name1, name2); + Expect.notEquals(name2, name1); +} + +testMA2() { + Symbol name1 = reflectClass(lib1.MA2).superclass.simpleName; + Symbol name2 = reflectClass(lib2.MA2).superclass.simpleName; + + Expect.equals('lib._S with lib._M, lib._M2', MirrorSystem.getName(name1)); + Expect.equals('lib._S with lib._M, lib._M2', MirrorSystem.getName(name2)); + + Expect.notEquals(name1, name2); + Expect.notEquals(name2, name1); +} + +main() { + testMA(); + testMA2(); +} diff --git a/tests/lib/mirrors/return_type_test.dart b/tests/lib/mirrors/return_type_test.dart new file mode 100644 index 00000000000..65115bd2448 --- /dev/null +++ b/tests/lib/mirrors/return_type_test.dart @@ -0,0 +1,49 @@ +// Copyright (c) 2013, 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 of [MethodMirror.returnType]. +library test.return_type_test; + +import 'dart:mirrors'; + +import 'stringify.dart'; + +class B { + f() {} + int g() {} + List h() {} + B i() {} + + // TODO(ahe): Test this when dart2js handles parameterized types. + // List j() {} +} + +methodsOf(ClassMirror cm) { + var result = new Map(); + cm.declarations.forEach((k, v) { + if (v is MethodMirror && v.isRegularMethod) result[k] = v; + }); + return result; +} + +main() { + var methods = methodsOf(reflectClass(B)); + + expect( + '{f: Method(s(f) in s(B)), ' + 'g: Method(s(g) in s(B)), ' + 'h: Method(s(h) in s(B)), ' + 'i: Method(s(i) in s(B))}', + methods); + + var f = methods[#f]; + var g = methods[#g]; + var h = methods[#h]; + var i = methods[#i]; + + expect('Type(s(dynamic), top-level)', f.returnType); + expect('Class(s(int) in s(dart.core), top-level)', g.returnType); + expect('Class(s(List) in s(dart.core), top-level)', h.returnType); + expect('Class(s(B) in s(test.return_type_test), top-level)', i.returnType); +} diff --git a/tests/lib/mirrors/runtime_type_test.dart b/tests/lib/mirrors/runtime_type_test.dart new file mode 100644 index 00000000000..82c88b6a927 --- /dev/null +++ b/tests/lib/mirrors/runtime_type_test.dart @@ -0,0 +1,19 @@ +// Copyright (c) 2014, 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. + +library test.runtime_type_test; + +import 'dart:mirrors'; + +import 'package:expect/expect.dart'; + +class A {} + +class B { + get runtimeType => A; +} + +main() { + Expect.equals(reflect(new B()).type, reflectClass(B)); +} diff --git a/tests/lib/mirrors/set_field_with_final_inheritance_test.dart b/tests/lib/mirrors/set_field_with_final_inheritance_test.dart new file mode 100644 index 00000000000..42812279015 --- /dev/null +++ b/tests/lib/mirrors/set_field_with_final_inheritance_test.dart @@ -0,0 +1,112 @@ +// Copyright (c) 2013, 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. + +library test.set_field_with_final_inheritance; + +import 'dart:mirrors'; +import 'package:expect/expect.dart'; + +class S { + var sideEffect = 0; + + var mutableWithInheritedMutable = 1; + final mutableWithInheritedFinal = 2; + set mutableWithInheritedSetter(x) => sideEffect = 3; + + var finalWithInheritedMutable = 4; + final finalWithInheritedFinal = 5; + set finalWithInheritedSetter(x) => sideEffect = 6; + + var setterWithInheritedMutable = 7; + final setterWithInheritedFinal = 8; + set setterWithInheritedSetter(x) => sideEffect = 9; +} + +class C extends S { + var mutableWithInheritedMutable = 10; + var mutableWithInheritedFinal = 11; + var mutableWithInheritedSetter = 12; + + final finalWithInheritedMutable = 13; + final finalWithInheritedFinal = 14; + final finalWithInheritedSetter = 15; + + set setterWithInheritedMutable(x) => sideEffect = 16; + set setterWithInheritedFinal(x) => sideEffect = 17; + set setterWithInheritedSetter(x) => sideEffect = 18; + + get superMutableWithInheritedMutable => super.mutableWithInheritedMutable; + get superMutableWithInheritedFinal => super.mutableWithInheritedFinal; + + get superFinalWithInheritedMutable => super.finalWithInheritedMutable; + get superFinalWithInheritedFinal => super.finalWithInheritedFinal; + + get superSetterWithInheritedMutable => super.setterWithInheritedMutable; + get superSetterWithInheritedFinal => super.setterWithInheritedFinal; +} + +main() { + C c; + InstanceMirror im; + + c = new C(); + im = reflect(c); + Expect.equals(19, im.setField(#mutableWithInheritedMutable, 19).reflectee); + Expect.equals(19, c.mutableWithInheritedMutable); + Expect.equals(1, c.superMutableWithInheritedMutable); + Expect.equals(0, c.sideEffect); + + c = new C(); + im = reflect(c); + Expect.equals(20, im.setField(#mutableWithInheritedFinal, 20).reflectee); + Expect.equals(20, c.mutableWithInheritedFinal); + Expect.equals(2, c.superMutableWithInheritedFinal); + Expect.equals(0, c.sideEffect); + + c = new C(); + im = reflect(c); + Expect.equals(21, im.setField(#mutableWithInheritedSetter, 21).reflectee); + Expect.equals(21, c.mutableWithInheritedSetter); + Expect.equals(0, c.sideEffect); + + c = new C(); + im = reflect(c); + Expect.equals(22, im.setField(#finalWithInheritedMutable, 22).reflectee); + Expect.equals(13, c.finalWithInheritedMutable); + Expect.equals(22, c.superFinalWithInheritedMutable); + Expect.equals(0, c.sideEffect); + + c = new C(); + im = reflect(c); + Expect.throwsNoSuchMethodError( + () => im.setField(#finalWithInheritedFinal, 23)); + Expect.equals(14, c.finalWithInheritedFinal); + Expect.equals(5, c.superFinalWithInheritedFinal); + Expect.equals(0, c.sideEffect); + + c = new C(); + im = reflect(c); + Expect.equals(24, im.setField(#finalWithInheritedSetter, 24).reflectee); + Expect.equals(15, c.finalWithInheritedSetter); + Expect.equals(6, c.sideEffect); + + c = new C(); + im = reflect(c); + Expect.equals(25, im.setField(#setterWithInheritedMutable, 25).reflectee); + Expect.equals(7, c.setterWithInheritedMutable); + Expect.equals(7, c.superSetterWithInheritedMutable); + Expect.equals(16, c.sideEffect); + + c = new C(); + im = reflect(c); + Expect.equals(26, im.setField(#setterWithInheritedFinal, 26).reflectee); + Expect.equals(8, c.setterWithInheritedFinal); + Expect.equals(8, c.superSetterWithInheritedFinal); + Expect.equals(17, c.sideEffect); + + c = new C(); + im = reflect(c); + Expect.equals(27, im.setField(#setterWithInheritedSetter, 27).reflectee); + Expect.equals(18, c.sideEffect); +} diff --git a/tests/lib/mirrors/set_field_with_final_test.dart b/tests/lib/mirrors/set_field_with_final_test.dart new file mode 100644 index 00000000000..d2515fdde4a --- /dev/null +++ b/tests/lib/mirrors/set_field_with_final_test.dart @@ -0,0 +1,32 @@ +// Copyright (c) 2013, 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. + +library test.set_field_with_final; + +import 'dart:mirrors'; +import 'package:expect/expect.dart'; + +class C { + final instanceField = 1; + get instanceGetter => 2; + static final staticFinal = 3; + static get staticGetter => 4; +} + +final toplevelFinal = 5; +get toplevelGetter => 6; + +main() { + InstanceMirror im = reflect(new C()); + Expect.throwsNoSuchMethodError(() => im.setField(#instanceField, 7)); + Expect.throwsNoSuchMethodError(() => im.setField(#instanceGetter, 8)); + + ClassMirror cm = im.type; + Expect.throwsNoSuchMethodError(() => cm.setField(#staticFinal, 9)); + Expect.throwsNoSuchMethodError(() => cm.setField(#staticGetter, 10)); + + LibraryMirror lm = cm.owner as LibraryMirror; + Expect.throwsNoSuchMethodError(() => lm.setField(#toplevelFinal, 11)); + Expect.throwsNoSuchMethodError(() => lm.setField(#toplevelGetter, 12)); +} diff --git a/tests/lib/mirrors/spawn_function_root_library_test.dart b/tests/lib/mirrors/spawn_function_root_library_test.dart new file mode 100644 index 00000000000..f2d7f6c656c --- /dev/null +++ b/tests/lib/mirrors/spawn_function_root_library_test.dart @@ -0,0 +1,27 @@ +// Copyright (c) 2015, 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. + +library lib; + +import 'dart:mirrors'; +import 'dart:isolate'; +import 'package:expect/expect.dart'; + +child(SendPort port) { + LibraryMirror root = currentMirrorSystem().isolate.rootLibrary; + Expect.isNotNull(root); + port.send(root.uri.toString()); +} + +main() { + final port = new RawReceivePort(); + port.handler = (String childRootUri) { + LibraryMirror root = currentMirrorSystem().isolate.rootLibrary; + Expect.isNotNull(root); + Expect.equals(root.uri.toString(), childRootUri); + port.close(); + }; + + Isolate.spawn(child, port.sendPort); +} diff --git a/tests/lib/mirrors/static_const_field_test.dart b/tests/lib/mirrors/static_const_field_test.dart new file mode 100644 index 00000000000..cf8c283ffb2 --- /dev/null +++ b/tests/lib/mirrors/static_const_field_test.dart @@ -0,0 +1,17 @@ +// Copyright (c) 2013, 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 static const fields are accessible by reflection. +// Regression test for http://dartbug.com/23811. + +import "dart:mirrors"; +import "package:expect/expect.dart"; + +class A { + static const ONE = 1; +} + +main() { + Expect.equals(1, reflectClass(A).getField(#ONE).reflectee); +} diff --git a/tests/lib/mirrors/static_members_easier_test.dart b/tests/lib/mirrors/static_members_easier_test.dart new file mode 100644 index 00000000000..b050a3c5fc0 --- /dev/null +++ b/tests/lib/mirrors/static_members_easier_test.dart @@ -0,0 +1,31 @@ +// Copyright (c) 2013, 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. + +library test.static_members; + +import 'dart:mirrors'; +import 'package:expect/expect.dart'; + +import 'stringify.dart'; +import 'declarations_model_easier.dart' as declarations_model; + +selectKeys(map, predicate) { + return map.keys.where((key) => predicate(map[key])); +} + +main() { + ClassMirror cm = reflectClass(declarations_model.Class); + LibraryMirror lm = cm.owner as LibraryMirror; + + Expect.setEquals([ + #staticVariable, + const Symbol('staticVariable='), + #staticGetter, + const Symbol('staticSetter='), + #staticMethod, + ], selectKeys(cm.staticMembers, (dm) => true)); + + Expect.setEquals([#staticVariable, const Symbol('staticVariable=')], + selectKeys(cm.staticMembers, (dm) => dm.isSynthetic)); +} diff --git a/tests/lib/mirrors/static_members_test.dart b/tests/lib/mirrors/static_members_test.dart new file mode 100644 index 00000000000..f84bc5357e1 --- /dev/null +++ b/tests/lib/mirrors/static_members_test.dart @@ -0,0 +1,40 @@ +// Copyright (c) 2013, 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. + +library test.static_members; + +import 'dart:mirrors'; +import 'package:expect/expect.dart'; + +import 'stringify.dart'; +import 'declarations_model.dart' as declarations_model; + +selectKeys(map, predicate) { + return map.keys.where((key) => predicate(map[key])); +} + +main() { + ClassMirror cm = reflectClass(declarations_model.Class); + LibraryMirror lm = cm.owner as LibraryMirror; + + Expect.setEquals([ + #staticVariable, + const Symbol('staticVariable='), + #staticGetter, + const Symbol('staticSetter='), + #staticMethod, + MirrorSystem.getSymbol('_staticVariable', lm), + MirrorSystem.getSymbol('_staticVariable=', lm), + MirrorSystem.getSymbol('_staticGetter', lm), + MirrorSystem.getSymbol('_staticSetter=', lm), + MirrorSystem.getSymbol('_staticMethod', lm), + ], selectKeys(cm.staticMembers, (dm) => true)); + + Expect.setEquals([ + #staticVariable, + const Symbol('staticVariable='), + MirrorSystem.getSymbol('_staticVariable', lm), + MirrorSystem.getSymbol('_staticVariable=', lm) + ], selectKeys(cm.staticMembers, (dm) => dm.isSynthetic)); +} diff --git a/tests/lib/mirrors/static_metatarget_test.dart b/tests/lib/mirrors/static_metatarget_test.dart new file mode 100644 index 00000000000..8024db8b280 --- /dev/null +++ b/tests/lib/mirrors/static_metatarget_test.dart @@ -0,0 +1,36 @@ +// Copyright (c) 2013, 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. + +// Regression test for the combined use of metatargets and static fields with +// annotations. + +import 'dart:mirrors'; + +class A { + @reflectable + var reflectableField = 0; //# 01: ok + + @UsedOnlyAsMetadata() + var unreflectableField = 1; //# 02: ok + + @reflectable + static var reflectableStaticField = 2; //# 03: ok + + @UsedOnlyAsMetadata() + static var unreflectableStaticField = 3; +} + +class Reflectable { + const Reflectable(); +} + +const Reflectable reflectable = const Reflectable(); + +class UsedOnlyAsMetadata { + const UsedOnlyAsMetadata(); +} + +void main() { + print(new A()); +} diff --git a/tests/lib/mirrors/static_test.dart b/tests/lib/mirrors/static_test.dart new file mode 100644 index 00000000000..6a2e4feeb92 --- /dev/null +++ b/tests/lib/mirrors/static_test.dart @@ -0,0 +1,30 @@ +// Copyright (c) 2013, 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 static members. + +library lib; + +import 'dart:mirrors'; + +import 'stringify.dart'; + +class Foo { + static String bar = '...'; + String aux = ''; + static foo() {} + baz() {} +} + +void main() { + expect('Variable(s(aux) in s(Foo))', + reflectClass(Foo).declarations[new Symbol('aux')]); + expect('Method(s(baz) in s(Foo))', + reflectClass(Foo).declarations[new Symbol('baz')]); + expect('', reflectClass(Foo).declarations[new Symbol('aux=')]); + expect('Method(s(foo) in s(Foo), static)', + reflectClass(Foo).declarations[new Symbol('foo')]); + expect('Variable(s(bar) in s(Foo), static)', + reflectClass(Foo).declarations[new Symbol('bar')]); +} diff --git a/tests/lib/mirrors/stringify.dart b/tests/lib/mirrors/stringify.dart new file mode 100644 index 00000000000..954067ccca9 --- /dev/null +++ b/tests/lib/mirrors/stringify.dart @@ -0,0 +1,190 @@ +// Copyright (c) 2013, 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. + +/// Helper methods for converting a [Mirror] to a [String]. +library test.stringify; + +import 'dart:mirrors'; + +import 'package:expect/expect.dart'; + +String name(DeclarationMirror mirror) { + return (mirror == null) ? '' : stringify(mirror.simpleName); +} + +String stringifyMap(Map map) { + var buffer = new StringBuffer(); + bool first = true; + var names = map.keys.map((s) => MirrorSystem.getName(s)).toList()..sort(); + for (String key in names) { + if (!first) buffer.write(', '); + first = false; + buffer.write(key); + buffer.write(': '); + buffer.write(stringify(map[new Symbol(key)])); + } + return '{$buffer}'; +} + +String stringifyIterable(Iterable list) { + var buffer = new StringBuffer(); + bool first = true; + for (String value in list.map(stringify)) { + if (!first) buffer.write(', '); + first = false; + buffer.write(value); + } + return '[$buffer]'; +} + +String stringifyInstance(InstanceMirror instance) { + var buffer = new StringBuffer(); + if (instance.hasReflectee) { + buffer.write('value = ${stringify(instance.reflectee)}'); + } + return 'Instance(${buffer})'; +} + +String stringifySymbol(Symbol symbol) => 's(${MirrorSystem.getName(symbol)})'; + +void writeDeclarationOn(DeclarationMirror mirror, StringBuffer buffer) { + buffer.write(stringify(mirror.simpleName)); + if (mirror.owner != null) { + buffer.write(' in '); + buffer.write(name(mirror.owner)); + } + if (mirror.isPrivate) buffer.write(', private'); + if (mirror.isTopLevel) buffer.write(', top-level'); +} + +void writeVariableOn(VariableMirror variable, StringBuffer buffer) { + writeDeclarationOn(variable, buffer); + if (variable.isStatic) buffer.write(', static'); + if (variable.isFinal) buffer.write(', final'); +} + +String stringifyVariable(VariableMirror variable) { + var buffer = new StringBuffer(); + writeVariableOn(variable, buffer); + return 'Variable($buffer)'; +} + +String stringifyParameter(ParameterMirror parameter) { + var buffer = new StringBuffer(); + writeVariableOn(parameter, buffer); + if (parameter.isOptional) buffer.write(', optional'); + if (parameter.isNamed) buffer.write(', named'); + // TODO(6490): dart2js always returns false for hasDefaultValue. + if (parameter.hasDefaultValue) { + buffer.write(', value = ${stringify(parameter.defaultValue)}'); + } + // TODO(ahe): Move to writeVariableOn. + buffer.write(', type = ${stringify(parameter.type)}'); + return 'Parameter($buffer)'; +} + +String stringifyTypeVariable(TypeVariableMirror typeVariable) { + var buffer = new StringBuffer(); + writeDeclarationOn(typeVariable, buffer); + buffer.write(', upperBound = ${stringify(typeVariable.upperBound)}'); + return 'TypeVariable($buffer)'; +} + +String stringifyType(TypeMirror type) { + var buffer = new StringBuffer(); + writeDeclarationOn(type, buffer); + return 'Type($buffer)'; +} + +String stringifyClass(ClassMirror cls) { + var buffer = new StringBuffer(); + writeDeclarationOn(cls, buffer); + return 'Class($buffer)'; +} + +String stringifyMethod(MethodMirror method) { + var buffer = new StringBuffer(); + writeDeclarationOn(method, buffer); + if (method.isAbstract) buffer.write(', abstract'); + if (method.isSynthetic) buffer.write(', synthetic'); + if (method.isStatic) buffer.write(', static'); + if (method.isGetter) buffer.write(', getter'); + if (method.isSetter) buffer.write(', setter'); + if (method.isConstructor) buffer.write(', constructor'); + return 'Method($buffer)'; +} + +String stringifyDependencies(LibraryMirror l) { + n(s) => s is Symbol ? MirrorSystem.getName(s) : s; + int compareDep(a, b) { + if (a.targetLibrary == b.targetLibrary) { + if ((a.prefix != null) && (b.prefix != null)) { + return n(a.prefix).compareTo(n(b.prefix)); + } + return a.prefix == null ? 1 : -1; + } + return n(a.targetLibrary.simpleName) + .compareTo(n(b.targetLibrary.simpleName)); + } + + int compareCom(a, b) => n(a.identifier).compareTo(n(b.identifier)); + int compareFirst(a, b) => a[0].compareTo(b[0]); + sortBy(c, p) => new List.from(c)..sort(p); + + var buffer = new StringBuffer(); + sortBy(l.libraryDependencies, compareDep).forEach((dep) { + if (dep.isImport) buffer.write('import '); + if (dep.isExport) buffer.write('export '); + buffer.write(n(dep.targetLibrary.simpleName)); + if (dep.isDeferred) buffer.write(' deferred'); + if (dep.prefix != null) buffer.write(' as ${n(dep.prefix)}'); + buffer.write('\n'); + + List flattenedCombinators = new List(); + dep.combinators.forEach((com) { + com.identifiers.forEach((ident) { + flattenedCombinators.add([n(ident), com.isShow, com.isHide]); + }); + }); + sortBy(flattenedCombinators, compareFirst).forEach((triple) { + buffer.write(' '); + if (triple[1]) buffer.write('show '); + if (triple[2]) buffer.write('hide '); + buffer.write(triple[0]); + buffer.write('\n'); + }); + }); + return buffer.toString(); +} + +String stringify(value) { + if (value == null) return ''; + if (value is Map) return stringifyMap(value); + if (value is Iterable) return stringifyIterable(value); + if (value is InstanceMirror) return stringifyInstance(value); + if (value is ParameterMirror) return stringifyParameter(value); + if (value is VariableMirror) return stringifyVariable(value); + if (value is MethodMirror) return stringifyMethod(value); + if (value is num) return value.toString(); + if (value is String) return value; + if (value is Symbol) return stringifySymbol(value); + if (value is ClassMirror) return stringifyClass(value); + if (value is TypeVariableMirror) return stringifyTypeVariable(value); + if (value is TypeMirror) return stringifyType(value); + throw 'Unexpected value: $value'; +} + +void expect(expected, actual, [String reason = ""]) { + Expect.stringEquals(expected, stringify(actual), reason); +} + +int compareSymbols(Symbol a, Symbol b) { + return MirrorSystem.getName(a).compareTo(MirrorSystem.getName(b)); +} + +Iterable simpleNames(Iterable i) => + i.map((e) => (e as DeclarationMirror).simpleName); + +List sort(Iterable symbols) => + symbols.toList()..sort(compareSymbols); diff --git a/tests/lib/mirrors/superclass2_test.dart b/tests/lib/mirrors/superclass2_test.dart new file mode 100644 index 00000000000..8a9ec391429 --- /dev/null +++ b/tests/lib/mirrors/superclass2_test.dart @@ -0,0 +1,28 @@ +// Copyright (c) 2013, 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. + +library test.superclass; + +import 'dart:mirrors'; +import 'package:expect/expect.dart'; + +checkSuperclassChain(ClassMirror cm) { + ClassMirror last; + do { + last = cm; + cm = cm.superclass; + } while (cm != null); + Expect.equals(reflectClass(Object), last); +} + +main() { + checkSuperclassChain(reflect(null).type); + checkSuperclassChain(reflect([]).type); + checkSuperclassChain(reflect([]).type); + checkSuperclassChain(reflect(0).type); + checkSuperclassChain(reflect(1.5).type); + checkSuperclassChain(reflect("str").type); + checkSuperclassChain(reflect(true).type); + checkSuperclassChain(reflect(false).type); +} diff --git a/tests/lib/mirrors/superclass_test.dart b/tests/lib/mirrors/superclass_test.dart new file mode 100644 index 00000000000..ad571beaa53 --- /dev/null +++ b/tests/lib/mirrors/superclass_test.dart @@ -0,0 +1,20 @@ +// Copyright (c) 2013, 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. + +library test.superclass; + +import 'dart:mirrors'; +import 'package:expect/expect.dart'; + +class MyClass {} + +main() { + var cls = reflectClass(MyClass); + Expect.isNotNull(cls, 'Failed to reflect on MyClass.'); + var superclass = cls.superclass; + Expect.isNotNull(superclass, 'Failed to obtain superclass of MyClass.'); + Expect.equals( + reflectClass(Object), superclass, 'Superclass of MyClass is not Object.'); + Expect.isNull(superclass.superclass, 'Superclass of Object is not null.'); +} diff --git a/tests/lib/mirrors/symbol_validation_test.dart b/tests/lib/mirrors/symbol_validation_test.dart new file mode 100644 index 00000000000..11a7d9422db --- /dev/null +++ b/tests/lib/mirrors/symbol_validation_test.dart @@ -0,0 +1,168 @@ +// Copyright (c) 2013, 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. + +library symbol_validation_test; + +import 'dart:mirrors'; +import 'package:expect/expect.dart'; + +validSymbol(String string) { + Expect.equals(string, MirrorSystem.getName(new Symbol(string)), + 'Valid symbol "$string" should be invertable'); + Expect.equals(string, MirrorSystem.getName(MirrorSystem.getSymbol(string)), + 'Valid symbol "$string" should be invertable'); +} + +invalidSymbol(String string) { + Expect.throwsArgumentError(() => new Symbol(string), + 'Invalid symbol "$string" should be rejected'); + Expect.throwsArgumentError(() => MirrorSystem.getSymbol(string), + 'Invalid symbol "$string" should be rejected'); +} + +validPrivateSymbol(String string) { + ClosureMirror closure = reflect(main) as ClosureMirror; + LibraryMirror library = closure.function.owner as LibraryMirror; + Expect.equals( + string, + MirrorSystem.getName(MirrorSystem.getSymbol(string, library)), + 'Valid private symbol "$string" should be invertable'); +} + +main() { + // Operators that can be declared as class member operators. + // These are all valid as symbols. + var operators = [ + '%', + '&', + '*', + '+', + '-', + '/', + '<', + '<<', + '<=', + '==', + '>', + '>=', + '>>', + '[]', + '[]=', + '^', + 'unary-', + '|', + '~', + '~/' + ]; + operators.expand((op) => [op, "x.$op"]).forEach(validSymbol); + operators + .expand((op) => [".$op", "$op.x", "x$op", "_x.$op"]) + .forEach(invalidSymbol); + operators + .expand((op) => operators.contains("$op=") ? [] : ["x.$op=", "$op="]) + .forEach(invalidSymbol); + + var simpleSymbols = [ + 'foo', + 'bar_', + 'baz.quz', + 'fisk1', + 'hest2fisk', + 'a.b.c.d.e', + r'$', + r'foo$', + r'bar$bar', + r'$.$', + r'x6$_', + r'$6_', + r'x.$$6_', + 'x_', + 'x_.x_', + 'unary', + 'x.unary' + ]; + simpleSymbols.expand((s) => [s, "s="]).forEach(validSymbol); + + var nonSymbols = [ + // Non-identifiers. + '6', '0foo', ',', 'S with M', '_invalid&private', "#foo", " foo", "foo ", + // Operator variants. + '+=', '()', 'operator+', 'unary+', '>>>', "&&", "||", "!", "@", "#", "[", + // Private symbols. + '_', '_x', 'x._y', 'x._', + // Empty parts of "qualified" symbols. + '.', 'x.', '.x', 'x..y' + ]; + nonSymbols.forEach(invalidSymbol); + + // Reserved words are not valid identifiers and therefore not valid symbols. + var reservedWords = [ + "assert", + "break", + "case", + "catch", + "class", + "const", + "continue", + "default", + "do", + "else", + "enum", + "extends", + "false", + "final", + "finally", + "for", + "if", + "in", + "is", + "new", + "null", + "rethrow", + "return", + "super", + "switch", + "this", + "throw", + "true", + "try", + "var", + "void", + "while", + "with" + ]; + reservedWords + .expand((w) => [w, "$w=", "x.$w", "$w.x", "x.$w.x"]) + .forEach(invalidSymbol); + reservedWords + .expand((w) => ["${w}_", "${w}\$", "${w}q"]) + .forEach(validSymbol); + + // Built-in identifiers are valid identifiers that are restricted from being + // used in some cases, but they are all valid symbols. + var builtInIdentifiers = [ + "abstract", + "as", + "dynamic", + "export", + "external", + "factory", + "get", + "implements", + "import", + "library", + "operator", + "part", + "set", + "static", + "typedef" + ]; + builtInIdentifiers + .expand((w) => [w, "$w=", "x.$w", "$w.x", "x.$w.x", "$w=", "x.$w="]) + .forEach(validSymbol); + + var privateSymbols = ['_', '_x', 'x._y', 'x._', 'x.y._', 'x._.y', '_true']; + privateSymbols.forEach(invalidSymbol); + privateSymbols.forEach(validPrivateSymbol); // //# 01: ok +} diff --git a/tests/lib/mirrors/syntax_error_test.dart b/tests/lib/mirrors/syntax_error_test.dart new file mode 100644 index 00000000000..227e7917740 --- /dev/null +++ b/tests/lib/mirrors/syntax_error_test.dart @@ -0,0 +1,28 @@ +// Copyright (c) 2013, 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. + +// Regression test for Issue 15744 +// Also, tests that syntax errors in reflected classes are reported correctly. + +library lib; + +import 'dart:mirrors'; + +class MD { + final String name; + const MD({this.name}); +} + +@MD(name: 'A') +class A {} + +@MD(name: 'B') +class B { + static x = { 0: 0; }; // //# 01: compile-time error +} + +main() { + reflectClass(A).metadata; + reflectClass(B).newInstance(Symbol.empty, []); +} diff --git a/tests/lib/mirrors/synthetic_accessor_properties_test.dart b/tests/lib/mirrors/synthetic_accessor_properties_test.dart new file mode 100644 index 00000000000..9d1d6e3ce44 --- /dev/null +++ b/tests/lib/mirrors/synthetic_accessor_properties_test.dart @@ -0,0 +1,72 @@ +// Copyright (c) 2013, 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. + +library test.synthetic_accessor_properties; + +import 'dart:mirrors'; +import 'package:expect/expect.dart'; + +import 'stringify.dart'; + +class C { + String instanceField = "1"; + final num finalInstanceField = 2; + + static bool staticField = false; + static final int finalStaticField = 4; +} + +String topLevelField = "5"; +final double finalTopLevelField = 6.0; + +main() { + ClassMirror cm = reflectClass(C); + LibraryMirror lm = cm.owner as LibraryMirror; + MethodMirror mm; + ParameterMirror pm; + + mm = cm.instanceMembers[#instanceField] as MethodMirror; + expect('Method(s(instanceField) in s(C), synthetic, getter)', mm); + Expect.equals(reflectClass(String), mm.returnType); + Expect.listEquals([], mm.parameters); + + mm = cm.instanceMembers[const Symbol('instanceField=')] as MethodMirror; + expect('Method(s(instanceField=) in s(C), synthetic, setter)', mm); + Expect.equals(reflectClass(String), mm.returnType); + pm = mm.parameters.single; + expect( + 'Parameter(s(instanceField) in s(instanceField=), final,' + ' type = Class(s(String) in s(dart.core), top-level))', + pm); + + mm = cm.instanceMembers[#finalInstanceField] as MethodMirror; + expect('Method(s(finalInstanceField) in s(C), synthetic, getter)', mm); + Expect.equals(reflectClass(num), mm.returnType); + Expect.listEquals([], mm.parameters); + + mm = cm.instanceMembers[const Symbol('finalInstanceField=')] as MethodMirror; + Expect.isNull(mm); + + mm = cm.staticMembers[#staticField] as MethodMirror; + expect('Method(s(staticField) in s(C), synthetic, static, getter)', mm); + Expect.equals(reflectClass(bool), mm.returnType); + Expect.listEquals([], mm.parameters); + + mm = cm.staticMembers[const Symbol('staticField=')] as MethodMirror; + expect('Method(s(staticField=) in s(C), synthetic, static, setter)', mm); + Expect.equals(reflectClass(bool), mm.returnType); + pm = mm.parameters.single; + expect( + 'Parameter(s(staticField) in s(staticField=), final,' + ' type = Class(s(bool) in s(dart.core), top-level))', + pm); + + mm = cm.staticMembers[#finalStaticField] as MethodMirror; + expect('Method(s(finalStaticField) in s(C), synthetic, static, getter)', mm); + Expect.equals(reflectClass(int), mm.returnType); + Expect.listEquals([], mm.parameters); + + mm = cm.staticMembers[const Symbol('finalStaticField=')] as MethodMirror; + Expect.isNull(mm); +} diff --git a/tests/lib/mirrors/to_string_test.dart b/tests/lib/mirrors/to_string_test.dart new file mode 100644 index 00000000000..23a04990f6c --- /dev/null +++ b/tests/lib/mirrors/to_string_test.dart @@ -0,0 +1,30 @@ +// Copyright (c) 2013, 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. + +library test.to_string_test; + +import 'dart:mirrors'; + +import 'package:expect/expect.dart'; + +expect(expected, actual) => Expect.stringEquals(expected, '$actual'); + +class Foo { + var field; + method() {} +} + +main() { + var mirrors = currentMirrorSystem(); + expect("TypeMirror on 'dynamic'", mirrors.dynamicType); + expect("TypeMirror on 'void'", mirrors.voidType); + expect("LibraryMirror on 'test.to_string_test'", + mirrors.findLibrary(#test.to_string_test)); + expect("InstanceMirror on 1", reflect(1)); + expect("ClassMirror on 'Foo'", reflectClass(Foo)); + expect("VariableMirror on 'field'", reflectClass(Foo).declarations[#field]); + expect("MethodMirror on 'method'", reflectClass(Foo).declarations[#method]); + String s = reflect(main).toString(); + Expect.isTrue(s.startsWith("ClosureMirror on '"), s); +} diff --git a/tests/lib/mirrors/top_level_accessors_test.dart b/tests/lib/mirrors/top_level_accessors_test.dart new file mode 100644 index 00000000000..269153e6857 --- /dev/null +++ b/tests/lib/mirrors/top_level_accessors_test.dart @@ -0,0 +1,28 @@ +// Copyright (c) 2012, 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. + +library test.top_level_accessors_test; + +import 'dart:mirrors'; + +import 'package:expect/expect.dart'; + +var field; + +get accessor => field; + +set accessor(value) { + field = value; + return 'fisk'; //# 01: compile-time error +} + +main() { + LibraryMirror library = + currentMirrorSystem().findLibrary(#test.top_level_accessors_test); + field = 42; + Expect.equals(42, library.getField(#accessor).reflectee); + Expect.equals(87, library.setField(#accessor, 87).reflectee); + Expect.equals(87, field); + Expect.equals(87, library.getField(#accessor).reflectee); +} diff --git a/tests/lib/mirrors/type_argument_is_type_variable_test.dart b/tests/lib/mirrors/type_argument_is_type_variable_test.dart new file mode 100644 index 00000000000..e9159443e7b --- /dev/null +++ b/tests/lib/mirrors/type_argument_is_type_variable_test.dart @@ -0,0 +1,54 @@ +// Copyright (c) 2013, 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. + +library test.type_argument_is_type_variable; + +import 'dart:mirrors'; + +import 'package:expect/expect.dart'; + +import 'generics_helper.dart'; + +class SuperSuper {} + +class Super extends SuperSuper {} + +class Generic extends Super {} + +main() { + // Declarations. + ClassMirror generic = reflectClass(Generic); + ClassMirror superOfGeneric = generic.superclass; + ClassMirror superOfSuperOfGeneric = superOfGeneric.superclass; + + TypeVariableMirror gFromGeneric = generic.typeVariables.single; + TypeVariableMirror sFromSuper = superOfGeneric.typeVariables.single; + TypeVariableMirror ssFromSuperSuper = + superOfSuperOfGeneric.typeVariables.single; + + Expect.equals(#G, gFromGeneric.simpleName); + Expect.equals(#S, sFromSuper.simpleName); + Expect.equals(#SS, ssFromSuperSuper.simpleName); + + typeParameters(generic, [#G]); + typeParameters(superOfGeneric, [#S]); + typeParameters(superOfSuperOfGeneric, [#SS]); + + typeArguments(generic, []); + typeArguments(superOfGeneric, [gFromGeneric]); + typeArguments(superOfSuperOfGeneric, [gFromGeneric]); + + // Instantiations. + ClassMirror genericWithInt = reflect(new Generic()).type; + ClassMirror superOfGenericWithInt = genericWithInt.superclass; + ClassMirror superOfSuperOfGenericWithInt = superOfGenericWithInt.superclass; + + typeParameters(genericWithInt, [#G]); + typeParameters(superOfGenericWithInt, [#S]); + typeParameters(superOfSuperOfGenericWithInt, [#SS]); + + typeArguments(genericWithInt, [reflectClass(int)]); + typeArguments(superOfGenericWithInt, [reflectClass(int)]); + typeArguments(superOfSuperOfGenericWithInt, [reflectClass(int)]); +} diff --git a/tests/lib/mirrors/type_mirror_for_type_test.dart b/tests/lib/mirrors/type_mirror_for_type_test.dart new file mode 100644 index 00000000000..92e101fe857 --- /dev/null +++ b/tests/lib/mirrors/type_mirror_for_type_test.dart @@ -0,0 +1,33 @@ +// Copyright (c) 2014, 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. + +// Regression test for the dart2js implementation of runtime types. + +library test.type_mirror_for_type; + +import 'package:expect/expect.dart'; + +import 'dart:mirrors'; + +class C {} + +class X { + Type foo() {} +} + +main() { + // Make sure that we need a type test against the runtime representation of + // [Type]. + var a = (new DateTime.now().millisecondsSinceEpoch != 42) + ? new C() + : new C(); + print(a is C); + + var typeMirror = reflectType(X) as ClassMirror; + var declarationMirror = typeMirror.declarations[#foo] as MethodMirror; + // Test that the runtime type implementation does not confuse the runtime type + // representation of [Type] with an actual value of type [Type] when analyzing + // the return type of [foo]. + Expect.equals(reflectType(Type), declarationMirror.returnType); +} diff --git a/tests/lib/mirrors/type_variable_is_static_test.dart b/tests/lib/mirrors/type_variable_is_static_test.dart new file mode 100644 index 00000000000..ff7bfa54679 --- /dev/null +++ b/tests/lib/mirrors/type_variable_is_static_test.dart @@ -0,0 +1,18 @@ +// Copyright (c) 2014, 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. + +library test.type_variable_owner; + +import "dart:mirrors"; + +import "package:expect/expect.dart"; + +class C {} + +typedef bool Predicate(T t); + +main() { + Expect.isFalse(reflectType(C).typeVariables.single.isStatic); + Expect.isFalse(reflectType(Predicate).typeVariables.single.isStatic); +} diff --git a/tests/lib/mirrors/type_variable_owner_test.dart b/tests/lib/mirrors/type_variable_owner_test.dart new file mode 100644 index 00000000000..8dec68181a8 --- /dev/null +++ b/tests/lib/mirrors/type_variable_owner_test.dart @@ -0,0 +1,55 @@ +// Copyright (c) 2013, 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. + +// Owner of a type variable should be the declaration of the generic class or +// typedef, not an instantiation. + +library test.type_variable_owner; + +import "dart:mirrors"; + +import "package:expect/expect.dart"; + +class A {} + +class B extends A {} + +testTypeVariableOfClass() { + ClassMirror aDecl = reflectClass(A); + ClassMirror bDecl = reflectClass(B); + ClassMirror aOfInt = reflect(new A()).type; + ClassMirror aOfR = bDecl.superclass; + ClassMirror bOfString = reflect(new B()).type; + ClassMirror aOfString = bOfString.superclass; + + Expect.equals(aDecl, aDecl.typeVariables[0].owner); + Expect.equals(aDecl, aOfInt.typeVariables[0].owner); + Expect.equals(aDecl, aOfR.typeVariables[0].owner); + Expect.equals(aDecl, aOfString.typeVariables[0].owner); + + Expect.equals(bDecl, bDecl.typeVariables[0].owner); + Expect.equals(bDecl, bOfString.typeVariables[0].owner); +} + +typedef bool Predicate(T t); +Predicate somePredicateOfList; + +testTypeVariableOfTypedef() { + LibraryMirror thisLibrary = + currentMirrorSystem().findLibrary(#test.type_variable_owner); + + TypedefMirror predicateOfDynamic = reflectType(Predicate) as TypedefMirror; + TypedefMirror predicateOfList = + (thisLibrary.declarations[#somePredicateOfList] as VariableMirror).type as TypedefMirror; + TypedefMirror predicateDecl = predicateOfList.originalDeclaration as TypedefMirror; + + Expect.equals(predicateDecl, predicateOfDynamic.typeVariables[0].owner); + Expect.equals(predicateDecl, predicateOfList.typeVariables[0].owner); + Expect.equals(predicateDecl, predicateDecl.typeVariables[0].owner); +} + +main() { + testTypeVariableOfClass(); + testTypeVariableOfTypedef(); // //# 01: ok +} diff --git a/tests/lib/mirrors/typearguments_mirror_test.dart b/tests/lib/mirrors/typearguments_mirror_test.dart new file mode 100644 index 00000000000..a5474d52b65 --- /dev/null +++ b/tests/lib/mirrors/typearguments_mirror_test.dart @@ -0,0 +1,74 @@ +// Copyright (c) 2013, 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. + +library lib; + +import 'package:expect/expect.dart'; +import 'stringify.dart'; +import 'dart:mirrors'; + +class Foo {} + +class Bar {} + +main() { + var cm = reflectClass(Foo); + var cm1 = reflect((new Foo())).type; + + Expect.notEquals(cm, cm1); + Expect.isFalse(cm1.isOriginalDeclaration); + Expect.isTrue(cm.isOriginalDeclaration); + + Expect.equals(cm, cm1.originalDeclaration); + + Expect.equals(cm, reflectClass(Foo)); + Expect.equals(cm, reflectClass((new Foo().runtimeType))); + Expect.equals(cm1, reflect(new Foo()).type); + + expect('[]', cm.typeArguments); + expect('[Class(s(String) in s(dart.core), top-level)]', cm1.typeArguments); + + cm = reflect(new Bar()).type; + cm1 = reflect(new Bar>()).type; + + var cm2 = reflect(new Bar, Set>()).type; + var cm3 = reflect(new Bar, Set>()).type; + + expect( + '[Class(s(List) in s(dart.core), top-level),' + ' Class(s(Set) in s(dart.core), top-level)]', + cm.typeArguments); + expect( + '[Class(s(List) in s(dart.core), top-level),' + ' Class(s(Set) in s(dart.core), top-level)]', + cm1.typeArguments); + expect( + '[Class(s(List) in s(dart.core), top-level),' + ' Class(s(Set) in s(dart.core), top-level)]', + cm2.typeArguments); + expect( + '[Class(s(List) in s(dart.core), top-level),' + ' Class(s(Set) in s(dart.core), top-level)]', + cm3.typeArguments); + + expect('[Class(s(String) in s(dart.core), top-level)]', + cm1.typeArguments[1].typeArguments); + expect('[Class(s(String) in s(dart.core), top-level)]', + cm2.typeArguments[0].typeArguments); + expect('[Class(s(String) in s(dart.core), top-level)]', + cm3.typeArguments[0].typeArguments); + expect('[Class(s(String) in s(dart.core), top-level)]', + cm3.typeArguments[1].typeArguments); + + var cm4 = reflect(new Bar, String>()).type; + + expect( + '[Class(s(Bar) in s(lib), top-level),' + ' Class(s(String) in s(dart.core), top-level)]', + cm4.typeArguments); + expect( + '[Class(s(List) in s(dart.core), top-level), ' + 'Class(s(Set) in s(dart.core), top-level)]', + cm4.typeArguments[0].typeArguments); +} diff --git a/tests/lib/mirrors/typedef_deferred_library_test.dart b/tests/lib/mirrors/typedef_deferred_library_test.dart new file mode 100644 index 00000000000..13631887a16 --- /dev/null +++ b/tests/lib/mirrors/typedef_deferred_library_test.dart @@ -0,0 +1,21 @@ +// Copyright (c) 2015, 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. + +library foo; + +import 'dart:mirrors'; +import 'typedef_library.dart' deferred as def; + +import 'package:async_helper/async_helper.dart'; +import 'package:expect/expect.dart'; + +main() { + asyncStart(); + def.loadLibrary().then((_) { + var barLibrary = currentMirrorSystem().findLibrary(new Symbol("bar")); + var gTypedef = barLibrary.declarations[new Symbol("G")]; + Expect.equals("G", MirrorSystem.getName(gTypedef.simpleName)); + asyncEnd(); + }); +} diff --git a/tests/lib/mirrors/typedef_in_signature_test.dart b/tests/lib/mirrors/typedef_in_signature_test.dart new file mode 100644 index 00000000000..869575006d3 --- /dev/null +++ b/tests/lib/mirrors/typedef_in_signature_test.dart @@ -0,0 +1,30 @@ +// Copyright (c) 2014, 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. + +library test.typedef_in_signature_test; + +import 'dart:mirrors'; + +import "package:expect/expect.dart"; + +typedef int foo(); +typedef String foo2(); +typedef foo foo3(foo2 x); + +foo2 bar(foo x) => throw "does-not-return"; // + +foo3 gee(int x, foo3 tt) => throw "does-not-return"; // + +main() { + var lm = currentMirrorSystem().findLibrary(#test.typedef_in_signature_test); + var mm = lm.declarations[#bar] as MethodMirror; + Expect.equals(reflectType(foo2), mm.returnType); + Expect.equals(reflectType(foo), mm.parameters[0].type); + mm = lm.declarations[#gee] as MethodMirror; + Expect.equals(reflectType(int), mm.parameters[0].type); + Expect.equals(reflectType(foo3), mm.returnType); + var ftm = (mm.returnType as TypedefMirror).referent; + Expect.equals(reflectType(foo), ftm.returnType); + Expect.equals(reflectType(foo2), ftm.parameters[0].type); +} diff --git a/tests/lib/mirrors/typedef_library.dart b/tests/lib/mirrors/typedef_library.dart new file mode 100644 index 00000000000..fcb3231612c --- /dev/null +++ b/tests/lib/mirrors/typedef_library.dart @@ -0,0 +1,7 @@ +// Copyright (c) 2015, 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. + +library bar; + +typedef G(); diff --git a/tests/lib/mirrors/typedef_library_test.dart b/tests/lib/mirrors/typedef_library_test.dart new file mode 100644 index 00000000000..b76878343eb --- /dev/null +++ b/tests/lib/mirrors/typedef_library_test.dart @@ -0,0 +1,16 @@ +// Copyright (c) 2015, 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. + +library foo; + +import 'dart:mirrors'; +import 'typedef_library.dart'; + +import 'package:expect/expect.dart'; + +main() { + var barLibrary = currentMirrorSystem().findLibrary(new Symbol("bar")); + var gTypedef = barLibrary.declarations[new Symbol("G")]; + Expect.equals("G", MirrorSystem.getName(gTypedef.simpleName)); +} diff --git a/tests/lib/mirrors/typedef_metadata_test.dart b/tests/lib/mirrors/typedef_metadata_test.dart new file mode 100644 index 00000000000..7b5e09872d5 --- /dev/null +++ b/tests/lib/mirrors/typedef_metadata_test.dart @@ -0,0 +1,26 @@ +// Copyright (c) 2013, 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. + +@string +@symbol +library test.typedef_metadata_test; + +import 'dart:mirrors'; + +import 'metadata_test.dart'; + +class S {} + +class M {} + +@symbol +class MA = S with M; + +@string +typedef bool Predicate(Object o); + +main() { + checkMetadata(reflectType(MA), [symbol]); + checkMetadata(reflectType(Predicate), [string]); +} diff --git a/tests/lib/mirrors/typedef_reflected_type_test.dart b/tests/lib/mirrors/typedef_reflected_type_test.dart new file mode 100644 index 00000000000..7b017f5e25c --- /dev/null +++ b/tests/lib/mirrors/typedef_reflected_type_test.dart @@ -0,0 +1,28 @@ +// Copyright (c) 2014, 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. + +library test; + +import 'package:expect/expect.dart'; + +import 'dart:mirrors'; + +typedef int Foo(String x); +typedef int Bar(); + +class C { + Bar fun(Foo x) => null; +} + +main() { + var m = reflectClass(C).declarations[#fun] as MethodMirror; + + Expect.equals(Bar, m.returnType.reflectedType); + Expect.equals("Foo", m.parameters[0].type.reflectedType.toString()); // //# 01: ok + Expect.equals(int, m.parameters[0].type.typeArguments[0].reflectedType); // //# 01: continued + Expect.isFalse(m.parameters[0].type.isOriginalDeclaration); // //# 01: continued + + var lib = currentMirrorSystem().findLibrary(#test); + Expect.isTrue((lib.declarations[#Foo] as TypeMirror).isOriginalDeclaration); +} diff --git a/tests/lib/mirrors/typedef_test.dart b/tests/lib/mirrors/typedef_test.dart new file mode 100644 index 00000000000..b7a152f3b83 --- /dev/null +++ b/tests/lib/mirrors/typedef_test.dart @@ -0,0 +1,135 @@ +// Copyright (c) 2013, 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. + +// This test is a multi-test with three positive tests. "01" pass on dart2js, +// "02" pass on the VM, and "none" is the correct behavior. +// The goal is to remove all "01" and "02" lines. + +library test.typedef_test; + +import 'dart:mirrors'; + +import 'package:expect/expect.dart'; + +typedef Func(); +typedef void Void(); +typedef String Foo(int x); +typedef String Bar(int x, [num y]); +typedef String Baz(int x, {num y}); +typedef String Foo2(int x, num y); +typedef String Bar2(int x, [num y, num z]); +typedef String Baz2(int x, {num y, num z}); + +check(t) { + var sb = new StringBuffer(); + writeln(o) { + sb.write(o); + sb.write('\n'); + } + + writeln(t); + t = t.referent; + writeln(t); + writeln(t.returnType); + writeln(t.parameters); + for (var p in t.parameters) { + writeln(p.simpleName); + writeln(p.type); + } + + return sb.toString(); +} + +// Return "$args -> $ret". +ft(args, ret) { + return '$args -> $ret'; +} + +void main() { + String x = 'x'; + String y = 'y'; + String z = 'z'; + + Expect.stringEquals(""" +TypedefMirror on 'Func' +FunctionTypeMirror on '${ft('()', 'dynamic')}' +TypeMirror on 'dynamic' +[] +""", check(reflectType(Func))); + Expect.stringEquals(""" +TypedefMirror on 'Void' +FunctionTypeMirror on '${ft('()', 'void')}' +TypeMirror on 'void' +[] +""", check(reflectType(Void))); + Expect.stringEquals(""" +TypedefMirror on 'Foo' +FunctionTypeMirror on '${ft('(dart.core.int)', 'dart.core.String')}' +ClassMirror on 'String' +[ParameterMirror on '$x'] +Symbol(\"$x\") +ClassMirror on 'int' +""", check(reflectType(Foo))); + String type = ft('(dart.core.int, dart.core.num)', 'dart.core.String'); + Expect.stringEquals(""" +TypedefMirror on 'Foo2' +FunctionTypeMirror on '$type' +ClassMirror on 'String' +[ParameterMirror on '$x', ParameterMirror on '$y'] +Symbol(\"$x\") +ClassMirror on 'int' +Symbol(\"$y\") +ClassMirror on 'num' +""", check(reflectType(Foo2))); + type = ft('(dart.core.int, [dart.core.num])', 'dart.core.String'); + Expect.stringEquals(""" +TypedefMirror on 'Bar' +FunctionTypeMirror on '$type' +ClassMirror on 'String' +[ParameterMirror on '$x', ParameterMirror on '$y'] +Symbol(\"$x\") +ClassMirror on 'int' +Symbol(\"$y\") +ClassMirror on 'num' +""", check(reflectType(Bar))); + type = + ft('(dart.core.int, [dart.core.num, dart.core.num])', 'dart.core.String'); + Expect.stringEquals(""" +TypedefMirror on 'Bar2' +FunctionTypeMirror on '$type' +ClassMirror on 'String' +[ParameterMirror on '$x', ParameterMirror on '$y', ParameterMirror on '$z'] +Symbol(\"$x\") +ClassMirror on 'int' +Symbol(\"$y\") +ClassMirror on 'num' +Symbol(\"$z\") +ClassMirror on 'num' +""", check(reflectType(Bar2))); + type = ft('(dart.core.int, {y: dart.core.num})', 'dart.core.String'); + Expect.stringEquals(""" +TypedefMirror on 'Baz' +FunctionTypeMirror on '$type' +ClassMirror on 'String' +[ParameterMirror on '$x', ParameterMirror on 'y'] +Symbol(\"$x\") +ClassMirror on 'int' +Symbol(\"y\") +ClassMirror on 'num' +""", check(reflectType(Baz))); + type = ft('(dart.core.int, {y: dart.core.num, z: dart.core.num})', + 'dart.core.String'); + Expect.stringEquals(""" +TypedefMirror on 'Baz2' +FunctionTypeMirror on '$type' +ClassMirror on 'String' +[ParameterMirror on '$x', ParameterMirror on 'y', ParameterMirror on 'z'] +Symbol(\"$x\") +ClassMirror on 'int' +Symbol(\"y\") +ClassMirror on 'num' +Symbol(\"z\") +ClassMirror on 'num' +""", check(reflectType(Baz2))); +} diff --git a/tests/lib/mirrors/typevariable_mirror_metadata_test.dart b/tests/lib/mirrors/typevariable_mirror_metadata_test.dart new file mode 100644 index 00000000000..7d2f69a56e4 --- /dev/null +++ b/tests/lib/mirrors/typevariable_mirror_metadata_test.dart @@ -0,0 +1,34 @@ +// Copyright (c) 2013, 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. + +library test.typevariable_metadata_test; + +import "dart:mirrors"; + +import "metadata_test.dart"; + +const m1 = 'm1'; +const m2 = #m2; +const m3 = 3; + +class A {} + +class B<@m3 T> {} + +typedef bool Predicate<@m1 @m2 G>(G a); + +main() { + ClassMirror cm; + cm = reflectClass(A); + checkMetadata(cm.typeVariables[0], []); + checkMetadata(cm.typeVariables[1], [m1, m2]); + + cm = reflectClass(B); + checkMetadata(cm.typeVariables[0], [m3]); + + TypedefMirror tm = reflectType(Predicate); + checkMetadata(tm.typeVariables[0], [m1, m2]); + FunctionTypeMirror ftm = tm.referent; + checkMetadata(ftm, []); +} diff --git a/tests/lib/mirrors/unmangled_type_test.dart b/tests/lib/mirrors/unmangled_type_test.dart new file mode 100644 index 00000000000..b9fa76343dd --- /dev/null +++ b/tests/lib/mirrors/unmangled_type_test.dart @@ -0,0 +1,16 @@ +// Copyright (c) 2013, 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. + +library lib; + +import 'dart:mirrors'; + +import 'package:expect/expect.dart'; + +class Foo {} + +main() { + Expect.stringEquals('Foo', '${new Foo().runtimeType}'); + Expect.stringEquals('foo', MirrorSystem.getName(new Symbol('foo'))); +} diff --git a/tests/lib/mirrors/unnamed_library_test.dart b/tests/lib/mirrors/unnamed_library_test.dart new file mode 100644 index 00000000000..5e6160d349b --- /dev/null +++ b/tests/lib/mirrors/unnamed_library_test.dart @@ -0,0 +1,21 @@ +// Copyright (c) 2013, 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. + +// No library declaration. + +import 'dart:mirrors'; + +import 'package:expect/expect.dart'; + +class Class {} + +main() { + ClassMirror cm = reflectClass(Class); + LibraryMirror lm = cm.owner as LibraryMirror; + + Expect.equals('Class', MirrorSystem.getName(cm.simpleName)); + Expect.equals('.Class', MirrorSystem.getName(cm.qualifiedName)); + Expect.equals('', MirrorSystem.getName(lm.simpleName)); + Expect.equals('', MirrorSystem.getName(lm.qualifiedName)); +} diff --git a/tests/lib/mirrors/unnamed_mixin_application_test.dart b/tests/lib/mirrors/unnamed_mixin_application_test.dart new file mode 100644 index 00000000000..d8844955715 --- /dev/null +++ b/tests/lib/mirrors/unnamed_mixin_application_test.dart @@ -0,0 +1,28 @@ +// 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. + +/// Test that the forwarding constructors of unnamed mixin applications are +/// included for reflection. + +library lib; + +import 'dart:mirrors'; + +class S { + S(); + S.anUnusedName(); +} + +class M {} + +class C extends S with M { + C(); +} + +main() { + // Use 'C#', 'S+M#' and 'S#' but not 'S#anUnusedName' nor 'S+M#anUnusedName'. + new C(); + // Disable tree shaking making 'S+M#anUnusedName' live. + reflectClass(C); +} diff --git a/tests/lib/mirrors/variable_is_const_test.dart b/tests/lib/mirrors/variable_is_const_test.dart new file mode 100644 index 00000000000..de3b0cb9c56 --- /dev/null +++ b/tests/lib/mirrors/variable_is_const_test.dart @@ -0,0 +1,35 @@ +// Copyright (c) 2013, 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. + +library test.variable_is_const; + +import 'dart:mirrors'; + +import 'package:expect/expect.dart'; + +class Class { + const //# 01: compile-time error + int instanceWouldBeConst = 1; + var instanceNonConst = 2; + + static const staticConst = 3; + static var staticNonConst = 4; +} + +const topLevelConst = 5; +var topLevelNonConst = 6; + +main() { + bool isConst(m, Symbol s) => (m.declarations[s] as VariableMirror).isConst; + + ClassMirror cm = reflectClass(Class); + Expect.isFalse(isConst(cm, #instanceWouldBeConst)); + Expect.isFalse(isConst(cm, #instanceNonConst)); + Expect.isTrue(isConst(cm, #staticConst)); + Expect.isFalse(isConst(cm, #staticNonConst)); + + LibraryMirror lm = cm.owner as LibraryMirror; + Expect.isTrue(isConst(lm, #topLevelConst)); + Expect.isFalse(isConst(lm, #topLevelNonConst)); +}