package nl.utwente.viskell.haskell.env;
import nl.utwente.viskell.haskell.type.Type;
import nl.utwente.viskell.ui.serialize.Bundleable;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
public abstract class FunctionInfo {
private static final Map<String, String> subClassMap;
static {
Map<String, String> aMap = new HashMap<>();
aMap.put(CatalogFunction.class.getSimpleName(), CatalogFunction.class.getName());
subClassMap = Collections.unmodifiableMap(aMap);
}
/** The function name. */
protected final String name;
/** The type signature the corresponding function. */
protected final Type signature;
/**
* @param name The function name.
* @param signature The type signature the corresponding function.
*/
protected FunctionInfo(String name, Type signature) {
this.name = name;
this.signature = signature;
}
public abstract Map<String, Object> toBundleFragment();
/** return a new instance of this type deserializing class-specific properties used in constructor **/
public static FunctionInfo fromBundleFragment(Map<String,Object> bundleFragment) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException, ClassNotFoundException {
String kind = (String)bundleFragment.get(Bundleable.KIND);
String className = subClassMap.get(kind);
Class<?> clazz = Class.forName(className);
// Find the static "fromBundleFragment" method for the named type and call it
Method fromBundleMethod = clazz.getDeclaredMethod("fromBundleFragment", Map.class);
return (FunctionInfo)fromBundleMethod.invoke(null, bundleFragment);
}
/** @return The internal name of this function. */
public final String getName() {
return this.name;
}
/** @return The name of this function used for the front-end. */
public String getDisplayName() {
return getName();
}
/** @return The a fresh copy of type signature of this function. */
public final Type getFreshSignature() {
return this.signature.getFresh();
}
/** @return the number of argument this function can take. */
public int argumentCount() {
return this.signature.countArguments();
}
}