Skip to content
Snippets Groups Projects
Commit 4f474c00 authored by Tomas Stupka's avatar Tomas Stupka
Browse files

S4 representation for jclassName, float, byte, short, character, long

parent 0e7ccbb3
Branches
No related tags found
No related merge requests found
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
.jnew <- function (class, ..., check = TRUE, silent = !check) { .jnew <- function (class, ..., check = TRUE, silent = !check) {
class <- gsub("/", ".", as.character(class)) class <- gsub("/", ".", as.character(class))
co <- new.java.class(class) co <- new.java.class(class)
args <- .fromS4(co, ...) args <- .ellipsisToJObj(co, ...)
o <- .fastr.interop.try(function() { do.call(new.external, args) }, check) o <- .fastr.interop.try(function() { do.call(new.external, args) }, check)
new("jobjRef", jobj=o, jclass=class) new("jobjRef", jobj=o, jclass=class)
} }
...@@ -23,16 +23,14 @@ ...@@ -23,16 +23,14 @@
.jcall <- function (obj, returnSig = "V", method, ..., evalArray = TRUE, .jcall <- function (obj, returnSig = "V", method, ..., evalArray = TRUE,
evalString = TRUE, check = TRUE, interface = "RcallMethod", evalString = TRUE, check = TRUE, interface = "RcallMethod",
simplify = FALSE, use.true.class = FALSE) { simplify = FALSE, use.true.class = FALSE) {
if (isS4(obj)) { obj <- .toJObj(obj)
obj <- obj@jobj
}
args <- .fromS4(...)
if (is.character(obj)) { if (is.character(obj)) {
obj <- gsub("/", ".", as.character(obj)) obj <- gsub("/", ".", as.character(obj))
obj <- new.java.class(obj) obj <- new.java.class(obj)
} }
args <- .ellipsisToJObj(...)
extMethod <- function(...) {obj[method](...)} extMethod <- function(...) {obj[method](...)}
r <- .fastr.interop.try(function() { do.call(extMethod, args) }, check) r <- .fastr.interop.try(function() { do.call(extMethod, args) }, check)
...@@ -69,43 +67,51 @@ ...@@ -69,43 +67,51 @@
#' @export #' @export
.jbyte <- function (x) { .jbyte <- function (x) {
x <- as.external.byte(x) storage.mode( x ) <- "integer"
invisible(x) new("jbyte", x)
} }
#' @export #' @export
.jchar <- function (x) { .jchar <- function (x) {
x <- as.external.char(x) storage.mode( x ) <- "character"
invisible(x) new("jchar", x)
} }
#' @export #' @export
.jshort <- function (x) { .jshort <- function (x) {
x <- as.external.short(x) storage.mode( x ) <- "integer"
invisible(x) new("jshort", x)
} }
#' @export #' @export
.jlong <- function (x) { .jlong <- function (x) {
x <- as.external.long(x) storage.mode( x ) <- "double"
invisible(x) new("jlong", x)
} }
#' @export #' @export
.jfloat <- function (x) { .jfloat <- function (x) {
x <- as.external.float(x) storage.mode( x ) <- "double"
invisible(x) new("jfloat", x )
} }
#' @export #' @export
J <- function (class, method, ...) { J <- function (class, method, ...) {
class <- gsub("/", ".", as.character(class))
javaClass <- new.java.class(class)
if (nargs() == 1L && missing(method)) { if (nargs() == 1L && missing(method)) {
javaClass if(inherits(class, "jclassName")) {
return(class)
} else if(is.character(class)) {
className <- class
jobj <- .jfindClass(class)
} else {
className <- as.character(class)
jobj <- .jfindClass(className)
}
new("jclassName", name=className, jobj=jobj)
} else { } else {
.jcall(javaClass, ,method, ...) # .jrcall(class, method, ...)
} .jcall(class, , method, ...)
}
} }
#' @export #' @export
...@@ -153,7 +159,17 @@ J <- function (class, method, ...) { ...@@ -153,7 +159,17 @@ J <- function (class, method, ...) {
#' @export #' @export
.jfindClass <- function (cl, silent = FALSE) { .jfindClass <- function (cl, silent = FALSE) {
new.java.class(cl) if (inherits(cl, "jclassName")) return(cl@jobj)
if (!is.character(cl) || length(cl)!=1) {
stop("invalid class name")
}
cl <- gsub("/", ".", as.character(cl))
javaClass <- new.java.class(cl)
cls <- new('jobjRef', jobj=javaClass, jclass='java.lang.Class', stringValue=paste0("class ", cl))
.jcheck(silent)
if (!silent && is.jnull(cls)) stop("class not found")
cls
} }
.toS4 <- function(obj) { .toS4 <- function(obj) {
...@@ -168,21 +184,28 @@ J <- function (class, method, ...) { ...@@ -168,21 +184,28 @@ J <- function (class, method, ...) {
res res
} }
.fromS4 <- function(...) { .ellipsisToJObj <- function(...) {
l <- list(...) lapply(list(...), function(x) .toJObj(x))
if (length(l)) { }
for (i in 1:length(l)) {
if (isS4(l[[i]])) { .toJObj <- function(x) {
o <- l[[i]]@jobj if (is(x, "jobjRef")) {
if (is.null(o)) { x@jobj
l[i] <- list(NULL) } else if (is(x, "jclassName")) {
} else { x@jobj@jobj
l[[i]] <- o } else if (is(x, "jbyte")) {
} as.external.byte(x)
} } else if (is(x, "jchar")) {
} as.external.char(x)
} } else if (is(x, "jfloat")) {
l as.external.float(x)
} else if (is(x, "jlong")) {
as.external.long(x)
} else if (is(x, "jshort")) {
as.external.short(x)
} else {
x
}
} }
#' @export #' @export
...@@ -204,7 +227,7 @@ J <- function (class, method, ...) { ...@@ -204,7 +227,7 @@ J <- function (class, method, ...) {
} }
#' @export #' @export
.jnull <- function (class = "java/lang/Object") { .jnull <- function (class = "java/lang/Object") {
new("jobjRef", jobj=NULL, jclass=class) new("jobjRef", jobj=NULL, jclass=class)
} }
...@@ -245,15 +268,22 @@ is.jnull <- function (x) { ...@@ -245,15 +268,22 @@ is.jnull <- function (x) {
#' @export #' @export
.jstrVal <- function (obj) { .jstrVal <- function (obj) {
if (is.character(obj)) if (is.character(obj)) {
return(obj) return(obj)
}
r <- NULL r <- NULL
if (!is(obj, "jobjRef")) if (!is(obj, "jobjRef")) {
stop("can get value of Java objects only") stop("can get value of Java objects only")
if (!is.null(obj@jclass) && obj@jclass == "lang/java/String") }
r <- .External(RgetStringValue, obj@jobj) if(!is.null(obj@stringValue)) {
else r <- obj@jobj["toString"]() obj@stringValue
r } else {
obj@jobj["toString"]()
}
}
.isJavaArray <- function(o){
is.external.array(o) && java.class(o) != NULL
} }
# #
...@@ -262,43 +292,86 @@ is.jnull <- function (x) { ...@@ -262,43 +292,86 @@ is.jnull <- function (x) {
setClass("truffle.object", representation(jobj="ANY")) setClass("truffle.object", representation(jobj="ANY"))
setClassUnion("TruffleObjectOrNull",members=c("truffle.object", "NULL")) setClassUnion("TruffleObjectOrNull",members=c("truffle.object", "NULL"))
setClassUnion("characterOrNull",members=c("character", "NULL"))
#
# jobjRef # jobjRef
setClass("jobjRef", representation(jobj="TruffleObjectOrNull", jclass="character"), prototype=list(jobj=NULL, jclass="java/lang/Object")) #
setClass("jobjRef", representation(jobj="TruffleObjectOrNull", jclass="character", stringValue="characterOrNull"), prototype=list(jobj=NULL, jclass="java/lang/Object", stringValue=NULL))
._jobjRef_dollar <- function(x, name) { setMethod("$", c(x="jobjRef"), function(x, name) {
if(name %in% names(x@jobj)) { if(name %in% names(x@jobj)) {
if(is.external.executable(x@jobj[name])) { if(is.external.executable(x@jobj[name])) {
function(...) { .jcall(x, , name, ...) } function(...) { .jcall(x, , name, ...) }
} else { } else {
.jfield(x, , name) .jfield(x, , name)
} }
} else if( is.character(name) && length(name) == 1L && name == "length" && is.external.array(x) ){ } else if( is.character(name) && length(name) == 1L && name == "length" && is.external.array(x) ) {
length( x@obj ) length( x@obj )
} else { } else {
stop(sprintf( "no field, method or inner class called '%s' ", name)) stop(sprintf( "no field, method or inner class called '%s' ", name))
} }
} })
setMethod("$", c(x="jobjRef"), ._jobjRef_dollar )
._jobjRef_dollargets <- function(x, name, value) { setMethod("$<-", c(x="jobjRef"), function(x, name, value) {
if(name %in% names(x@jobj)) { if(name %in% names(x@jobj)) {
if(!is.external.executable(x@jobj[name])) { if(!is.external.executable(x@jobj[name])) {
if(isS4(value)) { value <- .toJObj(value)
value <- value@jobj
}
x@jobj[name] <- value x@jobj[name] <- value
} }
} }
x x
} })
setMethod("$<-", c(x="jobjRef"), ._jobjRef_dollargets )
setMethod("show", c(object="jobjRef"), function(object) { setMethod("show", c(object="jobjRef"), function(object) {
if (is.jnull(object)) show("Java-Object<null>") else show(paste("Java-Object{", .jstrVal(object), "}", sep='')) if (is.jnull(object)) {
invisible(NULL) show("Java-Object<null>")
} else {
show(paste("Java-Object{", .jstrVal(object), "}", sep=''))
}
invisible(NULL)
}) })
#
# jclassName
#
setClass("jclassName", representation(name="character", jobj="jobjRef"))
setMethod("show", c(object="jclassName"), function(object) {
invisible(show(paste("Java-Class-Name:", object@name)))
})
setMethod("as.character", c(x="jclassName"), function(x, ...) x@name)
setMethod("$", c(x="jclassName"), function(x, name) {
if(name == "class") {
x@jobj
}
obj <- x@jobj@jobj
if(name %in% names(obj)) {
if(is.external.executable(obj[name])) {
function(...) { .jcall(obj, , name, ...) }
} else {
.jfield(obj, , name)
}
} else {
stop("no static field, method or inner class called `", name, "' in `", x@name, "'")
}
})
setMethod("$<-", c(x="jclassName"), function(x, name, value) {
value <- .toJObj(value)
x@jobj@jobj[name] <- value
x
})
# TODO makes CMD INSTALL complain
# setGeneric("new")
# setMethod("new", signature(Class="jclassName"), function(Class, ...) .jnew(Class, ...))
setClass("jfloat", representation("array"))
setClass("jlong", representation("array"))
setClass("jbyte", representation("array"))
setClass("jshort", representation("array"))
setClass("jchar", representation("array"))
# #
# noop stubs # noop stubs
# #
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment