Skip to content

Commit

Permalink
Fix enclosing positions (#11892)
Browse files Browse the repository at this point in the history
* Make zero range positions when reusing field/type pos for metadata

* [macro] Expose PositionTools.toZeroRange()

* That one was ok

* Restore CfOverride
  • Loading branch information
kLabz authored Jan 20, 2025
1 parent 30769c6 commit bdecee2
Show file tree
Hide file tree
Showing 9 changed files with 30 additions and 13 deletions.
4 changes: 4 additions & 0 deletions src/macro/macroApi.ml
Original file line number Diff line number Diff line change
Expand Up @@ -2356,6 +2356,10 @@ let macro_api ccom get_api =
] in
location
);
"position_to_zero_range", vfun1 (fun p ->
let p = decode_pos p in
encode_pos (mk_zero_range_pos p)
);
"on_null_safety_report", vfun1 (fun f ->
let f = prepare_callback f 1 in
(ccom()).callbacks#add_null_safety_report (fun (errors:(string*pos) list) ->
Expand Down
2 changes: 1 addition & 1 deletion src/optimization/analyzerTexpr.ml
Original file line number Diff line number Diff line change
Expand Up @@ -1259,7 +1259,7 @@ module Purity = struct
Hashtbl.iter (fun _ node ->
match node.pn_purity with
| Pure | MaybePure when not (List.exists (fun (m,_,_) -> m = Meta.Pure) node.pn_field.cf_meta) ->
node.pn_field.cf_meta <- (Meta.Pure,[EConst(Ident "inferredPure"),node.pn_field.cf_pos],node.pn_field.cf_pos) :: node.pn_field.cf_meta
node.pn_field.cf_meta <- (Meta.Pure,[EConst(Ident "inferredPure"),mk_zero_range_pos node.pn_field.cf_pos],mk_zero_range_pos node.pn_field.cf_pos) :: node.pn_field.cf_meta
| _ -> ()
) node_lut;
end
8 changes: 4 additions & 4 deletions src/optimization/dce.ml
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,7 @@ let mark_mt dce mt = match mt with
mark_enum dce e
| TAbstractDecl a ->
(* abstract 'feature' is defined as the abstract type beeing used as a value, not as a type *)
if not (Meta.has Meta.ValueUsed a.a_meta) then a.a_meta <- (Meta.ValueUsed,[],a.a_pos) :: a.a_meta;
if not (Meta.has Meta.ValueUsed a.a_meta) then a.a_meta <- (Meta.ValueUsed,[],mk_zero_range_pos a.a_pos) :: a.a_meta;
mark_abstract dce a
| TTypeDecl _ ->
()
Expand Down Expand Up @@ -370,11 +370,11 @@ and field dce c n kind =
and mark_directly_used_class dce c =
(* don't add @:directlyUsed if it's used within the class itself. this can happen with extern inline methods *)
if c != dce.curclass && not (Meta.has Meta.DirectlyUsed c.cl_meta) then
c.cl_meta <- (Meta.DirectlyUsed,[],c.cl_pos) :: c.cl_meta
c.cl_meta <- (Meta.DirectlyUsed,[],mk_zero_range_pos c.cl_pos) :: c.cl_meta

and mark_directly_used_enum e =
if not (Meta.has Meta.DirectlyUsed e.e_meta) then
e.e_meta <- (Meta.DirectlyUsed,[],e.e_pos) :: e.e_meta
e.e_meta <- (Meta.DirectlyUsed,[],mk_zero_range_pos e.e_pos) :: e.e_meta

and mark_directly_used_mt dce mt =
match mt with
Expand Down Expand Up @@ -828,7 +828,7 @@ let sweep dce com =
| (TClassDecl c) as mt :: l ->
let check_property cf stat =
let add_accessor_metadata cf =
if not (Meta.has Meta.Accessor cf.cf_meta) then cf.cf_meta <- (Meta.Accessor,[],c.cl_pos) :: cf.cf_meta
if not (Meta.has Meta.Accessor cf.cf_meta) then cf.cf_meta <- (Meta.Accessor,[],mk_zero_range_pos c.cl_pos) :: cf.cf_meta
in
begin match cf.cf_kind with
| Var {v_read = AccCall} ->
Expand Down
2 changes: 1 addition & 1 deletion src/optimization/inlineConstructors.ml
Original file line number Diff line number Diff line change
Expand Up @@ -729,7 +729,7 @@ let inline_constructors ctx original_e =
end else begin
let el,_ = final_map e in
let cf = ctx.f.curfield in
if !included_untyped && not (Meta.has Meta.HasUntyped cf.cf_meta) then cf.cf_meta <- (Meta.HasUntyped,[],e.epos) :: cf.cf_meta;
if !included_untyped && not (Meta.has Meta.HasUntyped cf.cf_meta) then cf.cf_meta <- (Meta.HasUntyped,[],mk_zero_range_pos e.epos) :: cf.cf_meta;
let e = make_expr_for_rev_list el e.etype e.epos in
let rec get_pretty_name iv : string list = match iv.iv_kind with
| IVKField(io,fname,None) ->
Expand Down
3 changes: 2 additions & 1 deletion src/typing/generic.ml
Original file line number Diff line number Diff line change
Expand Up @@ -505,7 +505,8 @@ let type_generic_function ctx fa fcc with_type p =
| Meta.Generic -> false
| _ -> true
) cf.cf_meta in
cf2.cf_meta <- (Meta.NoCompletion,[],p) :: (Meta.NoUsing,[],p) :: (Meta.GenericInstance,[],p) :: meta;
let p_zero = mk_zero_range_pos p in
cf2.cf_meta <- (Meta.NoCompletion,[],p_zero) :: (Meta.NoUsing,[],p_zero) :: (Meta.GenericInstance,[],p_zero) :: meta;
cf2.cf_params <- params
in
let mk_cf2 name =
Expand Down
4 changes: 2 additions & 2 deletions src/typing/typeloadCheck.ml
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ let valid_redefinition map1 map2 f1 t1 f2 t2 = (* child, parent *)
if is_null t1 <> is_null t2 || ((follow t1) == t_dynamic && (follow t2) != t_dynamic) then raise (Unify_error [Cannot_unify (t1,t2)]);
in
begin match PurityState.get_purity_from_meta f2.cf_meta,PurityState.get_purity_from_meta f1.cf_meta with
| PurityState.Pure,PurityState.MaybePure -> f1.cf_meta <- (Meta.Pure,[EConst(Ident "expect"),f2.cf_pos],null_pos) :: f1.cf_meta
| PurityState.Pure,PurityState.MaybePure -> f1.cf_meta <- (Meta.Pure,[EConst(Ident "expect"),mk_zero_range_pos f2.cf_pos],null_pos) :: f1.cf_meta
| PurityState.ExpectPure p,PurityState.MaybePure -> f1.cf_meta <- (Meta.Pure,[EConst(Ident "expect"),p],null_pos) :: f1.cf_meta
| _ -> ()
end;
Expand Down Expand Up @@ -501,7 +501,7 @@ module Inheritance = struct
let process_meta csup =
List.iter (fun m ->
match m with
| Meta.AutoBuild, el, p -> c.cl_meta <- (Meta.Build,el,{ c.cl_pos with pmax = c.cl_pos.pmin }(* prevent display metadata *)) :: m :: c.cl_meta
| Meta.AutoBuild, el, p -> c.cl_meta <- (Meta.Build,el,mk_zero_range_pos c.cl_pos) :: m :: c.cl_meta
| _ -> ()
) (List.rev csup.cl_meta);
if has_class_flag csup CFinal && not (((has_class_flag csup CExtern) && Meta.has Meta.Hack c.cl_meta) || (match c.cl_kind with KTypeParameter _ -> true | _ -> false)) then
Expand Down
8 changes: 5 additions & 3 deletions src/typing/typeloadFields.ml
Original file line number Diff line number Diff line change
Expand Up @@ -735,7 +735,7 @@ module TypeBinding = struct
let p = cf.cf_pos in
let ctx = TyperManager.clone_for_expr ctx_f (if fctx.is_static then FunStatic else FunMember) false in
if (has_class_flag c CInterface) then unexpected_expression ctx.com fctx "Initialization on field of interface" (pos e);
cf.cf_meta <- ((Meta.Value,[e],cf.cf_pos) :: cf.cf_meta);
cf.cf_meta <- ((Meta.Value,[e],mk_zero_range_pos cf.cf_pos) :: cf.cf_meta);
let check_cast e =
(* insert cast to keep explicit field type (issue #1901) *)
if type_iseq e.etype cf.cf_type then
Expand Down Expand Up @@ -1246,8 +1246,10 @@ let create_method (ctx,cctx,fctx) c f cf fd p =
if fctx.is_inline then invalid_modifier_combination fctx ctx.com fctx "dynamic" "inline" p;
if fctx.is_abstract_member then invalid_modifier ctx.com fctx "dynamic" "method of abstract" p;
end;
let is_override = Option.is_some fctx.override in
if (is_override && fctx.is_static) then invalid_modifier_combination fctx ctx.com fctx "override" "static" p;
if Option.is_some fctx.override then begin
if fctx.is_static then invalid_modifier_combination fctx ctx.com fctx "override" "static" p;
add_class_field_flag cf CfOverride;
end;

ctx.type_params <- params @ ctx.type_params;
let args,ret = setup_args_ret ctx cctx fctx (fst f.cff_name) fd p in
Expand Down
2 changes: 1 addition & 1 deletion src/typing/typer.ml
Original file line number Diff line number Diff line change
Expand Up @@ -1995,7 +1995,7 @@ and type_expr ?(mode=MGet) ctx (e,p) (with_type:WithType.t) =
| EUntyped e ->
let old = ctx.f.untyped in
ctx.f.untyped <- true;
if not (Meta.has Meta.HasUntyped ctx.f.curfield.cf_meta) then ctx.f.curfield.cf_meta <- (Meta.HasUntyped,[],p) :: ctx.f.curfield.cf_meta;
if not (Meta.has Meta.HasUntyped ctx.f.curfield.cf_meta) then ctx.f.curfield.cf_meta <- (Meta.HasUntyped,[],mk_zero_range_pos p) :: ctx.f.curfield.cf_meta;
let e = type_expr ctx e with_type in
ctx.f.untyped <- old;
{
Expand Down
10 changes: 10 additions & 0 deletions std/haxe/macro/PositionTools.hx
Original file line number Diff line number Diff line change
Expand Up @@ -70,5 +70,15 @@ class PositionTools {
public static function toLocation(p:Position):Location {
return Context.load("position_to_range", 1)(p);
}

/**
Returns a copy of a `haxe.macro.Position`, with `pmax` set to `pmin`.
This ensures that the resulting position will not enclose other positions that might be
looked at for display requests, which could lead to unexpected results.
**/
public static function toZeroRange(p:Position):Position {
return Context.load("position_to_zero_range", 1)(p);
}
#end
}

0 comments on commit bdecee2

Please sign in to comment.