Compare commits
No commits in common. "dcb4e76a406f033fbc464466f180524ce565abe4" and "3e0367fb1ead26c60f094a7b289f8bb6e69ab8fd" have entirely different histories.
dcb4e76a40
...
3e0367fb1e
2
Cargo.lock
generated
2
Cargo.lock
generated
@ -667,8 +667,6 @@ version = "1.0.0-beta.1"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"dashmap 6.1.0",
|
"dashmap 6.1.0",
|
||||||
"reid",
|
"reid",
|
||||||
"serde",
|
|
||||||
"serde_json",
|
|
||||||
"socket",
|
"socket",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tower-lsp",
|
"tower-lsp",
|
||||||
|
@ -1,7 +0,0 @@
|
|||||||
fn main() -> i32 {
|
|
||||||
let a = 4f32;
|
|
||||||
if (a % 2) == 0 {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -2,14 +2,11 @@ import std::print;
|
|||||||
import std::from_str;
|
import std::from_str;
|
||||||
import std::String;
|
import std::String;
|
||||||
|
|
||||||
/// Asd
|
|
||||||
struct Otus {
|
struct Otus {
|
||||||
field: u32,
|
field: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Otus {
|
impl Otus {
|
||||||
/// Some test documentation here.
|
|
||||||
/// On a second line
|
|
||||||
fn test(&self) -> u32 {
|
fn test(&self) -> u32 {
|
||||||
*self.field
|
*self.field
|
||||||
}
|
}
|
||||||
@ -31,6 +28,7 @@ fn main() -> u32 {
|
|||||||
let mut list = u64::malloc(15);
|
let mut list = u64::malloc(15);
|
||||||
list[4] = 17;
|
list[4] = 17;
|
||||||
|
|
||||||
|
|
||||||
print(from_str("value: ") + list[4]);
|
print(from_str("value: ") + list[4]);
|
||||||
|
|
||||||
return i32::sizeof() as u32;
|
return i32::sizeof() as u32;
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
// Arithmetic, function calls and imports!
|
// Arithmetic, function calls and imports!
|
||||||
|
|
||||||
/// Test stuff
|
|
||||||
fn changer(param: &mut u32) {
|
fn changer(param: &mut u32) {
|
||||||
*param = 17;
|
*param = 17;
|
||||||
}
|
}
|
||||||
|
@ -9,5 +9,3 @@ tokio = { version = "1.47.0", features = ["full"] }
|
|||||||
tower-lsp = "0.20.0"
|
tower-lsp = "0.20.0"
|
||||||
reid = { path = "../reid", version = "1.0.0-beta.4", registry="gitea-teascade", features=[] }
|
reid = { path = "../reid", version = "1.0.0-beta.4", registry="gitea-teascade", features=[] }
|
||||||
dashmap = "6.1.0"
|
dashmap = "6.1.0"
|
||||||
serde = "*"
|
|
||||||
serde_json = "*"
|
|
||||||
|
@ -2,7 +2,6 @@ use std::{collections::HashMap, hash::Hash, path::PathBuf};
|
|||||||
|
|
||||||
use reid::{
|
use reid::{
|
||||||
ast::{
|
ast::{
|
||||||
ReturnType,
|
|
||||||
lexer::{FullToken, Token},
|
lexer::{FullToken, Token},
|
||||||
token_stream::TokenRange,
|
token_stream::TokenRange,
|
||||||
},
|
},
|
||||||
@ -85,7 +84,7 @@ impl StaticAnalysis {
|
|||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct SemanticToken {
|
pub struct SemanticToken {
|
||||||
pub hover: Option<Hover>,
|
pub ty: Option<TypeKind>,
|
||||||
pub autocomplete: Vec<Autocomplete>,
|
pub autocomplete: Vec<Autocomplete>,
|
||||||
pub symbol: Option<SymbolId>,
|
pub symbol: Option<SymbolId>,
|
||||||
}
|
}
|
||||||
@ -93,7 +92,6 @@ pub struct SemanticToken {
|
|||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Autocomplete {
|
pub struct Autocomplete {
|
||||||
pub text: String,
|
pub text: String,
|
||||||
pub documentation: Option<String>,
|
|
||||||
pub kind: AutocompleteKind,
|
pub kind: AutocompleteKind,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -104,18 +102,6 @@ pub enum AutocompleteKind {
|
|||||||
Function(Vec<FunctionParam>, TypeKind),
|
Function(Vec<FunctionParam>, TypeKind),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
pub struct Hover {
|
|
||||||
pub documentation: Option<String>,
|
|
||||||
pub kind: Option<HoverKind>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
pub enum HoverKind {
|
|
||||||
Type(TypeKind),
|
|
||||||
Function(String, Vec<FunctionParam>, TypeKind),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ToString for AutocompleteKind {
|
impl ToString for AutocompleteKind {
|
||||||
fn to_string(&self) -> String {
|
fn to_string(&self) -> String {
|
||||||
match self {
|
match self {
|
||||||
@ -162,15 +148,12 @@ impl AnalysisState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl AnalysisState {
|
impl AnalysisState {
|
||||||
pub fn init_hover(&mut self, meta: &mir::Metadata, kind: Option<HoverKind>, documentation: Option<String>) {
|
pub fn init_types(&mut self, meta: &mir::Metadata, ty: Option<TypeKind>) {
|
||||||
for token in meta.range.start..=meta.range.end {
|
for token in meta.range.start..=meta.range.end {
|
||||||
self.map.insert(
|
self.map.insert(
|
||||||
token,
|
token,
|
||||||
SemanticToken {
|
SemanticToken {
|
||||||
hover: Some(Hover {
|
ty: ty.clone(),
|
||||||
documentation: documentation.clone(),
|
|
||||||
kind: kind.clone(),
|
|
||||||
}),
|
|
||||||
autocomplete: Vec::new(),
|
autocomplete: Vec::new(),
|
||||||
symbol: Default::default(),
|
symbol: Default::default(),
|
||||||
},
|
},
|
||||||
@ -185,7 +168,7 @@ impl AnalysisState {
|
|||||||
self.map.insert(
|
self.map.insert(
|
||||||
token_idx,
|
token_idx,
|
||||||
SemanticToken {
|
SemanticToken {
|
||||||
hover: None,
|
ty: None,
|
||||||
autocomplete: autocomplete.clone(),
|
autocomplete: autocomplete.clone(),
|
||||||
symbol: Default::default(),
|
symbol: Default::default(),
|
||||||
},
|
},
|
||||||
@ -193,33 +176,6 @@ impl AnalysisState {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_documentation(&mut self, token_idx: usize, documentation: Option<String>) {
|
|
||||||
if let Some(documentation) = documentation {
|
|
||||||
if let Some(token) = self.map.get_mut(&token_idx) {
|
|
||||||
if let Some(hover) = &mut token.hover {
|
|
||||||
hover.documentation = Some(documentation);
|
|
||||||
} else {
|
|
||||||
token.hover = Some(Hover {
|
|
||||||
documentation: Some(documentation),
|
|
||||||
kind: None,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
self.map.insert(
|
|
||||||
token_idx,
|
|
||||||
SemanticToken {
|
|
||||||
hover: Some(Hover {
|
|
||||||
documentation: Some(documentation),
|
|
||||||
kind: None,
|
|
||||||
}),
|
|
||||||
autocomplete: Vec::new(),
|
|
||||||
symbol: Default::default(),
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn set_symbol(&mut self, idx: usize, symbol: SymbolId) {
|
pub fn set_symbol(&mut self, idx: usize, symbol: SymbolId) {
|
||||||
self.symbol_to_token.insert(symbol, idx);
|
self.symbol_to_token.insert(symbol, idx);
|
||||||
if let Some(token) = self.map.get_mut(&idx) {
|
if let Some(token) = self.map.get_mut(&idx) {
|
||||||
@ -228,7 +184,7 @@ impl AnalysisState {
|
|||||||
self.map.insert(
|
self.map.insert(
|
||||||
idx,
|
idx,
|
||||||
SemanticToken {
|
SemanticToken {
|
||||||
hover: None,
|
ty: None,
|
||||||
autocomplete: Vec::new(),
|
autocomplete: Vec::new(),
|
||||||
symbol: Some(symbol),
|
symbol: Some(symbol),
|
||||||
},
|
},
|
||||||
@ -273,8 +229,8 @@ pub struct AnalysisScope<'a> {
|
|||||||
tokens: &'a Vec<FullToken>,
|
tokens: &'a Vec<FullToken>,
|
||||||
variables: HashMap<String, SymbolId>,
|
variables: HashMap<String, SymbolId>,
|
||||||
types: HashMap<TypeKind, (SourceModuleId, SymbolId)>,
|
types: HashMap<TypeKind, (SourceModuleId, SymbolId)>,
|
||||||
functions: HashMap<String, (SourceModuleId, SymbolId, Option<String>)>,
|
functions: HashMap<String, (SourceModuleId, SymbolId)>,
|
||||||
associated_functions: HashMap<(TypeKind, String), (SourceModuleId, SymbolId, Option<String>)>,
|
associated_functions: HashMap<(TypeKind, String), (SourceModuleId, SymbolId)>,
|
||||||
map: &'a StateMap,
|
map: &'a StateMap,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -445,33 +401,6 @@ pub fn analyze(
|
|||||||
return Ok(None);
|
return Ok(None);
|
||||||
}
|
}
|
||||||
|
|
||||||
// pub fn find_documentation(meta: &Metadata, tokens: &Vec<FullToken>) -> Option<String> {
|
|
||||||
// let mut documentation = None;
|
|
||||||
// for idx in meta.range.start..=meta.range.end {
|
|
||||||
// if let Some(token) = tokens.get(idx) {
|
|
||||||
// dbg!(&token);
|
|
||||||
// if matches!(token.token, Token::Whitespace(_) | Token::Doc(_) | Token::Comment(_)) {
|
|
||||||
// if let Token::Doc(doctext) = &token.token {
|
|
||||||
// documentation = Some(
|
|
||||||
// match documentation {
|
|
||||||
// Some(t) => t + " ",
|
|
||||||
// None => String::new(),
|
|
||||||
// } + doctext.trim(),
|
|
||||||
// );
|
|
||||||
// }
|
|
||||||
// } else {
|
|
||||||
// dbg!(&token);
|
|
||||||
// break;
|
|
||||||
// }
|
|
||||||
// } else {
|
|
||||||
// dbg!(&idx);
|
|
||||||
// break;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// dbg!(&documentation);
|
|
||||||
// documentation
|
|
||||||
// }
|
|
||||||
|
|
||||||
pub fn analyze_context(
|
pub fn analyze_context(
|
||||||
context: &mir::Context,
|
context: &mir::Context,
|
||||||
module: &mir::Module,
|
module: &mir::Module,
|
||||||
@ -576,7 +505,7 @@ pub fn analyze_context(
|
|||||||
.token_idx(&field.2, |t| matches!(t, Token::Identifier(_)))
|
.token_idx(&field.2, |t| matches!(t, Token::Identifier(_)))
|
||||||
.unwrap_or(field.2.range.end);
|
.unwrap_or(field.2.range.end);
|
||||||
|
|
||||||
scope.state.init_hover(
|
scope.state.init_types(
|
||||||
&Metadata {
|
&Metadata {
|
||||||
source_module_id: field.2.source_module_id,
|
source_module_id: field.2.source_module_id,
|
||||||
range: TokenRange {
|
range: TokenRange {
|
||||||
@ -585,8 +514,7 @@ pub fn analyze_context(
|
|||||||
},
|
},
|
||||||
position: None,
|
position: None,
|
||||||
},
|
},
|
||||||
Some(HoverKind::Type(field.1.clone())),
|
Some(field.1.clone()),
|
||||||
None,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
let field_symbol = scope.state.new_symbol(field_idx, SemanticKind::Property);
|
let field_symbol = scope.state.new_symbol(field_idx, SemanticKind::Property);
|
||||||
@ -628,7 +556,7 @@ pub fn analyze_context(
|
|||||||
scope.state.new_symbol(field_ty_idx, SemanticKind::Type)
|
scope.state.new_symbol(field_ty_idx, SemanticKind::Type)
|
||||||
};
|
};
|
||||||
|
|
||||||
scope.state.init_hover(
|
scope.state.init_types(
|
||||||
&Metadata {
|
&Metadata {
|
||||||
source_module_id: field.2.source_module_id,
|
source_module_id: field.2.source_module_id,
|
||||||
range: TokenRange {
|
range: TokenRange {
|
||||||
@ -637,8 +565,7 @@ pub fn analyze_context(
|
|||||||
},
|
},
|
||||||
position: None,
|
position: None,
|
||||||
},
|
},
|
||||||
Some(HoverKind::Type(field.1.clone())),
|
Some(field.1.clone()),
|
||||||
None,
|
|
||||||
);
|
);
|
||||||
scope.state.set_symbol(field_ty_idx, field_ty_symbol);
|
scope.state.set_symbol(field_ty_idx, field_ty_symbol);
|
||||||
}
|
}
|
||||||
@ -649,9 +576,7 @@ pub fn analyze_context(
|
|||||||
for binop in &module.binop_defs {
|
for binop in &module.binop_defs {
|
||||||
if binop.meta.source_module_id == module.module_id {
|
if binop.meta.source_module_id == module.module_id {
|
||||||
for param in [&binop.lhs, &binop.rhs] {
|
for param in [&binop.lhs, &binop.rhs] {
|
||||||
scope
|
scope.state.init_types(¶m.meta, Some(param.ty.clone()));
|
||||||
.state
|
|
||||||
.init_hover(¶m.meta, Some(HoverKind::Type(param.ty.clone())), None);
|
|
||||||
let idx = scope
|
let idx = scope
|
||||||
.token_idx(¶m.meta, |t| matches!(t, Token::Identifier(_)))
|
.token_idx(¶m.meta, |t| matches!(t, Token::Identifier(_)))
|
||||||
.unwrap_or(param.meta.range.end);
|
.unwrap_or(param.meta.range.end);
|
||||||
@ -673,10 +598,9 @@ pub fn analyze_context(
|
|||||||
if source_id != module.module_id {
|
if source_id != module.module_id {
|
||||||
if let Some(state) = map.get(&source_id) {
|
if let Some(state) = map.get(&source_id) {
|
||||||
if let Some(symbol) = state.associated_functions.get(&(ty.clone(), function.name.clone())) {
|
if let Some(symbol) = state.associated_functions.get(&(ty.clone(), function.name.clone())) {
|
||||||
scope.associated_functions.insert(
|
scope
|
||||||
(ty.clone(), function.name.clone()),
|
.associated_functions
|
||||||
(source_id, *symbol, function.documentation.clone()),
|
.insert((ty.clone(), function.name.clone()), (source_id, *symbol));
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
@ -692,10 +616,9 @@ pub fn analyze_context(
|
|||||||
.state
|
.state
|
||||||
.associated_functions
|
.associated_functions
|
||||||
.insert((ty.clone(), function.name.clone()), symbol);
|
.insert((ty.clone(), function.name.clone()), symbol);
|
||||||
scope.associated_functions.insert(
|
scope
|
||||||
(ty.clone(), function.name.clone()),
|
.associated_functions
|
||||||
(module.module_id, symbol, function.documentation.clone()),
|
.insert((ty.clone(), function.name.clone()), (module.module_id, symbol));
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (_, function) in &module.associated_functions {
|
for (_, function) in &module.associated_functions {
|
||||||
@ -721,21 +644,16 @@ pub fn analyze_context(
|
|||||||
if source_id != module.module_id {
|
if source_id != module.module_id {
|
||||||
if let Some(state) = map.get(&source_id) {
|
if let Some(state) = map.get(&source_id) {
|
||||||
if let Some(symbol) = state.functions.get(&function.name) {
|
if let Some(symbol) = state.functions.get(&function.name) {
|
||||||
scope.functions.insert(
|
scope.functions.insert(function.name.clone(), (source_id, *symbol));
|
||||||
function.name.clone(),
|
|
||||||
(source_id, *symbol, function.documentation.clone()),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
scope.state.init_hover(
|
scope
|
||||||
&function.signature(),
|
.state
|
||||||
Some(HoverKind::Type(function.return_type.clone())),
|
.init_types(&function.signature(), Some(function.return_type.clone()));
|
||||||
function.documentation.clone(),
|
|
||||||
);
|
|
||||||
|
|
||||||
let idx = scope
|
let idx = scope
|
||||||
.token_idx(&function.signature(), |t| matches!(t, Token::Identifier(_)))
|
.token_idx(&function.signature(), |t| matches!(t, Token::Identifier(_)))
|
||||||
@ -743,10 +661,9 @@ pub fn analyze_context(
|
|||||||
let function_symbol = scope.state.new_symbol(idx, SemanticKind::Function);
|
let function_symbol = scope.state.new_symbol(idx, SemanticKind::Function);
|
||||||
scope.state.set_symbol(idx, function_symbol);
|
scope.state.set_symbol(idx, function_symbol);
|
||||||
scope.state.functions.insert(function.name.clone(), function_symbol);
|
scope.state.functions.insert(function.name.clone(), function_symbol);
|
||||||
scope.functions.insert(
|
scope
|
||||||
function.name.clone(),
|
.functions
|
||||||
(module.module_id, function_symbol, function.documentation.clone()),
|
.insert(function.name.clone(), (module.module_id, function_symbol));
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for function in &module.functions {
|
for function in &module.functions {
|
||||||
@ -768,7 +685,7 @@ pub fn analyze_context(
|
|||||||
}
|
}
|
||||||
|
|
||||||
for import in &module.imports {
|
for import in &module.imports {
|
||||||
scope.state.init_hover(&import.1, None, None);
|
scope.state.init_types(&import.1, None);
|
||||||
if let Some((module_name, _)) = import.0.get(0) {
|
if let Some((module_name, _)) = import.0.get(0) {
|
||||||
let module_idx = scope
|
let module_idx = scope
|
||||||
.token_idx(&import.1, |t| matches!(t, Token::Identifier(_)))
|
.token_idx(&import.1, |t| matches!(t, Token::Identifier(_)))
|
||||||
@ -795,27 +712,27 @@ pub fn analyze_context(
|
|||||||
if !function.is_pub {
|
if !function.is_pub {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
autocompletes.push(Autocomplete {
|
if function.name.starts_with(&import_name) {
|
||||||
text: function.name.clone(),
|
autocompletes.push(Autocomplete {
|
||||||
documentation: function.documentation.clone(),
|
text: function.name.clone(),
|
||||||
kind: AutocompleteKind::Function(function.parameters.clone(), function.return_type.clone()),
|
kind: AutocompleteKind::Function(function.parameters.clone(), function.return_type.clone()),
|
||||||
});
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
for typedef in &module.typedefs {
|
for typedef in &module.typedefs {
|
||||||
autocompletes.push(Autocomplete {
|
if typedef.name.starts_with(&import_name) {
|
||||||
text: typedef.name.clone(),
|
autocompletes.push(Autocomplete {
|
||||||
documentation: None,
|
text: typedef.name.clone(),
|
||||||
kind: AutocompleteKind::Type,
|
kind: AutocompleteKind::Type,
|
||||||
});
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let symbol = if let Some((source_id, symbol_id, doc)) = scope.functions.get(&import_name) {
|
let symbol = if let Some((source_id, symbol_id)) = scope.functions.get(&import_name) {
|
||||||
let symbol_id = scope
|
scope
|
||||||
.state
|
.state
|
||||||
.new_symbol(import_idx, SemanticKind::Reference(*source_id, *symbol_id));
|
.new_symbol(import_idx, SemanticKind::Reference(*source_id, *symbol_id))
|
||||||
scope.state.set_documentation(import_idx, doc.clone());
|
|
||||||
symbol_id
|
|
||||||
} else if let Some(module_source) = scope.map.values().find(|s| s.module_name == *module_name) {
|
} else if let Some(module_source) = scope.map.values().find(|s| s.module_name == *module_name) {
|
||||||
if let Some((source_id, symbol_id)) = scope.types.get(&TypeKind::CustomType(CustomTypeKey(
|
if let Some((source_id, symbol_id)) = scope.types.get(&TypeKind::CustomType(CustomTypeKey(
|
||||||
import_name.clone(),
|
import_name.clone(),
|
||||||
@ -850,9 +767,7 @@ pub fn analyze_function_parameters(
|
|||||||
scope: &mut AnalysisScope,
|
scope: &mut AnalysisScope,
|
||||||
) {
|
) {
|
||||||
for param in &function.parameters {
|
for param in &function.parameters {
|
||||||
scope
|
scope.state.init_types(¶m.meta, Some(param.ty.clone()));
|
||||||
.state
|
|
||||||
.init_hover(¶m.meta, Some(HoverKind::Type(param.ty.clone())), None);
|
|
||||||
|
|
||||||
if param.meta.source_module_id == module.module_id {
|
if param.meta.source_module_id == module.module_id {
|
||||||
let param_var_idx = scope
|
let param_var_idx = scope
|
||||||
@ -891,14 +806,12 @@ pub fn analyze_block(
|
|||||||
for statement in &block.statements {
|
for statement in &block.statements {
|
||||||
match &statement.0 {
|
match &statement.0 {
|
||||||
mir::StmtKind::Let(named_variable_ref, _, expression) => {
|
mir::StmtKind::Let(named_variable_ref, _, expression) => {
|
||||||
scope.state.init_hover(
|
scope.state.init_types(
|
||||||
&named_variable_ref.2,
|
&named_variable_ref.2,
|
||||||
expression
|
expression
|
||||||
.return_type(&TypeRefs::unknown(), source_module.module_id)
|
.return_type(&TypeRefs::unknown(), source_module.module_id)
|
||||||
.ok()
|
.ok()
|
||||||
.map(|(_, ty)| ty)
|
.map(|(_, ty)| ty),
|
||||||
.map(|t| HoverKind::Type(t)),
|
|
||||||
None,
|
|
||||||
);
|
);
|
||||||
let idx = scope
|
let idx = scope
|
||||||
.token_idx(&named_variable_ref.2, |t| matches!(t, Token::Identifier(_)))
|
.token_idx(&named_variable_ref.2, |t| matches!(t, Token::Identifier(_)))
|
||||||
@ -910,6 +823,7 @@ pub fn analyze_block(
|
|||||||
let ty_idx = scope.token_idx(&named_variable_ref.2.after(idx + 1), |t| {
|
let ty_idx = scope.token_idx(&named_variable_ref.2.after(idx + 1), |t| {
|
||||||
matches!(t, Token::Identifier(_))
|
matches!(t, Token::Identifier(_))
|
||||||
});
|
});
|
||||||
|
dbg!(ty_idx);
|
||||||
if let Some(ty_idx) = ty_idx {
|
if let Some(ty_idx) = ty_idx {
|
||||||
let ty_symbol = if let Some((source_id, symbol_id)) = scope.types.get(&named_variable_ref.0) {
|
let ty_symbol = if let Some((source_id, symbol_id)) = scope.types.get(&named_variable_ref.0) {
|
||||||
scope
|
scope
|
||||||
@ -949,19 +863,16 @@ pub fn analyze_expr(
|
|||||||
expr: &mir::Expression,
|
expr: &mir::Expression,
|
||||||
scope: &mut AnalysisScope,
|
scope: &mut AnalysisScope,
|
||||||
) {
|
) {
|
||||||
scope.state.init_hover(
|
scope.state.init_types(
|
||||||
&expr.1,
|
&expr.1,
|
||||||
expr.return_type(&TypeRefs::unknown(), source_module.module_id)
|
expr.return_type(&TypeRefs::unknown(), source_module.module_id)
|
||||||
.ok()
|
.ok()
|
||||||
.map(|(_, t)| HoverKind::Type(t)),
|
.map(|(_, t)| t),
|
||||||
None,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
match &expr.0 {
|
match &expr.0 {
|
||||||
mir::ExprKind::Variable(var_ref) => {
|
mir::ExprKind::Variable(var_ref) => {
|
||||||
scope
|
scope.state.init_types(&var_ref.2, Some(var_ref.0.clone()));
|
||||||
.state
|
|
||||||
.init_hover(&var_ref.2, Some(HoverKind::Type(var_ref.0.clone())), None);
|
|
||||||
|
|
||||||
let idx = scope
|
let idx = scope
|
||||||
.token_idx(&var_ref.2, |t| matches!(t, Token::Identifier(_)))
|
.token_idx(&var_ref.2, |t| matches!(t, Token::Identifier(_)))
|
||||||
@ -991,10 +902,9 @@ pub fn analyze_expr(
|
|||||||
source_module
|
source_module
|
||||||
.associated_functions
|
.associated_functions
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|(t, _)| *t == accessed_type)
|
.filter(|(t, fun)| *t == accessed_type && fun.name.starts_with(name))
|
||||||
.map(|(_, fun)| Autocomplete {
|
.map(|(_, fun)| Autocomplete {
|
||||||
text: fun.name.clone(),
|
text: fun.name.clone(),
|
||||||
documentation: fun.documentation.clone(),
|
|
||||||
kind: AutocompleteKind::Function(fun.parameters.clone(), fun.return_type.clone()),
|
kind: AutocompleteKind::Function(fun.parameters.clone(), fun.return_type.clone()),
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
@ -1023,9 +933,8 @@ pub fn analyze_expr(
|
|||||||
if let Some(typedef) = typedef {
|
if let Some(typedef) = typedef {
|
||||||
autocompletes.extend(match &typedef.kind {
|
autocompletes.extend(match &typedef.kind {
|
||||||
mir::TypeDefinitionKind::Struct(StructType(fields)) => {
|
mir::TypeDefinitionKind::Struct(StructType(fields)) => {
|
||||||
fields.iter().map(|f| Autocomplete {
|
fields.iter().filter(|f| f.0.starts_with(name)).map(|f| Autocomplete {
|
||||||
text: f.0.clone(),
|
text: f.0.clone(),
|
||||||
documentation: None,
|
|
||||||
kind: AutocompleteKind::Field(f.1.clone()),
|
kind: AutocompleteKind::Field(f.1.clone()),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -1105,12 +1014,10 @@ pub fn analyze_expr(
|
|||||||
let idx = scope
|
let idx = scope
|
||||||
.token_idx(&meta, |t| matches!(t, Token::Identifier(_)))
|
.token_idx(&meta, |t| matches!(t, Token::Identifier(_)))
|
||||||
.unwrap_or(meta.range.end);
|
.unwrap_or(meta.range.end);
|
||||||
let symbol = if let Some((module_id, symbol_id, doc)) = scope.functions.get(name) {
|
let symbol = if let Some((module_id, symbol_id)) = scope.functions.get(name) {
|
||||||
let symbol = scope
|
scope
|
||||||
.state
|
.state
|
||||||
.new_symbol(idx, SemanticKind::Reference(*module_id, *symbol_id));
|
.new_symbol(idx, SemanticKind::Reference(*module_id, *symbol_id))
|
||||||
scope.state.set_documentation(idx, doc.clone());
|
|
||||||
symbol
|
|
||||||
} else {
|
} else {
|
||||||
scope.state.new_symbol(idx, SemanticKind::Function)
|
scope.state.new_symbol(idx, SemanticKind::Function)
|
||||||
};
|
};
|
||||||
@ -1143,14 +1050,12 @@ pub fn analyze_expr(
|
|||||||
let fn_idx = scope
|
let fn_idx = scope
|
||||||
.token_idx(&meta, |t| matches!(t, Token::Identifier(_)))
|
.token_idx(&meta, |t| matches!(t, Token::Identifier(_)))
|
||||||
.unwrap_or(meta.range.end);
|
.unwrap_or(meta.range.end);
|
||||||
let fn_symbol = if let Some((module_id, symbol_id, doc)) =
|
let fn_symbol = if let Some((module_id, symbol_id)) =
|
||||||
scope.associated_functions.get(&(invoked_ty.clone(), name.clone()))
|
scope.associated_functions.get(&(invoked_ty.clone(), name.clone()))
|
||||||
{
|
{
|
||||||
let symbol = scope
|
scope
|
||||||
.state
|
.state
|
||||||
.new_symbol(fn_idx, SemanticKind::Reference(*module_id, *symbol_id));
|
.new_symbol(fn_idx, SemanticKind::Reference(*module_id, *symbol_id))
|
||||||
scope.state.set_documentation(fn_idx, doc.clone());
|
|
||||||
symbol
|
|
||||||
} else {
|
} else {
|
||||||
scope.state.new_symbol(fn_idx, SemanticKind::Function)
|
scope.state.new_symbol(fn_idx, SemanticKind::Function)
|
||||||
};
|
};
|
||||||
@ -1162,19 +1067,18 @@ pub fn analyze_expr(
|
|||||||
let mut function_autocomplete = source_module
|
let mut function_autocomplete = source_module
|
||||||
.associated_functions
|
.associated_functions
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|(t, _)| *t == invoked_ty)
|
.filter(|(t, fun)| *t == invoked_ty && fun.name.starts_with(name))
|
||||||
.map(|(_, fun)| Autocomplete {
|
.map(|(_, fun)| Autocomplete {
|
||||||
text: fun.name.clone(),
|
text: fun.name.clone(),
|
||||||
documentation: fun.documentation.clone(),
|
|
||||||
kind: AutocompleteKind::Function(fun.parameters.clone(), fun.return_type.clone()),
|
kind: AutocompleteKind::Function(fun.parameters.clone(), fun.return_type.clone()),
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
function_autocomplete.extend(
|
function_autocomplete.extend(
|
||||||
get_intrinsic_assoc_functions(&invoked_ty)
|
get_intrinsic_assoc_functions(&invoked_ty)
|
||||||
.iter()
|
.iter()
|
||||||
|
.filter(|fun| fun.name.starts_with(name))
|
||||||
.map(|fun| Autocomplete {
|
.map(|fun| Autocomplete {
|
||||||
text: fun.name.clone(),
|
text: fun.name.clone(),
|
||||||
documentation: Some("intrinsic function documentation".to_string()),
|
|
||||||
kind: AutocompleteKind::Function(fun.parameters.clone(), fun.return_type.clone()),
|
kind: AutocompleteKind::Function(fun.parameters.clone(), fun.return_type.clone()),
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>(),
|
.collect::<Vec<_>>(),
|
||||||
|
@ -6,18 +6,17 @@ use reid::ast::lexer::{FullToken, Position};
|
|||||||
use reid::error_raporting::{self, ErrorModules, ReidError};
|
use reid::error_raporting::{self, ErrorModules, ReidError};
|
||||||
use reid::mir::SourceModuleId;
|
use reid::mir::SourceModuleId;
|
||||||
use reid::parse_module;
|
use reid::parse_module;
|
||||||
use serde::{Deserialize, Serialize};
|
|
||||||
use tokio::sync::Mutex;
|
use tokio::sync::Mutex;
|
||||||
use tower_lsp::lsp_types::{
|
use tower_lsp::lsp_types::{
|
||||||
self, CompletionItem, CompletionItemKind, CompletionOptions, CompletionParams, CompletionResponse, Diagnostic,
|
self, CompletionItem, CompletionOptions, CompletionParams, CompletionResponse, Diagnostic, DiagnosticSeverity,
|
||||||
DiagnosticSeverity, DidChangeTextDocumentParams, DidOpenTextDocumentParams, DidSaveTextDocumentParams,
|
DidChangeTextDocumentParams, DidOpenTextDocumentParams, DidSaveTextDocumentParams, DocumentFilter,
|
||||||
DocumentFilter, GotoDefinitionParams, GotoDefinitionResponse, Hover, HoverContents, HoverParams,
|
GotoDefinitionParams, GotoDefinitionResponse, Hover, HoverContents, HoverParams, HoverProviderCapability,
|
||||||
HoverProviderCapability, InitializeParams, InitializeResult, InitializedParams, Location, MarkedString,
|
InitializeParams, InitializeResult, InitializedParams, Location, MarkupContent, MarkupKind, MessageType, OneOf,
|
||||||
MarkupContent, MarkupKind, MessageType, OneOf, Range, ReferenceParams, RenameParams, SemanticToken,
|
Range, ReferenceParams, RenameParams, SemanticToken, SemanticTokensLegend, SemanticTokensOptions,
|
||||||
SemanticTokensLegend, SemanticTokensOptions, SemanticTokensParams, SemanticTokensResult,
|
SemanticTokensParams, SemanticTokensResult, SemanticTokensServerCapabilities, ServerCapabilities, TextDocumentItem,
|
||||||
SemanticTokensServerCapabilities, ServerCapabilities, TextDocumentItem, TextDocumentRegistrationOptions,
|
TextDocumentRegistrationOptions, TextDocumentSyncCapability, TextDocumentSyncKind, TextDocumentSyncOptions,
|
||||||
TextDocumentSyncCapability, TextDocumentSyncKind, TextDocumentSyncOptions, TextDocumentSyncSaveOptions, TextEdit,
|
TextDocumentSyncSaveOptions, TextEdit, Url, WorkspaceEdit, WorkspaceFoldersServerCapabilities,
|
||||||
Url, WorkspaceEdit, WorkspaceFoldersServerCapabilities, WorkspaceServerCapabilities,
|
WorkspaceServerCapabilities,
|
||||||
};
|
};
|
||||||
use tower_lsp::{Client, LanguageServer, LspService, Server, jsonrpc};
|
use tower_lsp::{Client, LanguageServer, LspService, Server, jsonrpc};
|
||||||
|
|
||||||
@ -34,12 +33,6 @@ struct Backend {
|
|||||||
module_id_counter: Mutex<SourceModuleId>,
|
module_id_counter: Mutex<SourceModuleId>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug)]
|
|
||||||
struct CompletionData {
|
|
||||||
token_idx: usize,
|
|
||||||
path: PathBuf,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tower_lsp::async_trait]
|
#[tower_lsp::async_trait]
|
||||||
impl LanguageServer for Backend {
|
impl LanguageServer for Backend {
|
||||||
async fn initialize(&self, _: InitializeParams) -> jsonrpc::Result<InitializeResult> {
|
async fn initialize(&self, _: InitializeParams) -> jsonrpc::Result<InitializeResult> {
|
||||||
@ -59,17 +52,7 @@ impl LanguageServer for Backend {
|
|||||||
|
|
||||||
let capabilities = ServerCapabilities {
|
let capabilities = ServerCapabilities {
|
||||||
hover_provider: Some(HoverProviderCapability::Simple(true)),
|
hover_provider: Some(HoverProviderCapability::Simple(true)),
|
||||||
completion_provider: Some(CompletionOptions {
|
completion_provider: Some(CompletionOptions { ..Default::default() }),
|
||||||
trigger_characters: Some(vec![".".to_string(), "::".to_string()]),
|
|
||||||
all_commit_characters: None,
|
|
||||||
completion_item: Some(lsp_types::CompletionOptionsCompletionItem {
|
|
||||||
label_details_support: Some(true),
|
|
||||||
}),
|
|
||||||
resolve_provider: Some(true),
|
|
||||||
work_done_progress_options: lsp_types::WorkDoneProgressOptions {
|
|
||||||
work_done_progress: Some(true),
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
text_document_sync: Some(TextDocumentSyncCapability::Options(sync)),
|
text_document_sync: Some(TextDocumentSyncCapability::Options(sync)),
|
||||||
workspace: Some(WorkspaceServerCapabilities {
|
workspace: Some(WorkspaceServerCapabilities {
|
||||||
workspace_folders: Some(WorkspaceFoldersServerCapabilities {
|
workspace_folders: Some(WorkspaceFoldersServerCapabilities {
|
||||||
@ -138,26 +121,11 @@ impl LanguageServer for Backend {
|
|||||||
// dbg!(position, token);
|
// dbg!(position, token);
|
||||||
|
|
||||||
let list = if let Some((idx, _)) = token {
|
let list = if let Some((idx, _)) = token {
|
||||||
if let Some(token_analysis) = self.analysis.get(&path).unwrap().state.map.get(&idx) {
|
if let Some(analysis) = self.analysis.get(&path).unwrap().state.map.get(&idx) {
|
||||||
token_analysis
|
analysis
|
||||||
.autocomplete
|
.autocomplete
|
||||||
.iter()
|
.iter()
|
||||||
.map(|autocomplete| {
|
.map(|s| CompletionItem::new_simple(s.text.to_string(), s.kind.to_string()))
|
||||||
let mut item =
|
|
||||||
CompletionItem::new_simple(autocomplete.text.to_string(), autocomplete.kind.to_string());
|
|
||||||
item.data = Some(
|
|
||||||
serde_json::to_value(CompletionData {
|
|
||||||
token_idx: idx,
|
|
||||||
path: path.clone(),
|
|
||||||
})
|
|
||||||
.unwrap(),
|
|
||||||
);
|
|
||||||
item.documentation = autocomplete
|
|
||||||
.documentation
|
|
||||||
.as_ref()
|
|
||||||
.and_then(|d| Some(lsp_types::Documentation::String(d.clone())));
|
|
||||||
item
|
|
||||||
})
|
|
||||||
.collect()
|
.collect()
|
||||||
} else {
|
} else {
|
||||||
Vec::new()
|
Vec::new()
|
||||||
@ -170,20 +138,6 @@ impl LanguageServer for Backend {
|
|||||||
Ok(Some(CompletionResponse::Array(list)))
|
Ok(Some(CompletionResponse::Array(list)))
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn completion_resolve(&self, params: CompletionItem) -> jsonrpc::Result<CompletionItem> {
|
|
||||||
let data: Option<CompletionData> = if let Some(data) = ¶ms.data {
|
|
||||||
serde_json::from_value(data.clone()).ok()
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
};
|
|
||||||
if let Some(data) = data {
|
|
||||||
let analysis = self.analysis.get(&data.path).unwrap();
|
|
||||||
let token = analysis.tokens.get(data.token_idx).unwrap();
|
|
||||||
if let Some(token_analysis) = analysis.state.map.get(&data.token_idx) {}
|
|
||||||
}
|
|
||||||
Ok(params)
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn hover(&self, params: HoverParams) -> jsonrpc::Result<Option<Hover>> {
|
async fn hover(&self, params: HoverParams) -> jsonrpc::Result<Option<Hover>> {
|
||||||
let path = PathBuf::from(params.text_document_position_params.text_document.uri.path());
|
let path = PathBuf::from(params.text_document_position_params.text_document.uri.path());
|
||||||
let analysis = self.analysis.get(&path);
|
let analysis = self.analysis.get(&path);
|
||||||
@ -199,7 +153,7 @@ impl LanguageServer for Backend {
|
|||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
let (range, ty, documentation) = if let Some((idx, token)) = token {
|
let (range, ty) = if let Some((idx, token)) = token {
|
||||||
if let Some(analysis) = self.analysis.get(&path).unwrap().state.map.get(&idx) {
|
if let Some(analysis) = self.analysis.get(&path).unwrap().state.map.get(&idx) {
|
||||||
let start = token.position;
|
let start = token.position;
|
||||||
let end = token.position.add(token.token.len() as u32);
|
let end = token.position.add(token.token.len() as u32);
|
||||||
@ -213,48 +167,22 @@ impl LanguageServer for Backend {
|
|||||||
character: (end.0 as i32 - 1).max(0) as u32,
|
character: (end.0 as i32 - 1).max(0) as u32,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
if let Some(hover) = analysis.hover.clone() {
|
if let Some(ty) = analysis.ty.clone() {
|
||||||
if let Some(kind) = hover.kind {
|
(Some(range), format!("{}", ty))
|
||||||
match kind {
|
|
||||||
analysis::HoverKind::Type(type_kind) => {
|
|
||||||
(Some(range), format!("{}", type_kind), hover.documentation)
|
|
||||||
}
|
|
||||||
analysis::HoverKind::Function(name, function_params, return_type) => (
|
|
||||||
Some(range),
|
|
||||||
format!(
|
|
||||||
"{}({}) -> {}",
|
|
||||||
name,
|
|
||||||
function_params
|
|
||||||
.iter()
|
|
||||||
.map(|p| format!("{}: {}", p.name, p.ty))
|
|
||||||
.collect::<Vec<_>>()
|
|
||||||
.join(", "),
|
|
||||||
return_type
|
|
||||||
),
|
|
||||||
hover.documentation,
|
|
||||||
),
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
(Some(range), String::from("No type"), hover.documentation)
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
(Some(range), String::from("No hover"), None)
|
(Some(range), String::from("None type"))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
(None, String::from("no type"), None)
|
(None, String::from("no type"))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
(None, String::from("no token"), None)
|
(None, String::from("no token"))
|
||||||
};
|
};
|
||||||
|
|
||||||
let contents = if let Some(doc) = documentation {
|
let contents = HoverContents::Markup(MarkupContent {
|
||||||
HoverContents::Array(vec![MarkedString::String(doc), MarkedString::String(format!("`{ty}`"))])
|
kind: MarkupKind::Markdown,
|
||||||
} else {
|
value: format!("`{ty}`"),
|
||||||
HoverContents::Markup(MarkupContent {
|
});
|
||||||
kind: MarkupKind::Markdown,
|
|
||||||
value: format!("`{ty}`"),
|
|
||||||
})
|
|
||||||
};
|
|
||||||
|
|
||||||
Ok(Some(Hover { contents, range }))
|
Ok(Some(Hover { contents, range }))
|
||||||
}
|
}
|
||||||
|
@ -116,7 +116,6 @@ pub enum Token {
|
|||||||
|
|
||||||
Whitespace(String),
|
Whitespace(String),
|
||||||
Comment(String),
|
Comment(String),
|
||||||
Doc(String),
|
|
||||||
Eof,
|
Eof,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -197,7 +196,6 @@ impl ToString for Token {
|
|||||||
Token::Percent => String::from('%'),
|
Token::Percent => String::from('%'),
|
||||||
Token::Whitespace(val) => val.clone(),
|
Token::Whitespace(val) => val.clone(),
|
||||||
Token::Comment(val) => format!("//{}", val.clone()),
|
Token::Comment(val) => format!("//{}", val.clone()),
|
||||||
Token::Doc(val) => format!("///{}", val.clone()),
|
|
||||||
Token::Unknown(val) => val.to_string(),
|
Token::Unknown(val) => val.to_string(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -311,25 +309,13 @@ pub fn tokenize<T: Into<String>>(to_tokenize: T) -> Result<Vec<FullToken>, Error
|
|||||||
}
|
}
|
||||||
// Comments
|
// Comments
|
||||||
'/' if cursor.first() == Some('/') => {
|
'/' if cursor.first() == Some('/') => {
|
||||||
cursor.next();
|
|
||||||
let doc = if cursor.first() == Some('/') {
|
|
||||||
cursor.next();
|
|
||||||
true
|
|
||||||
} else {
|
|
||||||
false
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut comment = String::new();
|
let mut comment = String::new();
|
||||||
while !matches!(cursor.first(), Some('\n') | None) {
|
while !matches!(cursor.first(), Some('\n') | None) {
|
||||||
if let Some(c) = cursor.next() {
|
if let Some(c) = cursor.next() {
|
||||||
comment.push(c);
|
comment.push(c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if doc {
|
Token::Comment(comment)
|
||||||
Token::Doc(comment)
|
|
||||||
} else {
|
|
||||||
Token::Comment(comment)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
'\"' | '\'' => {
|
'\"' | '\'' => {
|
||||||
let mut value = String::new();
|
let mut value = String::new();
|
||||||
|
@ -192,7 +192,6 @@ pub struct FunctionDefinition(pub FunctionSignature, pub bool, pub Block, pub To
|
|||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct FunctionSignature {
|
pub struct FunctionSignature {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub documentation: Option<String>,
|
|
||||||
pub self_kind: SelfKind,
|
pub self_kind: SelfKind,
|
||||||
pub params: Vec<(String, Type, TokenRange)>,
|
pub params: Vec<(String, Type, TokenRange)>,
|
||||||
pub return_type: Option<Type>,
|
pub return_type: Option<Type>,
|
||||||
|
@ -696,10 +696,6 @@ impl Parse for ImportStatement {
|
|||||||
|
|
||||||
impl Parse for FunctionDefinition {
|
impl Parse for FunctionDefinition {
|
||||||
fn parse(mut stream: TokenStream) -> Result<Self, Error> {
|
fn parse(mut stream: TokenStream) -> Result<Self, Error> {
|
||||||
let documentation = stream.find_documentation();
|
|
||||||
dbg!(&stream.get_range());
|
|
||||||
dbg!(&documentation);
|
|
||||||
|
|
||||||
let is_pub = if let Some(Token::PubKeyword) = stream.peek() {
|
let is_pub = if let Some(Token::PubKeyword) = stream.peek() {
|
||||||
stream.next(); // Consume pub
|
stream.next(); // Consume pub
|
||||||
true
|
true
|
||||||
@ -708,10 +704,8 @@ impl Parse for FunctionDefinition {
|
|||||||
};
|
};
|
||||||
|
|
||||||
stream.expect(Token::FnKeyword)?;
|
stream.expect(Token::FnKeyword)?;
|
||||||
let mut signature: FunctionSignature = stream.parse()?;
|
|
||||||
signature.documentation = documentation;
|
|
||||||
Ok(FunctionDefinition(
|
Ok(FunctionDefinition(
|
||||||
signature,
|
stream.parse()?,
|
||||||
is_pub,
|
is_pub,
|
||||||
stream.parse()?,
|
stream.parse()?,
|
||||||
stream.get_range().unwrap(),
|
stream.get_range().unwrap(),
|
||||||
@ -816,7 +810,6 @@ impl Parse for FunctionSignature {
|
|||||||
|
|
||||||
Ok(FunctionSignature {
|
Ok(FunctionSignature {
|
||||||
name,
|
name,
|
||||||
documentation: None,
|
|
||||||
params,
|
params,
|
||||||
self_kind,
|
self_kind,
|
||||||
return_type,
|
return_type,
|
||||||
@ -1096,12 +1089,9 @@ impl Parse for TopLevelStatement {
|
|||||||
Ok(match stream.peek() {
|
Ok(match stream.peek() {
|
||||||
Some(Token::ImportKeyword) => Stmt::Import(stream.parse()?),
|
Some(Token::ImportKeyword) => Stmt::Import(stream.parse()?),
|
||||||
Some(Token::Extern) => {
|
Some(Token::Extern) => {
|
||||||
let documentation = stream.find_documentation();
|
|
||||||
stream.next(); // Consume Extern
|
stream.next(); // Consume Extern
|
||||||
stream.expect(Token::FnKeyword)?;
|
stream.expect(Token::FnKeyword)?;
|
||||||
let mut signature: FunctionSignature = stream.parse()?;
|
let extern_fn = Stmt::ExternFunction(stream.parse()?);
|
||||||
signature.documentation = documentation;
|
|
||||||
let extern_fn = Stmt::ExternFunction(signature);
|
|
||||||
stream.expect_nonfatal(Token::Semi).ok();
|
stream.expect_nonfatal(Token::Semi).ok();
|
||||||
extern_fn
|
extern_fn
|
||||||
}
|
}
|
||||||
|
@ -43,7 +43,6 @@ impl ast::Module {
|
|||||||
ExternFunction(signature) => {
|
ExternFunction(signature) => {
|
||||||
let def = mir::FunctionDefinition {
|
let def = mir::FunctionDefinition {
|
||||||
name: signature.name.clone(),
|
name: signature.name.clone(),
|
||||||
documentation: signature.documentation.clone(),
|
|
||||||
linkage_name: None,
|
linkage_name: None,
|
||||||
is_pub: false,
|
is_pub: false,
|
||||||
is_imported: false,
|
is_imported: false,
|
||||||
@ -177,7 +176,6 @@ impl ast::FunctionDefinition {
|
|||||||
}));
|
}));
|
||||||
mir::FunctionDefinition {
|
mir::FunctionDefinition {
|
||||||
name: signature.name.clone(),
|
name: signature.name.clone(),
|
||||||
documentation: signature.documentation.clone(),
|
|
||||||
linkage_name: None,
|
linkage_name: None,
|
||||||
is_pub: *is_pub,
|
is_pub: *is_pub,
|
||||||
is_imported: false,
|
is_imported: false,
|
||||||
|
@ -87,28 +87,6 @@ impl<'a, 'b> TokenStream<'a, 'b> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn find_documentation(&mut self) -> Option<String> {
|
|
||||||
let mut from = self.position;
|
|
||||||
let mut documentation = None;
|
|
||||||
while let Some(token) = self.tokens.get(from) {
|
|
||||||
if matches!(token.token, Token::Whitespace(_) | Token::Comment(_) | Token::Doc(_)) {
|
|
||||||
from += 1;
|
|
||||||
if let Token::Doc(doctext) = &token.token {
|
|
||||||
documentation = Some(
|
|
||||||
match documentation {
|
|
||||||
Some(t) => t + " ",
|
|
||||||
None => String::new(),
|
|
||||||
} + doctext.trim(),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
dbg!(self.position, from, &documentation);
|
|
||||||
documentation
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn expect_nonfatal(&mut self, token: Token) -> Result<(), ()> {
|
pub fn expect_nonfatal(&mut self, token: Token) -> Result<(), ()> {
|
||||||
if let (pos, Some(peeked)) = self.next_token(self.position) {
|
if let (pos, Some(peeked)) = self.next_token(self.position) {
|
||||||
if token == peeked.token {
|
if token == peeked.token {
|
||||||
@ -271,7 +249,7 @@ impl<'a, 'b> TokenStream<'a, 'b> {
|
|||||||
fn previous_token(&self, mut from: usize) -> (usize, Option<&'a FullToken>) {
|
fn previous_token(&self, mut from: usize) -> (usize, Option<&'a FullToken>) {
|
||||||
from -= 1;
|
from -= 1;
|
||||||
while let Some(token) = self.tokens.get(from) {
|
while let Some(token) = self.tokens.get(from) {
|
||||||
if matches!(token.token, Token::Whitespace(_) | Token::Comment(_) | Token::Doc(_)) {
|
if matches!(token.token, Token::Whitespace(_) | Token::Comment(_)) {
|
||||||
from -= 1;
|
from -= 1;
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
@ -282,7 +260,7 @@ impl<'a, 'b> TokenStream<'a, 'b> {
|
|||||||
|
|
||||||
fn next_token(&self, mut from: usize) -> (usize, Option<&'a FullToken>) {
|
fn next_token(&self, mut from: usize) -> (usize, Option<&'a FullToken>) {
|
||||||
while let Some(token) = self.tokens.get(from) {
|
while let Some(token) = self.tokens.get(from) {
|
||||||
if matches!(token.token, Token::Whitespace(_) | Token::Comment(_) | Token::Doc(_)) {
|
if matches!(token.token, Token::Whitespace(_) | Token::Comment(_)) {
|
||||||
from += 1;
|
from += 1;
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
|
@ -71,7 +71,6 @@ pub fn form_intrinsics() -> Vec<FunctionDefinition> {
|
|||||||
|
|
||||||
intrinsics.push(FunctionDefinition {
|
intrinsics.push(FunctionDefinition {
|
||||||
name: MALLOC_IDENT.to_owned(),
|
name: MALLOC_IDENT.to_owned(),
|
||||||
documentation: Some("temp".to_string()),
|
|
||||||
linkage_name: Some("malloc".to_owned()),
|
linkage_name: Some("malloc".to_owned()),
|
||||||
is_pub: false,
|
is_pub: false,
|
||||||
is_imported: true,
|
is_imported: true,
|
||||||
@ -97,7 +96,6 @@ pub fn simple_intrinsic<T: Into<String> + Clone>(
|
|||||||
) -> FunctionDefinition {
|
) -> FunctionDefinition {
|
||||||
FunctionDefinition {
|
FunctionDefinition {
|
||||||
name: name.into(),
|
name: name.into(),
|
||||||
documentation: Some("temp".to_string()),
|
|
||||||
linkage_name: None,
|
linkage_name: None,
|
||||||
is_pub: true,
|
is_pub: true,
|
||||||
is_imported: false,
|
is_imported: false,
|
||||||
@ -117,7 +115,6 @@ pub fn get_intrinsic_assoc_functions(ty: &TypeKind) -> Vec<FunctionDefinition> {
|
|||||||
if let TypeKind::Array(_, len) = ty {
|
if let TypeKind::Array(_, len) = ty {
|
||||||
intrinsics.push(FunctionDefinition {
|
intrinsics.push(FunctionDefinition {
|
||||||
name: "length".to_owned(),
|
name: "length".to_owned(),
|
||||||
documentation: Some("temp".to_string()),
|
|
||||||
linkage_name: None,
|
linkage_name: None,
|
||||||
is_pub: true,
|
is_pub: true,
|
||||||
is_imported: false,
|
is_imported: false,
|
||||||
@ -255,7 +252,6 @@ pub fn get_intrinsic_assoc_functions(ty: &TypeKind) -> Vec<FunctionDefinition> {
|
|||||||
));
|
));
|
||||||
intrinsics.push(FunctionDefinition {
|
intrinsics.push(FunctionDefinition {
|
||||||
name: "powi".to_owned(),
|
name: "powi".to_owned(),
|
||||||
documentation: Some("temp".to_string()),
|
|
||||||
linkage_name: None,
|
linkage_name: None,
|
||||||
is_pub: true,
|
is_pub: true,
|
||||||
is_imported: false,
|
is_imported: false,
|
||||||
@ -297,7 +293,6 @@ pub fn get_intrinsic_assoc_functions(ty: &TypeKind) -> Vec<FunctionDefinition> {
|
|||||||
if ty.signed() {
|
if ty.signed() {
|
||||||
intrinsics.push(FunctionDefinition {
|
intrinsics.push(FunctionDefinition {
|
||||||
name: "abs".to_owned(),
|
name: "abs".to_owned(),
|
||||||
documentation: Some("temp".to_string()),
|
|
||||||
linkage_name: None,
|
linkage_name: None,
|
||||||
is_pub: true,
|
is_pub: true,
|
||||||
is_imported: false,
|
is_imported: false,
|
||||||
@ -328,7 +323,6 @@ pub fn get_intrinsic_assoc_functions(ty: &TypeKind) -> Vec<FunctionDefinition> {
|
|||||||
}
|
}
|
||||||
intrinsics.push(FunctionDefinition {
|
intrinsics.push(FunctionDefinition {
|
||||||
name: "sizeof".to_owned(),
|
name: "sizeof".to_owned(),
|
||||||
documentation: Some("temp".to_string()),
|
|
||||||
linkage_name: None,
|
linkage_name: None,
|
||||||
is_pub: true,
|
is_pub: true,
|
||||||
is_imported: false,
|
is_imported: false,
|
||||||
@ -340,7 +334,6 @@ pub fn get_intrinsic_assoc_functions(ty: &TypeKind) -> Vec<FunctionDefinition> {
|
|||||||
});
|
});
|
||||||
intrinsics.push(FunctionDefinition {
|
intrinsics.push(FunctionDefinition {
|
||||||
name: "malloc".to_owned(),
|
name: "malloc".to_owned(),
|
||||||
documentation: Some("temp".to_string()),
|
|
||||||
linkage_name: None,
|
linkage_name: None,
|
||||||
is_pub: true,
|
is_pub: true,
|
||||||
is_imported: false,
|
is_imported: false,
|
||||||
@ -357,7 +350,6 @@ pub fn get_intrinsic_assoc_functions(ty: &TypeKind) -> Vec<FunctionDefinition> {
|
|||||||
|
|
||||||
intrinsics.push(FunctionDefinition {
|
intrinsics.push(FunctionDefinition {
|
||||||
name: "memcpy".to_owned(),
|
name: "memcpy".to_owned(),
|
||||||
documentation: Some("temp".to_string()),
|
|
||||||
linkage_name: None,
|
linkage_name: None,
|
||||||
is_pub: true,
|
is_pub: true,
|
||||||
is_imported: false,
|
is_imported: false,
|
||||||
@ -386,7 +378,6 @@ pub fn get_intrinsic_assoc_functions(ty: &TypeKind) -> Vec<FunctionDefinition> {
|
|||||||
|
|
||||||
intrinsics.push(FunctionDefinition {
|
intrinsics.push(FunctionDefinition {
|
||||||
name: "null".to_owned(),
|
name: "null".to_owned(),
|
||||||
documentation: Some("temp".to_string()),
|
|
||||||
linkage_name: None,
|
linkage_name: None,
|
||||||
is_pub: true,
|
is_pub: true,
|
||||||
is_imported: false,
|
is_imported: false,
|
||||||
@ -399,7 +390,6 @@ pub fn get_intrinsic_assoc_functions(ty: &TypeKind) -> Vec<FunctionDefinition> {
|
|||||||
|
|
||||||
intrinsics.push(FunctionDefinition {
|
intrinsics.push(FunctionDefinition {
|
||||||
name: "is_null".to_owned(),
|
name: "is_null".to_owned(),
|
||||||
documentation: Some("temp".to_string()),
|
|
||||||
linkage_name: None,
|
linkage_name: None,
|
||||||
is_pub: true,
|
is_pub: true,
|
||||||
is_imported: false,
|
is_imported: false,
|
||||||
@ -595,9 +585,6 @@ pub fn form_intrinsic_binops() -> Vec<BinopDefinition> {
|
|||||||
intrinsics.push(boolean_binop_def(Cmp(CmpOperator::NE), &ty, |scope, lhs, rhs| {
|
intrinsics.push(boolean_binop_def(Cmp(CmpOperator::NE), &ty, |scope, lhs, rhs| {
|
||||||
scope.block.build(Instr::FCmp(CmpPredicate::NE, lhs, rhs)).unwrap()
|
scope.block.build(Instr::FCmp(CmpPredicate::NE, lhs, rhs)).unwrap()
|
||||||
}));
|
}));
|
||||||
intrinsics.push(boolean_binop_def(Cmp(CmpOperator::EQ), &ty, |scope, lhs, rhs| {
|
|
||||||
scope.block.build(Instr::FCmp(CmpPredicate::EQ, lhs, rhs)).unwrap()
|
|
||||||
}));
|
|
||||||
intrinsics.push(boolean_binop_def(Cmp(CmpOperator::GT), &ty, |scope, lhs, rhs| {
|
intrinsics.push(boolean_binop_def(Cmp(CmpOperator::GT), &ty, |scope, lhs, rhs| {
|
||||||
scope.block.build(Instr::FCmp(CmpPredicate::GT, lhs, rhs)).unwrap()
|
scope.block.build(Instr::FCmp(CmpPredicate::GT, lhs, rhs)).unwrap()
|
||||||
}));
|
}));
|
||||||
|
@ -226,6 +226,8 @@ impl mir::Module {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dbg!(&typedefs_sorted);
|
||||||
|
|
||||||
for typedef in typedefs_sorted {
|
for typedef in typedefs_sorted {
|
||||||
let type_key = CustomTypeKey(typedef.name.clone(), typedef.source_module);
|
let type_key = CustomTypeKey(typedef.name.clone(), typedef.source_module);
|
||||||
type_map.insert(type_key.clone(), typedef.clone());
|
type_map.insert(type_key.clone(), typedef.clone());
|
||||||
@ -334,6 +336,7 @@ impl mir::Module {
|
|||||||
if module_id == self.module_id {
|
if module_id == self.module_id {
|
||||||
format!("reid.{}.", self.name)
|
format!("reid.{}.", self.name)
|
||||||
} else {
|
} else {
|
||||||
|
dbg!(self.module_id, module_id);
|
||||||
format!("reid.{}.", modules.get(&module_id).unwrap().name)
|
format!("reid.{}.", modules.get(&module_id).unwrap().name)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -152,9 +152,6 @@ impl Display for StructField {
|
|||||||
|
|
||||||
impl Display for FunctionDefinition {
|
impl Display for FunctionDefinition {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
if let Some(documentation) = &self.documentation {
|
|
||||||
writeln!(f, "/// {}", documentation)?;
|
|
||||||
}
|
|
||||||
write!(
|
write!(
|
||||||
f,
|
f,
|
||||||
"{}fn {}({}) -> {:#} ",
|
"{}fn {}({}) -> {:#} ",
|
||||||
|
@ -311,7 +311,6 @@ impl<'map> Pass for LinkerPass<'map> {
|
|||||||
|
|
||||||
importer_module.functions.push(FunctionDefinition {
|
importer_module.functions.push(FunctionDefinition {
|
||||||
name: function.name.clone(),
|
name: function.name.clone(),
|
||||||
documentation: function.documentation.clone(),
|
|
||||||
linkage_name: None,
|
linkage_name: None,
|
||||||
is_pub: false,
|
is_pub: false,
|
||||||
is_imported: false,
|
is_imported: false,
|
||||||
@ -459,7 +458,6 @@ impl<'map> Pass for LinkerPass<'map> {
|
|||||||
ty.clone(),
|
ty.clone(),
|
||||||
FunctionDefinition {
|
FunctionDefinition {
|
||||||
name: func_name.clone(),
|
name: func_name.clone(),
|
||||||
documentation: func.documentation.clone(),
|
|
||||||
linkage_name: Some(format!("{}::{}", ty, func_name)),
|
linkage_name: Some(format!("{}::{}", ty, func_name)),
|
||||||
is_pub: false,
|
is_pub: false,
|
||||||
is_imported: false,
|
is_imported: false,
|
||||||
|
@ -318,7 +318,6 @@ pub struct FunctionCall {
|
|||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct FunctionDefinition {
|
pub struct FunctionDefinition {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub documentation: Option<String>,
|
|
||||||
pub linkage_name: Option<String>,
|
pub linkage_name: Option<String>,
|
||||||
/// Whether this function is visible to outside modules
|
/// Whether this function is visible to outside modules
|
||||||
pub is_pub: bool,
|
pub is_pub: bool,
|
||||||
|
Loading…
Reference in New Issue
Block a user