Skip to content

Commit

Permalink
feat(kotlin): add kotlin.rs with impl Language for Kotlin and add `…
Browse files Browse the repository at this point in the history
…PatternLanguage::Kotlin`

fixes #570
  • Loading branch information
Alex-ley-scrub committed Nov 9, 2024
1 parent b5f1dba commit 07f0922
Show file tree
Hide file tree
Showing 7 changed files with 165 additions and 34 deletions.
69 changes: 39 additions & 30 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions crates/language/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ tree-sitter-typescript = { path = "../../resources/language-metavariables/tree-s
tree-sitter-javascript = { path = "../../resources/language-metavariables/tree-sitter-javascript", optional = true }
tree-sitter-html = { path = "../../resources/language-metavariables/tree-sitter-html", optional = true }
tree-sitter-java = { path = "../../resources/language-metavariables/tree-sitter-java", optional = true }
tree-sitter-kotlin = { path = "../../resources/language-metavariables/tree-sitter-kotlin", optional = true }
tree-sitter-c-sharp = { path = "../../resources/language-metavariables/tree-sitter-c-sharp", optional = true }
tree-sitter-python = { path = "../../resources/language-metavariables/tree-sitter-python", optional = true }
tree-sitter-md = { path = "../../resources/language-metavariables/tree-sitter-markdown", optional = true }
Expand Down Expand Up @@ -64,6 +65,7 @@ builtin-parser = [
"tree-sitter-javascript",
"tree-sitter-html",
"tree-sitter-java",
"tree-sitter-kotlin",
"tree-sitter-c-sharp",
"tree-sitter-python",
"tree-sitter-md",
Expand Down
107 changes: 107 additions & 0 deletions crates/language/src/kotlin.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
use crate::language::{fields_for_nodes, Field, MarzanoLanguage, NodeTypes, SortId, TSLanguage};
use grit_util::Language;
use marzano_util::node_with_source::NodeWithSource;
use std::sync::OnceLock;

static NODE_TYPES_STRING: &str =
include_str!("../../../resources/node-types/kotlin-node-types.json");
static NODE_TYPES: OnceLock<Vec<Vec<Field>>> = OnceLock::new();
static LANGUAGE: OnceLock<TSLanguage> = OnceLock::new();

#[cfg(not(feature = "builtin-parser"))]
fn language() -> TSLanguage {
unimplemented!(
"tree-sitter parser must be initialized before use when [builtin-parser] is off."
)
}
#[cfg(feature = "builtin-parser")]
fn language() -> TSLanguage {
tree_sitter_kotlin::language().into()
}

#[derive(Debug, Clone, Copy)]
pub struct Kotlin {
node_types: &'static [Vec<Field>],
metavariable_sort: SortId,
comment_sorts: [SortId; 2],
language: &'static TSLanguage,
}

impl NodeTypes for Kotlin {
fn node_types(&self) -> &[Vec<Field>] {
self.node_types
}
}

impl Kotlin {
pub(crate) fn new(lang: Option<TSLanguage>) -> Self {
let language = LANGUAGE.get_or_init(|| lang.unwrap_or_else(language));
let node_types = NODE_TYPES.get_or_init(|| fields_for_nodes(language, NODE_TYPES_STRING));
let metavariable_sort = language.id_for_node_kind("grit_metavariable", true);
let comment_sorts = [
language.id_for_node_kind("line_comment", true),
language.id_for_node_kind("multiline_comment", true),
];
Self {
node_types,
metavariable_sort,
comment_sorts,
language,
}
}
pub(crate) fn is_initialized() -> bool {
LANGUAGE.get().is_some()
}
}
impl Language for Kotlin {
use_marzano_delegate!();

fn language_name(&self) -> &'static str {
"Kotlin"
}

fn snippet_context_strings(&self) -> &[(&'static str, &'static str)] {
&[
("", ""),
("import ", ""),
("val GRIT_VAR = ", ""),
("const val GRIT_VAR = ", ""),
("class GRIT_CLASS { ", " }"),
("class GRIT_CLASS { ", " fun GRIT_FUNCTION() {} }"),
("GRIT_FN(", ") {}"),
("fun GRIT_FN(", ") {}"),
("fun GRIT_FN(GRIT_ARG:", ") {}"),
]
}
}

impl<'a> MarzanoLanguage<'a> for Kotlin {
fn get_ts_language(&self) -> &TSLanguage {
self.language
}

fn is_comment_sort(&self, id: SortId) -> bool {
self.comment_sorts.contains(&id)
}

fn metavariable_sort(&self) -> SortId {
self.metavariable_sort
}
}

#[cfg(test)]
mod tests {
use crate::language::nodes_from_indices;

use super::*;

#[test]
fn pair_snippet() {
let snippet = "import kotlin.math.PI";
let lang = Kotlin::new(None);
let snippets = lang.parse_snippet_contexts(snippet);
let nodes = nodes_from_indices(&snippets);
println!("{:?}", nodes);
assert!(!nodes.is_empty());
}
}
1 change: 1 addition & 0 deletions crates/language/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ pub mod java;
pub mod javascript;
mod js_like;
pub mod json;
pub mod kotlin;
pub mod language;
pub mod markdown_block;
pub mod markdown_inline;
Expand Down
12 changes: 12 additions & 0 deletions crates/language/src/target_language.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use crate::{
java::Java,
javascript::JavaScript,
json::Json,
kotlin::Kotlin,
language::{
Field, FieldId, LeafEquivalenceClass, MarzanoLanguage, NodeTypes, SortId, TSLanguage, Tree,
},
Expand Down Expand Up @@ -58,6 +59,7 @@ pub enum PatternLanguage {
Css,
Json,
Java,
Kotlin,
CSharp,
Python,
MarkdownBlock,
Expand Down Expand Up @@ -86,6 +88,7 @@ impl fmt::Display for PatternLanguage {
PatternLanguage::Css => write!(f, "css"),
PatternLanguage::Json => write!(f, "json"),
PatternLanguage::Java => write!(f, "java"),
PatternLanguage::Kotlin => write!(f, "kotlin"),
PatternLanguage::CSharp => write!(f, "csharp"),
PatternLanguage::Python => write!(f, "python"),
PatternLanguage::MarkdownBlock => write!(f, "markdown"),
Expand Down Expand Up @@ -122,6 +125,7 @@ impl ValueEnum for PatternLanguage {
Self::Css,
Self::Json,
Self::Java,
Self::Kotlin,
Self::CSharp,
Self::Python,
Self::MarkdownBlock,
Expand Down Expand Up @@ -221,6 +225,7 @@ impl PatternLanguage {
"css" => Some(Self::Css),
"json" => Some(Self::Json),
"java" => Some(Self::Java),
"kotlin" => Some(Self::Kotlin),
"csharp" => Some(Self::CSharp),
"markdown" => match flavor {
Some("block") => Some(Self::MarkdownBlock),
Expand Down Expand Up @@ -286,6 +291,7 @@ impl PatternLanguage {
PatternLanguage::Css => &["css", "vue"],
PatternLanguage::Json => &["json"],
PatternLanguage::Java => &["java"],
PatternLanguage::Kotlin => &["kt", "kts"],
PatternLanguage::CSharp => &["cs"],
PatternLanguage::Python => &["py", "pyi", "ipynb"],
PatternLanguage::MarkdownBlock => &["md", "mdx", "mdoc"],
Expand Down Expand Up @@ -314,6 +320,7 @@ impl PatternLanguage {
PatternLanguage::Css => Some("css"),
PatternLanguage::Json => Some("json"),
PatternLanguage::Java => Some("java"),
PatternLanguage::Kotlin => Some("kt"),
PatternLanguage::CSharp => Some("cs"),
PatternLanguage::Python => Some("py"),
PatternLanguage::MarkdownBlock => Some("md"),
Expand Down Expand Up @@ -341,6 +348,7 @@ impl PatternLanguage {
"css" => Some(Self::Css),
"json" => Some(Self::Json),
"java" => Some(Self::Java),
"kt" | "kts" => Some(Self::Kotlin),
"cs" => Some(Self::CSharp),
"ipynb" => Some(Self::Python),
"py" | "pyi" => Some(Self::Python),
Expand Down Expand Up @@ -382,6 +390,7 @@ impl PatternLanguage {
PatternLanguage::Html => Ok(TargetLanguage::Html(Html::new(Some(lang)))),
PatternLanguage::Css => Ok(TargetLanguage::Css(Css::new(Some(lang)))),
PatternLanguage::Json => Ok(TargetLanguage::Json(Json::new(Some(lang)))),
PatternLanguage::Kotlin => Ok(TargetLanguage::Kotlin(Kotlin::new(Some(lang)))),
PatternLanguage::Java => Ok(TargetLanguage::Java(Java::new(Some(lang)))),
PatternLanguage::CSharp => Ok(TargetLanguage::CSharp(CSharp::new(Some(lang)))),
PatternLanguage::Python => Ok(TargetLanguage::Python(Python::new(Some(lang)))),
Expand Down Expand Up @@ -741,6 +750,7 @@ generate_target_language! {
Css,
Json,
Java,
Kotlin,
CSharp,
Python,
MarkdownBlock,
Expand Down Expand Up @@ -768,6 +778,7 @@ impl fmt::Display for TargetLanguage {
TargetLanguage::Css(_) => write!(f, "css"),
TargetLanguage::Json(_) => write!(f, "json"),
TargetLanguage::Java(_) => write!(f, "java"),
TargetLanguage::Kotlin(_) => write!(f, "kotlin"),
TargetLanguage::CSharp(_) => write!(f, "csharp"),
TargetLanguage::Python(_) => write!(f, "python"),
TargetLanguage::MarkdownBlock(_) => write!(f, "markdown"),
Expand Down Expand Up @@ -817,6 +828,7 @@ impl TargetLanguage {
TargetLanguage::CSharp(_)
| TargetLanguage::Go(_)
| TargetLanguage::Java(_)
| TargetLanguage::Kotlin(_)
| TargetLanguage::JavaScript(_)
| TargetLanguage::Json(_)
| TargetLanguage::Rust(_)
Expand Down
2 changes: 1 addition & 1 deletion resources/add_language.py
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ def main(args: Namespace):
1. patch the metavariable grammar to include $.grit_metavariable anywhere we want to substitute a metavariable
2. add `tree-sitter-{language}` to crates/language/Cargo.toml [dependencies] and [features.builtin-parser]
3. add `pub mod {language};` to crates/language/src/lib.rs
4. add `use crate::{language}::{language_title_case}` to crates/language/src/target_language.rs
4. add `use crate::{language}::{language_title_case}` to crates/language/src/target_language.rs and add it to all enums and match statements
5. test cases for {language} in crates/core/src/test.rs
""")

Expand Down
6 changes: 3 additions & 3 deletions resources/edit_grammars.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -52,16 +52,16 @@ const allLanguages = [
"json",
"kotlin",
"markdown",
"php",
"python",
"ruby",
"rust",
"solidity",
"sql",
"typescript",
"yaml",
"toml",
"typescript",
"vue",
"php",
"yaml",
];

// For these languages, copyMvGrammar is optional
Expand Down

0 comments on commit 07f0922

Please sign in to comment.