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

Unified Diff: runtime/vm/dart_api_impl.cc

Issue 10916252: Implement more of the mirrors library, primarily stuff to do with types. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 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
Index: runtime/vm/dart_api_impl.cc
===================================================================
--- runtime/vm/dart_api_impl.cc (revision 11702)
+++ runtime/vm/dart_api_impl.cc (working copy)
@@ -284,6 +284,29 @@
}
+// When we want to return a handle to a type to the user, we handle
+// class-types differently than some other types.
+static Dart_Handle TypeToHandle(Isolate* isolate,
+ const char* function_name,
+ const AbstractType& type) {
+ if (type.HasResolvedTypeClass()) {
+ const Class& cls = Class::Handle(isolate, type.type_class());
+#if defined(DEBUG)
+ const Library& lib = Library::Handle(cls.library());
+ if (lib.IsNull()) {
+ ASSERT(cls.IsDynamicClass() || cls.IsVoidClass());
+ }
+#endif
+ return Api::NewHandle(isolate, cls.raw());
+ } else if (type.IsTypeParameter()) {
+ return Api::NewHandle(isolate, type.raw());
+ } else {
+ return Api::NewError("%s: unexpected type '%s' encountered.",
+ function_name, type.ToCString());
+ }
+}
+
+
// --- Handles ---
@@ -2461,7 +2484,10 @@
#if defined(DEBUG)
const Library& lib = Library::Handle(cls.library());
if (lib.IsNull()) {
- ASSERT(cls.IsDynamicClass() || cls.IsVoidClass());
+ // ASSERT(cls.IsDynamicClass() || cls.IsVoidClass());
+ if (!cls.IsDynamicClass() && !cls.IsVoidClass()) {
+ fprintf(stderr, "NO LIBRARY: %s\n", cls.ToCString());
+ }
}
#endif
@@ -2540,6 +2566,69 @@
}
+DART_EXPORT bool Dart_ClassIsTypedef(Dart_Handle clazz) {
+ Isolate* isolate = Isolate::Current();
+ DARTSCOPE(isolate);
+ const Class& cls = Api::UnwrapClassHandle(isolate, clazz);
+ if (cls.IsNull()) {
+ RETURN_TYPE_ERROR(isolate, clazz, Class);
+ }
+ // For now we represent typedefs as non-canonical signature classes.
+ // I anticipate this may change if we make typedefs more general.
+ return cls.IsSignatureClass() && !cls.IsCanonicalSignatureClass();
+}
+
+
+DART_EXPORT Dart_Handle Dart_ClassGetTypedefReferent(Dart_Handle clazz) {
+ Isolate* isolate = Isolate::Current();
+ DARTSCOPE(isolate);
+ const Class& cls = Api::UnwrapClassHandle(isolate, clazz);
+ if (cls.IsNull()) {
+ RETURN_TYPE_ERROR(isolate, clazz, Class);
+ }
+
+ if (!cls.IsSignatureClass() && !cls.IsCanonicalSignatureClass()) {
+ const String& cls_name = String::Handle(cls.UserVisibleName());
+ return Api::NewError("%s: class '%s' is not a typedef class. "
+ "See Dart_ClassIsTypedef.",
+ CURRENT_FUNC, cls_name.ToCString());
+ }
+
+ const Function& func = Function::Handle(isolate, cls.signature_function());
+ return Api::NewHandle(isolate, func.signature_class());
+}
+
+
+DART_EXPORT bool Dart_ClassIsFunctionType(Dart_Handle clazz) {
+ Isolate* isolate = Isolate::Current();
+ DARTSCOPE(isolate);
+ const Class& cls = Api::UnwrapClassHandle(isolate, clazz);
+ if (cls.IsNull()) {
+ RETURN_TYPE_ERROR(isolate, clazz, Class);
+ }
+ // A class represents a function type when it is a canonical
+ // signature class.
+ return cls.IsCanonicalSignatureClass();
+}
+
+
+DART_EXPORT Dart_Handle Dart_ClassGetFunctionTypeSignature(Dart_Handle clazz) {
+ Isolate* isolate = Isolate::Current();
+ DARTSCOPE(isolate);
+ const Class& cls = Api::UnwrapClassHandle(isolate, clazz);
+ if (cls.IsNull()) {
+ RETURN_TYPE_ERROR(isolate, clazz, Class);
+ }
+ if (!cls.IsCanonicalSignatureClass()) {
+ const String& cls_name = String::Handle(cls.UserVisibleName());
+ return Api::NewError("%s: class '%s' is not a function-type class. "
+ "See Dart_ClassIsFunctionType.",
+ CURRENT_FUNC, cls_name.ToCString());
+ }
+ return Api::NewHandle(isolate, cls.signature_function());
+}
+
+
// --- Function and Variable Reflection ---
@@ -2817,6 +2906,28 @@
}
+DART_EXPORT Dart_Handle Dart_FunctionReturnType(Dart_Handle function) {
+ Isolate* isolate = Isolate::Current();
+ DARTSCOPE(isolate);
+ const Function& func = Api::UnwrapFunctionHandle(isolate, function);
+ if (func.IsNull()) {
+ RETURN_TYPE_ERROR(isolate, function, Function);
+ }
+
+ if (func.kind() == RawFunction::kConstructor) {
+ // Special case the return type for constructors. Inside the vm
+ // we mark them as returning Dynamic, but for the purposes of
+ // reflection, they return the type of the class being
+ // constructed.
+ return Api::NewHandle(isolate, func.Owner());
+ } else {
+ const AbstractType& return_type =
+ AbstractType::Handle(isolate, func.result_type());
+ return TypeToHandle(isolate, "Dart_FunctionReturnType", return_type);
+ }
+}
+
+
DART_EXPORT Dart_Handle Dart_FunctionParameterCounts(
Dart_Handle function,
int64_t* fixed_param_count,
@@ -2848,6 +2959,30 @@
}
+DART_EXPORT Dart_Handle Dart_FunctionParameterType(Dart_Handle function,
+ int parameter_index) {
+ Isolate* isolate = Isolate::Current();
+ DARTSCOPE(isolate);
+ const Function& func = Api::UnwrapFunctionHandle(isolate, function);
+ if (func.IsNull()) {
+ RETURN_TYPE_ERROR(isolate, function, Function);
+ }
+
+ const intptr_t num_implicit_params = func.NumberOfImplicitParameters();
+ const intptr_t num_params = func.NumberOfParameters() - num_implicit_params;
+ if (parameter_index < 0 || parameter_index >= num_params) {
+ return Api::NewError(
+ "%s: argument 'parameter_index' out of range. "
+ "Expected 0..%d but saw %d.",
+ CURRENT_FUNC, num_params, parameter_index);
+ }
+ const AbstractType& param_type =
+ AbstractType::Handle(isolate, func.ParameterTypeAt(
+ num_implicit_params + parameter_index));
+ return TypeToHandle(isolate, "Dart_FunctionParameterType", param_type);
+}
+
+
DART_EXPORT Dart_Handle Dart_GetVariableNames(Dart_Handle target) {
Isolate* isolate = Isolate::Current();
DARTSCOPE(isolate);
@@ -2971,6 +3106,122 @@
return Api::Success(isolate);
}
+
+DART_EXPORT Dart_Handle Dart_VariableType(Dart_Handle variable) {
+ Isolate* isolate = Isolate::Current();
+ DARTSCOPE(isolate);
+ const Field& var = Api::UnwrapFieldHandle(isolate, variable);
+ if (var.IsNull()) {
+ RETURN_TYPE_ERROR(isolate, variable, Field);
+ }
+
+ const AbstractType& type = AbstractType::Handle(isolate, var.type());
+ return TypeToHandle(isolate, "Dart_VariableType", type);
+}
+
+
+DART_EXPORT Dart_Handle Dart_GetTypeVariableNames(Dart_Handle clazz) {
+ Isolate* isolate = Isolate::Current();
+ DARTSCOPE(isolate);
+ const Class& cls = Api::UnwrapClassHandle(isolate, clazz);
+ if (cls.IsNull()) {
+ RETURN_TYPE_ERROR(isolate, clazz, Class);
+ }
+
+ const intptr_t num_type_params = cls.NumTypeParameters();
+ const TypeArguments& type_params =
+ TypeArguments::Handle(cls.type_parameters());
+
+ const GrowableObjectArray& names =
+ GrowableObjectArray::Handle(isolate, GrowableObjectArray::New());
+ TypeParameter& type_param = TypeParameter::Handle(isolate);
+ String& name = String::Handle(isolate);
+ for (intptr_t i = 0; i < num_type_params; i++) {
+ type_param ^= type_params.TypeAt(i);
+ name = type_param.name();
+ names.Add(name);
+ }
+ return Api::NewHandle(isolate, Array::MakeArray(names));
+}
+
+
+DART_EXPORT Dart_Handle Dart_LookupTypeVariable(
+ Dart_Handle clazz,
+ Dart_Handle type_variable_name) {
+ Isolate* isolate = Isolate::Current();
+ DARTSCOPE(isolate);
+ const Class& cls = Api::UnwrapClassHandle(isolate, clazz);
+ if (cls.IsNull()) {
+ RETURN_TYPE_ERROR(isolate, clazz, Class);
+ }
+ const String& var_name = Api::UnwrapStringHandle(isolate, type_variable_name);
+ if (var_name.IsNull()) {
+ RETURN_TYPE_ERROR(isolate, type_variable_name, String);
+ }
+
+ const intptr_t num_type_params = cls.NumTypeParameters();
+ const TypeArguments& type_params =
+ TypeArguments::Handle(cls.type_parameters());
+
+ TypeParameter& type_param = TypeParameter::Handle(isolate);
+ String& name = String::Handle(isolate);
+ for (intptr_t i = 0; i < num_type_params; i++) {
+ type_param ^= type_params.TypeAt(i);
+ name = type_param.name();
+ if (name.Equals(var_name)) {
+ return Api::NewHandle(isolate, type_param.raw());
+ }
+ }
+ const String& cls_name = String::Handle(cls.UserVisibleName());
+ return Api::NewError(
+ "%s: Could not find type variable named '%s' for class %s.\n",
+ var_name.ToCString(), cls_name.ToCString());
+}
+
+
+DART_EXPORT bool Dart_IsTypeVariable(Dart_Handle handle) {
+ return Api::ClassId(handle) == kTypeParameterCid;
+}
+
+DART_EXPORT Dart_Handle Dart_TypeVariableName(Dart_Handle type_variable) {
+ Isolate* isolate = Isolate::Current();
+ DARTSCOPE(isolate);
+ const TypeParameter& type_var =
+ Api::UnwrapTypeParameterHandle(isolate, type_variable);
+ if (type_var.IsNull()) {
+ RETURN_TYPE_ERROR(isolate, type_variable, TypeParameter);
+ }
+ return Api::NewHandle(isolate, type_var.name());
+}
+
+
+DART_EXPORT Dart_Handle Dart_TypeVariableOwner(Dart_Handle type_variable) {
+ Isolate* isolate = Isolate::Current();
+ DARTSCOPE(isolate);
+ const TypeParameter& type_var =
+ Api::UnwrapTypeParameterHandle(isolate, type_variable);
+ if (type_var.IsNull()) {
+ RETURN_TYPE_ERROR(isolate, type_variable, TypeParameter);
+ }
+ const Class& owner = Class::Handle(type_var.parameterized_class());
+ ASSERT(!owner.IsNull() && owner.IsClass());
+ return Api::NewHandle(isolate, owner.raw());
+}
+
+
+DART_EXPORT Dart_Handle Dart_TypeVariableUpperBound(Dart_Handle type_variable) {
+ Isolate* isolate = Isolate::Current();
+ DARTSCOPE(isolate);
+ const TypeParameter& type_var =
+ Api::UnwrapTypeParameterHandle(isolate, type_variable);
+ if (type_var.IsNull()) {
+ RETURN_TYPE_ERROR(isolate, type_variable, TypeParameter);
+ }
+ const AbstractType& bound = AbstractType::Handle(type_var.bound());
+ return TypeToHandle(isolate, "Dart_TypeVariableUpperBound", bound);
+}
+
+
// --- Constructors, Methods, and Fields ---
@@ -3976,11 +4227,15 @@
String& name = String::Handle();
while (it.HasNext()) {
cls = it.GetNextClass();
- // For now we suppress the signature classes of closures.
- //
- // TODO(turnidge): Add this to the unit test.
- const Function& signature_func = Function::Handle(cls.signature_function());
- if (signature_func.IsNull()) {
+ if (cls.IsSignatureClass()) {
+ if (!cls.IsCanonicalSignatureClass()) {
+ // This is a typedef. Add it to the list of class names.
+ name = cls.UserVisibleName();
+ names.Add(name);
+ } else {
+ // Skip canonical signature classes. These are not named.
+ }
+ } else {
name = cls.UserVisibleName();
names.Add(name);
}

Powered by Google App Engine
This is Rietveld 408576698