consistent API and usage for extracting Java types from strings

Reviewed By: jberdine

Differential Revision: D3165791

fb-gh-sync-id: c94eeed
fbshipit-source-id: c94eeed
master
Sam Blackshear 9 years ago committed by Facebook Github Bot 0
parent 35e1a8740a
commit 378ab69558

@ -32,36 +32,64 @@ let lookup tenv name =
try Some (TypenameHash.find tenv name) try Some (TypenameHash.find tenv name)
with Not_found -> None with Not_found -> None
exception Cannot_convert_string_to_typ of string
(** Lookup Java types by name *) (** Lookup Java types by name *)
let lookup_java_typ_from_string tenv typ_str = let lookup_java_typ_from_string tenv typ_str =
let rec loop = function let rec loop = function
| "" | "void" -> Sil.Tvoid | "" | "void" ->
| "int" -> Sil.Tint Sil.IInt Some Sil.Tvoid
| "byte" -> Sil.Tint Sil.IShort | "int" ->
| "short" -> Sil.Tint Sil.IShort Some (Sil.Tint Sil.IInt)
| "boolean" -> Sil.Tint Sil.IBool | "byte" ->
| "char" -> Sil.Tint Sil.IChar Some (Sil.Tint Sil.IShort)
| "long" -> Sil.Tint Sil.ILong | "short" ->
| "float" -> Sil.Tfloat Sil.FFloat Some (Sil.Tint Sil.IShort)
| "double" -> Sil.Tfloat Sil.FDouble | "boolean" ->
Some (Sil.Tint Sil.IBool)
| "char" ->
Some (Sil.Tint Sil.IChar)
| "long" ->
Some (Sil.Tint Sil.ILong)
| "float" ->
Some (Sil.Tfloat Sil.FFloat)
| "double" ->
Some (Sil.Tfloat Sil.FDouble)
| typ_str when String.contains typ_str '[' -> | typ_str when String.contains typ_str '[' ->
let stripped_typ = String.sub typ_str 0 ((String.length typ_str) - 2) in let stripped_typ = String.sub typ_str 0 ((String.length typ_str) - 2) in
let array_typ_size = Sil.exp_get_undefined false in let array_typ_size = Sil.exp_get_undefined false in
Sil.Tptr (Sil.Tarray (loop stripped_typ, array_typ_size), Sil.Pk_pointer) begin
match loop stripped_typ with
| Some typ -> Some (Sil.Tptr (Sil.Tarray (typ, array_typ_size), Sil.Pk_pointer))
| None -> None
end
| typ_str -> | typ_str ->
(* non-primitive/non-array type--resolve it in the tenv *) (* non-primitive/non-array type--resolve it in the tenv *)
let typename = Typename.TN_csu (Csu.Class Csu.Java, (Mangled.from_string typ_str)) in let typename = Typename.Java.from_string typ_str in
begin
match lookup tenv typename with match lookup tenv typename with
| Some struct_typ -> Sil.Tstruct struct_typ | Some struct_typ -> Some (Sil.Tstruct struct_typ)
| _ -> raise (Cannot_convert_string_to_typ typ_str) in | None -> None
end in
loop typ_str loop typ_str
(** resolve a type string to a Java *class* type. For strings that may represent primitive or array
typs, use [lookup_java_typ_from_string] *)
let lookup_java_class_from_string tenv typ_str =
match lookup_java_typ_from_string tenv typ_str with
| Some (Sil.Tstruct struct_typ) -> Some struct_typ
| _ -> None
(** Add a (name,type) pair to the global type environment. *) (** Add a (name,type) pair to the global type environment. *)
let add tenv name struct_typ = let add tenv name struct_typ =
TypenameHash.replace tenv name struct_typ TypenameHash.replace tenv name struct_typ
(** Return the declaring class type of [pname_java] *)
let proc_extract_declaring_class_typ tenv pname_java =
lookup_java_class_from_string tenv (Procname.java_get_class_name pname_java)
(** Return the return type of [pname_java]. *)
let proc_extract_return_typ tenv pname_java =
lookup_java_typ_from_string tenv (Procname.java_get_return_type pname_java)
(** expand a type if it is a typename by looking it up in the type environment *) (** expand a type if it is a typename by looking it up in the type environment *)
let expand_type tenv typ = let expand_type tenv typ =
match typ with match typ with

@ -32,9 +32,18 @@ val load_from_file : DB.filename -> t option
(** Look up a name in the global type environment. *) (** Look up a name in the global type environment. *)
val lookup : t -> Typename.t -> Sil.struct_typ option val lookup : t -> Typename.t -> Sil.struct_typ option
(** Lookup Java types by name. May raise [Cannot_convert_string_to_typ]. *) (** Lookup Java types by name. *)
exception Cannot_convert_string_to_typ of string val lookup_java_typ_from_string : t -> string -> Sil.typ option
val lookup_java_typ_from_string : t -> string -> Sil.typ
(** resolve a type string to a Java *class* type. For strings that may represent primitive or array
typs, use [lookup_java_typ_from_string]. *)
val lookup_java_class_from_string : t -> string -> Sil.struct_typ option
(** Return the declaring class type of [pname_java] *)
val proc_extract_declaring_class_typ : t -> Procname.java -> Sil.struct_typ option
(** Return the return type of [pname_java]. *)
val proc_extract_return_typ : t -> Procname.java -> Sil.typ option
(** Check if typename is found in t *) (** Check if typename is found in t *)
val mem : t -> Typename.t -> bool val mem : t -> Typename.t -> bool

@ -538,10 +538,11 @@ let resolve_virtual_pname tenv prop actuals callee_pname call_flags : Procname.t
let get_receiver_typ pname fallback_typ = let get_receiver_typ pname fallback_typ =
match pname with match pname with
| Procname.Java pname_java -> | Procname.Java pname_java ->
(try begin
let receiver_typ_str = Procname.java_get_class_name pname_java in match Tenv.proc_extract_declaring_class_typ tenv pname_java with
Sil.Tptr (Tenv.lookup_java_typ_from_string tenv receiver_typ_str, Sil.Pk_pointer) | Some struct_typ -> Sil.Tptr (Tstruct struct_typ, Pk_pointer)
with Tenv.Cannot_convert_string_to_typ _ -> fallback_typ) | None -> fallback_typ
end
| _ -> | _ ->
fallback_typ in fallback_typ in
let receiver_types_equal pname actual_receiver_typ = let receiver_types_equal pname actual_receiver_typ =
@ -1044,11 +1045,11 @@ let rec sym_exec tenv current_pdesc _instr (prop_: Prop.normal Prop.t) path
begin begin
match summary_opt with match summary_opt with
| None -> | None ->
let ret_typ_str = Procname.java_get_return_type callee_pname_java in
let ret_typ = let ret_typ =
match Tenv.lookup_java_typ_from_string tenv ret_typ_str with match Tenv.proc_extract_return_typ tenv callee_pname_java with
| Sil.Tstruct _ as typ -> Sil.Tptr (typ, Sil.Pk_pointer) | Some (Sil.Tstruct _ as typ) -> Sil.Tptr (typ, Pk_pointer)
| typ -> typ in | Some typ -> typ
| None -> Sil.Tvoid in
exec_skip_call resolved_pname ret_typ exec_skip_call resolved_pname ret_typ
| Some summary when call_should_be_skipped resolved_pname summary -> | Some summary when call_should_be_skipped resolved_pname summary ->
exec_skip_call resolved_pname summary.Specs.attributes.ProcAttributes.ret_type exec_skip_call resolved_pname summary.Specs.attributes.ProcAttributes.ret_type
@ -1057,7 +1058,7 @@ let rec sym_exec tenv current_pdesc _instr (prop_: Prop.normal Prop.t) path
end end
| Sil.Call (ret_ids, | Sil.Call (ret_ids,
Sil.Const (Sil.Cfun ((Procname.Java _) as callee_pname)), Sil.Const (Sil.Cfun ((Procname.Java callee_pname_java) as callee_pname)),
actual_params, loc, call_flags) -> actual_params, loc, call_flags) ->
do_error_checks (Paths.Path.curr_node path) instr current_pname current_pdesc; do_error_checks (Paths.Path.curr_node path) instr current_pname current_pdesc;
let norm_prop, norm_args = normalize_params current_pname prop_ actual_params in let norm_prop, norm_args = normalize_params current_pname prop_ actual_params in
@ -1071,15 +1072,11 @@ let rec sym_exec tenv current_pdesc _instr (prop_: Prop.normal Prop.t) path
skip_call norm_prop path pname loc ret_ids (Some ret_type) url_handled_args in skip_call norm_prop path pname loc ret_ids (Some ret_type) url_handled_args in
match Specs.get_summary pname with match Specs.get_summary pname with
| None -> | None ->
let ret_typ_str = match pname with
| Procname.Java pname_java ->
Procname.java_get_return_type pname_java
| _ ->
"unknown_return_type" in
let ret_typ = let ret_typ =
match Tenv.lookup_java_typ_from_string tenv ret_typ_str with match Tenv.proc_extract_return_typ tenv callee_pname_java with
| Sil.Tstruct _ as typ -> Sil.Tptr (typ, Sil.Pk_pointer) | Some (Sil.Tstruct _ as typ) -> Sil.Tptr (typ, Pk_pointer)
| typ -> typ in | Some typ -> typ
| None -> Sil.Tvoid in
exec_skip_call ret_typ exec_skip_call ret_typ
| Some summary when call_should_be_skipped pname summary -> | Some summary when call_should_be_skipped pname summary ->
exec_skip_call summary.Specs.attributes.ProcAttributes.ret_type exec_skip_call summary.Specs.attributes.ProcAttributes.ret_type

@ -46,16 +46,9 @@ let get_field_type_and_annotation fn = function
(** Return the annotations on the declaring class of [pname]. Only works for Java *) (** Return the annotations on the declaring class of [pname]. Only works for Java *)
let get_declaring_class_annotations pname tenv = let get_declaring_class_annotations pname tenv =
match pname with match Tenv.proc_extract_declaring_class_typ tenv pname with
| Procname.Java pname_java -> | Some { Sil.struct_annotations } -> Some struct_annotations
let receiver_typ_str = Procname.java_get_class_name pname_java in | None -> None
begin
match Tenv.lookup_java_typ_from_string tenv receiver_typ_str with
| Sil.Tstruct { struct_annotations; } -> Some struct_annotations
| exception Tenv.Cannot_convert_string_to_typ _ -> None
| _ -> None
end
| _ -> None
let ia_iter f = let ia_iter f =
let ann_iter (a, _) = f a in let ann_iter (a, _) = f a in

@ -54,8 +54,8 @@ val get_annotated_signature : ProcAttributes.t -> annotated_signature
val get_field_type_and_annotation : val get_field_type_and_annotation :
Ident.fieldname -> Sil.typ -> (Sil.typ * Sil.item_annotation) option Ident.fieldname -> Sil.typ -> (Sil.typ * Sil.item_annotation) option
(** Return the annotations on the declaring class of [pname]. Only works for Java *) (** Return the annotations on the declaring class of [java_pname]. *)
val get_declaring_class_annotations : Procname.t -> Tenv.t -> Sil.item_annotation option val get_declaring_class_annotations : Procname.java -> Tenv.t -> Sil.item_annotation option
val nullable : string val nullable : string

@ -40,10 +40,14 @@ let is_modeled_expensive =
let check_attributes check tenv pname = let check_attributes check tenv pname =
let check_class_attributes check tenv pname = let check_class_attributes check tenv = function
match Annotations.get_declaring_class_annotations pname tenv with | Procname.Java java_pname ->
begin
match Annotations.get_declaring_class_annotations java_pname tenv with
| Some annotations -> check annotations | Some annotations -> check annotations
| None -> false in | None -> false
end
| _ -> false in
let check_method_attributes check pname = let check_method_attributes check pname =
match Specs.proc_resolve_attributes pname with match Specs.proc_resolve_attributes pname with
| None -> false | None -> false

@ -582,11 +582,15 @@ let typecheck_instr
else Printf.sprintf "arg%d" i in else Printf.sprintf "arg%d" i in
(Mangled.from_string arg, typ)) (Mangled.from_string arg, typ))
etl_ in etl_ in
let ret_typ_str = Procname.java_get_return_type callee_pname_java in
let ret_type = let ret_type =
match Tenv.lookup_java_typ_from_string tenv ret_typ_str with match Tenv.proc_extract_return_typ tenv callee_pname_java with
| Sil.Tstruct _ as typ -> Sil.Tptr (typ, Sil.Pk_pointer) | Some (Sil.Tstruct _ as typ) ->
| typ -> typ in Sil.Tptr (typ, Pk_pointer)
| Some typ ->
typ
| None ->
let ret_typ_string = Procname.java_get_return_type callee_pname_java in
Sil.Tptr (Tvar (Typename.Java.from_string ret_typ_string), Pk_pointer) in
let proc_attributes = let proc_attributes =
{ (ProcAttributes.default callee_pname Config.Java) with { (ProcAttributes.default callee_pname Config.Java) with
ProcAttributes.formals; ProcAttributes.formals;

Loading…
Cancel
Save