Skip to content

Commit

Permalink
[textual] Translate __Infer_Constant__ attribute as const qualifier
Browse files Browse the repository at this point in the history
Summary:
This diff translates the `__Infer_Constant__` attribute of textual as
the const qualifier in SIL.

Reviewed By: jvillard

Differential Revision: D49874692

fbshipit-source-id: 417a0cbe4757d7b06a95602cb435d0e27c554627
  • Loading branch information
skcho authored and facebook-github-bot committed Oct 5, 2023
1 parent 7706262 commit 334841b
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 7 deletions.
2 changes: 2 additions & 0 deletions infer/src/textual/Textual.ml
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,8 @@ module Attr = struct

let is_async {name; values} = String.equal name "async" && List.is_empty values

let is_const {name; values} = String.equal name "__Infer_Constant__" && List.is_empty values

let is_curry {name; values} = String.equal name "curry" && List.is_empty values

let is_final {name; values} = String.equal name "final" && List.is_empty values
Expand Down
2 changes: 2 additions & 0 deletions infer/src/textual/Textual.mli
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,8 @@ module Attr : sig

val is_async : t -> bool

val is_const : t -> bool

val mk_trait : t

val pp : F.formatter -> t -> unit [@@warning "-unused-value-declaration"]
Expand Down
25 changes: 18 additions & 7 deletions infer/src/textual/TextualSil.ml
Original file line number Diff line number Diff line change
Expand Up @@ -199,8 +199,9 @@ let wildcard_sil_fieldname lang name =
module TypBridge = struct
open Typ

let rec to_sil lang (typ : t) : SilTyp.t =
let quals = SilTyp.mk_type_quals () in
let rec to_sil lang ?(attrs = []) (typ : t) : SilTyp.t =
let is_const = List.exists attrs ~f:Textual.Attr.is_const in
let quals = SilTyp.mk_type_quals ~is_const () in
let desc : SilTyp.desc =
match typ with
| Int ->
Expand Down Expand Up @@ -477,7 +478,9 @@ module StructBridge = struct
in
let fields =
List.map fields ~f:(fun (fdecl : FieldDecl.t) ->
(FieldDeclBridge.to_sil lang fdecl, TypBridge.to_sil lang fdecl.typ, Annot.Item.empty) )
( FieldDeclBridge.to_sil lang fdecl
, TypBridge.to_sil lang ~attrs:fdecl.attributes fdecl.typ
, Annot.Item.empty ) )
in
let annots =
List.filter_map attributes ~f:(fun attr ->
Expand Down Expand Up @@ -587,7 +590,10 @@ module ExpBridge = struct
L.die InternalError "field %a.%a has not been declared" TypeName.pp
field.enclosing_class FieldName.pp field.name
| Some field ->
Lfield (aux exp, FieldDeclBridge.to_sil lang field, TypBridge.to_sil lang field.typ) )
Lfield
( aux exp
, FieldDeclBridge.to_sil lang field
, TypBridge.to_sil lang ~attrs:field.attributes field.typ ) )
| Index (exp1, exp2) ->
Lindex (aux exp1, aux exp2)
| Const const ->
Expand Down Expand Up @@ -779,7 +785,10 @@ module InstrBridge = struct
raise (TextualTransformError [{loc; msg}])
in
let pname = ProcDeclBridge.call_to_sil lang procsig callee_procname in
let result_type = TypBridge.to_sil lang callee_procname.result_type.typ in
let result_type =
TypBridge.to_sil lang ~attrs:callee_procname.result_type.attributes
callee_procname.result_type.typ
in
let args = List.map ~f:(ExpBridge.to_sil lang decls_env procname) args in
let formals_types =
match formals_types with
Expand Down Expand Up @@ -954,14 +963,16 @@ module ProcDescBridge = struct
in
List.map locals ~f:(fun (var, annotated_typ) ->
let name = Mangled.from_string var.VarName.value in
let typ = TypBridge.to_sil lang annotated_typ.Typ.typ in
let typ = TypBridge.to_sil lang ~attrs:annotated_typ.Typ.attributes annotated_typ.Typ.typ in
make_var_data name typ )


let to_sil lang decls_env cfgs ({procdecl; nodes; start; exit_loc} as pdesc) =
let sourcefile = TextualDecls.source_file decls_env in
let sil_procname = ProcDeclBridge.to_sil lang procdecl in
let sil_ret_type = TypBridge.to_sil lang procdecl.result_type.typ in
let sil_ret_type =
TypBridge.to_sil lang ~attrs:procdecl.result_type.attributes procdecl.result_type.typ
in
let definition_loc = LocationBridge.to_sil sourcefile procdecl.qualified_name.name.loc in
let is_hack_async = List.exists procdecl.attributes ~f:Attr.is_async in
let formals = build_formals lang pdesc in
Expand Down
39 changes: 39 additions & 0 deletions infer/src/textual/unit/TextualSilTest.ml
Original file line number Diff line number Diff line change
Expand Up @@ -372,3 +372,42 @@ let%expect_test "trait vs class kind" =
annots: {<>}
class_info: {HackClassInfo (Trait)}
dummy: false |}]


let%expect_test "const" =
let source =
{|
.source_language = "hack"

type Uninit::A$static = .kind="class" .static {
FIELD: .public .__Infer_Constant__ *HackMixed
}
|}
in
let m = parse_module source in
let _, tenv = TextualSil.module_to_sil m in
F.printf "%a@\n" Tenv.pp tenv ;
[%expect
{|
hack HackMixed
fields: {}
statics: {}
supers: {}
objc_protocols: {}
methods: {}
exported_obj_methods: {}
annots: {<>}
class_info: {NoInfo}
dummy: true
hack Uninit::A$static
fields: {
HackMixed* const FIELD <>
}
statics: {}
supers: {}
objc_protocols: {}
methods: {}
exported_obj_methods: {}
annots: {<>}
class_info: {HackClassInfo (Class)}
dummy: false |}]

0 comments on commit 334841b

Please sign in to comment.