Working formatter #90
This commit is contained in:
@@ -16,14 +16,33 @@ use tower_lsp::lsp_types::{self, *};
|
|||||||
use tower_lsp::{Client, LanguageServer, LspService, Server};
|
use tower_lsp::{Client, LanguageServer, LspService, Server};
|
||||||
|
|
||||||
use crate::rust_analyzer::RustAnalyzer;
|
use crate::rust_analyzer::RustAnalyzer;
|
||||||
use crate::transpiler::{TranspileError, transpile_mist, transpile_mist_no_sem};
|
use crate::transpiler::{TranspileError, format_mist, transpile_mist, transpile_mist_no_sem};
|
||||||
|
|
||||||
static MARKER_COUNTER: AtomicU64 = AtomicU64::new(0);
|
static MARKER_COUNTER: AtomicU64 = AtomicU64::new(0);
|
||||||
|
|
||||||
const KEYWORDS: [&'static str; 22] = [
|
const KEYWORDS: [&'static str; 22] = [
|
||||||
"if", "else", "for", "while", "match", "return", "break", "continue ", "struct ", "enum ",
|
"if",
|
||||||
"class ", "trait ", "impl ", "pub ", "mut ", "let ", "dyn ", "loop", "unsafe",
|
"else",
|
||||||
"override", "module ", "void ",
|
"for",
|
||||||
|
"while",
|
||||||
|
"match",
|
||||||
|
"return",
|
||||||
|
"break",
|
||||||
|
"continue ",
|
||||||
|
"struct ",
|
||||||
|
"enum ",
|
||||||
|
"class ",
|
||||||
|
"trait ",
|
||||||
|
"impl ",
|
||||||
|
"pub ",
|
||||||
|
"mut ",
|
||||||
|
"let ",
|
||||||
|
"dyn ",
|
||||||
|
"loop",
|
||||||
|
"unsafe",
|
||||||
|
"override",
|
||||||
|
"module ",
|
||||||
|
"void ",
|
||||||
];
|
];
|
||||||
|
|
||||||
fn keyword_completion_items() -> impl Iterator<Item = CompletionItem> {
|
fn keyword_completion_items() -> impl Iterator<Item = CompletionItem> {
|
||||||
@@ -666,6 +685,8 @@ impl LanguageServer for Backend {
|
|||||||
},
|
},
|
||||||
));
|
));
|
||||||
|
|
||||||
|
res.capabilities.document_formatting_provider = Some(OneOf::Left(true));
|
||||||
|
|
||||||
res.capabilities.completion_provider = Some(CompletionOptions {
|
res.capabilities.completion_provider = Some(CompletionOptions {
|
||||||
resolve_provider: Some(false),
|
resolve_provider: Some(false),
|
||||||
trigger_characters: Some(vec![
|
trigger_characters: Some(vec![
|
||||||
@@ -1256,6 +1277,34 @@ impl LanguageServer for Backend {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn formatting(
|
||||||
|
&self,
|
||||||
|
params: DocumentFormattingParams,
|
||||||
|
) -> tower_lsp::jsonrpc::Result<Option<Vec<TextEdit>>> {
|
||||||
|
let mist_path = params
|
||||||
|
.text_document
|
||||||
|
.uri
|
||||||
|
.to_file_path()
|
||||||
|
.map_err(|_| tower_lsp::jsonrpc::Error::internal_error())?;
|
||||||
|
|
||||||
|
let docs = self.documents.lock().await;
|
||||||
|
|
||||||
|
let old_text = docs
|
||||||
|
.get(&mist_path)
|
||||||
|
.map_or_else(|| Err(tower_lsp::jsonrpc::Error::internal_error()), Ok)?;
|
||||||
|
|
||||||
|
let new_text = format_mist(&old_text.to_string())
|
||||||
|
.map_err(|_| tower_lsp::jsonrpc::Error::internal_error())?;
|
||||||
|
|
||||||
|
Ok(Some(vec![TextEdit {
|
||||||
|
new_text,
|
||||||
|
range: Range {
|
||||||
|
start: Position::new(0, 0),
|
||||||
|
end: Position::new(u32::MAX, u32::MAX),
|
||||||
|
},
|
||||||
|
}]))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn mist_ify_completions(source: &str, pos: &Position, items: &mut Vec<CompletionItem>) {
|
fn mist_ify_completions(source: &str, pos: &Position, items: &mut Vec<CompletionItem>) {
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
|
|
||||||
|
use mist_codegen::fmt::MistCodegen;
|
||||||
use mist_codegen::RustCodegen;
|
use mist_codegen::RustCodegen;
|
||||||
use mist_parser::parse;
|
use mist_parser::parse;
|
||||||
use mist_parser::rev_mapper::Mapping;
|
use mist_parser::rev_mapper::Mapping;
|
||||||
@@ -83,3 +84,13 @@ pub fn transpile_mist_no_sem(
|
|||||||
mapping: codegen.mapping,
|
mapping: codegen.mapping,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn format_mist(source: &str) -> Result<String, String> {
|
||||||
|
let parsed = parse(source).map_err(|e| format!("parse error: {e:?}"))?;
|
||||||
|
|
||||||
|
let mut codegen = MistCodegen::new();
|
||||||
|
codegen.generate(parsed.mod_attributes);
|
||||||
|
let output = codegen.generate(parsed.items);
|
||||||
|
|
||||||
|
Ok(output)
|
||||||
|
}
|
||||||
|
|||||||
@@ -2,55 +2,40 @@ pub module class_test;
|
|||||||
|
|
||||||
pub class Animal {
|
pub class Animal {
|
||||||
pub String name;
|
pub String name;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
self.name = "Rex".to_string();
|
self.name = "Rex".to_string();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub String speak(&self) {
|
pub String speak(&self) {
|
||||||
"Unknown".to_string()
|
"Unknown".to_string()
|
||||||
}
|
} pub void test_speak<'a>(&'a self) {
|
||||||
|
|
||||||
pub void test_speak<'a>(&'a self) {
|
|
||||||
assert_eq!(self.speak(), "Woof!");
|
assert_eq!(self.speak(), "Woof!");
|
||||||
}
|
} pub void static_method() {
|
||||||
|
}}
|
||||||
pub void static_method() {}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub class Mammal : Animal {
|
pub class Mammal : Animal {
|
||||||
constructor() {
|
constructor() {
|
||||||
super = Super::new();
|
super = Super::new();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub void args_test(&self, i32 x, str& y) {
|
pub void args_test(&self, i32 x, str& y) {
|
||||||
assert_eq!(x, 10);
|
assert_eq!(x, 10);
|
||||||
assert_eq!(y, "hello");
|
assert_eq!(y, "hello");
|
||||||
}
|
}}
|
||||||
}
|
|
||||||
|
|
||||||
pub class Dog : Mammal {
|
pub class Dog : Mammal {
|
||||||
constructor() {
|
constructor() {
|
||||||
super = Super::new();
|
super = Super::new();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub String speak(&self) override(Animal) {
|
pub String speak(&self) override(Animal) {
|
||||||
"Woof!".to_string()
|
"Woof!".to_string()
|
||||||
}
|
} implstd::fmt::Display {
|
||||||
|
Result<(), std::fmt::Error> fmt(&self, std::fmt::Formatter<'_>& mut f) {
|
||||||
impl std::fmt::Display {
|
|
||||||
Result<(), std::fmt::Error> fmt(&self, std::fmt::Formatter<'_> mut& f) {
|
|
||||||
write!(f, "🐾 {}", self.name)
|
write!(f, "🐾 {}", self.name)
|
||||||
}
|
} }
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub void run_tests() {
|
pub void run_tests() {
|
||||||
let dawg = Dog::new();
|
let dawg = Dog::new();
|
||||||
|
|
||||||
dawg.args_test(10, "hello");
|
dawg.args_test(10, "hello");
|
||||||
|
|
||||||
dawg.test_speak();
|
dawg.test_speak();
|
||||||
|
|
||||||
assert_eq!(format!("{dawg}"), "🐾 Rex");
|
assert_eq!(format!("{dawg}"), "🐾 Rex");
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user