2016-06-02 9 views
5

Chcę, aby moje makro proceduralne zastąpiło niektóre BinaryOps metodami. Jak ustawić przęsła, aby w przypadku wystąpienia błędów moi użytkownicy nie byli całkowicie zdezorientowani?Jak poprawnie radzić sobie z rozpiętościami w makrach proceduralnych?

+0

Czy możesz podać przykład? Chcesz, aby zakres podświetlał tylko BinaryOp lub całe wyrażenie binarne? – kennytm

+0

Każdy Expr potrzebuje rozpiętości. Mamy oryginalne 'BinaryOp'' Expr', operatora 'Expr' (które są niezmienione, więc zachowują swoje' Span's), nowo utworzone 'MethodCall'' Expr' z 'Span's dla obu 'Expr' i" Ident "metody. To te dwa ostatnie "Span", którymi jestem zainteresowany. – llogiq

Odpowiedz

1

Po zapoznaniu się ze źródłem doszedłem do wniosku, że po modelu "ekspansji" daje najlepsze rezultaty. Tak więc zachowujemy oryginalny Span, ale dla expn_id, który możemy uzyskać dzwoniąc pod numer ExtCtxt::backtrace().

Wydaje się, że dobrym pomysłem jest ustawienie tego w obu przypadkach opisanych w pytaniu. Operator może być postrzegany jako rozwinięty w ścieżkę (wywołanie funkcji), a oryginalny wyrażenie binarne jako rozszerzony do wywołania funkcji. W kodzie:

match expr.unwrap() { 
    .. 
    Expr { node: ExprKind::Binary(Spanned { node: Add, span: op }, l, r), span, .. } => { 
     let bt = self.cx.backtrace(); // get the expansion ID 
     let path = self.cx.path(Span { expn_id: bt, ..op }, vec![crate_name, trait_name, fn_name]); 
     let epath = self.cx.expr_path(path); // path expression 
     let args_expanded = self.fold_exprs(args); 
     self.cx.expr_call(Span { expn_id: bt, ..span }, epath, args_expanded) 
     //^outer expression 
    } 
    .. 
} 
Powiązane problemy