Line data Source code
1 : /* valatypecheck.vala
2 : *
3 : * Copyright (C) 2006-2010 Jürg Billeter
4 : *
5 : * This library is free software; you can redistribute it and/or
6 : * modify it under the terms of the GNU Lesser General Public
7 : * License as published by the Free Software Foundation; either
8 : * version 2.1 of the License, or (at your option) any later version.
9 :
10 : * This library is distributed in the hope that it will be useful,
11 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 : * Lesser General Public License for more details.
14 :
15 : * You should have received a copy of the GNU Lesser General Public
16 : * License along with this library; if not, write to the Free Software
17 : * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 : *
19 : * Author:
20 : * Jürg Billeter <j@bitron.ch>
21 : */
22 :
23 : using GLib;
24 :
25 : /**
26 : * Represents a type check (`is`) expression in the source code.
27 : */
28 1408 : public class Vala.TypeCheck : Expression {
29 : /**
30 : * The expression to be checked.
31 : */
32 : public Expression expression {
33 9257 : get { return _expression; }
34 1376 : private set {
35 4116 : _expression = value;
36 1376 : _expression.parent_node = this;
37 : }
38 : }
39 :
40 : /**
41 : * The type to be matched against.
42 : */
43 : public DataType type_reference {
44 11983 : get { return _data_type; }
45 2740 : private set {
46 5480 : _data_type = value;
47 2740 : _data_type.parent_node = this;
48 : }
49 : }
50 :
51 1370 : Expression _expression;
52 1370 : private DataType _data_type;
53 :
54 : /**
55 : * Creates a new type check expression.
56 : *
57 : * @param expr an expression
58 : * @param type a data type
59 : * @param source reference to source code
60 : * @return newly created type check expression
61 : */
62 4110 : public TypeCheck (Expression expr, DataType type, SourceReference? source = null) {
63 1370 : expression = expr;
64 1370 : type_reference = type;
65 1370 : source_reference = source;
66 : }
67 :
68 3639 : public override void accept (CodeVisitor visitor) {
69 3639 : visitor.visit_type_check (this);
70 :
71 3639 : visitor.visit_expression (this);
72 : }
73 :
74 1754 : public override void accept_children (CodeVisitor visitor) {
75 1754 : expression.accept (visitor);
76 :
77 1754 : type_reference.accept (visitor);
78 : }
79 :
80 0 : public override bool is_pure () {
81 0 : return expression.is_pure ();
82 : }
83 :
84 1370 : public override void replace_type (DataType old_type, DataType new_type) {
85 1370 : if (type_reference == old_type) {
86 1370 : type_reference = new_type;
87 : }
88 : }
89 :
90 6 : public override void replace_expression (Expression old_node, Expression new_node) {
91 6 : if (expression == old_node) {
92 6 : expression = new_node;
93 : }
94 : }
95 :
96 1386 : public override bool check (CodeContext context) {
97 1386 : if (checked) {
98 16 : return !error;
99 : }
100 :
101 1370 : checked = true;
102 :
103 1370 : expression.check (context);
104 :
105 1370 : type_reference.check (context);
106 :
107 1370 : if (expression.value_type == null) {
108 0 : Report.error (expression.source_reference, "invalid left operand");
109 0 : error = true;
110 0 : return false;
111 : }
112 :
113 1370 : if (type_reference.type_symbol == null) {
114 : /* if type resolving didn't succeed, skip this check */
115 0 : error = true;
116 0 : return false;
117 : }
118 :
119 1370 : if (type_reference is ErrorType && !(expression.value_type is ErrorType)) {
120 1 : Report.error (expression.source_reference, "`%s' must be an error", expression.to_string ());
121 1 : error = true;
122 1 : return false;
123 : }
124 :
125 1369 : if (context.profile == Profile.GOBJECT && type_reference.has_type_arguments ()) {
126 0 : Report.warning (_data_type.source_reference, "Type argument list has no effect");
127 : }
128 :
129 1369 : value_type = context.analyzer.bool_type;
130 :
131 1369 : return !error;
132 : }
133 :
134 1369 : public override void emit (CodeGenerator codegen) {
135 1369 : expression.emit (codegen);
136 :
137 1369 : codegen.visit_type_check (this);
138 :
139 1369 : codegen.visit_expression (this);
140 : }
141 :
142 0 : public override string to_string () {
143 0 : return "(%s is %s)".printf (expression.to_string (), type_reference.to_string ());
144 : }
145 : }
|