Skip to content

Commit b3b83eb

Browse files
committed
start working on module-level functions
1 parent e686af4 commit b3b83eb

File tree

11 files changed

+102
-5
lines changed

11 files changed

+102
-5
lines changed

src/codegen/gencommon/gencommon.ml

+3-3
Original file line numberDiff line numberDiff line change
@@ -617,11 +617,11 @@ let new_ctx con =
617617
gadd_type = (fun md should_filter ->
618618
if should_filter then begin
619619
gen.gtypes_list <- md :: gen.gtypes_list;
620-
gen.gmodules <- { m_id = alloc_mid(); m_path = (t_path md); m_types = [md]; m_extra = module_extra "" "" 0. MFake [] } :: gen.gmodules;
620+
gen.gmodules <- { m_id = alloc_mid(); m_path = (t_path md); m_types = [md]; m_statics = None; m_extra = module_extra "" "" 0. MFake [] } :: gen.gmodules;
621621
Hashtbl.add gen.gtypes (t_path md) md;
622622
end else gen.gafter_filters_ended <- (fun () ->
623623
gen.gtypes_list <- md :: gen.gtypes_list;
624-
gen.gmodules <- { m_id = alloc_mid(); m_path = (t_path md); m_types = [md]; m_extra = module_extra "" "" 0. MFake [] } :: gen.gmodules;
624+
gen.gmodules <- { m_id = alloc_mid(); m_path = (t_path md); m_types = [md]; m_statics = None; m_extra = module_extra "" "" 0. MFake [] } :: gen.gmodules;
625625
Hashtbl.add gen.gtypes (t_path md) md;
626626
) :: gen.gafter_filters_ended;
627627
);
@@ -682,7 +682,7 @@ let reorder_modules gen =
682682
Hashtbl.iter (fun md_path md ->
683683
if not (Hashtbl.mem processed md_path) then begin
684684
Hashtbl.add processed md_path true;
685-
gen.gmodules <- { m_id = alloc_mid(); m_path = md_path; m_types = List.rev ( Hashtbl.find_all modules md_path ); m_extra = (t_infos md).mt_module.m_extra } :: gen.gmodules
685+
gen.gmodules <- { m_id = alloc_mid(); m_path = md_path; m_types = List.rev ( Hashtbl.find_all modules md_path ); m_statics = None; m_extra = (t_infos md).mt_module.m_extra } :: gen.gmodules
686686
end
687687
) modules
688688

src/context/typecore.ml

+1
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,7 @@ let create_fake_module ctx file =
353353
m_id = alloc_mid();
354354
m_path = (["$DEP"],file);
355355
m_types = [];
356+
m_statics = None;
356357
m_extra = module_extra file (Define.get_signature ctx.com.defines) (file_time file) MFake [];
357358
} in
358359
Hashtbl.add fake_modules file mdep;

src/core/ast.ml

+1
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,7 @@ type type_def =
321321
| EEnum of (enum_flag, enum_constructor list) definition
322322
| ETypedef of (enum_flag, type_hint) definition
323323
| EAbstract of (abstract_flag, class_field list) definition
324+
| EGlobal of (placed_access, class_field_kind) definition
324325
| EImport of import
325326
| EUsing of placed_name list
326327

src/core/tFunctions.ml

+1
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,7 @@ let null_module = {
151151
m_id = alloc_mid();
152152
m_path = [] , "";
153153
m_types = [];
154+
m_statics = None;
154155
m_extra = module_extra "" "" 0. MFake [];
155156
}
156157

src/core/tType.ml

+2
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,7 @@ and tclass_kind =
185185
| KMacroType
186186
| KGenericBuild of class_field list
187187
| KAbstractImpl of tabstract
188+
| KModuleStatics of module_def
188189

189190
and metadata = Ast.metadata
190191

@@ -312,6 +313,7 @@ and module_def = {
312313
m_id : int;
313314
m_path : path;
314315
mutable m_types : module_type list;
316+
mutable m_statics : tclass option;
315317
m_extra : module_def_extra;
316318
}
317319

src/syntax/grammar.mly

+22
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,28 @@ and parse_type_decl mode s =
169169
| [< '(Kwd Using,p1) >] -> parse_using s p1
170170
| [< doc = get_doc; meta = parse_meta; c = parse_common_flags; s >] ->
171171
match s with parser
172+
| [< '(Kwd Function,p1); name = dollar_ident; pl = parse_constraint_params; '(POpen,_); args = psep Comma parse_fun_param; '(PClose,_); t = popt parse_type_hint; s >] ->
173+
let e, p2 = (match s with parser
174+
| [< e = expr; s >] ->
175+
ignore(semicolon s);
176+
Some e, pos e
177+
| [< p = semicolon >] -> None, p
178+
| [< >] -> serror()
179+
) in
180+
let f = {
181+
f_params = pl;
182+
f_args = args;
183+
f_type = t;
184+
f_expr = e;
185+
} in
186+
(EGlobal {
187+
d_name = name;
188+
d_doc = doc_from_string_opt doc;
189+
d_meta = meta;
190+
d_params = pl;
191+
d_flags = List.map decl_flag_to_global_flag c;
192+
d_data = FFun f;
193+
}, punion p1 p2)
172194
| [< '(Kwd Enum,p1) >] ->
173195
begin match s with parser
174196
| [< a,p = parse_abstract doc ((Meta.Enum,[],null_pos) :: meta) c >] ->

src/syntax/parser.ml

+5
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,11 @@ let decl_flag_to_abstract_flag (flag,p) = match flag with
106106
| DExtern -> AbExtern
107107
| DFinal -> error (Custom "final on abstracts is not allowed") p
108108

109+
let decl_flag_to_global_flag (flag,p) = match flag with
110+
| DPrivate -> (APrivate,p)
111+
| DExtern -> (AExtern,p)
112+
| DFinal -> (AFinal,p)
113+
109114
module TokenCache = struct
110115
let cache = ref (DynArray.create ())
111116
let add (token : (token * pos)) = DynArray.add (!cache) token

src/typing/generic.ml

+2
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,7 @@ let static_method_container gctx c cf p =
160160
m_id = alloc_mid();
161161
m_path = (pack,name);
162162
m_types = [];
163+
m_statics = None;
163164
m_extra = module_extra (s_type_path (pack,name)) m.m_extra.m_sign 0. MFake m.m_extra.m_check_policy;
164165
} in
165166
gctx.mg <- Some mg;
@@ -205,6 +206,7 @@ let rec build_generic ctx c p tl =
205206
m_id = alloc_mid();
206207
m_path = (pack,name);
207208
m_types = [];
209+
m_statics = None;
208210
m_extra = module_extra (s_type_path (pack,name)) m.m_extra.m_sign 0. MFake m.m_extra.m_check_policy;
209211
} in
210212
gctx.mg <- Some mg;

src/typing/typeloadFields.ml

+1-1
Original file line numberDiff line numberDiff line change
@@ -598,7 +598,7 @@ let is_public (ctx,cctx) access parent =
598598
true
599599
else match parent with
600600
| Some cf -> (has_class_field_flag cf CfPublic)
601-
| _ -> c.cl_extern || c.cl_interface || cctx.extends_public
601+
| _ -> c.cl_extern || c.cl_interface || cctx.extends_public || (match c.cl_kind with KModuleStatics _ -> true | _ -> false)
602602

603603
let rec get_parent c name =
604604
match c.cl_super with

src/typing/typeloadModule.ml

+55-1
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ let make_module ctx mpath file loadp =
3939
m_id = alloc_mid();
4040
m_path = mpath;
4141
m_types = [];
42+
m_statics = None;
4243
m_extra = module_extra (Path.unique_full_path file) (Define.get_signature ctx.com.defines) (file_time file) (if ctx.in_macro then MMacro else MCode) (get_policy ctx mpath);
4344
} in
4445
m
@@ -194,6 +195,7 @@ let module_pass_1 ctx m tdecls loadp =
194195
if priv then (fst m.m_path @ ["_" ^ snd m.m_path], name) else (fst m.m_path, name)
195196
in
196197
let pt = ref None in
198+
let globals = ref [] in
197199
let rec make_decl acc decl =
198200
let p = snd decl in
199201
let check_type_name type_name meta =
@@ -205,6 +207,9 @@ let module_pass_1 ctx m tdecls loadp =
205207
(match !pt with
206208
| None -> acc
207209
| Some _ -> error "import and using may not appear after a type declaration" p)
210+
| EGlobal d ->
211+
globals := (d,p) :: !globals;
212+
acc;
208213
| EClass d ->
209214
let name = fst d.d_name in
210215
pt := Some p;
@@ -341,6 +346,43 @@ let module_pass_1 ctx m tdecls loadp =
341346
decl :: acc
342347
in
343348
let tdecls = List.fold_left make_decl [] tdecls in
349+
let tdecls =
350+
match !globals with
351+
| [] ->
352+
tdecls
353+
| globals ->
354+
let first_pos = ref null_pos in
355+
let fields = List.map (fun (d,p) ->
356+
first_pos := p;
357+
{
358+
cff_name = d.d_name;
359+
cff_doc = d.d_doc;
360+
cff_pos = p;
361+
cff_meta = d.d_meta;
362+
cff_access = (AStatic,null_pos) :: d.d_flags;
363+
cff_kind = d.d_data;
364+
}
365+
) globals in
366+
let p = !first_pos in
367+
let c = EClass {
368+
d_name = (snd m.m_path) ^ "_Statics_", p;
369+
d_flags = [HPrivate];
370+
d_data = fields;
371+
d_doc = None;
372+
d_params = [];
373+
d_meta = []
374+
} in
375+
let tdecls = make_decl tdecls (c,p) in
376+
(match !decls with
377+
| (TClassDecl c,_) :: _ ->
378+
assert (m.m_statics = None);
379+
m.m_statics <- Some c;
380+
c.cl_kind <- KModuleStatics m;
381+
c.cl_final <- true;
382+
| _ -> assert false);
383+
tdecls
384+
385+
in
344386
let decls = List.rev !decls in
345387
decls, List.rev tdecls
346388

@@ -490,7 +532,16 @@ let init_module_type ctx context_init (decl,p) =
490532
| [] ->
491533
(match name with
492534
| None ->
493-
ctx.m.module_types <- List.filter no_private (List.map (fun t -> t,p) types) @ ctx.m.module_types
535+
ctx.m.module_types <- List.filter no_private (List.map (fun t -> t,p) types) @ ctx.m.module_types;
536+
Option.may (fun c ->
537+
context_init#add (fun () ->
538+
ignore(c.cl_build());
539+
List.iter (fun cf ->
540+
if has_class_field_flag cf CfPublic then
541+
ctx.m.module_globals <- PMap.add cf.cf_name (TClassDecl c,cf.cf_name,p) ctx.m.module_globals
542+
) c.cl_ordered_statics
543+
);
544+
) md.m_statics
494545
| Some(newname,pname) ->
495546
ctx.m.module_types <- (rebind (get_type tname) newname pname,p) :: ctx.m.module_types);
496547
| [tsub,p2] ->
@@ -802,6 +853,9 @@ let init_module_type ctx context_init (decl,p) =
802853
else
803854
error "Abstract is missing underlying type declaration" a.a_pos
804855
end
856+
| EGlobal _ ->
857+
(* nothing to do here as globals are collected into a special EClass *)
858+
()
805859

806860
let module_pass_2 ctx m decls tdecls p =
807861
(* here is an additional PASS 1 phase, which define the type parameters for all module types.

src/typing/typer.ml

+9
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,15 @@ let rec type_ident_raise ctx i p mode =
370370
let e = type_type ctx ctx.curclass.cl_path p in
371371
(* check_locals_masking already done in type_type *)
372372
field_access ctx mode f (FStatic (ctx.curclass,f)) (field_type ctx ctx.curclass [] f p) e p
373+
with Not_found -> try
374+
(* module-level statics *)
375+
(match ctx.m.curmod.m_statics with
376+
| None -> raise Not_found
377+
| Some c ->
378+
let f = PMap.find i c.cl_statics in
379+
let e = type_module_type ctx (TClassDecl c) None p in
380+
field_access ctx mode f (FStatic (c,f)) (field_type ctx c [] f p) e p
381+
)
373382
with Not_found -> try
374383
let wrap e = if mode = MSet then
375384
AKNo i

0 commit comments

Comments
 (0)