9 #include <utils/Error.h> 
   25    bool operator==(
SourceFile const& other) 
const { 
return id_ == other.id_; }
 
   28    explicit SourceFile(
void const* ptr) : id_{ptr} {}
 
   46    SourceManager() = 
default;
 
   54       if(path.size() < 5 || path.substr(path.size() - 5) != 
".java") {
 
   55          throw utils::
FatalError{
"File " + std::string{path} + 
" is not a .java file"};
 
   57       std::ifstream file{std::string{path}};
 
   59          throw utils::
FatalError{
"File " + std::string{path} + 
" does not exist"};
 
   61       files_.emplace_back(path, std::istreambuf_iterator<
char>{file}, 
this);
 
   66       auto name = 
"Buffer " + std::to_string(files_.size() + 1);
 
   67       files_.emplace_back(name, 
this);
 
   75       return files_ | std::views::all |
 
   76              std::views::transform([](File 
const& file) -> 
SourceFile {
 
   77                 return SourceFile{
static_cast<File 
const*>(&file)};
 
   83       auto* f = 
static_cast<File 
const*>(file.id_);
 
   84       if(f == 
nullptr || !f->isFile)
 
   93       if(file.id_ == 
nullptr) {
 
   96          os << 
static_cast<File 
const*>(file.id_)->name;
 
  104       return static_cast<File 
const*>(file.id_)->buffer;
 
  113       File(std::string_view name, std::istreambuf_iterator<
char> begin,
 
  115             : name{name}, buffer{begin, {}}, isFile{
true}, parent{parent} {}
 
  117             : name{name}, buffer{}, parent{parent} {}
 
  120    std::list<File> files_;