Use schema include name for keep-prefix (#7469)
This commit is contained in:
parent
8367664f15
commit
fef2ffc4d0
|
@ -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++
|
||||
|
@ -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;
|
||||
|
@ -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_;
|
||||
|
|
|
@ -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 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);
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
// 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_) + "\"";
|
||||
|
|
|
@ -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 {}; }
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue