From d7fa413dd70c1e1967a974bf0874cd3d8c7e9992 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=9F=B3=E5=8D=9A=E6=96=87?= Date: Thu, 21 Dec 2023 21:05:59 +0800 Subject: [PATCH] chore: use strum to iterate enum fields --- Cargo.lock | 21 +++++++++++++++++++ lsp/Cargo.toml | 4 +++- lsp/src/lsp.rs | 50 +++++++++++--------------------------------- lsp/src/lsp_types.rs | 46 ++++++++++++++++++++++++++++++++++++++++ lsp/src/main.rs | 1 + 5 files changed, 83 insertions(+), 39 deletions(-) create mode 100644 lsp/src/lsp_types.rs diff --git a/Cargo.lock b/Cargo.lock index e88a4c3..99c2d54 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -992,6 +992,8 @@ dependencies = [ "pretty_env_logger", "serde_json", "stc-rs", + "strum", + "strum_macros", "tokio", "tokio-util", "tower-lsp", @@ -1578,6 +1580,25 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" +[[package]] +name = "strum" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "290d54ea6f91c969195bdbcd7442c8c2a2ba87da8bf60a7ee86a235d4bc1e125" + +[[package]] +name = "strum_macros" +version = "0.25.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23dc1fa9ac9c169a78ba62f0b841814b7abae11bdd047b9c58f893439e309ea0" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "rustversion", + "syn 2.0.41", +] + [[package]] name = "syn" version = "1.0.109" diff --git a/lsp/Cargo.toml b/lsp/Cargo.toml index d320622..8460092 100644 --- a/lsp/Cargo.toml +++ b/lsp/Cargo.toml @@ -13,4 +13,6 @@ tokio-util = { version = "*", features = ["codec"] } serde_json = "*" tracing = "*" tracing-subscriber = { version = "*", features = ["env-filter"] } -once_cell = "*" \ No newline at end of file +once_cell = "*" +strum = "*" +strum_macros = "*" \ No newline at end of file diff --git a/lsp/src/lsp.rs b/lsp/src/lsp.rs index aeb790e..bbecb38 100644 --- a/lsp/src/lsp.rs +++ b/lsp/src/lsp.rs @@ -1,49 +1,23 @@ +use crate::lsp_types::{TokenModifiers, TokenTypes}; + use serde_json::Value; use stc::parser::{StLexerBuilder, Tok}; +use strum::IntoEnumIterator; use tower_lsp::jsonrpc; use tower_lsp::jsonrpc::Result; use tower_lsp::lsp_types::*; use tower_lsp::{Client, LanguageServer}; use tracing::*; -const TOKEN_MODIFIERS: &[SemanticTokenModifier] = &[ - SemanticTokenModifier::new("none"), - // 1, STATIC - SemanticTokenModifier::STATIC, - // 2, GLOBAL - SemanticTokenModifier::new("global"), - // 4, RETAIN - SemanticTokenModifier::new("retain"), -]; - -const TOKEN_TYPES: &[SemanticTokenType] = &[ - // 0, NONE - SemanticTokenType::new("none"), - // 1, keywords - SemanticTokenType::KEYWORD, - // 2, identifiers - SemanticTokenType::VARIABLE, - // 3, operators - SemanticTokenType::OPERATOR, - // 4, builtin functions - SemanticTokenType::new("builtin-functions"), - // 5, number literals - SemanticTokenType::NUMBER, - // 6, string literals - SemanticTokenType::STRING, - // 7, type - SemanticTokenType::TYPE, -]; - fn semantic_token_type_id(tok: &Tok) -> (u32, u32) { match tok { - Tok::Identifier(_) => (2, 0), - Tok::Literal(_) => (5, 0), - Tok::String => (6, 0), + Tok::Identifier(_) => (TokenTypes::Variable as u32, TokenModifiers::None as u32), + Tok::Literal(_) => (TokenTypes::Number as u32, TokenModifiers::None as u32), + Tok::String => (TokenTypes::String as u32, TokenModifiers::None as u32), // operators - op if op.is_operator() => (3, 0), + op if op.is_operator() => (TokenTypes::Operator as u32, TokenModifiers::None as u32), // builtin-types - Tok::Int => (7, 0), + Tok::Int => (TokenTypes::Type as u32, TokenModifiers::None as u32), // keywords Tok::If | Tok::Then @@ -51,8 +25,8 @@ fn semantic_token_type_id(tok: &Tok) -> (u32, u32) { | Tok::Var | Tok::EndVar | Tok::Program - | Tok::EndProgram => (1, 0), - _ => (0, 0), + | Tok::EndProgram => (TokenTypes::Keyword as u32, TokenModifiers::None as u32), + _ => (TokenTypes::None as u32, TokenModifiers::None as u32), } } @@ -74,8 +48,8 @@ impl LanguageServer for StcLsp { work_done_progress: None, }, legend: SemanticTokensLegend { - token_types: TOKEN_TYPES.to_vec(), - token_modifiers: TOKEN_MODIFIERS.to_vec(), + token_types: TokenTypes::iter().map(Into::into).collect(), + token_modifiers: TokenModifiers::iter().map(Into::into).collect(), }, range: Some(true), full: Some(SemanticTokensFullOptions::Delta { delta: Some(true) }), diff --git a/lsp/src/lsp_types.rs b/lsp/src/lsp_types.rs new file mode 100644 index 0000000..126ae3b --- /dev/null +++ b/lsp/src/lsp_types.rs @@ -0,0 +1,46 @@ +use strum_macros::{Display, EnumIter}; +use tower_lsp::lsp_types::{SemanticTokenModifier, SemanticTokenType}; + +#[derive(Debug, PartialEq, Eq, EnumIter, Display)] +#[repr(u32)] +pub enum TokenTypes { + None, + Keyword, + Variable, + Operator, + BuiltinFunction, + Number, + String, + Type, +} + +impl From for SemanticTokenType { + fn from(value: TokenTypes) -> Self { + match value { + TokenTypes::None => SemanticTokenType::new("none"), + TokenTypes::Keyword => SemanticTokenType::KEYWORD, + TokenTypes::Variable => SemanticTokenType::VARIABLE, + TokenTypes::Operator => SemanticTokenType::OPERATOR, + TokenTypes::BuiltinFunction => SemanticTokenType::new("builtin-functions"), + TokenTypes::Number => SemanticTokenType::NUMBER, + TokenTypes::String => SemanticTokenType::STRING, + TokenTypes::Type => SemanticTokenType::TYPE, + } + } +} + +#[derive(Debug, PartialEq, Eq, EnumIter, Display)] +#[repr(u32)] +pub enum TokenModifiers { + None, + Static, +} + +impl From for SemanticTokenModifier { + fn from(value: TokenModifiers) -> Self { + match value { + TokenModifiers::None => SemanticTokenModifier::new("none"), + TokenModifiers::Static => SemanticTokenModifier::STATIC, + } + } +} diff --git a/lsp/src/main.rs b/lsp/src/main.rs index e835c74..191038c 100644 --- a/lsp/src/main.rs +++ b/lsp/src/main.rs @@ -1,4 +1,5 @@ mod lsp; +mod lsp_types; use lsp::StcLsp; use std::io;