Allow passing key.sourcetext to provide in-memory-vfs contents

For testing, passing `-vfs-files=source=@target` with an '@' on the
target file will pass it as source text.
This commit is contained in:
Ben Langmuir
2019-06-26 09:15:19 -07:00
committed by Marc Rasi
parent 8784a7b96d
commit 6e2a7e5a3a
6 changed files with 47 additions and 19 deletions

View File

@@ -0,0 +1,7 @@
func foo(_ structDefinedInSameTarget: StructDefinedInSameTarget) {
let c: Double = structDefinedInSameTarget.methodDefinedInSameTarget()
// CHECK: cannot convert value of type '()' to specified type 'Double'
}
// RUN: %sourcekitd-test -req=open -vfs-files=/target_file1.swift=@%s,/target_file2.swift=@%S/../Inputs/vfs/other_file_in_target.swift /target_file1.swift -pass-as-sourcetext -- /target_file1.swift /target_file2.swift == \
// RUN: -req=print-diags -vfs-files=/target_file1.swift=@%s,/target_file2.swift=@%S/../Inputs/vfs/other_file_in_target.swift /target_file1.swift | %FileCheck %s

View File

@@ -208,6 +208,7 @@ class InMemoryFileSystemProvider: public SourceKit::FileSystemProvider {
static UIdent KeyFiles("key.files");
static UIdent KeyName("key.name");
static UIdent KeySourceFile("key.sourcefile");
static UIdent KeySourceText("key.sourcetext");
bool failed = options.forEach(KeyFiles, [&](OptionsDictionary &file) {
StringRef name;
if (!file.valueForOption(KeyName, name)) {
@@ -215,9 +216,16 @@ class InMemoryFileSystemProvider: public SourceKit::FileSystemProvider {
return true;
}
StringRef content;
if (file.valueForOption(KeySourceText, content)) {
auto buffer = llvm::MemoryBuffer::getMemBufferCopy(content, name);
InMemoryFS->addFile(name, 0, std::move(buffer));
return false;
}
StringRef mappedPath;
if (!file.valueForOption(KeySourceFile, mappedPath)) {
error = "missing 'key.sourcefile'";
error = "missing 'key.sourcefile' or 'key.sourcetext'";
return true;
}

View File

@@ -135,7 +135,7 @@ def repeat_request : Separate<["-"], "repeat-request">,
def repeat_request_EQ : Joined<["-"], "repeat-request=">, Alias<repeat_request>;
def vfs_files : CommaJoined<["-"], "vfs-files=">,
HelpText<"Injects a VFS into the request, overlaying files specified by the given <name>=<target> pairs over the real filesystem">;
HelpText<"Injects a VFS into the request, overlaying files specified by the given <name>=<target> pairs over the real filesystem. Prefix destination with '@' to pass as sourcetext.">;
def vfs_name : Separate<["-"], "vfs-name">,
HelpText<"Specify a virtual filesystem name">;

View File

@@ -355,10 +355,11 @@ bool TestOptions::parseArgs(llvm::ArrayRef<const char *> Args) {
case OPT_vfs_files:
VFSName = VFSName.getValueOr("in-memory-vfs");
for (const char *VFSFile : InputArg->getValues()) {
auto NameAndTarget = StringRef(VFSFile).split('=');
VFSFiles.try_emplace(std::get<0>(NameAndTarget),
std::get<1>(NameAndTarget).str());
for (const char *vfsFile : InputArg->getValues()) {
StringRef name, target;
std::tie(name, target) = StringRef(vfsFile).split('=');
bool passAsSourceText = target.consume_front("@");
VFSFiles.try_emplace(name, VFSFile(target.str(), passAsSourceText));
}
break;

View File

@@ -111,7 +111,13 @@ struct TestOptions {
bool isAsyncRequest = false;
bool timeRequest = false;
unsigned repeatRequest = 1;
llvm::StringMap<std::string> VFSFiles;
struct VFSFile {
std::string path;
bool passAsSourceText;
VFSFile(std::string path, bool passAsSourceText)
: path(std::move(path)), passAsSourceText(passAsSourceText) {}
};
llvm::StringMap<VFSFile> VFSFiles;
llvm::Optional<std::string> VFSName;
llvm::Optional<bool> CancelOnSubsequentRequest;
bool parseArgs(llvm::ArrayRef<const char *> Args);

View File

@@ -87,7 +87,7 @@ static bool handleResponse(sourcekitd_response_t Resp, const TestOptions &Opts,
std::unique_ptr<llvm::MemoryBuffer> SourceBuf,
TestOptions *InitOpts);
static void printCursorInfo(sourcekitd_variant_t Info, StringRef Filename,
const llvm::StringMap<std::string> &VFSFiles,
const llvm::StringMap<TestOptions::VFSFile> &VFSFiles,
llvm::raw_ostream &OS);
static void printNameTranslationInfo(sourcekitd_variant_t Info, llvm::raw_ostream &OS);
static void printRangeInfo(sourcekitd_variant_t Info, StringRef Filename,
@@ -97,7 +97,7 @@ static void printDocInfo(sourcekitd_variant_t Info, StringRef Filename);
static void printInterfaceGen(sourcekitd_variant_t Info, bool CheckASCII);
static void printSemanticInfo();
static void printRelatedIdents(sourcekitd_variant_t Info, StringRef Filename,
const llvm::StringMap<std::string> &VFSFiles,
const llvm::StringMap<TestOptions::VFSFile> &VFSFiles,
llvm::raw_ostream &OS);
static void printFoundInterface(sourcekitd_variant_t Info,
llvm::raw_ostream &OS);
@@ -123,19 +123,19 @@ static void printStatistics(sourcekitd_variant_t Info, raw_ostream &OS);
static unsigned
resolveFromLineCol(unsigned Line, unsigned Col, StringRef Filename,
const llvm::StringMap<std::string> &VFSFiles);
const llvm::StringMap<TestOptions::VFSFile> &VFSFiles);
static unsigned resolveFromLineCol(unsigned Line, unsigned Col,
llvm::MemoryBuffer *InputBuf);
static std::pair<unsigned, unsigned>
resolveToLineCol(unsigned Offset, StringRef Filename,
const llvm::StringMap<std::string> &VFSFiles);
const llvm::StringMap<TestOptions::VFSFile> &VFSFiles);
static std::pair<unsigned, unsigned> resolveToLineCol(unsigned Offset,
llvm::MemoryBuffer *InputBuf);
static std::pair<unsigned, unsigned> resolveToLineColFromBuf(unsigned Offset,
const char *Buf);
static llvm::MemoryBuffer *
getBufferForFilename(StringRef Filename,
const llvm::StringMap<std::string> &VFSFiles);
const llvm::StringMap<TestOptions::VFSFile> &VFSFiles);
static void notification_receiver(sourcekitd_response_t resp);
@@ -997,7 +997,13 @@ static int handleTestInvocation(TestOptions Opts, TestOptions &InitOpts) {
for (auto &NameAndTarget : Opts.VFSFiles) {
sourcekitd_object_t file = sourcekitd_request_dictionary_create(nullptr, nullptr, 0);
sourcekitd_request_dictionary_set_string(file, KeyName, NameAndTarget.first().data());
sourcekitd_request_dictionary_set_string(file, KeySourceFile, NameAndTarget.second.c_str());
if (NameAndTarget.second.passAsSourceText) {
auto content = getBufferForFilename(NameAndTarget.first(), Opts.VFSFiles);
sourcekitd_request_dictionary_set_string(file, KeySourceText, content->getBufferStart());
} else {
sourcekitd_request_dictionary_set_string(file, KeySourceFile, NameAndTarget.second.path.c_str());
}
sourcekitd_request_array_set_value(files, SOURCEKITD_ARRAY_APPEND, file);
}
sourcekitd_object_t vfsOpts = sourcekitd_request_dictionary_create(nullptr, nullptr, 0);
@@ -1408,7 +1414,7 @@ static void printNameTranslationInfo(sourcekitd_variant_t Info,
}
static void printCursorInfo(sourcekitd_variant_t Info, StringRef FilenameIn,
const llvm::StringMap<std::string> &VFSFiles,
const llvm::StringMap<TestOptions::VFSFile> &VFSFiles,
llvm::raw_ostream &OS) {
const char *InternalDiagnostic =
sourcekitd_variant_dictionary_get_string(Info, KeyInternalDiagnostic);
@@ -1883,7 +1889,7 @@ static void printInterfaceGen(sourcekitd_variant_t Info, bool CheckASCII) {
}
static void printRelatedIdents(sourcekitd_variant_t Info, StringRef Filename,
const llvm::StringMap<std::string> &VFSFiles,
const llvm::StringMap<TestOptions::VFSFile> &VFSFiles,
llvm::raw_ostream &OS) {
OS << "START RANGES\n";
sourcekitd_variant_t Res =
@@ -2095,7 +2101,7 @@ static void expandPlaceholders(llvm::MemoryBuffer *SourceBuf,
static std::pair<unsigned, unsigned>
resolveToLineCol(unsigned Offset, StringRef Filename,
const llvm::StringMap<std::string> &VFSFiles) {
const llvm::StringMap<TestOptions::VFSFile> &VFSFiles) {
return resolveToLineCol(Offset, getBufferForFilename(Filename, VFSFiles));
}
@@ -2128,7 +2134,7 @@ resolveToLineColFromBuf(unsigned Offset, const char *Ptr) {
static unsigned
resolveFromLineCol(unsigned Line, unsigned Col, StringRef Filename,
const llvm::StringMap<std::string> &VFSFiles) {
const llvm::StringMap<TestOptions::VFSFile> &VFSFiles) {
return resolveFromLineCol(Line, Col,
getBufferForFilename(Filename, VFSFiles));
}
@@ -2171,10 +2177,10 @@ static llvm::StringMap<llvm::MemoryBuffer*> Buffers;
static llvm::MemoryBuffer *
getBufferForFilename(StringRef Filename,
const llvm::StringMap<std::string> &VFSFiles) {
const llvm::StringMap<TestOptions::VFSFile> &VFSFiles) {
auto VFSFileIt = VFSFiles.find(Filename);
auto MappedFilename =
VFSFileIt == VFSFiles.end() ? Filename : StringRef(VFSFileIt->second);
VFSFileIt == VFSFiles.end() ? Filename : StringRef(VFSFileIt->second.path);
auto It = Buffers.find(MappedFilename);
if (It != Buffers.end())