5
手続き型マクロでBinaryOpsをメソッドに置き換えたいエラーが発生した場合、ユーザーが完全に混乱しないようにスパンを設定するにはどうすればよいですか?手続き型マクロのスパンを正しく扱うには?
手続き型マクロでBinaryOpsをメソッドに置き換えたいエラーが発生した場合、ユーザーが完全に混乱しないようにスパンを設定するにはどうすればよいですか?手続き型マクロのスパンを正しく扱うには?
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
}
..
}
例を挙げることができますか?スパンにBinaryOpまたはバイナリ式全体をハイライト表示させたいのですか? – kennytm
すべてのExprにはスパンが必要です。元の 'BinaryOp''Exp'演算子' Expr's(変更されていないので、 'Span'sを保持します)、新しく作成された' MethodCall''Exp''と ' 'Expr'とメソッドの' Ident'を返します。私が興味を持っているのは後者の2つの「スパン」です。 – llogiq