(import) and (using) for pure-kiss classes
This commit is contained in:
@@ -16,6 +16,7 @@ import kiss.SpecialForms;
|
||||
import kiss.Macros;
|
||||
import kiss.KissError;
|
||||
import kiss.cloner.Cloner;
|
||||
import tink.syntaxhub.*;
|
||||
|
||||
using kiss.Kiss;
|
||||
using kiss.Helpers;
|
||||
@@ -68,11 +69,11 @@ typedef KissState = {
|
||||
|
||||
class Kiss {
|
||||
#if macro
|
||||
public static function defaultKissState(?name):KissState {
|
||||
var className = if(name == null){
|
||||
public static function defaultKissState(?context:FrontendContext):KissState {
|
||||
var className = if (context == null) {
|
||||
Context.getLocalClass().get().name;
|
||||
}else{
|
||||
name;
|
||||
} else {
|
||||
context.name;
|
||||
}
|
||||
var k = {
|
||||
className: className,
|
||||
@@ -192,7 +193,7 @@ class Kiss {
|
||||
};
|
||||
|
||||
FieldForms.addBuiltins(k);
|
||||
k.specialForms = SpecialForms.builtins(k);
|
||||
k.specialForms = SpecialForms.builtins(k, context);
|
||||
k.macros = Macros.builtins(k);
|
||||
|
||||
return k;
|
||||
@@ -276,7 +277,7 @@ class Kiss {
|
||||
/**
|
||||
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;
|
||||
// (load... ) relative to the original file
|
||||
@@ -292,7 +293,7 @@ class Kiss {
|
||||
trace(kissFile);
|
||||
#end
|
||||
if (k == null)
|
||||
k = defaultKissState(className);
|
||||
k = defaultKissState(context);
|
||||
|
||||
if (useClassFields) {
|
||||
k.fieldList = Context.getBuildFields();
|
||||
|
@@ -14,16 +14,19 @@ class KissFrontend implements FrontendPlugin {
|
||||
return ['kiss'].iterator();
|
||||
|
||||
public function parse(file:String, context:FrontendContext):Void {
|
||||
|
||||
final fields = Kiss.build(file,null,false,context.name);
|
||||
var pos = Context.makePosition({ file: file, min: 0, max: 999 });
|
||||
#if debug trace(context.name); #end
|
||||
final type = context.getType();
|
||||
context.addImport('kiss.Prelude',INormal,pos);
|
||||
for (field in fields){
|
||||
|
||||
final fields = Kiss.build(file,null,false,context);
|
||||
#if debug
|
||||
trace(context.name);
|
||||
#end
|
||||
final type = context.getType();
|
||||
var pos = Context.makePosition({ file: file, min: 0, max: 0 });
|
||||
context.addImport('kiss.Prelude',INormal,pos);
|
||||
for (field in fields) {
|
||||
type.fields.push(field);
|
||||
}
|
||||
}
|
||||
|
||||
static function use()
|
||||
tink.SyntaxHub.frontends.whenever(new KissFrontend());
|
||||
}
|
@@ -13,12 +13,13 @@ using kiss.Helpers;
|
||||
using kiss.Prelude;
|
||||
using kiss.Kiss;
|
||||
using tink.MacroApi;
|
||||
import tink.syntaxhub.*;
|
||||
|
||||
// Special forms convert Kiss reader expressions into Haxe macro expressions
|
||||
typedef SpecialFormFunction = (wholeExp:ReaderExp, args:Array<ReaderExp>, k:KissState) -> Expr;
|
||||
|
||||
class SpecialForms {
|
||||
public static function builtins(k:KissState) {
|
||||
public static function builtins(k:KissState, ?context:FrontendContext) {
|
||||
var map:Map<String, SpecialFormFunction> = [];
|
||||
|
||||
function renameAndDeprecate(oldName:String, newName:String) {
|
||||
@@ -537,6 +538,48 @@ class SpecialForms {
|
||||
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;
|
||||
}
|
||||
|
||||
|
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();
|
||||
}
|
||||
|
||||
function testWhenLetGuards() {
|
||||
function testWhenLetGuards() {
|
||||
_testWhenLetGuards();
|
||||
}
|
||||
}
|
||||
|
||||
function testImportAndUsingInBuildMacro() {
|
||||
_testImportAndUsingInBuildMacro();
|
||||
}
|
||||
|
||||
function testPureKissClasses() {
|
||||
_testPureKissClasses();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@@ -693,4 +693,15 @@ From:[(assert false (+ \"false \" \"should \" \"have \" \"been \" \"true\"))]" m
|
||||
(function _testWhenLetGuards []
|
||||
// Guards should be allowed in whenLet patterns
|
||||
(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