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

Unified Diff: runtime/lib/mirrors.cc

Issue 22292002: Reflection on generics. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: address generic equality Created 7 years, 4 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/lib/mirrors_impl.dart » ('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 874915f014d0e29471272f1eac0dc59dd4f5c090..b69d8208056496c0336442e9899fac6c4655784f 100644
--- a/runtime/lib/mirrors.cc
+++ b/runtime/lib/mirrors.cc
@@ -4,6 +4,7 @@
#include "lib/invocation_mirror.h"
#include "vm/bootstrap_natives.h"
+#include "vm/class_finalizer.h"
#include "vm/dart_entry.h"
#include "vm/exceptions.h"
#include "vm/object_store.h"
@@ -99,6 +100,7 @@ static RawInstance* CreateTypeVariableList(const Class& cls) {
static RawInstance* CreateTypedefMirror(const Class& cls,
+ const AbstractType& type,
regis 2013/08/08 17:06:34 Parameter 'type' added but not used? If it is for
rmacnak 2013/08/08 20:04:06 Leftover from intermediate implementation that com
const Instance& owner_mirror) {
const Array& args = Array::Handle(Array::New(3));
args.SetAt(0, MirrorReference::Handle(MirrorReference::New(cls)));
@@ -108,9 +110,11 @@ static RawInstance* CreateTypedefMirror(const Class& cls,
}
-static RawInstance* CreateFunctionTypeMirror(const Class& cls) {
- const Array& args = Array::Handle(Array::New(1));
+static RawInstance* CreateFunctionTypeMirror(const Class& cls,
+ const AbstractType& type) {
+ const Array& args = Array::Handle(Array::New(2));
args.SetAt(0, MirrorReference::Handle(MirrorReference::New(cls)));
+ args.SetAt(1, type);
return CreateMirror(Symbols::_LocalFunctionTypeMirrorImpl(), args);
}
@@ -155,24 +159,45 @@ static RawInstance* CreateVariableMirror(const Field& field,
static RawInstance* CreateClassMirror(const Class& cls,
+ const AbstractType& type,
const Instance& owner_mirror) {
if (cls.IsSignatureClass()) {
if (cls.IsCanonicalSignatureClass()) {
// We represent function types as canonical signature classes.
- return CreateFunctionTypeMirror(cls);
+ return CreateFunctionTypeMirror(cls, type);
} else {
// We represent typedefs as non-canonical signature classes.
- return CreateTypedefMirror(cls, owner_mirror);
+ return CreateTypedefMirror(cls, type, owner_mirror);
}
}
- const Array& args = Array::Handle(Array::New(2));
+ AbstractTypeArguments& type_parameters =
+ AbstractTypeArguments::Handle(cls.type_parameters());
+ const Bool& is_generic =
+ type_parameters.IsNull() || type_parameters.Length() == 0
regis 2013/08/08 17:06:34 We like parenthesis (a lot!). In any case, this wo
rmacnak 2013/08/08 20:04:06 Done.
+ ? Bool::False()
+ : Bool::True();
+
+ const Array& args = Array::Handle(Array::New(4));
args.SetAt(0, MirrorReference::Handle(MirrorReference::New(cls)));
- args.SetAt(1, String::Handle(cls.UserVisibleName()));
+ args.SetAt(1, type);
+ args.SetAt(2, String::Handle(cls.UserVisibleName()));
+ args.SetAt(3, is_generic);
return CreateMirror(Symbols::_LocalClassMirrorImpl(), args);
}
+// Note a "raw type" is not the same as a RawType.
+static RawAbstractType* RawTypeOfClass(const Class& klass) {
regis 2013/08/08 17:06:34 Why 'klass' and 'cls' elsewhere? I think 'cls' is
rmacnak 2013/08/08 20:04:06 Different authors. Switched to cls, as its use is
+ AbstractTypeArguments& type_arguments = AbstractTypeArguments::Handle();
regis 2013/08/08 17:06:34 You can save a handle and pass directly Object::nu
rmacnak 2013/08/08 20:04:06 Done.
+ Type& type =
+ Type::Handle(Type::New(klass, type_arguments, Scanner::kDummyTokenIndex));
+ return ClassFinalizer::FinalizeType(klass,
+ type,
+ ClassFinalizer::kCanonicalize);
+}
+
+
static RawInstance* CreateLibraryMirror(const Library& lib) {
const Array& args = Array::Handle(Array::New(3));
args.SetAt(0, MirrorReference::Handle(MirrorReference::New(lib)));
@@ -201,7 +226,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, Object::null_instance());
+ return CreateClassMirror(cls, type, Object::null_instance());
} else if (type.IsTypeParameter()) {
return CreateTypeVariableMirror(TypeParameter::Cast(type),
Object::null_instance());
@@ -259,7 +284,16 @@ DEFINE_NATIVE_ENTRY(Mirrors_makeLocalMirrorSystem, 0) {
DEFINE_NATIVE_ENTRY(Mirrors_makeLocalClassMirror, 1) {
GET_NON_NULL_NATIVE_ARGUMENT(Type, type, arguments->NativeArgAt(0));
const Class& cls = Class::Handle(type.type_class());
- return CreateClassMirror(cls, Object::null_instance());
+ ASSERT(!cls.IsNull());
+ return CreateClassMirror(cls,
+ AbstractType::Handle(),
+ Instance::null_instance());
+}
+
+
+DEFINE_NATIVE_ENTRY(Mirrors_makeLocalTypeMirror, 1) {
+ GET_NON_NULL_NATIVE_ARGUMENT(AbstractType, type, arguments->NativeArgAt(0));
+ return CreateTypeMirror(type);
}
@@ -335,8 +369,7 @@ 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);
+ return func.result_type();
}
@@ -499,7 +532,9 @@ DEFINE_NATIVE_ENTRY(LibraryMirror_members, 2) {
// The various implementations of public classes don't always have the
// expected superinterfaces or other properties, so we filter them out.
if (!RawObject::IsImplementationClassId(klass.id())) {
- member_mirror = CreateClassMirror(klass, owner_mirror);
+ member_mirror = CreateClassMirror(klass,
+ AbstractType::Handle(),
+ owner_mirror);
member_mirrors.Add(member_mirror);
}
}
@@ -529,16 +564,46 @@ DEFINE_NATIVE_ENTRY(ClassMirror_type_variables, 1) {
}
-DEFINE_NATIVE_ENTRY(LocalTypeVariableMirror_owner, 1) {
+DEFINE_NATIVE_ENTRY(ClassMirror_type_arguments, 1) {
+ GET_NON_NULL_NATIVE_ARGUMENT(AbstractType, type, arguments->NativeArgAt(0));
+
+ const AbstractTypeArguments& args =
+ AbstractTypeArguments::Handle(type.arguments());
+ if (args.IsNull()) {
+ return Object::empty_array().raw();
+ }
+
+ const Class& klass = Class::Handle(type.type_class());
+ const TypeArguments& params = TypeArguments::Handle(klass.type_parameters());
+ intptr_t num_params = 0;
+ if (!params.IsNull()) {
+ num_params = params.Length();
+ }
regis 2013/08/08 17:06:34 You can replace the above 5 lines with const intpt
rmacnak 2013/08/08 20:04:06 Done.
+ const intptr_t num_inherited_args = args.Length() - num_params;
+
+ const Array& result = Array::Handle(Array::New(num_params));
+ AbstractType& arg_type = AbstractType::Handle();
+ Instance& type_mirror = Instance::Handle();
+ for (intptr_t i = 0; i < num_params; i++) {
+ arg_type ^= args.TypeAt(i + num_inherited_args);
+ type_mirror = CreateTypeMirror(arg_type);
+ result.SetAt(i, type_mirror);
+ }
+ return result.raw();
+}
+
+
+DEFINE_NATIVE_ENTRY(TypeVariableMirror_owner, 1) {
GET_NON_NULL_NATIVE_ARGUMENT(TypeParameter, param, arguments->NativeArgAt(0));
return CreateClassMirror(Class::Handle(param.parameterized_class()),
+ AbstractType::Handle(),
Instance::null_instance());
}
-DEFINE_NATIVE_ENTRY(LocalTypeVariableMirror_upper_bound, 1) {
+DEFINE_NATIVE_ENTRY(TypeVariableMirror_upper_bound, 1) {
GET_NON_NULL_NATIVE_ARGUMENT(TypeParameter, param, arguments->NativeArgAt(0));
- return CreateTypeMirror(AbstractType::Handle(param.bound()));
+ return param.bound();
}
@@ -763,11 +828,7 @@ static void ThrowNoSuchMethod(const Class& klass,
const Function& function,
const InvocationMirror::Call call,
const InvocationMirror::Type type) {
- AbstractTypeArguments& type_arguments = AbstractTypeArguments::Handle();
- Type& pre_type = Type::Handle(
- Type::New(klass, type_arguments, Scanner::kDummyTokenIndex));
- pre_type.SetIsFinalized();
- AbstractType& runtime_type = AbstractType::Handle(pre_type.Canonicalize());
+ AbstractType& runtime_type = AbstractType::Handle(RawTypeOfClass(klass));
ThrowNoSuchMethod(runtime_type,
function_name,
@@ -1151,7 +1212,9 @@ DEFINE_NATIVE_ENTRY(MethodMirror_owner, 1) {
if (owner.IsTopLevel()) {
return CreateLibraryMirror(Library::Handle(owner.library()));
}
- return CreateClassMirror(owner, Object::null_instance());
+ return CreateClassMirror(owner,
+ AbstractType::Handle(),
+ Object::null_instance());
}
@@ -1167,8 +1230,7 @@ DEFINE_NATIVE_ENTRY(MethodMirror_return_type, 1) {
const Function& func = Function::Handle(ref.GetFunctionReferent());
// We handle constructors in Dart code.
ASSERT(!func.IsConstructor());
- const AbstractType& return_type = AbstractType::Handle(func.result_type());
- return CreateTypeMirror(return_type);
+ return func.result_type();
}
@@ -1185,18 +1247,14 @@ 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));
const Function& func = Function::Handle(ref.GetFunctionReferent());
- const AbstractType& param_type = AbstractType::Handle(func.ParameterTypeAt(
- func.NumImplicitParameters() + pos.Value()));
- return CreateTypeMirror(param_type);
+ return func.ParameterTypeAt(func.NumImplicitParameters() + pos.Value());
}
DEFINE_NATIVE_ENTRY(VariableMirror_type, 1) {
GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(0));
const Field& field = Field::Handle(ref.GetFieldReferent());
-
- const AbstractType& type = AbstractType::Handle(field.type());
- return CreateTypeMirror(type);
+ return field.type();
}
} // namespace dart
« no previous file with comments | « no previous file | runtime/lib/mirrors_impl.dart » ('j') | runtime/lib/mirrors_impl.dart » ('J')

Powered by Google App Engine
This is Rietveld 408576698