Skip to content

Commit

Permalink
store structure extended types and expose it to the macro api with An…
Browse files Browse the repository at this point in the history
…onStatus.AExtend (closes #3198)
  • Loading branch information
nadako committed Aug 5, 2014
1 parent 5223f9b commit 715f727
Show file tree
Hide file tree
Showing 7 changed files with 45 additions and 7 deletions.
1 change: 1 addition & 0 deletions extra/CHANGES.txt
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
macro : added Context.getLocalTVars
macro : added TypedExprTools.iter
macro : changed @:genericBuild macros to prefer ComplexType returns
macro : [breaking] extended TAnonymous structures now have AExtend status instead of AClosed

Deprecations:

Expand Down
7 changes: 4 additions & 3 deletions interp.ml
Original file line number Diff line number Diff line change
Expand Up @@ -4374,9 +4374,10 @@ and encode_anon_status s =
| Closed -> 0, []
| Opened -> 1, []
| Type.Const -> 2, []
| Statics cl -> 3, [encode_clref cl]
| EnumStatics en -> 4, [encode_enref en]
| AbstractStatics ab -> 5, [encode_abref ab]
| Extend tl -> 3, [encode_ref tl (fun tl -> enc_array (List.map encode_type tl)) (fun() -> "<extended types>")]
| Statics cl -> 4, [encode_clref cl]
| EnumStatics en -> 5, [encode_enref en]
| AbstractStatics ab -> 6, [encode_abref ab]
)
in
enc_enum IAnonStatus tag pl
Expand Down
1 change: 1 addition & 0 deletions std/haxe/macro/Type.hx
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ enum AnonStatus {
AClosed;
AOpened;
AConst;
AExtend( tl:Ref<Array<Type>> );
AClassStatics( t : Ref<ClassType> );
AEnumStatics( t : Ref<EnumType> );
AAbstractStatics( t : Ref<AbstractType> );
Expand Down
33 changes: 33 additions & 0 deletions tests/unit/issues/Issue3198.hx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package unit.issues;

#if macro
import haxe.macro.Context;
#end

private typedef A = {a:Int}
private typedef B = {b:Int}
private typedef C = {>A,}
private typedef D = {>A, >B,}

class Issue3198 extends Test {
function test() {
eq(getExtends((null : C)), "A");
eq(getExtends((null : D)), "A,B");
}

static macro function getExtends(e) {
switch (Context.follow(Context.typeof(e))) {
case TAnonymous(_.get() => {status: AExtend(_.get() => tl)}):
var p = [];
for (t in tl) switch (t) {
case TType(_.get() => dt, []):
p.push(dt.name);
default:
throw false;
}
return macro $v{p.join(",")};
default:
throw false;
}
}
}
5 changes: 3 additions & 2 deletions type.ml
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ and anon_status =
| Closed
| Opened
| Const
| Extend of t list
| Statics of tclass
| EnumStatics of tenum
| AbstractStatics of tabstract
Expand Down Expand Up @@ -1360,7 +1361,7 @@ let rec unify a b =
(match !(an.a_status) with
| Opened -> an.a_status := Closed;
| Statics _ | EnumStatics _ | AbstractStatics _ -> error []
| Closed | Const -> ())
| Closed | Extend _ | Const -> ())
with
Unify_error l -> error (cannot_unify a b :: l))
| TAnon a1, TAnon a2 ->
Expand Down Expand Up @@ -1403,7 +1404,7 @@ let rec unify a b =
| EnumStatics e -> (match !(a1.a_status) with EnumStatics e2 when e == e2 -> () | _ -> error [])
| AbstractStatics a -> (match !(a1.a_status) with AbstractStatics a2 when a == a2 -> () | _ -> error [])
| Opened -> a2.a_status := Closed
| Const | Closed -> ())
| Const | Extend _ | Closed -> ())
with
Unify_error l -> error (cannot_unify a b :: l))
| TAnon an, TAbstract ({ a_path = [],"Class" },[pt]) ->
Expand Down
3 changes: 2 additions & 1 deletion typeload.ml
Original file line number Diff line number Diff line change
Expand Up @@ -466,7 +466,7 @@ and load_complex_type ctx p t =
error "Loop found in cascading signatures definitions. Please change order/import" p
| TAnon a2 ->
PMap.iter (fun _ cf -> ignore(is_redefined cf a2)) a.a_fields;
mk_anon (PMap.foldi PMap.add a.a_fields a2.a_fields)
TAnon { a_fields = (PMap.foldi PMap.add a.a_fields a2.a_fields); a_status = ref (Extend [t]); }
| _ -> error "Can only extend classes and structures" p
in
let loop t = match follow t with
Expand All @@ -488,6 +488,7 @@ and load_complex_type ctx p t =
mk_extension i
| _ ->
List.iter loop il;
a.a_status := Extend il;
ta);
t
) "constraint" in
Expand Down
2 changes: 1 addition & 1 deletion typer.ml
Original file line number Diff line number Diff line change
Expand Up @@ -1390,7 +1390,7 @@ and type_field ?(resume=false) ctx e i p mode =
let f = PMap.find i a.a_fields in
if not f.cf_public && not ctx.untyped then begin
match !(a.a_status) with
| Closed -> () (* always allow anon private fields access *)
| Closed | Extend _ -> () (* always allow anon private fields access *)
| Statics c when can_access ctx c f true -> ()
| _ -> display_error ctx ("Cannot access private field " ^ i) p
end;
Expand Down

0 comments on commit 715f727

Please sign in to comment.