diff --git a/compiler/src/prog8/compiler/ErrorReporter.kt b/compiler/src/prog8/compiler/ErrorReporter.kt index be80a48e5..4ac48b1a1 100644 --- a/compiler/src/prog8/compiler/ErrorReporter.kt +++ b/compiler/src/prog8/compiler/ErrorReporter.kt @@ -33,7 +33,7 @@ internal class ErrorReporter: IErrorReporter { 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.WARNING -> printer.print("\u001b[93mWARN\u001B[0m ") // bright yellow } printer.println(msg) alreadyReportedMessages.add(msg) diff --git a/compiler/src/prog8/compiler/astprocessing/AstIdentifiersChecker.kt b/compiler/src/prog8/compiler/astprocessing/AstIdentifiersChecker.kt index c1379810e..96aab69a9 100644 --- a/compiler/src/prog8/compiler/astprocessing/AstIdentifiersChecker.kt +++ b/compiler/src/prog8/compiler/astprocessing/AstIdentifiersChecker.kt @@ -88,9 +88,9 @@ internal class AstIdentifiersChecker(private val errors: IErrorReporter, val existing = subroutine.lookup(listOf(subroutine.name)) if (existing != null && existing !== subroutine) { if(existing.parent!==existing.parent) - nameShadowWarning(subroutine.name, subroutine.position, existing) + nameShadowWarning(subroutine.name, existing.position, subroutine) else - nameError(subroutine.name, subroutine.position, existing) + nameError(subroutine.name, existing.position, subroutine) } // check that there are no local symbols (variables, labels, subs) that redefine the subroutine's parameters. diff --git a/compiler/test/TestScoping.kt b/compiler/test/TestScoping.kt index 2ffc66447..e38b61f51 100644 --- a/compiler/test/TestScoping.kt +++ b/compiler/test/TestScoping.kt @@ -384,4 +384,56 @@ class TestScoping: FunSpec({ errors.errors[0] shouldContain "wrong address" errors.errors[1] shouldContain "takes parameters" } + + test("name shadowing and redefinition errors") { + val text = """ + main { + ubyte var1Warn + + sub start() { + ubyte var1Warn + ubyte var1Warn + ubyte main + ubyte start + ubyte outer ; is ok + ubyte internalOk + ubyte internalOk ; double defined + } + + sub outer() { + ubyte var1Warn + ubyte internalOk + } + } + """ + val errors = ErrorReporterForTests() + compileText(C64Target(), false, text, writeAssembly = false, errors = errors) shouldBe null + println(errors.errors) + errors.warnings.size shouldBe 3 + errors.warnings[0] shouldContain "var1Warn" + errors.warnings[0] shouldContain "shadows" + errors.warnings[0] shouldContain "line 3" + errors.warnings[1] shouldContain "var1Warn" + errors.warnings[1] shouldContain "shadows" + errors.warnings[1] shouldContain "line 3" + errors.warnings[2] shouldContain "var1Warn" + errors.warnings[2] shouldContain "shadows" + errors.warnings[2] shouldContain "line 3" + errors.errors.size shouldBe 5 + errors.errors[0] shouldContain "name conflict" + errors.errors[0] shouldContain "start" + errors.errors[0] shouldContain "line 5" + errors.errors[1] shouldContain "name conflict" + errors.errors[1] shouldContain "var1Warn" + errors.errors[1] shouldContain "line 6" + errors.errors[2] shouldContain "name conflict" + errors.errors[2] shouldContain "main" + errors.errors[2] shouldContain "line 2" + errors.errors[3] shouldContain "name conflict" + errors.errors[3] shouldContain "start" + errors.errors[3] shouldContain "line 5" + errors.errors[4] shouldContain "name conflict" + errors.errors[4] shouldContain "internalOk" + errors.errors[4] shouldContain "line 11" + } }) diff --git a/docs/source/todo.rst b/docs/source/todo.rst index 99891de3f..591c78f19 100644 --- a/docs/source/todo.rst +++ b/docs/source/todo.rst @@ -3,7 +3,6 @@ TODO For next release ^^^^^^^^^^^^^^^^ -- add unit test for name error and name shadowing warning. - optimize pointervar indexing codegen: writing (all sorts of things) - pipe operator: (targets other than 'Virtual'): allow non-unary function calls in the pipe that specify the other argument(s) in the calls. Already working for VM target. - add McCarthy evaluation to shortcircuit and/or expressions. First do ifs by splitting them up? Then do expressions that compute a value?