src/debugger/SourceFileManager.h (48 lines of code) (raw):
// Rkernel is an execution kernel for R interpreter
// Copyright (C) 2019 JetBrains s.r.o.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program 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 for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
#ifndef RWRAPPER_SOURCE_FILE_MANAGER_H
#define RWRAPPER_SOURCE_FILE_MANAGER_H
#include "../RStuff/MySEXP.h"
#include "RDebugger.h"
#include <functional>
#include <memory>
#include <string>
#include <unordered_map>
class SourceFileManager {
public:
// Return EXTPTR that can be assigned to VirtualFileInfoPtr
SEXP registerSrcfile(SEXP srcfile, std::string virtualFileId = "", int lineOffset = 0, int firstLineOffset = 0);
SEXP getVirtualFileById(std::string const& virtualFileId);
SEXP getFunctionSrcref(SEXP func, std::function<std::string()> const& suggestName = std::function<std::string()>());
SEXP getFunctionSrcref(SEXP func, std::string const& suggestedName);
SEXP saveState();
void loadState(SEXP obj);
static void preprocessSrcrefs(SEXP x);
private:
std::unordered_map<std::string, SEXP> virtualFiles;
int currentGeneratedFileId = 0;
std::string generateFileId();
static void createVirtualFileInfo(std::string const& id, SEXP ptr);
};
struct VirtualFileInfo {
const std::string id;
bool isGenerated = false;
std::string generatedName;
std::vector<std::vector<Breakpoint*>> breakpointsByLine;
/*
* Content of the file. Designed for getting text of generated files,
* does not work well with normal files because they can be executed by parts.
*/
PrSEXP lines;
SEXP extPtr;
VirtualFileInfo(std::string const& id) : id(id) {}
};
/*
* Lifetime of VirtualFileInfo is managed by R garbage collector.
* This structure is referenced by EXTPTR and is destroyed in its finalizer,
* so it's required to protect EXTPTR while you work with VirtualFileInfo.
* This class does it automatically.
*/
class VirtualFileInfoPtr {
public:
VirtualFileInfoPtr(SEXP ptr) : ptr(ptr) { assert(TYPEOF(ptr) == EXTPTRSXP || ptr == R_NilValue); }
VirtualFileInfoPtr(BaseSEXP const& ptr) : ptr((SEXP)ptr) { assert(TYPEOF(ptr) == EXTPTRSXP || ptr == R_NilValue); }
VirtualFileInfoPtr& operator = (VirtualFileInfoPtr rhs) = delete;
SEXP getExtPtr() { return ptr; }
VirtualFileInfo& operator *() { return *(VirtualFileInfo*)R_ExternalPtrAddr(ptr); }
VirtualFileInfo* operator ->() { return &**this; }
bool isNull() { return TYPEOF(ptr) != EXTPTRSXP || R_ExternalPtrAddr(ptr) == nullptr; }
bool operator == (VirtualFileInfoPtr const& rhs) const { return ptr == rhs.ptr; }
bool operator != (VirtualFileInfoPtr const& rhs) const { return ptr != rhs.ptr; }
private:
ShieldSEXP ptr;
};
extern SourceFileManager sourceFileManager;
#endif //RWRAPPER_SOURCE_FILE_MANAGER_H