Also fixes issue 11897.

R=asiva@google.com

Review URL: https://codereview.chromium.org//21124011

git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@25689 260f80e4-7a28-3924-810f-c04153c831b5
This commit is contained in:
mlippautz@google.com 2013-07-31 23:31:14 +00:00
parent 50cc2b4a1e
commit 9f602cfa83
6 changed files with 110 additions and 225 deletions

View file

@ -74,9 +74,6 @@ static Dart_Handle CreateMirrorReference(Dart_Handle handle) {
}
static Dart_Handle CreateLazyMirror(Dart_Handle target);
static RawInstance* CreateParameterMirrorList(const Function& func) {
HANDLESCOPE(Isolate::Current());
const intptr_t param_cnt = func.num_fixed_parameters() -
@ -100,76 +97,6 @@ static RawInstance* CreateParameterMirrorList(const Function& func) {
}
static Dart_Handle CreateParameterMirrorListUsingApi(Dart_Handle func) {
ASSERT(Dart_IsFunction(func));
Isolate* isolate = Isolate::Current();
return Api::NewHandle(
isolate, CreateParameterMirrorList(Api::UnwrapFunctionHandle(
isolate, func)));
}
static Dart_Handle CreateLazyMirror(Dart_Handle target) {
if (Dart_IsNull(target) || Dart_IsError(target)) {
return target;
}
if (Dart_IsLibrary(target)) {
Dart_Handle cls_name = NewString("_LazyLibraryMirror");
Dart_Handle type = Dart_GetType(MirrorLib(), cls_name, 0, NULL);
Dart_Handle args[] = { Dart_LibraryUrl(target) };
return Dart_New(type, Dart_Null(), ARRAY_SIZE(args), args);
}
if (Dart_IsClass(target)) {
if (Dart_ClassIsFunctionType(target)) {
Dart_Handle cls_name = NewString("_LazyFunctionTypeMirror");
Dart_Handle type = Dart_GetType(MirrorLib(), cls_name, 0, NULL);
Dart_Handle sig = Dart_ClassGetFunctionTypeSignature(target);
Dart_Handle return_type = Dart_FunctionReturnType(sig);
if (Dart_IsError(return_type)) {
return return_type;
}
Dart_Handle args[] = {
CreateMirrorReference(target),
CreateLazyMirror(return_type),
CreateParameterMirrorListUsingApi(sig),
};
return Dart_New(type, Dart_Null(), ARRAY_SIZE(args), args);
} else {
Dart_Handle cls_name = NewString("_LazyTypeMirror");
Dart_Handle type = Dart_GetType(MirrorLib(), cls_name, 0, NULL);
Dart_Handle lib = Dart_ClassGetLibrary(target);
Dart_Handle lib_url;
if (Dart_IsNull(lib)) {
lib_url = Dart_Null();
} else {
lib_url = Dart_LibraryUrl(lib);
}
Dart_Handle args[] = { lib_url, Dart_ClassName(target) };
return Dart_New(type, Dart_Null(), ARRAY_SIZE(args), args);
}
}
if (Dart_IsTypeVariable(target)) {
Dart_Handle var_name = Dart_TypeVariableName(target);
Dart_Handle owner = Dart_TypeVariableOwner(target);
Dart_Handle owner_mirror = CreateLazyMirror(owner);
Dart_Handle cls_name = NewString("_LazyTypeVariableMirror");
Dart_Handle type = Dart_GetType(MirrorLib(), cls_name, 0, NULL);
Dart_Handle args[] = { var_name, owner_mirror };
return Dart_New(type, Dart_Null(), ARRAY_SIZE(args), args);
}
UNREACHABLE();
return Dart_Null();
}
static RawInstance* CreateTypeVariableMirror(const TypeParameter& param,
const Instance& owner_mirror) {
const Array& args = Array::Handle(Array::New(3));
@ -201,29 +128,24 @@ static RawInstance* CreateTypeVariableList(const Class& cls) {
}
static Dart_Handle CreateTypedefMirror(Dart_Handle cls,
Dart_Handle cls_name,
Dart_Handle owner_mirror) {
Dart_Handle mirror_cls_name = NewString("_LocalTypedefMirrorImpl");
Dart_Handle mirror_type = Dart_GetType(MirrorLib(), mirror_cls_name, 0, NULL);
if (Dart_IsError(mirror_type)) {
return mirror_type;
}
static RawInstance* CreateTypedefMirror(const Class& cls,
const Instance& owner_mirror) {
const Array& args = Array::Handle(Array::New(3));
args.SetAt(0, MirrorReference::Handle(MirrorReference::New(cls)));
args.SetAt(1, String::Handle(cls.UserVisibleName()));
args.SetAt(2, owner_mirror);
return CreateMirror(Symbols::_LocalTypedefMirrorImpl(), args);
}
Dart_Handle referent = Dart_ClassGetTypedefReferent(cls);
if (Dart_IsError(referent)) {
return referent;
}
Dart_Handle args[] = {
CreateMirrorReference(cls),
cls_name,
owner_mirror,
CreateLazyMirror(referent),
};
Dart_Handle mirror =
Dart_New(mirror_type, Dart_Null(), ARRAY_SIZE(args), args);
return mirror;
static Dart_Handle CreateTypedefMirrorUsingApi(Dart_Handle cls,
Dart_Handle cls_name,
Dart_Handle owner_mirror) {
Isolate* isolate = Isolate::Current();
return Api::NewHandle(
isolate, CreateTypedefMirror(
Api::UnwrapClassHandle(isolate, cls),
Api::UnwrapInstanceHandle(isolate, owner_mirror)));
}
@ -234,7 +156,7 @@ static Dart_Handle CreateClassMirrorUsingApi(Dart_Handle intf,
if (Dart_ClassIsTypedef(intf)) {
// This class is actually a typedef. Represent it specially in
// reflection.
return CreateTypedefMirror(intf, intf_name, lib_mirror);
return CreateTypedefMirrorUsingApi(intf, intf_name, lib_mirror);
}
Dart_Handle cls_name = NewString("_LocalClassMirrorImpl");
@ -479,6 +401,23 @@ DEFINE_NATIVE_ENTRY(DeclarationMirror_metadata, 1) {
}
DEFINE_NATIVE_ENTRY(FunctionTypeMirror_parameters, 1) {
GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(0));
const Class& cls = Class::Handle(ref.GetClassReferent());
const Function& func = Function::Handle(cls.signature_function());
return CreateParameterMirrorList(func);
}
DEFINE_NATIVE_ENTRY(FunctionTypeMirror_return_type, 1) {
GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(0));
const Class& cls = Class::Handle(ref.GetClassReferent());
const Function& func = Function::Handle(cls.signature_function());
const AbstractType& return_type = AbstractType::Handle(func.result_type());
return CreateTypeMirror(return_type);
}
void HandleMirrorsMessage(Isolate* isolate,
Dart_Port reply_port,
const Instance& message) {
@ -1302,6 +1241,15 @@ DEFINE_NATIVE_ENTRY(MethodMirror_return_type, 1) {
}
DEFINE_NATIVE_ENTRY(TypedefMirror_referent, 1) {
GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(0));
const Class& cls = Class::Handle(ref.GetClassReferent());
const Function& sig_func = Function::Handle(cls.signature_function());
const Class& sig_cls = Class::Handle(sig_func.signature_class());
return MirrorReference::New(sig_cls);
}
DEFINE_NATIVE_ENTRY(ParameterMirror_type, 2) {
GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(0));
GET_NON_NULL_NATIVE_ARGUMENT(Smi, pos, arguments->NativeArgAt(1));

View file

@ -99,8 +99,7 @@ List _unwarpAsyncPositionals(wrappedArgs){
class _LocalMirrorSystemImpl extends MirrorSystem {
// Change parameter back to "this.libraries" when native code is changed.
_LocalMirrorSystemImpl(List<LibraryMirror> libraries, this.isolate)
: this.libraries = _createLibrariesMap(libraries),
_functionTypes = new Map<String, FunctionTypeMirror>();
: this.libraries = _createLibrariesMap(libraries);
final Map<Uri, LibraryMirror> libraries;
final IsolateMirror isolate;
@ -123,23 +122,6 @@ class _LocalMirrorSystemImpl extends MirrorSystem {
return _voidType;
}
final Map<String, FunctionTypeMirror> _functionTypes;
FunctionTypeMirror _lookupFunctionTypeMirror(
reflectee,
TypeMirror returnType,
List<ParameterMirror> parameters) {
var sigString = _makeSignatureString(returnType, parameters);
var mirror = _functionTypes[sigString];
if (mirror == null) {
mirror = new _LocalFunctionTypeMirrorImpl(reflectee,
sigString,
returnType,
parameters);
_functionTypes[sigString] = mirror;
}
return mirror;
}
String toString() => "MirrorSystem for isolate '${isolate.debugName}'";
}
@ -368,33 +350,6 @@ class _LocalClosureMirrorImpl extends _LocalInstanceMirrorImpl
native 'ClosureMirror_function';
}
class _LazyTypeMirror {
_LazyTypeMirror(String this.libraryUrl, String typeName)
: this.typeName = _s(typeName);
TypeMirror resolve(MirrorSystem mirrors) {
if (libraryUrl == null) {
if (typeName == const Symbol('dynamic')) {
return mirrors.dynamicType;
} else if (typeName == const Symbol('void')) {
return mirrors.voidType;
} else {
throw new UnimplementedError(
"Mirror for type '$typeName' is not implemented");
}
}
var resolved = mirrors.libraries[Uri.parse(libraryUrl)].members[typeName];
if (resolved == null) {
throw new UnimplementedError(
"Mirror for type '$typeName' is not implemented");
}
return resolved;
}
final String libraryUrl;
final Symbol typeName;
}
class _LocalClassMirrorImpl extends _LocalObjectMirrorImpl
implements ClassMirror {
_LocalClassMirrorImpl(reflectee,
@ -442,7 +397,7 @@ class _LocalClassMirrorImpl extends _LocalObjectMirrorImpl
bool get isClass => true;
ClassMirror get defaultFactory => null;
var _superclass;
ClassMirror _superclass;
ClassMirror get superclass {
if (_superclass == null) {
Type supertype = _supertype(_reflectee);
@ -452,9 +407,6 @@ class _LocalClassMirrorImpl extends _LocalObjectMirrorImpl
}
_superclass = reflectClass(supertype);
}
if (_superclass is! Mirror) {
_superclass = _superclass.resolve(mirrors);
}
return _superclass;
}
@ -631,44 +583,46 @@ class _LocalClassMirrorImpl extends _LocalObjectMirrorImpl
native "ClassMirror_type_variables";
}
class _LazyFunctionTypeMirror {
_LazyFunctionTypeMirror(this.reflectee, this.returnType, this.parameters) {}
ClassMirror resolve(MirrorSystem mirrors) {
return mirrors._lookupFunctionTypeMirror(reflectee,
returnType.resolve(mirrors),
parameters);
}
final reflectee;
final returnType;
final List<ParameterMirror> parameters;
}
class _LocalFunctionTypeMirrorImpl extends _LocalClassMirrorImpl
implements FunctionTypeMirror {
_LocalFunctionTypeMirrorImpl(reflectee,
simpleName,
this._returnType,
this.parameters)
: super(reflectee,
simpleName);
_LocalFunctionTypeMirrorImpl(reflectee) : super(reflectee, null);
Map<Symbol, Mirror> get members => new Map<Symbol,Mirror>();
Map<Symbol, MethodMirror> get constructors => new Map<Symbol,MethodMirror>();
// FunctionTypeMirrors have a simpleName generated from their signature.
Symbol _simpleName = null;
Symbol get simpleName {
if (_simpleName == null) {
_simpleName = _s(_makeSignatureString(returnType, parameters));
}
return _simpleName;
}
var _returnType;
TypeMirror _returnType = null;
TypeMirror get returnType {
if (_returnType is! Mirror) {
_returnType = _returnType.resolve(mirrors);
if (_returnType == null) {
_returnType = _FunctionTypeMirror_return_type(_reflectee);
}
return _returnType;
}
final List<ParameterMirror> parameters;
List<ParameterMirror> _parameters = null;
List<ParameterMirror> get parameters {
if (_parameters == null) {
_parameters = _FunctionTypeMirror_parameters(_reflectee);
}
return _parameters;
}
Map<Symbol, Mirror> get members => new Map<Symbol,Mirror>();
Map<Symbol, MethodMirror> get constructors => new Map<Symbol,MethodMirror>();
final Map<Symbol, TypeVariableMirror> typeVariables = const {};
String toString() => "FunctionTypeMirror on '${_n(simpleName)}'";
static TypeMirror _FunctionTypeMirror_return_type(reflectee)
native "FunctionTypeMirror_return_type";
static List<ParameterMirror> _FunctionTypeMirror_parameters(reflectee)
native "FunctionTypeMirror_parameters";
}
abstract class _LocalDeclarationMirrorImpl extends _LocalMirrorImpl
@ -694,19 +648,6 @@ abstract class _LocalDeclarationMirrorImpl extends _LocalMirrorImpl
}
}
class _LazyTypeVariableMirror {
_LazyTypeVariableMirror(String variableName, this._owner)
: this._variableName = _s(variableName);
TypeVariableMirror resolve(MirrorSystem mirrors) {
ClassMirror owner = _owner.resolve(mirrors);
return owner.typeVariables[_variableName];
}
final Symbol _variableName;
final _LazyTypeMirror _owner;
}
class _LocalTypeVariableMirrorImpl extends _LocalDeclarationMirrorImpl
implements TypeVariableMirror {
_LocalTypeVariableMirrorImpl(reflectee,
@ -714,15 +655,11 @@ class _LocalTypeVariableMirrorImpl extends _LocalDeclarationMirrorImpl
this._owner)
: super(reflectee, _s(simpleName));
var _owner;
DeclarationMirror _owner;
DeclarationMirror get owner {
if (_owner == null) {
_owner = _LocalTypeVariableMirror_owner(_reflectee);
}
// TODO(11897): This will go away, as soon as lazy mirrors go away.
if (_owner is! Mirror) {
_owner = _owner.resolve(mirrors);
}
return _owner;
}
@ -762,18 +699,14 @@ class _LocalTypedefMirrorImpl extends _LocalDeclarationMirrorImpl
implements TypedefMirror {
_LocalTypedefMirrorImpl(reflectee,
String simpleName,
this._owner,
this._referent)
this._owner)
: super(reflectee, _s(simpleName));
var _owner;
DeclarationMirror _owner;
DeclarationMirror get owner {
if (_owner == null) {
_owner = _LocalClassMirrorImpl._library(_reflectee);
}
if (_owner is! Mirror) {
_owner = _owner.resolve(mirrors);
}
return _owner;
}
@ -786,26 +719,19 @@ class _LocalTypedefMirrorImpl extends _LocalDeclarationMirrorImpl
'TypedefMirror.location is not implemented');
}
var _referent;
TypeMirror _referent = null;
TypeMirror get referent {
if (_referent is! Mirror) {
_referent = _referent.resolve(mirrors);
if (_referent == null) {
return new _LocalFunctionTypeMirrorImpl(
_TypedefMirror_referent(_reflectee));
}
return _referent;
}
String toString() => "TypedefMirror on '${_n(simpleName)}'";
}
class _LazyLibraryMirror {
_LazyLibraryMirror(String this.libraryUrl);
LibraryMirror resolve(MirrorSystem mirrors) {
return mirrors.libraries[Uri.parse(libraryUrl)];
}
final String libraryUrl;
static _TypedefMirror_referent(_reflectee)
native "TypedefMirror_referent";
}
class _LocalLibraryMirrorImpl extends _LocalObjectMirrorImpl
@ -930,17 +856,13 @@ class _LocalMethodMirrorImpl extends _LocalDeclarationMirrorImpl
this.isFactoryConstructor)
: super(reflectee, _s(simpleName));
var _owner;
DeclarationMirror _owner;
DeclarationMirror get owner {
// For nested closures it is possible, that the mirror for the owner has not
// been created yet.
if (_owner == null) {
_owner = _MethodMirror_owner(_reflectee);
}
// TODO(11897): This will go away, as soon as lazy mirrors go away.
if (_owner is! Mirror) {
_owner = _owner.resolve(mirrors);
}
return _owner;
}
@ -1032,19 +954,13 @@ class _LocalVariableMirrorImpl extends _LocalDeclarationMirrorImpl
implements VariableMirror {
_LocalVariableMirrorImpl(reflectee,
String simpleName,
this._owner,
this.owner,
this._type,
this.isStatic,
this.isFinal)
: super(reflectee, _s(simpleName));
var _owner;
DeclarationMirror get owner {
if (_owner is! Mirror) {
_owner = _owner.resolve(mirrors);
}
return _owner;
}
final DeclarationMirror owner;
bool get isPrivate {
return _n(simpleName).startsWith('_');
@ -1059,14 +975,11 @@ class _LocalVariableMirrorImpl extends _LocalDeclarationMirrorImpl
'VariableMirror.location is not implemented');
}
var _type;
TypeMirror _type;
TypeMirror get type {
if (_type == null) {
_type = _VariableMirror_type(_reflectee);
}
if (_type is! Mirror) {
_type = _type.resolve(mirrors);
}
return _type;
}

View file

@ -265,10 +265,13 @@ namespace dart {
V(LocalTypeVariableMirror_owner, 1) \
V(LocalTypeVariableMirror_upper_bound, 1) \
V(DeclarationMirror_metadata, 1) \
V(FunctionTypeMirror_parameters, 1) \
V(FunctionTypeMirror_return_type, 1) \
V(MethodMirror_owner, 1) \
V(MethodMirror_parameters, 1) \
V(MethodMirror_return_type, 1) \
V(ParameterMirror_type, 2) \
V(TypedefMirror_referent, 1) \
V(VariableMirror_type, 1) \
V(GrowableObjectArray_allocate, 2) \
V(GrowableObjectArray_getIndexed, 2) \

View file

@ -275,6 +275,7 @@ class ObjectPointerVisitor;
V(_LocalParameterMirrorImpl, "_LocalParameterMirrorImpl") \
V(_LocalIsolateMirrorImpl, "_LocalIsolateMirrorImpl") \
V(_LocalMirrorSystemImpl, "_LocalMirrorSystemImpl") \
V(_LocalTypedefMirrorImpl, "_LocalTypedefMirrorImpl") \
V(_LocalTypeVariableMirrorImpl, "_LocalTypeVariableMirrorImpl") \

View file

@ -5,6 +5,7 @@
[ $compiler == dart2js ]
math/*: Skip
mirrors/class_mirror_type_variables_test: Fail # Issue 12087
mirrors/function_type_mirror_test: Fail # Issue 12166
mirrors/method_mirror_name_test: Fail # Issue 6335
mirrors/method_mirror_properties_test: Fail # Issue 11861
mirrors/method_mirror_returntype_test : Fail # Issue 11928

View file

@ -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";
import "package:expect/expect.dart";
typedef void FooFunction(int a, double b);
main() {
// Right now we can only get to a FunctionTypeMirror by reflecting on a
// typedef. See issue 12135.
TypedefMirror tm = reflectClass(FooFunction);
FunctionTypeMirror ftm = tm.referent;
Expect.equals(const Symbol("void"), ftm.returnType.simpleName);
Expect.equals(const Symbol("int"), ftm.parameters[0].type.simpleName);
Expect.equals(const Symbol("double"), ftm.parameters[1].type.simpleName);
}