forked from LeenkxTeam/LNXSDK
Update Files
This commit is contained in:
258
Kha/Tools/linux_arm64/std/haxe/macro/ExampleJSGenerator.hx
Normal file
258
Kha/Tools/linux_arm64/std/haxe/macro/ExampleJSGenerator.hx
Normal file
@ -0,0 +1,258 @@
|
||||
/*
|
||||
* Copyright (C)2005-2019 Haxe Foundation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package haxe.macro;
|
||||
|
||||
import haxe.macro.Type;
|
||||
import haxe.macro.Expr;
|
||||
|
||||
using Lambda;
|
||||
|
||||
class ExampleJSGenerator {
|
||||
var api:JSGenApi;
|
||||
var buf:StringBuf;
|
||||
var inits:List<TypedExpr>;
|
||||
var statics:List<{c:ClassType, f:ClassField}>;
|
||||
var packages:haxe.ds.StringMap<Bool>;
|
||||
var forbidden:haxe.ds.StringMap<Bool>;
|
||||
|
||||
public function new(api) {
|
||||
this.api = api;
|
||||
buf = new StringBuf();
|
||||
inits = new List();
|
||||
statics = new List();
|
||||
packages = new haxe.ds.StringMap();
|
||||
forbidden = new haxe.ds.StringMap();
|
||||
for (x in ["prototype", "__proto__", "constructor"])
|
||||
forbidden.set(x, true);
|
||||
api.setTypeAccessor(getType);
|
||||
}
|
||||
|
||||
function getType(t:Type) {
|
||||
return switch (t) {
|
||||
case TInst(c, _): getPath(c.get());
|
||||
case TEnum(e, _): getPath(e.get());
|
||||
case TAbstract(a, _): getPath(a.get());
|
||||
default: throw "assert";
|
||||
};
|
||||
}
|
||||
|
||||
inline function print(str:String) {
|
||||
buf.add(str);
|
||||
}
|
||||
|
||||
inline function newline() {
|
||||
buf.add(";\n");
|
||||
}
|
||||
|
||||
inline function genExpr(e) {
|
||||
print(api.generateValue(e));
|
||||
}
|
||||
|
||||
function field(p) {
|
||||
return api.isKeyword(p) ? '["' + p + '"]' : "." + p;
|
||||
}
|
||||
|
||||
function genPackage(p:Array<String>) {
|
||||
var full = null;
|
||||
for (x in p) {
|
||||
var prev = full;
|
||||
if (full == null)
|
||||
full = x
|
||||
else
|
||||
full += "." + x;
|
||||
if (packages.exists(full))
|
||||
continue;
|
||||
packages.set(full, true);
|
||||
if (prev == null)
|
||||
print('if(typeof $x==\'undefined\') $x = {}');
|
||||
else {
|
||||
var p = prev + field(x);
|
||||
print('if(!$p) $p = {}');
|
||||
}
|
||||
newline();
|
||||
}
|
||||
}
|
||||
|
||||
function getPath(t:BaseType) {
|
||||
return (t.pack.length == 0) ? t.name : t.pack.join(".") + "." + t.name;
|
||||
}
|
||||
|
||||
function checkFieldName(c:ClassType, f:ClassField) {
|
||||
if (forbidden.exists(f.name))
|
||||
Context.error("The field " + f.name + " is not allowed in JS", c.pos);
|
||||
}
|
||||
|
||||
function genClassField(c:ClassType, p:String, f:ClassField) {
|
||||
checkFieldName(c, f);
|
||||
var field = field(f.name);
|
||||
print('$p.prototype$field = ');
|
||||
var e = f.expr();
|
||||
if (e == null)
|
||||
print("null");
|
||||
else {
|
||||
genExpr(e);
|
||||
}
|
||||
newline();
|
||||
}
|
||||
|
||||
function genStaticField(c:ClassType, p:String, f:ClassField) {
|
||||
checkFieldName(c, f);
|
||||
var field = field(f.name);
|
||||
var e = f.expr();
|
||||
if (e == null) {
|
||||
print('$p$field = null');
|
||||
newline();
|
||||
} else
|
||||
switch (f.kind) {
|
||||
case FMethod(_):
|
||||
print('$p$field = ');
|
||||
genExpr(e);
|
||||
newline();
|
||||
default:
|
||||
statics.add({c: c, f: f});
|
||||
}
|
||||
}
|
||||
|
||||
function genClass(c:ClassType) {
|
||||
genPackage(c.pack);
|
||||
api.setCurrentClass(c);
|
||||
var p = getPath(c);
|
||||
print('$p = $$hxClasses[\'$p\'] = ');
|
||||
if (c.constructor != null)
|
||||
genExpr(c.constructor.get().expr());
|
||||
else
|
||||
print("function() { }");
|
||||
newline();
|
||||
print('$p.__name__ = "$p"');
|
||||
newline();
|
||||
if (c.superClass != null) {
|
||||
var psup = getPath(c.superClass.t.get());
|
||||
print('$p.__super__ = $psup');
|
||||
newline();
|
||||
print('for(var k in $psup.prototype ) $p.prototype[k] = $psup.prototype[k]');
|
||||
newline();
|
||||
}
|
||||
for (f in c.statics.get())
|
||||
genStaticField(c, p, f);
|
||||
for (f in c.fields.get()) {
|
||||
switch (f.kind) {
|
||||
case FVar(r, _):
|
||||
if (r == AccResolve)
|
||||
continue;
|
||||
default:
|
||||
}
|
||||
genClassField(c, p, f);
|
||||
}
|
||||
print('$p.prototype.__class__ = $p');
|
||||
newline();
|
||||
if (c.interfaces.length > 0) {
|
||||
var me = this;
|
||||
var inter = c.interfaces.map(function(i) return me.getPath(i.t.get())).join(",");
|
||||
print('$p.__interfaces__ = [$inter]');
|
||||
newline();
|
||||
}
|
||||
}
|
||||
|
||||
function genEnum(e:EnumType) {
|
||||
genPackage(e.pack);
|
||||
var p = getPath(e);
|
||||
var constructs = e.names.map(api.quoteString).join(",");
|
||||
print('$p = $$hxClasses[\'$p\'] = { __ename__ : \'$p\', __constructs__ : [$constructs] }');
|
||||
newline();
|
||||
for (c in e.constructs.keys()) {
|
||||
var c = e.constructs.get(c);
|
||||
var f = field(c.name);
|
||||
print('$p$f = ');
|
||||
switch (c.type) {
|
||||
case TFun(args, _):
|
||||
var sargs = args.map(function(a) return a.name).join(",");
|
||||
print('function($sargs) { var $$x = ["${c.name}",${c.index},$sargs]; $$x.__enum__ = $p; $$x.toString = $$estr; return $$x; }');
|
||||
default:
|
||||
print("[" + api.quoteString(c.name) + "," + c.index + "]");
|
||||
newline();
|
||||
print('$p$f.toString = $$estr');
|
||||
newline();
|
||||
print('$p$f.__enum__ = $p');
|
||||
}
|
||||
newline();
|
||||
}
|
||||
var meta = api.buildMetaData(e);
|
||||
if (meta != null) {
|
||||
print('$p.__meta__ = ');
|
||||
genExpr(meta);
|
||||
newline();
|
||||
}
|
||||
}
|
||||
|
||||
function genStaticValue(c:ClassType, cf:ClassField) {
|
||||
var p = getPath(c);
|
||||
var f = field(cf.name);
|
||||
print('$p$f = ');
|
||||
genExpr(cf.expr());
|
||||
newline();
|
||||
}
|
||||
|
||||
function genType(t:Type) {
|
||||
switch (t) {
|
||||
case TInst(c, _):
|
||||
var c = c.get();
|
||||
if (c.init != null)
|
||||
inits.add(c.init);
|
||||
if (!c.isExtern)
|
||||
genClass(c);
|
||||
case TEnum(r, _):
|
||||
var e = r.get();
|
||||
if (!e.isExtern)
|
||||
genEnum(e);
|
||||
default:
|
||||
}
|
||||
}
|
||||
|
||||
public function generate() {
|
||||
print("var $_, $hxClasses = $hxClasses || {}, $estr = function() { return js.Boot.__string_rec(this,''); }");
|
||||
newline();
|
||||
print("function $bind(o,m) { var f = function(){ return f.method.apply(f.scope, arguments); }; f.scope = o; f.method = m; return f; };");
|
||||
newline();
|
||||
for (t in api.types)
|
||||
genType(t);
|
||||
for (e in inits) {
|
||||
print(api.generateStatement(e));
|
||||
newline();
|
||||
}
|
||||
for (s in statics) {
|
||||
genStaticValue(s.c, s.f);
|
||||
newline();
|
||||
}
|
||||
if (api.main != null) {
|
||||
genExpr(api.main);
|
||||
newline();
|
||||
}
|
||||
sys.io.File.saveContent(api.outputFile, buf.toString());
|
||||
}
|
||||
|
||||
#if (macro || display)
|
||||
public static function use() {
|
||||
Compiler.setCustomJSGenerator(function(api) new ExampleJSGenerator(api).generate());
|
||||
}
|
||||
#end
|
||||
}
|
Reference in New Issue
Block a user