Signed.java
package Hoot.Runtime.Behaviors;
import java.util.*;
import Hoot.Runtime.Faces.Named;
import Hoot.Runtime.Names.TypeName;
import static Hoot.Runtime.Functions.Utils.*;
/**
* Describes a method signature.
*
* @author nik <nikboyd@sonic.net>
* @see "Copyright 2010,2021 Nikolas S Boyd."
* @see "Permission is granted to copy this work provided this copyright statement is retained in all copies."
*/
public interface Signed extends Named {
boolean isStatic();
Typified faceType();
int argumentCount();
List<Typified> argumentTypes();
List<TypeName> argumentTypeNames();
default boolean overridesHeritage() {
Set<Typified> heritage = copySet(faceType().fullInheritance());
return matchAny(heritage, type -> {
Signed s = type.getSigned(this);
return hasAny(s) && !this.isStatic() && this.matches(s); }); }
default boolean matches(Signed s) {
boolean matchCounts = argumentCount() == s.argumentCount();
boolean matchNames = methodName().equals(s.methodName());
boolean faceDiffers = !faceName().equals(s.faceName());
boolean sameArgTypes = matchesArgumentTypes(s);
boolean result = matchCounts && matchNames && faceDiffers && sameArgTypes;
reportMatch(s, result);
return result; }
default boolean matchesArgumentTypes(Signed s) {
if (argumentCount() != s.argumentCount()) return false;
List<TypeName> aTypes = argumentTypeNames();
List<TypeName> bTypes = s.argumentTypeNames();
for (int index = 0; index < aTypes.size(); index++) {
if (hasNo(aTypes.get(index))) return reportMissingArg(index);
if (hasNo(bTypes.get(index))) return reportMissingArg(index);
if (!aTypes.get(index).matches(bTypes.get(index))) return false;
}
// all args match
return true; }
default String faceName() { return faceType().fullName(); }
default String methodName() { return name().toString(); }
default String fullSignature() { return shortSignature(); }
default String erasedSignature() { return shortSignature(); }
default String shortSignature() { return methodName(); }
default String matchSignature() { return methodName(); }
default String matchErasure() { return methodName(); }
default boolean anyGenericArgs() { return matchAny(argumentTypeNames(), type -> type.isGeneric()); }
default boolean overridesArguments(Signed s) { return matchesArgumentTypes(s); }
default boolean overrides(Signed s) {
boolean matchCounts = argumentCount() == s.argumentCount();
boolean matchNames = methodName().equals(s.methodName());
boolean canOverride = !isStatic() && !faceName().equals(s.faceName());
boolean overage = matchNames && matchCounts && canOverride;
boolean overrides = matchesArgumentTypes(s);
boolean result = overage && overrides;
if (canOverride)
reportMatch(s, overrides);
return result; }
static final String SigsReport = "sigs %s::%s %s %s::%s";
default boolean reportMatch(Signed s, boolean matched) {
String comp = (matched ? "~=" : "!=");
Object[] sigs = {
faceType().shortName(), matchSignature(), comp,
s.faceType().shortName(), s.matchSignature(),
};
if (matched) {
whisper(format(SigsReport, sigs));
}
else {
whisper(format(SigsReport, sigs));
}
return matched; }
static final String MissingReport = "missing arg %d in %s::%s";
default boolean reportMissingArg(int index) {
report(format(MissingReport, index, getClass().getCanonicalName(), methodName())); return false; }
} // Signed