eval(read_file("dehydra_scripts/query_inheritance.js"))

var overloadMaster = []

function OverloadSet(overloads) {
  this.ready = []
  this.unsolved = overloads
}

OverloadSet.prototype.process = function(outparamdelTarget) {
  var t = outparamdelTarget.methodParamTypes
  var type = t[outparamdelTarget.outparamIndex]
  if (!this.outparamType)
    this.outparamType = type
  else if (this.outparamType != type) {
    print("Overloading causes conflicting outparam types in " 
          + outparamdelTarget.klass.name + "::" + outparamdelTarget.methodName)
    return
  }
  for(var i in this.unsolved) {
    var j = 0
    for(;j < t.length;j++) {
      if (this.unsolved[i].params[j].type != t[j]){
        print(this.unsolved[i].params[j].type + " != " + t[j])
        break
      }
    }
    if (j < t.length)
      continue
    this.ready.push([this.unsolved.splice(i,1), outparamdelTarget])
  }
  print("unsolved:" + this.unsolved.length + " ready:"+ this.ready.length)
  if (this.unsolved.length == 0) 
    for each (var o in this.ready) {
      o[1].printIfOnlyImplementation(o[0])
    }
}

function OutparamdelTarget(klass, methodName, methodParamTypes, outparamIndex) {
  this.klass = klass
  this.methodName = methodName
  this.methodParamTypes = methodParamTypes
  this.outparamIndex = outparamIndex
  this.klass = getCachedClass(klass)
  this.overloads = this.klass.getMembers(methodName)
}

// outputs outparam to stdout or queues it up for later
// and outputs it when all of the method overloads were processed 
OutparamdelTarget.prototype.go = function() {
  if (this.overloads.length == 1) {
    this.printIfOnlyImplementation(this.overloads[0])
    return
  }
  var name = this.klass + "::" + this.methodName
  o = overloadMaster[name]
  if (!o) {
    overloadMaster[name] = o = new OverloadSet(this.overloads)
  }
  o.process(this)
}

OutparamdelTarget.prototype.printIfOnlyImplementation = function (method) {
  var parent = this.klass
  var matches = [parent]
  if (method.isVirtual) {
    parent = c.getParentWithMember(method)
    if (parent.isXPIDL())
      return
    var children = parent.getChildren()
    children.push(parent)
    // filter out children that don't have this method imlemented
    matches = children.filter(function (c) {
      var m = c.getMember(method)
      return m && !m.isPureVirtual()
    })
  }
  if (matches.length == 1) {
    print("OUTPARAMS:"+matches[0].name + "::" +this.methodName
          + "(" + method.params.map(function(p) {return p.type}).join(",") + ")"
          + "," + this.outparamIndex)
  }
}

function input_end() {
/*  o = new OutparamdelTarget("txResultRecycler", "getNodeSet", 
                            ["txNodeSet **"], 0)*/
  o = new OutparamdelTarget("txResultRecycler", "getStringResult", 
                            [ "StringResult **"], 0)
  o.go()
  o = new OutparamdelTarget("txResultRecycler", "getStringResult", 
                            [ "nsAString_internal const &", "txAExprResult **"], 0)
  o.go()
  
//  print("'"+parent.getLoc()+"'")
  /*print(c.name)
  print(m)
  print(parent.name)*/
}
