Skip to content

Commit 84bb60b

Browse files
committed
Merge branch 'fix-metasyntax'
2 parents 0f9345b + 5dfa32c commit 84bb60b

File tree

1 file changed

+70
-11
lines changed

1 file changed

+70
-11
lines changed

tmc-langs-framework/src/domain/meta_syntax.rs

Lines changed: 70 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use std::io::{BufRead, BufReader, Read};
1010
lazy_static! {
1111
static ref META_SYNTAXES_C: [MetaSyntax; 2] = [
1212
MetaSyntax::new("//", None),
13-
MetaSyntax::new("/\\*", Some("\\*/"))
13+
MetaSyntax::new(r"/\*", Some(r"\*/"))
1414
];
1515
static ref META_SYNTAXES_HTML: [MetaSyntax; 1] = [MetaSyntax::new("<!--", Some("-->"))];
1616
static ref META_SYNTAXES_PY: [MetaSyntax; 1] = [MetaSyntax::new("#", None)];
@@ -47,29 +47,30 @@ struct MetaSyntax {
4747
impl MetaSyntax {
4848
fn new(comment_start: &'static str, comment_end: Option<&'static str>) -> Self {
4949
// comment patterns
50-
let comment_start_pattern = format!("^(\\s*){}\\s*", comment_start);
50+
let comment_start_pattern = format!(r"^(\s*){}\s*", comment_start);
5151
let comment_end_pattern = match comment_end {
52-
Some(s) => format!("(.*){}\\s*", s),
52+
Some(s) => format!(r"(.*){}\s*", s),
5353
None => "(.*)".to_string(),
5454
};
5555

5656
// annotation patterns
5757
let solution_file = Regex::new(&format!(
58-
"{}SOLUTION\\s+FILE{}",
58+
r"{}SOLUTION\s+FILE{}",
5959
comment_start_pattern, comment_end_pattern
6060
))
6161
.unwrap();
6262
let solution_begin = Regex::new(&format!(
63-
"{}BEGIN\\s+SOLUTION{}",
63+
r"{}BEGIN\s+SOLUTION{}",
6464
comment_start_pattern, comment_end_pattern
6565
))
6666
.unwrap();
6767
let solution_end = Regex::new(&format!(
68-
"{}END\\s+SOLUTION{}",
68+
r"{}END\s+SOLUTION{}",
6969
comment_start_pattern, comment_end_pattern
7070
))
7171
.unwrap();
72-
let stub_begin = Regex::new(&format!("{}STUB:\\s*", comment_start_pattern)).unwrap();
72+
let stub_begin =
73+
Regex::new(&format!(r"{}STUB:[\s&&[^\n]]*", comment_start_pattern)).unwrap();
7374
let stub_end = Regex::new(&comment_end_pattern).unwrap();
7475

7576
Self {
@@ -128,14 +129,20 @@ impl<B: BufRead> Iterator for MetaSyntaxParser<B> {
128129
// check for stub
129130
if self.in_stub.is_none() && meta_syntax.stub_begin.is_match(&s) {
130131
log::debug!("stub start: '{}'", s);
131-
// save the syntax that started the current stub
132-
self.in_stub = Some(meta_syntax);
133132
// remove stub start
134133
s = meta_syntax
135134
.stub_begin
136135
.replace(&s, |caps: &Captures| caps[1].to_string())
137136
.to_string();
138-
log::debug!("parsed: '{}'", s);
137+
138+
if s.trim().is_empty() && meta_syntax.stub_end.is_match(&s) {
139+
// empty oneliner stubs are replaced by a newline
140+
return Some(Ok(MetaString::Stub("\n".to_string())));
141+
}
142+
143+
// save the syntax that started the current stub
144+
self.in_stub = Some(meta_syntax);
145+
139146
if s.trim().is_empty() {
140147
// only metadata, skip
141148
return self.next();
@@ -154,7 +161,6 @@ impl<B: BufRead> Iterator for MetaSyntaxParser<B> {
154161
.stub_end
155162
.replace(&s, |caps: &Captures| caps[1].to_string())
156163
.to_string();
157-
log::debug!("parsed: '{}'", s);
158164
if s.trim().is_empty() {
159165
// only metadata, skip
160166
return self.next();
@@ -303,4 +309,57 @@ public class JavaTestCase {
303309
let actual = filter.map(|l| l.unwrap()).collect::<Vec<MetaString>>();
304310
assert_eq!(expected, actual);
305311
}
312+
313+
#[test]
314+
fn stube() {
315+
init();
316+
317+
const PYTHON_FILE_STUB: &str = r#"
318+
# BEGIN SOLUTION
319+
print("a")
320+
# END SOLUTION
321+
# KOMMENTTI
322+
#STUB:class Kauppalista:
323+
#STUB:def __init__(self):
324+
#STUB:self.tuotteet = []
325+
#STUB:
326+
#STUB:def tuotteita(self):
327+
#STUB:return len(self.tuotteet)
328+
#STUB:
329+
#STUB:def lisaa(self, tuote: str, maara: int):
330+
#STUB:self.tuotteet.append((tuote, maara))
331+
#STUB:
332+
#STUB:def tuote(self, n: int):
333+
#STUB:return self.tuotteet[n - 1][0]
334+
#STUB:
335+
#STUB:def maara(self, n:int):
336+
#STUB:return self.uotteet[n - 1][1]
337+
"#;
338+
339+
let expected: Vec<MetaString> = vec![
340+
MetaString::str("\n"),
341+
MetaString::solution("print(\"a\")\n"),
342+
MetaString::str("# KOMMENTTI\n"),
343+
MetaString::stub("class Kauppalista:\n"),
344+
MetaString::stub(" def __init__(self):\n"),
345+
MetaString::stub(" self.tuotteet = []\n"),
346+
MetaString::stub("\n"),
347+
MetaString::stub(" def tuotteita(self):\n"),
348+
MetaString::stub(" return len(self.tuotteet)\n"),
349+
MetaString::stub("\n"),
350+
MetaString::stub(" def lisaa(self, tuote: str, maara: int):\n"),
351+
MetaString::stub(" self.tuotteet.append((tuote, maara))\n"),
352+
MetaString::stub("\n"),
353+
MetaString::stub(" def tuote(self, n: int):\n"),
354+
MetaString::stub(" return self.tuotteet[n - 1][0]\n"),
355+
MetaString::stub("\n"),
356+
MetaString::stub(" def maara(self, n:int):\n"),
357+
MetaString::stub(" return self.uotteet[n - 1][1]\n"),
358+
];
359+
360+
let source = PYTHON_FILE_STUB.as_bytes();
361+
let filter = MetaSyntaxParser::new(source, "py");
362+
let actual = filter.map(|l| l.unwrap()).collect::<Vec<MetaString>>();
363+
assert_eq!(expected, actual);
364+
}
306365
}

0 commit comments

Comments
 (0)