brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.0 KiB · 020ef60 Raw
144 lines · c
1//===--- RewriterTestContext.h ----------------------------------*- C++ -*-===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9//  This file defines a utility class for Rewriter related tests.10//11//===----------------------------------------------------------------------===//12 13#ifndef LLVM_CLANG_UNITTESTS_TOOLING_REWRITERTESTCONTEXT_H14#define LLVM_CLANG_UNITTESTS_TOOLING_REWRITERTESTCONTEXT_H15 16#include "clang/Basic/Diagnostic.h"17#include "clang/Basic/DiagnosticOptions.h"18#include "clang/Basic/FileManager.h"19#include "clang/Basic/LangOptions.h"20#include "clang/Basic/SourceManager.h"21#include "clang/Rewrite/Core/Rewriter.h"22#include "llvm/Support/FileSystem.h"23#include "llvm/Support/Path.h"24#include "llvm/Support/raw_ostream.h"25 26namespace clang {27 28/// \brief A very simple diagnostic consumer that prints to stderr and keeps29/// track of the number of diagnostics.30///31/// This avoids a dependency on clangFrontend for FormatTests.32struct RewriterDiagnosticConsumer : public DiagnosticConsumer {33  RewriterDiagnosticConsumer() : NumDiagnosticsSeen(0) {}34  void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,35                        const Diagnostic &Info) override {36    ++NumDiagnosticsSeen;37    SmallString<100> OutStr;38    Info.FormatDiagnostic(OutStr);39    llvm::errs() << OutStr;40  }41  unsigned NumDiagnosticsSeen;42};43 44/// \brief A class that sets up a ready to use Rewriter.45///46/// Useful in unit tests that need a Rewriter. Creates all dependencies47/// of a Rewriter with default values for testing and provides convenience48/// methods, which help with writing tests that change files.49class RewriterTestContext {50 public:51   RewriterTestContext()52       : Diagnostics(DiagnosticIDs::create(), DiagOpts),53         InMemoryFileSystem(54             llvm::makeIntrusiveRefCnt<llvm::vfs::InMemoryFileSystem>()),55         OverlayFileSystem(56             llvm::makeIntrusiveRefCnt<llvm::vfs::OverlayFileSystem>(57                 llvm::vfs::getRealFileSystem())),58         Files(FileSystemOptions(), OverlayFileSystem),59         Sources(Diagnostics, Files), Rewrite(Sources, Options) {60     Diagnostics.setClient(&DiagnosticPrinter, false);61     // FIXME: To make these tests truly in-memory, we need to overlay the62     // builtin headers.63     OverlayFileSystem->pushOverlay(InMemoryFileSystem);64   }65 66  ~RewriterTestContext() {}67 68  FileID createInMemoryFile(StringRef Name, StringRef Content) {69    std::unique_ptr<llvm::MemoryBuffer> Source =70        llvm::MemoryBuffer::getMemBuffer(Content);71    InMemoryFileSystem->addFile(Name, 0, std::move(Source));72 73    auto Entry = Files.getOptionalFileRef(Name);74    assert(Entry);75    return Sources.createFileID(*Entry, SourceLocation(), SrcMgr::C_User);76  }77 78  // FIXME: this code is mostly a duplicate of79  // unittests/Tooling/RefactoringTest.cpp. Figure out a way to share it.80  FileID createOnDiskFile(StringRef Name, StringRef Content) {81    SmallString<1024> Path;82    int FD;83    std::error_code EC = llvm::sys::fs::createTemporaryFile(Name, "", FD, Path);84    assert(!EC);85    (void)EC;86 87    llvm::raw_fd_ostream OutStream(FD, true);88    OutStream << Content;89    OutStream.close();90    auto File = Files.getOptionalFileRef(Path);91    assert(File);92 93    StringRef Found =94        TemporaryFiles.insert(std::make_pair(Name, std::string(Path.str())))95            .first->second;96    assert(Found == Path);97    (void)Found;98    return Sources.createFileID(*File, SourceLocation(), SrcMgr::C_User);99  }100 101  SourceLocation getLocation(FileID ID, unsigned Line, unsigned Column) {102    SourceLocation Result = Sources.translateFileLineCol(103        Sources.getFileEntryForID(ID), Line, Column);104    assert(Result.isValid());105    return Result;106  }107 108  std::string getRewrittenText(FileID ID) {109    std::string Result;110    llvm::raw_string_ostream OS(Result);111    Rewrite.getEditBuffer(ID).write(OS);112    return Result;113  }114 115  std::string getFileContentFromDisk(StringRef Name) {116    std::string Path = TemporaryFiles.lookup(Name);117    assert(!Path.empty());118    // We need to read directly from the FileManager without relaying through119    // a FileEntry, as otherwise we'd read through an already opened file120    // descriptor, which might not see the changes made.121    // FIXME: Figure out whether there is a way to get the SourceManger to122    // reopen the file.123    auto FileBuffer = Files.getBufferForFile(Path);124    return std::string((*FileBuffer)->getBuffer());125  }126 127  DiagnosticOptions DiagOpts;128  DiagnosticsEngine Diagnostics;129  RewriterDiagnosticConsumer DiagnosticPrinter;130  IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> InMemoryFileSystem;131  IntrusiveRefCntPtr<llvm::vfs::OverlayFileSystem> OverlayFileSystem;132  FileManager Files;133  SourceManager Sources;134  LangOptions Options;135  Rewriter Rewrite;136 137  // Will be set once on disk files are generated.138  llvm::StringMap<std::string> TemporaryFiles;139};140 141} // end namespace clang142 143#endif144