mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-29 13:25:09 +00:00
fix: Fix outline modules spilling inner doc injections into their parent
This commit is contained in:
parent
47591f0fb2
commit
b32f611b6e
3 changed files with 40 additions and 5 deletions
|
@ -390,7 +390,9 @@ impl AttrsWithOwner {
|
||||||
if let InFile { file_id, value: ModuleSource::SourceFile(file) } =
|
if let InFile { file_id, value: ModuleSource::SourceFile(file) } =
|
||||||
mod_data.definition_source(db)
|
mod_data.definition_source(db)
|
||||||
{
|
{
|
||||||
map.merge(AttrSourceMap::new(InFile::new(file_id, &file)));
|
map.append_module_inline_attrs(AttrSourceMap::new(InFile::new(
|
||||||
|
file_id, &file,
|
||||||
|
)));
|
||||||
}
|
}
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
@ -552,6 +554,11 @@ fn inner_attributes(
|
||||||
pub struct AttrSourceMap {
|
pub struct AttrSourceMap {
|
||||||
source: Vec<Either<ast::Attr, ast::Comment>>,
|
source: Vec<Either<ast::Attr, ast::Comment>>,
|
||||||
file_id: HirFileId,
|
file_id: HirFileId,
|
||||||
|
/// If this map is for a module, this will be the [`HirFileId`] of the module's definition site,
|
||||||
|
/// while `file_id` will be the one of the module declaration site.
|
||||||
|
/// The usize is the index into `source` from which point on the entries reside in the def site
|
||||||
|
/// file.
|
||||||
|
mod_def_site_file_id: Option<(HirFileId, usize)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AttrSourceMap {
|
impl AttrSourceMap {
|
||||||
|
@ -559,11 +566,19 @@ impl AttrSourceMap {
|
||||||
Self {
|
Self {
|
||||||
source: collect_attrs(owner.value).map(|(_, it)| it).collect(),
|
source: collect_attrs(owner.value).map(|(_, it)| it).collect(),
|
||||||
file_id: owner.file_id,
|
file_id: owner.file_id,
|
||||||
|
mod_def_site_file_id: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn merge(&mut self, other: Self) {
|
/// Append a second source map to this one, this is required for modules, whose outline and inline
|
||||||
|
/// attributes can reside in different files
|
||||||
|
fn append_module_inline_attrs(&mut self, other: Self) {
|
||||||
|
assert!(self.mod_def_site_file_id.is_none() && other.mod_def_site_file_id.is_none());
|
||||||
|
let len = self.source.len();
|
||||||
self.source.extend(other.source);
|
self.source.extend(other.source);
|
||||||
|
if other.file_id != self.file_id {
|
||||||
|
self.mod_def_site_file_id = Some((other.file_id, len));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Maps the lowered `Attr` back to its original syntax node.
|
/// Maps the lowered `Attr` back to its original syntax node.
|
||||||
|
@ -577,9 +592,15 @@ impl AttrSourceMap {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn source_of_id(&self, id: AttrId) -> InFile<&Either<ast::Attr, ast::Comment>> {
|
fn source_of_id(&self, id: AttrId) -> InFile<&Either<ast::Attr, ast::Comment>> {
|
||||||
|
let ast_idx = id.ast_index as usize;
|
||||||
|
let file_id = match self.mod_def_site_file_id {
|
||||||
|
Some((file_id, def_site_cut)) if def_site_cut <= ast_idx => file_id,
|
||||||
|
_ => self.file_id,
|
||||||
|
};
|
||||||
|
|
||||||
self.source
|
self.source
|
||||||
.get(id.ast_index as usize)
|
.get(ast_idx)
|
||||||
.map(|it| InFile::new(self.file_id, it))
|
.map(|it| InFile::new(file_id, it))
|
||||||
.unwrap_or_else(|| panic!("cannot find attr at index {:?}", id))
|
.unwrap_or_else(|| panic!("cannot find attr at index {:?}", id))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,6 +46,8 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
|
||||||
<span class="comment documentation">//! </span><span class="keyword injected">fn</span><span class="none injected"> </span><span class="function declaration injected">test</span><span class="parenthesis injected">(</span><span class="parenthesis injected">)</span><span class="none injected"> </span><span class="brace injected">{</span><span class="brace injected">}</span>
|
<span class="comment documentation">//! </span><span class="keyword injected">fn</span><span class="none injected"> </span><span class="function declaration injected">test</span><span class="parenthesis injected">(</span><span class="parenthesis injected">)</span><span class="none injected"> </span><span class="brace injected">{</span><span class="brace injected">}</span>
|
||||||
<span class="comment documentation">//! ```</span>
|
<span class="comment documentation">//! ```</span>
|
||||||
|
|
||||||
|
<span class="keyword">mod</span> <span class="module declaration">outline_module</span><span class="semicolon">;</span>
|
||||||
|
|
||||||
<span class="comment documentation">/// ```</span>
|
<span class="comment documentation">/// ```</span>
|
||||||
<span class="comment documentation">/// </span><span class="keyword injected">let</span><span class="none injected"> </span><span class="punctuation injected">_</span><span class="none injected"> </span><span class="operator injected">=</span><span class="none injected"> </span><span class="string_literal injected">"early doctests should not go boom"</span><span class="semicolon injected">;</span>
|
<span class="comment documentation">/// </span><span class="keyword injected">let</span><span class="none injected"> </span><span class="punctuation injected">_</span><span class="none injected"> </span><span class="operator injected">=</span><span class="none injected"> </span><span class="string_literal injected">"early doctests should not go boom"</span><span class="semicolon injected">;</span>
|
||||||
<span class="comment documentation">/// ```</span>
|
<span class="comment documentation">/// ```</span>
|
||||||
|
@ -170,4 +172,6 @@ It is beyond me why you'd use these when you got ///
|
||||||
```
|
```
|
||||||
</span><span class="function documentation injected intra_doc_link">[`block_comments`]</span><span class="comment documentation"> tests these without indentation
|
</span><span class="function documentation injected intra_doc_link">[`block_comments`]</span><span class="comment documentation"> tests these without indentation
|
||||||
*/</span>
|
*/</span>
|
||||||
<span class="keyword">pub</span> <span class="keyword">fn</span> <span class="function declaration public">block_comments2</span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="brace">{</span><span class="brace">}</span></code></pre>
|
<span class="keyword">pub</span> <span class="keyword">fn</span> <span class="function declaration public">block_comments2</span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="brace">{</span><span class="brace">}</span>
|
||||||
|
|
||||||
|
</code></pre>
|
|
@ -641,11 +641,14 @@ fn main() {
|
||||||
fn test_highlight_doc_comment() {
|
fn test_highlight_doc_comment() {
|
||||||
check_highlighting(
|
check_highlighting(
|
||||||
r#"
|
r#"
|
||||||
|
//- /main.rs
|
||||||
//! This is a module to test doc injection.
|
//! This is a module to test doc injection.
|
||||||
//! ```
|
//! ```
|
||||||
//! fn test() {}
|
//! fn test() {}
|
||||||
//! ```
|
//! ```
|
||||||
|
|
||||||
|
mod outline_module;
|
||||||
|
|
||||||
/// ```
|
/// ```
|
||||||
/// let _ = "early doctests should not go boom";
|
/// let _ = "early doctests should not go boom";
|
||||||
/// ```
|
/// ```
|
||||||
|
@ -771,6 +774,13 @@ pub fn block_comments() {}
|
||||||
[`block_comments`] tests these without indentation
|
[`block_comments`] tests these without indentation
|
||||||
*/
|
*/
|
||||||
pub fn block_comments2() {}
|
pub fn block_comments2() {}
|
||||||
|
|
||||||
|
//- /outline_module.rs
|
||||||
|
//! This is an outline module whose purpose is to test that its inline attribute injection does not
|
||||||
|
//! spill into its parent.
|
||||||
|
//! ```
|
||||||
|
//! fn test() {}
|
||||||
|
//! ```
|
||||||
"#
|
"#
|
||||||
.trim(),
|
.trim(),
|
||||||
expect_file!["./test_data/highlight_doctest.html"],
|
expect_file!["./test_data/highlight_doctest.html"],
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue