use{
std::cell::Cell,
crate::{
makepad_live_compiler::{
TokenSpan
},
shader_ast::*,
shader_registry::ShaderRegistry
}
};
#[derive(Clone)]
pub struct DepAnalyser<'a> {
pub fn_def: &'a FnDef,
pub shader_registry: &'a ShaderRegistry,
pub scopes: &'a Scopes,
}
impl<'a> DepAnalyser<'a> {
pub fn dep_analyse_expr(&mut self, expr: &Expr) {
match expr.kind {
ExprKind::Cond {
span,
ref expr,
ref expr_if_true,
ref expr_if_false,
} => self.dep_analyse_cond_expr(span, expr, expr_if_true, expr_if_false),
ExprKind::Bin {
span,
op,
ref left_expr,
ref right_expr,
} => self.dep_analyse_bin_expr(span, op, left_expr, right_expr),
ExprKind::Un {span, op, ref expr} => self.dep_analyse_un_expr(span, op, expr),
ExprKind::Field {
span,
ref expr,
field_ident,
} => self.dep_analyse_field_expr(span, expr, field_ident),
ExprKind::Index {
span,
ref expr,
ref index_expr,
} => self.dep_analyse_index_expr(span, expr, index_expr),
ExprKind::MethodCall {
span,
ident,
ref arg_exprs,
..
} => self.dep_analyse_method_call_expr(span, ident, arg_exprs),
ExprKind::PlainCall {
span,
ref arg_exprs,
ref param_index,
fn_ptr,
..
} => if param_index.get().is_none() {
self.dep_analyse_plain_call_expr(span, arg_exprs, fn_ptr.unwrap())
},
ExprKind::BuiltinCall {
span,
ident,
ref arg_exprs,
} => self.dep_analyse_builtin_call_expr(span, ident, arg_exprs),
ExprKind::ClosureDef(_) => (),
ExprKind::ConsCall {
span,
ty_lit,
ref arg_exprs,
} => self.dep_analyse_cons_call_expr(span, ty_lit, arg_exprs),
ExprKind::StructCons{
struct_ptr,
span,
ref args
} => self.dep_analyse_struct_cons(struct_ptr, span, args),
ExprKind::Var {
span,
ref kind,
..
} => self.dep_analyse_var_expr(span, expr.ty.borrow().as_ref(), kind),
ExprKind::Lit {span, lit} => self.dep_analyse_lit_expr(span, lit),
}
}
fn dep_analyse_cond_expr(
&mut self,
_span: TokenSpan,
expr: &Expr,
expr_if_true: &Expr,
expr_if_false: &Expr,
) {
self.dep_analyse_expr(expr);
self.dep_analyse_expr(expr_if_true);
self.dep_analyse_expr(expr_if_false);
}
fn dep_analyse_bin_expr(
&mut self,
_span: TokenSpan,
_op: BinOp,
left_expr: &Expr,
right_expr: &Expr,
) {
self.dep_analyse_expr(left_expr);
self.dep_analyse_expr(right_expr);
}
fn dep_analyse_un_expr(&mut self, _span: TokenSpan, _op: UnOp, expr: &Expr) {
self.dep_analyse_expr(expr);
}
fn dep_analyse_method_call_expr(
&mut self,
_span: TokenSpan,
method_ident: Ident,
arg_exprs: &[Expr],
) {
match arg_exprs[0].ty.borrow().as_ref().unwrap() {
Ty::Struct(struct_ptr) => {
for arg_expr in arg_exprs {
self.dep_analyse_expr(arg_expr);
}
let mut set = self.fn_def.callees.borrow_mut();
let struct_decl = self.shader_registry.structs.get(struct_ptr).unwrap();
if let Some(fn_node_ptr) = self.shader_registry.struct_method_ptr_from_ident(struct_decl, method_ident){
set.as_mut().unwrap().insert(fn_node_ptr);
}
}
Ty::DrawShader(shader_ptr)=>{
for arg_expr in arg_exprs {
self.dep_analyse_expr(arg_expr);
}
let mut set = self.fn_def.callees.borrow_mut();
let draw_shader_decl = self.shader_registry.draw_shader_defs.get(shader_ptr).unwrap();
if let Some(fn_node_ptr) = self.shader_registry.draw_shader_method_ptr_from_ident(draw_shader_decl, method_ident){
set.as_mut().unwrap().insert(fn_node_ptr);
}
}
_ => panic!(),
}
}
fn dep_analyse_builtin_call_expr(
&mut self,
_span: TokenSpan,
ident: Ident,
arg_exprs: &[Expr],
) {
for arg_expr in arg_exprs {
self.dep_analyse_expr(arg_expr);
}
self.fn_def
.builtin_deps
.borrow_mut()
.as_mut()
.unwrap()
.insert(ident);
}
fn dep_analyse_plain_call_expr(
&mut self,
_span: TokenSpan,
arg_exprs: &[Expr],
fn_ptr: FnPtr,
) {
for arg_expr in arg_exprs {
self.dep_analyse_expr(arg_expr);
}
let mut set = self.fn_def.callees.borrow_mut();
set.as_mut().unwrap().insert(fn_ptr);
}
fn dep_analyse_field_expr(&mut self, _span: TokenSpan, expr: &Expr, field_ident: Ident) {
match expr.ty.borrow().as_ref().unwrap(){
Ty::DrawShader(_)=>{
self.fn_def.draw_shader_refs.borrow_mut().as_mut().unwrap().insert(field_ident);
}
_=>{
self.dep_analyse_expr(expr)
}
}
}
fn dep_analyse_index_expr(&mut self, _span: TokenSpan, expr: &Expr, index_expr: &Expr) {
self.dep_analyse_expr(expr);
self.dep_analyse_expr(index_expr);
}
fn dep_analyse_cons_call_expr(&mut self, _span: TokenSpan, ty_lit: TyLit, arg_exprs: &[Expr]) {
for arg_expr in arg_exprs {
self.dep_analyse_expr(arg_expr);
}
self.fn_def
.constructor_fn_deps
.borrow_mut()
.as_mut()
.unwrap()
.insert((
ty_lit,
arg_exprs
.iter()
.map( | arg_expr | arg_expr.ty.borrow().as_ref().unwrap().clone())
.collect::<Vec<_ >> (),
));
}
fn dep_analyse_struct_cons(
&mut self,
struct_ptr: StructPtr,
_span: TokenSpan,
args: &Vec<(Ident,Expr)>,
) {
self.fn_def.struct_refs.borrow_mut().as_mut().unwrap().insert(struct_ptr);
for arg in args{
self.dep_analyse_expr(&arg.1);
}
}
fn dep_analyse_var_expr(&mut self, _span: TokenSpan, ty:Option<&Ty>, kind: &Cell<Option<VarKind >>) {
match kind.get().unwrap() {
VarKind::LiveValue(value_ptr)=>{
self.fn_def.live_refs.borrow_mut().as_mut().unwrap().insert(value_ptr, ty.unwrap().clone());
}
VarKind::Local{..} | VarKind::MutLocal{..}=>{ match ty{
Some(Ty::Struct(struct_ptr))=>{
self.fn_def.struct_refs.borrow_mut().as_mut().unwrap().insert(*struct_ptr);
}
Some(Ty::Array{..})=>{
todo!();
}
_=>()
}
},
};
}
fn dep_analyse_lit_expr(&mut self, _span: TokenSpan, _lit: Lit) {}
}