@@ -25,7 +25,7 @@ tag scope {
25
25
type env = rec ( list[ scope] scopes ,
26
26
session . session sess) ;
27
27
28
- type import_map = std. map. hashmap [ ast. def_id , def ] ;
28
+ type import_map = std. map. hashmap [ ast. def_id , def_wrap ] ;
29
29
30
30
// A simple wrapper over defs that stores a bit more information about modules
31
31
// and uses so that we can use the regular lookup_name when resolving imports.
@@ -34,68 +34,74 @@ tag def_wrap {
34
34
def_wrap_import ( @ast. view_item ) ;
35
35
def_wrap_mod ( @ast. item ) ;
36
36
def_wrap_other ( def) ;
37
+ def_wrap_resolving;
37
38
}
38
39
39
- fn lookup_name ( & env e, import_map index,
40
- ast . ident i) -> option. t[ def ] {
41
- auto d_ = lookup_name_wrapped ( e, i) ;
42
- alt ( d_) {
43
- case ( none[ tup ( @env, def_wrap) ] ) {
44
- ret none[ def] ;
45
- }
46
- case ( some[ tup ( @env, def_wrap) ] ( ?d) ) {
47
- alt ( d. _1 ) {
48
- case ( def_wrap_use ( ?it) ) {
49
- alt ( it. node ) {
50
- case ( ast. view_item_use ( _, _, ?id) ) {
51
- ret some[ def] ( ast. def_use ( id) ) ;
52
- }
53
- }
40
+ fn unwrap_def ( def_wrap d) -> def {
41
+ alt ( d) {
42
+ case ( def_wrap_use ( ?it) ) {
43
+ alt ( it. node ) {
44
+ case ( ast. view_item_use ( _, _, ?id) ) {
45
+ ret ast. def_use ( id) ;
54
46
}
55
- case ( def_wrap_import ( ?it) ) {
56
- alt ( it. node ) {
57
- case ( ast. view_item_import ( _, ?id) ) {
58
- ret index. find ( id) ;
47
+ }
48
+ }
49
+ case ( def_wrap_import ( ?it) ) {
50
+ alt ( it. node ) {
51
+ case ( ast. view_item_import ( _, ?id, ?target_def) ) {
52
+ alt ( target_def) {
53
+ case ( some[ def] ( ?d) ) {
54
+ ret d;
59
55
}
60
- }
61
- }
62
- case ( def_wrap_mod ( ?i) ) {
63
- alt ( i. node ) {
64
- case ( ast. item_mod ( _, _, ?id) ) {
65
- ret some[ def] ( ast. def_mod ( id) ) ;
56
+ case ( none[ def] ) {
57
+ fail;
66
58
}
67
59
}
68
60
}
69
- case ( def_wrap_other ( ?d) ) {
70
- ret some[ def] ( d) ;
61
+ }
62
+ }
63
+ case ( def_wrap_mod ( ?m) ) {
64
+ alt ( m. node ) {
65
+ case ( ast. item_mod ( _, _, ?id) ) {
66
+ ret ast. def_mod ( id) ;
71
67
}
72
68
}
73
69
}
70
+ case ( def_wrap_other ( ?d) ) {
71
+ ret d;
72
+ }
73
+ }
74
+ }
75
+
76
+ fn lookup_name ( & env e, ast . ident i) -> option. t[ def ] {
77
+ auto d_ = lookup_name_wrapped ( e, i) ;
78
+ alt ( d_) {
79
+ case ( none[ tup ( @env, def_wrap) ] ) {
80
+ ret none[ def] ;
81
+ }
82
+ case ( some[ tup ( @env, def_wrap) ] ( ?d) ) {
83
+ ret some ( unwrap_def ( d. _1 ) ) ;
84
+ }
74
85
}
75
86
}
76
87
77
88
// Follow the path of an import and return what it ultimately points to.
78
89
79
- fn find_final_def ( & env e, & span sp, vec[ ident] idents ) -> def_wrap {
90
+ fn find_final_def ( & env e, import_map index,
91
+ & span sp, vec[ ident] idents ,
92
+ ast. def_id import_id ) -> def_wrap {
80
93
81
94
// We are given a series of identifiers (a.b.c.d) and we know that
82
95
// in the environment 'e' the identifier 'a' was resolved to 'd'. We
83
96
// should return what a.b.c.d points to in the end.
84
- fn found_something ( & env e, std . map . hashmap [ ast . def_id , bool ] pending ,
97
+ fn found_something ( & env e, import_map index ,
85
98
& span sp, vec[ ident] idents , def_wrap d) -> def_wrap {
86
99
alt ( d) {
87
100
case ( def_wrap_import ( ?imp) ) {
88
101
alt ( imp. node ) {
89
- case ( ast. view_item_import ( ?new_idents, ?d) ) {
90
- if ( pending. contains_key ( d) ) {
91
- e. sess . span_err ( sp,
92
- "cyclic import" ) ;
93
- fail;
94
- }
95
- pending. insert ( d, true ) ;
96
- auto x = inner ( e, pending, sp, new_idents) ;
97
- pending. remove ( d) ;
98
- ret found_something ( e, pending, sp, idents, x) ;
102
+ case ( ast. view_item_import ( ?new_idents, ?d, _) ) {
103
+ auto x = inner ( e, index, sp, new_idents, d) ;
104
+ ret found_something ( e, index, sp, idents, x) ;
99
105
}
100
106
}
101
107
}
@@ -121,7 +127,7 @@ fn find_final_def(&env e, &span sp, vec[ident] idents) -> def_wrap {
121
127
}
122
128
case ( some[ tup ( @env, def_wrap) ] ( ?next) ) {
123
129
auto combined_e = update_env_for_item ( e, i) ;
124
- ret found_something ( combined_e, pending , sp,
130
+ ret found_something ( combined_e, index , sp,
125
131
rest_idents, next. _1 ) ;
126
132
}
127
133
}
@@ -136,22 +142,40 @@ fn find_final_def(&env e, &span sp, vec[ident] idents) -> def_wrap {
136
142
}
137
143
fail;
138
144
}
139
- fn inner ( & env e, std. map. hashmap[ ast. def_id, bool] pending ,
140
- & span sp, vec[ ident] idents ) -> def_wrap {
145
+
146
+ fn inner ( & env e, import_map index, & span sp, vec[ ident] idents ,
147
+ ast. def_id import_id ) -> def_wrap {
148
+ alt ( index. find ( import_id) ) {
149
+ case ( some[ def_wrap] ( ?x) ) {
150
+ alt ( x) {
151
+ case ( def_wrap_resolving) {
152
+ e. sess . span_err ( sp, "cyclic import" ) ;
153
+ fail;
154
+ }
155
+ case ( _) {
156
+ ret x;
157
+ }
158
+ }
159
+ }
160
+ case ( none[ def_wrap] ) {
161
+ }
162
+ }
141
163
auto first = idents. ( 0 ) ;
164
+ index. insert ( import_id, def_wrap_resolving) ;
142
165
auto d_ = lookup_name_wrapped ( e, first) ;
143
166
alt ( d_) {
144
167
case ( none[ tup ( @env, def_wrap) ] ) {
145
168
e. sess . span_err ( sp, "unresolved name: " + first) ;
146
169
fail;
147
170
}
148
171
case ( some[ tup ( @env, def_wrap) ] ( ?d) ) {
149
- ret found_something ( * d. _0 , pending, sp, idents, d. _1 ) ;
172
+ auto x = found_something ( * d. _0 , index, sp, idents, d. _1 ) ;
173
+ index. insert ( import_id, x) ;
174
+ ret x;
150
175
}
151
176
}
152
177
}
153
- auto pending = new_def_hash[ bool] ( ) ;
154
- ret inner( e, pending, sp, idents) ;
178
+ ret inner( e, index, sp, idents, import_id) ;
155
179
}
156
180
157
181
fn lookup_name_wrapped ( & env e, ast . ident i) -> option. t[ tup ( @env , def_wrap ) ] {
@@ -203,7 +227,7 @@ fn lookup_name_wrapped(&env e, ast.ident i) -> option.t[tup(@env, def_wrap)] {
203
227
case ( ast. view_item_use ( _, _, ?id) ) {
204
228
ret def_wrap_use ( i) ;
205
229
}
206
- case ( ast. view_item_import ( ?idents, ?d) ) {
230
+ case ( ast. view_item_import ( ?idents, ?d, _ ) ) {
207
231
ret def_wrap_import ( i) ;
208
232
}
209
233
}
@@ -327,11 +351,11 @@ fn lookup_name_wrapped(&env e, ast.ident i) -> option.t[tup(@env, def_wrap)] {
327
351
}
328
352
}
329
353
330
- fn fold_pat_tag ( & env e, & span sp, import_map index , ident i ,
331
- vec [ @ast . pat ] args , option. t[ ast. variant_def] old_def ,
354
+ fn fold_pat_tag ( & env e, & span sp, ident i , vec [ @ast . pat ] args ,
355
+ option. t[ ast. variant_def] old_def ,
332
356
ann a) -> @ast . pat {
333
357
auto new_def;
334
- alt ( lookup_name ( e, index , i) ) {
358
+ alt ( lookup_name ( e, i) ) {
335
359
case ( some[ def] ( ?d) ) {
336
360
alt ( d) {
337
361
case ( ast. def_variant ( ?did, ?vid) ) {
@@ -372,8 +396,8 @@ fn fold_pat_tag(&env e, &span sp, import_map index, ident i,
372
396
// and split that off as the 'primary' expr_path, with secondary expr_field
373
397
// expressions tacked on the end.
374
398
375
- fn fold_expr_path ( & env e, & span sp, import_map index ,
376
- & ast . path p , & option . t [ def ] d , ann a) -> @ast . expr {
399
+ fn fold_expr_path ( & env e, & span sp, & ast . path p , & option . t [ def ] d ,
400
+ ann a) -> @ast . expr {
377
401
378
402
if ( _vec. len [ @ast. ty ] ( p. node . types ) > 0 u) {
379
403
e. sess . unimpl ( "resolving name expr with ty params" ) ;
@@ -384,7 +408,7 @@ fn fold_expr_path(&env e, &span sp, import_map index,
384
408
check ( n_idents != 0 u) ;
385
409
auto id0 = p. node . idents . ( 0 ) ;
386
410
387
- auto d_ = lookup_name ( e, index , id0) ;
411
+ auto d_ = lookup_name ( e, id0) ;
388
412
389
413
alt ( d_) {
390
414
case ( some[ def] ( _) ) {
@@ -413,30 +437,19 @@ fn fold_expr_path(&env e, &span sp, import_map index,
413
437
414
438
fn fold_view_item_import ( & env e, & span sp,
415
439
import_map index,
416
- vec[ ident] is , ast. def_id id ) -> @ast. view_item {
440
+ vec[ ident] is , ast. def_id id ,
441
+ option. t[ def] target_id ) -> @ast. view_item {
417
442
// Produce errors for invalid imports
418
443
auto len = _vec. len [ ast. ident ] ( is) ;
419
444
auto last_id = is. ( len - 1 u) ;
420
- auto d = find_final_def ( e, sp, is) ;
421
- alt ( d) {
422
- case ( def_wrap_mod ( ?m) ) {
423
- alt ( m. node ) {
424
- case ( ast. item_mod ( _, _, ?id) ) {
425
- index. insert ( id, ast. def_mod ( id) ) ;
426
- }
427
- }
428
- }
429
- case ( def_wrap_other ( ?target_def) ) {
430
- index. insert ( id, target_def) ;
431
- }
432
- }
433
-
434
- ret @fold. respan [ ast. view_item_ ] ( sp, ast. view_item_import ( is, id) ) ;
445
+ auto d = find_final_def ( e, index, sp, is, id) ;
446
+ let option. t[ def] target_def = some ( unwrap_def ( d) ) ;
447
+ ret @fold. respan [ ast. view_item_ ] ( sp, ast. view_item_import ( is, id,
448
+ target_def) ) ;
435
449
}
436
450
437
451
438
- fn fold_ty_path ( & env e, & span sp, import_map index, ast . path p,
439
- & option. t[ def] d ) -> @ast . ty {
452
+ fn fold_ty_path ( & env e, & span sp, ast . path p, & option. t[ def] d ) -> @ast . ty {
440
453
441
454
let uint len = _vec. len [ ast. ident ] ( p. node . idents ) ;
442
455
check ( len != 0 u) ;
@@ -448,7 +461,7 @@ fn fold_ty_path(&env e, &span sp, import_map index, ast.path p,
448
461
e. sess . unimpl ( "resolving path ty with ty params" ) ;
449
462
}
450
463
451
- auto d_ = lookup_name ( e, index , p. node . idents . ( 0 ) ) ;
464
+ auto d_ = lookup_name ( e, p. node . idents . ( 0 ) ) ;
452
465
453
466
alt ( d_) {
454
467
case ( some[ def] ( ?d) ) {
@@ -478,16 +491,33 @@ fn update_env_for_arm(&env e, &ast.arm p) -> env {
478
491
ret rec ( scopes = cons[ scope] ( scope_arm ( p) , @e. scopes ) with e) ;
479
492
}
480
493
494
+ fn resolve_imports ( session . session sess, @ast. crate crate) -> @ast. crate {
495
+ let fold. ast_fold[ env] fld = fold. new_identity_fold [ env] ( ) ;
496
+
497
+ auto import_index = new_def_hash[ def_wrap] ( ) ;
498
+ fld = @rec ( fold_view_item_import
499
+ = bind fold_view_item_import ( _, _, import_index, _, _, _) ,
500
+ update_env_for_crate = bind update_env_for_crate ( _, _) ,
501
+ update_env_for_item = bind update_env_for_item ( _, _) ,
502
+ update_env_for_block = bind update_env_for_block ( _, _) ,
503
+ update_env_for_arm = bind update_env_for_arm ( _, _)
504
+ with * fld ) ;
505
+
506
+ auto e = rec ( scopes = nil[ scope] ,
507
+ sess = sess) ;
508
+
509
+ ret fold. fold_crate [ env] ( e, fld, crate ) ;
510
+ }
511
+
481
512
fn resolve_crate ( session . session sess, @ast. crate crate) -> @ast. crate {
482
513
483
514
let fold. ast_fold[ env] fld = fold. new_identity_fold [ env] ( ) ;
484
515
485
- auto import_index = new_def_hash[ def] ( ) ;
486
- fld = @rec ( fold_pat_tag = bind fold_pat_tag ( _, _, import_index, _, _, _, _) ,
487
- fold_expr_path = bind fold_expr_path ( _, _, import_index, _, _, _) ,
488
- fold_view_item_import
489
- = bind fold_view_item_import ( _, _, import_index, _, _) ,
490
- fold_ty_path = bind fold_ty_path ( _, _, import_index, _, _) ,
516
+ auto new_crate = resolve_imports ( sess, crate ) ;
517
+
518
+ fld = @rec ( fold_pat_tag = bind fold_pat_tag ( _, _, _, _, _, _) ,
519
+ fold_expr_path = bind fold_expr_path ( _, _, _, _, _) ,
520
+ fold_ty_path = bind fold_ty_path ( _, _, _, _) ,
491
521
update_env_for_crate = bind update_env_for_crate ( _, _) ,
492
522
update_env_for_item = bind update_env_for_item ( _, _) ,
493
523
update_env_for_block = bind update_env_for_block ( _, _) ,
@@ -497,7 +527,7 @@ fn resolve_crate(session.session sess, @ast.crate crate) -> @ast.crate {
497
527
auto e = rec ( scopes = nil[ scope] ,
498
528
sess = sess) ;
499
529
500
- ret fold. fold_crate [ env] ( e, fld, crate ) ;
530
+ ret fold. fold_crate [ env] ( e, fld, new_crate ) ;
501
531
}
502
532
503
533
// Local Variables:
0 commit comments