diff --git a/.taskcluster.yml b/.taskcluster.yml index 85864a9e8..f537d04c1 100644 --- a/.taskcluster.yml +++ b/.taskcluster.yml @@ -49,7 +49,7 @@ tasks: git -c advice.detachedHead=false checkout ${head_rev} && pip3 install --quiet pre-commit && pre-commit run -a --show-diff-on-failure && - cargo test" + cargo test --all --verbose --all-features" metadata: name: rust-code-analysis lint and test description: rust-code-analysis lint and test @@ -80,7 +80,7 @@ tasks: git clone --recursive --quiet ${repository} && cd rust-code-analysis && git -c advice.detachedHead=false checkout ${head_rev} && - cargo test && + cargo test --all --verbose --all-features && zip -0 ccov.zip `find . -name 'rust_code_analysis*.gc*' -print` && ../grcov ccov.zip -s . -t lcov --llvm --branch --ignore-not-existing --ignore '/*' -o lcov.info && bash <(curl -s https://codecov.io/bash) -f lcov.info" @@ -111,7 +111,7 @@ tasks: - git clone --recursive --quiet ${repository} - cd rust-code-analysis - git -c advice.detachedHead=false checkout ${head_rev} - - cargo test --verbose --all-features + - cargo test --all --verbose --all-features mounts: - content: url: https://win.rustup.rs/ diff --git a/Cargo.lock b/Cargo.lock index 3fa4899b1..d5018525c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1463,13 +1463,9 @@ dependencies = [ name = "rust-code-analysis" version = "0.0.16" dependencies = [ - "actix-rt", - "actix-web", "aho-corasick", - "bytes", "cc", "enum-iterator", - "futures", "fxhash", "json", "lazy_static", @@ -1493,11 +1489,17 @@ dependencies = [ name = "rust-code-analysis-cli" version = "0.0.1" dependencies = [ + "actix-rt", + "actix-web", + "bytes", "clap", "crossbeam", + "futures", "globset", "num_cpus", + "pretty_assertions", "rust-code-analysis", + "serde", "serde_json", "walkdir", ] diff --git a/Cargo.toml b/Cargo.toml index ec1223ff6..e0915d24c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,12 +10,8 @@ cc = "^1.0" phf_codegen = "^0.8" [dependencies] -actix-rt = "^1.0" -actix-web = "^2.0" aho-corasick = "^0.7" -bytes = "^0.5" enum-iterator = "^0.6" -futures = "^0.3" fxhash = "0.2" json = "^0.12" lazy_static = "^1.3" @@ -23,7 +19,7 @@ num-format = "^0.4" petgraph = "^0.5" phf = { version = "^0.8", features = ["macros"] } regex = "^1.1" -serde = "^1.0" +serde = { version = "^1.0", features = ["derive"] } serde_cbor = "^0.11" serde_json = "^1.0" termcolor = "^1.0" diff --git a/rust-code-analysis-cli/Cargo.toml b/rust-code-analysis-cli/Cargo.toml index 94810d7ce..06f7178c8 100644 --- a/rust-code-analysis-cli/Cargo.toml +++ b/rust-code-analysis-cli/Cargo.toml @@ -5,10 +5,18 @@ authors = ["Calixte Denizet "] edition = "2018" [dependencies] +actix-rt = "^1.0" +actix-web = "^2.0" +bytes = "^0.5" clap = "^2.33" crossbeam = "^0.7" +futures = "^0.3" globset = "^0.4" num_cpus = "^1.13" rust-code-analysis = { path = ".." } +serde = "^1.0" serde_json = "^1.0" walkdir = "^2.2" + +[dev-dependencies] +pretty_assertions = "^0.6" diff --git a/rust-code-analysis-cli/src/main.rs b/rust-code-analysis-cli/src/main.rs index 31f056e3d..2f2bc5907 100644 --- a/rust-code-analysis-cli/src/main.rs +++ b/rust-code-analysis-cli/src/main.rs @@ -2,8 +2,13 @@ extern crate clap; extern crate crossbeam; extern crate num_cpus; +#[macro_use] +extern crate serde; +#[cfg_attr(test, macro_use)] extern crate serde_json; +mod web; + use clap::{App, Arg}; use crossbeam::channel::{Receiver, Sender}; use crossbeam::crossbeam_channel::unbounded; @@ -16,8 +21,8 @@ use std::sync::{Arc, Mutex}; use std::{process, thread}; use walkdir::{DirEntry, WalkDir}; -use rust_code_analysis::web::server; use rust_code_analysis::*; +use web::server; #[derive(Debug)] struct Config { diff --git a/src/web/comment.rs b/rust-code-analysis-cli/src/web/comment.rs similarity index 90% rename from src/web/comment.rs rename to rust-code-analysis-cli/src/web/comment.rs index 43c7c387f..82129dfed 100644 --- a/src/web/comment.rs +++ b/rust-code-analysis-cli/src/web/comment.rs @@ -1,7 +1,6 @@ use serde::{Deserialize, Serialize}; -use crate::comment_rm::rm_comments; -use crate::traits::{Callback, TSParserTrait}; +use rust_code_analysis::{rm_comments, Callback, TSParserTrait}; #[derive(Debug, Deserialize, Serialize)] pub struct WebCommentPayload { diff --git a/src/web/function.rs b/rust-code-analysis-cli/src/web/function.rs similarity index 89% rename from src/web/function.rs rename to rust-code-analysis-cli/src/web/function.rs index dcf448cd2..3e2bef6f0 100644 --- a/src/web/function.rs +++ b/rust-code-analysis-cli/src/web/function.rs @@ -1,8 +1,7 @@ use serde::{Deserialize, Serialize}; use serde_json::{self, Value}; -use crate::function::{function, FunctionSpan}; -use crate::traits::{Callback, TSParserTrait}; +use rust_code_analysis::{function, Callback, FunctionSpan, TSParserTrait}; #[derive(Debug, Deserialize, Serialize)] pub struct WebFunctionPayload { diff --git a/src/web/metrics.rs b/rust-code-analysis-cli/src/web/metrics.rs similarity index 93% rename from src/web/metrics.rs rename to rust-code-analysis-cli/src/web/metrics.rs index 7a8e94c43..f601d8d3a 100644 --- a/src/web/metrics.rs +++ b/rust-code-analysis-cli/src/web/metrics.rs @@ -2,8 +2,7 @@ use serde::{Deserialize, Serialize}; use serde_json::{self, Value}; use std::path::PathBuf; -use crate::spaces::{metrics, FuncSpace}; -use crate::traits::{Callback, TSParserTrait}; +use rust_code_analysis::{metrics, Callback, FuncSpace, TSParserTrait}; #[derive(Debug, Deserialize, Serialize)] pub struct WebMetricsPayload { diff --git a/src/web/mod.rs b/rust-code-analysis-cli/src/web/mod.rs similarity index 68% rename from src/web/mod.rs rename to rust-code-analysis-cli/src/web/mod.rs index e148e52a8..f11bff644 100644 --- a/src/web/mod.rs +++ b/rust-code-analysis-cli/src/web/mod.rs @@ -1,5 +1,3 @@ -pub mod alterator; -pub mod ast; pub mod comment; pub mod function; pub mod metrics; diff --git a/src/web/server.rs b/rust-code-analysis-cli/src/web/server.rs similarity index 99% rename from src/web/server.rs rename to rust-code-analysis-cli/src/web/server.rs index 1f1468e56..acc4406e5 100644 --- a/src/web/server.rs +++ b/rust-code-analysis-cli/src/web/server.rs @@ -8,13 +8,11 @@ use actix_web::{ use futures::StreamExt; use std::path::PathBuf; -use super::ast::{AstCallback, AstCfg, AstPayload}; use super::comment::{WebCommentCallback, WebCommentCfg, WebCommentInfo, WebCommentPayload}; use super::function::{WebFunctionCallback, WebFunctionCfg, WebFunctionInfo, WebFunctionPayload}; use super::metrics::{WebMetricsCallback, WebMetricsCfg, WebMetricsInfo, WebMetricsPayload}; -use crate::langs::action; -use crate::tools::guess_language; -use crate::LANG; + +use rust_code_analysis::{action, guess_language, AstCallback, AstCfg, AstPayload, LANG}; const INVALID_LANGUAGE: &str = "The file extension doesn't correspond to a valid language"; diff --git a/src/web/alterator.rs b/src/alterator.rs similarity index 98% rename from src/web/alterator.rs rename to src/alterator.rs index bbcd14302..9a8d80e9b 100644 --- a/src/web/alterator.rs +++ b/src/alterator.rs @@ -1,8 +1,5 @@ use tree_sitter::Node; -use crate::checker::Checker; -use crate::web::ast::{AstNode, Span}; - use crate::*; pub trait Alterator diff --git a/src/web/ast.rs b/src/ast.rs similarity index 97% rename from src/web/ast.rs rename to src/ast.rs index 8c7733aa8..6cd8ee3ff 100644 --- a/src/web/ast.rs +++ b/src/ast.rs @@ -1,8 +1,7 @@ use serde::ser::{SerializeStruct, Serializer}; use serde::{Deserialize, Serialize}; -use super::alterator::Alterator; -use crate::traits::{Callback, TSParserTrait}; +use crate::*; pub type Span = Option<(usize, usize, usize, usize)>; diff --git a/src/lib.rs b/src/lib.rs index e69e6c52e..105cdd3f6 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -6,17 +6,14 @@ extern crate lazy_static; #[macro_use] extern crate serde; extern crate serde_cbor; -#[cfg_attr(test, macro_use)] extern crate serde_json; extern crate serde_yaml; extern crate toml; pub(crate) mod c_macro; -pub mod web; #[macro_use] mod asttools; -mod checker; #[macro_use] mod macros; @@ -31,6 +28,9 @@ pub(crate) use metrics::*; mod languages; pub(crate) use languages::*; +mod checker; +pub(crate) use checker::*; + mod output; pub use output::*; @@ -46,6 +46,12 @@ pub use crate::find::*; pub mod function; pub use crate::function::*; +mod alterator; +pub(crate) use crate::alterator::*; + +mod ast; +pub use crate::ast::*; + pub mod count; pub use crate::count::*; diff --git a/src/traits.rs b/src/traits.rs index 1f436c239..b7da5e951 100644 --- a/src/traits.rs +++ b/src/traits.rs @@ -2,6 +2,7 @@ use std::path::PathBuf; use std::sync::Arc; use tree_sitter::{Language, Node}; +use crate::alterator::Alterator; use crate::checker::Checker; use crate::cyclomatic::Cyclomatic; use crate::exit::Exit; @@ -14,7 +15,6 @@ use crate::mi::Mi; use crate::nom::Nom; use crate::preproc::PreprocResults; use crate::ts_parser::Filter; -use crate::web::alterator::Alterator; pub trait CodeMetricsT: Cyclomatic + Exit + Halstead + NArgs + Loc + Nom + Mi {} diff --git a/src/ts_parser.rs b/src/ts_parser.rs index eb5657fbd..6369a0953 100644 --- a/src/ts_parser.rs +++ b/src/ts_parser.rs @@ -3,13 +3,13 @@ use std::path::PathBuf; use std::sync::Arc; use tree_sitter::{Node, Parser, Tree}; +use crate::alterator::Alterator; use crate::c_macro; use crate::checker::*; use crate::getter::Getter; use crate::langs::*; use crate::preproc::{get_macros, PreprocResults}; use crate::traits::*; -use crate::web::alterator::Alterator; pub struct TSParser { code: Vec, diff --git a/src/web/ast.bak.rs b/src/web/ast.bak.rs deleted file mode 100644 index 29819538a..000000000 --- a/src/web/ast.bak.rs +++ /dev/null @@ -1,133 +0,0 @@ -use serde::ser::{SerializeStruct, Serializer}; -use serde::{Deserialize, Serialize}; -use std::cell::RefCell; -use std::rc::Rc; -use tree_sitter::Node; - -use crate::checker::Checker; -use crate::traits::{Callback, TSParserTrait}; - -type Span = Option<(usize, usize, usize, usize)>; - -#[derive(Debug, Deserialize)] -pub struct AstPayload { - pub id: String, - pub language: String, - pub code: String, - pub comment: bool, - pub span: bool, -} - -#[derive(Debug, Serialize)] -pub struct AstResponse { - id: String, - root: Option, -} - -#[derive(Debug)] -pub struct AstNode { - r#type: &'static str, - value: String, - span: Span, - children: Rc>>, -} - -impl Serialize for AstNode { - fn serialize(&self, serializer: S) -> Result - where - S: Serializer, - { - let mut st = serializer.serialize_struct("Node", 4)?; - st.serialize_field("Type", &self.r#type); - st.serialize_field("TextValue", &self.value); - st.serialize_field("Span", &self.span); - st.serialize_field("Children", &self.children.replace(Vec::new())); - st.end() - } -} - -impl AstNode { - fn new(r#type: &'static str, value: String, span: Span) -> Self { - Self { - r#type, - value, - span, - children: Rc::new(RefCell::new(Vec::new())), - } - } -} - -fn get_ast_node( - node: &Node, - span: bool, - code: &[u8], - comment: bool, -) -> Option { - if T::is_comment(node) { - None - } else { - let span = if span { - let spos = node.start_position(); - let epos = node.end_position(); - Some((spos.row + 1, spos.column + 1, epos.row + 1, epos.column + 1)) - } else { - None - }; - let text = if node.child_count() == 0 { - String::from_utf8(code[node.start_byte()..node.end_byte()].to_vec()).unwrap() - } else { - "".to_string() - }; - Some(AstNode::new(node.kind(), text, span)) - } -} - -fn build(parser: &T, span: bool, comment: bool) -> Option { - let code = parser.get_code(); - let root = parser.get_root(); - let mut cursor = root.walk(); - let mut stack = Vec::new(); - if let Some(node) = get_ast_node::(&root, span, code, comment) { - stack.push((root, Rc::clone(&node.children))); - - while let Some((ts_node, children)) = stack.pop() { - cursor.reset(ts_node); - if cursor.goto_first_child() { - let mut children = children.borrow_mut(); - loop { - let ts_node = cursor.node(); - if let Some(node) = get_ast_node::(&ts_node, span, code, comment) { - stack.push((ts_node, Rc::clone(&node.children))); - children.push(node); - } - if !cursor.goto_next_sibling() { - break; - } - } - } - } - Some(node) - } else { - None - } -} - -pub struct AstCallback {} - -pub struct AstCfg { - pub id: String, - pub comment: bool, - pub span: bool, -} - -impl Callback for AstCallback { - type Res = AstResponse; - type Cfg = AstCfg; - - fn call(cfg: Self::Cfg, parser: &T) -> Self::Res { - AstResponse { - id: cfg.id, - root: build(parser, cfg.span, cfg.comment), - } - } -}