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

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

Issue 16973003: Split dart_api.h into multiple parts: (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 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
« no previous file with comments | « runtime/vm/dart_api_message.h ('k') | runtime/vm/native_api_impl.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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
3 // BSD-style license that can be found in the LICENSE file.
4
5 #include "include/dart_mirrors_api.h"
6
7 #include "platform/assert.h"
8 #include "vm/class_finalizer.h"
9 #include "vm/dart.h"
10 #include "vm/dart_api_impl.h"
11 #include "vm/dart_api_state.h"
12 #include "vm/dart_entry.h"
13 #include "vm/exceptions.h"
14 #include "vm/growable_array.h"
15 #include "vm/object.h"
16 #include "vm/resolver.h"
17 #include "vm/stack_frame.h"
18 #include "vm/symbols.h"
19
20 namespace dart {
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
49 // --- Classes and Interfaces Reflection ---
50
51 DART_EXPORT Dart_Handle Dart_ClassName(Dart_Handle clazz) {
52 Isolate* isolate = Isolate::Current();
53 DARTSCOPE(isolate);
54 const Class& cls = Api::UnwrapClassHandle(isolate, clazz);
55 if (cls.IsNull()) {
56 RETURN_TYPE_ERROR(isolate, clazz, Class);
57 }
58 return Api::NewHandle(isolate, cls.UserVisibleName());
59 }
60
61
62 DART_EXPORT Dart_Handle Dart_ClassGetLibrary(Dart_Handle clazz) {
63 Isolate* isolate = Isolate::Current();
64 DARTSCOPE(isolate);
65 const Class& cls = Api::UnwrapClassHandle(isolate, clazz);
66 if (cls.IsNull()) {
67 RETURN_TYPE_ERROR(isolate, clazz, Class);
68 }
69
70 #if defined(DEBUG)
71 const Library& lib = Library::Handle(cls.library());
72 if (lib.IsNull()) {
73 // ASSERT(cls.IsDynamicClass() || cls.IsVoidClass());
74 if (!cls.IsDynamicClass() && !cls.IsVoidClass()) {
75 fprintf(stderr, "NO LIBRARY: %s\n", cls.ToCString());
76 }
77 }
78 #endif
79
80 return Api::NewHandle(isolate, cls.library());
81 }
82
83
84 DART_EXPORT Dart_Handle Dart_ClassGetInterfaceCount(Dart_Handle clazz,
85 intptr_t* count) {
86 Isolate* isolate = Isolate::Current();
87 DARTSCOPE(isolate);
88 const Class& cls = Api::UnwrapClassHandle(isolate, clazz);
89 if (cls.IsNull()) {
90 RETURN_TYPE_ERROR(isolate, clazz, Class);
91 }
92
93 const Array& interface_types = Array::Handle(isolate, cls.interfaces());
94 if (interface_types.IsNull()) {
95 *count = 0;
96 } else {
97 *count = interface_types.Length();
98 }
99 return Api::Success();
100 }
101
102
103 DART_EXPORT Dart_Handle Dart_ClassGetInterfaceAt(Dart_Handle clazz,
104 intptr_t index) {
105 Isolate* isolate = Isolate::Current();
106 DARTSCOPE(isolate);
107 const Class& cls = Api::UnwrapClassHandle(isolate, clazz);
108 if (cls.IsNull()) {
109 RETURN_TYPE_ERROR(isolate, clazz, Class);
110 }
111
112 // Finalize all classes.
113 Dart_Handle state = Api::CheckIsolateState(isolate);
114 if (::Dart_IsError(state)) {
115 return state;
116 }
117
118 const Array& interface_types = Array::Handle(isolate, cls.interfaces());
119 if (index < 0 || index >= interface_types.Length()) {
120 return Api::NewError("%s: argument 'index' out of bounds.", CURRENT_FUNC);
121 }
122 Type& interface_type = Type::Handle(isolate);
123 interface_type ^= interface_types.At(index);
124 if (interface_type.HasResolvedTypeClass()) {
125 return Api::NewHandle(isolate, interface_type.type_class());
126 }
127 const String& type_name =
128 String::Handle(isolate, interface_type.TypeClassName());
129 return Api::NewError("%s: internal error: found unresolved type class '%s'.",
130 CURRENT_FUNC, type_name.ToCString());
131 }
132
133
134 DART_EXPORT bool Dart_ClassIsTypedef(Dart_Handle clazz) {
135 Isolate* isolate = Isolate::Current();
136 DARTSCOPE(isolate);
137 const Class& cls = Api::UnwrapClassHandle(isolate, clazz);
138 if (cls.IsNull()) {
139 RETURN_TYPE_ERROR(isolate, clazz, Class);
140 }
141 // For now we represent typedefs as non-canonical signature classes.
142 // I anticipate this may change if we make typedefs more general.
143 return cls.IsSignatureClass() && !cls.IsCanonicalSignatureClass();
144 }
145
146
147 DART_EXPORT Dart_Handle Dart_ClassGetTypedefReferent(Dart_Handle clazz) {
148 Isolate* isolate = Isolate::Current();
149 DARTSCOPE(isolate);
150 const Class& cls = Api::UnwrapClassHandle(isolate, clazz);
151 if (cls.IsNull()) {
152 RETURN_TYPE_ERROR(isolate, clazz, Class);
153 }
154
155 if (!cls.IsSignatureClass() && !cls.IsCanonicalSignatureClass()) {
156 const String& cls_name = String::Handle(cls.UserVisibleName());
157 return Api::NewError("%s: class '%s' is not a typedef class. "
158 "See Dart_ClassIsTypedef.",
159 CURRENT_FUNC, cls_name.ToCString());
160 }
161
162 const Function& func = Function::Handle(isolate, cls.signature_function());
163 return Api::NewHandle(isolate, func.signature_class());
164 }
165
166
167 DART_EXPORT bool Dart_ClassIsFunctionType(Dart_Handle clazz) {
168 Isolate* isolate = Isolate::Current();
169 DARTSCOPE(isolate);
170 const Class& cls = Api::UnwrapClassHandle(isolate, clazz);
171 if (cls.IsNull()) {
172 RETURN_TYPE_ERROR(isolate, clazz, Class);
173 }
174 // A class represents a function type when it is a canonical
175 // signature class.
176 return cls.IsCanonicalSignatureClass();
177 }
178
179
180 DART_EXPORT Dart_Handle Dart_ClassGetFunctionTypeSignature(Dart_Handle clazz) {
181 Isolate* isolate = Isolate::Current();
182 DARTSCOPE(isolate);
183 const Class& cls = Api::UnwrapClassHandle(isolate, clazz);
184 if (cls.IsNull()) {
185 RETURN_TYPE_ERROR(isolate, clazz, Class);
186 }
187 if (!cls.IsCanonicalSignatureClass()) {
188 const String& cls_name = String::Handle(cls.UserVisibleName());
189 return Api::NewError("%s: class '%s' is not a function-type class. "
190 "See Dart_ClassIsFunctionType.",
191 CURRENT_FUNC, cls_name.ToCString());
192 }
193 return Api::NewHandle(isolate, cls.signature_function());
194 }
195
196
197 // --- Function and Variable Reflection ---
198
199 // Outside of the vm, we expose setter names with a trailing '='.
200 static bool HasExternalSetterSuffix(const String& name) {
201 return name.CharAt(name.Length() - 1) == '=';
202 }
203
204
205 static RawString* RemoveExternalSetterSuffix(const String& name) {
206 ASSERT(HasExternalSetterSuffix(name));
207 return String::SubString(name, 0, name.Length() - 1);
208 }
209
210
211 DART_EXPORT Dart_Handle Dart_GetFunctionNames(Dart_Handle target) {
212 Isolate* isolate = Isolate::Current();
213 DARTSCOPE(isolate);
214 const Object& obj = Object::Handle(isolate, Api::UnwrapHandle(target));
215 if (obj.IsError()) {
216 return target;
217 }
218
219 const GrowableObjectArray& names =
220 GrowableObjectArray::Handle(isolate, GrowableObjectArray::New());
221 Function& func = Function::Handle();
222 String& name = String::Handle();
223
224 if (obj.IsClass()) {
225 const Class& cls = Class::Cast(obj);
226 const Error& error = Error::Handle(isolate, cls.EnsureIsFinalized(isolate));
227 if (!error.IsNull()) {
228 return Api::NewHandle(isolate, error.raw());
229 }
230 const Array& func_array = Array::Handle(cls.functions());
231
232 // Some special types like 'dynamic' have a null functions list.
233 if (!func_array.IsNull()) {
234 for (intptr_t i = 0; i < func_array.Length(); ++i) {
235 func ^= func_array.At(i);
236
237 // Skip implicit getters and setters.
238 if (func.kind() == RawFunction::kImplicitGetter ||
239 func.kind() == RawFunction::kImplicitSetter ||
240 func.kind() == RawFunction::kConstImplicitGetter ||
241 func.kind() == RawFunction::kMethodExtractor) {
242 continue;
243 }
244
245 name = func.UserVisibleName();
246 names.Add(name);
247 }
248 }
249 } else if (obj.IsLibrary()) {
250 const Library& lib = Library::Cast(obj);
251 DictionaryIterator it(lib);
252 Object& obj = Object::Handle();
253 while (it.HasNext()) {
254 obj = it.GetNext();
255 if (obj.IsFunction()) {
256 func ^= obj.raw();
257 name = func.UserVisibleName();
258 names.Add(name);
259 }
260 }
261 } else {
262 return Api::NewError(
263 "%s expects argument 'target' to be a class or library.",
264 CURRENT_FUNC);
265 }
266 return Api::NewHandle(isolate, Array::MakeArray(names));
267 }
268
269
270 DART_EXPORT Dart_Handle Dart_LookupFunction(Dart_Handle target,
271 Dart_Handle function_name) {
272 Isolate* isolate = Isolate::Current();
273 DARTSCOPE(isolate);
274 const Object& obj = Object::Handle(isolate, Api::UnwrapHandle(target));
275 if (obj.IsError()) {
276 return target;
277 }
278 const String& func_name = Api::UnwrapStringHandle(isolate, function_name);
279 if (func_name.IsNull()) {
280 RETURN_TYPE_ERROR(isolate, function_name, String);
281 }
282
283 Function& func = Function::Handle(isolate);
284 String& tmp_name = String::Handle(isolate);
285 if (obj.IsClass()) {
286 const Class& cls = Class::Cast(obj);
287
288 // Case 1. Lookup the unmodified function name.
289 func = cls.LookupFunctionAllowPrivate(func_name);
290
291 // Case 2. Lookup the function without the external setter suffix
292 // '='. Make sure to do this check after the regular lookup, so
293 // that we don't interfere with operator lookups (like ==).
294 if (func.IsNull() && HasExternalSetterSuffix(func_name)) {
295 tmp_name = RemoveExternalSetterSuffix(func_name);
296 tmp_name = Field::SetterName(tmp_name);
297 func = cls.LookupFunctionAllowPrivate(tmp_name);
298 }
299
300 // Case 3. Lookup the funciton with the getter prefix prepended.
301 if (func.IsNull()) {
302 tmp_name = Field::GetterName(func_name);
303 func = cls.LookupFunctionAllowPrivate(tmp_name);
304 }
305
306 // Case 4. Lookup the function with a . appended to find the
307 // unnamed constructor.
308 if (func.IsNull()) {
309 tmp_name = String::Concat(func_name, Symbols::Dot());
310 func = cls.LookupFunctionAllowPrivate(tmp_name);
311 }
312 } else if (obj.IsLibrary()) {
313 const Library& lib = Library::Cast(obj);
314
315 // Case 1. Lookup the unmodified function name.
316 func = lib.LookupFunctionAllowPrivate(func_name);
317
318 // Case 2. Lookup the function without the external setter suffix
319 // '='. Make sure to do this check after the regular lookup, so
320 // that we don't interfere with operator lookups (like ==).
321 if (func.IsNull() && HasExternalSetterSuffix(func_name)) {
322 tmp_name = RemoveExternalSetterSuffix(func_name);
323 tmp_name = Field::SetterName(tmp_name);
324 func = lib.LookupFunctionAllowPrivate(tmp_name);
325 }
326
327 // Case 3. Lookup the function with the getter prefix prepended.
328 if (func.IsNull()) {
329 tmp_name = Field::GetterName(func_name);
330 func = lib.LookupFunctionAllowPrivate(tmp_name);
331 }
332 } else {
333 return Api::NewError(
334 "%s expects argument 'target' to be a class or library.",
335 CURRENT_FUNC);
336 }
337
338 #if defined(DEBUG)
339 if (!func.IsNull()) {
340 // We only provide access to a subset of function kinds.
341 RawFunction::Kind func_kind = func.kind();
342 ASSERT(func_kind == RawFunction::kRegularFunction ||
343 func_kind == RawFunction::kGetterFunction ||
344 func_kind == RawFunction::kSetterFunction ||
345 func_kind == RawFunction::kConstructor);
346 }
347 #endif
348 return Api::NewHandle(isolate, func.raw());
349 }
350
351
352 DART_EXPORT Dart_Handle Dart_FunctionName(Dart_Handle function) {
353 Isolate* isolate = Isolate::Current();
354 DARTSCOPE(isolate);
355 const Function& func = Api::UnwrapFunctionHandle(isolate, function);
356 if (func.IsNull()) {
357 RETURN_TYPE_ERROR(isolate, function, Function);
358 }
359 return Api::NewHandle(isolate, func.UserVisibleName());
360 }
361
362
363 DART_EXPORT Dart_Handle Dart_FunctionOwner(Dart_Handle function) {
364 Isolate* isolate = Isolate::Current();
365 DARTSCOPE(isolate);
366 const Function& func = Api::UnwrapFunctionHandle(isolate, function);
367 if (func.IsNull()) {
368 RETURN_TYPE_ERROR(isolate, function, Function);
369 }
370 if (func.IsNonImplicitClosureFunction()) {
371 RawFunction* parent_function = func.parent_function();
372 return Api::NewHandle(isolate, parent_function);
373 }
374 const Class& owner = Class::Handle(func.Owner());
375 ASSERT(!owner.IsNull());
376 if (owner.IsTopLevel()) {
377 // Top-level functions are implemented as members of a hidden class. We hide
378 // that class here and instead answer the library.
379 #if defined(DEBUG)
380 const Library& lib = Library::Handle(owner.library());
381 if (lib.IsNull()) {
382 ASSERT(owner.IsDynamicClass() || owner.IsVoidClass());
383 }
384 #endif
385 return Api::NewHandle(isolate, owner.library());
386 } else {
387 return Api::NewHandle(isolate, owner.raw());
388 }
389 }
390
391
392 DART_EXPORT Dart_Handle Dart_FunctionIsAbstract(Dart_Handle function,
393 bool* is_abstract) {
394 Isolate* isolate = Isolate::Current();
395 DARTSCOPE(isolate);
396 if (is_abstract == NULL) {
397 RETURN_NULL_ERROR(is_abstract);
398 }
399 const Function& func = Api::UnwrapFunctionHandle(isolate, function);
400 if (func.IsNull()) {
401 RETURN_TYPE_ERROR(isolate, function, Function);
402 }
403 *is_abstract = func.is_abstract();
404 return Api::Success();
405 }
406
407
408 DART_EXPORT Dart_Handle Dart_FunctionIsStatic(Dart_Handle function,
409 bool* is_static) {
410 Isolate* isolate = Isolate::Current();
411 DARTSCOPE(isolate);
412 if (is_static == NULL) {
413 RETURN_NULL_ERROR(is_static);
414 }
415 const Function& func = Api::UnwrapFunctionHandle(isolate, function);
416 if (func.IsNull()) {
417 RETURN_TYPE_ERROR(isolate, function, Function);
418 }
419 *is_static = func.is_static();
420 return Api::Success();
421 }
422
423
424 DART_EXPORT Dart_Handle Dart_FunctionIsConstructor(Dart_Handle function,
425 bool* is_constructor) {
426 Isolate* isolate = Isolate::Current();
427 DARTSCOPE(isolate);
428 if (is_constructor == NULL) {
429 RETURN_NULL_ERROR(is_constructor);
430 }
431 const Function& func = Api::UnwrapFunctionHandle(isolate, function);
432 if (func.IsNull()) {
433 RETURN_TYPE_ERROR(isolate, function, Function);
434 }
435 *is_constructor = func.kind() == RawFunction::kConstructor;
436 return Api::Success();
437 }
438
439
440 DART_EXPORT Dart_Handle Dart_FunctionIsGetter(Dart_Handle function,
441 bool* is_getter) {
442 Isolate* isolate = Isolate::Current();
443 DARTSCOPE(isolate);
444 if (is_getter == NULL) {
445 RETURN_NULL_ERROR(is_getter);
446 }
447 const Function& func = Api::UnwrapFunctionHandle(isolate, function);
448 if (func.IsNull()) {
449 RETURN_TYPE_ERROR(isolate, function, Function);
450 }
451 *is_getter = func.IsGetterFunction();
452 return Api::Success();
453 }
454
455
456 DART_EXPORT Dart_Handle Dart_FunctionIsSetter(Dart_Handle function,
457 bool* is_setter) {
458 Isolate* isolate = Isolate::Current();
459 DARTSCOPE(isolate);
460 if (is_setter == NULL) {
461 RETURN_NULL_ERROR(is_setter);
462 }
463 const Function& func = Api::UnwrapFunctionHandle(isolate, function);
464 if (func.IsNull()) {
465 RETURN_TYPE_ERROR(isolate, function, Function);
466 }
467 *is_setter = (func.kind() == RawFunction::kSetterFunction);
468 return Api::Success();
469 }
470
471
472 DART_EXPORT Dart_Handle Dart_FunctionReturnType(Dart_Handle function) {
473 Isolate* isolate = Isolate::Current();
474 DARTSCOPE(isolate);
475 const Function& func = Api::UnwrapFunctionHandle(isolate, function);
476 if (func.IsNull()) {
477 RETURN_TYPE_ERROR(isolate, function, Function);
478 }
479
480 if (func.kind() == RawFunction::kConstructor) {
481 // Special case the return type for constructors. Inside the vm
482 // we mark them as returning dynamic, but for the purposes of
483 // reflection, they return the type of the class being
484 // constructed.
485 return Api::NewHandle(isolate, func.Owner());
486 } else {
487 const AbstractType& return_type =
488 AbstractType::Handle(isolate, func.result_type());
489 return TypeToHandle(isolate, "Dart_FunctionReturnType", return_type);
490 }
491 }
492
493
494 DART_EXPORT Dart_Handle Dart_FunctionParameterCounts(
495 Dart_Handle function,
496 int64_t* fixed_param_count,
497 int64_t* opt_param_count) {
498 Isolate* isolate = Isolate::Current();
499 DARTSCOPE(isolate);
500 if (fixed_param_count == NULL) {
501 RETURN_NULL_ERROR(fixed_param_count);
502 }
503 if (opt_param_count == NULL) {
504 RETURN_NULL_ERROR(opt_param_count);
505 }
506 const Function& func = Api::UnwrapFunctionHandle(isolate, function);
507 if (func.IsNull()) {
508 RETURN_TYPE_ERROR(isolate, function, Function);
509 }
510
511 // We hide implicit parameters, such as a method's receiver. This is
512 // consistent with Invoke or New, which don't expect their callers to
513 // provide them in the argument lists they are handed.
514 *fixed_param_count = func.num_fixed_parameters() -
515 func.NumImplicitParameters();
516 // TODO(regis): Separately report named and positional optional param counts.
517 *opt_param_count = func.NumOptionalParameters();
518
519 ASSERT(*fixed_param_count >= 0);
520 ASSERT(*opt_param_count >= 0);
521
522 return Api::Success();
523 }
524
525
526 DART_EXPORT Dart_Handle Dart_FunctionParameterType(Dart_Handle function,
527 int parameter_index) {
528 Isolate* isolate = Isolate::Current();
529 DARTSCOPE(isolate);
530 const Function& func = Api::UnwrapFunctionHandle(isolate, function);
531 if (func.IsNull()) {
532 RETURN_TYPE_ERROR(isolate, function, Function);
533 }
534
535 const intptr_t num_implicit_params = func.NumImplicitParameters();
536 const intptr_t num_params = func.NumParameters() - num_implicit_params;
537 if (parameter_index < 0 || parameter_index >= num_params) {
538 return Api::NewError(
539 "%s: argument 'parameter_index' out of range. "
540 "Expected 0..%"Pd" but saw %d.",
541 CURRENT_FUNC, num_params, parameter_index);
542 }
543 const AbstractType& param_type =
544 AbstractType::Handle(isolate, func.ParameterTypeAt(
545 num_implicit_params + parameter_index));
546 return TypeToHandle(isolate, "Dart_FunctionParameterType", param_type);
547 }
548
549
550 DART_EXPORT Dart_Handle Dart_GetVariableNames(Dart_Handle target) {
551 Isolate* isolate = Isolate::Current();
552 DARTSCOPE(isolate);
553 const Object& obj = Object::Handle(isolate, Api::UnwrapHandle(target));
554 if (obj.IsError()) {
555 return target;
556 }
557
558 const GrowableObjectArray& names =
559 GrowableObjectArray::Handle(isolate, GrowableObjectArray::New());
560 Field& field = Field::Handle(isolate);
561 String& name = String::Handle(isolate);
562
563 if (obj.IsClass()) {
564 const Class& cls = Class::Cast(obj);
565 const Error& error = Error::Handle(isolate, cls.EnsureIsFinalized(isolate));
566 if (!error.IsNull()) {
567 return Api::NewHandle(isolate, error.raw());
568 }
569 const Array& field_array = Array::Handle(cls.fields());
570
571 // Some special types like 'dynamic' have a null fields list.
572 //
573 // TODO(turnidge): Fix 'dynamic' so that it does not have a null
574 // fields list. This will have to wait until the empty array is
575 // allocated in the vm isolate.
576 if (!field_array.IsNull()) {
577 for (intptr_t i = 0; i < field_array.Length(); ++i) {
578 field ^= field_array.At(i);
579 name = field.UserVisibleName();
580 names.Add(name);
581 }
582 }
583 } else if (obj.IsLibrary()) {
584 const Library& lib = Library::Cast(obj);
585 DictionaryIterator it(lib);
586 Object& obj = Object::Handle(isolate);
587 while (it.HasNext()) {
588 obj = it.GetNext();
589 if (obj.IsField()) {
590 field ^= obj.raw();
591 name = field.UserVisibleName();
592 names.Add(name);
593 }
594 }
595 } else {
596 return Api::NewError(
597 "%s expects argument 'target' to be a class or library.",
598 CURRENT_FUNC);
599 }
600 return Api::NewHandle(isolate, Array::MakeArray(names));
601 }
602
603
604 DART_EXPORT Dart_Handle Dart_LookupVariable(Dart_Handle target,
605 Dart_Handle variable_name) {
606 Isolate* isolate = Isolate::Current();
607 DARTSCOPE(isolate);
608 const Object& obj = Object::Handle(isolate, Api::UnwrapHandle(target));
609 if (obj.IsError()) {
610 return target;
611 }
612 const String& var_name = Api::UnwrapStringHandle(isolate, variable_name);
613 if (var_name.IsNull()) {
614 RETURN_TYPE_ERROR(isolate, variable_name, String);
615 }
616 if (obj.IsClass()) {
617 const Class& cls = Class::Cast(obj);
618 return Api::NewHandle(isolate, cls.LookupField(var_name));
619 }
620 if (obj.IsLibrary()) {
621 const Library& lib = Library::Cast(obj);
622 return Api::NewHandle(isolate, lib.LookupFieldAllowPrivate(var_name));
623 }
624 return Api::NewError(
625 "%s expects argument 'target' to be a class or library.",
626 CURRENT_FUNC);
627 }
628
629
630 DART_EXPORT Dart_Handle Dart_VariableName(Dart_Handle variable) {
631 Isolate* isolate = Isolate::Current();
632 DARTSCOPE(isolate);
633 const Field& var = Api::UnwrapFieldHandle(isolate, variable);
634 if (var.IsNull()) {
635 RETURN_TYPE_ERROR(isolate, variable, Field);
636 }
637 return Api::NewHandle(isolate, var.UserVisibleName());
638 }
639
640
641 DART_EXPORT Dart_Handle Dart_VariableIsStatic(Dart_Handle variable,
642 bool* is_static) {
643 Isolate* isolate = Isolate::Current();
644 DARTSCOPE(isolate);
645 if (is_static == NULL) {
646 RETURN_NULL_ERROR(is_static);
647 }
648 const Field& var = Api::UnwrapFieldHandle(isolate, variable);
649 if (var.IsNull()) {
650 RETURN_TYPE_ERROR(isolate, variable, Field);
651 }
652 *is_static = var.is_static();
653 return Api::Success();
654 }
655
656
657 DART_EXPORT Dart_Handle Dart_VariableIsFinal(Dart_Handle variable,
658 bool* is_final) {
659 Isolate* isolate = Isolate::Current();
660 DARTSCOPE(isolate);
661 if (is_final == NULL) {
662 RETURN_NULL_ERROR(is_final);
663 }
664 const Field& var = Api::UnwrapFieldHandle(isolate, variable);
665 if (var.IsNull()) {
666 RETURN_TYPE_ERROR(isolate, variable, Field);
667 }
668 *is_final = var.is_final();
669 return Api::Success();
670 }
671
672
673 DART_EXPORT Dart_Handle Dart_VariableType(Dart_Handle variable) {
674 Isolate* isolate = Isolate::Current();
675 DARTSCOPE(isolate);
676 const Field& var = Api::UnwrapFieldHandle(isolate, variable);
677 if (var.IsNull()) {
678 RETURN_TYPE_ERROR(isolate, variable, Field);
679 }
680
681 const AbstractType& type = AbstractType::Handle(isolate, var.type());
682 return TypeToHandle(isolate, "Dart_VariableType", type);
683 }
684
685
686 DART_EXPORT Dart_Handle Dart_GetTypeVariableNames(Dart_Handle clazz) {
687 Isolate* isolate = Isolate::Current();
688 DARTSCOPE(isolate);
689 const Class& cls = Api::UnwrapClassHandle(isolate, clazz);
690 if (cls.IsNull()) {
691 RETURN_TYPE_ERROR(isolate, clazz, Class);
692 }
693
694 const intptr_t num_type_params = cls.NumTypeParameters();
695 const TypeArguments& type_params =
696 TypeArguments::Handle(cls.type_parameters());
697
698 const GrowableObjectArray& names =
699 GrowableObjectArray::Handle(isolate, GrowableObjectArray::New());
700 TypeParameter& type_param = TypeParameter::Handle(isolate);
701 String& name = String::Handle(isolate);
702 for (intptr_t i = 0; i < num_type_params; i++) {
703 type_param ^= type_params.TypeAt(i);
704 name = type_param.name();
705 names.Add(name);
706 }
707 return Api::NewHandle(isolate, Array::MakeArray(names));
708 }
709
710
711 DART_EXPORT Dart_Handle Dart_LookupTypeVariable(
712 Dart_Handle clazz,
713 Dart_Handle type_variable_name) {
714 Isolate* isolate = Isolate::Current();
715 DARTSCOPE(isolate);
716 const Class& cls = Api::UnwrapClassHandle(isolate, clazz);
717 if (cls.IsNull()) {
718 RETURN_TYPE_ERROR(isolate, clazz, Class);
719 }
720 const String& var_name = Api::UnwrapStringHandle(isolate, type_variable_name);
721 if (var_name.IsNull()) {
722 RETURN_TYPE_ERROR(isolate, type_variable_name, String);
723 }
724
725 const intptr_t num_type_params = cls.NumTypeParameters();
726 const TypeArguments& type_params =
727 TypeArguments::Handle(cls.type_parameters());
728
729 TypeParameter& type_param = TypeParameter::Handle(isolate);
730 String& name = String::Handle(isolate);
731 for (intptr_t i = 0; i < num_type_params; i++) {
732 type_param ^= type_params.TypeAt(i);
733 name = type_param.name();
734 if (name.Equals(var_name)) {
735 return Api::NewHandle(isolate, type_param.raw());
736 }
737 }
738 const String& cls_name = String::Handle(cls.UserVisibleName());
739 return Api::NewError(
740 "%s: Could not find type variable named '%s' for class %s.\n",
741 CURRENT_FUNC, var_name.ToCString(), cls_name.ToCString());
742 }
743
744
745 DART_EXPORT Dart_Handle Dart_TypeVariableName(Dart_Handle type_variable) {
746 Isolate* isolate = Isolate::Current();
747 DARTSCOPE(isolate);
748 const TypeParameter& type_var =
749 Api::UnwrapTypeParameterHandle(isolate, type_variable);
750 if (type_var.IsNull()) {
751 RETURN_TYPE_ERROR(isolate, type_variable, TypeParameter);
752 }
753 return Api::NewHandle(isolate, type_var.name());
754 }
755
756
757 DART_EXPORT Dart_Handle Dart_TypeVariableOwner(Dart_Handle type_variable) {
758 Isolate* isolate = Isolate::Current();
759 DARTSCOPE(isolate);
760 const TypeParameter& type_var =
761 Api::UnwrapTypeParameterHandle(isolate, type_variable);
762 if (type_var.IsNull()) {
763 RETURN_TYPE_ERROR(isolate, type_variable, TypeParameter);
764 }
765 const Class& owner = Class::Handle(type_var.parameterized_class());
766 ASSERT(!owner.IsNull() && owner.IsClass());
767 return Api::NewHandle(isolate, owner.raw());
768 }
769
770
771 DART_EXPORT Dart_Handle Dart_TypeVariableUpperBound(Dart_Handle type_variable) {
772 Isolate* isolate = Isolate::Current();
773 DARTSCOPE(isolate);
774 const TypeParameter& type_var =
775 Api::UnwrapTypeParameterHandle(isolate, type_variable);
776 if (type_var.IsNull()) {
777 RETURN_TYPE_ERROR(isolate, type_variable, TypeParameter);
778 }
779 const AbstractType& bound = AbstractType::Handle(type_var.bound());
780 return TypeToHandle(isolate, "Dart_TypeVariableUpperBound", bound);
781 }
782
783
784 // --- Libraries Reflection ---
785
786 DART_EXPORT Dart_Handle Dart_LibraryName(Dart_Handle library) {
787 Isolate* isolate = Isolate::Current();
788 DARTSCOPE(isolate);
789 const Library& lib = Api::UnwrapLibraryHandle(isolate, library);
790 if (lib.IsNull()) {
791 RETURN_TYPE_ERROR(isolate, library, Library);
792 }
793 const String& name = String::Handle(isolate, lib.name());
794 ASSERT(!name.IsNull());
795 return Api::NewHandle(isolate, name.raw());
796 }
797
798
799 DART_EXPORT Dart_Handle Dart_LibraryGetClassNames(Dart_Handle library) {
800 Isolate* isolate = Isolate::Current();
801 DARTSCOPE(isolate);
802 const Library& lib = Api::UnwrapLibraryHandle(isolate, library);
803 if (lib.IsNull()) {
804 RETURN_TYPE_ERROR(isolate, library, Library);
805 }
806
807 const GrowableObjectArray& names =
808 GrowableObjectArray::Handle(isolate, GrowableObjectArray::New());
809 ClassDictionaryIterator it(lib);
810 Class& cls = Class::Handle();
811 String& name = String::Handle();
812 while (it.HasNext()) {
813 cls = it.GetNextClass();
814 if (cls.IsSignatureClass()) {
815 if (!cls.IsCanonicalSignatureClass()) {
816 // This is a typedef. Add it to the list of class names.
817 name = cls.UserVisibleName();
818 names.Add(name);
819 } else {
820 // Skip canonical signature classes. These are not named.
821 }
822 } else {
823 name = cls.UserVisibleName();
824 names.Add(name);
825 }
826 }
827 return Api::NewHandle(isolate, Array::MakeArray(names));
828 }
829
830
831 // --- Closures Reflection ---
832
833 DART_EXPORT Dart_Handle Dart_ClosureFunction(Dart_Handle closure) {
834 Isolate* isolate = Isolate::Current();
835 DARTSCOPE(isolate);
836 const Instance& closure_obj = Api::UnwrapInstanceHandle(isolate, closure);
837 if (closure_obj.IsNull() || !closure_obj.IsClosure()) {
838 RETURN_TYPE_ERROR(isolate, closure, Instance);
839 }
840
841 ASSERT(ClassFinalizer::AllClassesFinalized());
842
843 RawFunction* rf = Closure::function(closure_obj);
844 return Api::NewHandle(isolate, rf);
845 }
846
847
848 // --- Metadata Reflection ----
849
850 DART_EXPORT Dart_Handle Dart_GetMetadata(Dart_Handle object) {
851 Isolate* isolate = Isolate::Current();
852 CHECK_ISOLATE(isolate);
853 DARTSCOPE(isolate);
854 const Object& obj = Object::Handle(isolate, Api::UnwrapHandle(object));
855 Class& cls = Class::Handle(isolate);
856 if (obj.IsClass()) {
857 cls ^= obj.raw();
858 } else if (obj.IsFunction()) {
859 cls = Function::Cast(obj).origin();
860 } else if (obj.IsField()) {
861 cls = Field::Cast(obj).origin();
862 } else {
863 return Api::NewHandle(isolate, Object::empty_array().raw());
864 }
865 const Library& lib = Library::Handle(cls.library());
866 return Api::NewHandle(isolate, lib.GetMetadata(obj));
867 }
868
869 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/dart_api_message.h ('k') | runtime/vm/native_api_impl.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698