Skip to content

Commit f758845

Browse files
committed
rust: semantic module got comments
1 parent 2da6d29 commit f758845

File tree

4 files changed

+104
-22
lines changed

4 files changed

+104
-22
lines changed

rust/semantic/src/tools/combinators.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@
2020
use crate::{Meaning, RecognitionResult, Tool};
2121
use intercept::ipc::Execution;
2222

23+
/// Represents a set of tools, where any of them can recognize the semantic.
24+
/// The evaluation is done in the order of the tools. The first one which
25+
/// recognizes the semantic will be returned as result.
2326
pub struct Any {
2427
tools: Vec<Box<dyn Tool>>,
2528
}
@@ -31,7 +34,6 @@ impl Any {
3134
}
3235

3336
impl Tool for Any {
34-
/// Any of the tool recognize the semantic, will be returned as result.
3537
fn recognize(&self, x: &Execution) -> RecognitionResult {
3638
for tool in &self.tools {
3739
match tool.recognize(x) {

rust/semantic/src/tools/generic.rs

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -16,30 +16,33 @@
1616
You should have received a copy of the GNU General Public License
1717
along with this program. If not, see <http://www.gnu.org/licenses/>.
1818
*/
19-
20-
use std::path::{Path, PathBuf};
19+
use std::collections::HashSet;
20+
use std::path::PathBuf;
2121
use std::vec;
2222

2323
use super::super::{CompilerPass, Meaning, RecognitionResult, Tool};
2424
use super::matchers::source::looks_like_a_source_file;
2525
use intercept::ipc::Execution;
2626

27+
/// A tool to recognize a compiler by executable name.
2728
pub struct Generic {
28-
pub executable: PathBuf,
29+
executables: HashSet<PathBuf>,
2930
}
3031

3132
impl Generic {
32-
pub fn new(compiler: &Path) -> Box<dyn Tool> {
33-
Box::new(Self {
34-
executable: compiler.to_path_buf(),
35-
})
33+
pub fn from(compilers: &[PathBuf]) -> Box<dyn Tool> {
34+
let executables = compilers.iter().map(|compiler| compiler.clone()).collect();
35+
Box::new(Self { executables })
3636
}
3737
}
3838

3939
impl Tool for Generic {
40-
/// Any of the tool recognize the semantic, will be returned as result.
40+
/// This tool is a naive implementation only considering:
41+
/// - the executable name,
42+
/// - one of the arguments is a source file,
43+
/// - the rest of the arguments are flags.
4144
fn recognize(&self, x: &Execution) -> RecognitionResult {
42-
if x.executable == self.executable {
45+
if self.executables.contains(&x.executable) {
4346
let mut flags = vec![];
4447
let mut sources = vec![];
4548

@@ -80,7 +83,7 @@ mod test {
8083

8184
use lazy_static::lazy_static;
8285

83-
use crate::vec_of_strings;
86+
use crate::{vec_of_pathbuf, vec_of_strings};
8487

8588
use super::*;
8689

@@ -145,7 +148,7 @@ mod test {
145148

146149
lazy_static! {
147150
static ref SUT: Generic = Generic {
148-
executable: PathBuf::from("/usr/bin/something"),
151+
executables: vec_of_pathbuf!["/usr/bin/something"].into_iter().collect()
149152
};
150153
}
151154
}

rust/semantic/src/tools/ignore.rs

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ use std::path::PathBuf;
2323
use super::super::{Meaning, RecognitionResult, Tool};
2424
use intercept::ipc::Execution;
2525

26+
/// A tool to ignore a command execution by executable name.
2627
pub struct IgnoreByPath {
2728
executables: HashSet<PathBuf>,
2829
}
@@ -39,6 +40,7 @@ impl IgnoreByPath {
3940
}
4041
}
4142

43+
/// A tool to ignore a command execution by arguments.
4244
impl Tool for IgnoreByPath {
4345
fn recognize(&self, execution: &Execution) -> RecognitionResult {
4446
if self.executables.contains(&execution.executable) {
@@ -193,7 +195,7 @@ mod test {
193195
use super::*;
194196

195197
#[test]
196-
fn test_unix_tools_are_recognized() {
198+
fn test_executions_are_ignored_by_executable_name() {
197199
let input = Execution {
198200
executable: PathBuf::from("/usr/bin/ls"),
199201
arguments: vec_of_strings!["ls", "/home/user/build"],
@@ -221,5 +223,20 @@ mod test {
221223
assert_eq!(RecognitionResult::NotRecognized, sut.recognize(&input))
222224
}
223225

224-
// TODO: implement test cases for args
226+
#[test]
227+
fn test_executions_are_ignored_by_args() {
228+
let input = Execution {
229+
executable: PathBuf::from("/usr/bin/ls"),
230+
arguments: vec_of_strings!["ls", "-l", "/home/user/build"],
231+
working_dir: PathBuf::from("/home/user"),
232+
environment: HashMap::new(),
233+
};
234+
// let sut = IgnoreByArgs::new(&["-l".to_string()]);
235+
let sut = IgnoreByArgs::new(&vec_of_strings!("-l"));
236+
237+
assert_eq!(
238+
RecognitionResult::Recognized(Ok(Meaning::Ignored)),
239+
sut.recognize(&input)
240+
)
241+
}
225242
}

rust/semantic/src/tools/mod.rs

Lines changed: 68 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -30,40 +30,42 @@ mod generic;
3030
mod ignore;
3131
mod matchers;
3232

33+
/// A builder for creating a tool which can recognize the semantic of a compiler,
34+
/// or ignore known non-compilers.
3335
pub struct Builder {
3436
tools: Vec<Box<dyn Tool>>,
3537
}
3638

37-
// TODO: write unit test for this!!!
3839
impl Builder {
40+
/// Creates a new builder with default settings.
3941
pub fn new() -> Self {
40-
// FIXME: replace this with gcc, when it's implemented
41-
let gcc = PathBuf::from("/usr/bin/g++");
42+
// FIXME: replace generic with gcc, when it's implemented
4243
Builder {
4344
tools: vec![
4445
// ignore executables which are not compilers,
4546
IgnoreByPath::new(),
4647
// recognize default compiler
47-
Generic::new(gcc.as_path()),
48+
Generic::from(&[PathBuf::from("/usr/bin/g++")]),
4849
],
4950
}
5051
}
5152

53+
/// Factory method to create a new tool from the builder.
5254
pub fn build(self) -> impl Tool {
5355
Any::new(self.tools)
5456
}
5557

58+
/// Adds new tools to recognize as compilers by executable name.
5659
pub fn compilers_to_recognize(mut self, compilers: &[PathBuf]) -> Self {
5760
if !compilers.is_empty() {
5861
// Add the new compilers at the end of the tools.
59-
for compiler in compilers {
60-
let tool = Generic::new(compiler);
61-
self.tools.push(tool);
62-
}
62+
let tool = Generic::from(compilers);
63+
self.tools.push(tool);
6364
}
6465
self
6566
}
6667

68+
/// Adds new tools to recognize as non-compilers by executable names.
6769
pub fn compilers_to_exclude(mut self, compilers: &[PathBuf]) -> Self {
6870
if !compilers.is_empty() {
6971
// Add these new compilers at the front of the tools.
@@ -73,6 +75,7 @@ impl Builder {
7375
self
7476
}
7577

78+
/// Adds new tools to recognize as non-compilers by arguments.
7679
pub fn compilers_to_exclude_by_arguments(mut self, args: &[String]) -> Self {
7780
if !args.is_empty() {
7881
// Add these new compilers at the front of the tools.
@@ -82,3 +85,60 @@ impl Builder {
8285
self
8386
}
8487
}
88+
89+
#[cfg(test)]
90+
mod test {
91+
use std::collections::HashMap;
92+
use std::path::PathBuf;
93+
94+
use super::super::{vec_of_pathbuf, vec_of_strings};
95+
use super::super::{Meaning, RecognitionResult};
96+
use super::*;
97+
use intercept::ipc::Execution;
98+
99+
#[test]
100+
fn test_builder() {
101+
let sut = Builder::new().build();
102+
103+
let input = any_execution();
104+
match sut.recognize(&input) {
105+
RecognitionResult::Recognized(Ok(Meaning::Compiler { .. })) => assert!(true),
106+
_ => assert!(false),
107+
}
108+
}
109+
110+
#[test]
111+
fn test_builder_with_compilers_to_exclude() {
112+
let compilers = vec_of_pathbuf!["/usr/bin/g++"];
113+
let sut = Builder::new().compilers_to_exclude(&compilers).build();
114+
115+
let input = any_execution();
116+
match sut.recognize(&input) {
117+
RecognitionResult::Recognized(Ok(Meaning::Ignored)) => assert!(true),
118+
_ => assert!(false),
119+
}
120+
}
121+
122+
#[test]
123+
fn test_builder_with_compilers_to_exclude_by_arguments() {
124+
let args = vec_of_strings!["-c"];
125+
let sut = Builder::new()
126+
.compilers_to_exclude_by_arguments(&args)
127+
.build();
128+
129+
let input = any_execution();
130+
match sut.recognize(&input) {
131+
RecognitionResult::Recognized(Ok(Meaning::Ignored)) => assert!(true),
132+
_ => assert!(false),
133+
}
134+
}
135+
136+
fn any_execution() -> Execution {
137+
Execution {
138+
executable: PathBuf::from("/usr/bin/g++"),
139+
arguments: vec_of_strings!["g++", "-c", "main.cpp"],
140+
environment: HashMap::new(),
141+
working_dir: PathBuf::from("/home/user"),
142+
}
143+
}
144+
}

0 commit comments

Comments
 (0)