Skip to content

Commit 310b717

Browse files
committed
es6 arrows
1 parent 8b3761f commit 310b717

File tree

15 files changed

+75
-22
lines changed

15 files changed

+75
-22
lines changed

src-json/meta.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -543,6 +543,13 @@
543543
"targets": ["TClass"],
544544
"links": ["https://haxe.org/manual/target-javascript-require.html"]
545545
},
546+
{
547+
"name": "JsFunction",
548+
"metadata": ":js.function",
549+
"doc": "Generate `function` keyword instead of arrow function in `-D js_es >= 6` mode to enable access to function scope `this`.",
550+
"platforms": ["js"],
551+
"targets": ["TExpr"]
552+
},
546553
{
547554
"name": "LuaRequire",
548555
"metadata": ":luaRequire",

src/context/common.ml

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -482,6 +482,7 @@ let default_config =
482482
vs_scope = BlockScope;
483483
vs_flags = [];
484484
};
485+
pf_can_capture_this = true;
485486
pf_supports_atomics = false;
486487
}
487488

@@ -516,6 +517,7 @@ let get_config com =
516517
(if defined Define.JsUnflatten then ReserveAllTopLevelSymbols else ReserveAllTypesFlat)
517518
:: if es6 then [NoShadowing; SwitchCasesNoBlocks;] else [VarHoisting; NoCatchVarShadowing];
518519
};
520+
pf_can_capture_this = es6;
519521
pf_supports_atomics = true;
520522
}
521523
| Lua ->
@@ -527,7 +529,8 @@ let get_config com =
527529
pf_supports_rest_args = true;
528530
pf_exceptions = { default_config.pf_exceptions with
529531
ec_avoid_wrapping = false;
530-
}
532+
};
533+
pf_can_capture_this = false;
531534
}
532535
| Neko ->
533536
{
@@ -542,7 +545,8 @@ let get_config com =
542545
};
543546
pf_exceptions = { default_config.pf_exceptions with
544547
ec_avoid_wrapping = false
545-
}
548+
};
549+
pf_can_capture_this = false;
546550
}
547551
| Flash ->
548552
{
@@ -567,6 +571,7 @@ let get_config com =
567571
vs_scope = FunctionScope;
568572
vs_flags = [VarHoisting];
569573
};
574+
pf_can_capture_this = false;
570575
}
571576
| Php ->
572577
{
@@ -603,6 +608,7 @@ let get_config com =
603608
vs_flags = [NoShadowing];
604609
vs_scope = FunctionScope;
605610
};
611+
pf_can_capture_this = false;
606612
pf_supports_atomics = true;
607613
}
608614
| Jvm ->
@@ -626,6 +632,7 @@ let get_config com =
626632
ec_wildcard_catch = (["java";"lang"],"Throwable");
627633
ec_base_throw = (["java";"lang"],"RuntimeException");
628634
};
635+
pf_can_capture_this = false;
629636
pf_supports_atomics = true;
630637
}
631638
| Python ->
@@ -650,6 +657,7 @@ let get_config com =
650657
vs_scope = FunctionScope;
651658
vs_flags = [VarHoisting]
652659
};
660+
pf_can_capture_this = false;
653661
}
654662
| Hl ->
655663
{
@@ -664,7 +672,8 @@ let get_config com =
664672
};
665673
pf_exceptions = { default_config.pf_exceptions with
666674
ec_avoid_wrapping = false
667-
}
675+
};
676+
pf_can_capture_this = false;
668677
}
669678
| Eval ->
670679
{
@@ -676,7 +685,8 @@ let get_config com =
676685
pf_capture_policy = CPWrapRef;
677686
pf_exceptions = { default_config.pf_exceptions with
678687
ec_avoid_wrapping = false
679-
}
688+
};
689+
pf_can_capture_this = false;
680690
}
681691

682692
let memory_marker = [|Unix.time()|]

src/context/platformConfig.ml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,8 @@ type platform_config = {
118118
pf_exceptions : exceptions_config;
119119
(** the scoping of local variables *)
120120
pf_scoping : var_scoping_config;
121+
(** whether or not the target needs a variable to capture `this` *)
122+
pf_can_capture_this : bool;
121123
(** target supports atomic operations via haxe.Atomic **)
122124
pf_supports_atomics : bool;
123-
}
125+
}

src/generators/genjs.ml

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -569,6 +569,8 @@ and gen_expr ctx e =
569569
| TBreak ->
570570
print ctx "break _hx_loop%s" n;
571571
| _ -> die "" __LOC__)
572+
| TMeta ((Meta.JsFunction, [], _),{eexpr = TFunction f}) ->
573+
gen_function ~hasJsFunction:true ctx f e.epos
572574
| TMeta (_,e) ->
573575
gen_expr ctx e
574576
| TReturn eo ->
@@ -733,7 +735,7 @@ and gen_expr ctx e =
733735
);
734736
clear_mapping ()
735737

736-
and gen_function ?(keyword="function") ctx f pos =
738+
and gen_function ?(keyword="function") ?(hasJsFunction=false) ctx f pos =
737739
let old = ctx.in_value, ctx.in_loop in
738740
ctx.in_value <- None;
739741
ctx.in_loop <- false;
@@ -771,7 +773,15 @@ and gen_function ?(keyword="function") ctx f pos =
771773
| _ ->
772774
f, mk_non_rest_arg_names f.tf_args
773775
in
774-
print ctx "%s(%s) " keyword (String.concat "," args);
776+
let can_be_arrow =
777+
keyword = "function" &&
778+
ctx.es_version >= 6 &&
779+
not hasJsFunction
780+
in
781+
if can_be_arrow then
782+
print ctx "(%s) => " (String.concat "," args)
783+
else
784+
print ctx "%s(%s) " keyword (String.concat "," args);
775785
gen_expr ctx (fun_block ctx f pos);
776786
ctx.in_value <- fst old;
777787
ctx.in_loop <- snd old;
@@ -842,6 +852,7 @@ and gen_value ctx e =
842852
| TNew _
843853
| TUnop _
844854
| TFunction _
855+
| TMeta ((Meta.JsFunction, [], _),_)
845856
| TIdent _ ->
846857
gen_expr ctx e
847858
| TMeta (_,e1) ->

src/macro/macroApi.ml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -465,6 +465,7 @@ and encode_platform_config pc =
465465
"supportsRestArgs", vbool pc.pf_supports_rest_args;
466466
"exceptions", encode_exceptions_config pc.pf_exceptions;
467467
"scoping", encode_var_scoping_config pc.pf_scoping;
468+
"canCaptureThis", vbool pc.pf_can_capture_this;
468469
"supportsAtomics", vbool pc.pf_supports_atomics;
469470
]
470471

@@ -1723,6 +1724,7 @@ let decode_platform_config v =
17231724
pf_supports_rest_args = decode_bool (field v "supportsRestArgs");
17241725
pf_exceptions = exception_config;
17251726
pf_scoping = var_scoping_config;
1727+
pf_can_capture_this = decode_bool (field v "canCaptureThis");
17261728
pf_supports_atomics = decode_bool (field v "supportsAtomics");
17271729
}
17281730

src/optimization/inline.ml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -482,7 +482,7 @@ object(self)
482482
_inlined_vars <- vars; (* Order is reversed due to tail-recursion *)
483483
in
484484
match ethis.eexpr with
485-
| TConst TNull ->
485+
| TConst TNull | TConst TThis ->
486486
set_inlined_vars params f.tf_args;
487487
None
488488
| _ ->
@@ -712,7 +712,8 @@ let rec type_inline (ictx : inline_context) cf f ethis params tret config p ?(se
712712
l.i_read <- l.i_read + (if !in_loop then 2 else 1);
713713
{ e with eexpr = TLocal l.i_subst }
714714
| None ->
715-
raise_typing_error "Could not inline `this` outside of an instance context" po
715+
{ e with eexpr = TConst TThis }
716+
(* raise_typing_error "Could not inline `this` outside of an instance context" po *)
716717
)
717718
| TVar (v,eo) ->
718719
if has_var_flag v VStatic then raise_typing_error "Inline functions cannot have static locals" v.v_pos;

src/typing/typer.ml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1523,6 +1523,14 @@ and type_meta ?(mode=MGet) ctx m e1 with_type p =
15231523
| (Meta.NullSafety, [(EConst (Ident "Off"), _)],_) ->
15241524
let e = e() in
15251525
{e with eexpr = TMeta(m,e)}
1526+
| (Meta.JsFunction, [],pos) when ctx.com.platform=Js ->
1527+
let e = e() in
1528+
begin match e.eexpr with
1529+
| TFunction f ->
1530+
{e with eexpr = TMeta(m,e)}
1531+
| _ ->
1532+
raise_typing_error "@:js.function can be applied only to anonymous functions" pos
1533+
end
15261534
| (Meta.BypassAccessor,_,p) ->
15271535
let old_counter = ctx.e.bypass_accessor in
15281536
ctx.e.bypass_accessor <- old_counter + 1;

src/typing/typerBase.ml

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -149,10 +149,17 @@ let is_lower_ident s p =
149149
with Invalid_argument msg -> raise_typing_error msg p
150150

151151
let get_this ctx p =
152+
let has_jsfun_meta metas =
153+
ctx.com.platform == Js && List.exists (fun (name,args,pos) ->
154+
match name with
155+
| Meta.JsFunction -> true
156+
| _ -> false
157+
) metas
158+
in
152159
match ctx.e.curfun with
153160
| FunStatic ->
154161
raise_typing_error "Cannot access this from a static function" p
155-
| FunMemberClassLocal | FunMemberAbstractLocal ->
162+
| FunMemberClassLocal | FunMemberAbstractLocal when not ctx.com.config.pf_can_capture_this || has_jsfun_meta ctx.f.meta ->
156163
let v = match ctx.f.vthis with
157164
| None ->
158165
let v = if ctx.e.curfun = FunMemberAbstractLocal then begin
@@ -169,10 +176,10 @@ let get_this ctx p =
169176
v
170177
in
171178
mk (TLocal v) ctx.c.tthis p
172-
| FunMemberAbstract ->
179+
| FunMemberAbstract | FunMemberAbstractLocal ->
173180
let v = (try PMap.find "this" ctx.f.locals with Not_found -> raise_typing_error "Cannot reference this abstract here" p) in
174181
mk (TLocal v) v.v_type p
175-
| FunConstructor | FunMember ->
182+
| FunConstructor | FunMember | FunMemberClassLocal ->
176183
mk (TConst TThis) ctx.c.tthis p
177184

178185
let get_stored_typed_expr ctx id =
@@ -406,4 +413,4 @@ let get_safe_nav_base ctx eobj =
406413
let v = alloc_var VGenerated "tmp" eobj.etype eobj.epos in
407414
let temp_var = mk (TVar(v, Some eobj)) ctx.t.tvoid v.v_pos in
408415
let eobj = mk (TLocal v) v.v_type v.v_pos in
409-
eobj, Some temp_var
416+
eobj, Some temp_var

std/haxe/macro/PlatformConfig.hx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,10 @@ typedef PlatformConfig = {
9191
**/
9292
final supportsAtomics:Bool;
9393

94+
/**
95+
Whether or not the target needs a variable to capture `this`
96+
**/
97+
final canCaptureThis:Bool;
9498
}
9599

96100
enum CapturePolicy {

std/js/_std/HxOverrides.hx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -129,10 +129,10 @@ class HxOverrides {
129129
return {
130130
cur: 0,
131131
arr: a,
132-
hasNext: function() {
132+
hasNext: @:js.function function() {
133133
return __this__.cur < __this__.arr.length;
134134
},
135-
next: function() {
135+
next: @:js.function function() {
136136
return __this__.arr[__this__.cur++];
137137
}
138138
};

0 commit comments

Comments
 (0)