mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-27 05:23:24 +00:00
internal: Split out a span crate
This commit is contained in:
parent
cfc959d73a
commit
66e29be1bd
50 changed files with 477 additions and 403 deletions
19
Cargo.lock
generated
19
Cargo.lock
generated
|
@ -74,6 +74,7 @@ dependencies = [
|
||||||
"profile",
|
"profile",
|
||||||
"rust-analyzer-salsa",
|
"rust-analyzer-salsa",
|
||||||
"rustc-hash",
|
"rustc-hash",
|
||||||
|
"span",
|
||||||
"stdx",
|
"stdx",
|
||||||
"syntax",
|
"syntax",
|
||||||
"test-utils",
|
"test-utils",
|
||||||
|
@ -516,6 +517,7 @@ dependencies = [
|
||||||
"rustc-dependencies",
|
"rustc-dependencies",
|
||||||
"rustc-hash",
|
"rustc-hash",
|
||||||
"smallvec",
|
"smallvec",
|
||||||
|
"span",
|
||||||
"stdx",
|
"stdx",
|
||||||
"syntax",
|
"syntax",
|
||||||
"test-utils",
|
"test-utils",
|
||||||
|
@ -542,6 +544,7 @@ dependencies = [
|
||||||
"profile",
|
"profile",
|
||||||
"rustc-hash",
|
"rustc-hash",
|
||||||
"smallvec",
|
"smallvec",
|
||||||
|
"span",
|
||||||
"stdx",
|
"stdx",
|
||||||
"syntax",
|
"syntax",
|
||||||
"test-utils",
|
"test-utils",
|
||||||
|
@ -695,6 +698,7 @@ dependencies = [
|
||||||
"rayon",
|
"rayon",
|
||||||
"rustc-hash",
|
"rustc-hash",
|
||||||
"sourcegen",
|
"sourcegen",
|
||||||
|
"span",
|
||||||
"stdx",
|
"stdx",
|
||||||
"syntax",
|
"syntax",
|
||||||
"test-utils",
|
"test-utils",
|
||||||
|
@ -910,6 +914,7 @@ dependencies = [
|
||||||
"itertools",
|
"itertools",
|
||||||
"proc-macro-api",
|
"proc-macro-api",
|
||||||
"project-model",
|
"project-model",
|
||||||
|
"span",
|
||||||
"tracing",
|
"tracing",
|
||||||
"tt",
|
"tt",
|
||||||
"vfs",
|
"vfs",
|
||||||
|
@ -977,6 +982,7 @@ dependencies = [
|
||||||
"parser",
|
"parser",
|
||||||
"rustc-hash",
|
"rustc-hash",
|
||||||
"smallvec",
|
"smallvec",
|
||||||
|
"span",
|
||||||
"stdx",
|
"stdx",
|
||||||
"syntax",
|
"syntax",
|
||||||
"test-utils",
|
"test-utils",
|
||||||
|
@ -1253,6 +1259,7 @@ dependencies = [
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"snap",
|
"snap",
|
||||||
|
"span",
|
||||||
"stdx",
|
"stdx",
|
||||||
"text-size",
|
"text-size",
|
||||||
"tracing",
|
"tracing",
|
||||||
|
@ -1728,6 +1735,17 @@ dependencies = [
|
||||||
"xshell",
|
"xshell",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "span"
|
||||||
|
version = "0.0.0"
|
||||||
|
dependencies = [
|
||||||
|
"la-arena 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"rust-analyzer-salsa",
|
||||||
|
"stdx",
|
||||||
|
"syntax",
|
||||||
|
"vfs",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "static_assertions"
|
name = "static_assertions"
|
||||||
version = "1.1.0"
|
version = "1.1.0"
|
||||||
|
@ -2000,6 +2018,7 @@ name = "tt"
|
||||||
version = "0.0.0"
|
version = "0.0.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"smol_str",
|
"smol_str",
|
||||||
|
"span",
|
||||||
"stdx",
|
"stdx",
|
||||||
"text-size",
|
"text-size",
|
||||||
]
|
]
|
||||||
|
|
|
@ -71,6 +71,7 @@ proc-macro-srv-cli = { path = "./crates/proc-macro-srv-cli", version = "0.0.0" }
|
||||||
profile = { path = "./crates/profile", version = "0.0.0" }
|
profile = { path = "./crates/profile", version = "0.0.0" }
|
||||||
project-model = { path = "./crates/project-model", version = "0.0.0" }
|
project-model = { path = "./crates/project-model", version = "0.0.0" }
|
||||||
sourcegen = { path = "./crates/sourcegen", version = "0.0.0" }
|
sourcegen = { path = "./crates/sourcegen", version = "0.0.0" }
|
||||||
|
span = { path = "./crates/span", version = "0.0.0" }
|
||||||
stdx = { path = "./crates/stdx", version = "0.0.0" }
|
stdx = { path = "./crates/stdx", version = "0.0.0" }
|
||||||
syntax = { path = "./crates/syntax", version = "0.0.0" }
|
syntax = { path = "./crates/syntax", version = "0.0.0" }
|
||||||
test-utils = { path = "./crates/test-utils", version = "0.0.0" }
|
test-utils = { path = "./crates/test-utils", version = "0.0.0" }
|
||||||
|
|
|
@ -25,3 +25,4 @@ syntax.workspace = true
|
||||||
test-utils.workspace = true
|
test-utils.workspace = true
|
||||||
tt.workspace = true
|
tt.workspace = true
|
||||||
vfs.workspace = true
|
vfs.workspace = true
|
||||||
|
span.workspace = true
|
||||||
|
|
|
@ -4,12 +4,11 @@
|
||||||
|
|
||||||
mod input;
|
mod input;
|
||||||
mod change;
|
mod change;
|
||||||
pub mod span;
|
|
||||||
|
|
||||||
use std::panic;
|
use std::panic;
|
||||||
|
|
||||||
use rustc_hash::FxHashSet;
|
use rustc_hash::FxHashSet;
|
||||||
use syntax::{ast, Parse, SourceFile, TextRange, TextSize};
|
use syntax::{ast, Parse, SourceFile};
|
||||||
use triomphe::Arc;
|
use triomphe::Arc;
|
||||||
|
|
||||||
pub use crate::{
|
pub use crate::{
|
||||||
|
@ -21,6 +20,7 @@ pub use crate::{
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
pub use salsa::{self, Cancelled};
|
pub use salsa::{self, Cancelled};
|
||||||
|
pub use span::{FilePosition, FileRange};
|
||||||
pub use vfs::{file_set::FileSet, AnchoredPath, AnchoredPathBuf, FileId, VfsPath};
|
pub use vfs::{file_set::FileSet, AnchoredPath, AnchoredPathBuf, FileId, VfsPath};
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
|
@ -41,18 +41,6 @@ pub trait Upcast<T: ?Sized> {
|
||||||
fn upcast(&self) -> &T;
|
fn upcast(&self) -> &T;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug)]
|
|
||||||
pub struct FilePosition {
|
|
||||||
pub file_id: FileId,
|
|
||||||
pub offset: TextSize,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
|
|
||||||
pub struct FileRange {
|
|
||||||
pub file_id: FileId,
|
|
||||||
pub range: TextRange,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub const DEFAULT_PARSE_LRU_CAP: usize = 128;
|
pub const DEFAULT_PARSE_LRU_CAP: usize = 128;
|
||||||
|
|
||||||
pub trait FileLoader {
|
pub trait FileLoader {
|
||||||
|
|
|
@ -42,6 +42,7 @@ mbe.workspace = true
|
||||||
cfg.workspace = true
|
cfg.workspace = true
|
||||||
tt.workspace = true
|
tt.workspace = true
|
||||||
limit.workspace = true
|
limit.workspace = true
|
||||||
|
span.workspace = true
|
||||||
|
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
//! Currently, it tests `#[doc(hidden)]` and `#[doc(alias)]`.
|
//! Currently, it tests `#[doc(hidden)]` and `#[doc(alias)]`.
|
||||||
|
|
||||||
use base_db::FileId;
|
use base_db::FileId;
|
||||||
use hir_expand::span::{RealSpanMap, SpanMapRef};
|
use hir_expand::span_map::{RealSpanMap, SpanMapRef};
|
||||||
use mbe::syntax_node_to_token_tree;
|
use mbe::syntax_node_to_token_tree;
|
||||||
use syntax::{ast, AstNode};
|
use syntax::{ast, AstNode};
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ use base_db::CrateId;
|
||||||
use cfg::CfgOptions;
|
use cfg::CfgOptions;
|
||||||
use drop_bomb::DropBomb;
|
use drop_bomb::DropBomb;
|
||||||
use hir_expand::{
|
use hir_expand::{
|
||||||
attrs::RawAttrs, mod_path::ModPath, span::SpanMap, ExpandError, ExpandResult, HirFileId,
|
attrs::RawAttrs, mod_path::ModPath, span_map::SpanMap, ExpandError, ExpandResult, HirFileId,
|
||||||
InFile, MacroCallId,
|
InFile, MacroCallId,
|
||||||
};
|
};
|
||||||
use limit::Limit;
|
use limit::Limit;
|
||||||
|
|
|
@ -42,7 +42,7 @@ use std::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use ast::{AstNode, HasName, StructKind};
|
use ast::{AstNode, HasName, StructKind};
|
||||||
use base_db::{span::SyntaxContextId, CrateId};
|
use base_db::CrateId;
|
||||||
use either::Either;
|
use either::Either;
|
||||||
use hir_expand::{
|
use hir_expand::{
|
||||||
ast_id_map::{AstIdNode, FileAstId},
|
ast_id_map::{AstIdNode, FileAstId},
|
||||||
|
@ -55,6 +55,7 @@ use la_arena::{Arena, Idx, IdxRange, RawIdx};
|
||||||
use profile::Count;
|
use profile::Count;
|
||||||
use rustc_hash::FxHashMap;
|
use rustc_hash::FxHashMap;
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
|
use span::SyntaxContextId;
|
||||||
use stdx::never;
|
use stdx::never;
|
||||||
use syntax::{ast, match_ast, SyntaxKind};
|
use syntax::{ast, match_ast, SyntaxKind};
|
||||||
use triomphe::Arc;
|
use triomphe::Arc;
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
use std::collections::hash_map::Entry;
|
use std::collections::hash_map::Entry;
|
||||||
|
|
||||||
use hir_expand::{ast_id_map::AstIdMap, span::SpanMapRef, HirFileId};
|
use hir_expand::{ast_id_map::AstIdMap, span_map::SpanMapRef, HirFileId};
|
||||||
use syntax::ast::{self, HasModuleItem, HasTypeBounds};
|
use syntax::ast::{self, HasModuleItem, HasTypeBounds};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
|
|
@ -63,7 +63,7 @@ use std::{
|
||||||
panic::{RefUnwindSafe, UnwindSafe},
|
panic::{RefUnwindSafe, UnwindSafe},
|
||||||
};
|
};
|
||||||
|
|
||||||
use base_db::{impl_intern_key, salsa, span::SyntaxContextId, CrateId};
|
use base_db::{impl_intern_key, salsa, CrateId};
|
||||||
use hir_expand::{
|
use hir_expand::{
|
||||||
ast_id_map::{AstIdNode, FileAstId},
|
ast_id_map::{AstIdNode, FileAstId},
|
||||||
attrs::{Attr, AttrId, AttrInput},
|
attrs::{Attr, AttrId, AttrInput},
|
||||||
|
@ -80,6 +80,7 @@ use hir_expand::{
|
||||||
use item_tree::ExternBlock;
|
use item_tree::ExternBlock;
|
||||||
use la_arena::Idx;
|
use la_arena::Idx;
|
||||||
use nameres::DefMap;
|
use nameres::DefMap;
|
||||||
|
use span::SyntaxContextId;
|
||||||
use stdx::impl_from;
|
use stdx::impl_from;
|
||||||
use syntax::{ast, AstNode};
|
use syntax::{ast, AstNode};
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@ use std::cell::OnceCell;
|
||||||
|
|
||||||
use hir_expand::{
|
use hir_expand::{
|
||||||
ast_id_map::{AstIdMap, AstIdNode},
|
ast_id_map::{AstIdMap, AstIdNode},
|
||||||
span::{SpanMap, SpanMapRef},
|
span_map::{SpanMap, SpanMapRef},
|
||||||
AstId, HirFileId, InFile,
|
AstId, HirFileId, InFile,
|
||||||
};
|
};
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
|
|
|
@ -16,15 +16,16 @@ mod proc_macros;
|
||||||
|
|
||||||
use std::{iter, ops::Range, sync};
|
use std::{iter, ops::Range, sync};
|
||||||
|
|
||||||
use base_db::{span::SpanData, SourceDatabase};
|
use base_db::SourceDatabase;
|
||||||
use expect_test::Expect;
|
use expect_test::Expect;
|
||||||
use hir_expand::{
|
use hir_expand::{
|
||||||
db::ExpandDatabase,
|
db::ExpandDatabase,
|
||||||
fixture::WithFixture,
|
fixture::WithFixture,
|
||||||
proc_macro::{ProcMacro, ProcMacroExpander, ProcMacroExpansionError, ProcMacroKind},
|
proc_macro::{ProcMacro, ProcMacroExpander, ProcMacroExpansionError, ProcMacroKind},
|
||||||
span::SpanMapRef,
|
span_map::SpanMapRef,
|
||||||
InFile, MacroFileId, MacroFileIdExt,
|
InFile, MacroFileId, MacroFileIdExt,
|
||||||
};
|
};
|
||||||
|
use span::Span;
|
||||||
use stdx::format_to;
|
use stdx::format_to;
|
||||||
use syntax::{
|
use syntax::{
|
||||||
ast::{self, edit::IndentLevel},
|
ast::{self, edit::IndentLevel},
|
||||||
|
@ -319,9 +320,9 @@ impl ProcMacroExpander for IdentityWhenValidProcMacroExpander {
|
||||||
subtree: &Subtree,
|
subtree: &Subtree,
|
||||||
_: Option<&Subtree>,
|
_: Option<&Subtree>,
|
||||||
_: &base_db::Env,
|
_: &base_db::Env,
|
||||||
_: SpanData,
|
_: Span,
|
||||||
_: SpanData,
|
_: Span,
|
||||||
_: SpanData,
|
_: Span,
|
||||||
) -> Result<Subtree, ProcMacroExpansionError> {
|
) -> Result<Subtree, ProcMacroExpansionError> {
|
||||||
let (parse, _) =
|
let (parse, _) =
|
||||||
::mbe::token_tree_to_syntax_node(subtree, ::mbe::TopEntryPoint::MacroItems);
|
::mbe::token_tree_to_syntax_node(subtree, ::mbe::TopEntryPoint::MacroItems);
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
|
|
||||||
use std::{cmp::Ordering, iter, mem};
|
use std::{cmp::Ordering, iter, mem};
|
||||||
|
|
||||||
use base_db::{span::SyntaxContextId, CrateId, Dependency, Edition, FileId};
|
use base_db::{CrateId, Dependency, Edition, FileId};
|
||||||
use cfg::{CfgExpr, CfgOptions};
|
use cfg::{CfgExpr, CfgOptions};
|
||||||
use either::Either;
|
use either::Either;
|
||||||
use hir_expand::{
|
use hir_expand::{
|
||||||
|
@ -23,6 +23,7 @@ use itertools::{izip, Itertools};
|
||||||
use la_arena::Idx;
|
use la_arena::Idx;
|
||||||
use limit::Limit;
|
use limit::Limit;
|
||||||
use rustc_hash::{FxHashMap, FxHashSet};
|
use rustc_hash::{FxHashMap, FxHashSet};
|
||||||
|
use span::{Span, SyntaxContextId};
|
||||||
use stdx::always;
|
use stdx::always;
|
||||||
use syntax::{ast, SmolStr};
|
use syntax::{ast, SmolStr};
|
||||||
use triomphe::Arc;
|
use triomphe::Arc;
|
||||||
|
@ -86,11 +87,11 @@ pub(super) fn collect_defs(db: &dyn DefDatabase, def_map: DefMap, tree_id: TreeI
|
||||||
// FIXME: a hacky way to create a Name from string.
|
// FIXME: a hacky way to create a Name from string.
|
||||||
let name = tt::Ident {
|
let name = tt::Ident {
|
||||||
text: it.name.clone(),
|
text: it.name.clone(),
|
||||||
span: tt::SpanData {
|
span: Span {
|
||||||
range: syntax::TextRange::empty(syntax::TextSize::new(0)),
|
range: syntax::TextRange::empty(syntax::TextSize::new(0)),
|
||||||
anchor: base_db::span::SpanAnchor {
|
anchor: span::SpanAnchor {
|
||||||
file_id: FileId::BOGUS,
|
file_id: FileId::BOGUS,
|
||||||
ast_id: base_db::span::ROOT_ERASED_FILE_AST_ID,
|
ast_id: span::ROOT_ERASED_FILE_AST_ID,
|
||||||
},
|
},
|
||||||
ctx: SyntaxContextId::ROOT,
|
ctx: SyntaxContextId::ROOT,
|
||||||
},
|
},
|
||||||
|
@ -2095,11 +2096,11 @@ impl ModCollector<'_, '_> {
|
||||||
// FIXME: a hacky way to create a Name from string.
|
// FIXME: a hacky way to create a Name from string.
|
||||||
name = tt::Ident {
|
name = tt::Ident {
|
||||||
text: it.clone(),
|
text: it.clone(),
|
||||||
span: tt::SpanData {
|
span: Span {
|
||||||
range: syntax::TextRange::empty(syntax::TextSize::new(0)),
|
range: syntax::TextRange::empty(syntax::TextSize::new(0)),
|
||||||
anchor: base_db::span::SpanAnchor {
|
anchor: span::SpanAnchor {
|
||||||
file_id: FileId::BOGUS,
|
file_id: FileId::BOGUS,
|
||||||
ast_id: base_db::span::ROOT_ERASED_FILE_AST_ID,
|
ast_id: span::ROOT_ERASED_FILE_AST_ID,
|
||||||
},
|
},
|
||||||
ctx: SyntaxContextId::ROOT,
|
ctx: SyntaxContextId::ROOT,
|
||||||
},
|
},
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
use std::iter;
|
use std::iter;
|
||||||
|
|
||||||
use hir_expand::{span::SpanMapRef, InFile};
|
use hir_expand::{span_map::SpanMapRef, InFile};
|
||||||
use la_arena::ArenaMap;
|
use la_arena::ArenaMap;
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
use triomphe::Arc;
|
use triomphe::Arc;
|
||||||
|
|
|
@ -32,6 +32,7 @@ profile.workspace = true
|
||||||
tt.workspace = true
|
tt.workspace = true
|
||||||
mbe.workspace = true
|
mbe.workspace = true
|
||||||
limit.workspace = true
|
limit.workspace = true
|
||||||
|
span.workspace = true
|
||||||
test-utils.workspace = true
|
test-utils.workspace = true
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
|
|
|
@ -5,6 +5,8 @@
|
||||||
//! item as an ID. That way, id's don't change unless the set of items itself
|
//! item as an ID. That way, id's don't change unless the set of items itself
|
||||||
//! changes.
|
//! changes.
|
||||||
|
|
||||||
|
// FIXME: Consider moving this into the span crate
|
||||||
|
|
||||||
use std::{
|
use std::{
|
||||||
any::type_name,
|
any::type_name,
|
||||||
fmt,
|
fmt,
|
||||||
|
@ -17,9 +19,9 @@ use profile::Count;
|
||||||
use rustc_hash::FxHasher;
|
use rustc_hash::FxHasher;
|
||||||
use syntax::{ast, AstNode, AstPtr, SyntaxNode, SyntaxNodePtr};
|
use syntax::{ast, AstNode, AstPtr, SyntaxNode, SyntaxNodePtr};
|
||||||
|
|
||||||
use crate::db;
|
use crate::db::ExpandDatabase;
|
||||||
|
|
||||||
pub use base_db::span::ErasedFileAstId;
|
pub use span::ErasedFileAstId;
|
||||||
|
|
||||||
/// `AstId` points to an AST node in any file.
|
/// `AstId` points to an AST node in any file.
|
||||||
///
|
///
|
||||||
|
@ -27,13 +29,13 @@ pub use base_db::span::ErasedFileAstId;
|
||||||
pub type AstId<N> = crate::InFile<FileAstId<N>>;
|
pub type AstId<N> = crate::InFile<FileAstId<N>>;
|
||||||
|
|
||||||
impl<N: AstIdNode> AstId<N> {
|
impl<N: AstIdNode> AstId<N> {
|
||||||
pub fn to_node(&self, db: &dyn db::ExpandDatabase) -> N {
|
pub fn to_node(&self, db: &dyn ExpandDatabase) -> N {
|
||||||
self.to_ptr(db).to_node(&db.parse_or_expand(self.file_id))
|
self.to_ptr(db).to_node(&db.parse_or_expand(self.file_id))
|
||||||
}
|
}
|
||||||
pub fn to_in_file_node(&self, db: &dyn db::ExpandDatabase) -> crate::InFile<N> {
|
pub fn to_in_file_node(&self, db: &dyn ExpandDatabase) -> crate::InFile<N> {
|
||||||
crate::InFile::new(self.file_id, self.to_ptr(db).to_node(&db.parse_or_expand(self.file_id)))
|
crate::InFile::new(self.file_id, self.to_ptr(db).to_node(&db.parse_or_expand(self.file_id)))
|
||||||
}
|
}
|
||||||
pub fn to_ptr(&self, db: &dyn db::ExpandDatabase) -> AstPtr<N> {
|
pub fn to_ptr(&self, db: &dyn ExpandDatabase) -> AstPtr<N> {
|
||||||
db.ast_id_map(self.file_id).get(self.value)
|
db.ast_id_map(self.file_id).get(self.value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -41,7 +43,7 @@ impl<N: AstIdNode> AstId<N> {
|
||||||
pub type ErasedAstId = crate::InFile<ErasedFileAstId>;
|
pub type ErasedAstId = crate::InFile<ErasedFileAstId>;
|
||||||
|
|
||||||
impl ErasedAstId {
|
impl ErasedAstId {
|
||||||
pub fn to_ptr(&self, db: &dyn db::ExpandDatabase) -> SyntaxNodePtr {
|
pub fn to_ptr(&self, db: &dyn ExpandDatabase) -> SyntaxNodePtr {
|
||||||
db.ast_id_map(self.file_id).get_erased(self.value)
|
db.ast_id_map(self.file_id).get_erased(self.value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,19 +1,20 @@
|
||||||
//! A higher level attributes based on TokenTree, with also some shortcuts.
|
//! A higher level attributes based on TokenTree, with also some shortcuts.
|
||||||
use std::{fmt, ops};
|
use std::{fmt, ops};
|
||||||
|
|
||||||
use base_db::{span::SyntaxContextId, CrateId};
|
use base_db::CrateId;
|
||||||
use cfg::CfgExpr;
|
use cfg::CfgExpr;
|
||||||
use either::Either;
|
use either::Either;
|
||||||
use intern::Interned;
|
use intern::Interned;
|
||||||
use mbe::{syntax_node_to_token_tree, DelimiterKind, Punct};
|
use mbe::{syntax_node_to_token_tree, DelimiterKind, Punct};
|
||||||
use smallvec::{smallvec, SmallVec};
|
use smallvec::{smallvec, SmallVec};
|
||||||
|
use span::SyntaxContextId;
|
||||||
use syntax::{ast, match_ast, AstNode, AstToken, SmolStr, SyntaxNode};
|
use syntax::{ast, match_ast, AstNode, AstToken, SmolStr, SyntaxNode};
|
||||||
use triomphe::Arc;
|
use triomphe::Arc;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
db::ExpandDatabase,
|
db::ExpandDatabase,
|
||||||
mod_path::ModPath,
|
mod_path::ModPath,
|
||||||
span::SpanMapRef,
|
span_map::SpanMapRef,
|
||||||
tt::{self, Subtree},
|
tt::{self, Subtree},
|
||||||
InFile,
|
InFile,
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,12 +1,8 @@
|
||||||
//! Builtin attributes.
|
//! Builtin attributes.
|
||||||
|
use span::{FileId, MacroCallId, Span, SyntaxContextId, ROOT_ERASED_FILE_AST_ID};
|
||||||
use base_db::{
|
|
||||||
span::{SyntaxContextId, ROOT_ERASED_FILE_AST_ID},
|
|
||||||
FileId,
|
|
||||||
};
|
|
||||||
use syntax::{TextRange, TextSize};
|
use syntax::{TextRange, TextSize};
|
||||||
|
|
||||||
use crate::{db::ExpandDatabase, name, tt, ExpandResult, MacroCallId, MacroCallKind};
|
use crate::{db::ExpandDatabase, name, tt, ExpandResult, MacroCallKind};
|
||||||
|
|
||||||
macro_rules! register_builtin {
|
macro_rules! register_builtin {
|
||||||
($expand_fn:ident: $(($name:ident, $variant:ident) => $expand:ident),* ) => {
|
($expand_fn:ident: $(($name:ident, $variant:ident) => $expand:ident),* ) => {
|
||||||
|
@ -120,9 +116,9 @@ pub fn pseudo_derive_attr_expansion(
|
||||||
tt::TokenTree::Leaf(tt::Leaf::Punct(tt::Punct {
|
tt::TokenTree::Leaf(tt::Leaf::Punct(tt::Punct {
|
||||||
char,
|
char,
|
||||||
spacing: tt::Spacing::Alone,
|
spacing: tt::Spacing::Alone,
|
||||||
span: tt::SpanData {
|
span: Span {
|
||||||
range: TextRange::empty(TextSize::new(0)),
|
range: TextRange::empty(TextSize::new(0)),
|
||||||
anchor: base_db::span::SpanAnchor {
|
anchor: span::SpanAnchor {
|
||||||
file_id: FileId::BOGUS,
|
file_id: FileId::BOGUS,
|
||||||
ast_id: ROOT_ERASED_FILE_AST_ID,
|
ast_id: ROOT_ERASED_FILE_AST_ID,
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,20 +1,21 @@
|
||||||
//! Builtin derives.
|
//! Builtin derives.
|
||||||
|
|
||||||
use base_db::{span::SpanData, CrateOrigin, LangCrateOrigin};
|
use base_db::{CrateOrigin, LangCrateOrigin};
|
||||||
use itertools::izip;
|
use itertools::izip;
|
||||||
use rustc_hash::FxHashSet;
|
use rustc_hash::FxHashSet;
|
||||||
|
use span::{MacroCallId, Span};
|
||||||
use stdx::never;
|
use stdx::never;
|
||||||
use tracing::debug;
|
use tracing::debug;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
hygiene::span_with_def_site_ctxt,
|
hygiene::span_with_def_site_ctxt,
|
||||||
name::{AsName, Name},
|
name::{AsName, Name},
|
||||||
span::SpanMapRef,
|
span_map::SpanMapRef,
|
||||||
tt,
|
tt,
|
||||||
};
|
};
|
||||||
use syntax::ast::{self, AstNode, FieldList, HasAttrs, HasGenericParams, HasName, HasTypeBounds};
|
use syntax::ast::{self, AstNode, FieldList, HasAttrs, HasGenericParams, HasName, HasTypeBounds};
|
||||||
|
|
||||||
use crate::{db::ExpandDatabase, name, quote, ExpandError, ExpandResult, MacroCallId};
|
use crate::{db::ExpandDatabase, name, quote, ExpandError, ExpandResult};
|
||||||
|
|
||||||
macro_rules! register_builtin {
|
macro_rules! register_builtin {
|
||||||
( $($trait:ident => $expand:ident),* ) => {
|
( $($trait:ident => $expand:ident),* ) => {
|
||||||
|
@ -73,16 +74,16 @@ enum VariantShape {
|
||||||
Unit,
|
Unit,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn tuple_field_iterator(span: SpanData, n: usize) -> impl Iterator<Item = tt::Ident> {
|
fn tuple_field_iterator(span: Span, n: usize) -> impl Iterator<Item = tt::Ident> {
|
||||||
(0..n).map(move |it| tt::Ident::new(format!("f{it}"), span))
|
(0..n).map(move |it| tt::Ident::new(format!("f{it}"), span))
|
||||||
}
|
}
|
||||||
|
|
||||||
impl VariantShape {
|
impl VariantShape {
|
||||||
fn as_pattern(&self, path: tt::Subtree, span: SpanData) -> tt::Subtree {
|
fn as_pattern(&self, path: tt::Subtree, span: Span) -> tt::Subtree {
|
||||||
self.as_pattern_map(path, span, |it| quote!(span => #it))
|
self.as_pattern_map(path, span, |it| quote!(span => #it))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn field_names(&self, span: SpanData) -> Vec<tt::Ident> {
|
fn field_names(&self, span: Span) -> Vec<tt::Ident> {
|
||||||
match self {
|
match self {
|
||||||
VariantShape::Struct(s) => s.clone(),
|
VariantShape::Struct(s) => s.clone(),
|
||||||
VariantShape::Tuple(n) => tuple_field_iterator(span, *n).collect(),
|
VariantShape::Tuple(n) => tuple_field_iterator(span, *n).collect(),
|
||||||
|
@ -93,7 +94,7 @@ impl VariantShape {
|
||||||
fn as_pattern_map(
|
fn as_pattern_map(
|
||||||
&self,
|
&self,
|
||||||
path: tt::Subtree,
|
path: tt::Subtree,
|
||||||
span: SpanData,
|
span: Span,
|
||||||
field_map: impl Fn(&tt::Ident) -> tt::Subtree,
|
field_map: impl Fn(&tt::Ident) -> tt::Subtree,
|
||||||
) -> tt::Subtree {
|
) -> tt::Subtree {
|
||||||
match self {
|
match self {
|
||||||
|
@ -143,11 +144,11 @@ enum AdtShape {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AdtShape {
|
impl AdtShape {
|
||||||
fn as_pattern(&self, span: SpanData, name: &tt::Ident) -> Vec<tt::Subtree> {
|
fn as_pattern(&self, span: Span, name: &tt::Ident) -> Vec<tt::Subtree> {
|
||||||
self.as_pattern_map(name, |it| quote!(span =>#it), span)
|
self.as_pattern_map(name, |it| quote!(span =>#it), span)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn field_names(&self, span: SpanData) -> Vec<Vec<tt::Ident>> {
|
fn field_names(&self, span: Span) -> Vec<Vec<tt::Ident>> {
|
||||||
match self {
|
match self {
|
||||||
AdtShape::Struct(s) => {
|
AdtShape::Struct(s) => {
|
||||||
vec![s.field_names(span)]
|
vec![s.field_names(span)]
|
||||||
|
@ -166,7 +167,7 @@ impl AdtShape {
|
||||||
&self,
|
&self,
|
||||||
name: &tt::Ident,
|
name: &tt::Ident,
|
||||||
field_map: impl Fn(&tt::Ident) -> tt::Subtree,
|
field_map: impl Fn(&tt::Ident) -> tt::Subtree,
|
||||||
span: SpanData,
|
span: Span,
|
||||||
) -> Vec<tt::Subtree> {
|
) -> Vec<tt::Subtree> {
|
||||||
match self {
|
match self {
|
||||||
AdtShape::Struct(s) => {
|
AdtShape::Struct(s) => {
|
||||||
|
@ -199,7 +200,7 @@ struct BasicAdtInfo {
|
||||||
fn parse_adt(
|
fn parse_adt(
|
||||||
tm: SpanMapRef<'_>,
|
tm: SpanMapRef<'_>,
|
||||||
adt: &ast::Adt,
|
adt: &ast::Adt,
|
||||||
call_site: SpanData,
|
call_site: Span,
|
||||||
) -> Result<BasicAdtInfo, ExpandError> {
|
) -> Result<BasicAdtInfo, ExpandError> {
|
||||||
let (name, generic_param_list, shape) = match adt {
|
let (name, generic_param_list, shape) = match adt {
|
||||||
ast::Adt::Struct(it) => (
|
ast::Adt::Struct(it) => (
|
||||||
|
@ -349,7 +350,7 @@ fn name_to_token(
|
||||||
/// therefore does not get bound by the derived trait.
|
/// therefore does not get bound by the derived trait.
|
||||||
fn expand_simple_derive(
|
fn expand_simple_derive(
|
||||||
// FIXME: use
|
// FIXME: use
|
||||||
invoc_span: SpanData,
|
invoc_span: Span,
|
||||||
tt: &ast::Adt,
|
tt: &ast::Adt,
|
||||||
tm: SpanMapRef<'_>,
|
tm: SpanMapRef<'_>,
|
||||||
trait_path: tt::Subtree,
|
trait_path: tt::Subtree,
|
||||||
|
@ -397,7 +398,7 @@ fn expand_simple_derive(
|
||||||
ExpandResult::ok(expanded)
|
ExpandResult::ok(expanded)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn find_builtin_crate(db: &dyn ExpandDatabase, id: MacroCallId, span: SpanData) -> tt::TokenTree {
|
fn find_builtin_crate(db: &dyn ExpandDatabase, id: MacroCallId, span: Span) -> tt::TokenTree {
|
||||||
// FIXME: make hygiene works for builtin derive macro
|
// FIXME: make hygiene works for builtin derive macro
|
||||||
// such that $crate can be used here.
|
// such that $crate can be used here.
|
||||||
let cg = db.crate_graph();
|
let cg = db.crate_graph();
|
||||||
|
@ -416,7 +417,7 @@ fn find_builtin_crate(db: &dyn ExpandDatabase, id: MacroCallId, span: SpanData)
|
||||||
fn copy_expand(
|
fn copy_expand(
|
||||||
db: &dyn ExpandDatabase,
|
db: &dyn ExpandDatabase,
|
||||||
id: MacroCallId,
|
id: MacroCallId,
|
||||||
span: SpanData,
|
span: Span,
|
||||||
tt: &ast::Adt,
|
tt: &ast::Adt,
|
||||||
tm: SpanMapRef<'_>,
|
tm: SpanMapRef<'_>,
|
||||||
) -> ExpandResult<tt::Subtree> {
|
) -> ExpandResult<tt::Subtree> {
|
||||||
|
@ -427,7 +428,7 @@ fn copy_expand(
|
||||||
fn clone_expand(
|
fn clone_expand(
|
||||||
db: &dyn ExpandDatabase,
|
db: &dyn ExpandDatabase,
|
||||||
id: MacroCallId,
|
id: MacroCallId,
|
||||||
span: SpanData,
|
span: Span,
|
||||||
tt: &ast::Adt,
|
tt: &ast::Adt,
|
||||||
tm: SpanMapRef<'_>,
|
tm: SpanMapRef<'_>,
|
||||||
) -> ExpandResult<tt::Subtree> {
|
) -> ExpandResult<tt::Subtree> {
|
||||||
|
@ -470,13 +471,13 @@ fn clone_expand(
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This function exists since `quote! {span => => }` doesn't work.
|
/// This function exists since `quote! {span => => }` doesn't work.
|
||||||
fn fat_arrow(span: SpanData) -> tt::Subtree {
|
fn fat_arrow(span: Span) -> tt::Subtree {
|
||||||
let eq = tt::Punct { char: '=', spacing: ::tt::Spacing::Joint, span };
|
let eq = tt::Punct { char: '=', spacing: ::tt::Spacing::Joint, span };
|
||||||
quote! {span => #eq> }
|
quote! {span => #eq> }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This function exists since `quote! {span => && }` doesn't work.
|
/// This function exists since `quote! {span => && }` doesn't work.
|
||||||
fn and_and(span: SpanData) -> tt::Subtree {
|
fn and_and(span: Span) -> tt::Subtree {
|
||||||
let and = tt::Punct { char: '&', spacing: ::tt::Spacing::Joint, span };
|
let and = tt::Punct { char: '&', spacing: ::tt::Spacing::Joint, span };
|
||||||
quote! {span => #and& }
|
quote! {span => #and& }
|
||||||
}
|
}
|
||||||
|
@ -484,7 +485,7 @@ fn and_and(span: SpanData) -> tt::Subtree {
|
||||||
fn default_expand(
|
fn default_expand(
|
||||||
db: &dyn ExpandDatabase,
|
db: &dyn ExpandDatabase,
|
||||||
id: MacroCallId,
|
id: MacroCallId,
|
||||||
span: SpanData,
|
span: Span,
|
||||||
tt: &ast::Adt,
|
tt: &ast::Adt,
|
||||||
tm: SpanMapRef<'_>,
|
tm: SpanMapRef<'_>,
|
||||||
) -> ExpandResult<tt::Subtree> {
|
) -> ExpandResult<tt::Subtree> {
|
||||||
|
@ -529,7 +530,7 @@ fn default_expand(
|
||||||
fn debug_expand(
|
fn debug_expand(
|
||||||
db: &dyn ExpandDatabase,
|
db: &dyn ExpandDatabase,
|
||||||
id: MacroCallId,
|
id: MacroCallId,
|
||||||
span: SpanData,
|
span: Span,
|
||||||
tt: &ast::Adt,
|
tt: &ast::Adt,
|
||||||
tm: SpanMapRef<'_>,
|
tm: SpanMapRef<'_>,
|
||||||
) -> ExpandResult<tt::Subtree> {
|
) -> ExpandResult<tt::Subtree> {
|
||||||
|
@ -607,7 +608,7 @@ fn debug_expand(
|
||||||
fn hash_expand(
|
fn hash_expand(
|
||||||
db: &dyn ExpandDatabase,
|
db: &dyn ExpandDatabase,
|
||||||
id: MacroCallId,
|
id: MacroCallId,
|
||||||
span: SpanData,
|
span: Span,
|
||||||
tt: &ast::Adt,
|
tt: &ast::Adt,
|
||||||
tm: SpanMapRef<'_>,
|
tm: SpanMapRef<'_>,
|
||||||
) -> ExpandResult<tt::Subtree> {
|
) -> ExpandResult<tt::Subtree> {
|
||||||
|
@ -660,7 +661,7 @@ fn hash_expand(
|
||||||
fn eq_expand(
|
fn eq_expand(
|
||||||
db: &dyn ExpandDatabase,
|
db: &dyn ExpandDatabase,
|
||||||
id: MacroCallId,
|
id: MacroCallId,
|
||||||
span: SpanData,
|
span: Span,
|
||||||
tt: &ast::Adt,
|
tt: &ast::Adt,
|
||||||
tm: SpanMapRef<'_>,
|
tm: SpanMapRef<'_>,
|
||||||
) -> ExpandResult<tt::Subtree> {
|
) -> ExpandResult<tt::Subtree> {
|
||||||
|
@ -671,7 +672,7 @@ fn eq_expand(
|
||||||
fn partial_eq_expand(
|
fn partial_eq_expand(
|
||||||
db: &dyn ExpandDatabase,
|
db: &dyn ExpandDatabase,
|
||||||
id: MacroCallId,
|
id: MacroCallId,
|
||||||
span: SpanData,
|
span: Span,
|
||||||
tt: &ast::Adt,
|
tt: &ast::Adt,
|
||||||
tm: SpanMapRef<'_>,
|
tm: SpanMapRef<'_>,
|
||||||
) -> ExpandResult<tt::Subtree> {
|
) -> ExpandResult<tt::Subtree> {
|
||||||
|
@ -725,7 +726,7 @@ fn partial_eq_expand(
|
||||||
fn self_and_other_patterns(
|
fn self_and_other_patterns(
|
||||||
adt: &BasicAdtInfo,
|
adt: &BasicAdtInfo,
|
||||||
name: &tt::Ident,
|
name: &tt::Ident,
|
||||||
span: SpanData,
|
span: Span,
|
||||||
) -> (Vec<tt::Subtree>, Vec<tt::Subtree>) {
|
) -> (Vec<tt::Subtree>, Vec<tt::Subtree>) {
|
||||||
let self_patterns = adt.shape.as_pattern_map(
|
let self_patterns = adt.shape.as_pattern_map(
|
||||||
name,
|
name,
|
||||||
|
@ -749,7 +750,7 @@ fn self_and_other_patterns(
|
||||||
fn ord_expand(
|
fn ord_expand(
|
||||||
db: &dyn ExpandDatabase,
|
db: &dyn ExpandDatabase,
|
||||||
id: MacroCallId,
|
id: MacroCallId,
|
||||||
span: SpanData,
|
span: Span,
|
||||||
tt: &ast::Adt,
|
tt: &ast::Adt,
|
||||||
tm: SpanMapRef<'_>,
|
tm: SpanMapRef<'_>,
|
||||||
) -> ExpandResult<tt::Subtree> {
|
) -> ExpandResult<tt::Subtree> {
|
||||||
|
@ -760,7 +761,7 @@ fn ord_expand(
|
||||||
left: tt::Subtree,
|
left: tt::Subtree,
|
||||||
right: tt::Subtree,
|
right: tt::Subtree,
|
||||||
rest: tt::Subtree,
|
rest: tt::Subtree,
|
||||||
span: SpanData,
|
span: Span,
|
||||||
) -> tt::Subtree {
|
) -> tt::Subtree {
|
||||||
let fat_arrow1 = fat_arrow(span);
|
let fat_arrow1 = fat_arrow(span);
|
||||||
let fat_arrow2 = fat_arrow(span);
|
let fat_arrow2 = fat_arrow(span);
|
||||||
|
@ -813,7 +814,7 @@ fn ord_expand(
|
||||||
fn partial_ord_expand(
|
fn partial_ord_expand(
|
||||||
db: &dyn ExpandDatabase,
|
db: &dyn ExpandDatabase,
|
||||||
id: MacroCallId,
|
id: MacroCallId,
|
||||||
span: SpanData,
|
span: Span,
|
||||||
tt: &ast::Adt,
|
tt: &ast::Adt,
|
||||||
tm: SpanMapRef<'_>,
|
tm: SpanMapRef<'_>,
|
||||||
) -> ExpandResult<tt::Subtree> {
|
) -> ExpandResult<tt::Subtree> {
|
||||||
|
@ -824,7 +825,7 @@ fn partial_ord_expand(
|
||||||
left: tt::Subtree,
|
left: tt::Subtree,
|
||||||
right: tt::Subtree,
|
right: tt::Subtree,
|
||||||
rest: tt::Subtree,
|
rest: tt::Subtree,
|
||||||
span: SpanData,
|
span: Span,
|
||||||
) -> tt::Subtree {
|
) -> tt::Subtree {
|
||||||
let fat_arrow1 = fat_arrow(span);
|
let fat_arrow1 = fat_arrow(span);
|
||||||
let fat_arrow2 = fat_arrow(span);
|
let fat_arrow2 = fat_arrow(span);
|
||||||
|
|
|
@ -1,13 +1,11 @@
|
||||||
//! Builtin macro
|
//! Builtin macro
|
||||||
|
|
||||||
use base_db::{
|
use base_db::{AnchoredPath, Edition, FileId};
|
||||||
span::{SpanAnchor, SpanData, SyntaxContextId, ROOT_ERASED_FILE_AST_ID},
|
|
||||||
AnchoredPath, Edition, FileId,
|
|
||||||
};
|
|
||||||
use cfg::CfgExpr;
|
use cfg::CfgExpr;
|
||||||
use either::Either;
|
use either::Either;
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use mbe::{parse_exprs_with_sep, parse_to_token_tree};
|
use mbe::{parse_exprs_with_sep, parse_to_token_tree};
|
||||||
|
use span::{Span, SpanAnchor, SyntaxContextId, ROOT_ERASED_FILE_AST_ID};
|
||||||
use syntax::{
|
use syntax::{
|
||||||
ast::{self, AstToken},
|
ast::{self, AstToken},
|
||||||
SmolStr,
|
SmolStr,
|
||||||
|
@ -122,7 +120,7 @@ register_builtin! {
|
||||||
(option_env, OptionEnv) => option_env_expand
|
(option_env, OptionEnv) => option_env_expand
|
||||||
}
|
}
|
||||||
|
|
||||||
fn mk_pound(span: SpanData) -> tt::Subtree {
|
fn mk_pound(span: Span) -> tt::Subtree {
|
||||||
crate::quote::IntoTt::to_subtree(
|
crate::quote::IntoTt::to_subtree(
|
||||||
vec![crate::tt::Leaf::Punct(crate::tt::Punct {
|
vec![crate::tt::Leaf::Punct(crate::tt::Punct {
|
||||||
char: '#',
|
char: '#',
|
||||||
|
@ -138,7 +136,7 @@ fn module_path_expand(
|
||||||
_db: &dyn ExpandDatabase,
|
_db: &dyn ExpandDatabase,
|
||||||
_id: MacroCallId,
|
_id: MacroCallId,
|
||||||
_tt: &tt::Subtree,
|
_tt: &tt::Subtree,
|
||||||
span: SpanData,
|
span: Span,
|
||||||
) -> ExpandResult<tt::Subtree> {
|
) -> ExpandResult<tt::Subtree> {
|
||||||
// Just return a dummy result.
|
// Just return a dummy result.
|
||||||
ExpandResult::ok(quote! {span =>
|
ExpandResult::ok(quote! {span =>
|
||||||
|
@ -150,7 +148,7 @@ fn line_expand(
|
||||||
_db: &dyn ExpandDatabase,
|
_db: &dyn ExpandDatabase,
|
||||||
_id: MacroCallId,
|
_id: MacroCallId,
|
||||||
_tt: &tt::Subtree,
|
_tt: &tt::Subtree,
|
||||||
span: SpanData,
|
span: Span,
|
||||||
) -> ExpandResult<tt::Subtree> {
|
) -> ExpandResult<tt::Subtree> {
|
||||||
// dummy implementation for type-checking purposes
|
// dummy implementation for type-checking purposes
|
||||||
// Note that `line!` and `column!` will never be implemented properly, as they are by definition
|
// Note that `line!` and `column!` will never be implemented properly, as they are by definition
|
||||||
|
@ -168,7 +166,7 @@ fn log_syntax_expand(
|
||||||
_db: &dyn ExpandDatabase,
|
_db: &dyn ExpandDatabase,
|
||||||
_id: MacroCallId,
|
_id: MacroCallId,
|
||||||
_tt: &tt::Subtree,
|
_tt: &tt::Subtree,
|
||||||
span: SpanData,
|
span: Span,
|
||||||
) -> ExpandResult<tt::Subtree> {
|
) -> ExpandResult<tt::Subtree> {
|
||||||
ExpandResult::ok(quote! {span =>})
|
ExpandResult::ok(quote! {span =>})
|
||||||
}
|
}
|
||||||
|
@ -177,7 +175,7 @@ fn trace_macros_expand(
|
||||||
_db: &dyn ExpandDatabase,
|
_db: &dyn ExpandDatabase,
|
||||||
_id: MacroCallId,
|
_id: MacroCallId,
|
||||||
_tt: &tt::Subtree,
|
_tt: &tt::Subtree,
|
||||||
span: SpanData,
|
span: Span,
|
||||||
) -> ExpandResult<tt::Subtree> {
|
) -> ExpandResult<tt::Subtree> {
|
||||||
ExpandResult::ok(quote! {span =>})
|
ExpandResult::ok(quote! {span =>})
|
||||||
}
|
}
|
||||||
|
@ -186,7 +184,7 @@ fn stringify_expand(
|
||||||
_db: &dyn ExpandDatabase,
|
_db: &dyn ExpandDatabase,
|
||||||
_id: MacroCallId,
|
_id: MacroCallId,
|
||||||
tt: &tt::Subtree,
|
tt: &tt::Subtree,
|
||||||
span: SpanData,
|
span: Span,
|
||||||
) -> ExpandResult<tt::Subtree> {
|
) -> ExpandResult<tt::Subtree> {
|
||||||
let pretty = ::tt::pretty(&tt.token_trees);
|
let pretty = ::tt::pretty(&tt.token_trees);
|
||||||
|
|
||||||
|
@ -201,7 +199,7 @@ fn assert_expand(
|
||||||
_db: &dyn ExpandDatabase,
|
_db: &dyn ExpandDatabase,
|
||||||
_id: MacroCallId,
|
_id: MacroCallId,
|
||||||
tt: &tt::Subtree,
|
tt: &tt::Subtree,
|
||||||
span: SpanData,
|
span: Span,
|
||||||
) -> ExpandResult<tt::Subtree> {
|
) -> ExpandResult<tt::Subtree> {
|
||||||
let args = parse_exprs_with_sep(tt, ',');
|
let args = parse_exprs_with_sep(tt, ',');
|
||||||
let dollar_crate = tt::Ident { text: SmolStr::new_inline("$crate"), span };
|
let dollar_crate = tt::Ident { text: SmolStr::new_inline("$crate"), span };
|
||||||
|
@ -233,7 +231,7 @@ fn file_expand(
|
||||||
_db: &dyn ExpandDatabase,
|
_db: &dyn ExpandDatabase,
|
||||||
_id: MacroCallId,
|
_id: MacroCallId,
|
||||||
_tt: &tt::Subtree,
|
_tt: &tt::Subtree,
|
||||||
span: SpanData,
|
span: Span,
|
||||||
) -> ExpandResult<tt::Subtree> {
|
) -> ExpandResult<tt::Subtree> {
|
||||||
// FIXME: RA purposefully lacks knowledge of absolute file names
|
// FIXME: RA purposefully lacks knowledge of absolute file names
|
||||||
// so just return "".
|
// so just return "".
|
||||||
|
@ -250,7 +248,7 @@ fn format_args_expand(
|
||||||
db: &dyn ExpandDatabase,
|
db: &dyn ExpandDatabase,
|
||||||
id: MacroCallId,
|
id: MacroCallId,
|
||||||
tt: &tt::Subtree,
|
tt: &tt::Subtree,
|
||||||
span: SpanData,
|
span: Span,
|
||||||
) -> ExpandResult<tt::Subtree> {
|
) -> ExpandResult<tt::Subtree> {
|
||||||
format_args_expand_general(db, id, tt, "", span)
|
format_args_expand_general(db, id, tt, "", span)
|
||||||
}
|
}
|
||||||
|
@ -259,7 +257,7 @@ fn format_args_nl_expand(
|
||||||
db: &dyn ExpandDatabase,
|
db: &dyn ExpandDatabase,
|
||||||
id: MacroCallId,
|
id: MacroCallId,
|
||||||
tt: &tt::Subtree,
|
tt: &tt::Subtree,
|
||||||
span: SpanData,
|
span: Span,
|
||||||
) -> ExpandResult<tt::Subtree> {
|
) -> ExpandResult<tt::Subtree> {
|
||||||
format_args_expand_general(db, id, tt, "\\n", span)
|
format_args_expand_general(db, id, tt, "\\n", span)
|
||||||
}
|
}
|
||||||
|
@ -270,7 +268,7 @@ fn format_args_expand_general(
|
||||||
tt: &tt::Subtree,
|
tt: &tt::Subtree,
|
||||||
// FIXME: Make use of this so that mir interpretation works properly
|
// FIXME: Make use of this so that mir interpretation works properly
|
||||||
_end_string: &str,
|
_end_string: &str,
|
||||||
span: SpanData,
|
span: Span,
|
||||||
) -> ExpandResult<tt::Subtree> {
|
) -> ExpandResult<tt::Subtree> {
|
||||||
let pound = mk_pound(span);
|
let pound = mk_pound(span);
|
||||||
let mut tt = tt.clone();
|
let mut tt = tt.clone();
|
||||||
|
@ -284,7 +282,7 @@ fn asm_expand(
|
||||||
_db: &dyn ExpandDatabase,
|
_db: &dyn ExpandDatabase,
|
||||||
_id: MacroCallId,
|
_id: MacroCallId,
|
||||||
tt: &tt::Subtree,
|
tt: &tt::Subtree,
|
||||||
span: SpanData,
|
span: Span,
|
||||||
) -> ExpandResult<tt::Subtree> {
|
) -> ExpandResult<tt::Subtree> {
|
||||||
// We expand all assembly snippets to `format_args!` invocations to get format syntax
|
// We expand all assembly snippets to `format_args!` invocations to get format syntax
|
||||||
// highlighting for them.
|
// highlighting for them.
|
||||||
|
@ -314,7 +312,7 @@ fn global_asm_expand(
|
||||||
_db: &dyn ExpandDatabase,
|
_db: &dyn ExpandDatabase,
|
||||||
_id: MacroCallId,
|
_id: MacroCallId,
|
||||||
_tt: &tt::Subtree,
|
_tt: &tt::Subtree,
|
||||||
span: SpanData,
|
span: Span,
|
||||||
) -> ExpandResult<tt::Subtree> {
|
) -> ExpandResult<tt::Subtree> {
|
||||||
// Expand to nothing (at item-level)
|
// Expand to nothing (at item-level)
|
||||||
ExpandResult::ok(quote! {span =>})
|
ExpandResult::ok(quote! {span =>})
|
||||||
|
@ -324,7 +322,7 @@ fn cfg_expand(
|
||||||
db: &dyn ExpandDatabase,
|
db: &dyn ExpandDatabase,
|
||||||
id: MacroCallId,
|
id: MacroCallId,
|
||||||
tt: &tt::Subtree,
|
tt: &tt::Subtree,
|
||||||
span: SpanData,
|
span: Span,
|
||||||
) -> ExpandResult<tt::Subtree> {
|
) -> ExpandResult<tt::Subtree> {
|
||||||
let loc = db.lookup_intern_macro_call(id);
|
let loc = db.lookup_intern_macro_call(id);
|
||||||
let expr = CfgExpr::parse(tt);
|
let expr = CfgExpr::parse(tt);
|
||||||
|
@ -337,7 +335,7 @@ fn panic_expand(
|
||||||
db: &dyn ExpandDatabase,
|
db: &dyn ExpandDatabase,
|
||||||
id: MacroCallId,
|
id: MacroCallId,
|
||||||
tt: &tt::Subtree,
|
tt: &tt::Subtree,
|
||||||
span: SpanData,
|
span: Span,
|
||||||
) -> ExpandResult<tt::Subtree> {
|
) -> ExpandResult<tt::Subtree> {
|
||||||
let loc: MacroCallLoc = db.lookup_intern_macro_call(id);
|
let loc: MacroCallLoc = db.lookup_intern_macro_call(id);
|
||||||
let dollar_crate = tt::Ident { text: SmolStr::new_inline("$crate"), span };
|
let dollar_crate = tt::Ident { text: SmolStr::new_inline("$crate"), span };
|
||||||
|
@ -357,7 +355,7 @@ fn unreachable_expand(
|
||||||
db: &dyn ExpandDatabase,
|
db: &dyn ExpandDatabase,
|
||||||
id: MacroCallId,
|
id: MacroCallId,
|
||||||
tt: &tt::Subtree,
|
tt: &tt::Subtree,
|
||||||
span: SpanData,
|
span: Span,
|
||||||
) -> ExpandResult<tt::Subtree> {
|
) -> ExpandResult<tt::Subtree> {
|
||||||
let loc: MacroCallLoc = db.lookup_intern_macro_call(id);
|
let loc: MacroCallLoc = db.lookup_intern_macro_call(id);
|
||||||
// Expand to a macro call `$crate::panic::unreachable_{edition}`
|
// Expand to a macro call `$crate::panic::unreachable_{edition}`
|
||||||
|
@ -395,7 +393,7 @@ fn compile_error_expand(
|
||||||
_db: &dyn ExpandDatabase,
|
_db: &dyn ExpandDatabase,
|
||||||
_id: MacroCallId,
|
_id: MacroCallId,
|
||||||
tt: &tt::Subtree,
|
tt: &tt::Subtree,
|
||||||
span: SpanData,
|
span: Span,
|
||||||
) -> ExpandResult<tt::Subtree> {
|
) -> ExpandResult<tt::Subtree> {
|
||||||
let err = match &*tt.token_trees {
|
let err = match &*tt.token_trees {
|
||||||
[tt::TokenTree::Leaf(tt::Leaf::Literal(it))] => match unquote_str(it) {
|
[tt::TokenTree::Leaf(tt::Leaf::Literal(it))] => match unquote_str(it) {
|
||||||
|
@ -412,7 +410,7 @@ fn concat_expand(
|
||||||
_db: &dyn ExpandDatabase,
|
_db: &dyn ExpandDatabase,
|
||||||
_arg_id: MacroCallId,
|
_arg_id: MacroCallId,
|
||||||
tt: &tt::Subtree,
|
tt: &tt::Subtree,
|
||||||
span: SpanData,
|
span: Span,
|
||||||
) -> ExpandResult<tt::Subtree> {
|
) -> ExpandResult<tt::Subtree> {
|
||||||
let mut err = None;
|
let mut err = None;
|
||||||
let mut text = String::new();
|
let mut text = String::new();
|
||||||
|
@ -459,7 +457,7 @@ fn concat_bytes_expand(
|
||||||
_db: &dyn ExpandDatabase,
|
_db: &dyn ExpandDatabase,
|
||||||
_arg_id: MacroCallId,
|
_arg_id: MacroCallId,
|
||||||
tt: &tt::Subtree,
|
tt: &tt::Subtree,
|
||||||
span: SpanData,
|
span: Span,
|
||||||
) -> ExpandResult<tt::Subtree> {
|
) -> ExpandResult<tt::Subtree> {
|
||||||
let mut bytes = Vec::new();
|
let mut bytes = Vec::new();
|
||||||
let mut err = None;
|
let mut err = None;
|
||||||
|
@ -543,7 +541,7 @@ fn concat_idents_expand(
|
||||||
_db: &dyn ExpandDatabase,
|
_db: &dyn ExpandDatabase,
|
||||||
_arg_id: MacroCallId,
|
_arg_id: MacroCallId,
|
||||||
tt: &tt::Subtree,
|
tt: &tt::Subtree,
|
||||||
span: SpanData,
|
span: Span,
|
||||||
) -> ExpandResult<tt::Subtree> {
|
) -> ExpandResult<tt::Subtree> {
|
||||||
let mut err = None;
|
let mut err = None;
|
||||||
let mut ident = String::new();
|
let mut ident = String::new();
|
||||||
|
@ -596,7 +594,7 @@ fn include_expand(
|
||||||
db: &dyn ExpandDatabase,
|
db: &dyn ExpandDatabase,
|
||||||
arg_id: MacroCallId,
|
arg_id: MacroCallId,
|
||||||
tt: &tt::Subtree,
|
tt: &tt::Subtree,
|
||||||
span: SpanData,
|
span: Span,
|
||||||
) -> ExpandResult<tt::Subtree> {
|
) -> ExpandResult<tt::Subtree> {
|
||||||
let file_id = match include_input_to_file_id(db, arg_id, tt) {
|
let file_id = match include_input_to_file_id(db, arg_id, tt) {
|
||||||
Ok(it) => it,
|
Ok(it) => it,
|
||||||
|
@ -629,7 +627,7 @@ fn include_bytes_expand(
|
||||||
_db: &dyn ExpandDatabase,
|
_db: &dyn ExpandDatabase,
|
||||||
_arg_id: MacroCallId,
|
_arg_id: MacroCallId,
|
||||||
_tt: &tt::Subtree,
|
_tt: &tt::Subtree,
|
||||||
span: SpanData,
|
span: Span,
|
||||||
) -> ExpandResult<tt::Subtree> {
|
) -> ExpandResult<tt::Subtree> {
|
||||||
// FIXME: actually read the file here if the user asked for macro expansion
|
// FIXME: actually read the file here if the user asked for macro expansion
|
||||||
let res = tt::Subtree {
|
let res = tt::Subtree {
|
||||||
|
@ -646,7 +644,7 @@ fn include_str_expand(
|
||||||
db: &dyn ExpandDatabase,
|
db: &dyn ExpandDatabase,
|
||||||
arg_id: MacroCallId,
|
arg_id: MacroCallId,
|
||||||
tt: &tt::Subtree,
|
tt: &tt::Subtree,
|
||||||
span: SpanData,
|
span: Span,
|
||||||
) -> ExpandResult<tt::Subtree> {
|
) -> ExpandResult<tt::Subtree> {
|
||||||
let path = match parse_string(tt) {
|
let path = match parse_string(tt) {
|
||||||
Ok(it) => it,
|
Ok(it) => it,
|
||||||
|
@ -681,7 +679,7 @@ fn env_expand(
|
||||||
db: &dyn ExpandDatabase,
|
db: &dyn ExpandDatabase,
|
||||||
arg_id: MacroCallId,
|
arg_id: MacroCallId,
|
||||||
tt: &tt::Subtree,
|
tt: &tt::Subtree,
|
||||||
span: SpanData,
|
span: Span,
|
||||||
) -> ExpandResult<tt::Subtree> {
|
) -> ExpandResult<tt::Subtree> {
|
||||||
let key = match parse_string(tt) {
|
let key = match parse_string(tt) {
|
||||||
Ok(it) => it,
|
Ok(it) => it,
|
||||||
|
@ -713,7 +711,7 @@ fn option_env_expand(
|
||||||
db: &dyn ExpandDatabase,
|
db: &dyn ExpandDatabase,
|
||||||
arg_id: MacroCallId,
|
arg_id: MacroCallId,
|
||||||
tt: &tt::Subtree,
|
tt: &tt::Subtree,
|
||||||
span: SpanData,
|
span: Span,
|
||||||
) -> ExpandResult<tt::Subtree> {
|
) -> ExpandResult<tt::Subtree> {
|
||||||
let key = match parse_string(tt) {
|
let key = match parse_string(tt) {
|
||||||
Ok(it) => it,
|
Ok(it) => it,
|
||||||
|
|
|
@ -2,13 +2,13 @@
|
||||||
|
|
||||||
use base_db::{
|
use base_db::{
|
||||||
salsa::{self, debug::DebugQueryTable},
|
salsa::{self, debug::DebugQueryTable},
|
||||||
span::SyntaxContextId,
|
|
||||||
CrateId, Edition, FileId, SourceDatabase,
|
CrateId, Edition, FileId, SourceDatabase,
|
||||||
};
|
};
|
||||||
use either::Either;
|
use either::Either;
|
||||||
use limit::Limit;
|
use limit::Limit;
|
||||||
use mbe::{syntax_node_to_token_tree, ValueResult};
|
use mbe::{syntax_node_to_token_tree, ValueResult};
|
||||||
use rustc_hash::FxHashSet;
|
use rustc_hash::FxHashSet;
|
||||||
|
use span::SyntaxContextId;
|
||||||
use syntax::{
|
use syntax::{
|
||||||
ast::{self, HasAttrs},
|
ast::{self, HasAttrs},
|
||||||
AstNode, Parse, SyntaxError, SyntaxNode, SyntaxToken, T,
|
AstNode, Parse, SyntaxError, SyntaxNode, SyntaxToken, T,
|
||||||
|
@ -23,7 +23,7 @@ use crate::{
|
||||||
fixup::{self, reverse_fixups, SyntaxFixupUndoInfo},
|
fixup::{self, reverse_fixups, SyntaxFixupUndoInfo},
|
||||||
hygiene::{apply_mark, SyntaxContextData, Transparency},
|
hygiene::{apply_mark, SyntaxContextData, Transparency},
|
||||||
proc_macro::ProcMacros,
|
proc_macro::ProcMacros,
|
||||||
span::{RealSpanMap, SpanMap, SpanMapRef},
|
span_map::{RealSpanMap, SpanMap, SpanMapRef},
|
||||||
tt, AstId, BuiltinAttrExpander, BuiltinDeriveExpander, BuiltinFnLikeExpander,
|
tt, AstId, BuiltinAttrExpander, BuiltinDeriveExpander, BuiltinFnLikeExpander,
|
||||||
CustomProcMacroExpander, EagerCallInfo, ExpandError, ExpandResult, ExpandTo, ExpansionSpanMap,
|
CustomProcMacroExpander, EagerCallInfo, ExpandError, ExpandResult, ExpandTo, ExpansionSpanMap,
|
||||||
HirFileId, HirFileIdRepr, MacroCallId, MacroCallKind, MacroCallLoc, MacroDefId, MacroDefKind,
|
HirFileId, HirFileIdRepr, MacroCallId, MacroCallKind, MacroCallLoc, MacroDefId, MacroDefKind,
|
||||||
|
@ -41,7 +41,7 @@ static TOKEN_LIMIT: Limit = Limit::new(1_048_576);
|
||||||
#[derive(Debug, Clone, Eq, PartialEq)]
|
#[derive(Debug, Clone, Eq, PartialEq)]
|
||||||
/// Old-style `macro_rules` or the new macros 2.0
|
/// Old-style `macro_rules` or the new macros 2.0
|
||||||
pub struct DeclarativeMacroExpander {
|
pub struct DeclarativeMacroExpander {
|
||||||
pub mac: mbe::DeclarativeMacro<base_db::span::SpanData>,
|
pub mac: mbe::DeclarativeMacro<span::Span>,
|
||||||
pub transparency: Transparency,
|
pub transparency: Transparency,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,8 @@
|
||||||
//!
|
//!
|
||||||
//!
|
//!
|
||||||
//! See the full discussion : <https://rust-lang.zulipchat.com/#narrow/stream/131828-t-compiler/topic/Eager.20expansion.20of.20built-in.20macros>
|
//! See the full discussion : <https://rust-lang.zulipchat.com/#narrow/stream/131828-t-compiler/topic/Eager.20expansion.20of.20built-in.20macros>
|
||||||
use base_db::{span::SyntaxContextId, CrateId};
|
use base_db::CrateId;
|
||||||
|
use span::SyntaxContextId;
|
||||||
use syntax::{ted, Parse, SyntaxElement, SyntaxNode, TextSize, WalkEvent};
|
use syntax::{ted, Parse, SyntaxElement, SyntaxNode, TextSize, WalkEvent};
|
||||||
use triomphe::Arc;
|
use triomphe::Arc;
|
||||||
|
|
||||||
|
@ -26,7 +27,7 @@ use crate::{
|
||||||
ast::{self, AstNode},
|
ast::{self, AstNode},
|
||||||
db::ExpandDatabase,
|
db::ExpandDatabase,
|
||||||
mod_path::ModPath,
|
mod_path::ModPath,
|
||||||
span::SpanMapRef,
|
span_map::SpanMapRef,
|
||||||
EagerCallInfo, ExpandError, ExpandResult, ExpandTo, ExpansionSpanMap, InFile, MacroCallId,
|
EagerCallInfo, ExpandError, ExpandResult, ExpandTo, ExpansionSpanMap, InFile, MacroCallId,
|
||||||
MacroCallKind, MacroCallLoc, MacroDefId, MacroDefKind,
|
MacroCallKind, MacroCallLoc, MacroDefId, MacroDefKind,
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,11 +1,8 @@
|
||||||
//! Things to wrap other things in file ids.
|
//! Things to wrap other things in file ids.
|
||||||
use std::iter;
|
use std::iter;
|
||||||
|
|
||||||
use base_db::{
|
|
||||||
span::{HirFileId, HirFileIdRepr, MacroFileId, SyntaxContextId},
|
|
||||||
FileId, FileRange,
|
|
||||||
};
|
|
||||||
use either::Either;
|
use either::Either;
|
||||||
|
use span::{FileId, FileRange, HirFileId, HirFileIdRepr, MacroFileId, SyntaxContextId};
|
||||||
use syntax::{AstNode, SyntaxNode, SyntaxToken, TextRange, TextSize};
|
use syntax::{AstNode, SyntaxNode, SyntaxToken, TextRange, TextSize};
|
||||||
|
|
||||||
use crate::{db, ExpansionInfo, MacroFileIdExt};
|
use crate::{db, ExpansionInfo, MacroFileIdExt};
|
||||||
|
|
|
@ -2,12 +2,13 @@
|
||||||
use std::{mem, ops::Not, str::FromStr, sync};
|
use std::{mem, ops::Not, str::FromStr, sync};
|
||||||
|
|
||||||
use base_db::{
|
use base_db::{
|
||||||
salsa::Durability, span::SpanData, CrateDisplayName, CrateGraph, CrateId, CrateName,
|
salsa::Durability, CrateDisplayName, CrateGraph, CrateId, CrateName, CrateOrigin, Dependency,
|
||||||
CrateOrigin, Dependency, DependencyKind, Edition, Env, FileChange, FileId, FilePosition,
|
DependencyKind, Edition, Env, FileChange, FileSet, LangCrateOrigin, ReleaseChannel,
|
||||||
FileRange, FileSet, LangCrateOrigin, ReleaseChannel, SourceDatabaseExt, SourceRoot, VfsPath,
|
SourceDatabaseExt, SourceRoot, VfsPath,
|
||||||
};
|
};
|
||||||
use cfg::CfgOptions;
|
use cfg::CfgOptions;
|
||||||
use rustc_hash::FxHashMap;
|
use rustc_hash::FxHashMap;
|
||||||
|
use span::{FileId, FilePosition, FileRange, Span};
|
||||||
use test_utils::{
|
use test_utils::{
|
||||||
extract_range_or_offset, Fixture, FixtureWithProjectMeta, RangeOrOffset, CURSOR_MARKER,
|
extract_range_or_offset, Fixture, FixtureWithProjectMeta, RangeOrOffset, CURSOR_MARKER,
|
||||||
ESCAPED_CURSOR_MARKER,
|
ESCAPED_CURSOR_MARKER,
|
||||||
|
@ -580,13 +581,13 @@ struct IdentityProcMacroExpander;
|
||||||
impl ProcMacroExpander for IdentityProcMacroExpander {
|
impl ProcMacroExpander for IdentityProcMacroExpander {
|
||||||
fn expand(
|
fn expand(
|
||||||
&self,
|
&self,
|
||||||
subtree: &Subtree<SpanData>,
|
subtree: &Subtree<Span>,
|
||||||
_: Option<&Subtree<SpanData>>,
|
_: Option<&Subtree<Span>>,
|
||||||
_: &Env,
|
_: &Env,
|
||||||
_: SpanData,
|
_: Span,
|
||||||
_: SpanData,
|
_: Span,
|
||||||
_: SpanData,
|
_: Span,
|
||||||
) -> Result<Subtree<SpanData>, ProcMacroExpansionError> {
|
) -> Result<Subtree<Span>, ProcMacroExpansionError> {
|
||||||
Ok(subtree.clone())
|
Ok(subtree.clone())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -597,13 +598,13 @@ struct AttributeInputReplaceProcMacroExpander;
|
||||||
impl ProcMacroExpander for AttributeInputReplaceProcMacroExpander {
|
impl ProcMacroExpander for AttributeInputReplaceProcMacroExpander {
|
||||||
fn expand(
|
fn expand(
|
||||||
&self,
|
&self,
|
||||||
_: &Subtree<SpanData>,
|
_: &Subtree<Span>,
|
||||||
attrs: Option<&Subtree<SpanData>>,
|
attrs: Option<&Subtree<Span>>,
|
||||||
_: &Env,
|
_: &Env,
|
||||||
_: SpanData,
|
_: Span,
|
||||||
_: SpanData,
|
_: Span,
|
||||||
_: SpanData,
|
_: Span,
|
||||||
) -> Result<Subtree<SpanData>, ProcMacroExpansionError> {
|
) -> Result<Subtree<Span>, ProcMacroExpansionError> {
|
||||||
attrs
|
attrs
|
||||||
.cloned()
|
.cloned()
|
||||||
.ok_or_else(|| ProcMacroExpansionError::Panic("Expected attribute input".into()))
|
.ok_or_else(|| ProcMacroExpansionError::Panic("Expected attribute input".into()))
|
||||||
|
@ -615,14 +616,14 @@ struct MirrorProcMacroExpander;
|
||||||
impl ProcMacroExpander for MirrorProcMacroExpander {
|
impl ProcMacroExpander for MirrorProcMacroExpander {
|
||||||
fn expand(
|
fn expand(
|
||||||
&self,
|
&self,
|
||||||
input: &Subtree<SpanData>,
|
input: &Subtree<Span>,
|
||||||
_: Option<&Subtree<SpanData>>,
|
_: Option<&Subtree<Span>>,
|
||||||
_: &Env,
|
_: &Env,
|
||||||
_: SpanData,
|
_: Span,
|
||||||
_: SpanData,
|
_: Span,
|
||||||
_: SpanData,
|
_: Span,
|
||||||
) -> Result<Subtree<SpanData>, ProcMacroExpansionError> {
|
) -> Result<Subtree<Span>, ProcMacroExpansionError> {
|
||||||
fn traverse(input: &Subtree<SpanData>) -> Subtree<SpanData> {
|
fn traverse(input: &Subtree<Span>) -> Subtree<Span> {
|
||||||
let mut token_trees = vec![];
|
let mut token_trees = vec![];
|
||||||
for tt in input.token_trees.iter().rev() {
|
for tt in input.token_trees.iter().rev() {
|
||||||
let tt = match tt {
|
let tt = match tt {
|
||||||
|
@ -645,16 +646,16 @@ struct ShortenProcMacroExpander;
|
||||||
impl ProcMacroExpander for ShortenProcMacroExpander {
|
impl ProcMacroExpander for ShortenProcMacroExpander {
|
||||||
fn expand(
|
fn expand(
|
||||||
&self,
|
&self,
|
||||||
input: &Subtree<SpanData>,
|
input: &Subtree<Span>,
|
||||||
_: Option<&Subtree<SpanData>>,
|
_: Option<&Subtree<Span>>,
|
||||||
_: &Env,
|
_: &Env,
|
||||||
_: SpanData,
|
_: Span,
|
||||||
_: SpanData,
|
_: Span,
|
||||||
_: SpanData,
|
_: Span,
|
||||||
) -> Result<Subtree<SpanData>, ProcMacroExpansionError> {
|
) -> Result<Subtree<Span>, ProcMacroExpansionError> {
|
||||||
return Ok(traverse(input));
|
return Ok(traverse(input));
|
||||||
|
|
||||||
fn traverse(input: &Subtree<SpanData>) -> Subtree<SpanData> {
|
fn traverse(input: &Subtree<Span>) -> Subtree<Span> {
|
||||||
let token_trees = input
|
let token_trees = input
|
||||||
.token_trees
|
.token_trees
|
||||||
.iter()
|
.iter()
|
||||||
|
@ -666,7 +667,7 @@ impl ProcMacroExpander for ShortenProcMacroExpander {
|
||||||
Subtree { delimiter: input.delimiter, token_trees }
|
Subtree { delimiter: input.delimiter, token_trees }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn modify_leaf(leaf: &Leaf<SpanData>) -> Leaf<SpanData> {
|
fn modify_leaf(leaf: &Leaf<Span>) -> Leaf<Span> {
|
||||||
let mut leaf = leaf.clone();
|
let mut leaf = leaf.clone();
|
||||||
match &mut leaf {
|
match &mut leaf {
|
||||||
Leaf::Literal(it) => {
|
Leaf::Literal(it) => {
|
||||||
|
|
|
@ -1,23 +1,20 @@
|
||||||
//! To make attribute macros work reliably when typing, we need to take care to
|
//! To make attribute macros work reliably when typing, we need to take care to
|
||||||
//! fix up syntax errors in the code we're passing to them.
|
//! fix up syntax errors in the code we're passing to them.
|
||||||
|
|
||||||
use base_db::{
|
|
||||||
span::{ErasedFileAstId, SpanAnchor, SpanData},
|
|
||||||
FileId,
|
|
||||||
};
|
|
||||||
use la_arena::RawIdx;
|
use la_arena::RawIdx;
|
||||||
use rustc_hash::{FxHashMap, FxHashSet};
|
use rustc_hash::{FxHashMap, FxHashSet};
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
|
use span::{ErasedFileAstId, FileId, SpanAnchor, SpanData};
|
||||||
use stdx::never;
|
use stdx::never;
|
||||||
use syntax::{
|
use syntax::{
|
||||||
ast::{self, AstNode, HasLoopBody},
|
ast::{self, AstNode, HasLoopBody},
|
||||||
match_ast, SyntaxElement, SyntaxKind, SyntaxNode, TextRange, TextSize,
|
match_ast, SyntaxElement, SyntaxKind, SyntaxNode, TextRange, TextSize,
|
||||||
};
|
};
|
||||||
use triomphe::Arc;
|
use triomphe::Arc;
|
||||||
use tt::{Spacing, Span};
|
use tt::Spacing;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
span::SpanMapRef,
|
span_map::SpanMapRef,
|
||||||
tt::{Ident, Leaf, Punct, Subtree},
|
tt::{Ident, Leaf, Punct, Subtree},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -301,6 +298,7 @@ fn has_error_to_handle(node: &SyntaxNode) -> bool {
|
||||||
pub(crate) fn reverse_fixups(tt: &mut Subtree, undo_info: &SyntaxFixupUndoInfo) {
|
pub(crate) fn reverse_fixups(tt: &mut Subtree, undo_info: &SyntaxFixupUndoInfo) {
|
||||||
let Some(undo_info) = undo_info.original.as_deref() else { return };
|
let Some(undo_info) = undo_info.original.as_deref() else { return };
|
||||||
let undo_info = &**undo_info;
|
let undo_info = &**undo_info;
|
||||||
|
#[allow(deprecated)]
|
||||||
if never!(
|
if never!(
|
||||||
tt.delimiter.close.anchor.file_id == FIXUP_DUMMY_FILE
|
tt.delimiter.close.anchor.file_id == FIXUP_DUMMY_FILE
|
||||||
|| tt.delimiter.open.anchor.file_id == FIXUP_DUMMY_FILE
|
|| tt.delimiter.open.anchor.file_id == FIXUP_DUMMY_FILE
|
||||||
|
@ -364,7 +362,7 @@ mod tests {
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
fixup::reverse_fixups,
|
fixup::reverse_fixups,
|
||||||
span::{RealSpanMap, SpanMap},
|
span_map::{RealSpanMap, SpanMap},
|
||||||
tt,
|
tt,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
//! this moment, this is horribly incomplete and handles only `$crate`.
|
//! this moment, this is horribly incomplete and handles only `$crate`.
|
||||||
use std::iter;
|
use std::iter;
|
||||||
|
|
||||||
use base_db::span::{MacroCallId, SpanData, SyntaxContextId};
|
use span::{MacroCallId, Span, SyntaxContextId};
|
||||||
|
|
||||||
use crate::db::ExpandDatabase;
|
use crate::db::ExpandDatabase;
|
||||||
|
|
||||||
|
@ -78,37 +78,29 @@ pub enum Transparency {
|
||||||
Opaque,
|
Opaque,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn span_with_def_site_ctxt(
|
pub fn span_with_def_site_ctxt(db: &dyn ExpandDatabase, span: Span, expn_id: MacroCallId) -> Span {
|
||||||
db: &dyn ExpandDatabase,
|
|
||||||
span: SpanData,
|
|
||||||
expn_id: MacroCallId,
|
|
||||||
) -> SpanData {
|
|
||||||
span_with_ctxt_from_mark(db, span, expn_id, Transparency::Opaque)
|
span_with_ctxt_from_mark(db, span, expn_id, Transparency::Opaque)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn span_with_call_site_ctxt(
|
pub fn span_with_call_site_ctxt(db: &dyn ExpandDatabase, span: Span, expn_id: MacroCallId) -> Span {
|
||||||
db: &dyn ExpandDatabase,
|
|
||||||
span: SpanData,
|
|
||||||
expn_id: MacroCallId,
|
|
||||||
) -> SpanData {
|
|
||||||
span_with_ctxt_from_mark(db, span, expn_id, Transparency::Transparent)
|
span_with_ctxt_from_mark(db, span, expn_id, Transparency::Transparent)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn span_with_mixed_site_ctxt(
|
pub fn span_with_mixed_site_ctxt(
|
||||||
db: &dyn ExpandDatabase,
|
db: &dyn ExpandDatabase,
|
||||||
span: SpanData,
|
span: Span,
|
||||||
expn_id: MacroCallId,
|
expn_id: MacroCallId,
|
||||||
) -> SpanData {
|
) -> Span {
|
||||||
span_with_ctxt_from_mark(db, span, expn_id, Transparency::SemiTransparent)
|
span_with_ctxt_from_mark(db, span, expn_id, Transparency::SemiTransparent)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn span_with_ctxt_from_mark(
|
fn span_with_ctxt_from_mark(
|
||||||
db: &dyn ExpandDatabase,
|
db: &dyn ExpandDatabase,
|
||||||
span: SpanData,
|
span: Span,
|
||||||
expn_id: MacroCallId,
|
expn_id: MacroCallId,
|
||||||
transparency: Transparency,
|
transparency: Transparency,
|
||||||
) -> SpanData {
|
) -> Span {
|
||||||
SpanData { ctx: apply_mark(db, SyntaxContextId::ROOT, expn_id, transparency), ..span }
|
Span { ctx: apply_mark(db, SyntaxContextId::ROOT, expn_id, transparency), ..span }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn apply_mark(
|
pub(super) fn apply_mark(
|
||||||
|
|
|
@ -20,7 +20,7 @@ pub mod mod_path;
|
||||||
pub mod name;
|
pub mod name;
|
||||||
pub mod proc_macro;
|
pub mod proc_macro;
|
||||||
pub mod quote;
|
pub mod quote;
|
||||||
pub mod span;
|
pub mod span_map;
|
||||||
mod fixup;
|
mod fixup;
|
||||||
|
|
||||||
use attrs::collect_attrs;
|
use attrs::collect_attrs;
|
||||||
|
@ -28,11 +28,9 @@ use triomphe::Arc;
|
||||||
|
|
||||||
use std::{fmt, hash::Hash};
|
use std::{fmt, hash::Hash};
|
||||||
|
|
||||||
use base_db::{
|
use base_db::{CrateId, FileId};
|
||||||
span::{HirFileIdRepr, SpanData, SyntaxContextId},
|
|
||||||
CrateId, FileId, FileRange,
|
|
||||||
};
|
|
||||||
use either::Either;
|
use either::Either;
|
||||||
|
use span::{FileRange, HirFileIdRepr, Span, SyntaxContextId};
|
||||||
use syntax::{
|
use syntax::{
|
||||||
ast::{self, AstNode},
|
ast::{self, AstNode},
|
||||||
SyntaxNode, SyntaxToken, TextRange, TextSize,
|
SyntaxNode, SyntaxToken, TextRange, TextSize,
|
||||||
|
@ -47,29 +45,29 @@ use crate::{
|
||||||
fixup::SyntaxFixupUndoInfo,
|
fixup::SyntaxFixupUndoInfo,
|
||||||
mod_path::ModPath,
|
mod_path::ModPath,
|
||||||
proc_macro::{CustomProcMacroExpander, ProcMacroKind},
|
proc_macro::{CustomProcMacroExpander, ProcMacroKind},
|
||||||
span::{ExpansionSpanMap, SpanMap},
|
span_map::{ExpansionSpanMap, SpanMap},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub use crate::ast_id_map::{AstId, ErasedAstId, ErasedFileAstId};
|
pub use crate::ast_id_map::{AstId, ErasedAstId, ErasedFileAstId};
|
||||||
pub use crate::files::{InFile, InMacroFile, InRealFile};
|
pub use crate::files::{InFile, InMacroFile, InRealFile};
|
||||||
|
|
||||||
pub use base_db::span::{HirFileId, MacroCallId, MacroFileId};
|
|
||||||
pub use mbe::ValueResult;
|
pub use mbe::ValueResult;
|
||||||
|
pub use span::{HirFileId, MacroCallId, MacroFileId};
|
||||||
|
|
||||||
pub type DeclarativeMacro = ::mbe::DeclarativeMacro<tt::SpanData>;
|
pub type DeclarativeMacro = ::mbe::DeclarativeMacro<tt::Span>;
|
||||||
|
|
||||||
pub mod tt {
|
pub mod tt {
|
||||||
pub use base_db::span::SpanData;
|
pub use span::Span;
|
||||||
pub use tt::{DelimiterKind, Spacing, Span, SpanAnchor};
|
pub use tt::{DelimiterKind, Spacing};
|
||||||
|
|
||||||
pub type Delimiter = ::tt::Delimiter<SpanData>;
|
pub type Delimiter = ::tt::Delimiter<Span>;
|
||||||
pub type DelimSpan = ::tt::DelimSpan<SpanData>;
|
pub type DelimSpan = ::tt::DelimSpan<Span>;
|
||||||
pub type Subtree = ::tt::Subtree<SpanData>;
|
pub type Subtree = ::tt::Subtree<Span>;
|
||||||
pub type Leaf = ::tt::Leaf<SpanData>;
|
pub type Leaf = ::tt::Leaf<Span>;
|
||||||
pub type Literal = ::tt::Literal<SpanData>;
|
pub type Literal = ::tt::Literal<Span>;
|
||||||
pub type Punct = ::tt::Punct<SpanData>;
|
pub type Punct = ::tt::Punct<Span>;
|
||||||
pub type Ident = ::tt::Ident<SpanData>;
|
pub type Ident = ::tt::Ident<Span>;
|
||||||
pub type TokenTree = ::tt::TokenTree<SpanData>;
|
pub type TokenTree = ::tt::TokenTree<Span>;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type ExpandResult<T> = ValueResult<T, ExpandError>;
|
pub type ExpandResult<T> = ValueResult<T, ExpandError>;
|
||||||
|
@ -212,8 +210,8 @@ impl HirFileIdExt for HirFileId {
|
||||||
fn original_file_respecting_includes(mut self, db: &dyn db::ExpandDatabase) -> FileId {
|
fn original_file_respecting_includes(mut self, db: &dyn db::ExpandDatabase) -> FileId {
|
||||||
loop {
|
loop {
|
||||||
match self.repr() {
|
match self.repr() {
|
||||||
base_db::span::HirFileIdRepr::FileId(id) => break id,
|
HirFileIdRepr::FileId(id) => break id,
|
||||||
base_db::span::HirFileIdRepr::MacroFile(file) => {
|
HirFileIdRepr::MacroFile(file) => {
|
||||||
let loc = db.lookup_intern_macro_call(file.macro_call_id);
|
let loc = db.lookup_intern_macro_call(file.macro_call_id);
|
||||||
if loc.def.is_include() {
|
if loc.def.is_include() {
|
||||||
if let Some(eager) = &loc.eager {
|
if let Some(eager) = &loc.eager {
|
||||||
|
@ -420,7 +418,7 @@ impl MacroDefId {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MacroCallLoc {
|
impl MacroCallLoc {
|
||||||
pub fn span(&self, db: &dyn db::ExpandDatabase) -> SpanData {
|
pub fn span(&self, db: &dyn db::ExpandDatabase) -> Span {
|
||||||
let ast_id = self.kind.erased_ast_id();
|
let ast_id = self.kind.erased_ast_id();
|
||||||
let file_id = self.kind.file_id();
|
let file_id = self.kind.file_id();
|
||||||
let range = db.ast_id_map(file_id).get_erased(ast_id).text_range();
|
let range = db.ast_id_map(file_id).get_erased(ast_id).text_range();
|
||||||
|
@ -618,7 +616,7 @@ impl ExpansionInfo {
|
||||||
/// Maps the passed in file range down into a macro expansion if it is the input to a macro call.
|
/// Maps the passed in file range down into a macro expansion if it is the input to a macro call.
|
||||||
pub fn map_range_down<'a>(
|
pub fn map_range_down<'a>(
|
||||||
&'a self,
|
&'a self,
|
||||||
span: SpanData,
|
span: Span,
|
||||||
) -> Option<InMacroFile<impl Iterator<Item = SyntaxToken> + 'a>> {
|
) -> Option<InMacroFile<impl Iterator<Item = SyntaxToken> + 'a>> {
|
||||||
let tokens = self
|
let tokens = self
|
||||||
.exp_map
|
.exp_map
|
||||||
|
@ -652,7 +650,7 @@ impl ExpansionInfo {
|
||||||
) -> Option<(FileRange, SyntaxContextId)> {
|
) -> Option<(FileRange, SyntaxContextId)> {
|
||||||
debug_assert!(self.expanded.value.text_range().contains_range(range));
|
debug_assert!(self.expanded.value.text_range().contains_range(range));
|
||||||
let mut spans = self.exp_map.spans_for_range(range);
|
let mut spans = self.exp_map.spans_for_range(range);
|
||||||
let SpanData { range, anchor, ctx } = spans.next()?;
|
let Span { range, anchor, ctx } = spans.next()?;
|
||||||
let mut start = range.start();
|
let mut start = range.start();
|
||||||
let mut end = range.end();
|
let mut end = range.end();
|
||||||
|
|
||||||
|
|
|
@ -9,10 +9,11 @@ use crate::{
|
||||||
db::ExpandDatabase,
|
db::ExpandDatabase,
|
||||||
hygiene::{marks_rev, SyntaxContextExt, Transparency},
|
hygiene::{marks_rev, SyntaxContextExt, Transparency},
|
||||||
name::{known, AsName, Name},
|
name::{known, AsName, Name},
|
||||||
span::SpanMapRef,
|
span_map::SpanMapRef,
|
||||||
};
|
};
|
||||||
use base_db::{span::SyntaxContextId, CrateId};
|
use base_db::CrateId;
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
|
use span::SyntaxContextId;
|
||||||
use syntax::{ast, AstNode};
|
use syntax::{ast, AstNode};
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
|
|
|
@ -3,8 +3,9 @@
|
||||||
use core::fmt;
|
use core::fmt;
|
||||||
use std::{panic::RefUnwindSafe, sync};
|
use std::{panic::RefUnwindSafe, sync};
|
||||||
|
|
||||||
use base_db::{span::SpanData, CrateId, Env};
|
use base_db::{CrateId, Env};
|
||||||
use rustc_hash::FxHashMap;
|
use rustc_hash::FxHashMap;
|
||||||
|
use span::Span;
|
||||||
use stdx::never;
|
use stdx::never;
|
||||||
use syntax::SmolStr;
|
use syntax::SmolStr;
|
||||||
|
|
||||||
|
@ -26,9 +27,9 @@ pub trait ProcMacroExpander: fmt::Debug + Send + Sync + RefUnwindSafe {
|
||||||
subtree: &tt::Subtree,
|
subtree: &tt::Subtree,
|
||||||
attrs: Option<&tt::Subtree>,
|
attrs: Option<&tt::Subtree>,
|
||||||
env: &Env,
|
env: &Env,
|
||||||
def_site: SpanData,
|
def_site: Span,
|
||||||
call_site: SpanData,
|
call_site: Span,
|
||||||
mixed_site: SpanData,
|
mixed_site: Span,
|
||||||
) -> Result<tt::Subtree, ProcMacroExpansionError>;
|
) -> Result<tt::Subtree, ProcMacroExpansionError>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,9 +79,9 @@ impl CustomProcMacroExpander {
|
||||||
calling_crate: CrateId,
|
calling_crate: CrateId,
|
||||||
tt: &tt::Subtree,
|
tt: &tt::Subtree,
|
||||||
attr_arg: Option<&tt::Subtree>,
|
attr_arg: Option<&tt::Subtree>,
|
||||||
def_site: SpanData,
|
def_site: Span,
|
||||||
call_site: SpanData,
|
call_site: Span,
|
||||||
mixed_site: SpanData,
|
mixed_site: Span,
|
||||||
) -> ExpandResult<tt::Subtree> {
|
) -> ExpandResult<tt::Subtree> {
|
||||||
match self.proc_macro_id {
|
match self.proc_macro_id {
|
||||||
ProcMacroId(DUMMY_ID) => ExpandResult::new(
|
ProcMacroId(DUMMY_ID) => ExpandResult::new(
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
//! A simplified version of quote-crate like quasi quote macro
|
//! A simplified version of quote-crate like quasi quote macro
|
||||||
|
|
||||||
use base_db::span::SpanData;
|
use span::Span;
|
||||||
|
|
||||||
// A helper macro quote macro
|
// A helper macro quote macro
|
||||||
// FIXME:
|
// FIXME:
|
||||||
|
@ -130,12 +130,12 @@ macro_rules! quote {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) trait IntoTt {
|
pub(crate) trait IntoTt {
|
||||||
fn to_subtree(self, span: SpanData) -> crate::tt::Subtree;
|
fn to_subtree(self, span: Span) -> crate::tt::Subtree;
|
||||||
fn to_tokens(self) -> Vec<crate::tt::TokenTree>;
|
fn to_tokens(self) -> Vec<crate::tt::TokenTree>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl IntoTt for Vec<crate::tt::TokenTree> {
|
impl IntoTt for Vec<crate::tt::TokenTree> {
|
||||||
fn to_subtree(self, span: SpanData) -> crate::tt::Subtree {
|
fn to_subtree(self, span: Span) -> crate::tt::Subtree {
|
||||||
crate::tt::Subtree {
|
crate::tt::Subtree {
|
||||||
delimiter: crate::tt::Delimiter::invisible_spanned(span),
|
delimiter: crate::tt::Delimiter::invisible_spanned(span),
|
||||||
token_trees: self,
|
token_trees: self,
|
||||||
|
@ -148,7 +148,7 @@ impl IntoTt for Vec<crate::tt::TokenTree> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl IntoTt for crate::tt::Subtree {
|
impl IntoTt for crate::tt::Subtree {
|
||||||
fn to_subtree(self, _: SpanData) -> crate::tt::Subtree {
|
fn to_subtree(self, _: Span) -> crate::tt::Subtree {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -158,23 +158,23 @@ impl IntoTt for crate::tt::Subtree {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) trait ToTokenTree {
|
pub(crate) trait ToTokenTree {
|
||||||
fn to_token(self, span: SpanData) -> crate::tt::TokenTree;
|
fn to_token(self, span: Span) -> crate::tt::TokenTree;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ToTokenTree for crate::tt::TokenTree {
|
impl ToTokenTree for crate::tt::TokenTree {
|
||||||
fn to_token(self, _: SpanData) -> crate::tt::TokenTree {
|
fn to_token(self, _: Span) -> crate::tt::TokenTree {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ToTokenTree for &crate::tt::TokenTree {
|
impl ToTokenTree for &crate::tt::TokenTree {
|
||||||
fn to_token(self, _: SpanData) -> crate::tt::TokenTree {
|
fn to_token(self, _: Span) -> crate::tt::TokenTree {
|
||||||
self.clone()
|
self.clone()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ToTokenTree for crate::tt::Subtree {
|
impl ToTokenTree for crate::tt::Subtree {
|
||||||
fn to_token(self, _: SpanData) -> crate::tt::TokenTree {
|
fn to_token(self, _: Span) -> crate::tt::TokenTree {
|
||||||
self.into()
|
self.into()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -183,14 +183,14 @@ macro_rules! impl_to_to_tokentrees {
|
||||||
($($span:ident: $ty:ty => $this:ident $im:block);*) => {
|
($($span:ident: $ty:ty => $this:ident $im:block);*) => {
|
||||||
$(
|
$(
|
||||||
impl ToTokenTree for $ty {
|
impl ToTokenTree for $ty {
|
||||||
fn to_token($this, $span: SpanData) -> crate::tt::TokenTree {
|
fn to_token($this, $span: Span) -> crate::tt::TokenTree {
|
||||||
let leaf: crate::tt::Leaf = $im.into();
|
let leaf: crate::tt::Leaf = $im.into();
|
||||||
leaf.into()
|
leaf.into()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ToTokenTree for &$ty {
|
impl ToTokenTree for &$ty {
|
||||||
fn to_token($this, $span: SpanData) -> crate::tt::TokenTree {
|
fn to_token($this, $span: Span) -> crate::tt::TokenTree {
|
||||||
let leaf: crate::tt::Leaf = $im.clone().into();
|
let leaf: crate::tt::Leaf = $im.clone().into();
|
||||||
leaf.into()
|
leaf.into()
|
||||||
}
|
}
|
||||||
|
@ -215,14 +215,12 @@ impl_to_to_tokentrees! {
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use crate::tt;
|
use crate::tt;
|
||||||
use base_db::{
|
use base_db::FileId;
|
||||||
span::{SpanAnchor, SyntaxContextId, ROOT_ERASED_FILE_AST_ID},
|
|
||||||
FileId,
|
|
||||||
};
|
|
||||||
use expect_test::expect;
|
use expect_test::expect;
|
||||||
|
use span::{SpanAnchor, SyntaxContextId, ROOT_ERASED_FILE_AST_ID};
|
||||||
use syntax::{TextRange, TextSize};
|
use syntax::{TextRange, TextSize};
|
||||||
|
|
||||||
const DUMMY: tt::SpanData = tt::SpanData {
|
const DUMMY: tt::Span = tt::Span {
|
||||||
range: TextRange::empty(TextSize::new(0)),
|
range: TextRange::empty(TextSize::new(0)),
|
||||||
anchor: SpanAnchor { file_id: FileId::BOGUS, ast_id: ROOT_ERASED_FILE_AST_ID },
|
anchor: SpanAnchor { file_id: FileId::BOGUS, ast_id: ROOT_ERASED_FILE_AST_ID },
|
||||||
ctx: SyntaxContextId::ROOT,
|
ctx: SyntaxContextId::ROOT,
|
||||||
|
@ -261,8 +259,8 @@ mod tests {
|
||||||
assert_eq!(quoted.to_string(), "hello");
|
assert_eq!(quoted.to_string(), "hello");
|
||||||
let t = format!("{quoted:?}");
|
let t = format!("{quoted:?}");
|
||||||
expect![[r#"
|
expect![[r#"
|
||||||
SUBTREE $$ SpanData { range: 0..0, anchor: SpanAnchor(FileId(937550), 0), ctx: SyntaxContextId(0) } SpanData { range: 0..0, anchor: SpanAnchor(FileId(937550), 0), ctx: SyntaxContextId(0) }
|
SUBTREE $$ Span { range: 0..0, anchor: SpanAnchor(FileId(937550), 0), ctx: SyntaxContextId(0) } Span { range: 0..0, anchor: SpanAnchor(FileId(937550), 0), ctx: SyntaxContextId(0) }
|
||||||
IDENT hello SpanData { range: 0..0, anchor: SpanAnchor(FileId(937550), 0), ctx: SyntaxContextId(0) }"#]].assert_eq(&t);
|
IDENT hello Span { range: 0..0, anchor: SpanAnchor(FileId(937550), 0), ctx: SyntaxContextId(0) }"#]].assert_eq(&t);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
@ -1,15 +1,16 @@
|
||||||
//! Spanmaps allow turning absolute ranges into relative ranges for incrementality purposes as well
|
//! Spanmaps allow turning absolute ranges into relative ranges for incrementality purposes as well
|
||||||
//! as associating spans with text ranges in a particular file.
|
//! as associating spans with text ranges in a particular file.
|
||||||
use base_db::{
|
|
||||||
span::{ErasedFileAstId, SpanAnchor, SpanData, SyntaxContextId, ROOT_ERASED_FILE_AST_ID},
|
// FIXME: Consider moving this into the span crate
|
||||||
FileId,
|
|
||||||
};
|
use base_db::FileId;
|
||||||
|
use span::{ErasedFileAstId, Span, SpanAnchor, SyntaxContextId, ROOT_ERASED_FILE_AST_ID};
|
||||||
use syntax::{ast::HasModuleItem, AstNode, TextRange, TextSize};
|
use syntax::{ast::HasModuleItem, AstNode, TextRange, TextSize};
|
||||||
use triomphe::Arc;
|
use triomphe::Arc;
|
||||||
|
|
||||||
use crate::db::ExpandDatabase;
|
use crate::db::ExpandDatabase;
|
||||||
|
|
||||||
pub type ExpansionSpanMap = mbe::SpanMap<SpanData>;
|
pub type ExpansionSpanMap = span::SpanMap<Span>;
|
||||||
|
|
||||||
/// Spanmap for a macro file or a real file
|
/// Spanmap for a macro file or a real file
|
||||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||||
|
@ -28,24 +29,24 @@ pub enum SpanMapRef<'a> {
|
||||||
RealSpanMap(&'a RealSpanMap),
|
RealSpanMap(&'a RealSpanMap),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl mbe::SpanMapper<SpanData> for SpanMap {
|
impl mbe::SpanMapper<Span> for SpanMap {
|
||||||
fn span_for(&self, range: TextRange) -> SpanData {
|
fn span_for(&self, range: TextRange) -> Span {
|
||||||
self.span_for_range(range)
|
self.span_for_range(range)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl mbe::SpanMapper<SpanData> for SpanMapRef<'_> {
|
impl mbe::SpanMapper<Span> for SpanMapRef<'_> {
|
||||||
fn span_for(&self, range: TextRange) -> SpanData {
|
fn span_for(&self, range: TextRange) -> Span {
|
||||||
self.span_for_range(range)
|
self.span_for_range(range)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl mbe::SpanMapper<SpanData> for RealSpanMap {
|
impl mbe::SpanMapper<Span> for RealSpanMap {
|
||||||
fn span_for(&self, range: TextRange) -> SpanData {
|
fn span_for(&self, range: TextRange) -> Span {
|
||||||
self.span_for_range(range)
|
self.span_for_range(range)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SpanMap {
|
impl SpanMap {
|
||||||
pub fn span_for_range(&self, range: TextRange) -> SpanData {
|
pub fn span_for_range(&self, range: TextRange) -> Span {
|
||||||
match self {
|
match self {
|
||||||
Self::ExpansionSpanMap(span_map) => span_map.span_at(range.start()),
|
Self::ExpansionSpanMap(span_map) => span_map.span_at(range.start()),
|
||||||
Self::RealSpanMap(span_map) => span_map.span_for_range(range),
|
Self::RealSpanMap(span_map) => span_map.span_for_range(range),
|
||||||
|
@ -61,7 +62,7 @@ impl SpanMap {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SpanMapRef<'_> {
|
impl SpanMapRef<'_> {
|
||||||
pub fn span_for_range(self, range: TextRange) -> SpanData {
|
pub fn span_for_range(self, range: TextRange) -> Span {
|
||||||
match self {
|
match self {
|
||||||
Self::ExpansionSpanMap(span_map) => span_map.span_at(range.start()),
|
Self::ExpansionSpanMap(span_map) => span_map.span_at(range.start()),
|
||||||
Self::RealSpanMap(span_map) => span_map.span_for_range(range),
|
Self::RealSpanMap(span_map) => span_map.span_for_range(range),
|
||||||
|
@ -103,7 +104,7 @@ impl RealSpanMap {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn span_for_range(&self, range: TextRange) -> SpanData {
|
pub fn span_for_range(&self, range: TextRange) -> Span {
|
||||||
assert!(
|
assert!(
|
||||||
range.end() <= self.end,
|
range.end() <= self.end,
|
||||||
"range {range:?} goes beyond the end of the file {:?}",
|
"range {range:?} goes beyond the end of the file {:?}",
|
||||||
|
@ -115,7 +116,7 @@ impl RealSpanMap {
|
||||||
.binary_search_by(|&(it, _)| it.cmp(&start).then(std::cmp::Ordering::Less))
|
.binary_search_by(|&(it, _)| it.cmp(&start).then(std::cmp::Ordering::Less))
|
||||||
.unwrap_err();
|
.unwrap_err();
|
||||||
let (offset, ast_id) = self.pairs[idx - 1];
|
let (offset, ast_id) = self.pairs[idx - 1];
|
||||||
SpanData {
|
Span {
|
||||||
range: range - offset,
|
range: range - offset,
|
||||||
anchor: SpanAnchor { file_id: self.file_id, ast_id },
|
anchor: SpanAnchor { file_id: self.file_id, ast_id },
|
||||||
ctx: SyntaxContextId::ROOT,
|
ctx: SyntaxContextId::ROOT,
|
|
@ -11,7 +11,7 @@ use hir_def::{
|
||||||
};
|
};
|
||||||
use hir_expand::{
|
use hir_expand::{
|
||||||
name::Name,
|
name::Name,
|
||||||
span::{RealSpanMap, SpanMapRef},
|
span_map::{RealSpanMap, SpanMapRef},
|
||||||
};
|
};
|
||||||
use hir_ty::db::HirDatabase;
|
use hir_ty::db::HirDatabase;
|
||||||
use syntax::{ast, AstNode};
|
use syntax::{ast, AstNode};
|
||||||
|
|
|
@ -148,7 +148,7 @@ use {
|
||||||
hir_def::path::Path,
|
hir_def::path::Path,
|
||||||
hir_expand::{
|
hir_expand::{
|
||||||
name::AsName,
|
name::AsName,
|
||||||
span::{ExpansionSpanMap, RealSpanMap, SpanMap, SpanMapRef},
|
span_map::{ExpansionSpanMap, RealSpanMap, SpanMap, SpanMapRef},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -34,6 +34,7 @@ profile.workspace = true
|
||||||
stdx.workspace = true
|
stdx.workspace = true
|
||||||
syntax.workspace = true
|
syntax.workspace = true
|
||||||
text-edit.workspace = true
|
text-edit.workspace = true
|
||||||
|
span.workspace = true
|
||||||
# ide should depend only on the top-level `hir` package. if you need
|
# ide should depend only on the top-level `hir` package. if you need
|
||||||
# something from some `hir-xxx` subpackage, reexport the API via `hir`.
|
# something from some `hir-xxx` subpackage, reexport the API via `hir`.
|
||||||
hir.workspace = true
|
hir.workspace = true
|
||||||
|
|
|
@ -22,9 +22,10 @@
|
||||||
//! Our current behavior is ¯\_(ツ)_/¯.
|
//! Our current behavior is ¯\_(ツ)_/¯.
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
use base_db::{span::SyntaxContextId, AnchoredPathBuf, FileId, FileRange};
|
use base_db::{AnchoredPathBuf, FileId, FileRange};
|
||||||
use either::Either;
|
use either::Either;
|
||||||
use hir::{FieldSource, HasSource, HirFileIdExt, InFile, ModuleSource, Semantics};
|
use hir::{FieldSource, HasSource, HirFileIdExt, InFile, ModuleSource, Semantics};
|
||||||
|
use span::SyntaxContextId;
|
||||||
use stdx::{never, TupleExt};
|
use stdx::{never, TupleExt};
|
||||||
use syntax::{
|
use syntax::{
|
||||||
ast::{self, HasName},
|
ast::{self, HasName},
|
||||||
|
|
|
@ -23,5 +23,6 @@ project-model.workspace = true
|
||||||
tt.workspace = true
|
tt.workspace = true
|
||||||
vfs.workspace = true
|
vfs.workspace = true
|
||||||
vfs-notify.workspace = true
|
vfs-notify.workspace = true
|
||||||
|
span.workspace = true
|
||||||
|
|
||||||
hir-expand.workspace = true
|
hir-expand.workspace = true
|
||||||
|
|
|
@ -11,13 +11,14 @@ use hir_expand::proc_macro::{
|
||||||
};
|
};
|
||||||
use ide::{AnalysisHost, SourceRoot};
|
use ide::{AnalysisHost, SourceRoot};
|
||||||
use ide_db::{
|
use ide_db::{
|
||||||
base_db::{span::SpanData, CrateGraph, Env},
|
base_db::{CrateGraph, Env},
|
||||||
fixture::Change,
|
fixture::Change,
|
||||||
FxHashMap,
|
FxHashMap,
|
||||||
};
|
};
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use proc_macro_api::{MacroDylib, ProcMacroServer};
|
use proc_macro_api::{MacroDylib, ProcMacroServer};
|
||||||
use project_model::{CargoConfig, PackageRoot, ProjectManifest, ProjectWorkspace};
|
use project_model::{CargoConfig, PackageRoot, ProjectManifest, ProjectWorkspace};
|
||||||
|
use span::Span;
|
||||||
use tt::DelimSpan;
|
use tt::DelimSpan;
|
||||||
use vfs::{file_set::FileSetConfig, loader::Handle, AbsPath, AbsPathBuf, VfsPath};
|
use vfs::{file_set::FileSetConfig, loader::Handle, AbsPath, AbsPathBuf, VfsPath};
|
||||||
|
|
||||||
|
@ -376,13 +377,13 @@ struct Expander(proc_macro_api::ProcMacro);
|
||||||
impl ProcMacroExpander for Expander {
|
impl ProcMacroExpander for Expander {
|
||||||
fn expand(
|
fn expand(
|
||||||
&self,
|
&self,
|
||||||
subtree: &tt::Subtree<SpanData>,
|
subtree: &tt::Subtree<Span>,
|
||||||
attrs: Option<&tt::Subtree<SpanData>>,
|
attrs: Option<&tt::Subtree<Span>>,
|
||||||
env: &Env,
|
env: &Env,
|
||||||
def_site: SpanData,
|
def_site: Span,
|
||||||
call_site: SpanData,
|
call_site: Span,
|
||||||
mixed_site: SpanData,
|
mixed_site: Span,
|
||||||
) -> Result<tt::Subtree<SpanData>, ProcMacroExpansionError> {
|
) -> Result<tt::Subtree<Span>, ProcMacroExpansionError> {
|
||||||
let env = env.iter().map(|(k, v)| (k.to_string(), v.to_string())).collect();
|
let env = env.iter().map(|(k, v)| (k.to_string(), v.to_string())).collect();
|
||||||
match self.0.expand(subtree, attrs, env, def_site, call_site, mixed_site) {
|
match self.0.expand(subtree, attrs, env, def_site, call_site, mixed_site) {
|
||||||
Ok(Ok(subtree)) => Ok(subtree),
|
Ok(Ok(subtree)) => Ok(subtree),
|
||||||
|
@ -399,13 +400,13 @@ struct IdentityExpander;
|
||||||
impl ProcMacroExpander for IdentityExpander {
|
impl ProcMacroExpander for IdentityExpander {
|
||||||
fn expand(
|
fn expand(
|
||||||
&self,
|
&self,
|
||||||
subtree: &tt::Subtree<SpanData>,
|
subtree: &tt::Subtree<Span>,
|
||||||
_: Option<&tt::Subtree<SpanData>>,
|
_: Option<&tt::Subtree<Span>>,
|
||||||
_: &Env,
|
_: &Env,
|
||||||
_: SpanData,
|
_: Span,
|
||||||
_: SpanData,
|
_: Span,
|
||||||
_: SpanData,
|
_: Span,
|
||||||
) -> Result<tt::Subtree<SpanData>, ProcMacroExpansionError> {
|
) -> Result<tt::Subtree<Span>, ProcMacroExpansionError> {
|
||||||
Ok(subtree.clone())
|
Ok(subtree.clone())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -417,13 +418,13 @@ struct EmptyExpander;
|
||||||
impl ProcMacroExpander for EmptyExpander {
|
impl ProcMacroExpander for EmptyExpander {
|
||||||
fn expand(
|
fn expand(
|
||||||
&self,
|
&self,
|
||||||
_: &tt::Subtree<SpanData>,
|
_: &tt::Subtree<Span>,
|
||||||
_: Option<&tt::Subtree<SpanData>>,
|
_: Option<&tt::Subtree<Span>>,
|
||||||
_: &Env,
|
_: &Env,
|
||||||
call_site: SpanData,
|
call_site: Span,
|
||||||
_: SpanData,
|
_: Span,
|
||||||
_: SpanData,
|
_: Span,
|
||||||
) -> Result<tt::Subtree<SpanData>, ProcMacroExpansionError> {
|
) -> Result<tt::Subtree<Span>, ProcMacroExpansionError> {
|
||||||
Ok(tt::Subtree::empty(DelimSpan { open: call_site, close: call_site }))
|
Ok(tt::Subtree::empty(DelimSpan { open: call_site, close: call_site }))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,7 @@ syntax.workspace = true
|
||||||
parser.workspace = true
|
parser.workspace = true
|
||||||
tt.workspace = true
|
tt.workspace = true
|
||||||
stdx.workspace = true
|
stdx.workspace = true
|
||||||
|
span.workspace = true
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
test-utils.workspace = true
|
test-utils.workspace = true
|
||||||
|
|
|
@ -226,6 +226,7 @@ fn expand_subtree<S: Span>(
|
||||||
tt::Leaf::Literal(tt::Literal {
|
tt::Leaf::Literal(tt::Literal {
|
||||||
text: index.to_string().into(),
|
text: index.to_string().into(),
|
||||||
// FIXME
|
// FIXME
|
||||||
|
#[allow(deprecated)]
|
||||||
span: S::DUMMY,
|
span: S::DUMMY,
|
||||||
})
|
})
|
||||||
.into(),
|
.into(),
|
||||||
|
@ -286,6 +287,7 @@ fn expand_subtree<S: Span>(
|
||||||
tt::Leaf::Literal(tt::Literal {
|
tt::Leaf::Literal(tt::Literal {
|
||||||
text: c.to_string().into(),
|
text: c.to_string().into(),
|
||||||
// FIXME
|
// FIXME
|
||||||
|
#[allow(deprecated)]
|
||||||
span: S::DUMMY,
|
span: S::DUMMY,
|
||||||
})
|
})
|
||||||
.into(),
|
.into(),
|
||||||
|
@ -343,8 +345,10 @@ fn expand_var<S: Span>(
|
||||||
Err(e) => ExpandResult {
|
Err(e) => ExpandResult {
|
||||||
value: Fragment::Tokens(tt::TokenTree::Subtree(tt::Subtree::empty(tt::DelimSpan {
|
value: Fragment::Tokens(tt::TokenTree::Subtree(tt::Subtree::empty(tt::DelimSpan {
|
||||||
// FIXME
|
// FIXME
|
||||||
|
#[allow(deprecated)]
|
||||||
open: S::DUMMY,
|
open: S::DUMMY,
|
||||||
// FIXME
|
// FIXME
|
||||||
|
#[allow(deprecated)]
|
||||||
close: S::DUMMY,
|
close: S::DUMMY,
|
||||||
}))),
|
}))),
|
||||||
err: Some(e),
|
err: Some(e),
|
||||||
|
@ -487,6 +491,7 @@ fn fix_up_and_push_path_tt<S: Span>(buf: &mut Vec<tt::TokenTree<S>>, subtree: tt
|
||||||
char: ':',
|
char: ':',
|
||||||
spacing: tt::Spacing::Joint,
|
spacing: tt::Spacing::Joint,
|
||||||
// FIXME
|
// FIXME
|
||||||
|
#[allow(deprecated)]
|
||||||
span: S::DUMMY,
|
span: S::DUMMY,
|
||||||
})
|
})
|
||||||
.into(),
|
.into(),
|
||||||
|
@ -496,6 +501,7 @@ fn fix_up_and_push_path_tt<S: Span>(buf: &mut Vec<tt::TokenTree<S>>, subtree: tt
|
||||||
char: ':',
|
char: ':',
|
||||||
spacing: tt::Spacing::Alone,
|
spacing: tt::Spacing::Alone,
|
||||||
// FIXME
|
// FIXME
|
||||||
|
#[allow(deprecated)]
|
||||||
span: S::DUMMY,
|
span: S::DUMMY,
|
||||||
})
|
})
|
||||||
.into(),
|
.into(),
|
||||||
|
|
|
@ -16,7 +16,6 @@ mod to_parser_input;
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod benchmark;
|
mod benchmark;
|
||||||
mod token_map;
|
|
||||||
|
|
||||||
use stdx::impl_from;
|
use stdx::impl_from;
|
||||||
use tt::Span;
|
use tt::Span;
|
||||||
|
@ -30,15 +29,12 @@ use crate::{
|
||||||
|
|
||||||
// FIXME: we probably should re-think `token_tree_to_syntax_node` interfaces
|
// FIXME: we probably should re-think `token_tree_to_syntax_node` interfaces
|
||||||
pub use ::parser::TopEntryPoint;
|
pub use ::parser::TopEntryPoint;
|
||||||
pub use tt::{Delimiter, DelimiterKind, Punct, SyntaxContext};
|
pub use tt::{Delimiter, DelimiterKind, Punct};
|
||||||
|
|
||||||
pub use crate::{
|
pub use crate::syntax_bridge::{
|
||||||
syntax_bridge::{
|
|
||||||
parse_exprs_with_sep, parse_to_token_tree, parse_to_token_tree_static_span,
|
parse_exprs_with_sep, parse_to_token_tree, parse_to_token_tree_static_span,
|
||||||
syntax_node_to_token_tree, syntax_node_to_token_tree_modified, token_tree_to_syntax_node,
|
syntax_node_to_token_tree, syntax_node_to_token_tree_modified, token_tree_to_syntax_node,
|
||||||
SpanMapper,
|
SpanMapper,
|
||||||
},
|
|
||||||
token_map::SpanMap,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
pub use crate::syntax_bridge::dummy_test_span_utils::*;
|
pub use crate::syntax_bridge::dummy_test_span_utils::*;
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
//! Conversions between [`SyntaxNode`] and [`tt::TokenTree`].
|
//! Conversions between [`SyntaxNode`] and [`tt::TokenTree`].
|
||||||
|
|
||||||
use rustc_hash::{FxHashMap, FxHashSet};
|
use rustc_hash::{FxHashMap, FxHashSet};
|
||||||
|
use span::{SpanAnchor, SpanData, SpanMap};
|
||||||
use stdx::{never, non_empty_vec::NonEmptyVec};
|
use stdx::{never, non_empty_vec::NonEmptyVec};
|
||||||
use syntax::{
|
use syntax::{
|
||||||
ast::{self, make::tokens::doc_comment},
|
ast::{self, make::tokens::doc_comment},
|
||||||
|
@ -10,10 +11,10 @@ use syntax::{
|
||||||
};
|
};
|
||||||
use tt::{
|
use tt::{
|
||||||
buffer::{Cursor, TokenBuffer},
|
buffer::{Cursor, TokenBuffer},
|
||||||
Span, SpanData, SyntaxContext,
|
Span, SyntaxContext,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{to_parser_input::to_parser_input, tt_iter::TtIter, SpanMap};
|
use crate::{to_parser_input::to_parser_input, tt_iter::TtIter};
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests;
|
mod tests;
|
||||||
|
@ -36,16 +37,20 @@ impl<S: Span, SM: SpanMapper<S>> SpanMapper<S> for &SM {
|
||||||
|
|
||||||
/// Dummy things for testing where spans don't matter.
|
/// Dummy things for testing where spans don't matter.
|
||||||
pub(crate) mod dummy_test_span_utils {
|
pub(crate) mod dummy_test_span_utils {
|
||||||
|
use tt::SyntaxContext;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
pub type DummyTestSpanData = tt::SpanData<DummyTestSpanAnchor, DummyTestSyntaxContext>;
|
pub type DummyTestSpanData = span::SpanData<DummyTestSyntaxContext>;
|
||||||
pub const DUMMY: DummyTestSpanData = DummyTestSpanData::DUMMY;
|
pub const DUMMY: DummyTestSpanData = span::SpanData {
|
||||||
|
range: TextRange::empty(TextSize::new(0)),
|
||||||
|
anchor: span::SpanAnchor {
|
||||||
|
file_id: span::FileId::BOGUS,
|
||||||
|
ast_id: span::ROOT_ERASED_FILE_AST_ID,
|
||||||
|
},
|
||||||
|
ctx: DummyTestSyntaxContext,
|
||||||
|
};
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
|
||||||
pub struct DummyTestSpanAnchor;
|
|
||||||
impl tt::SpanAnchor for DummyTestSpanAnchor {
|
|
||||||
const DUMMY: Self = DummyTestSpanAnchor;
|
|
||||||
}
|
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||||
pub struct DummyTestSyntaxContext;
|
pub struct DummyTestSyntaxContext;
|
||||||
impl SyntaxContext for DummyTestSyntaxContext {
|
impl SyntaxContext for DummyTestSyntaxContext {
|
||||||
|
@ -54,27 +59,30 @@ pub(crate) mod dummy_test_span_utils {
|
||||||
|
|
||||||
pub struct DummyTestSpanMap;
|
pub struct DummyTestSpanMap;
|
||||||
|
|
||||||
impl SpanMapper<tt::SpanData<DummyTestSpanAnchor, DummyTestSyntaxContext>> for DummyTestSpanMap {
|
impl SpanMapper<span::SpanData<DummyTestSyntaxContext>> for DummyTestSpanMap {
|
||||||
fn span_for(
|
fn span_for(&self, range: syntax::TextRange) -> span::SpanData<DummyTestSyntaxContext> {
|
||||||
&self,
|
span::SpanData {
|
||||||
range: syntax::TextRange,
|
range,
|
||||||
) -> tt::SpanData<DummyTestSpanAnchor, DummyTestSyntaxContext> {
|
anchor: span::SpanAnchor {
|
||||||
tt::SpanData { range, anchor: DummyTestSpanAnchor, ctx: DummyTestSyntaxContext }
|
file_id: span::FileId::BOGUS,
|
||||||
|
ast_id: span::ROOT_ERASED_FILE_AST_ID,
|
||||||
|
},
|
||||||
|
ctx: DummyTestSyntaxContext,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Converts a syntax tree to a [`tt::Subtree`] using the provided span map to populate the
|
/// Converts a syntax tree to a [`tt::Subtree`] using the provided span map to populate the
|
||||||
/// subtree's spans.
|
/// subtree's spans.
|
||||||
pub fn syntax_node_to_token_tree<Anchor, Ctx, SpanMap>(
|
pub fn syntax_node_to_token_tree<Ctx, SpanMap>(
|
||||||
node: &SyntaxNode,
|
node: &SyntaxNode,
|
||||||
map: SpanMap,
|
map: SpanMap,
|
||||||
) -> tt::Subtree<SpanData<Anchor, Ctx>>
|
) -> tt::Subtree<SpanData<Ctx>>
|
||||||
where
|
where
|
||||||
SpanData<Anchor, Ctx>: Span,
|
SpanData<Ctx>: Span,
|
||||||
Anchor: Copy,
|
|
||||||
Ctx: SyntaxContext,
|
Ctx: SyntaxContext,
|
||||||
SpanMap: SpanMapper<SpanData<Anchor, Ctx>>,
|
SpanMap: SpanMapper<SpanData<Ctx>>,
|
||||||
{
|
{
|
||||||
let mut c = Converter::new(node, map, Default::default(), Default::default());
|
let mut c = Converter::new(node, map, Default::default(), Default::default());
|
||||||
convert_tokens(&mut c)
|
convert_tokens(&mut c)
|
||||||
|
@ -83,16 +91,15 @@ where
|
||||||
/// Converts a syntax tree to a [`tt::Subtree`] using the provided span map to populate the
|
/// Converts a syntax tree to a [`tt::Subtree`] using the provided span map to populate the
|
||||||
/// subtree's spans. Additionally using the append and remove parameters, the additional tokens can
|
/// subtree's spans. Additionally using the append and remove parameters, the additional tokens can
|
||||||
/// be injected or hidden from the output.
|
/// be injected or hidden from the output.
|
||||||
pub fn syntax_node_to_token_tree_modified<Anchor, Ctx, SpanMap>(
|
pub fn syntax_node_to_token_tree_modified<Ctx, SpanMap>(
|
||||||
node: &SyntaxNode,
|
node: &SyntaxNode,
|
||||||
map: SpanMap,
|
map: SpanMap,
|
||||||
append: FxHashMap<SyntaxElement, Vec<tt::Leaf<SpanData<Anchor, Ctx>>>>,
|
append: FxHashMap<SyntaxElement, Vec<tt::Leaf<SpanData<Ctx>>>>,
|
||||||
remove: FxHashSet<SyntaxNode>,
|
remove: FxHashSet<SyntaxNode>,
|
||||||
) -> tt::Subtree<SpanData<Anchor, Ctx>>
|
) -> tt::Subtree<SpanData<Ctx>>
|
||||||
where
|
where
|
||||||
SpanMap: SpanMapper<SpanData<Anchor, Ctx>>,
|
SpanMap: SpanMapper<SpanData<Ctx>>,
|
||||||
SpanData<Anchor, Ctx>: Span,
|
SpanData<Ctx>: Span,
|
||||||
Anchor: Copy,
|
|
||||||
Ctx: SyntaxContext,
|
Ctx: SyntaxContext,
|
||||||
{
|
{
|
||||||
let mut c = Converter::new(node, map, append, remove);
|
let mut c = Converter::new(node, map, append, remove);
|
||||||
|
@ -113,13 +120,12 @@ where
|
||||||
|
|
||||||
/// Converts a [`tt::Subtree`] back to a [`SyntaxNode`].
|
/// Converts a [`tt::Subtree`] back to a [`SyntaxNode`].
|
||||||
/// The produced `SpanMap` contains a mapping from the syntax nodes offsets to the subtree's spans.
|
/// The produced `SpanMap` contains a mapping from the syntax nodes offsets to the subtree's spans.
|
||||||
pub fn token_tree_to_syntax_node<Anchor, Ctx>(
|
pub fn token_tree_to_syntax_node<Ctx>(
|
||||||
tt: &tt::Subtree<SpanData<Anchor, Ctx>>,
|
tt: &tt::Subtree<SpanData<Ctx>>,
|
||||||
entry_point: parser::TopEntryPoint,
|
entry_point: parser::TopEntryPoint,
|
||||||
) -> (Parse<SyntaxNode>, SpanMap<SpanData<Anchor, Ctx>>)
|
) -> (Parse<SyntaxNode>, SpanMap<SpanData<Ctx>>)
|
||||||
where
|
where
|
||||||
SpanData<Anchor, Ctx>: Span,
|
SpanData<Ctx>: Span,
|
||||||
Anchor: Copy,
|
|
||||||
Ctx: SyntaxContext,
|
Ctx: SyntaxContext,
|
||||||
{
|
{
|
||||||
let buffer = match tt {
|
let buffer = match tt {
|
||||||
|
@ -150,21 +156,20 @@ where
|
||||||
|
|
||||||
/// Convert a string to a `TokenTree`. The spans of the subtree will be anchored to the provided
|
/// Convert a string to a `TokenTree`. The spans of the subtree will be anchored to the provided
|
||||||
/// anchor with the given context.
|
/// anchor with the given context.
|
||||||
pub fn parse_to_token_tree<Anchor, Ctx>(
|
pub fn parse_to_token_tree<Ctx>(
|
||||||
anchor: Anchor,
|
anchor: SpanAnchor,
|
||||||
ctx: Ctx,
|
ctx: Ctx,
|
||||||
text: &str,
|
text: &str,
|
||||||
) -> Option<tt::Subtree<SpanData<Anchor, Ctx>>>
|
) -> Option<tt::Subtree<SpanData<Ctx>>>
|
||||||
where
|
where
|
||||||
SpanData<Anchor, Ctx>: Span,
|
SpanData<Ctx>: Span,
|
||||||
Anchor: Copy,
|
|
||||||
Ctx: SyntaxContext,
|
Ctx: SyntaxContext,
|
||||||
{
|
{
|
||||||
let lexed = parser::LexedStr::new(text);
|
let lexed = parser::LexedStr::new(text);
|
||||||
if lexed.errors().next().is_some() {
|
if lexed.errors().next().is_some() {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
let mut conv = RawConverter { lexed, pos: 0, anchor, ctx };
|
let mut conv = RawConverter { lexed, anchor, pos: 0, ctx };
|
||||||
Some(convert_tokens(&mut conv))
|
Some(convert_tokens(&mut conv))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -450,10 +455,10 @@ fn convert_doc_comment<S: Copy>(
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A raw token (straight from lexer) converter
|
/// A raw token (straight from lexer) converter
|
||||||
struct RawConverter<'a, Anchor, Ctx> {
|
struct RawConverter<'a, Ctx> {
|
||||||
lexed: parser::LexedStr<'a>,
|
lexed: parser::LexedStr<'a>,
|
||||||
pos: usize,
|
pos: usize,
|
||||||
anchor: Anchor,
|
anchor: SpanAnchor,
|
||||||
ctx: Ctx,
|
ctx: Ctx,
|
||||||
}
|
}
|
||||||
/// A raw token (straight from lexer) converter that gives every token the same span.
|
/// A raw token (straight from lexer) converter that gives every token the same span.
|
||||||
|
@ -487,16 +492,16 @@ trait TokenConverter<S>: Sized {
|
||||||
fn span_for(&self, range: TextRange) -> S;
|
fn span_for(&self, range: TextRange) -> S;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Anchor, S, Ctx> SrcToken<RawConverter<'_, Anchor, Ctx>, S> for usize {
|
impl<S, Ctx> SrcToken<RawConverter<'_, Ctx>, S> for usize {
|
||||||
fn kind(&self, ctx: &RawConverter<'_, Anchor, Ctx>) -> SyntaxKind {
|
fn kind(&self, ctx: &RawConverter<'_, Ctx>) -> SyntaxKind {
|
||||||
ctx.lexed.kind(*self)
|
ctx.lexed.kind(*self)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_char(&self, ctx: &RawConverter<'_, Anchor, Ctx>) -> Option<char> {
|
fn to_char(&self, ctx: &RawConverter<'_, Ctx>) -> Option<char> {
|
||||||
ctx.lexed.text(*self).chars().next()
|
ctx.lexed.text(*self).chars().next()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_text(&self, ctx: &RawConverter<'_, Anchor, Ctx>) -> SmolStr {
|
fn to_text(&self, ctx: &RawConverter<'_, Ctx>) -> SmolStr {
|
||||||
ctx.lexed.text(*self).into()
|
ctx.lexed.text(*self).into()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -515,18 +520,17 @@ impl<S: Span> SrcToken<StaticRawConverter<'_, S>, S> for usize {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Anchor: Copy, Ctx: SyntaxContext> TokenConverter<SpanData<Anchor, Ctx>>
|
impl<Ctx: SyntaxContext> TokenConverter<SpanData<Ctx>> for RawConverter<'_, Ctx>
|
||||||
for RawConverter<'_, Anchor, Ctx>
|
|
||||||
where
|
where
|
||||||
SpanData<Anchor, Ctx>: Span,
|
SpanData<Ctx>: Span,
|
||||||
{
|
{
|
||||||
type Token = usize;
|
type Token = usize;
|
||||||
|
|
||||||
fn convert_doc_comment(
|
fn convert_doc_comment(
|
||||||
&self,
|
&self,
|
||||||
&token: &usize,
|
&token: &usize,
|
||||||
span: SpanData<Anchor, Ctx>,
|
span: SpanData<Ctx>,
|
||||||
) -> Option<Vec<tt::TokenTree<SpanData<Anchor, Ctx>>>> {
|
) -> Option<Vec<tt::TokenTree<SpanData<Ctx>>>> {
|
||||||
let text = self.lexed.text(token);
|
let text = self.lexed.text(token);
|
||||||
convert_doc_comment(&doc_comment(text), span)
|
convert_doc_comment(&doc_comment(text), span)
|
||||||
}
|
}
|
||||||
|
@ -550,7 +554,7 @@ where
|
||||||
Some(self.pos)
|
Some(self.pos)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn span_for(&self, range: TextRange) -> SpanData<Anchor, Ctx> {
|
fn span_for(&self, range: TextRange) -> SpanData<Ctx> {
|
||||||
SpanData { range, anchor: self.anchor, ctx: self.ctx }
|
SpanData { range, anchor: self.anchor, ctx: self.ctx }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -778,22 +782,22 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct TtTreeSink<'a, Anchor, Ctx>
|
struct TtTreeSink<'a, Ctx>
|
||||||
where
|
where
|
||||||
SpanData<Anchor, Ctx>: Span,
|
SpanData<Ctx>: Span,
|
||||||
{
|
{
|
||||||
buf: String,
|
buf: String,
|
||||||
cursor: Cursor<'a, SpanData<Anchor, Ctx>>,
|
cursor: Cursor<'a, SpanData<Ctx>>,
|
||||||
text_pos: TextSize,
|
text_pos: TextSize,
|
||||||
inner: SyntaxTreeBuilder,
|
inner: SyntaxTreeBuilder,
|
||||||
token_map: SpanMap<SpanData<Anchor, Ctx>>,
|
token_map: SpanMap<SpanData<Ctx>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, Anchor, Ctx> TtTreeSink<'a, Anchor, Ctx>
|
impl<'a, Ctx> TtTreeSink<'a, Ctx>
|
||||||
where
|
where
|
||||||
SpanData<Anchor, Ctx>: Span,
|
SpanData<Ctx>: Span,
|
||||||
{
|
{
|
||||||
fn new(cursor: Cursor<'a, SpanData<Anchor, Ctx>>) -> Self {
|
fn new(cursor: Cursor<'a, SpanData<Ctx>>) -> Self {
|
||||||
TtTreeSink {
|
TtTreeSink {
|
||||||
buf: String::new(),
|
buf: String::new(),
|
||||||
cursor,
|
cursor,
|
||||||
|
@ -803,7 +807,7 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn finish(mut self) -> (Parse<SyntaxNode>, SpanMap<SpanData<Anchor, Ctx>>) {
|
fn finish(mut self) -> (Parse<SyntaxNode>, SpanMap<SpanData<Ctx>>) {
|
||||||
self.token_map.finish();
|
self.token_map.finish();
|
||||||
(self.inner.finish(), self.token_map)
|
(self.inner.finish(), self.token_map)
|
||||||
}
|
}
|
||||||
|
@ -821,9 +825,9 @@ fn delim_to_str(d: tt::DelimiterKind, closing: bool) -> Option<&'static str> {
|
||||||
Some(&texts[idx..texts.len() - (1 - idx)])
|
Some(&texts[idx..texts.len() - (1 - idx)])
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Anchor, Ctx> TtTreeSink<'_, Anchor, Ctx>
|
impl<Ctx> TtTreeSink<'_, Ctx>
|
||||||
where
|
where
|
||||||
SpanData<Anchor, Ctx>: Span,
|
SpanData<Ctx>: Span,
|
||||||
{
|
{
|
||||||
/// Parses a float literal as if it was a one to two name ref nodes with a dot inbetween.
|
/// Parses a float literal as if it was a one to two name ref nodes with a dot inbetween.
|
||||||
/// This occurs when a float literal is used as a field access.
|
/// This occurs when a float literal is used as a field access.
|
||||||
|
|
|
@ -33,6 +33,7 @@ tt.workspace = true
|
||||||
stdx.workspace = true
|
stdx.workspace = true
|
||||||
profile.workspace = true
|
profile.workspace = true
|
||||||
text-size.workspace = true
|
text-size.workspace = true
|
||||||
|
span.workspace = true
|
||||||
# Ideally this crate would not depend on salsa things, but we need span information here which wraps
|
# Ideally this crate would not depend on salsa things, but we need span information here which wraps
|
||||||
# InternIds for the syntax context
|
# InternIds for the syntax context
|
||||||
base-db.workspace = true
|
base-db.workspace = true
|
||||||
|
|
|
@ -11,9 +11,9 @@ pub mod msg;
|
||||||
mod process;
|
mod process;
|
||||||
mod version;
|
mod version;
|
||||||
|
|
||||||
use base_db::span::SpanData;
|
|
||||||
use indexmap::IndexSet;
|
use indexmap::IndexSet;
|
||||||
use paths::AbsPathBuf;
|
use paths::AbsPathBuf;
|
||||||
|
use span::Span;
|
||||||
use std::{fmt, io, sync::Mutex};
|
use std::{fmt, io, sync::Mutex};
|
||||||
use triomphe::Arc;
|
use triomphe::Arc;
|
||||||
|
|
||||||
|
@ -136,13 +136,13 @@ impl ProcMacro {
|
||||||
|
|
||||||
pub fn expand(
|
pub fn expand(
|
||||||
&self,
|
&self,
|
||||||
subtree: &tt::Subtree<SpanData>,
|
subtree: &tt::Subtree<Span>,
|
||||||
attr: Option<&tt::Subtree<SpanData>>,
|
attr: Option<&tt::Subtree<Span>>,
|
||||||
env: Vec<(String, String)>,
|
env: Vec<(String, String)>,
|
||||||
def_site: SpanData,
|
def_site: Span,
|
||||||
call_site: SpanData,
|
call_site: Span,
|
||||||
mixed_site: SpanData,
|
mixed_site: Span,
|
||||||
) -> Result<Result<tt::Subtree<SpanData>, PanicMessage>, ServerError> {
|
) -> Result<Result<tt::Subtree<Span>, PanicMessage>, ServerError> {
|
||||||
let version = self.process.lock().unwrap_or_else(|e| e.into_inner()).version();
|
let version = self.process.lock().unwrap_or_else(|e| e.into_inner()).version();
|
||||||
let current_dir = env
|
let current_dir = env
|
||||||
.iter()
|
.iter()
|
||||||
|
|
|
@ -136,29 +136,27 @@ fn write_json(out: &mut impl Write, msg: &str) -> io::Result<()> {
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use base_db::{
|
use base_db::FileId;
|
||||||
span::{ErasedFileAstId, SpanAnchor, SpanData, SyntaxContextId},
|
|
||||||
FileId,
|
|
||||||
};
|
|
||||||
use la_arena::RawIdx;
|
use la_arena::RawIdx;
|
||||||
|
use span::{ErasedFileAstId, Span, SpanAnchor, SyntaxContextId};
|
||||||
use text_size::{TextRange, TextSize};
|
use text_size::{TextRange, TextSize};
|
||||||
use tt::{Delimiter, DelimiterKind, Ident, Leaf, Literal, Punct, Spacing, Subtree, TokenTree};
|
use tt::{Delimiter, DelimiterKind, Ident, Leaf, Literal, Punct, Spacing, Subtree, TokenTree};
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
fn fixture_token_tree() -> Subtree<SpanData> {
|
fn fixture_token_tree() -> Subtree<Span> {
|
||||||
let anchor = SpanAnchor {
|
let anchor = SpanAnchor {
|
||||||
file_id: FileId::from_raw(0),
|
file_id: FileId::from_raw(0),
|
||||||
ast_id: ErasedFileAstId::from_raw(RawIdx::from(0)),
|
ast_id: ErasedFileAstId::from_raw(RawIdx::from(0)),
|
||||||
};
|
};
|
||||||
let mut subtree = Subtree {
|
let mut subtree = Subtree {
|
||||||
delimiter: Delimiter {
|
delimiter: Delimiter {
|
||||||
open: SpanData {
|
open: Span {
|
||||||
range: TextRange::empty(TextSize::new(0)),
|
range: TextRange::empty(TextSize::new(0)),
|
||||||
anchor,
|
anchor,
|
||||||
ctx: SyntaxContextId::ROOT,
|
ctx: SyntaxContextId::ROOT,
|
||||||
},
|
},
|
||||||
close: SpanData {
|
close: Span {
|
||||||
range: TextRange::empty(TextSize::new(13)),
|
range: TextRange::empty(TextSize::new(13)),
|
||||||
anchor,
|
anchor,
|
||||||
ctx: SyntaxContextId::ROOT,
|
ctx: SyntaxContextId::ROOT,
|
||||||
|
@ -170,7 +168,7 @@ mod tests {
|
||||||
subtree.token_trees.push(TokenTree::Leaf(
|
subtree.token_trees.push(TokenTree::Leaf(
|
||||||
Ident {
|
Ident {
|
||||||
text: "struct".into(),
|
text: "struct".into(),
|
||||||
span: SpanData {
|
span: Span {
|
||||||
range: TextRange::at(TextSize::new(0), TextSize::of("struct")),
|
range: TextRange::at(TextSize::new(0), TextSize::of("struct")),
|
||||||
anchor,
|
anchor,
|
||||||
ctx: SyntaxContextId::ROOT,
|
ctx: SyntaxContextId::ROOT,
|
||||||
|
@ -181,7 +179,7 @@ mod tests {
|
||||||
subtree.token_trees.push(TokenTree::Leaf(
|
subtree.token_trees.push(TokenTree::Leaf(
|
||||||
Ident {
|
Ident {
|
||||||
text: "Foo".into(),
|
text: "Foo".into(),
|
||||||
span: SpanData {
|
span: Span {
|
||||||
range: TextRange::at(TextSize::new(5), TextSize::of("Foo")),
|
range: TextRange::at(TextSize::new(5), TextSize::of("Foo")),
|
||||||
anchor,
|
anchor,
|
||||||
ctx: SyntaxContextId::ROOT,
|
ctx: SyntaxContextId::ROOT,
|
||||||
|
@ -192,7 +190,7 @@ mod tests {
|
||||||
subtree.token_trees.push(TokenTree::Leaf(Leaf::Literal(Literal {
|
subtree.token_trees.push(TokenTree::Leaf(Leaf::Literal(Literal {
|
||||||
text: "Foo".into(),
|
text: "Foo".into(),
|
||||||
|
|
||||||
span: SpanData {
|
span: Span {
|
||||||
range: TextRange::at(TextSize::new(8), TextSize::of("Foo")),
|
range: TextRange::at(TextSize::new(8), TextSize::of("Foo")),
|
||||||
anchor,
|
anchor,
|
||||||
ctx: SyntaxContextId::ROOT,
|
ctx: SyntaxContextId::ROOT,
|
||||||
|
@ -200,7 +198,7 @@ mod tests {
|
||||||
})));
|
})));
|
||||||
subtree.token_trees.push(TokenTree::Leaf(Leaf::Punct(Punct {
|
subtree.token_trees.push(TokenTree::Leaf(Leaf::Punct(Punct {
|
||||||
char: '@',
|
char: '@',
|
||||||
span: SpanData {
|
span: Span {
|
||||||
range: TextRange::at(TextSize::new(11), TextSize::of('@')),
|
range: TextRange::at(TextSize::new(11), TextSize::of('@')),
|
||||||
anchor,
|
anchor,
|
||||||
ctx: SyntaxContextId::ROOT,
|
ctx: SyntaxContextId::ROOT,
|
||||||
|
@ -209,12 +207,12 @@ mod tests {
|
||||||
})));
|
})));
|
||||||
subtree.token_trees.push(TokenTree::Subtree(Subtree {
|
subtree.token_trees.push(TokenTree::Subtree(Subtree {
|
||||||
delimiter: Delimiter {
|
delimiter: Delimiter {
|
||||||
open: SpanData {
|
open: Span {
|
||||||
range: TextRange::at(TextSize::new(12), TextSize::of('{')),
|
range: TextRange::at(TextSize::new(12), TextSize::of('{')),
|
||||||
anchor,
|
anchor,
|
||||||
ctx: SyntaxContextId::ROOT,
|
ctx: SyntaxContextId::ROOT,
|
||||||
},
|
},
|
||||||
close: SpanData {
|
close: Span {
|
||||||
range: TextRange::at(TextSize::new(13), TextSize::of('}')),
|
range: TextRange::at(TextSize::new(13), TextSize::of('}')),
|
||||||
anchor,
|
anchor,
|
||||||
ctx: SyntaxContextId::ROOT,
|
ctx: SyntaxContextId::ROOT,
|
||||||
|
|
|
@ -37,13 +37,13 @@
|
||||||
|
|
||||||
use std::collections::{HashMap, VecDeque};
|
use std::collections::{HashMap, VecDeque};
|
||||||
|
|
||||||
use base_db::span::SpanData;
|
|
||||||
use indexmap::IndexSet;
|
use indexmap::IndexSet;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
use span::Span;
|
||||||
|
|
||||||
use crate::msg::ENCODE_CLOSE_SPAN_VERSION;
|
use crate::msg::ENCODE_CLOSE_SPAN_VERSION;
|
||||||
|
|
||||||
type SpanDataIndexMap = IndexSet<SpanData>;
|
type SpanIndexMap = IndexSet<Span>;
|
||||||
|
|
||||||
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
|
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
|
||||||
pub struct TokenId(pub u32);
|
pub struct TokenId(pub u32);
|
||||||
|
@ -93,9 +93,9 @@ struct IdentRepr {
|
||||||
|
|
||||||
impl FlatTree {
|
impl FlatTree {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
subtree: &tt::Subtree<SpanData>,
|
subtree: &tt::Subtree<Span>,
|
||||||
version: u32,
|
version: u32,
|
||||||
span_data_table: &mut SpanDataIndexMap,
|
span_data_table: &mut SpanIndexMap,
|
||||||
) -> FlatTree {
|
) -> FlatTree {
|
||||||
let mut w = Writer {
|
let mut w = Writer {
|
||||||
string_table: HashMap::new(),
|
string_table: HashMap::new(),
|
||||||
|
@ -157,8 +157,8 @@ impl FlatTree {
|
||||||
pub fn to_subtree_resolved(
|
pub fn to_subtree_resolved(
|
||||||
self,
|
self,
|
||||||
version: u32,
|
version: u32,
|
||||||
span_data_table: &SpanDataIndexMap,
|
span_data_table: &SpanIndexMap,
|
||||||
) -> tt::Subtree<SpanData> {
|
) -> tt::Subtree<Span> {
|
||||||
Reader {
|
Reader {
|
||||||
subtree: if version >= ENCODE_CLOSE_SPAN_VERSION {
|
subtree: if version >= ENCODE_CLOSE_SPAN_VERSION {
|
||||||
read_vec(self.subtree, SubtreeRepr::read_with_close_span)
|
read_vec(self.subtree, SubtreeRepr::read_with_close_span)
|
||||||
|
@ -281,13 +281,13 @@ impl IdentRepr {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
trait Span: Copy {
|
trait InternableSpan: Copy {
|
||||||
type Table;
|
type Table;
|
||||||
fn token_id_of(table: &mut Self::Table, s: Self) -> TokenId;
|
fn token_id_of(table: &mut Self::Table, s: Self) -> TokenId;
|
||||||
fn span_for_token_id(table: &Self::Table, id: TokenId) -> Self;
|
fn span_for_token_id(table: &Self::Table, id: TokenId) -> Self;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Span for TokenId {
|
impl InternableSpan for TokenId {
|
||||||
type Table = ();
|
type Table = ();
|
||||||
fn token_id_of((): &mut Self::Table, token_id: Self) -> TokenId {
|
fn token_id_of((): &mut Self::Table, token_id: Self) -> TokenId {
|
||||||
token_id
|
token_id
|
||||||
|
@ -297,8 +297,8 @@ impl Span for TokenId {
|
||||||
id
|
id
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl Span for SpanData {
|
impl InternableSpan for Span {
|
||||||
type Table = IndexSet<SpanData>;
|
type Table = IndexSet<Span>;
|
||||||
fn token_id_of(table: &mut Self::Table, span: Self) -> TokenId {
|
fn token_id_of(table: &mut Self::Table, span: Self) -> TokenId {
|
||||||
TokenId(table.insert_full(span).0 as u32)
|
TokenId(table.insert_full(span).0 as u32)
|
||||||
}
|
}
|
||||||
|
@ -307,7 +307,7 @@ impl Span for SpanData {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Writer<'a, 'span, S: Span> {
|
struct Writer<'a, 'span, S: InternableSpan> {
|
||||||
work: VecDeque<(usize, &'a tt::Subtree<S>)>,
|
work: VecDeque<(usize, &'a tt::Subtree<S>)>,
|
||||||
string_table: HashMap<&'a str, u32>,
|
string_table: HashMap<&'a str, u32>,
|
||||||
span_data_table: &'span mut S::Table,
|
span_data_table: &'span mut S::Table,
|
||||||
|
@ -320,7 +320,7 @@ struct Writer<'a, 'span, S: Span> {
|
||||||
text: Vec<String>,
|
text: Vec<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'span, S: Span> Writer<'a, 'span, S> {
|
impl<'a, 'span, S: InternableSpan> Writer<'a, 'span, S> {
|
||||||
fn write(&mut self, root: &'a tt::Subtree<S>) {
|
fn write(&mut self, root: &'a tt::Subtree<S>) {
|
||||||
self.enqueue(root);
|
self.enqueue(root);
|
||||||
while let Some((idx, subtree)) = self.work.pop_front() {
|
while let Some((idx, subtree)) = self.work.pop_front() {
|
||||||
|
@ -393,7 +393,7 @@ impl<'a, 'span, S: Span> Writer<'a, 'span, S> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Reader<'span, S: Span> {
|
struct Reader<'span, S: InternableSpan> {
|
||||||
subtree: Vec<SubtreeRepr>,
|
subtree: Vec<SubtreeRepr>,
|
||||||
literal: Vec<LiteralRepr>,
|
literal: Vec<LiteralRepr>,
|
||||||
punct: Vec<PunctRepr>,
|
punct: Vec<PunctRepr>,
|
||||||
|
@ -403,7 +403,7 @@ struct Reader<'span, S: Span> {
|
||||||
span_data_table: &'span S::Table,
|
span_data_table: &'span S::Table,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'span, S: Span> Reader<'span, S> {
|
impl<'span, S: InternableSpan> Reader<'span, S> {
|
||||||
pub(crate) fn read(self) -> tt::Subtree<S> {
|
pub(crate) fn read(self) -> tt::Subtree<S> {
|
||||||
let mut res: Vec<Option<tt::Subtree<S>>> = vec![None; self.subtree.len()];
|
let mut res: Vec<Option<tt::Subtree<S>>> = vec![None; self.subtree.len()];
|
||||||
let read_span = |id| S::span_for_token_id(self.span_data_table, id);
|
let read_span = |id| S::span_for_token_id(self.span_data_table, id);
|
||||||
|
|
18
crates/span/Cargo.toml
Normal file
18
crates/span/Cargo.toml
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
[package]
|
||||||
|
name = "span"
|
||||||
|
version = "0.0.0"
|
||||||
|
rust-version.workspace = true
|
||||||
|
edition.workspace = true
|
||||||
|
license.workspace = true
|
||||||
|
authors.workspace = true
|
||||||
|
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
la-arena.workspace = true
|
||||||
|
rust-analyzer-salsa.workspace = true
|
||||||
|
|
||||||
|
|
||||||
|
# local deps
|
||||||
|
vfs.workspace = true
|
||||||
|
syntax.workspace = true
|
||||||
|
stdx.workspace = true
|
|
@ -1,10 +1,28 @@
|
||||||
//! File and span related types.
|
//! File and span related types.
|
||||||
// FIXME: This should probably be moved into its own crate.
|
// FIXME: This should be moved into its own crate to get rid of the dependency inversion, base-db
|
||||||
|
// has business depending on tt, tt should depend on a span crate only (which unforunately will have
|
||||||
|
// to depend on salsa)
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
use salsa::InternId;
|
use salsa::InternId;
|
||||||
use tt::SyntaxContext;
|
|
||||||
use vfs::FileId;
|
mod map;
|
||||||
|
|
||||||
|
pub use crate::map::SpanMap;
|
||||||
|
pub use syntax::{TextRange, TextSize};
|
||||||
|
pub use vfs::FileId;
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Debug)]
|
||||||
|
pub struct FilePosition {
|
||||||
|
pub file_id: FileId,
|
||||||
|
pub offset: TextSize,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
|
||||||
|
pub struct FileRange {
|
||||||
|
pub file_id: FileId,
|
||||||
|
pub range: TextRange,
|
||||||
|
}
|
||||||
|
|
||||||
pub type ErasedFileAstId = la_arena::Idx<syntax::SyntaxNodePtr>;
|
pub type ErasedFileAstId = la_arena::Idx<syntax::SyntaxNodePtr>;
|
||||||
|
|
||||||
|
@ -12,7 +30,26 @@ pub type ErasedFileAstId = la_arena::Idx<syntax::SyntaxNodePtr>;
|
||||||
pub const ROOT_ERASED_FILE_AST_ID: ErasedFileAstId =
|
pub const ROOT_ERASED_FILE_AST_ID: ErasedFileAstId =
|
||||||
la_arena::Idx::from_raw(la_arena::RawIdx::from_u32(0));
|
la_arena::Idx::from_raw(la_arena::RawIdx::from_u32(0));
|
||||||
|
|
||||||
pub type SpanData = tt::SpanData<SpanAnchor, SyntaxContextId>;
|
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
|
||||||
|
pub struct SpanData<Ctx> {
|
||||||
|
/// The text range of this span, relative to the anchor.
|
||||||
|
/// We need the anchor for incrementality, as storing absolute ranges will require
|
||||||
|
/// recomputation on every change in a file at all times.
|
||||||
|
pub range: TextRange,
|
||||||
|
pub anchor: SpanAnchor,
|
||||||
|
/// The syntax context of the span.
|
||||||
|
pub ctx: Ctx,
|
||||||
|
}
|
||||||
|
impl Span {
|
||||||
|
#[deprecated = "dummy spans will panic if surfaced incorrectly, as such they should be replaced appropriately"]
|
||||||
|
pub const DUMMY: Self = SpanData {
|
||||||
|
range: TextRange::empty(TextSize::new(0)),
|
||||||
|
anchor: SpanAnchor { file_id: FileId::BOGUS, ast_id: ROOT_ERASED_FILE_AST_ID },
|
||||||
|
ctx: SyntaxContextId::ROOT,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type Span = SpanData<SyntaxContextId>;
|
||||||
|
|
||||||
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
pub struct SyntaxContextId(InternId);
|
pub struct SyntaxContextId(InternId);
|
||||||
|
@ -33,7 +70,15 @@ impl fmt::Debug for SyntaxContextId {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
crate::impl_intern_key!(SyntaxContextId);
|
|
||||||
|
impl salsa::InternKey for SyntaxContextId {
|
||||||
|
fn from_intern_id(v: salsa::InternId) -> Self {
|
||||||
|
SyntaxContextId(v)
|
||||||
|
}
|
||||||
|
fn as_intern_id(&self) -> salsa::InternId {
|
||||||
|
self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl fmt::Display for SyntaxContextId {
|
impl fmt::Display for SyntaxContextId {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
@ -41,9 +86,6 @@ impl fmt::Display for SyntaxContextId {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SyntaxContext for SyntaxContextId {
|
|
||||||
const DUMMY: Self = Self::ROOT;
|
|
||||||
}
|
|
||||||
// inherent trait impls please tyvm
|
// inherent trait impls please tyvm
|
||||||
impl SyntaxContextId {
|
impl SyntaxContextId {
|
||||||
pub const ROOT: Self = SyntaxContextId(unsafe { InternId::new_unchecked(0) });
|
pub const ROOT: Self = SyntaxContextId(unsafe { InternId::new_unchecked(0) });
|
||||||
|
@ -69,10 +111,6 @@ impl fmt::Debug for SpanAnchor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl tt::SpanAnchor for SpanAnchor {
|
|
||||||
const DUMMY: Self = SpanAnchor { file_id: FileId::BOGUS, ast_id: ROOT_ERASED_FILE_AST_ID };
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Input to the analyzer is a set of files, where each file is identified by
|
/// Input to the analyzer is a set of files, where each file is identified by
|
||||||
/// `FileId` and contains source code. However, another source of source code in
|
/// `FileId` and contains source code. However, another source of source code in
|
||||||
/// Rust are macros: each macro can be thought of as producing a "temporary
|
/// Rust are macros: each macro can be thought of as producing a "temporary
|
||||||
|
@ -90,6 +128,7 @@ impl tt::SpanAnchor for SpanAnchor {
|
||||||
/// The two variants are encoded in a single u32 which are differentiated by the MSB.
|
/// The two variants are encoded in a single u32 which are differentiated by the MSB.
|
||||||
/// If the MSB is 0, the value represents a `FileId`, otherwise the remaining 31 bits represent a
|
/// If the MSB is 0, the value represents a `FileId`, otherwise the remaining 31 bits represent a
|
||||||
/// `MacroCallId`.
|
/// `MacroCallId`.
|
||||||
|
// FIXME: Give this a better fitting name
|
||||||
#[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
#[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
||||||
pub struct HirFileId(u32);
|
pub struct HirFileId(u32);
|
||||||
|
|
||||||
|
@ -120,7 +159,15 @@ pub struct MacroFileId {
|
||||||
/// `println!("Hello, {}", world)`.
|
/// `println!("Hello, {}", world)`.
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
pub struct MacroCallId(salsa::InternId);
|
pub struct MacroCallId(salsa::InternId);
|
||||||
crate::impl_intern_key!(MacroCallId);
|
|
||||||
|
impl salsa::InternKey for MacroCallId {
|
||||||
|
fn from_intern_id(v: salsa::InternId) -> Self {
|
||||||
|
MacroCallId(v)
|
||||||
|
}
|
||||||
|
fn as_intern_id(&self) -> salsa::InternId {
|
||||||
|
self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl MacroCallId {
|
impl MacroCallId {
|
||||||
pub fn as_file(self) -> HirFileId {
|
pub fn as_file(self) -> HirFileId {
|
|
@ -1,18 +1,20 @@
|
||||||
//! Mapping between `TokenId`s and the token's position in macro definitions or inputs.
|
//! A map that maps a span to every position in a file. Usually maps a span to some range of positions.
|
||||||
|
//! Allows bidirectional lookup.
|
||||||
|
|
||||||
use std::hash::Hash;
|
use std::hash::Hash;
|
||||||
|
|
||||||
use stdx::{always, itertools::Itertools};
|
use stdx::{always, itertools::Itertools};
|
||||||
use syntax::{TextRange, TextSize};
|
use syntax::{TextRange, TextSize};
|
||||||
use tt::Span;
|
|
||||||
|
|
||||||
/// Maps absolute text ranges for the corresponding file to the relevant span data.
|
/// Maps absolute text ranges for the corresponding file to the relevant span data.
|
||||||
#[derive(Debug, PartialEq, Eq, Clone, Hash)]
|
#[derive(Debug, PartialEq, Eq, Clone, Hash)]
|
||||||
pub struct SpanMap<S: Span> {
|
pub struct SpanMap<S> {
|
||||||
spans: Vec<(TextSize, S)>,
|
spans: Vec<(TextSize, S)>,
|
||||||
|
// FIXME: Should be
|
||||||
|
// spans: Vec<(TextSize, crate::SyntaxContextId)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: Span> SpanMap<S> {
|
impl<S: Copy> SpanMap<S> {
|
||||||
/// Creates a new empty [`SpanMap`].
|
/// Creates a new empty [`SpanMap`].
|
||||||
pub fn empty() -> Self {
|
pub fn empty() -> Self {
|
||||||
Self { spans: Vec::new() }
|
Self { spans: Vec::new() }
|
||||||
|
@ -44,7 +46,10 @@ impl<S: Span> SpanMap<S> {
|
||||||
/// Returns all [`TextRange`]s that correspond to the given span.
|
/// Returns all [`TextRange`]s that correspond to the given span.
|
||||||
///
|
///
|
||||||
/// Note this does a linear search through the entire backing vector.
|
/// Note this does a linear search through the entire backing vector.
|
||||||
pub fn ranges_with_span(&self, span: S) -> impl Iterator<Item = TextRange> + '_ {
|
pub fn ranges_with_span(&self, span: S) -> impl Iterator<Item = TextRange> + '_
|
||||||
|
where
|
||||||
|
S: Eq,
|
||||||
|
{
|
||||||
// FIXME: This should ignore the syntax context!
|
// FIXME: This should ignore the syntax context!
|
||||||
self.spans.iter().enumerate().filter_map(move |(idx, &(end, s))| {
|
self.spans.iter().enumerate().filter_map(move |(idx, &(end, s))| {
|
||||||
if s != span {
|
if s != span {
|
|
@ -16,3 +16,6 @@ smol_str.workspace = true
|
||||||
text-size.workspace = true
|
text-size.workspace = true
|
||||||
|
|
||||||
stdx.workspace = true
|
stdx.workspace = true
|
||||||
|
|
||||||
|
# FIXME: Remove this dependency once the `Span` trait is gone (that is once Span::DUMMY has been removed)
|
||||||
|
span.workspace = true
|
||||||
|
|
|
@ -11,47 +11,35 @@ use stdx::impl_from;
|
||||||
pub use smol_str::SmolStr;
|
pub use smol_str::SmolStr;
|
||||||
pub use text_size::{TextRange, TextSize};
|
pub use text_size::{TextRange, TextSize};
|
||||||
|
|
||||||
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
|
|
||||||
pub struct SpanData<Anchor, Ctx> {
|
|
||||||
/// The text range of this span, relative to the anchor.
|
|
||||||
/// We need the anchor for incrementality, as storing absolute ranges will require
|
|
||||||
/// recomputation on every change in a file at all times.
|
|
||||||
pub range: TextRange,
|
|
||||||
pub anchor: Anchor,
|
|
||||||
/// The syntax context of the span.
|
|
||||||
pub ctx: Ctx,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<Anchor: SpanAnchor, Ctx: SyntaxContext> Span for SpanData<Anchor, Ctx> {
|
|
||||||
#[allow(deprecated)]
|
|
||||||
const DUMMY: Self = SpanData {
|
|
||||||
range: TextRange::empty(TextSize::new(0)),
|
|
||||||
anchor: Anchor::DUMMY,
|
|
||||||
ctx: Ctx::DUMMY,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait Span: std::fmt::Debug + Copy + Sized + Eq {
|
pub trait Span: std::fmt::Debug + Copy + Sized + Eq {
|
||||||
// FIXME: Should not exist. Dummy spans will always be wrong if they leak somewhere. Instead,
|
// FIXME: Should not exist. Dummy spans will always be wrong if they leak somewhere. Instead,
|
||||||
// the call site or def site spans should be used in relevant places, its just that we don't
|
// the call site or def site spans should be used in relevant places, its just that we don't
|
||||||
// expose those everywhere in the yet.
|
// expose those everywhere in the yet.
|
||||||
|
#[deprecated = "dummy spans will panic if surfaced incorrectly, as such they should be replaced appropriately"]
|
||||||
const DUMMY: Self;
|
const DUMMY: Self;
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: Should not exist
|
|
||||||
pub trait SpanAnchor:
|
|
||||||
std::fmt::Debug + Copy + Sized + Eq + Copy + fmt::Debug + std::hash::Hash
|
|
||||||
{
|
|
||||||
#[deprecated(note = "this should not exist")]
|
|
||||||
const DUMMY: Self;
|
|
||||||
}
|
|
||||||
|
|
||||||
// FIXME: Should not exist
|
|
||||||
pub trait SyntaxContext: std::fmt::Debug + Copy + Sized + Eq {
|
pub trait SyntaxContext: std::fmt::Debug + Copy + Sized + Eq {
|
||||||
#[deprecated(note = "this should not exist")]
|
#[deprecated = "dummy spans will panic if surfaced incorrectly, as such they should be replaced appropriately"]
|
||||||
const DUMMY: Self;
|
const DUMMY: Self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<Ctx: SyntaxContext> Span for span::SpanData<Ctx> {
|
||||||
|
#[allow(deprecated)]
|
||||||
|
const DUMMY: Self = span::SpanData {
|
||||||
|
range: TextRange::empty(TextSize::new(0)),
|
||||||
|
anchor: span::SpanAnchor {
|
||||||
|
file_id: span::FileId::BOGUS,
|
||||||
|
ast_id: span::ROOT_ERASED_FILE_AST_ID,
|
||||||
|
},
|
||||||
|
ctx: Ctx::DUMMY,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SyntaxContext for span::SyntaxContextId {
|
||||||
|
const DUMMY: Self = Self::ROOT;
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||||
pub enum TokenTree<S> {
|
pub enum TokenTree<S> {
|
||||||
Leaf(Leaf<S>),
|
Leaf(Leaf<S>),
|
||||||
|
@ -136,6 +124,7 @@ pub struct DelimSpan<S> {
|
||||||
|
|
||||||
impl<S: Span> DelimSpan<S> {
|
impl<S: Span> DelimSpan<S> {
|
||||||
// FIXME should not exist
|
// FIXME should not exist
|
||||||
|
#[allow(deprecated)]
|
||||||
pub const DUMMY: Self = Self { open: S::DUMMY, close: S::DUMMY };
|
pub const DUMMY: Self = Self { open: S::DUMMY, close: S::DUMMY };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -148,6 +137,7 @@ pub struct Delimiter<S> {
|
||||||
|
|
||||||
impl<S: Span> Delimiter<S> {
|
impl<S: Span> Delimiter<S> {
|
||||||
// FIXME should not exist
|
// FIXME should not exist
|
||||||
|
#[allow(deprecated)]
|
||||||
pub const DUMMY_INVISIBLE: Self =
|
pub const DUMMY_INVISIBLE: Self =
|
||||||
Self { open: S::DUMMY, close: S::DUMMY, kind: DelimiterKind::Invisible };
|
Self { open: S::DUMMY, close: S::DUMMY, kind: DelimiterKind::Invisible };
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue