Compare commits
5 Commits
genes-issu
...
no-reflect
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8890b62b46 | ||
|
|
cce63becd6 | ||
|
|
a101378a4c | ||
|
|
b48b300cbc | ||
|
|
27c9b20330 |
2
.haxerc
2
.haxerc
@@ -1,4 +1,4 @@
|
|||||||
{
|
{
|
||||||
"version": "e552bdc",
|
"version": "4.0.5",
|
||||||
"resolveLibs": "scoped"
|
"resolveLibs": "scoped"
|
||||||
}
|
}
|
||||||
@@ -21,7 +21,7 @@ class Constructor {
|
|||||||
var afterArgs:Array<FunctionArg>;
|
var afterArgs:Array<FunctionArg>;
|
||||||
var pos:Position;
|
var pos:Position;
|
||||||
var onGenerateHooks:Array<Function->Void>;
|
var onGenerateHooks:Array<Function->Void>;
|
||||||
var superCall:Array<Expr>;
|
var superCall:Expr;
|
||||||
var owner:ClassBuilder;
|
var owner:ClassBuilder;
|
||||||
var meta:Metadata;
|
var meta:Metadata;
|
||||||
public var isPublic:Null<Bool>;
|
public var isPublic:Null<Bool>;
|
||||||
@@ -57,17 +57,12 @@ class Constructor {
|
|||||||
default: oldStatements = [f.expr];
|
default: oldStatements = [f.expr];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
superCall =
|
||||||
for (i in 0...oldStatements.length)
|
if (oldStatements.length == 0) [].toBlock();
|
||||||
switch oldStatements[i] {
|
else switch oldStatements[0] {
|
||||||
case macro super($a{_}):
|
case macro super($a{_}): oldStatements.shift();
|
||||||
superCall = oldStatements.splice(0, i + 1);
|
default: [].toBlock();
|
||||||
break;
|
|
||||||
default:
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (superCall == null)
|
|
||||||
superCall = [];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getArgList():Array<FunctionArg>
|
public function getArgList():Array<FunctionArg>
|
||||||
@@ -100,10 +95,33 @@ class Constructor {
|
|||||||
case Value(e): e;
|
case Value(e): e;
|
||||||
}
|
}
|
||||||
|
|
||||||
var tmp = MacroApi.tempName();
|
var member = owner.memberByName(name).sure(),
|
||||||
var member = owner.memberByName(name).sure();
|
initStatement = macro @:pos(pos) this.$name = $e;
|
||||||
|
|
||||||
if (options.bypass && member.kind.match(FProp(_, 'never' | 'set', _, _))) {
|
var bypass = switch options.bypass {
|
||||||
|
case null:
|
||||||
|
switch member.kind {
|
||||||
|
case FProp(_, 'default' | 'null', _):
|
||||||
|
false;
|
||||||
|
#if haxe4
|
||||||
|
case FProp('default', 'never', _):
|
||||||
|
member.isFinal = true;
|
||||||
|
false;
|
||||||
|
case FProp(_, 'set', _):
|
||||||
|
member.addMeta(':isVar');
|
||||||
|
initStatement = macro @:pos(pos) @:bypassAccessor this.$name = $e;
|
||||||
|
false;
|
||||||
|
#end
|
||||||
|
case FProp(_):
|
||||||
|
true;
|
||||||
|
case FFun(_):
|
||||||
|
pos.error('cannot rebind function');
|
||||||
|
default: false;
|
||||||
|
}
|
||||||
|
case v: v;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bypass && member.kind.match(FProp(_, 'never' | 'set', _, _))) {
|
||||||
|
|
||||||
member.addMeta(':isVar');
|
member.addMeta(':isVar');
|
||||||
|
|
||||||
@@ -135,8 +153,14 @@ class Constructor {
|
|||||||
macro @:pos(pos) this.$name = $e;
|
macro @:pos(pos) this.$name = $e;
|
||||||
case FVar(AccNo | AccNormal, AccNever):
|
case FVar(AccNo | AccNormal, AccNever):
|
||||||
setDirectly(Context.typeExpr(macro @:pos(pos) this.$name));
|
setDirectly(Context.typeExpr(macro @:pos(pos) this.$name));
|
||||||
|
#if haxe4
|
||||||
|
case FVar(AccCall, _):
|
||||||
|
var target = Context.storeTypedExpr(Context.typeExpr(macro @:pos(pos) @:bypassAccessor this.$name));
|
||||||
|
macro @:pos(pos) $target = $e;
|
||||||
|
#else
|
||||||
case FVar(AccCall, AccNever):
|
case FVar(AccCall, AccNever):
|
||||||
setDirectly(fields['get_$name'].expr());
|
setDirectly(fields['get_$name'].expr());
|
||||||
|
#end
|
||||||
case FVar(_, AccCall):
|
case FVar(_, AccCall):
|
||||||
setDirectly(fields['set_$name'].expr());
|
setDirectly(fields['set_$name'].expr());
|
||||||
default:
|
default:
|
||||||
@@ -146,14 +170,17 @@ class Constructor {
|
|||||||
}).bounce(), options.prepend);
|
}).bounce(), options.prepend);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
addStatement(macro @:pos(pos) this.$name = $e, options.prepend);
|
addStatement(
|
||||||
|
initStatement,
|
||||||
|
options.prepend
|
||||||
|
);
|
||||||
}
|
}
|
||||||
public inline function publish()
|
public inline function publish()
|
||||||
if (isPublic == null)
|
if (isPublic == null)
|
||||||
isPublic = true;
|
isPublic = true;
|
||||||
|
|
||||||
function toBlock()
|
function toBlock()
|
||||||
return superCall
|
return [superCall]
|
||||||
.concat(nuStatements)
|
.concat(nuStatements)
|
||||||
.concat(oldStatements)
|
.concat(oldStatements)
|
||||||
.toBlock(pos);
|
.toBlock(pos);
|
||||||
|
|||||||
@@ -1,12 +1,11 @@
|
|||||||
package tink.macro;
|
package tink.macro;
|
||||||
|
|
||||||
import Type in Inspect;
|
|
||||||
|
|
||||||
import haxe.macro.Context;
|
import haxe.macro.Context;
|
||||||
import haxe.macro.Expr;
|
import haxe.macro.Expr;
|
||||||
import haxe.macro.Type;
|
import haxe.macro.Type;
|
||||||
import haxe.PosInfos;
|
import haxe.PosInfos;
|
||||||
import haxe.macro.Printer;
|
import haxe.macro.Printer;
|
||||||
|
import haxe.DynamicAccess as Dict;
|
||||||
|
|
||||||
using Lambda;
|
using Lambda;
|
||||||
using StringTools;
|
using StringTools;
|
||||||
@@ -20,6 +19,7 @@ typedef VarDecl = { name : String, type : ComplexType, expr : Null<Expr> };
|
|||||||
typedef ParamSubst = {
|
typedef ParamSubst = {
|
||||||
var exists(default, null):String->Bool;
|
var exists(default, null):String->Bool;
|
||||||
var get(default, null):String->ComplexType;
|
var get(default, null):String->ComplexType;
|
||||||
|
function iterator():Iterator<ComplexType>;
|
||||||
}
|
}
|
||||||
|
|
||||||
private class Heureka { public function new() {} }
|
private class Heureka { public function new() {} }
|
||||||
@@ -34,7 +34,7 @@ class Exprs {
|
|||||||
case _ if (condition(e)): throw new Heureka();
|
case _ if (condition(e)): throw new Heureka();
|
||||||
default: haxe.macro.ExprTools.iter(e, seek);
|
default: haxe.macro.ExprTools.iter(e, seek);
|
||||||
}
|
}
|
||||||
|
|
||||||
return try {
|
return try {
|
||||||
haxe.macro.ExprTools.iter(e, seek);
|
haxe.macro.ExprTools.iter(e, seek);
|
||||||
false;
|
false;
|
||||||
@@ -48,22 +48,23 @@ class Exprs {
|
|||||||
static public inline function as(e:Expr, c:ComplexType)
|
static public inline function as(e:Expr, c:ComplexType)
|
||||||
return ECheckType(e, c).at(e.pos);
|
return ECheckType(e, c).at(e.pos);
|
||||||
|
|
||||||
static public function finalize(e:Expr, ?nuPos:Position, ?rules:Dynamic<String>, ?skipFields = false, ?callPos:PosInfos) {
|
static public function finalize(e:Expr, ?nuPos:Position, ?rules:Dict<String>, ?skipFields = false, ?callPos:PosInfos) {
|
||||||
if (nuPos == null)
|
if (nuPos == null)
|
||||||
nuPos = Context.currentPos();
|
nuPos = Context.currentPos();
|
||||||
if (rules == null)
|
if (rules == null)
|
||||||
rules = { };
|
rules = { };
|
||||||
function replace(s:String)
|
|
||||||
return {
|
function replace(s:String):String
|
||||||
if (Reflect.hasField(rules, s))
|
return switch rules[s] {
|
||||||
Reflect.field(rules, s)
|
case null:
|
||||||
else if (s.startsWith('tmp')) {
|
if (s.startsWith('tmp')) {
|
||||||
Reflect.setField(rules, s, MacroApi.tempName(s.substr(3)));
|
rules[s] = MacroApi.tempName(s.substr(3));
|
||||||
replace(s);
|
replace(s);
|
||||||
}
|
}
|
||||||
else s;
|
else s;
|
||||||
|
case v: v;
|
||||||
}
|
}
|
||||||
|
|
||||||
return e.transform(function (e:Expr) {
|
return e.transform(function (e:Expr) {
|
||||||
return
|
return
|
||||||
if (Context.getPosInfos(e.pos).file != callPos.fileName) e;
|
if (Context.getPosInfos(e.pos).file != callPos.fileName) e;
|
||||||
@@ -71,7 +72,7 @@ class Exprs {
|
|||||||
e.pos = nuPos;
|
e.pos = nuPos;
|
||||||
switch (e.expr) {
|
switch (e.expr) {
|
||||||
case EVars(vars):
|
case EVars(vars):
|
||||||
for (v in vars)
|
for (v in vars)
|
||||||
v.name = replace(v.name);
|
v.name = replace(v.name);
|
||||||
e;
|
e;
|
||||||
case EField(owner, field):
|
case EField(owner, field):
|
||||||
@@ -86,7 +87,7 @@ class Exprs {
|
|||||||
for (f in fields)
|
for (f in fields)
|
||||||
f.field = replace(f.field);
|
f.field = replace(f.field);
|
||||||
e;
|
e;
|
||||||
default:
|
default:
|
||||||
switch (e.getIdent()) {
|
switch (e.getIdent()) {
|
||||||
case Success(s): replace(s).resolve(e.pos);
|
case Success(s): replace(s).resolve(e.pos);
|
||||||
default: e;
|
default: e;
|
||||||
@@ -95,10 +96,10 @@ class Exprs {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
static public function withPrivateAccess(e:Expr)
|
static public function withPrivateAccess(e:Expr)
|
||||||
return
|
return
|
||||||
e.transform(function (e:Expr)
|
e.transform(function (e:Expr)
|
||||||
return
|
return
|
||||||
switch (e.expr) {
|
switch (e.expr) {
|
||||||
case EField(owner, field):
|
case EField(owner, field):
|
||||||
@@ -106,72 +107,95 @@ class Exprs {
|
|||||||
default: e;
|
default: e;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
static public function getPrivate(e:Expr, field:String, ?pos:Position)
|
static public function getPrivate(e:Expr, field:String, ?pos:Position)
|
||||||
return macro @:pos(pos.sanitize()) @:privateAccess $e.$field;
|
return macro @:pos(pos.sanitize()) @:privateAccess $e.$field;
|
||||||
|
|
||||||
static public function substitute(source:Expr, vars:Dynamic<Expr>, ?pos)
|
static public function substitute(source:Expr, vars:Dict<Expr>, ?pos)
|
||||||
return
|
return
|
||||||
transform(source, function (e:Expr) {
|
transform(source, function (e:Expr) {
|
||||||
return
|
return switch e {
|
||||||
switch (e.getIdent()) {
|
case macro $i{name}:
|
||||||
case Success(name):
|
switch vars[name] {
|
||||||
if (Reflect.hasField(vars, name))
|
case null: e;
|
||||||
Reflect.field(vars, name);
|
case v: v;
|
||||||
else
|
}
|
||||||
e;
|
default: e;
|
||||||
default: e;
|
}
|
||||||
}
|
|
||||||
}, pos);
|
}, pos);
|
||||||
|
|
||||||
static public inline function ifNull(e:Expr, fallback:Expr)
|
static public inline function ifNull(e:Expr, fallback:Expr)
|
||||||
return
|
return
|
||||||
switch e {
|
switch e {
|
||||||
case macro null: fallback;
|
case macro null: fallback;
|
||||||
default: e;
|
default: e;
|
||||||
}
|
}
|
||||||
|
|
||||||
static public function substParams(source:Expr, subst:ParamSubst, ?pos):Expr
|
static public function substParams(source:Expr, subst:ParamSubst, ?pos:Position):Expr {
|
||||||
return crawl(
|
if (!subst.iterator().hasNext())
|
||||||
source,
|
return source;
|
||||||
function (e)
|
|
||||||
return switch e.expr {
|
function replace(ct:ComplexType)
|
||||||
case ENew({ pack: [], name: name }, args) if (subst.exists(name)):
|
return switch ct {
|
||||||
switch subst.get(name) {
|
case TPath({ pack: [], name: name }) if (subst.exists(name)):
|
||||||
case TPath(p):
|
subst.get(name);
|
||||||
ENew(p, args).at(e.pos);
|
default: ct;
|
||||||
default: e;//TODO: report an error?
|
}
|
||||||
}
|
|
||||||
case EConst(CIdent(name)) if (subst.exists(name)):
|
return source
|
||||||
|
.transform(
|
||||||
|
function (e) return switch e {
|
||||||
|
case macro $i{name} if (subst.exists(name)):
|
||||||
switch subst.get(name) {
|
switch subst.get(name) {
|
||||||
case TPath({ pack: pack, name: name }):
|
case TPath({ pack: pack, name: name }):
|
||||||
pack.concat([name]).drill(e.pos);
|
pack.concat([name]).drill(e.pos);
|
||||||
default: e;//TODO: report an error?
|
default: e;//TODO: report an error?
|
||||||
}
|
}
|
||||||
default: e;
|
default: e;
|
||||||
},
|
})
|
||||||
function (c:ComplexType)
|
.mapTypes(replace);
|
||||||
return
|
}
|
||||||
switch (c) {
|
|
||||||
case TPath({ pack: [], name: name }) if (subst.exists(name)):
|
static public function mapTypes(e:Expr, transformer:ComplexType->ComplexType, ?pos:Position) {
|
||||||
subst.get(name);
|
return e.transform(
|
||||||
default: c;
|
function (e) return switch e {
|
||||||
|
case { expr: ENew(p, args) }:
|
||||||
|
switch TPath(p).map(transformer) {
|
||||||
|
case TPath(nu):
|
||||||
|
ENew(nu, args).at(e.pos);
|
||||||
|
case v:
|
||||||
|
pos.error(v.toString() + ' cannot be instantiated in ${e.pos}');
|
||||||
}
|
}
|
||||||
, pos);
|
case macro cast($v, $ct):
|
||||||
|
ct = ct.map(transformer);
|
||||||
static public function transform(source:Expr, transformer:Expr->Expr, ?pos):Expr
|
(macro @:pos(e.pos) cast($v, $ct));
|
||||||
return crawl(source, transformer, function (t) return t, pos);
|
case { expr: ECheckType(v, ct) }: // cannot use reification, because that's `EParentheses(ECheckType)` and macros can (and apparently do) generate a non-wrapped one
|
||||||
|
ECheckType(v, ct.map(transformer)).at(e.pos);
|
||||||
static function crawlArray(a:Array<Dynamic>, transformer:Expr->Expr, retyper:ComplexType-> ComplexType, pos:Position):Array<Dynamic>
|
case { expr: EVars(vars) }:
|
||||||
|
EVars([for (v in vars) {
|
||||||
|
name: v.name,
|
||||||
|
type: v.type.map(transformer),
|
||||||
|
expr: v.expr,
|
||||||
|
}]).at(e.pos);
|
||||||
|
case { expr: EFunction(kind, f) }:
|
||||||
|
EFunction(kind, Functions.mapSignature(f, transformer)).at(e.pos);
|
||||||
|
default: e;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static public function transform(source:Expr, transformer:Expr->Expr, ?pos):Expr {
|
||||||
|
function apply(e:Expr)
|
||||||
|
return switch e {
|
||||||
|
case null | { expr: null }: e;
|
||||||
|
default: transformer(haxe.macro.ExprTools.map(e, apply));
|
||||||
|
}
|
||||||
|
|
||||||
|
return apply(source);
|
||||||
|
}
|
||||||
|
|
||||||
|
static public function getIterType(target:Expr)
|
||||||
return
|
return
|
||||||
if (a == null) a;
|
|
||||||
else
|
|
||||||
[for (v in a)
|
|
||||||
crawl(v, transformer, retyper, pos)
|
|
||||||
];
|
|
||||||
|
|
||||||
static public function getIterType(target:Expr)
|
|
||||||
return
|
|
||||||
(macro @:pos(target.pos) {
|
(macro @:pos(target.pos) {
|
||||||
var t = null,
|
var t = null,
|
||||||
target = $target;
|
target = $target;
|
||||||
@@ -179,21 +203,21 @@ class Exprs {
|
|||||||
t = i;
|
t = i;
|
||||||
t;
|
t;
|
||||||
}).typeof();
|
}).typeof();
|
||||||
|
|
||||||
static public function yield(e:Expr, yielder:Expr->Expr, ?options: { ?leaveLoops: Bool }):Expr {
|
static public function yield(e:Expr, yielder:Expr->Expr, ?options: { ?leaveLoops: Bool }):Expr {
|
||||||
inline function rec(e)
|
inline function rec(e)
|
||||||
return yield(e, yielder, options);
|
return yield(e, yielder, options);
|
||||||
|
|
||||||
if (options == null)
|
if (options == null)
|
||||||
options = { };
|
options = { };
|
||||||
|
|
||||||
var loops = options.leaveLoops != true;
|
var loops = options.leaveLoops != true;
|
||||||
return
|
return
|
||||||
if (e == null || e.expr == null) e;
|
if (e == null || e.expr == null) e;
|
||||||
else switch (e.expr) {
|
else switch (e.expr) {
|
||||||
case EVars(_):
|
case EVars(_):
|
||||||
e.pos.error('Variable declaration not supported here');
|
e.pos.error('Variable declaration not supported here');
|
||||||
case EBlock(exprs) if (exprs.length > 0):
|
case EBlock(exprs) if (exprs.length > 0):
|
||||||
exprs = exprs.copy();
|
exprs = exprs.copy();
|
||||||
exprs.push(rec(exprs.pop()));
|
exprs.push(rec(exprs.pop()));
|
||||||
EBlock(exprs).at(e.pos);
|
EBlock(exprs).at(e.pos);
|
||||||
@@ -201,10 +225,11 @@ class Exprs {
|
|||||||
,ETernary(econd, eif, eelse):
|
,ETernary(econd, eif, eelse):
|
||||||
EIf(econd, rec(eif), rec(eelse)).at(e.pos);
|
EIf(econd, rec(eif), rec(eelse)).at(e.pos);
|
||||||
case ESwitch(e, cases, edef):
|
case ESwitch(e, cases, edef):
|
||||||
cases = Reflect.copy(cases);//not exactly pretty, but does the job
|
ESwitch(e, [for (c in cases) {
|
||||||
for (c in cases)
|
expr: rec(c.expr),
|
||||||
c.expr = rec(c.expr);
|
guard: c.guard,
|
||||||
ESwitch(e, cases, rec(edef)).at(e.pos);
|
values: c.values,
|
||||||
|
}], rec(edef)).at(e.pos);
|
||||||
case EFor(it, expr) if (loops):
|
case EFor(it, expr) if (loops):
|
||||||
EFor(it, rec(expr)).at(e.pos);
|
EFor(it, rec(expr)).at(e.pos);
|
||||||
case EWhile(cond, body, normal) if (loops):
|
case EWhile(cond, body, normal) if (loops):
|
||||||
@@ -218,101 +243,77 @@ class Exprs {
|
|||||||
default: yielder(e);
|
default: yielder(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static function crawl(target:Dynamic, transformer:Expr->Expr, retyper:ComplexType->ComplexType, pos:Position):Dynamic
|
static public inline function iterate(target:Expr, body:Expr, ?loopVar:String = 'i', ?pos:Position)
|
||||||
return
|
|
||||||
if (Std.is(target, Array))
|
|
||||||
crawlArray(target, transformer, retyper, pos);
|
|
||||||
else
|
|
||||||
switch (Inspect.typeof(target)) {
|
|
||||||
case TNull, TInt, TFloat, TBool, TFunction, TUnknown, TClass(_): target;
|
|
||||||
case TEnum(e):
|
|
||||||
var ret:Dynamic = Inspect.createEnumIndex(e, Inspect.enumIndex(target), crawlArray(Inspect.enumParameters(target), transformer, retyper, pos));
|
|
||||||
if (Inspect.getEnum(ret) == ComplexType)
|
|
||||||
retyper(ret);
|
|
||||||
else
|
|
||||||
ret;
|
|
||||||
case TObject:
|
|
||||||
var ret:Dynamic = { };
|
|
||||||
for (field in Reflect.fields(target))
|
|
||||||
Reflect.setField(ret, field, crawl(Reflect.field(target, field), transformer, retyper, pos));
|
|
||||||
if (Std.is(ret.expr, ExprDef)) {
|
|
||||||
ret = transformer(ret);
|
|
||||||
if (pos != null) ret.pos = pos;
|
|
||||||
}
|
|
||||||
ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static public inline function iterate(target:Expr, body:Expr, ?loopVar:String = 'i', ?pos:Position)
|
|
||||||
return macro @:pos(pos.sanitize()) for ($i{loopVar} in $target) $body;
|
return macro @:pos(pos.sanitize()) for ($i{loopVar} in $target) $body;
|
||||||
|
|
||||||
static public function toFields(object:Dynamic<Expr>, ?pos:Position)
|
static public function toFields(object:Dict<Expr>, ?pos:Position)
|
||||||
return EObjectDecl([for (field in Reflect.fields(object))
|
return EObjectDecl([for (field in object.keys())
|
||||||
{ field:field, expr: untyped Reflect.field(object, field) }
|
{ field:field, expr: object[field] }
|
||||||
]).at(pos);
|
]).at(pos);
|
||||||
|
|
||||||
static public inline function log(e:Expr, ?pos:PosInfos):Expr {
|
static public inline function log(e:Expr, ?pos:PosInfos):Expr {
|
||||||
haxe.Log.trace(e.toString(), pos);
|
haxe.Log.trace(e.toString(), pos);
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
static public inline function reject(e:Expr, ?reason:String = 'cannot handle expression'):Dynamic
|
static public inline function reject(e:Expr, ?reason:String = 'cannot handle expression'):Dynamic
|
||||||
return e.pos.error(reason);
|
return e.pos.error(reason);
|
||||||
|
|
||||||
static public inline function toString(e:Expr):String
|
static public inline function toString(e:Expr):String
|
||||||
return new haxe.macro.Printer().printExpr(e);
|
return new haxe.macro.Printer().printExpr(e);
|
||||||
|
|
||||||
static public inline function at(e:ExprDef, ?pos:Position)
|
static public inline function at(e:ExprDef, ?pos:Position)
|
||||||
return {
|
return {
|
||||||
expr: e,
|
expr: e,
|
||||||
pos: pos.sanitize()
|
pos: pos.sanitize()
|
||||||
};
|
};
|
||||||
|
|
||||||
static public inline function instantiate(s:String, ?args:Array<Expr>, ?params:Array<TypeParam>, ?pos:Position)
|
static public inline function instantiate(s:String, ?args:Array<Expr>, ?params:Array<TypeParam>, ?pos:Position)
|
||||||
return s.asTypePath(params).instantiate(args, pos);
|
return s.asTypePath(params).instantiate(args, pos);
|
||||||
|
|
||||||
static public inline function assign(target:Expr, value:Expr, ?op:Binop, ?pos:Position)
|
static public inline function assign(target:Expr, value:Expr, ?op:Binop, ?pos:Position)
|
||||||
return binOp(target, value, op == null ? OpAssign : OpAssignOp(op), pos);
|
return binOp(target, value, op == null ? OpAssign : OpAssignOp(op), pos);
|
||||||
|
|
||||||
static public inline function define(name:String, ?init:Expr, ?typ:ComplexType, ?pos:Position)
|
static public inline function define(name:String, ?init:Expr, ?typ:ComplexType, ?pos:Position)
|
||||||
return at(EVars([ { name:name, type: typ, expr: init } ]), pos);
|
return at(EVars([ { name:name, type: typ, expr: init } ]), pos);
|
||||||
|
|
||||||
static public inline function add(e1:Expr, e2, ?pos)
|
static public inline function add(e1:Expr, e2, ?pos)
|
||||||
return binOp(e1, e2, OpAdd, pos);
|
return binOp(e1, e2, OpAdd, pos);
|
||||||
|
|
||||||
static public inline function unOp(e:Expr, op, ?postFix = false, ?pos)
|
static public inline function unOp(e:Expr, op, ?postFix = false, ?pos)
|
||||||
return EUnop(op, postFix, e).at(pos);
|
return EUnop(op, postFix, e).at(pos);
|
||||||
|
|
||||||
static public inline function binOp(e1:Expr, e2, op, ?pos)
|
static public inline function binOp(e1:Expr, e2, op, ?pos)
|
||||||
return EBinop(op, e1, e2).at(pos);
|
return EBinop(op, e1, e2).at(pos);
|
||||||
|
|
||||||
static public inline function field(e:Expr, field, ?pos)
|
static public inline function field(e:Expr, field, ?pos)
|
||||||
return EField(e, field).at(pos);
|
return EField(e, field).at(pos);
|
||||||
|
|
||||||
static public inline function call(e:Expr, ?params, ?pos)
|
static public inline function call(e:Expr, ?params, ?pos)
|
||||||
return ECall(e, params == null ? [] : params).at(pos);
|
return ECall(e, params == null ? [] : params).at(pos);
|
||||||
|
|
||||||
static public inline function toExpr(v:Dynamic, ?pos:Position)
|
static public inline function toExpr(v:Dynamic, ?pos:Position)
|
||||||
return Context.makeExpr(v, pos.sanitize());
|
return Context.makeExpr(v, pos.sanitize());
|
||||||
|
|
||||||
static public inline function toArray(exprs:Iterable<Expr>, ?pos)
|
static public inline function toArray(exprs:Iterable<Expr>, ?pos)
|
||||||
return EArrayDecl(exprs.array()).at(pos);
|
return EArrayDecl(exprs.array()).at(pos);
|
||||||
|
|
||||||
static public inline function toMBlock(exprs:Array<Expr>, ?pos)
|
static public inline function toMBlock(exprs:Array<Expr>, ?pos)
|
||||||
return EBlock(exprs).at(pos);
|
return EBlock(exprs).at(pos);
|
||||||
|
|
||||||
static public inline function toBlock(exprs:Iterable<Expr>, ?pos)
|
static public inline function toBlock(exprs:Iterable<Expr>, ?pos)
|
||||||
return toMBlock(Lambda.array(exprs), pos);
|
return toMBlock(Lambda.array(exprs), pos);
|
||||||
|
|
||||||
static public function drill(parts:Array<String>, ?pos:Position, ?target:Expr) {
|
static public function drill(parts:Array<String>, ?pos:Position, ?target:Expr) {
|
||||||
if (target == null)
|
if (target == null)
|
||||||
target = at(EConst(CIdent(parts.shift())), pos);
|
target = at(EConst(CIdent(parts.shift())), pos);
|
||||||
for (part in parts)
|
for (part in parts)
|
||||||
target = field(target, part, pos);
|
target = field(target, part, pos);
|
||||||
return target;
|
return target;
|
||||||
}
|
}
|
||||||
|
|
||||||
static public inline function resolve(s:String, ?pos)
|
static public inline function resolve(s:String, ?pos)
|
||||||
return drill(s.split('.'), pos);
|
return drill(s.split('.'), pos);
|
||||||
|
|
||||||
static var scopes = new Array<Array<Var>>();
|
static var scopes = new Array<Array<Var>>();
|
||||||
@@ -320,7 +321,7 @@ class Exprs {
|
|||||||
static function inScope<T>(a:Array<Var>, f:Void->T) {
|
static function inScope<T>(a:Array<Var>, f:Void->T) {
|
||||||
scopes.push(a);
|
scopes.push(a);
|
||||||
|
|
||||||
inline function leave()
|
inline function leave()
|
||||||
scopes.pop();
|
scopes.pop();
|
||||||
try {
|
try {
|
||||||
var ret = f();
|
var ret = f();
|
||||||
@@ -330,24 +331,24 @@ class Exprs {
|
|||||||
catch (e:Dynamic) {
|
catch (e:Dynamic) {
|
||||||
leave();
|
leave();
|
||||||
return Error.rethrow(e);
|
return Error.rethrow(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static public function scoped<T>(f:Void->T)
|
static public function scoped<T>(f:Void->T)
|
||||||
return inScope([], f);
|
return inScope([], f);
|
||||||
|
|
||||||
static public function inSubScope<T>(f:Void->T, a:Array<Var>)
|
static public function inSubScope<T>(f:Void->T, a:Array<Var>)
|
||||||
return inScope(switch scopes[scopes.length - 1] {
|
return inScope(switch scopes[scopes.length - 1] {
|
||||||
case null: a;
|
case null: a;
|
||||||
case v: v.concat(a);
|
case v: v.concat(a);
|
||||||
}, f);
|
}, f);
|
||||||
|
|
||||||
static public function typeof(expr:Expr, ?locals)
|
static public function typeof(expr:Expr, ?locals)
|
||||||
return
|
return
|
||||||
try {
|
try {
|
||||||
if (locals == null)
|
if (locals == null)
|
||||||
locals = scopes[scopes.length - 1];
|
locals = scopes[scopes.length - 1];
|
||||||
if (locals != null)
|
if (locals != null)
|
||||||
expr = [EVars(locals).at(expr.pos), expr].toMBlock(expr.pos);
|
expr = [EVars(locals).at(expr.pos), expr].toMBlock(expr.pos);
|
||||||
Success(Context.typeof(expr));
|
Success(Context.typeof(expr));
|
||||||
}
|
}
|
||||||
@@ -356,20 +357,20 @@ class Exprs {
|
|||||||
}
|
}
|
||||||
catch (e:Dynamic) {
|
catch (e:Dynamic) {
|
||||||
expr.pos.makeFailure(e);
|
expr.pos.makeFailure(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
static public inline function cond(cond:Expr, cons:Expr, ?alt:Expr, ?pos)
|
static public inline function cond(cond:Expr, cons:Expr, ?alt:Expr, ?pos)
|
||||||
return EIf(cond, cons, alt).at(pos);
|
return EIf(cond, cons, alt).at(pos);
|
||||||
|
|
||||||
static public function isWildcard(e:Expr)
|
static public function isWildcard(e:Expr)
|
||||||
return
|
return
|
||||||
switch e {
|
switch e {
|
||||||
case macro _: true;
|
case macro _: true;
|
||||||
default: false;
|
default: false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static public function getString(e:Expr)
|
static public function getString(e:Expr)
|
||||||
return
|
return
|
||||||
switch (e.expr) {
|
switch (e.expr) {
|
||||||
case EConst(c):
|
case EConst(c):
|
||||||
switch (c) {
|
switch (c) {
|
||||||
@@ -377,10 +378,10 @@ class Exprs {
|
|||||||
default: e.pos.makeFailure(NOT_A_STRING);
|
default: e.pos.makeFailure(NOT_A_STRING);
|
||||||
}
|
}
|
||||||
default: e.pos.makeFailure(NOT_A_STRING);
|
default: e.pos.makeFailure(NOT_A_STRING);
|
||||||
}
|
}
|
||||||
|
|
||||||
static public function getInt(e:Expr)
|
static public function getInt(e:Expr)
|
||||||
return
|
return
|
||||||
switch (e.expr) {
|
switch (e.expr) {
|
||||||
case EConst(c):
|
case EConst(c):
|
||||||
switch (c) {
|
switch (c) {
|
||||||
@@ -388,22 +389,22 @@ class Exprs {
|
|||||||
default: e.pos.makeFailure(NOT_AN_INT);
|
default: e.pos.makeFailure(NOT_AN_INT);
|
||||||
}
|
}
|
||||||
default: e.pos.makeFailure(NOT_AN_INT);
|
default: e.pos.makeFailure(NOT_AN_INT);
|
||||||
}
|
}
|
||||||
|
|
||||||
static public function getIdent(e:Expr)
|
static public function getIdent(e:Expr)
|
||||||
return
|
return
|
||||||
switch (e.expr) {
|
switch (e.expr) {
|
||||||
case EConst(c):
|
case EConst(c):
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case CIdent(id): Success(id);
|
case CIdent(id): Success(id);
|
||||||
default: e.pos.makeFailure(NOT_AN_IDENT);
|
default: e.pos.makeFailure(NOT_AN_IDENT);
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
e.pos.makeFailure(NOT_AN_IDENT);
|
e.pos.makeFailure(NOT_AN_IDENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
static public function getName(e:Expr)
|
static public function getName(e:Expr)
|
||||||
return
|
return
|
||||||
switch (e.expr) {
|
switch (e.expr) {
|
||||||
case EConst(c):
|
case EConst(c):
|
||||||
switch (c) {
|
switch (c) {
|
||||||
@@ -411,15 +412,15 @@ class Exprs {
|
|||||||
default: e.pos.makeFailure(NOT_A_NAME);
|
default: e.pos.makeFailure(NOT_A_NAME);
|
||||||
}
|
}
|
||||||
default: e.pos.makeFailure(NOT_A_NAME);
|
default: e.pos.makeFailure(NOT_A_NAME);
|
||||||
}
|
}
|
||||||
|
|
||||||
static public function getFunction(e:Expr)
|
static public function getFunction(e:Expr)
|
||||||
return
|
return
|
||||||
switch (e.expr) {
|
switch (e.expr) {
|
||||||
case EFunction(_, f): Success(f);
|
case EFunction(_, f): Success(f);
|
||||||
default: e.pos.makeFailure(NOT_A_FUNCTION);
|
default: e.pos.makeFailure(NOT_A_FUNCTION);
|
||||||
}
|
}
|
||||||
|
|
||||||
static public function concat(e:Expr, with:Expr, ?pos) {
|
static public function concat(e:Expr, with:Expr, ?pos) {
|
||||||
if(pos == null) pos = e.pos;
|
if(pos == null) pos = e.pos;
|
||||||
return
|
return
|
||||||
@@ -430,7 +431,7 @@ class Exprs {
|
|||||||
default: EBlock([e, with]).at(pos);
|
default: EBlock([e, with]).at(pos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static var FIRST = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
|
static var FIRST = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
|
||||||
static var LATER = FIRST + '0123456789';
|
static var LATER = FIRST + '0123456789';
|
||||||
|
|
||||||
@@ -438,7 +439,7 @@ class Exprs {
|
|||||||
var ret = FIRST.charAt(i % FIRST.length);
|
var ret = FIRST.charAt(i % FIRST.length);
|
||||||
|
|
||||||
i = Std.int(i / FIRST.length);
|
i = Std.int(i / FIRST.length);
|
||||||
|
|
||||||
while (i > 0) {
|
while (i > 0) {
|
||||||
ret += LATER.charAt(i % LATER.length);
|
ret += LATER.charAt(i % LATER.length);
|
||||||
i = Std.int(i / LATER.length);
|
i = Std.int(i / LATER.length);
|
||||||
@@ -446,7 +447,7 @@ class Exprs {
|
|||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline var NOT_AN_INT = "integer constant expected";
|
static inline var NOT_AN_INT = "integer constant expected";
|
||||||
static inline var NOT_AN_IDENT = "identifier expected";
|
static inline var NOT_AN_IDENT = "identifier expected";
|
||||||
static inline var NOT_A_STRING = "string constant expected";
|
static inline var NOT_A_STRING = "string constant expected";
|
||||||
|
|||||||
@@ -14,9 +14,9 @@ private typedef Kind = String;
|
|||||||
#end
|
#end
|
||||||
|
|
||||||
class Functions {
|
class Functions {
|
||||||
static public inline function asExpr(f:Function, ?kind:Kind, ?pos)
|
static public inline function asExpr(f:Function, ?kind:Kind, ?pos)
|
||||||
return EFunction(kind, f).at(pos);
|
return EFunction(kind, f).at(pos);
|
||||||
|
|
||||||
static public inline function toArg(name:String, ?t, ?opt = false, ?value = null):FunctionArg {
|
static public inline function toArg(name:String, ?t, ?opt = false, ?value = null):FunctionArg {
|
||||||
return {
|
return {
|
||||||
name: name,
|
name: name,
|
||||||
@@ -31,8 +31,24 @@ class Functions {
|
|||||||
ret: ret,
|
ret: ret,
|
||||||
params: params == null ? [] : params,
|
params: params == null ? [] : params,
|
||||||
expr: if (makeReturn) EReturn(e).at(e.pos) else e
|
expr: if (makeReturn) EReturn(e).at(e.pos) else e
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static public function mapSignature(f:Function, transform):Function
|
||||||
|
return {
|
||||||
|
ret: Types.map(f.ret, transform),
|
||||||
|
args: [for (a in f.args) {
|
||||||
|
name: a.name,
|
||||||
|
value: a.value,
|
||||||
|
type: Types.map(a.type, transform),
|
||||||
|
#if haxe4
|
||||||
|
meta: a.meta,
|
||||||
|
#end
|
||||||
|
}],
|
||||||
|
expr: f.expr,
|
||||||
|
params: Types.mapTypeParamDecls(f.params, transform),
|
||||||
|
}
|
||||||
|
|
||||||
static public function getArgIdents(f:Function):Array<Expr> {
|
static public function getArgIdents(f:Function):Array<Expr> {
|
||||||
var ret = [];
|
var ret = [];
|
||||||
for (arg in f.args)
|
for (arg in f.args)
|
||||||
|
|||||||
@@ -70,6 +70,79 @@ class Types {
|
|||||||
getDeclaredFields(t.superClass.t.get(), out, marker);
|
getDeclaredFields(t.superClass.t.get(), out, marker);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static public function mapTypeParams(a:Array<TypeParam>, f)
|
||||||
|
return
|
||||||
|
if (a == null) null;
|
||||||
|
else [for (p in a) switch p {
|
||||||
|
case TPType(t): TPType(t.map(f));
|
||||||
|
default: p;
|
||||||
|
}];
|
||||||
|
|
||||||
|
static public function mapTypeParamDecls(a:Array<TypeParamDecl>, f:ComplexType->ComplexType):Array<TypeParamDecl>
|
||||||
|
return
|
||||||
|
if (a == null) null;
|
||||||
|
else [for (p in a) {
|
||||||
|
name: p.name,
|
||||||
|
meta: p.meta,
|
||||||
|
params: mapTypeParamDecls(p.params, f),
|
||||||
|
constraints: switch p.constraints {
|
||||||
|
case null: null;
|
||||||
|
case a: [for (t in a) map(t, f)];
|
||||||
|
}
|
||||||
|
}];
|
||||||
|
|
||||||
|
static public function mapTypePath(p:TypePath, transform):TypePath
|
||||||
|
return {
|
||||||
|
name: p.name,
|
||||||
|
pack: p.pack,
|
||||||
|
sub: p.sub,
|
||||||
|
params: mapTypeParams(p.params, transform),
|
||||||
|
}
|
||||||
|
|
||||||
|
static public function map(ct:ComplexType, transform:ComplexType->ComplexType) {
|
||||||
|
if (ct == null)
|
||||||
|
return null;
|
||||||
|
inline function rec(ct)
|
||||||
|
return map(transform(ct), transform);
|
||||||
|
|
||||||
|
function mapFields(fields:Array<Field>):Array<Field>
|
||||||
|
return [for (f in fields) {
|
||||||
|
name: f.name,
|
||||||
|
pos: f.pos,
|
||||||
|
kind: switch f.kind {
|
||||||
|
case FVar(t, e): FVar(rec(t), e);
|
||||||
|
case FProp(get, set, t, e): FProp(get, set, rec(t), e);
|
||||||
|
case FFun(f): FFun(Functions.mapSignature(f, transform));
|
||||||
|
},
|
||||||
|
access: f.access,
|
||||||
|
meta: switch f.meta {
|
||||||
|
case null: null;
|
||||||
|
case a: [for (m in a) {
|
||||||
|
name: m.name,
|
||||||
|
pos: m.pos,
|
||||||
|
params: [for (e in m.params) e.mapTypes(transform)],
|
||||||
|
}];
|
||||||
|
},
|
||||||
|
doc: f.doc,
|
||||||
|
}];
|
||||||
|
return transform(switch ct {
|
||||||
|
case TParent(t): TParent(rec(t));
|
||||||
|
#if haxe4
|
||||||
|
case TNamed(n, t): TNamed(n, rec(t));
|
||||||
|
case TIntersection(tl): TIntersection([for (t in tl) rec(t)]);
|
||||||
|
#end
|
||||||
|
case TOptional(t): TOptional(rec(t));
|
||||||
|
case TAnonymous(fields):
|
||||||
|
TAnonymous(mapFields(fields));
|
||||||
|
case TPath(p):
|
||||||
|
TPath(mapTypePath(p, transform));
|
||||||
|
case TExtend(paths, fields):
|
||||||
|
TExtend([for (p in paths) mapTypePath(p, transform)], mapFields(fields));
|
||||||
|
case TFunction(args, ret):
|
||||||
|
TFunction([for (a in args) rec(a)], rec(ret));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
static var fieldsCache = new Map();
|
static var fieldsCache = new Map();
|
||||||
static public function getFields(t:Type, ?substituteParams = true)
|
static public function getFields(t:Type, ?substituteParams = true)
|
||||||
return
|
return
|
||||||
@@ -84,12 +157,28 @@ class Types {
|
|||||||
}
|
}
|
||||||
var ret = fieldsCache.get(id);
|
var ret = fieldsCache.get(id);
|
||||||
if (substituteParams && ret.isSuccess()) {
|
if (substituteParams && ret.isSuccess()) {
|
||||||
var fields = Reflect.copy(ret.sure());
|
ret = Success([
|
||||||
|
for (field in ret.sure()) ({
|
||||||
for (field in fields)
|
name: field.name,
|
||||||
field.type = haxe.macro.TypeTools.applyTypeParameters(field.type, c.params, params);
|
type: haxe.macro.TypeTools.applyTypeParameters(field.type, c.params, params),
|
||||||
|
pos: field.pos,
|
||||||
|
meta: field.meta,
|
||||||
|
doc: field.doc,
|
||||||
|
expr: function () return field.expr(),
|
||||||
|
isPublic: field.isPublic,
|
||||||
|
params: field.params,
|
||||||
|
kind: field.kind,
|
||||||
|
overloads: field.overloads,
|
||||||
|
#if haxe4
|
||||||
|
isExtern: field.isExtern,
|
||||||
|
isFinal: field.isFinal,
|
||||||
|
#end
|
||||||
|
}:ClassField)
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
|
#if !haxe4
|
||||||
fieldsCache.remove(id);//TODO: find a proper solution to avoid stale cache
|
fieldsCache.remove(id);//TODO: find a proper solution to avoid stale cache
|
||||||
|
#end
|
||||||
ret;
|
ret;
|
||||||
case TAnonymous(anon): Success(anon.get().fields);
|
case TAnonymous(anon): Success(anon.get().fields);
|
||||||
default: Context.currentPos().makeFailure('type $t has no fields');
|
default: Context.currentPos().makeFailure('type $t has no fields');
|
||||||
@@ -101,8 +190,8 @@ class Types {
|
|||||||
case TInst(t, _): Success(t.get().statics.get());
|
case TInst(t, _): Success(t.get().statics.get());
|
||||||
default: Failure('type has no statics');
|
default: Failure('type has no statics');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static public function getPosition(t:Type)
|
static public function getPosition(t:Type)
|
||||||
return
|
return
|
||||||
switch t {
|
switch t {
|
||||||
@@ -115,8 +204,8 @@ class Types {
|
|||||||
case TDynamic(v) if(v != null): getPosition(v);
|
case TDynamic(v) if(v != null): getPosition(v);
|
||||||
default: Failure('type "$t" has no position');
|
default: Failure('type "$t" has no position');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static public function toString(t:ComplexType)
|
static public function toString(t:ComplexType)
|
||||||
return new Printer().printComplexType(t);
|
return new Printer().printComplexType(t);
|
||||||
@@ -202,7 +291,7 @@ class Types {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static public function intersect(types:Array<ComplexType>, ?pos:Position):Outcome<ComplexType, Error> {
|
static public function intersect(types:Array<ComplexType>, ?pos:Position):Outcome<ComplexType, Error> {
|
||||||
|
|
||||||
if (types.length == 1) return Success(types[1]);
|
if (types.length == 1) return Success(types[1]);
|
||||||
|
|
||||||
var paths = [],
|
var paths = [],
|
||||||
@@ -211,17 +300,17 @@ class Types {
|
|||||||
for (t in types)
|
for (t in types)
|
||||||
switch t {
|
switch t {
|
||||||
case TPath(p): paths.push(p);
|
case TPath(p): paths.push(p);
|
||||||
case TAnonymous(f):
|
case TAnonymous(f):
|
||||||
|
|
||||||
for (f in f) fields.push(f);
|
for (f in f) fields.push(f);
|
||||||
|
|
||||||
case TExtend(p, f):
|
case TExtend(p, f):
|
||||||
|
|
||||||
for (f in f) fields.push(f);
|
for (f in f) fields.push(f);
|
||||||
for (p in p) paths.push(p);
|
for (p in p) paths.push(p);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
||||||
return Failure(new Error(t.toString() + ' cannot be interesected', pos));
|
return Failure(new Error(t.toString() + ' cannot be interesected', pos));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -251,23 +340,23 @@ class Types {
|
|||||||
t1 = t1.reduce();
|
t1 = t1.reduce();
|
||||||
t2 = t2.reduce();
|
t2 = t2.reduce();
|
||||||
}
|
}
|
||||||
|
|
||||||
return switch t1.getIndex() - t2.getIndex() {
|
return switch t1.getIndex() - t2.getIndex() {
|
||||||
case 0:
|
case 0:
|
||||||
Reflect.compare(t1.toString(), t2.toString());//much to my surprise, this actually seems to work (at least with 3.4)
|
Reflect.compare(t1.toString(), t2.toString());//much to my surprise, this actually seems to work (at least with 3.4)
|
||||||
case v: v;
|
case v: v;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static var SUGGESTIONS = ~/ \(Suggestions?: .*\)$/;
|
static var SUGGESTIONS = ~/ \(Suggestions?: .*\)$/;
|
||||||
|
|
||||||
static public function getFieldSuggestions(type:ComplexType, name:String):String
|
static public function getFieldSuggestions(type:ComplexType, name:String):String
|
||||||
return switch (macro (null : $type).$name).typeof() {
|
return switch (macro (null : $type).$name).typeof() {
|
||||||
case Failure(SUGGESTIONS.match(_.message) => true): SUGGESTIONS.matched(0);
|
case Failure(SUGGESTIONS.match(_.message) => true): SUGGESTIONS.matched(0);
|
||||||
default: '';
|
default: '';
|
||||||
}
|
}
|
||||||
|
|
||||||
static public function toDecl(p:TypeParameter):TypeParamDecl
|
static public function toDecl(p:TypeParameter):TypeParamDecl
|
||||||
return {
|
return {
|
||||||
name: p.name,
|
name: p.name,
|
||||||
constraints: switch p.t {
|
constraints: switch p.t {
|
||||||
@@ -279,4 +368,4 @@ class Types {
|
|||||||
static public function toTypeParam(p:TypeParameter):TypeParam
|
static public function toTypeParam(p:TypeParameter):TypeParam
|
||||||
return TPType(p.t.toComplex());
|
return TPType(p.t.toComplex());
|
||||||
|
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user