(* * Copyright (c) Facebook, Inc. and its affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. *) open! IStd module F = Format module Trust = struct type t = All | Only of Typ.name list [@@deriving compare, equal] let none = Only [] let extract_trust_list = function | Annot.Array class_values -> (* The only elements of this array can be class names; therefore short-circuit and return None if it's not the case. *) IList.traverse_opt class_values ~f:(fun el -> match el with Annot.Class class_typ -> Typ.name class_typ | _ -> None ) | _ -> None let of_annot annot = let open IOption.Let_syntax in let trust_all = Annot.find_parameter annot ~name:"trustAll" in let* trust_list = Annot.find_parameter annot ~name:"value" in let* trust_classes = extract_trust_list trust_list in match trust_all with | None -> return (Only trust_classes) | Some (Annot.Bool trust_all') -> if trust_all' then return All else return (Only trust_classes) | _ -> None let is_trusted_name t name = match t with All -> true | Only classes -> List.exists classes ~f:(Typ.Name.equal name) let pp fmt t = match t with | All -> F.fprintf fmt "all" | Only [] -> F.fprintf fmt "none" | Only _names -> F.fprintf fmt "selected" end type t = Default | Local of Trust.t | Strict [@@deriving compare, equal] let pp fmt t = match t with | Default -> F.fprintf fmt "Def" | Strict -> F.fprintf fmt "Strict" | Local trust -> F.fprintf fmt "Local(trust=%a)" Trust.pp trust let of_annot annot = let open IOption.Let_syntax in let* mode = Annot.find_parameter annot ~name:"value" in match mode with | Annot.Enum {value= "STRICT"} -> return Strict | Annot.Enum {value= "LOCAL"} -> ( match Annot.find_parameter annot ~name:"trustOnly" with | None -> (* When trustOnly values is missing, the default is in effect, which is Trust.All *) return (Local Trust.All) | Some (Annot.Annot trustOnly') -> let* trust = Trust.of_annot trustOnly' in return (Local trust) | Some _ -> None ) | _ -> None let of_class tenv typ_name = match PatternMatch.type_name_get_annotation tenv typ_name with | Some annots -> ( if Annotations.ia_is_nullsafe_strict annots then Strict else match Annotations.ia_find_nullsafe annots with | Some nullsafe_annot -> Option.value_exn (of_annot nullsafe_annot) ~message:"Unexpected change in @Nullsafe annotation format" | _ -> Default ) | None -> Default let of_procname tenv pname = let class_name = match pname with | Procname.Java jn -> Procname.Java.get_class_type_name jn | _ -> Logging.die InternalError "Unexpected non-Java procname %a" Procname.pp pname in of_class tenv class_name let is_trusted_name t name = match t with Strict -> false | Default -> true | Local trust -> Trust.is_trusted_name trust name let severity = function Strict | Local _ -> Exceptions.Error | Default -> Exceptions.Warning