Skip to content

Commit

Permalink
More documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
adpaco-aws committed Sep 20, 2024
1 parent 923e606 commit 812231e
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 35 deletions.
2 changes: 1 addition & 1 deletion tools/kani-cov/src/coverage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use std::{collections::BTreeMap, fmt::Display};
use std::{fmt, fs};
use tree_sitter::{Node, Parser};

pub type LineResults = Vec<Option<(u32, MarkerInfo)>>;
pub type LineResults = Vec<(usize, Option<(u32, MarkerInfo)>)>;

#[derive(Copy, Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "UPPERCASE")]
Expand Down
4 changes: 2 additions & 2 deletions tools/kani-cov/src/merge.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ pub fn merge_main(args: &MergeArgs) -> Result<()> {
Ok(())
}

// Validate arguments to the `merge` subcommand in addition to clap's
// validation.
/// Validate arguments to the `merge` subcommand in addition to clap's
/// validation.
pub fn validate_merge_args(_args: &MergeArgs) -> Result<()> {
// No validation is done at the moment
Ok(())
Expand Down
58 changes: 36 additions & 22 deletions tools/kani-cov/src/report.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ use std::{fs::File, io::BufReader, path::PathBuf};
use anyhow::Result;

use crate::args::ReportFormat;
use crate::coverage::{function_coverage_results, function_info_from_file, CovResult, MarkerInfo};
use crate::coverage::{
function_coverage_results, function_info_from_file, CovResult, LineResults, MarkerInfo,
};
use crate::summary::line_coverage_results;
use crate::{args::ReportArgs, coverage::CombinedCoverageResults};

Expand Down Expand Up @@ -41,13 +43,19 @@ pub fn report_main(args: &ReportArgs) -> Result<()> {
Ok(())
}

// Validate arguments to the `report` subcommand in addition to clap's
// validation.
/// Validate arguments to the `report` subcommand in addition to clap's
/// validation.
pub fn validate_report_args(_args: &ReportArgs) -> Result<()> {
// No validation is done at the moment
Ok(())
}

/// Checks the `format` argument for the `report` subcommand and selects to
/// another format if the one we are checking is not possible for any reason.
///
/// For example, if the `Terminal` format is specified but we are not writing to
/// a terminal, it will auto-select the `Escapes` format to avoid character
/// issues.
fn check_format(format: &ReportFormat) -> ReportFormat {
let is_terminal = std::io::stdout().is_terminal();
match format {
Expand All @@ -65,7 +73,7 @@ fn check_format(format: &ReportFormat) -> ReportFormat {
pub fn print_coverage_results(
format: &ReportFormat,
filepath: PathBuf,
results: Vec<Vec<(usize, Option<(u32, MarkerInfo)>)>>,
results: Vec<LineResults>,
) -> Result<()> {
let flattened_results: Vec<(usize, Option<(u32, MarkerInfo)>)> =
results.into_iter().flatten().collect();
Expand All @@ -89,10 +97,9 @@ pub fn print_coverage_results(
Some(max),
insert_escapes(&line, vec![(0, true), (line.len(), false)], format),
),
MarkerInfo::Markers(results) =>
// Note: I'm not sure why we need to offset the columns by -1
{
MarkerInfo::Markers(results) => {
// Filter out cases where the span is a single unit AND it ends after the line
// TODO: Create issue and link
let results: Vec<&CovResult> = results
.iter()
.filter(|m| {
Expand Down Expand Up @@ -120,7 +127,7 @@ pub fn print_coverage_results(
]
})
.collect();
// println!("COMPLETE: {complete_escapes:?}");

let mut starting_escapes: Vec<(usize, bool)> = results
.iter()
.filter(|m| {
Expand All @@ -130,20 +137,17 @@ pub fn print_coverage_results(
})
.flat_map(|m| vec![((m.region.start.1 - 1) as usize, true)])
.collect();
// println!("{starting_escapes:?}");

let mut ending_escapes: Vec<(usize, bool)> = results
.iter()
.filter(|m| {
m.times_covered == 0
&& m.region.start.0 as usize != idx
&& m.region.end.0 as usize == idx
})
.map(|m| vec![((m.region.end.1 - 1) as usize, false)])
.flatten()
.flat_map(|m| vec![((m.region.end.1 - 1) as usize, false)])
.collect();

// println!("{starting_escapes:?}");
// println!("{ending_escapes:?}");
if must_highlight && !ending_escapes.is_empty() {
ending_escapes.push((0_usize, true));
must_highlight = false;
Expand Down Expand Up @@ -194,22 +198,32 @@ pub fn print_coverage_results(
Ok(())
}

fn insert_escapes(str: &String, markers: Vec<(usize, bool)>, format: &ReportFormat) -> String {
let mut new_str = str.clone();
let mut offset = 0;

/// Inserts opening/closing escape strings into `str` given a set of `markers`.
/// Each marker is a tuple `(offset, type)` where:
/// * `offset` represents the offset in which the marker must be inserted, and
/// * `type` represents whether it is an opening (`true`) or closing (`false`)
/// escape.
/// The specific escape to be used are determined by the report format.
fn insert_escapes(str: &str, markers: Vec<(usize, bool)>, format: &ReportFormat) -> String {
// Determine the escape strings based on the format
let (open_escape, close_escape) = match format {
ReportFormat::Terminal => ("\x1b[41m", "\x1b[0m"),
ReportFormat::Escapes => ("```", "'''"),
};

let mut sym_markers: Vec<(&usize, &str)> =
let mut escape_markers: Vec<(&usize, &str)> =
markers.iter().map(|(i, b)| (i, if *b { open_escape } else { close_escape })).collect();
escape_markers.sort();

let mut escaped_str = str.to_owned();
let mut offset = 0;

sym_markers.sort();
for (i, b) in sym_markers {
new_str.insert_str(i + offset, b);
// Iteratively insert the escape strings into the original string
for (i, b) in escape_markers {
escaped_str.insert_str(i + offset, b);
// `offset` keeps track of the bytes we've already inserted so the original
// index is shifted by the appropriate amount in subsequent insertions.
offset += b.bytes().len();
}
new_str
escaped_str
}
22 changes: 12 additions & 10 deletions tools/kani-cov/src/summary.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,20 @@
// Copyright Kani Contributors
// SPDX-License-Identifier: Apache-2.0 OR MIT

use std::{cmp::max, fs::File, io::BufReader, path::PathBuf};
use std::{
cmp::max,
fs::File,
io::BufReader,
path::{Path, PathBuf},
};

use anyhow::Result;

use crate::{
args::{SummaryArgs, SummaryFormat},
coverage::{
function_coverage_results, function_info_from_file, CombinedCoverageResults, CovResult,
CoverageMetric, CoverageRegion, FileCoverageInfo, FunctionInfo, LineResults, MarkerInfo,
CoverageMetric, CoverageRegion, FileCoverageInfo, FunctionInfo, MarkerInfo,
},
};

Expand Down Expand Up @@ -52,10 +57,7 @@ pub fn summary_main(args: &SummaryArgs) -> Result<()> {
Ok(())
}

fn aggregate_cov_info(
file: &PathBuf,
file_cov_info: &Vec<FunctionCoverageResults>,
) -> FileCoverageInfo {
fn aggregate_cov_info(file: &Path, file_cov_info: &[FunctionCoverageResults]) -> FileCoverageInfo {
let total_functions = file_cov_info.len().try_into().unwrap();
let covered_functions =
file_cov_info.iter().filter(|f| f.is_covered).count().try_into().unwrap();
Expand Down Expand Up @@ -89,8 +91,8 @@ struct FunctionCoverageResults {
total_regions: u32,
}

// Validate arguments to the `summary` subcommand in addition to clap's
// validation.
/// Validate arguments to the `summary` subcommand in addition to clap's
/// validation.
pub fn validate_summary_args(_args: &SummaryArgs) -> Result<()> {
// No validation is done at the moment
Ok(())
Expand All @@ -113,8 +115,8 @@ pub fn validate_summary_args(_args: &SummaryArgs) -> Result<()> {
/// for the generation of coverage reports.
pub fn line_coverage_results(
info: &FunctionInfo,
fun_results: &Option<(String, Vec<crate::coverage::CovResult>)>,
) -> LineResults {
fun_results: &Option<(String, Vec<CovResult>)>,
) -> Vec<Option<(u32, MarkerInfo)>> {
let start_line: u32 = info.start.0.try_into().unwrap();
let end_line: u32 = info.end.0.try_into().unwrap();

Expand Down

0 comments on commit 812231e

Please sign in to comment.