blob: a1c996dccf1457ff199754c428fd10b04a18d1cf [file] [log] [blame]
Brian Anderson45efb1f2011-06-27 23:03:011// Metadata encoding
2
Graydon Hoare6f5853f2012-03-13 03:04:273import std::{ebml, map, list};
Patrick Waltonc9375fe2012-03-08 00:48:574import std::map::hashmap;
Marijn Haverbeke34d7f052012-01-11 14:15:545import io::writer_util;
Niko Matsakisf3ca50c2012-02-14 23:21:536import ebml::writer;
Marijn Haverbeke6fd6fde2011-07-05 09:48:197import syntax::ast::*;
Niko Matsakisf3ca50c2012-02-14 23:21:538import syntax::print::pprust;
Marijn Haverbekefe90c182012-03-08 22:37:459import syntax::{ast_util, visit};
Brian Anderson152cbaa2011-08-22 04:44:4110import syntax::ast_util::local_def;
Brian Andersone29ef1b2011-07-07 19:22:3911import common::*;
Marijn Haverbeke03e9dac2012-01-27 12:17:0612import middle::trans::common::crate_ctxt;
Brian Anderson33294c72011-06-27 22:20:1713import middle::ty;
Marijn Haverbeke86d473a2012-01-30 16:28:3014import middle::ty::node_id_to_type;
Niko Matsakisfdddf8f2012-02-10 14:01:3215import middle::ast_map;
Brian Anderson0e870392012-03-23 01:16:2216import syntax::attr;
Tim Chevalierfba35e12012-01-31 05:00:5717import driver::session::session;
Niko Matsakisf3ca50c2012-02-14 23:21:5318import std::serialization::serializer;
Niko Matsakis3c995fb2012-04-19 04:26:2519import std::ebml::serializer;
Brian Anderson33294c72011-06-27 22:20:1720
Brian Anderson33294c72011-06-27 22:20:1721export encode_metadata;
Brian Anderson6ee1ffe2011-07-07 19:56:0122export encoded_ty;
Brian Andersonb4a3d522012-04-24 06:40:5323export reachable;
Brian Anderson33294c72011-06-27 22:20:1724
Niko Matsakisf3ca50c2012-02-14 23:21:5325// used by astencode:
26export def_to_str;
27export encode_ctxt;
28export write_type;
29export encode_def_id;
30
Erick Tryzelaare4a0f992011-08-12 14:15:1831type abbrev_map = map::hashmap<ty::t, tyencode::ty_abbrev>;
Brian Andersond0a432f2011-07-08 06:55:4132
Patrick Walton273c5e52012-03-15 00:31:1633type encode_ctxt = {ccx: @crate_ctxt,
Marijn Haverbekeade12072012-03-20 11:28:4634 type_abbrevs: abbrev_map};
Brian Andersond0a432f2011-07-08 06:55:4135
Brian Andersonb4a3d522012-04-24 06:40:5336fn reachable(ecx: @encode_ctxt, id: node_id) -> bool {
37 ecx.ccx.reachable.contains_key(id)
38}
39
Brian Anderson33294c72011-06-27 22:20:1740// Path table encoding
Marijn Haverbekefc6b7c82011-09-12 09:27:3041fn encode_name(ebml_w: ebml::writer, name: str) {
Niko Matsakisf3ca50c2012-02-14 23:21:5342 ebml_w.wr_tagged_str(tag_paths_data_name, name);
Brian Anderson33294c72011-06-27 22:20:1743}
44
Marijn Haverbekefc6b7c82011-09-12 09:27:3045fn encode_def_id(ebml_w: ebml::writer, id: def_id) {
Niko Matsakisf3ca50c2012-02-14 23:21:5346 ebml_w.wr_tagged_str(tag_def_id, def_to_str(id));
Niko Matsakis5d57fa32012-02-06 15:13:1447}
48
Niko Matsakis3c995fb2012-04-19 04:26:2549fn encode_region_param(ebml_w: ebml::writer, rp: region_param) {
50 ebml_w.wr_tag(tag_region_param) {||
51 serialize_region_param(ebml_w, rp)
52 }
53}
54
Niko Matsakis5d57fa32012-02-06 15:13:1455fn encode_named_def_id(ebml_w: ebml::writer, name: str, id: def_id) {
56 ebml_w.wr_tag(tag_paths_data_item) {||
57 encode_name(ebml_w, name);
58 encode_def_id(ebml_w, id);
59 }
Brian Anderson33294c72011-06-27 22:20:1760}
61
Tim Chevalieredb747c2012-03-28 05:08:4862fn encode_mutability(ebml_w: ebml::writer, mt: class_mutability) {
63 ebml_w.wr_tag(tag_class_mut) {||
64 ebml_w.writer.write([alt mt { class_immutable { 'i' }
Graydon Hoare753b6832012-04-26 00:18:0665 class_mutable { 'm' } } as u8]/&);
Tim Chevalieredb747c2012-03-28 05:08:4866 }
67}
68
Erick Tryzelaar4abc4712011-08-12 13:36:5169type entry<T> = {val: T, pos: uint};
Marijn Haverbekeaea53772011-07-26 12:06:0270
Marijn Haverbeke76aabbe2012-01-25 13:34:3171fn encode_enum_variant_paths(ebml_w: ebml::writer, variants: [variant],
Marijn Haverbekeca1df2b2011-09-12 10:39:3872 path: [str], &index: [entry<str>]) {
Marijn Haverbekec902eaf2012-04-06 18:01:4373 for variants.each {|variant|
Brian Anderson03119fe2011-08-26 00:00:1274 add_to_index(ebml_w, path, index, variant.node.name);
Niko Matsakis5d57fa32012-02-06 15:13:1475 ebml_w.wr_tag(tag_paths_data_item) {||
76 encode_name(ebml_w, variant.node.name);
77 encode_def_id(ebml_w, local_def(variant.node.id));
78 }
Brian Anderson33294c72011-06-27 22:20:1779 }
80}
81
Marijn Haverbekeca1df2b2011-09-12 10:39:3882fn add_to_index(ebml_w: ebml::writer, path: [str], &index: [entry<str>],
83 name: str) {
Brian Anderson518dc522011-08-19 22:16:4884 let full_path = path + [name];
Marijn Haverbekedf7f21d2011-07-27 12:19:3985 index +=
Brian Anderson5c49e4f2011-09-02 22:34:5886 [{val: str::connect(full_path, "::"), pos: ebml_w.writer.tell()}];
Brian Anderson33294c72011-06-27 22:20:1787}
88
Marijn Haverbekefc6b7c82011-09-12 09:27:3089fn encode_native_module_item_paths(ebml_w: ebml::writer, nmod: native_mod,
Marijn Haverbekeca1df2b2011-09-12 10:39:3890 path: [str], &index: [entry<str>]) {
Marijn Haverbekec902eaf2012-04-06 18:01:4391 for nmod.items.each {|nitem|
Brian Anderson03119fe2011-08-26 00:00:1292 add_to_index(ebml_w, path, index, nitem.ident);
Niko Matsakis5d57fa32012-02-06 15:13:1493 encode_named_def_id(ebml_w, nitem.ident, local_def(nitem.id));
Brian Anderson33294c72011-06-27 22:20:1794 }
95}
96
Tim Chevalier1680ccc2012-03-06 16:02:1397fn encode_class_item_paths(ebml_w: ebml::writer,
Tim Chevalierf7bbe532012-03-29 01:50:3398 items: [@class_member], path: [str], &index: [entry<str>]) {
Marijn Haverbekec902eaf2012-04-06 18:01:4399 for items.each {|it|
Tim Chevalierf7bbe532012-03-29 01:50:33100 alt ast_util::class_member_privacy(it) {
Tim Chevalier1680ccc2012-03-06 16:02:13101 priv { cont; }
102 pub {
Tim Chevalierf7bbe532012-03-29 01:50:33103 let (id, ident) = alt it.node {
104 instance_var(v, _, _, vid, _) { (vid, v) }
Tim Chevalierb06dc882012-03-19 17:19:00105 class_method(it) { (it.id, it.ident) }
Tim Chevalier1680ccc2012-03-06 16:02:13106 };
107 add_to_index(ebml_w, path, index, ident);
108 encode_named_def_id(ebml_w, ident, local_def(id));
109 }
110 }
111 }
112}
113
Marijn Haverbekefb61b8f2012-03-06 11:52:13114fn encode_module_item_paths(ebml_w: ebml::writer, ecx: @encode_ctxt,
115 module: _mod, path: [str], &index: [entry<str>]) {
Marijn Haverbeke057617c2011-12-20 15:33:55116 // FIXME factor out add_to_index/start/encode_name/encode_def_id/end ops
Marijn Haverbekec902eaf2012-04-06 18:01:43117 for module.items.each {|it|
Brian Andersonb4a3d522012-04-24 06:40:53118 if !reachable(ecx, it.id) ||
Marijn Haverbekec67679e2012-03-08 09:58:23119 !ast_util::is_exported(it.ident, module) { cont; }
Marijn Haverbekedf7f21d2011-07-27 12:19:39120 alt it.node {
121 item_const(_, _) {
Brian Anderson03119fe2011-08-26 00:00:12122 add_to_index(ebml_w, path, index, it.ident);
Niko Matsakis5d57fa32012-02-06 15:13:14123 encode_named_def_id(ebml_w, it.ident, local_def(it.id));
Marijn Haverbekedf7f21d2011-07-27 12:19:39124 }
Marijn Haverbeke0490c362011-12-22 16:49:54125 item_fn(_, tps, _) {
Brian Anderson03119fe2011-08-26 00:00:12126 add_to_index(ebml_w, path, index, it.ident);
Niko Matsakis5d57fa32012-02-06 15:13:14127 encode_named_def_id(ebml_w, it.ident, local_def(it.id));
Marijn Haverbekedf7f21d2011-07-27 12:19:39128 }
129 item_mod(_mod) {
Brian Anderson03119fe2011-08-26 00:00:12130 add_to_index(ebml_w, path, index, it.ident);
Niko Matsakisf3ca50c2012-02-14 23:21:53131 ebml_w.start_tag(tag_paths_data_mod);
Brian Anderson03119fe2011-08-26 00:00:12132 encode_name(ebml_w, it.ident);
Marijn Haverbekedf7f21d2011-07-27 12:19:39133 encode_def_id(ebml_w, local_def(it.id));
Marijn Haverbekefb61b8f2012-03-06 11:52:13134 encode_module_item_paths(ebml_w, ecx, _mod, path + [it.ident],
135 index);
Niko Matsakisf3ca50c2012-02-14 23:21:53136 ebml_w.end_tag();
Marijn Haverbekedf7f21d2011-07-27 12:19:39137 }
138 item_native_mod(nmod) {
Brian Anderson03119fe2011-08-26 00:00:12139 add_to_index(ebml_w, path, index, it.ident);
Niko Matsakisf3ca50c2012-02-14 23:21:53140 ebml_w.start_tag(tag_paths_data_mod);
Brian Anderson03119fe2011-08-26 00:00:12141 encode_name(ebml_w, it.ident);
Marijn Haverbekedf7f21d2011-07-27 12:19:39142 encode_def_id(ebml_w, local_def(it.id));
Brian Anderson5c49e4f2011-09-02 22:34:58143 encode_native_module_item_paths(ebml_w, nmod, path + [it.ident],
144 index);
Niko Matsakisf3ca50c2012-02-14 23:21:53145 ebml_w.end_tag();
Marijn Haverbekedf7f21d2011-07-27 12:19:39146 }
Niko Matsakis3c995fb2012-04-19 04:26:25147 item_ty(_, tps, _) {
Brian Anderson03119fe2011-08-26 00:00:12148 add_to_index(ebml_w, path, index, it.ident);
Niko Matsakisf3ca50c2012-02-14 23:21:53149 ebml_w.start_tag(tag_paths_data_item);
Brian Anderson03119fe2011-08-26 00:00:12150 encode_name(ebml_w, it.ident);
Marijn Haverbekedf7f21d2011-07-27 12:19:39151 encode_def_id(ebml_w, local_def(it.id));
Niko Matsakisf3ca50c2012-02-14 23:21:53152 ebml_w.end_tag();
Marijn Haverbekedf7f21d2011-07-27 12:19:39153 }
Niko Matsakis3c995fb2012-04-19 04:26:25154 item_res(_, tps, _, _, ctor_id, _) {
Brian Anderson03119fe2011-08-26 00:00:12155 add_to_index(ebml_w, path, index, it.ident);
Niko Matsakisf3ca50c2012-02-14 23:21:53156 ebml_w.start_tag(tag_paths_data_item);
Brian Anderson03119fe2011-08-26 00:00:12157 encode_name(ebml_w, it.ident);
Marijn Haverbekedf7f21d2011-07-27 12:19:39158 encode_def_id(ebml_w, local_def(ctor_id));
Niko Matsakisf3ca50c2012-02-14 23:21:53159 ebml_w.end_tag();
Brian Anderson03119fe2011-08-26 00:00:12160 add_to_index(ebml_w, path, index, it.ident);
Niko Matsakisf3ca50c2012-02-14 23:21:53161 ebml_w.start_tag(tag_paths_data_item);
Brian Anderson03119fe2011-08-26 00:00:12162 encode_name(ebml_w, it.ident);
Marijn Haverbekedf7f21d2011-07-27 12:19:39163 encode_def_id(ebml_w, local_def(it.id));
Niko Matsakisf3ca50c2012-02-14 23:21:53164 ebml_w.end_tag();
Marijn Haverbekedf7f21d2011-07-27 12:19:39165 }
Niko Matsakis3c995fb2012-04-19 04:26:25166 item_class(_, _, items, ctor, _) {
Tim Chevalierb06dc882012-03-19 17:19:00167 add_to_index(ebml_w, path, index, it.ident);
168 ebml_w.start_tag(tag_paths_data_item);
169 encode_name(ebml_w, it.ident);
170 encode_def_id(ebml_w, local_def(it.id));
171 ebml_w.end_tag();
172 ebml_w.start_tag(tag_paths);
173 add_to_index(ebml_w, path, index, it.ident);
174 #debug("ctor id: %d", ctor.node.id);
175 encode_named_def_id(ebml_w, it.ident, local_def(ctor.node.id));
176 encode_class_item_paths(ebml_w, items, path + [it.ident],
Tim Chevalier1680ccc2012-03-06 16:02:13177 index);
Tim Chevalierb06dc882012-03-19 17:19:00178 ebml_w.end_tag();
Tim Chevalierf3343b32012-02-01 03:30:40179 }
Niko Matsakis3c995fb2012-04-19 04:26:25180 item_enum(variants, _, _) {
Brian Anderson03119fe2011-08-26 00:00:12181 add_to_index(ebml_w, path, index, it.ident);
Niko Matsakisf3ca50c2012-02-14 23:21:53182 ebml_w.start_tag(tag_paths_data_item);
Brian Anderson03119fe2011-08-26 00:00:12183 encode_name(ebml_w, it.ident);
Marijn Haverbekedf7f21d2011-07-27 12:19:39184 encode_def_id(ebml_w, local_def(it.id));
Niko Matsakisf3ca50c2012-02-14 23:21:53185 ebml_w.end_tag();
Marijn Haverbeke76aabbe2012-01-25 13:34:31186 encode_enum_variant_paths(ebml_w, variants, path, index);
Marijn Haverbekedf7f21d2011-07-27 12:19:39187 }
Niko Matsakis825fd182012-04-24 22:52:52188 item_iface(*) {
Marijn Haverbeke057617c2011-12-20 15:33:55189 add_to_index(ebml_w, path, index, it.ident);
Niko Matsakisf3ca50c2012-02-14 23:21:53190 ebml_w.start_tag(tag_paths_data_item);
Marijn Haverbeke057617c2011-12-20 15:33:55191 encode_name(ebml_w, it.ident);
192 encode_def_id(ebml_w, local_def(it.id));
Niko Matsakisf3ca50c2012-02-14 23:21:53193 ebml_w.end_tag();
Marijn Haverbeke057617c2011-12-20 15:33:55194 }
Niko Matsakis825fd182012-04-24 22:52:52195 item_impl(*) {}
Brian Anderson33294c72011-06-27 22:20:17196 }
197 }
198}
199
Haitao Li9bb290c2011-12-15 10:42:27200fn encode_item_paths(ebml_w: ebml::writer, ecx: @encode_ctxt, crate: @crate)
201 -> [entry<str>] {
Niko Matsakisb653a182012-03-15 13:47:03202 let mut index: [entry<str>] = [];
203 let mut path: [str] = [];
Niko Matsakisf3ca50c2012-02-14 23:21:53204 ebml_w.start_tag(tag_paths);
Marijn Haverbekefb61b8f2012-03-06 11:52:13205 encode_module_item_paths(ebml_w, ecx, crate.node.module, path, index);
Haitao Li9bb290c2011-12-15 10:42:27206 encode_reexport_paths(ebml_w, ecx, index);
Niko Matsakisf3ca50c2012-02-14 23:21:53207 ebml_w.end_tag();
Brian Anderson33294c72011-06-27 22:20:17208 ret index;
209}
210
Haitao Li9bb290c2011-12-15 10:42:27211fn encode_reexport_paths(ebml_w: ebml::writer,
212 ecx: @encode_ctxt, &index: [entry<str>]) {
Marijn Haverbeke4e4bd582012-03-06 12:57:07213 let tcx = ecx.ccx.tcx;
Marijn Haverbeke9053f542012-04-23 11:42:15214 for ecx.ccx.exp_map.each {|exp_id, defs|
Marijn Haverbekec902eaf2012-04-06 18:01:43215 for defs.each {|def|
Marijn Haverbeke4e4bd582012-03-06 12:57:07216 if !def.reexp { cont; }
217 let path = alt check tcx.items.get(exp_id) {
218 ast_map::node_export(_, path) { ast_map::path_to_str(*path) }
219 };
Marijn Haverbekec590bde2012-01-26 16:33:12220 index += [{val: path, pos: ebml_w.writer.tell()}];
Niko Matsakisf3ca50c2012-02-14 23:21:53221 ebml_w.start_tag(tag_paths_data_item);
Marijn Haverbekec590bde2012-01-26 16:33:12222 encode_name(ebml_w, path);
Marijn Haverbeke4e4bd582012-03-06 12:57:07223 encode_def_id(ebml_w, def.id);
Niko Matsakisf3ca50c2012-02-14 23:21:53224 ebml_w.end_tag();
Marijn Haverbekec590bde2012-01-26 16:33:12225 }
Haitao Li9bb290c2011-12-15 10:42:27226 }
227}
228
Brian Anderson33294c72011-06-27 22:20:17229
230// Item info table encoding
Marijn Haverbeke72591492012-02-13 19:55:23231fn encode_family(ebml_w: ebml::writer, c: char) {
Niko Matsakisf3ca50c2012-02-14 23:21:53232 ebml_w.start_tag(tag_items_data_item_family);
Graydon Hoare753b6832012-04-26 00:18:06233 ebml_w.writer.write([c as u8]/&);
Niko Matsakisf3ca50c2012-02-14 23:21:53234 ebml_w.end_tag();
Brian Anderson33294c72011-06-27 22:20:17235}
236
Marijn Haverbekefc6b7c82011-09-12 09:27:30237fn def_to_str(did: def_id) -> str { ret #fmt["%d:%d", did.crate, did.node]; }
Brian Anderson33294c72011-06-27 22:20:17238
Marijn Haverbeke1ed6a272011-12-28 16:50:12239fn encode_type_param_bounds(ebml_w: ebml::writer, ecx: @encode_ctxt,
240 params: [ty_param]) {
241 let ty_str_ctxt = @{ds: def_to_str,
242 tcx: ecx.ccx.tcx,
Brian Andersonb4a3d522012-04-24 06:40:53243 reachable: reachable(ecx, _),
Marijn Haverbeke1ed6a272011-12-28 16:50:12244 abbrevs: tyencode::ac_use_abbrevs(ecx.type_abbrevs)};
Marijn Haverbekec902eaf2012-04-06 18:01:43245 for params.each {|param|
Niko Matsakisf3ca50c2012-02-14 23:21:53246 ebml_w.start_tag(tag_items_data_item_ty_param_bounds);
Marijn Haverbeke3a1710d2012-01-02 11:13:26247 let bs = ecx.ccx.tcx.ty_param_bounds.get(param.id);
Marijn Haverbeke34d7f052012-01-11 14:15:54248 tyencode::enc_bounds(ebml_w.writer, ty_str_ctxt, bs);
Niko Matsakisf3ca50c2012-02-14 23:21:53249 ebml_w.end_tag();
Graydon Hoare59c441a2011-07-29 23:40:23250 }
Brian Anderson33294c72011-06-27 22:20:17251}
252
Marijn Haverbekefc6b7c82011-09-12 09:27:30253fn encode_variant_id(ebml_w: ebml::writer, vid: def_id) {
Niko Matsakisf3ca50c2012-02-14 23:21:53254 ebml_w.start_tag(tag_items_data_item_variant);
Brian Andersonab6bb032011-09-02 00:27:58255 ebml_w.writer.write(str::bytes(def_to_str(vid)));
Niko Matsakisf3ca50c2012-02-14 23:21:53256 ebml_w.end_tag();
Brian Anderson33294c72011-06-27 22:20:17257}
258
Marijn Haverbeke6559aa82012-01-05 09:57:19259fn write_type(ecx: @encode_ctxt, ebml_w: ebml::writer, typ: ty::t) {
Marijn Haverbekedf7f21d2011-07-27 12:19:39260 let ty_str_ctxt =
Marijn Haverbeke1ed6a272011-12-28 16:50:12261 @{ds: def_to_str,
Marijn Haverbekedf7f21d2011-07-27 12:19:39262 tcx: ecx.ccx.tcx,
Brian Andersonb4a3d522012-04-24 06:40:53263 reachable: reachable(ecx, _),
Marijn Haverbekedf7f21d2011-07-27 12:19:39264 abbrevs: tyencode::ac_use_abbrevs(ecx.type_abbrevs)};
Marijn Haverbeke34d7f052012-01-11 14:15:54265 tyencode::enc_ty(ebml_w.writer, ty_str_ctxt, typ);
Marijn Haverbeke6559aa82012-01-05 09:57:19266}
267
268fn encode_type(ecx: @encode_ctxt, ebml_w: ebml::writer, typ: ty::t) {
Niko Matsakisf3ca50c2012-02-14 23:21:53269 ebml_w.start_tag(tag_items_data_item_type);
Marijn Haverbeke6559aa82012-01-05 09:57:19270 write_type(ecx, ebml_w, typ);
Niko Matsakisf3ca50c2012-02-14 23:21:53271 ebml_w.end_tag();
Brian Anderson33294c72011-06-27 22:20:17272}
273
Marijn Haverbekefc6b7c82011-09-12 09:27:30274fn encode_symbol(ecx: @encode_ctxt, ebml_w: ebml::writer, id: node_id) {
Niko Matsakisf3ca50c2012-02-14 23:21:53275 ebml_w.start_tag(tag_items_data_item_symbol);
Tim Chevalierb06dc882012-03-19 17:19:00276 let sym = alt ecx.ccx.item_symbols.find(id) {
277 some(x) { x }
278 none { ecx.ccx.tcx.sess.bug(#fmt("encode_symbol: \
279 id not found %d", id)); }
280 };
281 ebml_w.writer.write(str::bytes(sym));
Niko Matsakisf3ca50c2012-02-14 23:21:53282 ebml_w.end_tag();
Brian Anderson33294c72011-06-27 22:20:17283}
284
Marijn Haverbekefc6b7c82011-09-12 09:27:30285fn encode_discriminant(ecx: @encode_ctxt, ebml_w: ebml::writer, id: node_id) {
Niko Matsakisf3ca50c2012-02-14 23:21:53286 ebml_w.start_tag(tag_items_data_item_symbol);
Brian Andersonab6bb032011-09-02 00:27:58287 ebml_w.writer.write(str::bytes(ecx.ccx.discrim_symbols.get(id)));
Niko Matsakisf3ca50c2012-02-14 23:21:53288 ebml_w.end_tag();
Brian Anderson33294c72011-06-27 22:20:17289}
290
Kevin Atkinson08abf8d2012-01-10 21:50:40291fn encode_disr_val(_ecx: @encode_ctxt, ebml_w: ebml::writer, disr_val: int) {
Niko Matsakisf3ca50c2012-02-14 23:21:53292 ebml_w.start_tag(tag_disr_val);
Kevin Atkinson08abf8d2012-01-10 21:50:40293 ebml_w.writer.write(str::bytes(int::to_str(disr_val,10u)));
Niko Matsakisf3ca50c2012-02-14 23:21:53294 ebml_w.end_tag();
Kevin Atkinson08abf8d2012-01-10 21:50:40295}
296
Marijn Haverbeke2c8c50d2012-03-08 22:13:57297fn encode_parent_item(ebml_w: ebml::writer, id: def_id) {
298 ebml_w.start_tag(tag_items_data_parent_item);
Brian Andersonab6bb032011-09-02 00:27:58299 ebml_w.writer.write(str::bytes(def_to_str(id)));
Niko Matsakisf3ca50c2012-02-14 23:21:53300 ebml_w.end_tag();
Brian Anderson33294c72011-06-27 22:20:17301}
302
Marijn Haverbeke76aabbe2012-01-25 13:34:31303fn encode_enum_variant_info(ecx: @encode_ctxt, ebml_w: ebml::writer,
Niko Matsakisfdddf8f2012-02-10 14:01:32304 id: node_id, variants: [variant],
Graydon Hoare6e6798c2012-03-27 01:35:18305 path: ast_map::path, index: @mut [entry<int>],
Niko Matsakisfdddf8f2012-02-10 14:01:32306 ty_params: [ty_param]) {
Niko Matsakisb653a182012-03-15 13:47:03307 let mut disr_val = 0;
308 let mut i = 0;
Marijn Haverbeke76aabbe2012-01-25 13:34:31309 let vi = ty::enum_variants(ecx.ccx.tcx, {crate: local_crate, node: id});
Marijn Haverbekec902eaf2012-04-06 18:01:43310 for variants.each {|variant|
Marijn Haverbekefe90c182012-03-08 22:37:45311 *index += [{val: variant.node.id, pos: ebml_w.writer.tell()}];
Niko Matsakisf3ca50c2012-02-14 23:21:53312 ebml_w.start_tag(tag_items_data_item);
Brian Anderson33294c72011-06-27 22:20:17313 encode_def_id(ebml_w, local_def(variant.node.id));
Marijn Haverbeke72591492012-02-13 19:55:23314 encode_family(ebml_w, 'v');
Niko Matsakisa83ad1b2012-01-16 05:42:10315 encode_name(ebml_w, variant.node.name);
Marijn Haverbeke2c8c50d2012-03-08 22:13:57316 encode_parent_item(ebml_w, local_def(id));
Brian Andersond0a432f2011-07-08 06:55:41317 encode_type(ecx, ebml_w,
Marijn Haverbeke86d473a2012-01-30 16:28:30318 node_id_to_type(ecx.ccx.tcx, variant.node.id));
Marijn Haverbeke168398b2012-03-08 12:30:22319 if vec::len(variant.node.args) > 0u && ty_params.len() == 0u {
Brian Andersond0a432f2011-07-08 06:55:41320 encode_symbol(ecx, ebml_w, variant.node.id);
Brian Anderson33294c72011-06-27 22:20:17321 }
Brian Andersond0a432f2011-07-08 06:55:41322 encode_discriminant(ecx, ebml_w, variant.node.id);
Kevin Atkinsone1c50c42012-01-16 09:36:47323 if vi[i].disr_val != disr_val {
324 encode_disr_val(ecx, ebml_w, vi[i].disr_val);
325 disr_val = vi[i].disr_val;
Kevin Atkinson08abf8d2012-01-10 21:50:40326 }
Marijn Haverbeke1ed6a272011-12-28 16:50:12327 encode_type_param_bounds(ebml_w, ecx, ty_params);
Niko Matsakisfdddf8f2012-02-10 14:01:32328 encode_path(ebml_w, path, ast_map::path_name(variant.node.name));
Niko Matsakisf3ca50c2012-02-14 23:21:53329 ebml_w.end_tag();
Kevin Atkinson08abf8d2012-01-10 21:50:40330 disr_val += 1;
Kevin Atkinsone1c50c42012-01-16 09:36:47331 i += 1;
Brian Anderson33294c72011-06-27 22:20:17332 }
333}
334
Niko Matsakisfdddf8f2012-02-10 14:01:32335fn encode_path(ebml_w: ebml::writer,
336 path: ast_map::path,
337 name: ast_map::path_elt) {
338 fn encode_path_elt(ebml_w: ebml::writer, elt: ast_map::path_elt) {
339 let (tag, name) = alt elt {
340 ast_map::path_mod(name) { (tag_path_elt_mod, name) }
341 ast_map::path_name(name) { (tag_path_elt_name, name) }
342 };
343
Niko Matsakisf3ca50c2012-02-14 23:21:53344 ebml_w.wr_tagged_str(tag, name);
Niko Matsakisfdddf8f2012-02-10 14:01:32345 }
346
347 ebml_w.wr_tag(tag_path) {||
Niko Matsakisf3ca50c2012-02-14 23:21:53348 ebml_w.wr_tagged_u32(tag_path_len, (vec::len(path) + 1u) as u32);
Niko Matsakisfdddf8f2012-02-10 14:01:32349 vec::iter(path) {|pe| encode_path_elt(ebml_w, pe); }
350 encode_path_elt(ebml_w, name);
351 }
352}
353
Marijn Haverbekec590bde2012-01-26 16:33:12354fn encode_info_for_mod(ecx: @encode_ctxt, ebml_w: ebml::writer, md: _mod,
Niko Matsakisfdddf8f2012-02-10 14:01:32355 id: node_id, path: ast_map::path, name: ident) {
Niko Matsakisf3ca50c2012-02-14 23:21:53356 ebml_w.start_tag(tag_items_data_item);
Marijn Haverbeke58a81a62011-12-16 13:41:12357 encode_def_id(ebml_w, local_def(id));
Marijn Haverbeke72591492012-02-13 19:55:23358 encode_family(ebml_w, 'm');
Haitao Libd300632011-12-19 19:30:23359 encode_name(ebml_w, name);
Niko Matsakisf3ca50c2012-02-14 23:21:53360 alt ecx.ccx.maps.impl_map.get(id) {
Marijn Haverbekec590bde2012-01-26 16:33:12361 list::cons(impls, @list::nil) {
Marijn Haverbekec902eaf2012-04-06 18:01:43362 for vec::each(*impls) {|i|
Marijn Haverbeke58a81a62011-12-16 13:41:12363 if ast_util::is_exported(i.ident, md) {
Niko Matsakisf3ca50c2012-02-14 23:21:53364 ebml_w.wr_tagged_str(tag_mod_impl, def_to_str(i.did));
Marijn Haverbeke58a81a62011-12-16 13:41:12365 }
Marijn Haverbeke58a81a62011-12-16 13:41:12366 }
Marijn Haverbekec590bde2012-01-26 16:33:12367 }
Tim Chevalier1680ccc2012-03-06 16:02:13368 _ { ecx.ccx.tcx.sess.bug(#fmt("encode_info_for_mod: empty impl_map \
369 entry for %?", path)); }
Marijn Haverbeke58a81a62011-12-16 13:41:12370 }
Niko Matsakisfdddf8f2012-02-10 14:01:32371 encode_path(ebml_w, path, ast_map::path_mod(name));
Niko Matsakisf3ca50c2012-02-14 23:21:53372 ebml_w.end_tag();
Marijn Haverbeke58a81a62011-12-16 13:41:12373}
374
Tim Chevalierc2828102012-03-26 16:59:59375fn encode_privacy(ebml_w: ebml::writer, privacy: privacy) {
376 encode_family(ebml_w, alt privacy {
377 pub { 'g' } priv { 'j' }});
378}
379
Tim Chevalierb06dc882012-03-19 17:19:00380/* Returns an index of items in this class */
Tim Chevalier1680ccc2012-03-06 16:02:13381fn encode_info_for_class(ecx: @encode_ctxt, ebml_w: ebml::writer,
Tim Chevalier73a0c172012-03-23 01:03:12382 id: node_id, path: ast_map::path,
Tim Chevalierfd267432012-04-10 17:52:06383 class_tps: [ty_param],
Tim Chevalierf7bbe532012-03-29 01:50:33384 items: [@class_member],
Graydon Hoare6e6798c2012-03-27 01:35:18385 global_index: @mut[entry<int>])
Tim Chevalierb06dc882012-03-19 17:19:00386 -> [entry<int>] {
Graydon Hoare6e6798c2012-03-27 01:35:18387 let index = @mut [];
Tim Chevalier1680ccc2012-03-06 16:02:13388 let tcx = ecx.ccx.tcx;
Marijn Haverbekec902eaf2012-04-06 18:01:43389 for items.each {|ci|
Tim Chevalierb06dc882012-03-19 17:19:00390 /* We encode both private and public fields -- need to include
391 private fields to get the offsets right */
Tim Chevalierf7bbe532012-03-29 01:50:33392 alt ci.node {
393 instance_var(nm, _, mt, id, pr) {
Tim Chevalierb06dc882012-03-19 17:19:00394 *index += [{val: id, pos: ebml_w.writer.tell()}];
395 ebml_w.start_tag(tag_items_data_item);
396 #debug("encode_info_for_class: doing %s %d", nm, id);
Tim Chevalierf7bbe532012-03-29 01:50:33397 encode_privacy(ebml_w, pr);
Tim Chevalierb06dc882012-03-19 17:19:00398 encode_name(ebml_w, nm);
399 encode_path(ebml_w, path, ast_map::path_name(nm));
400 encode_type(ecx, ebml_w, node_id_to_type(tcx, id));
Tim Chevalieredb747c2012-03-28 05:08:48401 encode_mutability(ebml_w, mt);
Tim Chevalierb06dc882012-03-19 17:19:00402 encode_def_id(ebml_w, local_def(id));
Tim Chevalier73a0c172012-03-23 01:03:12403 ebml_w.end_tag();
Tim Chevalierb06dc882012-03-19 17:19:00404 }
405 class_method(m) {
Tim Chevalierf7bbe532012-03-29 01:50:33406 alt m.privacy {
407 pub {
408 *index += [{val: m.id, pos: ebml_w.writer.tell()}];
409 /* Not sure whether we really need to have two indices,
410 but it works for now -- tjc */
411 *global_index += [{val: m.id, pos: ebml_w.writer.tell()}];
412 let impl_path = path + [ast_map::path_name(m.ident)];
Tim Chevalierf7bbe532012-03-29 01:50:33413 #debug("encode_info_for_class: doing %s %d", m.ident, m.id);
414 encode_info_for_method(ecx, ebml_w, impl_path,
Tim Chevalierfd267432012-04-10 17:52:06415 should_inline(m.attrs), id, m,
416 class_tps + m.tps);
Tim Chevalierf7bbe532012-03-29 01:50:33417 }
418 _ { /* don't encode private methods */ }
419 }
Tim Chevalierb06dc882012-03-19 17:19:00420 }
421 }
Marijn Haverbekec902eaf2012-04-06 18:01:43422 };
Tim Chevalierb06dc882012-03-19 17:19:00423 *index
Tim Chevalier1680ccc2012-03-06 16:02:13424}
425
426fn encode_info_for_fn(ecx: @encode_ctxt, ebml_w: ebml::writer,
427 id: node_id, ident: ident, path: ast_map::path,
Tim Chevalierfd267432012-04-10 17:52:06428 item: option<inlined_item>, tps: [ty_param],
429 decl: fn_decl) {
Tim Chevalier1680ccc2012-03-06 16:02:13430 ebml_w.start_tag(tag_items_data_item);
Tim Chevalier73a0c172012-03-23 01:03:12431 encode_name(ebml_w, ident);
Tim Chevalier1680ccc2012-03-06 16:02:13432 encode_def_id(ebml_w, local_def(id));
433 encode_family(ebml_w, purity_fn_family(decl.purity));
434 encode_type_param_bounds(ebml_w, ecx, tps);
435 let its_ty = node_id_to_type(ecx.ccx.tcx, id);
436 #debug("fn name = %s ty = %s", ident,
437 util::ppaux::ty_to_str(ecx.ccx.tcx, its_ty));
438 encode_type(ecx, ebml_w, its_ty);
439 encode_path(ebml_w, path, ast_map::path_name(ident));
440 alt item {
441 some(it) {
Tim Chevalierfd267432012-04-10 17:52:06442 astencode::encode_inlined_item(ecx, ebml_w, path, it);
Tim Chevalier1680ccc2012-03-06 16:02:13443 }
444 none {
445 encode_symbol(ecx, ebml_w, id);
446 }
447 }
448 ebml_w.end_tag();
449}
450
Tim Chevalierb06dc882012-03-19 17:19:00451fn encode_info_for_method(ecx: @encode_ctxt, ebml_w: ebml::writer,
452 impl_path: ast_map::path, should_inline: bool,
453 parent_id: node_id,
454 m: @method, all_tps: [ty_param]) {
Tim Chevalierfd267432012-04-10 17:52:06455 #debug("encode_info_for_method: %d %s %u", m.id, m.ident, all_tps.len());
Tim Chevalierb06dc882012-03-19 17:19:00456 ebml_w.start_tag(tag_items_data_item);
457 encode_def_id(ebml_w, local_def(m.id));
458 encode_family(ebml_w, purity_fn_family(m.decl.purity));
459 encode_type_param_bounds(ebml_w, ecx, all_tps);
460 encode_type(ecx, ebml_w, node_id_to_type(ecx.ccx.tcx, m.id));
461 encode_name(ebml_w, m.ident);
462 encode_path(ebml_w, impl_path, ast_map::path_name(m.ident));
463 if all_tps.len() > 0u || should_inline {
464 astencode::encode_inlined_item(
465 ecx, ebml_w, impl_path,
466 ii_method(local_def(parent_id), m));
467 } else {
468 encode_symbol(ecx, ebml_w, m.id);
469 }
470 ebml_w.end_tag();
471}
472
Marijn Haverbeke6c9d95a2012-02-13 17:56:09473fn purity_fn_family(p: purity) -> char {
Brian Anderson6943b382012-02-10 21:39:15474 alt p {
475 unsafe_fn { 'u' }
476 pure_fn { 'p' }
477 impure_fn { 'f' }
478 crust_fn { 'c' }
479 }
Marijn Haverbeke6c9d95a2012-02-13 17:56:09480}
481
Tim Chevalierb06dc882012-03-19 17:19:00482
483fn should_inline(attrs: [attribute]) -> bool {
484 alt attr::find_inline_attr(attrs) {
485 attr::ia_none { false }
486 attr::ia_hint | attr::ia_always { true }
487 }
488}
489
490
Marijn Haverbekefc6b7c82011-09-12 09:27:30491fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item,
Graydon Hoare6e6798c2012-03-27 01:35:18492 index: @mut [entry<int>], path: ast_map::path) {
Niko Matsakis0416a942012-03-02 21:14:10493
Marijn Haverbeke3a20dda2012-01-05 12:57:27494 let tcx = ecx.ccx.tcx;
Niko Matsakis3c995fb2012-04-19 04:26:25495 let must_write =
496 alt item.node { item_enum(_, _, _) { true } _ { false } };
Brian Andersonb4a3d522012-04-24 06:40:53497 if !must_write && !reachable(ecx, item.id) { ret; }
Tim Chevalier73a0c172012-03-23 01:03:12498
499 fn add_to_index_(item: @item, ebml_w: ebml::writer,
Graydon Hoare6e6798c2012-03-27 01:35:18500 index: @mut [entry<int>]) {
Tim Chevalier73a0c172012-03-23 01:03:12501 *index += [{val: item.id, pos: ebml_w.writer.tell()}];
502 }
503 let add_to_index = bind add_to_index_(item, ebml_w, index);
Marijn Haverbekefb61b8f2012-03-06 11:52:13504
Marijn Haverbekedf7f21d2011-07-27 12:19:39505 alt item.node {
506 item_const(_, _) {
Tim Chevalier73a0c172012-03-23 01:03:12507 add_to_index();
Niko Matsakisf3ca50c2012-02-14 23:21:53508 ebml_w.start_tag(tag_items_data_item);
Marijn Haverbekedf7f21d2011-07-27 12:19:39509 encode_def_id(ebml_w, local_def(item.id));
Marijn Haverbeke72591492012-02-13 19:55:23510 encode_family(ebml_w, 'c');
Marijn Haverbeke86d473a2012-01-30 16:28:30511 encode_type(ecx, ebml_w, node_id_to_type(tcx, item.id));
Marijn Haverbekedf7f21d2011-07-27 12:19:39512 encode_symbol(ecx, ebml_w, item.id);
Niko Matsakisfdddf8f2012-02-10 14:01:32513 encode_path(ebml_w, path, ast_map::path_name(item.ident));
Niko Matsakisf3ca50c2012-02-14 23:21:53514 ebml_w.end_tag();
Marijn Haverbekedf7f21d2011-07-27 12:19:39515 }
Marijn Haverbeke0490c362011-12-22 16:49:54516 item_fn(decl, tps, _) {
Tim Chevalier73a0c172012-03-23 01:03:12517 add_to_index();
Niko Matsakisf3ca50c2012-02-14 23:21:53518 ebml_w.start_tag(tag_items_data_item);
Marijn Haverbekedf7f21d2011-07-27 12:19:39519 encode_def_id(ebml_w, local_def(item.id));
Marijn Haverbeke72591492012-02-13 19:55:23520 encode_family(ebml_w, purity_fn_family(decl.purity));
Marijn Haverbeke1ed6a272011-12-28 16:50:12521 encode_type_param_bounds(ebml_w, ecx, tps);
Marijn Haverbeke86d473a2012-01-30 16:28:30522 encode_type(ecx, ebml_w, node_id_to_type(tcx, item.id));
Niko Matsakisfdddf8f2012-02-10 14:01:32523 encode_path(ebml_w, path, ast_map::path_name(item.ident));
Marijn Haverbekec67679e2012-03-08 09:58:23524 if tps.len() > 0u || should_inline(item.attrs) {
Niko Matsakis6473a872012-03-02 03:37:52525 astencode::encode_inlined_item(ecx, ebml_w, path, ii_item(item));
Marijn Haverbeke168398b2012-03-08 12:30:22526 } else {
527 encode_symbol(ecx, ebml_w, item.id);
Niko Matsakisf3ca50c2012-02-14 23:21:53528 }
529 ebml_w.end_tag();
Marijn Haverbekedf7f21d2011-07-27 12:19:39530 }
Marijn Haverbeke0a362612011-12-16 13:17:52531 item_mod(m) {
Tim Chevalier73a0c172012-03-23 01:03:12532 add_to_index();
Niko Matsakisfdddf8f2012-02-10 14:01:32533 encode_info_for_mod(ecx, ebml_w, m, item.id, path, item.ident);
Marijn Haverbekedf7f21d2011-07-27 12:19:39534 }
535 item_native_mod(_) {
Tim Chevalier73a0c172012-03-23 01:03:12536 add_to_index();
Niko Matsakisf3ca50c2012-02-14 23:21:53537 ebml_w.start_tag(tag_items_data_item);
Marijn Haverbekedf7f21d2011-07-27 12:19:39538 encode_def_id(ebml_w, local_def(item.id));
Marijn Haverbeke72591492012-02-13 19:55:23539 encode_family(ebml_w, 'n');
Haitao Libd300632011-12-19 19:30:23540 encode_name(ebml_w, item.ident);
Niko Matsakisfdddf8f2012-02-10 14:01:32541 encode_path(ebml_w, path, ast_map::path_name(item.ident));
Niko Matsakisf3ca50c2012-02-14 23:21:53542 ebml_w.end_tag();
Marijn Haverbekedf7f21d2011-07-27 12:19:39543 }
Niko Matsakis3c995fb2012-04-19 04:26:25544 item_ty(_, tps, rp) {
Tim Chevalier73a0c172012-03-23 01:03:12545 add_to_index();
Niko Matsakisf3ca50c2012-02-14 23:21:53546 ebml_w.start_tag(tag_items_data_item);
Marijn Haverbekedf7f21d2011-07-27 12:19:39547 encode_def_id(ebml_w, local_def(item.id));
Marijn Haverbeke72591492012-02-13 19:55:23548 encode_family(ebml_w, 'y');
Marijn Haverbeke1ed6a272011-12-28 16:50:12549 encode_type_param_bounds(ebml_w, ecx, tps);
Marijn Haverbeke86d473a2012-01-30 16:28:30550 encode_type(ecx, ebml_w, node_id_to_type(tcx, item.id));
Marijn Haverbeke619d7c32011-12-19 12:52:58551 encode_name(ebml_w, item.ident);
Niko Matsakisfdddf8f2012-02-10 14:01:32552 encode_path(ebml_w, path, ast_map::path_name(item.ident));
Niko Matsakis3c995fb2012-04-19 04:26:25553 encode_region_param(ebml_w, rp);
Niko Matsakisf3ca50c2012-02-14 23:21:53554 ebml_w.end_tag();
Marijn Haverbekedf7f21d2011-07-27 12:19:39555 }
Niko Matsakis3c995fb2012-04-19 04:26:25556 item_enum(variants, tps, rp) {
Tim Chevalier73a0c172012-03-23 01:03:12557 add_to_index();
Niko Matsakis3c995fb2012-04-19 04:26:25558 ebml_w.wr_tag(tag_items_data_item) {||
559 encode_def_id(ebml_w, local_def(item.id));
560 encode_family(ebml_w, 't');
561 encode_type_param_bounds(ebml_w, ecx, tps);
562 encode_type(ecx, ebml_w, node_id_to_type(tcx, item.id));
563 encode_name(ebml_w, item.ident);
564 for variants.each {|v|
565 encode_variant_id(ebml_w, local_def(v.node.id));
566 }
567 astencode::encode_inlined_item(ecx, ebml_w, path, ii_item(item));
568 encode_path(ebml_w, path, ast_map::path_name(item.ident));
569 encode_region_param(ebml_w, rp);
Brian Anderson33294c72011-06-27 22:20:17570 }
Niko Matsakisfdddf8f2012-02-10 14:01:32571 encode_enum_variant_info(ecx, ebml_w, item.id, variants,
572 path, index, tps);
Marijn Haverbekedf7f21d2011-07-27 12:19:39573 }
Niko Matsakis3c995fb2012-04-19 04:26:25574 item_class(tps, _ifaces, items, ctor, rp) {
Tim Chevalier73a0c172012-03-23 01:03:12575 /* First, encode the fields and methods
576 These come first because we need to write them to make
577 the index, and the index needs to be in the item for the
578 class itself */
Tim Chevalierfd267432012-04-10 17:52:06579 let idx = encode_info_for_class(ecx, ebml_w, item.id, path, tps,
580 items, index);
Tim Chevalier73a0c172012-03-23 01:03:12581 /* Index the class*/
582 add_to_index();
583 /* Now, make an item for the class itself */
Tim Chevalier16dd6c42012-03-17 02:19:37584 ebml_w.start_tag(tag_items_data_item);
Tim Chevalier73a0c172012-03-23 01:03:12585 encode_def_id(ebml_w, local_def(item.id));
586 encode_family(ebml_w, 'C');
587 encode_type_param_bounds(ebml_w, ecx, tps);
588 encode_type(ecx, ebml_w, node_id_to_type(tcx, item.id));
589 encode_name(ebml_w, item.ident);
590 encode_path(ebml_w, path, ast_map::path_name(item.ident));
Niko Matsakis3c995fb2012-04-19 04:26:25591 encode_region_param(ebml_w, rp);
Tim Chevalier5c12cd72012-04-11 23:18:00592 /* FIXME: encode ifaces */
Tim Chevalier73a0c172012-03-23 01:03:12593 /* Encode def_ids for each field and method
594 for methods, write all the stuff get_iface_method
595 needs to know*/
596 let (fs,ms) = ast_util::split_class_items(items);
Marijn Haverbekec902eaf2012-04-06 18:01:43597 for fs.each {|f|
Tim Chevalier73a0c172012-03-23 01:03:12598 ebml_w.start_tag(tag_item_field);
Tim Chevalierc2828102012-03-26 16:59:59599 encode_privacy(ebml_w, f.privacy);
Tim Chevalier73a0c172012-03-23 01:03:12600 encode_name(ebml_w, f.ident);
601 encode_def_id(ebml_w, local_def(f.id));
602 ebml_w.end_tag();
603 }
Marijn Haverbekec902eaf2012-04-06 18:01:43604 for ms.each {|m|
Tim Chevalierf7bbe532012-03-29 01:50:33605 alt m.privacy {
Tim Chevalierc2828102012-03-26 16:59:59606 priv { /* do nothing */ }
607 pub {
Tim Chevalierc2828102012-03-26 16:59:59608 ebml_w.start_tag(tag_item_method);
609 #debug("Writing %s %d", m.ident, m.id);
610 encode_family(ebml_w, purity_fn_family(m.decl.purity));
611 encode_name(ebml_w, m.ident);
Tim Chevalierfd267432012-04-10 17:52:06612 encode_type_param_bounds(ebml_w, ecx, tps + m.tps);
Tim Chevalierc2828102012-03-26 16:59:59613 encode_type(ecx, ebml_w, node_id_to_type(tcx, m.id));
614 encode_def_id(ebml_w, local_def(m.id));
615 ebml_w.end_tag();
616 }
617 }
Tim Chevalier73a0c172012-03-23 01:03:12618 }
619 /* Each class has its own index -- encode it */
Tim Chevalierb06dc882012-03-19 17:19:00620 let bkts = create_index(idx, hash_node_id);
621 encode_index(ebml_w, bkts, write_int);
Tim Chevalier16dd6c42012-03-17 02:19:37622 ebml_w.end_tag();
Tim Chevalierf3343b32012-02-01 03:30:40623 }
Niko Matsakis3c995fb2012-04-19 04:26:25624 item_res(_, tps, _, _, ctor_id, rp) {
Tim Chevalier73a0c172012-03-23 01:03:12625 add_to_index();
Marijn Haverbeke86d473a2012-01-30 16:28:30626 let fn_ty = node_id_to_type(tcx, ctor_id);
Brian Anderson33294c72011-06-27 22:20:17627
Niko Matsakisf3ca50c2012-02-14 23:21:53628 ebml_w.start_tag(tag_items_data_item);
Marijn Haverbekedf7f21d2011-07-27 12:19:39629 encode_def_id(ebml_w, local_def(ctor_id));
Marijn Haverbeke72591492012-02-13 19:55:23630 encode_family(ebml_w, 'y');
Marijn Haverbeke1ed6a272011-12-28 16:50:12631 encode_type_param_bounds(ebml_w, ecx, tps);
Marijn Haverbeke8673c4f2012-02-03 14:15:28632 encode_type(ecx, ebml_w, ty::ty_fn_ret(fn_ty));
Marijn Haverbeke619d7c32011-12-19 12:52:58633 encode_name(ebml_w, item.ident);
Marijn Haverbeke2c8c50d2012-03-08 22:13:57634 astencode::encode_inlined_item(ecx, ebml_w, path, ii_item(item));
Marijn Haverbeke054a3122012-04-18 11:46:21635 if (tps.len() == 0u) {
636 encode_symbol(ecx, ebml_w, item.id);
637 }
Niko Matsakisfdddf8f2012-02-10 14:01:32638 encode_path(ebml_w, path, ast_map::path_name(item.ident));
Niko Matsakis3c995fb2012-04-19 04:26:25639 encode_region_param(ebml_w, rp);
Niko Matsakisf3ca50c2012-02-14 23:21:53640 ebml_w.end_tag();
Brian Anderson33294c72011-06-27 22:20:17641
Marijn Haverbekefe90c182012-03-08 22:37:45642 *index += [{val: ctor_id, pos: ebml_w.writer.tell()}];
Niko Matsakisf3ca50c2012-02-14 23:21:53643 ebml_w.start_tag(tag_items_data_item);
Marijn Haverbekedf7f21d2011-07-27 12:19:39644 encode_def_id(ebml_w, local_def(ctor_id));
Marijn Haverbeke72591492012-02-13 19:55:23645 encode_family(ebml_w, 'f');
Marijn Haverbeke1ed6a272011-12-28 16:50:12646 encode_type_param_bounds(ebml_w, ecx, tps);
Marijn Haverbekedf7f21d2011-07-27 12:19:39647 encode_type(ecx, ebml_w, fn_ty);
Marijn Haverbeke2c8c50d2012-03-08 22:13:57648 encode_parent_item(ebml_w, local_def(item.id));
Niko Matsakisfdddf8f2012-02-10 14:01:32649 encode_path(ebml_w, path, ast_map::path_name(item.ident));
Niko Matsakisf3ca50c2012-02-14 23:21:53650 ebml_w.end_tag();
Marijn Haverbekedf7f21d2011-07-27 12:19:39651 }
Niko Matsakis825fd182012-04-24 22:52:52652 item_impl(tps, rp, ifce, _, methods) {
Tim Chevalier73a0c172012-03-23 01:03:12653 add_to_index();
Niko Matsakisf3ca50c2012-02-14 23:21:53654 ebml_w.start_tag(tag_items_data_item);
Marijn Haverbeke0a362612011-12-16 13:17:52655 encode_def_id(ebml_w, local_def(item.id));
Marijn Haverbeke72591492012-02-13 19:55:23656 encode_family(ebml_w, 'i');
Niko Matsakis825fd182012-04-24 22:52:52657 encode_region_param(ebml_w, rp);
Marijn Haverbeke1ed6a272011-12-28 16:50:12658 encode_type_param_bounds(ebml_w, ecx, tps);
Marijn Haverbeke86d473a2012-01-30 16:28:30659 encode_type(ecx, ebml_w, node_id_to_type(tcx, item.id));
Marijn Haverbeke58a81a62011-12-16 13:41:12660 encode_name(ebml_w, item.ident);
Marijn Haverbekec902eaf2012-04-06 18:01:43661 for methods.each {|m|
Niko Matsakisf3ca50c2012-02-14 23:21:53662 ebml_w.start_tag(tag_item_method);
Marijn Haverbeke0490c362011-12-22 16:49:54663 ebml_w.writer.write(str::bytes(def_to_str(local_def(m.id))));
Niko Matsakisf3ca50c2012-02-14 23:21:53664 ebml_w.end_tag();
Marijn Haverbeke0a362612011-12-16 13:17:52665 }
Marijn Haverbeke6559aa82012-01-05 09:57:19666 alt ifce {
Marijn Haverbekec71306b2012-03-07 11:54:00667 some(t) {
Tim Chevalierf7641282012-04-13 19:22:35668 let i_ty = ty::node_id_to_type(tcx, t.id);
Niko Matsakisf3ca50c2012-02-14 23:21:53669 ebml_w.start_tag(tag_impl_iface);
Marijn Haverbeke3a20dda2012-01-05 12:57:27670 write_type(ecx, ebml_w, i_ty);
Niko Matsakisf3ca50c2012-02-14 23:21:53671 ebml_w.end_tag();
Marijn Haverbeke6559aa82012-01-05 09:57:19672 }
673 _ {}
674 }
Niko Matsakisfdddf8f2012-02-10 14:01:32675 encode_path(ebml_w, path, ast_map::path_name(item.ident));
Niko Matsakisf3ca50c2012-02-14 23:21:53676 ebml_w.end_tag();
Marijn Haverbeke0a362612011-12-16 13:17:52677
Niko Matsakisfdddf8f2012-02-10 14:01:32678 let impl_path = path + [ast_map::path_name(item.ident)];
Marijn Haverbekec902eaf2012-04-06 18:01:43679 for methods.each {|m|
Marijn Haverbekefe90c182012-03-08 22:37:45680 *index += [{val: m.id, pos: ebml_w.writer.tell()}];
Tim Chevalierb06dc882012-03-19 17:19:00681 encode_info_for_method(ecx, ebml_w, impl_path,
682 should_inline(m.attrs), item.id, m, tps + m.tps);
Marijn Haverbeke0a362612011-12-16 13:17:52683 }
684 }
Niko Matsakis825fd182012-04-24 22:52:52685 item_iface(tps, rp, ms) {
Tim Chevalier73a0c172012-03-23 01:03:12686 add_to_index();
Niko Matsakisf3ca50c2012-02-14 23:21:53687 ebml_w.start_tag(tag_items_data_item);
Marijn Haverbeke3a20dda2012-01-05 12:57:27688 encode_def_id(ebml_w, local_def(item.id));
Marijn Haverbeke72591492012-02-13 19:55:23689 encode_family(ebml_w, 'I');
Niko Matsakis825fd182012-04-24 22:52:52690 encode_region_param(ebml_w, rp);
Marijn Haverbeke3a20dda2012-01-05 12:57:27691 encode_type_param_bounds(ebml_w, ecx, tps);
Marijn Haverbeke86d473a2012-01-30 16:28:30692 encode_type(ecx, ebml_w, node_id_to_type(tcx, item.id));
Marijn Haverbeke3a20dda2012-01-05 12:57:27693 encode_name(ebml_w, item.ident);
Niko Matsakisb653a182012-03-15 13:47:03694 let mut i = 0u;
Marijn Haverbekec902eaf2012-04-06 18:01:43695 for vec::each(*ty::iface_methods(tcx, local_def(item.id))) {|mty|
Niko Matsakisf3ca50c2012-02-14 23:21:53696 ebml_w.start_tag(tag_item_method);
Marijn Haverbeke3a20dda2012-01-05 12:57:27697 encode_name(ebml_w, mty.ident);
698 encode_type_param_bounds(ebml_w, ecx, ms[i].tps);
699 encode_type(ecx, ebml_w, ty::mk_fn(tcx, mty.fty));
Marijn Haverbeke72591492012-02-13 19:55:23700 encode_family(ebml_w, purity_fn_family(mty.purity));
Niko Matsakisf3ca50c2012-02-14 23:21:53701 ebml_w.end_tag();
Marijn Haverbeke3a20dda2012-01-05 12:57:27702 i += 1u;
703 }
Niko Matsakisfdddf8f2012-02-10 14:01:32704 encode_path(ebml_w, path, ast_map::path_name(item.ident));
Niko Matsakisf3ca50c2012-02-14 23:21:53705 ebml_w.end_tag();
Marijn Haverbeke3a20dda2012-01-05 12:57:27706 }
Brian Anderson33294c72011-06-27 22:20:17707 }
708}
709
Marijn Haverbekefc6b7c82011-09-12 09:27:30710fn encode_info_for_native_item(ecx: @encode_ctxt, ebml_w: ebml::writer,
Marijn Haverbekefe90c182012-03-08 22:37:45711 nitem: @native_item,
Graydon Hoare6e6798c2012-03-27 01:35:18712 index: @mut [entry<int>],
Marijn Haverbekeb6ad34b2012-03-09 12:35:20713 path: ast_map::path, abi: native_abi) {
Brian Andersonb4a3d522012-04-24 06:40:53714 if !reachable(ecx, nitem.id) { ret; }
Marijn Haverbekefe90c182012-03-08 22:37:45715 *index += [{val: nitem.id, pos: ebml_w.writer.tell()}];
716
Niko Matsakisf3ca50c2012-02-14 23:21:53717 ebml_w.start_tag(tag_items_data_item);
Marijn Haverbekedf7f21d2011-07-27 12:19:39718 alt nitem.node {
Haitao Li3b683f52011-11-14 13:06:39719 native_item_fn(fn_decl, tps) {
Marijn Haverbekedf7f21d2011-07-27 12:19:39720 encode_def_id(ebml_w, local_def(nitem.id));
Marijn Haverbeke72591492012-02-13 19:55:23721 encode_family(ebml_w, purity_fn_family(fn_decl.purity));
Marijn Haverbeke1ed6a272011-12-28 16:50:12722 encode_type_param_bounds(ebml_w, ecx, tps);
Marijn Haverbeke52d618a2012-03-23 11:51:20723 encode_type(ecx, ebml_w, node_id_to_type(ecx.ccx.tcx, nitem.id));
Marijn Haverbeke1b81c512012-03-23 14:05:16724 if abi == native_abi_rust_intrinsic {
Marijn Haverbekeea2e3792012-03-21 14:42:20725 astencode::encode_inlined_item(ecx, ebml_w, path,
726 ii_native(nitem));
727 } else {
728 encode_symbol(ecx, ebml_w, nitem.id);
729 }
Niko Matsakisfdddf8f2012-02-10 14:01:32730 encode_path(ebml_w, path, ast_map::path_name(nitem.ident));
Marijn Haverbekedf7f21d2011-07-27 12:19:39731 }
Brian Anderson33294c72011-06-27 22:20:17732 }
Niko Matsakisf3ca50c2012-02-14 23:21:53733 ebml_w.end_tag();
Brian Anderson33294c72011-06-27 22:20:17734}
735
Marijn Haverbeke58a81a62011-12-16 13:41:12736fn encode_info_for_items(ecx: @encode_ctxt, ebml_w: ebml::writer,
Marijn Haverbekefe90c182012-03-08 22:37:45737 crate: @crate) -> [entry<int>] {
Graydon Hoare6e6798c2012-03-27 01:35:18738 let index = @mut [];
Niko Matsakisf3ca50c2012-02-14 23:21:53739 ebml_w.start_tag(tag_items_data);
Marijn Haverbekefe90c182012-03-08 22:37:45740 *index += [{val: crate_node_id, pos: ebml_w.writer.tell()}];
741 encode_info_for_mod(ecx, ebml_w, crate.node.module,
742 crate_node_id, [], "");
743 visit::visit_crate(*crate, (), visit::mk_vt(@{
744 visit_expr: {|_e, _cx, _v|},
745 visit_item: {|i, cx, v|
746 visit::visit_item(i, cx, v);
Marijn Haverbekeb6ad34b2012-03-09 12:35:20747 alt check ecx.ccx.tcx.items.get(i.id) {
748 ast_map::node_item(_, pt) {
749 encode_info_for_item(ecx, ebml_w, i, index, *pt);
Tim Chevalier16dd6c42012-03-17 02:19:37750 /* encode ctor, then encode items */
751 alt i.node {
Niko Matsakis3c995fb2012-04-19 04:26:25752 item_class(tps, _, _, ctor, _) {
Tim Chevalier1680ccc2012-03-06 16:02:13753 /* this is assuming that ctors aren't inlined...
754 probably shouldn't assume that */
Tim Chevalier16dd6c42012-03-17 02:19:37755 #debug("encoding info for ctor %s %d", i.ident,
756 ctor.node.id);
757 *index += [{val: ctor.node.id, pos: ebml_w.writer.tell()}];
Tim Chevalier1680ccc2012-03-06 16:02:13758 encode_info_for_fn(ecx, ebml_w, ctor.node.id, i.ident,
Tim Chevalierfd267432012-04-10 17:52:06759 *pt, if tps.len() > 0u {
760 some(ii_ctor(ctor, i.ident, tps,
761 local_def(i.id))) }
762 else { none }, tps, ctor.node.dec)
Tim Chevalier16dd6c42012-03-17 02:19:37763 }
764 _ {}
Patrick Waltonba39e272012-03-21 02:06:04765 }
766 }
Tim Chevalier1680ccc2012-03-06 16:02:13767 }
Marijn Haverbekefe90c182012-03-08 22:37:45768 },
769 visit_native_item: {|ni, cx, v|
770 visit::visit_native_item(ni, cx, v);
Marijn Haverbekeb6ad34b2012-03-09 12:35:20771 alt check ecx.ccx.tcx.items.get(ni.id) {
772 ast_map::node_native_item(_, abi, pt) {
773 encode_info_for_native_item(ecx, ebml_w, ni, index, *pt, abi);
774 }
775 }
Marijn Haverbekefe90c182012-03-08 22:37:45776 }
777 with *visit::default_visitor()
778 }));
Niko Matsakisf3ca50c2012-02-14 23:21:53779 ebml_w.end_tag();
Marijn Haverbekefe90c182012-03-08 22:37:45780 ret *index;
Brian Anderson33294c72011-06-27 22:20:17781}
782
783
784// Path and definition ID indexing
785
Niko Matsakis455f8b02012-01-11 17:58:05786fn create_index<T: copy>(index: [entry<T>], hash_fn: fn@(T) -> uint) ->
Erick Tryzelaare4a0f992011-08-12 14:15:18787 [@[entry<T>]] {
Graydon Hoare6e6798c2012-03-27 01:35:18788 let mut buckets: [@mut [entry<T>]] = [];
789 uint::range(0u, 256u) {|_i| buckets += [@mut []]; };
Marijn Haverbekec902eaf2012-04-06 18:01:43790 for index.each {|elt|
Marijn Haverbekedf7f21d2011-07-27 12:19:39791 let h = hash_fn(elt.val);
Brian Anderson518dc522011-08-19 22:16:48792 *buckets[h % 256u] += [elt];
Brian Anderson33294c72011-06-27 22:20:17793 }
Patrick Walton1a6419b2011-07-14 21:25:43794
Niko Matsakisb653a182012-03-15 13:47:03795 let mut buckets_frozen = [];
Marijn Haverbekec902eaf2012-04-06 18:01:43796 for buckets.each {|bucket|
Brian Anderson518dc522011-08-19 22:16:48797 buckets_frozen += [@*bucket];
Patrick Walton1a6419b2011-07-14 21:25:43798 }
799 ret buckets_frozen;
Brian Anderson33294c72011-06-27 22:20:17800}
801
Marijn Haverbekefc6b7c82011-09-12 09:27:30802fn encode_index<T>(ebml_w: ebml::writer, buckets: [@[entry<T>]],
Niko Matsakis5e13d192012-01-23 22:59:00803 write_fn: fn(io::writer, T)) {
Niko Matsakis3f3bfee2012-01-11 20:52:25804 let writer = ebml_w.writer;
Niko Matsakisf3ca50c2012-02-14 23:21:53805 ebml_w.start_tag(tag_index);
Niko Matsakisb653a182012-03-15 13:47:03806 let mut bucket_locs: [uint] = [];
Niko Matsakisf3ca50c2012-02-14 23:21:53807 ebml_w.start_tag(tag_index_buckets);
Marijn Haverbekec902eaf2012-04-06 18:01:43808 for buckets.each {|bucket|
Brian Anderson518dc522011-08-19 22:16:48809 bucket_locs += [ebml_w.writer.tell()];
Niko Matsakisf3ca50c2012-02-14 23:21:53810 ebml_w.start_tag(tag_index_buckets_bucket);
Marijn Haverbekec902eaf2012-04-06 18:01:43811 for vec::each(*bucket) {|elt|
Niko Matsakisf3ca50c2012-02-14 23:21:53812 ebml_w.start_tag(tag_index_buckets_bucket_elt);
Marijn Haverbekeaea53772011-07-26 12:06:02813 writer.write_be_uint(elt.pos, 4u);
814 write_fn(writer, elt.val);
Niko Matsakisf3ca50c2012-02-14 23:21:53815 ebml_w.end_tag();
Brian Anderson33294c72011-06-27 22:20:17816 }
Niko Matsakisf3ca50c2012-02-14 23:21:53817 ebml_w.end_tag();
Brian Anderson33294c72011-06-27 22:20:17818 }
Niko Matsakisf3ca50c2012-02-14 23:21:53819 ebml_w.end_tag();
820 ebml_w.start_tag(tag_index_table);
Marijn Haverbekec902eaf2012-04-06 18:01:43821 for bucket_locs.each {|pos| writer.write_be_uint(pos, 4u); }
Niko Matsakisf3ca50c2012-02-14 23:21:53822 ebml_w.end_tag();
823 ebml_w.end_tag();
Brian Anderson33294c72011-06-27 22:20:17824}
825
Marijn Haverbeke33167f72011-10-10 11:54:03826fn write_str(writer: io::writer, &&s: str) { writer.write_str(s); }
Brian Anderson33294c72011-06-27 22:20:17827
Marijn Haverbekef9fbd862011-10-06 10:26:12828fn write_int(writer: io::writer, &&n: int) {
Brian Anderson33294c72011-06-27 22:20:17829 writer.write_be_uint(n as uint, 4u);
830}
831
Marijn Haverbekefc6b7c82011-09-12 09:27:30832fn encode_meta_item(ebml_w: ebml::writer, mi: meta_item) {
Marijn Haverbekedf7f21d2011-07-27 12:19:39833 alt mi.node {
834 meta_word(name) {
Niko Matsakisf3ca50c2012-02-14 23:21:53835 ebml_w.start_tag(tag_meta_item_word);
836 ebml_w.start_tag(tag_meta_item_name);
Brian Andersonab6bb032011-09-02 00:27:58837 ebml_w.writer.write(str::bytes(name));
Niko Matsakisf3ca50c2012-02-14 23:21:53838 ebml_w.end_tag();
839 ebml_w.end_tag();
Marijn Haverbekedf7f21d2011-07-27 12:19:39840 }
841 meta_name_value(name, value) {
842 alt value.node {
Brian Anderson9c173f12011-09-02 05:08:59843 lit_str(value) {
Niko Matsakisf3ca50c2012-02-14 23:21:53844 ebml_w.start_tag(tag_meta_item_name_value);
845 ebml_w.start_tag(tag_meta_item_name);
Brian Andersonab6bb032011-09-02 00:27:58846 ebml_w.writer.write(str::bytes(name));
Niko Matsakisf3ca50c2012-02-14 23:21:53847 ebml_w.end_tag();
848 ebml_w.start_tag(tag_meta_item_value);
Brian Andersonab6bb032011-09-02 00:27:58849 ebml_w.writer.write(str::bytes(value));
Niko Matsakisf3ca50c2012-02-14 23:21:53850 ebml_w.end_tag();
851 ebml_w.end_tag();
Marijn Haverbekedf7f21d2011-07-27 12:19:39852 }
853 _ {/* FIXME (#611) */ }
Brian Andersonf53c4f72011-06-28 02:41:48854 }
Marijn Haverbekedf7f21d2011-07-27 12:19:39855 }
856 meta_list(name, items) {
Niko Matsakisf3ca50c2012-02-14 23:21:53857 ebml_w.start_tag(tag_meta_item_list);
858 ebml_w.start_tag(tag_meta_item_name);
Brian Andersonab6bb032011-09-02 00:27:58859 ebml_w.writer.write(str::bytes(name));
Niko Matsakisf3ca50c2012-02-14 23:21:53860 ebml_w.end_tag();
Marijn Haverbekec902eaf2012-04-06 18:01:43861 for items.each {|inner_item|
Marijn Haverbekedf7f21d2011-07-27 12:19:39862 encode_meta_item(ebml_w, *inner_item);
863 }
Niko Matsakisf3ca50c2012-02-14 23:21:53864 ebml_w.end_tag();
Marijn Haverbekedf7f21d2011-07-27 12:19:39865 }
Brian Andersonf53c4f72011-06-28 02:41:48866 }
Brian Andersonf53c4f72011-06-28 02:41:48867}
868
Marijn Haverbekefc6b7c82011-09-12 09:27:30869fn encode_attributes(ebml_w: ebml::writer, attrs: [attribute]) {
Niko Matsakisf3ca50c2012-02-14 23:21:53870 ebml_w.start_tag(tag_attributes);
Marijn Haverbekec902eaf2012-04-06 18:01:43871 for attrs.each {|attr|
Niko Matsakisf3ca50c2012-02-14 23:21:53872 ebml_w.start_tag(tag_attribute);
Brian Andersonf53c4f72011-06-28 02:41:48873 encode_meta_item(ebml_w, attr.node.value);
Niko Matsakisf3ca50c2012-02-14 23:21:53874 ebml_w.end_tag();
Brian Anderson33294c72011-06-27 22:20:17875 }
Niko Matsakisf3ca50c2012-02-14 23:21:53876 ebml_w.end_tag();
Brian Andersonf53c4f72011-06-28 02:41:48877}
878
Graydon Hoarec796a8f2011-06-29 22:11:20879// So there's a special crate attribute called 'link' which defines the
880// metadata that Rust cares about for linking crates. This attribute requires
Brian Anderson70a28dc2011-07-01 00:03:08881// 'name' and 'vers' items, so if the user didn't provide them we will throw
Graydon Hoarec796a8f2011-06-29 22:11:20882// them in anyway with default values.
Marijn Haverbekefc6b7c82011-09-12 09:27:30883fn synthesize_crate_attrs(ecx: @encode_ctxt, crate: @crate) -> [attribute] {
Brian Anderson29afe1a2011-06-29 21:17:23884
Marijn Haverbekefc6b7c82011-09-12 09:27:30885 fn synthesize_link_attr(ecx: @encode_ctxt, items: [@meta_item]) ->
Marijn Haverbekedf7f21d2011-07-27 12:19:39886 attribute {
Brian Anderson29afe1a2011-06-29 21:17:23887
Brian Anderson5c49e4f2011-09-02 22:34:58888 assert (ecx.ccx.link_meta.name != "");
889 assert (ecx.ccx.link_meta.vers != "");
Brian Anderson29afe1a2011-06-29 21:17:23890
Marijn Haverbekedf7f21d2011-07-27 12:19:39891 let name_item =
Brian Anderson5c49e4f2011-09-02 22:34:58892 attr::mk_name_value_item_str("name", ecx.ccx.link_meta.name);
Marijn Haverbekedf7f21d2011-07-27 12:19:39893 let vers_item =
Brian Anderson5c49e4f2011-09-02 22:34:58894 attr::mk_name_value_item_str("vers", ecx.ccx.link_meta.vers);
Brian Anderson29afe1a2011-06-29 21:17:23895
Marijn Haverbekedf7f21d2011-07-27 12:19:39896 let other_items =
897 {
Brian Anderson5c49e4f2011-09-02 22:34:58898 let tmp = attr::remove_meta_items_by_name(items, "name");
899 attr::remove_meta_items_by_name(tmp, "vers")
Marijn Haverbekedf7f21d2011-07-27 12:19:39900 };
Brian Anderson29afe1a2011-06-29 21:17:23901
Brian Anderson518dc522011-08-19 22:16:48902 let meta_items = [name_item, vers_item] + other_items;
Brian Anderson5c49e4f2011-09-02 22:34:58903 let link_item = attr::mk_list_item("link", meta_items);
Brian Anderson29afe1a2011-06-29 21:17:23904
Brian Anderson70a28dc2011-07-01 00:03:08905 ret attr::mk_attr(link_item);
Brian Anderson29afe1a2011-06-29 21:17:23906 }
907
Niko Matsakisb653a182012-03-15 13:47:03908 let mut attrs: [attribute] = [];
909 let mut found_link_attr = false;
Marijn Haverbekec902eaf2012-04-06 18:01:43910 for crate.node.attrs.each {|attr|
Marijn Haverbekedf7f21d2011-07-27 12:19:39911 attrs +=
Brian Anderson5c49e4f2011-09-02 22:34:58912 if attr::get_attr_name(attr) != "link" {
Brian Anderson518dc522011-08-19 22:16:48913 [attr]
Marijn Haverbekedf7f21d2011-07-27 12:19:39914 } else {
915 alt attr.node.value.node {
916 meta_list(n, l) {
Marijn Haverbekefc6b7c82011-09-12 09:27:30917 found_link_attr = true;;
Brian Anderson518dc522011-08-19 22:16:48918 [synthesize_link_attr(ecx, l)]
Marijn Haverbekedf7f21d2011-07-27 12:19:39919 }
Brian Anderson518dc522011-08-19 22:16:48920 _ { [attr] }
Brian Anderson29afe1a2011-06-29 21:17:23921 }
Marijn Haverbeke7298b8f2011-09-15 07:48:39922 };
Brian Anderson29afe1a2011-06-29 21:17:23923 }
924
Brian Anderson518dc522011-08-19 22:16:48925 if !found_link_attr { attrs += [synthesize_link_attr(ecx, [])]; }
Brian Anderson29afe1a2011-06-29 21:17:23926
927 ret attrs;
928}
929
Marijn Haverbekefc6b7c82011-09-12 09:27:30930fn encode_crate_deps(ebml_w: ebml::writer, cstore: cstore::cstore) {
Brian Anderson30704392011-07-08 18:29:56931
Haitao Li5aa52202012-04-07 17:59:37932 fn get_ordered_deps(cstore: cstore::cstore) -> [decoder::crate_dep] {
Marijn Haverbekedf7f21d2011-07-27 12:19:39933 type hashkv = @{key: crate_num, val: cstore::crate_metadata};
Haitao Li5aa52202012-04-07 17:59:37934 type numdep = decoder::crate_dep;
Brian Anderson30704392011-07-08 18:29:56935
Haitao Li5aa52202012-04-07 17:59:37936 // Pull the cnums and name,vers,hash out of cstore
937 let mut deps: [mut numdep] = [mut];
Marijn Haverbeke4ebbbe52011-10-21 10:21:27938 cstore::iter_crate_data(cstore) {|key, val|
Haitao Li5aa52202012-04-07 17:59:37939 let dep = {cnum: key, name: val.name,
940 vers: decoder::get_crate_vers(val.data),
941 hash: decoder::get_crate_hash(val.data)};
942 deps += [mut dep];
Marijn Haverbeke4ebbbe52011-10-21 10:21:27943 };
Brian Anderson30704392011-07-08 18:29:56944
945 // Sort by cnum
Haitao Li5aa52202012-04-07 17:59:37946 fn lteq(kv1: numdep, kv2: numdep) -> bool { kv1.cnum <= kv2.cnum }
947 std::sort::quick_sort(lteq, deps);
Brian Anderson30704392011-07-08 18:29:56948
949 // Sanity-check the crate numbers
Niko Matsakisb653a182012-03-15 13:47:03950 let mut expected_cnum = 1;
Haitao Li5aa52202012-04-07 17:59:37951 for deps.each {|n|
952 assert (n.cnum == expected_cnum);
Brian Anderson30704392011-07-08 18:29:56953 expected_cnum += 1;
954 }
955
Graydon Hoare6e6798c2012-03-27 01:35:18956 // mut -> immutable hack for vec::map
Haitao Li5aa52202012-04-07 17:59:37957 ret vec::slice(deps, 0u, vec::len(deps));
Brian Anderson30704392011-07-08 18:29:56958 }
959
Haitao Li5aa52202012-04-07 17:59:37960 // We're just going to write a list of crate 'name-hash-version's, with
961 // the assumption that they are numbered 1 to n.
Brian Anderson30704392011-07-08 18:29:56962 // FIXME: This is not nearly enough to support correct versioning
963 // but is enough to get transitive crate dependencies working.
Niko Matsakisf3ca50c2012-02-14 23:21:53964 ebml_w.start_tag(tag_crate_deps);
Haitao Li5aa52202012-04-07 17:59:37965 for get_ordered_deps(cstore).each {|dep|
966 encode_crate_dep(ebml_w, dep);
Brian Anderson30704392011-07-08 18:29:56967 }
Niko Matsakisf3ca50c2012-02-14 23:21:53968 ebml_w.end_tag();
Brian Anderson30704392011-07-08 18:29:56969}
970
Haitao Li5aa52202012-04-07 17:59:37971fn encode_crate_dep(ebml_w: ebml::writer, dep: decoder::crate_dep) {
972 ebml_w.start_tag(tag_crate_dep);
973 ebml_w.start_tag(tag_crate_dep_name);
974 ebml_w.writer.write(str::bytes(dep.name));
975 ebml_w.end_tag();
976 ebml_w.start_tag(tag_crate_dep_vers);
977 ebml_w.writer.write(str::bytes(dep.vers));
978 ebml_w.end_tag();
979 ebml_w.start_tag(tag_crate_dep_hash);
980 ebml_w.writer.write(str::bytes(dep.hash));
981 ebml_w.end_tag();
982 ebml_w.end_tag();
983}
984
Haitao Lif3c206c2011-12-11 15:23:38985fn encode_hash(ebml_w: ebml::writer, hash: str) {
Niko Matsakisf3ca50c2012-02-14 23:21:53986 ebml_w.start_tag(tag_crate_hash);
Haitao Lif3c206c2011-12-11 15:23:38987 ebml_w.writer.write(str::bytes(hash));
Niko Matsakisf3ca50c2012-02-14 23:21:53988 ebml_w.end_tag();
Haitao Lif3c206c2011-12-11 15:23:38989}
990
Patrick Walton273c5e52012-03-15 00:31:16991fn encode_metadata(cx: @crate_ctxt, crate: @crate) -> [u8] {
Marijn Haverbekeade12072012-03-20 11:28:46992 let ecx = @{ccx: cx, type_abbrevs: ty::new_ty_hash()};
Brian Andersond0a432f2011-07-08 06:55:41993
Niko Matsakisb30cb8e2012-03-13 14:55:45994 let buf = io::mem_buffer();
Marijn Haverbeke34d7f052012-01-11 14:15:54995 let buf_w = io::mem_buffer_writer(buf);
Brian Andersoncd72b1f2012-03-12 22:52:30996 let ebml_w = ebml::writer(buf_w);
Brian Anderson33294c72011-06-27 22:20:17997
Haitao Lif3c206c2011-12-11 15:23:38998 encode_hash(ebml_w, cx.link_meta.extras_hash);
999
Marijn Haverbekedf7f21d2011-07-27 12:19:391000 let crate_attrs = synthesize_crate_attrs(ecx, crate);
Brian Anderson29afe1a2011-06-29 21:17:231001 encode_attributes(ebml_w, crate_attrs);
Brian Anderson30704392011-07-08 18:29:561002
Marijn Haverbekeefb9df12012-01-12 16:59:491003 encode_crate_deps(ebml_w, cx.sess.cstore);
Brian Anderson30704392011-07-08 18:29:561004
Brian Anderson33294c72011-06-27 22:20:171005 // Encode and index the paths.
Niko Matsakisf3ca50c2012-02-14 23:21:531006 ebml_w.start_tag(tag_paths);
Haitao Li9bb290c2011-12-15 10:42:271007 let paths_index = encode_item_paths(ebml_w, ecx, crate);
Marijn Haverbekedf7f21d2011-07-27 12:19:391008 let paths_buckets = create_index(paths_index, hash_path);
Marijn Haverbekee949aab2011-07-25 13:07:481009 encode_index(ebml_w, paths_buckets, write_str);
Niko Matsakisf3ca50c2012-02-14 23:21:531010 ebml_w.end_tag();
Brian Anderson33294c72011-06-27 22:20:171011
Marijn Haverbeke34d7f052012-01-11 14:15:541012 // Encode and index the items.
Niko Matsakisf3ca50c2012-02-14 23:21:531013 ebml_w.start_tag(tag_items);
Marijn Haverbekefe90c182012-03-08 22:37:451014 let items_index = encode_info_for_items(ecx, ebml_w, crate);
Marijn Haverbekedf7f21d2011-07-27 12:19:391015 let items_buckets = create_index(items_index, hash_node_id);
Marijn Haverbekee949aab2011-07-25 13:07:481016 encode_index(ebml_w, items_buckets, write_int);
Niko Matsakisf3ca50c2012-02-14 23:21:531017 ebml_w.end_tag();
Marijn Haverbeke34d7f052012-01-11 14:15:541018
Brian Anderson33294c72011-06-27 22:20:171019 // Pad this, since something (LLVM, presumably) is cutting off the
Brian Anderson2e7e5882011-08-11 23:36:201020 // remaining % 4 bytes.
Graydon Hoare753b6832012-04-26 00:18:061021 buf_w.write([0u8, 0u8, 0u8, 0u8]/&);
Kevin Cantu4d7c2972012-01-26 06:27:291022 io::mem_buffer_buf(buf)
Brian Anderson33294c72011-06-27 22:20:171023}
Brian Anderson894e2222011-06-28 02:16:161024
Brian Anderson7d26d1d2011-07-07 19:47:391025// Get the encoded string for a type
Marijn Haverbekefc6b7c82011-09-12 09:27:301026fn encoded_ty(tcx: ty::ctxt, t: ty::t) -> str {
Niko Matsakis042c5322012-03-23 03:06:011027 let cx = @{ds: def_to_str,
1028 tcx: tcx,
Brian Andersonb4a3d522012-04-24 06:40:531029 reachable: {|_id| false},
Niko Matsakis042c5322012-03-23 03:06:011030 abbrevs: tyencode::ac_no_abbrevs};
Niko Matsakisb30cb8e2012-03-13 14:55:451031 let buf = io::mem_buffer();
Marijn Haverbeke34d7f052012-01-11 14:15:541032 tyencode::enc_ty(io::mem_buffer_writer(buf), cx, t);
1033 ret io::mem_buffer_str(buf);
Brian Anderson7d26d1d2011-07-07 19:47:391034}
1035
Brian Anderson894e2222011-06-28 02:16:161036
1037// Local Variables:
1038// mode: rust
1039// fill-column: 78;
1040// indent-tabs-mode: nil
1041// c-basic-offset: 4
1042// buffer-file-coding-system: utf-8-unix
Brian Anderson894e2222011-06-28 02:16:161043// End: