blob: ed90eaf1263f2b948d351e67145086667d18d654 [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;
21
22// Path table encoding
23fn encode_name(&ebml::writer ebml_w, &str name) {
24 ebml::start_tag(ebml_w, tag_paths_data_name);
25 ebml_w.writer.write(str::bytes(name));
26 ebml::end_tag(ebml_w);
27}
28
29fn encode_def_id(&ebml::writer ebml_w, &def_id id) {
30 ebml::start_tag(ebml_w, tag_def_id);
31 ebml_w.writer.write(str::bytes(def_to_str(id)));
32 ebml::end_tag(ebml_w);
33}
34
Patrick Walton0e2fff52011-07-07 02:00:0035fn encode_tag_variant_paths(&ebml::writer ebml_w, &variant[] variants,
Brian Anderson33294c72011-06-27 22:20:1736 &vec[str] path,
37 &mutable vec[tup(str, uint)] index) {
38 for (variant variant in variants) {
39 add_to_index(ebml_w, path, index, variant.node.name);
40 ebml::start_tag(ebml_w, tag_paths_data_item);
41 encode_name(ebml_w, variant.node.name);
42 encode_def_id(ebml_w, local_def(variant.node.id));
43 ebml::end_tag(ebml_w);
44 }
45}
46
47fn add_to_index(&ebml::writer ebml_w, &vec[str] path,
48 &mutable vec[tup(str, uint)] index, &str name) {
49 auto full_path = path + [name];
50 index += [tup(str::connect(full_path, "::"), ebml_w.writer.tell())];
51}
52
53fn encode_native_module_item_paths(&ebml::writer ebml_w,
54 &native_mod nmod, &vec[str] path,
55 &mutable vec[tup(str, uint)] index) {
56 for (@native_item nitem in nmod.items) {
57 add_to_index(ebml_w, path, index, nitem.ident);
58 ebml::start_tag(ebml_w, tag_paths_data_item);
59 encode_name(ebml_w, nitem.ident);
60 encode_def_id(ebml_w, local_def(nitem.id));
61 ebml::end_tag(ebml_w);
62 }
63}
64
65fn encode_module_item_paths(&ebml::writer ebml_w, &_mod module,
66 &vec[str] path,
67 &mutable vec[tup(str, uint)] index) {
68 for (@item it in module.items) {
69 if (!is_exported(it.ident, module)) { cont; }
70 alt (it.node) {
71 case (item_const(_, _)) {
72 add_to_index(ebml_w, path, index, it.ident);
73 ebml::start_tag(ebml_w, tag_paths_data_item);
74 encode_name(ebml_w, it.ident);
75 encode_def_id(ebml_w, local_def(it.id));
76 ebml::end_tag(ebml_w);
77 }
78 case (item_fn(_, ?tps)) {
79 add_to_index(ebml_w, path, index, it.ident);
80 ebml::start_tag(ebml_w, tag_paths_data_item);
81 encode_name(ebml_w, it.ident);
82 encode_def_id(ebml_w, local_def(it.id));
83 ebml::end_tag(ebml_w);
84 }
85 case (item_mod(?_mod)) {
86 add_to_index(ebml_w, path, index, it.ident);
87 ebml::start_tag(ebml_w, tag_paths_data_mod);
88 encode_name(ebml_w, it.ident);
89 encode_def_id(ebml_w, local_def(it.id));
90 encode_module_item_paths(ebml_w, _mod, path + [it.ident],
91 index);
92 ebml::end_tag(ebml_w);
93 }
94 case (item_native_mod(?nmod)) {
95 add_to_index(ebml_w, path, index, it.ident);
96 ebml::start_tag(ebml_w, tag_paths_data_mod);
97 encode_name(ebml_w, it.ident);
98 encode_def_id(ebml_w, local_def(it.id));
99 encode_native_module_item_paths(ebml_w, nmod,
100 path + [it.ident], index);
101 ebml::end_tag(ebml_w);
102 }
103 case (item_ty(_, ?tps)) {
104 add_to_index(ebml_w, path, index, it.ident);
105 ebml::start_tag(ebml_w, tag_paths_data_item);
106 encode_name(ebml_w, it.ident);
107 encode_def_id(ebml_w, local_def(it.id));
108 ebml::end_tag(ebml_w);
109 }
110 case (item_res(_, _, ?tps, ?ctor_id)) {
111 add_to_index(ebml_w, path, index, it.ident);
112 ebml::start_tag(ebml_w, tag_paths_data_item);
113 encode_name(ebml_w, it.ident);
114 encode_def_id(ebml_w, local_def(ctor_id));
115 ebml::end_tag(ebml_w);
116 add_to_index(ebml_w, path, index, it.ident);
117 ebml::start_tag(ebml_w, tag_paths_data_item);
118 encode_name(ebml_w, it.ident);
119 encode_def_id(ebml_w, local_def(it.id));
120 ebml::end_tag(ebml_w);
121 }
122 case (item_tag(?variants, ?tps)) {
123 add_to_index(ebml_w, path, index, it.ident);
124 ebml::start_tag(ebml_w, tag_paths_data_item);
125 encode_name(ebml_w, it.ident);
126 encode_def_id(ebml_w, local_def(it.id));
127 ebml::end_tag(ebml_w);
128 encode_tag_variant_paths(ebml_w, variants, path, index);
129 }
130 case (item_obj(_, ?tps, ?ctor_id)) {
131 add_to_index(ebml_w, path, index, it.ident);
132 ebml::start_tag(ebml_w, tag_paths_data_item);
133 encode_name(ebml_w, it.ident);
134 encode_def_id(ebml_w, local_def(ctor_id));
135 ebml::end_tag(ebml_w);
136 add_to_index(ebml_w, path, index, it.ident);
137 ebml::start_tag(ebml_w, tag_paths_data_item);
138 encode_name(ebml_w, it.ident);
139 encode_def_id(ebml_w, local_def(it.id));
140 ebml::end_tag(ebml_w);
141 }
142 }
143 }
144}
145
146fn encode_item_paths(&ebml::writer ebml_w, &@crate crate) ->
147 vec[tup(str, uint)] {
148 let vec[tup(str, uint)] index = [];
149 let vec[str] path = [];
150 ebml::start_tag(ebml_w, tag_paths);
151 encode_module_item_paths(ebml_w, crate.node.module, path, index);
152 ebml::end_tag(ebml_w);
153 ret index;
154}
155
156
157// Item info table encoding
158fn encode_kind(&ebml::writer ebml_w, u8 c) {
159 ebml::start_tag(ebml_w, tag_items_data_item_kind);
160 ebml_w.writer.write([c]);
161 ebml::end_tag(ebml_w);
162}
163
164fn def_to_str(&def_id did) -> str { ret #fmt("%d:%d", did._0, did._1); }
165
Patrick Walton0e2fff52011-07-07 02:00:00166fn encode_type_param_count(&ebml::writer ebml_w, &ty_param[] tps) {
Brian Anderson33294c72011-06-27 22:20:17167 ebml::start_tag(ebml_w, tag_items_data_item_ty_param_count);
Patrick Walton0e2fff52011-07-07 02:00:00168 ebml::write_vint(ebml_w.writer, ivec::len[ty_param](tps));
Brian Anderson33294c72011-06-27 22:20:17169 ebml::end_tag(ebml_w);
170}
171
172fn encode_variant_id(&ebml::writer ebml_w, &def_id vid) {
173 ebml::start_tag(ebml_w, tag_items_data_item_variant);
174 ebml_w.writer.write(str::bytes(def_to_str(vid)));
175 ebml::end_tag(ebml_w);
176}
177
178fn encode_type(&@crate_ctxt cx, &ebml::writer ebml_w, &ty::t typ) {
179 ebml::start_tag(ebml_w, tag_items_data_item_type);
180 auto f = def_to_str;
181 auto ty_str_ctxt =
Graydon Hoarec796a8f2011-06-29 22:11:20182 @rec(ds=f, tcx=cx.tcx,
183 abbrevs=tyencode::ac_use_abbrevs(cx.type_abbrevs));
Brian Anderson33294c72011-06-27 22:20:17184 tyencode::enc_ty(io::new_writer_(ebml_w.writer), ty_str_ctxt, typ);
185 ebml::end_tag(ebml_w);
186}
187
188fn encode_symbol(&@crate_ctxt cx, &ebml::writer ebml_w,
189 node_id id) {
190 ebml::start_tag(ebml_w, tag_items_data_item_symbol);
191 ebml_w.writer.write(str::bytes(cx.item_symbols.get(id)));
192 ebml::end_tag(ebml_w);
193}
194
195fn encode_discriminant(&@crate_ctxt cx, &ebml::writer ebml_w,
196 node_id id) {
197 ebml::start_tag(ebml_w, tag_items_data_item_symbol);
198 ebml_w.writer.write(str::bytes(cx.discrim_symbols.get(id)));
199 ebml::end_tag(ebml_w);
200}
201
202fn encode_tag_id(&ebml::writer ebml_w, &def_id id) {
203 ebml::start_tag(ebml_w, tag_items_data_item_tag_id);
204 ebml_w.writer.write(str::bytes(def_to_str(id)));
205 ebml::end_tag(ebml_w);
206}
207
208fn encode_tag_variant_info(&@crate_ctxt cx, &ebml::writer ebml_w,
Patrick Walton0e2fff52011-07-07 02:00:00209 node_id id, &variant[] variants,
Brian Anderson33294c72011-06-27 22:20:17210 &mutable vec[tup(int, uint)] index,
Patrick Walton0e2fff52011-07-07 02:00:00211 &ty_param[] ty_params) {
Brian Anderson33294c72011-06-27 22:20:17212 for (variant variant in variants) {
213 index += [tup(variant.node.id, ebml_w.writer.tell())];
214 ebml::start_tag(ebml_w, tag_items_data_item);
215 encode_def_id(ebml_w, local_def(variant.node.id));
216 encode_kind(ebml_w, 'v' as u8);
217 encode_tag_id(ebml_w, local_def(id));
Brian Andersond2362592011-07-07 17:10:10218 encode_type(cx, ebml_w, node_id_to_monotype(cx.tcx, variant.node.id));
Brian Anderson33294c72011-06-27 22:20:17219 if (vec::len[variant_arg](variant.node.args) > 0u) {
220 encode_symbol(cx, ebml_w, variant.node.id);
221 }
222 encode_discriminant(cx, ebml_w, variant.node.id);
223 encode_type_param_count(ebml_w, ty_params);
224 ebml::end_tag(ebml_w);
225 }
226}
227
228fn encode_info_for_item(@crate_ctxt cx, &ebml::writer ebml_w,
229 @item item, &mutable vec[tup(int, uint)] index) {
230 alt (item.node) {
231 case (item_const(_, _)) {
232 ebml::start_tag(ebml_w, tag_items_data_item);
233 encode_def_id(ebml_w, local_def(item.id));
234 encode_kind(ebml_w, 'c' as u8);
Brian Andersond2362592011-07-07 17:10:10235 encode_type(cx, ebml_w, node_id_to_monotype(cx.tcx, item.id));
Brian Anderson33294c72011-06-27 22:20:17236 encode_symbol(cx, ebml_w, item.id);
237 ebml::end_tag(ebml_w);
238 }
239 case (item_fn(?fd, ?tps)) {
240 ebml::start_tag(ebml_w, tag_items_data_item);
241 encode_def_id(ebml_w, local_def(item.id));
242 encode_kind(ebml_w, alt (fd.decl.purity) {
243 case (pure_fn) { 'p' }
244 case (impure_fn) { 'f' } } as u8);
245 encode_type_param_count(ebml_w, tps);
Brian Andersond2362592011-07-07 17:10:10246 encode_type(cx, ebml_w, node_id_to_monotype(cx.tcx, item.id));
Brian Anderson33294c72011-06-27 22:20:17247 encode_symbol(cx, ebml_w, item.id);
248 ebml::end_tag(ebml_w);
249 }
250 case (item_mod(_)) {
251 ebml::start_tag(ebml_w, tag_items_data_item);
252 encode_def_id(ebml_w, local_def(item.id));
253 encode_kind(ebml_w, 'm' as u8);
254 ebml::end_tag(ebml_w);
255 }
256 case (item_native_mod(_)) {
257 ebml::start_tag(ebml_w, tag_items_data_item);
258 encode_def_id(ebml_w, local_def(item.id));
259 encode_kind(ebml_w, 'n' as u8);
260 ebml::end_tag(ebml_w);
261 }
262 case (item_ty(_, ?tps)) {
263 ebml::start_tag(ebml_w, tag_items_data_item);
264 encode_def_id(ebml_w, local_def(item.id));
265 encode_kind(ebml_w, 'y' as u8);
266 encode_type_param_count(ebml_w, tps);
Brian Andersond2362592011-07-07 17:10:10267 encode_type(cx, ebml_w, node_id_to_monotype(cx.tcx, item.id));
Brian Anderson33294c72011-06-27 22:20:17268 ebml::end_tag(ebml_w);
269 }
270 case (item_tag(?variants, ?tps)) {
271 ebml::start_tag(ebml_w, tag_items_data_item);
272 encode_def_id(ebml_w, local_def(item.id));
273 encode_kind(ebml_w, 't' as u8);
274 encode_type_param_count(ebml_w, tps);
Brian Andersond2362592011-07-07 17:10:10275 encode_type(cx, ebml_w, node_id_to_monotype(cx.tcx, item.id));
Brian Anderson33294c72011-06-27 22:20:17276 for (variant v in variants) {
277 encode_variant_id(ebml_w, local_def(v.node.id));
278 }
279 ebml::end_tag(ebml_w);
280 encode_tag_variant_info(cx, ebml_w, item.id, variants, index,
281 tps);
282 }
283 case (item_res(_, _, ?tps, ?ctor_id)) {
Brian Andersond2362592011-07-07 17:10:10284 auto fn_ty = node_id_to_monotype(cx.tcx, ctor_id);
Brian Anderson33294c72011-06-27 22:20:17285
286 ebml::start_tag(ebml_w, tag_items_data_item);
Graydon Hoare5b2c17f2011-06-29 19:08:35287 encode_def_id(ebml_w, local_def(ctor_id));
Brian Anderson33294c72011-06-27 22:20:17288 encode_kind(ebml_w, 'y' as u8);
289 encode_type_param_count(ebml_w, tps);
290 encode_type(cx, ebml_w, ty::ty_fn_ret(cx.tcx, fn_ty));
Marijn Haverbeke31ec26d2011-06-30 10:35:19291 encode_symbol(cx, ebml_w, item.id);
Brian Anderson33294c72011-06-27 22:20:17292 ebml::end_tag(ebml_w);
293
294 index += [tup(ctor_id, ebml_w.writer.tell())];
295 ebml::start_tag(ebml_w, tag_items_data_item);
296 encode_def_id(ebml_w, local_def(ctor_id));
297 encode_kind(ebml_w, 'f' as u8);
298 encode_type_param_count(ebml_w, tps);
299 encode_type(cx, ebml_w, fn_ty);
300 encode_symbol(cx, ebml_w, ctor_id);
301 ebml::end_tag(ebml_w);
302 }
303 case (item_obj(_, ?tps, ?ctor_id)) {
Brian Andersond2362592011-07-07 17:10:10304 auto fn_ty = node_id_to_monotype(cx.tcx, ctor_id);
Brian Anderson33294c72011-06-27 22:20:17305
306 ebml::start_tag(ebml_w, tag_items_data_item);
307 encode_def_id(ebml_w, local_def(item.id));
308 encode_kind(ebml_w, 'y' as u8);
309 encode_type_param_count(ebml_w, tps);
310 encode_type(cx, ebml_w, ty::ty_fn_ret(cx.tcx, fn_ty));
311 ebml::end_tag(ebml_w);
312
313 index += [tup(ctor_id, ebml_w.writer.tell())];
314 ebml::start_tag(ebml_w, tag_items_data_item);
315 encode_def_id(ebml_w, local_def(ctor_id));
316 encode_kind(ebml_w, 'f' as u8);
317 encode_type_param_count(ebml_w, tps);
318 encode_type(cx, ebml_w, fn_ty);
319 encode_symbol(cx, ebml_w, ctor_id);
320 ebml::end_tag(ebml_w);
321 }
322 }
323}
324
325fn encode_info_for_native_item(&@crate_ctxt cx, &ebml::writer ebml_w,
326 &@native_item nitem) {
327 ebml::start_tag(ebml_w, tag_items_data_item);
328 alt (nitem.node) {
329 case (native_item_ty) {
330 encode_def_id(ebml_w, local_def(nitem.id));
331 encode_kind(ebml_w, 'T' as u8);
Marijn Haverbeke77f5d142011-07-01 16:39:24332 encode_type(cx, ebml_w,
333 ty::mk_native(cx.tcx, local_def(nitem.id)));
Brian Anderson33294c72011-06-27 22:20:17334 }
335 case (native_item_fn(_, _, ?tps)) {
336 encode_def_id(ebml_w, local_def(nitem.id));
337 encode_kind(ebml_w, 'F' as u8);
338 encode_type_param_count(ebml_w, tps);
Brian Andersond2362592011-07-07 17:10:10339 encode_type(cx, ebml_w, node_id_to_monotype(cx.tcx, nitem.id));
Brian Anderson33294c72011-06-27 22:20:17340 encode_symbol(cx, ebml_w, nitem.id);
341 }
342 }
343 ebml::end_tag(ebml_w);
344}
345
346fn encode_info_for_items(&@crate_ctxt cx, &ebml::writer ebml_w) ->
347 vec[tup(int, uint)] {
348 let vec[tup(int, uint)] index = [];
349 ebml::start_tag(ebml_w, tag_items_data);
Graydon Hoarec796a8f2011-06-29 22:11:20350 for each (@tup(node_id, middle::ast_map::ast_node) kvp in
351 cx.ast_map.items()) {
Brian Anderson33294c72011-06-27 22:20:17352 alt (kvp._1) {
353 case (middle::ast_map::node_item(?i)) {
354 index += [tup(kvp._0, ebml_w.writer.tell())];
355 encode_info_for_item(cx, ebml_w, i, index);
356 }
357 case (middle::ast_map::node_native_item(?i)) {
358 index += [tup(kvp._0, ebml_w.writer.tell())];
359 encode_info_for_native_item(cx, ebml_w, i);
360 }
361 case (_) {}
362 }
363 }
364 ebml::end_tag(ebml_w);
365 ret index;
366}
367
368
369// Path and definition ID indexing
370
Brian Anderson33294c72011-06-27 22:20:17371fn create_index[T](&vec[tup(T, uint)] index, fn(&T) -> uint hash_fn) ->
372 vec[vec[tup(T, uint)]] {
373 let vec[mutable vec[tup(T, uint)]] buckets = vec::empty_mut();
374 for each (uint i in uint::range(0u, 256u)) { buckets += [mutable []]; }
375 for (tup(T, uint) elt in index) {
376 auto h = hash_fn(elt._0);
377 buckets.(h % 256u) += [elt];
378 }
379 ret vec::freeze(buckets);
380}
381
382fn encode_index[T](&ebml::writer ebml_w, &vec[vec[tup(T, uint)]] buckets,
383 fn(&io::writer, &T) write_fn) {
384 auto writer = io::new_writer_(ebml_w.writer);
385 ebml::start_tag(ebml_w, tag_index);
386 let vec[uint] bucket_locs = [];
387 ebml::start_tag(ebml_w, tag_index_buckets);
388 for (vec[tup(T, uint)] bucket in buckets) {
389 bucket_locs += [ebml_w.writer.tell()];
390 ebml::start_tag(ebml_w, tag_index_buckets_bucket);
391 for (tup(T, uint) elt in bucket) {
392 ebml::start_tag(ebml_w, tag_index_buckets_bucket_elt);
393 writer.write_be_uint(elt._1, 4u);
394 write_fn(writer, elt._0);
395 ebml::end_tag(ebml_w);
396 }
397 ebml::end_tag(ebml_w);
398 }
399 ebml::end_tag(ebml_w);
400 ebml::start_tag(ebml_w, tag_index_table);
401 for (uint pos in bucket_locs) { writer.write_be_uint(pos, 4u); }
402 ebml::end_tag(ebml_w);
403 ebml::end_tag(ebml_w);
404}
405
406fn write_str(&io::writer writer, &str s) { writer.write_str(s); }
407
408fn write_int(&io::writer writer, &int n) {
409 writer.write_be_uint(n as uint, 4u);
410}
411
Brian Andersonf53c4f72011-06-28 02:41:48412fn encode_meta_item(&ebml::writer ebml_w, &meta_item mi) {
Brian Andersonf53c4f72011-06-28 02:41:48413 alt (mi.node) {
Brian Andersoncab73f82011-06-28 06:02:02414 case (meta_word(?name)) {
415 ebml::start_tag(ebml_w, tag_meta_item_word);
416 ebml::start_tag(ebml_w, tag_meta_item_name);
417 ebml_w.writer.write(str::bytes(name));
418 ebml::end_tag(ebml_w);
419 ebml::end_tag(ebml_w);
420 }
421 case (meta_name_value(?name, ?value)) {
Brian Anderson2cb12932011-07-06 00:01:23422 alt (value.node) {
423 case (lit_str(?value, _)) {
424 ebml::start_tag(ebml_w, tag_meta_item_name_value);
425 ebml::start_tag(ebml_w, tag_meta_item_name);
426 ebml_w.writer.write(str::bytes(name));
427 ebml::end_tag(ebml_w);
428 ebml::start_tag(ebml_w, tag_meta_item_value);
429 ebml_w.writer.write(str::bytes(value));
430 ebml::end_tag(ebml_w);
431 ebml::end_tag(ebml_w);
432 }
433 case (_) { /* FIXME (#611) */ }
434 }
Brian Anderson33294c72011-06-27 22:20:17435 }
Brian Andersoncab73f82011-06-28 06:02:02436 case (meta_list(?name, ?items)) {
437 ebml::start_tag(ebml_w, tag_meta_item_list);
438 ebml::start_tag(ebml_w, tag_meta_item_name);
439 ebml_w.writer.write(str::bytes(name));
440 ebml::end_tag(ebml_w);
441 for (@meta_item inner_item in items) {
442 encode_meta_item(ebml_w, *inner_item);
443 }
444 ebml::end_tag(ebml_w);
Brian Andersonf53c4f72011-06-28 02:41:48445 }
446 }
Brian Andersonf53c4f72011-06-28 02:41:48447}
448
449fn encode_attributes(&ebml::writer ebml_w, &vec[attribute] attrs) {
450 ebml::start_tag(ebml_w, tag_attributes);
451 for (attribute attr in attrs) {
452 ebml::start_tag(ebml_w, tag_attribute);
453 encode_meta_item(ebml_w, attr.node.value);
Brian Anderson33294c72011-06-27 22:20:17454 ebml::end_tag(ebml_w);
455 }
Brian Andersonf53c4f72011-06-28 02:41:48456 ebml::end_tag(ebml_w);
457}
458
Graydon Hoarec796a8f2011-06-29 22:11:20459// So there's a special crate attribute called 'link' which defines the
460// metadata that Rust cares about for linking crates. This attribute requires
Brian Anderson70a28dc2011-07-01 00:03:08461// 'name' and 'vers' items, so if the user didn't provide them we will throw
Graydon Hoarec796a8f2011-06-29 22:11:20462// them in anyway with default values.
Brian Anderson29afe1a2011-06-29 21:17:23463fn synthesize_crate_attrs(&@crate_ctxt cx,
464 &@crate crate) -> vec[attribute] {
465
Patrick Walton401b6362011-07-06 00:57:34466 fn synthesize_link_attr(&@crate_ctxt cx, &(@meta_item)[] items)
467 -> attribute {
Brian Anderson29afe1a2011-06-29 21:17:23468
Brian Anderson70a28dc2011-07-01 00:03:08469 assert cx.link_meta.name != "";
470 assert cx.link_meta.vers != "";
Brian Anderson29afe1a2011-06-29 21:17:23471
Brian Anderson2cb12932011-07-06 00:01:23472 auto name_item = attr::mk_name_value_item_str("name",
473 cx.link_meta.name);
474 auto vers_item = attr::mk_name_value_item_str("vers",
475 cx.link_meta.vers);
Brian Anderson29afe1a2011-06-29 21:17:23476
477 auto other_items = {
478 auto tmp = attr::remove_meta_items_by_name(items, "name");
479 attr::remove_meta_items_by_name(tmp, "vers")
480 };
481
Patrick Walton401b6362011-07-06 00:57:34482 auto meta_items = ~[name_item, vers_item] + other_items;
Brian Anderson70a28dc2011-07-01 00:03:08483 auto link_item = attr::mk_list_item("link", meta_items);
Brian Anderson29afe1a2011-06-29 21:17:23484
Brian Anderson70a28dc2011-07-01 00:03:08485 ret attr::mk_attr(link_item);
Brian Anderson29afe1a2011-06-29 21:17:23486 }
487
488 let vec[attribute] attrs = [];
489 auto found_link_attr = false;
490 for (attribute attr in crate.node.attrs) {
491 attrs += if (attr::get_attr_name(attr) != "link") {
492 [attr]
493 } else {
494 alt (attr.node.value.node) {
495 case (meta_list(?n, ?l)) {
496 found_link_attr = true;
497 [synthesize_link_attr(cx, l)]
498 }
499 case (_) { [attr] }
500 }
501 }
502 }
503
504 if (!found_link_attr) {
Patrick Walton401b6362011-07-06 00:57:34505 attrs += [synthesize_link_attr(cx, ~[])];
Brian Anderson29afe1a2011-06-29 21:17:23506 }
507
508 ret attrs;
509}
510
Brian Anderson33294c72011-06-27 22:20:17511fn encode_metadata(&@crate_ctxt cx, &@crate crate) -> str {
512 auto string_w = io::string_writer();
513 auto buf_w = string_w.get_writer().get_buf_writer();
514 auto ebml_w = ebml::create_writer(buf_w);
Brian Anderson33294c72011-06-27 22:20:17515
Brian Anderson29afe1a2011-06-29 21:17:23516 auto crate_attrs = synthesize_crate_attrs(cx, crate);
517 encode_attributes(ebml_w, crate_attrs);
Brian Anderson33294c72011-06-27 22:20:17518 // Encode and index the paths.
519
520 ebml::start_tag(ebml_w, tag_paths);
521 auto paths_index = encode_item_paths(ebml_w, crate);
522 auto str_writer = write_str;
523 auto path_hasher = hash_path;
524 auto paths_buckets = create_index[str](paths_index, path_hasher);
525 encode_index[str](ebml_w, paths_buckets, str_writer);
526 ebml::end_tag(ebml_w);
527 // Encode and index the items.
528
529 ebml::start_tag(ebml_w, tag_items);
530 auto items_index = encode_info_for_items(cx, ebml_w);
531 auto int_writer = write_int;
Brian Andersonb7230822011-07-07 19:12:25532 auto item_hasher = hash_node_id;
Brian Anderson33294c72011-06-27 22:20:17533 auto items_buckets = create_index[int](items_index, item_hasher);
534 encode_index[int](ebml_w, items_buckets, int_writer);
535 ebml::end_tag(ebml_w);
536 // Pad this, since something (LLVM, presumably) is cutting off the
537 // remaining % 4 bytes.
538
539 buf_w.write([0u8, 0u8, 0u8, 0u8]);
540 ret string_w.get_str();
541}
Brian Anderson894e2222011-06-28 02:16:16542
543
544// Local Variables:
545// mode: rust
546// fill-column: 78;
547// indent-tabs-mode: nil
548// c-basic-offset: 4
549// buffer-file-coding-system: utf-8-unix
550// compile-command: "make -k -C $RBUILD 2>&1 | sed -e 's/\\/x\\//x:\\//g'";
551// End: