Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Added configure --macro to specify which features are compiled in

  • Loading branch information...
commit bb92c4829db5c2bee4f693bfb487aeeb3e05ee05 1 parent 3530a5f
@misprintt misprintt authored
View
8 src/m/cover/AllClasses.hx
@@ -5,6 +5,7 @@ import m.cover.coverage.client.PrintClient;
import m.cover.coverage.client.TraceClient;
import m.cover.coverage.CoverageException;
import m.cover.coverage.CoverageLogger;
+import m.cover.coverage.CoverageMacro;
import m.cover.coverage.CoverageReportClient;
import m.cover.coverage.data.AbstractBlock;
import m.cover.coverage.data.AbstractNode;
@@ -21,6 +22,7 @@ import m.cover.coverage.data.Package;
import m.cover.coverage.data.Statement;
import m.cover.coverage.DataTypes;
import m.cover.coverage.macro.CoverageBuildMacro;
+import m.cover.coverage.MCoverage;
import m.cover.coverage.munit.client.MCoverPrintClient;
import m.cover.coverage.util.Timer;
import m.cover.Exception;
@@ -31,12 +33,16 @@ import m.cover.logger.data.LogRecording;
import m.cover.logger.LogException;
import m.cover.logger.Logger;
import m.cover.logger.LoggerImpl;
+import m.cover.logger.LoggerMacro;
import m.cover.logger.macro.LoggerBuildMacro;
+import m.cover.logger.MLogger;
import m.cover.logger.Utils;
import m.cover.macro.BuildMacro;
+import m.cover.macro.BuildMacroParser;
+import m.cover.macro.IncludeMacro;
+import m.cover.macro.MacroUtil;
import m.cover.macro.PackageHelper;
import m.cover.MCover;
-import m.cover.MLogger;
@IgnoreCover
class AllClasses
View
119 src/m/cover/MCover.hx
@@ -4,35 +4,48 @@ package m.cover;
import haxe.macro.Expr;
import haxe.macro.Context;
import haxe.macro.Compiler;
-
-import m.cover.coverage.macro.CoverageBuildMacro;
+import m.cover.macro.BuildMacro;
+import m.cover.coverage.CoverageMacro;
+import m.cover.logger.LoggerMacro;
import m.cover.macro.PackageHelper;
+import m.cover.macro.IncludeMacro;
+
+
/**
-* Main Coverage class containing macro and runtime methods for creating,
-* logging and reporting code coverage.
+* MCover provides a collection of macro based tools for measuring code quality and behavior.
*
* MACRO USAGE:
*
-* Use --macro m.cover.MCover.include(['package.name'],['sourcePath'], ['ignored patterns'])
-* to specifiy which packages/src directories to cover
-*
-*
-* RUNTIME USAGE:
+* To configure which tools to include, use:
+* --macro m.cover.MCover.configure(...);
*
-* See detailed documentation below for the following:
-* getLogger();
+* To specify which class paths/packages to include, use:
+* --macro m.cover.MCover.include(['package.name'],['sourcePath'], ['ignored patterns'])
+*
*/
@:keep class MCover
{
- static public var RESOURCE_DATA:String = "MCoverData";
-
- static public var classPathHash:IntHash<String> = new IntHash();
- //--------------- MACROS --------------..
+ public static var includes:Array<IncludeMacro> = [];
+
+ /**
+ * Configures MCover features for compilation
+ * A
+ * From the command line/hxml add a macro reference:
+ * --macro m.cover.MCover.configure();
+ *
+ * @param coverage include code coverage macros
+ * @param logging include function logging macros
+ **/
+ public static function configure(?coverage:Bool=true, ?logging:Bool=false):Void
+ {
+ if(coverage) includes.push(new CoverageMacro());
+ if(logging) includes.push(new LoggerMacro());
+ }
/**
- * Includes classes/packages logging.
- * Adds @:build(macro.BuildMacro.build()) to included classes
+ * Includes classes/packages for MCover.
+ * Adds @:build(m.cover.macro.BuildMacro.build()) to included classes
*
* From the command line/hxml add a macro reference:
* --macro m.cover.MCover.include(['package.name'], ['src'], null)
@@ -41,22 +54,27 @@ import m.cover.macro.PackageHelper;
* @param classPaths - array of classpaths to search in (defaults to local scope only (''))
* @param exclusions - array of qualified class names to exclude (supports '*' wildcard patterns)
**/
- public static function include(?packages : Array<String>=null, ?classPaths : Array<String>=null, ?exclusions : Array<String>=null)
+ static function include(?packages : Array<String>=null, ?classPaths : Array<String>=null, ?exclusions : Array<String>=null)
{
- if(packages == null || packages.length == 0) packages = [""];
- var helper = new PackageHelper();
- helper.ignoreClassMeta = "@IgnoreCover";
- var classes = helper.include(classPaths, packages, exclusions);
+ var classes:Array<String> = [];
- for(cp in classPaths)
+ if(includes.length == 0)
+ {
+ var pos = haxe.macro.Context.makePosition({file:"m.cover.MCover", min:0, max:0});//haxe.macro.Context.currentPos()
+ haxe.macro.Context.error("MCover not configured. Please ensure to set --macro m.cover.MCover.configure() before calling --macro m.cover.MCover.include", pos);
+ }
+
+ for(item in includes)
{
- classPathHash.set(Lambda.count(classPathHash), cp);
+ item.initialize();
+ var a = item.getClasses(packages, classPaths, exclusions);
+ classes = appendClasses(a, classes);
}
for(cl in classes)
{
//trace(cl);
- Compiler.addMetadata("@:build(m.cover.coverage.macro.CoverageBuildMacro.build())", cl);
+ Compiler.addMetadata("@:build(m.cover.macro.BuildMacro.build())", cl);
//Compiler.keep(cl, null, true);
}
@@ -65,53 +83,28 @@ import m.cover.macro.PackageHelper;
Compiler.include(pack, true, exclusions, classPaths);
}
- haxe.macro.Context.onGenerate(CoverageBuildMacro.onGenerate);
- }
-
- public static function onGenerate(types:Array<haxe.macro.Type>):Void
- {
-
+ haxe.macro.Context.onGenerate(onGenerate);
}
-}
-#else
-
-#if neko
-import neko.vm.Deque;
-#end
-
-import m.cover.coverage.CoverageLogger;
-
-class MCover
-{
- static public var RESOURCE_DATA:String = "MCoverData";
- #if neko
- static public var mutex:neko.vm.Mutex;
- #end
-
- static public var logger(default, null):CoverageLogger;
-
-
- @IgnoreCover
- public static function getLogger():CoverageLogger
+ static function appendClasses(a1:Array<String>, a2:Array<String>):Array<String>
{
- #if neko
- if(mutex == null) mutex = new neko.vm.Mutex();
- mutex.acquire();
- #end
- if(logger == null)
+ for(a in a1)
{
- logger = new CoverageLoggerImpl();
+ a2.remove(a);
}
- #if neko mutex.release(); #end
- return logger;
+
+ return a2.concat(a1);
}
- @IgnoreCover
- function new()
- {
+ static function onGenerate(types:Array<haxe.macro.Type>):Void
+ {
+ for(item in includes)
+ {
+ item.onGenerate(types);
+ }
}
}
+
#end
View
86 src/m/cover/MLogger.hx
@@ -1,86 +0,0 @@
-package m.cover;
-
-#if macro
-import haxe.macro.Expr;
-import haxe.macro.Context;
-import haxe.macro.Compiler;
-
-import m.cover.macro.PackageHelper;
-
-
-@:keep class MLogger
-{
- //--------------- MACROS --------------..
-
- /**
- * Includes classes/packages logging.
- * Adds @:build(macro.BuildMacro.build()) to included classes
- *
- * From the command line/hxml add a macro reference:
- * --macro MLog.include(['package.name'], ['src'], null)
- *
- * @param packages - array of packages to include (e.g. "com.example"). Defaults to all ([""])
- * @param classPaths - array of classpaths to search in (defaults to local scope only (''))
- * @param exclusions - array of qualified class names to exclude (supports '*' wildcard patterns)
- **/
- public static function include(?packages : Array<String>, ?classPaths : Array<String>, ?exclusions : Array<String> )
- {
- if(packages == null || packages.length == 0) packages = [""];
- var helper = new PackageHelper();
- var classes = helper.include(classPaths, packages, exclusions);
-
- for(cl in classes)
- {
- Compiler.addMetadata("@:build(m.cover.logger.macro.LoggerBuildMacro.build())", cl);
- //Compiler.keep(cl, null, true);
- }
-
- for(pack in packages)
- {
- Compiler.include(pack, true, exclusions, classPaths);
- }
-
- haxe.macro.Context.onGenerate(MLogger.onGenerate);
- }
-
- public static function onGenerate(types:Array<haxe.macro.Type>):Void
- {
-
- }
-}
-#else
-
-#if neko
-import neko.vm.Deque;
-#end
-import m.cover.logger.Logger;
-import m.cover.logger.LoggerImpl;
-
-class MLogger
-{
- #if neko
- static public var mutex:neko.vm.Mutex;
- #end
-
- static public var logger(default, null):Logger;
-
- public static function getLogger():Logger
- {
- #if neko
- if(mutex == null) mutex = new neko.vm.Mutex();
- mutex.acquire();
- #end
- if(logger == null)
- {
- logger = new LoggerImpl();
- }
- #if neko mutex.release(); #end
- return logger;
- }
-
- function new()
- {
-
- }
-}
-#end
View
14 src/m/cover/coverage/CoverageLogger.hx
@@ -75,7 +75,7 @@ interface CoverageLogger
class CoverageLoggerImpl implements CoverageLogger
{
#if neko
- static public var mutex:neko.vm.Mutex = new neko.vm.Mutex();
+ static public var mutex:neko.vm.Mutex;
#end
/**
@@ -189,7 +189,7 @@ class CoverageLoggerImpl implements CoverageLogger
public function initializeCoverage(?resourceName:String = null)
{
- if(resourceName == null) resourceName = MCover.RESOURCE_DATA;
+ if(resourceName == null) resourceName = MCoverage.RESOURCE_DATA;
var serializedData:String = haxe.Resource.getString(resourceName);
if(serializedData == null) throw new CoverageException("No generated coverage data found in haxe Resource '" + resourceName + "'");
try
@@ -209,7 +209,10 @@ class CoverageLoggerImpl implements CoverageLogger
@IgnoreCover
public function logStatement(id:Int)
{
- #if neko mutex.acquire(); #end
+ #if neko
+ if(mutex == null) mutex = new neko.vm.Mutex();
+ mutex.acquire();
+ #end
updateStatementHash(allStatementResultsById, id);
@@ -242,7 +245,10 @@ class CoverageLoggerImpl implements CoverageLogger
@IgnoreCover
public function logBranch(id:Int, value:Dynamic, ?compareValue:Dynamic=null):Dynamic
{
- #if neko mutex.acquire(); #end
+ #if neko
+ if(mutex == null) mutex = new neko.vm.Mutex();
+ mutex.acquire();
+ #end
var bool = false;
View
56 src/m/cover/coverage/CoverageMacro.hx
@@ -0,0 +1,56 @@
+package m.cover.coverage;
+
+#if macro
+import haxe.macro.Context;
+import m.cover.MCover;
+import m.cover.macro.PackageHelper;
+import m.cover.macro.BuildMacro;
+import m.cover.macro.IncludeMacro;
+import m.cover.coverage.data.Coverage;
+import m.cover.coverage.macro.CoverageBuildMacro;
+
+class CoverageMacro implements IncludeMacro
+{
+ static public var coverage = new Coverage();
+ static public var classPathHash:IntHash<String> = new IntHash();
+
+ public function new()
+ {
+
+ }
+
+ public function initialize()
+ {
+ BuildMacro.addParserClass(CoverageBuildMacro);
+ }
+
+ public function getClasses(?packages : Array<String>=null, ?classPaths : Array<String>=null, ?exclusions : Array<String>=null):Array<String>
+ {
+ if(packages == null || packages.length == 0) packages = [""];
+ var helper = new PackageHelper();
+ helper.ignoreClassMeta = "IgnoreCover";
+
+ var classes = helper.include(classPaths, packages, exclusions);
+
+ for(cp in classPaths)
+ {
+ classPathHash.set(Lambda.count(classPathHash), cp);
+ }
+
+
+ return classes;
+
+ }
+
+ /**
+ * Inserts reference to all identified code coverage blocks into a haxe.Resource file called 'MCover'.
+ * This resource is used by MCoverRunner to determine code coverage results
+ */
+ public function onGenerate(types:Array<haxe.macro.Type>):Void
+ {
+ var serializedData = haxe.Serializer.run(CoverageMacro.coverage);
+ Context.addResource(MCoverage.RESOURCE_DATA, haxe.io.Bytes.ofString(serializedData));
+ }
+}
+
+#end
View
40 src/m/cover/coverage/MCoverage.hx
@@ -0,0 +1,40 @@
+package m.cover.coverage;
+
+#if neko
+import neko.vm.Deque;
+#end
+
+import m.cover.coverage.CoverageLogger;
+
+class MCoverage
+{
+ static public var RESOURCE_DATA:String = "MCoverData";
+
+ #if neko
+ static public var mutex:neko.vm.Mutex;
+ #end
+
+ static public var logger(default, null):CoverageLogger;
+
+
+ @IgnoreCover
+ public static function getLogger():CoverageLogger
+ {
+ #if neko
+ if(mutex == null) mutex = new neko.vm.Mutex();
+ mutex.acquire();
+ #end
+ if(logger == null)
+ {
+ logger = new CoverageLoggerImpl();
+ }
+ #if neko mutex.release(); #end
+ return logger;
+ }
+
+ @IgnoreCover
+ function new()
+ {
+
+ }
+}
View
103 src/m/cover/coverage/macro/CoverageBuildMacro.hx
@@ -9,87 +9,67 @@ import m.cover.macro.BuildMacro;
import m.cover.coverage.DataTypes;
-@:keep class CoverageBuildMacro extends BuildMacro
-{
+import m.cover.macro.MacroUtil;
+import m.cover.macro.BuildMacro;
+import m.cover.macro.BuildMacroParser;
+@:keep class CoverageBuildMacro implements BuildMacroParser
+{
+ public var ignoreFieldMeta(default, default):String;
+ public var includeFieldMeta(default, default):String;
+
static var statementCount:Int = 0;
static var branchCount:Int = 0;
- static var coverage = new Coverage();
- /**
- * Inserts reference to all identified code coverage blocks into a haxe.Resource file called 'MCover'.
- * This resource is used by MCoverRunner to determine code coverage results
- */
- static public function onGenerate(types:Array<haxe.macro.Type>):Void
- {
- var serializedData = haxe.Serializer.run(coverage);
- Context.addResource(MCover.RESOURCE_DATA, haxe.io.Bytes.ofString(serializedData));
- }
- /**
- Inserts coverage code into the specified class.
+ public var target(default, default):IBuildMacro;
- @return updated array of fields for the class
- */
- @:macro public static function build():Array<Field>
- {
- var instance = new CoverageBuildMacro();
- var fields = instance.parseFields();
- return fields;
- }
-
- var counter:Int;
-
public function new()
{
ignoreFieldMeta = "IgnoreCover";
- counter = 0;
- super();
+ includeFieldMeta = null;
+
}
/**
- Overrides defauld BuildMacro.parse() to wrap branches and statement blocks
+ Wraps code branches and statement blocks with coverage logs
- @param expr - the current expression
+ @param expr the current expression
+ @param target the current BuildMacro instance
@return the updated expression
- @see BuildMacro.parse
+ @see BuildMacro.parseExpr
*/
- override function parse(expr:Expr):Expr
+ public function parseExpr(expr:Expr):Expr
{
switch(expr.expr)
{
case EIf(econd, eif, eelse):
{
- expr = super.parse(expr);
econd = createBranchCoverageExpr(econd);
expr.expr = EIf(econd, eif, eelse);
}
case EWhile(econd, e, normalWhile):
{
- expr = super.parse(expr);
econd = createBranchCoverageExpr(econd);
expr.expr = EWhile(econd, e, normalWhile);
}
case ETernary(econd, eif, eelse):
{
//e.g. var n = (1 + 1 == 2) ? 4 : 5;
- expr = super.parse(expr);
econd = createBranchCoverageExpr(econd);
expr.expr = ETernary(econd, eif, eelse);
}
case EBlock(exprs):
{
//e.g. {...}
- super.parse(expr);
parseEBlock(expr, exprs);
}
case EBinop(op, e1, e2):
{
//e.g. i<2; a||b, i==b
- super.parse(expr);
parseEBinop(expr, op, e1, e2);
}
- default: expr = super.parse(expr);
+ default: null;
}
return expr;
}
@@ -103,7 +83,7 @@ import m.cover.coverage.DataTypes;
if(exprs.length == 0)
{
//ensure empty methods are still covered (e.g. empty constructor)
- if(expr != functionStack[functionStack.length-1].expr) return;
+ if(expr != target.functionStack[target.functionStack.length-1].expr) return;
}
var pos:Position = (exprs.length == 0) ? expr.pos : exprs[0].pos;
@@ -148,19 +128,19 @@ import m.cover.coverage.DataTypes;
pos = baseExpr.pos;
var eField = EField(baseExpr, "logStatement");
- pos = incrementPos(pos, 13);
+ pos = MacroUtil.incrementPos(pos, 13);
var fieldExpr = {expr:eField, pos:pos};
- pos = incrementPos(pos, blockId.length);
+ pos = MacroUtil.incrementPos(pos, blockId.length);
var arg1 = {expr:EConst(CInt(blockId)), pos:pos};
- pos = incrementPos(pos, 2);
+ pos = MacroUtil.incrementPos(pos, 2);
return {expr:ECall(fieldExpr, [arg1]), pos:pos};
}
/**
- * wraps a boolean value within a branch in a call to MCover.getLogger().logBranch(id, value, compareValue);
+ * wraps a boolean value within a branch in a call to MCoverage.getLogger().logBranch(id, value, compareValue);
**/
function createBranchCoverageExpr(expr:Expr, ?compareExpr:Expr = null):Expr
{
@@ -173,21 +153,21 @@ import m.cover.coverage.DataTypes;
pos = baseExpr.pos;
var eField = EField(baseExpr, "logBranch");
- pos = incrementPos(pos, 4);
+ pos = MacroUtil.incrementPos(pos, 4);
var fieldExpr = {expr:eField, pos:pos};
var args:Array<Expr> = [];
- pos = incrementPos(pos, blockId.length);
+ pos = MacroUtil.incrementPos(pos, blockId.length);
args.push({expr:EConst(CInt(blockId)), pos:pos});
- pos = incrementPos(pos, 5);
+ pos = MacroUtil.incrementPos(pos, 5);
args.push({expr:expr.expr, pos:pos});
if(compareExpr != null)
{
- pos = incrementPos(pos, 5);
+ pos = MacroUtil.incrementPos(pos, 5);
args.push({expr:compareExpr.expr, pos:pos});
}
@@ -201,7 +181,7 @@ import m.cover.coverage.DataTypes;
var posInfo = Context.getPosInfos(pos);
var file:String = posInfo.file;
- for (cp in MCover.classPathHash)
+ for (cp in CoverageMacro.classPathHash)
{
if(file.indexOf(cp) == 0)
{
@@ -238,9 +218,9 @@ import m.cover.coverage.DataTypes;
parts.pop();
block.packageName = (parts.length > 0) ? parts.join(".") : "";
- block.className = currentClassName;
+ block.className = target.currentClassName;
block.qualifiedClassName = (block.packageName != "") ? block.packageName + "." + block.className : block.className;
- block.methodName = currentMethodName;
+ block.methodName = target.currentMethodName;
var posInfo = Context.getPosInfos(pos);
@@ -254,40 +234,45 @@ import m.cover.coverage.DataTypes;
if(isBranch)
{
- coverage.addBranch(cast(block, Branch));
+ CoverageMacro.coverage.addBranch(cast(block, Branch));
}
else
{
- coverage.addStatement(cast(block, Statement));
+ CoverageMacro.coverage.addStatement(cast(block, Statement));
}
return block;
}
/**
- Creates a call to MCover.getLogger();
+ Creates a call to MCoverage.getLogger();
@param pos - the position to add to
- @return expr matching "m.cover.MCover.getLogger()"
+ @return expr matching "m.cover.coverage.MCoverage.getLogger()"
*/
function getReferenceToLogger(pos:Position):Expr
{
var cIdent = EConst(CIdent("m"));
- pos = incrementPos(pos, 7);
+ pos = MacroUtil.incrementPos(pos, 7);
var identExpr = {expr:cIdent, pos:pos};
var eIdentField = EField(identExpr, "cover");
- pos = incrementPos(pos, 7);
+ pos = MacroUtil.incrementPos(pos, 7);
var identFieldExpr = {expr:eIdentField, pos:pos};
- var eType = EType(identFieldExpr, "MCover");
- pos = incrementPos(pos, 5);
+ var eIdentField2 = EField(identFieldExpr, "coverage");
+ pos = MacroUtil.incrementPos(pos, 7);
+ var identFieldExpr2 = {expr:eIdentField2, pos:pos};
+
+
+ var eType = EType(identFieldExpr2, "MCoverage");
+ pos = MacroUtil.incrementPos(pos, 5);
var typeExpr = {expr:eType, pos:pos};
var eField = EField(typeExpr, "getLogger");
- pos = incrementPos(pos, 9);
+ pos = MacroUtil.incrementPos(pos, 9);
var fieldExpr = {expr:eField, pos:pos};
- pos = incrementPos(pos, 2);
+ pos = MacroUtil.incrementPos(pos, 2);
return {expr:ECall(fieldExpr, []), pos:pos};
}
View
4 src/m/cover/coverage/munit/client/MCoverPrintClient.hx
@@ -33,7 +33,7 @@ import massive.munit.client.RichPrintClient;
import massive.munit.TestResult;
import m.cover.coverage.CoverageReportClient;
import m.cover.coverage.DataTypes;
-import m.cover.MCover;
+import m.cover.coverage.MCoverage;
class MCoverPrintClient implements IAdvancedTestResultClient
{
@@ -146,7 +146,7 @@ class MCoverPrintClient implements IAdvancedTestResultClient
{
try
{
- return MCover.getLogger();
+ return MCoverage.getLogger();
}
catch(e:Dynamic)
{
View
1  src/m/cover/coverage/util/Timer.hx
@@ -65,7 +65,6 @@ class Timer
static var arr:Array<Timer> = [];
var timerId:Int;
#elseif neko
- static var mutex = new neko.vm.Mutex();
var runThread:neko.vm.Thread;
#end
View
1  src/m/cover/logger/LoggerImpl.hx
@@ -6,6 +6,7 @@ import m.cover.logger.data.LogRecording;
import m.cover.logger.client.LogClient;
import m.cover.logger.client.LogClientImpl;
+@IgnoreLogging
class LoggerImpl implements Logger
{
static public var MAX_STACK_DEPTH_LIMIT:Int = 26;
View
42 src/m/cover/logger/LoggerMacro.hx
@@ -0,0 +1,42 @@
+package m.cover.logger;
+
+#if macro
+
+import m.cover.MCover;
+import m.cover.macro.PackageHelper;
+import m.cover.macro.BuildMacro;
+import m.cover.macro.IncludeMacro;
+
+import m.cover.logger.macro.LoggerBuildMacro;
+
+class LoggerMacro implements IncludeMacro
+{
+ public function new()
+ {
+
+ }
+
+ public function initialize()
+ {
+ BuildMacro.addParserClass(LoggerBuildMacro);
+ }
+
+ public function getClasses(?packages : Array<String>=null, ?classPaths : Array<String>=null, ?exclusions : Array<String>=null):Array<String>
+ {
+ if(packages == null || packages.length == 0) packages = [""];
+ var helper = new PackageHelper();
+ helper.ignoreClassMeta = "IgnoreLogging";
+
+ var classes = helper.include(classPaths, packages, exclusions);
+ return classes;
+
+ }
+
+
+ public function onGenerate(types:Array<haxe.macro.Type>):Void
+ {
+
+ }
+}
+
+#end
View
36 src/m/cover/logger/MLogger.hx
@@ -0,0 +1,36 @@
+package m.cover.logger;
+
+#if neko
+import neko.vm.Deque;
+#end
+import m.cover.logger.Logger;
+import m.cover.logger.LoggerImpl;
+
+@IgnoreLogging
+class MLogger
+{
+ #if neko
+ static public var mutex:neko.vm.Mutex;
+ #end
+
+ static public var logger(default, null):Logger;
+
+ public static function getLogger():Logger
+ {
+ #if neko
+ if(mutex == null) mutex = new neko.vm.Mutex();
+ mutex.acquire();
+ #end
+ if(logger == null)
+ {
+ logger = new LoggerImpl();
+ }
+ #if neko mutex.release(); #end
+ return logger;
+ }
+
+ function new()
+ {
+
+ }
+}
View
1  src/m/cover/logger/client/LogClientImpl.hx
@@ -5,6 +5,7 @@ import m.cover.logger.data.LogRecording;
import m.cover.logger.client.LogClient;
+@IgnoreLogging
class LogClientImpl implements LogClient
{
/**
View
61 src/m/cover/logger/macro/LoggerBuildMacro.hx
@@ -6,22 +6,16 @@ import haxe.macro.Context;
import haxe.macro.Compiler;
import haxe.macro.Type;
+import m.cover.macro.MacroUtil;
import m.cover.macro.BuildMacro;
+import m.cover.macro.BuildMacroParser;
-
-class LoggerBuildMacro extends BuildMacro
+class LoggerBuildMacro implements BuildMacroParser
{
- /**
- Inserts code into the specified class.
-
- @return updated array of fields for the class
- */
- @:macro public static function build():Array<Field>
- {
- var instance = new LoggerBuildMacro();
- var fields = instance.parseFields();
- return fields;
- }
+ public var ignoreFieldMeta(default, default):String;
+ public var includeFieldMeta(default, default):String;
+
+ public var target(default, default):IBuildMacro;
var counter:Int;
@@ -29,37 +23,35 @@ class LoggerBuildMacro extends BuildMacro
{
counter = 0;
ignoreFieldMeta = "IgnoreLogging";
- super();
+ includeFieldMeta = null;
}
/**
Overrides defauld BuildMacro.parse() to wrap method entry and exit points
- @param expr - the current expression
+ @param expr the current expression
+ @param target the current BuildMacro instance
@return the updated expression
- @see BuildMacro.parse
+ @see BuildMacro.parseExpr
*/
- override function parse(expr:Expr):Expr
+ public function parseExpr(expr:Expr):Expr
{
switch(expr.expr)
{
case EReturn(e):
{
- super.parse(expr);
parseEReturn(expr, e);
}
case EBlock(exprs):
{
//e.g. {...}
- super.parse(expr);
parseEBlock(expr, exprs);
}
case EThrow(e):
{
- super.parse(expr);
parseEThrow(expr, e);
}
- default: expr = super.parse(expr);
+ default: null;
}
return expr;
}
@@ -75,11 +67,11 @@ class LoggerBuildMacro extends BuildMacro
{
if(exprs.length == 0) return;
- if(expr != functionStack[functionStack.length-1].expr) return;//only care about the main block in a function
+ if(expr != target.functionStack[target.functionStack.length-1].expr) return;//only care about the main block in a function
var pos:Position = exprs[0].pos;
- var entryLogExpr = logEntry(pos, functionStack.length > 1);
+ var entryLogExpr = logEntry(pos, target.functionStack.length > 1);
exprs.unshift(entryLogExpr);
var lastExpr = exprs[exprs.length-1];
@@ -203,7 +195,7 @@ class LoggerBuildMacro extends BuildMacro
function wrapExitExpr(expr:Expr, e:Expr)
{
var exitExprs = createExitExprs(expr, e);
- var parentExpr = exprStack[exprStack.length-2];
+ var parentExpr = target.exprStack[target.exprStack.length-2];
switch(parentExpr.expr)
{
@@ -267,7 +259,6 @@ class LoggerBuildMacro extends BuildMacro
if(e != null)
{
- macrotools.Print.make(e);
var tempVarName = "____m" + counter++;
var eVar = {
type:null,
@@ -328,7 +319,7 @@ class LoggerBuildMacro extends BuildMacro
var loggerExpr = getReferenceToLogger(pos);
var eField = EField(loggerExpr, method);
- pos = incrementPos(pos, method.length + 1);
+ pos = MacroUtil.incrementPos(pos, method.length + 1);
var fieldExpr = {
expr:eField,
@@ -353,24 +344,30 @@ class LoggerBuildMacro extends BuildMacro
function getReferenceToLogger(pos:Position):Expr
{
var cIdent = EConst(CIdent("m"));
- pos = incrementPos(pos, 7);
+ pos = MacroUtil.incrementPos(pos, 7);
var identExpr = {expr:cIdent, pos:pos};
var eIdentField = EField(identExpr, "cover");
- pos = incrementPos(pos, 7);
+ pos = MacroUtil.incrementPos(pos, 7);
var identFieldExpr = {expr:eIdentField, pos:pos};
- var eType = EType(identFieldExpr, "MLogger");
- pos = incrementPos(pos, 5);
+ var eIdentField2 = EField(identFieldExpr, "logger");
+ pos = MacroUtil.incrementPos(pos, 7);
+ var identFieldExpr2 = {expr:eIdentField2, pos:pos};
+
+
+ var eType = EType(identFieldExpr2, "MLogger");
+ pos = MacroUtil.incrementPos(pos, 5);
var typeExpr = {expr:eType, pos:pos};
var eField = EField(typeExpr, "getLogger");
- pos = incrementPos(pos, 9);
+ pos = MacroUtil.incrementPos(pos, 9);
var fieldExpr = {expr:eField, pos:pos};
- pos = incrementPos(pos, 2);
+ pos = MacroUtil.incrementPos(pos, 2);
return {expr:ECall(fieldExpr, []), pos:pos};
}
+
}
typedef ExitExprs =
View
158 src/m/cover/macro/BuildMacro.hx
@@ -5,10 +5,19 @@ package m.cover.macro;
import haxe.macro.Expr;
import haxe.macro.Context;
import haxe.macro.Compiler;
-import haxe.macro.Type;
import haxe.PosInfos;
-class BuildMacro
+
+interface IBuildMacro
+{
+ var exprStack(default, null):Array<Expr>;
+ var functionStack(default, null):Array<Function>;
+ var currentClassName(default, null):String;
+ var currentPackageName(default, null):String;
+ var currentMethodName(default, null):String;
+}
+
+class BuildMacro implements IBuildMacro
{
/**
@@ -24,33 +33,62 @@ class BuildMacro
return fields;
}
+ static var parserClasses:Array<Class<BuildMacroParser>> = [];
+
+
+ public static function addParserClass(parser:Class<BuildMacroParser>)
+ {
+ parserClasses.remove(parser);
+ parserClasses.push(parser);
+ }
+
+ public static function removeParserClass(parser:Class<BuildMacroParser>)
+ {
+ parserClasses.remove(parser);
+ }
+
+ public static function removeAllParserClasses(parser:Class<BuildMacroParser>)
+ {
+ parserClasses = [];
+ }
+
+
/////////////////
- /**
- optional metadata values to filter fields on
- */
- var ignoreFieldMeta:String;
- var includeFieldMeta:String;
+ public var currentClassName(default, null):String;
+ public var currentPackageName(default, null):String;
+ public var currentMethodName(default, null):String;
- var fields:Array<Field>;
- var type:Null<Type>;
+ public var functionStack(default, null):Array<Function>;
+ public var exprStack(default, null):Array<Expr>;
- var currentClassName:String;
- var currentPackageName:String;
- var currentMethodName:String;
- var functionStack:Array<Function>;
+ var fields:Array<Field>;
+ var type:Null<haxe.macro.Type>;
+
+
var generatedFields:Array<Field>;
- var exprStack:Array<Expr>;
+
+
+ var parsers:Array<BuildMacroParser>;
+ var fieldParsers:Array<BuildMacroParser>;
public function new()
{
fields = Context.getBuildFields();
type = Context.getLocalType();
+
+ parsers = [];
+ for(parserClass in parserClasses)
+ {
+ var parserInst = Type.createInstance(parserClass, []);
+ parserInst.target = this;
+ parsers.push(parserInst);
+ }
switch(type)
{
@@ -73,9 +111,11 @@ class BuildMacro
*/
public function parseFields():Array<Field>
{
+ if(parsers.length == 0) return null;
+
functionStack = [];
- generatedFields = [];
exprStack = [];
+ generatedFields = [];
for(field in fields)
{
@@ -91,20 +131,16 @@ class BuildMacro
function parseField(field:Field):Field
{
- if(ignoreFieldMeta != null)
- {
- for(item in field.meta)
- {
- if(item.name == ignoreFieldMeta) return field;
- }
- }
- else if(includeFieldMeta != null)
+ fieldParsers = [];
+ for(parser in parsers)
{
- for(item in field.meta)
+ if(isFieldParser(parser, field))
{
- if(item.name != includeFieldMeta) return field;
+ fieldParsers.push(parser);
}
}
+
+ if(fieldParsers.length == 0) return field;
switch(field.kind)
{
@@ -114,6 +150,29 @@ class BuildMacro
return field;
}
+
+ function isFieldParser(parser:BuildMacroParser, field:Field):Bool
+ {
+ if(parser.ignoreFieldMeta != null)
+ {
+ for(item in field.meta)
+ {
+ if(item.name == parser.ignoreFieldMeta) return false;
+ }
+ }
+ else if(parser.includeFieldMeta != null)
+ {
+ for(item in field.meta)
+ {
+ if(item.name != parser.includeFieldMeta) return false;
+ }
+ }
+
+ return true;
+ }
+
+
+
function parseMethod(field:Field, f:Function)
{
currentMethodName = field.name;
@@ -134,11 +193,18 @@ class BuildMacro
expr = parse(expr);
+ for(parser in fieldParsers)
+ {
+ expr = parser.parseExpr(expr);
+ }
+
exprStack.pop();
return expr;
}
+
+
function parse(expr:Expr):Expr
{
switch(expr.expr)
@@ -312,23 +378,6 @@ class BuildMacro
}
- /**
- parses an array of expressions
-
- @return updated array of expressions
- */
- function parseExprs(exprs:Array<Expr>):Array<Expr>
- {
- var temp:Array<Expr> = exprs.concat([]);
-
- for(expr in temp)
- {
- expr = parseExpr(expr);
- }
- return exprs;
- }
-
-
function parseEIf(expr:Expr, econd:Expr, eif:Expr, eelse:Expr)
{
econd = parseExpr(econd);
@@ -362,15 +411,30 @@ class BuildMacro
/////////
- function incrementPos(pos:Position, length:Int):Position
+
+
+ /**
+ parses an array of expressions
+
+ @return updated array of expressions
+ */
+ public function parseExprs(exprs:Array<Expr>):Array<Expr>
{
- var posInfos = Context.getPosInfos(pos);
- posInfos.max = posInfos.min + length;
- return Context.makePosition(posInfos);
+ var temp:Array<Expr> = exprs.concat([]);
+
+ for(expr in temp)
+ {
+ expr = parseExpr(expr);
+ }
+ return exprs;
}
- function debug(value:Dynamic, ?pos:PosInfos)
+
+
+
+
+ public function debug(value:Dynamic, ?pos:PosInfos)
{
#if MACRO_LOGGER_DEBUG
var msg = pos.className + "(" + pos.lineNumber + "):\n " + Std.string(value);
View
18 src/m/cover/macro/BuildMacroParser.hx
@@ -0,0 +1,18 @@
+package m.cover.macro;
+
+#if macro
+import haxe.macro.Expr;
+import m.cover.macro.BuildMacro;
+
+interface BuildMacroParser
+{
+ var ignoreFieldMeta(default, default):String;
+ var includeFieldMeta(default, default):String;
+
+ var target(default, default):IBuildMacro;
+
+ function parseExpr(expr:Expr):Expr;
+
+}
+
+#end
View
7 src/m/cover/macro/IncludeMacro.hx
@@ -0,0 +1,7 @@
+package m.cover.macro;
+interface IncludeMacro
+{
+ function initialize():Void;
+ function getClasses(?packages : Array<String>=null, ?classPaths : Array<String>=null, ?exclusions : Array<String>=null):Array<String>;
+ function onGenerate(types:Array<haxe.macro.Type>):Void;
+}
View
14 src/m/cover/macro/MacroUtil.hx
@@ -0,0 +1,14 @@
+package m.cover.macro;
+
+import haxe.macro.Expr;
+import haxe.macro.Context;
+
+class MacroUtil
+{
+ static public function incrementPos(pos:Position, length:Int):Position
+ {
+ var posInfos = Context.getPosInfos(pos);
+ posInfos.max = posInfos.min + length;
+ return Context.makePosition(posInfos);
+ }
+}
View
4 src/m/cover/macro/PackageHelper.hx
@@ -182,7 +182,7 @@ class PackageHelper
if(ignoreClassMeta != null)
{
//var regIgnore:EReg = ~/@IgnoreCover([^{]*)class ([A-Z]([A-Za-z0-9])+)/m;
- var regIgnore:EReg = new EReg(ignoreClassMeta + "([^{]*)class ([A-Z]([A-Za-z0-9])+)", "m");
+ var regIgnore:EReg = new EReg("@" + ignoreClassMeta + "([^{]*)class ([A-Z]([A-Za-z0-9])+)", "m");
contents = neko.io.File.getContent(path);
@@ -197,7 +197,7 @@ class PackageHelper
if(includeClassMeta != null)
{
- regInclude = new EReg(includeClassMeta + "([^{]*)class ([A-Z]([A-Za-z0-9])+)", "m");
+ regInclude = new EReg("@" + includeClassMeta + "([^{]*)class ([A-Z]([A-Za-z0-9])+)", "m");
}
else
{
View
3  test.hxml
@@ -48,5 +48,8 @@
-debug
-neko build/test/neko_test.n
-D MCOVER_DEBUG
+--macro m.cover.MCover.configure(true)
-resource test/m/cover/coverage/MockResouce.txt@MockMCoverResource
+
+# --macro m.cover.MLogger.include([''], ['src'], null)
# --macro m.cover.MCover.include('',['src'])
View
4 test/TestSuite.hx
@@ -18,7 +18,7 @@ import m.cover.coverage.data.FileTest;
import m.cover.coverage.data.MethodTest;
import m.cover.coverage.data.PackageTest;
import m.cover.coverage.data.StatementTest;
-import m.cover.coverage.MCoverTest;
+import m.cover.coverage.MCoverageTest;
import m.cover.coverage.munit.client.MCoverPrintClientTest;
import m.cover.coverage.util.TimerTest;
import m.cover.ExceptionTest;
@@ -53,7 +53,7 @@ class TestSuite extends massive.munit.TestSuite
add(m.cover.coverage.data.MethodTest);
add(m.cover.coverage.data.PackageTest);
add(m.cover.coverage.data.StatementTest);
- add(m.cover.coverage.MCoverTest);
+ add(m.cover.coverage.MCoverageTest);
add(m.cover.coverage.munit.client.MCoverPrintClientTest);
add(m.cover.coverage.util.TimerTest);
add(m.cover.ExceptionTest);
View
2  test/m/cover/coverage/CoverageLoggerTest.hx
@@ -51,7 +51,7 @@ class CoverageLoggerTest
@Test
public function shouldCreateCoverageOnInitializeCoverage()
{
- logger.initializeCoverage(MCover.RESOURCE_DATA);
+ logger.initializeCoverage(MCoverage.RESOURCE_DATA);
Assert.isNotNull(logger.coverage);
}
View
6 test/m/cover/coverage/MCoverTest.hx → test/m/cover/coverage/MCoverageTest.hx
@@ -5,7 +5,7 @@ import massive.munit.Assert;
import massive.munit.async.AsyncFactory;
-class MCoverTest
+class MCoverageTest
{
public function new()
@@ -38,7 +38,7 @@ class MCoverTest
@Test
public function shouldGetDefaultLogger()
{
- var logger:CoverageLogger = MCover.getLogger();
- Assert.areEqual(MCover.logger, logger);
+ var logger:CoverageLogger = MCoverage.getLogger();
+ Assert.areEqual(MCoverage.logger, logger);
}
}
Please sign in to comment.
Something went wrong with that request. Please try again.