Skip to content

Commit

Permalink
Resolves #33.
Browse files Browse the repository at this point in the history
  • Loading branch information
back2dos committed Feb 16, 2020
1 parent 1d4da3d commit 00d35d6
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 18 deletions.
4 changes: 2 additions & 2 deletions haxe_libraries/tink_anon.hxml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# @install: lix --silent download "gh://github.com/haxetink/tink_anon#4582ebd94bd0e45d568424306e1b74e8049bd5c0" into tink_anon/0.4.1/github/4582ebd94bd0e45d568424306e1b74e8049bd5c0
# @install: lix --silent download "gh://github.com/haxetink/tink_anon#8270b66b9ddbc499523716cd78a29a977918dfd9" into tink_anon/0.4.1/github/8270b66b9ddbc499523716cd78a29a977918dfd9
-lib tink_macro
-cp ${HAXE_LIBCACHE}/tink_anon/0.4.1/github/4582ebd94bd0e45d568424306e1b74e8049bd5c0/src
-cp ${HAXE_LIBCACHE}/tink_anon/0.4.1/github/8270b66b9ddbc499523716cd78a29a977918dfd9/src
-D tink_anon=0.4.1
8 changes: 5 additions & 3 deletions src/tink/hxx/Generator.hx
Original file line number Diff line number Diff line change
Expand Up @@ -151,11 +151,13 @@ class Generator {

args.unshift(
compute(function () {
var attrType = fieldsType.toComplex({ direct: true });
var paramatrized = tag.parametrized();
var attrType = paramatrized.fieldsType;

return mergeParts(
attributes,
spreads,
RStatic(fieldsToInfos(fields)),
paramatrized.requiredFields,
function (name) return switch aliases[name] {
case null: name;
case v: v;
Expand Down Expand Up @@ -293,7 +295,7 @@ class Generator {
#end

for (c in requiredArgs[0].t.getFields().sure())
tags[c.name] = Tag.declaration.bind(c.name, _, c.type);
tags[c.name] = Tag.declaration.bind(c.name, _, c.type, c.params);

macro @:pos(n.name.pos) {
tink.Anon.splat(__data__);
Expand Down
55 changes: 42 additions & 13 deletions src/tink/hxx/Tag.hx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package tink.hxx;

#if macro
import tink.anon.Macro;
import haxe.macro.Context;
import haxe.macro.Type;
import haxe.macro.Expr;
Expand All @@ -19,6 +20,11 @@ using StringTools;
public var isVoid(default, null):Bool;
public var hxxMeta(default, null):Map<String, Type>;

public var parametrized(default, null):Void->{
var fieldsType(default, null):ComplexType;
var requiredFields(default, null):RequireFields;
}

static function startsCapital(s:String)
return s.charAt(0).toUpperCase() == s.charAt(0);

Expand All @@ -37,25 +43,25 @@ using StringTools;
if (found == null)
name.pos.makeFailure('unknown tag <${name.value}>');
else
Success((localTags[name.value] = declaration.bind(name.value, _, found))(name.pos));
Success((localTags[name.value] = declaration.bind(name.value, _, found, []))(name.pos));
case get: Success(get(name.pos));
}

static public function getAllInScope(defaults:Lazy<Array<Named<Position->Tag>>>) {
var localTags = new Map();
function add(name:String, type)
function add(name:String, type, params)
if (name.charAt(0) != '_')//seems reasonable
localTags[name] = {
var ret = null;
function (pos) {//seems I've reimplemented `tink.core.Lazy` here for some reason
if (ret == null)
ret = declaration(name, pos, type);
ret = declaration(name, pos, type, params);
return ret;
}
}
var vars = Context.getLocalVars();
for (name in vars.keys())
add(name, vars[name]);
add(name, vars[name], []);

switch Context.getLocalType() {
case null:
Expand All @@ -67,9 +73,9 @@ using StringTools;
if (fields.exists(method) || method == 'new')
for (f in fields)
if (f.kind.match(FMethod(MethNormal | MethInline | MethDynamic)))
add(f.name, f.type);
add(f.name, f.type, f.params);
for (f in statics)
add(f.name, f.type);
add(f.name, f.type, f.params);

default:
}
Expand Down Expand Up @@ -103,7 +109,7 @@ using StringTools;
return localTags;
}

static function makeArgs(pos:Position, name:String, t:Type, ?children:Type):TagArgs {
static function makeArgs(pos:Position, name:String, t:Type, params:Array<TypeParameter>, ?children:Type):TagArgs {
function anon(anon:AnonType, t, lift:Bool, children:Type):TagArgs {
var fields = new Map(),
aliases = new Map(),
Expand Down Expand Up @@ -230,9 +236,9 @@ using StringTools;
}
}

static public function declaration(name:String, pos:Position, type:Type, ?isVoid:Bool):Tag {
static public function declaration(name:String, pos:Position, type:Type, params:Array<TypeParameter>, ?isVoid:Bool):Tag {

function mk(args, create, callee, ?realPath):Tag {
function mk(args, create, callee, params, ?realPath):Tag {
if (false)
TFun(args, null);//force inference

Expand Down Expand Up @@ -274,7 +280,7 @@ using StringTools;
default: reject('defines too many arguments');
}

var args = makeArgs(pos, name, attr, children);
var args = makeArgs(pos, name, attr, params, children);
for (keys in [args.aliases.keys(), args.fields.keys()])
for (k in keys)
if (hxxMeta.exists(k))
Expand All @@ -290,6 +296,29 @@ using StringTools;
name: name,
realPath: realPath,
isVoid: isVoid,
parametrized: switch params {
case []:
var ret = {
fieldsType: args.fieldsType.toComplex({ direct: true }),
requiredFields: RStatic(Macro.fieldsToInfos(args.fields)),
}
function () return ret;
default:
function () {
var ct = args.fieldsType.reduce().applyTypeParameters(params, [for (t in params) Context.typeof(macro cast null)]).toComplex({ direct: true });
var placeholder = macro (cast null : $ct);
return {
fieldsType: ct,
requiredFields: RStatic(Macro.fieldsToInfos(
args.fields,
function (f) {
var name = f.name;
return Context.typeof(macro $placeholder.$name);
}
))
}
}
}
}
}

Expand Down Expand Up @@ -325,7 +354,7 @@ using StringTools;
return
switch f.type.reduce() {
case TFun(args, _):
mk(args, kind, '$name.$kind', realPath);
mk(args, kind, '$name.$kind', f.params, realPath);
case v:
throw 'assert $v';
}
Expand Down Expand Up @@ -356,7 +385,7 @@ using StringTools;
return
switch type.reduce() {
case TFun(args, _):
mk(args, Call, name);
mk(args, Call, name, []);
default:
fromType(Context.getType(name));
}
Expand Down Expand Up @@ -391,7 +420,7 @@ using StringTools;
var decl = null;
function make(pos) {
if (decl == null)
decl = declaration('$name.${f.name}', pos, f.type, f.meta.extract(':voidTag').length > 0);
decl = declaration('$name.${f.name}', pos, f.type, f.params, f.meta.extract(':voidTag').length > 0);
return decl;
}

Expand Down

0 comments on commit 00d35d6

Please sign in to comment.