diff --git a/infer/src/clang/cGeneral_utils.ml b/infer/src/clang/cGeneral_utils.ml index 3577f6235..90cedfa60 100644 --- a/infer/src/clang/cGeneral_utils.ml +++ b/infer/src/clang/cGeneral_utils.ml @@ -30,20 +30,11 @@ let rec string_from_list l = match l with [] -> "" | [item] -> item | item :: l' -> item ^ " " ^ string_from_list l' -let rec append_no_duplicates eq list1 list2 = - match list2 with - | el :: rest2 -> - if List.mem ~equal:eq list1 el then append_no_duplicates eq list1 rest2 - else append_no_duplicates eq list1 rest2 @ [el] - | [] -> - list1 - - -let append_no_duplicates_csu list1 list2 = append_no_duplicates Typ.Name.equal list1 list2 - let append_no_duplicates_annotations list1 list2 = - let eq (annot1, _) (annot2, _) = String.equal annot1.Annot.class_name annot2.Annot.class_name in - append_no_duplicates eq list1 list2 + let equal (annot1, _) (annot2, _) = + String.equal annot1.Annot.class_name annot2.Annot.class_name + in + IList.append_no_duplicates equal list1 list2 let add_no_duplicates_fields field_tuple l = @@ -201,4 +192,3 @@ let mk_sil_var trans_unit_ctx named_decl_info decl_info_qual_type_opt procname o CAst_utils.get_qualified_name named_decl_info |> QualifiedCppName.to_qual_string in Pvar.mk (Mangled.from_string name_string) procname - diff --git a/infer/src/clang/cGeneral_utils.mli b/infer/src/clang/cGeneral_utils.mli index 44fb8ab48..dce413599 100644 --- a/infer/src/clang/cGeneral_utils.mli +++ b/infer/src/clang/cGeneral_utils.mli @@ -19,8 +19,6 @@ val append_no_duplicates_fields : (Typ.Fieldname.t * Typ.t * Annot.Item.t) list -> (Typ.Fieldname.t * Typ.t * Annot.Item.t) list -> (Typ.Fieldname.t * Typ.t * Annot.Item.t) list -val append_no_duplicates_csu : Typ.Name.t list -> Typ.Name.t list -> Typ.Name.t list - val collect_list_tuples : ('a list * 'b list * 'c list * 'd list * 'e list) list -> 'a list * 'b list * 'c list * 'd list * 'e list diff --git a/infer/src/clang/objcInterface_decl.ml b/infer/src/clang/objcInterface_decl.ml index 85e1426a9..c2a4cbfa8 100644 --- a/infer/src/clang/objcInterface_decl.ml +++ b/infer/src/clang/objcInterface_decl.ml @@ -111,7 +111,7 @@ let add_class_to_tenv qual_type_to_sil_type tenv decl_info name_info decl_list o match Tenv.lookup tenv interface_name with | Some {fields; supers} -> ( CGeneral_utils.append_no_duplicates_fields decl_fields fields - , CGeneral_utils.append_no_duplicates_csu decl_supers supers ) + , IList.append_no_duplicates Typ.Name.equal decl_supers supers ) | _ -> (decl_fields, decl_supers) in @@ -177,4 +177,3 @@ let interface_impl_declaration qual_type_to_sil_type tenv decl = class_desc | _ -> assert false - diff --git a/infer/src/istd/IList.ml b/infer/src/istd/IList.ml index f66b793a6..20a2f8fad 100644 --- a/infer/src/istd/IList.ml +++ b/infer/src/istd/IList.ml @@ -102,3 +102,7 @@ let to_string f l = let uncons_exn = function [] -> failwith "uncons_exn" | hd :: tl -> (hd, tl) + +let append_no_duplicates eq list1 list2 = + let list2_no_dup = List.filter (fun x2 -> List.for_all (fun x1 -> not (eq x2 x1)) list1) list2 in + list1 @ list2_no_dup diff --git a/infer/src/istd/IList.mli b/infer/src/istd/IList.mli index c4e004dcb..540cbc95a 100644 --- a/infer/src/istd/IList.mli +++ b/infer/src/istd/IList.mli @@ -30,3 +30,8 @@ val to_string : ('a -> string) -> 'a list -> string val uncons_exn : 'a list -> 'a * 'a list (** deconstruct a list, like hd_exn and tl_exn *) + +val append_no_duplicates : ('a -> 'a -> bool) -> 'a list -> 'a list -> 'a list +(** [append_no_duplicates list1 list2], assuming that list1 and list2 have no duplicates on their own, + it computes list1 @ (filtered list2), so it keeps the order of both lists and has no duplicates. + However, the complexity is O(n^2), don't use for big lists! *)