[C++] Make QualifiedCppName.t reversed list

Summary: This representation is more natural and results in less `List.rev` calls.

Reviewed By: jberdine

Differential Revision: D4762629

fbshipit-source-id: 481cbe4
master
Andrzej Kotulski 8 years ago committed by Facebook Github Bot
parent f5adab59ec
commit f598360786

@ -8,30 +8,42 @@
*/ */
open! IStd; open! IStd;
/* internally it uses reversed list to store qualified name, for example: ["get", "shared_ptr<int>", "std"]*/
type t = list string [@@deriving compare]; type t = list string [@@deriving compare];
let equal = [%compare.equal : t]; let equal = [%compare.equal : t];
let empty = []; let empty = [];
let append_qualifier quals qual::qual => List.append quals [qual]; let append_qualifier quals qual::qual => List.cons qual quals;
let to_list quals => quals; let extract_last =
fun
| [last, ...rest] => Some (last, rest)
| [] => None;
let of_list quals => quals; let to_list = List.rev;
let to_rev_list = ident;
let of_list = List.rev;
let of_rev_list = ident;
let cpp_separator = "::"; let cpp_separator = "::";
/* This is simplistic and will give the wrong answer in some cases, eg /* This is simplistic and will give the wrong answer in some cases, eg
"foo<bar::baz<goo>>::someMethod" will get parsed as ["foo<bar", "baz<goo>>", "foo<bar::baz<goo>>::someMethod" will get parsed as ["foo<bar", "baz<goo>>",
"someMethod"]. Avoid using it if possible */ "someMethod"]. Avoid using it if possible */
let of_qual_string = { let of_qual_string str => {
let class_sep_regex = Str.regexp_string cpp_separator; let class_sep_regex = Str.regexp_string cpp_separator;
/* wait until here to define the function so that [class_sep_regex] is only computed once */ /* wait until here to define the function so that [class_sep_regex] is only computed once */
Str.split class_sep_regex Str.split class_sep_regex str |> List.rev
}; };
let to_qual_string = String.concat sep::cpp_separator; let to_separated_string quals sep::sep => List.rev quals |> String.concat sep::sep;
let to_qual_string = to_separated_string sep::cpp_separator;
let pp fmt quals => Format.fprintf fmt "%s" (to_qual_string quals); let pp fmt quals => Format.fprintf fmt "%s" (to_qual_string quals);
@ -39,7 +51,7 @@ let module Match = {
type quals_matcher = Str.regexp; type quals_matcher = Str.regexp;
let matching_separator = "#"; let matching_separator = "#";
let regexp_string_of_qualifiers quals => let regexp_string_of_qualifiers quals =>
Str.quote (String.concat sep::matching_separator quals) ^ "$"; Str.quote (to_separated_string sep::matching_separator quals) ^ "$";
let qualifiers_list_matcher quals_list => let qualifiers_list_matcher quals_list =>
( (
if (List.is_empty quals_list) { if (List.is_empty quals_list) {
@ -66,6 +78,6 @@ let module Match = {
let no_template_name s => List.hd_exn (String.split on::'<' s); let no_template_name s => List.hd_exn (String.split on::'<' s);
List.map f::no_template_name quals List.map f::no_template_name quals
}; };
Str.string_match matcher (String.concat sep::matching_separator normalized_qualifiers) 0 Str.string_match matcher (to_separated_string sep::matching_separator normalized_qualifiers) 0
}; };
}; };

@ -29,13 +29,25 @@ let to_qual_string: t => string;
let append_qualifier: t => qual::string => t; let append_qualifier: t => qual::string => t;
/** returns last (innermost scope) qualifier and qualified name without last qualifier */
let extract_last: t => option (string, t);
/** returns list of qualifers */ /** returns list of qualifers */
let to_list: t => list string; let to_list: t => list string;
/** returns reversed list of qualifiers, ie innermost scope is the first element */
let to_rev_list: t => list string;
/** given list of qualifiers in normal order produce qualified name ["std", "move"] */ /** given list of qualifiers in normal order produce qualified name ["std", "move"] */
let of_list: list string => t; let of_list: list string => t;
/** given reversed list of qualifiers, produce qualified name (ie. ["move", "std"] for std::move )*/
let of_rev_list: list string => t;
let pp: Format.formatter => t => unit; let pp: Format.formatter => t => unit;
/* Module to match qualified C++ procnames "fuzzily", that is up to namescapes and templating. In /* Module to match qualified C++ procnames "fuzzily", that is up to namescapes and templating. In

@ -911,7 +911,7 @@ let module Procname = {
let to_filename pname => { let to_filename pname => {
/* filenames for clang procs are REVERSED qualifiers with '#' as separator */ /* filenames for clang procs are REVERSED qualifiers with '#' as separator */
let get_qual_name_str pname => let get_qual_name_str pname =>
get_qualifiers pname |> QualifiedCppName.to_list |> List.rev |> String.concat sep::"#"; get_qualifiers pname |> QualifiedCppName.to_rev_list |> String.concat sep::"#";
let proc_id = let proc_id =
switch pname { switch pname {
| C {mangled} => | C {mangled} =>

@ -19,7 +19,7 @@ type type_ptr_to_sil_type = Tenv.t -> Clang_ast_t.type_ptr -> Typ.t
let sanitize_name = Str.global_replace (Str.regexp "[/ ]") "_" let sanitize_name = Str.global_replace (Str.regexp "[/ ]") "_"
let get_qual_name qual_name_list = let get_qual_name qual_name_list =
List.rev_map ~f:sanitize_name qual_name_list |> QualifiedCppName.of_list List.map ~f:sanitize_name qual_name_list |> QualifiedCppName.of_rev_list
let get_qualified_name name_info = let get_qualified_name name_info =
get_qual_name name_info.Clang_ast_t.ni_qual_name get_qual_name name_info.Clang_ast_t.ni_qual_name

@ -139,16 +139,14 @@ struct
QualifiedCppName.Match.of_fuzzy_qual_names Config.whitelisted_cpp_methods in QualifiedCppName.Match.of_fuzzy_qual_names Config.whitelisted_cpp_methods in
let class_matcher = let class_matcher =
QualifiedCppName.Match.of_fuzzy_qual_names Config.whitelisted_cpp_classes in QualifiedCppName.Match.of_fuzzy_qual_names Config.whitelisted_cpp_classes in
fun qual_method_rev -> fun qual_name ->
(* either the method is explictely whitelisted, or the whole class is whitelisted *) (* either the method is explictely whitelisted, or the whole class is whitelisted *)
QualifiedCppName.Match.match_qualifiers method_matcher QualifiedCppName.Match.match_qualifiers method_matcher qual_name ||
(List.rev qual_method_rev |> QualifiedCppName.of_list) || match QualifiedCppName.extract_last qual_name with
match qual_method_rev with | Some (_, class_qual_name) ->
| _::(_::_ as class_name_rev) ->
(* make sure the class name is not empty; in particular, it cannot be a C function *) (* make sure the class name is not empty; in particular, it cannot be a C function *)
QualifiedCppName.Match.match_qualifiers class_matcher QualifiedCppName.Match.match_qualifiers class_matcher class_qual_name
(List.rev class_name_rev |> QualifiedCppName.of_list) | None ->
| _ ->
false false
let should_translate_decl trans_unit_ctx dec decl_trans_context = let should_translate_decl trans_unit_ctx dec decl_trans_context =
@ -157,7 +155,7 @@ struct
let translate_when_used = match dec with let translate_when_used = match dec with
| Clang_ast_t.FunctionDecl (_, name_info, _, _) | Clang_ast_t.FunctionDecl (_, name_info, _, _)
| Clang_ast_t.CXXMethodDecl (_, name_info, _, _, _) -> | Clang_ast_t.CXXMethodDecl (_, name_info, _, _, _) ->
is_whitelisted_cpp_method name_info.Clang_ast_t.ni_qual_name is_whitelisted_cpp_method (CAst_utils.get_qualified_name name_info)
| _ -> false in | _ -> false in
let translate_location = let translate_location =
CLocation.should_translate_lib trans_unit_ctx source_range decl_trans_context CLocation.should_translate_lib trans_unit_ctx source_range decl_trans_context

Loading…
Cancel
Save