diff --git a/src/cpp/r/RSexp.cpp b/src/cpp/r/RSexp.cpp index 20592724785..77ca7662f51 100644 --- a/src/cpp/r/RSexp.cpp +++ b/src/cpp/r/RSexp.cpp @@ -206,10 +206,6 @@ SEXP getAttrib(SEXP object, SEXP attrib) return Rf_getAttrib(object, attrib); } -SEXP getSrcAttrib(SEXP object) -{ - return R_NilValue; -} Error extract(SEXP valueSEXP, int* pInt) { diff --git a/src/cpp/r/include/r/RSexp.hpp b/src/cpp/r/include/r/RSexp.hpp index fa910c8c98c..92d334ac27d 100644 --- a/src/cpp/r/include/r/RSexp.hpp +++ b/src/cpp/r/include/r/RSexp.hpp @@ -79,7 +79,6 @@ double asReal(SEXP object); bool asLogical(SEXP object); SEXP getAttrib(SEXP object, SEXP attrib); -SEXP getSrcAttrib(SEXP object); // extract c++ type from R SEXP core::Error extract(SEXP valueSEXP, int* pInt); diff --git a/src/cpp/session/modules/SessionCodeSearch.cpp b/src/cpp/session/modules/SessionCodeSearch.cpp index f9c0904c356..d1f89c6dece 100644 --- a/src/cpp/session/modules/SessionCodeSearch.cpp +++ b/src/cpp/session/modules/SessionCodeSearch.cpp @@ -737,6 +737,27 @@ bool findFunction(const std::string& token, } +void getFunctionSource(SEXP functionSEXP, + std::vector* pLines, + bool* pFromSrcAttrib) +{ + // check if the function has a "srcref" attribute + *pFromSrcAttrib = false; + r::exec::RFunction getSrcRefFunc(".rs.functionHasSrcRef", functionSEXP); + Error error = getSrcRefFunc.call(pFromSrcAttrib); + if (error) + LOG_ERROR(error); + + // deparse + r::exec::RFunction deparseFunc(".rs.deparseFunction"); + deparseFunc.addParam(functionSEXP); + deparseFunc.addParam(*pFromSrcAttrib); + error = deparseFunc.call(pLines); + if (error) + LOG_ERROR(error); +} + + json::Object createFunctionDefinition(const std::string& name, const std::string& namespaceName) { @@ -746,7 +767,7 @@ json::Object createFunctionDefinition(const std::string& name, funDef["namespace"] = namespaceName; // function source code - bool hasSrcAttrib = false; + bool fromSrcAttrib = false; std::vector lines; // get the function @@ -759,16 +780,8 @@ json::Object createFunctionDefinition(const std::string& name, // did we get a function if (!r::sexp::isNull(functionSEXP)) { - // does it have a src attrib? - hasSrcAttrib = !r::sexp::isNull(r::sexp::getSrcAttrib(functionSEXP)); - - // get the code - r::exec::RFunction deparseFunc(".rs.deparseFunction", - functionSEXP, - hasSrcAttrib); - Error error = deparseFunc.call(&lines); - if (error) - LOG_ERROR(error); + // get the function source + getFunctionSource(functionSEXP, &lines, &fromSrcAttrib); } } else @@ -790,7 +803,7 @@ json::Object createFunctionDefinition(const std::string& name, code.append("\n"); } funDef["code"] = code; - funDef["from_src_attrib"] = hasSrcAttrib; + funDef["from_src_attrib"] = fromSrcAttrib; } else { diff --git a/src/cpp/session/modules/SessionCodeTools.R b/src/cpp/session/modules/SessionCodeTools.R index 78ae796b878..0f5ed504a3e 100644 --- a/src/cpp/session/modules/SessionCodeTools.R +++ b/src/cpp/session/modules/SessionCodeTools.R @@ -92,6 +92,11 @@ eval(parse(text=paste(packageName, ":::", name, sep=""))) }) +.rs.addFunction("functionHasSrcRef", function(func) +{ + return (!is.null(attr(func, "srcref"))) +}) + .rs.addFunction("deparseFunction", function(func, useSource) { control <- c("keepInteger", "keepNA")