Skip to content

Commit

Permalink
Merge pull request #3228 from nadako/3198_anon_extend
Browse files Browse the repository at this point in the history
store structure extended types and expose it to the macro api with AnonStatus.AExtend (closes #3198)
  • Loading branch information
ncannasse committed Aug 6, 2014
2 parents 5223f9b + 715f727 commit 0097423
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 0097423

Please sign in to comment.