| ... | ... | @@ -4865,14 +4865,31 @@ pub fn importFile( |
| 4865 | 4865 | }; |
| 4866 | 4866 | } |
| 4867 | 4867 | |
| 4868 | | pub fn embedFile(mod: *Module, cur_file: *File, rel_file_path: []const u8) !*EmbedFile { |
| 4868 | pub fn embedFile(mod: *Module, cur_file: *File, import_string: []const u8) !*EmbedFile { |
| 4869 | 4869 | const gpa = mod.gpa; |
| 4870 | 4870 | |
| 4871 | | // The resolved path is used as the key in the table, to detect if |
| 4872 | | // a file refers to the same as another, despite different relative paths. |
| 4871 | if (cur_file.pkg.table.get(import_string)) |pkg| { |
| 4872 | const resolved_path = try std.fs.path.resolve(gpa, &[_][]const u8{ |
| 4873 | pkg.root_src_directory.path orelse ".", pkg.root_src_path, |
| 4874 | }); |
| 4875 | var keep_resolved_path = false; |
| 4876 | defer if (!keep_resolved_path) gpa.free(resolved_path); |
| 4877 | |
| 4878 | const gop = try mod.embed_table.getOrPut(gpa, resolved_path); |
| 4879 | errdefer assert(mod.embed_table.remove(resolved_path)); |
| 4880 | if (gop.found_existing) return gop.value_ptr.*; |
| 4881 | |
| 4882 | const sub_file_path = try gpa.dupe(u8, pkg.root_src_path); |
| 4883 | errdefer gpa.free(sub_file_path); |
| 4884 | |
| 4885 | return newEmbedFile(mod, pkg, sub_file_path, resolved_path, &keep_resolved_path, gop); |
| 4886 | } |
| 4887 | |
| 4888 | // The resolved path is used as the key in the table, to detect if a file |
| 4889 | // refers to the same as another, despite different relative paths. |
| 4873 | 4890 | const cur_pkg_dir_path = cur_file.pkg.root_src_directory.path orelse "."; |
| 4874 | 4891 | const resolved_path = try std.fs.path.resolve(gpa, &[_][]const u8{ |
| 4875 | | cur_pkg_dir_path, cur_file.sub_file_path, "..", rel_file_path, |
| 4892 | cur_pkg_dir_path, cur_file.sub_file_path, "..", import_string, |
| 4876 | 4893 | }); |
| 4877 | 4894 | var keep_resolved_path = false; |
| 4878 | 4895 | defer if (!keep_resolved_path) gpa.free(resolved_path); |
| ... | ... | @@ -4881,9 +4898,6 @@ pub fn embedFile(mod: *Module, cur_file: *File, rel_file_path: []const u8) !*Emb |
| 4881 | 4898 | errdefer assert(mod.embed_table.remove(resolved_path)); |
| 4882 | 4899 | if (gop.found_existing) return gop.value_ptr.*; |
| 4883 | 4900 | |
| 4884 | | const new_file = try gpa.create(EmbedFile); |
| 4885 | | errdefer gpa.destroy(new_file); |
| 4886 | | |
| 4887 | 4901 | const resolved_root_path = try std.fs.path.resolve(gpa, &[_][]const u8{cur_pkg_dir_path}); |
| 4888 | 4902 | defer gpa.free(resolved_root_path); |
| 4889 | 4903 | |
| ... | ... | @@ -4902,7 +4916,23 @@ pub fn embedFile(mod: *Module, cur_file: *File, rel_file_path: []const u8) !*Emb |
| 4902 | 4916 | }; |
| 4903 | 4917 | errdefer gpa.free(sub_file_path); |
| 4904 | 4918 | |
| 4905 | | var file = try cur_file.pkg.root_src_directory.handle.openFile(sub_file_path, .{}); |
| 4919 | return newEmbedFile(mod, cur_file.pkg, sub_file_path, resolved_path, &keep_resolved_path, gop); |
| 4920 | } |
| 4921 | |
| 4922 | fn newEmbedFile( |
| 4923 | mod: *Module, |
| 4924 | pkg: *Package, |
| 4925 | sub_file_path: []const u8, |
| 4926 | resolved_path: []const u8, |
| 4927 | keep_resolved_path: *bool, |
| 4928 | gop: std.StringHashMapUnmanaged(*EmbedFile).GetOrPutResult, |
| 4929 | ) !*EmbedFile { |
| 4930 | const gpa = mod.gpa; |
| 4931 | |
| 4932 | const new_file = try gpa.create(EmbedFile); |
| 4933 | errdefer gpa.destroy(new_file); |
| 4934 | |
| 4935 | var file = try pkg.root_src_directory.handle.openFile(sub_file_path, .{}); |
| 4906 | 4936 | defer file.close(); |
| 4907 | 4937 | |
| 4908 | 4938 | const actual_stat = try file.stat(); |
| ... | ... | @@ -4915,10 +4945,6 @@ pub fn embedFile(mod: *Module, cur_file: *File, rel_file_path: []const u8) !*Emb |
| 4915 | 4945 | const bytes = try file.readToEndAllocOptions(gpa, std.math.maxInt(u32), size_usize, 1, 0); |
| 4916 | 4946 | errdefer gpa.free(bytes); |
| 4917 | 4947 | |
| 4918 | | log.debug("new embedFile. resolved_root_path={s}, resolved_path={s}, sub_file_path={s}, rel_file_path={s}", .{ |
| 4919 | | resolved_root_path, resolved_path, sub_file_path, rel_file_path, |
| 4920 | | }); |
| 4921 | | |
| 4922 | 4948 | if (mod.comp.whole_cache_manifest) |whole_cache_manifest| { |
| 4923 | 4949 | const copied_resolved_path = try gpa.dupe(u8, resolved_path); |
| 4924 | 4950 | errdefer gpa.free(copied_resolved_path); |
| ... | ... | @@ -4927,13 +4953,13 @@ pub fn embedFile(mod: *Module, cur_file: *File, rel_file_path: []const u8) !*Emb |
| 4927 | 4953 | try whole_cache_manifest.addFilePostContents(copied_resolved_path, bytes, stat); |
| 4928 | 4954 | } |
| 4929 | 4955 | |
| 4930 | | keep_resolved_path = true; // It's now owned by embed_table. |
| 4956 | keep_resolved_path.* = true; // It's now owned by embed_table. |
| 4931 | 4957 | gop.value_ptr.* = new_file; |
| 4932 | 4958 | new_file.* = .{ |
| 4933 | 4959 | .sub_file_path = sub_file_path, |
| 4934 | 4960 | .bytes = bytes, |
| 4935 | 4961 | .stat = stat, |
| 4936 | | .pkg = cur_file.pkg, |
| 4962 | .pkg = pkg, |
| 4937 | 4963 | .owner_decl = undefined, // Set by Sema immediately after this function returns. |
| 4938 | 4964 | }; |
| 4939 | 4965 | return new_file; |