Compare commits
2 Commits
1.0.3
...
build-cach
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bc9f7460c2 | ||
|
|
043df0f47d |
@@ -17,18 +17,18 @@ typedef BuildContextN = {
|
|||||||
|
|
||||||
|
|
||||||
typedef BuildContext = {
|
typedef BuildContext = {
|
||||||
pos:Position,
|
var pos(default, never):Position;
|
||||||
type:Type,
|
var type(default, never):Type;
|
||||||
usings:Array<TypePath>,
|
var usings(default, never):Array<TypePath>;
|
||||||
name:String,
|
var name(default, never):String;
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef BuildContext2 = {>BuildContext,
|
typedef BuildContext2 = {>BuildContext,
|
||||||
type2:Type,
|
var type2(default, never):Type;
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef BuildContext3 = {>BuildContext2,
|
typedef BuildContext3 = {>BuildContext2,
|
||||||
type3:Type,
|
var type3(default, never):Type;
|
||||||
}
|
}
|
||||||
|
|
||||||
class BuildCache {
|
class BuildCache {
|
||||||
@@ -36,29 +36,20 @@ class BuildCache {
|
|||||||
@:persistent static var cache = new Map();
|
@:persistent static var cache = new Map();
|
||||||
|
|
||||||
static public function getType3(name, ?types, ?pos:Position, build:BuildContext3->TypeDefinition, ?normalizer:Type->Type) {
|
static public function getType3(name, ?types, ?pos:Position, build:BuildContext3->TypeDefinition, ?normalizer:Type->Type) {
|
||||||
if (types == null)
|
return _getTypeN(name, 3, switch types {
|
||||||
switch Context.getLocalType() {
|
case null: null;
|
||||||
case TInst(_.toString() == name => true, [t1, t2, t3]):
|
case v: [types.t1, types.t2, types.t3];
|
||||||
types = { t1: t1, t2: t2, t3: t3 };
|
}, pos, ctx -> build({
|
||||||
default:
|
|
||||||
throw 'assert';
|
|
||||||
}
|
|
||||||
|
|
||||||
var t1 = types.t1.toComplexType(),
|
|
||||||
t2 = types.t2.toComplexType(),
|
|
||||||
t3 = types.t2.toComplexType();
|
|
||||||
|
|
||||||
return getType(name, (macro : { t1: $t1, t2: $t2, t3: $t3 } ).toType(), pos, function (ctx) return build({
|
|
||||||
type: types.t1,
|
|
||||||
type2: types.t2,
|
|
||||||
type3: types.t3,
|
|
||||||
pos: ctx.pos,
|
pos: ctx.pos,
|
||||||
name: ctx.name,
|
type: ctx.types[0],
|
||||||
usings: ctx.usings
|
type2: ctx.types[1],
|
||||||
|
type3: ctx.types[2],
|
||||||
|
usings: ctx.usings,
|
||||||
|
name: ctx.name
|
||||||
}), normalizer);
|
}), normalizer);
|
||||||
}
|
}
|
||||||
|
|
||||||
static public function getTypeN(name, ?types, ?pos:Position, build:BuildContextN->TypeDefinition, ?normalizer:Type->Type) {
|
static function _getTypeN(name, length, ?types, ?pos:Position, build:BuildContextN->TypeDefinition, ?normalizer:Type->Type) {
|
||||||
|
|
||||||
if (pos == null)
|
if (pos == null)
|
||||||
pos = Context.currentPos();
|
pos = Context.currentPos();
|
||||||
@@ -67,50 +58,37 @@ class BuildCache {
|
|||||||
switch Context.getLocalType() {
|
switch Context.getLocalType() {
|
||||||
case TInst(_.toString() == name => true, params):
|
case TInst(_.toString() == name => true, params):
|
||||||
types = params;
|
types = params;
|
||||||
default:
|
case t:
|
||||||
throw 'assert';
|
pos.error('expected $name but found ${t.toString()}');
|
||||||
}
|
}
|
||||||
|
|
||||||
var compound = ComplexType.TAnonymous([for (i in 0...types.length) {
|
if (length != -1 && types.length != length)
|
||||||
name: 't$i',
|
pos.error('expected $length parameter${if (length == 1) '' else 's'}');
|
||||||
pos: pos,
|
|
||||||
kind: FVar(switch types[i] {
|
|
||||||
case TInst(_.get().kind => KExpr(e), _):
|
|
||||||
TPath('tink.macro.ConstParam'.asTypePath([TPExpr(e)]));
|
|
||||||
case t: t.toComplex();
|
|
||||||
}),
|
|
||||||
}]).toType();
|
|
||||||
|
|
||||||
return getType(name, compound, pos, function (ctx) return build({
|
var forName =
|
||||||
types: types,
|
switch cache[name] {
|
||||||
pos: ctx.pos,
|
case null: cache[name] = new Group(name);
|
||||||
name: ctx.name,
|
case v: v;
|
||||||
usings: ctx.usings
|
|
||||||
}), normalizer);
|
|
||||||
}
|
|
||||||
|
|
||||||
static public function getType2(name, ?types, ?pos:Position, build:BuildContext2->TypeDefinition, ?normalizer:Type->Type) {
|
|
||||||
if (types == null)
|
|
||||||
switch Context.getLocalType() {
|
|
||||||
case TInst(_.toString() == name => true, [t1, t2]):
|
|
||||||
types = { t1: t1, t2: t2 };
|
|
||||||
default:
|
|
||||||
throw 'assert';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var t1 = types.t1.toComplexType(),
|
var ret = forName.get(types, pos.sanitize(), build, normalizer);
|
||||||
t2 = types.t2.toComplexType();
|
ret.getFields();// workaround for https://github.com/HaxeFoundation/haxe/issues/7905
|
||||||
|
return ret;
|
||||||
return getType(name, (macro : { t1: $t1, t2: $t2 } ).toType(), pos, function (ctx) return build({
|
|
||||||
type: types.t1,
|
|
||||||
type2: types.t2,
|
|
||||||
pos: ctx.pos,
|
|
||||||
name: ctx.name,
|
|
||||||
usings: ctx.usings
|
|
||||||
}), normalizer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static public function getParams(name:String, ?pos:Position)
|
static public function getType2(name, ?types, ?pos:Position, build:BuildContext2->TypeDefinition, ?normalizer:Type->Type)
|
||||||
|
return _getTypeN(name, 2, switch types {
|
||||||
|
case null: null;
|
||||||
|
case v: [types.t1, types.t2];
|
||||||
|
}, pos, ctx -> build({
|
||||||
|
pos: ctx.pos,
|
||||||
|
type: ctx.types[0],
|
||||||
|
type2: ctx.types[1],
|
||||||
|
usings: ctx.usings,
|
||||||
|
name: ctx.name
|
||||||
|
}), normalizer);
|
||||||
|
|
||||||
|
static public function getParams(name:String, ?pos:Position, ?count:Int)
|
||||||
return
|
return
|
||||||
switch Context.getLocalType() {
|
switch Context.getLocalType() {
|
||||||
case TInst(_.toString() == name => true, v):
|
case TInst(_.toString() == name => true, v):
|
||||||
@@ -131,70 +109,50 @@ class BuildCache {
|
|||||||
});
|
});
|
||||||
|
|
||||||
static public function getType(name, ?type, ?pos:Position, build:BuildContext->TypeDefinition, ?normalizer:Type->Type) {
|
static public function getType(name, ?type, ?pos:Position, build:BuildContext->TypeDefinition, ?normalizer:Type->Type) {
|
||||||
|
return _getTypeN(name, 1, switch type {
|
||||||
if (type == null)
|
case null: null;
|
||||||
type = getParam(name, pos).sure();
|
case v: [v];
|
||||||
|
}, pos, ctx -> build({
|
||||||
var forName =
|
pos: ctx.pos,
|
||||||
switch cache[name] {
|
type: ctx.types[0],
|
||||||
case null: cache[name] = new Group(name, normalizer);
|
usings: ctx.usings,
|
||||||
case v: v;
|
name: ctx.name
|
||||||
}
|
}), normalizer);
|
||||||
|
|
||||||
var ret = forName.get(type, pos.sanitize(), build);
|
|
||||||
ret.getFields();// workaround for https://github.com/HaxeFoundation/haxe/issues/7905
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private typedef Entry = {
|
private class Group {//TODO: this is somewhat obsolete
|
||||||
name:String,
|
|
||||||
}
|
|
||||||
|
|
||||||
private class Group {
|
|
||||||
|
|
||||||
var name:String;
|
var name:String;
|
||||||
var counter = 0;
|
|
||||||
var entries:TypeMap<Entry>;
|
|
||||||
|
|
||||||
public function new(name, ?normalizer) {
|
public function new(name) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.entries = new TypeMap(normalizer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function get(type:Type, pos:Position, build:BuildContext->TypeDefinition):Type {
|
public function get(types:Array<Type>, pos:Position, build:BuildContextN->TypeDefinition, ?normalizer):Type {
|
||||||
|
|
||||||
function make(path:String) {
|
types = types.map(switch normalizer {
|
||||||
var usings = [];
|
case null: function (t) return Context.follow(t);
|
||||||
var def = build({
|
case f: f;
|
||||||
pos: pos,
|
});
|
||||||
type: type,
|
|
||||||
usings: usings,
|
|
||||||
name: path.split('.').pop()
|
|
||||||
});
|
|
||||||
|
|
||||||
entries.set(type, { name: path } );
|
var retName = name + '_' + Context.signature(Sisyphus.exactParams(types));
|
||||||
Context.defineModule(path, [def], usings);
|
|
||||||
return Context.getType(path);
|
return switch retName.definedType() {
|
||||||
|
case Some(v): v;
|
||||||
|
case None:
|
||||||
|
var usings = [];
|
||||||
|
var path = name.split('.');
|
||||||
|
|
||||||
|
var ret = build({
|
||||||
|
pos: pos,
|
||||||
|
types: types,
|
||||||
|
usings: usings,
|
||||||
|
name: retName.split('.').pop(),
|
||||||
|
});
|
||||||
|
|
||||||
|
Context.defineModule(retName, [ret], usings);
|
||||||
|
Context.getType(retName);
|
||||||
}
|
}
|
||||||
|
|
||||||
function doMake()
|
|
||||||
while (true)
|
|
||||||
switch '$name${counter++}' {
|
|
||||||
case _.definedType() => Some(_):
|
|
||||||
case v:
|
|
||||||
return make(v);
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
|
||||||
switch entries.get(type) {
|
|
||||||
case null:
|
|
||||||
doMake();
|
|
||||||
case v:
|
|
||||||
switch v.name.definedType() {
|
|
||||||
case Some(v): v;
|
|
||||||
default: doMake();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -148,11 +148,7 @@ class Sisyphus {
|
|||||||
return (
|
return (
|
||||||
if (isMain) t.pack.concat([t.name]).join('.')
|
if (isMain) t.pack.concat([t.name]).join('.')
|
||||||
else t.module + '.' + t.name
|
else t.module + '.' + t.name
|
||||||
) + switch params {
|
) + exactParams(params);
|
||||||
case []: '';
|
|
||||||
case params:
|
|
||||||
'<${params.map(toExactString).join(', ')}>';
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline function isFinal(c:ClassField)
|
static inline function isFinal(c:ClassField)
|
||||||
@@ -183,6 +179,12 @@ class Sisyphus {
|
|||||||
static function exactSig(args:Array<{name:String, opt:Bool, t:Type}>, ret:Type, sep:String)
|
static function exactSig(args:Array<{name:String, opt:Bool, t:Type}>, ret:Type, sep:String)
|
||||||
return '(${[for (a in args) (if (a.opt) '?' else '') + a.name + ':' + toExactString(a.t)].join(', ')})$sep${toExactString(ret)}';
|
return '(${[for (a in args) (if (a.opt) '?' else '') + a.name + ':' + toExactString(a.t)].join(', ')})$sep${toExactString(ret)}';
|
||||||
|
|
||||||
|
static public function exactParams(params:Array<Type>)
|
||||||
|
return switch params {
|
||||||
|
case []: '';
|
||||||
|
case params:
|
||||||
|
'<${params.map(toExactString).join(', ')}>';
|
||||||
|
}
|
||||||
static public function toExactString(t:Type)
|
static public function toExactString(t:Type)
|
||||||
return switch t {
|
return switch t {
|
||||||
case TMono(t): t.toString();
|
case TMono(t): t.toString();
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import haxe.macro.Type.Ref;
|
|||||||
|
|
||||||
class Types {
|
class Types {
|
||||||
|
|
||||||
static public function definedType(typeName:String)
|
static public function definedType(typeName:String):Option<Type>
|
||||||
return
|
return
|
||||||
try {
|
try {
|
||||||
Some(Context.getType(typeName));
|
Some(Context.getType(typeName));
|
||||||
|
|||||||
Reference in New Issue
Block a user