219 lines
4.6 KiB
Haxe
219 lines
4.6 KiB
Haxe
package lime._macros; #if macro
|
|
|
|
|
|
import haxe.macro.Context;
|
|
import haxe.macro.Expr;
|
|
import haxe.macro.Type;
|
|
using haxe.macro.Tools;
|
|
|
|
|
|
class HTTPRequestMacro {
|
|
|
|
|
|
private static function build () {
|
|
|
|
var paramType;
|
|
var type:BaseType, typeArgs;
|
|
var stringAbstract = false;
|
|
var bytesAbstract = false;
|
|
|
|
switch (Context.follow (Context.getLocalType ())) {
|
|
|
|
case TInst (localType, [ t ]):
|
|
|
|
paramType = t;
|
|
|
|
switch (t) {
|
|
|
|
case TInst (t, args):
|
|
|
|
type = t.get ();
|
|
typeArgs = args;
|
|
|
|
case TAbstract (t, args):
|
|
|
|
type = t.get ();
|
|
typeArgs = args;
|
|
|
|
stringAbstract = isStringAbstract (t.get ());
|
|
if (!stringAbstract) bytesAbstract = isBytesAbstract (t.get ());
|
|
|
|
case TType (t, args):
|
|
|
|
type = t.get ();
|
|
typeArgs = args;
|
|
|
|
case TMono (_):
|
|
|
|
Context.fatalError ("Invalid number of type parameters for " + localType.toString (), Context.currentPos ());
|
|
return null;
|
|
|
|
case TDynamic (_):
|
|
|
|
switch (Context.getType ("haxe.io.Bytes")) {
|
|
|
|
case TInst (t, args):
|
|
|
|
type = t.get ();
|
|
typeArgs = args;
|
|
|
|
default:
|
|
|
|
throw false;
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
throw false;
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
throw false;
|
|
|
|
}
|
|
|
|
var typeString = type.module;
|
|
|
|
if (type.name != type.module && !StringTools.endsWith (type.module, "." + type.name)) {
|
|
|
|
typeString += "." + type.name;
|
|
|
|
}
|
|
|
|
if (typeString == "String" || stringAbstract) {
|
|
|
|
return TPath ( { pack: [ "lime", "net" ], name: "HTTPRequest", sub: "_HTTPRequest_String", params: [ TPType (paramType.toComplexType ()) ] } ).toType ();
|
|
|
|
} else if (typeString == "haxe.io.Bytes" || bytesAbstract) {
|
|
|
|
return TPath ( { pack: [ "lime", "net" ], name: "HTTPRequest", sub: "_HTTPRequest_Bytes", params: [ TPType (paramType.toComplexType ()) ] } ).toType ();
|
|
|
|
} else {
|
|
|
|
var typeParamString = typeString;
|
|
|
|
if (typeArgs.length > 0) {
|
|
|
|
typeParamString += "<";
|
|
|
|
for (i in 0...typeArgs.length) {
|
|
|
|
if (i > 0) typeParamString += ",";
|
|
typeParamString += typeArgs[i].toString ();
|
|
|
|
}
|
|
|
|
typeParamString += ">";
|
|
|
|
}
|
|
|
|
var flattenedTypeString = typeParamString;
|
|
|
|
flattenedTypeString = StringTools.replace (flattenedTypeString, "->", "_");
|
|
flattenedTypeString = StringTools.replace (flattenedTypeString, ".", "_");
|
|
flattenedTypeString = StringTools.replace (flattenedTypeString, "<", "_");
|
|
flattenedTypeString = StringTools.replace (flattenedTypeString, ">", "_");
|
|
|
|
var name = "_HTTPRequest_" + flattenedTypeString;
|
|
|
|
try {
|
|
|
|
Context.getType ("lime.net." + name);
|
|
|
|
} catch (e:Dynamic) {
|
|
|
|
var pos = Context.currentPos ();
|
|
|
|
var fields = [
|
|
{ name: "new", access: [ APublic ], kind: FFun({ args: [ { name: "uri", type: macro :String, opt: true } ], expr: macro { super (uri); }, params: [], ret: macro :Void }), pos: Context.currentPos () },
|
|
{ name: "fromBytes", access: [ APrivate, AOverride ], kind: FFun ( { args: [ { name: "bytes", type: macro :haxe.io.Bytes } ], expr: Context.parse ("return " + typeString + ".fromBytes (bytes)", pos), params: [], ret: paramType.toComplexType () } ), pos: pos }
|
|
];
|
|
|
|
var meta:Array<MetadataEntry> = [];
|
|
|
|
#if !lime_debug
|
|
meta.push ({ name: ":fileXml", params: [ macro 'tags="haxe,release"' ], pos: pos });
|
|
meta.push ({ name: ":noDebug", pos: pos });
|
|
#end
|
|
|
|
Context.defineType ({
|
|
|
|
name: name,
|
|
pack: [ "lime", "net" ],
|
|
kind: TDClass ({ pack: [ "lime", "net" ], name: "HTTPRequest", sub: "_HTTPRequest_Bytes", params: [ TPType (paramType.toComplexType ()) ] }, null, false),
|
|
fields: fields,
|
|
pos: pos,
|
|
meta: meta
|
|
|
|
});
|
|
|
|
}
|
|
|
|
return TPath ( { pack: [ "lime", "net" ], name: name, params: [] } ).toType ();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
private static function isBytesAbstract (type:AbstractType):Bool {
|
|
|
|
while (type != null) {
|
|
|
|
switch (type.type) {
|
|
|
|
case TInst (t, _):
|
|
|
|
return t.get ().module == "haxe.io.Bytes";
|
|
|
|
case TAbstract (t, _):
|
|
|
|
type = t.get ();
|
|
|
|
default:
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
private static function isStringAbstract (type:AbstractType):Bool {
|
|
|
|
while (type != null) {
|
|
|
|
switch (type.type) {
|
|
|
|
case TInst (t, _):
|
|
|
|
return t.get ().module == "String";
|
|
|
|
case TAbstract (t, _):
|
|
|
|
type = t.get ();
|
|
|
|
default:
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
#end |