Index: runtime/lib/mirrors.cc |
diff --git a/runtime/lib/mirrors.cc b/runtime/lib/mirrors.cc |
index a30df6bcd38c780af61edab69c7632542b48c2a9..564db227d8f6aac65ce2b9c47838d60c54e97251 100644 |
--- a/runtime/lib/mirrors.cc |
+++ b/runtime/lib/mirrors.cc |
@@ -139,12 +139,18 @@ static RawInstance* CreateParameterMirrorList(const Function& func, |
// This covers the default constructor and forwarding constructors. |
has_extra_parameter_info = false; |
} |
+ if (func.IsSignatureFunction() && |
+ (func.token_pos() == Token::kNoSourcePos)) { |
+ // Signature functions (except those describing typedefs) get canonicalized, |
+ // hence do not have a token position, and therefore cannot be reparsed. |
+ has_extra_parameter_info = false; |
+ } |
Array& param_descriptor = Array::Handle(); |
if (has_extra_parameter_info) { |
// Reparse the function for the following information: |
// * The default value of a parameter. |
- // * Whether a parameters has been deflared as final. |
+ // * Whether a parameters has been declared as final. |
// * Any metadata associated with the parameter. |
const Object& result = |
Object::Handle(Parser::ParseFunctionParameters(func)); |
@@ -237,18 +243,21 @@ static RawInstance* CreateTypedefMirror(const Class& cls, |
args.SetAt(0, MirrorReference::Handle(MirrorReference::New(cls))); |
args.SetAt(1, type); |
args.SetAt(2, String::Handle(cls.Name())); |
- args.SetAt(3, Bool::Get(cls.NumTypeParameters() != 0)); |
- args.SetAt(4, cls.NumTypeParameters() == 0 ? Bool::False() : is_declaration); |
+ args.SetAt(3, Bool::Get(cls.IsGeneric())); |
+ args.SetAt(4, cls.IsGeneric() ? is_declaration : Bool::False()); |
args.SetAt(5, owner_mirror); |
return CreateMirror(Symbols::_LocalTypedefMirror(), args); |
} |
-static RawInstance* CreateFunctionTypeMirror(const Class& cls, |
- const AbstractType& type) { |
- const Array& args = Array::Handle(Array::New(2)); |
+static RawInstance* CreateFunctionTypeMirror(const AbstractType& type) { |
+ ASSERT(type.IsFunctionType()); |
+ const Class& cls = Class::Handle(FunctionType::Cast(type).scope_class()); |
+ const Function& func = Function::Handle(FunctionType::Cast(type).signature()); |
+ const Array& args = Array::Handle(Array::New(3)); |
args.SetAt(0, MirrorReference::Handle(MirrorReference::New(cls))); |
- args.SetAt(1, type); |
+ args.SetAt(1, MirrorReference::Handle(MirrorReference::New(func))); |
+ args.SetAt(2, type); |
return CreateMirror(Symbols::_LocalFunctionTypeMirror(), args); |
} |
@@ -304,22 +313,6 @@ static RawInstance* CreateVariableMirror(const Field& field, |
return CreateMirror(Symbols::_LocalVariableMirror(), args); |
} |
-static RawFunction* CallMethod(const Class& cls) { |
- if (cls.IsSignatureClass()) { |
- return cls.signature_function(); |
- } |
- |
- Class& lookup_cls = Class::Handle(cls.raw()); |
- Function& call_function = Function::Handle(); |
- do { |
- call_function = lookup_cls.LookupDynamicFunction(Symbols::Call()); |
- if (!call_function.IsNull()) { |
- return call_function.raw(); |
- } |
- lookup_cls = lookup_cls.SuperClass(); |
- } while (!lookup_cls.IsNull()); |
- return Function::null(); |
-} |
static RawInstance* CreateClassMirror(const Class& cls, |
const AbstractType& type, |
@@ -335,14 +328,8 @@ static RawInstance* CreateClassMirror(const Class& cls, |
ASSERT(!type.IsNull()); |
ASSERT(type.IsFinalized()); |
- if (cls.IsSignatureClass()) { |
- if (cls.IsCanonicalSignatureClass()) { |
- // We represent function types as canonical signature classes. |
- return CreateFunctionTypeMirror(cls, type); |
- } else { |
- // We represent typedefs as non-canonical signature classes. |
- return CreateTypedefMirror(cls, type, is_declaration, owner_mirror); |
- } |
+ if (cls.IsTypedefClass()) { |
+ return CreateTypedefMirror(cls, type, is_declaration, owner_mirror); |
} |
const Error& error = Error::Handle(cls.EnsureIsFinalized(Thread::Current())); |
@@ -554,6 +541,16 @@ static RawInstance* CreateTypeMirror(const AbstractType& type) { |
PROPAGATE_IF_MALFORMED(type); |
ASSERT(type.IsCanonical() || type.IsTypeParameter() || type.IsBoundedType()); |
+ if (type.IsFunctionType()) { |
+ const Class& scope_class = |
+ Class::Handle(FunctionType::Cast(type).scope_class()); |
+ if (scope_class.IsTypedefClass()) { |
+ return CreateTypedefMirror(scope_class, |
+ type, Bool::False(), Object::null_instance()); |
+ } else { |
+ return CreateFunctionTypeMirror(type); |
+ } |
+ } |
if (type.HasResolvedTypeClass()) { |
const Class& cls = Class::Handle(type.type_class()); |
// Handle void and dynamic types. |
@@ -785,8 +782,8 @@ static RawAbstractType* InstantiateType(const AbstractType& type, |
const TypeArguments& type_args = |
TypeArguments::Handle(instantiator.arguments()); |
Error& bound_error = Error::Handle(); |
- AbstractType& result = |
- AbstractType::Handle(type.InstantiateFrom(type_args, &bound_error)); |
+ AbstractType& result = AbstractType::Handle( |
+ type.InstantiateFrom(type_args, &bound_error, NULL, Heap::kOld)); |
if (!bound_error.IsNull()) { |
Exceptions::PropagateError(bound_error); |
UNREACHABLE(); |
@@ -828,12 +825,10 @@ DEFINE_NATIVE_ENTRY(Mirrors_makeLocalClassMirror, 1) { |
GET_NON_NULL_NATIVE_ARGUMENT(AbstractType, type, arguments->NativeArgAt(0)); |
PROPAGATE_IF_MALFORMED(type); |
ASSERT(type.IsFinalized()); |
- ASSERT(type.HasResolvedTypeClass()); |
+ ASSERT(type.IsFunctionType() || type.HasResolvedTypeClass()); |
const Class& cls = Class::Handle(type.type_class()); |
ASSERT(!cls.IsNull()); |
- if (cls.IsDynamicClass() || |
- cls.IsVoidClass() || |
- (cls.IsSignatureClass() && !cls.IsCanonicalSignatureClass())) { |
+ if (cls.IsDynamicClass() || cls.IsVoidClass() || cls.IsTypedefClass()) { |
Exceptions::ThrowArgumentError(type); |
UNREACHABLE(); |
} |
@@ -911,8 +906,9 @@ DEFINE_NATIVE_ENTRY(FunctionTypeMirror_call_method, 2) { |
owner_mirror, |
arguments->NativeArgAt(0)); |
GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(1)); |
- const Class& cls = Class::Handle(ref.GetClassReferent()); |
- const Function& func = Function::Handle(CallMethod(cls)); |
+ // TODO(rmacnak): Return get:call() method on class _Closure instead? |
+ // This now returns the result of invoking that call getter. |
+ const Function& func = Function::Handle(ref.GetFunctionReferent()); |
ASSERT(!func.IsNull()); |
return CreateMethodMirror(func, owner_mirror, AbstractType::Handle()); |
} |
@@ -921,8 +917,7 @@ DEFINE_NATIVE_ENTRY(FunctionTypeMirror_call_method, 2) { |
DEFINE_NATIVE_ENTRY(FunctionTypeMirror_parameters, 2) { |
GET_NON_NULL_NATIVE_ARGUMENT(Instance, owner, arguments->NativeArgAt(0)); |
GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(1)); |
- const Class& cls = Class::Handle(ref.GetClassReferent()); |
- const Function& func = Function::Handle(cls.signature_function()); |
+ const Function& func = Function::Handle(ref.GetFunctionReferent()); |
return CreateParameterMirrorList(func, owner); |
} |
@@ -932,8 +927,7 @@ DEFINE_NATIVE_ENTRY(FunctionTypeMirror_return_type, 2) { |
GET_NON_NULL_NATIVE_ARGUMENT(AbstractType, |
instantiator, |
arguments->NativeArgAt(1)); |
- const Class& cls = Class::Handle(ref.GetClassReferent()); |
- const Function& func = Function::Handle(CallMethod(cls)); |
+ const Function& func = Function::Handle(ref.GetFunctionReferent()); |
ASSERT(!func.IsNull()); |
AbstractType& type = AbstractType::Handle(func.result_type()); |
return InstantiateType(type, instantiator); |
@@ -953,10 +947,6 @@ DEFINE_NATIVE_ENTRY(ClassMirror_supertype, 1) { |
GET_NON_NULL_NATIVE_ARGUMENT(AbstractType, type, arguments->NativeArgAt(0)); |
PROPAGATE_IF_MALFORMED(type); |
ASSERT(type.IsFinalized()); |
- if (!type.HasResolvedTypeClass()) { |
- Exceptions::ThrowArgumentError(type); |
- UNREACHABLE(); |
- } |
const Class& cls = Class::Handle(type.type_class()); |
const AbstractType& super_type = AbstractType::Handle(cls.super_type()); |
ASSERT(super_type.IsNull() || super_type.IsFinalized()); |
@@ -968,10 +958,6 @@ DEFINE_NATIVE_ENTRY(ClassMirror_supertype_instantiated, 1) { |
GET_NON_NULL_NATIVE_ARGUMENT(AbstractType, type, arguments->NativeArgAt(0)); |
PROPAGATE_IF_MALFORMED(type); |
ASSERT(type.IsFinalized()); |
- if (!type.HasResolvedTypeClass()) { |
- Exceptions::ThrowArgumentError(type); |
- UNREACHABLE(); |
- } |
const Class& cls = Class::Handle(type.type_class()); |
const AbstractType& super_type = AbstractType::Handle(cls.super_type()); |
return InstantiateType(super_type, type); |
@@ -982,10 +968,6 @@ DEFINE_NATIVE_ENTRY(ClassMirror_interfaces, 1) { |
GET_NON_NULL_NATIVE_ARGUMENT(AbstractType, type, arguments->NativeArgAt(0)); |
PROPAGATE_IF_MALFORMED(type); |
ASSERT(type.IsFinalized()); |
- if (!type.HasResolvedTypeClass()) { |
- Exceptions::ThrowArgumentError(type); |
- UNREACHABLE(); |
- } |
const Class& cls = Class::Handle(type.type_class()); |
const Error& error = Error::Handle(cls.EnsureIsFinalized(thread)); |
if (!error.IsNull()) { |
@@ -999,10 +981,6 @@ DEFINE_NATIVE_ENTRY(ClassMirror_interfaces_instantiated, 1) { |
GET_NON_NULL_NATIVE_ARGUMENT(AbstractType, type, arguments->NativeArgAt(0)); |
PROPAGATE_IF_MALFORMED(type); |
ASSERT(type.IsFinalized()); |
- if (!type.HasResolvedTypeClass()) { |
- Exceptions::ThrowArgumentError(type); |
- UNREACHABLE(); |
- } |
const Class& cls = Class::Handle(type.type_class()); |
const Error& error = Error::Handle(cls.EnsureIsFinalized(thread)); |
if (!error.IsNull()) { |
@@ -1027,10 +1005,6 @@ DEFINE_NATIVE_ENTRY(ClassMirror_mixin, 1) { |
GET_NON_NULL_NATIVE_ARGUMENT(AbstractType, type, arguments->NativeArgAt(0)); |
PROPAGATE_IF_MALFORMED(type); |
ASSERT(type.IsFinalized()); |
- if (!type.HasResolvedTypeClass()) { |
- Exceptions::ThrowArgumentError(type); |
- UNREACHABLE(); |
- } |
const Class& cls = Class::Handle(type.type_class()); |
const AbstractType& mixin_type = AbstractType::Handle(cls.mixin()); |
ASSERT(mixin_type.IsNull() || mixin_type.IsFinalized()); |
@@ -1045,10 +1019,6 @@ DEFINE_NATIVE_ENTRY(ClassMirror_mixin_instantiated, 2) { |
arguments->NativeArgAt(1)); |
PROPAGATE_IF_MALFORMED(type); |
ASSERT(type.IsFinalized()); |
- if (!type.HasResolvedTypeClass()) { |
- Exceptions::ThrowArgumentError(type); |
- UNREACHABLE(); |
- } |
const Class& cls = Class::Handle(type.type_class()); |
const AbstractType& mixin_type = AbstractType::Handle(cls.mixin()); |
if (mixin_type.IsNull()) { |
@@ -1166,13 +1136,11 @@ DEFINE_NATIVE_ENTRY(LibraryMirror_members, 2) { |
entry = entries.GetNext(); |
if (entry.IsClass()) { |
const Class& klass = Class::Cast(entry); |
- // We filter out function signature classes and dynamic. |
+ // We filter out mixin application classes and dynamic. |
// TODO(12478): Should not need to filter out dynamic. |
// Note that the VM does not consider mixin application aliases to be |
// mixin applications. |
- if (!klass.IsCanonicalSignatureClass() && |
- !klass.IsDynamicClass() && |
- !klass.IsMixinApplication()) { |
+ if (!klass.IsDynamicClass() && !klass.IsMixinApplication()) { |
type = klass.DeclarationType(); |
member_mirror = CreateClassMirror(klass, |
type, |
@@ -1307,9 +1275,8 @@ DEFINE_NATIVE_ENTRY(Mirrors_evalInLibraryWithPrivateKey, 2) { |
// setters, assume the result is a closure and mark its function as invisible, |
// so it will not appear in stack traces. Whenever we support |
// ObjectMirror.evaluate this will need to be separated. |
- ASSERT(Instance::Cast(result).IsClosure()); |
- const Function& func = |
- Function::Handle(Closure::function(Instance::Cast(result))); |
+ ASSERT(result.IsClosure()); |
+ const Function& func = Function::Handle(Closure::Cast(result).function()); |
func.set_is_visible(false); |
func.set_is_debuggable(false); |
@@ -1317,10 +1284,9 @@ DEFINE_NATIVE_ENTRY(Mirrors_evalInLibraryWithPrivateKey, 2) { |
} |
DEFINE_NATIVE_ENTRY(TypedefMirror_declaration, 1) { |
- GET_NON_NULL_NATIVE_ARGUMENT(Type, type, arguments->NativeArgAt(0)); |
- const Class& cls = Class::Handle(type.type_class()); |
- // We represent typedefs as non-canonical signature classes. |
- ASSERT(cls.IsSignatureClass() && !cls.IsCanonicalSignatureClass()); |
+ GET_NON_NULL_NATIVE_ARGUMENT(FunctionType, type, arguments->NativeArgAt(0)); |
+ const Class& cls = Class::Handle(type.scope_class()); |
+ ASSERT(cls.IsTypedefClass()); |
return CreateTypedefMirror(cls, |
AbstractType::Handle(cls.DeclarationType()), |
Bool::True(), // is_declaration |
@@ -1454,7 +1420,7 @@ DEFINE_NATIVE_ENTRY(InstanceMirror_invokeSetter, 4) { |
DEFINE_NATIVE_ENTRY(InstanceMirror_computeType, 1) { |
GET_NON_NULL_NATIVE_ARGUMENT(Instance, instance, arguments->NativeArgAt(0)); |
- const Type& type = Type::Handle(instance.GetType()); |
+ const AbstractType& type = AbstractType::Handle(instance.GetType()); |
// The static type of null is specified to be the bottom type, however, the |
// runtime type of null is the Null type, which we correctly return here. |
return type.Canonicalize(); |
@@ -1479,7 +1445,7 @@ DEFINE_NATIVE_ENTRY(ClosureMirror_function, 1) { |
Type& instantiator = Type::Handle(); |
if (closure.IsClosure()) { |
const TypeArguments& arguments = |
- TypeArguments::Handle(Closure::GetTypeArguments(closure)); |
+ TypeArguments::Handle(closure.GetTypeArguments()); |
const Class& cls = |
Class::Handle(Isolate::Current()->object_store()->object_class()); |
instantiator = Type::New(cls, arguments, Token::kNoSourcePos); |
@@ -1708,8 +1674,8 @@ DEFINE_NATIVE_ENTRY(ClassMirror_invokeConstructor, 5) { |
// The type arguments of the redirection type are instantiated from the |
// type arguments of the type reflected by the class mirror. |
Error& bound_error = Error::Handle(); |
- redirect_type ^= redirect_type.InstantiateFrom(type_arguments, |
- &bound_error); |
+ redirect_type ^= redirect_type.InstantiateFrom( |
+ type_arguments, &bound_error, NULL, Heap::kOld); |
if (!bound_error.IsNull()) { |
Exceptions::PropagateError(bound_error); |
UNREACHABLE(); |
@@ -2015,8 +1981,7 @@ DEFINE_NATIVE_ENTRY(DeclarationMirror_location, 1) { |
token_pos = func.token_pos(); |
} else if (decl.IsClass()) { |
const Class& cls = Class::Cast(decl); |
- const bool is_typedef = cls.IsSignatureClass() && |
- !cls.IsCanonicalSignatureClass(); |
+ const bool is_typedef = cls.IsTypedefClass(); |
if (cls.is_synthesized_class() && |
!is_typedef && |
!cls.is_mixin_app_alias() && |
@@ -2077,15 +2042,25 @@ DEFINE_NATIVE_ENTRY(DeclarationMirror_location, 1) { |
DEFINE_NATIVE_ENTRY(TypedefMirror_referent, 1) { |
- GET_NON_NULL_NATIVE_ARGUMENT(Type, type, arguments->NativeArgAt(0)); |
- const Class& cls = Class::Handle(type.type_class()); |
+ GET_NON_NULL_NATIVE_ARGUMENT(FunctionType, type, arguments->NativeArgAt(0)); |
+ const Class& cls = Class::Handle(type.scope_class()); |
+ ASSERT(cls.IsTypedefClass()); |
const Function& sig_func = Function::Handle(cls.signature_function()); |
- const Class& sig_cls = Class::Handle(sig_func.signature_class()); |
- |
- AbstractType& referent_type = AbstractType::Handle(sig_cls.DeclarationType()); |
- referent_type = InstantiateType(referent_type, type); |
- |
- return CreateFunctionTypeMirror(sig_cls, referent_type); |
+ FunctionType& referent_type = FunctionType::Handle(sig_func.SignatureType()); |
+ // If the scope class of the function type is not generic, replace it with |
+ // Closure class (Function::SignatureType() keeps it). |
+ ASSERT(cls.raw() == referent_type.scope_class()); |
+ if (!cls.IsGeneric()) { |
+ referent_type = FunctionType::New( |
+ Class::Handle(Isolate::Current()->object_store()->closure_class()), |
+ TypeArguments::Handle(referent_type.arguments()), |
+ sig_func, |
+ referent_type.token_pos()); |
+ referent_type ^= ClassFinalizer::FinalizeType( |
+ cls, referent_type, ClassFinalizer::kCanonicalize); |
+ } |
+ referent_type ^= InstantiateType(referent_type, type); |
+ return CreateFunctionTypeMirror(referent_type); |
} |