diff --git a/infer/src/python/PyBuiltin.mli b/infer/src/python/PyBuiltin.mli index 42b638c09d2..8d164bf6889 100644 --- a/infer/src/python/PyBuiltin.mli +++ b/infer/src/python/PyBuiltin.mli @@ -63,7 +63,7 @@ val textual : textual -> builtin val of_string : string -> builtin option -val to_proc_name : builtin -> Textual.qualified_procname +val to_proc_name : builtin -> Textual.QualifiedProcName.t module Set : sig (** This module keeps track of the builtins used by a code unit. Only the necessary Textual diff --git a/infer/src/python/PyCommon.ml b/infer/src/python/PyCommon.ml index 83d7350a497..c708afb3006 100644 --- a/infer/src/python/PyCommon.ml +++ b/infer/src/python/PyCommon.ml @@ -20,7 +20,7 @@ let node_name ?(loc = T.Location.Unknown) value = {T.NodeName.value; loc} let field_name ?(loc = T.Location.Unknown) value = {T.FieldName.value; loc} (* TODO: only deal with toplevel functions for now *) -let qualified_procname ~enclosing_class name : T.qualified_procname = +let qualified_procname ~enclosing_class name : T.QualifiedProcName.t = {enclosing_class= Enclosing enclosing_class; name} @@ -75,9 +75,9 @@ let pyIterItemStruct = let builtins = "$builtins" -let builtin_scope = T.Enclosing T.{TypeName.value= builtins; loc= Unknown} +let builtin_scope = T.QualifiedProcName.Enclosing T.{TypeName.value= builtins; loc= Unknown} -let builtin_name (value : string) : T.qualified_procname = +let builtin_name (value : string) : T.QualifiedProcName.t = let name = T.ProcName.{value; loc= T.Location.Unknown} in {enclosing_class= builtin_scope; name} @@ -118,14 +118,14 @@ let mk_string (s : string) = let get_string = function | T.Exp.Call {proc; args= [arg]; kind= NonVirtual} - when T.equal_qualified_procname proc python_string -> ( + when T.QualifiedProcName.equal proc python_string -> ( match arg with Const (Str s) -> Some s | _ -> None ) | _ -> None let get_tuple_as_list = function - | T.Exp.Call {proc; args; kind= NonVirtual} when T.equal_qualified_procname proc python_tuple -> + | T.Exp.Call {proc; args; kind= NonVirtual} when T.QualifiedProcName.equal proc python_tuple -> Some args | _ -> None @@ -234,20 +234,20 @@ module Ident = struct match path with Empty -> name | Path {path; last} -> to_enclosing_name name path sep last - let to_qualified_procname {root= {name; loc}; path} : T.qualified_procname = + let to_qualified_procname {root= {name; loc}; path} : T.QualifiedProcName.t = match path with | Empty -> - {T.enclosing_class= TopLevel; name= proc_name ~loc name} + {enclosing_class= TopLevel; name= proc_name ~loc name} | Path {path; last} -> let enclosing_class = let value = if List.is_empty path then name else Format.asprintf "%s::%a" name pp_rev_list path in let type_name = type_name ~loc value in - T.Enclosing type_name + T.QualifiedProcName.Enclosing type_name in let name = {T.ProcName.value= last; loc} in - {T.enclosing_class; name} + {enclosing_class; name} let to_type_name ?(static = false) {root= {name; loc}; path} : T.TypeName.t = diff --git a/infer/src/python/PyCommon.mli b/infer/src/python/PyCommon.mli index 9622057de70..d8d3ad26f1a 100644 --- a/infer/src/python/PyCommon.mli +++ b/infer/src/python/PyCommon.mli @@ -20,28 +20,28 @@ val field_name : ?loc:Textual.Location.t -> string -> Textual.FieldName.t val mk_type : string -> Textual.Typ.t val qualified_procname : - enclosing_class:Textual.TypeName.t -> Textual.ProcName.t -> Textual.qualified_procname + enclosing_class:Textual.TypeName.t -> Textual.ProcName.t -> Textual.QualifiedProcName.t -val builtin_name : string -> Textual.qualified_procname +val builtin_name : string -> Textual.QualifiedProcName.t (** Helper function to encode known builtin names correctly *) -val python_int : Textual.qualified_procname +val python_int : Textual.QualifiedProcName.t (** Encoding of Python [int] type. Since Python integers are of arbitrary precision, they are not modeled directly with [int]. *) -val python_float : Textual.qualified_procname +val python_float : Textual.QualifiedProcName.t (** Encoding of Python [float] type. *) -val python_string : Textual.qualified_procname +val python_string : Textual.QualifiedProcName.t (** Encoding of Python [str] type. *) -val python_bytes : Textual.qualified_procname +val python_bytes : Textual.QualifiedProcName.t (** Encoding of Python [bytes] type. *) -val python_bool : Textual.qualified_procname +val python_bool : Textual.QualifiedProcName.t (** Encoding of Python [bool] type. *) -val python_tuple : Textual.qualified_procname +val python_tuple : Textual.QualifiedProcName.t (** Encoding of Python [tuple] type. It is the raw "untyped" one where every item is of type [object]. *) @@ -137,7 +137,7 @@ module Ident : sig val to_string : sep:string -> t -> string - val to_qualified_procname : t -> Textual.qualified_procname + val to_qualified_procname : t -> Textual.QualifiedProcName.t val to_type_name : ?static:bool -> t -> Textual.TypeName.t diff --git a/infer/src/python/PyEnv.ml b/infer/src/python/PyEnv.ml index f2196940bfd..b6d976240ee 100644 --- a/infer/src/python/PyEnv.ml +++ b/infer/src/python/PyEnv.ml @@ -86,8 +86,8 @@ module DataStack = struct | BuiltinBuildClass | Import of {import_path: Ident.t; symbols: string list} | ImportCall of {id: Ident.t; loc: T.Location.t} - | MethodCall of {receiver: T.Exp.t; name: T.qualified_procname} - | StaticCall of {call_name: T.qualified_procname; receiver: T.Exp.t option} + | MethodCall of {receiver: T.Exp.t; name: T.QualifiedProcName.t} + | StaticCall of {call_name: T.QualifiedProcName.t; receiver: T.Exp.t option} | Super | Path of Ident.t | WithContext of @@ -120,9 +120,9 @@ module DataStack = struct | ImportCall {id} -> F.fprintf fmt "ImportCall(%a)" Ident.pp id | MethodCall {receiver; name} -> - F.fprintf fmt "MethodCall(%a, %a)" T.Exp.pp receiver T.pp_qualified_procname name + F.fprintf fmt "MethodCall(%a, %a)" T.Exp.pp receiver T.QualifiedProcName.pp name | StaticCall {call_name; receiver} -> - F.fprintf fmt "StaticCall(%a, %a)" T.pp_qualified_procname call_name (Pp.option T.Exp.pp) + F.fprintf fmt "StaticCall(%a, %a)" T.QualifiedProcName.pp call_name (Pp.option T.Exp.pp) receiver | Super -> F.pp_print_string fmt "Super" @@ -529,7 +529,7 @@ let globals {shared= {globals}} = globals let get_used_builtins {shared= {builtins}} = builtins let register_builtin ({shared} as env) builtin = - PyDebug.p "[register_builtin] %a\n" T.pp_qualified_procname (Builtin.to_proc_name builtin) ; + PyDebug.p "[register_builtin] %a\n" T.QualifiedProcName.pp (Builtin.to_proc_name builtin) ; let register_builtin ({builtins} as env) builtin = {env with builtins= Builtin.Set.register builtins builtin} in diff --git a/infer/src/python/PyEnv.mli b/infer/src/python/PyEnv.mli index c23fbda5ccb..ad3dafcce17 100644 --- a/infer/src/python/PyEnv.mli +++ b/infer/src/python/PyEnv.mli @@ -67,10 +67,10 @@ module DataStack : sig | Import of {import_path: Ident.t; symbols: string list} (** imported module path, with optional name of symbols *) | ImportCall of {id: Ident.t; loc: T.Location.t} (** Static call to export definition *) - | MethodCall of {receiver: T.Exp.t; name: T.qualified_procname} + | MethodCall of {receiver: T.Exp.t; name: T.QualifiedProcName.t} (** Virtual call, usually of a method of a class. Could be an access to a closure that is called straight away *) - | StaticCall of {call_name: T.qualified_procname; receiver: T.Exp.t option} + | StaticCall of {call_name: T.QualifiedProcName.t; receiver: T.Exp.t option} (** call to static method in class. Because we turn some method calls into static ones, we have to keep the receiver around, just in case. *) | Super (** special name to refer to the parent class, like in [super().__init__()] *) diff --git a/infer/src/python/PyTrans.ml b/infer/src/python/PyTrans.ml index c641057abb4..a24598bfb1e 100644 --- a/infer/src/python/PyTrans.ml +++ b/infer/src/python/PyTrans.ml @@ -125,7 +125,7 @@ module Error = struct | CallKeywordBuildClass | RaiseExceptionInvalid of int | RaiseExceptionUnknown of DataStack.cell - | DefaultArgSpecialization of T.qualified_procname * int * int + | DefaultArgSpecialization of T.QualifiedProcName.t * int * int type t = L.error * kind @@ -226,7 +226,7 @@ module Error = struct F.fprintf fmt "RAISE_VARARGS unknown construct %a" DataStack.pp_cell cell | DefaultArgSpecialization (name, param_size, default_size) -> F.fprintf fmt "%a has more default arguments (%d) then actual arguments (%d)" - T.pp_qualified_procname name default_size param_size + T.QualifiedProcName.pp name default_size param_size let class_decl kind = (L.InternalError, ClassDecl kind) @@ -753,7 +753,7 @@ module FUNCTION = struct (* TODO: support nesting. Maybe add to_proc_name to Symbol *) let typ = Ident.to_typ id in let name = Ident.to_constructor id in - let proc : T.qualified_procname = {enclosing_class= TopLevel; name} in + let proc : T.QualifiedProcName.t = {enclosing_class= TopLevel; name} in mk env ~typ proc ) @@ -1121,7 +1121,7 @@ module METHOD = struct let* env, receiver, _ = load_cell env cell in let loc = Env.loc env in let name = proc_name ~loc method_name in - let name : T.qualified_procname = {T.enclosing_class= Enclosing T.TypeName.wildcard; name} in + let name : T.QualifiedProcName.t = {enclosing_class= Enclosing T.TypeName.wildcard; name} in let env = Env.push env (DataStack.MethodCall {receiver; name}) in Ok (env, None) @@ -1183,7 +1183,7 @@ module METHOD = struct (* We're in [LOAD_METHOD] but we fake a static call because of how method resolution works. *) let loc = Env.loc env in let name = proc_name ~loc method_name in - let call_name : T.qualified_procname = {T.enclosing_class= Enclosing super_type; name} in + let call_name : T.QualifiedProcName.t = {enclosing_class= Enclosing super_type; name} in let env = Env.push env (DataStack.StaticCall {call_name; receiver= Some receiver}) in Ok (env, None) | Error (_, err) -> @@ -3002,7 +3002,7 @@ let constructor full_name loc has_init = let mk typ = annotated_type_of_annotation typ in let full_type_name = Ident.to_type_name full_name in let struct_ = T.Typ.(Struct full_type_name) in - let sil_allocate : T.qualified_procname = + let sil_allocate : T.QualifiedProcName.t = {enclosing_class= TopLevel; name= proc_name T.builtin_allocate} in let alloc = T.Exp.call_non_virtual sil_allocate [T.Exp.Typ struct_] in @@ -3068,14 +3068,14 @@ let constructor_stubs ~kind loc class_name = let qualified_name, result_type = match kind with | `Ctor -> - let qualified_name : T.qualified_procname = - {T.enclosing_class= TopLevel; name= Ident.to_constructor class_name} + let qualified_name : T.QualifiedProcName.t = + {enclosing_class= TopLevel; name= Ident.to_constructor class_name} in let result_type = T.Typ.mk_without_attributes @@ Ident.to_typ class_name in (qualified_name, result_type) | `Init -> - let qualified_name : T.qualified_procname = - { T.enclosing_class= Enclosing (Ident.to_type_name class_name) + let qualified_name : T.QualifiedProcName.t = + { enclosing_class= Enclosing (Ident.to_type_name class_name) ; name= proc_name ~loc PyCommon.init__ } in let result_type = T.Typ.mk_without_attributes @@ PyCommon.pyNone in diff --git a/infer/src/textual/Textual.ml b/infer/src/textual/Textual.ml index e301339fd2e..66870705835 100644 --- a/infer/src/textual/Textual.ml +++ b/infer/src/textual/Textual.ml @@ -137,32 +137,33 @@ end = struct let wildcard = {value= "?"; loc= Location.Unknown} end -type enclosing_class = TopLevel | Enclosing of TypeName.t [@@deriving equal, hash, compare] +module QualifiedProcName = struct + type enclosing_class = TopLevel | Enclosing of TypeName.t [@@deriving equal, hash, compare] -type qualified_procname = {enclosing_class: enclosing_class; name: ProcName.t} -[@@deriving compare, equal, hash] -(* procedure name [name] is attached to the name space [enclosing_class] *) + type t = {enclosing_class: enclosing_class; name: ProcName.t} [@@deriving compare, equal, hash] + (* procedure name [name] is attached to the name space [enclosing_class] *) -let pp_enclosing_class fmt = function - | TopLevel -> - () - | Enclosing tname -> - F.fprintf fmt "%a." TypeName.pp tname + let pp_enclosing_class fmt = function + | TopLevel -> + () + | Enclosing tname -> + F.fprintf fmt "%a." TypeName.pp tname -let pp_qualified_procname fmt ({enclosing_class; name} : qualified_procname) = - F.fprintf fmt "%a%a" pp_enclosing_class enclosing_class ProcName.pp name + let pp fmt {enclosing_class; name} = + F.fprintf fmt "%a%a" pp_enclosing_class enclosing_class ProcName.pp name -let qualified_procname_contains_wildcard {enclosing_class} = - match enclosing_class with - | Enclosing class_name -> - TypeName.equal class_name TypeName.wildcard - | TopLevel -> - false + let contains_wildcard {enclosing_class} = + match enclosing_class with + | Enclosing class_name -> + TypeName.equal class_name TypeName.wildcard + | TopLevel -> + false -let qualified_procname_name {name} = name + let name {name} = name +end type qualified_fieldname = {enclosing_class: TypeName.t; name: FieldName.t} (* field name [name] must be declared in type [enclosing_class] *) @@ -305,9 +306,9 @@ let pp_list_with_comma pp fmt l = Pp.seq ~sep:", " pp fmt l module ProcSig = struct module T = struct type t = - | Hack of {qualified_name: qualified_procname; arity: int option} - | Python of {qualified_name: qualified_procname; arity: int option} - | Other of {qualified_name: qualified_procname} + | Hack of {qualified_name: QualifiedProcName.t; arity: int option} + | Python of {qualified_name: QualifiedProcName.t; arity: int option} + | Other of {qualified_name: QualifiedProcName.t} [@@deriving equal, hash] end @@ -323,14 +324,14 @@ end module ProcDecl = struct type t = - { qualified_name: qualified_procname + { qualified_name: QualifiedProcName.t ; formals_types: Typ.annotated list option ; result_type: Typ.annotated ; attributes: Attr.t list } let formals_or_die ?(context = "") {qualified_name; formals_types} = Option.value_or_thunk formals_types ~default:(fun () -> - L.die InternalError "List of formals is unknown in %a: %s" pp_qualified_procname + L.die InternalError "List of formals is unknown in %a: %s" QualifiedProcName.pp qualified_name context ) @@ -353,11 +354,11 @@ module ProcDecl = struct let pp fmt {qualified_name; formals_types; result_type; attributes} = List.iter attributes ~f:(fun attr -> F.fprintf fmt "%a " Attr.pp attr) ; - F.fprintf fmt "%a(%a) : %a" pp_qualified_procname qualified_name pp_formals formals_types + F.fprintf fmt "%a(%a) : %a" QualifiedProcName.pp qualified_name pp_formals formals_types Typ.pp_annotated result_type - let make_toplevel_name string loc : qualified_procname = + let make_toplevel_name string loc : QualifiedProcName.t = let name : ProcName.t = {value= string; loc} in {enclosing_class= TopLevel; name} @@ -387,7 +388,7 @@ module ProcDecl = struct make_toplevel_name value Location.Unknown - let to_unop ({enclosing_class; name} : qualified_procname) : Unop.t option = + let to_unop ({enclosing_class; name} : QualifiedProcName.t) : Unop.t option = match enclosing_class with | TopLevel -> List.Assoc.find ~equal:String.equal unop_inverse_table name.value @@ -476,24 +477,24 @@ module ProcDecl = struct let binop_inverse_map = inverse_assoc_list binop_table |> Map.Poly.of_alist_exn let is_allocate_object_builtin qualified_name = - equal_qualified_procname allocate_object_name qualified_name + QualifiedProcName.equal allocate_object_name qualified_name let is_allocate_array_builtin qualified_name = - equal_qualified_procname allocate_array_name qualified_name + QualifiedProcName.equal allocate_array_name qualified_name let is_lazy_class_initialize_builtin qualified_name = - equal_qualified_procname lazy_class_initialize_name qualified_name + QualifiedProcName.equal lazy_class_initialize_name qualified_name let is_get_lazy_class_builtin qualified_name = - equal_qualified_procname get_lazy_class_name qualified_name + QualifiedProcName.equal get_lazy_class_name qualified_name - let is_cast_builtin = equal_qualified_procname cast_name + let is_cast_builtin = QualifiedProcName.equal cast_name - let is_instanceof_builtin = equal_qualified_procname instanceof_name + let is_instanceof_builtin = QualifiedProcName.equal instanceof_name let is_type_builtin qualified_name = is_allocate_object_builtin qualified_name @@ -503,7 +504,7 @@ module ProcDecl = struct || is_instanceof_builtin qualified_name - let is_side_effect_free_sil_expr ({enclosing_class; name} as qualified_name : qualified_procname) + let is_side_effect_free_sil_expr ({enclosing_class; name} as qualified_name : QualifiedProcName.t) = is_cast_builtin qualified_name || @@ -518,7 +519,7 @@ module ProcDecl = struct let is_not_regular_proc proc = is_type_builtin proc || is_side_effect_free_sil_expr proc - let to_binop ({enclosing_class; name} : qualified_procname) : Binop.t option = + let to_binop ({enclosing_class; name} : QualifiedProcName.t) : Binop.t option = match enclosing_class with TopLevel -> Map.Poly.find binop_inverse_map name.value | _ -> None @@ -573,7 +574,7 @@ module Exp = struct | Index of t * t (* | Sizeof of sizeof_data *) | Const of Const.t - | Call of {proc: qualified_procname; args: t list; kind: call_kind} + | Call of {proc: QualifiedProcName.t; args: t list; kind: call_kind} | Typ of Typ.t let call_non_virtual proc args = Call {proc; args; kind= NonVirtual} @@ -613,11 +614,11 @@ module Exp = struct | Virtual -> ( match args with | recv :: other -> - F.fprintf fmt "%a.%a%a" pp recv pp_qualified_procname proc pp_list other + F.fprintf fmt "%a.%a%a" pp recv QualifiedProcName.pp proc pp_list other | _ -> - L.die InternalError "virtual call with 0 args: %a" pp_qualified_procname proc ) + L.die InternalError "virtual call with 0 args: %a" QualifiedProcName.pp proc ) | NonVirtual -> - F.fprintf fmt "%a%a" pp_qualified_procname proc pp_list args ) + F.fprintf fmt "%a%a" QualifiedProcName.pp proc pp_list args ) | Typ typ -> F.fprintf fmt "<%a>" Typ.pp typ @@ -820,7 +821,7 @@ module ProcDesc = struct let formals_types = formals t in match List.zip formals_types params with | Ok args -> - F.fprintf fmt "%a(%a) : %a" pp_qualified_procname procdecl.qualified_name + F.fprintf fmt "%a(%a) : %a" QualifiedProcName.pp procdecl.qualified_name (pp_list_with_comma pp) args Typ.pp_annotated procdecl.result_type | _ -> L.die InternalError diff --git a/infer/src/textual/Textual.mli b/infer/src/textual/Textual.mli index f1fe8ee0856..43f67baa44c 100644 --- a/infer/src/textual/Textual.mli +++ b/infer/src/textual/Textual.mli @@ -60,17 +60,18 @@ module TypeName : sig val wildcard : t end -type enclosing_class = TopLevel | Enclosing of TypeName.t +module QualifiedProcName : sig + type enclosing_class = TopLevel | Enclosing of TypeName.t -type qualified_procname = {enclosing_class: enclosing_class; name: ProcName.t} -[@@deriving compare, equal, hash] -(* procedure name [name] is attached to the name space [enclosing_class] *) + type t = {enclosing_class: enclosing_class; name: ProcName.t} [@@deriving compare, equal, hash] + (* procedure name [name] is attached to the name space [enclosing_class] *) -val pp_qualified_procname : F.formatter -> qualified_procname -> unit + val pp : F.formatter -> t -> unit -val qualified_procname_name : qualified_procname -> ProcName.t + val name : t -> ProcName.t -val qualified_procname_contains_wildcard : qualified_procname -> bool + val contains_wildcard : t -> bool +end type qualified_fieldname = {enclosing_class: TypeName.t; name: FieldName.t} (* field name [name] must be declared in type [enclosing_class] *) @@ -154,14 +155,14 @@ end module ProcSig : sig (** Signature uniquely identifies a called procedure in a target language. *) type t = - | Hack of {qualified_name: qualified_procname; arity: int option} + | Hack of {qualified_name: QualifiedProcName.t; arity: int option} (** Hack doesn't support function overloading but it does support functions with default arguments. This means that a procedure is uniquely identified by its name and the number of arguments. *) - | Python of {qualified_name: qualified_procname; arity: int option} + | Python of {qualified_name: QualifiedProcName.t; arity: int option} (** Python supports function overloading and default arguments. This means that a procedure is uniquely identified by its name and the number of arguments. *) - | Other of {qualified_name: qualified_procname} + | Other of {qualified_name: QualifiedProcName.t} (** Catch-all case for languages that currently lack support for function overloading at the Textual level. @@ -172,14 +173,14 @@ module ProcSig : sig add support for other languages. *) [@@deriving equal, hash] - val to_qualified_procname : t -> qualified_procname + val to_qualified_procname : t -> QualifiedProcName.t module Hashtbl : Hashtbl.S with type key = t end module ProcDecl : sig type t = - { qualified_name: qualified_procname + { qualified_name: QualifiedProcName.t ; formals_types: Typ.annotated list option (** The list of formal argument types may be unknown. Currently, it is possible only for external function declarations when translating from Hack and is denoted with a @@ -194,33 +195,33 @@ module ProcDecl : sig val pp : F.formatter -> t -> unit - val of_unop : Unop.t -> qualified_procname + val of_unop : Unop.t -> QualifiedProcName.t - val to_unop : qualified_procname -> Unop.t option + val to_unop : QualifiedProcName.t -> Unop.t option - val of_binop : Binop.t -> qualified_procname + val of_binop : Binop.t -> QualifiedProcName.t - val to_binop : qualified_procname -> Binop.t option + val to_binop : QualifiedProcName.t -> Binop.t option - val is_cast_builtin : qualified_procname -> bool + val is_cast_builtin : QualifiedProcName.t -> bool - val is_instanceof_builtin : qualified_procname -> bool + val is_instanceof_builtin : QualifiedProcName.t -> bool - val allocate_object_name : qualified_procname + val allocate_object_name : QualifiedProcName.t - val is_allocate_object_builtin : qualified_procname -> bool + val is_allocate_object_builtin : QualifiedProcName.t -> bool - val allocate_array_name : qualified_procname + val allocate_array_name : QualifiedProcName.t - val is_allocate_array_builtin : qualified_procname -> bool + val is_allocate_array_builtin : QualifiedProcName.t -> bool - val is_get_lazy_class_builtin : qualified_procname -> bool + val is_get_lazy_class_builtin : QualifiedProcName.t -> bool - val is_lazy_class_initialize_builtin : qualified_procname -> bool + val is_lazy_class_initialize_builtin : QualifiedProcName.t -> bool - val is_side_effect_free_sil_expr : qualified_procname -> bool + val is_side_effect_free_sil_expr : QualifiedProcName.t -> bool - val is_not_regular_proc : qualified_procname -> bool + val is_not_regular_proc : QualifiedProcName.t -> bool val is_curry_invoke : t -> bool end @@ -243,14 +244,14 @@ module Exp : sig | Field of {exp: t; field: qualified_fieldname} (** field offset *) | Index of t * t (** an array index offset: [exp1\[exp2\]] *) | Const of Const.t - | Call of {proc: qualified_procname; args: t list; kind: call_kind} + | Call of {proc: QualifiedProcName.t; args: t list; kind: call_kind} | Typ of Typ.t - val call_non_virtual : qualified_procname -> t list -> t + val call_non_virtual : QualifiedProcName.t -> t list -> t - val call_virtual : qualified_procname -> t -> t list -> t + val call_virtual : QualifiedProcName.t -> t -> t list -> t - val call_sig : qualified_procname -> t list -> Lang.t option -> ProcSig.t + val call_sig : QualifiedProcName.t -> t list -> Lang.t option -> ProcSig.t (* logical not ! *) val not : t -> t diff --git a/infer/src/textual/TextualBasicVerification.ml b/infer/src/textual/TextualBasicVerification.ml index 6718c9edd95..21356d4cf88 100644 --- a/infer/src/textual/TextualBasicVerification.ml +++ b/infer/src/textual/TextualBasicVerification.ml @@ -12,9 +12,9 @@ type error = | UnknownField of qualified_fieldname (* TODO(arr): This is too specific to the Hack use-case. We should really check if there are other overloads and provide an error message based on this. *) - | UnknownProc of {proc: qualified_procname; args: int} - | UnknownLabel of {label: NodeName.t; pname: qualified_procname} - | WrongArgNumber of {proc: qualified_procname; args: int; formals: int; loc: Location.t} + | UnknownProc of {proc: QualifiedProcName.t; args: int} + | UnknownLabel of {label: NodeName.t; pname: QualifiedProcName.t} + | WrongArgNumber of {proc: QualifiedProcName.t; args: int; formals: int; loc: Location.t} let error_loc = function | UnknownField {enclosing_class; _} -> @@ -35,13 +35,13 @@ let pp_error sourcefile fmt error = F.fprintf fmt "field %a.%a is not declared" TypeName.pp enclosing_class FieldName.pp name | UnknownProc {proc; args} -> F.fprintf fmt "function %a which can be called with %d arguments is not declared" - pp_qualified_procname proc args + QualifiedProcName.pp proc args | UnknownLabel {label; pname} -> - F.fprintf fmt "label %a is not declared in function %a" NodeName.pp label - pp_qualified_procname pname + F.fprintf fmt "label %a is not declared in function %a" NodeName.pp label QualifiedProcName.pp + pname | WrongArgNumber {proc; args; formals} -> F.fprintf fmt "function %a called with %d arguments while declared with %d parameters" - pp_qualified_procname proc args formals + QualifiedProcName.pp proc args formals let verify_decl ~env errors (decl : Module.decl) = @@ -61,7 +61,7 @@ let verify_decl ~env errors (decl : Module.decl) = else let procsig = Exp.call_sig proc args (TextualDecls.lang env) in match TextualDecls.get_procdecl env procsig with - | None when qualified_procname_contains_wildcard proc -> + | None when QualifiedProcName.contains_wildcard proc -> errors | None -> UnknownProc {proc; args= List.length args} :: errors diff --git a/infer/src/textual/TextualDecls.ml b/infer/src/textual/TextualDecls.ml index c5556fe596d..9fcbd5c0924 100644 --- a/infer/src/textual/TextualDecls.ml +++ b/infer/src/textual/TextualDecls.ml @@ -39,9 +39,9 @@ let init sourcefile lang = type error = | FieldDeclaredTwice of qualified_fieldname | GlobalDeclaredTwice of Global.t - | NodeImplementedTwice of qualified_procname * NodeName.t - | ParameterDeclatedTwice of qualified_procname * VarName.t - | ProcImplementedTwice of qualified_procname + | NodeImplementedTwice of QualifiedProcName.t * NodeName.t + | ParameterDeclatedTwice of QualifiedProcName.t * VarName.t + | ProcImplementedTwice of QualifiedProcName.t | StructDeclaredTwice of TypeName.t let pp_error sourcefile fmt err = @@ -54,12 +54,12 @@ let pp_error sourcefile fmt err = F.fprintf fmt "global %a is declared twice in the same file" VarName.pp global.name | NodeImplementedTwice (qualified_procname, label) -> F.fprintf fmt "node %a is implemented twice in the same function %a" NodeName.pp label - pp_qualified_procname qualified_procname + QualifiedProcName.pp qualified_procname | ParameterDeclatedTwice (qualified_procname, varname) -> F.fprintf fmt "parameter %a is declared twice in the same function %a" VarName.pp varname - pp_qualified_procname qualified_procname + QualifiedProcName.pp qualified_procname | ProcImplementedTwice qualified_procname -> - F.fprintf fmt "function %a is implemented twice in the same file" pp_qualified_procname + F.fprintf fmt "function %a is implemented twice in the same file" QualifiedProcName.pp qualified_procname | StructDeclaredTwice tname -> F.fprintf fmt "type %a is declared twice in the same file" TypeName.pp tname diff --git a/infer/src/textual/TextualMenhir.mly b/infer/src/textual/TextualMenhir.mly index 5b5dbe9f86b..f84cee026f0 100644 --- a/infer/src/textual/TextualMenhir.mly +++ b/infer/src/textual/TextualMenhir.mly @@ -77,8 +77,8 @@ %start Textual.Module.t> main %type attribute %type declaration -%type qualified_pname_and_lparen -%type opt_qualified_pname_and_lparen +%type qualified_pname_and_lparen +%type opt_qualified_pname_and_lparen %type fname %type nname %type tname @@ -133,12 +133,12 @@ main: name_and_lparen: | proc_ident=opt_qualified_pname_and_lparen - { match (proc_ident : qualified_procname).enclosing_class with + { match (proc_ident : QualifiedProcName.t).enclosing_class with | Enclosing _ -> let loc = location_of_pos $startpos(proc_ident) in - let string = Format.asprintf "%a" pp_qualified_procname proc_ident in + let string = Format.asprintf "%a" QualifiedProcName.pp proc_ident in raise (SpecialSyntaxError (loc, string)) - | _ -> (proc_ident : qualified_procname).name.value } + | _ -> (proc_ident : QualifiedProcName.t).name.value } fname: | id=ident @@ -171,20 +171,20 @@ opt_qualified_pname_and_lparen: { let enclosing, id = proc_ident in let loc = location_of_pos $startpos(proc_ident) in let name : ProcName.t = { value=id; loc } in - let enclosing_class : enclosing_class = + let enclosing_class = Option.value_map enclosing - ~default:TopLevel - ~f:(fun value -> Enclosing {value; loc}) + ~default:QualifiedProcName.TopLevel + ~f:(fun value -> QualifiedProcName.Enclosing {value; loc}) in - ( {enclosing_class; name} : qualified_procname) + ( {enclosing_class; name} : QualifiedProcName.t) } qualified_pname_and_lparen: | proc_ident=opt_qualified_pname_and_lparen - { match (proc_ident : qualified_procname).enclosing_class with + { match (proc_ident : QualifiedProcName.t).enclosing_class with | Enclosing tname when String.equal tname.TypeName.value "?" -> let loc = location_of_pos $startpos(proc_ident) in - let string = Format.asprintf "%a" pp_qualified_procname proc_ident in + let string = Format.asprintf "%a" QualifiedProcName.pp proc_ident in raise (SpecialSyntaxError (loc, string)) | _ -> proc_ident } diff --git a/infer/src/textual/TextualSil.ml b/infer/src/textual/TextualSil.ml index 0acd403eb95..78cf1bfe473 100644 --- a/infer/src/textual/TextualSil.ml +++ b/infer/src/textual/TextualSil.ml @@ -292,10 +292,10 @@ module ProcDeclBridge = struct match pname with | Java jpname -> let enclosing_class = - Enclosing (TypeName.of_java_name (Procname.Java.get_class_name jpname)) + QualifiedProcName.Enclosing (TypeName.of_java_name (Procname.Java.get_class_name jpname)) in let name = mangle_java_procname jpname |> ProcName.of_java_name in - let qualified_name : qualified_procname = {enclosing_class; name} in + let qualified_name : QualifiedProcName.t = {enclosing_class; name} in let formals_types = Procname.Java.get_parameters jpname |> List.map ~f:TypBridge.annotated_of_sil in @@ -317,16 +317,16 @@ module ProcDeclBridge = struct let hack_class_name_to_sil = function - | TopLevel -> + | QualifiedProcName.TopLevel -> None - | Enclosing name -> + | QualifiedProcName.Enclosing name -> Some (HackClassName.make name.value) let python_class_name_to_sil = function - | TopLevel -> + | QualifiedProcName.TopLevel -> None - | Enclosing name -> + | QualifiedProcName.Enclosing name -> Some (PythonClassName.make name.value) @@ -601,7 +601,7 @@ module ExpBridge = struct BinOp (binop, aux exp1, aux exp2) | _, _, _, _ -> L.die InternalError "Internal error: procname %a has an unexpected property" - pp_qualified_procname proc + QualifiedProcName.pp proc (* FIXME: transform instruction to put call at head of expressions *) ) | Typ _ -> L.die InternalError "Internal error: type expressions should not appear outside builtins" @@ -748,7 +748,7 @@ module InstrBridge = struct match TextualDecls.get_procdecl decls_env procsig with | Some procname -> procname - | None when qualified_procname_contains_wildcard proc -> + | None when QualifiedProcName.contains_wildcard proc -> let textual_ret_typ = (* Declarations with unknown formals are expected in Hack/Python. Assume that unknown return types are *HackMixed/*PyObject respectively. *) @@ -927,7 +927,7 @@ module ProcDescBridge = struct l | Unequal_lengths -> L.die InternalError "procname %a has not the same number of arg names and arg types" - pp_qualified_procname procdecl.qualified_name + QualifiedProcName.pp procdecl.qualified_name let build_locals lang {locals} = diff --git a/infer/src/textual/TextualTypeVerification.ml b/infer/src/textual/TextualTypeVerification.ml index c93038e72f6..2e6eeee6e4b 100644 --- a/infer/src/textual/TextualTypeVerification.ml +++ b/infer/src/textual/TextualTypeVerification.ml @@ -75,7 +75,7 @@ let pp_expected_kind fmt expected = type error = | TypeMismatch of {exp: Exp.t; typ: Typ.t; expected: expected_kind; loc: Location.t} | WrongNumberBuiltinArgs of - { proc: qualified_procname + { proc: QualifiedProcName.t ; expected: int ; at_least: bool (* is the number of expected arguments a lower bound *) ; given: int @@ -83,7 +83,7 @@ type error = | IdentAssignedTwice of {id: Ident.t; typ1: Typ.t; typ2: Typ.t; loc1: Location.t; loc2: Location.t} | IdentReadBeforeWrite of {id: Ident.t; loc: Location.t} | VarTypeNotDeclared of {var: VarName.t; loc: Location.t} - | MissingDeclaration of {proc: qualified_procname; loc: Location.t} + | MissingDeclaration of {proc: QualifiedProcName.t; loc: Location.t} | ArityMismatch of {length1: int; length2: int; loc: Location.t} let error_loc = function @@ -113,7 +113,7 @@ let pp_error sourcefile fmt error = pp_expected_kind expected | WrongNumberBuiltinArgs {proc; expected; at_least; given; _} -> F.fprintf fmt "builtin %a is called with %d arguments while it expects %s%d" - pp_qualified_procname proc given + QualifiedProcName.pp proc given (if at_least then "at least " else "") expected | IdentAssignedTwice {id; typ1; typ2; loc2; _} -> @@ -124,7 +124,7 @@ let pp_error sourcefile fmt error = | VarTypeNotDeclared {var; _} -> F.fprintf fmt "variable %a has not been declared" VarName.pp var | MissingDeclaration {proc} -> - F.fprintf fmt "procname %a should be user-declared or a builtin" pp_qualified_procname proc + F.fprintf fmt "procname %a should be user-declared or a builtin" QualifiedProcName.pp proc | ArityMismatch {length1; length2; loc} -> F.fprintf fmt "iter2 was run on lists of different lengths at %a: %d vs %d" Location.pp loc length1 length2 @@ -153,8 +153,8 @@ let mk_type_mismatch_error expected loc exp typ : error = TypeMismatch {exp; typ; expected; loc} -let mk_missing_declaration_error (proc : qualified_procname) : error = - let name = qualified_procname_name proc in +let mk_missing_declaration_error (proc : QualifiedProcName.t) : error = + let name = QualifiedProcName.name proc in let {ProcName.loc} = name in MissingDeclaration {proc; loc} @@ -354,7 +354,7 @@ let typeof_const (const : Const.t) : Typ.t = Float -let typeof_reserved_proc (proc : qualified_procname) : (Typ.t * Typ.t list option) monad = +let typeof_reserved_proc (proc : QualifiedProcName.t) : (Typ.t * Typ.t list option) monad = if ProcDecl.to_binop proc |> Option.is_some then ret (Typ.Int, Some [Typ.Int; Typ.Int]) else if ProcDecl.to_unop proc |> Option.is_some then ret (Typ.Int, Some [Typ.Int]) else @@ -372,7 +372,7 @@ let typeof_procname (procsig : ProcSig.t) : (Typ.t * Typ.t list option) monad = |> Option.map ~f:(fun formals_types -> List.map formals_types ~f:(fun {Typ.typ} -> typ)) in ret (procdecl.result_type.typ, formals_types) state - | None when ProcSig.to_qualified_procname procsig |> qualified_procname_contains_wildcard -> + | None when ProcSig.to_qualified_procname procsig |> QualifiedProcName.contains_wildcard -> ret (Typ.Void, None) state | None -> (typeof_reserved_proc (ProcSig.to_qualified_procname procsig)) state @@ -475,7 +475,7 @@ and typeof_exp (exp : Exp.t) : (Exp.t * Typ.t) monad = ret (exp, Typ.Struct TypeNameBridge.sil_type_of_types) -and typeof_allocate_builtin (proc : qualified_procname) args = +and typeof_allocate_builtin (proc : QualifiedProcName.t) args = match args with | [Exp.Typ typ] -> ret (Exp.Call {proc; args; kind= Exp.NonVirtual}, Typ.Ptr typ) @@ -493,7 +493,7 @@ and typeof_allocate_builtin (proc : qualified_procname) args = abort -and typeof_allocate_array_builtin (proc : qualified_procname) args = +and typeof_allocate_array_builtin (proc : QualifiedProcName.t) args = match args with | Exp.Typ typ :: dim :: dims -> let* loc = get_location in @@ -517,7 +517,7 @@ and typeof_allocate_array_builtin (proc : qualified_procname) args = abort -and typeof_cast_builtin (proc : qualified_procname) args = +and typeof_cast_builtin (proc : QualifiedProcName.t) args = match args with | [Exp.Typ typ; exp] -> let+ exp, _old_typ = typeof_exp exp in @@ -536,7 +536,7 @@ and typeof_cast_builtin (proc : qualified_procname) args = abort -and typeof_instanceof_builtin (proc : qualified_procname) args = +and typeof_instanceof_builtin (proc : QualifiedProcName.t) args = match args with | [exp1; (Exp.Typ _ as exp2)] -> let+ exp1, _ = typeof_exp exp1 in