mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-27 05:23:24 +00:00
Merge #6048
6048: Code Docs r=matklad a=matklad Co-authored-by: Aleksey Kladov <aleksey.kladov@gmail.com>
This commit is contained in:
commit
bcdedbb3d5
2 changed files with 47 additions and 0 deletions
|
@ -18,6 +18,34 @@ pub fn apply<'a, N: AstNode>(transformer: &dyn AstTransform<'a>, node: N) -> N {
|
||||||
.rewrite_ast(&node)
|
.rewrite_ast(&node)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// `AstTransform` helps with applying bulk transformations to syntax nodes.
|
||||||
|
///
|
||||||
|
/// This is mostly useful for IDE code generation. If you paste some existing
|
||||||
|
/// code into a new context (for example, to add method overrides to an `impl`
|
||||||
|
/// block), you generally want to appropriately qualify the names, and sometimes
|
||||||
|
/// you might want to substitute generic parameters as well:
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// mod x {
|
||||||
|
/// pub struct A;
|
||||||
|
/// pub trait T<U> { fn foo(&self, _: U) -> A; }
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// mod y {
|
||||||
|
/// use x::T;
|
||||||
|
///
|
||||||
|
/// impl T<()> for () {
|
||||||
|
/// // If we invoke **Add Missing Members** here, we want to copy-paste `foo`.
|
||||||
|
/// // But we want a slightly-modified version of it:
|
||||||
|
/// fn foo(&self, _: ()) -> x::A {}
|
||||||
|
/// }
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// So, a single `AstTransform` describes such function from `SyntaxNode` to
|
||||||
|
/// `SyntaxNode`. Note that the API here is a bit too high-order and high-brow.
|
||||||
|
/// We'd want to somehow express this concept simpler, but so far nobody got to
|
||||||
|
/// simplifying this!
|
||||||
pub trait AstTransform<'a> {
|
pub trait AstTransform<'a> {
|
||||||
fn get_substitution(&self, node: &syntax::SyntaxNode) -> Option<syntax::SyntaxNode>;
|
fn get_substitution(&self, node: &syntax::SyntaxNode) -> Option<syntax::SyntaxNode>;
|
||||||
|
|
||||||
|
|
|
@ -697,6 +697,25 @@ fn find_root(node: &SyntaxNode) -> SyntaxNode {
|
||||||
node.ancestors().last().unwrap()
|
node.ancestors().last().unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// `SemanticScope` encapsulates the notion of a scope (the set of visible
|
||||||
|
/// names) at a particular program point.
|
||||||
|
///
|
||||||
|
/// It is a bit tricky, as scopes do not really exist inside the compiler.
|
||||||
|
/// Rather, the compiler directly computes for each reference the definition it
|
||||||
|
/// refers to. It might transiently compute the explicit scope map while doing
|
||||||
|
/// so, but, generally, this is not something left after the analysis.
|
||||||
|
///
|
||||||
|
/// However, we do very much need explicit scopes for IDE purposes --
|
||||||
|
/// completion, at its core, lists the contents of the current scope. The notion
|
||||||
|
/// of scope is also useful to answer questions like "what would be the meaning
|
||||||
|
/// of this piece of code if we inserted it into this position?".
|
||||||
|
///
|
||||||
|
/// So `SemanticsScope` is constructed from a specific program point (a syntax
|
||||||
|
/// node or just a raw offset) and provides access to the set of visible names
|
||||||
|
/// on a somewhat best-effort basis.
|
||||||
|
///
|
||||||
|
/// Note that if you are wondering "what does this specific existing name mean?",
|
||||||
|
/// you'd better use the `resolve_` family of methods.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct SemanticsScope<'a> {
|
pub struct SemanticsScope<'a> {
|
||||||
pub db: &'a dyn HirDatabase,
|
pub db: &'a dyn HirDatabase,
|
||||||
|
|
Loading…
Reference in a new issue