Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions mdsf/src/filetype/generated_file_types.rs

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ibfeel like this file is out the svope of this PR

Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,7 @@ pub fn language_to_ext(language: &str) -> Option<&'static str> {
"fortran free form" => Some(".f90"),
"fortran" => Some(".f"),
"foxpro" => Some(".prg"),
"fpp" => Some(".fpp"),
"freebasic" => Some(".bi"),
"freemarker" => Some(".ftl"),
"frege" => Some(".fr"),
Expand Down Expand Up @@ -851,6 +852,7 @@ pub fn language_to_ext(language: &str) -> Option<&'static str> {
"qsharp" => Some(".qs"),
"qt script" => Some(".qs"),
"quakec" => Some(".qc"),
"quartus simulation ip" => Some(".sip"),
"quickbasic" => Some(".bas"),
"quint" => Some(".qnt"),
"r" => Some(".r"),
Expand Down Expand Up @@ -888,6 +890,7 @@ pub fn language_to_ext(language: &str) -> Option<&'static str> {
"restructuredtext" => Some(".rst"),
"rexx" => Some(".rexx"),
"rez" => Some(".r"),
"rhai" => Some(".rhai"),
"rhtml" => Some(".erb"),
"rich text format" => Some(".rtf"),
"ring" => Some(".ring"),
Expand Down Expand Up @@ -946,6 +949,7 @@ pub fn language_to_ext(language: &str) -> Option<&'static str> {
"shen" => Some(".shen"),
"sieve" => Some(".sieve"),
"simple file verification" => Some(".sfv"),
"sip" => Some(".sip"),
"slang" => Some(".slang"),
"slash" => Some(".sl"),
"slice" => Some(".ice"),
Expand Down Expand Up @@ -1085,6 +1089,8 @@ pub fn language_to_ext(language: &str) -> Option<&'static str> {
"vento" => Some(".vto"),
"verilog" => Some(".v"),
"verse" => Some(".verse"),
"vespa schema definition" => Some(".sd"),
"vespa" => Some(".sd"),
"vhdl" => Some(".vhdl"),
"vhs" => Some(".tape"),
"vim help file" => Some(".txt"),
Expand Down Expand Up @@ -1520,6 +1526,7 @@ mod test_language_to_ext {
("fortran free form", ".f90"),
("fortran", ".f"),
("foxpro", ".prg"),
("fpp", ".fpp"),
("freebasic", ".bi"),
("freemarker", ".ftl"),
("frege", ".fr"),
Expand Down Expand Up @@ -2035,6 +2042,7 @@ mod test_language_to_ext {
("qsharp", ".qs"),
("qt script", ".qs"),
("quakec", ".qc"),
("quartus simulation ip", ".sip"),
("quickbasic", ".bas"),
("quint", ".qnt"),
("r", ".r"),
Expand Down Expand Up @@ -2072,6 +2080,7 @@ mod test_language_to_ext {
("restructuredtext", ".rst"),
("rexx", ".rexx"),
("rez", ".r"),
("rhai", ".rhai"),
("rhtml", ".erb"),
("rich text format", ".rtf"),
("ring", ".ring"),
Expand Down Expand Up @@ -2130,6 +2139,7 @@ mod test_language_to_ext {
("shen", ".shen"),
("sieve", ".sieve"),
("simple file verification", ".sfv"),
("sip", ".sip"),
("slang", ".slang"),
("slash", ".sl"),
("slice", ".ice"),
Expand Down Expand Up @@ -2269,6 +2279,8 @@ mod test_language_to_ext {
("vento", ".vto"),
("verilog", ".v"),
("verse", ".verse"),
("vespa schema definition", ".sd"),
("vespa", ".sd"),
("vhdl", ".vhdl"),
("vhs", ".tape"),
("vim help file", ".txt"),
Expand Down
56 changes: 54 additions & 2 deletions mdsf/src/parser/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,17 +32,39 @@ pub fn parse_generic_codeblock(lines: &mut Enumerate<Lines>) -> (bool, String, u
pub fn parse_go_codeblock(lines: &mut Enumerate<Lines>) -> (bool, String, usize) {
let (is_snippet, mut code_snippet, snippet_lines) = parse_generic_codeblock(lines);

if is_snippet && !GO_PACKAGE_RE.is_match(&code_snippet) {
if is_snippet && !has_go_package(&code_snippet) {
code_snippet.insert_str(0, GO_TEMPORARY_PACKAGE_NAME);
}

(is_snippet, code_snippet, snippet_lines)
}

// TODO: check for multiline comments
pub static GO_PACKAGE_RE: std::sync::LazyLock<Regex> =
std::sync::LazyLock::new(|| Regex::new(r"^\s*package\s+\w").unwrap());

/// A Go package clause is the first token of a file that is neither a comment
/// nor whitespace, so leading comments are skipped before looking for it.
#[inline]
pub fn has_go_package(snippet: &str) -> bool {
let mut rest = snippet.trim_start();

loop {
if let Some(after) = rest.strip_prefix("//") {
rest = after
.split_once('\n')
.map_or("", |(_, tail)| tail)
.trim_start();
} else if let Some(after) = rest.strip_prefix("/*") {
rest = after
.split_once("*/")
.map_or("", |(_, tail)| tail)
.trim_start();
} else {
return GO_PACKAGE_RE.is_match(rest);
}
}
}

#[inline]
pub fn remove_go_package(snippet: String) -> String {
if snippet.contains(GO_TEMPORARY_PACKAGE_NAME) {
Expand Down Expand Up @@ -99,3 +121,33 @@ mod test_go_package_re {
}
}
}

#[cfg(test)]
mod test_has_go_package {
use crate::parser::has_go_package;

#[test]
fn it_should_match() {
for s in [
"package mdsf",
"// mdsf.go\npackage mdsf",
"//go:build integration\n\npackage mdsf",
"// mdsf.go\n// second line\npackage mdsf",
"/*\nI like my\npackage manager\n*/\npackage mdsf",
] {
assert!(has_go_package(s), "'{s}' did not match");
}
}

#[test]
fn it_should_not_match() {
for s in [
"const foo = 1",
"// package mdsf",
"// mdsf.go\nconst foo = 1",
"/*\nI like my\npackage manager\n*/\n\nconst foo = 1",
] {
assert!(!has_go_package(s), "'{s}' matched");
}
}
}