aboutsummaryrefslogtreecommitdiff
path: root/gcc/rust/ast/rust-ast-full-test.cc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/rust/ast/rust-ast-full-test.cc')
-rw-r--r--gcc/rust/ast/rust-ast-full-test.cc70
1 files changed, 70 insertions, 0 deletions
diff --git a/gcc/rust/ast/rust-ast-full-test.cc b/gcc/rust/ast/rust-ast-full-test.cc
index dfd9cdb..6033ce9 100644
--- a/gcc/rust/ast/rust-ast-full-test.cc
+++ b/gcc/rust/ast/rust-ast-full-test.cc
@@ -17,6 +17,9 @@ You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
+// FIXME: This does not work on Windows
+#include <unistd.h>
+
#include "rust-ast-full.h"
#include "rust-diagnostics.h"
#include "rust-ast-visitor.h"
@@ -4050,6 +4053,73 @@ Module::add_crate_name (std::vector<std::string> &names) const
item->add_crate_name (names);
}
+static bool
+file_exists (const std::string path)
+{
+ // Simply check if the file exists
+ // FIXME: This does not work on Windows
+ return access (path.c_str (), F_OK) != -1;
+}
+
+// FIXME: This function should also check if the module has a `path` outer
+// attribute and fetch the path from here in that case, i.e:
+// ```
+// #[path="<dir>/<subdir>/<file>.rs"]
+// mod <mod_name>;
+// ```
+std::string
+Module::get_filename ()
+{
+ rust_assert (kind == Module::ModuleKind::UNLOADED);
+
+ // This corresponds to the path of the file 'including' the module. So the
+ // file that contains the 'mod <file>;' directive
+ std::string including_fname (outer_filename);
+
+ std::string expected_file_path = module_name + ".rs";
+ std::string expected_dir_path = "mod.rs";
+
+ auto dir_slash_pos = including_fname.rfind (file_separator);
+ std::string current_directory_name;
+
+ // If we haven't found a file_separator, then we have to look for files in the
+ // current directory ('.')
+ if (dir_slash_pos == std::string::npos)
+ current_directory_name = std::string (".") + file_separator;
+ else
+ current_directory_name
+ = including_fname.substr (0, dir_slash_pos) + file_separator;
+
+ // FIXME: We also have to search for
+ // <directory>/<including_fname>/<module_name>.rs In rustc, this is done via
+ // the concept of `DirOwnernship`, which is based on whether or not the
+ // current file is titled `mod.rs`.
+
+ // First, we search for <directory>/<module_name>.rs
+ bool file_mod_found
+ = file_exists (current_directory_name + expected_file_path);
+
+ // Then, search for <directory>/<module_name>/mod.rs
+ current_directory_name += module_name + file_separator;
+ bool dir_mod_found = file_exists (current_directory_name + expected_dir_path);
+
+ bool multiple_candidates_found = file_mod_found && dir_mod_found;
+ bool no_candidates_found = !file_mod_found && !dir_mod_found;
+
+ if (multiple_candidates_found)
+ rust_error_at (locus,
+ "two candidates found for module %s: %s.rs and %s%smod.rs",
+ module_name.c_str (), module_name.c_str (),
+ module_name.c_str (), file_separator);
+
+ if (no_candidates_found)
+ rust_error_at (locus, "no candidate found for module %s",
+ module_name.c_str ());
+
+ return file_mod_found ? expected_file_path
+ : current_directory_name + expected_dir_path;
+}
+
void
Attribute::parse_attr_to_meta_item ()
{