diff options
| author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2020-09-21 12:36:05 +0000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-09-21 12:36:05 +0000 |
| commit | bcdedbb3d5a45ea974cc5f8e9068e9604c43a757 (patch) | |
| tree | 517f29aab74a5906d02f9035f39e352a055d6088 | |
| parent | 3b52d3181a44a0ccedd30c52e70ce84231918e72 (diff) | |
| parent | fcc3c49013c681d7f7cc98a59fe140e076837813 (diff) | |
| download | rust-bcdedbb3d5a45ea974cc5f8e9068e9604c43a757.tar.gz rust-bcdedbb3d5a45ea974cc5f8e9068e9604c43a757.zip | |
Merge #6048
6048: Code Docs r=matklad a=matklad Co-authored-by: Aleksey Kladov <aleksey.kladov@gmail.com>
| -rw-r--r-- | crates/assists/src/ast_transform.rs | 28 | ||||
| -rw-r--r-- | crates/hir/src/semantics.rs | 19 |
2 files changed, 47 insertions, 0 deletions
diff --git a/crates/assists/src/ast_transform.rs b/crates/assists/src/ast_transform.rs index bbcd2d48830..835da3bb261 100644 --- a/crates/assists/src/ast_transform.rs +++ b/crates/assists/src/ast_transform.rs @@ -18,6 +18,34 @@ pub fn apply<'a, N: AstNode>(transformer: &dyn AstTransform<'a>, node: N) -> N { .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> { fn get_substitution(&self, node: &syntax::SyntaxNode) -> Option<syntax::SyntaxNode>; diff --git a/crates/hir/src/semantics.rs b/crates/hir/src/semantics.rs index 0516a05b415..c61a430e11b 100644 --- a/crates/hir/src/semantics.rs +++ b/crates/hir/src/semantics.rs @@ -697,6 +697,25 @@ fn find_root(node: &SyntaxNode) -> SyntaxNode { 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)] pub struct SemanticsScope<'a> { pub db: &'a dyn HirDatabase, |
