1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
use crate::hir::apply_use_clauses;
use crate::hir::prelude::*;
use crate::hir::TypeDecl2;
#[derive(Debug)]
pub struct Package2<'t> {
id: NodeId,
span: Span,
name: Spanned<Name>,
decls: Vec<&'t LatentNode<'t, Decl2<'t>>>,
scope: &'t ScopeData<'t>,
}
impl<'t> Package2<'t> {
pub fn name(&self) -> Spanned<Name> {
self.name
}
pub fn decls(&self) -> &[&'t LatentNode<'t, Decl2<'t>>] {
&self.decls
}
pub fn scope(&self) -> &'t ScopeData<'t> {
self.scope
}
}
impl<'t> FromAst<'t> for Package2<'t> {
type AllocInput = &'t ast::PkgDecl;
type LatentInput = Self::AllocInput;
type Context = AllocContext<'t>;
type Latent = &'t Slot<'t, Self>;
fn alloc_slot(ast: Self::AllocInput, context: Self::Context) -> Result<Self::Latent> {
let slot = context.alloc(Slot::new(ast, context));
context.define(ast.name.map(Into::into), Def2::Pkg(slot))?;
Ok(slot)
}
fn from_ast(ast: Self::LatentInput, context: Self::Context) -> Result<Self> {
debugln!("create package decl {}", ast.name.value);
let context = context.create_subscope();
let mut uses = Vec::new();
let decls = ast
.decls
.iter()
.flat_map(|decl| -> Option<&'t LatentNode<'t, Decl2>> {
match *decl {
ast::DeclItem::PkgDecl(ref decl) => {
Some(Package2::alloc_slot(decl, context).ok()?)
}
ast::DeclItem::TypeDecl(ref decl) => {
Some(TypeDecl2::alloc_slot(decl, context).ok()?)
}
ast::DeclItem::UseClause(_, ref clause) => {
uses.extend(clause.value.iter());
None
}
_ => None,
}
})
.collect::<Vec<_>>();
apply_use_clauses(uses.into_iter(), context);
Ok(Package2 {
id: NodeId::alloc(),
span: ast.span,
name: ast.name,
decls: decls,
scope: context.scope(),
})
}
}
impl<'t> Node<'t> for Package2<'t> {
fn span(&self) -> Span {
self.span
}
fn desc_kind(&self) -> String {
"package".into()
}
fn desc_name(&self) -> String {
format!("package `{}`", self.name.value)
}
fn accept(&'t self, visitor: &mut Visitor<'t>) {
visitor.visit_pkg(self);
}
fn walk(&'t self, visitor: &mut Visitor<'t>) {
visitor.visit_name(self.name);
for decl in &self.decls {
decl.accept(visitor);
}
}
}
impl<'t> Decl2<'t> for Package2<'t> {
fn name(&self) -> Spanned<ResolvableName> {
self.name.map(Into::into)
}
}