(import) and (using) for pure-kiss classes
This commit is contained in:
@@ -16,6 +16,7 @@ import kiss.SpecialForms;
|
|||||||
import kiss.Macros;
|
import kiss.Macros;
|
||||||
import kiss.KissError;
|
import kiss.KissError;
|
||||||
import kiss.cloner.Cloner;
|
import kiss.cloner.Cloner;
|
||||||
|
import tink.syntaxhub.*;
|
||||||
|
|
||||||
using kiss.Kiss;
|
using kiss.Kiss;
|
||||||
using kiss.Helpers;
|
using kiss.Helpers;
|
||||||
@@ -68,11 +69,11 @@ typedef KissState = {
|
|||||||
|
|
||||||
class Kiss {
|
class Kiss {
|
||||||
#if macro
|
#if macro
|
||||||
public static function defaultKissState(?name):KissState {
|
public static function defaultKissState(?context:FrontendContext):KissState {
|
||||||
var className = if(name == null){
|
var className = if (context == null) {
|
||||||
Context.getLocalClass().get().name;
|
Context.getLocalClass().get().name;
|
||||||
}else{
|
} else {
|
||||||
name;
|
context.name;
|
||||||
}
|
}
|
||||||
var k = {
|
var k = {
|
||||||
className: className,
|
className: className,
|
||||||
@@ -192,7 +193,7 @@ class Kiss {
|
|||||||
};
|
};
|
||||||
|
|
||||||
FieldForms.addBuiltins(k);
|
FieldForms.addBuiltins(k);
|
||||||
k.specialForms = SpecialForms.builtins(k);
|
k.specialForms = SpecialForms.builtins(k, context);
|
||||||
k.macros = Macros.builtins(k);
|
k.macros = Macros.builtins(k);
|
||||||
|
|
||||||
return k;
|
return k;
|
||||||
@@ -276,7 +277,7 @@ class Kiss {
|
|||||||
/**
|
/**
|
||||||
Build macro: add fields to a class from a corresponding .kiss file
|
Build macro: add fields to a class from a corresponding .kiss file
|
||||||
**/
|
**/
|
||||||
public static function build(?kissFile:String, ?k:KissState, useClassFields = true, ?className:String):Array<Field> {
|
public static function build(?kissFile:String, ?k:KissState, useClassFields = true, ?context:FrontendContext):Array<Field> {
|
||||||
|
|
||||||
var classPath = Context.getPosInfos(Context.currentPos()).file;
|
var classPath = Context.getPosInfos(Context.currentPos()).file;
|
||||||
// (load... ) relative to the original file
|
// (load... ) relative to the original file
|
||||||
@@ -292,7 +293,7 @@ class Kiss {
|
|||||||
trace(kissFile);
|
trace(kissFile);
|
||||||
#end
|
#end
|
||||||
if (k == null)
|
if (k == null)
|
||||||
k = defaultKissState(className);
|
k = defaultKissState(context);
|
||||||
|
|
||||||
if (useClassFields) {
|
if (useClassFields) {
|
||||||
k.fieldList = Context.getBuildFields();
|
k.fieldList = Context.getBuildFields();
|
||||||
|
@@ -15,15 +15,18 @@ class KissFrontend implements FrontendPlugin {
|
|||||||
|
|
||||||
public function parse(file:String, context:FrontendContext):Void {
|
public function parse(file:String, context:FrontendContext):Void {
|
||||||
|
|
||||||
final fields = Kiss.build(file,null,false,context.name);
|
final fields = Kiss.build(file,null,false,context);
|
||||||
var pos = Context.makePosition({ file: file, min: 0, max: 999 });
|
#if debug
|
||||||
#if debug trace(context.name); #end
|
trace(context.name);
|
||||||
final type = context.getType();
|
#end
|
||||||
context.addImport('kiss.Prelude',INormal,pos);
|
final type = context.getType();
|
||||||
for (field in fields){
|
var pos = Context.makePosition({ file: file, min: 0, max: 0 });
|
||||||
|
context.addImport('kiss.Prelude',INormal,pos);
|
||||||
|
for (field in fields) {
|
||||||
type.fields.push(field);
|
type.fields.push(field);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static function use()
|
static function use()
|
||||||
tink.SyntaxHub.frontends.whenever(new KissFrontend());
|
tink.SyntaxHub.frontends.whenever(new KissFrontend());
|
||||||
}
|
}
|
@@ -13,12 +13,13 @@ using kiss.Helpers;
|
|||||||
using kiss.Prelude;
|
using kiss.Prelude;
|
||||||
using kiss.Kiss;
|
using kiss.Kiss;
|
||||||
using tink.MacroApi;
|
using tink.MacroApi;
|
||||||
|
import tink.syntaxhub.*;
|
||||||
|
|
||||||
// Special forms convert Kiss reader expressions into Haxe macro expressions
|
// Special forms convert Kiss reader expressions into Haxe macro expressions
|
||||||
typedef SpecialFormFunction = (wholeExp:ReaderExp, args:Array<ReaderExp>, k:KissState) -> Expr;
|
typedef SpecialFormFunction = (wholeExp:ReaderExp, args:Array<ReaderExp>, k:KissState) -> Expr;
|
||||||
|
|
||||||
class SpecialForms {
|
class SpecialForms {
|
||||||
public static function builtins(k:KissState) {
|
public static function builtins(k:KissState, ?context:FrontendContext) {
|
||||||
var map:Map<String, SpecialFormFunction> = [];
|
var map:Map<String, SpecialFormFunction> = [];
|
||||||
|
|
||||||
function renameAndDeprecate(oldName:String, newName:String) {
|
function renameAndDeprecate(oldName:String, newName:String) {
|
||||||
@@ -537,6 +538,48 @@ class SpecialForms {
|
|||||||
return e;
|
return e;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function requireContext(exp, formName) {
|
||||||
|
if (context == null) {
|
||||||
|
throw KissError.fromExp(exp, '$formName cannot be used when calling Kiss as a build macro in a Haxe file.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function none(exp) {
|
||||||
|
return EBlock([]).withMacroPosOf(exp);
|
||||||
|
}
|
||||||
|
|
||||||
|
k.doc("import", 1, null, "(import <types...>)");
|
||||||
|
map["import"] = (wholeExp:ReaderExp, exps:Array<ReaderExp>, k:KissState) -> {
|
||||||
|
requireContext(wholeExp, "import");
|
||||||
|
for (type in exps) {
|
||||||
|
context.addImport(Reader.toString(type.def), INormal, wholeExp.macroPos());
|
||||||
|
}
|
||||||
|
return none(wholeExp);
|
||||||
|
};
|
||||||
|
|
||||||
|
k.doc("importAs", 2, 2, "(importAs <Type> <Alias>)");
|
||||||
|
map["importAs"] = (wholeExp:ReaderExp, exps:Array<ReaderExp>, k:KissState) -> {
|
||||||
|
requireContext(wholeExp, "importAs");
|
||||||
|
context.addImport(Reader.toString(exps[0].def), IAsName(Reader.toString(exps[1].def)), wholeExp.macroPos());
|
||||||
|
return none(wholeExp);
|
||||||
|
};
|
||||||
|
|
||||||
|
k.doc("importAll", 1, 1, "(importAll <package>)");
|
||||||
|
map["importAll"] = (wholeExp:ReaderExp, exps:Array<ReaderExp>, k:KissState) -> {
|
||||||
|
requireContext(wholeExp, "importAll");
|
||||||
|
context.addImport(Reader.toString(exps[0].def), IAll, wholeExp.macroPos());
|
||||||
|
return none(wholeExp);
|
||||||
|
};
|
||||||
|
|
||||||
|
k.doc("using", 1, null, "(using <Types...>)");
|
||||||
|
map["using"] = (wholeExp:ReaderExp, exps:Array<ReaderExp>, k:KissState) -> {
|
||||||
|
requireContext(wholeExp, "using");
|
||||||
|
for (type in exps) {
|
||||||
|
context.addUsing(Reader.toString(type.def), wholeExp.macroPos());
|
||||||
|
}
|
||||||
|
return none(wholeExp);
|
||||||
|
};
|
||||||
|
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
3
kiss/src/test/OtherPureKissClass.kiss
Normal file
3
kiss/src/test/OtherPureKissClass.kiss
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
(function extensionMethod [:String s] "EXTENDED")
|
||||||
|
|
||||||
|
(defNew [&prop :Int num])
|
9
kiss/src/test/PureKissClass.kiss
Normal file
9
kiss/src/test/PureKissClass.kiss
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
(import test.OtherPureKissClass)
|
||||||
|
(importAs test.OtherPureKissClass Alias)
|
||||||
|
(using test.OtherPureKissClass)
|
||||||
|
|
||||||
|
(function test []
|
||||||
|
(assert (= (.extensionMethod "string") "EXTENDED"))
|
||||||
|
(let [instance (new OtherPureKissClass 5)
|
||||||
|
other (new Alias 5)]
|
||||||
|
(assert (= instance.num other.num 5))))
|
@@ -364,9 +364,17 @@ class BasicTestCase extends Test {
|
|||||||
_testQuickFractions();
|
_testQuickFractions();
|
||||||
}
|
}
|
||||||
|
|
||||||
function testWhenLetGuards() {
|
function testWhenLetGuards() {
|
||||||
_testWhenLetGuards();
|
_testWhenLetGuards();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function testImportAndUsingInBuildMacro() {
|
||||||
|
_testImportAndUsingInBuildMacro();
|
||||||
|
}
|
||||||
|
|
||||||
|
function testPureKissClasses() {
|
||||||
|
_testPureKissClasses();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -694,3 +694,14 @@ From:[(assert false (+ \"false \" \"should \" \"have \" \"been \" \"true\"))]" m
|
|||||||
// Guards should be allowed in whenLet patterns
|
// Guards should be allowed in whenLet patterns
|
||||||
(whenLet [(when true 5) 5]
|
(whenLet [(when true 5) 5]
|
||||||
(Assert.pass)))
|
(Assert.pass)))
|
||||||
|
|
||||||
|
(function _testImportAndUsingInBuildMacro []
|
||||||
|
(assertThrowsAtCompileTime (import pack.Type))
|
||||||
|
(assertThrowsAtCompileTime (importAs pack.Type Alias))
|
||||||
|
(assertThrowsAtCompileTime (importAll pack))
|
||||||
|
(assertThrowsAtCompileTime (using pack.Type))
|
||||||
|
(Assert.pass))
|
||||||
|
|
||||||
|
(function _testPureKissClasses []
|
||||||
|
(PureKissClass.test)
|
||||||
|
(Assert.pass))
|
Reference in New Issue
Block a user