| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "include/dart_mirrors_api.h" | 5 #include "include/dart_mirrors_api.h" |
| 6 | 6 |
| 7 #include "platform/assert.h" | 7 #include "platform/assert.h" |
| 8 #include "vm/class_finalizer.h" | 8 #include "vm/class_finalizer.h" |
| 9 #include "vm/dart.h" | 9 #include "vm/dart.h" |
| 10 #include "vm/dart_api_impl.h" | 10 #include "vm/dart_api_impl.h" |
| 11 #include "vm/dart_api_state.h" | 11 #include "vm/dart_api_state.h" |
| 12 #include "vm/dart_entry.h" | 12 #include "vm/dart_entry.h" |
| 13 #include "vm/exceptions.h" | 13 #include "vm/exceptions.h" |
| 14 #include "vm/growable_array.h" | 14 #include "vm/growable_array.h" |
| 15 #include "vm/object.h" | 15 #include "vm/object.h" |
| 16 #include "vm/resolver.h" | 16 #include "vm/resolver.h" |
| 17 #include "vm/stack_frame.h" | 17 #include "vm/stack_frame.h" |
| 18 #include "vm/symbols.h" | 18 #include "vm/symbols.h" |
| 19 | 19 |
| 20 namespace dart { | 20 namespace dart { |
| 21 | 21 |
| 22 // When we want to return a handle to a type to the user, we handle | |
| 23 // class-types differently than some other types. | |
| 24 static Dart_Handle TypeToHandle(Isolate* isolate, | |
| 25 const char* function_name, | |
| 26 const AbstractType& type) { | |
| 27 if (type.IsMalformed()) { | |
| 28 const Error& error = Error::Handle(type.malformed_error()); | |
| 29 return Api::NewError("%s: malformed type encountered: %s.", | |
| 30 function_name, error.ToErrorCString()); | |
| 31 } else if (type.HasResolvedTypeClass()) { | |
| 32 const Class& cls = Class::Handle(isolate, type.type_class()); | |
| 33 #if defined(DEBUG) | |
| 34 const Library& lib = Library::Handle(cls.library()); | |
| 35 if (lib.IsNull()) { | |
| 36 ASSERT(cls.IsDynamicClass() || cls.IsVoidClass()); | |
| 37 } | |
| 38 #endif | |
| 39 return Api::NewHandle(isolate, cls.raw()); | |
| 40 } else if (type.IsTypeParameter()) { | |
| 41 return Api::NewHandle(isolate, type.raw()); | |
| 42 } else { | |
| 43 return Api::NewError("%s: unexpected type '%s' encountered.", | |
| 44 function_name, type.ToCString()); | |
| 45 } | |
| 46 } | |
| 47 | |
| 48 | 22 |
| 49 // --- Classes and Interfaces Reflection --- | 23 // --- Classes and Interfaces Reflection --- |
| 50 | 24 |
| 51 DART_EXPORT Dart_Handle Dart_ClassName(Dart_Handle object) { | 25 DART_EXPORT Dart_Handle Dart_ClassName(Dart_Handle object) { |
| 52 Isolate* isolate = Isolate::Current(); | 26 Isolate* isolate = Isolate::Current(); |
| 53 DARTSCOPE(isolate); | 27 DARTSCOPE(isolate); |
| 54 const Object& obj = Object::Handle(isolate, Api::UnwrapHandle(object)); | 28 const Object& obj = Object::Handle(isolate, Api::UnwrapHandle(object)); |
| 55 if (obj.IsType() || obj.IsClass()) { | 29 if (obj.IsType() || obj.IsClass()) { |
| 56 const Class& cls = (obj.IsType()) ? | 30 const Class& cls = (obj.IsType()) ? |
| 57 Class::Handle(Type::Cast(obj).type_class()) : Class::Cast(obj); | 31 Class::Handle(Type::Cast(obj).type_class()) : Class::Cast(obj); |
| 58 return Api::NewHandle(isolate, cls.UserVisibleName()); | 32 return Api::NewHandle(isolate, cls.UserVisibleName()); |
| 59 } else { | 33 } else { |
| 60 RETURN_TYPE_ERROR(isolate, object, Class/Type); | 34 RETURN_TYPE_ERROR(isolate, object, Class/Type); |
| 61 } | 35 } |
| 62 } | 36 } |
| 63 | 37 |
| 64 | |
| 65 DART_EXPORT Dart_Handle Dart_ClassGetLibrary(Dart_Handle object) { | |
| 66 Isolate* isolate = Isolate::Current(); | |
| 67 DARTSCOPE(isolate); | |
| 68 const Object& obj = Object::Handle(isolate, Api::UnwrapHandle(object)); | |
| 69 if (!obj.IsType() && !obj.IsClass()) { | |
| 70 RETURN_TYPE_ERROR(isolate, object, Class/Type); | |
| 71 } | |
| 72 const Class& cls = (obj.IsType()) ? | |
| 73 Class::Handle(Type::Cast(obj).type_class()) : Class::Cast(obj); | |
| 74 | |
| 75 #if defined(DEBUG) | |
| 76 const Library& lib = Library::Handle(cls.library()); | |
| 77 if (lib.IsNull()) { | |
| 78 // ASSERT(cls.IsDynamicClass() || cls.IsVoidClass()); | |
| 79 if (!cls.IsDynamicClass() && !cls.IsVoidClass()) { | |
| 80 fprintf(stderr, "NO LIBRARY: %s\n", cls.ToCString()); | |
| 81 } | |
| 82 } | |
| 83 #endif | |
| 84 | |
| 85 return Api::NewHandle(isolate, cls.library()); | |
| 86 } | |
| 87 | |
| 88 | |
| 89 DART_EXPORT Dart_Handle Dart_ClassGetInterfaceCount(Dart_Handle object, | |
| 90 intptr_t* count) { | |
| 91 Isolate* isolate = Isolate::Current(); | |
| 92 DARTSCOPE(isolate); | |
| 93 const Object& obj = Object::Handle(isolate, Api::UnwrapHandle(object)); | |
| 94 if (!obj.IsType() && !obj.IsClass()) { | |
| 95 RETURN_TYPE_ERROR(isolate, object, Class/Type); | |
| 96 } | |
| 97 const Class& cls = (obj.IsType()) ? | |
| 98 Class::Handle(Type::Cast(obj).type_class()) : Class::Cast(obj); | |
| 99 const Array& interface_types = Array::Handle(isolate, cls.interfaces()); | |
| 100 if (interface_types.IsNull()) { | |
| 101 *count = 0; | |
| 102 } else { | |
| 103 *count = interface_types.Length(); | |
| 104 } | |
| 105 return Api::Success(); | |
| 106 } | |
| 107 | |
| 108 | |
| 109 DART_EXPORT Dart_Handle Dart_ClassGetInterfaceAt(Dart_Handle object, | |
| 110 intptr_t index) { | |
| 111 Isolate* isolate = Isolate::Current(); | |
| 112 DARTSCOPE(isolate); | |
| 113 const Object& obj = Object::Handle(isolate, Api::UnwrapHandle(object)); | |
| 114 if (!obj.IsType() && !obj.IsClass()) { | |
| 115 RETURN_TYPE_ERROR(isolate, object, Class/Type); | |
| 116 } | |
| 117 const Class& cls = (obj.IsType()) ? | |
| 118 Class::Handle(Type::Cast(obj).type_class()) : Class::Cast(obj); | |
| 119 | |
| 120 // Finalize all classes. | |
| 121 Dart_Handle state = Api::CheckIsolateState(isolate); | |
| 122 if (::Dart_IsError(state)) { | |
| 123 return state; | |
| 124 } | |
| 125 | |
| 126 const Array& interface_types = Array::Handle(isolate, cls.interfaces()); | |
| 127 if (index < 0 || index >= interface_types.Length()) { | |
| 128 return Api::NewError("%s: argument 'index' out of bounds.", CURRENT_FUNC); | |
| 129 } | |
| 130 Type& interface_type = Type::Handle(isolate); | |
| 131 interface_type ^= interface_types.At(index); | |
| 132 if (interface_type.HasResolvedTypeClass()) { | |
| 133 return Api::NewHandle(isolate, interface_type.type_class()); | |
| 134 } | |
| 135 const String& type_name = | |
| 136 String::Handle(isolate, interface_type.TypeClassName()); | |
| 137 return Api::NewError("%s: internal error: found unresolved type class '%s'.", | |
| 138 CURRENT_FUNC, type_name.ToCString()); | |
| 139 } | |
| 140 | |
| 141 | |
| 142 DART_EXPORT bool Dart_ClassIsTypedef(Dart_Handle object) { | |
| 143 Isolate* isolate = Isolate::Current(); | |
| 144 DARTSCOPE(isolate); | |
| 145 const Object& obj = Object::Handle(isolate, Api::UnwrapHandle(object)); | |
| 146 if (!obj.IsType() && !obj.IsClass()) { | |
| 147 RETURN_TYPE_ERROR(isolate, object, Class/Type); | |
| 148 } | |
| 149 const Class& cls = (obj.IsType()) ? | |
| 150 Class::Handle(Type::Cast(obj).type_class()) : Class::Cast(obj); | |
| 151 // For now we represent typedefs as non-canonical signature classes. | |
| 152 // I anticipate this may change if we make typedefs more general. | |
| 153 return cls.IsSignatureClass() && !cls.IsCanonicalSignatureClass(); | |
| 154 } | |
| 155 | |
| 156 | |
| 157 DART_EXPORT Dart_Handle Dart_ClassGetTypedefReferent(Dart_Handle object) { | |
| 158 Isolate* isolate = Isolate::Current(); | |
| 159 DARTSCOPE(isolate); | |
| 160 const Object& obj = Object::Handle(isolate, Api::UnwrapHandle(object)); | |
| 161 if (!obj.IsType() && !obj.IsClass()) { | |
| 162 RETURN_TYPE_ERROR(isolate, object, Class/Type); | |
| 163 } | |
| 164 const Class& cls = (obj.IsType()) ? | |
| 165 Class::Handle(Type::Cast(obj).type_class()) : Class::Cast(obj); | |
| 166 if (!cls.IsSignatureClass() && !cls.IsCanonicalSignatureClass()) { | |
| 167 const String& cls_name = String::Handle(cls.UserVisibleName()); | |
| 168 return Api::NewError("%s: class '%s' is not a typedef class. " | |
| 169 "See Dart_ClassIsTypedef.", | |
| 170 CURRENT_FUNC, cls_name.ToCString()); | |
| 171 } | |
| 172 | |
| 173 const Function& func = Function::Handle(isolate, cls.signature_function()); | |
| 174 return Api::NewHandle(isolate, func.signature_class()); | |
| 175 } | |
| 176 | |
| 177 | |
| 178 DART_EXPORT bool Dart_ClassIsFunctionType(Dart_Handle object) { | |
| 179 Isolate* isolate = Isolate::Current(); | |
| 180 DARTSCOPE(isolate); | |
| 181 const Object& obj = Object::Handle(isolate, Api::UnwrapHandle(object)); | |
| 182 if (!obj.IsType() && !obj.IsClass()) { | |
| 183 RETURN_TYPE_ERROR(isolate, object, Class/Type); | |
| 184 } | |
| 185 // Ensure all classes are finalized. | |
| 186 Dart_Handle state = Api::CheckIsolateState(isolate); | |
| 187 if (::Dart_IsError(state)) { | |
| 188 return state; | |
| 189 } | |
| 190 const Class& cls = (obj.IsType()) ? | |
| 191 Class::Handle(Type::Cast(obj).type_class()) : Class::Cast(obj); | |
| 192 // A class represents a function type when it is a canonical | |
| 193 // signature class. | |
| 194 return cls.IsCanonicalSignatureClass(); | |
| 195 } | |
| 196 | |
| 197 | |
| 198 DART_EXPORT Dart_Handle Dart_ClassGetFunctionTypeSignature(Dart_Handle object) { | |
| 199 Isolate* isolate = Isolate::Current(); | |
| 200 DARTSCOPE(isolate); | |
| 201 const Object& obj = Object::Handle(isolate, Api::UnwrapHandle(object)); | |
| 202 if (!obj.IsType() && !obj.IsClass()) { | |
| 203 RETURN_TYPE_ERROR(isolate, object, Class/Type); | |
| 204 } | |
| 205 const Class& cls = (obj.IsType()) ? | |
| 206 Class::Handle(Type::Cast(obj).type_class()) : Class::Cast(obj); | |
| 207 if (!cls.IsCanonicalSignatureClass()) { | |
| 208 const String& cls_name = String::Handle(cls.UserVisibleName()); | |
| 209 return Api::NewError("%s: class '%s' is not a function-type class. " | |
| 210 "See Dart_ClassIsFunctionType.", | |
| 211 CURRENT_FUNC, cls_name.ToCString()); | |
| 212 } | |
| 213 return Api::NewHandle(isolate, cls.signature_function()); | |
| 214 } | |
| 215 | |
| 216 | |
| 217 // --- Function and Variable Reflection --- | 38 // --- Function and Variable Reflection --- |
| 218 | 39 |
| 219 // Outside of the vm, we expose setter names with a trailing '='. | 40 // Outside of the vm, we expose setter names with a trailing '='. |
| 220 static bool HasExternalSetterSuffix(const String& name) { | 41 static bool HasExternalSetterSuffix(const String& name) { |
| 221 return name.CharAt(name.Length() - 1) == '='; | 42 return name.CharAt(name.Length() - 1) == '='; |
| 222 } | 43 } |
| 223 | 44 |
| 224 | 45 |
| 225 static RawString* RemoveExternalSetterSuffix(const String& name) { | 46 static RawString* RemoveExternalSetterSuffix(const String& name) { |
| 226 ASSERT(HasExternalSetterSuffix(name)); | 47 ASSERT(HasExternalSetterSuffix(name)); |
| (...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 416 ASSERT(owner.IsDynamicClass() || owner.IsVoidClass()); | 237 ASSERT(owner.IsDynamicClass() || owner.IsVoidClass()); |
| 417 } | 238 } |
| 418 #endif | 239 #endif |
| 419 return Api::NewHandle(isolate, owner.library()); | 240 return Api::NewHandle(isolate, owner.library()); |
| 420 } else { | 241 } else { |
| 421 return Api::NewHandle(isolate, owner.raw()); | 242 return Api::NewHandle(isolate, owner.raw()); |
| 422 } | 243 } |
| 423 } | 244 } |
| 424 | 245 |
| 425 | 246 |
| 426 DART_EXPORT Dart_Handle Dart_FunctionIsAbstract(Dart_Handle function, | |
| 427 bool* is_abstract) { | |
| 428 Isolate* isolate = Isolate::Current(); | |
| 429 DARTSCOPE(isolate); | |
| 430 if (is_abstract == NULL) { | |
| 431 RETURN_NULL_ERROR(is_abstract); | |
| 432 } | |
| 433 const Function& func = Api::UnwrapFunctionHandle(isolate, function); | |
| 434 if (func.IsNull()) { | |
| 435 RETURN_TYPE_ERROR(isolate, function, Function); | |
| 436 } | |
| 437 *is_abstract = func.is_abstract(); | |
| 438 return Api::Success(); | |
| 439 } | |
| 440 | |
| 441 | |
| 442 DART_EXPORT Dart_Handle Dart_FunctionIsStatic(Dart_Handle function, | 247 DART_EXPORT Dart_Handle Dart_FunctionIsStatic(Dart_Handle function, |
| 443 bool* is_static) { | 248 bool* is_static) { |
| 444 Isolate* isolate = Isolate::Current(); | 249 Isolate* isolate = Isolate::Current(); |
| 445 DARTSCOPE(isolate); | 250 DARTSCOPE(isolate); |
| 446 if (is_static == NULL) { | 251 if (is_static == NULL) { |
| 447 RETURN_NULL_ERROR(is_static); | 252 RETURN_NULL_ERROR(is_static); |
| 448 } | 253 } |
| 449 const Function& func = Api::UnwrapFunctionHandle(isolate, function); | 254 const Function& func = Api::UnwrapFunctionHandle(isolate, function); |
| 450 if (func.IsNull()) { | 255 if (func.IsNull()) { |
| 451 RETURN_TYPE_ERROR(isolate, function, Function); | 256 RETURN_TYPE_ERROR(isolate, function, Function); |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 496 } | 301 } |
| 497 const Function& func = Api::UnwrapFunctionHandle(isolate, function); | 302 const Function& func = Api::UnwrapFunctionHandle(isolate, function); |
| 498 if (func.IsNull()) { | 303 if (func.IsNull()) { |
| 499 RETURN_TYPE_ERROR(isolate, function, Function); | 304 RETURN_TYPE_ERROR(isolate, function, Function); |
| 500 } | 305 } |
| 501 *is_setter = (func.kind() == RawFunction::kSetterFunction); | 306 *is_setter = (func.kind() == RawFunction::kSetterFunction); |
| 502 return Api::Success(); | 307 return Api::Success(); |
| 503 } | 308 } |
| 504 | 309 |
| 505 | 310 |
| 506 DART_EXPORT Dart_Handle Dart_FunctionReturnType(Dart_Handle function) { | |
| 507 Isolate* isolate = Isolate::Current(); | |
| 508 DARTSCOPE(isolate); | |
| 509 const Function& func = Api::UnwrapFunctionHandle(isolate, function); | |
| 510 if (func.IsNull()) { | |
| 511 RETURN_TYPE_ERROR(isolate, function, Function); | |
| 512 } | |
| 513 // Ensure all classes are finalized. | |
| 514 Dart_Handle state = Api::CheckIsolateState(isolate); | |
| 515 if (::Dart_IsError(state)) { | |
| 516 return state; | |
| 517 } | |
| 518 if (func.kind() == RawFunction::kConstructor) { | |
| 519 // Special case the return type for constructors. Inside the vm | |
| 520 // we mark them as returning dynamic, but for the purposes of | |
| 521 // reflection, they return the type of the class being | |
| 522 // constructed. | |
| 523 return Api::NewHandle(isolate, func.Owner()); | |
| 524 } else { | |
| 525 const AbstractType& return_type = | |
| 526 AbstractType::Handle(isolate, func.result_type()); | |
| 527 return TypeToHandle(isolate, "Dart_FunctionReturnType", return_type); | |
| 528 } | |
| 529 } | |
| 530 | |
| 531 | |
| 532 DART_EXPORT Dart_Handle Dart_FunctionParameterCounts( | |
| 533 Dart_Handle function, | |
| 534 int64_t* fixed_param_count, | |
| 535 int64_t* opt_param_count) { | |
| 536 Isolate* isolate = Isolate::Current(); | |
| 537 DARTSCOPE(isolate); | |
| 538 if (fixed_param_count == NULL) { | |
| 539 RETURN_NULL_ERROR(fixed_param_count); | |
| 540 } | |
| 541 if (opt_param_count == NULL) { | |
| 542 RETURN_NULL_ERROR(opt_param_count); | |
| 543 } | |
| 544 const Function& func = Api::UnwrapFunctionHandle(isolate, function); | |
| 545 if (func.IsNull()) { | |
| 546 RETURN_TYPE_ERROR(isolate, function, Function); | |
| 547 } | |
| 548 | |
| 549 // We hide implicit parameters, such as a method's receiver. This is | |
| 550 // consistent with Invoke or New, which don't expect their callers to | |
| 551 // provide them in the argument lists they are handed. | |
| 552 *fixed_param_count = func.num_fixed_parameters() - | |
| 553 func.NumImplicitParameters(); | |
| 554 // TODO(regis): Separately report named and positional optional param counts. | |
| 555 *opt_param_count = func.NumOptionalParameters(); | |
| 556 | |
| 557 ASSERT(*fixed_param_count >= 0); | |
| 558 ASSERT(*opt_param_count >= 0); | |
| 559 | |
| 560 return Api::Success(); | |
| 561 } | |
| 562 | |
| 563 | |
| 564 DART_EXPORT Dart_Handle Dart_FunctionParameterType(Dart_Handle function, | |
| 565 int parameter_index) { | |
| 566 Isolate* isolate = Isolate::Current(); | |
| 567 DARTSCOPE(isolate); | |
| 568 const Function& func = Api::UnwrapFunctionHandle(isolate, function); | |
| 569 if (func.IsNull()) { | |
| 570 RETURN_TYPE_ERROR(isolate, function, Function); | |
| 571 } | |
| 572 // Ensure all classes are finalized. | |
| 573 Dart_Handle state = Api::CheckIsolateState(isolate); | |
| 574 if (::Dart_IsError(state)) { | |
| 575 return state; | |
| 576 } | |
| 577 const intptr_t num_implicit_params = func.NumImplicitParameters(); | |
| 578 const intptr_t num_params = func.NumParameters() - num_implicit_params; | |
| 579 if (parameter_index < 0 || parameter_index >= num_params) { | |
| 580 return Api::NewError( | |
| 581 "%s: argument 'parameter_index' out of range. " | |
| 582 "Expected 0..%"Pd" but saw %d.", | |
| 583 CURRENT_FUNC, num_params, parameter_index); | |
| 584 } | |
| 585 const AbstractType& param_type = | |
| 586 AbstractType::Handle(isolate, func.ParameterTypeAt( | |
| 587 num_implicit_params + parameter_index)); | |
| 588 return TypeToHandle(isolate, "Dart_FunctionParameterType", param_type); | |
| 589 } | |
| 590 | |
| 591 | |
| 592 DART_EXPORT Dart_Handle Dart_GetVariableNames(Dart_Handle target) { | |
| 593 Isolate* isolate = Isolate::Current(); | |
| 594 DARTSCOPE(isolate); | |
| 595 const Object& obj = Object::Handle(isolate, Api::UnwrapHandle(target)); | |
| 596 if (obj.IsError()) { | |
| 597 return target; | |
| 598 } | |
| 599 | |
| 600 const GrowableObjectArray& names = | |
| 601 GrowableObjectArray::Handle(isolate, GrowableObjectArray::New()); | |
| 602 Field& field = Field::Handle(isolate); | |
| 603 String& name = String::Handle(isolate); | |
| 604 | |
| 605 if (obj.IsType() || obj.IsClass()) { | |
| 606 // For backwards compatibility we allow class objects to be passed in | |
| 607 // for now. This needs to be removed once all code that uses class | |
| 608 // objects to invoke Dart_Invoke is removed. | |
| 609 const Class& cls = (obj.IsType()) ? | |
| 610 Class::Handle(Type::Cast(obj).type_class()) : Class::Cast(obj); | |
| 611 const Error& error = Error::Handle(isolate, cls.EnsureIsFinalized(isolate)); | |
| 612 if (!error.IsNull()) { | |
| 613 return Api::NewHandle(isolate, error.raw()); | |
| 614 } | |
| 615 const Array& field_array = Array::Handle(cls.fields()); | |
| 616 | |
| 617 // Some special types like 'dynamic' have a null fields list. | |
| 618 // | |
| 619 // TODO(turnidge): Fix 'dynamic' so that it does not have a null | |
| 620 // fields list. This will have to wait until the empty array is | |
| 621 // allocated in the vm isolate. | |
| 622 if (!field_array.IsNull()) { | |
| 623 for (intptr_t i = 0; i < field_array.Length(); ++i) { | |
| 624 field ^= field_array.At(i); | |
| 625 name = field.UserVisibleName(); | |
| 626 names.Add(name); | |
| 627 } | |
| 628 } | |
| 629 } else if (obj.IsLibrary()) { | |
| 630 const Library& lib = Library::Cast(obj); | |
| 631 DictionaryIterator it(lib); | |
| 632 Object& obj = Object::Handle(isolate); | |
| 633 while (it.HasNext()) { | |
| 634 obj = it.GetNext(); | |
| 635 if (obj.IsField()) { | |
| 636 field ^= obj.raw(); | |
| 637 name = field.UserVisibleName(); | |
| 638 names.Add(name); | |
| 639 } | |
| 640 } | |
| 641 } else { | |
| 642 return Api::NewError( | |
| 643 "%s expects argument 'target' to be a class or library.", | |
| 644 CURRENT_FUNC); | |
| 645 } | |
| 646 return Api::NewHandle(isolate, Array::MakeArray(names)); | |
| 647 } | |
| 648 | |
| 649 | |
| 650 DART_EXPORT Dart_Handle Dart_LookupVariable(Dart_Handle target, | |
| 651 Dart_Handle variable_name) { | |
| 652 Isolate* isolate = Isolate::Current(); | |
| 653 DARTSCOPE(isolate); | |
| 654 const Object& obj = Object::Handle(isolate, Api::UnwrapHandle(target)); | |
| 655 if (obj.IsError()) { | |
| 656 return target; | |
| 657 } | |
| 658 const String& var_name = Api::UnwrapStringHandle(isolate, variable_name); | |
| 659 if (var_name.IsNull()) { | |
| 660 RETURN_TYPE_ERROR(isolate, variable_name, String); | |
| 661 } | |
| 662 if (obj.IsType() || obj.IsClass()) { | |
| 663 // For backwards compatibility we allow class objects to be passed in | |
| 664 // for now. This needs to be removed once all code that uses class | |
| 665 // objects to invoke Dart_Invoke is removed. | |
| 666 const Class& cls = (obj.IsType()) ? | |
| 667 Class::Handle(Type::Cast(obj).type_class()) : Class::Cast(obj); | |
| 668 return Api::NewHandle(isolate, cls.LookupField(var_name)); | |
| 669 } | |
| 670 if (obj.IsLibrary()) { | |
| 671 const Library& lib = Library::Cast(obj); | |
| 672 String& ambiguity_error_msg = String::Handle(isolate); | |
| 673 const Field& variable = Field::Handle( | |
| 674 lib.LookupFieldAllowPrivate(var_name, &ambiguity_error_msg)); | |
| 675 if (!ambiguity_error_msg.IsNull()) { | |
| 676 return Api::NewError("%s.", ambiguity_error_msg.ToCString()); | |
| 677 } | |
| 678 return Api::NewHandle(isolate, variable.raw()); | |
| 679 } | |
| 680 return Api::NewError( | |
| 681 "%s expects argument 'target' to be a class or library.", | |
| 682 CURRENT_FUNC); | |
| 683 } | |
| 684 | |
| 685 | |
| 686 DART_EXPORT Dart_Handle Dart_VariableName(Dart_Handle variable) { | |
| 687 Isolate* isolate = Isolate::Current(); | |
| 688 DARTSCOPE(isolate); | |
| 689 const Field& var = Api::UnwrapFieldHandle(isolate, variable); | |
| 690 if (var.IsNull()) { | |
| 691 RETURN_TYPE_ERROR(isolate, variable, Field); | |
| 692 } | |
| 693 return Api::NewHandle(isolate, var.UserVisibleName()); | |
| 694 } | |
| 695 | |
| 696 | |
| 697 DART_EXPORT Dart_Handle Dart_VariableIsStatic(Dart_Handle variable, | |
| 698 bool* is_static) { | |
| 699 Isolate* isolate = Isolate::Current(); | |
| 700 DARTSCOPE(isolate); | |
| 701 if (is_static == NULL) { | |
| 702 RETURN_NULL_ERROR(is_static); | |
| 703 } | |
| 704 const Field& var = Api::UnwrapFieldHandle(isolate, variable); | |
| 705 if (var.IsNull()) { | |
| 706 RETURN_TYPE_ERROR(isolate, variable, Field); | |
| 707 } | |
| 708 *is_static = var.is_static(); | |
| 709 return Api::Success(); | |
| 710 } | |
| 711 | |
| 712 | |
| 713 DART_EXPORT Dart_Handle Dart_VariableIsFinal(Dart_Handle variable, | |
| 714 bool* is_final) { | |
| 715 Isolate* isolate = Isolate::Current(); | |
| 716 DARTSCOPE(isolate); | |
| 717 if (is_final == NULL) { | |
| 718 RETURN_NULL_ERROR(is_final); | |
| 719 } | |
| 720 const Field& var = Api::UnwrapFieldHandle(isolate, variable); | |
| 721 if (var.IsNull()) { | |
| 722 RETURN_TYPE_ERROR(isolate, variable, Field); | |
| 723 } | |
| 724 *is_final = var.is_final(); | |
| 725 return Api::Success(); | |
| 726 } | |
| 727 | |
| 728 | |
| 729 DART_EXPORT Dart_Handle Dart_VariableType(Dart_Handle variable) { | |
| 730 Isolate* isolate = Isolate::Current(); | |
| 731 DARTSCOPE(isolate); | |
| 732 const Field& var = Api::UnwrapFieldHandle(isolate, variable); | |
| 733 if (var.IsNull()) { | |
| 734 RETURN_TYPE_ERROR(isolate, variable, Field); | |
| 735 } | |
| 736 // Ensure all classes are finalized. | |
| 737 Dart_Handle state = Api::CheckIsolateState(isolate); | |
| 738 if (::Dart_IsError(state)) { | |
| 739 return state; | |
| 740 } | |
| 741 const AbstractType& type = AbstractType::Handle(isolate, var.type()); | |
| 742 return TypeToHandle(isolate, "Dart_VariableType", type); | |
| 743 } | |
| 744 | |
| 745 | |
| 746 DART_EXPORT Dart_Handle Dart_GetTypeVariableNames(Dart_Handle object) { | |
| 747 Isolate* isolate = Isolate::Current(); | |
| 748 DARTSCOPE(isolate); | |
| 749 const Object& obj = Object::Handle(isolate, Api::UnwrapHandle(object)); | |
| 750 if (!obj.IsType() && !obj.IsClass()) { | |
| 751 RETURN_TYPE_ERROR(isolate, object, Class/Type); | |
| 752 } | |
| 753 // Ensure all classes are finalized. | |
| 754 Dart_Handle state = Api::CheckIsolateState(isolate); | |
| 755 if (::Dart_IsError(state)) { | |
| 756 return state; | |
| 757 } | |
| 758 const Class& cls = (obj.IsType()) ? | |
| 759 Class::Handle(Type::Cast(obj).type_class()) : Class::Cast(obj); | |
| 760 const intptr_t num_type_params = cls.NumTypeParameters(); | |
| 761 const TypeArguments& type_params = | |
| 762 TypeArguments::Handle(cls.type_parameters()); | |
| 763 | |
| 764 const GrowableObjectArray& names = | |
| 765 GrowableObjectArray::Handle(isolate, GrowableObjectArray::New()); | |
| 766 TypeParameter& type_param = TypeParameter::Handle(isolate); | |
| 767 String& name = String::Handle(isolate); | |
| 768 for (intptr_t i = 0; i < num_type_params; i++) { | |
| 769 type_param ^= type_params.TypeAt(i); | |
| 770 name = type_param.name(); | |
| 771 names.Add(name); | |
| 772 } | |
| 773 return Api::NewHandle(isolate, Array::MakeArray(names)); | |
| 774 } | |
| 775 | |
| 776 | |
| 777 DART_EXPORT Dart_Handle Dart_LookupTypeVariable( | |
| 778 Dart_Handle object, | |
| 779 Dart_Handle type_variable_name) { | |
| 780 Isolate* isolate = Isolate::Current(); | |
| 781 DARTSCOPE(isolate); | |
| 782 const Object& obj = Object::Handle(isolate, Api::UnwrapHandle(object)); | |
| 783 if (!obj.IsType() && !obj.IsClass()) { | |
| 784 RETURN_TYPE_ERROR(isolate, object, Class/Type); | |
| 785 } | |
| 786 const Class& cls = (obj.IsType()) ? | |
| 787 Class::Handle(Type::Cast(obj).type_class()) : Class::Cast(obj); | |
| 788 const String& var_name = Api::UnwrapStringHandle(isolate, type_variable_name); | |
| 789 if (var_name.IsNull()) { | |
| 790 RETURN_TYPE_ERROR(isolate, type_variable_name, String); | |
| 791 } | |
| 792 | |
| 793 const intptr_t num_type_params = cls.NumTypeParameters(); | |
| 794 const TypeArguments& type_params = | |
| 795 TypeArguments::Handle(cls.type_parameters()); | |
| 796 | |
| 797 TypeParameter& type_param = TypeParameter::Handle(isolate); | |
| 798 String& name = String::Handle(isolate); | |
| 799 for (intptr_t i = 0; i < num_type_params; i++) { | |
| 800 type_param ^= type_params.TypeAt(i); | |
| 801 name = type_param.name(); | |
| 802 if (name.Equals(var_name)) { | |
| 803 return Api::NewHandle(isolate, type_param.raw()); | |
| 804 } | |
| 805 } | |
| 806 const String& cls_name = String::Handle(cls.UserVisibleName()); | |
| 807 return Api::NewError( | |
| 808 "%s: Could not find type variable named '%s' for class %s.\n", | |
| 809 CURRENT_FUNC, var_name.ToCString(), cls_name.ToCString()); | |
| 810 } | |
| 811 | |
| 812 | |
| 813 DART_EXPORT Dart_Handle Dart_TypeVariableName(Dart_Handle type_variable) { | |
| 814 Isolate* isolate = Isolate::Current(); | |
| 815 DARTSCOPE(isolate); | |
| 816 const TypeParameter& type_var = | |
| 817 Api::UnwrapTypeParameterHandle(isolate, type_variable); | |
| 818 if (type_var.IsNull()) { | |
| 819 RETURN_TYPE_ERROR(isolate, type_variable, TypeParameter); | |
| 820 } | |
| 821 return Api::NewHandle(isolate, type_var.name()); | |
| 822 } | |
| 823 | |
| 824 | |
| 825 DART_EXPORT Dart_Handle Dart_TypeVariableOwner(Dart_Handle type_variable) { | |
| 826 Isolate* isolate = Isolate::Current(); | |
| 827 DARTSCOPE(isolate); | |
| 828 const TypeParameter& type_var = | |
| 829 Api::UnwrapTypeParameterHandle(isolate, type_variable); | |
| 830 if (type_var.IsNull()) { | |
| 831 RETURN_TYPE_ERROR(isolate, type_variable, TypeParameter); | |
| 832 } | |
| 833 const Class& owner = Class::Handle(type_var.parameterized_class()); | |
| 834 ASSERT(!owner.IsNull() && owner.IsClass()); | |
| 835 return Api::NewHandle(isolate, owner.raw()); | |
| 836 } | |
| 837 | |
| 838 | |
| 839 DART_EXPORT Dart_Handle Dart_TypeVariableUpperBound(Dart_Handle type_variable) { | |
| 840 Isolate* isolate = Isolate::Current(); | |
| 841 DARTSCOPE(isolate); | |
| 842 const TypeParameter& type_var = | |
| 843 Api::UnwrapTypeParameterHandle(isolate, type_variable); | |
| 844 if (type_var.IsNull()) { | |
| 845 RETURN_TYPE_ERROR(isolate, type_variable, TypeParameter); | |
| 846 } | |
| 847 const AbstractType& bound = AbstractType::Handle(type_var.bound()); | |
| 848 return TypeToHandle(isolate, "Dart_TypeVariableUpperBound", bound); | |
| 849 } | |
| 850 | |
| 851 | |
| 852 // --- Libraries Reflection --- | 311 // --- Libraries Reflection --- |
| 853 | 312 |
| 854 DART_EXPORT Dart_Handle Dart_LibraryName(Dart_Handle library) { | 313 DART_EXPORT Dart_Handle Dart_LibraryName(Dart_Handle library) { |
| 855 Isolate* isolate = Isolate::Current(); | 314 Isolate* isolate = Isolate::Current(); |
| 856 DARTSCOPE(isolate); | 315 DARTSCOPE(isolate); |
| 857 const Library& lib = Api::UnwrapLibraryHandle(isolate, library); | 316 const Library& lib = Api::UnwrapLibraryHandle(isolate, library); |
| 858 if (lib.IsNull()) { | 317 if (lib.IsNull()) { |
| 859 RETURN_TYPE_ERROR(isolate, library, Library); | 318 RETURN_TYPE_ERROR(isolate, library, Library); |
| 860 } | 319 } |
| 861 const String& name = String::Handle(isolate, lib.name()); | 320 const String& name = String::Handle(isolate, lib.name()); |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 905 if (closure_obj.IsNull() || !closure_obj.IsClosure()) { | 364 if (closure_obj.IsNull() || !closure_obj.IsClosure()) { |
| 906 RETURN_TYPE_ERROR(isolate, closure, Instance); | 365 RETURN_TYPE_ERROR(isolate, closure, Instance); |
| 907 } | 366 } |
| 908 | 367 |
| 909 ASSERT(ClassFinalizer::AllClassesFinalized()); | 368 ASSERT(ClassFinalizer::AllClassesFinalized()); |
| 910 | 369 |
| 911 RawFunction* rf = Closure::function(closure_obj); | 370 RawFunction* rf = Closure::function(closure_obj); |
| 912 return Api::NewHandle(isolate, rf); | 371 return Api::NewHandle(isolate, rf); |
| 913 } | 372 } |
| 914 | 373 |
| 915 | |
| 916 // --- Metadata Reflection ---- | |
| 917 | |
| 918 DART_EXPORT Dart_Handle Dart_GetMetadata(Dart_Handle object) { | |
| 919 Isolate* isolate = Isolate::Current(); | |
| 920 CHECK_ISOLATE(isolate); | |
| 921 DARTSCOPE(isolate); | |
| 922 const Object& obj = Object::Handle(isolate, Api::UnwrapHandle(object)); | |
| 923 Class& cls = Class::Handle(isolate); | |
| 924 if (obj.IsClass()) { | |
| 925 cls ^= obj.raw(); | |
| 926 } else if (obj.IsFunction()) { | |
| 927 cls = Function::Cast(obj).origin(); | |
| 928 } else if (obj.IsField()) { | |
| 929 cls = Field::Cast(obj).origin(); | |
| 930 } else { | |
| 931 return Api::NewHandle(isolate, Object::empty_array().raw()); | |
| 932 } | |
| 933 const Library& lib = Library::Handle(cls.library()); | |
| 934 return Api::NewHandle(isolate, lib.GetMetadata(obj)); | |
| 935 } | |
| 936 | |
| 937 } // namespace dart | 374 } // namespace dart |
| OLD | NEW |