From 9c1b11d60527d9240b0cb63d1bfcd96bb151ff42 Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Thu, 28 Dec 2023 13:48:01 +0100 Subject: [PATCH] some WARN messages are now INFO --- .../src/prog8/code/core/IErrorReporter.kt | 5 ++-- codeGenCpu6502/test/Dummies.kt | 14 +++++++--- .../intermediate/IRUnusedCodeRemover.kt | 4 +-- codeGenIntermediate/test/Dummies.kt | 14 +++++++--- .../src/prog8/optimizer/StatementOptimizer.kt | 6 ++--- .../src/prog8/optimizer/UnusedCodeRemover.kt | 18 ++++++------- .../src/prog8/buildversion/BuildVersion.kt | 12 ++++----- compiler/src/prog8/compiler/ErrorReporter.kt | 26 ++++++++++++++----- .../compiler/astprocessing/AstChecker.kt | 16 ++++++------ .../astprocessing/IntermediateAstMaker.kt | 2 +- .../compiler/astprocessing/VariousCleanups.kt | 6 ++--- .../test/helpers/ErrorReporterForTests.kt | 14 +++++++--- docs/source/todo.rst | 3 --- 13 files changed, 87 insertions(+), 53 deletions(-) diff --git a/codeCore/src/prog8/code/core/IErrorReporter.kt b/codeCore/src/prog8/code/core/IErrorReporter.kt index e60aa9a19..eebf5ca0d 100644 --- a/codeCore/src/prog8/code/core/IErrorReporter.kt +++ b/codeCore/src/prog8/code/core/IErrorReporter.kt @@ -3,11 +3,12 @@ package prog8.code.core interface IErrorReporter { fun err(msg: String, position: Position) fun warn(msg: String, position: Position) + fun info(msg: String, position: Position) fun undefined(symbol: List, position: Position) fun noErrors(): Boolean fun report() - fun finalizeNumErrors(numErrors: Int, numWarnings: Int) { + fun finalizeNumErrors(numErrors: Int, numWarnings: Int, numInfos: Int) { if(numErrors>0) - throw ErrorsReportedException("There are $numErrors errors and $numWarnings warnings.") + throw ErrorsReportedException("There are $numErrors errors, $numWarnings warnings, and $numInfos infos.") } } diff --git a/codeGenCpu6502/test/Dummies.kt b/codeGenCpu6502/test/Dummies.kt index 0e75d5c23..c5999e56f 100644 --- a/codeGenCpu6502/test/Dummies.kt +++ b/codeGenCpu6502/test/Dummies.kt @@ -29,11 +29,11 @@ internal object DummyStringEncoder : IStringEncoding { } } -internal class ErrorReporterForTests(private val throwExceptionAtReportIfErrors: Boolean=true, private val keepMessagesAfterReporting: Boolean=false): - IErrorReporter { +internal class ErrorReporterForTests(private val throwExceptionAtReportIfErrors: Boolean=true, private val keepMessagesAfterReporting: Boolean=false): IErrorReporter { val errors = mutableListOf() val warnings = mutableListOf() + val infos = mutableListOf() override fun err(msg: String, position: Position) { val text = "${position.toClickableStr()} $msg" @@ -47,6 +47,12 @@ internal class ErrorReporterForTests(private val throwExceptionAtReportIfErrors: warnings.add(text) } + override fun info(msg: String, position: Position) { + val text = "${position.toClickableStr()} $msg" + if(text !in infos) + infos.add(text) + } + override fun undefined(symbol: List, position: Position) { err("undefined symbol: ${symbol.joinToString(".")}", position) } @@ -54,10 +60,11 @@ internal class ErrorReporterForTests(private val throwExceptionAtReportIfErrors: override fun noErrors(): Boolean = errors.isEmpty() override fun report() { + infos.forEach { println("UNITTEST COMPILATION REPORT: INFO: $it") } warnings.forEach { println("UNITTEST COMPILATION REPORT: WARNING: $it") } errors.forEach { println("UNITTEST COMPILATION REPORT: ERROR: $it") } if(throwExceptionAtReportIfErrors) - finalizeNumErrors(errors.size, warnings.size) + finalizeNumErrors(errors.size, warnings.size, infos.size) if(!keepMessagesAfterReporting) { clear() } @@ -66,5 +73,6 @@ internal class ErrorReporterForTests(private val throwExceptionAtReportIfErrors: fun clear() { errors.clear() warnings.clear() + infos.clear() } } diff --git a/codeGenIntermediate/src/prog8/codegen/intermediate/IRUnusedCodeRemover.kt b/codeGenIntermediate/src/prog8/codegen/intermediate/IRUnusedCodeRemover.kt index 021d4bc1e..c3c2b48f5 100644 --- a/codeGenIntermediate/src/prog8/codegen/intermediate/IRUnusedCodeRemover.kt +++ b/codeGenIntermediate/src/prog8/codegen/intermediate/IRUnusedCodeRemover.kt @@ -61,7 +61,7 @@ class IRUnusedCodeRemover( block.children.filterIsInstance().reversed().forEach { sub -> if(sub.isEmpty()) { if(!block.options.ignoreUnused) { - errors.warn("unused subroutine '${sub.label}'", sub.position) + errors.info("unused subroutine '${sub.label}'", sub.position) } block.children.remove(sub) irprog.st.removeTree(sub.label) @@ -82,7 +82,7 @@ class IRUnusedCodeRemover( block.children.filterIsInstance().reversed().forEach { sub -> if(sub.isEmpty()) { if(!block.options.ignoreUnused) { - errors.warn("unused subroutine '${sub.label}'", sub.position) + errors.info("unused subroutine '${sub.label}'", sub.position) } block.children.remove(sub) irprog.st.removeTree(sub.label) diff --git a/codeGenIntermediate/test/Dummies.kt b/codeGenIntermediate/test/Dummies.kt index 848d1ec28..1eaa6b827 100644 --- a/codeGenIntermediate/test/Dummies.kt +++ b/codeGenIntermediate/test/Dummies.kt @@ -27,11 +27,11 @@ internal object DummyStringEncoder : IStringEncoding { } } -internal class ErrorReporterForTests(private val throwExceptionAtReportIfErrors: Boolean=true, private val keepMessagesAfterReporting: Boolean=false): - IErrorReporter { +internal class ErrorReporterForTests(private val throwExceptionAtReportIfErrors: Boolean=true, private val keepMessagesAfterReporting: Boolean=false): IErrorReporter { val errors = mutableListOf() val warnings = mutableListOf() + val infos = mutableListOf() override fun err(msg: String, position: Position) { val text = "${position.toClickableStr()} $msg" @@ -45,6 +45,12 @@ internal class ErrorReporterForTests(private val throwExceptionAtReportIfErrors: warnings.add(text) } + override fun info(msg: String, position: Position) { + val text = "${position.toClickableStr()} $msg" + if(text !in infos) + infos.add(text) + } + override fun undefined(symbol: List, position: Position) { err("undefined symbol: ${symbol.joinToString(".")}", position) } @@ -52,10 +58,11 @@ internal class ErrorReporterForTests(private val throwExceptionAtReportIfErrors: override fun noErrors(): Boolean = errors.isEmpty() override fun report() { + infos.forEach { println("UNITTEST COMPILATION REPORT: INFO: $it") } warnings.forEach { println("UNITTEST COMPILATION REPORT: WARNING: $it") } errors.forEach { println("UNITTEST COMPILATION REPORT: ERROR: $it") } if(throwExceptionAtReportIfErrors) - finalizeNumErrors(errors.size, warnings.size) + finalizeNumErrors(errors.size, warnings.size, infos.size) if(!keepMessagesAfterReporting) { clear() } @@ -64,5 +71,6 @@ internal class ErrorReporterForTests(private val throwExceptionAtReportIfErrors: fun clear() { errors.clear() warnings.clear() + infos.clear() } } diff --git a/codeOptimizers/src/prog8/optimizer/StatementOptimizer.kt b/codeOptimizers/src/prog8/optimizer/StatementOptimizer.kt index ca63f6b46..498a2a14e 100644 --- a/codeOptimizers/src/prog8/optimizer/StatementOptimizer.kt +++ b/codeOptimizers/src/prog8/optimizer/StatementOptimizer.kt @@ -131,7 +131,7 @@ class StatementOptimizer(private val program: Program, override fun after(forLoop: ForLoop, parent: Node): Iterable { if(forLoop.body.isEmpty()) { - errors.warn("removing empty for loop", forLoop.position) + errors.info("removing empty for loop", forLoop.position) return listOf(IAstModification.Remove(forLoop, parent as IStatementContainer)) } else if(forLoop.body.statements.size==1) { val loopvar = forLoop.body.statements[0] as? VarDecl @@ -287,7 +287,7 @@ class StatementOptimizer(private val program: Program, val iter = repeatLoop.iterations if(iter!=null) { if(repeatLoop.body.isEmpty()) { - errors.warn("empty loop removed", repeatLoop.position) + errors.info("empty loop removed", repeatLoop.position) return listOf(IAstModification.Remove(repeatLoop, parent as IStatementContainer)) } val iterations = iter.constValue(program)?.number?.toInt() @@ -469,7 +469,7 @@ class StatementOptimizer(private val program: Program, fun replaceWithIf(condition: Expression, trueBlock: AnonymousScope, elseBlock: AnonymousScope?): List { val ifStmt = IfElse(condition, trueBlock, elseBlock ?: AnonymousScope(mutableListOf(), whenStmt.position), whenStmt.position) - errors.warn("for boolean condition a normal if statement is preferred", whenStmt.position) + errors.info("for boolean condition a normal if statement is preferred", whenStmt.position) return listOf(IAstModification.ReplaceNode(whenStmt, ifStmt, parent)) } diff --git a/codeOptimizers/src/prog8/optimizer/UnusedCodeRemover.kt b/codeOptimizers/src/prog8/optimizer/UnusedCodeRemover.kt index b3efd8b0e..c61f78790 100644 --- a/codeOptimizers/src/prog8/optimizer/UnusedCodeRemover.kt +++ b/codeOptimizers/src/prog8/optimizer/UnusedCodeRemover.kt @@ -60,14 +60,14 @@ class UnusedCodeRemover(private val program: Program, if (block.containsNoCodeNorVars) { if(block.name != internedStringsModuleName) { if(!block.statements.any { it is Subroutine && it.hasBeenInlined }) - errors.warn("removing unused block '${block.name}'", block.position) + errors.info("removing unused block '${block.name}'", block.position) } return listOf(IAstModification.Remove(block, parent as IStatementContainer)) } if(callgraph.unused(block)) { if(block.statements.any{ it !is VarDecl || it.type== VarDeclType.VAR}) { if(!block.statements.any { it is Subroutine && it.hasBeenInlined }) - errors.warn("removing unused block '${block.name}'", block.position) + errors.info("removing unused block '${block.name}'", block.position) } if(!block.statements.any { it is Subroutine && it.hasBeenInlined }) { program.removeInternedStringsFromRemovedBlock(block) @@ -85,7 +85,7 @@ class UnusedCodeRemover(private val program: Program, if(callgraph.unused(subroutine)) { if(subroutine.containsNoCodeNorVars) { if("ignore_unused" !in subroutine.definingBlock.options()) - errors.warn("removing empty subroutine '${subroutine.name}'", subroutine.position) + errors.info("removing empty subroutine '${subroutine.name}'", subroutine.position) val removals = mutableListOf(IAstModification.Remove(subroutine, parent as IStatementContainer)) callgraph.calledBy[subroutine]?.let { for(node in it) @@ -94,7 +94,7 @@ class UnusedCodeRemover(private val program: Program, return removals } if(!subroutine.hasBeenInlined && "ignore_unused" !in subroutine.definingBlock.options()) { - errors.warn("unused subroutine '${subroutine.name}'", subroutine.position) + errors.info("unused subroutine '${subroutine.name}'", subroutine.position) } if(!subroutine.inline) { program.removeInternedStringsFromRemovedSubroutine(subroutine) @@ -114,7 +114,7 @@ class UnusedCodeRemover(private val program: Program, val usages = callgraph.usages(decl) if (usages.isEmpty()) { if("ignore_unused" !in decl.definingBlock.options()) - errors.warn("removing unused variable '${decl.name}'", decl.position) + errors.info("removing unused variable '${decl.name}'", decl.position) return listOf(IAstModification.Remove(decl, parent as IStatementContainer)) } else { @@ -130,7 +130,7 @@ class UnusedCodeRemover(private val program: Program, if (singleAssignment!=null && reads.isNotEmpty()) { if (singleAssignment.origin == AssignmentOrigin.VARINIT && singleAssignment.value.constValue(program) != null) { // variable only has a single write and it is the initialization value, so it can be replaced with a constant, IF the value is a constant - errors.warn("variable is never written to and was replaced by a constant", decl.position) + errors.info("variable is never written to and was replaced by a constant", decl.position) val const = VarDecl(VarDeclType.CONST, decl.origin, decl.datatype, decl.zeropage, decl.arraysize, decl.name, decl.names, singleAssignment.value, decl.sharedWithAsm, decl.splitArray, decl.position) return listOf( IAstModification.ReplaceNode(decl, const, parent), @@ -156,7 +156,7 @@ class UnusedCodeRemover(private val program: Program, if(assignment.value.isSimple) { // remove the vardecl if("ignore_unused" !in decl.definingBlock.options()) - errors.warn("removing unused variable '${decl.name}'", decl.position) + errors.info("removing unused variable '${decl.name}'", decl.position) return listOf( IAstModification.Remove(decl, parent as IStatementContainer), IAstModification.Remove(assignment, assignment.parent as IStatementContainer) @@ -168,7 +168,7 @@ class UnusedCodeRemover(private val program: Program, val declIndex = (parent as IStatementContainer).statements.indexOf(decl) val singleUseIndex = (parent as IStatementContainer).statements.indexOf(singleUse.parent) if(declIndex==singleUseIndex-1) { - errors.warn("replaced unused variable '${decl.name}' with void call, maybe this can be removed altogether", decl.position) + errors.info("replaced unused variable '${decl.name}' with void call, maybe this can be removed altogether", decl.position) val fcall = assignment.value as IFunctionCall val voidCall = FunctionCallStatement(fcall.target, fcall.args, true, fcall.position) return listOf( @@ -178,7 +178,7 @@ class UnusedCodeRemover(private val program: Program, } } } else { - errors.warn("variable '${decl.name}' is unused but has non-trivial initialization assignment. Leaving this in but maybe it can be removed altogether", decl.position) + errors.info("variable '${decl.name}' is unused but has non-trivial initialization assignment. Leaving this in but maybe it can be removed altogether", decl.position) } } } diff --git a/compiler/src/prog8/buildversion/BuildVersion.kt b/compiler/src/prog8/buildversion/BuildVersion.kt index f1915a774..35b6f5724 100644 --- a/compiler/src/prog8/buildversion/BuildVersion.kt +++ b/compiler/src/prog8/buildversion/BuildVersion.kt @@ -6,10 +6,10 @@ package prog8.buildversion const val MAVEN_GROUP = "prog8" const val MAVEN_NAME = "compiler" const val VERSION = "9.8-SNAPSHOT" -const val GIT_REVISION = 4287 -const val GIT_SHA = "08a079a96e67c26298b81de2d35919be51a3dfd0" -const val GIT_DATE = "2023-12-11T20:15:48Z" -const val GIT_BRANCH = "no-vardecls" -const val BUILD_DATE = "2023-12-11T21:48:14Z" -const val BUILD_UNIX_TIME = 1702331294381L +const val GIT_REVISION = 4335 +const val GIT_SHA = "44d82f9190763aa5113a3dce4a7d4623018a1c25" +const val GIT_DATE = "2023-12-28T12:30:07Z" +const val GIT_BRANCH = "master" +const val BUILD_DATE = "2023-12-28T12:44:26Z" +const val BUILD_UNIX_TIME = 1703767466828L const val DIRTY = 1 diff --git a/compiler/src/prog8/compiler/ErrorReporter.kt b/compiler/src/prog8/compiler/ErrorReporter.kt index 0748f68a4..e0be2d7cc 100644 --- a/compiler/src/prog8/compiler/ErrorReporter.kt +++ b/compiler/src/prog8/compiler/ErrorReporter.kt @@ -6,6 +6,7 @@ import prog8.code.core.Position internal class ErrorReporter: IErrorReporter { private enum class MessageSeverity { + INFO, WARNING, ERROR } @@ -20,6 +21,9 @@ internal class ErrorReporter: IErrorReporter { override fun warn(msg: String, position: Position) { messages.add(CompilerMessage(MessageSeverity.WARNING, msg, position)) } + override fun info(msg: String, position: Position) { + messages.add(CompilerMessage(MessageSeverity.INFO, msg, position)) + } override fun undefined(symbol: List, position: Position) { err("undefined symbol: ${symbol.joinToString(".")}", position) @@ -28,29 +32,37 @@ internal class ErrorReporter: IErrorReporter { override fun report() { var numErrors = 0 var numWarnings = 0 + var numInfos = 0 messages.forEach { val printer = when(it.severity) { + MessageSeverity.INFO -> System.out MessageSeverity.WARNING -> System.out MessageSeverity.ERROR -> System.err } val msg = "${it.position.toClickableStr()} ${it.message}".trim() if(msg !in alreadyReportedMessages) { when(it.severity) { - MessageSeverity.ERROR -> printer.print("\u001b[91mERROR\u001B[0m ") // bright red - MessageSeverity.WARNING -> printer.print("\u001b[93mWARN\u001B[0m ") // bright yellow + MessageSeverity.ERROR -> { + printer.print("\u001b[91mERROR\u001B[0m ") // bright red + numErrors++ + } + MessageSeverity.WARNING -> { + printer.print("\u001b[93mWARN\u001B[0m ") // bright yellow + numWarnings++ + } + MessageSeverity.INFO -> { + printer.print("\u001b[92mINFO\u001B[0m ") // bright green + numInfos++ + } } printer.println(msg) alreadyReportedMessages.add(msg) - when(it.severity) { - MessageSeverity.WARNING -> numWarnings++ - MessageSeverity.ERROR -> numErrors++ - } } } System.out.flush() System.err.flush() messages.clear() - finalizeNumErrors(numErrors, numWarnings) + finalizeNumErrors(numErrors, numWarnings, numInfos) } override fun noErrors() = messages.none { it.severity==MessageSeverity.ERROR } diff --git a/compiler/src/prog8/compiler/astprocessing/AstChecker.kt b/compiler/src/prog8/compiler/astprocessing/AstChecker.kt index be0983c44..397b28837 100644 --- a/compiler/src/prog8/compiler/astprocessing/AstChecker.kt +++ b/compiler/src/prog8/compiler/astprocessing/AstChecker.kt @@ -122,7 +122,7 @@ internal class AstChecker(private val program: Program, if (expectedReturnValues[0] != valueDt.getOr(DataType.UNDEFINED)) { if(valueDt istype DataType.BOOL && expectedReturnValues[0] == DataType.UBYTE) { // if the return value is a bool and the return type is ubyte, allow this. But give a warning. - errors.warn("return type of the subroutine should probably be bool instead of ubyte", returnStmt.position) + errors.info("return type of the subroutine should probably be bool instead of ubyte", returnStmt.position) } else if(valueDt istype DataType.UBYTE && expectedReturnValues[0] == DataType.BOOL) { // if the return value is ubyte and the return type is bool, allow this only if value is 0 or 1 val returnValue = returnStmt.value as? NumericLiteral @@ -933,7 +933,7 @@ internal class AstChecker(private val program: Program, try { // just *try* if it can be encoded, don't actually do it val bytes = compilerOptions.compTarget.encodeString(string.value, string.encoding) if(0u in bytes) - errors.warn("a character in the string encodes as 0-byte, which will terminate the string prematurely", string.position) + errors.info("a character in the string encodes as 0-byte, which will terminate the string prematurely", string.position) } catch (cx: CharConversionException) { errors.err(cx.message ?: "can't encode string", string.position) } @@ -1187,14 +1187,14 @@ internal class AstChecker(private val program: Program, when(targetStatement) { is BuiltinFunctionPlaceholder -> { if(!builtinFunctionReturnType(targetStatement.name).isKnown) - errors.warn("redundant void", functionCallStatement.position) + errors.info("redundant void", functionCallStatement.position) } is Label -> { - errors.warn("redundant void", functionCallStatement.position) + errors.info("redundant void", functionCallStatement.position) } is Subroutine -> { if(targetStatement.returntypes.isEmpty()) - errors.warn("redundant void", functionCallStatement.position) + errors.info("redundant void", functionCallStatement.position) } else -> {} } @@ -1745,13 +1745,13 @@ internal fun checkUnusedReturnValues(call: FunctionCallStatement, target: Statem // check for unused return values if (target is Subroutine && target.returntypes.isNotEmpty()) { if (target.returntypes.size == 1) - errors.warn("result value of subroutine call is discarded (use void?)", call.position) + errors.info("result value of subroutine call is discarded (use void?)", call.position) else - errors.warn("result values of subroutine call are discarded (use void?)", call.position) + errors.info("result values of subroutine call are discarded (use void?)", call.position) } else if (target is BuiltinFunctionPlaceholder) { val rt = builtinFunctionReturnType(target.name) if (rt.isKnown) - errors.warn("result value of a function call is discarded (use void?)", call.position) + errors.info("result value of a function call is discarded (use void?)", call.position) } } } diff --git a/compiler/src/prog8/compiler/astprocessing/IntermediateAstMaker.kt b/compiler/src/prog8/compiler/astprocessing/IntermediateAstMaker.kt index 5990e91e4..b25dc2dcc 100644 --- a/compiler/src/prog8/compiler/astprocessing/IntermediateAstMaker.kt +++ b/compiler/src/prog8/compiler/astprocessing/IntermediateAstMaker.kt @@ -497,7 +497,7 @@ class IntermediateAstMaker(private val program: Program, private val errors: IEr if(value==null) { val blockOptions = srcVar.definingBlock.options() if("align_page" in blockOptions || "align_word" in blockOptions) { - errors.warn("converting uninitialized array to explicit zeros because of block alignment option", srcVar.position) + errors.info("converting uninitialized array to explicit zeros because of block alignment option", srcVar.position) val zeros = PtArray(srcVar.datatype, srcVar.position) repeat(srcVar.arraysize!!.constIndex()!!) { zeros.children.add(PtNumber(ArrayToElementTypes.getValue(srcVar.datatype), 0.0, srcVar.position)) diff --git a/compiler/src/prog8/compiler/astprocessing/VariousCleanups.kt b/compiler/src/prog8/compiler/astprocessing/VariousCleanups.kt index 81298e05c..03f62020f 100644 --- a/compiler/src/prog8/compiler/astprocessing/VariousCleanups.kt +++ b/compiler/src/prog8/compiler/astprocessing/VariousCleanups.kt @@ -174,7 +174,7 @@ internal class VariousCleanups(val program: Program, val errors: IErrorReporter, override fun after(containment: ContainmentCheck, parent: Node): Iterable { // replace trivial containment checks with just false or a single comparison fun replaceWithEquals(value: NumericLiteral): Iterable { - errors.warn("containment could be written as just a single comparison", containment.position) + errors.info("containment could be written as just a single comparison", containment.position) val equals = BinaryExpression(containment.element, "==", value, containment.position) return listOf(IAstModification.ReplaceNode(containment, equals, parent)) } @@ -258,7 +258,7 @@ internal class VariousCleanups(val program: Program, val errors: IErrorReporter, override fun after(branch: ConditionalBranch, parent: Node): Iterable { if(branch.truepart.isEmpty() && branch.elsepart.isEmpty()) { - errors.warn("removing empty conditional branch", branch.position) + errors.info("removing empty conditional branch", branch.position) return listOf(IAstModification.Remove(branch, parent as IStatementContainer)) } @@ -267,7 +267,7 @@ internal class VariousCleanups(val program: Program, val errors: IErrorReporter, override fun after(ifElse: IfElse, parent: Node): Iterable { if(ifElse.truepart.isEmpty() && ifElse.elsepart.isEmpty()) { - errors.warn("removing empty if-else statement", ifElse.position) + errors.info("removing empty if-else statement", ifElse.position) return listOf(IAstModification.Remove(ifElse, parent as IStatementContainer)) } return noModifications diff --git a/compiler/test/helpers/ErrorReporterForTests.kt b/compiler/test/helpers/ErrorReporterForTests.kt index e8d61f339..55f74c336 100644 --- a/compiler/test/helpers/ErrorReporterForTests.kt +++ b/compiler/test/helpers/ErrorReporterForTests.kt @@ -3,11 +3,11 @@ package prog8tests.helpers import prog8.code.core.IErrorReporter import prog8.code.core.Position -internal class ErrorReporterForTests(private val throwExceptionAtReportIfErrors: Boolean=true, private val keepMessagesAfterReporting: Boolean=false): - IErrorReporter { +internal class ErrorReporterForTests(private val throwExceptionAtReportIfErrors: Boolean=true, private val keepMessagesAfterReporting: Boolean=false): IErrorReporter { val errors = mutableListOf() val warnings = mutableListOf() + val infos = mutableListOf() override fun err(msg: String, position: Position) { val text = "${position.toClickableStr()} $msg" @@ -21,6 +21,12 @@ internal class ErrorReporterForTests(private val throwExceptionAtReportIfErrors: warnings.add(text) } + override fun info(msg: String, position: Position) { + val text = "${position.toClickableStr()} $msg" + if(text !in infos) + infos.add(text) + } + override fun undefined(symbol: List, position: Position) { err("undefined symbol: ${symbol.joinToString(".")}", position) } @@ -28,10 +34,11 @@ internal class ErrorReporterForTests(private val throwExceptionAtReportIfErrors: override fun noErrors(): Boolean = errors.isEmpty() override fun report() { + infos.forEach { println("UNITTEST COMPILATION REPORT: INFO: $it") } warnings.forEach { println("UNITTEST COMPILATION REPORT: WARNING: $it") } errors.forEach { println("UNITTEST COMPILATION REPORT: ERROR: $it") } if(throwExceptionAtReportIfErrors) - finalizeNumErrors(errors.size, warnings.size) + finalizeNumErrors(errors.size, warnings.size, infos.size) if(!keepMessagesAfterReporting) { clear() } @@ -40,5 +47,6 @@ internal class ErrorReporterForTests(private val throwExceptionAtReportIfErrors: fun clear() { errors.clear() warnings.clear() + infos.clear() } } diff --git a/docs/source/todo.rst b/docs/source/todo.rst index 350c27b69..d013d03eb 100644 --- a/docs/source/todo.rst +++ b/docs/source/todo.rst @@ -2,9 +2,6 @@ TODO ==== -- add INFO error level and move some warnings to info -- add switch to enable INFO error messages (default is WARN and up) - - [on branch: shortcircuit] investigate McCarthy evaluation again? this may also reduce code size perhaps for things like if a>4 or a<2 .... ...