Resolves #12. Resolves #18.

This commit is contained in:
Juraj Kirchheim
2020-04-24 15:38:51 +02:00
parent e3bac681ce
commit acb7237ae4
2 changed files with 52 additions and 50 deletions

View File

@@ -31,23 +31,23 @@ typedef BuildContext3 = {>BuildContext2,
type3:Type,
}
class BuildCache {
class BuildCache {
@:persistent static var cache = new Map();
static public function getType3(name, ?types, ?pos:Position, build:BuildContext3->TypeDefinition) {
static public function getType3(name, ?types, ?pos:Position, build:BuildContext3->TypeDefinition, ?normalizer:Type->Type) {
if (types == null)
switch Context.getLocalType() {
case TInst(_.toString() == name => true, [t1, t2, t3]):
types = { t1: t1, t2: t2, t3: t3 };
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,
@@ -55,62 +55,62 @@ class BuildCache {
pos: ctx.pos,
name: ctx.name,
usings: ctx.usings
}));
}), normalizer);
}
static public function getTypeN(name, ?types, ?pos:Position, build:BuildContextN->TypeDefinition) {
static public function getTypeN(name, ?types, ?pos:Position, build:BuildContextN->TypeDefinition, ?normalizer:Type->Type) {
if (pos == null)
pos = Context.currentPos();
if (types == null)
switch Context.getLocalType() {
case TInst(_.toString() == name => true, params):
types = params;
default:
throw 'assert';
}
}
var compound = ComplexType.TAnonymous([for (i in 0...types.length) {
name: 't$i',
pos: pos,
kind: FVar(switch types[i] {
case TInst(_.get().kind => KExpr(e), _):
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({
types: types,
pos: ctx.pos,
name: ctx.name,
usings: ctx.usings
}));
}
static public function getType2(name, ?types, ?pos:Position, build:BuildContext2->TypeDefinition) {
}), 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(),
t2 = types.t2.toComplexType();
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 getParams(name:String, ?pos:Position)
return
switch Context.getLocalType() {
case TInst(_.toString() == name => true, v):
@@ -119,9 +119,9 @@ class BuildCache {
pos.makeFailure('Expected $name');
case v:
pos.makeFailure('$v should be a class');
}
}
static public function getParam(name:String, ?pos:Position)
static public function getParam(name:String, ?pos:Position)
return
getParams(name, pos)
.flatMap(function (args:Array<Type>) return switch args {
@@ -130,18 +130,18 @@ class BuildCache {
default: pos.makeFailure('too many parameters');
});
static public function getType(name, ?type, ?pos:Position, build:BuildContext->TypeDefinition) {
static public function getType(name, ?type, ?pos:Position, build:BuildContext->TypeDefinition, ?normalizer:Type->Type) {
if (type == null)
type = getParam(name, pos).sure();
var forName =
var forName =
switch cache[name] {
case null: cache[name] = new Group(name);
case null: cache[name] = new Group(name, normalizer);
case v: v;
}
var ret = forName.get(type, pos.sanitize(), build);
var ret = forName.get(type, pos.sanitize(), build);
ret.getFields();// workaround for https://github.com/HaxeFoundation/haxe/issues/7905
return ret;
}
@@ -152,23 +152,24 @@ private typedef Entry = {
}
private class Group {
var name:String;
var counter = 0;
var entries = new TypeMap<Entry>();
public function new(name) {
var entries:TypeMap<Entry>;
public function new(name, ?normalizer) {
this.name = name;
this.entries = new TypeMap(normalizer);
}
public function get(type:Type, pos:Position, build:BuildContext->TypeDefinition):Type {
function make(path:String) {
var usings = [];
var def = build({
pos: pos,
type: type,
usings: usings,
pos: pos,
type: type,
usings: usings,
name: path.split('.').pop()
});
@@ -177,15 +178,15 @@ private class Group {
return Context.getType(path);
}
function doMake()
while (true)
function doMake()
while (true)
switch '$name${counter++}' {
case _.definedType() => Some(_):
case v:
return make(v);
}
}
return
return
switch entries.get(type) {
case null:
doMake();