[java] extract java split name from typ module

Summary:
Extract `Typ.Name.Java.Split` into a standalone module.
- This module is really only used in `Procname` so no need to be in `Typ`.
- Remove some pointless conversions to strings and back.
- Reduce the interface of `Split` to the minimum ahead of possible removal in favour of normal types.

Reviewed By: mityal

Differential Revision: D20322887

fbshipit-source-id: 7963757cb
master
Nikos Gorogiannis 5 years ago committed by Facebook Github Bot
parent 95807702fc
commit 711c48aa86

@ -43,3 +43,7 @@ let classname {classname} = classname
let is_external_via_config t = let is_external_via_config t =
let package = package t in let package = package t in
Option.exists ~f:Config.java_package_is_external package Option.exists ~f:Config.java_package_is_external package
let pp_with_verbosity ~verbose fmt t =
if verbose then pp fmt t else F.pp_print_string fmt (classname t)

@ -15,6 +15,9 @@ val to_string : t -> string
val pp : Format.formatter -> t -> unit val pp : Format.formatter -> t -> unit
val pp_with_verbosity : verbose:bool -> Format.formatter -> t -> unit
(** if [verbose] then print package if present, otherwise only print class *)
val package : t -> string option val package : t -> string option
val classname : t -> string val classname : t -> string

@ -0,0 +1,39 @@
(*
* 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_string = make ~package:"java.lang" "String"
let void = make "void"
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

@ -0,0 +1,35 @@
(*
* 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_string : t
(** [java.lang.String] type *)
val void : t
(** Java [void] type *)
val package : t -> string option
val type_name : t -> string
val pp_type_verbosity : verbose:bool -> F.formatter -> t -> unit

@ -8,6 +8,7 @@
open! IStd open! IStd
module Hashtbl = Caml.Hashtbl module Hashtbl = Caml.Hashtbl
module F = Format module F = Format
module L = Logging
(** Level of verbosity of some to_string functions. *) (** Level of verbosity of some to_string functions. *)
type detail_level = Verbose | Non_verbose | Simple [@@deriving compare, equal] type detail_level = Verbose | Non_verbose | Simple [@@deriving compare, equal]
@ -22,9 +23,9 @@ module Java = struct
[@@deriving compare] [@@deriving compare]
(* TODO: use Mangled.t here *) (* TODO: use Mangled.t here *)
type java_type = Typ.Name.Java.Split.t [@@deriving compare, equal] type java_type = JavaSplitName.t [@@deriving compare, equal]
let java_void = Typ.Name.Java.Split.make "void" let java_void = JavaSplitName.void
(** Type of java procedure names. *) (** Type of java procedure names. *)
type t = type t =
@ -40,7 +41,7 @@ module Java = struct
let pp_type_verbosity verbosity fmt java_type = let pp_type_verbosity verbosity fmt java_type =
Typ.Name.Java.Split.pp_type_verbosity ~verbose:(is_verbose verbosity) fmt java_type JavaSplitName.pp_type_verbosity ~verbose:(is_verbose verbosity) fmt java_type
(** Given a list of types, it creates a unique string of types separated by commas *) (** Given a list of types, it creates a unique string of types separated by commas *)
@ -56,8 +57,6 @@ module Java = struct
pp_param_list verbosity fmt rest pp_param_list verbosity fmt rest
let java_type_of_name class_name = Typ.Name.Java.Split.of_string (Typ.Name.name class_name)
(** It is the same as java_type_to_string_verbosity, but Java return types are optional because of (** It is the same as java_type_to_string_verbosity, but Java return types are optional because of
constructors without type *) constructors without type *)
let pp_return_type verbosity fmt j = let pp_return_type verbosity fmt j =
@ -68,9 +67,17 @@ module Java = struct
let get_class_type_name j = j.class_name let get_class_type_name j = j.class_name
let get_simple_class_name j = Typ.Name.Java.Split.(j |> get_class_name |> of_string |> type_name) let get_java_class_name_exn j =
match j.class_name with
| Typ.JavaClass java_class_name ->
java_class_name
| _ ->
L.die InternalError "Asked for java class name but got something else"
let get_simple_class_name j = JavaClassName.classname (get_java_class_name_exn j)
let get_package j = Typ.Name.Java.Split.(j |> get_class_name |> of_string |> package) let get_package j = JavaClassName.package (get_java_class_name_exn j)
let get_method j = j.method_name let get_method j = j.method_name
@ -84,14 +91,15 @@ module Java = struct
(** Prints a string of a java procname with the given level of verbosity *) (** Prints a string of a java procname with the given level of verbosity *)
let pp ?(withclass = false) verbosity fmt j = let pp ?(withclass = false) verbosity fmt j =
let pp_class_name verbosity fmt j =
JavaClassName.pp_with_verbosity ~verbose:(is_verbose verbosity) fmt
(get_java_class_name_exn j)
in
match verbosity with match verbosity with
| Verbose | Non_verbose -> | Verbose | Non_verbose ->
(* if verbose, then package.class.method(params): rtype, (* if verbose, then package.class.method(params): rtype,
else rtype package.class.method(params) else rtype package.class.method(params)
verbose is used for example to create unique filenames, non_verbose to create reports *) verbose is used for example to create unique filenames, non_verbose to create reports *)
let pp_class_name verbosity fmt j =
pp_type_verbosity verbosity fmt (Typ.Name.Java.split_typename j.class_name)
in
let separator = let separator =
match (j.return_type, verbosity) with None, _ -> "" | Some _, Verbose -> ":" | _ -> " " match (j.return_type, verbosity) with None, _ -> "" | Some _, Verbose -> ":" | _ -> " "
in in
@ -104,9 +112,7 @@ module Java = struct
| Simple -> | Simple ->
(* methodname(...) or without ... if there are no parameters *) (* methodname(...) or without ... if there are no parameters *)
let pp_class_prefix ~withclass verbosity fmt j = let pp_class_prefix ~withclass verbosity fmt j =
if withclass then if withclass then F.fprintf fmt "%a." (pp_class_name verbosity) j
F.fprintf fmt "%a." (pp_type_verbosity verbosity)
(Typ.Name.Java.split_typename j.class_name)
in in
let params = match j.parameters with [] -> "" | _ -> "..." in let params = match j.parameters with [] -> "" | _ -> "..." in
let pp_method_name ~withclass verbosity fmt j = let pp_method_name ~withclass verbosity fmt j =
@ -197,7 +203,7 @@ module Java = struct
(* FIXME this looks wrong due to the dot in the type name *) (* FIXME this looks wrong due to the dot in the type name *)
List.last parameters List.last parameters
|> Option.exists ~f:(fun java_type -> |> Option.exists ~f:(fun java_type ->
String.equal "java.lang.Object[]" (Typ.Name.Java.Split.type_name java_type) ) String.equal "java.lang.Object[]" (JavaSplitName.type_name java_type) )
let is_external java_pname = let is_external java_pname =
@ -715,7 +721,7 @@ let rec replace_parameters new_parameters procname =
let parameter_of_name procname class_name = let parameter_of_name procname class_name =
match procname with match procname with
| Java _ -> | Java _ ->
Parameter.JavaParameter (Java.java_type_of_name class_name) Parameter.JavaParameter (JavaSplitName.of_string (Typ.Name.name class_name))
| _ -> | _ ->
Parameter.ClangParameter (Parameter.clang_param_of_name class_name) Parameter.ClangParameter (Parameter.clang_param_of_name class_name)

@ -19,7 +19,7 @@ module Java : sig
type t [@@deriving compare] type t [@@deriving compare]
type java_type = Typ.Name.Java.Split.t [@@deriving compare, equal] type java_type = JavaSplitName.t [@@deriving compare, equal]
val constructor_method_name : string val constructor_method_name : string

@ -451,47 +451,6 @@ module Name = struct
end end
module Java = struct module Java = struct
module Split = struct
(** e.g. {type_name="int"; package=None} for primitive types
* or {type_name="PrintWriter"; package=Some "java.io"} for objects.
*)
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 of_java_class_name java_class_name =
let package = JavaClassName.package java_class_name in
let type_name = JavaClassName.classname java_class_name in
make ?package type_name
let package {package} = package
let type_name {type_name} = type_name
let java_lang_object = make ~package:"java.lang" "Object"
let java_lang_string = make ~package:"java.lang" "String"
let void = make "void"
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
end
let from_string name_str = JavaClass (JavaClassName.from_string name_str) let from_string name_str = JavaClass (JavaClassName.from_string name_str)
let is_class = function JavaClass _ -> true | _ -> false let is_class = function JavaClass _ -> true | _ -> false
@ -514,8 +473,6 @@ module Name = struct
L.die InternalError "Tried to split a non-java class name into a java split type@." L.die InternalError "Tried to split a non-java class name into a java split type@."
let split_typename typename = Split.of_java_class_name (get_java_class_name_exn typename)
let is_anonymous_inner_class_name class_name = let is_anonymous_inner_class_name class_name =
let java_class_name = get_java_class_name_exn class_name in let java_class_name = get_java_class_name_exn class_name in
let class_name_no_package = JavaClassName.classname java_class_name in let class_name_no_package = JavaClassName.classname java_class_name in

@ -219,26 +219,6 @@ module Name : sig
end end
module Java : sig module Java : sig
module Split : sig
type t [@@deriving compare, equal]
val make : ?package:string -> string -> t
val of_string : string -> t
val java_lang_object : t
val java_lang_string : t
val void : t
val package : t -> string option
val type_name : t -> string
val pp_type_verbosity : verbose:bool -> F.formatter -> t -> unit
end
val from_string : string -> t val from_string : string -> t
(** Create a typename from a Java classname in the form "package.class" *) (** Create a typename from a Java classname in the form "package.class" *)
@ -250,8 +230,6 @@ module Name : sig
val is_anonymous_inner_class_name : t -> bool val is_anonymous_inner_class_name : t -> bool
val split_typename : t -> Split.t
val java_lang_object : t val java_lang_object : t
val java_io_serializable : t val java_io_serializable : t

@ -465,7 +465,7 @@ let rec find_superclasses_with_attributes check tenv tname =
let is_override_of_java_lang_object_equals curr_pname = let is_override_of_java_lang_object_equals curr_pname =
let is_only_param_of_object_type = function let is_only_param_of_object_type = function
| [Procname.Parameter.JavaParameter param_type] | [Procname.Parameter.JavaParameter param_type]
when Typ.Name.Java.Split.equal param_type Typ.Name.Java.Split.java_lang_object -> when JavaSplitName.equal param_type JavaSplitName.java_lang_object ->
true true
| _ -> | _ ->
false false

@ -736,9 +736,7 @@ let call_constructor_url_update_args pname actual_params =
Procname.Java Procname.Java
(Procname.Java.make (Procname.Java.make
(Typ.Name.Java.from_string "java.net.URL") (Typ.Name.Java.from_string "java.net.URL")
None "<init>" None "<init>" [JavaSplitName.java_lang_string] Procname.Java.Non_Static)
[Typ.Name.Java.Split.java_lang_string]
Procname.Java.Non_Static)
in in
if Procname.equal url_pname pname then if Procname.equal url_pname pname then
match actual_params with match actual_params with

@ -68,7 +68,7 @@ module JNI = struct
let rec to_java_type jni = let rec to_java_type jni =
let make = Typ.Name.Java.Split.make in let make = JavaSplitName.make in
match jni with match jni with
| Boolean -> | Boolean ->
make "bool" make "bool"
@ -92,8 +92,8 @@ module JNI = struct
make ~package:pkg cl make ~package:pkg cl
| Array typ -> | Array typ ->
let java_type = to_java_type typ in let java_type = to_java_type typ in
let typ_str = Typ.Name.Java.Split.type_name java_type in let typ_str = JavaSplitName.type_name java_type in
make ?package:(Typ.Name.Java.Split.package java_type) (Printf.sprintf "%s[]" typ_str) make ?package:(JavaSplitName.package java_type) (Printf.sprintf "%s[]" typ_str)
| Method _ -> | Method _ ->
L.(die UserError "Cannot express a method as a Procname.Java.java_type") L.(die UserError "Cannot express a method as a Procname.Java.java_type")

@ -152,7 +152,7 @@ let rec string_of_type vt =
let package_to_string = function [] -> None | p -> Some (String.concat ~sep:"." p) let package_to_string = function [] -> None | p -> Some (String.concat ~sep:"." p)
let cn_to_java_type cn = let cn_to_java_type cn =
Typ.Name.Java.Split.make JavaSplitName.make
?package:(package_to_string (JBasics.cn_package cn)) ?package:(package_to_string (JBasics.cn_package cn))
(JBasics.cn_simple_name cn) (JBasics.cn_simple_name cn)
@ -160,11 +160,11 @@ let cn_to_java_type cn =
let vt_to_java_type vt = let vt_to_java_type vt =
match vt with match vt with
| JBasics.TBasic bt -> | JBasics.TBasic bt ->
Typ.Name.Java.Split.make (string_of_basic_type bt) JavaSplitName.make (string_of_basic_type bt)
| JBasics.TObject ot -> ( | JBasics.TObject ot -> (
match ot with match ot with
| JBasics.TArray vt -> | JBasics.TArray vt ->
Typ.Name.Java.Split.make (string_of_type vt ^ "[]") JavaSplitName.make (string_of_type vt ^ "[]")
| JBasics.TClass cn -> | JBasics.TClass cn ->
cn_to_java_type cn ) cn_to_java_type cn )
@ -176,7 +176,7 @@ let method_signature_names ms =
| None when String.equal method_name JConfig.constructor_name -> | None when String.equal method_name JConfig.constructor_name ->
None None
| None -> | None ->
Some (Typ.Name.Java.Split.make JConfig.void) Some (JavaSplitName.make JConfig.void)
| Some vt -> | Some vt ->
Some (vt_to_java_type vt) Some (vt_to_java_type vt)
in in

@ -49,8 +49,8 @@ let string_of_parsing_error = function
let pp_unique_repr fmt signature = Sexp.pp fmt (sexp_of_unique_repr signature) let pp_unique_repr fmt signature = Sexp.pp fmt (sexp_of_unique_repr signature)
let java_type_to_string java_type = let java_type_to_string java_type =
let package = Typ.Name.Java.Split.package java_type in let package = JavaSplitName.package java_type in
let type_name = Typ.Name.Java.Split.type_name java_type in let type_name = JavaSplitName.type_name java_type in
match package with match package with
| None -> | None ->
(* Primitive type *) (* Primitive type *)

@ -570,7 +570,7 @@ let do_map_put call_params callee_pname tenv loc node curr_pname curr_pdesc call
instr_ref ~nullsafe_mode find_canonical_duplicate typestate' = instr_ref ~nullsafe_mode find_canonical_duplicate typestate' =
(* Get the proc name for map.get() from map.put() *) (* Get the proc name for map.get() from map.put() *)
let pname_get_from_pname_put pname_put = let pname_get_from_pname_put pname_put =
let object_t = Typ.Name.Java.Split.java_lang_object in let object_t = JavaSplitName.java_lang_object in
let parameters = [object_t] in let parameters = [object_t] in
pname_put pname_put
|> Procname.Java.replace_method_name "get" |> Procname.Java.replace_method_name "get"
@ -709,7 +709,7 @@ let rec check_condition_for_sil_prune tenv idenv calls_this find_canonical_dupli
(DExp.Dretcall (DExp.Dretcall
(DExp.Dconst (Const.Cfun (Procname.Java pname_java)), args, loc, call_flags)) -> (DExp.Dconst (Const.Cfun (Procname.Java pname_java)), args, loc, call_flags)) ->
let pname_java' = let pname_java' =
let object_t = Typ.Name.Java.Split.java_lang_object in let object_t = JavaSplitName.java_lang_object in
pname_java pname_java
|> Procname.Java.replace_method_name "get" |> Procname.Java.replace_method_name "get"
|> Procname.Java.replace_return_type object_t |> Procname.Java.replace_return_type object_t

@ -18,8 +18,8 @@ let topl_class_typ = Typ.mk (Tstruct topl_class_name)
let topl_call ret_id (ret_typ : Typ.desc) loc name arg_ts : Sil.instr = let topl_call ret_id (ret_typ : Typ.desc) loc name arg_ts : Sil.instr =
let e_fun = let e_fun =
let ret_typ = Some Typ.Name.Java.Split.void in let ret_typ = Some JavaSplitName.void in
let args_typ = List.map arg_ts ~f:(fun _ -> Typ.Name.Java.Split.java_lang_object) in let args_typ = List.map arg_ts ~f:(fun _ -> JavaSplitName.java_lang_object) in
Exp.Const Exp.Const
(Const.Cfun (Const.Cfun
(Procname.Java (Procname.Java

@ -9,7 +9,7 @@ open! IStd
open OUnit2 open OUnit2
module T = JProcname.JNI.VISIBLE_FOR_TESTING_DO_NOT_USE_DIRECTLY module T = JProcname.JNI.VISIBLE_FOR_TESTING_DO_NOT_USE_DIRECTLY
let mk_split (pkg, typ) = Typ.Name.Java.Split.make ?package:pkg typ let mk_split (pkg, typ) = JavaSplitName.make ?package:pkg typ
let test_jni_pp = let test_jni_pp =
let create_test input expected _ = let create_test input expected _ =
@ -130,10 +130,10 @@ let test_jni_to_java_type_with_valid_input =
let create_test input expected _ = let create_test input expected _ =
let found = T.to_java_type input in let found = T.to_java_type input in
let pp_diff fmt (expected, actual) = let pp_diff fmt (expected, actual) =
let exp_pkg = Option.value ~default:"<None>" (Typ.Name.Java.Split.package expected) in let exp_pkg = Option.value ~default:"<None>" (JavaSplitName.package expected) in
let exp_cl = Typ.Name.Java.Split.type_name expected in let exp_cl = JavaSplitName.type_name expected in
let actual_pkg = Option.value ~default:"<None>" (Typ.Name.Java.Split.package actual) in let actual_pkg = Option.value ~default:"<None>" (JavaSplitName.package actual) in
let actual_cl = Typ.Name.Java.Split.type_name 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 Format.fprintf fmt "Expected: '(%s, %s)', found: '(%s, %s)'" exp_pkg exp_cl actual_pkg
actual_cl actual_cl
in in

Loading…
Cancel
Save