comindly_core/lang/
mod.rs1pub mod go;
5pub mod java;
6pub mod kotlin;
7pub mod python;
8pub mod rust;
9pub mod spring;
10pub mod typescript;
11
12use tree_sitter::Node;
13
14use crate::facts::{Args, Import, RefKind, TypeSource, ValueExpr};
15use crate::model::{Language, SymbolKind};
16
17pub enum Target {
19 Var(String),
21 Attr(String),
23}
24
25pub enum RawContract {
27 Route {
28 handler: String,
29 receiver: Vec<String>,
30 method: String,
31 path: ValueExpr,
32 client: bool,
33 },
34 Handle {
35 receiver: Vec<String>,
36 method: String,
37 path: ValueExpr,
38 handler: Vec<String>,
39 },
40 Construct {
41 target: Target,
42 ctor: Vec<String>,
43 args: Args,
44 },
45 Op {
46 receiver: Vec<String>,
47 method: String,
48 args: Args,
49 },
50 TableName(String),
51}
52
53pub trait LangSpec: Sync {
54 fn receiver(&self) -> &'static str;
56
57 fn def(&self, node: Node, src: &[u8], in_class: bool) -> Option<(SymbolKind, String)>;
59
60 fn owned_bases(&self, _node: Node, _src: &[u8]) -> Option<(String, RefKind, Vec<String>)> {
62 None
63 }
64
65 fn contract(&self, _node: Node, _src: &[u8]) -> Option<RawContract> {
67 None
68 }
69
70 fn contracts(&self, node: Node, src: &[u8]) -> Vec<RawContract> {
72 self.contract(node, src).into_iter().collect()
73 }
74
75 fn param_names(&self, _def: Node, _src: &[u8]) -> Vec<String> {
77 Vec::new()
78 }
79
80 fn call(&self, _node: Node, _src: &[u8]) -> Option<(Vec<String>, Args)> {
82 None
83 }
84
85 fn value(&self, _node: Node, _src: &[u8]) -> Option<(String, ValueExpr)> {
87 None
88 }
89
90 fn package(&self, _root: Node, _src: &[u8]) -> Option<String> {
92 None
93 }
94
95 fn owner(&self, _def: Node, _src: &[u8]) -> Option<String> {
97 None
98 }
99
100 fn variable(&self, node: Node, src: &[u8]) -> Option<String>;
102
103 fn import(&self, node: Node, src: &[u8]) -> Option<Vec<Import>>;
105
106 fn reference(&self, node: Node, src: &[u8]) -> Option<(RefKind, Vec<String>)>;
108
109 fn assignment(&self, node: Node, src: &[u8]) -> Option<(Target, TypeSource)>;
111
112 fn bases(&self, def: Node, src: &[u8]) -> Vec<(RefKind, Vec<String>)>;
114
115 fn returns(&self, def: Node, src: &[u8]) -> Option<Vec<String>>;
117
118 fn params(&self, def: Node, src: &[u8]) -> Vec<(String, Vec<String>, bool)>;
120}
121
122pub fn spec(lang: &Language) -> Option<&'static dyn LangSpec> {
123 match lang {
124 Language::Python => Some(&python::Python),
125 Language::TypeScript | Language::JavaScript => Some(&typescript::TypeScript),
126 Language::Go => Some(&go::Go),
127 Language::Java => Some(&java::Java),
128 Language::Kotlin => Some(&kotlin::Kotlin),
129 Language::Rust => Some(&rust::Rust),
130 _ => None,
131 }
132}
133
134pub(crate) fn text<'a>(node: Node, src: &'a [u8]) -> &'a str {
135 node.utf8_text(src).unwrap_or("")
136}
137
138pub(crate) fn field_text<'a>(node: Node, field: &str, src: &'a [u8]) -> Option<&'a str> {
139 node.child_by_field_name(field).map(|n| text(n, src))
140}
141
142pub(crate) fn named_children(node: Node) -> Vec<Node> {
143 let mut c = node.walk();
144 node.named_children(&mut c).collect()
145}
146
147pub(crate) fn line(node: Node) -> u32 {
148 node.start_position().row as u32 + 1
149}