pub struct Detector<'a> { /* private fields */ }Expand description
Searches a database for functions similar to checked ones.
§Examples
let original = br#"class Search {
static int find(int[] values, int key) {
int low = 0, high = values.length - 1;
while (low <= high) {
int mid = (low + high) >>> 1;
if (values[mid] < key) low = mid + 1;
else if (values[mid] > key) high = mid - 1;
else return mid;
}
return -(low + 1);
}
}"#;
let package = PackageInfo {
ecosystem: "maven".into(),
name: "org.example:search".into(),
version: "1.0".into(),
..PackageInfo::default()
};
let stored = extract_bytes("Search.java".as_ref(), Language::Java, original, &config).unwrap();
db.index(&package, &[stored]).unwrap();
// The same code with other names.
let copy = String::from_utf8_lossy(original)
.replace("Search", "Finder").replace("values", "xs").replace("key", "target");
let checked = extract_bytes("Finder.java".as_ref(), Language::Java, copy.as_bytes(), &config).unwrap();
let detector = Detector::new(&db, Options { min_tokens: 20, ..Options::default() }).unwrap();
let reports = detector.detect(&[checked], |_, _| true).unwrap();
assert_eq!(reports[0].name, "find");
assert_eq!(reports[0].candidates[0].kind, MatchKind::Exact(pelicode_core::Level::N1));
assert_eq!(reports[0].candidates[0].occurrences[0].package, "org.example:search");Implementations§
Source§impl<'a> Detector<'a>
impl<'a> Detector<'a>
Sourcepub fn new(db: &'a Database, options: Options) -> Result<Detector<'a>>
pub fn new(db: &'a Database, options: Options) -> Result<Detector<'a>>
db must have been opened for features computed like the checked ones
(see Database::config_from_meta).
§Errors
Error when the database cannot be read.
§Examples
use pelicode_core::Config;
use pelicode_db::Database;
use pelicode_detect::{Detector, Options};
let dir = tempfile::tempdir().unwrap();
let db = Database::open(dir.path().join("pelicode.db"), &Config::default()).unwrap();
let detector = Detector::new(&db, Options::default()).unwrap();Sourcepub fn excluded_as_dependencies(&self) -> usize
pub fn excluded_as_dependencies(&self) -> usize
Number of candidates left out so far because they were found only in
Options::dependencies.
§Examples
use pelicode_core::{Config, Language, extract_bytes};
use pelicode_db::{Database, PackageInfo};
use pelicode_detect::{Detector, Options, dependencies::Dependencies};
let dir = tempfile::tempdir().unwrap();
let config = Config { min_tokens: 0, ..Config::default() };
let mut db = Database::open(dir.path().join("pelicode.db"), &config).unwrap();
let source = b"def total(xs):\n s = 0\n for x in xs:\n s += x * 2\n return s\n";
let file = extract_bytes("calc.py".as_ref(), Language::Python, source, &config).unwrap();
let package = PackageInfo {
ecosystem: "pypi".into(), name: "calc".into(), version: "1.0".into(), ..PackageInfo::default()
};
db.index(&package, &[file.clone()]).unwrap();
// The checked project depends on calc.
let mut dependencies = Dependencies::default();
dependencies.add_file("requirements.txt", "calc>=1\n");
let options = Options { min_tokens: 0, dependencies, ..Options::default() };
let detector = Detector::new(&db, options).unwrap();
assert!(detector.detect(&[file], |_, _| true).unwrap().is_empty());
assert_eq!(detector.excluded_as_dependencies(), 1);Sourcepub fn detect(
&self,
files: &[FileFeatures],
select: impl Fn(&FileFeatures, &FunctionFeatures) -> bool,
) -> Result<Vec<Report>>
pub fn detect( &self, files: &[FileFeatures], select: impl Fn(&FileFeatures, &FunctionFeatures) -> bool, ) -> Result<Vec<Report>>
Checks the functions of files accepted by select; only functions
with at least one candidate are reported.
§Errors
Error when the database cannot be read.
§Examples
Only the functions accepted by select are checked, here those starting
after line 1:
let original = br#"class Search {
static int find(int[] values, int key) {
int low = 0, high = values.length - 1;
while (low <= high) {
int mid = (low + high) >>> 1;
if (values[mid] < key) low = mid + 1;
else if (values[mid] > key) high = mid - 1;
else return mid;
}
return -(low + 1);
}
}"#;
let package = PackageInfo {
ecosystem: "maven".into(),
name: "org.example:search".into(),
version: "1.0".into(),
..PackageInfo::default()
};
let stored = extract_bytes("Search.java".as_ref(), Language::Java, original, &config).unwrap();
db.index(&package, &[stored]).unwrap();
// The same code with other names.
let copy = String::from_utf8_lossy(original)
.replace("Search", "Finder").replace("values", "xs").replace("key", "target");
let checked = extract_bytes("Finder.java".as_ref(), Language::Java, copy.as_bytes(), &config).unwrap();
let detector = Detector::new(&db, Options { min_tokens: 20, ..Options::default() }).unwrap();
let reports = detector.detect(&[checked], |_, f| f.start_line > 1).unwrap();
assert_eq!(reports.len(), 1);Sourcepub fn candidates(&self, function: &FunctionFeatures) -> Result<Vec<Candidate>>
pub fn candidates(&self, function: &FunctionFeatures) -> Result<Vec<Candidate>>
Candidates for one function, best first.
Unlike Detector::detect, the function is checked whatever its size.
§Errors
Error when the database cannot be read.
§Examples
let original = br#"class Search {
static int find(int[] values, int key) {
int low = 0, high = values.length - 1;
while (low <= high) {
int mid = (low + high) >>> 1;
if (values[mid] < key) low = mid + 1;
else if (values[mid] > key) high = mid - 1;
else return mid;
}
return -(low + 1);
}
}"#;
let package = PackageInfo {
ecosystem: "maven".into(),
name: "org.example:search".into(),
version: "1.0".into(),
..PackageInfo::default()
};
let stored = extract_bytes("Search.java".as_ref(), Language::Java, original, &config).unwrap();
db.index(&package, &[stored]).unwrap();
// The same code with other names.
let copy = String::from_utf8_lossy(original)
.replace("Search", "Finder").replace("values", "xs").replace("key", "target");
let checked = extract_bytes("Finder.java".as_ref(), Language::Java, copy.as_bytes(), &config).unwrap();
let detector = Detector::new(&db, Options::default()).unwrap();
let candidates = detector.candidates(&checked.functions[0]).unwrap();
assert_eq!(candidates[0].similarity, 1.0);
assert_eq!(candidates[0].function.name, "find");Auto Trait Implementations§
impl<'a> !Freeze for Detector<'a>
impl<'a> !RefUnwindSafe for Detector<'a>
impl<'a> !Send for Detector<'a>
impl<'a> !Sync for Detector<'a>
impl<'a> !UnwindSafe for Detector<'a>
impl<'a> Unpin for Detector<'a>
impl<'a> UnsafeUnpin for Detector<'a>
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
Converts
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
Converts
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more