+static void
+check_duplicate(Class *c,Node *node,char *id, int line_no)
+{
+ GList *l;
+ for(l=c->nodes;l;l=g_list_next(l)) {
+ Node *n = l->data;
+ char *nid;
+ int nline_no;
+ char *s;
+ if(n->type == METHOD_NODE) {
+ Method *m = (Method *)n;
+ nid = m->id;
+ nline_no = m->line_no;
+ } else if(n->type == VARIABLE_NODE) {
+ Variable *v = (Variable *)n;
+ nid = v->id;
+ nline_no = v->line_no;
+ } else
+ continue;
+ if(n==node ||
+ line_no>=nline_no ||
+ strcmp(nid,id)!=0)
+ continue;
+ s = g_strdup_printf("symbol '%s' redefined, "
+ "first defined on line %d",
+ id,line_no);
+ print_error(FALSE,s,nline_no);
+ }
+}
+
+static void
+check_duplicate_symbols(Class *c)
+{
+ GList *l;
+ for(l=c->nodes;l;l=g_list_next(l)) {
+ Node *n = l->data;
+ if(n->type == METHOD_NODE) {
+ Method *m = (Method *)n;
+ check_duplicate(c,n,m->id,m->line_no);
+ } else if(n->type == VARIABLE_NODE) {
+ Variable *v = (Variable *)n;
+ check_duplicate(c,n,v->id,v->line_no);
+ }
+ }
+}
+
+static void
+check_duplicate_named(Class *c,Node *node,char *id, int line_no)
+{
+ GList *l;
+ for(l=c->nodes;l;l=g_list_next(l)) {
+ Node *n = l->data;
+ char *nid;
+ int nline_no;
+ char *s;
+ if(n->type == METHOD_NODE) {
+ Method *m = (Method *)n;
+ if(m->scope == SIGNAL_LAST_METHOD ||
+ m->scope == SIGNAL_FIRST_METHOD) {
+ nid = m->id;
+ nline_no = m->line_no;
+ } else
+ continue;
+ } else if(n->type == ARGUMENT_NODE) {
+ Argument *a = (Argument *)n;
+ nid = a->name;
+ nline_no = a->line_no;
+ } else
+ continue;
+ if(n==node ||
+ line_no>=nline_no ||
+ strcmp(nid,id)!=0)
+ continue;
+ s = g_strdup_printf("named symbol (argument or signal) '%s' "
+ "redefined, first defined on line %d",
+ id,line_no);
+ print_error(FALSE,s,nline_no);
+ }
+}
+
+static void
+check_duplicate_signals_args(Class *c)
+{
+ GList *l;
+ for(l=c->nodes;l;l=g_list_next(l)) {
+ Node *n = l->data;
+ if(n->type == METHOD_NODE) {
+ Method *m = (Method *)n;
+ if(m->scope == SIGNAL_LAST_METHOD ||
+ m->scope == SIGNAL_FIRST_METHOD)
+ check_duplicate_named(c,n,m->id,m->line_no);
+ } else if(n->type == ARGUMENT_NODE) {
+ Argument *a = (Argument *)n;
+ check_duplicate_named(c,n,a->name,a->line_no);
+ }
+ }
+}
+
+static void
+check_public_new(Class *c)
+{
+ GList *l;
+ for(l=c->nodes;l;l=g_list_next(l)) {
+ Node *n = l->data;
+ if(n->type == METHOD_NODE) {
+ Method *m = (Method *)n;
+ if(m->scope!=PUBLIC_SCOPE &&
+ strcmp(m->id,"new")==0)
+ print_error(TRUE,
+ "'new' should be a public method",
+ m->line_no);
+ }
+ }
+}
+