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

Side by Side Diff: runtime/vm/dart_api_impl.cc

Issue 10687004: Implement method and variable reflection in dart:mirrors. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 6 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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_api.h" 5 #include "include/dart_api.h"
6 6
7 #include "vm/bigint_operations.h" 7 #include "vm/bigint_operations.h"
8 #include "vm/class_finalizer.h" 8 #include "vm/class_finalizer.h"
9 #include "vm/compiler.h" 9 #include "vm/compiler.h"
10 #include "vm/dart.h" 10 #include "vm/dart.h"
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
51 CURRENT_FUNC, #dart_handle); \ 51 CURRENT_FUNC, #dart_handle); \
52 } else if (tmp.IsError()) { \ 52 } else if (tmp.IsError()) { \
53 return dart_handle; \ 53 return dart_handle; \
54 } else { \ 54 } else { \
55 return Api::NewError("%s expects argument '%s' to be of type %s.", \ 55 return Api::NewError("%s expects argument '%s' to be of type %s.", \
56 CURRENT_FUNC, #dart_handle, #Type); \ 56 CURRENT_FUNC, #dart_handle, #Type); \
57 } \ 57 } \
58 } while (0) 58 } while (0)
59 59
60 60
61 // Removes internal vm prefixes and suffixes from an identifier.
62 static RawString* StripName(Isolate* isolate, const String& name) {
cshapiro 2012/06/28 23:57:47 IdentifierPrettyName? Better comment with example
turnidge 2012/07/09 23:45:17 Done.
63 intptr_t len = name.Length();
64 intptr_t start = 0;
65 intptr_t at_pos = len; // Position of '@' in the name.
66 intptr_t dot_pos = len; // Position of '.' in the name.
67
68 for (int i = 0; i < name.Length(); i++) {
69 if (name.CharAt(i) == ':') {
70 ASSERT(start == 0);
71 start = i + 1;
72 } else if (name.CharAt(i) == '@') {
73 ASSERT(at_pos == len);
74 at_pos = i;
75 } else if (name.CharAt(i) == '.') {
76 dot_pos = i;
77 break;
78 }
79 }
80 intptr_t limit = (at_pos < dot_pos ? at_pos : dot_pos);
81 if (start == 0 && limit == len) {
82 // This name is fine as it is.
83 return name.raw();
84 }
85
86 String& result = String::Handle(isolate);
87 result = String::SubString(name, start, (limit - start));
88
89 // Look for a second '@' now to correctly handle names like
90 // "_ReceivePortImpl@6be832b._internal@6be832b".
91 at_pos = len;
92 for (int i = dot_pos; i < name.Length(); i++) {
93 if (name.CharAt(i) == '@') {
94 ASSERT(at_pos == len);
95 at_pos = i;
96 }
97 }
98
99 intptr_t suffix_len = at_pos - dot_pos;
100 if (suffix_len <= 1) {
101 // The constructor name is of length 0 or 1. That means that
102 // either this isn't a constructor or that this is an unnamed
103 // constructor. In either case, we're done.
104 return result.raw();
105 }
106
107 const String& suffix =
108 String::Handle(isolate, String::SubString(name, dot_pos, suffix_len));
109 return String::Concat(result, suffix);
110 }
111
112
61 // Return error if isolate is in an inconsistent state. 113 // Return error if isolate is in an inconsistent state.
62 // Return NULL when no error condition exists. 114 // Return NULL when no error condition exists.
63 // 115 //
64 // TODO(turnidge): Make this function return an error handle directly 116 // TODO(turnidge): Make this function return an error handle directly
65 // rather than returning an error string. The current behavior can 117 // rather than returning an error string. The current behavior can
66 // cause compilation errors to appear to be api errors. 118 // cause compilation errors to appear to be api errors.
67 const char* CheckIsolateState(Isolate* isolate, bool generating_snapshot) { 119 const char* CheckIsolateState(Isolate* isolate, bool generating_snapshot) {
68 bool success = true; 120 bool success = true;
69 if (!ClassFinalizer::AllClassesFinalized()) { 121 if (!ClassFinalizer::AllClassesFinalized()) {
70 success = (generating_snapshot) ? 122 success = (generating_snapshot) ?
(...skipping 30 matching lines...) Expand all
101 ApiLocalScope* scope = state->top_scope(); 153 ApiLocalScope* scope = state->top_scope();
102 ASSERT(scope != NULL); 154 ASSERT(scope != NULL);
103 LocalHandles* local_handles = scope->local_handles(); 155 LocalHandles* local_handles = scope->local_handles();
104 ASSERT(local_handles != NULL); 156 ASSERT(local_handles != NULL);
105 LocalHandle* ref = local_handles->AllocateHandle(); 157 LocalHandle* ref = local_handles->AllocateHandle();
106 ref->set_raw(raw); 158 ref->set_raw(raw);
107 return reinterpret_cast<Dart_Handle>(ref); 159 return reinterpret_cast<Dart_Handle>(ref);
108 } 160 }
109 161
110 RawObject* Api::UnwrapHandle(Dart_Handle object) { 162 RawObject* Api::UnwrapHandle(Dart_Handle object) {
111 #ifdef DEBUG 163 #if defined(DEBUG)
112 Isolate* isolate = Isolate::Current(); 164 Isolate* isolate = Isolate::Current();
113 ASSERT(isolate != NULL); 165 ASSERT(isolate != NULL);
114 ApiState* state = isolate->api_state(); 166 ApiState* state = isolate->api_state();
115 ASSERT(state != NULL); 167 ASSERT(state != NULL);
116 ASSERT(state->IsValidPrologueWeakPersistentHandle(object) || 168 ASSERT(state->IsValidPrologueWeakPersistentHandle(object) ||
117 state->IsValidWeakPersistentHandle(object) || 169 state->IsValidWeakPersistentHandle(object) ||
118 state->IsValidPersistentHandle(object) || 170 state->IsValidPersistentHandle(object) ||
119 state->IsValidLocalHandle(object)); 171 state->IsValidLocalHandle(object));
120 ASSERT(FinalizablePersistentHandle::raw_offset() == 0 && 172 ASSERT(FinalizablePersistentHandle::raw_offset() == 0 &&
121 PersistentHandle::raw_offset() == 0 && 173 PersistentHandle::raw_offset() == 0 &&
(...skipping 2303 matching lines...) Expand 10 before | Expand all | Expand 10 after
2425 2477
2426 2478
2427 DART_EXPORT Dart_Handle Dart_ClassName(Dart_Handle clazz) { 2479 DART_EXPORT Dart_Handle Dart_ClassName(Dart_Handle clazz) {
2428 Isolate* isolate = Isolate::Current(); 2480 Isolate* isolate = Isolate::Current();
2429 DARTSCOPE(isolate); 2481 DARTSCOPE(isolate);
2430 Class& cls = Class::Handle(isolate); 2482 Class& cls = Class::Handle(isolate);
2431 cls ^= Api::UnwrapClassHandle(isolate, clazz).raw(); 2483 cls ^= Api::UnwrapClassHandle(isolate, clazz).raw();
2432 if (cls.IsNull()) { 2484 if (cls.IsNull()) {
2433 RETURN_TYPE_ERROR(isolate, clazz, Class); 2485 RETURN_TYPE_ERROR(isolate, clazz, Class);
2434 } 2486 }
2435 return Api::NewHandle(isolate, cls.Name()); 2487 const String& cls_name = String::Handle(isolate, cls.Name());
2488 return Api::NewHandle(isolate, StripName(isolate, cls_name));
2436 } 2489 }
2437 2490
2438 2491
2439 DART_EXPORT Dart_Handle Dart_ClassGetLibrary(Dart_Handle clazz) { 2492 DART_EXPORT Dart_Handle Dart_ClassGetLibrary(Dart_Handle clazz) {
2440 Isolate* isolate = Isolate::Current(); 2493 Isolate* isolate = Isolate::Current();
2441 DARTSCOPE(isolate); 2494 DARTSCOPE(isolate);
2442 Class& cls = Class::Handle(isolate); 2495 Class& cls = Class::Handle(isolate);
2443 cls ^= Api::UnwrapClassHandle(isolate, clazz).raw(); 2496 cls ^= Api::UnwrapClassHandle(isolate, clazz).raw();
2444 if (cls.IsNull()) { 2497 if (cls.IsNull()) {
2445 RETURN_TYPE_ERROR(isolate, clazz, Class); 2498 RETURN_TYPE_ERROR(isolate, clazz, Class);
2446 } 2499 }
2500
2501 #if defined(DEBUG)
2502 const Library& lib = Library::Handle(cls.library());
2503 if (lib.IsNull()) {
2504 ASSERT(cls.IsDynamicClass() || cls.IsVoidClass());
2505 }
2506 #endif
2507
2447 return Api::NewHandle(isolate, cls.library()); 2508 return Api::NewHandle(isolate, cls.library());
2448 } 2509 }
2449 2510
2450 2511
2451 DART_EXPORT Dart_Handle Dart_ClassGetDefault(Dart_Handle clazz) { 2512 DART_EXPORT Dart_Handle Dart_ClassGetDefault(Dart_Handle clazz) {
2452 Isolate* isolate = Isolate::Current(); 2513 Isolate* isolate = Isolate::Current();
2453 DARTSCOPE(isolate); 2514 DARTSCOPE(isolate);
2454 Class& cls = Class::Handle(isolate); 2515 Class& cls = Class::Handle(isolate);
2455 cls ^= Api::UnwrapClassHandle(isolate, clazz).raw(); 2516 cls ^= Api::UnwrapClassHandle(isolate, clazz).raw();
2456 if (cls.IsNull()) { 2517 if (cls.IsNull()) {
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
2515 if (interface_type.HasResolvedTypeClass()) { 2576 if (interface_type.HasResolvedTypeClass()) {
2516 return Api::NewHandle(isolate, interface_type.type_class()); 2577 return Api::NewHandle(isolate, interface_type.type_class());
2517 } 2578 }
2518 const String& type_name = 2579 const String& type_name =
2519 String::Handle(isolate, interface_type.TypeClassName()); 2580 String::Handle(isolate, interface_type.TypeClassName());
2520 return Api::NewError("%s: internal error: found unresolved type class '%s'.", 2581 return Api::NewError("%s: internal error: found unresolved type class '%s'.",
2521 CURRENT_FUNC, type_name.ToCString()); 2582 CURRENT_FUNC, type_name.ToCString());
2522 } 2583 }
2523 2584
2524 2585
2586 // --- Function and Variable Reflection ---
2587
2588
2589 // Outside of the vm, we expose setter names with a trailing '='.
2590 static bool HasExternalSetterSuffix(const String& name) {
2591 return name.CharAt(name.Length() - 1) == '=';
2592 }
2593
2594
2595 static RawString* AddExternalSetterSuffix(const String& name) {
2596 const String& equals = String::Handle(String::NewSymbol("="));
2597 return String::Concat(name, equals);
2598 }
2599
2600
2601 static RawString* RemoveExternalSetterSuffix(const String& name) {
2602 ASSERT(HasExternalSetterSuffix(name));
2603 return String::SubString(name, 0, name.Length() - 1);
2604 }
2605
2606
2607 DART_EXPORT Dart_Handle Dart_GetFunctionNames(Dart_Handle target) {
2608 Isolate* isolate = Isolate::Current();
2609 DARTSCOPE(isolate);
2610 const Object& obj = Object::Handle(isolate, Api::UnwrapHandle(target));
2611 if (obj.IsError()) {
2612 return target;
2613 }
2614
2615 const GrowableObjectArray& names =
2616 GrowableObjectArray::Handle(isolate, GrowableObjectArray::New());
2617 Function& func = Function::Handle();
2618 String& name = String::Handle();
2619
2620 if (obj.IsClass()) {
2621 Class& cls = Class::Handle(isolate);
2622 cls ^= obj.raw();
2623 const Array& func_array = Array::Handle(cls.functions());
2624
2625 // Some special types like 'Dynamic' have a null functions list.
2626 if (!func_array.IsNull()) {
2627 for (intptr_t i = 0; i < func_array.Length(); ++i) {
2628 func ^= func_array.At(i);
2629
2630 // Skip implicit getters and setters.
2631 if (func.kind() == RawFunction::kImplicitGetter ||
2632 func.kind() == RawFunction::kImplicitSetter ||
2633 func.kind() == RawFunction::kConstImplicitGetter) {
2634 continue;
2635 }
2636
2637 name = func.name();
2638 bool is_setter = Field::IsSetterName(name);
2639 name = StripName(isolate, name);
2640
2641 if (is_setter) {
2642 name = AddExternalSetterSuffix(name);
2643 }
2644 names.Add(name);
2645 }
2646 }
2647 } else if (obj.IsLibrary()) {
2648 Library& lib = Library::Handle(isolate);
2649 lib ^= obj.raw();
2650 DictionaryIterator it(lib);
2651 Object& obj = Object::Handle();
2652 while (it.HasNext()) {
2653 obj = it.GetNext();
2654 if (obj.IsFunction()) {
2655 func ^= obj.raw();
2656 name = func.name();
2657 bool is_setter = Field::IsSetterName(name);
2658 name = StripName(isolate, name);
2659 if (is_setter) {
2660 name = AddExternalSetterSuffix(name);
2661 }
2662 names.Add(name);
2663 }
2664 }
2665 } else {
2666 return Api::NewError(
2667 "%s expects argument 'target' to be a class or library.",
2668 CURRENT_FUNC);
2669 }
2670 return Api::NewHandle(isolate, Array::MakeArray(names));
2671 }
2672
2673
2674 DART_EXPORT Dart_Handle Dart_LookupFunction(Dart_Handle target,
2675 Dart_Handle function_name) {
2676 Isolate* isolate = Isolate::Current();
2677 DARTSCOPE(isolate);
2678 const Object& obj = Object::Handle(isolate, Api::UnwrapHandle(target));
2679 if (obj.IsError()) {
2680 return target;
2681 }
2682 const String& func_name = Api::UnwrapStringHandle(isolate, function_name);
2683 if (func_name.IsNull()) {
2684 RETURN_TYPE_ERROR(isolate, function_name, String);
2685 }
2686
2687 Function& func = Function::Handle(isolate);
2688 String& tmp_name = String::Handle(isolate);
2689 if (obj.IsClass()) {
2690 Class& cls = Class::Handle(isolate);
2691 cls ^= obj.raw();
2692 func = cls.LookupFunction(func_name);
2693
2694 // Check for functions with the external setter suffix '='. Make
cshapiro 2012/06/28 23:57:47 Totally optional, maybe make it clear that we are
turnidge 2012/07/09 23:45:17 Done.
turnidge 2012/07/09 23:45:17 Done.
2695 // sure to do this check after the regular lookup, so that we
2696 // don't interfere with operator lookups (like ==).
2697 if (func.IsNull() && HasExternalSetterSuffix(func_name)) {
2698 tmp_name = RemoveExternalSetterSuffix(func_name);
2699 tmp_name = Field::SetterName(tmp_name);
2700 func = cls.LookupFunction(tmp_name);
2701 }
2702
2703 // Try to look up the function as a getter.
2704 if (func.IsNull()) {
2705 tmp_name = Field::GetterName(func_name);
2706 func = cls.LookupFunction(tmp_name);
2707 }
2708
2709 // Special case for the unnamed constructor. We need to add a dot
2710 // at the end of the name.
2711 if (func.IsNull()) {
2712 const String& dot = String::Handle(String::NewSymbol("."));
2713 tmp_name = String::Concat(func_name, dot);
2714 func = cls.LookupFunction(tmp_name);
2715 }
2716
2717 if (func.IsNull()) {
2718 const String& cls_name = String::Handle(cls.Name());
2719 fprintf(stderr, "---> Couldn't find method '%s' in class '%s'\n",
cshapiro 2012/06/28 23:57:47 No arrows allowed!
turnidge 2012/07/09 23:45:17 Done.
2720 func_name.ToCString(), cls_name.ToCString());
2721 }
2722 } else if (obj.IsLibrary()) {
2723 Library& lib = Library::Handle(isolate);
2724 lib ^= obj.raw();
2725 func = lib.LookupFunctionAllowPrivate(func_name);
2726
2727 // Check for functions with the external setter suffix '='. Make
cshapiro 2012/06/28 23:57:47 Ditto.
turnidge 2012/07/09 23:45:17 Done.
2728 // sure to do this check after the regular lookup, so that we
2729 // don't interfere with operator lookups (like ==).
2730 if (func.IsNull() && HasExternalSetterSuffix(func_name)) {
2731 tmp_name = RemoveExternalSetterSuffix(func_name);
2732 tmp_name = Field::SetterName(tmp_name);
2733 func = lib.LookupFunctionAllowPrivate(tmp_name);
2734 }
2735
2736 // Try to look up the function as a getter.
2737 if (func.IsNull()) {
2738 tmp_name = Field::GetterName(func_name);
2739 func = lib.LookupFunctionAllowPrivate(tmp_name);
2740 }
2741 } else {
2742 return Api::NewError(
2743 "%s expects argument 'target' to be a class or library.",
2744 CURRENT_FUNC);
2745 }
2746
2747 #if defined(DEBUG)
2748 if (!func.IsNull()) {
2749 // We only provide access to a subset of function kinds.
2750 RawFunction::Kind func_kind = func.kind();
2751 ASSERT(func_kind == RawFunction::kFunction ||
2752 func_kind == RawFunction::kGetterFunction ||
2753 func_kind == RawFunction::kSetterFunction ||
2754 func_kind == RawFunction::kConstructor ||
2755 func_kind == RawFunction::kAbstract);
2756 }
2757 #endif
2758 return Api::NewHandle(isolate, func.raw());
2759 }
2760
2761
2762 DART_EXPORT bool Dart_IsFunction(Dart_Handle handle) {
2763 return Api::ClassId(handle) == kFunction;
2764 }
2765
2766
2767 DART_EXPORT Dart_Handle Dart_FunctionName(Dart_Handle function) {
2768 Isolate* isolate = Isolate::Current();
2769 DARTSCOPE(isolate);
2770 const Function& func = Api::UnwrapFunctionHandle(isolate, function);
2771 if (func.IsNull()) {
2772 RETURN_TYPE_ERROR(isolate, function, Function);
2773 }
2774 String& func_name = String::Handle(isolate);
2775 func_name = func.name();
2776 bool is_setter = Field::IsSetterName(func_name);
2777 func_name = StripName(isolate, func_name);
2778 if (is_setter) {
2779 func_name = AddExternalSetterSuffix(func_name);
2780 }
2781 return Api::NewHandle(isolate, func_name.raw());
2782 }
2783
2784
2785 DART_EXPORT Dart_Handle Dart_FunctionIsAbstract(Dart_Handle function,
2786 bool* is_abstract) {
cshapiro 2012/06/28 23:57:47 Null check.
turnidge 2012/07/09 23:45:17 Done.
2787 Isolate* isolate = Isolate::Current();
2788 DARTSCOPE(isolate);
2789 const Function& func = Api::UnwrapFunctionHandle(isolate, function);
2790 if (func.IsNull()) {
2791 RETURN_TYPE_ERROR(isolate, function, Function);
2792 }
2793 *is_abstract = func.kind() == RawFunction::kAbstract;
cshapiro 2012/06/28 23:57:47 Stick parens around the inner double equal.
turnidge 2012/07/09 23:45:17 Done.
2794 return Api::Success(isolate);
2795 }
2796
2797
2798 DART_EXPORT Dart_Handle Dart_FunctionIsStatic(Dart_Handle function,
2799 bool* is_static) {
cshapiro 2012/06/28 23:57:47 Null check.
turnidge 2012/07/09 23:45:17 Done.
2800 Isolate* isolate = Isolate::Current();
2801 DARTSCOPE(isolate);
2802 const Function& func = Api::UnwrapFunctionHandle(isolate, function);
2803 if (func.IsNull()) {
2804 RETURN_TYPE_ERROR(isolate, function, Function);
2805 }
2806 *is_static = func.is_static();
2807 return Api::Success(isolate);
2808 }
2809
2810
2811 DART_EXPORT Dart_Handle Dart_FunctionIsConstructor(Dart_Handle function,
2812 bool* is_constructor) {
cshapiro 2012/06/28 23:57:47 Null check.
turnidge 2012/07/09 23:45:17 Done.
2813 Isolate* isolate = Isolate::Current();
2814 DARTSCOPE(isolate);
2815 const Function& func = Api::UnwrapFunctionHandle(isolate, function);
2816 if (func.IsNull()) {
2817 RETURN_TYPE_ERROR(isolate, function, Function);
2818 }
2819 *is_constructor = func.kind() == RawFunction::kConstructor;
2820 return Api::Success(isolate);
2821 }
2822
2823
2824 DART_EXPORT Dart_Handle Dart_FunctionIsGetter(Dart_Handle function,
2825 bool* is_getter) {
cshapiro 2012/06/28 23:57:47 Null check.
turnidge 2012/07/09 23:45:17 Done.
2826 Isolate* isolate = Isolate::Current();
2827 DARTSCOPE(isolate);
2828 const Function& func = Api::UnwrapFunctionHandle(isolate, function);
2829 if (func.IsNull()) {
2830 RETURN_TYPE_ERROR(isolate, function, Function);
2831 }
2832 // TODO(turnidge): It would be nice if I could just use func.kind()
2833 // to check for a getter function here, but unfortunately the only
2834 // way to distinguish abstract getter functions is to use the name
2835 // itself. Consider adding a RawFunction::kAbstractGetter type.
2836 const String& func_name = String::Handle(isolate, func.name());
2837 *is_getter = Field::IsGetterName(func_name);
2838
2839 return Api::Success(isolate);
2840 }
2841
2842
2843 DART_EXPORT Dart_Handle Dart_FunctionIsSetter(Dart_Handle function,
2844 bool* is_setter) {
cshapiro 2012/06/28 23:57:47 Null check.
turnidge 2012/07/09 23:45:17 Done.
2845 Isolate* isolate = Isolate::Current();
2846 DARTSCOPE(isolate);
2847 const Function& func = Api::UnwrapFunctionHandle(isolate, function);
2848 if (func.IsNull()) {
2849 RETURN_TYPE_ERROR(isolate, function, Function);
2850 }
2851 // TODO(turnidge): It would be nice if I could just use func.kind()
2852 // to check for a setter function here, but unfortunately the only
2853 // way to distinguish abstract setter functions is to use the name
2854 // itself. Consider adding a RawFunction::kAbstractSetter type.
2855 const String& func_name = String::Handle(isolate, func.name());
2856 *is_setter = Field::IsSetterName(func_name);
2857
2858 return Api::Success(isolate);
2859 }
2860
2861
2862 DART_EXPORT Dart_Handle Dart_GetVariableNames(Dart_Handle target) {
2863 Isolate* isolate = Isolate::Current();
2864 DARTSCOPE(isolate);
2865 const Object& obj = Object::Handle(isolate, Api::UnwrapHandle(target));
2866 if (obj.IsError()) {
2867 return target;
2868 }
2869
2870 const GrowableObjectArray& names =
2871 GrowableObjectArray::Handle(isolate, GrowableObjectArray::New());
2872 Field& field = Field::Handle(isolate);
2873 String& name = String::Handle(isolate);
2874
2875 if (obj.IsClass()) {
2876 Class& cls = Class::Handle(isolate);
2877 cls ^= obj.raw();
2878 const Array& field_array = Array::Handle(cls.fields());
2879
2880 // Some special types like 'Dynamic' have a null fields list.
cshapiro 2012/06/28 23:57:47 Maybe fix this at the source if it is not too much
turnidge 2012/07/09 23:45:17 Investigated. Since Dynamic is allocated in the v
2881 if (!field_array.IsNull()) {
2882 for (intptr_t i = 0; i < field_array.Length(); ++i) {
2883 field ^= field_array.At(i);
2884 name = field.name();
2885 name = StripName(isolate, name);
2886 names.Add(name);
2887 }
2888 }
2889 } else if (obj.IsLibrary()) {
2890 Library& lib = Library::Handle(isolate);
2891 lib ^= obj.raw();
2892 DictionaryIterator it(lib);
2893 Object& obj = Object::Handle(isolate);
2894 while (it.HasNext()) {
2895 obj = it.GetNext();
2896 if (obj.IsField()) {
2897 field ^= obj.raw();
2898 name = field.name();
2899 name = StripName(isolate, name);
2900 names.Add(name);
2901 }
2902 }
2903 } else {
2904 return Api::NewError(
2905 "%s expects argument 'target' to be a class or library.",
2906 CURRENT_FUNC);
2907 }
2908 return Api::NewHandle(isolate, Array::MakeArray(names));
2909 }
2910
2911
2912 DART_EXPORT Dart_Handle Dart_LookupVariable(Dart_Handle target,
2913 Dart_Handle variable_name) {
2914 Isolate* isolate = Isolate::Current();
2915 DARTSCOPE(isolate);
2916 const Object& obj = Object::Handle(isolate, Api::UnwrapHandle(target));
2917 if (obj.IsError()) {
2918 return target;
2919 }
2920 const String& var_name = Api::UnwrapStringHandle(isolate, variable_name);
2921 if (var_name.IsNull()) {
2922 RETURN_TYPE_ERROR(isolate, variable_name, String);
2923 }
2924 if (obj.IsClass()) {
2925 Class& cls = Class::Handle(isolate);
2926 cls ^= obj.raw();
2927 return Api::NewHandle(isolate, cls.LookupField(var_name));
cshapiro 2012/06/28 23:57:47 If you have a return, why not get rid of the else
turnidge 2012/07/09 23:45:17 Done.
2928 } else if (obj.IsLibrary()) {
2929 Library& lib = Library::Handle(isolate);
2930 lib ^= obj.raw();
2931 return Api::NewHandle(isolate, lib.LookupFieldAllowPrivate(var_name));
2932 } else {
2933 return Api::NewError(
2934 "%s expects argument 'target' to be a class or library.",
2935 CURRENT_FUNC);
2936 }
2937 }
2938
2939
2940 DART_EXPORT bool Dart_IsVariable(Dart_Handle handle) {
2941 return Api::ClassId(handle) == kField;
cshapiro 2012/06/28 23:57:47 Maybe make sure this is safe?
turnidge 2012/07/09 23:45:17 We do this a lot.
2942 }
2943
2944
2945 DART_EXPORT Dart_Handle Dart_VariableName(Dart_Handle variable) {
2946 Isolate* isolate = Isolate::Current();
2947 DARTSCOPE(isolate);
2948 const Field& var = Api::UnwrapFieldHandle(isolate, variable);
2949 if (var.IsNull()) {
2950 RETURN_TYPE_ERROR(isolate, variable, Field);
2951 }
2952 const String& var_name = String::Handle(var.name());
2953 return Api::NewHandle(isolate, StripName(isolate, var_name));
2954 }
2955
2956
2957 DART_EXPORT Dart_Handle Dart_VariableIsStatic(Dart_Handle variable,
2958 bool* is_static) {
cshapiro 2012/06/28 23:57:47 Do we normally do null check for out variables? A
turnidge 2012/07/09 23:45:17 Done.
2959 Isolate* isolate = Isolate::Current();
2960 DARTSCOPE(isolate);
2961 const Field& var = Api::UnwrapFieldHandle(isolate, variable);
2962 if (var.IsNull()) {
2963 RETURN_TYPE_ERROR(isolate, variable, Field);
2964 }
2965 *is_static = var.is_static();
2966 return Api::Success(isolate);
2967 }
2968
2969
2970 DART_EXPORT Dart_Handle Dart_VariableIsFinal(Dart_Handle variable,
2971 bool* is_final) {
cshapiro 2012/06/28 23:57:47 Null check for is_final too.
turnidge 2012/07/09 23:45:17 Done.
2972 Isolate* isolate = Isolate::Current();
2973 DARTSCOPE(isolate);
2974 const Field& var = Api::UnwrapFieldHandle(isolate, variable);
2975 if (var.IsNull()) {
2976 RETURN_TYPE_ERROR(isolate, variable, Field);
2977 }
2978 *is_final = var.is_final();
2979 return Api::Success(isolate);
2980 }
2981
2525 // --- Constructors, Methods, and Fields --- 2982 // --- Constructors, Methods, and Fields ---
2526 2983
2527 2984
2528 static RawObject* ResolveConstructor(const char* current_func, 2985 static RawObject* ResolveConstructor(const char* current_func,
2529 const Class& cls, 2986 const Class& cls,
2530 const String& class_name, 2987 const String& class_name,
2531 const String& dotted_name, 2988 const String& dotted_name,
2532 int num_args) { 2989 int num_args) {
2533 // The constructor must be present in the interface. 2990 // The constructor must be present in the interface.
2534 String& constr_name = String::Handle(String::Concat(class_name, dotted_name)); 2991 String& constr_name = String::Handle(String::Concat(class_name, dotted_name));
(...skipping 957 matching lines...) Expand 10 before | Expand all | Expand 10 after
3492 RETURN_TYPE_ERROR(isolate, library, Library); 3949 RETURN_TYPE_ERROR(isolate, library, Library);
3493 } 3950 }
3494 3951
3495 const GrowableObjectArray& names = 3952 const GrowableObjectArray& names =
3496 GrowableObjectArray::Handle(isolate, GrowableObjectArray::New()); 3953 GrowableObjectArray::Handle(isolate, GrowableObjectArray::New());
3497 ClassDictionaryIterator it(lib); 3954 ClassDictionaryIterator it(lib);
3498 Class& cls = Class::Handle(); 3955 Class& cls = Class::Handle();
3499 String& name = String::Handle(); 3956 String& name = String::Handle();
3500 while (it.HasNext()) { 3957 while (it.HasNext()) {
3501 cls = it.GetNextClass(); 3958 cls = it.GetNextClass();
3502 name = cls.Name(); 3959 // For now we suppress the signature classes of closures.
3503 names.Add(name); 3960 //
3961 // TODO(turnidge): Add this to the unit test.
3962 const Function& signature_func = Function::Handle(cls.signature_function());
3963 if (signature_func.IsNull()) {
3964 name = cls.Name();
3965 name = StripName(isolate, name);
3966 names.Add(name);
3967 }
3504 } 3968 }
3505 return Api::NewHandle(isolate, Array::MakeArray(names)); 3969 return Api::NewHandle(isolate, Array::MakeArray(names));
3506 } 3970 }
3507 3971
3508 3972
3509 DART_EXPORT Dart_Handle Dart_LookupLibrary(Dart_Handle url) { 3973 DART_EXPORT Dart_Handle Dart_LookupLibrary(Dart_Handle url) {
3510 Isolate* isolate = Isolate::Current(); 3974 Isolate* isolate = Isolate::Current();
3511 DARTSCOPE(isolate); 3975 DARTSCOPE(isolate);
3512 const String& url_str = Api::UnwrapStringHandle(isolate, url); 3976 const String& url_str = Api::UnwrapStringHandle(isolate, url);
3513 if (url_str.IsNull()) { 3977 if (url_str.IsNull()) {
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
3656 *buffer_size = 0; 4120 *buffer_size = 0;
3657 } 4121 }
3658 } 4122 }
3659 4123
3660 4124
3661 DART_EXPORT void Dart_InitFlowGraphPrinting(FileWriterFunction function) { 4125 DART_EXPORT void Dart_InitFlowGraphPrinting(FileWriterFunction function) {
3662 Dart::set_flow_graph_writer(function); 4126 Dart::set_flow_graph_writer(function);
3663 } 4127 }
3664 4128
3665 } // namespace dart 4129 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698