Skip to content

Commit

Permalink
Use schema include name for keep-prefix (google#7469)
Browse files Browse the repository at this point in the history
  • Loading branch information
dbaileychess authored and sssooonnnggg committed Aug 25, 2022
1 parent 8367664 commit 7ea6a53
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 37 deletions.
22 changes: 20 additions & 2 deletions include/flatbuffers/idl.h
Expand Up @@ -537,6 +537,24 @@ struct ServiceDef : public Definition {
SymbolTable<RPCCall> calls;
};

struct IncludedFile {
// The name of the schema file being included, as defined in the .fbs file.
// This includes the prefix (e.g., include "foo/bar/baz.fbs" would mean this
// value is "foo/bar/baz.fbs").
std::string schema_name;

// The filename of where the included file was found, after searching the
// relative paths plus any other paths included with `flatc -I ...`. Note,
// while this is sometimes the same as schema_name, it is not always, since it
// can be defined relative to where flatc was invoked.
std::string filename;
};

// Since IncludedFile is contained within a std::set, need to provide ordering.
inline bool operator<(const IncludedFile &a, const IncludedFile &b) {
return a.filename < b.filename;
}

// Container of options that may apply to any of the source/text generators.
struct IDLOptions {
// field case style options for C++
Expand Down Expand Up @@ -914,7 +932,7 @@ class Parser : public ParserState {
// Get the set of included files that are directly referenced by the file
// being parsed. This does not include files that are transitively included by
// others includes.
std::vector<std::string> GetIncludedFiles() const;
std::vector<IncludedFile> GetIncludedFiles() const;

private:
class ParseDepthGuard;
Expand Down Expand Up @@ -1043,7 +1061,7 @@ class Parser : public ParserState {
std::string file_extension_;

std::map<uint64_t, std::string> included_files_;
std::map<std::string, std::set<std::string>> files_included_per_file_;
std::map<std::string, std::set<IncludedFile>> files_included_per_file_;
std::vector<std::string> native_included_files_;

std::map<std::string, bool> known_attributes_;
Expand Down
39 changes: 13 additions & 26 deletions src/idl_gen_cpp.cpp
Expand Up @@ -233,37 +233,24 @@ class CppGenerator : public BaseGenerator {
}

// Get the directly included file of the file being parsed.
std::vector<std::string> included_files(parser_.GetIncludedFiles());
std::vector<IncludedFile> included_files(parser_.GetIncludedFiles());

// We are safe to sort them alphabetically, since there shouldn't be any
// interdependence between them.
std::stable_sort(included_files.begin(), included_files.end());

// The absolute path of the file being parsed.
const std::string parsed_path =
flatbuffers::StripFileName(AbsolutePath(parser_.file_being_parsed_));

for (const std::string &included_file : included_files) {
// The base name of the file, without path or extensions.
std::string basename =
flatbuffers::StripPath(flatbuffers::StripExtension(included_file));

// If we are keeping the prefix
if (opts_.keep_prefix) {
// The absolute path of the included file.
const std::string included_path =
flatbuffers::StripFileName(AbsolutePath(included_file));

// The relative path of the parsed file to the included file.
const std::string relative_path =
RelativeToRootPath(parsed_path, included_path).substr(2);

// Only consider cases where the included path is a subdirectory of the
// parsed path.
if (strncmp("..", relative_path.c_str(), 2) != 0) {
basename = relative_path + kPathSeparator + basename;
}
}
for (const IncludedFile &included_file : included_files) {
// Get the name of the included file as defined by the schema, and strip
// the .fbs extension.
const std::string name_without_ext =
flatbuffers::StripExtension(included_file.schema_name);

// If we are told to keep the prefix of the included schema, leave it
// unchanged, otherwise strip the leading path off so just the "basename"
// of the include is retained.
const std::string basename =
opts_.keep_prefix ? name_without_ext
: flatbuffers::StripPath(name_without_ext);

code_ += "#include \"" +
GeneratedFileName(opts_.include_prefix, basename, opts_) + "\"";
Expand Down
24 changes: 15 additions & 9 deletions src/idl_parser.cpp
Expand Up @@ -2545,7 +2545,7 @@ CheckedError Parser::CheckClash(std::vector<FieldDef *> &fields,
return NoError();
}

std::vector<std::string> Parser::GetIncludedFiles() const {
std::vector<IncludedFile> Parser::GetIncludedFiles() const {
const auto it = files_included_per_file_.find(file_being_parsed_);
if (it == files_included_per_file_.end()) { return {}; }

Expand Down Expand Up @@ -3435,7 +3435,7 @@ CheckedError Parser::DoParse(const char *source, const char **include_paths,

if (included_files_.find(source_hash) == included_files_.end()) {
included_files_[source_hash] = include_filename ? include_filename : "";
files_included_per_file_[source_filename] = std::set<std::string>();
files_included_per_file_[source_filename] = std::set<IncludedFile>();
} else {
return NoError();
}
Expand Down Expand Up @@ -3483,8 +3483,12 @@ CheckedError Parser::DoParse(const char *source, const char **include_paths,
}
if (filepath.empty())
return Error("unable to locate include file: " + name);
if (source_filename)
files_included_per_file_[source_filename].insert(filepath);
if (source_filename) {
IncludedFile included_file;
included_file.filename = filepath;
included_file.schema_name = name;
files_included_per_file_[source_filename].insert(included_file);
}

std::string contents;
bool file_loaded = LoadFile(filepath.c_str(), true, &contents);
Expand Down Expand Up @@ -3621,11 +3625,11 @@ std::set<std::string> Parser::GetIncludedFilesRecursive(

// Workaround the lack of const accessor in C++98 maps.
auto &new_files =
(*const_cast<std::map<std::string, std::set<std::string>> *>(
(*const_cast<std::map<std::string, std::set<IncludedFile>> *>(
&files_included_per_file_))[current];
for (auto it = new_files.begin(); it != new_files.end(); ++it) {
if (included_files.find(*it) == included_files.end())
to_process.push_back(*it);
if (included_files.find(it->filename) == included_files.end())
to_process.push_back(it->filename);
}
}

Expand Down Expand Up @@ -3675,7 +3679,7 @@ void Parser::Serialize() {
RelativeToRootPath(opts.project_root, f->first));
for (auto i = f->second.begin(); i != f->second.end(); i++) {
included_files.push_back(builder_.CreateSharedString(
RelativeToRootPath(opts.project_root, *i)));
RelativeToRootPath(opts.project_root, i->filename)));
}
const auto included_files__ = builder_.CreateVector(included_files);
included_files.clear();
Expand Down Expand Up @@ -4107,7 +4111,9 @@ bool Parser::Deserialize(const reflection::Schema *schema) {
++s) {
for (auto f = s->included_filenames()->begin();
f != s->included_filenames()->end(); ++f) {
files_included_per_file_[s->filename()->str()].insert(f->str());
IncludedFile included_file;
included_file.filename = f->str();
files_included_per_file_[s->filename()->str()].insert(included_file);
}
}

Expand Down

0 comments on commit 7ea6a53

Please sign in to comment.