| use rls_span as span; |
| |
| #[cfg(feature = "derive")] |
| #[macro_use] |
| extern crate serde_derive; |
| |
| pub mod config; |
| mod serde_expanded; |
| |
| use std::path::PathBuf; |
| |
| pub use config::Config; |
| |
| #[derive(Debug, Clone, Default)] |
| #[cfg_attr(feature = "derive", derive(Serialize, Deserialize))] |
| #[repr(C)] |
| pub struct Analysis { |
| /// The Config used to generate this analysis data. |
| pub config: Config, |
| pub version: Option<String>, |
| pub compilation: Option<CompilationOptions>, |
| pub prelude: Option<CratePreludeData>, |
| pub imports: Vec<Import>, |
| pub defs: Vec<Def>, |
| pub impls: Vec<Impl>, |
| pub refs: Vec<Ref>, |
| pub macro_refs: Vec<MacroRef>, |
| pub relations: Vec<Relation>, |
| } |
| |
| impl Analysis { |
| /// Returns an initialized `Analysis` struct with `config` and also |
| /// `version` field to Cargo package version. |
| pub fn new(config: Config) -> Analysis { |
| Analysis { |
| config, |
| version: option_env!("CARGO_PKG_VERSION").map(ToString::to_string), |
| ..Analysis::default() |
| } |
| } |
| } |
| |
| // DefId::index is a newtype and so the JSON serialisation is ugly. Therefore |
| // we use our own Id which is the same, but without the newtype. |
| #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] |
| #[cfg_attr(feature = "derive", derive(Serialize, Deserialize))] |
| pub struct Id { |
| pub krate: u32, |
| pub index: u32, |
| } |
| |
| /// Crate name, along with its disambiguator (128-bit hash) represents a globally |
| /// unique crate identifier, which should allow for differentiation between |
| /// different crate targets or versions and should point to the same crate when |
| /// pulled by different other, dependent crates. |
| #[derive(Debug, Clone, PartialEq, Eq, Hash)] |
| #[cfg_attr(feature = "derive", derive(Serialize, Deserialize))] |
| pub struct GlobalCrateId { |
| pub name: String, |
| pub disambiguator: (u64, u64), |
| } |
| |
| #[derive(Debug, Clone)] |
| #[cfg_attr(feature = "derive", derive(Serialize, Deserialize))] |
| pub struct SpanData { |
| pub file_name: PathBuf, |
| pub byte_start: u32, |
| pub byte_end: u32, |
| pub line_start: span::Row<span::OneIndexed>, |
| pub line_end: span::Row<span::OneIndexed>, |
| // Character offset. |
| pub column_start: span::Column<span::OneIndexed>, |
| pub column_end: span::Column<span::OneIndexed>, |
| } |
| |
| #[derive(Debug, Clone)] |
| #[cfg_attr(feature = "derive", derive(Serialize, Deserialize))] |
| pub struct CompilationOptions { |
| pub directory: PathBuf, |
| pub program: String, |
| pub arguments: Vec<String>, |
| pub output: PathBuf, |
| } |
| |
| #[derive(Debug, Clone)] |
| #[cfg_attr(feature = "derive", derive(Serialize, Deserialize))] |
| pub struct CratePreludeData { |
| pub crate_id: GlobalCrateId, |
| pub crate_root: String, |
| pub external_crates: Vec<ExternalCrateData>, |
| pub span: SpanData, |
| } |
| |
| /// Data for external crates in the prelude of a crate. |
| #[derive(Debug, Clone)] |
| #[cfg_attr(feature = "derive", derive(Serialize, Deserialize))] |
| pub struct ExternalCrateData { |
| /// Source file where the external crate is declared. |
| pub file_name: String, |
| /// A crate-local crate index of an external crate. Local crate index is |
| /// always 0, so these should start from 1 and range should be contiguous, |
| /// e.g. from 1 to n for n external crates. |
| pub num: u32, |
| pub id: GlobalCrateId, |
| } |
| |
| #[derive(Debug, Clone)] |
| #[cfg_attr(feature = "derive", derive(Serialize, Deserialize))] |
| pub struct Import { |
| pub kind: ImportKind, |
| pub ref_id: Option<Id>, |
| pub span: SpanData, |
| pub alias_span: Option<SpanData>, |
| pub name: String, |
| pub value: String, |
| pub parent: Option<Id>, |
| } |
| |
| #[derive(Debug, Clone, Copy, PartialEq, Eq)] |
| #[cfg_attr(feature = "derive", derive(Serialize, Deserialize))] |
| pub enum ImportKind { |
| ExternCrate, |
| Use, |
| GlobUse, |
| } |
| |
| #[derive(Debug, Clone)] |
| #[cfg_attr(feature = "derive", derive(Serialize, Deserialize))] |
| pub struct Def { |
| pub kind: DefKind, |
| pub id: Id, |
| pub span: SpanData, |
| pub name: String, |
| pub qualname: String, |
| pub value: String, |
| pub parent: Option<Id>, |
| pub children: Vec<Id>, |
| pub decl_id: Option<Id>, |
| pub docs: String, |
| pub sig: Option<Signature>, |
| pub attributes: Vec<Attribute>, |
| } |
| |
| #[derive(Debug, Clone, Copy, PartialEq, Eq)] |
| #[cfg_attr(feature = "derive", derive(Serialize, Deserialize))] |
| pub enum DefKind { |
| // value = variant names |
| Enum, |
| // value = enum name + variant name + types |
| TupleVariant, |
| // value = enum name + name + fields |
| StructVariant, |
| // value = variant name + types |
| Tuple, |
| // value = name + fields |
| Struct, |
| Union, |
| // value = signature |
| Trait, |
| // value = type + generics |
| Function, |
| ForeignFunction, |
| // value = type + generics |
| Method, |
| // No id, no value. |
| Macro, |
| // value = file_name |
| Mod, |
| // value = aliased type |
| Type, |
| // value = type and init expression (for all variable kinds). |
| Local, |
| Static, |
| ForeignStatic, |
| Const, |
| Field, |
| // no value |
| ExternType, |
| } |
| |
| #[derive(Debug, Clone)] |
| #[cfg_attr(feature = "derive", derive(Serialize, Deserialize))] |
| pub struct Impl { |
| pub id: u32, |
| pub kind: ImplKind, |
| pub span: SpanData, |
| pub value: String, |
| pub parent: Option<Id>, |
| pub children: Vec<Id>, |
| pub docs: String, |
| pub sig: Option<Signature>, |
| pub attributes: Vec<Attribute>, |
| } |
| |
| #[derive(Debug, Clone, PartialEq, Eq)] |
| #[cfg_attr(feature = "derive", derive(Serialize, Deserialize))] |
| pub enum ImplKind { |
| // impl Foo { ... } |
| Inherent, |
| // impl Bar for Foo { ... } |
| Direct, |
| // impl Bar for &Foo { ... } |
| Indirect, |
| // impl<T: Baz> Bar for T { ... } |
| // where Foo: Baz |
| Blanket, |
| // impl Bar for Baz { ... } or impl Baz { ... }, etc. |
| // where Foo: Deref<Target = Baz> |
| // Args are name and id of Baz |
| Deref(String, Id), |
| } |
| |
| #[derive(Debug, Clone)] |
| #[cfg_attr(feature = "derive", derive(Serialize, Deserialize))] |
| pub struct Attribute { |
| pub value: String, |
| pub span: SpanData, |
| } |
| |
| #[derive(Debug, Clone)] |
| #[cfg_attr(feature = "derive", derive(Serialize, Deserialize))] |
| pub struct Ref { |
| pub kind: RefKind, |
| pub span: SpanData, |
| pub ref_id: Id, |
| } |
| |
| #[derive(Debug, Clone, Copy, PartialEq, Eq)] |
| #[cfg_attr(feature = "derive", derive(Serialize, Deserialize))] |
| pub enum RefKind { |
| Function, |
| Mod, |
| Type, |
| Variable, |
| } |
| |
| #[derive(Debug, Clone)] |
| #[cfg_attr(feature = "derive", derive(Serialize, Deserialize))] |
| pub struct MacroRef { |
| pub span: SpanData, |
| pub qualname: String, |
| pub callee_span: SpanData, |
| } |
| |
| #[derive(Debug, Clone)] |
| #[cfg_attr(feature = "derive", derive(Serialize, Deserialize))] |
| pub struct Relation { |
| pub span: SpanData, |
| pub kind: RelationKind, |
| pub from: Id, |
| pub to: Id, |
| } |
| |
| #[derive(Debug, Clone, Copy, PartialEq, Eq)] |
| #[cfg_attr(feature = "derive", derive(Serialize, Deserialize))] |
| pub enum RelationKind { |
| Impl { id: u32 }, |
| SuperTrait, |
| } |
| |
| #[derive(Debug, Clone)] |
| #[cfg_attr(feature = "derive", derive(Serialize, Deserialize))] |
| pub struct Signature { |
| pub text: String, |
| pub defs: Vec<SigElement>, |
| pub refs: Vec<SigElement>, |
| } |
| |
| #[derive(Debug, Clone)] |
| #[cfg_attr(feature = "derive", derive(Serialize, Deserialize))] |
| pub struct SigElement { |
| pub id: Id, |
| pub start: usize, |
| pub end: usize, |
| } |
| |
| // Following macros are copied from the `static-assertions` library: |
| // https://github.com/nvzqz/static-assertions-rs/blob/9f0f8aa871390f74f2afcdba53c1e02db90b2d17/src/assert_impl.rs |
| #[macro_export(local_inner_macros)] |
| macro_rules! assert_impl { |
| ($($xs:tt)+) => { _assert_impl!($($xs)+); }; |
| } |
| |
| #[doc(hidden)] |
| #[macro_export(local_inner_macros)] |
| macro_rules! _assert_impl { |
| ($x:ty, $($t:path),+ $(,)*) => { |
| { |
| fn assert_impl<'hidden, T>() where T: ?Sized $(+ $t)+ {} |
| assert_impl::<$x>(); |
| } |
| }; |
| ($label:ident; $($xs:tt)+) => { |
| #[allow(dead_code, non_snake_case)] |
| fn $label() { assert_impl!($($xs)+); } |
| }; |
| } |
| |
| #[doc(hidden)] |
| macro_rules! assert_serde { |
| ($($typ:path),* $(,)*) => { |
| $( assert_impl!($typ, Serialize, Deserialize<'hidden>); )* |
| }; |
| } |
| |
| /// Since we manually provide impls in `cfg(not(feature = "derive"))`, it's good |
| /// to ensure that the types actually implement all the required traits. |
| #[doc(hidden)] |
| fn _assertions() { |
| use serde::{Deserialize, Serialize}; |
| |
| assert_serde!( |
| // rls-data |
| Analysis, |
| Id, |
| GlobalCrateId, |
| SpanData, |
| CompilationOptions, |
| CratePreludeData, |
| ExternalCrateData, |
| Import, |
| Def, |
| Impl, |
| Attribute, |
| Ref, |
| MacroRef, |
| Relation, |
| Signature, |
| SigElement, |
| Config, |
| // rls-span |
| span::Column<span::ZeroIndexed>, |
| span::Location<span::ZeroIndexed>, |
| span::Position<span::ZeroIndexed>, |
| span::Range<span::ZeroIndexed>, |
| span::Row<span::ZeroIndexed>, |
| span::Span<span::ZeroIndexed>, |
| span::Column<span::OneIndexed>, |
| span::Location<span::OneIndexed>, |
| span::Position<span::OneIndexed>, |
| span::Range<span::OneIndexed>, |
| span::Row<span::OneIndexed>, |
| span::Span<span::OneIndexed>, |
| ); |
| } |