pub mod go;
pub mod java;
pub mod kotlin;
pub mod python;
pub mod rust;
pub mod spring;
pub mod typescript;
use tree_sitter::Node;
use crate::facts::{Args, Import, RefKind, TypeSource, ValueExpr};
use crate::model::{Language, SymbolKind};
pub enum Target {
Var(String),
Attr(String),
}
pub enum RawContract {
Route {
handler: String,
receiver: Vec<String>,
method: String,
path: ValueExpr,
client: bool,
},
Handle {
receiver: Vec<String>,
method: String,
path: ValueExpr,
handler: Vec<String>,
},
Construct {
target: Target,
ctor: Vec<String>,
args: Args,
},
Op {
receiver: Vec<String>,
method: String,
args: Args,
},
TableName(String),
}
pub trait LangSpec: Sync {
fn receiver(&self) -> &'static str;
fn def(&self, node: Node, src: &[u8], in_class: bool) -> Option<(SymbolKind, String)>;
fn owned_bases(&self, _node: Node, _src: &[u8]) -> Option<(String, RefKind, Vec<String>)> {
None
}
fn contract(&self, _node: Node, _src: &[u8]) -> Option<RawContract> {
None
}
fn contracts(&self, node: Node, src: &[u8]) -> Vec<RawContract> {
self.contract(node, src).into_iter().collect()
}
fn param_names(&self, _def: Node, _src: &[u8]) -> Vec<String> {
Vec::new()
}
fn call(&self, _node: Node, _src: &[u8]) -> Option<(Vec<String>, Args)> {
None
}
fn value(&self, _node: Node, _src: &[u8]) -> Option<(String, ValueExpr)> {
None
}
fn package(&self, _root: Node, _src: &[u8]) -> Option<String> {
None
}
fn owner(&self, _def: Node, _src: &[u8]) -> Option<String> {
None
}
fn variable(&self, node: Node, src: &[u8]) -> Option<String>;
fn import(&self, node: Node, src: &[u8]) -> Option<Vec<Import>>;
fn reference(&self, node: Node, src: &[u8]) -> Option<(RefKind, Vec<String>)>;
fn assignment(&self, node: Node, src: &[u8]) -> Option<(Target, TypeSource)>;
fn bases(&self, def: Node, src: &[u8]) -> Vec<(RefKind, Vec<String>)>;
fn returns(&self, def: Node, src: &[u8]) -> Option<Vec<String>>;
fn params(&self, def: Node, src: &[u8]) -> Vec<(String, Vec<String>, bool)>;
}
pub fn spec(lang: &Language) -> Option<&'static dyn LangSpec> {
match lang {
Language::Python => Some(&python::Python),
Language::TypeScript | Language::JavaScript => Some(&typescript::TypeScript),
Language::Go => Some(&go::Go),
Language::Java => Some(&java::Java),
Language::Kotlin => Some(&kotlin::Kotlin),
Language::Rust => Some(&rust::Rust),
_ => None,
}
}
pub(crate) fn text<'a>(node: Node, src: &'a [u8]) -> &'a str {
node.utf8_text(src).unwrap_or("")
}
pub(crate) fn field_text<'a>(node: Node, field: &str, src: &'a [u8]) -> Option<&'a str> {
node.child_by_field_name(field).map(|n| text(n, src))
}
pub(crate) fn named_children(node: Node) -> Vec<Node> {
let mut c = node.walk();
node.named_children(&mut c).collect()
}
pub(crate) fn line(node: Node) -> u32 {
node.start_position().row as u32 + 1
}