use crate::ingest::detect::Language;
#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum SemanticKind {
Function,
Type,
Variable,
Module,
Enum,
Trait,
TypeAlias,
Constant,
Constructor,
Unknown,
}
impl SemanticKind {
pub fn as_str(&self) -> &'static str {
match self {
SemanticKind::Function => "function",
SemanticKind::Type => "type",
SemanticKind::Variable => "variable",
SemanticKind::Module => "module",
SemanticKind::Enum => "enum",
SemanticKind::Trait => "trait",
SemanticKind::TypeAlias => "type_alias",
SemanticKind::Constant => "constant",
SemanticKind::Constructor => "constructor",
SemanticKind::Unknown => "unknown",
}
}
}
pub fn detect_semantic_kind(node_type: &str, language: Language) -> SemanticKind {
match language {
Language::Rust => detect_rust_kind(node_type),
Language::Python => detect_python_kind(node_type),
Language::JavaScript => detect_javascript_kind(node_type),
Language::TypeScript => detect_typescript_kind(node_type),
Language::Java => detect_java_kind(node_type),
Language::C => detect_c_kind(node_type),
Language::Cpp => detect_cpp_kind(node_type),
}
}
fn detect_rust_kind(node_type: &str) -> SemanticKind {
match node_type {
"function_item" => SemanticKind::Function,
"struct_item" | "enum_item" => SemanticKind::Type,
"trait_item" => SemanticKind::Trait,
"impl_item" => SemanticKind::Trait,
"mod_item" => SemanticKind::Module,
"type_item" => SemanticKind::TypeAlias,
"const_item" | "static_item" => SemanticKind::Constant,
_ => SemanticKind::Unknown,
}
}
fn detect_python_kind(node_type: &str) -> SemanticKind {
match node_type {
"function_definition" => SemanticKind::Function,
"class_definition" => SemanticKind::Type,
"import_statement" | "import_from_statement" => SemanticKind::Module,
"assignment" | "annotated_assignment" => SemanticKind::Variable,
"type_alias_statement" => SemanticKind::TypeAlias,
_ => SemanticKind::Unknown,
}
}
fn detect_javascript_kind(node_type: &str) -> SemanticKind {
match node_type {
"function_declaration" | "function_expression" | "arrow_function" => SemanticKind::Function,
"class_declaration" | "class_expression" => SemanticKind::Type,
"variable_declaration" | "lexical_declaration" => SemanticKind::Variable,
"enum_declaration" => SemanticKind::Enum,
"import_statement" | "export_statement" => SemanticKind::Module,
_ => SemanticKind::Unknown,
}
}
fn detect_typescript_kind(node_type: &str) -> SemanticKind {
match node_type {
"function_declaration" | "function_expression" | "arrow_function" => SemanticKind::Function,
"method_definition" => SemanticKind::Function,
"class_declaration" | "class_expression" => SemanticKind::Type,
"interface_declaration" => SemanticKind::Trait,
"enum_declaration" => SemanticKind::Enum,
"type_alias_declaration" => SemanticKind::TypeAlias,
"namespace_declaration" => SemanticKind::Module,
"variable_declaration" | "lexical_declaration" => SemanticKind::Variable,
"constructor_parameters" => SemanticKind::Constructor,
_ => SemanticKind::Unknown,
}
}
fn detect_java_kind(node_type: &str) -> SemanticKind {
match node_type {
"method_declaration" => SemanticKind::Function,
"class_declaration" | "interface_declaration" => SemanticKind::Type,
"enum_declaration" => SemanticKind::Enum,
"field_declaration" => SemanticKind::Variable,
"constructor_declaration" => SemanticKind::Constructor,
_ => SemanticKind::Unknown,
}
}
fn detect_c_kind(node_type: &str) -> SemanticKind {
match node_type {
"function_definition" | "function_declarator" => SemanticKind::Function,
"struct_specifier" | "union_specifier" => SemanticKind::Type,
"enum_specifier" => SemanticKind::Enum,
"declaration" => SemanticKind::Variable,
"type_definition" => SemanticKind::TypeAlias,
_ => SemanticKind::Unknown,
}
}
fn detect_cpp_kind(node_type: &str) -> SemanticKind {
match node_type {
"function_definition" | "function_declarator" => SemanticKind::Function,
"class_specifier" | "struct_specifier" => SemanticKind::Type,
"namespace_definition" => SemanticKind::Module,
"enum_specifier" => SemanticKind::Enum,
"declaration" => SemanticKind::Variable,
"type_definition" => SemanticKind::TypeAlias,
"constructor_definition" => SemanticKind::Constructor,
"template_function" => SemanticKind::Function,
"template_class" => SemanticKind::Type,
_ => SemanticKind::Unknown,
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_rust_semantic_kinds() {
assert_eq!(
detect_semantic_kind("function_item", Language::Rust),
SemanticKind::Function
);
assert_eq!(
detect_semantic_kind("struct_item", Language::Rust),
SemanticKind::Type
);
assert_eq!(
detect_semantic_kind("enum_item", Language::Rust),
SemanticKind::Type
);
assert_eq!(
detect_semantic_kind("trait_item", Language::Rust),
SemanticKind::Trait
);
assert_eq!(
detect_semantic_kind("impl_item", Language::Rust),
SemanticKind::Trait
);
assert_eq!(
detect_semantic_kind("mod_item", Language::Rust),
SemanticKind::Module
);
assert_eq!(
detect_semantic_kind("type_item", Language::Rust),
SemanticKind::TypeAlias
);
assert_eq!(
detect_semantic_kind("const_item", Language::Rust),
SemanticKind::Constant
);
assert_eq!(
detect_semantic_kind("static_item", Language::Rust),
SemanticKind::Constant
);
}
#[test]
fn test_python_semantic_kinds() {
assert_eq!(
detect_semantic_kind("function_definition", Language::Python),
SemanticKind::Function
);
assert_eq!(
detect_semantic_kind("class_definition", Language::Python),
SemanticKind::Type
);
assert_eq!(
detect_semantic_kind("assignment", Language::Python),
SemanticKind::Variable
);
assert_eq!(
detect_semantic_kind("type_alias_statement", Language::Python),
SemanticKind::TypeAlias
);
}
#[test]
fn test_javascript_semantic_kinds() {
assert_eq!(
detect_semantic_kind("function_declaration", Language::JavaScript),
SemanticKind::Function
);
assert_eq!(
detect_semantic_kind("arrow_function", Language::JavaScript),
SemanticKind::Function
);
assert_eq!(
detect_semantic_kind("class_declaration", Language::JavaScript),
SemanticKind::Type
);
assert_eq!(
detect_semantic_kind("variable_declaration", Language::JavaScript),
SemanticKind::Variable
);
}
#[test]
fn test_typescript_semantic_kinds() {
assert_eq!(
detect_semantic_kind("function_declaration", Language::TypeScript),
SemanticKind::Function
);
assert_eq!(
detect_semantic_kind("method_definition", Language::TypeScript),
SemanticKind::Function
);
assert_eq!(
detect_semantic_kind("interface_declaration", Language::TypeScript),
SemanticKind::Trait
);
assert_eq!(
detect_semantic_kind("enum_declaration", Language::TypeScript),
SemanticKind::Enum
);
assert_eq!(
detect_semantic_kind("type_alias_declaration", Language::TypeScript),
SemanticKind::TypeAlias
);
assert_eq!(
detect_semantic_kind("namespace_declaration", Language::TypeScript),
SemanticKind::Module
);
}
#[test]
fn test_java_semantic_kinds() {
assert_eq!(
detect_semantic_kind("method_declaration", Language::Java),
SemanticKind::Function
);
assert_eq!(
detect_semantic_kind("class_declaration", Language::Java),
SemanticKind::Type
);
assert_eq!(
detect_semantic_kind("interface_declaration", Language::Java),
SemanticKind::Type
);
assert_eq!(
detect_semantic_kind("enum_declaration", Language::Java),
SemanticKind::Enum
);
assert_eq!(
detect_semantic_kind("field_declaration", Language::Java),
SemanticKind::Variable
);
assert_eq!(
detect_semantic_kind("constructor_declaration", Language::Java),
SemanticKind::Constructor
);
}
#[test]
fn test_c_semantic_kinds() {
assert_eq!(
detect_semantic_kind("function_definition", Language::C),
SemanticKind::Function
);
assert_eq!(
detect_semantic_kind("struct_specifier", Language::C),
SemanticKind::Type
);
assert_eq!(
detect_semantic_kind("enum_specifier", Language::C),
SemanticKind::Enum
);
assert_eq!(
detect_semantic_kind("type_definition", Language::C),
SemanticKind::TypeAlias
);
}
#[test]
fn test_cpp_semantic_kinds() {
assert_eq!(
detect_semantic_kind("function_definition", Language::Cpp),
SemanticKind::Function
);
assert_eq!(
detect_semantic_kind("class_specifier", Language::Cpp),
SemanticKind::Type
);
assert_eq!(
detect_semantic_kind("namespace_definition", Language::Cpp),
SemanticKind::Module
);
assert_eq!(
detect_semantic_kind("enum_specifier", Language::Cpp),
SemanticKind::Enum
);
assert_eq!(
detect_semantic_kind("constructor_definition", Language::Cpp),
SemanticKind::Constructor
);
assert_eq!(
detect_semantic_kind("template_function", Language::Cpp),
SemanticKind::Function
);
}
#[test]
fn test_unknown_node_types() {
assert_eq!(
detect_semantic_kind("unknown_node", Language::Rust),
SemanticKind::Unknown
);
assert_eq!(
detect_semantic_kind("weird_construct", Language::Python),
SemanticKind::Unknown
);
assert_eq!(
detect_semantic_kind("future_syntax", Language::Java),
SemanticKind::Unknown
);
}
#[test]
fn test_semantic_kind_as_str() {
assert_eq!(SemanticKind::Function.as_str(), "function");
assert_eq!(SemanticKind::Type.as_str(), "type");
assert_eq!(SemanticKind::Variable.as_str(), "variable");
assert_eq!(SemanticKind::Module.as_str(), "module");
assert_eq!(SemanticKind::Enum.as_str(), "enum");
assert_eq!(SemanticKind::Trait.as_str(), "trait");
assert_eq!(SemanticKind::TypeAlias.as_str(), "type_alias");
assert_eq!(SemanticKind::Constant.as_str(), "constant");
assert_eq!(SemanticKind::Constructor.as_str(), "constructor");
assert_eq!(SemanticKind::Unknown.as_str(), "unknown");
}
}