private void CheckThatAllAbstractSuperClassMethodsAreImplemented(){
//By the time we get here all abstract superclass members that are implemented by this class are already replaced by
//their names in superMembers. What remains is to weed out those that are implemented by more derived base classes
//and then to complain about any that are left over.
for (int i = 0, n = this.superMembers.Length; i < n; i++){
Object ob = this.superMembers[i];
MethodInfo meth = ob as MethodInfo;
if (meth != null){
if (!meth.IsAbstract) continue;
//Check to see if implemented by a more derived base class
for (int j = i-1; j >= 0; j--){
Object mem = this.superMembers[j];
if (mem is MethodInfo){
MethodInfo meth2 = (MethodInfo)mem;
if (meth2.Name != meth.Name) break;
if (!meth2.IsAbstract && Class.ParametersMatch(meth2.GetParameters(), meth.GetParameters())){
IReflect rt = meth is JSFieldMethod ? ((JSFieldMethod)meth).ReturnIR() : meth.ReturnType;
IReflect rt2 = meth2 is JSFieldMethod ? ((JSFieldMethod)meth2).ReturnIR() : meth2.ReturnType;
if (rt == rt2){
this.superMembers[i] = meth.Name;
goto noError;
}
}
}
}
//Nope, give an error (unless class is marked abstract, but not if the method comes from an interface)
if (!this.isAbstract || (!this.isInterface && Class.DefinedOnInterface(meth))){
StringBuilder sig = new StringBuilder(meth.DeclaringType.ToString());
sig.Append('.');
sig.Append(meth.Name);
sig.Append('(');
ParameterInfo[] pars = meth.GetParameters();
for (int j = 0, m = pars.Length; j < m; j++){
sig.Append(pars[j].ParameterType.FullName);
if (j < m-1)
sig.Append(", ");
}
sig.Append(")");
if (meth.ReturnType != Typeob.Void){
sig.Append(" : ");
sig.Append(meth.ReturnType.FullName);
}
this.context.HandleError(JSError.MustImplementMethod, sig.ToString());
this.attributes |= TypeAttributes.Abstract; //Make the class compilable
}
//If the super class method comes from an interface, emit an abstract method that implements it
}
noError:;
}
}