import java.util.*;
import java.lang.reflect.*;
+/** use of this class is not recommended; it can handle only S-attributed grammars */
public class ReflectiveWalker extends StringWalker {
public ReflectiveWalker() { this.target = this; }
public ReflectiveWalker(Object target) { this.target = target; }
}
return ret.toString();
}
+ /*
+ public Object walk(Tree<String> tree) {
+ if (tree.head()!=null) {
+ Member m = member("$"+normalize(tree.head()), 0, false);
+ if (m!=null) {
+ if ((m instanceof Method) && ((Method)m).getReturnType()==Void.TYPE) {
+ Reflection.fuzzyInvoke(target, m, new Object[0]);
+ }
+ }
+ }
+ return super.walk(tree);
+ }
+ */
+ public void walk(String tag) {
+ if (tag==null) return;
+ Member m = member(normalize(tag), 0, false);
+ if (m!=null) Reflection.fuzzyInvoke(target, m);
+ }
+ protected Object defaultWalk(String tag, Object[] argo) { return super.walk(tag, argo); }
public Object walk(String tag, Object[] argo) {
if (argo.length==0) return super.walk(tag, argo);
if (argo==null) return tag;
if (tag==null || "".equals(tag)) return argo;
- Member m = member(normalize(tag), argo.length);
+ Member m = tag==null ? null : member(normalize(tag), argo.length, false);
+ if (m==null) return defaultWalk(tag, argo);
//System.out.println("preparing to invoke method " + (m==null ? "null" : (m.toString())) + " for sequence " + (owner()+"."+tag));
if (m != null) return Reflection.fuzzyInvoke(target, m, argo);
if (argo.length==0) return null;
return ret;
}
- public Member member(String methodName, int nonVoid) {
+ public Member member(String methodName, int nonVoid, boolean complain) {
Class target = this.target.getClass();
if (methodName == null || methodName.equals("")) return null;
Member ret = null;
for (Method m : target.getMethods()) {
if (!m.getName().equals(methodName)) continue;
if (m.getParameterTypes().length != nonVoid) continue;
- if (ret != null) throw new Error("two methods with " + nonVoid + " parameters: " + target.getName() + "." + methodName);
+ if (ret != null) {
+ if (!complain) return null;
+ throw new Error("two methods with " + nonVoid + " parameters: " + target.getName() + "." + methodName);
+ }
ret = m;
}
if (ret != null) return ret;
if (c != null) {
for (Constructor m : c.getConstructors()) {
if (m.getParameterTypes().length != nonVoid) continue;
- if (ret != null) throw new Error("two constructors with " + nonVoid + " parameters: " + c.getName() + ".<init>()");
+ if (ret != null) {
+ if (!complain) return null;
+ throw new Error("two constructors with " + nonVoid + " parameters: " + c.getName() + ".<init>()");
+ }
ret = m;
}
if (ret != null) return ret;
t = t.getSuperclass();
}
if (ret != null) return ret;
+ if (!complain) return null;
throw new Error("while computing return type of " +methodName+ " could not find method with name " + methodName +
" and " + nonVoid + " arguments");
}