diff --git a/runtime/lib/mirrors.cc b/runtime/lib/mirrors.cc index 9b7e9e6d593..14280038fa7 100644 --- a/runtime/lib/mirrors.cc +++ b/runtime/lib/mirrors.cc @@ -16,6 +16,10 @@ namespace dart { +DEFINE_FLAG(bool, use_mirrored_compilation_error, false, + "Wrap compilation errors that occur during reflective access in a " + "MirroredCompilationError, rather than suspending the isolate."); + static RawInstance* CreateMirror(const String& mirror_class_name, const Array& constructor_arguments) { const Library& mirrors_lib = Library::Handle(Library::MirrorsLibrary()); @@ -41,7 +45,7 @@ static void ThrowMirroredCompilationError(const String& message) { static void ThrowInvokeError(const Error& error) { - if (error.IsLanguageError()) { + if (FLAG_use_mirrored_compilation_error && error.IsLanguageError()) { // A compilation error that was delayed by lazy compilation. const LanguageError& compilation_error = LanguageError::Cast(error); String& message = String::Handle(compilation_error.message()); diff --git a/runtime/tests/vm/dart/isolate_mirror_local_test.dart b/runtime/tests/vm/dart/isolate_mirror_local_test.dart index 1576139df41..4ffcaef3d5e 100644 --- a/runtime/tests/vm/dart/isolate_mirror_local_test.dart +++ b/runtime/tests/vm/dart/isolate_mirror_local_test.dart @@ -149,8 +149,6 @@ void testRootLibraryMirror(LibraryMirror lib_mirror) { 'function, ' 'global_var, ' 'main, ' - 'methodWithError, ' - 'methodWithException, ' 'myFunc, ' 'myVar, ' 'myVar=, ' @@ -161,7 +159,6 @@ void testRootLibraryMirror(LibraryMirror lib_mirror) { 'testImplements, ' 'testIntegerInstanceMirror, ' 'testLibrariesMap, ' - 'testMirrorErrors, ' 'testMirrorSystem, ' 'testNullInstanceMirror, ' 'testRootLibraryMirror, ' @@ -202,8 +199,6 @@ void testRootLibraryMirror(LibraryMirror lib_mirror) { 'buildVariableString, ' 'function, ' 'main, ' - 'methodWithError, ' - 'methodWithException, ' 'myVar, ' 'myVar=, ' 'sort, ' @@ -213,7 +208,6 @@ void testRootLibraryMirror(LibraryMirror lib_mirror) { 'testImplements, ' 'testIntegerInstanceMirror, ' 'testLibrariesMap, ' - 'testMirrorErrors, ' 'testMirrorSystem, ' 'testNullInstanceMirror, ' 'testRootLibraryMirror, ' @@ -430,7 +424,6 @@ class MySuperClass { class MyInterface { } -@notDefined class MyClass extends MySuperClass implements MyInterface { MyClass(this.value) {} MyClass.named() {} @@ -469,9 +462,6 @@ void testCustomInstanceMirror(InstanceMirror mirror) { cls.owner.simpleName); Expect.isTrue(cls.isClass); Expect.equals(const Symbol('MyInterface'), cls.superinterfaces[0].simpleName); - Expect.throws(() => cls.metadata, - (e) => e is MirroredCompilationError, - 'Bad metadata'); Expect.equals("ClassMirror on 'MyClass'", cls.toString()); // Invoke mirror.method(1000). @@ -491,57 +481,6 @@ class MyException implements Exception { String toString() { return 'MyException: $_message'; } } -void methodWithException() { - throw new MyException("from methodWithException"); -} - -void methodWithError() { - // We get a parse error when we try to run this function. - +++; -} - -void testMirrorErrors(MirrorSystem mirrors) { - LibraryMirror lib_mirror = mirrors.isolate.rootLibrary; - - lib_mirror.invokeAsync(const Symbol('methodWithException'), []) - .then((InstanceMirror retval) { - // Should not reach here. - Expect.isTrue(false); - }) - .catchError((error) { - Expect.isTrue(error is MyException); - Expect.equals('MyException: from methodWithException', - error.toString()); - testDone('testMirrorErrors1'); - }); - - lib_mirror.invokeAsync(const Symbol('methodWithError'), []) - .then((InstanceMirror retval) { - // Should not reach here. - Expect.isTrue(false); - }) - .catchError((error) { - Expect.isTrue(error is MirroredCompilationError); - Expect.isTrue(error.message.contains('unexpected token')); - testDone('testMirrorErrors2'); - }); - - // TODO(turnidge): When we call a method that doesn't exist, we - // should probably call noSuchMethod(). I'm adding this test to - // document the current behavior in the meantime. - lib_mirror.invokeAsync(const Symbol('methodNotFound'), []) - .then((InstanceMirror retval) { - // Should not reach here. - Expect.isTrue(false); - }) - .catchError((error) { - Expect.isTrue(error is NoSuchMethodError); - Expect.isTrue(error.toString().contains( - "No top-level method 'methodNotFound'")); - testDone('testMirrorErrors3'); - }); -} - void main() { // When all of the expected tests complete, the exit_port is closed, // allowing the program to terminate. @@ -553,10 +492,7 @@ void main() { 'testStringInstanceMirror', 'testBoolInstanceMirror', 'testNullInstanceMirror', - 'testCustomInstanceMirror', - 'testMirrorErrors1', - 'testMirrorErrors2', - 'testMirrorErrors3']); + 'testCustomInstanceMirror']); // Test that an isolate can reflect on itself. mirrorSystemOf(exit_port.toSendPort()).then(testMirrorSystem); @@ -566,5 +502,4 @@ void main() { testBoolInstanceMirror(reflect(true)); testNullInstanceMirror(reflect(null)); testCustomInstanceMirror(reflect(new MyClass(17))); - testMirrorErrors(currentMirrorSystem()); } diff --git a/runtime/tests/vm/dart/mirrored_compilation_error_test.dart b/runtime/tests/vm/dart/mirrored_compilation_error_test.dart new file mode 100644 index 00000000000..b661afe6517 --- /dev/null +++ b/runtime/tests/vm/dart/mirrored_compilation_error_test.dart @@ -0,0 +1,103 @@ +// 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=--use_mirrored_compilation_error=true + +@notDefined +library mirrored_compilation_error_test; + +import 'dart:mirrors'; +import "package:expect/expect.dart"; + +@notDefined +class Class<@notDefined T> { + @notDefined + var field; + + @notDefined + method(@notDefined param) {} +} + +class Class2 { + method() { +++; } + get getter { +++; } + set setter(x) { +++; } + + static staticFunction() { +++; } + static get staticGetter { +++; } + static set staticSetter(x) { +++; } + + Class2() {} + Class2.constructor() { +++; } +} + +toplevelFunction() { +++; } +get toplevelGetter { +++; } +set toplevelSetter(x) { +++; } + + +class G { + G(); + factory G.swap() = G; /// static type warning +} + +raises(closure) { + Expect.throws(closure, + (e) => e is MirroredCompilationError, + 'Expected a deferred compilation error'); +} + +bool get inCheckedMode { + try { + var i = 1; + String s = i; + return false; + } catch (e) { + return true; + } +} + +main() { + + // Metadata. + + raises(() => reflectClass(Class).metadata); + raises(() => reflectClass(Class).typeVariables.single.metadata); + raises(() => reflectClass(Class).variables[#field].metadata); + raises(() => reflectClass(Class).methods[#method].metadata); + raises(() => reflectClass(Class).methods[#method].parameters.single.metadata); + raises(() => reflectClass(Class).owner.metadata); + + + // Invocation. + + InstanceMirror im = reflect(new Class2()); + raises(() => im.invoke(#method, [])); + raises(() => im.getField(#getter)); + raises(() => im.setField(#setter, 'some value')); + // The implementation is within its right to defer the compilation even + // further here, so we apply the tear-off to force compilation. + raises(() => im.getField(#method).apply([])); + + ClassMirror cm = reflectClass(Class2); + raises(() => cm.invoke(#staticFunction, [])); + raises(() => cm.getField(#staticGetter)); + raises(() => cm.setField(#staticSetter, 'some value')); + raises(() => cm.getField(#staticFunction).apply([])); + raises(() => cm.newInstance(#constructor, [])); + + LibraryMirror lm = reflectClass(Class2).owner; + raises(() => lm.invoke(#toplevelFunction, [])); + raises(() => lm.getField(#toplevelGetter)); + raises(() => lm.setField(#toplevelSetter, 'some value')); + raises(() => lm.getField(#toplevelFunction).apply([])); + + + // Bounds violation. + + if (inCheckedMode) { + ClassMirror cm = reflect(new G()).type; + raises(() => cm.newInstance(#swap, [])); + } +} diff --git a/tests/lib/mirrors/redirection_type_shuffling_test.dart b/runtime/tests/vm/dart/redirection_type_shuffling_test.dart similarity index 51% rename from tests/lib/mirrors/redirection_type_shuffling_test.dart rename to runtime/tests/vm/dart/redirection_type_shuffling_test.dart index 582b4148202..c1db64c58e4 100644 --- a/tests/lib/mirrors/redirection_type_shuffling_test.dart +++ b/runtime/tests/vm/dart/redirection_type_shuffling_test.dart @@ -7,30 +7,14 @@ import "package:expect/expect.dart"; class G { G(); - factory G.swap() = G; /// static type warning + factory G.swap() = G; /// 00: static type warning factory G.retain() = G; } -bool get inCheckedMode { - try { - var i = 1; - String s = i; - return false; - } catch(e) { - return true; - } -} - main() { ClassMirror cm = reflect(new G()).type; - if (inCheckedMode) { - Expect.throws(() => cm.newInstance(#swap, []), - (e) => e is MirroredCompilationError, - 'Checked mode should not allow violation of type bounds'); - } else { - Expect.isTrue(cm.newInstance(#swap, []).reflectee is G); - } - Expect.isTrue(cm.newInstance(#retain, []).reflectee is G); + + Expect.isTrue(cm.newInstance(#swap, []).reflectee is G); /// 00: dynamic type error } diff --git a/runtime/vm/exceptions.cc b/runtime/vm/exceptions.cc index 1e0e9166060..c8d82f99eb2 100644 --- a/runtime/vm/exceptions.cc +++ b/runtime/vm/exceptions.cc @@ -694,10 +694,6 @@ RawObject* Exceptions::Create(ExceptionType type, const Array& arguments) { class_name = &Symbols::AbstractClassInstantiationError(); constructor_name = &Symbols::DotCreate(); break; - case kMirroredUncaughtExceptionError: - library = Library::MirrorsLibrary(); - class_name = &Symbols::MirroredUncaughtExceptionError(); - break; case kMirroredCompilationError: library = Library::MirrorsLibrary(); class_name = &Symbols::MirroredCompilationError(); diff --git a/runtime/vm/exceptions.h b/runtime/vm/exceptions.h index 5be049d3f7f..c49b9038685 100644 --- a/runtime/vm/exceptions.h +++ b/runtime/vm/exceptions.h @@ -58,7 +58,6 @@ class Exceptions : AllStatic { kType, kFallThrough, kAbstractClassInstantiation, - kMirroredUncaughtExceptionError, kMirroredCompilationError, }; diff --git a/runtime/vm/symbols.h b/runtime/vm/symbols.h index 1f2da7a20bf..60464fb22b9 100644 --- a/runtime/vm/symbols.h +++ b/runtime/vm/symbols.h @@ -237,7 +237,6 @@ class ObjectPointerVisitor; V(IsolateUnhandledException, "IsolateUnhandledException") \ V(JavascriptIntegerOverflowError, "_JavascriptIntegerOverflowError") \ V(MirroredCompilationError, "MirroredCompilationError") \ - V(MirroredUncaughtExceptionError, "MirroredUncaughtExceptionError") \ V(_setupFullStackTrace, "_setupFullStackTrace") \ V(BooleanExpression, "boolean expression") \ V(Malformed, "malformed") \ diff --git a/tests/lib/lib.status b/tests/lib/lib.status index 9fbf45d891e..5d5565a5907 100644 --- a/tests/lib/lib.status +++ b/tests/lib/lib.status @@ -74,9 +74,6 @@ mirrors/unnamed_library_test: RuntimeError # Issue 10580 mirrors/generic_bounded_test/02: RuntimeError # Issue 12087 mirrors/generic_bounded_by_type_parameter_test/02: RuntimeError # Issue 12087 -[ $compiler == dart2js && $checked ] -mirrors/redirection_type_shuffling_test: RuntimeError # Issue 13706 - [ $runtime == safari ] mirrors/return_type_test: Pass, Timeout # Issue 12858