blob: 0ed91e8bbae5605ec8935d40d054eb3cfbb47c12 [file] [log] [blame]
Brian Anderson45efb1f2011-06-27 23:03:011// Metadata encoding
2
Patrick Walton0e2fff52011-07-07 02:00:003import std::ivec;
Brian Anderson33294c72011-06-27 22:20:174import std::str;
5import std::vec;
6import std::uint;
7import std::io;
8import std::option;
9import std::option::some;
10import std::option::none;
11import std::ebml;
Marijn Haverbeke6fd6fde2011-07-05 09:48:1912import syntax::ast::*;
Brian Andersone29ef1b2011-07-07 19:22:3913import common::*;
Brian Anderson33294c72011-06-27 22:20:1714import middle::trans::crate_ctxt;
Brian Anderson33294c72011-06-27 22:20:1715import middle::ty;
Brian Andersond2362592011-07-07 17:10:1016import middle::ty::node_id_to_monotype;
Brian Anderson5de916d2011-06-30 06:42:3517import front::attr;
Brian Anderson33294c72011-06-27 22:20:1718
19export def_to_str;
Brian Anderson33294c72011-06-27 22:20:1720export encode_metadata;
Brian Anderson7d26d1d2011-07-07 19:47:3921export ty_str;
Brian Anderson33294c72011-06-27 22:20:1722
23// Path table encoding
24fn encode_name(&ebml::writer ebml_w, &str name) {
25 ebml::start_tag(ebml_w, tag_paths_data_name);
26 ebml_w.writer.write(str::bytes(name));
27 ebml::end_tag(ebml_w);
28}
29
30fn encode_def_id(&ebml::writer ebml_w, &def_id id) {
31 ebml::start_tag(ebml_w, tag_def_id);
32 ebml_w.writer.write(str::bytes(def_to_str(id)));
33 ebml::end_tag(ebml_w);
34}
35
Patrick Walton0e2fff52011-07-07 02:00:0036fn encode_tag_variant_paths(&ebml::writer ebml_w, &variant[] variants,
Brian Anderson33294c72011-06-27 22:20:1737 &vec[str] path,
38 &mutable vec[tup(str, uint)] index) {
39 for (variant variant in variants) {
40 add_to_index(ebml_w, path, index, variant.node.name);
41 ebml::start_tag(ebml_w, tag_paths_data_item);
42 encode_name(ebml_w, variant.node.name);
43 encode_def_id(ebml_w, local_def(variant.node.id));
44 ebml::end_tag(ebml_w);
45 }
46}
47
48fn add_to_index(&ebml::writer ebml_w, &vec[str] path,
49 &mutable vec[tup(str, uint)] index, &str name) {
50 auto full_path = path + [name];
51 index += [tup(str::connect(full_path, "::"), ebml_w.writer.tell())];
52}
53
54fn encode_native_module_item_paths(&ebml::writer ebml_w,
55 &native_mod nmod, &vec[str] path,
56 &mutable vec[tup(str, uint)] index) {
57 for (@native_item nitem in nmod.items) {
58 add_to_index(ebml_w, path, index, nitem.ident);
59 ebml::start_tag(ebml_w, tag_paths_data_item);
60 encode_name(ebml_w, nitem.ident);
61 encode_def_id(ebml_w, local_def(nitem.id));
62 ebml::end_tag(ebml_w);
63 }
64}
65
66fn encode_module_item_paths(&ebml::writer ebml_w, &_mod module,
67 &vec[str] path,
68 &mutable vec[tup(str, uint)] index) {
69 for (@item it in module.items) {
70 if (!is_exported(it.ident, module)) { cont; }
71 alt (it.node) {
72 case (item_const(_, _)) {
73 add_to_index(ebml_w, path, index, it.ident);
74 ebml::start_tag(ebml_w, tag_paths_data_item);
75 encode_name(ebml_w, it.ident);
76 encode_def_id(ebml_w, local_def(it.id));
77 ebml::end_tag(ebml_w);
78 }
79 case (item_fn(_, ?tps)) {
80 add_to_index(ebml_w, path, index, it.ident);
81 ebml::start_tag(ebml_w, tag_paths_data_item);
82 encode_name(ebml_w, it.ident);
83 encode_def_id(ebml_w, local_def(it.id));
84 ebml::end_tag(ebml_w);
85 }
86 case (item_mod(?_mod)) {
87 add_to_index(ebml_w, path, index, it.ident);
88 ebml::start_tag(ebml_w, tag_paths_data_mod);
89 encode_name(ebml_w, it.ident);
90 encode_def_id(ebml_w, local_def(it.id));
91 encode_module_item_paths(ebml_w, _mod, path + [it.ident],
92 index);
93 ebml::end_tag(ebml_w);
94 }
95 case (item_native_mod(?nmod)) {
96 add_to_index(ebml_w, path, index, it.ident);
97 ebml::start_tag(ebml_w, tag_paths_data_mod);
98 encode_name(ebml_w, it.ident);
99 encode_def_id(ebml_w, local_def(it.id));
100 encode_native_module_item_paths(ebml_w, nmod,
101 path + [it.ident], index);
102 ebml::end_tag(ebml_w);
103 }
104 case (item_ty(_, ?tps)) {
105 add_to_index(ebml_w, path, index, it.ident);
106 ebml::start_tag(ebml_w, tag_paths_data_item);
107 encode_name(ebml_w, it.ident);
108 encode_def_id(ebml_w, local_def(it.id));
109 ebml::end_tag(ebml_w);
110 }
111 case (item_res(_, _, ?tps, ?ctor_id)) {
112 add_to_index(ebml_w, path, index, it.ident);
113 ebml::start_tag(ebml_w, tag_paths_data_item);
114 encode_name(ebml_w, it.ident);
115 encode_def_id(ebml_w, local_def(ctor_id));
116 ebml::end_tag(ebml_w);
117 add_to_index(ebml_w, path, index, it.ident);
118 ebml::start_tag(ebml_w, tag_paths_data_item);
119 encode_name(ebml_w, it.ident);
120 encode_def_id(ebml_w, local_def(it.id));
121 ebml::end_tag(ebml_w);
122 }
123 case (item_tag(?variants, ?tps)) {
124 add_to_index(ebml_w, path, index, it.ident);
125 ebml::start_tag(ebml_w, tag_paths_data_item);
126 encode_name(ebml_w, it.ident);
127 encode_def_id(ebml_w, local_def(it.id));
128 ebml::end_tag(ebml_w);
129 encode_tag_variant_paths(ebml_w, variants, path, index);
130 }
131 case (item_obj(_, ?tps, ?ctor_id)) {
132 add_to_index(ebml_w, path, index, it.ident);
133 ebml::start_tag(ebml_w, tag_paths_data_item);
134 encode_name(ebml_w, it.ident);
135 encode_def_id(ebml_w, local_def(ctor_id));
136 ebml::end_tag(ebml_w);
137 add_to_index(ebml_w, path, index, it.ident);
138 ebml::start_tag(ebml_w, tag_paths_data_item);
139 encode_name(ebml_w, it.ident);
140 encode_def_id(ebml_w, local_def(it.id));
141 ebml::end_tag(ebml_w);
142 }
143 }
144 }
145}
146
147fn encode_item_paths(&ebml::writer ebml_w, &@crate crate) ->
148 vec[tup(str, uint)] {
149 let vec[tup(str, uint)] index = [];
150 let vec[str] path = [];
151 ebml::start_tag(ebml_w, tag_paths);
152 encode_module_item_paths(ebml_w, crate.node.module, path, index);
153 ebml::end_tag(ebml_w);
154 ret index;
155}
156
157
158// Item info table encoding
159fn encode_kind(&ebml::writer ebml_w, u8 c) {
160 ebml::start_tag(ebml_w, tag_items_data_item_kind);
161 ebml_w.writer.write([c]);
162 ebml::end_tag(ebml_w);
163}
164
165fn def_to_str(&def_id did) -> str { ret #fmt("%d:%d", did._0, did._1); }
166
Patrick Walton0e2fff52011-07-07 02:00:00167fn encode_type_param_count(&ebml::writer ebml_w, &ty_param[] tps) {
Brian Anderson33294c72011-06-27 22:20:17168 ebml::start_tag(ebml_w, tag_items_data_item_ty_param_count);
Patrick Walton0e2fff52011-07-07 02:00:00169 ebml::write_vint(ebml_w.writer, ivec::len[ty_param](tps));
Brian Anderson33294c72011-06-27 22:20:17170 ebml::end_tag(ebml_w);
171}
172
173fn encode_variant_id(&ebml::writer ebml_w, &def_id vid) {
174 ebml::start_tag(ebml_w, tag_items_data_item_variant);
175 ebml_w.writer.write(str::bytes(def_to_str(vid)));
176 ebml::end_tag(ebml_w);
177}
178
179fn encode_type(&@crate_ctxt cx, &ebml::writer ebml_w, &ty::t typ) {
180 ebml::start_tag(ebml_w, tag_items_data_item_type);
181 auto f = def_to_str;
182 auto ty_str_ctxt =
Graydon Hoarec796a8f2011-06-29 22:11:20183 @rec(ds=f, tcx=cx.tcx,
184 abbrevs=tyencode::ac_use_abbrevs(cx.type_abbrevs));
Brian Anderson33294c72011-06-27 22:20:17185 tyencode::enc_ty(io::new_writer_(ebml_w.writer), ty_str_ctxt, typ);
186 ebml::end_tag(ebml_w);
187}
188
189fn encode_symbol(&@crate_ctxt cx, &ebml::writer ebml_w,
190 node_id id) {
191 ebml::start_tag(ebml_w, tag_items_data_item_symbol);
192 ebml_w.writer.write(str::bytes(cx.item_symbols.get(id)));
193 ebml::end_tag(ebml_w);
194}
195
196fn encode_discriminant(&@crate_ctxt cx, &ebml::writer ebml_w,
197 node_id id) {
198 ebml::start_tag(ebml_w, tag_items_data_item_symbol);
199 ebml_w.writer.write(str::bytes(cx.discrim_symbols.get(id)));
200 ebml::end_tag(ebml_w);
201}
202
203fn encode_tag_id(&ebml::writer ebml_w, &def_id id) {
204 ebml::start_tag(ebml_w, tag_items_data_item_tag_id);
205 ebml_w.writer.write(str::bytes(def_to_str(id)));
206 ebml::end_tag(ebml_w);
207}
208
209fn encode_tag_variant_info(&@crate_ctxt cx, &ebml::writer ebml_w,
Patrick Walton0e2fff52011-07-07 02:00:00210 node_id id, &variant[] variants,
Brian Anderson33294c72011-06-27 22:20:17211 &mutable vec[tup(int, uint)] index,
Patrick Walton0e2fff52011-07-07 02:00:00212 &ty_param[] ty_params) {
Brian Anderson33294c72011-06-27 22:20:17213 for (variant variant in variants) {
214 index += [tup(variant.node.id, ebml_w.writer.tell())];
215 ebml::start_tag(ebml_w, tag_items_data_item);
216 encode_def_id(ebml_w, local_def(variant.node.id));
217 encode_kind(ebml_w, 'v' as u8);
218 encode_tag_id(ebml_w, local_def(id));
Brian Andersond2362592011-07-07 17:10:10219 encode_type(cx, ebml_w, node_id_to_monotype(cx.tcx, variant.node.id));
Brian Anderson33294c72011-06-27 22:20:17220 if (vec::len[variant_arg](variant.node.args) > 0u) {
221 encode_symbol(cx, ebml_w, variant.node.id);
222 }
223 encode_discriminant(cx, ebml_w, variant.node.id);
224 encode_type_param_count(ebml_w, ty_params);
225 ebml::end_tag(ebml_w);
226 }
227}
228
229fn encode_info_for_item(@crate_ctxt cx, &ebml::writer ebml_w,
230 @item item, &mutable vec[tup(int, uint)] index) {
231 alt (item.node) {
232 case (item_const(_, _)) {
233 ebml::start_tag(ebml_w, tag_items_data_item);
234 encode_def_id(ebml_w, local_def(item.id));
235 encode_kind(ebml_w, 'c' as u8);
Brian Andersond2362592011-07-07 17:10:10236 encode_type(cx, ebml_w, node_id_to_monotype(cx.tcx, item.id));
Brian Anderson33294c72011-06-27 22:20:17237 encode_symbol(cx, ebml_w, item.id);
238 ebml::end_tag(ebml_w);
239 }
240 case (item_fn(?fd, ?tps)) {
241 ebml::start_tag(ebml_w, tag_items_data_item);
242 encode_def_id(ebml_w, local_def(item.id));
243 encode_kind(ebml_w, alt (fd.decl.purity) {
244 case (pure_fn) { 'p' }
245 case (impure_fn) { 'f' } } as u8);
246 encode_type_param_count(ebml_w, tps);
Brian Andersond2362592011-07-07 17:10:10247 encode_type(cx, ebml_w, node_id_to_monotype(cx.tcx, item.id));
Brian Anderson33294c72011-06-27 22:20:17248 encode_symbol(cx, ebml_w, item.id);
249 ebml::end_tag(ebml_w);
250 }
251 case (item_mod(_)) {
252 ebml::start_tag(ebml_w, tag_items_data_item);
253 encode_def_id(ebml_w, local_def(item.id));
254 encode_kind(ebml_w, 'm' as u8);
255 ebml::end_tag(ebml_w);
256 }
257 case (item_native_mod(_)) {
258 ebml::start_tag(ebml_w, tag_items_data_item);
259 encode_def_id(ebml_w, local_def(item.id));
260 encode_kind(ebml_w, 'n' as u8);
261 ebml::end_tag(ebml_w);
262 }
263 case (item_ty(_, ?tps)) {
264 ebml::start_tag(ebml_w, tag_items_data_item);
265 encode_def_id(ebml_w, local_def(item.id));
266 encode_kind(ebml_w, 'y' as u8);
267 encode_type_param_count(ebml_w, tps);
Brian Andersond2362592011-07-07 17:10:10268 encode_type(cx, ebml_w, node_id_to_monotype(cx.tcx, item.id));
Brian Anderson33294c72011-06-27 22:20:17269 ebml::end_tag(ebml_w);
270 }
271 case (item_tag(?variants, ?tps)) {
272 ebml::start_tag(ebml_w, tag_items_data_item);
273 encode_def_id(ebml_w, local_def(item.id));
274 encode_kind(ebml_w, 't' as u8);
275 encode_type_param_count(ebml_w, tps);
Brian Andersond2362592011-07-07 17:10:10276 encode_type(cx, ebml_w, node_id_to_monotype(cx.tcx, item.id));
Brian Anderson33294c72011-06-27 22:20:17277 for (variant v in variants) {
278 encode_variant_id(ebml_w, local_def(v.node.id));
279 }
280 ebml::end_tag(ebml_w);
281 encode_tag_variant_info(cx, ebml_w, item.id, variants, index,
282 tps);
283 }
284 case (item_res(_, _, ?tps, ?ctor_id)) {
Brian Andersond2362592011-07-07 17:10:10285 auto fn_ty = node_id_to_monotype(cx.tcx, ctor_id);
Brian Anderson33294c72011-06-27 22:20:17286
287 ebml::start_tag(ebml_w, tag_items_data_item);
Graydon Hoare5b2c17f2011-06-29 19:08:35288 encode_def_id(ebml_w, local_def(ctor_id));
Brian Anderson33294c72011-06-27 22:20:17289 encode_kind(ebml_w, 'y' as u8);
290 encode_type_param_count(ebml_w, tps);
291 encode_type(cx, ebml_w, ty::ty_fn_ret(cx.tcx, fn_ty));
Marijn Haverbeke31ec26d2011-06-30 10:35:19292 encode_symbol(cx, ebml_w, item.id);
Brian Anderson33294c72011-06-27 22:20:17293 ebml::end_tag(ebml_w);
294
295 index += [tup(ctor_id, ebml_w.writer.tell())];
296 ebml::start_tag(ebml_w, tag_items_data_item);
297 encode_def_id(ebml_w, local_def(ctor_id));
298 encode_kind(ebml_w, 'f' as u8);
299 encode_type_param_count(ebml_w, tps);
300 encode_type(cx, ebml_w, fn_ty);
301 encode_symbol(cx, ebml_w, ctor_id);
302 ebml::end_tag(ebml_w);
303 }
304 case (item_obj(_, ?tps, ?ctor_id)) {
Brian Andersond2362592011-07-07 17:10:10305 auto fn_ty = node_id_to_monotype(cx.tcx, ctor_id);
Brian Anderson33294c72011-06-27 22:20:17306
307 ebml::start_tag(ebml_w, tag_items_data_item);
308 encode_def_id(ebml_w, local_def(item.id));
309 encode_kind(ebml_w, 'y' as u8);
310 encode_type_param_count(ebml_w, tps);
311 encode_type(cx, ebml_w, ty::ty_fn_ret(cx.tcx, fn_ty));
312 ebml::end_tag(ebml_w);
313
314 index += [tup(ctor_id, ebml_w.writer.tell())];
315 ebml::start_tag(ebml_w, tag_items_data_item);
316 encode_def_id(ebml_w, local_def(ctor_id));
317 encode_kind(ebml_w, 'f' as u8);
318 encode_type_param_count(ebml_w, tps);
319 encode_type(cx, ebml_w, fn_ty);
320 encode_symbol(cx, ebml_w, ctor_id);
321 ebml::end_tag(ebml_w);
322 }
323 }
324}
325
326fn encode_info_for_native_item(&@crate_ctxt cx, &ebml::writer ebml_w,
327 &@native_item nitem) {
328 ebml::start_tag(ebml_w, tag_items_data_item);
329 alt (nitem.node) {
330 case (native_item_ty) {
331 encode_def_id(ebml_w, local_def(nitem.id));
332 encode_kind(ebml_w, 'T' as u8);
Marijn Haverbeke77f5d142011-07-01 16:39:24333 encode_type(cx, ebml_w,
334 ty::mk_native(cx.tcx, local_def(nitem.id)));
Brian Anderson33294c72011-06-27 22:20:17335 }
336 case (native_item_fn(_, _, ?tps)) {
337 encode_def_id(ebml_w, local_def(nitem.id));
338 encode_kind(ebml_w, 'F' as u8);
339 encode_type_param_count(ebml_w, tps);
Brian Andersond2362592011-07-07 17:10:10340 encode_type(cx, ebml_w, node_id_to_monotype(cx.tcx, nitem.id));
Brian Anderson33294c72011-06-27 22:20:17341 encode_symbol(cx, ebml_w, nitem.id);
342 }
343 }
344 ebml::end_tag(ebml_w);
345}
346
347fn encode_info_for_items(&@crate_ctxt cx, &ebml::writer ebml_w) ->
348 vec[tup(int, uint)] {
349 let vec[tup(int, uint)] index = [];
350 ebml::start_tag(ebml_w, tag_items_data);
Graydon Hoarec796a8f2011-06-29 22:11:20351 for each (@tup(node_id, middle::ast_map::ast_node) kvp in
352 cx.ast_map.items()) {
Brian Anderson33294c72011-06-27 22:20:17353 alt (kvp._1) {
354 case (middle::ast_map::node_item(?i)) {
355 index += [tup(kvp._0, ebml_w.writer.tell())];
356 encode_info_for_item(cx, ebml_w, i, index);
357 }
358 case (middle::ast_map::node_native_item(?i)) {
359 index += [tup(kvp._0, ebml_w.writer.tell())];
360 encode_info_for_native_item(cx, ebml_w, i);
361 }
362 case (_) {}
363 }
364 }
365 ebml::end_tag(ebml_w);
366 ret index;
367}
368
369
370// Path and definition ID indexing
371
Brian Anderson33294c72011-06-27 22:20:17372fn create_index[T](&vec[tup(T, uint)] index, fn(&T) -> uint hash_fn) ->
373 vec[vec[tup(T, uint)]] {
374 let vec[mutable vec[tup(T, uint)]] buckets = vec::empty_mut();
375 for each (uint i in uint::range(0u, 256u)) { buckets += [mutable []]; }
376 for (tup(T, uint) elt in index) {
377 auto h = hash_fn(elt._0);
378 buckets.(h % 256u) += [elt];
379 }
380 ret vec::freeze(buckets);
381}
382
383fn encode_index[T](&ebml::writer ebml_w, &vec[vec[tup(T, uint)]] buckets,
384 fn(&io::writer, &T) write_fn) {
385 auto writer = io::new_writer_(ebml_w.writer);
386 ebml::start_tag(ebml_w, tag_index);
387 let vec[uint] bucket_locs = [];
388 ebml::start_tag(ebml_w, tag_index_buckets);
389 for (vec[tup(T, uint)] bucket in buckets) {
390 bucket_locs += [ebml_w.writer.tell()];
391 ebml::start_tag(ebml_w, tag_index_buckets_bucket);
392 for (tup(T, uint) elt in bucket) {
393 ebml::start_tag(ebml_w, tag_index_buckets_bucket_elt);
394 writer.write_be_uint(elt._1, 4u);
395 write_fn(writer, elt._0);
396 ebml::end_tag(ebml_w);
397 }
398 ebml::end_tag(ebml_w);
399 }
400 ebml::end_tag(ebml_w);
401 ebml::start_tag(ebml_w, tag_index_table);
402 for (uint pos in bucket_locs) { writer.write_be_uint(pos, 4u); }
403 ebml::end_tag(ebml_w);
404 ebml::end_tag(ebml_w);
405}
406
407fn write_str(&io::writer writer, &str s) { writer.write_str(s); }
408
409fn write_int(&io::writer writer, &int n) {
410 writer.write_be_uint(n as uint, 4u);
411}
412
Brian Andersonf53c4f72011-06-28 02:41:48413fn encode_meta_item(&ebml::writer ebml_w, &meta_item mi) {
Brian Andersonf53c4f72011-06-28 02:41:48414 alt (mi.node) {
Brian Andersoncab73f82011-06-28 06:02:02415 case (meta_word(?name)) {
416 ebml::start_tag(ebml_w, tag_meta_item_word);
417 ebml::start_tag(ebml_w, tag_meta_item_name);
418 ebml_w.writer.write(str::bytes(name));
419 ebml::end_tag(ebml_w);
420 ebml::end_tag(ebml_w);
421 }
422 case (meta_name_value(?name, ?value)) {
Brian Anderson2cb12932011-07-06 00:01:23423 alt (value.node) {
424 case (lit_str(?value, _)) {
425 ebml::start_tag(ebml_w, tag_meta_item_name_value);
426 ebml::start_tag(ebml_w, tag_meta_item_name);
427 ebml_w.writer.write(str::bytes(name));
428 ebml::end_tag(ebml_w);
429 ebml::start_tag(ebml_w, tag_meta_item_value);
430 ebml_w.writer.write(str::bytes(value));
431 ebml::end_tag(ebml_w);
432 ebml::end_tag(ebml_w);
433 }
434 case (_) { /* FIXME (#611) */ }
435 }
Brian Anderson33294c72011-06-27 22:20:17436 }
Brian Andersoncab73f82011-06-28 06:02:02437 case (meta_list(?name, ?items)) {
438 ebml::start_tag(ebml_w, tag_meta_item_list);
439 ebml::start_tag(ebml_w, tag_meta_item_name);
440 ebml_w.writer.write(str::bytes(name));
441 ebml::end_tag(ebml_w);
442 for (@meta_item inner_item in items) {
443 encode_meta_item(ebml_w, *inner_item);
444 }
445 ebml::end_tag(ebml_w);
Brian Andersonf53c4f72011-06-28 02:41:48446 }
447 }
Brian Andersonf53c4f72011-06-28 02:41:48448}
449
450fn encode_attributes(&ebml::writer ebml_w, &vec[attribute] attrs) {
451 ebml::start_tag(ebml_w, tag_attributes);
452 for (attribute attr in attrs) {
453 ebml::start_tag(ebml_w, tag_attribute);
454 encode_meta_item(ebml_w, attr.node.value);
Brian Anderson33294c72011-06-27 22:20:17455 ebml::end_tag(ebml_w);
456 }
Brian Andersonf53c4f72011-06-28 02:41:48457 ebml::end_tag(ebml_w);
458}
459
Graydon Hoarec796a8f2011-06-29 22:11:20460// So there's a special crate attribute called 'link' which defines the
461// metadata that Rust cares about for linking crates. This attribute requires
Brian Anderson70a28dc2011-07-01 00:03:08462// 'name' and 'vers' items, so if the user didn't provide them we will throw
Graydon Hoarec796a8f2011-06-29 22:11:20463// them in anyway with default values.
Brian Anderson29afe1a2011-06-29 21:17:23464fn synthesize_crate_attrs(&@crate_ctxt cx,
465 &@crate crate) -> vec[attribute] {
466
Patrick Walton401b6362011-07-06 00:57:34467 fn synthesize_link_attr(&@crate_ctxt cx, &(@meta_item)[] items)
468 -> attribute {
Brian Anderson29afe1a2011-06-29 21:17:23469
Brian Anderson70a28dc2011-07-01 00:03:08470 assert cx.link_meta.name != "";
471 assert cx.link_meta.vers != "";
Brian Anderson29afe1a2011-06-29 21:17:23472
Brian Anderson2cb12932011-07-06 00:01:23473 auto name_item = attr::mk_name_value_item_str("name",
474 cx.link_meta.name);
475 auto vers_item = attr::mk_name_value_item_str("vers",
476 cx.link_meta.vers);
Brian Anderson29afe1a2011-06-29 21:17:23477
478 auto other_items = {
479 auto tmp = attr::remove_meta_items_by_name(items, "name");
480 attr::remove_meta_items_by_name(tmp, "vers")
481 };
482
Patrick Walton401b6362011-07-06 00:57:34483 auto meta_items = ~[name_item, vers_item] + other_items;
Brian Anderson70a28dc2011-07-01 00:03:08484 auto link_item = attr::mk_list_item("link", meta_items);
Brian Anderson29afe1a2011-06-29 21:17:23485
Brian Anderson70a28dc2011-07-01 00:03:08486 ret attr::mk_attr(link_item);
Brian Anderson29afe1a2011-06-29 21:17:23487 }
488
489 let vec[attribute] attrs = [];
490 auto found_link_attr = false;
491 for (attribute attr in crate.node.attrs) {
492 attrs += if (attr::get_attr_name(attr) != "link") {
493 [attr]
494 } else {
495 alt (attr.node.value.node) {
496 case (meta_list(?n, ?l)) {
497 found_link_attr = true;
498 [synthesize_link_attr(cx, l)]
499 }
500 case (_) { [attr] }
501 }
502 }
503 }
504
505 if (!found_link_attr) {
Patrick Walton401b6362011-07-06 00:57:34506 attrs += [synthesize_link_attr(cx, ~[])];
Brian Anderson29afe1a2011-06-29 21:17:23507 }
508
509 ret attrs;
510}
511
Brian Anderson33294c72011-06-27 22:20:17512fn encode_metadata(&@crate_ctxt cx, &@crate crate) -> str {
513 auto string_w = io::string_writer();
514 auto buf_w = string_w.get_writer().get_buf_writer();
515 auto ebml_w = ebml::create_writer(buf_w);
Brian Anderson33294c72011-06-27 22:20:17516
Brian Anderson29afe1a2011-06-29 21:17:23517 auto crate_attrs = synthesize_crate_attrs(cx, crate);
518 encode_attributes(ebml_w, crate_attrs);
Brian Anderson33294c72011-06-27 22:20:17519 // Encode and index the paths.
520
521 ebml::start_tag(ebml_w, tag_paths);
522 auto paths_index = encode_item_paths(ebml_w, crate);
523 auto str_writer = write_str;
524 auto path_hasher = hash_path;
525 auto paths_buckets = create_index[str](paths_index, path_hasher);
526 encode_index[str](ebml_w, paths_buckets, str_writer);
527 ebml::end_tag(ebml_w);
528 // Encode and index the items.
529
530 ebml::start_tag(ebml_w, tag_items);
531 auto items_index = encode_info_for_items(cx, ebml_w);
532 auto int_writer = write_int;
Brian Andersonb7230822011-07-07 19:12:25533 auto item_hasher = hash_node_id;
Brian Anderson33294c72011-06-27 22:20:17534 auto items_buckets = create_index[int](items_index, item_hasher);
535 encode_index[int](ebml_w, items_buckets, int_writer);
536 ebml::end_tag(ebml_w);
537 // Pad this, since something (LLVM, presumably) is cutting off the
538 // remaining % 4 bytes.
539
540 buf_w.write([0u8, 0u8, 0u8, 0u8]);
541 ret string_w.get_str();
542}
Brian Anderson894e2222011-06-28 02:16:16543
Brian Anderson7d26d1d2011-07-07 19:47:39544// Get the encoded string for a type
545fn ty_str(&ty::ctxt tcx, &ty::t t) -> str {
546 auto cx = @rec(ds = encoder::def_to_str,
547 tcx = tcx,
548 abbrevs = metadata::tyencode::ac_no_abbrevs);
549 auto sw = io::string_writer();
550 tyencode::enc_ty(sw.get_writer(), cx, t);
551 ret sw.get_str();
552}
553
Brian Anderson894e2222011-06-28 02:16:16554
555// Local Variables:
556// mode: rust
557// fill-column: 78;
558// indent-tabs-mode: nil
559// c-basic-offset: 4
560// buffer-file-coding-system: utf-8-unix
561// compile-command: "make -k -C $RBUILD 2>&1 | sed -e 's/\\/x\\//x:\\//g'";
562// End: