[typ] extract Struct module

Summary: There is no reason for this to be in Typ.

Reviewed By: ezgicicek

Differential Revision: D19161751

fbshipit-source-id: de33f5fa1
master
Nikos Gorogiannis 5 years ago committed by Facebook Github Bot
parent c1d4e57561
commit cef051dd1a

@ -65,7 +65,7 @@ module Raw = struct
let lookup_field_type_annot tenv base_typ field_name = let lookup_field_type_annot tenv base_typ field_name =
let lookup = Tenv.lookup tenv in let lookup = Tenv.lookup tenv in
Typ.Struct.get_field_type_and_annotation ~lookup field_name base_typ Struct.get_field_type_and_annotation ~lookup field_name base_typ
(* Get the type of an access, or None if the type cannot be determined *) (* Get the type of an access, or None if the type cannot be determined *)

@ -413,7 +413,7 @@ let rec ignore_integer_cast e =
let rec get_java_class_initializer tenv = function let rec get_java_class_initializer tenv = function
| Lfield (Lvar pvar, fn, typ) when Pvar.is_global pvar -> ( | Lfield (Lvar pvar, fn, typ) when Pvar.is_global pvar -> (
match Typ.Struct.get_field_type_and_annotation ~lookup:(Tenv.lookup tenv) fn typ with match Struct.get_field_type_and_annotation ~lookup:(Tenv.lookup tenv) fn typ with
| Some (field_typ, annot) when Annot.Item.is_final annot -> | Some (field_typ, annot) when Annot.Item.is_final annot ->
let java_class = Typ.JavaClass (Pvar.get_name pvar) in let java_class = Typ.JavaClass (Pvar.get_name pvar) in
Some Some

@ -259,7 +259,7 @@ module AccessExpression = struct
let lookup_field_type_annot tenv base_typ field_name = let lookup_field_type_annot tenv base_typ field_name =
let lookup = Tenv.lookup tenv in let lookup = Tenv.lookup tenv in
Typ.Struct.get_field_type_and_annotation ~lookup field_name base_typ Struct.get_field_type_and_annotation ~lookup field_name base_typ
let rec get_typ t tenv : Typ.t option = let rec get_typ t tenv : Typ.t option =

@ -11,7 +11,7 @@ open! IStd
module F = Format module F = Format
(** Type for ObjC accessors *) (** Type for ObjC accessors *)
type objc_accessor_type = Objc_getter of Typ.Struct.field | Objc_setter of Typ.Struct.field type objc_accessor_type = Objc_getter of Struct.field | Objc_setter of Struct.field
[@@deriving compare] [@@deriving compare]
let kind_of_objc_accessor_type accessor = let kind_of_objc_accessor_type accessor =

@ -9,7 +9,7 @@ open! IStd
(** Attributes of a procedure. *) (** Attributes of a procedure. *)
type objc_accessor_type = Objc_getter of Typ.Struct.field | Objc_setter of Typ.Struct.field type objc_accessor_type = Objc_getter of Struct.field | Objc_setter of Struct.field
val kind_of_objc_accessor_type : objc_accessor_type -> string val kind_of_objc_accessor_type : objc_accessor_type -> string

@ -730,9 +730,9 @@ let pp_variable_list fmt etl =
let pp_objc_accessor fmt accessor = let pp_objc_accessor fmt accessor =
match accessor with match accessor with
| Some (ProcAttributes.Objc_getter field) -> | Some (ProcAttributes.Objc_getter field) ->
Format.fprintf fmt "Getter of %a, " (Typ.Struct.pp_field Pp.text) field Format.fprintf fmt "Getter of %a, " (Struct.pp_field Pp.text) field
| Some (ProcAttributes.Objc_setter field) -> | Some (ProcAttributes.Objc_setter field) ->
Format.fprintf fmt "Setter of %a, " (Typ.Struct.pp_field Pp.text) field Format.fprintf fmt "Setter of %a, " (Struct.pp_field Pp.text) field
| None -> | None ->
() ()

@ -0,0 +1,146 @@
(*
* 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 field = Typ.Fieldname.t * Typ.t * Annot.Item.t [@@deriving compare]
type fields = field list
(** Type for a structured value. *)
type t =
{ fields: fields (** non-static fields *)
; statics: fields (** static fields *)
; supers: Typ.Name.t list (** superclasses *)
; methods: Typ.Procname.t list (** methods defined *)
; exported_objc_methods: Typ.Procname.t list
(** methods in ObjC interface, subset of [methods] *)
; annots: Annot.Item.t (** annotations *)
; dummy: bool (** dummy struct for class including static method *) }
type lookup = Typ.Name.t -> t option
let pp_field pe f (field_name, typ, ann) =
F.fprintf f "@\n\t\t%a %a %a" (Typ.pp_full pe) typ Typ.Fieldname.pp field_name Annot.Item.pp ann
let pp pe name f {fields; supers; methods; exported_objc_methods; annots} =
if Config.debug_mode then
(* change false to true to print the details of struct *)
F.fprintf f
"%a @\n\
\tfields: {%a@\n\
\t}@\n\
\tsupers: {%a@\n\
\t}@\n\
\tmethods: {%a@\n\
\t}@\n\
\texported_obj_methods: {%a@\n\
\t}@\n\
\tannots: {%a@\n\
\t}"
Typ.Name.pp name
(Pp.seq (pp_field pe))
fields
(Pp.seq (fun f n -> F.fprintf f "@\n\t\t%a" Typ.Name.pp n))
supers
(Pp.seq (fun f m -> F.fprintf f "@\n\t\t%a" Typ.Procname.pp m))
methods
(Pp.seq (fun f m -> F.fprintf f "@\n\t\t%a" Typ.Procname.pp m))
exported_objc_methods Annot.Item.pp annots
else Typ.Name.pp f name
let internal_mk_struct ?default ?fields ?statics ?methods ?exported_objc_methods ?supers ?annots
?dummy () =
let default_ =
{ fields= []
; statics= []
; methods= []
; exported_objc_methods= []
; supers= []
; annots= Annot.Item.empty
; dummy= false }
in
let mk_struct_ ?(default = default_) ?(fields = default.fields) ?(statics = default.statics)
?(methods = default.methods) ?(exported_objc_methods = default.exported_objc_methods)
?(supers = default.supers) ?(annots = default.annots) ?(dummy = default.dummy) () =
{fields; statics; methods; exported_objc_methods; supers; annots; dummy}
in
mk_struct_ ?default ?fields ?statics ?methods ?exported_objc_methods ?supers ?annots ?dummy ()
(** the element typ of the final extensible array in the given typ, if any *)
let rec get_extensible_array_element_typ ~lookup (typ : Typ.t) =
match typ.desc with
| Tarray {elt} ->
Some elt
| Tstruct name -> (
match lookup name with
| Some {fields} -> (
match List.last fields with
| Some (_, fld_typ, _) ->
get_extensible_array_element_typ ~lookup fld_typ
| None ->
None )
| None ->
None )
| _ ->
None
(** If a struct type with field f, return the type of f. If not, return the default *)
let fld_typ ~lookup ~default fn (typ : Typ.t) =
(* Note: would be nice migrate it to get_field_info
(for that one needs to ensure adding Tptr to pattern match does not break thing) *)
match typ.desc with
| Tstruct name -> (
match lookup name with
| Some {fields} ->
List.find ~f:(fun (f, _, _) -> Typ.Fieldname.equal f fn) fields
|> Option.value_map ~f:snd3 ~default
| None ->
default )
| _ ->
default
type field_info = {typ: Typ.t; annotations: Annot.Item.t; is_static: bool}
let find_field field_list field_name_to_lookup =
List.find_map
~f:(fun (field_name, typ, annotations) ->
if Typ.Fieldname.equal field_name field_name_to_lookup then Some (typ, annotations) else None
)
field_list
let get_field_info ~lookup field_name_to_lookup (typ : Typ.t) =
let find_field_info field_list ~is_static =
find_field field_list field_name_to_lookup
|> Option.map ~f:(fun (typ, annotations) -> {typ; annotations; is_static})
in
match typ.desc with
| Tstruct name | Tptr ({desc= Tstruct name}, _) -> (
match lookup name with
| Some {fields= non_statics; statics} ->
(* Search in both lists and return the first found *)
find_field_info statics ~is_static:true
|> IOption.if_none_evalopt ~f:(fun () -> find_field_info non_statics ~is_static:false)
| None ->
None )
| _ ->
None
let get_field_type_and_annotation ~lookup field_name_to_lookup typ =
get_field_info ~lookup field_name_to_lookup typ
|> Option.map ~f:(fun {typ; annotations} -> (typ, annotations))
let is_dummy {dummy} = dummy

@ -0,0 +1,63 @@
(*
* Copyright (c) 2009-2013, Monoidics ltd.
* 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 field = Typ.Fieldname.t * Typ.t * Annot.Item.t [@@deriving compare]
type fields = field list
(** Type for a structured value. *)
type t = private
{ fields: fields (** non-static fields *)
; statics: fields (** static fields *)
; supers: Typ.Name.t list (** supers *)
; methods: Typ.Procname.t list (** methods defined *)
; exported_objc_methods: Typ.Procname.t list
(** methods in ObjC interface, subset of [methods] *)
; annots: Annot.Item.t (** annotations *)
; dummy: bool (** dummy struct for class including static method *) }
type lookup = Typ.Name.t -> t option
val pp_field : Pp.env -> F.formatter -> field -> unit
val pp : Pp.env -> Typ.Name.t -> F.formatter -> t -> unit
(** Pretty print a struct type. *)
val internal_mk_struct :
?default:t
-> ?fields:fields
-> ?statics:fields
-> ?methods:Typ.Procname.t list
-> ?exported_objc_methods:Typ.Procname.t list
-> ?supers:Typ.Name.t list
-> ?annots:Annot.Item.t
-> ?dummy:bool
-> unit
-> t
(** Construct a struct_typ, normalizing field types *)
val get_extensible_array_element_typ : lookup:lookup -> Typ.t -> Typ.t option
(** the element typ of the final extensible array in the given typ, if any *)
type field_info = {typ: Typ.t; annotations: Annot.Item.t; is_static: bool}
val get_field_info : lookup:lookup -> Typ.Fieldname.t -> Typ.t -> field_info option
(** Lookup for info associated with the field [fn]. None if [typ] has no field named [fn] *)
val fld_typ : lookup:lookup -> default:Typ.t -> Typ.Fieldname.t -> Typ.t -> Typ.t
(** If a struct type with field f, return the type of f. If not, return the default type if given,
otherwise raise an exception *)
val get_field_type_and_annotation :
lookup:lookup -> Typ.Fieldname.t -> Typ.t -> (Typ.t * Annot.Item.t) option
(** Return the type of the field [fn] and its annotation, None if [typ] has no field named [fn] *)
val is_dummy : t -> bool

@ -15,13 +15,13 @@ module TypenameHash = Caml.Hashtbl.Make (Typ.Name)
module TypenameHashNormalizer = MaximumSharing.ForHashtbl (TypenameHash) module TypenameHashNormalizer = MaximumSharing.ForHashtbl (TypenameHash)
(** Type for type environment. *) (** Type for type environment. *)
type t = Typ.Struct.t TypenameHash.t type t = Struct.t TypenameHash.t
let pp fmt (tenv : t) = let pp fmt (tenv : t) =
TypenameHash.iter TypenameHash.iter
(fun name typ -> (fun name typ ->
Format.fprintf fmt "@[<6>NAME: %s@]@," (Typ.Name.to_string name) ; Format.fprintf fmt "@[<6>NAME: %s@]@," (Typ.Name.to_string name) ;
Format.fprintf fmt "@[<6>TYPE: %a@]@," (Typ.Struct.pp Pp.text name) typ ) Format.fprintf fmt "@[<6>TYPE: %a@]@," (Struct.pp Pp.text name) typ )
tenv tenv
@ -32,7 +32,7 @@ let create () = TypenameHash.create 1000
let mk_struct tenv ?default ?fields ?statics ?methods ?exported_objc_methods ?supers ?annots ?dummy let mk_struct tenv ?default ?fields ?statics ?methods ?exported_objc_methods ?supers ?annots ?dummy
name = name =
let struct_typ = let struct_typ =
Typ.Struct.internal_mk_struct ?default ?fields ?statics ?methods ?exported_objc_methods ?supers Struct.internal_mk_struct ?default ?fields ?statics ?methods ?exported_objc_methods ?supers
?annots ?dummy () ?annots ?dummy ()
in in
TypenameHash.replace tenv name struct_typ ; TypenameHash.replace tenv name struct_typ ;
@ -40,7 +40,7 @@ let mk_struct tenv ?default ?fields ?statics ?methods ?exported_objc_methods ?su
(** Look up a name in the global type environment. *) (** Look up a name in the global type environment. *)
let lookup tenv name : Typ.Struct.t option = let lookup tenv name : Struct.t option =
try Some (TypenameHash.find tenv name) try Some (TypenameHash.find tenv name)
with Caml.Not_found -> ( with Caml.Not_found -> (
(* ToDo: remove the following additional lookups once C/C++ interop is resolved *) (* ToDo: remove the following additional lookups once C/C++ interop is resolved *)
@ -103,7 +103,7 @@ end
let merge ~src ~dst = let merge ~src ~dst =
TypenameHash.iter TypenameHash.iter
(fun pname cfg -> (fun pname cfg ->
if (not (Typ.Struct.is_dummy cfg)) || not (TypenameHash.mem dst pname) then if (not (Struct.is_dummy cfg)) || not (TypenameHash.mem dst pname) then
TypenameHash.replace dst pname cfg ) TypenameHash.replace dst pname cfg )
src src

@ -29,24 +29,24 @@ val load_global : unit -> t option
val store_global : t -> unit val store_global : t -> unit
(** save a global type environment (Java) *) (** save a global type environment (Java) *)
val lookup : t -> Typ.Name.t -> Typ.Struct.t option val lookup : t -> Typ.Name.t -> Struct.t option
(** Look up a name in the global type environment. *) (** Look up a name in the global type environment. *)
val mk_struct : val mk_struct :
t t
-> ?default:Typ.Struct.t -> ?default:Struct.t
-> ?fields:Typ.Struct.fields -> ?fields:Struct.fields
-> ?statics:Typ.Struct.fields -> ?statics:Struct.fields
-> ?methods:Typ.Procname.t list -> ?methods:Typ.Procname.t list
-> ?exported_objc_methods:Typ.Procname.t list -> ?exported_objc_methods:Typ.Procname.t list
-> ?supers:Typ.Name.t list -> ?supers:Typ.Name.t list
-> ?annots:Annot.Item.t -> ?annots:Annot.Item.t
-> ?dummy:bool -> ?dummy:bool
-> Typ.Name.t -> Typ.Name.t
-> Typ.Struct.t -> Struct.t
(** Construct a struct_typ, normalizing field types *) (** Construct a struct_typ, normalizing field types *)
val add_field : t -> Typ.Name.t -> Typ.Struct.field -> unit val add_field : t -> Typ.Name.t -> Struct.field -> unit
(** Add a field to a given struct in the global type environment. *) (** Add a field to a given struct in the global type environment. *)
val pp : Format.formatter -> t -> unit [@@warning "-32"] val pp : Format.formatter -> t -> unit [@@warning "-32"]

@ -1477,140 +1477,3 @@ module Fieldname = struct
(last_char >= '0' && last_char <= '9') (last_char >= '0' && last_char <= '9')
&& String.is_suffix field_name ~suffix:(this ^ String.of_char last_char) && String.is_suffix field_name ~suffix:(this ^ String.of_char last_char)
end end
module Struct = struct
type field = Fieldname.t * T.t * Annot.Item.t [@@deriving compare]
type fields = field list
(** Type for a structured value. *)
type t =
{ fields: fields (** non-static fields *)
; statics: fields (** static fields *)
; supers: Name.t list (** superclasses *)
; methods: Procname.t list (** methods defined *)
; exported_objc_methods: Procname.t list (** methods in ObjC interface, subset of [methods] *)
; annots: Annot.Item.t (** annotations *)
; dummy: bool (** dummy struct for class including static method *) }
type lookup = Name.t -> t option
let pp_field pe f (field_name, typ, ann) =
F.fprintf f "@\n\t\t%a %a %a" (pp_full pe) typ Fieldname.pp field_name Annot.Item.pp ann
let pp pe name f {fields; supers; methods; exported_objc_methods; annots} =
if Config.debug_mode then
(* change false to true to print the details of struct *)
F.fprintf f
"%a @\n\
\tfields: {%a@\n\
\t}@\n\
\tsupers: {%a@\n\
\t}@\n\
\tmethods: {%a@\n\
\t}@\n\
\texported_obj_methods: {%a@\n\
\t}@\n\
\tannots: {%a@\n\
\t}"
Name.pp name
(Pp.seq (pp_field pe))
fields
(Pp.seq (fun f n -> F.fprintf f "@\n\t\t%a" Name.pp n))
supers
(Pp.seq (fun f m -> F.fprintf f "@\n\t\t%a" Procname.pp m))
methods
(Pp.seq (fun f m -> F.fprintf f "@\n\t\t%a" Procname.pp m))
exported_objc_methods Annot.Item.pp annots
else Name.pp f name
let internal_mk_struct ?default ?fields ?statics ?methods ?exported_objc_methods ?supers ?annots
?dummy () =
let default_ =
{ fields= []
; statics= []
; methods= []
; exported_objc_methods= []
; supers= []
; annots= Annot.Item.empty
; dummy= false }
in
let mk_struct_ ?(default = default_) ?(fields = default.fields) ?(statics = default.statics)
?(methods = default.methods) ?(exported_objc_methods = default.exported_objc_methods)
?(supers = default.supers) ?(annots = default.annots) ?(dummy = default.dummy) () =
{fields; statics; methods; exported_objc_methods; supers; annots; dummy}
in
mk_struct_ ?default ?fields ?statics ?methods ?exported_objc_methods ?supers ?annots ?dummy ()
(** the element typ of the final extensible array in the given typ, if any *)
let rec get_extensible_array_element_typ ~lookup (typ : T.t) =
match typ.desc with
| Tarray {elt} ->
Some elt
| Tstruct name -> (
match lookup name with
| Some {fields} -> (
match List.last fields with
| Some (_, fld_typ, _) ->
get_extensible_array_element_typ ~lookup fld_typ
| None ->
None )
| None ->
None )
| _ ->
None
(** If a struct type with field f, return the type of f. If not, return the default *)
let fld_typ ~lookup ~default fn (typ : T.t) =
(* Note: would be nice migrate it to get_field_info
(for that one needs to ensure adding Tptr to pattern match does not break thing) *)
match typ.desc with
| Tstruct name -> (
match lookup name with
| Some {fields} ->
List.find ~f:(fun (f, _, _) -> Fieldname.equal f fn) fields
|> Option.value_map ~f:snd3 ~default
| None ->
default )
| _ ->
default
type field_info = {typ: typ; annotations: Annot.Item.t; is_static: bool}
let find_field field_list field_name_to_lookup =
List.find_map
~f:(fun (field_name, typ, annotations) ->
if Fieldname.equal field_name field_name_to_lookup then Some (typ, annotations) else None )
field_list
let get_field_info ~lookup field_name_to_lookup (typ : T.t) =
let find_field_info field_list ~is_static =
find_field field_list field_name_to_lookup
|> Option.map ~f:(fun (typ, annotations) -> {typ; annotations; is_static})
in
match typ.desc with
| Tstruct name | Tptr ({desc= Tstruct name}, _) -> (
match lookup name with
| Some {fields= non_statics; statics} ->
(* Search in both lists and return the first found *)
find_field_info statics ~is_static:true
|> IOption.if_none_evalopt ~f:(fun () -> find_field_info non_statics ~is_static:false)
| None ->
None )
| _ ->
None
let get_field_type_and_annotation ~lookup field_name_to_lookup typ =
get_field_info ~lookup field_name_to_lookup typ
|> Option.map ~f:(fun {typ; annotations} -> (typ, annotations))
let is_dummy {dummy} = dummy
end

@ -672,57 +672,3 @@ module Fieldname : sig
val pp : Format.formatter -> t -> unit val pp : Format.formatter -> t -> unit
(** Pretty print a field name. *) (** Pretty print a field name. *)
end end
module Struct : sig
type field = Fieldname.t * typ * Annot.Item.t [@@deriving compare]
type fields = field list
(** Type for a structured value. *)
type t = private
{ fields: fields (** non-static fields *)
; statics: fields (** static fields *)
; supers: Name.t list (** supers *)
; methods: Procname.t list (** methods defined *)
; exported_objc_methods: Procname.t list (** methods in ObjC interface, subset of [methods] *)
; annots: Annot.Item.t (** annotations *)
; dummy: bool (** dummy struct for class including static method *) }
type lookup = Name.t -> t option
val pp_field : Pp.env -> F.formatter -> field -> unit
val pp : Pp.env -> Name.t -> F.formatter -> t -> unit
(** Pretty print a struct type. *)
val internal_mk_struct :
?default:t
-> ?fields:fields
-> ?statics:fields
-> ?methods:Procname.t list
-> ?exported_objc_methods:Procname.t list
-> ?supers:Name.t list
-> ?annots:Annot.Item.t
-> ?dummy:bool
-> unit
-> t
(** Construct a struct_typ, normalizing field types *)
val get_extensible_array_element_typ : lookup:lookup -> typ -> typ option
(** the element typ of the final extensible array in the given typ, if any *)
type field_info = {typ: typ; annotations: Annot.Item.t; is_static: bool}
val get_field_info : lookup:lookup -> Fieldname.t -> typ -> field_info option
(** Lookup for info associated with the field [fn]. None if [typ] has no field named [fn] *)
val fld_typ : lookup:lookup -> default:typ -> Fieldname.t -> typ -> typ
(** If a struct type with field f, return the type of f.
If not, return the default type if given, otherwise raise an exception *)
val get_field_type_and_annotation :
lookup:lookup -> Fieldname.t -> typ -> (typ * Annot.Item.t) option
(** Return the type of the field [fn] and its annotation, None if [typ] has no field named [fn] *)
val is_dummy : t -> bool
end

@ -348,7 +348,7 @@ let override_find ?(check_current_type = true) f tenv proc_name =
let is_override = Staged.unstage (is_override_of proc_name) in let is_override = Staged.unstage (is_override_of proc_name) in
let rec find_super_type super_class_name = let rec find_super_type super_class_name =
Tenv.lookup tenv super_class_name Tenv.lookup tenv super_class_name
|> Option.bind ~f:(fun {Typ.Struct.methods; supers} -> |> Option.bind ~f:(fun {Struct.methods; supers} ->
match List.find ~f:(fun pname -> is_override pname && f pname) methods with match List.find ~f:(fun pname -> is_override pname && f pname) methods with
| None -> | None ->
List.find_map ~f:find_super_type supers List.find_map ~f:find_super_type supers
@ -422,7 +422,7 @@ let is_java_enum tenv typename = is_subtype_of_str tenv typename "java.lang.Enum
for supertypes*) for supertypes*)
let check_class_attributes check tenv = function let check_class_attributes check tenv = function
| Typ.Procname.Java java_pname -> | Typ.Procname.Java java_pname ->
let check_class_annots _ {Typ.Struct.annots} = check annots in let check_class_annots _ {Struct.annots} = check annots in
supertype_exists tenv check_class_annots (Typ.Procname.Java.get_class_type_name java_pname) supertype_exists tenv check_class_annots (Typ.Procname.Java.get_class_type_name java_pname)
| _ -> | _ ->
false false

@ -94,7 +94,7 @@ val implements_android : string -> Tenv.t -> string -> bool
val implements_xmob_utils : string -> Tenv.t -> string -> bool val implements_xmob_utils : string -> Tenv.t -> string -> bool
(** Check whether class implements a class of xmod.utils *) (** Check whether class implements a class of xmod.utils *)
val supertype_exists : Tenv.t -> (Typ.Name.t -> Typ.Struct.t -> bool) -> Typ.Name.t -> bool val supertype_exists : Tenv.t -> (Typ.Name.t -> Struct.t -> bool) -> Typ.Name.t -> bool
(** Holds iff the predicate holds on a supertype of the named type, including the type itself *) (** Holds iff the predicate holds on a supertype of the named type, including the type itself *)
val supertype_find_map_opt : Tenv.t -> (Typ.Name.t -> 'a option) -> Typ.Name.t -> 'a option val supertype_find_map_opt : Tenv.t -> (Typ.Name.t -> 'a option) -> Typ.Name.t -> 'a option

@ -145,7 +145,7 @@ let is_suppressed ?(field_name = None) tenv proc_desc kind =
let is_field_suppressed () = let is_field_suppressed () =
match (field_name, PatternMatch.get_this_type_nonstatic_methods_only proc_attributes) with match (field_name, PatternMatch.get_this_type_nonstatic_methods_only proc_attributes) with
| Some field_name, Some t -> ( | Some field_name, Some t -> (
match Typ.Struct.get_field_type_and_annotation ~lookup field_name t with match Struct.get_field_type_and_annotation ~lookup field_name t with
| Some (_, ia) -> | Some (_, ia) ->
Annotations.ia_has_annotation_with ia annotation_matches Annotations.ia_has_annotation_with ia annotation_matches
| None -> | None ->

@ -613,7 +613,7 @@ let check_after_array_abstraction tenv prop =
| Predicates.Estruct (fsel, _) -> | Predicates.Estruct (fsel, _) ->
List.iter List.iter
~f:(fun (f, se) -> ~f:(fun (f, se) ->
let typ_f = Typ.Struct.fld_typ ~lookup ~default:(Typ.mk Tvoid) f typ in let typ_f = Struct.fld_typ ~lookup ~default:(Typ.mk Tvoid) f typ in
check_se root (offs @ [Predicates.Off_fld (f, typ)]) typ_f se ) check_se root (offs @ [Predicates.Off_fld (f, typ)]) typ_f se )
fsel fsel
in in

@ -835,7 +835,7 @@ module Normalize = struct
(* test if the extensible array at the end of [typ] has elements of type [elt] *) (* test if the extensible array at the end of [typ] has elements of type [elt] *)
let extensible_array_element_typ_equal elt typ = let extensible_array_element_typ_equal elt typ =
Option.value_map ~f:(Typ.equal elt) ~default:false Option.value_map ~f:(Typ.equal elt) ~default:false
(Typ.Struct.get_extensible_array_element_typ ~lookup typ) (Struct.get_extensible_array_element_typ ~lookup typ)
in in
match (e1', e2') with match (e1', e2') with
(* pattern for arrays and extensible structs: (* pattern for arrays and extensible structs:

@ -429,7 +429,7 @@ end = struct
| Predicates.Estruct (fsel, _), t -> | Predicates.Estruct (fsel, _), t ->
let get_field_type f = let get_field_type f =
Option.bind t ~f:(fun t' -> Option.bind t ~f:(fun t' ->
Option.map ~f:fst @@ Typ.Struct.get_field_type_and_annotation ~lookup f t' ) Option.map ~f:fst @@ Struct.get_field_type_and_annotation ~lookup f t' )
in in
List.iter ~f:(fun (f, se) -> strexp_extract (se, get_field_type f)) fsel List.iter ~f:(fun (f, se) -> strexp_extract (se, get_field_type f)) fsel
| Predicates.Earray (len, isel, _), t -> | Predicates.Earray (len, isel, _), t ->
@ -1520,8 +1520,8 @@ let rec sexp_imply tenv source calc_index_frame calc_missing subs se1 se2 typ2 :
let se2' = Predicates.Earray (len, [(Exp.zero, se2)], inst) in let se2' = Predicates.Earray (len, [(Exp.zero, se2)], inst) in
let typ2' = Typ.mk_array typ2 in let typ2' = Typ.mk_array typ2 in
(* In the sexp_imply, struct_imply, array_imply, and sexp_imply_nolhs functions, the typ2 (* In the sexp_imply, struct_imply, array_imply, and sexp_imply_nolhs functions, the typ2
argument is only used by eventually passing its value to Typ.Struct.fld, Exp.Lfield, argument is only used by eventually passing its value to Struct.fld, Exp.Lfield,
Typ.Struct.fld, or Typ.array_elem. None of these are sensitive to the length field Struct.fld, or Typ.array_elem. None of these are sensitive to the length field
of Tarray, so forgetting the length of typ2' here is not a problem. Not one of those of Tarray, so forgetting the length of typ2' here is not a problem. Not one of those
functions use typ.quals either *) functions use typ.quals either *)
sexp_imply tenv source true calc_missing subs se1 se2' typ2' sexp_imply tenv source true calc_missing subs se1 se2' typ2'
@ -1541,7 +1541,7 @@ and struct_imply tenv source calc_missing subs fsel1 fsel2 typ2 :
| (f1, se1) :: fsel1', (f2, se2) :: fsel2' -> ( | (f1, se1) :: fsel1', (f2, se2) :: fsel2' -> (
match Typ.Fieldname.compare f1 f2 with match Typ.Fieldname.compare f1 f2 with
| 0 -> | 0 ->
let typ' = Typ.Struct.fld_typ ~lookup ~default:(Typ.mk Tvoid) f2 typ2 in let typ' = Struct.fld_typ ~lookup ~default:(Typ.mk Tvoid) f2 typ2 in
let subs', se_frame, se_missing = let subs', se_frame, se_missing =
sexp_imply tenv (Exp.Lfield (source, f2, typ2)) false calc_missing subs se1 se2 typ' sexp_imply tenv (Exp.Lfield (source, f2, typ2)) false calc_missing subs se1 se2 typ'
in in
@ -1561,7 +1561,7 @@ and struct_imply tenv source calc_missing subs fsel1 fsel2 typ2 :
in in
(subs', (f1, se1) :: fld_frame, fld_missing) (subs', (f1, se1) :: fld_frame, fld_missing)
| _ -> | _ ->
let typ' = Typ.Struct.fld_typ ~lookup ~default:(Typ.mk Tvoid) f2 typ2 in let typ' = Struct.fld_typ ~lookup ~default:(Typ.mk Tvoid) f2 typ2 in
let subs' = let subs' =
sexp_imply_nolhs tenv (Exp.Lfield (source, f2, typ2)) calc_missing subs se2 typ' sexp_imply_nolhs tenv (Exp.Lfield (source, f2, typ2)) calc_missing subs se2 typ'
in in
@ -1571,7 +1571,7 @@ and struct_imply tenv source calc_missing subs fsel1 fsel2 typ2 :
let fld_missing' = (f2, se2) :: fld_missing in let fld_missing' = (f2, se2) :: fld_missing in
(subs', fld_frame, fld_missing') ) (subs', fld_frame, fld_missing') )
| [], (f2, se2) :: fsel2' -> | [], (f2, se2) :: fsel2' ->
let typ' = Typ.Struct.fld_typ ~lookup ~default:(Typ.mk Tvoid) f2 typ2 in let typ' = Struct.fld_typ ~lookup ~default:(Typ.mk Tvoid) f2 typ2 in
let subs' = let subs' =
sexp_imply_nolhs tenv (Exp.Lfield (source, f2, typ2)) calc_missing subs se2 typ' sexp_imply_nolhs tenv (Exp.Lfield (source, f2, typ2)) calc_missing subs se2 typ'
in in

@ -115,7 +115,7 @@ let rec create_struct_values pname tenv orig_prop footprint_part kind max_stamp
if Typ.Fieldname.equal f f' then (f, res_t', a') else (f', t', a') if Typ.Fieldname.equal f f' then (f, res_t', a') else (f', t', a')
in in
let fields' = let fields' =
List.sort ~compare:Typ.Struct.compare_field (List.map ~f:replace_typ_of_f fields) List.sort ~compare:Struct.compare_field (List.map ~f:replace_typ_of_f fields)
in in
ignore (Tenv.mk_struct tenv ~default:struct_typ ~fields:fields' name) ; ignore (Tenv.mk_struct tenv ~default:struct_typ ~fields:fields' name) ;
(atoms', se, t) (atoms', se, t)
@ -223,7 +223,7 @@ let rec strexp_extend_values_ pname tenv orig_prop footprint_part kind max_stamp
if Typ.Fieldname.equal f f1 then (f1, res_typ', a1) else fta1 if Typ.Fieldname.equal f f1 then (f1, res_typ', a1) else fta1
in in
let fields' = let fields' =
List.sort ~compare:Typ.Struct.compare_field (List.map ~f:replace_fta fields) List.sort ~compare:Struct.compare_field (List.map ~f:replace_fta fields)
in in
ignore (Tenv.mk_struct tenv ~default:struct_typ ~fields:fields' name) ; ignore (Tenv.mk_struct tenv ~default:struct_typ ~fields:fields' name) ;
(res_atoms', Predicates.Estruct (res_fsel', inst'), typ) :: acc (res_atoms', Predicates.Estruct (res_fsel', inst'), typ) :: acc
@ -240,7 +240,7 @@ let rec strexp_extend_values_ pname tenv orig_prop footprint_part kind max_stamp
if Typ.Fieldname.equal f' f then (f, res_typ', a') else (f', t', a') if Typ.Fieldname.equal f' f then (f, res_typ', a') else (f', t', a')
in in
let fields' = let fields' =
List.sort ~compare:Typ.Struct.compare_field (List.map ~f:replace_fta fields) List.sort ~compare:Struct.compare_field (List.map ~f:replace_fta fields)
in in
ignore (Tenv.mk_struct tenv ~default:struct_typ ~fields:fields' name) ; ignore (Tenv.mk_struct tenv ~default:struct_typ ~fields:fields' name) ;
[(atoms', Predicates.Estruct (res_fsel', inst'), typ)] ) [(atoms', Predicates.Estruct (res_fsel', inst'), typ)] )
@ -776,7 +776,7 @@ let add_guarded_by_constraints tenv prop lexp pdesc =
in in
(* if [fld] is annotated with @GuardedBy("mLock"), return mLock *) (* if [fld] is annotated with @GuardedBy("mLock"), return mLock *)
let get_guarded_by_fld_str fld typ = let get_guarded_by_fld_str fld typ =
match Typ.Struct.get_field_type_and_annotation ~lookup fld typ with match Struct.get_field_type_and_annotation ~lookup fld typ with
| Some (_, item_annot) -> ( | Some (_, item_annot) -> (
match extract_guarded_by_str item_annot with match extract_guarded_by_str item_annot with
| Some "this" -> | Some "this" ->
@ -797,7 +797,7 @@ let add_guarded_by_constraints tenv prop lexp pdesc =
in in
let get_fld_strexp_and_typ typ f flds = let get_fld_strexp_and_typ typ f flds =
let match_one (fld, strexp) = let match_one (fld, strexp) =
match Typ.Struct.get_field_type_and_annotation ~lookup fld typ with match Struct.get_field_type_and_annotation ~lookup fld typ with
| Some (fld_typ, _) when f fld fld_typ -> | Some (fld_typ, _) when f fld fld_typ ->
Some (strexp, fld_typ) Some (strexp, fld_typ)
| _ -> | _ ->
@ -1482,7 +1482,7 @@ let attr_has_annot is_annotation tenv prop exp =
let is_strexp_pt_fld_with_annot tenv obj_str is_annotation typ deref_exp (fld, strexp) = let is_strexp_pt_fld_with_annot tenv obj_str is_annotation typ deref_exp (fld, strexp) =
let lookup = Tenv.lookup tenv in let lookup = Tenv.lookup tenv in
let fld_has_annot fld = let fld_has_annot fld =
match Typ.Struct.get_field_type_and_annotation ~lookup fld typ with match Struct.get_field_type_and_annotation ~lookup fld typ with
| Some (_, annot) -> | Some (_, annot) ->
is_annotation annot is_annotation annot
| _ -> | _ ->

@ -1088,8 +1088,7 @@ let check_uninitialize_dangling_deref caller_pname tenv callee_pname actual_pre
let missing_sigma_need_adding_to_tenv tenv hpreds = let missing_sigma_need_adding_to_tenv tenv hpreds =
let field_is_missing struc (field, _) = let field_is_missing struc (field, _) =
not not (List.exists struc.Struct.fields ~f:(fun (fname, _, _) -> Typ.Fieldname.equal fname field))
(List.exists struc.Typ.Struct.fields ~f:(fun (fname, _, _) -> Typ.Fieldname.equal fname field))
in in
let missing_hpred_need_adding_to_tenv hpred = let missing_hpred_need_adding_to_tenv hpred =
match hpred with match hpred with

@ -57,7 +57,7 @@ let mk pdesc =
match BufferOverrunField.get_type fn with match BufferOverrunField.get_type fn with
| None -> | None ->
let lookup = Tenv.lookup tenv in let lookup = Tenv.lookup tenv in
Option.map (typ_of_param_path x) ~f:(Typ.Struct.fld_typ ~lookup ~default:Typ.void fn) Option.map (typ_of_param_path x) ~f:(Struct.fld_typ ~lookup ~default:Typ.void fn)
| some_typ -> | some_typ ->
some_typ ) some_typ )
| SPath.StarField {last_field} -> | SPath.StarField {last_field} ->
@ -65,7 +65,7 @@ let mk pdesc =
| SPath.Callsite {ret_typ} -> | SPath.Callsite {ret_typ} ->
Some ret_typ Some ret_typ
in in
let is_last_field fn (fields : Typ.Struct.field list) = let is_last_field fn (fields : Struct.field list) =
Option.value_map (List.last fields) ~default:false ~f:(fun (last_fn, _, _) -> Option.value_map (List.last fields) ~default:false ~f:(fun (last_fn, _, _) ->
Typ.Fieldname.equal fn last_fn ) Typ.Fieldname.equal fn last_fn )
in in
@ -79,7 +79,7 @@ let mk pdesc =
| Tstruct typename -> | Tstruct typename ->
let opt_struct = Tenv.lookup tenv typename in let opt_struct = Tenv.lookup tenv typename in
Option.value_map opt_struct ~default:false ~f:(fun str -> Option.value_map opt_struct ~default:false ~f:(fun str ->
is_last_field fn str.Typ.Struct.fields ) is_last_field fn str.Struct.fields )
| _ -> | _ ->
true ) true )
in in

@ -136,7 +136,7 @@ module Exec = struct
match Tenv.lookup tenv typename with match Tenv.lookup tenv typename with
| Some str -> | Some str ->
let f = init_field path locs (dimension + 1) in let f = init_field path locs (dimension + 1) in
IList.fold_last ~f ~f_last:(f ?dyn_length) ~init:(mem, 1) str.Typ.Struct.fields |> fst IList.fold_last ~f ~f_last:(f ?dyn_length) ~init:(mem, 1) str.Struct.fields |> fst
| None -> | None ->
mem ) mem )
| _ -> | _ ->

@ -162,7 +162,7 @@ let pname_has_return_annot pname ~attrs_of_pname predicate =
false false
let field_has_annot fieldname (struct_typ : Typ.Struct.t) predicate = let field_has_annot fieldname (struct_typ : Struct.t) predicate =
let fld_has_taint_annot (fname, _, annot) = let fld_has_taint_annot (fname, _, annot) =
Typ.Fieldname.equal fieldname fname && predicate annot Typ.Fieldname.equal fieldname fname && predicate annot
in in
@ -170,7 +170,7 @@ let field_has_annot fieldname (struct_typ : Typ.Struct.t) predicate =
|| List.exists ~f:fld_has_taint_annot struct_typ.statics || List.exists ~f:fld_has_taint_annot struct_typ.statics
let struct_typ_has_annot (struct_typ : Typ.Struct.t) predicate = predicate struct_typ.annots let struct_typ_has_annot (struct_typ : Struct.t) predicate = predicate struct_typ.annots
let ia_is_not_thread_safe ia = ia_ends_with ia not_thread_safe let ia_is_not_thread_safe ia = ia_ends_with ia not_thread_safe

@ -132,7 +132,7 @@ val pdesc_return_annot_ends_with : Procdesc.t -> string -> bool
val ma_has_annotation_with : Annot.Method.t -> (Annot.t -> bool) -> bool val ma_has_annotation_with : Annot.Method.t -> (Annot.t -> bool) -> bool
val field_has_annot : Typ.Fieldname.t -> Typ.Struct.t -> (Annot.Item.t -> bool) -> bool val field_has_annot : Typ.Fieldname.t -> Struct.t -> (Annot.Item.t -> bool) -> bool
val struct_typ_has_annot : Typ.Struct.t -> (Annot.Item.t -> bool) -> bool val struct_typ_has_annot : Struct.t -> (Annot.Item.t -> bool) -> bool
(** return true if the given predicate evaluates to true on some annotation of [struct_typ] *) (** return true if the given predicate evaluates to true on some annotation of [struct_typ] *)

@ -7,13 +7,13 @@
open! IStd open! IStd
module L = Logging module L = Logging
(* Sources: Java Virtual Machine Specification (* Sources: Java Virtual Machine Specification
- Chapter 5. Loading, Linking and Initializing - Chapter 5. Loading, Linking and Initializing
- Chapter 6. The Java Virtual Machine Instruction Set - Chapter 6. The Java Virtual Machine Instruction Set
*) *)
(* TODO (* TODO
- catch / throw with exception classes - catch / throw with exception classes
*) *)
module Payload = SummaryPayload.Make (struct module Payload = SummaryPayload.Make (struct
@ -42,7 +42,7 @@ let rec load_class summary tenv loc astate class_name =
in in
(* finally, recursively load all superclasses *) (* finally, recursively load all superclasses *)
Tenv.lookup tenv class_name Tenv.lookup tenv class_name
|> Option.value_map ~default:[] ~f:(fun tstruct -> tstruct.Typ.Struct.supers) |> Option.value_map ~default:[] ~f:(fun tstruct -> tstruct.Struct.supers)
|> List.fold ~init:astate2 ~f:(load_class summary tenv loc) |> List.fold ~init:astate2 ~f:(load_class summary tenv loc)

@ -11,10 +11,9 @@ open! IStd
type var_info = Clang_ast_t.decl_info * Clang_ast_t.qual_type * Clang_ast_t.var_decl_info * bool type var_info = Clang_ast_t.decl_info * Clang_ast_t.qual_type * Clang_ast_t.var_decl_info * bool
val add_no_duplicates_fields : Typ.Struct.field -> Typ.Struct.field list -> Typ.Struct.field list val add_no_duplicates_fields : Struct.field -> Struct.field list -> Struct.field list
val append_no_duplicates_fields : val append_no_duplicates_fields : Struct.field list -> Struct.field list -> Struct.field list
Typ.Struct.field list -> Typ.Struct.field list -> Typ.Struct.field list
val append_no_duplicates_methods : Typ.Procname.t list -> Typ.Procname.t list -> Typ.Procname.t list val append_no_duplicates_methods : Typ.Procname.t list -> Typ.Procname.t list -> Typ.Procname.t list

@ -369,7 +369,7 @@ let find_override_or_superclass_annotated ~attrs_of_pname is_annot tenv proc_nam
None None
| Some tstruct when Annotations.struct_typ_has_annot tstruct is_annot -> | Some tstruct when Annotations.struct_typ_has_annot tstruct is_annot ->
Some (SuperClass class_name) Some (SuperClass class_name)
| Some (tstruct : Typ.Struct.t) -> ( | Some (tstruct : Struct.t) -> (
match match
List.find_map tstruct.methods ~f:(fun pn -> List.find_map tstruct.methods ~f:(fun pn ->
if is_override pn && is_annotated pn then Some (Override pn) else None ) if is_override pn && is_annotated pn then Some (Override pn) else None )

@ -862,13 +862,13 @@ let should_report_on_proc tenv procdesc =
Procdesc.get_access procdesc <> PredSymb.Private Procdesc.get_access procdesc <> PredSymb.Private
| ObjCClassMethod | ObjCInstanceMethod | ObjCInternalMethod -> | ObjCClassMethod | ObjCInstanceMethod | ObjCInternalMethod ->
Tenv.lookup tenv class_name Tenv.lookup tenv class_name
|> Option.exists ~f:(fun {Typ.Struct.exported_objc_methods} -> |> Option.exists ~f:(fun {Struct.exported_objc_methods} ->
List.mem ~equal:Typ.Procname.equal exported_objc_methods proc_name ) ) List.mem ~equal:Typ.Procname.equal exported_objc_methods proc_name ) )
&& &&
let matcher = ConcurrencyModels.cpp_lock_types_matcher in let matcher = ConcurrencyModels.cpp_lock_types_matcher in
Option.exists (Tenv.lookup tenv class_name) ~f:(fun class_str -> Option.exists (Tenv.lookup tenv class_name) ~f:(fun class_str ->
(* check if the class contains a lock member *) (* check if the class contains a lock member *)
List.exists class_str.Typ.Struct.fields ~f:(fun (_, ft, _) -> List.exists class_str.Struct.fields ~f:(fun (_, ft, _) ->
Option.exists (Typ.name ft) ~f:(fun name -> Option.exists (Typ.name ft) ~f:(fun name ->
QualifiedCppName.Match.match_qualifiers matcher (Typ.Name.qual_name name) ) ) ) QualifiedCppName.Match.match_qualifiers matcher (Typ.Name.qual_name name) ) ) )
| _ -> | _ ->
@ -906,7 +906,7 @@ let should_report_guardedby_violation classname_str ({snapshot; tenv; procname}
(* is the base class a subclass of the one containing the GuardedBy annotation? *) (* is the base class a subclass of the one containing the GuardedBy annotation? *)
PatternMatch.is_subtype tenv base_name (Typ.Name.Java.from_string classname_str) PatternMatch.is_subtype tenv base_name (Typ.Name.Java.from_string classname_str)
&& Tenv.lookup tenv base_name && Tenv.lookup tenv base_name
|> Option.exists ~f:(fun ({fields; statics} : Typ.Struct.t) -> |> Option.exists ~f:(fun ({fields; statics} : Struct.t) ->
let f fld = field_is_annotated_guardedby field_name fld in let f fld = field_is_annotated_guardedby field_name fld in
List.exists fields ~f || List.exists statics ~f ) List.exists fields ~f || List.exists statics ~f )
| _ -> | _ ->

@ -282,7 +282,7 @@ let rec get_executor_thread_annotation_constraint tenv (receiver : HilExp.Access
| FieldOffset (_, field_name) when Typ.Fieldname.is_java field_name -> | FieldOffset (_, field_name) when Typ.Fieldname.is_java field_name ->
Typ.Fieldname.get_class_name field_name Typ.Fieldname.get_class_name field_name
|> Tenv.lookup tenv |> Tenv.lookup tenv
|> Option.map ~f:(fun (tstruct : Typ.Struct.t) -> tstruct.fields @ tstruct.statics) |> Option.map ~f:(fun (tstruct : Struct.t) -> tstruct.fields @ tstruct.statics)
|> Option.bind ~f:(List.find ~f:(fun (fld, _, _) -> Typ.Fieldname.equal fld field_name)) |> Option.bind ~f:(List.find ~f:(fun (fld, _, _) -> Typ.Fieldname.equal fld field_name))
|> Option.bind ~f:(fun (_, _, annot) -> |> Option.bind ~f:(fun (_, _, annot) ->
if Annotations.(ia_ends_with annot for_ui_thread) then Some ForUIThread if Annotations.(ia_ends_with annot for_ui_thread) then Some ForUIThread
@ -312,7 +312,7 @@ let get_run_method_from_runnable tenv runnable =
|> Option.map ~f:(function Typ.{desc= Tptr (typ, _)} -> typ | typ -> typ) |> Option.map ~f:(function Typ.{desc= Tptr (typ, _)} -> typ | typ -> typ)
|> Option.bind ~f:Typ.name |> Option.bind ~f:Typ.name
|> Option.bind ~f:(Tenv.lookup tenv) |> Option.bind ~f:(Tenv.lookup tenv)
|> Option.map ~f:(fun (tstruct : Typ.Struct.t) -> tstruct.methods) |> Option.map ~f:(fun (tstruct : Struct.t) -> tstruct.methods)
|> Option.bind ~f:(List.find ~f:is_run_method) |> Option.bind ~f:(List.find ~f:is_run_method)

@ -341,7 +341,7 @@ let set_constructor_attributes tenv procname (astate : Domain.t) =
(* retrieve its definition *) (* retrieve its definition *)
|> Option.bind ~f:(Tenv.lookup tenv) |> Option.bind ~f:(Tenv.lookup tenv)
(* get the list of methods in the class *) (* get the list of methods in the class *)
|> Option.value_map ~default:[] ~f:(fun (tstruct : Typ.Struct.t) -> tstruct.methods) |> Option.value_map ~default:[] ~f:(fun (tstruct : Struct.t) -> tstruct.methods)
(* keep only the constructors *) (* keep only the constructors *)
|> List.filter ~f:Typ.Procname.(function Java jname -> Java.is_constructor jname | _ -> false) |> List.filter ~f:Typ.Procname.(function Java jname -> Java.is_constructor jname | _ -> false)
(* get the summaries of the constructors *) (* get the summaries of the constructors *)
@ -615,7 +615,7 @@ let should_report pdesc =
let fold_reportable_summaries (tenv, current_summary) clazz ~init ~f = let fold_reportable_summaries (tenv, current_summary) clazz ~init ~f =
let methods = let methods =
Tenv.lookup tenv clazz Tenv.lookup tenv clazz
|> Option.value_map ~default:[] ~f:(fun tstruct -> tstruct.Typ.Struct.methods) |> Option.value_map ~default:[] ~f:(fun tstruct -> tstruct.Struct.methods)
in in
let f acc mthd = let f acc mthd =
Ondemand.get_proc_desc mthd Ondemand.get_proc_desc mthd

@ -77,7 +77,7 @@ let retrieve_fieldname fieldname =
let get_field_name program static tenv cn fs = let get_field_name program static tenv cn fs =
let {Typ.Struct.fields; statics} = JTransType.get_class_struct_typ program tenv cn in let {Struct.fields; statics} = JTransType.get_class_struct_typ program tenv cn in
match match
List.find List.find
~f:(fun (fieldname, _, _) -> String.equal (retrieve_fieldname fieldname) (JBasics.fs_name fs)) ~f:(fun (fieldname, _, _) -> String.equal (retrieve_fieldname fieldname) (JBasics.fs_name fs))

@ -278,7 +278,7 @@ let add_model_fields program classpath_fields cn =
let rec get_method_procname program tenv cn ms method_kind = let rec get_method_procname program tenv cn ms method_kind =
let (_ : Typ.Struct.t) = get_class_struct_typ program tenv cn in let (_ : Struct.t) = get_class_struct_typ program tenv cn in
let return_type_name, method_name, args_type_name = method_signature_names ms in let return_type_name, method_name, args_type_name = method_signature_names ms in
let class_name = Typ.Name.Java.from_string (JBasics.cn_name cn) in let class_name = Typ.Name.Java.from_string (JBasics.cn_name cn) in
let proc_name_java = let proc_name_java =
@ -297,7 +297,7 @@ and translate_method_name program tenv m =
and get_all_fields program tenv cn = and get_all_fields program tenv cn =
let extract_class_fields classname = let extract_class_fields classname =
let {Typ.Struct.fields; statics} = get_class_struct_typ program tenv classname in let {Struct.fields; statics} = get_class_struct_typ program tenv classname in
(statics, fields) (statics, fields)
in in
let trans_fields classname = let trans_fields classname =

@ -28,7 +28,7 @@ val translate_method_name :
JClasspath.program -> Tenv.t -> JCode.jcode Javalib.jmethod -> Typ.Procname.t JClasspath.program -> Tenv.t -> JCode.jcode Javalib.jmethod -> Typ.Procname.t
(** translate the SIL procedure name of the Java method *) (** translate the SIL procedure name of the Java method *)
val get_class_struct_typ : JClasspath.program -> Tenv.t -> JBasics.class_name -> Typ.Struct.t val get_class_struct_typ : JClasspath.program -> Tenv.t -> JBasics.class_name -> Struct.t
(** [get_class_struct_typ program tenv cn] returns the struct_typ representation of the class *) (** [get_class_struct_typ program tenv cn] returns the struct_typ representation of the class *)
val get_class_type_no_pointer : JClasspath.program -> Tenv.t -> JBasics.class_name -> Typ.t val get_class_type_no_pointer : JClasspath.program -> Tenv.t -> JBasics.class_name -> Typ.t

@ -25,7 +25,7 @@ let rec get_type_name {Typ.desc} =
(* A heuristic to guess if the field is actually a Java enum value. *) (* A heuristic to guess if the field is actually a Java enum value. *)
let is_enum_value tenv ~class_typ (field_info : Typ.Struct.field_info) = let is_enum_value tenv ~class_typ (field_info : Struct.field_info) =
(* It is tricky to get this information with 100% precision, but this works in most of (* It is tricky to get this information with 100% precision, but this works in most of
practical cases. practical cases.
In Java, enums are special classes, and enum values are (implicitly generated) static fields in these classes, In Java, enums are special classes, and enum values are (implicitly generated) static fields in these classes,
@ -48,8 +48,8 @@ let get tenv field_name class_typ =
let lookup = Tenv.lookup tenv in let lookup = Tenv.lookup tenv in
(* We currently don't support field-level strict mode annotation, so fetch it from class *) (* We currently don't support field-level strict mode annotation, so fetch it from class *)
let is_strict_mode = is_class_in_strict_mode tenv class_typ in let is_strict_mode = is_class_in_strict_mode tenv class_typ in
Typ.Struct.get_field_info ~lookup field_name class_typ Struct.get_field_info ~lookup field_name class_typ
|> Option.map ~f:(fun (Typ.Struct.{typ= field_typ; annotations} as field_info) -> |> Option.map ~f:(fun (Struct.{typ= field_typ; annotations} as field_info) ->
let is_enum_value = is_enum_value tenv ~class_typ field_info in let is_enum_value = is_enum_value tenv ~class_typ field_info in
let nullability = let nullability =
AnnotatedNullability.of_type_and_annotation field_typ annotations ~is_strict_mode AnnotatedNullability.of_type_and_annotation field_typ annotations ~is_strict_mode

Loading…
Cancel
Save