@@ -321,7 +321,7 @@ impure fn resolve_path(vec[ast.ident] path, vec[u8] data) -> resolve_result {
321
321
fail;
322
322
}
323
323
324
- impure fn move_to_item ( & ebml. reader ebml_r, ast . def_id did ) {
324
+ impure fn move_to_item ( & ebml. reader ebml_r, int item_id ) {
325
325
while ( ebml. bytes_left ( ebml_r) > 0 u) {
326
326
auto outer_ebml_tag = ebml. peek ( ebml_r) ;
327
327
if ( outer_ebml_tag. id == metadata. tag_items ) {
@@ -341,8 +341,7 @@ impure fn move_to_item(&ebml.reader ebml_r, ast.def_id did) {
341
341
ebml. move_to_parent ( ebml_r) ;
342
342
343
343
auto this_did = parse_def_id ( did_data) ;
344
- if ( did. _0 == this_did. _0 &&
345
- did. _1 == this_did. _1 ) {
344
+ if ( this_did. _1 == item_id) {
346
345
// Move to the start of this item's data.
347
346
ebml. move_to_parent ( ebml_r) ;
348
347
ebml. move_to_first_child ( ebml_r) ;
@@ -360,58 +359,102 @@ impure fn move_to_item(&ebml.reader ebml_r, ast.def_id did) {
360
359
ebml. move_to_next_sibling ( ebml_r) ;
361
360
}
362
361
363
- log #fmt( "move_to_item: item not found: %d:%d " , did . _0 , did . _1 ) ;
362
+ log #fmt( "move_to_item: item not found: %d" , item_id ) ;
364
363
}
365
364
366
365
// Looks up an item in the given metadata and returns an EBML reader pointing
367
366
// to the item data.
368
- impure fn lookup_item ( ast . def_id did , vec[ u8] data) -> ebml. reader {
367
+ impure fn lookup_item ( int item_id , vec[ u8] data ) -> ebml. reader {
369
368
auto io_r = io. new_reader_ ( io. new_byte_buf_reader ( data) ) ;
370
369
auto ebml_r = ebml. create_reader ( io_r) ;
371
- move_to_item ( ebml_r, did ) ;
370
+ move_to_item ( ebml_r, item_id ) ;
372
371
ret ebml_r;
373
372
}
374
373
375
- impure fn get_item_kind ( & ebml. reader ebml_r) -> u8 {
374
+ impure fn get_item_generic[ T ] ( & ebml. reader ebml_r, uint tag_id,
375
+ impure fn( vec[ u8] buf) -> T converter) -> T {
376
376
while ( ebml. bytes_left ( ebml_r) > 0 u) {
377
377
auto ebml_tag = ebml. peek ( ebml_r) ;
378
- if ( ebml_tag. id == metadata . tag_items_kind ) {
378
+ if ( ebml_tag. id == tag_id ) {
379
379
ebml. move_to_first_child ( ebml_r) ;
380
- auto kind_ch = ebml. read_data ( ebml_r) . ( 0 ) ;
380
+ auto result = converter ( ebml. read_data ( ebml_r) ) ;
381
381
382
- // Reset the EBML reader so the callee can use it to look up
383
- // additional info about the item.
382
+ // Be kind, rewind.
384
383
ebml. move_to_parent ( ebml_r) ;
385
384
ebml. move_to_parent ( ebml_r) ;
386
385
ebml. move_to_first_child ( ebml_r) ;
387
386
388
- ret kind_ch ;
387
+ ret result ;
389
388
}
390
389
ebml. move_to_next_sibling ( ebml_r) ;
391
390
}
392
391
393
- log "get_item_kind (): no kind found";
392
+ log # fmt ( "get_item_generic (): tag %u not found", tag_id ) ;
394
393
fail;
395
394
}
396
395
396
+ impure fn get_item_kind ( & ebml. reader ebml_r) -> u8 {
397
+ impure fn converter ( vec[ u8] data) -> u8 {
398
+ auto x = @mutable 3 ;
399
+ * x = 5 ;
400
+ ret data. ( 0 ) ;
401
+ }
402
+ auto f = converter;
403
+ ret get_item_generic[ u8] ( ebml_r, metadata. tag_items_kind , f) ;
404
+ }
405
+
406
+ // FIXME: This is a *terrible* botch.
407
+ impure fn impure_parse_def_id( vec[ u8] data) -> ast. def_id {
408
+ auto x = @mutable 3 ;
409
+ * x = 5 ;
410
+ ret parse_def_id ( data) ;
411
+ }
412
+
397
413
impure fn get_variant_tag_id ( & ebml. reader ebml_r) -> ast. def_id {
414
+ auto f = impure_parse_def_id;
415
+ ret get_item_generic[ ast. def_id ] ( ebml_r, metadata. tag_items_tag_id , f) ;
416
+ }
417
+
418
+ impure fn get_item_type ( & ebml. reader ebml_r , int this_cnum ) -> @ty. t {
419
+ impure fn converter ( int this_cnum , vec[ u8] data ) -> @ty. t {
420
+ fn parse_external_def_id ( int this_cnum , str s) -> ast. def_id {
421
+ // FIXME: This is completely wrong when linking against a crate
422
+ // that, in turn, links against another crate. We need a mapping
423
+ // from crate ID to crate "meta" attributes as part of the crate
424
+ // metadata.
425
+ auto buf = _str. bytes ( s) ;
426
+ auto external_def_id = parse_def_id ( buf) ;
427
+ ret tup( this_cnum, external_def_id. _1 ) ;
428
+ }
429
+ auto s = _str. unsafe_from_bytes ( data) ;
430
+ ret parse_ty_str ( s, bind parse_external_def_id ( this_cnum, _) ) ;
431
+ }
432
+ auto f = bind converter ( this_cnum, _) ;
433
+ ret get_item_generic[ @ty. t] ( ebml_r, metadata. tag_items_type , f) ;
434
+ }
435
+
436
+ impure fn get_item_ty_params ( & ebml. reader ebml_r, int this_cnum)
437
+ -> vec[ ast. def_id ] {
438
+ let vec[ ast. def_id ] tps = vec ( ) ;
398
439
while ( ebml. bytes_left ( ebml_r) > 0 u) {
399
440
auto ebml_tag = ebml. peek ( ebml_r) ;
400
- if ( ebml_tag. id == metadata. tag_items_tag_id ) {
441
+ if ( ebml_tag. id == metadata. tag_items_ty_param ) {
401
442
ebml. move_to_first_child ( ebml_r) ;
402
- auto tid = parse_def_id ( ebml. read_data ( ebml_r) ) ;
403
443
404
- // Be kind, rewind.
405
- ebml. move_to_parent ( ebml_r) ;
406
- ebml. move_to_parent ( ebml_r) ;
407
- ebml. move_to_first_child ( ebml_r) ;
444
+ auto data = ebml. read_data ( ebml_r) ;
445
+ auto external_def_id = parse_def_id ( data) ;
446
+ tps += vec ( tup ( this_cnum, external_def_id. _1 ) ) ;
408
447
409
- ret tid ;
448
+ ebml . move_to_parent ( ebml_r ) ;
410
449
}
450
+ ebml. move_to_next_sibling ( ebml_r) ;
411
451
}
412
452
413
- log "get_variant_tag_id(): no tag ID found" ;
414
- fail;
453
+ // Be kind, rewind.
454
+ ebml. move_to_parent ( ebml_r) ;
455
+ ebml. move_to_first_child ( ebml_r) ;
456
+
457
+ ret tps;
415
458
}
416
459
417
460
@@ -500,7 +543,7 @@ fn lookup_def(session.session sess, &span sp, int cnum, vec[ast.ident] path)
500
543
}
501
544
}
502
545
503
- auto ebml_r = lookup_item( did, data) ;
546
+ auto ebml_r = lookup_item( did. _1 , data) ;
504
547
auto kind_ch = get_item_kind( ebml_r) ;
505
548
506
549
did = tup( cnum, did. _1) ;
@@ -522,8 +565,12 @@ fn lookup_def(session.session sess, &span sp, int cnum, vec[ast.ident] path)
522
565
}
523
566
524
567
fn get_type( session. session sess, ast. def_id def) -> ty. ty_params_and_ty {
525
- // FIXME: fill in.
526
- fail;
568
+ auto external_crate_id = def. _0;
569
+ auto data = sess. get_external_crate( external_crate_id) ;
570
+ auto ebml_r = lookup_item( def. _1, data) ;
571
+ auto t = get_item_type( ebml_r, external_crate_id) ;
572
+ auto tps = get_item_ty_params( ebml_r, external_crate_id) ;
573
+ ret tup( tps, t) ;
527
574
}
528
575
529
576
// Local Variables:
0 commit comments