/* -----------------------------------------------------------------------------
 * This file is part of SWIG, which is licensed as a whole under version 3 
 * (or any later version) of the GNU General Public License. Some additional
 * terms also apply to certain portions of SWIG. The full details of the SWIG
 * license and copyrights can be found in the LICENSE and COPYRIGHT files
 * included with the SWIG source code as distributed by the SWIG developers
 * and at https://www.swig.org/legal.html.
 *
 * extend.c
 *
 * Extensions support (%extend)
 * ----------------------------------------------------------------------------- */

#include "swig.h"
#include "cparse.h"

static Hash *extendhash = 0;     /* Hash table of added methods */

/* -----------------------------------------------------------------------------
 * Swig_extend_hash()
 *
 * Access the extend hash
 * ----------------------------------------------------------------------------- */
Hash *Swig_extend_hash(void) {
  if (!extendhash)
    extendhash = NewHash();
  return extendhash;
}

/* -----------------------------------------------------------------------------
 * Swig_extend_merge()
 *
 * Extension merge.  This function is used to handle the %extend directive
 * when it appears before a class definition.   To handle this, the %extend
 * actually needs to take precedence.  Therefore, we will selectively nuke symbols
 * from the current symbol table, replacing them with the added methods.
 * ----------------------------------------------------------------------------- */

void Swig_extend_merge(Node *cls, Node *am) {
  Node *n;

  n = firstChild(am);
  while (n) {
    String *symname;
    if (Strcmp(nodeType(n),"constructor") == 0) {
      symname = Getattr(n,"sym:name");
      if (symname) {
	if (Strcmp(symname,Getattr(n,"name")) == 0) {
	  /* If the name and the sym:name of a constructor are the same,
             then it hasn't been renamed.  However---the name of the class
             itself might have been renamed so we need to do a consistency
             check here */
	  if (Getattr(cls,"sym:name")) {
	    Setattr(n,"sym:name", Getattr(cls,"sym:name"));
	  }
	}
      } 
    }

    symname = Getattr(n,"sym:name");
    DohIncref(symname);
    if ((symname) && (!Getattr(n,"error"))) {
      Node *c;
      /* Remove node from its symbol table */
      Swig_symbol_remove(n);
      c = Swig_symbol_add(symname,n);
      if (c != n) {
	/* Conflict with previous definition.  Nuke previous definition */
	String *e = NewStringEmpty();
	String *en = NewStringEmpty();
	String *ec = NewStringEmpty();
	Printf(ec, "Redefinition of identifier '%s' by %%extend ignored,", symname);
	Printf(en, "%%extend definition of '%s'.", symname);
	SWIG_WARN_NODE_BEGIN(n);
	Swig_warning(WARN_PARSE_REDEFINED, Getfile(c), Getline(c), "%s\n", ec);
	Swig_warning(WARN_PARSE_REDEFINED, Getfile(n), Getline(n), "%s\n", en);
	SWIG_WARN_NODE_END(n);
	Printf(e, "%s:%d:%s\n%s:%d:%s\n", Getfile(c), Getline(c), ec, Getfile(n),Getline(n),en);
	Setattr(c, "error", e);
	Delete(e);
	Delete(en);
	Delete(ec);
	Swig_symbol_remove(c);                /* Remove class definition */
	Swig_symbol_add(symname, n);          /* Insert extend definition */
      }
    }
    n = nextSibling(n);
  }
}

/* -----------------------------------------------------------------------------
 * Swig_extend_append_previous()
 * ----------------------------------------------------------------------------- */

void Swig_extend_append_previous(Node *cls, Node *am) {
  Node *n, *ne;
  Node *pe = 0;
  Node *ae = 0;

  if (!am) return;
  
  n = firstChild(am);
  while (n) {
    ne = nextSibling(n);
    set_nextSibling(n,0);
    /* typemaps and fragments need to be prepended */
    if (((Cmp(nodeType(n),"typemap") == 0) || (Cmp(nodeType(n),"fragment") == 0)))  {
      if (!pe) pe = Swig_cparse_new_node("extend");
      appendChild(pe, n);
    } else {
      if (!ae) ae = Swig_cparse_new_node("extend");
      appendChild(ae, n);
    }    
    n = ne;
  }
  if (pe) prependChild(cls,pe);
  if (ae) appendChild(cls,ae);
}
 

/* -----------------------------------------------------------------------------
 * Swig_extend_unused_check()
 *
 * Check for unused %extend.  Special case, don't report unused
 * extensions for templates
 * ----------------------------------------------------------------------------- */
 
void Swig_extend_unused_check(void) {
  Iterator ki;

  if (!extendhash) return;
  for (ki = First(extendhash); ki.key; ki = Next(ki)) {
    if (!Strchr(ki.key,'<')) {
      SWIG_WARN_NODE_BEGIN(ki.item);
      Swig_warning(WARN_PARSE_EXTEND_UNDEF,Getfile(ki.item), Getline(ki.item), "%%extend defined for an undeclared class %s.\n", SwigType_namestr(ki.key));
      SWIG_WARN_NODE_END(ki.item);
    }
  }
}

