You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

82 lines
2.2 KiB

(*
* 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.
*)
(** The Smallfoot Intermediate Language: Annotations *)
open! IStd
module F = Format
type parameters = string list [@@deriving compare]
(** Type to represent one @Annotation. *)
type t =
{ class_name: string (** name of the annotation *)
; parameters: parameters (** currently only one string parameter *) }
[@@deriving compare]
let volatile = {class_name= "volatile"; parameters= []}
let final = {class_name= "final"; parameters= []}
(** Pretty print an annotation. *)
let prefix = match Language.curr_language_is Java with true -> "@" | false -> "_"
let pp fmt annotation =
F.fprintf fmt "%s%s%s" prefix annotation.class_name
(String.concat ~sep:"," annotation.parameters)
module Item = struct
(* Don't use nonrec due to https://github.com/janestreet/ppx_compare/issues/2 *)
(* type nonrec t = list (t, bool) [@@deriving compare]; *)
(** Annotation for one item: a list of annotations with visibility. *)
type t_ = (t * bool) list [@@deriving compare]
type t = t_ [@@deriving compare]
(** Pretty print an item annotation. *)
let pp fmt ann =
let pp fmt (a, _) = pp fmt a in
F.fprintf fmt "<%a>" (Pp.seq pp) ann
(** Empty item annotation. *)
let empty = []
(** Check if the item annotation is empty. *)
let is_empty ia = List.is_empty ia
end
module Class = struct
let objc_str = "ObjC-Class"
let cpp_str = "Cpp-Class"
let of_string class_string = [({class_name= class_string; parameters= []}, true)]
let objc = of_string objc_str
let cpp = of_string cpp_str
end
module Method = struct
type t = {return: Item.t; params: Item.t list}
[explore] print only non-default values in the attributes Summary: Attributes have lots of fields, but the majority is usually the same from one procedure to the other. This attempts to print only non-default values, where the default is the "empty" attributes (as opposed to the "most commonly seen value" for each field), in an attempt to be predictible. This is largely something that should be done with a ppx but since there's only one use case it didn't seem worth the trouble. Output of `infer explore --procedures --procedures-attributes --procedures-name` before: ``` test: examples/hello.c test <defined> {access= <Default>; captured= []; did_preanalysis= false; err_log= [ ]; exceptions= []; formals= []; const_formals= []; by_vals= []; func_attributes= []; is_abstract= false; is_bridge_method= false; is_defined= true; is_cpp_noexcept_method= false; is_java_synchronized_method= false; is_model= false; is_specialized= false; is_synthetic_method= false; clang_method_kind= C_FUNCTION; loc= line 12, column 1; translation_unit= Some examples/hello.c; locals= [{name= s;typ= ;attributes= }]; method_annotation= <> (); objc_accessor= None; proc_flags= []; proc_name= test; ret_type= ; source_file_captured=examples/hello.c} int Hello.test(): examples/Hello.java int Hello.test() <defined> {access= <Default>; captured= []; did_preanalysis= false; err_log= [ ]; exceptions= []; formals= [(this,)]; const_formals= []; by_vals= [ ]; func_attributes= []; is_abstract= false; is_bridge_method= false; is_defined= true; is_cpp_noexcept_method= false; is_java_synchronized_method= false; is_model= false; is_specialized= false; is_synthetic_method= false; clang_method_kind= C_FUNCTION; loc= line 11; translation_unit= None; locals= [{name= $irvar0;typ= ;attributes= }; {name= s;typ= ;attributes= }]; method_annotation= <> (); objc_accessor= None; proc_flags= []; proc_name= int Hello.test(); ret_type= ; source_file_captured=examples/Hello.java} Hello.<init>(): examples/Hello.java Hello.<init>() <defined> {access= <Default>; captured= []; did_preanalysis= false; err_log= [ ]; exceptions= []; formals= [(this,)]; const_formals= []; by_vals= [ ]; func_attributes= []; is_abstract= false; is_bridge_method= false; is_defined= true; is_cpp_noexcept_method= false; is_java_synchronized_method= false; is_model= false; is_specialized= false; is_synthetic_method= false; clang_method_kind= C_FUNCTION; loc= line 10; translation_unit= None; locals= []; method_annotation= <> (); objc_accessor= None; proc_flags= []; proc_name= Hello.<init>(); ret_type= ; source_file_captured=examples/Hello.java} ``` Now: ``` test source_file: examples/hello.c proc_name: test attribute_kind: <defined> attributes: { proc_name= test ; source_file_captured= examples/hello.c ; formals= [] ; is_defined= true ; loc= line 12, column 1 ; translation_unit= <Some examples/hello.c> ; locals= [{ name= s; typ= int* }] ; ret_type= void } int Hello.test() source_file: examples/Hello.java proc_name: int Hello.test() attribute_kind: <defined> attributes: { proc_name= int Hello.test() ; source_file_captured= examples/Hello.java ; formals= [(this,Hello*)] ; is_defined= true ; loc= line 11 ; locals= [{ name= $irvar0; typ= void }; { name= s; typ= java.lang.String* }] ; ret_type= int } Hello.<init>() source_file: examples/Hello.java proc_name: Hello.<init>() attribute_kind: <defined> attributes: { proc_name= Hello.<init>() ; source_file_captured= examples/Hello.java ; formals= [(this,Hello*)] ; is_defined= true ; loc= line 10 ; ret_type= void } ``` Reviewed By: mbouaziz Differential Revision: D7757890 fbshipit-source-id: 5507ec6
7 years ago
(** Pretty print a method annotation. *)
let pp s fmt {return; params} =
F.fprintf fmt "%a %s(%a)" Item.pp return s (Pp.seq Item.pp) params
(** Empty method annotation. *)
let empty = {return= []; params= []}
(** Check if the method annotation is empty. *)
let is_empty {return; params} = Item.is_empty return && List.for_all ~f:Item.is_empty params
end