diff --git a/infer/src/IR/JavaSplitName.ml b/infer/src/IR/JavaSplitName.ml deleted file mode 100644 index 83921c33e..000000000 --- a/infer/src/IR/JavaSplitName.ml +++ /dev/null @@ -1,41 +0,0 @@ -(* - * 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 - -type t = {package: string option; type_name: string} [@@deriving compare, equal] - -let make ?package type_name = {type_name; package} - -(** Given a package.class_name string, it looks for the latest dot and split the string in two - (package, class_name) *) -let of_string package_classname = - match String.rsplit2 package_classname ~on:'.' with - | Some (package, type_name) -> - {type_name; package= Some package} - | None -> - {type_name= package_classname; package= None} - - -let package {package} = package - -let type_name {type_name} = type_name - -let java_lang_object = make ~package:"java.lang" "Object" - -let java_lang_object_array = make ~package:"java.lang" "Object[]" - -let java_lang_string = make ~package:"java.lang" "String" - -let java_lang_string_array = make ~package:"java.lang" "String[]" - -let pp_type_verbosity ~verbose fmt = function - | {package= Some package; type_name} when verbose -> - F.fprintf fmt "%s.%s" package type_name - | {type_name} -> - F.pp_print_string fmt type_name diff --git a/infer/src/IR/JavaSplitName.mli b/infer/src/IR/JavaSplitName.mli deleted file mode 100644 index 716848c6d..000000000 --- a/infer/src/IR/JavaSplitName.mli +++ /dev/null @@ -1,38 +0,0 @@ -(* - * 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 for representing a Java type. *) - -type t [@@deriving compare, equal] - -val make : ?package:string -> string -> t - -val of_string : string -> t -(** Given a package.type_name string, it looks for the latest dot and splits the string in two - (package, rest-of-type-name). If there is no dot symbol, assumes the whole string is a type - name. NB the RHS is not just a classname, eg it can be an array type. *) - -val java_lang_object : t -(** [java.lang.Object] type *) - -val java_lang_object_array : t -(** [java.lang.Object\[\]] type *) - -val java_lang_string : t -(** [java.lang.String] type *) - -val java_lang_string_array : t -(** [java.lang.String\[\]] type *) - -val package : t -> string option - -val type_name : t -> string - -val pp_type_verbosity : verbose:bool -> F.formatter -> t -> unit diff --git a/infer/src/IR/Procname.ml b/infer/src/IR/Procname.ml index 99ae69a44..750e44c8d 100644 --- a/infer/src/IR/Procname.ml +++ b/infer/src/IR/Procname.ml @@ -22,13 +22,10 @@ module Java = struct | Static (** in Java, procedures called with invokestatic *) [@@deriving compare] - (* TODO: use Mangled.t here *) - type java_type = JavaSplitName.t [@@deriving compare, equal] - (** Type of java procedure names. *) type t = { method_name: string - ; parameters: java_type list + ; parameters: Typ.t list ; class_name: Typ.Name.t ; return_type: Typ.t option (* option because constructors have no return type *) ; kind: kind } @@ -84,9 +81,7 @@ module Java = struct F.pp_print_char fmt '.' in let pp_package_method_and_params fmt j = - let pp_param_list fmt params = - Pp.seq ~sep:"," (JavaSplitName.pp_type_verbosity ~verbose) fmt params - in + let pp_param_list fmt params = Pp.seq ~sep:"," (Typ.pp_java ~verbose) fmt params in F.fprintf fmt "%a%s(%a)" pp_class_name_dot j j.method_name pp_param_list j.parameters in match verbosity with @@ -164,7 +159,11 @@ module Java = struct (** Check if the proc name has the type of a java vararg. Note: currently only checks that the last argument has type Object[]. *) let is_vararg {parameters} = - List.last parameters |> Option.exists ~f:JavaSplitName.(equal java_lang_object_array) + match List.last parameters with + | Some {desc= Tptr ({desc= Tarray {elt}}, Pk_pointer)} -> + Typ.(equal pointer_to_java_lang_object elt) + | _ -> + false let is_external java_pname = @@ -179,8 +178,7 @@ module Parameter = struct type clang_parameter = Typ.Name.t option [@@deriving compare, equal] (** Type for parameters in procnames, for java and clang. *) - type t = JavaParameter of Java.java_type | ClangParameter of clang_parameter - [@@deriving compare, equal] + type t = JavaParameter of Typ.t | ClangParameter of clang_parameter [@@deriving compare, equal] let of_typ typ = match typ.Typ.desc with Typ.Tptr ({desc= Tstruct name}, Pk_pointer) -> Some name | _ -> None @@ -695,7 +693,7 @@ let rec replace_parameters new_parameters procname = let parameter_of_name procname class_name = match procname with | Java _ -> - Parameter.JavaParameter (JavaSplitName.of_string (Typ.Name.name class_name)) + Parameter.JavaParameter Typ.(mk_ptr (mk_struct class_name)) | _ -> Parameter.ClangParameter (Parameter.clang_param_of_name class_name) diff --git a/infer/src/IR/Procname.mli b/infer/src/IR/Procname.mli index 0d118bd1a..c1efa816e 100644 --- a/infer/src/IR/Procname.mli +++ b/infer/src/IR/Procname.mli @@ -19,8 +19,6 @@ module Java : sig type t [@@deriving compare] - type java_type = JavaSplitName.t [@@deriving compare, equal] - val constructor_method_name : string val class_initializer_method_name : string @@ -28,7 +26,7 @@ module Java : sig val replace_method_name : string -> t -> t (** Replace the method name of an existing java procname. *) - val replace_parameters : java_type list -> t -> t + val replace_parameters : Typ.t list -> t -> t (** Replace the parameters of a java procname. *) val replace_return_type : Typ.t -> t -> t @@ -49,7 +47,7 @@ module Java : sig val get_method : t -> string (** Return the method name of a java procedure name. *) - val get_parameters : t -> java_type list + val get_parameters : t -> Typ.t list (** Return the parameters of a java procedure name. *) val get_return_typ : t -> Typ.t @@ -105,8 +103,7 @@ module Parameter : sig type clang_parameter = Typ.Name.t option [@@deriving compare, equal] (** Type for parameters in procnames, for java and clang. *) - type t = JavaParameter of Java.java_type | ClangParameter of clang_parameter - [@@deriving compare, equal] + type t = JavaParameter of Typ.t | ClangParameter of clang_parameter [@@deriving compare, equal] val of_typ : Typ.t -> clang_parameter end @@ -256,7 +253,7 @@ val make_java : class_name:Typ.Name.t -> return_type:Typ.t option -> method_name:string - -> parameters:Java.java_type list + -> parameters:Typ.t list -> kind:Java.kind -> unit -> t diff --git a/infer/src/IR/Typ.ml b/infer/src/IR/Typ.ml index 1d66d81b6..508ed59f9 100644 --- a/infer/src/IR/Typ.ml +++ b/infer/src/IR/Typ.ml @@ -656,3 +656,8 @@ let rec is_java_type t = is_java_type elt | _ -> false + + +let pointer_to_java_lang_object = mk_ptr (mk_struct Name.Java.java_lang_object) + +let pointer_to_java_lang_string = mk_ptr (mk_struct Name.Java.java_lang_string) diff --git a/infer/src/IR/Typ.mli b/infer/src/IR/Typ.mli index 2f56c31d6..e51953929 100644 --- a/infer/src/IR/Typ.mli +++ b/infer/src/IR/Typ.mli @@ -167,6 +167,10 @@ val double : t val void_star : t (** void* type *) +val pointer_to_java_lang_object : t + +val pointer_to_java_lang_string : t + val get_ikind_opt : t -> ikind option (** Get ikind if the type is integer. *) diff --git a/infer/src/absint/PatternMatch.ml b/infer/src/absint/PatternMatch.ml index 2202dc607..2ef9f807d 100644 --- a/infer/src/absint/PatternMatch.ml +++ b/infer/src/absint/PatternMatch.ml @@ -271,7 +271,7 @@ module Java = struct let is_override_of_lang_object_equals curr_pname = let is_only_param_of_object_type = function | [Procname.Parameter.JavaParameter param_type] - when JavaSplitName.equal param_type JavaSplitName.java_lang_object -> + when Typ.equal param_type Typ.pointer_to_java_lang_object -> true | _ -> false diff --git a/infer/src/biabduction/SymExec.ml b/infer/src/biabduction/SymExec.ml index 0f0d87727..65ab24138 100644 --- a/infer/src/biabduction/SymExec.ml +++ b/infer/src/biabduction/SymExec.ml @@ -621,31 +621,32 @@ let resolve_and_analyze (** recognize calls to the constructor java.net.URL and splits the argument string to be only the protocol. *) -let call_constructor_url_update_args pname actual_params = +let call_constructor_url_update_args = let url_pname = Procname.make_java ~class_name:(Typ.Name.Java.from_string "java.net.URL") ~return_type:None ~method_name:Procname.Java.constructor_method_name - ~parameters:[JavaSplitName.java_lang_string] ~kind:Procname.Java.Non_Static () + ~parameters:[Typ.pointer_to_java_lang_string] ~kind:Procname.Java.Non_Static () in - if Procname.equal url_pname pname then - match actual_params with - | [this; (Exp.Const (Const.Cstr s), atype)] -> ( - let parts = Str.split (Str.regexp_string "://") s in - match parts with - | frst :: _ -> - if - String.equal frst "http" || String.equal frst "ftp" || String.equal frst "https" - || String.equal frst "mailto" || String.equal frst "jar" - then [this; (Exp.Const (Const.Cstr frst), atype)] - else actual_params - | _ -> - actual_params ) - | [this; (_, atype)] -> - [this; (Exp.Const (Const.Cstr "file"), atype)] - | _ -> - actual_params - else actual_params + fun pname actual_params -> + if Procname.equal url_pname pname then + match actual_params with + | [this; (Exp.Const (Const.Cstr s), atype)] -> ( + let parts = Str.split (Str.regexp_string "://") s in + match parts with + | frst :: _ -> + if + String.equal frst "http" || String.equal frst "ftp" || String.equal frst "https" + || String.equal frst "mailto" || String.equal frst "jar" + then [this; (Exp.Const (Const.Cstr frst), atype)] + else actual_params + | _ -> + actual_params ) + | [this; (_, atype)] -> + [this; (Exp.Const (Const.Cstr "file"), atype)] + | _ -> + actual_params + else actual_params let receiver_self receiver prop = diff --git a/infer/src/concurrency/StarvationModels.ml b/infer/src/concurrency/StarvationModels.ml index 0aa434c81..a0cb8a206 100644 --- a/infer/src/concurrency/StarvationModels.ml +++ b/infer/src/concurrency/StarvationModels.ml @@ -402,8 +402,9 @@ let is_assume_true = let is_java_main_method (pname : Procname.t) = + let pointer_to_array_of_java_lang_string = Typ.(mk_ptr (mk_array pointer_to_java_lang_string)) in let check_main_args args = - match args with [arg] -> JavaSplitName.(equal java_lang_string_array arg) | _ -> false + match args with [arg] -> Typ.equal pointer_to_array_of_java_lang_string arg | _ -> false in match pname with | C _ | Linters_dummy_method | Block _ | ObjC_Cpp _ | WithBlockParameters _ -> diff --git a/infer/src/java/jTransType.ml b/infer/src/java/jTransType.ml index 32b7a99dc..813582b6b 100644 --- a/infer/src/java/jTransType.ml +++ b/infer/src/java/jTransType.ml @@ -110,57 +110,8 @@ let object_type_to_string ot = array_type_to_string vt -let string_of_basic_type = function - | `Bool -> - JConfig.boolean_st - | `Byte -> - JConfig.byte_st - | `Char -> - JConfig.char_st - | `Double -> - JConfig.double_st - | `Float -> - JConfig.float_st - | `Int -> - JConfig.int_st - | `Long -> - JConfig.long_st - | `Short -> - JConfig.short_st - - -let rec string_of_type vt = - match vt with - | JBasics.TBasic bt -> - string_of_basic_type bt - | JBasics.TObject ot -> ( - match ot with - | JBasics.TArray vt -> - string_of_type vt ^ "[]" - | JBasics.TClass cn -> - JBasics.cn_name cn ) - - let package_to_string = function [] -> None | p -> Some (String.concat ~sep:"." p) -let cn_to_java_type cn = - JavaSplitName.make - ?package:(package_to_string (JBasics.cn_package cn)) - (JBasics.cn_simple_name cn) - - -let vt_to_java_type vt = - match vt with - | JBasics.TBasic bt -> - JavaSplitName.of_string (string_of_basic_type bt) - | JBasics.TObject ot -> ( - match ot with - | JBasics.TArray vt -> - JavaSplitName.of_string (string_of_type vt ^ "[]") - | JBasics.TClass cn -> - cn_to_java_type cn ) - - let method_signature_names ms = let method_name = JBasics.ms_name ms in let return_type_name = @@ -172,7 +123,7 @@ let method_signature_names ms = | Some vt -> Some (get_named_type vt) in - let args_types = List.map ~f:vt_to_java_type (JBasics.ms_args ms) in + let args_types = List.map ~f:get_named_type (JBasics.ms_args ms) in (return_type_name, method_name, args_types) diff --git a/infer/src/nullsafe/ThirdPartyAnnotationInfo.ml b/infer/src/nullsafe/ThirdPartyAnnotationInfo.ml index be8263efb..967ef2245 100644 --- a/infer/src/nullsafe/ThirdPartyAnnotationInfo.ml +++ b/infer/src/nullsafe/ThirdPartyAnnotationInfo.ml @@ -21,9 +21,7 @@ let unique_repr_of_signature ThirdPartyMethod.{class_name; method_name; params} {class_name; method_name; param_types= List.map params ~f:(fun (param_type, _) -> param_type)} -let java_type_to_string java_type = - Pp.string_of_pp (JavaSplitName.pp_type_verbosity ~verbose:true) java_type - +let java_type_to_string java_type = Pp.string_of_pp (Typ.pp_java ~verbose:true) java_type let unique_repr_of_java_proc_name java_proc_name = let class_name = Procname.Java.get_class_name java_proc_name in diff --git a/infer/src/nullsafe/models.ml b/infer/src/nullsafe/models.ml index 68d28528b..faeb72e3d 100644 --- a/infer/src/nullsafe/models.ml +++ b/infer/src/nullsafe/models.ml @@ -55,7 +55,7 @@ let get_special_method_modelled_nullability tenv proc_name = Some (false, []) (* valueOf() is a synthetic enum method that is never null *) | "valueOf", [Procname.Parameter.JavaParameter param_type_name] - when JavaSplitName.equal param_type_name JavaSplitName.java_lang_string -> + when Typ.equal param_type_name Typ.pointer_to_java_lang_string -> Some (false, [false]) | _ -> None diff --git a/infer/src/nullsafe/typeCheck.ml b/infer/src/nullsafe/typeCheck.ml index c412bec0d..5d9d4c61a 100644 --- a/infer/src/nullsafe/typeCheck.ml +++ b/infer/src/nullsafe/typeCheck.ml @@ -635,8 +635,7 @@ let do_map_put ({IntraproceduralAnalysis.proc_desc= curr_pdesc; tenv; _} as anal find_canonical_duplicate typestate' = (* Get the proc name for map.get() from map.put() *) let pname_get_from_pname_put pname_put = - let object_t = JavaSplitName.java_lang_object in - let parameters = [object_t] in + let parameters = [object_typ] in pname_put |> Procname.Java.replace_method_name "get" |> Procname.Java.replace_return_type object_typ diff --git a/infer/src/test_determinator/JProcname.ml b/infer/src/test_determinator/JProcname.ml index 529fa9fbe..4ad879604 100644 --- a/infer/src/test_determinator/JProcname.ml +++ b/infer/src/test_determinator/JProcname.ml @@ -67,37 +67,6 @@ module JNI = struct Format.fprintf fmt "(%a)%a" (Pp.seq ~sep:"" pp) args pp ret_typ - let rec to_java_type jni = - let make = JavaSplitName.make in - match jni with - | Boolean -> - make "bool" - | Byte -> - make "byte" - | Char -> - make "char" - | Short -> - make "short" - | Int -> - make "int" - | Long -> - make "long" - | Float -> - make "float" - | Double -> - make "double" - | Void -> - make "void" - | FullyQualifiedClass (pkg, cl) -> - make ~package:pkg cl - | Array typ -> - let java_type = to_java_type typ in - let typ_str = JavaSplitName.type_name java_type in - make ?package:(JavaSplitName.package java_type) (Printf.sprintf "%s[]" typ_str) - | Method _ -> - L.(die UserError "Cannot express a method as a Procname.Java.java_type") - - let rec to_typ jni = match jni with | Boolean -> @@ -279,8 +248,6 @@ module JNI = struct let parse_method_str = parse_method_str - let to_java_type = to_java_type - let pp = pp end end @@ -289,7 +256,7 @@ let create_procname ~classname ~methodname:method_name ~signature ~use_signature let signature = if use_signature then signature else JNI.void_method_with_no_arguments in let class_name = Typ.Name.Java.from_string classname in let args, return_type = JNI.parse_method_str signature in - let parameters = List.map ~f:JNI.to_java_type args in + let parameters = List.map ~f:JNI.to_typ args in let return_type = if String.equal method_name Procname.Java.constructor_method_name diff --git a/infer/src/test_determinator/JProcname.mli b/infer/src/test_determinator/JProcname.mli index 18dfbad66..a7e0fb00d 100644 --- a/infer/src/test_determinator/JProcname.mli +++ b/infer/src/test_determinator/JProcname.mli @@ -33,8 +33,6 @@ module JNI : sig val parse_method_str : string -> t list * t - val to_java_type : t -> Procname.Java.java_type - val pp : Format.formatter -> t -> unit end end diff --git a/infer/src/topl/ToplUtils.ml b/infer/src/topl/ToplUtils.ml index f5e9f2b2d..9a8f898db 100644 --- a/infer/src/topl/ToplUtils.ml +++ b/infer/src/topl/ToplUtils.ml @@ -19,7 +19,7 @@ let topl_class_typ = Typ.mk (Tstruct topl_class_name) let topl_call ret_id (ret_typ : Typ.desc) loc method_name arg_ts : Sil.instr = let e_fun = let return_type = Some Typ.void in - let parameters = List.map arg_ts ~f:(fun _ -> JavaSplitName.java_lang_object) in + let parameters = List.map arg_ts ~f:(fun _ -> Typ.pointer_to_java_lang_object) in Exp.Const (Const.Cfun (Procname.make_java ~class_name:topl_class_name ~return_type ~method_name ~parameters diff --git a/infer/src/unit/JavaProfilerSamplesTest.ml b/infer/src/unit/JavaProfilerSamplesTest.ml index e5e45865a..1b576d59c 100644 --- a/infer/src/unit/JavaProfilerSamplesTest.ml +++ b/infer/src/unit/JavaProfilerSamplesTest.ml @@ -9,8 +9,6 @@ open! IStd open OUnit2 module T = JProcname.JNI.VISIBLE_FOR_TESTING_DO_NOT_USE_DIRECTLY -let mk_split (pkg, typ) = JavaSplitName.make ?package:pkg typ - let test_jni_pp = let create_test input expected _ = let found = Format.asprintf "%a" T.pp input in @@ -126,37 +124,6 @@ let test_jni_parse_str_with_invalid_input = name >:: create_test test_input expected_exception ) -let test_jni_to_java_type_with_valid_input = - let create_test input expected _ = - let found = T.to_java_type input in - let pp_diff fmt (expected, actual) = - let exp_pkg = Option.value ~default:"" (JavaSplitName.package expected) in - let exp_cl = JavaSplitName.type_name expected in - let actual_pkg = Option.value ~default:"" (JavaSplitName.package actual) in - let actual_cl = JavaSplitName.type_name actual in - Format.fprintf fmt "Expected: '(%s, %s)', found: '(%s, %s)'" exp_pkg exp_cl actual_pkg - actual_cl - in - let cmp a b = Int.equal 0 (Procname.Java.compare_java_type a b) in - assert_equal ~cmp ~pp_diff expected found - in - [ ("test_jni_to_java_type_1", T.Boolean, mk_split (None, "bool")) - ; ( "test_jni_to_java_type_2" - , T.FullyQualifiedClass ("java.lang", "String") - , mk_split (Some "java.lang", "String") ) ] - |> List.map ~f:(fun (name, test_input, expected_output) -> - name >:: create_test test_input expected_output ) - - -let test_jni_to_java_type_with_invalid_input = - let run () = T.to_java_type (Method ([], Void)) in - let expected_exception = - Logging.InferUserError "Cannot express a method as a Procname.Java.java_type" - in - let do_assert _ = assert_raises expected_exception run in - "test_jni_to_java_type_with_method_should_fail" >:: do_assert - - let test_from_json_string_with_valid_input = let create_test input expected ~use_signature _ = let found = JavaProfilerSamples.from_json_string input ~use_signature in @@ -183,19 +150,13 @@ let test_from_json_string_with_valid_input = make_java ~class_name:(Typ.Name.Java.from_string "lll.mmm.Nnn") ~return_type:None ~method_name:Java.constructor_method_name - ~parameters: - [ mk_split (Some "java.lang", "String") - ; mk_split (None, "int[]") - ; mk_split (None, "long") ] + ~parameters:[Typ.pointer_to_java_lang_string; Typ.(mk_ptr (mk_array int)); Typ.long] ~kind:Java.Non_Static ()) ; Procname.( make_java ~class_name:(Typ.Name.Java.from_string "ggg.hhh.Iii") ~return_type:None ~method_name:Java.class_initializer_method_name - ~parameters: - [ mk_split (Some "java.lang", "String") - ; mk_split (None, "int[]") - ; mk_split (None, "long") ] + ~parameters:[Typ.pointer_to_java_lang_string; Typ.(mk_ptr (mk_array int)); Typ.long] ~kind:Java.Non_Static ()) ] ) ; ( "label2" , Procname.Set.of_list @@ -204,10 +165,7 @@ let test_from_json_string_with_valid_input = ~class_name:(Typ.Name.Java.from_string "ddd.eee.Fff") ~return_type:(Some Typ.(mk_ptr (mk_array (mk_ptr (mk_array java_char))))) ~method_name:"methodTwo" - ~parameters: - [ mk_split (Some "java.lang", "String") - ; mk_split (None, "int[]") - ; mk_split (None, "long") ] + ~parameters:[Typ.pointer_to_java_lang_string; Typ.(mk_ptr (mk_array int)); Typ.long] ~kind:Java.Non_Static ()) ; Procname.( make_java @@ -273,7 +231,6 @@ let test_from_json_string_with_invalid_input = let tests = "java_profiler_samples" - >::: (test_jni_to_java_type_with_invalid_input :: test_jni_parse_str_with_valid_input) - @ test_jni_parse_str_with_invalid_input @ test_jni_parse_method_str_with_invalid_input - @ test_jni_pp @ test_jni_to_java_type_with_valid_input + >::: test_jni_parse_str_with_valid_input @ test_jni_parse_str_with_invalid_input + @ test_jni_parse_method_str_with_invalid_input @ test_jni_pp @ test_from_json_string_with_valid_input @ test_from_json_string_with_invalid_input