From 4ec966035d2dfbede7a330cbdbf321d4be72cb92 Mon Sep 17 00:00:00 2001 From: stepan <stepan.sindelar@oracle.com> Date: Thu, 5 Apr 2018 17:59:15 +0200 Subject: [PATCH] Make SVG related functions public and add their documentation --- .../fastrGrid/FastRGridExternalLookup.java | 3 + .../r/library/fastrGrid/device/SVGDevice.java | 18 ++++-- .../fastrGrid/grDevices/R/fastrGridDevices.R | 29 ++++++++-- .../r/library/fastrGrid/grDevices/Rd/awt.Rd | 26 +++++++++ .../library/fastrGrid/grDevices/Rd/svg.off.Rd | 28 +++++++++ .../fastrGrid/grDevices/Rd/svg.string.Rd | 24 ++++++++ .../fastrGrid/grDevices/SvgString.java | 48 +++++++++++++++ .../r/nodes/builtin/base/BasePackage.java | 2 + .../r/nodes/builtin/base/R/base_overrides.R | 1 + .../foreign/CallAndExternalFunctions.java | 6 +- .../r/nodes/builtin/fastr/FastRHelp.java | 58 ++++++++++++++++--- .../r/nodes/builtin/utils/R/utils_overrides.R | 4 +- .../r/test/library/fastr/TestInterop.java | 16 ----- .../r/test/library/utils/TestHelp.java | 54 +++++++++++++++++ 14 files changed, 279 insertions(+), 38 deletions(-) create mode 100644 com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/grDevices/Rd/awt.Rd create mode 100644 com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/grDevices/Rd/svg.off.Rd create mode 100644 com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/grDevices/Rd/svg.string.Rd create mode 100644 com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/grDevices/SvgString.java create mode 100644 com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/utils/TestHelp.java diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/FastRGridExternalLookup.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/FastRGridExternalLookup.java index 6d6a78006a..754b02266a 100644 --- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/FastRGridExternalLookup.java +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/FastRGridExternalLookup.java @@ -37,6 +37,7 @@ import com.oracle.truffle.r.library.fastrGrid.grDevices.DevSize; import com.oracle.truffle.r.library.fastrGrid.grDevices.InitWindowedDevice; import com.oracle.truffle.r.library.fastrGrid.grDevices.PDF; import com.oracle.truffle.r.library.fastrGrid.grDevices.SavePlot; +import com.oracle.truffle.r.library.fastrGrid.grDevices.SvgString; import com.oracle.truffle.r.library.fastrGrid.graphics.CPar; import com.oracle.truffle.r.nodes.builtin.RExternalBuiltinNode; import com.oracle.truffle.r.nodes.builtin.RInternalCodeBuiltinNode; @@ -64,6 +65,8 @@ public final class FastRGridExternalLookup { return new DevCurr(); case "devoff": return DevOff.create(); + case "svgstring": + return new SvgString(); case "PDF": return new PDF(); case "devCairo": diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/device/SVGDevice.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/device/SVGDevice.java index 413d1c638d..4867d5a0b0 100644 --- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/device/SVGDevice.java +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/device/SVGDevice.java @@ -59,10 +59,16 @@ public class SVGDevice implements GridDevice, FileGridDevice { } public String closeAndGetContents() { - closeSVGDocument(); + closeSVGDocument(data); return data.toString(); } + public String getContents() { + StringBuilder result = new StringBuilder(data); + closeSVGDocument(result); + return result.toString(); + } + @Override public void openNewPage() { // We stay compatible with GnuR: opening new page wipes out what has been drawn without @@ -207,7 +213,7 @@ public class SVGDevice implements GridDevice, FileGridDevice { } private void saveFile() throws DeviceCloseException { - closeSVGDocument(); + closeSVGDocument(data); try { Files.write(Paths.get(filename), Collections.singleton(data.toString()), StandardCharsets.UTF_8); } catch (IOException e) { @@ -215,15 +221,15 @@ public class SVGDevice implements GridDevice, FileGridDevice { } } - private void closeSVGDocument() { - if (data.length() == 0) { + private void closeSVGDocument(StringBuilder sb) { + if (sb.length() == 0) { return; } if (cachedCtx != null) { // see #appendStyle - data.append("</g>"); + sb.append("</g>"); } - data.append("</svg>"); + sb.append("</svg>"); } // closes opened <g> tag if necessary diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/grDevices/R/fastrGridDevices.R b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/grDevices/R/fastrGridDevices.R index f32979e54a..ef9033a667 100644 --- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/grDevices/R/fastrGridDevices.R +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/grDevices/R/fastrGridDevices.R @@ -20,21 +20,40 @@ # questions. eval(expression({ + + assignInNs <- function(x, val) { + ns <- asNamespace("grDevices") + unlockBinding(x, ns) + assign(x, val, envir = ns, inherits = T) + lockBinding(x, ns) + } + # This should be preffered way of starting the FastR java device. # For compatibility reasons, both X11 and awt end up calling C_X11. # In the future, this function may support extra parameters like a # reference to java 2D graphics object, which will be used for the drawing. - awt <- function(width = NULL, height = NULL, graphicsObj = NULL) { - .External2(grDevices:::C_X11, ".FASTR.AWT", width, height, graphicsObj) - } + assignInNs('awt', function(width = NULL, height = NULL, graphicsObj = NULL) { + invisible(.External2(grDevices:::C_X11, ".FASTR.AWT", width, height, graphicsObj)) + }) + # Allows to get the SVG code from SVG device, it also closes the device, # but the contents are not saved to the given file. - svg.off <- function(which = dev.cur()) { + assignInNs('svg.off', function(which = dev.cur()) { if (which == 1) { stop("cannot shut down device 1 (the null device)") } .External(C_devoff, as.integer(-which)) - } + }) + + # Allows to get the SVG code from SVG device without closing it + svgStringSymbol <- list(name='svgstring') + assignInNs('svg.string', function() { + .External(svgStringSymbol) + }) + + # Adds help files for the new public functions + .fastr.addHelpPath('/com/oracle/truffle/r/library/fastrGrid/grDevices/Rd') + # GnuR version only works with "X11cairo" device. Our version of savePlot # works with "awt" device and "X11cairo", which is for us only alias for # "awt". Moreover, we only support formats that awt supports. diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/grDevices/Rd/awt.Rd b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/grDevices/Rd/awt.Rd new file mode 100644 index 0000000000..3b1d1f58bd --- /dev/null +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/grDevices/Rd/awt.Rd @@ -0,0 +1,26 @@ +\name{awt} +\alias{awt} +\title{Opens the AWT device, which is an interactive window.} +\usage{ +awt(width = NULL, height = NULL, graphicsObj = NULL) +} +\arguments{ +\item{width}{window width in AWT units (~pixel).} +\item{height}{window height in AWT units (~pixel).} +\item{java.awt.graphicsObj}{Java object of type \code{java.awt.Graphics2D}.} +} +\value{ +Invisible NULL. +} +\description{ +The AWT device draws into given Java \code{java.awt.Graphics2D} object. +If \code{NULL} is given as \code{graphicsObj}, then the function creates a +window whose \code{Graphics2D} is used, i.e. plots will be drawn into the window. +In FastR \code{X11} is aliased to \code{awt}. +} +\examples{ +awt() +} +\seealso{ +\code{X11} +} diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/grDevices/Rd/svg.off.Rd b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/grDevices/Rd/svg.off.Rd new file mode 100644 index 0000000000..8083d822d1 --- /dev/null +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/grDevices/Rd/svg.off.Rd @@ -0,0 +1,28 @@ +\name{svg.off} +\alias{svg.off} +\title{Closes the SVG device and returns the SVG code as a character vector.} +\usage{ +svg.off(which = dev.cur()) +} +\arguments{ +\item{which}{device number.} +} +\value{ +Character vector with a single element. +} +\description{ +The semantics is the same as for \code{dev.off} function from the graphics package, +except that \code{svg.off} does not write into any file and returns the SVG code as +a character vector. \code{svg.off} can be invoked only when SVG device has been opened +with \code{svg}. +} +\examples{ +library(grid) +svg() +grid.rect() +print(svg.off()) +} +\seealso{ +\code{dev.off} +} + diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/grDevices/Rd/svg.string.Rd b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/grDevices/Rd/svg.string.Rd new file mode 100644 index 0000000000..3a511fa64e --- /dev/null +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/grDevices/Rd/svg.string.Rd @@ -0,0 +1,24 @@ +\name{svg.string} +\alias{svg.string} +\title{Returns SVG code of the current plot.} +\usage{ +svg.string() +} +\value{ +Character vector with a single element. +} +\description{ +Returns SVG code of the current plot. +\code{svg.string} can be invoked only when SVG device has been opened using \code{svg}. +Unlike \code{svg.off} this function does not close the SVG device. +} +\examples{ +library(grid) +svg() +grid.rect() +print(svg.string()) +} +\seealso{ +\code{svg.off} +} + diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/grDevices/SvgString.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/grDevices/SvgString.java new file mode 100644 index 0000000000..ba9f84f251 --- /dev/null +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/grDevices/SvgString.java @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.truffle.r.library.fastrGrid.grDevices; + +import com.oracle.truffle.r.library.fastrGrid.GridContext; +import com.oracle.truffle.r.library.fastrGrid.device.GridDevice; +import com.oracle.truffle.r.library.fastrGrid.device.SVGDevice; +import com.oracle.truffle.r.nodes.builtin.RExternalBuiltinNode; +import com.oracle.truffle.r.runtime.RError.Message; + +/** + * FastR specific external used to implement {@code svg.string}, which returns the SVG code of + * current drawing. + */ +public class SvgString extends RExternalBuiltinNode.Arg0 { + @Override + public Object execute() { + GridContext ctx = GridContext.getContext(); + if (ctx.getCurrentDeviceIndex() <= 0) { + throw error(Message.GENERIC, "No device opened."); + } + GridDevice dev = ctx.getCurrentDevice(); + if (!(dev instanceof SVGDevice)) { + throw error(Message.GENERIC, "No SVG device opened, use svg() to open one."); + } + return ((SVGDevice) dev).getContents(); + } +} diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/BasePackage.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/BasePackage.java index 406d3eb5d2..c6fcd9a521 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/BasePackage.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/BasePackage.java @@ -99,6 +99,7 @@ import com.oracle.truffle.r.nodes.builtin.fastr.FastRContext; import com.oracle.truffle.r.nodes.builtin.fastr.FastRContextFactory; import com.oracle.truffle.r.nodes.builtin.fastr.FastRDebug; import com.oracle.truffle.r.nodes.builtin.fastr.FastRDebugNodeGen; +import com.oracle.truffle.r.nodes.builtin.fastr.FastRHelp.FastRAddHelpPath; import com.oracle.truffle.r.nodes.builtin.fastr.FastRHelp.FastRHelpPath; import com.oracle.truffle.r.nodes.builtin.fastr.FastRHelp.FastRHelpRd; import com.oracle.truffle.r.nodes.builtin.fastr.FastRHelpFactory.FastRHelpPathNodeGen; @@ -445,6 +446,7 @@ public class BasePackage extends RBuiltinPackage { add(FastrDqrls.class, FastrDqrlsNodeGen::create); add(FastRDebug.class, FastRDebugNodeGen::create); add(FastRSetBreakpoint.class, FastRSetBreakpointNodeGen::create); + add(FastRAddHelpPath.class, FastRAddHelpPath::create); add(FastRHelpPath.class, FastRHelpPathNodeGen::create); add(FastRHelpRd.class, FastRHelpRdNodeGen::create); add(FastRIdentity.class, FastRIdentityNodeGen::create); diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/R/base_overrides.R b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/R/base_overrides.R index 9b10332922..58a96ab5a8 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/R/base_overrides.R +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/R/base_overrides.R @@ -10,6 +10,7 @@ # eval(expression({ +.fastr.addHelpPath('/com/oracle/truffle/r/nodes/builtin/base/Rd') .libPaths <- local({ .lib.loc <- character() # Profiles need to set this. function(new) { diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/CallAndExternalFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/CallAndExternalFunctions.java index e5aa670388..70b8e12f2d 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/CallAndExternalFunctions.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/CallAndExternalFunctions.java @@ -798,8 +798,9 @@ public class CallAndExternalFunctions { } @SuppressWarnings("unused") - @Specialization(limit = "1", guards = {"cached.symbol == symbol"}) + @Specialization(limit = "1", guards = {"cached.symbol == symbol", "builtin == null"}) protected Object callNamedFunction(VirtualFrame frame, RList symbol, RArgsValuesAndNames args, Object packageName, + @Cached("lookupBuiltin(symbol)") RExternalBuiltinNode builtin, @Cached("new(symbol)") CallNamedFunctionNode cached, @Cached("createBinaryProfile()") ConditionProfile registeredProfile) { if (registeredProfile.profile(isRegisteredRFunction(cached.nativeCallInfo))) { @@ -913,8 +914,9 @@ public class CallAndExternalFunctions { } @SuppressWarnings("unused") - @Specialization(limit = "1", guards = {"cached.symbol == symbol"}) + @Specialization(limit = "1", guards = {"cached.symbol == symbol", "builtin == null"}) protected Object callNamedFunction(RList symbol, RArgsValuesAndNames args, Object packageName, + @Cached("lookupBuiltin(symbol)") RExternalBuiltinNode builtin, @Cached("new(symbol)") CallNamedFunctionNode cached) { Object list = encodeArgumentPairList(args, cached.nativeCallInfo.name); return dispatch(cached.nativeCallInfo, new Object[]{CALL, getOp(), list, RHO}); diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/FastRHelp.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/FastRHelp.java index 4f0b1b556e..de2ff48697 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/FastRHelp.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/FastRHelp.java @@ -30,20 +30,62 @@ import com.oracle.truffle.api.dsl.Specialization; import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.singleElement; import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.stringValue; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; +import com.oracle.truffle.r.nodes.builtin.fastr.FastRHelpFactory.FastRAddHelpPathNodeGen; import com.oracle.truffle.r.runtime.RError; import static com.oracle.truffle.r.runtime.RVisibility.ON; import com.oracle.truffle.r.runtime.ResourceHandlerFactory; import com.oracle.truffle.r.runtime.builtins.RBuiltin; import com.oracle.truffle.r.runtime.data.RNull; +import com.oracle.truffle.r.runtime.nodes.RNode; + import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; +import java.util.ArrayList; public class FastRHelp { - @RBuiltin(name = ".fastr.interop.helpPath", visibility = ON, kind = PRIMITIVE, parameterNames = {"builtinName"}, behavior = COMPLEX) + private static ArrayList<String> paths; + + private static synchronized void initPaths() { + if (paths == null) { + paths = new ArrayList<>(3); + } + } + + private static synchronized void addPath(String path) { + initPaths(); + paths.add(path); + } + + private static synchronized String[] getPaths() { + initPaths(); + return paths.toArray(new String[paths.size()]); + } + + @RBuiltin(name = ".fastr.addHelpPath", visibility = ON, kind = PRIMITIVE, parameterNames = {"path"}, behavior = COMPLEX) + public abstract static class FastRAddHelpPath extends RBuiltinNode.Arg1 { + + static { + Casts casts = new Casts(FastRAddHelpPath.class); + casts.arg("path").mustBe(stringValue()).asStringVector().mustBe(singleElement()).findFirst(); + } + + @Specialization() + @TruffleBoundary + public Object helpPath(String path) { + addPath(path); + return RNull.instance; + } + + public static FastRAddHelpPath create() { + return FastRAddHelpPathNodeGen.create(); + } + } + + @RBuiltin(name = ".fastr.helpPath", visibility = ON, kind = PRIMITIVE, parameterNames = {"builtinName"}, behavior = COMPLEX) public abstract static class FastRHelpPath extends RBuiltinNode.Arg1 { static { @@ -54,18 +96,20 @@ public class FastRHelp { @Specialization() @TruffleBoundary public Object helpPath(String builtinName) { - String path = "/com/oracle/truffle/r/nodes/builtin/base/Rd/" + builtinName + ".Rd"; - try (InputStream in = ResourceHandlerFactory.getHandler().getResourceAsStream(getClass(), path)) { - if (in != null) { - return path; + for (String path : getPaths()) { + String filename = path + '/' + builtinName + ".Rd"; + try (InputStream in = ResourceHandlerFactory.getHandler().getResourceAsStream(getClass(), filename)) { + if (in != null) { + return filename; + } + } catch (IOException ex) { } - } catch (IOException ex) { } return RNull.instance; } } - @RBuiltin(name = ".fastr.interop.helpRd", visibility = ON, kind = PRIMITIVE, parameterNames = {"path"}, behavior = COMPLEX) + @RBuiltin(name = ".fastr.helpRd", visibility = ON, kind = PRIMITIVE, parameterNames = {"path"}, behavior = COMPLEX) public abstract static class FastRHelpRd extends RBuiltinNode.Arg1 { static { diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/utils/R/utils_overrides.R b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/utils/R/utils_overrides.R index bc72ccbeb2..db7cf13a49 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/utils/R/utils_overrides.R +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/utils/R/utils_overrides.R @@ -39,7 +39,7 @@ index.search <- function (topic, paths, firstOnly = FALSE) res <- index.search.orig(topic, paths, firstOnly) if(length(res) == 0) { - fastrHelpRd <- .fastr.interop.helpPath(topic) + fastrHelpRd <- .fastr.helpPath(topic) if(!is.null(fastrHelpRd)) { res <- fastrHelpRd } @@ -52,7 +52,7 @@ eval(expression({ .getHelpFile.orig <- utils:::.getHelpFile .getHelpFile <- function (file) { - fastrHelpRd <- .fastr.interop.helpRd(file) + fastrHelpRd <- .fastr.helpRd(file) if(!is.null(fastrHelpRd)) { return(tools::parse_Rd(textConnection(fastrHelpRd))) } diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/fastr/TestInterop.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/fastr/TestInterop.java index 0ab685c7b6..fd8c622bad 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/fastr/TestInterop.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/fastr/TestInterop.java @@ -107,22 +107,6 @@ public class TestInterop extends TestBase { "cat('Error in fo@bitLength :\n cannot get a slot (\"bitLength\") from an object of type \"external object\"\n')"); } - @Test - public void testHelp() { - assertHelpResult(fastREval("?as.external.byte", ContextKind.SHARE_PARENT_RW, false), "==== R Help on ‘as.external.byte’ ====", "converted to a byte", "byteClass$valueOf(javaByte)"); - assertHelpResult(fastREval("help(as.external.byte)", ContextKind.SHARE_PARENT_RW, false), "==== R Help on ‘as.external.byte’ ====", "converted to a byte", "byteClass$valueOf(javaByte)"); - assertHelpResult(fastREval("example(as.external.byte)", ContextKind.SHARE_PARENT_RW, false), null, "byteClass$valueOf(javaByte)", "[1] 123"); - } - - private static void assertHelpResult(String result, String startsWith, String... contains) { - if (startsWith != null) { - assertTrue(result.startsWith(startsWith)); - } - for (String s : contains) { - assertTrue(result.contains(s)); - } - } - /** * Used for testing interop functionality. */ diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/utils/TestHelp.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/utils/TestHelp.java new file mode 100644 index 0000000000..aa0e530f8d --- /dev/null +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/utils/TestHelp.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2018, 2018, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.truffle.r.test.library.utils; + +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +import com.oracle.truffle.r.runtime.context.RContext.ContextKind; +import com.oracle.truffle.r.test.TestBase; + +public class TestHelp extends TestBase { + @Test + public void testInteropHelp() { + assertHelpResult(fastREval("?as.external.byte", ContextKind.SHARE_PARENT_RW, false), "==== R Help on ‘as.external.byte’ ====", "converted to a byte", "byteClass$valueOf(javaByte)"); + assertHelpResult(fastREval("help(as.external.byte)", ContextKind.SHARE_PARENT_RW, false), "==== R Help on ‘as.external.byte’ ====", "converted to a byte", "byteClass$valueOf(javaByte)"); + assertHelpResult(fastREval("example(as.external.byte)", ContextKind.SHARE_PARENT_RW, false), null, "byteClass$valueOf(javaByte)", "[1] 123"); + } + + @Test + public void testGrDevicesHelp() { + assertHelpResult(fastREval("?svg.off", ContextKind.SHARE_PARENT_RW, false), "==== R Help on ‘svg.off’ ====", "SVG"); + assertHelpResult(fastREval("help(svg.off)", ContextKind.SHARE_PARENT_RW, false), "==== R Help on ‘svg.off’ ====", "SVG"); + } + + private static void assertHelpResult(String result, String startsWith, String... contains) { + if (startsWith != null) { + assertTrue(result.startsWith(startsWith)); + } + for (String s : contains) { + assertTrue(result.contains(s)); + } + } +} -- GitLab