@Internal("file.copy") public static LogicalVector fileCopy( @Current Context context, StringVector fromFiles, String to, boolean overwrite, final boolean recursive) throws FileSystemException { LogicalArrayVector.Builder result = new LogicalArrayVector.Builder(); FileObject toFile = context.resolveFile(to); for (String from : fromFiles) { try { toFile.copyFrom( context.resolveFile(from), new FileSelector() { @Override public boolean traverseDescendents(FileSelectInfo fileInfo) throws Exception { return true; } @Override public boolean includeFile(FileSelectInfo fileInfo) throws Exception { return recursive; } }); result.add(true); } catch (FileSystemException e) { result.add(false); } } return result.build(); }
/** * Extract files from or list a zip archive. * * @param context the current call Context * @param zipFile The pathname of the zip file: tilde expansion (see path.expand) will be * performed. * @param files A character vector of recorded filepaths to be extracted: the default is to * extract all files. * @param exdirUri The directory to extract files to (the equivalent of unzip -d). It will be * created if necessary. * @param list If TRUE, list the files and extract none. The equivalent of unzip -l. * @param overwrite If TRUE, overwrite existing files, otherwise ignore such files. The equivalent * of unzip -o. * @param junkpaths If TRUE, use only the basename of the stored filepath when extracting. The * equivalent of unzip -j. * @return If list = TRUE, a data frame with columns Name, Length (the size of the uncompressed * file) and Date (of class "POSIXct"). Otherwise, a character vector of the filepaths * extracted to, invisibly. * @throws IOException */ @Internal public static SEXP unzip( @Current Context context, String zipFile, Vector files, String exdirUri, boolean list, boolean overwrite, boolean junkpaths) throws IOException { ZipInputStream zin = new ZipInputStream(context.resolveFile(pathExpand(zipFile)).getContent().getInputStream()); try { FileObject exdir = context.resolveFile(exdirUri); if (list) { throw new EvalException("unzip(list=true) not yet implemented"); } ZipEntry entry; while ((entry = zin.getNextEntry()) != null) { if (unzipMatches(entry, files)) { unzipExtract(zin, entry, exdir, junkpaths, overwrite); } } context.setInvisibleFlag(); return new IntArrayVector(0); } finally { zin.close(); } }
/** * ‘file.append’ attempts to append the files named by its second argument to those named by its * first. The R subscript recycling rule is used to align names given in vectors of different * lengths. */ @Internal("file.append") @DataParallel public static boolean fileAppend( @Current Context context, String destFileName, String sourceFileName) { try { FileObject sourceFile = context.resolveFile(sourceFileName); if (!sourceFile.exists()) { return false; } FileObject destFile = context.resolveFile(destFileName); OutputStream out = destFile.getContent().getOutputStream(true); try { InputStream in = sourceFile.getContent().getInputStream(); try { ByteStreams.copy(in, out); } finally { try { in.close(); } catch (Exception ignored) { } } } finally { try { out.close(); } catch (Exception ignored) { } } return true; } catch (Exception e) { return false; } }
public int getFrameDepth() { int nframe = 0; Context cptr = this; while (!cptr.isTopLevel()) { if (cptr.getType() == Type.FUNCTION) nframe++; cptr = cptr.getParent(); } return nframe; }
/** * Creates the last element of the path, unless recursive = TRUE. Trailing path separators are * removed. * * @param context the current call Context * @param path the path * @param showWarnings should the warnings on failure be shown? * @param recursive Should elements of the path other than the last be created? If true, like * Unix's mkdir -p * @param mode the file mode to be used on Unix-alikes: it will be coerced by as.octmode. * (currently ignored by renjin) * @return true if the operation succeeded for each of the files attempted. Using a missing value * for a path name will always be regarded as a failure. returns false if the directory * already exists * @throws FileSystemException */ @Internal("dir.create") public static SEXP dirCreate( @Current Context context, String path, boolean showWarnings, boolean recursive, int mode) throws FileSystemException { FileObject dir = context.resolveFile(path); dir.createFolder(); // TODO: return correct value and implement warnings documented above context.setInvisibleFlag(); return new LogicalArrayVector(true); }
protected void evalBaseResource(String resourceName) throws IOException { Context evalContext = this.beginEvalContext(session.getBaseNamespaceEnv()); InputStream in = getClass().getResourceAsStream(resourceName); if (in == null) { throw new IOException("Could not load resource '" + resourceName + "'"); } Reader reader = new InputStreamReader(in); try { evalContext.evaluate(RParser.parseSource(reader)); } finally { reader.close(); } }
@Invisible @Internal public static String setwd(@Current Context context, String workingDirectoryName) throws FileSystemException { FileObject newWorkingDirectory = context.resolveFile(workingDirectoryName); if (!newWorkingDirectory.exists() || newWorkingDirectory.getType() != FileType.FOLDER) { throw new EvalException("cannot change working directory"); } String previous = context.getSession().getWorkingDirectory().getName().getURI(); context.getSession().setWorkingDirectory(newWorkingDirectory); return previous; }
public Context beginFunction( Environment rho, FunctionCall call, Closure closure, PairList arguments) { Context context = new Context(); context.type = Type.FUNCTION; context.parent = this; context.evaluationDepth = evaluationDepth + 1; context.closure = closure; context.environment = Environment.createChildEnvironment(closure.getEnclosingEnvironment()); context.session = session; context.arguments = arguments; context.call = call; context.callingEnvironment = rho; return context; }
private static SubstituteContext buildContext(Context context, Environment rho, SEXP argument) { if (argument == Symbol.MISSING_ARG) { return buildContext(context, rho); } SEXP env = context.evaluate(argument, rho); return buildContext(context, env); }
/** * Convert file paths to canonical form for the platform, to display them in a user-understandable * form. * * <p>If a path is not a real path the result is undefined. This implementation will return the * input. */ @Internal @DataParallel public static String normalizePath( @Current Context context, @Recycle String path, String winSlash, SEXP mustWork) { try { return context.resolveFile(path).getName().getURI(); } catch (FileSystemException e) { return path; } }
@Internal("file.access") public static IntVector fileAccess(@Current Context context, StringVector names, int mode) throws FileSystemException { IntArrayVector.Builder result = new IntArrayVector.Builder(); for (String name : names) { FileObject file = context.resolveFile(pathExpand(name)); result.add(checkAccess(file, mode)); } result.setAttribute(Symbols.NAMES, new StringArrayVector(names.toArray())); return result.build(); }
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; } }
@Internal("Sys.setenv") public static LogicalVector setEnvironment( @Current Context context, StringVector names, StringVector values) { Map<String, String> map = context.getSession().getSystemEnvironment(); LogicalArrayVector.Builder result = new LogicalArrayVector.Builder(); for (int i = 0; i != names.length(); ++i) { map.put(names.getElementAsString(i), values.getElementAsString(i)); result.add(true); } return result.build(); }
/** * Utility function to extract information about files on the user's file systems. * * @param context current call Context * @param paths the list of files for which to return information * @return list column-oriented table of file information * @throws FileSystemException */ @Internal("file.info") public static ListVector fileInfo(@Current Context context, StringVector paths) throws FileSystemException { DoubleArrayVector.Builder size = new DoubleArrayVector.Builder(); LogicalArrayVector.Builder isdir = new LogicalArrayVector.Builder(); IntArrayVector.Builder mode = (IntArrayVector.Builder) new IntArrayVector.Builder() .setAttribute(Symbols.CLASS, StringVector.valueOf("octmode")); DoubleArrayVector.Builder mtime = new DoubleArrayVector.Builder(); StringVector.Builder exe = new StringVector.Builder(); for (String path : paths) { if (StringVector.isNA(path)) { throw new EvalException("invalid filename argument"); } FileObject file = context.resolveFile(path); if (file.exists()) { if (file.getType() == FileType.FILE) { size.add((int) file.getContent().getSize()); } else { size.add(0); } isdir.add(file.getType() == FileType.FOLDER); mode.add(mode(file)); try { mtime.add(file.getContent().getLastModifiedTime()); } catch (Exception e) { mtime.add(0); } exe.add(file.getName().getBaseName().endsWith(".exe") ? "yes" : "no"); } else { size.addNA(); isdir.addNA(); mode.addNA(); mtime.addNA(); exe.addNA(); } } return ListVector.newNamedBuilder() .add("size", size) .add("isdir", isdir) .add("mode", mode) .add("mtime", mtime) .add("ctime", mtime) .add("atime", mtime) .add("exe", exe) .build(); }
public Context beginEvalContext(Environment environment) { Context context = new Context(); context.type = Type.RETURN; context.parent = this; context.evaluationDepth = evaluationDepth + 1; context.environment = environment; context.session = session; return context; }
/** * Unlink deletes the file(s) or directories specified by {@code paths}. * * @param context the current call Context * @param paths list of paths to delete * @param recursive Should directories be deleted recursively? * @return 0 for success, 1 for failure. Not deleting a non-existent file is not a failure, nor is * being unable to delete a directory if recursive = FALSE. However, missing values in x are * regarded as failures. * @throws FileSystemException */ @Internal public static IntVector unlink( @Current Context context, StringVector paths, boolean recursive, boolean force) throws FileSystemException { IntArrayVector.Builder result = new IntArrayVector.Builder(); for (String path : paths) { if (StringVector.isNA(path)) { result.add(0); } else { FileObject file = context.resolveFile(path); delete(file, recursive); result.add(1); } } return result.build(); }
private static SubstituteContext buildContext(Context context, SEXP evaluatedEnv) { if (evaluatedEnv instanceof Environment) { if (context.getGlobalEnvironment() == evaluatedEnv) { return new GlobalEnvironmentContext(); } else { return new EnvironmentContext((Environment) evaluatedEnv); } } else if (evaluatedEnv instanceof ListVector) { return new ListContext((ListVector) evaluatedEnv); } else if (evaluatedEnv instanceof PairList) { return new PairListContext((PairList) evaluatedEnv); } else { throw new EvalException( "Cannot substitute using environment of type %s: expected list, pairlist, or environment", evaluatedEnv.getTypeName()); } }
@Internal("Sys.getenv") public static StringVector getEnvironment( @Current Context context, StringVector names, String unset) { StringVector.Builder result = new StringArrayVector.Builder(); Map<String, String> map = context.getSession().getSystemEnvironment(); if (names.length() == 0) { for (Map.Entry<String, String> entry : map.entrySet()) { result.add(entry.getKey() + "=" + entry.getValue()); } } else { for (String name : names) { String value = map.get(name); result.add(value == null ? unset : value); } } return result.build(); }
private SEXP R_S_MethodsListSelect(Context context, SEXP fname, SEXP ev, SEXP mlist, SEXP f_env) { PairList.Builder args = new PairList.Builder(); args.add(fname); args.add(ev); args.add(mlist); if (f_env != Null.INSTANCE) { args.add(f_env); } try { return context.evaluate( new FunctionCall(s_MethodsListSelect, args.build()), methodsNamespace); } catch (EvalException e) { throw new EvalException( String.format( "S language method selection got an error when called from" + " internal dispatch for function '%s'", fname), e); } }
@Internal("system") public static SEXP system( @Current Context context, String command, int flag, SEXP stdin, SEXP stdout, SEXP stderr) throws IOException, InterruptedException { boolean invisible = (flag >= 20 && flag < 29); boolean minimized = (flag >= 10 && flag < 19); List<String> args = parseArgs(command); ProcessBuilder builder = new ProcessBuilder(args); FileObject workingDir = context.getSession().getWorkingDirectory(); if (workingDir instanceof LocalFile) { File localDir = new File(workingDir.getURL().getFile()); builder.directory(localDir); } Process process = builder.start(); process.waitFor(); int exitValue = process.exitValue(); return new IntArrayVector(exitValue); }
@Internal("file.create") @DataParallel public static boolean fileCreate( @Current Context context, @Recycle String fileName, @Recycle(false) boolean showWarnings) throws IOException { try { FileObject file = context.resolveFile(fileName); // VFS will create the parent folder if it doesn't exist, // which the R method is not supposed to do if (!file.getParent().exists()) { throw new IOException("No such file or directory"); } file.getContent().getOutputStream().close(); return true; } catch (Exception e) { if (showWarnings) { Warning.invokeWarning( context, "cannot create file '%s', reason '%s'", fileName, e.getMessage()); } return false; } }
@Internal public static String getRHome(@Current Context context) throws URISyntaxException { return context.getSession().getHomeDirectory(); }
@Internal public static StringVector commandArgs(@Current Context context) { return context.getSession().getCommandLineArguments(); }
private SEXP do_dispatch( Context context, String fname, SEXP ev, SEXP mlist, boolean firstTry, boolean evalArgs) { String klass; SEXP arg_slot; Symbol arg_sym; SEXP method, value = Null.INSTANCE; int nprotect = 0; /* check for dispatch turned off inside MethodsListSelect */ if (mlist instanceof Function) { return mlist; } arg_slot = Methods.R_do_slot(context, mlist, s_argument); if (arg_slot == Null.INSTANCE) { throw new EvalException( "object of class \"%s\" used as methods list for function '%s' " + "( no 'argument' slot)", mlist.toString(), fname); } if (arg_slot instanceof Symbol) { arg_sym = (Symbol) arg_slot; } else { /* shouldn't happen, since argument in class MethodsList has class "name" */ arg_sym = Symbol.get(arg_slot.asString()); } // if(arg_sym == Symbols.ELLIPSES || DDVAL(arg_sym) > 0) // error(_("(in selecting a method for function '%s') '...' and related variables cannot be // used for methods dispatch"), // CHAR(asChar(fname))); // if(TYPEOF(ev) != ENVSXP) { // error(_("(in selecting a method for function '%s') the 'environment' argument for dispatch // must be an R environment; got an object of class \"%s\""), // CHAR(asChar(fname)), class_string(ev)); // return(R_NilValue); /* -Wall */ // } /* find the symbol in the frame, but don't use eval, yet, because missing arguments are ok & don't require defaults */ if (evalArgs) { if (is_missing_arg(context, arg_sym, (Environment) ev)) { klass = "missing"; } else { /* get its class */ SEXP arg, class_obj; try { arg = context.evaluate(arg_sym, (Environment) ev); } catch (EvalException e) { throw new EvalException( String.format( "error in evaluating the argument '%s' in selecting a method for function '%s'", arg_sym.getPrintName(), fname), e); } class_obj = Methods.R_data_class(arg, true); klass = class_obj.asString(); } } else { /* the arg contains the class as a string */ SEXP arg; int check_err; try { arg = context.evaluate(arg_sym, (Environment) ev); } catch (Exception e) { throw new EvalException( String.format( "error in evaluating the argument '%s' in selecting a method for function '%s'", arg_sym.getPrintName(), fname)); } klass = arg.asString(); } method = R_find_method(mlist, klass, fname); if (method == Null.INSTANCE) { if (!firstTry) { throw new EvalException( "no matching method for function '%s' (argument '%s', with class \"%s\")", fname, arg_sym.getPrintName(), klass); } } if (value == Symbol.MISSING_ARG) { /* the check put in before calling function MethodListSelect in R */ throw new EvalException( "recursive use of function '%s' in method selection, with no default method", fname); } if (!(method instanceof Function)) { /* assumes method is a methods list itself. */ /* call do_dispatch recursively. Note the NULL for fname; this is passed on to the S language search function for inherited methods, to indicate a recursive call, not one to be stored in the methods metadata */ method = do_dispatch(context, null, ev, method, firstTry, evalArgs); } return method; }
/* 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; }
public static SEXP R_execMethod(Context context, Closure op, Environment rho) { /* create a new environment frame enclosed by the lexical environment of the method */ Environment newrho = Environment.createChildEnvironment(op.getEnclosingEnvironment()); /* copy the bindings for the formal environment from the top frame of the internal environment of the generic call to the new frame. need to make sure missingness information is preserved and the environments for any default expression promises are set to the new environment. should move this to envir.c where it can be done more efficiently. */ for (PairList.Node next : op.getFormals().nodes()) { // R_varloc_t loc; // int missing; // TODO(alex): redo missingness handling // loc = R_findVarLocInFrame(rho,symbol); // if(loc == NULL) // throw new EvalException("could not find symbol \"%s\" in environment of the generic // function"), // CHAR(PRINTNAME(symbol))); // missing = R_GetVarLocMISSING(loc); // val = R_GetVarLocValue(loc); if (!next.hasTag()) { throw new EvalException("closure formal has no tag! op = " + op); } Symbol symbol = next.getTag(); SEXP val = rho.findVariable(symbol); if (val == Symbol.UNBOUND_VALUE) { throw new EvalException( "could not find symbol \"%s\" in the environment of the generic function", symbol.getPrintName()); } // SET_FRAME(newrho, CONS(val, FRAME(newrho))); // SET_TAG(FRAME(newrho), symbol); newrho.setVariable(symbol, val); // if (missing) { // SET_MISSING(FRAME(newrho), missing); // if (TYPEOF(val) == PROMSXP && PRENV(val) == rho) { // SEXP deflt; // SET_PRENV(val, newrho); // /* find the symbol in the method, copy its expression // * to the promise */ // for(deflt = CAR(op); deflt != R_NilValue; deflt = CDR(deflt)) { // if(TAG(deflt) == symbol) // break; // } // if(deflt == R_NilValue) // error(_("symbol \"%s\" not in environment of method"), // CHAR(PRINTNAME(symbol))); // SET_PRCODE(val, CAR(deflt)); // } // } } /* copy the bindings of the spacial dispatch variables in the top frame of the generic call to the new frame */ newrho.setVariable(DOT_DEFINED, rho.getVariable(DOT_DEFINED)); newrho.setVariable(DOT_METHOD, rho.getVariable(DOT_METHOD)); newrho.setVariable(DOT_TARGET, rho.getVariable(DOT_TARGET)); /* copy the bindings for .Generic and .Methods. We know (I think) that they are in the second frame, so we could use that. */ newrho.setVariable(Symbols.GENERIC, newrho.getVariable(".Generic")); newrho.setVariable(DOT_METHODS, newrho.getVariable(DOT_METHODS)); /* Find the calling context. Should be R_GlobalContext unless profiling has inserted a CTXT_BUILTIN frame. */ Context cptr = context; // cptr = R_GlobalContext; // if (cptr->callflag & CTXT_BUILTIN) // cptr = cptr->nextcontext; /* The calling environment should either be the environment of the generic, rho, or the environment of the caller of the generic, the current sysparent. */ Environment callerenv = cptr.getCallingEnvironment(); /* or rho? */ /* get the rest of the stuff we need from the current context, execute the method, and return the result */ FunctionCall call = cptr.getCall(); PairList arglist = cptr.getArguments(); SEXP val = R_execClosure(context, call, op, arglist, callerenv, newrho); return val; }
/** * Returns an absolute filename representing the current working directory of the R process; * setwd(dir) is used to set the working directory to dir. * * <p>Renjin maintains its own internal pointer to the working directory which lives in {@link * org.renjin.eval.Session} * * @param context the current call Context * @return an absolute filename representing the current working directory */ @Internal public static String getwd(@Current Context context) { return context.getSession().getWorkingDirectory().getName().getURI(); }
private SEXP do_inherited_table( Context context, SEXP class_objs, SEXP fdef, SEXP mtable, Environment ev) { SEXP fun = methodsNamespace.findFunction(context, Symbol.get(".InheritForDispatch")); return context.evaluate(FunctionCall.newCall(fun, class_objs, fdef, mtable), ev); }
public SEXP R_dispatchGeneric(Context context, Symbol fname, Environment ev, SEXP fdef) { SEXP method; SEXP f; SEXP val = Null.INSTANCE; // char *buf, *bufptr; int lwidth = 0; boolean prim_case = false; Environment f_env; if (fdef instanceof Closure) { f_env = ((Closure) fdef).getEnclosingEnvironment(); } else if (fdef instanceof PrimitiveFunction) { fdef = R_primitive_generic(fdef); if (!(fdef instanceof Closure)) { throw new EvalException( "Failed to get the generic for the primitive \"%s\"", fname.asString()); } f_env = ((Closure) fdef).getEnclosingEnvironment(); prim_case = true; } else { throw new EvalException( "Expected a generic function or a primitive for dispatch, " + "got an object of class \"%s\"", fdef.getImplicitClass()); } SEXP mtable = f_env.getVariable(R_allmtable); if (mtable == Symbol.UNBOUND_VALUE) { do_mtable(fdef, ev); /* Should initialize the generic */ mtable = f_env.getVariable(R_allmtable); } SEXP sigargs = f_env.getVariable(R_sigargs); SEXP siglength = f_env.getVariable(R_siglength); if (sigargs == Symbol.UNBOUND_VALUE || siglength == Symbol.UNBOUND_VALUE || mtable == Symbol.UNBOUND_VALUE) { throw new EvalException( "Generic \"%s\" seems not to have been initialized for table dispatch---need to have .SigArgs and .AllMtable assigned in its environment", fname.asString()); } int nargs = (int) siglength.asReal(); ListVector.Builder classListBuilder = ListVector.newBuilder(); StringVector thisClass; StringBuilder buf = new StringBuilder(); for (int i = 0; i < nargs; i++) { Symbol arg_sym = sigargs.getElementAsSEXP(i); if (is_missing_arg(context, arg_sym, ev)) { thisClass = s_missing; } else { /* get its class */ SEXP arg; try { arg = context.evaluate(arg_sym, ev); } catch (EvalException e) { throw new EvalException( String.format( "error in evaluating the argument '%s' in selecting a " + "method for function '%s'", arg_sym.getPrintName(), fname.asString()), e); } thisClass = Methods.R_data_class(arg, true); } classListBuilder.set(i, thisClass); if (i > 0) { buf.append("#"); } buf.append(thisClass.asString()); } ListVector classes = classListBuilder.build(); method = ((Environment) mtable).getVariable(buf.toString()); if (method == Symbol.UNBOUND_VALUE) { method = do_inherited_table(context, classes, fdef, mtable, (Environment) ev); } /* the rest of this is identical to R_standardGeneric; hence the f=method to remind us */ f = method; if (f.isObject()) f = R_loadMethod(context, f, fname.getPrintName(), ev); if (f instanceof Closure) { val = 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; }
/** * Returns true if the file exists. * * @param context the current call Context * @param path the path * @return true if the file exists * @throws FileSystemException */ @Internal("file.exists") @DataParallel public static boolean fileExists(@Current Context context, String path) throws FileSystemException { return context.resolveFile(path).exists(); }