Line data Source code
1 : /* valadatatype.vala
2 : *
3 : * Copyright (C) 2006-2010 Jürg Billeter
4 : * Copyright (C) 2006-2008 Raffaele Sandrini
5 : *
6 : * This library is free software; you can redistribute it and/or
7 : * modify it under the terms of the GNU Lesser General Public
8 : * License as published by the Free Software Foundation; either
9 : * version 2.1 of the License, or (at your option) any later version.
10 :
11 : * This library is distributed in the hope that it will be useful,
12 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 : * Lesser General Public License for more details.
15 :
16 : * You should have received a copy of the GNU Lesser General Public
17 : * License along with this library; if not, write to the Free Software
18 : * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 : *
20 : * Author:
21 : * Jürg Billeter <j@bitron.ch>
22 : * Raffaele Sandrini <raffaele@sandrini.ch>
23 : */
24 :
25 : using GLib;
26 :
27 : /**
28 : * A reference to a data type. This is used to specify static types of
29 : * expressions.
30 : */
31 78777389 : public abstract class Vala.DataType : CodeNode {
32 : /**
33 : * Specifies that the expression or variable owns the value.
34 : */
35 79513488 : public bool value_owned { get; set; }
36 :
37 : /**
38 : * Specifies that the expression may be null.
39 : */
40 76691479 : public bool nullable { get; set; }
41 :
42 : /**
43 : * The referred symbol.
44 : */
45 41463267 : public weak Symbol? symbol { get; private set; }
46 :
47 : /**
48 : * The referred symbol in the current context.
49 : */
50 98045 : public weak Symbol? context_symbol { get; set; }
51 :
52 : /**
53 : * The referred type symbol.
54 : */
55 : public weak TypeSymbol? type_symbol {
56 214509992 : get {
57 214509992 : return symbol as TypeSymbol;
58 : }
59 : }
60 :
61 : /**
62 : * Specifies that the expression transfers a floating reference.
63 : */
64 13199174 : public bool floating_reference { get; set; }
65 :
66 : /**
67 : * Specifies that the type supports dynamic lookup.
68 : */
69 59920181 : public bool is_dynamic { get; set; }
70 :
71 56053671 : private List<DataType> type_argument_list;
72 : private static List<DataType> _empty_type_list;
73 :
74 33331498 : protected DataType.with_symbol (Symbol? symbol, SourceReference? source_reference = null) {
75 33331498 : this.symbol = symbol;
76 33331498 : this.source_reference = source_reference;
77 : }
78 :
79 : /**
80 : * Appends the specified type as generic type argument.
81 : *
82 : * @param arg a type reference
83 : */
84 2355486 : public void add_type_argument (DataType arg) {
85 2355486 : if (type_argument_list == null) {
86 2127305 : type_argument_list = new ArrayList<DataType> ();
87 : }
88 2355486 : type_argument_list.add (arg);
89 2355486 : arg.parent_node = this;
90 : }
91 :
92 : /**
93 : * Returns the list of generic type arguments.
94 : *
95 : * @return type argument list
96 : */
97 120944466 : public unowned List<DataType> get_type_arguments () {
98 120944466 : if (type_argument_list != null) {
99 120944466 : return type_argument_list;
100 : }
101 114887597 : if (_empty_type_list == null) {
102 1538 : _empty_type_list = new ArrayList<DataType> ();
103 : }
104 114887597 : return _empty_type_list;
105 : }
106 :
107 135655 : public bool has_type_arguments () {
108 135655 : if (type_argument_list == null) {
109 112604 : return false;
110 : }
111 :
112 23051 : return type_argument_list.size > 0;
113 : }
114 :
115 : /**
116 : * Removes all generic type arguments.
117 : */
118 0 : public void remove_all_type_arguments () {
119 0 : type_argument_list = null;
120 : }
121 :
122 40866479 : public override void accept (CodeVisitor visitor) {
123 40866479 : visitor.visit_data_type (this);
124 : }
125 :
126 32422371 : public override void accept_children (CodeVisitor visitor) {
127 32422371 : if (type_argument_list != null && type_argument_list.size > 0) {
128 3014735 : foreach (DataType type_arg in type_argument_list) {
129 1035396 : type_arg.accept (visitor);
130 : }
131 : }
132 : }
133 :
134 587 : public override string to_string () {
135 587 : return to_qualified_string (null);
136 : }
137 :
138 32999 : public virtual string to_qualified_string (Scope? scope = null) {
139 : string s;
140 :
141 52501 : if (type_symbol != null) {
142 38569 : Symbol global_symbol = type_symbol;
143 38569 : while (global_symbol.parent_symbol != null && global_symbol.parent_symbol.name != null) {
144 24638 : global_symbol = global_symbol.parent_symbol;
145 : }
146 :
147 26250 : Symbol sym = null;
148 99457 : Scope parent_scope = scope;
149 99457 : while (sym == null && parent_scope != null) {
150 73207 : sym = parent_scope.lookup (global_symbol.name);
151 120562 : parent_scope = parent_scope.parent_scope;
152 : }
153 :
154 26250 : if (sym != null && global_symbol != sym) {
155 4 : s = "global::" + type_symbol.get_full_name ();;
156 : } else {
157 26246 : s = type_symbol.get_full_name ();
158 : }
159 : } else {
160 1 : s = "null";
161 : }
162 :
163 3487645 : var type_args = get_type_arguments ();
164 26251 : if (type_args.size > 0) {
165 214 : s += "<";
166 214 : bool first = true;
167 718 : foreach (DataType type_arg in type_args) {
168 252 : if (!first) {
169 38 : s += ",";
170 : } else {
171 : first = false;
172 : }
173 252 : if (type_arg.is_weak ()) {
174 30 : s += "weak ";
175 : }
176 252 : s += type_arg.to_qualified_string (scope);
177 : }
178 214 : s += ">";
179 : }
180 26251 : if (nullable) {
181 853 : s += "?";
182 : }
183 :
184 26251 : return s;
185 : }
186 :
187 : /**
188 : * Creates a shallow copy of this type reference.
189 : *
190 : * @return copy of this type reference
191 : */
192 10899269 : public abstract DataType copy ();
193 :
194 : /**
195 : * Checks two type references for equality. May only be used with
196 : * resolved type references.
197 : *
198 : * @param type2 a type reference
199 : * @return true if this type reference is equal to type2, false
200 : * otherwise
201 : */
202 116502 : public virtual bool equals (DataType type2) {
203 58034 : if (type2.is_disposable () != is_disposable ()) {
204 55 : return false;
205 : }
206 58019 : if (type2.nullable != nullable) {
207 : //TODO Allow equality between nullable and non-nullable generic-types
208 : // This mitigation allows fixing affected source code without breaking it.
209 : // It has to be removed at some point
210 0 : var context = CodeContext.get ();
211 0 : return !context.experimental_non_null && this is GenericType == type2 is GenericType;
212 : }
213 58019 : if (type2.type_symbol != type_symbol) {
214 55 : return false;
215 : }
216 57982 : if (type2 is GenericType || this is GenericType) {
217 255 : if (!(type2 is GenericType) || !(this is GenericType)) {
218 55 : return false;
219 : }
220 255 : if (!((GenericType) type2).type_parameter.equals (((GenericType) this).type_parameter)) {
221 55 : return false;
222 : }
223 : }
224 57982 : if (type2.floating_reference != floating_reference) {
225 55 : return false;
226 : }
227 :
228 57982 : var type_args = get_type_arguments ();
229 57982 : var type2_args = type2.get_type_arguments ();
230 57982 : if (type2_args.size != type_args.size) {
231 0 : return false;
232 : }
233 :
234 58967 : for (int i = 0; i < type_args.size; i++) {
235 988 : if (!type2_args[i].equals (type_args[i]))
236 3 : return false;
237 : }
238 :
239 57979 : return true;
240 : }
241 :
242 : /**
243 : * Checks whether this type reference is at least as strict as the
244 : * specified type reference type2.
245 : *
246 : * @param type2 a type reference
247 : * @return true if this type reference is stricter or equal
248 : */
249 28337 : public virtual bool stricter (DataType type2) {
250 7385 : if (type2.is_disposable () != is_disposable ()) {
251 : return false;
252 : }
253 :
254 7385 : if (!type2.nullable && nullable) {
255 : return false;
256 : }
257 :
258 : /* temporarily ignore type parameters */
259 7385 : if (this is GenericType || type2 is GenericType) {
260 : return true;
261 : }
262 :
263 4553 : if (type2.type_symbol != type_symbol) {
264 : // FIXME: allow this type reference to refer to a
265 : // subtype of the type type2 is referring to
266 : return false;
267 : }
268 :
269 4553 : if (type2.floating_reference != floating_reference) {
270 : return false;
271 : }
272 :
273 : return true;
274 : }
275 :
276 538631 : public override void replace_type (DataType old_type, DataType new_type) {
277 538631 : if (type_argument_list != null) {
278 585922 : for (int i = 0; i < type_argument_list.size; i++) {
279 585922 : if (type_argument_list[i] == old_type) {
280 538631 : type_argument_list[i] = new_type;
281 538631 : return;
282 : }
283 : }
284 : }
285 : }
286 :
287 3494419 : public virtual bool compatible (DataType target_type) {
288 1255119 : var context = CodeContext.get ();
289 :
290 1255119 : if (context.experimental_non_null && nullable && !target_type.nullable) {
291 7 : return false;
292 : }
293 :
294 1255112 : if (context.profile == Profile.GOBJECT && target_type.type_symbol != null) {
295 1232317 : unowned DataType? gvalue_type = context.analyzer.gvalue_type;
296 1232317 : if (gvalue_type != null && target_type.type_symbol.is_subtype_of (gvalue_type.type_symbol)) {
297 : // allow implicit conversion to GValue
298 167 : return true;
299 : }
300 :
301 1232150 : unowned DataType? gvariant_type = context.analyzer.gvariant_type;
302 1232150 : if (gvariant_type != null && target_type.type_symbol.is_subtype_of (gvariant_type.type_symbol)) {
303 : // allow implicit conversion to GVariant
304 116 : return true;
305 : }
306 : }
307 :
308 1254829 : if (target_type is PointerType) {
309 : /* any reference or array type or pointer type can be cast to a generic pointer */
310 19844 : if (this is GenericType ||
311 9938 : (type_symbol != null && (
312 : type_symbol.is_reference_type () ||
313 0 : this is DelegateType))) {
314 19844 : return true;
315 : }
316 :
317 0 : return false;
318 : }
319 :
320 : /* temporarily ignore type parameters */
321 1234985 : if (target_type is GenericType) {
322 80787 : return true;
323 : }
324 :
325 1154198 : if (this is ArrayType != target_type is ArrayType) {
326 1 : return false;
327 : }
328 :
329 1154197 : if (type_symbol is Enum && target_type.type_symbol is Struct && ((Struct) target_type.type_symbol).is_integer_type ()) {
330 88 : return true;
331 1154109 : } else if (target_type.type_symbol is Enum && type_symbol is Struct && ((Struct) type_symbol).is_integer_type ()) {
332 : //FIXME Drop this unsafe direction in the future?
333 17 : return true;
334 : }
335 :
336 : // check for matching ownership of type-arguments
337 1154092 : var type_args = get_type_arguments ();
338 1154092 : var target_type_args = target_type.get_type_arguments ();
339 1154092 : if (type_args.size == target_type_args.size) {
340 1224543 : for (int i = 0; i < type_args.size; i++) {
341 36996 : var type_arg = type_args[i];
342 36996 : var target_type_arg = target_type_args[i];
343 : // Ignore non-boxed simple-type structs
344 36996 : if (!type_arg.is_non_null_simple_type ()
345 36846 : && type_arg.is_weak () != target_type_arg.is_weak ()) {
346 1 : return false;
347 : }
348 : }
349 : }
350 :
351 1154091 : if (type_symbol != null && target_type.type_symbol != null && type_symbol.is_subtype_of (target_type.type_symbol)) {
352 1036256 : var base_type = SemanticAnalyzer.get_instance_base_type_for_member(this, target_type.type_symbol, this);
353 : // check compatibility of generic type arguments
354 1036256 : var base_type_args = base_type.get_type_arguments();
355 1036256 : if (base_type_args.size == target_type_args.size) {
356 1073157 : for (int i = 0; i < base_type_args.size; i++) {
357 : // mutable generic types require type argument equality,
358 : // not just one way compatibility
359 : // as we do not currently have immutable generic container types,
360 : // the additional check would be very inconvenient, so we
361 : // skip the additional check for now
362 36995 : if (!base_type_args[i].compatible (target_type_args[i])) {
363 2 : return false;
364 : }
365 : }
366 : }
367 1036254 : return true;
368 : }
369 :
370 117835 : if (type_symbol is Struct && target_type.type_symbol is Struct) {
371 26122 : unowned Struct expr_struct = (Struct) type_symbol;
372 26122 : unowned Struct target_struct = (Struct) target_type.type_symbol;
373 :
374 : // Allow compatibility of struct subtypes in both ways
375 26122 : if (target_struct.is_subtype_of (expr_struct)) {
376 2 : return true;
377 : }
378 :
379 : // Negative ranks are used for handle types that are not implicitly convertible
380 26120 : if ((expr_struct.is_integer_type () || expr_struct.is_floating_type ()) && expr_struct.rank < 0) {
381 2 : return false;
382 26118 : } else if ((target_struct.is_integer_type () || target_struct.is_floating_type ()) && target_struct.rank < 0) {
383 1 : return false;
384 : }
385 :
386 : /* integer types may be implicitly cast to floating point types */
387 26117 : if (expr_struct.is_integer_type () && target_struct.is_floating_type ()) {
388 1478 : return true;
389 : }
390 :
391 24639 : if ((expr_struct.is_integer_type () && target_struct.is_integer_type ()) ||
392 137 : (expr_struct.is_floating_type () && target_struct.is_floating_type ())) {
393 24560 : if (expr_struct.rank <= target_struct.rank) {
394 24551 : return true;
395 : }
396 : }
397 :
398 88 : if (expr_struct.is_boolean_type () && target_struct.is_boolean_type ()) {
399 6 : return true;
400 : }
401 : }
402 :
403 91795 : return false;
404 : }
405 :
406 : /**
407 : * Returns whether instances of this type are invokable.
408 : *
409 : * @return true if invokable, false otherwise
410 : */
411 191425 : public virtual bool is_invokable () {
412 0 : return false;
413 : }
414 :
415 : /**
416 : * Returns the return type of this invokable.
417 : *
418 : * @return return type
419 : */
420 234869 : public virtual unowned DataType? get_return_type () {
421 0 : return null;
422 : }
423 :
424 : /**
425 : * Returns the list of invocation parameters.
426 : *
427 : * @return parameter list
428 : */
429 221546 : public virtual unowned List<Parameter>? get_parameters () {
430 0 : return null;
431 : }
432 :
433 284500 : public virtual bool is_reference_type_or_type_parameter () {
434 527349 : return (type_symbol != null &&
435 256451 : type_symbol.is_reference_type ()) ||
436 177834 : this is GenericType;
437 : }
438 :
439 : // check whether this type is at least as accessible as the specified symbol
440 47982093 : public virtual bool is_accessible (Symbol sym) {
441 25146898 : foreach (var type_arg in get_type_arguments ()) {
442 943326 : if (!type_arg.is_accessible (sym)) {
443 0 : return false;
444 : }
445 : }
446 23260246 : if (type_symbol != null) {
447 21310942 : return type_symbol.is_accessible (sym);
448 : }
449 23260246 : return true;
450 : }
451 :
452 523889 : public virtual Symbol? get_member (string member_name) {
453 252371 : Symbol? member = null;
454 252371 : if (context_symbol != null) {
455 50 : member = SemanticAnalyzer.symbol_lookup_inherited (context_symbol, member_name);
456 : }
457 252371 : if (member == null && type_symbol != null) {
458 252323 : member = SemanticAnalyzer.symbol_lookup_inherited (type_symbol, member_name);
459 : }
460 : return member;
461 : }
462 :
463 2 : public virtual Symbol? get_pointer_member (string member_name) {
464 : return null;
465 : }
466 :
467 : /**
468 : * Checks whether this data type references a real struct. A real struct
469 : * is a struct which is not a simple (fundamental) type.
470 : */
471 533368 : public virtual bool is_real_struct_type () {
472 533368 : unowned Struct? s = type_symbol as Struct;
473 142450 : if (s != null && !s.is_simple_type ()) {
474 : return true;
475 : }
476 : return false;
477 : }
478 :
479 153806 : public bool is_real_non_null_struct_type () {
480 153806 : return is_real_struct_type () && !nullable;
481 : }
482 :
483 479836 : public bool is_non_null_simple_type () {
484 479836 : unowned Struct? s = type_symbol as Struct;
485 111249 : if (s != null && s.is_simple_type ()) {
486 109955 : return !nullable;
487 : }
488 369881 : if (type_symbol is Enum) {
489 1136 : return !nullable;
490 : }
491 479836 : return false;
492 : }
493 :
494 : /**
495 : * Returns whether the value needs to be disposed, i.e. whether
496 : * allocated memory or other resources need to be released when
497 : * the value is no longer needed.
498 : */
499 1024655 : public virtual bool is_disposable () {
500 355309 : if (!value_owned) {
501 : return false;
502 : }
503 :
504 115617 : if (is_reference_type_or_type_parameter ()) {
505 : return true;
506 : }
507 : return false;
508 : }
509 :
510 1091645 : public virtual DataType get_actual_type (DataType? derived_instance_type, List<DataType>? method_type_arguments, CodeNode? node_reference) {
511 842693 : DataType result = this.copy ();
512 :
513 842693 : if (derived_instance_type == null && method_type_arguments == null) {
514 : return result;
515 : }
516 :
517 675616 : if (result.type_argument_list != null) {
518 : // recursely get actual types for type arguments
519 139026 : for (int i = 0; i < result.type_argument_list.size; i++) {
520 70700 : result.type_argument_list[i] = result.type_argument_list[i].get_actual_type (derived_instance_type, method_type_arguments, node_reference);
521 : }
522 : }
523 :
524 : return result;
525 : }
526 :
527 206 : public bool is_generic () {
528 206 : if (this is GenericType) {
529 7 : return true;
530 : }
531 :
532 200 : if (!has_type_arguments ()) {
533 199 : return false;
534 : }
535 3 : foreach (var type_arg in type_argument_list) {
536 2 : if (type_arg.is_generic ()) {
537 1 : return true;
538 : }
539 : }
540 206 : return false;
541 : }
542 :
543 14 : public void replace_type_parameter (TypeParameter old_type_param, TypeParameter new_type_param) {
544 14 : if (this is GenericType) {
545 10 : if (symbol == old_type_param) {
546 6 : symbol = new_type_param;
547 : }
548 10 : return;
549 : }
550 4 : if (!has_type_arguments ()) {
551 : return;
552 : }
553 5 : foreach (var type_arg in type_argument_list) {
554 2 : type_arg.replace_type_parameter (old_type_param, new_type_param);
555 : }
556 : }
557 :
558 : /**
559 : * Search for the type parameter in this formal type and match it in
560 : * value_type.
561 : */
562 313 : public virtual DataType? infer_type_argument (TypeParameter type_param, DataType value_type) {
563 105 : var value_type_arg_it = value_type.get_type_arguments ().iterator ();
564 109 : foreach (var formal_type_arg in this.get_type_arguments ()) {
565 11 : if (value_type_arg_it.next ()) {
566 11 : var inferred_type = formal_type_arg.infer_type_argument (type_param, value_type_arg_it.get ());
567 11 : if (inferred_type != null) {
568 9 : return inferred_type;
569 : }
570 : }
571 : }
572 :
573 96 : return null;
574 : }
575 :
576 : /**
577 : * Returns a stringified representation used for detailed error output
578 : *
579 : * @param override_name used as name if given
580 : * @return stringified representation
581 : */
582 58 : public virtual string to_prototype_string (string? override_name = null) {
583 40 : return "%s%s".printf (is_weak () ? "unowned " : "", to_qualified_string ());
584 : }
585 :
586 88827 : public bool is_weak () {
587 88827 : if (this.value_owned) {
588 : return false;
589 10397 : } else if (this is VoidType || this is PointerType) {
590 : return false;
591 6502 : } else if (this is ValueType) {
592 3509 : if (this.nullable) {
593 : // nullable structs are heap allocated
594 : return true;
595 : }
596 :
597 : // TODO return true for structs with destroy
598 : return false;
599 : }
600 :
601 : return true;
602 : }
603 :
604 1228 : public string? get_type_signature (Symbol? symbol = null) {
605 1469 : if (symbol != null) {
606 251 : string sig = symbol.get_attribute_string ("DBus", "signature");
607 251 : if (sig != null) {
608 : // allow overriding signature in attribute, used for raw GVariants
609 1228 : return sig;
610 : }
611 : }
612 :
613 1218 : unowned ArrayType? array_type = this as ArrayType;
614 :
615 1218 : if (array_type != null) {
616 218 : string element_type_signature = array_type.element_type.get_type_signature ();
617 :
618 218 : if (element_type_signature == null) {
619 3 : return null;
620 : }
621 :
622 215 : return string.nfill (array_type.rank, 'a') + element_type_signature;
623 1000 : } else if (type_symbol is Enum && type_symbol.get_attribute_bool ("DBus", "use_string_marshalling")) {
624 6 : return "s";
625 994 : } else if (type_symbol != null) {
626 994 : string sig = type_symbol.get_attribute_string ("CCode", "type_signature");
627 :
628 994 : unowned Struct? st = type_symbol as Struct;
629 994 : unowned Enum? en = type_symbol as Enum;
630 994 : if (sig == null && st != null) {
631 42 : var str = new StringBuilder ();
632 84 : str.append_c ('(');
633 206 : foreach (Field f in st.get_fields ()) {
634 86 : if (f.binding == MemberBinding.INSTANCE) {
635 86 : var s = f.variable_type.get_type_signature (f);
636 86 : if (s != null) {
637 164 : str.append (s);
638 : } else {
639 4 : return null;
640 : }
641 : }
642 : }
643 38 : str.append_c (')');
644 76 : sig = str.str;
645 952 : } else if (sig == null && en != null) {
646 0 : if (en.is_flags) {
647 0 : return "u";
648 : } else {
649 0 : return "i";
650 : }
651 : }
652 :
653 990 : var type_args = get_type_arguments ();
654 990 : if (sig != null && "%s" in sig && type_args.size > 0) {
655 38 : string element_sig = "";
656 190 : foreach (DataType type_arg in type_args) {
657 76 : var s = type_arg.get_type_signature ();
658 76 : if (s != null) {
659 76 : element_sig += s;
660 : }
661 : }
662 :
663 38 : sig = sig.replace ("%s", element_sig);
664 : }
665 :
666 990 : if (sig == null &&
667 20 : (type_symbol.get_full_name () == "GLib.UnixInputStream" ||
668 8 : type_symbol.get_full_name () == "GLib.UnixOutputStream" ||
669 6 : type_symbol.get_full_name () == "GLib.Socket")) {
670 14 : return "h";
671 : }
672 :
673 976 : return sig;
674 : } else {
675 7 : return null;
676 : }
677 : }
678 :
679 : /**
680 : * Returns whether the given amount of type-argument matches the symbol's count of type-parameters
681 : *
682 : * @param context a CodeContext
683 : * @param allow_none whether no type-argments are allowed
684 : * @return true if successful
685 : */
686 37102840 : public bool check_type_arguments (CodeContext context, bool allow_none = false) {
687 37102840 : int n_type_args = get_type_arguments ().size;
688 37102840 : int expected_n_type_args = 0;
689 :
690 37102840 : if (type_symbol is GenericSymbol) {
691 35589704 : expected_n_type_args = ((GenericSymbol) type_symbol).get_type_parameters ().size;
692 1513136 : } else if (n_type_args > 0) {
693 0 : Report.error (source_reference, "`%s' does not support type arguments", type_symbol.get_full_name ());
694 0 : error = true;
695 0 : return false;
696 : } else {
697 : // nothing to do here
698 37102789 : return true;
699 : }
700 :
701 35589704 : if ((!allow_none || n_type_args > 0) && n_type_args < expected_n_type_args) {
702 26 : error = true;
703 26 : Report.error (source_reference, "too few type arguments for `%s'", type_symbol.to_string ());
704 26 : return false;
705 35589678 : } else if ((!allow_none || n_type_args > 0) && n_type_args > expected_n_type_args) {
706 23 : error = true;
707 23 : Report.error (source_reference, "too many type arguments for `%s'", type_symbol.to_string ());
708 23 : return false;
709 : }
710 :
711 39999499 : foreach (DataType type in get_type_arguments ()) {
712 2204924 : if (!type.check (context)) {
713 2 : return false;
714 : }
715 : }
716 :
717 37102840 : return true;
718 : }
719 : }
|