Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1512)

Unified Diff: runtime/lib/mirrors.cc

Issue 23983026: Fill in type arguments when creating an object from the mirrors or embedding API. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: RareType Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | runtime/lib/mirrors_impl.dart » ('j') | runtime/vm/object.cc » ('J')
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/lib/mirrors.cc
diff --git a/runtime/lib/mirrors.cc b/runtime/lib/mirrors.cc
index b42a00a9232d22c6ffcaa653d5cb3d683f51926d..0cbe9890be9ad9a5e7c083d45eff18e415459160 100644
--- a/runtime/lib/mirrors.cc
+++ b/runtime/lib/mirrors.cc
@@ -29,15 +29,6 @@ static RawInstance* CreateMirror(const String& mirror_class_name,
}
-// Note a "raw type" is not the same as a RawType.
-static RawAbstractType* RawTypeOfClass(const Class& cls) {
- Type& type = Type::Handle(Type::New(cls,
- Object::null_abstract_type_arguments(),
- Scanner::kDummyTokenIndex));
- return ClassFinalizer::FinalizeType(cls, type, ClassFinalizer::kCanonicalize);
-}
-
-
static void ThrowMirroredCompilationError(const String& message) {
Array& args = Array::Handle(Array::New(1));
args.SetAt(0, message);
@@ -294,6 +285,7 @@ static RawFunction* CallMethod(const Class& cls) {
static RawInstance* CreateClassMirror(const Class& cls,
const AbstractType& type,
+ const Bool& is_declaration,
const Instance& owner_mirror) {
ASSERT(!cls.IsDynamicClass() && !cls.IsVoidClass());
@@ -307,16 +299,12 @@ static RawInstance* CreateClassMirror(const Class& cls,
}
}
+ ASSERT(!type.IsNull());
+
const Bool& is_generic = Bool::Get(cls.NumTypeParameters() != 0);
const Bool& is_mixin_typedef = Bool::Get(cls.is_mixin_typedef());
- // If the class is not generic, the mirror must have a non-null runtime type.
- // If the class is generic, the mirror will have a null runtime type if it
- // represents the declaration or a non-null runtime type if it represents an
- // instantiation.
- ASSERT(!(cls.NumTypeParameters() == 0) || !type.IsNull());
-
- const Array& args = Array::Handle(Array::New(5));
+ const Array& args = Array::Handle(Array::New(6));
args.SetAt(0, MirrorReference::Handle(MirrorReference::New(cls)));
args.SetAt(1, type);
// We do not set the names of anonymous mixin applications because the mirrors
@@ -327,6 +315,7 @@ static RawInstance* CreateClassMirror(const Class& cls,
}
args.SetAt(3, is_generic);
args.SetAt(4, is_mixin_typedef);
+ args.SetAt(5, cls.NumTypeParameters() == 0 ? Bool::False() : is_declaration);
return CreateMirror(Symbols::_LocalClassMirrorImpl(), args);
}
@@ -359,7 +348,7 @@ static RawInstance* CreateTypeMirror(const AbstractType& type) {
// TODO(mlippautz): Create once in the VM isolate and retrieve from there.
return CreateMirror(Symbols::_SpecialTypeMirrorImpl(), args);
}
- return CreateClassMirror(cls, type, Object::null_instance());
+ return CreateClassMirror(cls, type, Bool::False(), Object::null_instance());
} else if (type.IsTypeParameter()) {
return CreateTypeVariableMirror(TypeParameter::Cast(type),
Object::null_instance());
@@ -424,16 +413,11 @@ DEFINE_NATIVE_ENTRY(Mirrors_makeLocalClassMirror, 1) {
Exceptions::ThrowByType(Exceptions::kArgument, args);
UNREACHABLE();
}
- // Strip the type for generics only.
- if (cls.NumTypeParameters() == 0) {
- return CreateClassMirror(cls,
- type,
- Object::null_instance());
- } else {
- return CreateClassMirror(cls,
- AbstractType::Handle(),
- Object::null_instance());
- }
+ const Type& stripped_type = Type::Handle(cls.RareType());
+ return CreateClassMirror(cls,
+ stripped_type,
+ Bool::True(), // is_declaration
+ Object::null_instance());
}
@@ -661,13 +645,11 @@ DEFINE_NATIVE_ENTRY(LibraryMirror_members, 2) {
if (!klass.IsCanonicalSignatureClass() &&
!klass.IsDynamicClass() &&
!RawObject::IsImplementationClassId(klass.id())) {
- if (klass.NumTypeParameters() == 0) {
- // Include runtime type for non-generics only.
- type = RawTypeOfClass(klass);
- } else {
- type = AbstractType::null();
- }
- member_mirror = CreateClassMirror(klass, type, owner_mirror);
+ type = klass.RareType();
+ member_mirror = CreateClassMirror(klass,
+ type,
+ Bool::True(), // is_declaration
+ owner_mirror);
member_mirrors.Add(member_mirror);
}
} else if (entry.IsField()) {
@@ -738,11 +720,10 @@ DEFINE_NATIVE_ENTRY(ClassMirror_type_arguments, 1) {
DEFINE_NATIVE_ENTRY(TypeVariableMirror_owner, 1) {
GET_NON_NULL_NATIVE_ARGUMENT(TypeParameter, param, arguments->NativeArgAt(0));
const Class& owner = Class::Handle(param.parameterized_class());
- // The owner of a type variable must be a generic class: pass a null runtime
- // type to get a mirror on the declaration.
- ASSERT(owner.NumTypeParameters() != 0);
+ const Type& type = Type::Handle(owner.RareType());
return CreateClassMirror(owner,
- AbstractType::Handle(),
+ type,
+ Bool::True(), // is_declaration
Instance::null_instance());
}
@@ -967,7 +948,7 @@ DEFINE_NATIVE_ENTRY(ClassMirror_invoke, 5) {
if (function.IsNull() ||
!function.AreValidArguments(args_descriptor, NULL) ||
!function.is_visible()) {
- ThrowNoSuchMethod(AbstractType::Handle(RawTypeOfClass(klass)),
+ ThrowNoSuchMethod(AbstractType::Handle(klass.RareType()),
function_name,
function,
InvocationMirror::kStatic,
@@ -1002,7 +983,7 @@ DEFINE_NATIVE_ENTRY(ClassMirror_invokeGetter, 3) {
klass.LookupStaticFunctionAllowPrivate(internal_getter_name));
if (getter.IsNull() || !getter.is_visible()) {
- ThrowNoSuchMethod(AbstractType::Handle(RawTypeOfClass(klass)),
+ ThrowNoSuchMethod(AbstractType::Handle(klass.RareType()),
getter_name,
getter,
InvocationMirror::kStatic,
@@ -1041,7 +1022,7 @@ DEFINE_NATIVE_ENTRY(ClassMirror_invokeSetter, 4) {
klass.LookupStaticFunctionAllowPrivate(internal_setter_name));
if (setter.IsNull() || !setter.is_visible()) {
- ThrowNoSuchMethod(AbstractType::Handle(RawTypeOfClass(klass)),
+ ThrowNoSuchMethod(AbstractType::Handle(klass.RareType()),
setter_name,
setter,
InvocationMirror::kStatic,
@@ -1077,13 +1058,14 @@ DEFINE_NATIVE_ENTRY(ClassMirror_invokeSetter, 4) {
}
-DEFINE_NATIVE_ENTRY(ClassMirror_invokeConstructor, 4) {
+DEFINE_NATIVE_ENTRY(ClassMirror_invokeConstructor, 5) {
GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(0));
const Class& klass = Class::Handle(ref.GetClassReferent());
+ GET_NATIVE_ARGUMENT(Type, type, arguments->NativeArgAt(1));
GET_NON_NULL_NATIVE_ARGUMENT(
- String, constructor_name, arguments->NativeArgAt(1));
- GET_NON_NULL_NATIVE_ARGUMENT(Array, explicit_args, arguments->NativeArgAt(2));
- GET_NON_NULL_NATIVE_ARGUMENT(Array, arg_names, arguments->NativeArgAt(3));
+ String, constructor_name, arguments->NativeArgAt(2));
+ GET_NON_NULL_NATIVE_ARGUMENT(Array, explicit_args, arguments->NativeArgAt(3));
+ GET_NON_NULL_NATIVE_ARGUMENT(Array, arg_names, arguments->NativeArgAt(4));
// By convention, the static function implementing a named constructor 'C'
// for class 'A' is labeled 'A.C', and the static function implementing the
@@ -1106,7 +1088,7 @@ DEFINE_NATIVE_ENTRY(ClassMirror_invokeConstructor, 4) {
// Pretend we didn't find the constructor at all when the arity is wrong
// so as to produce the same NoSuchMethodError as the non-reflective case.
lookup_constructor = Function::null();
- ThrowNoSuchMethod(AbstractType::Handle(RawTypeOfClass(klass)),
+ ThrowNoSuchMethod(AbstractType::Handle(klass.RareType()),
internal_constructor_name,
lookup_constructor,
InvocationMirror::kConstructor,
@@ -1147,7 +1129,7 @@ DEFINE_NATIVE_ENTRY(ClassMirror_invokeConstructor, 4) {
// Pretend we didn't find the constructor at all when the arity is wrong
// so as to produce the same NoSuchMethodError as the non-reflective case.
redirected_constructor = Function::null();
- ThrowNoSuchMethod(AbstractType::Handle(RawTypeOfClass(klass)),
+ ThrowNoSuchMethod(AbstractType::Handle(klass.RareType()),
internal_constructor_name,
redirected_constructor,
InvocationMirror::kConstructor,
@@ -1155,19 +1137,27 @@ DEFINE_NATIVE_ENTRY(ClassMirror_invokeConstructor, 4) {
UNREACHABLE();
}
+ ASSERT(!type.IsNull());
+ const AbstractTypeArguments& type_arguments =
+ AbstractTypeArguments::Handle(type.arguments());
+
Instance& new_object = Instance::Handle();
if (redirected_constructor.IsConstructor()) {
// Constructors get the uninitialized object and a constructor phase. Note
// we have delayed allocation until after the function type and argument
// matching checks.
new_object = Instance::New(redirected_klass);
+ if (!type_arguments.IsNull()) {
+ // The type arguments will be null if the class has no type parameters, in
+ // which case the following call would fail because there is no slot
+ // reserved in the object for the type vector.
+ new_object.SetTypeArguments(type_arguments);
+ }
args.SetAt(0, new_object);
args.SetAt(1, Smi::Handle(Smi::New(Function::kCtorPhaseAll)));
} else {
// Factories get type arguments.
- // TODO(12921): Should we allow the user to specify type arguments? Use type
- // arguments from the mirror?
- args.SetAt(0, Object::null_abstract_type_arguments());
+ args.SetAt(0, type_arguments);
}
// Invoke the constructor and return the new object.
@@ -1347,12 +1337,8 @@ DEFINE_NATIVE_ENTRY(MethodMirror_owner, 1) {
return CreateLibraryMirror(Library::Handle(owner.library()));
}
- AbstractType& type = AbstractType::Handle();
- if (owner.NumTypeParameters() == 0) {
- // Include runtime type for non-generics only.
- type = RawTypeOfClass(owner);
- }
- return CreateClassMirror(owner, type, Object::null_instance());
+ Type& type = Type::Handle(owner.RareType());
+ return CreateClassMirror(owner, type, Bool::True(), Object::null_instance());
}
« no previous file with comments | « no previous file | runtime/lib/mirrors_impl.dart » ('j') | runtime/vm/object.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698