diff --git a/plugins/coco_struct_analysis/src/coco_struct.rs b/plugins/coco_struct_analysis/src/coco_struct.rs index d086c279..22d15dc0 100644 --- a/plugins/coco_struct_analysis/src/coco_struct.rs +++ b/plugins/coco_struct_analysis/src/coco_struct.rs @@ -13,11 +13,11 @@ pub struct MethodInfo { } impl MethodInfo { - pub fn new(name: &str, access: &str) -> Self { + pub fn new(name: &str, access: &str, data_type: String) -> Self { MethodInfo { name: name.to_string(), access: access.to_string(), - return_type: "".to_string(), + return_type: data_type, } } } diff --git a/plugins/coco_struct_analysis/src/ctags_parser.rs b/plugins/coco_struct_analysis/src/ctags_parser.rs index 6731e089..38ea32ac 100644 --- a/plugins/coco_struct_analysis/src/ctags_parser.rs +++ b/plugins/coco_struct_analysis/src/ctags_parser.rs @@ -36,8 +36,9 @@ lazy_static! { .unwrap(); static ref RE_CLASS: Regex = Regex::new(r"class:(?P[A-Za-z0-9_\.]+)").unwrap(); static ref RE_ACCESS: Regex = Regex::new(r"access:(?P[A-Za-z0-9_]+)").unwrap(); + static ref RE_LANGUAGE: Regex = Regex::new(r"language:(?P[A-Za-z0-9_\#]+)").unwrap(); static ref RE_TYPE: Regex = - Regex::new(r"/\^([ ]*)([A-Za-z0-9_.]+)([^A-Za-z0-9_]+)(.*)\$/").unwrap(); + Regex::new(r"/\^([ ]*)(?P[A-Za-z0-9_.]+)([^A-Za-z0-9_]+)(.*)\$/").unwrap(); static ref TYPE_KEYWORDS: [&'static str; 18] = [ "private", "public", @@ -61,6 +62,21 @@ lazy_static! { } impl CtagsParser { + pub fn parse_str(str: &str) -> CtagsParser { + let mut parser = CtagsParser::default(); + let split = str.split("\n"); + for line in split.clone() { + parser.parse_class(line); + } + + for line in split { + println!("{}", line); + parser.parse_method_methods(line); + } + + parser + } + pub fn parse(dir: PathBuf) -> CtagsParser { let file = File::open(format!("{}", dir.display()).as_str()).expect("cannot find file"); let reader = BufReader::new(file); @@ -125,15 +141,28 @@ impl CtagsParser { } } - let data_type = ""; - let ty = CtagsParser::remove_keywords(line.to_string()); + let lang_capts = RE_LANGUAGE.captures(line).unwrap(); + let language = &lang_capts["language"]; + + let without_keywords = CtagsParser::remove_keywords(line.to_string()); + let match_type = RE_TYPE.captures(without_keywords.as_str()); + + let mut data_type = "".to_string(); + if match_type.is_some() && (CtagsParser::datatype_supported(language)) { + let capts = match_type.unwrap(); + data_type = (&capts["datatype"]).to_string(); + } if tag_type.eq("method") { - let method = MethodInfo::new(name, access); + let method = MethodInfo::new(name, access, data_type); clazz.method.push(method); } } + pub fn datatype_supported(lang: &str) -> bool { + return lang == "C++" || lang == "C#" || lang == "Java"; + } + pub fn remove_keywords(mut line: String) -> String { for keyword in TYPE_KEYWORDS.iter() { line = line.replacen(keyword, "", 1) @@ -209,6 +238,19 @@ mod test { assert_eq!("", CtagsParser::remove_keywords("public".to_string())); } + #[test] + pub fn should_get_return_type() { + let str = "MethodIdentifier SubscriberRegistry.java /^ MethodIdentifier(Method method) {$/;\" method line:239 language:Java class:SubscriberRegistry.MethodIdentifier access:default +MethodIdentifier SubscriberRegistry.java /^ private static final class MethodIdentifier {$/;\" class line:234 language:Java class:SubscriberRegistry access:private"; + + let parser = CtagsParser::parse_str(str); + let classes = parser.classes(); + + assert_eq!(1, classes.len()); + let first_method = classes[0].method[0].clone(); + assert_eq!("MethodIdentifier", first_method.return_type); + } + #[test] pub fn should_parse_java_file() { let dir = tags_dir().join("java_tags");