Directory macro loading

This commit is contained in:
2019-05-13 05:56:57 -06:00
parent 435e86be42
commit df5651d27a
6 changed files with 76 additions and 56 deletions

View File

@@ -1,36 +0,0 @@
package hank;
class DirectoryLoadingMacro {
public static macro function build(directory: String, recursive: Bool=true): Array<Field> {
var files = if (recursive) {
recursiveLoop(directory, []);
} else {
sys.FileSystem.readDirectory(directory);
}
return FileLoadingMacro.build(files);
}
// this function is nabbed from https://code.haxe.org/category/beginner/using-filesystem.html
static function recursiveLoop(directory:String, files: Array<String>): Array<String> {
if (sys.FileSystem.exists(directory)) {
trace("directory found: " + directory);
for (file in sys.FileSystem.readDirectory(directory)) {
var path = haxe.io.Path.join([directory, file]);
if (!sys.FileSystem.isDirectory(path)) {
trace("file found: " + path);
// do something with file
files.push(path.toString());
} else {
var directory = haxe.io.Path.addTrailingSlash(path);
trace("directory found: " + directory);
files = recursiveLoop(directory, files);
}
}
} else {
trace('"$directory" does not exists');
}
return files;
}
}

View File

@@ -1,29 +1,72 @@
package hank;
using StringTools;
import haxe.macro.Context;
import haxe.macro.Expr;
import haxe.Serializer;
import hank.HankBuffer;
class FileLoadingMacro {
public static macro function build(files: Array<String>): Array<Field> {
var fields = Context.getBuildFields();
var files = [for (file in files) file => sys.io.File.getContent(file)];
var serializer = new Serializer();
serializer.serialize(files);
var i = 0;
while (i < files.length) {
var file = files[i];
if (file.endsWith("/")) {
files.remove(file);
files = files.concat(recursiveLoop(file, []));
} else {
++i;
}
}
var loadedFiles = [for (file in files) macro $v{file} => $v{sys.io.File.getContent(file)}];
var filesField = {
name: "_serializedFiles",
name: "files",
doc: null,
meta: [],
access: [AStatic, APrivate],
kind: FVar(macro : String, {expr: EConst(CString(serializer.toString())), pos: Context.currentPos()}),
kind: FVar(macro : Map<String, String>, macro $a{loadedFiles}),
pos: Context.currentPos()
};
var bufferFunction = {
name: "fileBuffer",
doc: null,
meta: [],
access: [AStatic, APrivate],
kind: FVar(macro : String -> hank.HankBuffer, macro function (path) { return new hank.HankBuffer(path, files[path]);}),
pos: Context.currentPos()
}
fields.push(filesField);
fields.push(bufferFunction);
return fields;
}
// this function is nabbed from https://code.haxe.org/category/beginner/using-filesystem.html
static function recursiveLoop(directory:String, files: Array<String>): Array<String> {
if (sys.FileSystem.exists(directory)) {
trace("directory found: " + directory);
for (file in sys.FileSystem.readDirectory(directory)) {
var path = haxe.io.Path.join([directory, file]);
if (!sys.FileSystem.isDirectory(path)) {
trace("file found: " + path);
// do something with file
files.push(path.toString());
} else {
var directory = haxe.io.Path.addTrailingSlash(path);
trace("directory found: " + directory);
files = recursiveLoop(directory, files);
}
}
} else {
trace('"$directory" does not exists');
}
return files;
}
}

View File

@@ -56,6 +56,7 @@ typedef BufferOutput = {
/**
Helper class for reading/parsing information from a string buffer. Completely drops comments
**/
@:allow(tests.HankBufferTest)
class HankBuffer {
var path: String;
var cleanBuffer: String;
@@ -63,7 +64,11 @@ class HankBuffer {
var line: Int;
var column: Int;
private function new(path: String, rawBuffer: String, line: Int = 1, column: Int = 1) {
public function new(path: String, rawBuffer: String, line: Int = 1, column: Int = 1) {
if (rawBuffer == null) {
throw 'Tried to create buffer of path $path with null contents: $rawBuffer';
}
this.path = path;
this.rawBuffer = rawBuffer;
// Keep a clean buffer for returning data without comments getting in the way
@@ -73,11 +78,14 @@ class HankBuffer {
this.column = column;
}
// TODO because this obfuscates the position of parsing, maybe it should be deprecated
public static function Dummy(text: String) {
return new HankBuffer('_', text, 1, 1);
}
public static function FromFile(path: String) {
// TODO document why this is private -- to prevent the user from using sys at runtime
@:allow(hank.Parser, hank.FileLoadingMacro)
private static function FromFile(path: String) {
// Keep a raw buffer of the file for tracking accurate file positions
var rawBuffer = sys.io.File.getContent(path);
return new HankBuffer(path, rawBuffer);

View File

@@ -1,8 +0,0 @@
package tests;
//@:build(hank.DirectoryLoadingMacro.build("examples"))
class DirectoryLoadingMacroTest extends utest.Test {
function testLoadDir() {
}
}

View File

@@ -3,11 +3,24 @@ package tests;
import utest.Test;
import utest.Assert;
using hank.Extensions;
import hank.HankAssert;
@:build(hank.FileLoadingMacro.build(["README.md", "LICENSE"]))
@:build(hank.FileLoadingMacro.build(["README.md", "LICENSE", "examples/"]))
class FileLoadingMacroTest extends utest.Test {
function testLoadFiles() {
function testLoadIndividualFiles() {
var buffer = fileBuffer("README.md");
Assert.equals("# hank", buffer.takeLine().unwrap());
buffer = fileBuffer("LICENSE");
Assert.equals("MIT License", buffer.takeLine().unwrap());
}
function testLoadDirectoryRecursive() {
var buffer = fileBuffer("examples/main/main.hank");
Assert.equals("INCLUDE extra.hank", buffer.takeLine().unwrap());
buffer = fileBuffer("examples/hello/main.hank");
var buffer2 = fileBuffer("examples/hello/test1.hlog");
HankAssert.equals(buffer.takeLine(), buffer2.takeLine());
}
}

View File

@@ -4,6 +4,6 @@ import hank.StoryTestCase;
class InternalsTestMain extends Test {
public static function main() {
utest.UTest.run([new HInterfaceTest(), new HankBufferTest(), new ParserTest(), new StoryTreeTest(), new FileLoadingMacroTest(), new DirectoryLoadingMacroTest()]);
utest.UTest.run([new HInterfaceTest(), new HankBufferTest(), new ParserTest(), new StoryTreeTest(), new FileLoadingMacroTest()]);
}
}