Hide MirroredCompilationErrror behind a flag until post-1.0. Remove VM reference to MirroredUncaughtExceptionError.
R=asiva@google.com, gbracha@google.com Review URL: https://codereview.chromium.org//28053005 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@28946 260f80e4-7a28-3924-810f-c04153c831b5
This commit is contained in:
@@ -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());
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
@@ -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<A extends int, B extends String> {
|
||||
G();
|
||||
factory G.swap() = G<B,A>; /// 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<int, String>()).type;
|
||||
raises(() => cm.newInstance(#swap, []));
|
||||
}
|
||||
}
|
||||
+3
-19
@@ -7,30 +7,14 @@ import "package:expect/expect.dart";
|
||||
|
||||
class G<A extends int, B extends String> {
|
||||
G();
|
||||
factory G.swap() = G<B,A>; /// static type warning
|
||||
factory G.swap() = G<B,A>; /// 00: static type warning
|
||||
factory G.retain() = G<A,B>;
|
||||
}
|
||||
|
||||
bool get inCheckedMode {
|
||||
try {
|
||||
var i = 1;
|
||||
String s = i;
|
||||
return false;
|
||||
} catch(e) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
main() {
|
||||
ClassMirror cm = reflect(new G<int, String>()).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<String,int>);
|
||||
}
|
||||
|
||||
Expect.isTrue(cm.newInstance(#retain, []).reflectee is G<int,String>);
|
||||
|
||||
Expect.isTrue(cm.newInstance(#swap, []).reflectee is G<String,int>); /// 00: dynamic type error
|
||||
}
|
||||
@@ -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();
|
||||
|
||||
@@ -58,7 +58,6 @@ class Exceptions : AllStatic {
|
||||
kType,
|
||||
kFallThrough,
|
||||
kAbstractClassInstantiation,
|
||||
kMirroredUncaughtExceptionError,
|
||||
kMirroredCompilationError,
|
||||
};
|
||||
|
||||
|
||||
@@ -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") \
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user