2016-06-02 7 views
5

手続き型マクロでBinaryOpsをメソッドに置き換えたいエラーが発生した場合、ユーザーが完全に混乱しないようにスパンを設定するにはどうすればよいですか?手続き型マクロのスパンを正しく扱うには?

+0

例を挙げることができますか?スパンにBinaryOpまたはバイナリ式全体をハイライト表示させたいのですか? – kennytm

+0

すべてのExprにはスパンが必要です。元の 'BinaryOp''Exp'演算子' Expr's(変更されていないので、 'Span'sを保持します)、新しく作成された' MethodCall''Exp''と ' 'Expr'とメソッドの' Ident'を返します。私が興味を持っているのは後者の2つの「スパン」です。 – llogiq

答えて

1

rustcのソースを調べた後、「拡張」モデルに従えば最良の結果が得られるとの結論に達しました。したがって、オリジナルはSpanですが、を呼び出して取得できるexpn_idの場合はそのままです。

質問に記載されている両方のケースでこれを設定することをお勧めします。 オペレータは(ファンクションコール)パスに展開され、元のバイナリオペレーションの式が関数呼び出しに展開されています。コード内:

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 
    } 
    .. 
} 
関連する問題