@Override public void visit(Symbol name) { if (!unique || !set.contains(name)) { if (maxNames == -1 || names.length() < maxNames) { names.add(StringArrayVector.valueOf(name.getPrintName())); set.add(name); } } }
private static SEXP R_loadMethod(Context context, SEXP def, String fname, Environment ev) { /* since this is called every time a method is dispatched with a definition that has a class, it should be as efficient as possible => we build in knowledge of the standard MethodDefinition and MethodWithNext slots. If these (+ the class slot) don't account for all the attributes, regular dispatch is done. */ int found = 1; /* we "know" the class attribute is there */ found++; // we also have our fake __S4_BIt for renjin PairList attrib = def.getAttributes().asPairList(); for (PairList.Node s : attrib.nodes()) { SEXP t = s.getTag(); if (t == R_target) { ev.setVariable(R_dot_target, s.getValue()); found++; } else if (t == R_defined) { ev.setVariable(R_dot_defined, s.getValue()); found++; } else if (t == R_nextMethod) { ev.setVariable(R_dot_nextMethod, s.getValue()); found++; } else if (t == Symbols.SOURCE) { /* ignore */ found++; } } ev.setVariable(R_dot_Method, def); /* this shouldn't be needed but check the generic being "loadMethod", which would produce a recursive loop */ if (fname.equals("loadMethod")) { return def; } if (found < attrib.length()) { FunctionCall call = FunctionCall.newCall(R_loadMethod_name, def, StringArrayVector.valueOf(fname), ev); return context.evaluate(call, ev); // SEXP e, val; // PROTECT(e = allocVector(LANGSXP, 4)); // SETCAR(e, R_loadMethod_name); val = CDR(e); // SETCAR(val, def); val = CDR(val); // SETCAR(val, fname); val = CDR(val); // SETCAR(val, ev); // val = eval(e, ev); // return val; } else { return def; } }
/* C version of the standardGeneric R function. */ public SEXP R_standardGeneric(Context context, Symbol fsym, Environment ev, SEXP fdef) { String fname = fsym.getPrintName(); Environment f_env = context.getGlobalEnvironment().getBaseEnvironment(); SEXP mlist = Null.INSTANCE; SEXP f; SEXP val = Null.INSTANCE; int nprotect = 0; // if(!initialized) // R_initMethodDispatch(NULL); if (fdef instanceof Closure) { f_env = ((Closure) fdef).getEnclosingEnvironment(); mlist = f_env.getVariable(".Methods"); if (mlist == Symbol.UNBOUND_VALUE) { mlist = Null.INSTANCE; } } else if (fdef instanceof PrimitiveFunction) { f_env = context.getBaseEnvironment(); // mlist = R_primitive_methods((PrimitiveFunction)fdef); throw new UnsupportedOperationException(); } else { throw new EvalException( "invalid generic function object for method selection for function '%s': expected a function or a primitive, got an object of class \"%s\"", fsym.getPrintName(), fdef.getAttributes().getClassVector()); } if (mlist instanceof Null || mlist instanceof Closure || mlist instanceof PrimitiveFunction) { f = mlist; } else { // f = do_dispatch(fname, ev, mlist, TRUE, TRUE); throw new UnsupportedOperationException(); } if (f == Null.INSTANCE) { SEXP value = R_S_MethodsListSelect(context, StringArrayVector.valueOf(fname), ev, mlist, f_env); if (value == Null.INSTANCE) { throw new EvalException( "no direct or inherited method for function '%s' for this call", fname); } mlist = value; /* now look again. This time the necessary method should have been inserted in the MethodsList object */ f = do_dispatch(context, fname, (Environment) ev, mlist, false, true); } // /* loadMethod methods */ if (f.isObject()) { f = R_loadMethod(context, f, fsym.getPrintName(), ev); } if (f instanceof Closure) { return R_execMethod(context, (Closure) f, ev); } else if (f instanceof PrimitiveFunction) { /* primitives can't be methods; they arise only as the default method when a primitive is made generic. In this case, return a special marker telling the C code to go on with the internal computations. */ // val = R_deferred_default_method(); throw new UnsupportedOperationException(); } else { throw new EvalException("invalid object (non-function) used as method"); } // return val; }