Skip to content

Commit a957904

Browse files
authored
Fix diagnostic module (#12906)
1 parent 71fdfc2 commit a957904

3 files changed

Lines changed: 56 additions & 1 deletion

File tree

src/context/display/displayFields.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -447,7 +447,7 @@ let handle_missing_field_raise ctx tthis i mode with_type pfield =
447447
mf_cause = FieldAccess;
448448
} in
449449
let cm = DiagnosticsPrinter.make_missing_fields_message diag in
450-
CompilerMessage.add_module_diagnostic ctx.com (t_infos mt).mt_module cm
450+
CompilerMessage.add_module_diagnostic ctx.com ctx.m.curmod cm
451451

452452
let handle_missing_ident ctx i mode with_type p =
453453
match ctx.e.curfun with
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package cases.issues;
2+
3+
import haxe.display.Diagnostic;
4+
5+
// Regression test for https://github.com/HaxeFoundation/haxe/issues/12861
6+
// Stale diagnostics must be cleared after the underlying problem is fixed.
7+
class Issue12861 extends TestCase {
8+
function test(_) {
9+
// File with a type error: Int has no field charAt
10+
final errContent = getTemplate("diagnostics/Issue12861.hx");
11+
// Fixed version: use String instead of Int
12+
final okContent = "class Issue12861 { static function main() { var v:String = ''; var _ = v.charAt(0); } }";
13+
14+
final args = ["--main", "Issue12861", "--interp", "--no-output"];
15+
16+
// --- First diagnostics run: file has the type error ---
17+
vfs.putContent("Issue12861.hx", errContent);
18+
final res1 = runHaxeJson(args, DisplayMethods.Diagnostics, {file: new FsPath("Issue12861.hx")});
19+
Assert.equals(1, res1.length);
20+
final diags1:Array<Diagnostic<Dynamic>> = cast res1[0].diagnostics;
21+
// Exactly one MissingFields diagnostic expected (Int has no field charAt)
22+
Assert.equals(1, diags1.length);
23+
Assert.isTrue(diags1.exists(d -> d.kind == MissingFields));
24+
25+
// --- Second diagnostics run on the SAME erroneous file (after invalidation) ---
26+
// Without the fix, add_module_diagnostic polluted Int's cached
27+
// m_cache_bound_objects on the first run. The second run would then
28+
// replay that stale message AND add another one, producing 2 entries.
29+
runHaxeJson([], ServerMethods.Invalidate, {file: new FsPath("Issue12861.hx")});
30+
final res2 = runHaxeJson(args, DisplayMethods.Diagnostics, {file: new FsPath("Issue12861.hx")});
31+
Assert.equals(1, res2.length);
32+
final diags2:Array<Diagnostic<Dynamic>> = cast res2[0].diagnostics;
33+
// Must still be exactly 1, not 2 or more (no stacking)
34+
Assert.equals(1, diags2.length);
35+
Assert.isTrue(diags2.exists(d -> d.kind == MissingFields));
36+
37+
// --- Third diagnostics run: fix the file ---
38+
// The old error must not persist; the result must be clean.
39+
vfs.putContent("Issue12861.hx", okContent);
40+
runHaxeJson([], ServerMethods.Invalidate, {file: new FsPath("Issue12861.hx")});
41+
final res3 = runHaxeJson(args, DisplayMethods.Diagnostics, {file: new FsPath("Issue12861.hx")});
42+
// Without the fix, the stale DKMissingFields from Int's cache was
43+
// replayed here, making res3 still show an error.
44+
if (res3.length > 0) {
45+
final diags3:Array<Diagnostic<Dynamic>> = cast res3[0].diagnostics;
46+
Assert.isFalse(diags3.exists(d -> d.kind == MissingFields));
47+
}
48+
}
49+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
class Issue12861 {
2+
static function main() {
3+
var v:Int = 0;
4+
var _ = v.charAt(0); // Int has no field charAt
5+
}
6+
}

0 commit comments

Comments
 (0)