Skip to content

Commit

Permalink
rust: interpreter factory method moved
Browse files Browse the repository at this point in the history
  • Loading branch information
rizsotto committed Dec 25, 2024
1 parent 0dcd3ea commit ecc1cae
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 43 deletions.
41 changes: 5 additions & 36 deletions rust/bear/src/modes/semantic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

use crate::intercept::Envelope;
use crate::output::OutputWriter;
use crate::semantic::interpreters::Builder;
use crate::semantic::transformation::Transformation;
use crate::semantic::Transform;
use crate::{args, config, semantic};
use anyhow::{anyhow, Context};
use path_absolutize::Absolutize;
Expand All @@ -14,55 +14,24 @@ use std::path::{Path, PathBuf};
/// The semantic analysis that is independent of the event source.
pub(super) struct SemanticAnalysisPipeline {
interpreter: Box<dyn semantic::Interpreter>,
transform: Transformation,
transform: Box<dyn semantic::Transform>,
output_writer: OutputWriterImpl,
}

impl SemanticAnalysisPipeline {
/// Create a new semantic mode instance.
pub(super) fn from(output: args::BuildSemantic, config: &config::Main) -> anyhow::Result<Self> {
let interpreter = Self::interpreter(config)?;
let interpreter = Builder::from(config);
let transform = Transformation::from(&config.output);
let output_writer = OutputWriterImpl::create(&output, &config.output)?;

Ok(Self {
interpreter,
transform,
interpreter: Box::new(interpreter),
transform: Box::new(transform),
output_writer,
})
}

/// Creates an interpreter to recognize the compiler calls.
///
/// Using the configuration we can define which compilers to include and exclude.
/// Also read the environment variables to detect the compiler to include (and
/// make sure those are not excluded either).
// TODO: Use the CC or CXX environment variables to detect the compiler to include.
// Use the CC or CXX environment variables and make sure those are not excluded.
// Make sure the environment variables are passed to the method.
// TODO: Move this method to the `semantic` module. (instead of expose the builder)
// TODO: Take environment variables as input.
fn interpreter(config: &config::Main) -> anyhow::Result<Box<dyn semantic::Interpreter>> {
let compilers_to_include = match &config.intercept {
config::Intercept::Wrapper { executables, .. } => executables.clone(),
_ => vec![],
};
let compilers_to_exclude = match &config.output {
config::Output::Clang { compilers, .. } => compilers
.iter()
.filter(|compiler| compiler.ignore == config::Ignore::Always)
.map(|compiler| compiler.path.clone())
.collect(),
_ => vec![],
};
let interpreter = semantic::interpreters::Builder::new()
.compilers_to_recognize(compilers_to_include.as_slice())
.compilers_to_exclude(compilers_to_exclude.as_slice())
.build();

Ok(Box::new(interpreter))
}

/// Consumer the envelopes for analysis and write the result to the output file.
/// This implements the pipeline of the semantic analysis.
pub(super) fn analyze_and_write(
Expand Down
40 changes: 34 additions & 6 deletions rust/bear/src/semantic/interpreters/mod.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
// SPDX-License-Identifier: GPL-3.0-or-later

use std::path::PathBuf;

use super::interpreters::combinators::Any;
use super::interpreters::generic::Generic;
use super::interpreters::ignore::IgnoreByPath;
use super::Interpreter;
use crate::config;
use std::path::PathBuf;

mod combinators;
mod gcc;
Expand All @@ -20,8 +20,36 @@ pub struct Builder {
}

impl Builder {
/// Creates an interpreter to recognize the compiler calls.
///
/// Using the configuration we can define which compilers to include and exclude.
/// Also read the environment variables to detect the compiler to include (and
/// make sure those are not excluded either).
// TODO: Use the CC or CXX environment variables to detect the compiler to include.
// Use the CC or CXX environment variables and make sure those are not excluded.
// Make sure the environment variables are passed to the method.
// TODO: Take environment variables as input.
pub fn from(config: &config::Main) -> impl Interpreter {
let compilers_to_include = match &config.intercept {
config::Intercept::Wrapper { executables, .. } => executables.clone(),
_ => vec![],
};
let compilers_to_exclude = match &config.output {
config::Output::Clang { compilers, .. } => compilers
.iter()
.filter(|compiler| compiler.ignore == config::Ignore::Always)
.map(|compiler| compiler.path.clone())
.collect(),
_ => vec![],
};
Builder::new()
.compilers_to_recognize(compilers_to_include.as_slice())
.compilers_to_exclude(compilers_to_exclude.as_slice())
.build()
}

/// Creates a new builder with default settings.
pub fn new() -> Self {
fn new() -> Self {
// FIXME: replace generic with gcc, when it's implemented
Builder {
interpreters: vec![
Expand All @@ -34,12 +62,12 @@ impl Builder {
}

/// Factory method to create a new tool from the builder.
pub fn build(self) -> impl Interpreter {
fn build(self) -> impl Interpreter {
Any::new(self.interpreters)
}

/// Adds new interpreters to recognize as compilers by executable name.
pub fn compilers_to_recognize(mut self, compilers: &[PathBuf]) -> Self {
fn compilers_to_recognize(mut self, compilers: &[PathBuf]) -> Self {
if !compilers.is_empty() {
// Add the new compilers at the end of the interpreters.
let tool = Generic::from(compilers);
Expand All @@ -49,7 +77,7 @@ impl Builder {
}

/// Adds new interpreters to recognize as non-compilers by executable names.
pub fn compilers_to_exclude(mut self, compilers: &[PathBuf]) -> Self {
fn compilers_to_exclude(mut self, compilers: &[PathBuf]) -> Self {
if !compilers.is_empty() {
// Add these new compilers at the front of the interpreters.
let tool = IgnoreByPath::from(compilers);
Expand Down
2 changes: 1 addition & 1 deletion rust/bear/src/semantic/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ impl<T> IntoIterator for Recognition<T> {
/// It conditionally removes compiler calls based on compiler names or flags.
/// It can also alter the compiler flags of the compiler calls. The actions
/// are defined in the configuration this module is given.
pub trait Transform {
pub trait Transform: Send {
fn apply(&self, _: CompilerCall) -> Option<CompilerCall>;
}

Expand Down

0 comments on commit ecc1cae

Please sign in to comment.