Summary: Polymorphic models, and type environment refinements, need mutual references between general types and struct types. Reviewed By: cristianoc Differential Revision: D4620076 fbshipit-source-id: f9d01e6master
parent
f5bb35e245
commit
95725e4dd0
@ -1,141 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2009 - 2013 Monoidics ltd.
|
|
||||||
* Copyright (c) 2013 - present Facebook, Inc.
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
* This source code is licensed under the BSD style license found in the
|
|
||||||
* LICENSE file in the root directory of this source tree. An additional grant
|
|
||||||
* of patent rights can be found in the PATENTS file in the same directory.
|
|
||||||
*/
|
|
||||||
open! IStd;
|
|
||||||
|
|
||||||
|
|
||||||
/** The Smallfoot Intermediate Language: Struct Types */
|
|
||||||
let module L = Logging;
|
|
||||||
|
|
||||||
let module F = Format;
|
|
||||||
|
|
||||||
type field = (Ident.fieldname, Typ.t, Annot.Item.t) [@@deriving compare];
|
|
||||||
|
|
||||||
type fields = list field;
|
|
||||||
|
|
||||||
|
|
||||||
/** Type for a structured value. */
|
|
||||||
type t = {
|
|
||||||
fields: fields, /** non-static fields */
|
|
||||||
statics: fields, /** static fields */
|
|
||||||
supers: list Typename.t, /** superclasses */
|
|
||||||
methods: list Procname.t, /** methods defined */
|
|
||||||
annots: Annot.Item.t /** annotations */
|
|
||||||
};
|
|
||||||
|
|
||||||
type lookup = Typename.t => option t;
|
|
||||||
|
|
||||||
let pp pe name f {fields, supers, methods, annots} =>
|
|
||||||
if Config.debug_mode {
|
|
||||||
/* 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\tannots: {%a\n\t}"
|
|
||||||
Typename.pp
|
|
||||||
name
|
|
||||||
(
|
|
||||||
Pp.seq (
|
|
||||||
fun f (fld, t, _) => F.fprintf f "\n\t\t%a %a" (Typ.pp_full pe) t Ident.pp_fieldname fld
|
|
||||||
)
|
|
||||||
)
|
|
||||||
fields
|
|
||||||
(Pp.seq (fun f n => F.fprintf f "\n\t\t%a" Typename.pp n))
|
|
||||||
supers
|
|
||||||
(Pp.seq (fun f m => F.fprintf f "\n\t\t%a" Procname.pp m))
|
|
||||||
methods
|
|
||||||
Annot.Item.pp
|
|
||||||
annots
|
|
||||||
} else {
|
|
||||||
F.fprintf f "%a" Typename.pp name
|
|
||||||
};
|
|
||||||
|
|
||||||
let internal_mk_struct
|
|
||||||
default::default=?
|
|
||||||
fields::fields=?
|
|
||||||
statics::statics=?
|
|
||||||
methods::methods=?
|
|
||||||
supers::supers=?
|
|
||||||
annots::annots=?
|
|
||||||
() => {
|
|
||||||
let mk_struct_
|
|
||||||
default::default={fields: [], statics: [], methods: [], supers: [], annots: Annot.Item.empty}
|
|
||||||
fields::fields=default.fields
|
|
||||||
statics::statics=default.statics
|
|
||||||
methods::methods=default.methods
|
|
||||||
supers::supers=default.supers
|
|
||||||
annots::annots=default.annots
|
|
||||||
() => {
|
|
||||||
fields,
|
|
||||||
statics,
|
|
||||||
methods,
|
|
||||||
supers,
|
|
||||||
annots
|
|
||||||
};
|
|
||||||
mk_struct_
|
|
||||||
default::?default
|
|
||||||
fields::?fields
|
|
||||||
statics::?statics
|
|
||||||
methods::?methods
|
|
||||||
supers::?supers
|
|
||||||
annots::?annots
|
|
||||||
()
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/** the element typ of the final extensible array in the given typ, if any */
|
|
||||||
let rec get_extensible_array_element_typ lookup::lookup (typ: Typ.t) =>
|
|
||||||
switch typ {
|
|
||||||
| Tarray typ _ => Some typ
|
|
||||||
| Tstruct name =>
|
|
||||||
switch (lookup name) {
|
|
||||||
| Some {fields} =>
|
|
||||||
switch (List.last fields) {
|
|
||||||
| Some (_, fld_typ, _) => get_extensible_array_element_typ lookup::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::lookup default::default fn (typ: Typ.t) =>
|
|
||||||
switch typ {
|
|
||||||
| Tstruct name =>
|
|
||||||
switch (lookup name) {
|
|
||||||
| Some {fields} =>
|
|
||||||
List.find f::(fun (f, _, _) => Ident.equal_fieldname f fn) fields |>
|
|
||||||
Option.value_map f::snd3 default::default
|
|
||||||
| None => default
|
|
||||||
}
|
|
||||||
| _ => default
|
|
||||||
};
|
|
||||||
|
|
||||||
let get_field_type_and_annotation lookup::lookup fn (typ: Typ.t) =>
|
|
||||||
switch typ {
|
|
||||||
| Tstruct name
|
|
||||||
| Tptr (Tstruct name) _ =>
|
|
||||||
switch (lookup name) {
|
|
||||||
| Some {fields, statics} =>
|
|
||||||
List.find_map
|
|
||||||
f::(fun (f, t, a) => Ident.equal_fieldname f fn ? Some (t, a) : None) (fields @ statics)
|
|
||||||
| None => None
|
|
||||||
}
|
|
||||||
| _ => None
|
|
||||||
};
|
|
||||||
|
|
||||||
let objc_ref_counter_annot = [({Annot.class_name: "ref_counter", parameters: []}, false)];
|
|
||||||
|
|
||||||
|
|
||||||
/** Field used for objective-c reference counting */
|
|
||||||
let objc_ref_counter_field = (Ident.fieldname_hidden, Typ.Tint IInt, objc_ref_counter_annot);
|
|
||||||
|
|
||||||
let is_objc_ref_counter_field (fld, _, a) =>
|
|
||||||
Ident.fieldname_is_hidden fld && Annot.Item.equal a objc_ref_counter_annot;
|
|
@ -1,66 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2009 - 2013 Monoidics ltd.
|
|
||||||
* Copyright (c) 2013 - present Facebook, Inc.
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
* This source code is licensed under the BSD style license found in the
|
|
||||||
* LICENSE file in the root directory of this source tree. An additional grant
|
|
||||||
* of patent rights can be found in the PATENTS file in the same directory.
|
|
||||||
*/
|
|
||||||
open! IStd;
|
|
||||||
|
|
||||||
|
|
||||||
/** The Smallfoot Intermediate Language: Struct Types */
|
|
||||||
let module F = Format;
|
|
||||||
|
|
||||||
type field = (Ident.fieldname, Typ.t, Annot.Item.t) [@@deriving compare];
|
|
||||||
|
|
||||||
type fields = list field;
|
|
||||||
|
|
||||||
|
|
||||||
/** Type for a structured value. */
|
|
||||||
type t = private {
|
|
||||||
fields: fields, /** non-static fields */
|
|
||||||
statics: fields, /** static fields */
|
|
||||||
supers: list Typename.t, /** supers */
|
|
||||||
methods: list Procname.t, /** methods defined */
|
|
||||||
annots: Annot.Item.t /** annotations */
|
|
||||||
};
|
|
||||||
|
|
||||||
type lookup = Typename.t => option t;
|
|
||||||
|
|
||||||
|
|
||||||
/** Pretty print a struct type. */
|
|
||||||
let pp: Pp.env => Typename.t => F.formatter => t => unit;
|
|
||||||
|
|
||||||
|
|
||||||
/** Construct a struct_typ, normalizing field types */
|
|
||||||
let internal_mk_struct:
|
|
||||||
default::t? =>
|
|
||||||
fields::fields? =>
|
|
||||||
statics::fields? =>
|
|
||||||
methods::list Procname.t? =>
|
|
||||||
supers::list Typename.t? =>
|
|
||||||
annots::Annot.Item.t? =>
|
|
||||||
unit =>
|
|
||||||
t;
|
|
||||||
|
|
||||||
|
|
||||||
/** the element typ of the final extensible array in the given typ, if any */
|
|
||||||
let get_extensible_array_element_typ: lookup::lookup => Typ.t => option 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 */
|
|
||||||
let fld_typ: lookup::lookup => default::Typ.t => Ident.fieldname => Typ.t => Typ.t;
|
|
||||||
|
|
||||||
|
|
||||||
/** Return the type of the field [fn] and its annotation, None if [typ] has no field named [fn] */
|
|
||||||
let get_field_type_and_annotation:
|
|
||||||
lookup::lookup => Ident.fieldname => Typ.t => option (Typ.t, Annot.Item.t);
|
|
||||||
|
|
||||||
|
|
||||||
/** Field used for objective-c reference counting */
|
|
||||||
let objc_ref_counter_field: (Ident.fieldname, Typ.t, Annot.Item.t);
|
|
||||||
|
|
||||||
let is_objc_ref_counter_field: (Ident.fieldname, Typ.t, Annot.Item.t) => bool;
|
|
Loading…
Reference in new issue