private void CheckMethodDeclarationConsistency(FunctionObject func){
if (func.isStatic && !func.isExpandoMethod) return; //static methods do not clash with superclass methods
if (func.isConstructor) return; //Constructors cannot clash with superclass members
Object index = this.firstIndex[func.name];
if (index == null){
//There is no super class member with the same name as the function
this.CheckThatMethodIsNotMarkedWithOverrideOrHide(func);
if ((func.attributes & MethodAttributes.Final) != 0)
func.attributes &= ~(MethodAttributes.Virtual|MethodAttributes.NewSlot|MethodAttributes.Final);
return;
}
MemberInfo differentTypeOfMember = null;
for (int i = (int)index, n = this.superMembers.Length; i < n; i++){
MemberInfo member = this.superMembers[i] as MemberInfo;
if (member == null)
//if we do not get a MemberInfo we have already processed this superclass member and it matches another member of the current class
continue;
if (!member.Name.Equals(func.name)) break;
if (!this.CanSee(member)) continue;
if (member.MemberType != MemberTypes.Method){
//JScript does not allow overloading among different member types.
//Unless there is a superclass method with the same signature as the method, we have to give an error
differentTypeOfMember = member;
continue;
}
if (func.isExpandoMethod){
differentTypeOfMember = member;
break;
}
MethodInfo supmeth = (MethodInfo)member;
if (func.implementedIface != null){
//Skip superclass methods that do not come from the appropriate interface
if (supmeth is JSFieldMethod){
if (((JSFieldMethod)supmeth).EnclosingScope() != func.implementedIface) continue;
}else{
if (supmeth.DeclaringType != func.implementedIface) continue;
}
}
if (Class.ParametersMatch(supmeth.GetParameters(), func.parameter_declarations)){
if (supmeth is JSWrappedMethod)
supmeth = ((JSWrappedMethod)supmeth).method;
if (func.noVersionSafeAttributeSpecified || (func.attributes & MethodAttributes.VtableLayoutMask) != MethodAttributes.NewSlot){
//Check consistency of implicit or explicit override (a hiding method may be inconsistent)
this.CheckMatchingMethodForConsistency(supmeth, func, i, n);
}
return;
}
}
if (differentTypeOfMember != null){
//Did not find a superclass method with the same signature, but did find a member with same name that was not a method
//This is a no no for JScript unless the hide attribute has been specified
if (func.noVersionSafeAttributeSpecified ||
(func.attributes & MethodAttributes.VtableLayoutMask) != MethodAttributes.NewSlot && !func.isExpandoMethod){
String supMemberName = this.GetFullNameFor(differentTypeOfMember);
func.funcContext.HandleError(JSError.HidesParentMember, supMemberName, this.IsInTheSameCompilationUnit(differentTypeOfMember));
}
return;
}
//No matching method in superclass. Give an error if hide/override was specified
this.CheckThatMethodIsNotMarkedWithOverrideOrHide(func);
//Make final methods into non virtual
if ((func.attributes & MethodAttributes.Final) != 0)
func.attributes &= ~(MethodAttributes.Virtual|MethodAttributes.NewSlot|MethodAttributes.Final);
}