blob: 12106e5bc4515056d5cb06c661134a0fa1812477 [file] [log] [blame]
Brian Anderson45efb1f2011-06-27 23:03:011// Metadata encoding
2
Tim Chevalier3d4ef742012-04-26 19:15:463import util::ppaux::ty_to_str;
4
Brian Anderson322b20d2012-05-17 05:28:015import std::{ebml, map};
Patrick Waltonc9375fe2012-03-08 00:48:576import std::map::hashmap;
Marijn Haverbeke34d7f052012-01-11 14:15:547import io::writer_util;
Niko Matsakisf3ca50c2012-02-14 23:21:538import ebml::writer;
Marijn Haverbeke6fd6fde2011-07-05 09:48:199import syntax::ast::*;
Niko Matsakisf3ca50c2012-02-14 23:21:5310import syntax::print::pprust;
Marijn Haverbekefe90c182012-03-08 22:37:4511import syntax::{ast_util, visit};
Tim Chevalieraa9d2d82012-06-12 23:25:0912import syntax::ast_util::*;
Brian Andersone29ef1b2011-07-07 19:22:3913import common::*;
Brian Anderson33294c72011-06-27 22:20:1714import middle::ty;
Marijn Haverbeke86d473a2012-01-30 16:28:3015import middle::ty::node_id_to_type;
Brian Anderson9aa18c22012-05-22 06:34:3416import syntax::ast_map;
Brian Anderson0e870392012-03-23 01:16:2217import syntax::attr;
Niko Matsakisf3ca50c2012-02-14 23:21:5318import std::serialization::serializer;
Niko Matsakis3c995fb2012-04-19 04:26:2519import std::ebml::serializer;
Brian Andersona2572fe2012-05-14 00:01:5220import syntax::ast;
Brian Anderson452fc462012-05-15 03:41:3321import syntax::diagnostic::span_handler;
Brian Anderson33294c72011-06-27 22:20:1722
Brian Andersona2572fe2012-05-14 00:01:5223export encode_parms;
Brian Anderson33294c72011-06-27 22:20:1724export encode_metadata;
Brian Anderson6ee1ffe2011-07-07 19:56:0125export encoded_ty;
Brian Andersonb4a3d522012-04-24 06:40:5326export reachable;
Brian Anderson5c864e92012-05-15 00:38:1727export encode_inlined_item;
Brian Anderson33294c72011-06-27 22:20:1728
Niko Matsakisf3ca50c2012-02-14 23:21:5329// used by astencode:
30export def_to_str;
31export encode_ctxt;
32export write_type;
33export encode_def_id;
34
Erick Tryzelaare4a0f992011-08-12 14:15:1835type abbrev_map = map::hashmap<ty::t, tyencode::ty_abbrev>;
Brian Andersond0a432f2011-07-08 06:55:4136
Brian Anderson5c864e92012-05-15 00:38:1737type encode_inlined_item = fn@(ecx: @encode_ctxt,
38 ebml_w: ebml::writer,
39 path: ast_map::path,
40 ii: ast::inlined_item);
41
Brian Andersona2572fe2012-05-14 00:01:5242type encode_parms = {
Brian Anderson452fc462012-05-15 03:41:3343 diag: span_handler,
Brian Andersona2572fe2012-05-14 00:01:5244 tcx: ty::ctxt,
45 reachable: hashmap<ast::node_id, ()>,
Michael Sullivan98e161f2012-06-29 23:26:5646 reexports: ~[(str, def_id)],
47 impl_map: fn@(ast::node_id) -> ~[(ident, def_id)],
Brian Andersona2572fe2012-05-14 00:01:5248 item_symbols: hashmap<ast::node_id, str>,
49 discrim_symbols: hashmap<ast::node_id, str>,
Brian Anderson0f499282012-05-15 01:29:0150 link_meta: link_meta,
Brian Andersona2572fe2012-05-14 00:01:5251 cstore: cstore::cstore,
Brian Anderson5c864e92012-05-15 00:38:1752 encode_inlined_item: encode_inlined_item
Brian Andersona2572fe2012-05-14 00:01:5253};
54
Brian Anderson5c864e92012-05-15 00:38:1755enum encode_ctxt = {
Brian Anderson452fc462012-05-15 03:41:3356 diag: span_handler,
Brian Andersona2572fe2012-05-14 00:01:5257 tcx: ty::ctxt,
58 reachable: hashmap<ast::node_id, ()>,
Michael Sullivan98e161f2012-06-29 23:26:5659 reexports: ~[(str, def_id)],
60 impl_map: fn@(ast::node_id) -> ~[(ident, def_id)],
Brian Andersona2572fe2012-05-14 00:01:5261 item_symbols: hashmap<ast::node_id, str>,
62 discrim_symbols: hashmap<ast::node_id, str>,
Brian Anderson0f499282012-05-15 01:29:0163 link_meta: link_meta,
Brian Andersona2572fe2012-05-14 00:01:5264 cstore: cstore::cstore,
Brian Anderson5c864e92012-05-15 00:38:1765 encode_inlined_item: encode_inlined_item,
Brian Andersona2572fe2012-05-14 00:01:5266 type_abbrevs: abbrev_map
67};
Brian Andersond0a432f2011-07-08 06:55:4168
Brian Andersonb4a3d522012-04-24 06:40:5369fn reachable(ecx: @encode_ctxt, id: node_id) -> bool {
Brian Andersona2572fe2012-05-14 00:01:5270 ecx.reachable.contains_key(id)
Brian Andersonb4a3d522012-04-24 06:40:5371}
72
Brian Anderson33294c72011-06-27 22:20:1773// Path table encoding
Brian Andersonce750a72012-06-10 07:49:5974fn encode_name(ebml_w: ebml::writer, name: ident) {
75 ebml_w.wr_tagged_str(tag_paths_data_name, *name);
Brian Anderson33294c72011-06-27 22:20:1776}
77
Marijn Haverbekefc6b7c82011-09-12 09:27:3078fn encode_def_id(ebml_w: ebml::writer, id: def_id) {
Niko Matsakisf3ca50c2012-02-14 23:21:5379 ebml_w.wr_tagged_str(tag_def_id, def_to_str(id));
Niko Matsakis5d57fa32012-02-06 15:13:1480}
81
Tim Chevalierc97b29a2012-05-18 03:37:1782/* Encodes the given name, then def_id as tagged strings */
83fn encode_name_and_def_id(ebml_w: ebml::writer, nm: ident,
84 id: node_id) {
85 encode_name(ebml_w, nm);
86 encode_def_id(ebml_w, local_def(id));
87}
88
Niko Matsakisb9aa9de2012-07-11 17:28:3089fn encode_region_param(ecx: @encode_ctxt, ebml_w: ebml::writer,
90 it: @ast::item) {
91 let rp = ecx.tcx.region_paramd_items.contains_key(it.id);
92 if rp { do ebml_w.wr_tag(tag_region_param) { } }
Niko Matsakis3c995fb2012-04-19 04:26:2593}
94
Brian Andersonce750a72012-06-10 07:49:5995fn encode_named_def_id(ebml_w: ebml::writer, name: ident, id: def_id) {
Ben Striegelf2e2a142012-07-04 19:04:2896 do ebml_w.wr_tag(tag_paths_data_item) {
Niko Matsakis5d57fa32012-02-06 15:13:1497 encode_name(ebml_w, name);
98 encode_def_id(ebml_w, id);
99 }
Brian Anderson33294c72011-06-27 22:20:17100}
101
Tim Chevalieredb747c2012-03-28 05:08:48102fn encode_mutability(ebml_w: ebml::writer, mt: class_mutability) {
Ben Striegelf2e2a142012-07-04 19:04:28103 do ebml_w.wr_tag(tag_class_mut) {
Michael Sullivan98e161f2012-06-29 23:26:56104 ebml_w.writer.write(&[alt mt { class_immutable { 'i' }
105 class_mutable { 'm' } } as u8]);
Tim Chevalieredb747c2012-03-28 05:08:48106 }
107}
108
Erick Tryzelaar4abc4712011-08-12 13:36:51109type entry<T> = {val: T, pos: uint};
Marijn Haverbekeaea53772011-07-26 12:06:02110
Michael Sullivan98e161f2012-06-29 23:26:56111fn encode_enum_variant_paths(ebml_w: ebml::writer, variants: ~[variant],
112 path: ~[ident], &index: ~[entry<str>]) {
Brian Andersond1fc2b52012-06-30 23:19:07113 for variants.each |variant| {
Brian Anderson03119fe2011-08-26 00:00:12114 add_to_index(ebml_w, path, index, variant.node.name);
Ben Striegelf2e2a142012-07-04 19:04:28115 do ebml_w.wr_tag(tag_paths_data_item) {
Niko Matsakis5d57fa32012-02-06 15:13:14116 encode_name(ebml_w, variant.node.name);
117 encode_def_id(ebml_w, local_def(variant.node.id));
118 }
Brian Anderson33294c72011-06-27 22:20:17119 }
120}
121
Michael Sullivan98e161f2012-06-29 23:26:56122fn add_to_index(ebml_w: ebml::writer, path: &[ident], &index: ~[entry<str>],
Brian Andersonce750a72012-06-10 07:49:59123 name: ident) {
Michael Sullivan98e161f2012-06-29 23:26:56124 let mut full_path = ~[];
Eric Holk87eaf912012-06-28 22:00:03125 vec::push_all(full_path, path);
126 vec::push(full_path, name);
Michael Sullivan329eca62012-06-26 03:00:46127 vec::push(index, {val: ast_util::path_name_i(full_path),
128 pos: ebml_w.writer.tell()});
Brian Anderson33294c72011-06-27 22:20:17129}
130
Graydon Hoare697f1e32012-06-26 23:18:37131fn encode_foreign_module_item_paths(ebml_w: ebml::writer, nmod: foreign_mod,
Michael Sullivan98e161f2012-06-29 23:26:56132 path: ~[ident], &index: ~[entry<str>]) {
Brian Andersond1fc2b52012-06-30 23:19:07133 for nmod.items.each |nitem| {
Tim Chevalier271da612012-07-09 22:19:34134 add_to_index(ebml_w, path, index, nitem.ident);
135 do ebml_w.wr_tag(tag_paths_foreign_path) {
136 encode_name(ebml_w, nitem.ident);
137 encode_def_id(ebml_w, local_def(nitem.id));
138 }
Brian Anderson33294c72011-06-27 22:20:17139 }
140}
141
Tim Chevalier1680ccc2012-03-06 16:02:13142fn encode_class_item_paths(ebml_w: ebml::writer,
Michael Sullivan98e161f2012-06-29 23:26:56143 items: ~[@class_member], path: ~[ident], &index: ~[entry<str>]) {
Brian Andersond1fc2b52012-06-30 23:19:07144 for items.each |it| {
Marijn Haverbekeb6199542012-05-08 14:06:24145 alt ast_util::class_member_visibility(it) {
Graydon Hoarec26d0252012-07-09 21:37:48146 private { again; }
Marijn Haverbekeb6199542012-05-08 14:06:24147 public {
Tim Chevalierf7bbe532012-03-29 01:50:33148 let (id, ident) = alt it.node {
149 instance_var(v, _, _, vid, _) { (vid, v) }
Tim Chevalierb06dc882012-03-19 17:19:00150 class_method(it) { (it.id, it.ident) }
Tim Chevalier1680ccc2012-03-06 16:02:13151 };
152 add_to_index(ebml_w, path, index, ident);
153 encode_named_def_id(ebml_w, ident, local_def(id));
154 }
155 }
156 }
157}
158
Marijn Haverbekefb61b8f2012-03-06 11:52:13159fn encode_module_item_paths(ebml_w: ebml::writer, ecx: @encode_ctxt,
Michael Sullivan98e161f2012-06-29 23:26:56160 module: _mod, path: ~[ident],
161 &index: ~[entry<str>]) {
Brian Andersond1fc2b52012-06-30 23:19:07162 for module.items.each |it| {
Brian Andersonb4a3d522012-04-24 06:40:53163 if !reachable(ecx, it.id) ||
Graydon Hoarec26d0252012-07-09 21:37:48164 !ast_util::is_exported(it.ident, module) { again; }
Tim Chevalierc97b29a2012-05-18 03:37:17165 if !ast_util::is_item_impl(it) {
166 add_to_index(ebml_w, path, index, it.ident);
167 }
Marijn Haverbekedf7f21d2011-07-27 12:19:39168 alt it.node {
169 item_const(_, _) {
Niko Matsakis5d57fa32012-02-06 15:13:14170 encode_named_def_id(ebml_w, it.ident, local_def(it.id));
Marijn Haverbekedf7f21d2011-07-27 12:19:39171 }
Marijn Haverbeke0490c362011-12-22 16:49:54172 item_fn(_, tps, _) {
Niko Matsakis5d57fa32012-02-06 15:13:14173 encode_named_def_id(ebml_w, it.ident, local_def(it.id));
Marijn Haverbekedf7f21d2011-07-27 12:19:39174 }
175 item_mod(_mod) {
Ben Striegelf2e2a142012-07-04 19:04:28176 do ebml_w.wr_tag(tag_paths_data_mod) {
Tim Chevalierc97b29a2012-05-18 03:37:17177 encode_name_and_def_id(ebml_w, it.ident, it.id);
Michael Sullivan329eca62012-06-26 03:00:46178 encode_module_item_paths(ebml_w, ecx, _mod,
Eric Holk87eaf912012-06-28 22:00:03179 vec::append_one(path, it.ident),
Tim Chevalierc97b29a2012-05-18 03:37:17180 index);
181 }
Marijn Haverbekedf7f21d2011-07-27 12:19:39182 }
Graydon Hoare697f1e32012-06-26 23:18:37183 item_foreign_mod(nmod) {
Ben Striegelf2e2a142012-07-04 19:04:28184 do ebml_w.wr_tag(tag_paths_data_mod) {
Tim Chevalierc97b29a2012-05-18 03:37:17185 encode_name_and_def_id(ebml_w, it.ident, it.id);
Eric Holk87eaf912012-06-28 22:00:03186 encode_foreign_module_item_paths(
187 ebml_w, nmod,
188 vec::append_one(path, it.ident), index);
Tim Chevalierc97b29a2012-05-18 03:37:17189 }
Marijn Haverbekedf7f21d2011-07-27 12:19:39190 }
Niko Matsakisb9aa9de2012-07-11 17:28:30191 item_ty(_, tps) {
Ben Striegelf2e2a142012-07-04 19:04:28192 do ebml_w.wr_tag(tag_paths_data_item) {
Tim Chevalierc97b29a2012-05-18 03:37:17193 encode_name_and_def_id(ebml_w, it.ident, it.id);
194 }
Marijn Haverbekedf7f21d2011-07-27 12:19:39195 }
Niko Matsakisb9aa9de2012-07-11 17:28:30196 item_class(_, _, items, ctor, m_dtor) {
Ben Striegelf2e2a142012-07-04 19:04:28197 do ebml_w.wr_tag(tag_paths_data_item) {
Tim Chevalierc97b29a2012-05-18 03:37:17198 encode_name_and_def_id(ebml_w, it.ident, it.id);
199 }
Ben Striegelf2e2a142012-07-04 19:04:28200 do ebml_w.wr_tag(tag_paths) {
Tim Chevalierf1acc692012-06-25 23:49:14201 // We add the same ident twice: for the
Tim Chevalierc97b29a2012-05-18 03:37:17202 // class and for its ctor
203 add_to_index(ebml_w, path, index, it.ident);
204 encode_named_def_id(ebml_w, it.ident,
205 local_def(ctor.node.id));
Eric Holk87eaf912012-06-28 22:00:03206 encode_class_item_paths(ebml_w, items,
207 vec::append_one(path, it.ident),
Tim Chevalierc97b29a2012-05-18 03:37:17208 index);
209 }
Tim Chevalierf3343b32012-02-01 03:30:40210 }
Niko Matsakisb9aa9de2012-07-11 17:28:30211 item_enum(variants, _) {
Ben Striegelf2e2a142012-07-04 19:04:28212 do ebml_w.wr_tag(tag_paths_data_item) {
Tim Chevalierc97b29a2012-05-18 03:37:17213 encode_name_and_def_id(ebml_w, it.ident, it.id);
214 }
215 encode_enum_variant_paths(ebml_w, variants, path, index);
Marijn Haverbekedf7f21d2011-07-27 12:19:39216 }
Lindsey Kuper33334f32012-07-03 23:30:42217 item_trait(*) {
Ben Striegelf2e2a142012-07-04 19:04:28218 do ebml_w.wr_tag(tag_paths_data_item) {
Tim Chevalierc97b29a2012-05-18 03:37:17219 encode_name_and_def_id(ebml_w, it.ident, it.id);
220 }
Marijn Haverbeke057617c2011-12-20 15:33:55221 }
Niko Matsakis825fd182012-04-24 22:52:52222 item_impl(*) {}
Eric Holk05cdda32012-07-05 19:10:33223 item_mac(*) { fail "item macros unimplemented" }
Brian Anderson33294c72011-06-27 22:20:17224 }
225 }
226}
227
Lindsey Kuper33334f32012-07-03 23:30:42228fn encode_trait_ref(ebml_w: ebml::writer, ecx: @encode_ctxt, t: @trait_ref) {
229 ebml_w.start_tag(tag_impl_trait);
Tim Chevalier07a81ad2012-06-26 23:25:52230 encode_type(ecx, ebml_w, node_id_to_type(ecx.tcx, t.ref_id));
Tim Chevalier3d4ef742012-04-26 19:15:46231 ebml_w.end_tag();
232}
233
Haitao Li9bb290c2011-12-15 10:42:27234fn encode_item_paths(ebml_w: ebml::writer, ecx: @encode_ctxt, crate: @crate)
Michael Sullivan98e161f2012-06-29 23:26:56235 -> ~[entry<str>] {
236 let mut index: ~[entry<str>] = ~[];
237 let mut path: ~[ident] = ~[];
Niko Matsakisf3ca50c2012-02-14 23:21:53238 ebml_w.start_tag(tag_paths);
Marijn Haverbekefb61b8f2012-03-06 11:52:13239 encode_module_item_paths(ebml_w, ecx, crate.node.module, path, index);
Haitao Li9bb290c2011-12-15 10:42:27240 encode_reexport_paths(ebml_w, ecx, index);
Niko Matsakisf3ca50c2012-02-14 23:21:53241 ebml_w.end_tag();
Brian Anderson33294c72011-06-27 22:20:17242 ret index;
243}
244
Haitao Li9bb290c2011-12-15 10:42:27245fn encode_reexport_paths(ebml_w: ebml::writer,
Michael Sullivan98e161f2012-06-29 23:26:56246 ecx: @encode_ctxt, &index: ~[entry<str>]) {
Brian Andersond1fc2b52012-06-30 23:19:07247 for ecx.reexports.each |reexport| {
Brian Anderson6a41eb02012-05-17 04:50:17248 let (path, def_id) = reexport;
Eric Holkb9d3ad02012-06-26 07:39:18249 vec::push(index, {val: path, pos: ebml_w.writer.tell()});
Tim Chevalier271da612012-07-09 22:19:34250 // List metadata ignores tag_paths_foreign_path things, but
251 // other things look at it.
252 ebml_w.start_tag(tag_paths_foreign_path);
Brian Andersonce750a72012-06-10 07:49:59253 encode_name(ebml_w, @path);
Brian Anderson6a41eb02012-05-17 04:50:17254 encode_def_id(ebml_w, def_id);
255 ebml_w.end_tag();
Haitao Li9bb290c2011-12-15 10:42:27256 }
257}
258
Brian Anderson33294c72011-06-27 22:20:17259
260// Item info table encoding
Marijn Haverbeke72591492012-02-13 19:55:23261fn encode_family(ebml_w: ebml::writer, c: char) {
Niko Matsakisf3ca50c2012-02-14 23:21:53262 ebml_w.start_tag(tag_items_data_item_family);
Michael Sullivan98e161f2012-06-29 23:26:56263 ebml_w.writer.write(&[c as u8]);
Niko Matsakisf3ca50c2012-02-14 23:21:53264 ebml_w.end_tag();
Brian Anderson33294c72011-06-27 22:20:17265}
266
Marijn Haverbekefc6b7c82011-09-12 09:27:30267fn def_to_str(did: def_id) -> str { ret #fmt["%d:%d", did.crate, did.node]; }
Brian Anderson33294c72011-06-27 22:20:17268
Marijn Haverbeke1ed6a272011-12-28 16:50:12269fn encode_type_param_bounds(ebml_w: ebml::writer, ecx: @encode_ctxt,
Michael Sullivan98e161f2012-06-29 23:26:56270 params: ~[ty_param]) {
Brian Anderson452fc462012-05-15 03:41:33271 let ty_str_ctxt = @{diag: ecx.diag,
272 ds: def_to_str,
Brian Andersona2572fe2012-05-14 00:01:52273 tcx: ecx.tcx,
Brian Andersond1fc2b52012-06-30 23:19:07274 reachable: |a| reachable(ecx, a),
Marijn Haverbeke1ed6a272011-12-28 16:50:12275 abbrevs: tyencode::ac_use_abbrevs(ecx.type_abbrevs)};
Brian Andersond1fc2b52012-06-30 23:19:07276 for params.each |param| {
Niko Matsakisf3ca50c2012-02-14 23:21:53277 ebml_w.start_tag(tag_items_data_item_ty_param_bounds);
Brian Andersona2572fe2012-05-14 00:01:52278 let bs = ecx.tcx.ty_param_bounds.get(param.id);
Marijn Haverbeke34d7f052012-01-11 14:15:54279 tyencode::enc_bounds(ebml_w.writer, ty_str_ctxt, bs);
Niko Matsakisf3ca50c2012-02-14 23:21:53280 ebml_w.end_tag();
Graydon Hoare59c441a2011-07-29 23:40:23281 }
Brian Anderson33294c72011-06-27 22:20:17282}
283
Marijn Haverbekefc6b7c82011-09-12 09:27:30284fn encode_variant_id(ebml_w: ebml::writer, vid: def_id) {
Niko Matsakisf3ca50c2012-02-14 23:21:53285 ebml_w.start_tag(tag_items_data_item_variant);
Brian Andersonab6bb032011-09-02 00:27:58286 ebml_w.writer.write(str::bytes(def_to_str(vid)));
Niko Matsakisf3ca50c2012-02-14 23:21:53287 ebml_w.end_tag();
Brian Anderson33294c72011-06-27 22:20:17288}
289
Marijn Haverbeke6559aa82012-01-05 09:57:19290fn write_type(ecx: @encode_ctxt, ebml_w: ebml::writer, typ: ty::t) {
Marijn Haverbekedf7f21d2011-07-27 12:19:39291 let ty_str_ctxt =
Brian Anderson452fc462012-05-15 03:41:33292 @{diag: ecx.diag,
293 ds: def_to_str,
Brian Andersona2572fe2012-05-14 00:01:52294 tcx: ecx.tcx,
Brian Andersond1fc2b52012-06-30 23:19:07295 reachable: |a| reachable(ecx, a),
Marijn Haverbekedf7f21d2011-07-27 12:19:39296 abbrevs: tyencode::ac_use_abbrevs(ecx.type_abbrevs)};
Marijn Haverbeke34d7f052012-01-11 14:15:54297 tyencode::enc_ty(ebml_w.writer, ty_str_ctxt, typ);
Marijn Haverbeke6559aa82012-01-05 09:57:19298}
299
300fn encode_type(ecx: @encode_ctxt, ebml_w: ebml::writer, typ: ty::t) {
Niko Matsakisf3ca50c2012-02-14 23:21:53301 ebml_w.start_tag(tag_items_data_item_type);
Marijn Haverbeke6559aa82012-01-05 09:57:19302 write_type(ecx, ebml_w, typ);
Niko Matsakisf3ca50c2012-02-14 23:21:53303 ebml_w.end_tag();
Brian Anderson33294c72011-06-27 22:20:17304}
305
Marijn Haverbekefc6b7c82011-09-12 09:27:30306fn encode_symbol(ecx: @encode_ctxt, ebml_w: ebml::writer, id: node_id) {
Niko Matsakisf3ca50c2012-02-14 23:21:53307 ebml_w.start_tag(tag_items_data_item_symbol);
Brian Andersona2572fe2012-05-14 00:01:52308 let sym = alt ecx.item_symbols.find(id) {
Tim Chevalierb06dc882012-03-19 17:19:00309 some(x) { x }
Brian Anderson452fc462012-05-15 03:41:33310 none {
311 ecx.diag.handler().bug(
312 #fmt("encode_symbol: id not found %d", id));
313 }
Tim Chevalierb06dc882012-03-19 17:19:00314 };
315 ebml_w.writer.write(str::bytes(sym));
Niko Matsakisf3ca50c2012-02-14 23:21:53316 ebml_w.end_tag();
Brian Anderson33294c72011-06-27 22:20:17317}
318
Marijn Haverbekefc6b7c82011-09-12 09:27:30319fn encode_discriminant(ecx: @encode_ctxt, ebml_w: ebml::writer, id: node_id) {
Niko Matsakisf3ca50c2012-02-14 23:21:53320 ebml_w.start_tag(tag_items_data_item_symbol);
Brian Andersona2572fe2012-05-14 00:01:52321 ebml_w.writer.write(str::bytes(ecx.discrim_symbols.get(id)));
Niko Matsakisf3ca50c2012-02-14 23:21:53322 ebml_w.end_tag();
Brian Anderson33294c72011-06-27 22:20:17323}
324
Kevin Atkinson08abf8d2012-01-10 21:50:40325fn encode_disr_val(_ecx: @encode_ctxt, ebml_w: ebml::writer, disr_val: int) {
Niko Matsakisf3ca50c2012-02-14 23:21:53326 ebml_w.start_tag(tag_disr_val);
Kevin Atkinson08abf8d2012-01-10 21:50:40327 ebml_w.writer.write(str::bytes(int::to_str(disr_val,10u)));
Niko Matsakisf3ca50c2012-02-14 23:21:53328 ebml_w.end_tag();
Kevin Atkinson08abf8d2012-01-10 21:50:40329}
330
Marijn Haverbeke2c8c50d2012-03-08 22:13:57331fn encode_parent_item(ebml_w: ebml::writer, id: def_id) {
332 ebml_w.start_tag(tag_items_data_parent_item);
Brian Andersonab6bb032011-09-02 00:27:58333 ebml_w.writer.write(str::bytes(def_to_str(id)));
Niko Matsakisf3ca50c2012-02-14 23:21:53334 ebml_w.end_tag();
Brian Anderson33294c72011-06-27 22:20:17335}
336
Marijn Haverbeke76aabbe2012-01-25 13:34:31337fn encode_enum_variant_info(ecx: @encode_ctxt, ebml_w: ebml::writer,
Michael Sullivan98e161f2012-06-29 23:26:56338 id: node_id, variants: ~[variant],
339 path: ast_map::path, index: @mut ~[entry<int>],
340 ty_params: ~[ty_param]) {
Niko Matsakisb653a182012-03-15 13:47:03341 let mut disr_val = 0;
342 let mut i = 0;
Brian Andersona2572fe2012-05-14 00:01:52343 let vi = ty::enum_variants(ecx.tcx, {crate: local_crate, node: id});
Brian Andersond1fc2b52012-06-30 23:19:07344 for variants.each |variant| {
Eric Holkb9d3ad02012-06-26 07:39:18345 vec::push(*index, {val: variant.node.id, pos: ebml_w.writer.tell()});
Niko Matsakisf3ca50c2012-02-14 23:21:53346 ebml_w.start_tag(tag_items_data_item);
Brian Anderson33294c72011-06-27 22:20:17347 encode_def_id(ebml_w, local_def(variant.node.id));
Marijn Haverbeke72591492012-02-13 19:55:23348 encode_family(ebml_w, 'v');
Niko Matsakisa83ad1b2012-01-16 05:42:10349 encode_name(ebml_w, variant.node.name);
Marijn Haverbeke2c8c50d2012-03-08 22:13:57350 encode_parent_item(ebml_w, local_def(id));
Brian Andersond0a432f2011-07-08 06:55:41351 encode_type(ecx, ebml_w,
Brian Andersona2572fe2012-05-14 00:01:52352 node_id_to_type(ecx.tcx, variant.node.id));
Marijn Haverbeke168398b2012-03-08 12:30:22353 if vec::len(variant.node.args) > 0u && ty_params.len() == 0u {
Brian Andersond0a432f2011-07-08 06:55:41354 encode_symbol(ecx, ebml_w, variant.node.id);
Brian Anderson33294c72011-06-27 22:20:17355 }
Brian Andersond0a432f2011-07-08 06:55:41356 encode_discriminant(ecx, ebml_w, variant.node.id);
Kevin Atkinsone1c50c42012-01-16 09:36:47357 if vi[i].disr_val != disr_val {
358 encode_disr_val(ecx, ebml_w, vi[i].disr_val);
359 disr_val = vi[i].disr_val;
Kevin Atkinson08abf8d2012-01-10 21:50:40360 }
Marijn Haverbeke1ed6a272011-12-28 16:50:12361 encode_type_param_bounds(ebml_w, ecx, ty_params);
Niko Matsakisfdddf8f2012-02-10 14:01:32362 encode_path(ebml_w, path, ast_map::path_name(variant.node.name));
Niko Matsakisf3ca50c2012-02-14 23:21:53363 ebml_w.end_tag();
Kevin Atkinson08abf8d2012-01-10 21:50:40364 disr_val += 1;
Kevin Atkinsone1c50c42012-01-16 09:36:47365 i += 1;
Brian Anderson33294c72011-06-27 22:20:17366 }
367}
368
Niko Matsakisfdddf8f2012-02-10 14:01:32369fn encode_path(ebml_w: ebml::writer,
370 path: ast_map::path,
371 name: ast_map::path_elt) {
372 fn encode_path_elt(ebml_w: ebml::writer, elt: ast_map::path_elt) {
373 let (tag, name) = alt elt {
374 ast_map::path_mod(name) { (tag_path_elt_mod, name) }
375 ast_map::path_name(name) { (tag_path_elt_name, name) }
376 };
377
Brian Andersonce750a72012-06-10 07:49:59378 ebml_w.wr_tagged_str(tag, *name);
Niko Matsakisfdddf8f2012-02-10 14:01:32379 }
380
Ben Striegelf2e2a142012-07-04 19:04:28381 do ebml_w.wr_tag(tag_path) {
Niko Matsakisf3ca50c2012-02-14 23:21:53382 ebml_w.wr_tagged_u32(tag_path_len, (vec::len(path) + 1u) as u32);
Brian Andersond1fc2b52012-06-30 23:19:07383 do vec::iter(path) |pe| { encode_path_elt(ebml_w, pe); }
Niko Matsakisfdddf8f2012-02-10 14:01:32384 encode_path_elt(ebml_w, name);
385 }
386}
387
Marijn Haverbekec590bde2012-01-26 16:33:12388fn encode_info_for_mod(ecx: @encode_ctxt, ebml_w: ebml::writer, md: _mod,
Niko Matsakisfdddf8f2012-02-10 14:01:32389 id: node_id, path: ast_map::path, name: ident) {
Niko Matsakisf3ca50c2012-02-14 23:21:53390 ebml_w.start_tag(tag_items_data_item);
Marijn Haverbeke58a81a62011-12-16 13:41:12391 encode_def_id(ebml_w, local_def(id));
Marijn Haverbeke72591492012-02-13 19:55:23392 encode_family(ebml_w, 'm');
Haitao Libd300632011-12-19 19:30:23393 encode_name(ebml_w, name);
Patrick Waltonf093d372012-05-22 17:54:12394 #debug("(encoding info for module) encoding info for module ID %d", id);
Tim Chevalier07a81ad2012-06-26 23:25:52395 // the impl map contains ref_ids
Brian Anderson322b20d2012-05-17 05:28:01396 let impls = ecx.impl_map(id);
Brian Andersond1fc2b52012-06-30 23:19:07397 for impls.each |i| {
Brian Anderson322b20d2012-05-17 05:28:01398 let (ident, did) = i;
Patrick Waltonf093d372012-05-22 17:54:12399 #debug("(encoding info for module) ... encoding impl %s (%?), \
400 exported? %?",
401 *ident, did, ast_util::is_exported(ident, md));
Brian Anderson322b20d2012-05-17 05:28:01402 if ast_util::is_exported(ident, md) {
403 ebml_w.start_tag(tag_mod_impl);
Tim Chevaliere5a5fc22012-06-13 22:46:57404 alt ecx.tcx.items.find(did.node) {
405 some(ast_map::node_item(it@@{node: cl@item_class(*),_},_)) {
Lindsey Kuper33334f32012-07-03 23:30:42406 /* If did stands for a trait
Brian Anderson322b20d2012-05-17 05:28:01407 ref, we need to map it to its parent class */
Brian Anderson322b20d2012-05-17 05:28:01408 ebml_w.wr_str(def_to_str(local_def(it.id)));
Brian Anderson322b20d2012-05-17 05:28:01409 }
Niko Matsakisb9aa9de2012-07-11 17:28:30410 some(ast_map::node_item(@{node: item_impl(_,
Tim Chevaliere5a5fc22012-06-13 22:46:57411 some(ifce),_,_),_},_)) {
Brian Anderson322b20d2012-05-17 05:28:01412 ebml_w.wr_str(def_to_str(did));
Brian Anderson322b20d2012-05-17 05:28:01413 }
Tim Chevaliere5a5fc22012-06-13 22:46:57414 some(_) {
415 ebml_w.wr_str(def_to_str(did));
416 }
417 none {
418 // Must be a re-export, then!
Tim Chevalier07a81ad2012-06-26 23:25:52419 // ...or an iface ref
Brian Anderson239cf802012-05-20 02:09:02420 ebml_w.wr_str(def_to_str(did));
Brian Anderson322b20d2012-05-17 05:28:01421 }
422 };
423 ebml_w.end_tag();
424 } // if
425 } // for
426
Niko Matsakisfdddf8f2012-02-10 14:01:32427 encode_path(ebml_w, path, ast_map::path_mod(name));
Niko Matsakisf3ca50c2012-02-14 23:21:53428 ebml_w.end_tag();
Marijn Haverbeke58a81a62011-12-16 13:41:12429}
430
Marijn Haverbekeb6199542012-05-08 14:06:24431fn encode_visibility(ebml_w: ebml::writer, visibility: visibility) {
432 encode_family(ebml_w, alt visibility {
433 public { 'g' } private { 'j' }
434 });
Tim Chevalierc2828102012-03-26 16:59:59435}
436
Tim Chevalierb06dc882012-03-19 17:19:00437/* Returns an index of items in this class */
Tim Chevalier1680ccc2012-03-06 16:02:13438fn encode_info_for_class(ecx: @encode_ctxt, ebml_w: ebml::writer,
Tim Chevalier73a0c172012-03-23 01:03:12439 id: node_id, path: ast_map::path,
Michael Sullivan98e161f2012-06-29 23:26:56440 class_tps: ~[ty_param],
441 items: ~[@class_member],
442 global_index: @mut~[entry<int>]) -> ~[entry<int>] {
Tim Chevalierf1acc692012-06-25 23:49:14443 /* Each class has its own index, since different classes
444 may have fields with the same name */
Michael Sullivan98e161f2012-06-29 23:26:56445 let index = @mut ~[];
Brian Andersona2572fe2012-05-14 00:01:52446 let tcx = ecx.tcx;
Brian Andersond1fc2b52012-06-30 23:19:07447 for items.each |ci| {
Tim Chevalierb06dc882012-03-19 17:19:00448 /* We encode both private and public fields -- need to include
449 private fields to get the offsets right */
Tim Chevalierf7bbe532012-03-29 01:50:33450 alt ci.node {
Marijn Haverbekeb6199542012-05-08 14:06:24451 instance_var(nm, _, mt, id, vis) {
Eric Holkb9d3ad02012-06-26 07:39:18452 vec::push(*index, {val: id, pos: ebml_w.writer.tell()});
453 vec::push(*global_index, {val: id, pos: ebml_w.writer.tell()});
Tim Chevalierb06dc882012-03-19 17:19:00454 ebml_w.start_tag(tag_items_data_item);
Brian Andersonce750a72012-06-10 07:49:59455 #debug("encode_info_for_class: doing %s %d", *nm, id);
Marijn Haverbekeb6199542012-05-08 14:06:24456 encode_visibility(ebml_w, vis);
Tim Chevalierb06dc882012-03-19 17:19:00457 encode_name(ebml_w, nm);
458 encode_path(ebml_w, path, ast_map::path_name(nm));
459 encode_type(ecx, ebml_w, node_id_to_type(tcx, id));
Tim Chevalieredb747c2012-03-28 05:08:48460 encode_mutability(ebml_w, mt);
Tim Chevalierb06dc882012-03-19 17:19:00461 encode_def_id(ebml_w, local_def(id));
Tim Chevalier73a0c172012-03-23 01:03:12462 ebml_w.end_tag();
Tim Chevalierb06dc882012-03-19 17:19:00463 }
464 class_method(m) {
Marijn Haverbekeb6199542012-05-08 14:06:24465 alt m.vis {
466 public {
Eric Holkb9d3ad02012-06-26 07:39:18467 vec::push(*index, {val: m.id, pos: ebml_w.writer.tell()});
468 vec::push(*global_index,
469 {val: m.id, pos: ebml_w.writer.tell()});
Eric Holk87eaf912012-06-28 22:00:03470 let impl_path = vec::append_one(path,
471 ast_map::path_name(m.ident));
Brian Andersonce750a72012-06-10 07:49:59472 #debug("encode_info_for_class: doing %s %d", *m.ident, m.id);
Tim Chevalierf7bbe532012-03-29 01:50:33473 encode_info_for_method(ecx, ebml_w, impl_path,
Tim Chevalierfd267432012-04-10 17:52:06474 should_inline(m.attrs), id, m,
Eric Holk87eaf912012-06-28 22:00:03475 vec::append(class_tps, m.tps));
Tim Chevalierf7bbe532012-03-29 01:50:33476 }
477 _ { /* don't encode private methods */ }
478 }
Tim Chevalierb06dc882012-03-19 17:19:00479 }
480 }
Marijn Haverbekec902eaf2012-04-06 18:01:43481 };
Tim Chevalierb06dc882012-03-19 17:19:00482 *index
Tim Chevalier1680ccc2012-03-06 16:02:13483}
484
485fn encode_info_for_fn(ecx: @encode_ctxt, ebml_w: ebml::writer,
486 id: node_id, ident: ident, path: ast_map::path,
Michael Sullivan98e161f2012-06-29 23:26:56487 item: option<inlined_item>, tps: ~[ty_param],
Tim Chevalierfd267432012-04-10 17:52:06488 decl: fn_decl) {
Tim Chevalier1680ccc2012-03-06 16:02:13489 ebml_w.start_tag(tag_items_data_item);
Tim Chevalier73a0c172012-03-23 01:03:12490 encode_name(ebml_w, ident);
Tim Chevalier1680ccc2012-03-06 16:02:13491 encode_def_id(ebml_w, local_def(id));
492 encode_family(ebml_w, purity_fn_family(decl.purity));
493 encode_type_param_bounds(ebml_w, ecx, tps);
Brian Andersona2572fe2012-05-14 00:01:52494 let its_ty = node_id_to_type(ecx.tcx, id);
Brian Andersonce750a72012-06-10 07:49:59495 #debug("fn name = %s ty = %s its node id = %d", *ident,
Tim Chevalieraa9d2d82012-06-12 23:25:09496 util::ppaux::ty_to_str(ecx.tcx, its_ty), id);
Tim Chevalier1680ccc2012-03-06 16:02:13497 encode_type(ecx, ebml_w, its_ty);
498 encode_path(ebml_w, path, ast_map::path_name(ident));
499 alt item {
500 some(it) {
Brian Anderson5c864e92012-05-15 00:38:17501 ecx.encode_inlined_item(ecx, ebml_w, path, it);
Tim Chevalier1680ccc2012-03-06 16:02:13502 }
503 none {
504 encode_symbol(ecx, ebml_w, id);
505 }
506 }
507 ebml_w.end_tag();
508}
509
Tim Chevalierb06dc882012-03-19 17:19:00510fn encode_info_for_method(ecx: @encode_ctxt, ebml_w: ebml::writer,
511 impl_path: ast_map::path, should_inline: bool,
512 parent_id: node_id,
Michael Sullivan98e161f2012-06-29 23:26:56513 m: @method, all_tps: ~[ty_param]) {
Brian Andersonce750a72012-06-10 07:49:59514 #debug("encode_info_for_method: %d %s %u", m.id, *m.ident, all_tps.len());
Tim Chevalierb06dc882012-03-19 17:19:00515 ebml_w.start_tag(tag_items_data_item);
516 encode_def_id(ebml_w, local_def(m.id));
517 encode_family(ebml_w, purity_fn_family(m.decl.purity));
518 encode_type_param_bounds(ebml_w, ecx, all_tps);
Brian Andersona2572fe2012-05-14 00:01:52519 encode_type(ecx, ebml_w, node_id_to_type(ecx.tcx, m.id));
Tim Chevalierb06dc882012-03-19 17:19:00520 encode_name(ebml_w, m.ident);
521 encode_path(ebml_w, impl_path, ast_map::path_name(m.ident));
522 if all_tps.len() > 0u || should_inline {
Brian Anderson5c864e92012-05-15 00:38:17523 ecx.encode_inlined_item(
Tim Chevalierb06dc882012-03-19 17:19:00524 ecx, ebml_w, impl_path,
525 ii_method(local_def(parent_id), m));
526 } else {
527 encode_symbol(ecx, ebml_w, m.id);
528 }
529 ebml_w.end_tag();
530}
531
Marijn Haverbeke6c9d95a2012-02-13 17:56:09532fn purity_fn_family(p: purity) -> char {
Brian Anderson6943b382012-02-10 21:39:15533 alt p {
534 unsafe_fn { 'u' }
535 pure_fn { 'p' }
536 impure_fn { 'f' }
Josh Matthewsa7f6e002012-07-07 04:52:31537 extern_fn { 'F' }
Brian Anderson6943b382012-02-10 21:39:15538 }
Marijn Haverbeke6c9d95a2012-02-13 17:56:09539}
540
Tim Chevalierb06dc882012-03-19 17:19:00541
Michael Sullivan98e161f2012-06-29 23:26:56542fn should_inline(attrs: ~[attribute]) -> bool {
Tim Chevalierb06dc882012-03-19 17:19:00543 alt attr::find_inline_attr(attrs) {
544 attr::ia_none { false }
545 attr::ia_hint | attr::ia_always { true }
546 }
547}
548
549
Marijn Haverbekefc6b7c82011-09-12 09:27:30550fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item,
Michael Sullivan98e161f2012-06-29 23:26:56551 index: @mut ~[entry<int>], path: ast_map::path) {
Niko Matsakis0416a942012-03-02 21:14:10552
Brian Andersona2572fe2012-05-14 00:01:52553 let tcx = ecx.tcx;
Niko Matsakis3c995fb2012-04-19 04:26:25554 let must_write =
Niko Matsakisb9aa9de2012-07-11 17:28:30555 alt item.node { item_enum(_, _) { true } _ { false } };
Brian Andersonb4a3d522012-04-24 06:40:53556 if !must_write && !reachable(ecx, item.id) { ret; }
Tim Chevalier73a0c172012-03-23 01:03:12557
558 fn add_to_index_(item: @item, ebml_w: ebml::writer,
Michael Sullivan98e161f2012-06-29 23:26:56559 index: @mut ~[entry<int>]) {
Eric Holkb9d3ad02012-06-26 07:39:18560 vec::push(*index, {val: item.id, pos: ebml_w.writer.tell()});
Tim Chevalier73a0c172012-03-23 01:03:12561 }
Brian Andersond1fc2b52012-06-30 23:19:07562 let add_to_index = |copy ebml_w| add_to_index_(item, ebml_w, index);
Marijn Haverbekefb61b8f2012-03-06 11:52:13563
Marijn Haverbekedf7f21d2011-07-27 12:19:39564 alt item.node {
565 item_const(_, _) {
Tim Chevalier73a0c172012-03-23 01:03:12566 add_to_index();
Niko Matsakisf3ca50c2012-02-14 23:21:53567 ebml_w.start_tag(tag_items_data_item);
Marijn Haverbekedf7f21d2011-07-27 12:19:39568 encode_def_id(ebml_w, local_def(item.id));
Marijn Haverbeke72591492012-02-13 19:55:23569 encode_family(ebml_w, 'c');
Marijn Haverbeke86d473a2012-01-30 16:28:30570 encode_type(ecx, ebml_w, node_id_to_type(tcx, item.id));
Marijn Haverbekedf7f21d2011-07-27 12:19:39571 encode_symbol(ecx, ebml_w, item.id);
Niko Matsakisfdddf8f2012-02-10 14:01:32572 encode_path(ebml_w, path, ast_map::path_name(item.ident));
Niko Matsakisf3ca50c2012-02-14 23:21:53573 ebml_w.end_tag();
Marijn Haverbekedf7f21d2011-07-27 12:19:39574 }
Marijn Haverbeke0490c362011-12-22 16:49:54575 item_fn(decl, tps, _) {
Tim Chevalier73a0c172012-03-23 01:03:12576 add_to_index();
Niko Matsakisf3ca50c2012-02-14 23:21:53577 ebml_w.start_tag(tag_items_data_item);
Marijn Haverbekedf7f21d2011-07-27 12:19:39578 encode_def_id(ebml_w, local_def(item.id));
Marijn Haverbeke72591492012-02-13 19:55:23579 encode_family(ebml_w, purity_fn_family(decl.purity));
Marijn Haverbeke1ed6a272011-12-28 16:50:12580 encode_type_param_bounds(ebml_w, ecx, tps);
Marijn Haverbeke86d473a2012-01-30 16:28:30581 encode_type(ecx, ebml_w, node_id_to_type(tcx, item.id));
Niko Matsakisfdddf8f2012-02-10 14:01:32582 encode_path(ebml_w, path, ast_map::path_name(item.ident));
Marijn Haverbekec67679e2012-03-08 09:58:23583 if tps.len() > 0u || should_inline(item.attrs) {
Brian Anderson5c864e92012-05-15 00:38:17584 ecx.encode_inlined_item(ecx, ebml_w, path, ii_item(item));
Marijn Haverbeke168398b2012-03-08 12:30:22585 } else {
586 encode_symbol(ecx, ebml_w, item.id);
Niko Matsakisf3ca50c2012-02-14 23:21:53587 }
588 ebml_w.end_tag();
Marijn Haverbekedf7f21d2011-07-27 12:19:39589 }
Marijn Haverbeke0a362612011-12-16 13:17:52590 item_mod(m) {
Tim Chevalier73a0c172012-03-23 01:03:12591 add_to_index();
Niko Matsakisfdddf8f2012-02-10 14:01:32592 encode_info_for_mod(ecx, ebml_w, m, item.id, path, item.ident);
Marijn Haverbekedf7f21d2011-07-27 12:19:39593 }
Graydon Hoare697f1e32012-06-26 23:18:37594 item_foreign_mod(_) {
Tim Chevalier73a0c172012-03-23 01:03:12595 add_to_index();
Niko Matsakisf3ca50c2012-02-14 23:21:53596 ebml_w.start_tag(tag_items_data_item);
Marijn Haverbekedf7f21d2011-07-27 12:19:39597 encode_def_id(ebml_w, local_def(item.id));
Marijn Haverbeke72591492012-02-13 19:55:23598 encode_family(ebml_w, 'n');
Haitao Libd300632011-12-19 19:30:23599 encode_name(ebml_w, item.ident);
Niko Matsakisfdddf8f2012-02-10 14:01:32600 encode_path(ebml_w, path, ast_map::path_name(item.ident));
Niko Matsakisf3ca50c2012-02-14 23:21:53601 ebml_w.end_tag();
Marijn Haverbekedf7f21d2011-07-27 12:19:39602 }
Niko Matsakisb9aa9de2012-07-11 17:28:30603 item_ty(_, tps) {
Tim Chevalier73a0c172012-03-23 01:03:12604 add_to_index();
Niko Matsakisf3ca50c2012-02-14 23:21:53605 ebml_w.start_tag(tag_items_data_item);
Marijn Haverbekedf7f21d2011-07-27 12:19:39606 encode_def_id(ebml_w, local_def(item.id));
Marijn Haverbeke72591492012-02-13 19:55:23607 encode_family(ebml_w, 'y');
Marijn Haverbeke1ed6a272011-12-28 16:50:12608 encode_type_param_bounds(ebml_w, ecx, tps);
Marijn Haverbeke86d473a2012-01-30 16:28:30609 encode_type(ecx, ebml_w, node_id_to_type(tcx, item.id));
Marijn Haverbeke619d7c32011-12-19 12:52:58610 encode_name(ebml_w, item.ident);
Niko Matsakisfdddf8f2012-02-10 14:01:32611 encode_path(ebml_w, path, ast_map::path_name(item.ident));
Niko Matsakisb9aa9de2012-07-11 17:28:30612 encode_region_param(ecx, ebml_w, item);
Niko Matsakisf3ca50c2012-02-14 23:21:53613 ebml_w.end_tag();
Marijn Haverbekedf7f21d2011-07-27 12:19:39614 }
Niko Matsakisb9aa9de2012-07-11 17:28:30615 item_enum(variants, tps) {
Tim Chevalier73a0c172012-03-23 01:03:12616 add_to_index();
Ben Striegelf2e2a142012-07-04 19:04:28617 do ebml_w.wr_tag(tag_items_data_item) {
Niko Matsakis3c995fb2012-04-19 04:26:25618 encode_def_id(ebml_w, local_def(item.id));
619 encode_family(ebml_w, 't');
620 encode_type_param_bounds(ebml_w, ecx, tps);
621 encode_type(ecx, ebml_w, node_id_to_type(tcx, item.id));
622 encode_name(ebml_w, item.ident);
Brian Andersond1fc2b52012-06-30 23:19:07623 for variants.each |v| {
Niko Matsakis3c995fb2012-04-19 04:26:25624 encode_variant_id(ebml_w, local_def(v.node.id));
625 }
Brian Anderson5c864e92012-05-15 00:38:17626 ecx.encode_inlined_item(ecx, ebml_w, path, ii_item(item));
Niko Matsakis3c995fb2012-04-19 04:26:25627 encode_path(ebml_w, path, ast_map::path_name(item.ident));
Niko Matsakisb9aa9de2012-07-11 17:28:30628 encode_region_param(ecx, ebml_w, item);
Brian Anderson33294c72011-06-27 22:20:17629 }
Niko Matsakisfdddf8f2012-02-10 14:01:32630 encode_enum_variant_info(ecx, ebml_w, item.id, variants,
631 path, index, tps);
Marijn Haverbekedf7f21d2011-07-27 12:19:39632 }
Niko Matsakisb9aa9de2012-07-11 17:28:30633 item_class(tps, traits, items, ctor, m_dtor) {
Tim Chevalier73a0c172012-03-23 01:03:12634 /* First, encode the fields and methods
635 These come first because we need to write them to make
636 the index, and the index needs to be in the item for the
637 class itself */
Tim Chevalierfd267432012-04-10 17:52:06638 let idx = encode_info_for_class(ecx, ebml_w, item.id, path, tps,
639 items, index);
Tim Chevalieraa9d2d82012-06-12 23:25:09640 /* Encode the dtor */
Brian Andersond1fc2b52012-06-30 23:19:07641 do option::iter(m_dtor) |dtor| {
Eric Holkb9d3ad02012-06-26 07:39:18642 vec::push(*index, {val: dtor.node.id, pos: ebml_w.writer.tell()});
Brian Andersonce750a72012-06-10 07:49:59643 encode_info_for_fn(ecx, ebml_w, dtor.node.id, @(*item.ident
644 + "_dtor"), path, if tps.len() > 0u {
Tim Chevalieraa9d2d82012-06-12 23:25:09645 some(ii_dtor(dtor, item.ident, tps,
646 local_def(item.id))) }
647 else { none }, tps, ast_util::dtor_dec());
648 }
649
Tim Chevalier73a0c172012-03-23 01:03:12650 /* Index the class*/
651 add_to_index();
652 /* Now, make an item for the class itself */
Tim Chevalier16dd6c42012-03-17 02:19:37653 ebml_w.start_tag(tag_items_data_item);
Tim Chevalier73a0c172012-03-23 01:03:12654 encode_def_id(ebml_w, local_def(item.id));
655 encode_family(ebml_w, 'C');
656 encode_type_param_bounds(ebml_w, ecx, tps);
657 encode_type(ecx, ebml_w, node_id_to_type(tcx, item.id));
658 encode_name(ebml_w, item.ident);
659 encode_path(ebml_w, path, ast_map::path_name(item.ident));
Niko Matsakisb9aa9de2012-07-11 17:28:30660 encode_region_param(ecx, ebml_w, item);
Lindsey Kuper33334f32012-07-03 23:30:42661 for traits.each |t| {
662 encode_trait_ref(ebml_w, ecx, t);
Tim Chevalier3d4ef742012-04-26 19:15:46663 }
Tim Chevalieraa9d2d82012-06-12 23:25:09664 /* Encode the dtor */
665 /* Encode id for dtor */
Brian Andersond1fc2b52012-06-30 23:19:07666 do option::iter(m_dtor) |dtor| {
Ben Striegelf2e2a142012-07-04 19:04:28667 do ebml_w.wr_tag(tag_item_dtor) {
Tim Chevalieraa9d2d82012-06-12 23:25:09668 encode_def_id(ebml_w, local_def(dtor.node.id));
669 }
670 };
671
Tim Chevalier73a0c172012-03-23 01:03:12672 /* Encode def_ids for each field and method
Lindsey Kuper33334f32012-07-03 23:30:42673 for methods, write all the stuff get_trait_method
Tim Chevalier73a0c172012-03-23 01:03:12674 needs to know*/
675 let (fs,ms) = ast_util::split_class_items(items);
Brian Andersond1fc2b52012-06-30 23:19:07676 for fs.each |f| {
Tim Chevalier73a0c172012-03-23 01:03:12677 ebml_w.start_tag(tag_item_field);
Marijn Haverbekeb6199542012-05-08 14:06:24678 encode_visibility(ebml_w, f.vis);
Tim Chevalier73a0c172012-03-23 01:03:12679 encode_name(ebml_w, f.ident);
680 encode_def_id(ebml_w, local_def(f.id));
681 ebml_w.end_tag();
682 }
Brian Andersond1fc2b52012-06-30 23:19:07683 for ms.each |m| {
Marijn Haverbekeb6199542012-05-08 14:06:24684 alt m.vis {
685 private { /* do nothing */ }
686 public {
Tim Chevalier3d4ef742012-04-26 19:15:46687 /* Write the info that's needed when viewing this class
Lindsey Kuper33334f32012-07-03 23:30:42688 as a trait */
689 ebml_w.start_tag(tag_item_trait_method);
Tim Chevalierc2828102012-03-26 16:59:59690 encode_family(ebml_w, purity_fn_family(m.decl.purity));
691 encode_name(ebml_w, m.ident);
Niko Matsakis3c4baf62012-06-04 18:21:11692 encode_type_param_bounds(ebml_w, ecx, m.tps);
Tim Chevalierc2828102012-03-26 16:59:59693 encode_type(ecx, ebml_w, node_id_to_type(tcx, m.id));
694 encode_def_id(ebml_w, local_def(m.id));
695 ebml_w.end_tag();
Tim Chevalier3d4ef742012-04-26 19:15:46696 /* Write the info that's needed when viewing this class
697 as an impl (just the method def_id) */
698 ebml_w.start_tag(tag_item_impl_method);
699 ebml_w.writer.write(str::bytes(def_to_str(local_def(m.id))));
700 ebml_w.end_tag();
Tim Chevalierc2828102012-03-26 16:59:59701 }
702 }
Tim Chevalier73a0c172012-03-23 01:03:12703 }
704 /* Each class has its own index -- encode it */
Tim Chevalierb06dc882012-03-19 17:19:00705 let bkts = create_index(idx, hash_node_id);
706 encode_index(ebml_w, bkts, write_int);
Tim Chevalier16dd6c42012-03-17 02:19:37707 ebml_w.end_tag();
Tim Chevalierf3343b32012-02-01 03:30:40708 }
Niko Matsakisb9aa9de2012-07-11 17:28:30709 item_impl(tps, ifce, _, methods) {
Tim Chevalier73a0c172012-03-23 01:03:12710 add_to_index();
Niko Matsakisf3ca50c2012-02-14 23:21:53711 ebml_w.start_tag(tag_items_data_item);
Marijn Haverbeke0a362612011-12-16 13:17:52712 encode_def_id(ebml_w, local_def(item.id));
Marijn Haverbeke72591492012-02-13 19:55:23713 encode_family(ebml_w, 'i');
Niko Matsakisb9aa9de2012-07-11 17:28:30714 encode_region_param(ecx, ebml_w, item);
Marijn Haverbeke1ed6a272011-12-28 16:50:12715 encode_type_param_bounds(ebml_w, ecx, tps);
Marijn Haverbeke86d473a2012-01-30 16:28:30716 encode_type(ecx, ebml_w, node_id_to_type(tcx, item.id));
Marijn Haverbeke58a81a62011-12-16 13:41:12717 encode_name(ebml_w, item.ident);
Brian Andersond1fc2b52012-06-30 23:19:07718 for methods.each |m| {
Tim Chevalier3d4ef742012-04-26 19:15:46719 ebml_w.start_tag(tag_item_impl_method);
Marijn Haverbeke0490c362011-12-22 16:49:54720 ebml_w.writer.write(str::bytes(def_to_str(local_def(m.id))));
Niko Matsakisf3ca50c2012-02-14 23:21:53721 ebml_w.end_tag();
Marijn Haverbeke0a362612011-12-16 13:17:52722 }
Brian Andersond1fc2b52012-06-30 23:19:07723 do option::iter(ifce) |t| {
Lindsey Kuper33334f32012-07-03 23:30:42724 encode_trait_ref(ebml_w, ecx, t)
Tim Chevalier3d4ef742012-04-26 19:15:46725 };
Niko Matsakisfdddf8f2012-02-10 14:01:32726 encode_path(ebml_w, path, ast_map::path_name(item.ident));
Niko Matsakisf3ca50c2012-02-14 23:21:53727 ebml_w.end_tag();
Marijn Haverbeke0a362612011-12-16 13:17:52728
Eric Holk87eaf912012-06-28 22:00:03729 let impl_path = vec::append_one(path,
730 ast_map::path_name(item.ident));
Brian Andersond1fc2b52012-06-30 23:19:07731 for methods.each |m| {
Eric Holkb9d3ad02012-06-26 07:39:18732 vec::push(*index, {val: m.id, pos: ebml_w.writer.tell()});
Tim Chevalierb06dc882012-03-19 17:19:00733 encode_info_for_method(ecx, ebml_w, impl_path,
Eric Holk87eaf912012-06-28 22:00:03734 should_inline(m.attrs), item.id, m,
735 vec::append(tps, m.tps));
Marijn Haverbeke0a362612011-12-16 13:17:52736 }
737 }
Niko Matsakisb9aa9de2012-07-11 17:28:30738 item_trait(tps, ms) {
Tim Chevalier73a0c172012-03-23 01:03:12739 add_to_index();
Niko Matsakisf3ca50c2012-02-14 23:21:53740 ebml_w.start_tag(tag_items_data_item);
Marijn Haverbeke3a20dda2012-01-05 12:57:27741 encode_def_id(ebml_w, local_def(item.id));
Marijn Haverbeke72591492012-02-13 19:55:23742 encode_family(ebml_w, 'I');
Niko Matsakisb9aa9de2012-07-11 17:28:30743 encode_region_param(ecx, ebml_w, item);
Marijn Haverbeke3a20dda2012-01-05 12:57:27744 encode_type_param_bounds(ebml_w, ecx, tps);
Marijn Haverbeke86d473a2012-01-30 16:28:30745 encode_type(ecx, ebml_w, node_id_to_type(tcx, item.id));
Marijn Haverbeke3a20dda2012-01-05 12:57:27746 encode_name(ebml_w, item.ident);
Niko Matsakisb653a182012-03-15 13:47:03747 let mut i = 0u;
Lindsey Kuper33334f32012-07-03 23:30:42748 for vec::each(*ty::trait_methods(tcx, local_def(item.id))) |mty| {
Lindsey Kuperfc9c4c32012-07-10 20:44:20749 alt ms[i] {
750 required(ty_m) {
751 ebml_w.start_tag(tag_item_trait_method);
752 encode_name(ebml_w, mty.ident);
753 encode_type_param_bounds(ebml_w, ecx, ty_m.tps);
754 encode_type(ecx, ebml_w, ty::mk_fn(tcx, mty.fty));
755 encode_family(ebml_w, purity_fn_family(mty.purity));
756 ebml_w.end_tag();
757 }
758 provided(m) {
759 encode_info_for_method(ecx, ebml_w, path,
760 should_inline(m.attrs), item.id,
761 m, m.tps);
762 }
763 }
Marijn Haverbeke3a20dda2012-01-05 12:57:27764 i += 1u;
765 }
Niko Matsakisfdddf8f2012-02-10 14:01:32766 encode_path(ebml_w, path, ast_map::path_name(item.ident));
Niko Matsakisf3ca50c2012-02-14 23:21:53767 ebml_w.end_tag();
Marijn Haverbeke3a20dda2012-01-05 12:57:27768 }
Eric Holk05cdda32012-07-05 19:10:33769 item_mac(*) { fail "item macros unimplemented" }
Brian Anderson33294c72011-06-27 22:20:17770 }
771}
772
Graydon Hoare697f1e32012-06-26 23:18:37773fn encode_info_for_foreign_item(ecx: @encode_ctxt, ebml_w: ebml::writer,
774 nitem: @foreign_item,
Michael Sullivan98e161f2012-06-29 23:26:56775 index: @mut ~[entry<int>],
Graydon Hoare697f1e32012-06-26 23:18:37776 path: ast_map::path, abi: foreign_abi) {
Brian Andersonb4a3d522012-04-24 06:40:53777 if !reachable(ecx, nitem.id) { ret; }
Eric Holkb9d3ad02012-06-26 07:39:18778 vec::push(*index, {val: nitem.id, pos: ebml_w.writer.tell()});
Marijn Haverbekefe90c182012-03-08 22:37:45779
Niko Matsakisf3ca50c2012-02-14 23:21:53780 ebml_w.start_tag(tag_items_data_item);
Marijn Haverbekedf7f21d2011-07-27 12:19:39781 alt nitem.node {
Graydon Hoare697f1e32012-06-26 23:18:37782 foreign_item_fn(fn_decl, tps) {
Marijn Haverbekedf7f21d2011-07-27 12:19:39783 encode_def_id(ebml_w, local_def(nitem.id));
Marijn Haverbeke72591492012-02-13 19:55:23784 encode_family(ebml_w, purity_fn_family(fn_decl.purity));
Marijn Haverbeke1ed6a272011-12-28 16:50:12785 encode_type_param_bounds(ebml_w, ecx, tps);
Brian Andersona2572fe2012-05-14 00:01:52786 encode_type(ecx, ebml_w, node_id_to_type(ecx.tcx, nitem.id));
Graydon Hoare697f1e32012-06-26 23:18:37787 if abi == foreign_abi_rust_intrinsic {
Brian Anderson5c864e92012-05-15 00:38:17788 ecx.encode_inlined_item(ecx, ebml_w, path,
Graydon Hoare697f1e32012-06-26 23:18:37789 ii_foreign(nitem));
Marijn Haverbekeea2e3792012-03-21 14:42:20790 } else {
791 encode_symbol(ecx, ebml_w, nitem.id);
792 }
Niko Matsakisfdddf8f2012-02-10 14:01:32793 encode_path(ebml_w, path, ast_map::path_name(nitem.ident));
Marijn Haverbekedf7f21d2011-07-27 12:19:39794 }
Brian Anderson33294c72011-06-27 22:20:17795 }
Niko Matsakisf3ca50c2012-02-14 23:21:53796 ebml_w.end_tag();
Brian Anderson33294c72011-06-27 22:20:17797}
798
Marijn Haverbeke58a81a62011-12-16 13:41:12799fn encode_info_for_items(ecx: @encode_ctxt, ebml_w: ebml::writer,
Michael Sullivan98e161f2012-06-29 23:26:56800 crate: @crate) -> ~[entry<int>] {
801 let index = @mut ~[];
Niko Matsakisf3ca50c2012-02-14 23:21:53802 ebml_w.start_tag(tag_items_data);
Eric Holkb9d3ad02012-06-26 07:39:18803 vec::push(*index, {val: crate_node_id, pos: ebml_w.writer.tell()});
Marijn Haverbekefe90c182012-03-08 22:37:45804 encode_info_for_mod(ecx, ebml_w, crate.node.module,
Michael Sullivan98e161f2012-06-29 23:26:56805 crate_node_id, ~[], @"");
Marijn Haverbekefe90c182012-03-08 22:37:45806 visit::visit_crate(*crate, (), visit::mk_vt(@{
Brian Andersond1fc2b52012-06-30 23:19:07807 visit_expr: |_e, _cx, _v| { },
808 visit_item: |i, cx, v, copy ebml_w| {
Marijn Haverbekefe90c182012-03-08 22:37:45809 visit::visit_item(i, cx, v);
Brian Andersona2572fe2012-05-14 00:01:52810 alt check ecx.tcx.items.get(i.id) {
Marijn Haverbekeb6ad34b2012-03-09 12:35:20811 ast_map::node_item(_, pt) {
812 encode_info_for_item(ecx, ebml_w, i, index, *pt);
Tim Chevalier16dd6c42012-03-17 02:19:37813 /* encode ctor, then encode items */
814 alt i.node {
Niko Matsakisb9aa9de2012-07-11 17:28:30815 item_class(tps, _, _, ctor, m_dtor) {
Brian Andersonce750a72012-06-10 07:49:59816 #debug("encoding info for ctor %s %d", *i.ident,
Tim Chevalier16dd6c42012-03-17 02:19:37817 ctor.node.id);
Eric Holk87eaf912012-06-28 22:00:03818 vec::push(*index,
819 {val: ctor.node.id, pos: ebml_w.writer.tell()});
Tim Chevalier1680ccc2012-03-06 16:02:13820 encode_info_for_fn(ecx, ebml_w, ctor.node.id, i.ident,
Tim Chevalierfd267432012-04-10 17:52:06821 *pt, if tps.len() > 0u {
822 some(ii_ctor(ctor, i.ident, tps,
823 local_def(i.id))) }
Tim Chevalieraa9d2d82012-06-12 23:25:09824 else { none }, tps, ctor.node.dec);
Tim Chevalier16dd6c42012-03-17 02:19:37825 }
826 _ {}
Patrick Waltonba39e272012-03-21 02:06:04827 }
828 }
Tim Chevalier1680ccc2012-03-06 16:02:13829 }
Marijn Haverbekefe90c182012-03-08 22:37:45830 },
Brian Andersond1fc2b52012-06-30 23:19:07831 visit_foreign_item: |ni, cx, v, copy ebml_w| {
Graydon Hoare697f1e32012-06-26 23:18:37832 visit::visit_foreign_item(ni, cx, v);
Brian Andersona2572fe2012-05-14 00:01:52833 alt check ecx.tcx.items.get(ni.id) {
Graydon Hoare697f1e32012-06-26 23:18:37834 ast_map::node_foreign_item(_, abi, pt) {
835 encode_info_for_foreign_item(ecx, ebml_w, ni,
836 index, *pt, abi);
Marijn Haverbekeb6ad34b2012-03-09 12:35:20837 }
838 }
Marijn Haverbekefe90c182012-03-08 22:37:45839 }
840 with *visit::default_visitor()
841 }));
Niko Matsakisf3ca50c2012-02-14 23:21:53842 ebml_w.end_tag();
Marijn Haverbekefe90c182012-03-08 22:37:45843 ret *index;
Brian Anderson33294c72011-06-27 22:20:17844}
845
846
847// Path and definition ID indexing
848
Michael Sullivan98e161f2012-06-29 23:26:56849fn create_index<T: copy>(index: ~[entry<T>], hash_fn: fn@(T) -> uint) ->
850 ~[@~[entry<T>]] {
851 let mut buckets: ~[@mut ~[entry<T>]] = ~[];
Brian Andersond1fc2b52012-06-30 23:19:07852 for uint::range(0u, 256u) |_i| { vec::push(buckets, @mut ~[]); };
853 for index.each |elt| {
Marijn Haverbekedf7f21d2011-07-27 12:19:39854 let h = hash_fn(elt.val);
Michael Sullivan329eca62012-06-26 03:00:46855 vec::push(*buckets[h % 256u], elt);
Brian Anderson33294c72011-06-27 22:20:17856 }
Patrick Walton1a6419b2011-07-14 21:25:43857
Michael Sullivan98e161f2012-06-29 23:26:56858 let mut buckets_frozen = ~[];
Brian Andersond1fc2b52012-06-30 23:19:07859 for buckets.each |bucket| {
Michael Sullivan329eca62012-06-26 03:00:46860 vec::push(buckets_frozen, @*bucket);
Patrick Walton1a6419b2011-07-14 21:25:43861 }
862 ret buckets_frozen;
Brian Anderson33294c72011-06-27 22:20:17863}
864
Michael Sullivan98e161f2012-06-29 23:26:56865fn encode_index<T>(ebml_w: ebml::writer, buckets: ~[@~[entry<T>]],
Niko Matsakis5e13d192012-01-23 22:59:00866 write_fn: fn(io::writer, T)) {
Niko Matsakis3f3bfee2012-01-11 20:52:25867 let writer = ebml_w.writer;
Niko Matsakisf3ca50c2012-02-14 23:21:53868 ebml_w.start_tag(tag_index);
Michael Sullivan98e161f2012-06-29 23:26:56869 let mut bucket_locs: ~[uint] = ~[];
Niko Matsakisf3ca50c2012-02-14 23:21:53870 ebml_w.start_tag(tag_index_buckets);
Brian Andersond1fc2b52012-06-30 23:19:07871 for buckets.each |bucket| {
Eric Holkb9d3ad02012-06-26 07:39:18872 vec::push(bucket_locs, ebml_w.writer.tell());
Niko Matsakisf3ca50c2012-02-14 23:21:53873 ebml_w.start_tag(tag_index_buckets_bucket);
Brian Andersond1fc2b52012-06-30 23:19:07874 for vec::each(*bucket) |elt| {
Niko Matsakisf3ca50c2012-02-14 23:21:53875 ebml_w.start_tag(tag_index_buckets_bucket_elt);
Marijn Haverbekeaea53772011-07-26 12:06:02876 writer.write_be_uint(elt.pos, 4u);
877 write_fn(writer, elt.val);
Niko Matsakisf3ca50c2012-02-14 23:21:53878 ebml_w.end_tag();
Brian Anderson33294c72011-06-27 22:20:17879 }
Niko Matsakisf3ca50c2012-02-14 23:21:53880 ebml_w.end_tag();
Brian Anderson33294c72011-06-27 22:20:17881 }
Niko Matsakisf3ca50c2012-02-14 23:21:53882 ebml_w.end_tag();
883 ebml_w.start_tag(tag_index_table);
Brian Andersond1fc2b52012-06-30 23:19:07884 for bucket_locs.each |pos| { writer.write_be_uint(pos, 4u); }
Niko Matsakisf3ca50c2012-02-14 23:21:53885 ebml_w.end_tag();
886 ebml_w.end_tag();
Brian Anderson33294c72011-06-27 22:20:17887}
888
Marijn Haverbeke33167f72011-10-10 11:54:03889fn write_str(writer: io::writer, &&s: str) { writer.write_str(s); }
Brian Anderson33294c72011-06-27 22:20:17890
Marijn Haverbekef9fbd862011-10-06 10:26:12891fn write_int(writer: io::writer, &&n: int) {
Brian Anderson33294c72011-06-27 22:20:17892 writer.write_be_uint(n as uint, 4u);
893}
894
Marijn Haverbekefc6b7c82011-09-12 09:27:30895fn encode_meta_item(ebml_w: ebml::writer, mi: meta_item) {
Marijn Haverbekedf7f21d2011-07-27 12:19:39896 alt mi.node {
897 meta_word(name) {
Niko Matsakisf3ca50c2012-02-14 23:21:53898 ebml_w.start_tag(tag_meta_item_word);
899 ebml_w.start_tag(tag_meta_item_name);
Brian Andersonce750a72012-06-10 07:49:59900 ebml_w.writer.write(str::bytes(*name));
Niko Matsakisf3ca50c2012-02-14 23:21:53901 ebml_w.end_tag();
902 ebml_w.end_tag();
Marijn Haverbekedf7f21d2011-07-27 12:19:39903 }
904 meta_name_value(name, value) {
905 alt value.node {
Brian Anderson9c173f12011-09-02 05:08:59906 lit_str(value) {
Niko Matsakisf3ca50c2012-02-14 23:21:53907 ebml_w.start_tag(tag_meta_item_name_value);
908 ebml_w.start_tag(tag_meta_item_name);
Brian Andersonce750a72012-06-10 07:49:59909 ebml_w.writer.write(str::bytes(*name));
Niko Matsakisf3ca50c2012-02-14 23:21:53910 ebml_w.end_tag();
911 ebml_w.start_tag(tag_meta_item_value);
Brian Andersonce750a72012-06-10 07:49:59912 ebml_w.writer.write(str::bytes(*value));
Niko Matsakisf3ca50c2012-02-14 23:21:53913 ebml_w.end_tag();
914 ebml_w.end_tag();
Marijn Haverbekedf7f21d2011-07-27 12:19:39915 }
Tim Chevaliercf2fc2c2012-05-17 23:17:11916 _ {/* FIXME (#623): encode other variants */ }
Brian Andersonf53c4f72011-06-28 02:41:48917 }
Marijn Haverbekedf7f21d2011-07-27 12:19:39918 }
919 meta_list(name, items) {
Niko Matsakisf3ca50c2012-02-14 23:21:53920 ebml_w.start_tag(tag_meta_item_list);
921 ebml_w.start_tag(tag_meta_item_name);
Brian Andersonce750a72012-06-10 07:49:59922 ebml_w.writer.write(str::bytes(*name));
Niko Matsakisf3ca50c2012-02-14 23:21:53923 ebml_w.end_tag();
Brian Andersond1fc2b52012-06-30 23:19:07924 for items.each |inner_item| {
Marijn Haverbekedf7f21d2011-07-27 12:19:39925 encode_meta_item(ebml_w, *inner_item);
926 }
Niko Matsakisf3ca50c2012-02-14 23:21:53927 ebml_w.end_tag();
Marijn Haverbekedf7f21d2011-07-27 12:19:39928 }
Brian Andersonf53c4f72011-06-28 02:41:48929 }
Brian Andersonf53c4f72011-06-28 02:41:48930}
931
Michael Sullivan98e161f2012-06-29 23:26:56932fn encode_attributes(ebml_w: ebml::writer, attrs: ~[attribute]) {
Niko Matsakisf3ca50c2012-02-14 23:21:53933 ebml_w.start_tag(tag_attributes);
Brian Andersond1fc2b52012-06-30 23:19:07934 for attrs.each |attr| {
Niko Matsakisf3ca50c2012-02-14 23:21:53935 ebml_w.start_tag(tag_attribute);
Brian Andersonf53c4f72011-06-28 02:41:48936 encode_meta_item(ebml_w, attr.node.value);
Niko Matsakisf3ca50c2012-02-14 23:21:53937 ebml_w.end_tag();
Brian Anderson33294c72011-06-27 22:20:17938 }
Niko Matsakisf3ca50c2012-02-14 23:21:53939 ebml_w.end_tag();
Brian Andersonf53c4f72011-06-28 02:41:48940}
941
Graydon Hoarec796a8f2011-06-29 22:11:20942// So there's a special crate attribute called 'link' which defines the
943// metadata that Rust cares about for linking crates. This attribute requires
Brian Anderson70a28dc2011-07-01 00:03:08944// 'name' and 'vers' items, so if the user didn't provide them we will throw
Graydon Hoarec796a8f2011-06-29 22:11:20945// them in anyway with default values.
Michael Sullivan98e161f2012-06-29 23:26:56946fn synthesize_crate_attrs(ecx: @encode_ctxt, crate: @crate) -> ~[attribute] {
Brian Anderson29afe1a2011-06-29 21:17:23947
Michael Sullivan98e161f2012-06-29 23:26:56948 fn synthesize_link_attr(ecx: @encode_ctxt, items: ~[@meta_item]) ->
Marijn Haverbekedf7f21d2011-07-27 12:19:39949 attribute {
Brian Anderson29afe1a2011-06-29 21:17:23950
Brian Andersonce750a72012-06-10 07:49:59951 assert (*ecx.link_meta.name != "");
952 assert (*ecx.link_meta.vers != "");
Brian Anderson29afe1a2011-06-29 21:17:23953
Marijn Haverbekedf7f21d2011-07-27 12:19:39954 let name_item =
Brian Andersonce750a72012-06-10 07:49:59955 attr::mk_name_value_item_str(@"name", *ecx.link_meta.name);
Marijn Haverbekedf7f21d2011-07-27 12:19:39956 let vers_item =
Brian Andersonce750a72012-06-10 07:49:59957 attr::mk_name_value_item_str(@"vers", *ecx.link_meta.vers);
Brian Anderson29afe1a2011-06-29 21:17:23958
Marijn Haverbekedf7f21d2011-07-27 12:19:39959 let other_items =
960 {
Brian Andersonce750a72012-06-10 07:49:59961 let tmp = attr::remove_meta_items_by_name(items, @"name");
962 attr::remove_meta_items_by_name(tmp, @"vers")
Marijn Haverbekedf7f21d2011-07-27 12:19:39963 };
Brian Anderson29afe1a2011-06-29 21:17:23964
Michael Sullivan98e161f2012-06-29 23:26:56965 let meta_items = vec::append(~[name_item, vers_item], other_items);
Brian Andersonce750a72012-06-10 07:49:59966 let link_item = attr::mk_list_item(@"link", meta_items);
Brian Anderson29afe1a2011-06-29 21:17:23967
Brian Anderson70a28dc2011-07-01 00:03:08968 ret attr::mk_attr(link_item);
Brian Anderson29afe1a2011-06-29 21:17:23969 }
970
Michael Sullivan98e161f2012-06-29 23:26:56971 let mut attrs: ~[attribute] = ~[];
Niko Matsakisb653a182012-03-15 13:47:03972 let mut found_link_attr = false;
Brian Andersond1fc2b52012-06-30 23:19:07973 for crate.node.attrs.each |attr| {
Eric Holk87eaf912012-06-28 22:00:03974 vec::push(
975 attrs,
Brian Andersonce750a72012-06-10 07:49:59976 if *attr::get_attr_name(attr) != "link" {
Eric Holk87eaf912012-06-28 22:00:03977 attr
Marijn Haverbekedf7f21d2011-07-27 12:19:39978 } else {
979 alt attr.node.value.node {
980 meta_list(n, l) {
Marijn Haverbekefc6b7c82011-09-12 09:27:30981 found_link_attr = true;;
Eric Holk87eaf912012-06-28 22:00:03982 synthesize_link_attr(ecx, l)
Marijn Haverbekedf7f21d2011-07-27 12:19:39983 }
Eric Holk87eaf912012-06-28 22:00:03984 _ { attr }
Brian Anderson29afe1a2011-06-29 21:17:23985 }
Eric Holk87eaf912012-06-28 22:00:03986 });
Brian Anderson29afe1a2011-06-29 21:17:23987 }
988
Michael Sullivan98e161f2012-06-29 23:26:56989 if !found_link_attr { vec::push(attrs, synthesize_link_attr(ecx, ~[])); }
Brian Anderson29afe1a2011-06-29 21:17:23990
991 ret attrs;
992}
993
Marijn Haverbekefc6b7c82011-09-12 09:27:30994fn encode_crate_deps(ebml_w: ebml::writer, cstore: cstore::cstore) {
Brian Anderson30704392011-07-08 18:29:56995
Michael Sullivan98e161f2012-06-29 23:26:56996 fn get_ordered_deps(cstore: cstore::cstore) -> ~[decoder::crate_dep] {
Marijn Haverbekedf7f21d2011-07-27 12:19:39997 type hashkv = @{key: crate_num, val: cstore::crate_metadata};
Haitao Li5aa52202012-04-07 17:59:37998 type numdep = decoder::crate_dep;
Brian Anderson30704392011-07-08 18:29:56999
Haitao Li5aa52202012-04-07 17:59:371000 // Pull the cnums and name,vers,hash out of cstore
Michael Sullivan98e161f2012-06-29 23:26:561001 let mut deps: ~[mut numdep] = ~[mut];
Brian Andersond1fc2b52012-06-30 23:19:071002 do cstore::iter_crate_data(cstore) |key, val| {
Brian Andersonce750a72012-06-10 07:49:591003 let dep = {cnum: key, name: @val.name,
Haitao Li5aa52202012-04-07 17:59:371004 vers: decoder::get_crate_vers(val.data),
Brian Andersonce750a72012-06-10 07:49:591005 hash: decoder::get_crate_hash(val.data)};
Eric Holkb9d3ad02012-06-26 07:39:181006 vec::push(deps, dep);
Marijn Haverbeke4ebbbe52011-10-21 10:21:271007 };
Brian Anderson30704392011-07-08 18:29:561008
1009 // Sort by cnum
Haitao Li5aa52202012-04-07 17:59:371010 fn lteq(kv1: numdep, kv2: numdep) -> bool { kv1.cnum <= kv2.cnum }
1011 std::sort::quick_sort(lteq, deps);
Brian Anderson30704392011-07-08 18:29:561012
1013 // Sanity-check the crate numbers
Niko Matsakisb653a182012-03-15 13:47:031014 let mut expected_cnum = 1;
Brian Andersond1fc2b52012-06-30 23:19:071015 for deps.each |n| {
Haitao Li5aa52202012-04-07 17:59:371016 assert (n.cnum == expected_cnum);
Brian Anderson30704392011-07-08 18:29:561017 expected_cnum += 1;
1018 }
1019
Graydon Hoare6e6798c2012-03-27 01:35:181020 // mut -> immutable hack for vec::map
Haitao Li5aa52202012-04-07 17:59:371021 ret vec::slice(deps, 0u, vec::len(deps));
Brian Anderson30704392011-07-08 18:29:561022 }
1023
Haitao Li5aa52202012-04-07 17:59:371024 // We're just going to write a list of crate 'name-hash-version's, with
1025 // the assumption that they are numbered 1 to n.
Graydon Hoare312faf32012-06-21 23:44:101026 // FIXME (#2166): This is not nearly enough to support correct versioning
Brian Anderson30704392011-07-08 18:29:561027 // but is enough to get transitive crate dependencies working.
Niko Matsakisf3ca50c2012-02-14 23:21:531028 ebml_w.start_tag(tag_crate_deps);
Brian Andersond1fc2b52012-06-30 23:19:071029 for get_ordered_deps(cstore).each |dep| {
Haitao Li5aa52202012-04-07 17:59:371030 encode_crate_dep(ebml_w, dep);
Brian Anderson30704392011-07-08 18:29:561031 }
Niko Matsakisf3ca50c2012-02-14 23:21:531032 ebml_w.end_tag();
Brian Anderson30704392011-07-08 18:29:561033}
1034
Haitao Li5aa52202012-04-07 17:59:371035fn encode_crate_dep(ebml_w: ebml::writer, dep: decoder::crate_dep) {
1036 ebml_w.start_tag(tag_crate_dep);
1037 ebml_w.start_tag(tag_crate_dep_name);
Brian Andersonce750a72012-06-10 07:49:591038 ebml_w.writer.write(str::bytes(*dep.name));
Haitao Li5aa52202012-04-07 17:59:371039 ebml_w.end_tag();
1040 ebml_w.start_tag(tag_crate_dep_vers);
Brian Andersonce750a72012-06-10 07:49:591041 ebml_w.writer.write(str::bytes(*dep.vers));
Haitao Li5aa52202012-04-07 17:59:371042 ebml_w.end_tag();
1043 ebml_w.start_tag(tag_crate_dep_hash);
Brian Andersonce750a72012-06-10 07:49:591044 ebml_w.writer.write(str::bytes(*dep.hash));
Haitao Li5aa52202012-04-07 17:59:371045 ebml_w.end_tag();
1046 ebml_w.end_tag();
1047}
1048
Haitao Lif3c206c2011-12-11 15:23:381049fn encode_hash(ebml_w: ebml::writer, hash: str) {
Niko Matsakisf3ca50c2012-02-14 23:21:531050 ebml_w.start_tag(tag_crate_hash);
Haitao Lif3c206c2011-12-11 15:23:381051 ebml_w.writer.write(str::bytes(hash));
Niko Matsakisf3ca50c2012-02-14 23:21:531052 ebml_w.end_tag();
Haitao Lif3c206c2011-12-11 15:23:381053}
1054
Michael Sullivan98e161f2012-06-29 23:26:561055fn encode_metadata(parms: encode_parms, crate: @crate) -> ~[u8] {
Brian Anderson5c864e92012-05-15 00:38:171056 let ecx: @encode_ctxt = @encode_ctxt({
Brian Anderson452fc462012-05-15 03:41:331057 diag: parms.diag,
Brian Andersona2572fe2012-05-14 00:01:521058 tcx: parms.tcx,
1059 reachable: parms.reachable,
Brian Anderson6a41eb02012-05-17 04:50:171060 reexports: parms.reexports,
Brian Andersonfce6a472012-05-15 00:46:451061 impl_map: parms.impl_map,
Brian Andersona2572fe2012-05-14 00:01:521062 item_symbols: parms.item_symbols,
1063 discrim_symbols: parms.discrim_symbols,
1064 link_meta: parms.link_meta,
1065 cstore: parms.cstore,
Brian Anderson5c864e92012-05-15 00:38:171066 encode_inlined_item: parms.encode_inlined_item,
Brian Andersona2572fe2012-05-14 00:01:521067 type_abbrevs: ty::new_ty_hash()
Brian Anderson5c864e92012-05-15 00:38:171068 });
Brian Andersond0a432f2011-07-08 06:55:411069
Niko Matsakisb30cb8e2012-03-13 14:55:451070 let buf = io::mem_buffer();
Marijn Haverbeke34d7f052012-01-11 14:15:541071 let buf_w = io::mem_buffer_writer(buf);
Brian Andersoncd72b1f2012-03-12 22:52:301072 let ebml_w = ebml::writer(buf_w);
Brian Anderson33294c72011-06-27 22:20:171073
Brian Andersona2572fe2012-05-14 00:01:521074 encode_hash(ebml_w, ecx.link_meta.extras_hash);
Haitao Lif3c206c2011-12-11 15:23:381075
Marijn Haverbekedf7f21d2011-07-27 12:19:391076 let crate_attrs = synthesize_crate_attrs(ecx, crate);
Brian Anderson29afe1a2011-06-29 21:17:231077 encode_attributes(ebml_w, crate_attrs);
Brian Anderson30704392011-07-08 18:29:561078
Brian Andersona2572fe2012-05-14 00:01:521079 encode_crate_deps(ebml_w, ecx.cstore);
Brian Anderson30704392011-07-08 18:29:561080
Brian Anderson33294c72011-06-27 22:20:171081 // Encode and index the paths.
Niko Matsakisf3ca50c2012-02-14 23:21:531082 ebml_w.start_tag(tag_paths);
Haitao Li9bb290c2011-12-15 10:42:271083 let paths_index = encode_item_paths(ebml_w, ecx, crate);
Marijn Haverbekedf7f21d2011-07-27 12:19:391084 let paths_buckets = create_index(paths_index, hash_path);
Marijn Haverbekee949aab2011-07-25 13:07:481085 encode_index(ebml_w, paths_buckets, write_str);
Niko Matsakisf3ca50c2012-02-14 23:21:531086 ebml_w.end_tag();
Brian Anderson33294c72011-06-27 22:20:171087
Marijn Haverbeke34d7f052012-01-11 14:15:541088 // Encode and index the items.
Niko Matsakisf3ca50c2012-02-14 23:21:531089 ebml_w.start_tag(tag_items);
Marijn Haverbekefe90c182012-03-08 22:37:451090 let items_index = encode_info_for_items(ecx, ebml_w, crate);
Marijn Haverbekedf7f21d2011-07-27 12:19:391091 let items_buckets = create_index(items_index, hash_node_id);
Marijn Haverbekee949aab2011-07-25 13:07:481092 encode_index(ebml_w, items_buckets, write_int);
Niko Matsakisf3ca50c2012-02-14 23:21:531093 ebml_w.end_tag();
Marijn Haverbeke34d7f052012-01-11 14:15:541094
Brian Anderson33294c72011-06-27 22:20:171095 // Pad this, since something (LLVM, presumably) is cutting off the
Brian Anderson2e7e5882011-08-11 23:36:201096 // remaining % 4 bytes.
Michael Sullivan98e161f2012-06-29 23:26:561097 buf_w.write(&[0u8, 0u8, 0u8, 0u8]);
Kevin Cantu4d7c2972012-01-26 06:27:291098 io::mem_buffer_buf(buf)
Brian Anderson33294c72011-06-27 22:20:171099}
Brian Anderson894e2222011-06-28 02:16:161100
Brian Anderson7d26d1d2011-07-07 19:47:391101// Get the encoded string for a type
Marijn Haverbekefc6b7c82011-09-12 09:27:301102fn encoded_ty(tcx: ty::ctxt, t: ty::t) -> str {
Brian Anderson452fc462012-05-15 03:41:331103 let cx = @{diag: tcx.diag,
1104 ds: def_to_str,
Niko Matsakis042c5322012-03-23 03:06:011105 tcx: tcx,
Brian Andersond1fc2b52012-06-30 23:19:071106 reachable: |_id| false,
Niko Matsakis042c5322012-03-23 03:06:011107 abbrevs: tyencode::ac_no_abbrevs};
Niko Matsakisb30cb8e2012-03-13 14:55:451108 let buf = io::mem_buffer();
Marijn Haverbeke34d7f052012-01-11 14:15:541109 tyencode::enc_ty(io::mem_buffer_writer(buf), cx, t);
1110 ret io::mem_buffer_str(buf);
Brian Anderson7d26d1d2011-07-07 19:47:391111}
1112
Brian Anderson894e2222011-06-28 02:16:161113
1114// Local Variables:
1115// mode: rust
1116// fill-column: 78;
1117// indent-tabs-mode: nil
1118// c-basic-offset: 4
1119// buffer-file-coding-system: utf-8-unix
Brian Anderson894e2222011-06-28 02:16:161120// End: