diff --git a/de.peeeq.wurstscript/src/main/java/de/peeeq/wurstscript/validation/WurstValidator.java b/de.peeeq.wurstscript/src/main/java/de/peeeq/wurstscript/validation/WurstValidator.java index 170578a37..da9a5b204 100644 --- a/de.peeeq.wurstscript/src/main/java/de/peeeq/wurstscript/validation/WurstValidator.java +++ b/de.peeeq.wurstscript/src/main/java/de/peeeq/wurstscript/validation/WurstValidator.java @@ -1850,8 +1850,7 @@ private void visit(ModuleDef moduleDef) { private void visit(ExprDestroy stmtDestroy) { if (stmtDestroy.getDestroyedObj() instanceof ExprThis) { if (isInConstructor(stmtDestroy)) { - stmtDestroy.addError("Cannot destroy 'this' in constructor"); - return; + stmtDestroy.addWarning("Should not destroy 'this' in constructor, because 'new' would return an invalid object.\nMove destruction logic into a separate function outside the constructor.\nThis will be an error in the future."); } } diff --git a/de.peeeq.wurstscript/src/test/java/tests/wurstscript/tests/BugTests.java b/de.peeeq.wurstscript/src/test/java/tests/wurstscript/tests/BugTests.java index f7ad3f19c..59b8a35d9 100644 --- a/de.peeeq.wurstscript/src/test/java/tests/wurstscript/tests/BugTests.java +++ b/de.peeeq.wurstscript/src/test/java/tests/wurstscript/tests/BugTests.java @@ -1462,7 +1462,7 @@ public void duplicateNameInClassHierachy() { @Test public void callingDestroyThisInConstructor() { - testAssertErrorsLines(false, "Cannot destroy 'this' in constructor", + testAssertWarningsLines(false, "Should not destroy 'this' in constructor", "package test", "native testSuccess()", "class A", diff --git a/de.peeeq.wurstscript/src/test/java/tests/wurstscript/tests/WurstScriptTest.java b/de.peeeq.wurstscript/src/test/java/tests/wurstscript/tests/WurstScriptTest.java index 2647f59b6..9fa4cf11b 100644 --- a/de.peeeq.wurstscript/src/test/java/tests/wurstscript/tests/WurstScriptTest.java +++ b/de.peeeq.wurstscript/src/test/java/tests/wurstscript/tests/WurstScriptTest.java @@ -63,6 +63,8 @@ class TestConfig { private boolean executeTests; private boolean executeProgOnlyAfterTransforms; private String expectedError; + private String expectedWarning; + private final List inputFiles = new ArrayList<>(); private final List additionalCompilationUnits = new ArrayList<>(); private boolean stopOnFirstError = true; @@ -106,6 +108,11 @@ TestConfig executeProg(boolean b) { return this; } + TestConfig expectWarning(String expectedWarning) { + this.expectedWarning = expectedWarning; + return this; + } + public TestConfig executeProgOnlyAfterTransforms() { this.executeProgOnlyAfterTransforms = true; return this; @@ -149,6 +156,18 @@ CompilationResult run() { } } } + if (expectedWarning != null) { + List warnings = res.getGui().getWarningList(); + if (warnings.isEmpty()) { + fail("No warnings were discovered"); + } else if (warnings.stream() + .noneMatch(w -> w.getMessage().toLowerCase().contains(expectedWarning.toLowerCase()))) { + for (CompileError w : warnings) { + System.err.println("Unexpected warning:" + w); + } + throw new RuntimeException("Unexpected warning", warnings.get(0)); + } + } return res; } catch (CompileError e) { if (expectedError != null) { @@ -355,6 +374,23 @@ void testAssertErrors(String name, boolean executeProg, String prog, String erro test().executeProg(executeProg).expectError(errorMessage).lines(prog); } + public void testAssertWarningsLines(boolean executeProg, String warningMessage, String... input) { + test() + .setStopOnFirstError(false) + .executeProg(executeProg) + .expectWarning(warningMessage) + .lines(input); + } + + public void testAssertWarningsLinesWithStdLib(boolean executeProg, String warningMessage, String... input) { + test() + .withStdLib() + .setStopOnFirstError(false) + .executeProg(executeProg) + .expectWarning(warningMessage) + .lines(input); + } + protected WurstModel testScript(String name, boolean executeProg, String prog) { return test().executeProg(executeProg).lines(prog).getModel(); }