2 * Copyright (C) 1999-2000 the Free Software Foundation.
3 * Copyright (C) 2000 Eazel, Inc.
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
28 #include "treefuncs.h"
35 check_duplicate(Class *c, Node *node, char *id, int line_no,
39 for(l = c->nodes; l != NULL; l = g_list_next(l)) {
43 gboolean here_underscore = FALSE;
45 if(n->type == METHOD_NODE) {
46 Method *m = (Method *)n;
48 /* override methods are checked separately */
49 if(m->method == OVERRIDE_METHOD)
52 nid = get_real_id(m->id);
53 nline_no = m->line_no;
55 if(m->id[0] == '_' && m->id[1] != '\0')
56 here_underscore = TRUE;
57 } else if(n->type == VARIABLE_NODE) {
58 Variable *v = (Variable *)n;
60 nline_no = v->line_no;
65 n->type != node->type ||
68 /* this can only happen if the things were methods and
69 * one had an underscore and the other one didn't */
70 if(!no_kill_underscores && underscore != here_underscore)
71 s = g_strdup_printf("symbol '%s' ('_%s') redefined, "
72 "first defined on line %d. "
73 "Note that '%s' and '_%s' are "
75 id, id, line_no, id, id);
77 s = g_strdup_printf("symbol '%s' redefined, "
78 "first defined on line %d",
80 print_error(FALSE, s, nline_no);
86 check_duplicate_symbols(Class *c)
89 for(l = c->nodes; l != NULL; l = g_list_next(l)) {
91 if(n->type == METHOD_NODE) {
92 Method *m = (Method *)n;
93 gboolean underscore = FALSE;
94 /* override methods are checked separately */
95 if(m->method == OVERRIDE_METHOD)
97 if(m->id[0] == '_' && m->id[1] != '\0')
99 check_duplicate(c, n, get_real_id(m->id), m->line_no,
101 } else if(n->type == VARIABLE_NODE) {
102 Variable *v = (Variable *)n;
103 check_duplicate(c, n, v->id, v->line_no, FALSE);
109 check_duplicate_override(Class *c, Method *method)
112 for(l = c->nodes; l != NULL; l = g_list_next(l)) {
114 Method *m = (Method *)n;
116 if(n->type != METHOD_NODE ||
117 m->method != OVERRIDE_METHOD)
121 method->line_no > m->line_no ||
122 strcmp(m->id, method->id) != 0 ||
123 strcmp(m->otype, method->otype) != 0)
125 s = g_strdup_printf("override '%s(%s)' redefined, "
126 "first defined on line %d",
127 m->id, m->otype, method->line_no);
128 print_error(FALSE, s, m->line_no);
134 check_duplicate_overrides(Class *c)
137 for(l = c->nodes; l != NULL; l = g_list_next(l)) {
139 Method *m = (Method *)n;
140 if(n->type != METHOD_NODE ||
141 m->method != OVERRIDE_METHOD)
143 check_duplicate_override(c, m);
148 check_bad_symbols(Class *c)
151 for(l = c->nodes; l != NULL; l = g_list_next(l)) {
153 if(n->type == METHOD_NODE) {
154 Method *m = (Method *)n;
155 if((m->method == SIGNAL_LAST_METHOD ||
156 m->method == SIGNAL_FIRST_METHOD ||
157 m->method == VIRTUAL_METHOD) &&
158 strcmp(m->id, "__parent__")==0) {
160 s = g_strdup_printf("'%s' not allowed as an "
161 "identifier of signal "
162 "or virtual methods",
164 print_error(FALSE,s,m->line_no);
167 if(m->method != INIT_METHOD &&
168 m->method != CLASS_INIT_METHOD &&
169 (strcmp(m->id, "init")==0 ||
170 strcmp(m->id, "class_init")==0)) {
171 print_error(FALSE,"init, or class_init not "
174 "constructor methods", m->line_no);
176 } else if(n->type == VARIABLE_NODE) {
177 Variable *v = (Variable *)n;
178 if(strcmp(v->id, "_priv")==0 ||
179 strcmp(v->id, "__parent__")==0) {
181 s = g_strdup_printf("'%s' not allowed as a "
182 "data member name", v->id);
183 print_error(FALSE, s, v->line_no);
191 check_duplicate_named(Class *c, Node *node, char *id, int line_no)
194 for(l = c->nodes; l != NULL; l = g_list_next(l)) {
199 if(n->type == METHOD_NODE) {
200 Method *m = (Method *)n;
201 if(m->method == SIGNAL_LAST_METHOD ||
202 m->method == SIGNAL_FIRST_METHOD) {
204 nline_no = m->line_no;
207 } else if(n->type == ARGUMENT_NODE) {
208 Argument *a = (Argument *)n;
210 nline_no = a->line_no;
215 g_strcasecmp(nid,id)!=0)
217 s = g_strdup_printf("named symbol (argument or signal) '%s' "
218 "redefined, first defined on line %d "
219 "(case insensitive)",
221 print_error(FALSE,s,nline_no);
226 check_duplicate_signals_args(Class *c)
229 for(l = c->nodes; l != NULL; l = g_list_next(l)) {
231 if(n->type == METHOD_NODE) {
232 Method *m = (Method *)n;
233 if(m->method == SIGNAL_LAST_METHOD ||
234 m->method == SIGNAL_FIRST_METHOD)
235 check_duplicate_named(c,n,m->id,m->line_no);
236 } else if(n->type == ARGUMENT_NODE) {
237 Argument *a = (Argument *)n;
238 check_duplicate_named(c,n,a->name,a->line_no);
244 check_public_new(Class *c)
247 for(l = c->nodes; l != NULL; l = g_list_next(l)) {
249 if(n->type == METHOD_NODE) {
250 Method *m = (Method *)n;
251 if((strcmp(m->id,"new")==0) &&
252 (m->method != REGULAR_METHOD ||
253 m->scope != PUBLIC_SCOPE))
255 "'new' should be a regular\n"
263 check_vararg(Class *c)
266 for(l = c->nodes; l != NULL; l = g_list_next(l)) {
268 if(n->type == METHOD_NODE) {
269 Method *m = (Method *)n;
272 if(m->method == OVERRIDE_METHOD ||
273 m->method == SIGNAL_LAST_METHOD ||
274 m->method == SIGNAL_FIRST_METHOD ||
275 m->method == VIRTUAL_METHOD) {
277 "signals, overrides and virtuals, "
278 "can't have variable argument "
287 check_firstarg(Class *c)
290 for(l = c->nodes; l != NULL; l = g_list_next(l)) {
292 if(n->type == METHOD_NODE) {
293 Method *m = (Method *)n;
296 if(m->method == OVERRIDE_METHOD ||
297 m->method == SIGNAL_LAST_METHOD ||
298 m->method == SIGNAL_FIRST_METHOD ||
299 m->method == VIRTUAL_METHOD) {
301 "signals, overrides and virtuals, "
302 "can't have no arguments",
310 check_nonvoidempty(Class *c)
313 for(li = c->nodes; li != NULL; li = g_list_next(li)) {
315 if(n->type == METHOD_NODE) {
316 Method *m = (Method *)n;
317 if(m->method != REGULAR_METHOD)
319 if(!(strcmp(m->mtype->name, "void")==0 &&
320 m->mtype->stars == 0) &&
323 "non-void empty method found, "
324 "regular non-void function should "
327 /* add a body here, so that the user will also
328 get a warning from gcc, and so that it will
329 at least point him to the prototype of the
330 function in the .gob file */
331 m->cbuf = g_strdup("/*empty*/");
332 m->ccode_line = m->line_no;
339 check_signal_args(Class *c)
342 for(li = c->nodes; li != NULL; li = g_list_next(li)) {
344 if(n->type == METHOD_NODE) {
345 Method *m = (Method *)n;
347 if(m->method != SIGNAL_LAST_METHOD &&
348 m->method != SIGNAL_FIRST_METHOD)
351 for(l=m->gtktypes;l;l=l->next) {
353 if(get_cast(l->data, FALSE))
355 s = g_strdup_printf("Unknown GTK+ type '%s' "
356 "among signal types",
358 print_error(FALSE, s, m->line_no);
366 check_argument_types(Class *c)
369 for(l = c->nodes; l != NULL; l = g_list_next(l)) {
371 if(n->type == ARGUMENT_NODE) {
372 Argument *a = (Argument *)n;
374 if(get_cast(a->gtktype, FALSE))
376 s = g_strdup_printf("Unknown GTK+ type '%s' "
379 /* this could perhaps be a warning, but
380 can there really be a type beyond the
382 print_error(FALSE, s, a->line_no);
389 count_signals(Class *c)
393 for(l = c->nodes; l != NULL; l = g_list_next(l)) {
395 if(n->type == METHOD_NODE) {
396 Method *m = (Method *)n;
397 if(m->method == SIGNAL_LAST_METHOD ||
398 m->method == SIGNAL_FIRST_METHOD)
406 count_arguments(Class *c)
410 for(li = c->nodes; li != NULL; li = g_list_next(li)) {
412 if(n->type == ARGUMENT_NODE)
419 count_overrides(Class *c)
423 for(l = c->nodes; l != NULL; l = g_list_next(l)) {
425 if(n->type == METHOD_NODE) {
426 Method *m = (Method *)n;
427 if(m->method == OVERRIDE_METHOD)
435 count_privates(Class *c)
439 for(l = c->nodes; l != NULL; l = g_list_next(l)) {
441 if(n->type == VARIABLE_NODE) {
442 Variable *v = (Variable *)n;
443 if(v->scope == PRIVATE_SCOPE)
451 count_protecteds(Class *c)
455 for(l = c->nodes; l != NULL; l = g_list_next(l)) {
457 if(n->type == METHOD_NODE) {
458 Method *m = (Method *)n;
459 if(m->scope == PROTECTED_SCOPE)
467 count_destructors(Class *c)
471 for(l = c->nodes; l != NULL; l = g_list_next(l)) {
473 if(n->type == VARIABLE_NODE) {
474 Variable *v = (Variable *)n;
483 count_initializers(Class *c)
487 for(l = c->nodes; l != NULL; l = g_list_next(l)) {
489 if(n->type == VARIABLE_NODE) {
490 Variable *v = (Variable *)n;