use std::sync::Arc;
use pedant_types::{ReferenceKind, SymbolKind};
use crate::node::GraphNodeKind;
use crate::reference::GraphReferenceKind;
pub(crate) struct Vocabulary {
module: Arc<str>,
package: Arc<str>,
function: Arc<str>,
method: Arc<str>,
interface_method: Arc<str>,
structure: Arc<str>,
interface: Arc<str>,
defined_type: Arc<str>,
type_alias: Arc<str>,
constant: Arc<str>,
variable: Arc<str>,
field: Arc<str>,
}
impl Vocabulary {
pub(crate) fn new() -> Self {
Self {
module: Arc::from("module"),
package: Arc::from("package"),
function: Arc::from("function"),
method: Arc::from("method"),
interface_method: Arc::from("interface_method"),
structure: Arc::from("struct"),
interface: Arc::from("interface"),
defined_type: Arc::from("defined_type"),
type_alias: Arc::from("type_alias"),
constant: Arc::from("constant"),
variable: Arc::from("variable"),
field: Arc::from("field"),
}
}
pub(crate) fn module_root(&self) -> GraphNodeKind {
self.container(&self.module)
}
pub(crate) fn definition(
&self,
kind: SymbolKind,
holder: Option<SymbolKind>,
) -> Option<GraphNodeKind> {
match kind {
SymbolKind::Package => Some(self.container(&self.package)),
SymbolKind::Function => Some(self.callable(&self.function)),
SymbolKind::Method => self.method_level(holder).map(|level| self.callable(level)),
SymbolKind::Struct => Some(self.declared_type(&self.structure)),
SymbolKind::Interface => Some(self.declared_type(&self.interface)),
SymbolKind::DefinedType => Some(self.declared_type(&self.defined_type)),
SymbolKind::TypeAlias => Some(self.declared_type(&self.type_alias)),
SymbolKind::Constant => Some(self.value(&self.constant)),
SymbolKind::Variable => Some(self.value(&self.variable)),
SymbolKind::Field => Some(self.value(&self.field)),
SymbolKind::Module
| SymbolKind::Enum
| SymbolKind::Union
| SymbolKind::Trait
| SymbolKind::Static => None,
}
}
fn method_level(&self, holder: Option<SymbolKind>) -> Option<&Arc<str>> {
match holder {
Some(SymbolKind::Interface) => Some(&self.interface_method),
None | Some(SymbolKind::Struct | SymbolKind::DefinedType | SymbolKind::TypeAlias) => {
Some(&self.method)
}
Some(
SymbolKind::Package
| SymbolKind::Module
| SymbolKind::Function
| SymbolKind::Method
| SymbolKind::Enum
| SymbolKind::Union
| SymbolKind::Trait
| SymbolKind::Constant
| SymbolKind::Variable
| SymbolKind::Static
| SymbolKind::Field,
) => None,
}
}
fn container(&self, level: &Arc<str>) -> GraphNodeKind {
GraphNodeKind::Container {
level: Arc::clone(level),
}
}
fn callable(&self, declaration: &Arc<str>) -> GraphNodeKind {
GraphNodeKind::Function {
declaration: Arc::clone(declaration),
}
}
fn declared_type(&self, declaration: &Arc<str>) -> GraphNodeKind {
GraphNodeKind::Type {
declaration: Arc::clone(declaration),
}
}
fn value(&self, declaration: &Arc<str>) -> GraphNodeKind {
GraphNodeKind::Value {
declaration: Arc::clone(declaration),
}
}
}
pub(crate) fn reference_kind(kind: ReferenceKind) -> Option<GraphReferenceKind> {
match kind {
ReferenceKind::Call => Some(GraphReferenceKind::Call),
ReferenceKind::Import => Some(GraphReferenceKind::Import),
ReferenceKind::Implementation => Some(GraphReferenceKind::Implementation),
ReferenceKind::Type | ReferenceKind::Value => Some(GraphReferenceKind::Reference),
ReferenceKind::Module => None,
}
}