xref: /llvm-project/mlir/test/python/ir/diagnostic_handler.py (revision 8934b10642664c0824f45f115b2a0afcb56a5e5f)
17ee25bc5SStella Laurenzo# RUN: %PYTHON %s | FileCheck %s
27ee25bc5SStella Laurenzo
37ee25bc5SStella Laurenzoimport gc
47ee25bc5SStella Laurenzofrom mlir.ir import *
57ee25bc5SStella Laurenzo
6f9008e63STobias Hieta
77ee25bc5SStella Laurenzodef run(f):
87ee25bc5SStella Laurenzo    print("\nTEST:", f.__name__)
97ee25bc5SStella Laurenzo    f()
107ee25bc5SStella Laurenzo    gc.collect()
117ee25bc5SStella Laurenzo    assert Context._get_live_count() == 0
127ee25bc5SStella Laurenzo    return f
137ee25bc5SStella Laurenzo
147ee25bc5SStella Laurenzo
157ee25bc5SStella Laurenzo@run
167ee25bc5SStella Laurenzodef testLifecycleContextDestroy():
177ee25bc5SStella Laurenzo    ctx = Context()
18f9008e63STobias Hieta
19f9008e63STobias Hieta    def callback(foo):
20f9008e63STobias Hieta        ...
21f9008e63STobias Hieta
227ee25bc5SStella Laurenzo    handler = ctx.attach_diagnostic_handler(callback)
237ee25bc5SStella Laurenzo    assert handler.attached
247ee25bc5SStella Laurenzo    # If context is destroyed before the handler, it should auto-detach.
257ee25bc5SStella Laurenzo    ctx = None
267ee25bc5SStella Laurenzo    gc.collect()
277ee25bc5SStella Laurenzo    assert not handler.attached
287ee25bc5SStella Laurenzo
297ee25bc5SStella Laurenzo    # And finally collecting the handler should be fine.
307ee25bc5SStella Laurenzo    handler = None
317ee25bc5SStella Laurenzo    gc.collect()
327ee25bc5SStella Laurenzo
337ee25bc5SStella Laurenzo
347ee25bc5SStella Laurenzo@run
357ee25bc5SStella Laurenzodef testLifecycleExplicitDetach():
367ee25bc5SStella Laurenzo    ctx = Context()
37f9008e63STobias Hieta
38f9008e63STobias Hieta    def callback(foo):
39f9008e63STobias Hieta        ...
40f9008e63STobias Hieta
417ee25bc5SStella Laurenzo    handler = ctx.attach_diagnostic_handler(callback)
427ee25bc5SStella Laurenzo    assert handler.attached
437ee25bc5SStella Laurenzo    handler.detach()
447ee25bc5SStella Laurenzo    assert not handler.attached
457ee25bc5SStella Laurenzo
467ee25bc5SStella Laurenzo
477ee25bc5SStella Laurenzo@run
487ee25bc5SStella Laurenzodef testLifecycleWith():
497ee25bc5SStella Laurenzo    ctx = Context()
50f9008e63STobias Hieta
51f9008e63STobias Hieta    def callback(foo):
52f9008e63STobias Hieta        ...
53f9008e63STobias Hieta
547ee25bc5SStella Laurenzo    with ctx.attach_diagnostic_handler(callback) as handler:
557ee25bc5SStella Laurenzo        assert handler.attached
567ee25bc5SStella Laurenzo    assert not handler.attached
577ee25bc5SStella Laurenzo
587ee25bc5SStella Laurenzo
597ee25bc5SStella Laurenzo@run
607ee25bc5SStella Laurenzodef testLifecycleWithAndExplicitDetach():
617ee25bc5SStella Laurenzo    ctx = Context()
62f9008e63STobias Hieta
63f9008e63STobias Hieta    def callback(foo):
64f9008e63STobias Hieta        ...
65f9008e63STobias Hieta
667ee25bc5SStella Laurenzo    with ctx.attach_diagnostic_handler(callback) as handler:
677ee25bc5SStella Laurenzo        assert handler.attached
687ee25bc5SStella Laurenzo        handler.detach()
697ee25bc5SStella Laurenzo    assert not handler.attached
707ee25bc5SStella Laurenzo
717ee25bc5SStella Laurenzo
727ee25bc5SStella Laurenzo# CHECK-LABEL: TEST: testDiagnosticCallback
737ee25bc5SStella Laurenzo@run
747ee25bc5SStella Laurenzodef testDiagnosticCallback():
757ee25bc5SStella Laurenzo    ctx = Context()
76f9008e63STobias Hieta
777ee25bc5SStella Laurenzo    def callback(d):
787ee25bc5SStella Laurenzo        # CHECK: DIAGNOSTIC: message='foobar', severity=DiagnosticSeverity.ERROR, loc=loc(unknown)
79f9008e63STobias Hieta        print(
80f9008e63STobias Hieta            f"DIAGNOSTIC: message='{d.message}', severity={d.severity}, loc={d.location}"
81f9008e63STobias Hieta        )
827ee25bc5SStella Laurenzo        return True
83f9008e63STobias Hieta
847ee25bc5SStella Laurenzo    handler = ctx.attach_diagnostic_handler(callback)
857ee25bc5SStella Laurenzo    loc = Location.unknown(ctx)
867ee25bc5SStella Laurenzo    loc.emit_error("foobar")
877ee25bc5SStella Laurenzo    assert not handler.had_error
887ee25bc5SStella Laurenzo
897ee25bc5SStella Laurenzo
907ee25bc5SStella Laurenzo# CHECK-LABEL: TEST: testDiagnosticEmptyNotes
917ee25bc5SStella Laurenzo# TODO: Come up with a way to inject a diagnostic with notes from this API.
927ee25bc5SStella Laurenzo@run
937ee25bc5SStella Laurenzodef testDiagnosticEmptyNotes():
947ee25bc5SStella Laurenzo    ctx = Context()
95f9008e63STobias Hieta
967ee25bc5SStella Laurenzo    def callback(d):
977ee25bc5SStella Laurenzo        # CHECK: DIAGNOSTIC: notes=()
987ee25bc5SStella Laurenzo        print(f"DIAGNOSTIC: notes={d.notes}")
997ee25bc5SStella Laurenzo        return True
100f9008e63STobias Hieta
1017ee25bc5SStella Laurenzo    handler = ctx.attach_diagnostic_handler(callback)
1027ee25bc5SStella Laurenzo    loc = Location.unknown(ctx)
1037ee25bc5SStella Laurenzo    loc.emit_error("foobar")
1047ee25bc5SStella Laurenzo    assert not handler.had_error
1057ee25bc5SStella Laurenzo
1067ee25bc5SStella Laurenzo
10765aedd33Srkayaith# CHECK-LABEL: TEST: testDiagnosticNonEmptyNotes
10865aedd33Srkayaith@run
10965aedd33Srkayaithdef testDiagnosticNonEmptyNotes():
11065aedd33Srkayaith    ctx = Context()
1113ea4c501SRahul Kayaith    ctx.emit_error_diagnostics = True
112f9008e63STobias Hieta
11365aedd33Srkayaith    def callback(d):
11465aedd33Srkayaith        # CHECK: DIAGNOSTIC:
11565aedd33Srkayaith        # CHECK:   message='arith.addi' op requires one result
116*8934b106SJacques Pienaar        # CHECK:   notes=['see current operation: "arith.addi"() {{.*}} : () -> ()']
11765aedd33Srkayaith        print(f"DIAGNOSTIC:")
11865aedd33Srkayaith        print(f"  message={d.message}")
11965aedd33Srkayaith        print(f"  notes={list(map(str, d.notes))}")
12065aedd33Srkayaith        return True
121f9008e63STobias Hieta
12265aedd33Srkayaith    handler = ctx.attach_diagnostic_handler(callback)
12365aedd33Srkayaith    loc = Location.unknown(ctx)
1243ea4c501SRahul Kayaith    try:
125f9008e63STobias Hieta        Operation.create("arith.addi", loc=loc).verify()
1263ea4c501SRahul Kayaith    except MLIRError:
1273ea4c501SRahul Kayaith        pass
12865aedd33Srkayaith    assert not handler.had_error
12965aedd33Srkayaith
130f9008e63STobias Hieta
1317ee25bc5SStella Laurenzo# CHECK-LABEL: TEST: testDiagnosticCallbackException
1327ee25bc5SStella Laurenzo@run
1337ee25bc5SStella Laurenzodef testDiagnosticCallbackException():
1347ee25bc5SStella Laurenzo    ctx = Context()
135f9008e63STobias Hieta
1367ee25bc5SStella Laurenzo    def callback(d):
1377ee25bc5SStella Laurenzo        raise ValueError("Error in handler")
138f9008e63STobias Hieta
1397ee25bc5SStella Laurenzo    handler = ctx.attach_diagnostic_handler(callback)
1407ee25bc5SStella Laurenzo    loc = Location.unknown(ctx)
1417ee25bc5SStella Laurenzo    loc.emit_error("foobar")
1427ee25bc5SStella Laurenzo    assert handler.had_error
1437ee25bc5SStella Laurenzo
1447ee25bc5SStella Laurenzo
1457ee25bc5SStella Laurenzo# CHECK-LABEL: TEST: testEscapingDiagnostic
1467ee25bc5SStella Laurenzo@run
1477ee25bc5SStella Laurenzodef testEscapingDiagnostic():
1487ee25bc5SStella Laurenzo    ctx = Context()
1497ee25bc5SStella Laurenzo    diags = []
150f9008e63STobias Hieta
1517ee25bc5SStella Laurenzo    def callback(d):
1527ee25bc5SStella Laurenzo        diags.append(d)
1537ee25bc5SStella Laurenzo        return True
154f9008e63STobias Hieta
1557ee25bc5SStella Laurenzo    handler = ctx.attach_diagnostic_handler(callback)
1567ee25bc5SStella Laurenzo    loc = Location.unknown(ctx)
1577ee25bc5SStella Laurenzo    loc.emit_error("foobar")
1587ee25bc5SStella Laurenzo    assert not handler.had_error
1597ee25bc5SStella Laurenzo
1607ee25bc5SStella Laurenzo    # CHECK: DIAGNOSTIC: <Invalid Diagnostic>
1617ee25bc5SStella Laurenzo    print(f"DIAGNOSTIC: {str(diags[0])}")
1627ee25bc5SStella Laurenzo    try:
1637ee25bc5SStella Laurenzo        diags[0].severity
1647ee25bc5SStella Laurenzo        raise RuntimeError("expected exception")
1657ee25bc5SStella Laurenzo    except ValueError:
1667ee25bc5SStella Laurenzo        pass
1677ee25bc5SStella Laurenzo    try:
1687ee25bc5SStella Laurenzo        diags[0].location
1697ee25bc5SStella Laurenzo        raise RuntimeError("expected exception")
1707ee25bc5SStella Laurenzo    except ValueError:
1717ee25bc5SStella Laurenzo        pass
1727ee25bc5SStella Laurenzo    try:
1737ee25bc5SStella Laurenzo        diags[0].message
1747ee25bc5SStella Laurenzo        raise RuntimeError("expected exception")
1757ee25bc5SStella Laurenzo    except ValueError:
1767ee25bc5SStella Laurenzo        pass
1777ee25bc5SStella Laurenzo    try:
1787ee25bc5SStella Laurenzo        diags[0].notes
1797ee25bc5SStella Laurenzo        raise RuntimeError("expected exception")
1807ee25bc5SStella Laurenzo    except ValueError:
1817ee25bc5SStella Laurenzo        pass
1827ee25bc5SStella Laurenzo
1837ee25bc5SStella Laurenzo
1847ee25bc5SStella Laurenzo# CHECK-LABEL: TEST: testDiagnosticReturnTrueHandles
1857ee25bc5SStella Laurenzo@run
1867ee25bc5SStella Laurenzodef testDiagnosticReturnTrueHandles():
1877ee25bc5SStella Laurenzo    ctx = Context()
188f9008e63STobias Hieta
1897ee25bc5SStella Laurenzo    def callback1(d):
1907ee25bc5SStella Laurenzo        print(f"CALLBACK1: {d}")
1917ee25bc5SStella Laurenzo        return True
192f9008e63STobias Hieta
1937ee25bc5SStella Laurenzo    def callback2(d):
1947ee25bc5SStella Laurenzo        print(f"CALLBACK2: {d}")
1957ee25bc5SStella Laurenzo        return True
196f9008e63STobias Hieta
1977ee25bc5SStella Laurenzo    ctx.attach_diagnostic_handler(callback1)
1987ee25bc5SStella Laurenzo    ctx.attach_diagnostic_handler(callback2)
1997ee25bc5SStella Laurenzo    loc = Location.unknown(ctx)
2007ee25bc5SStella Laurenzo    # CHECK-NOT: CALLBACK1
2017ee25bc5SStella Laurenzo    # CHECK: CALLBACK2: foobar
2027ee25bc5SStella Laurenzo    # CHECK-NOT: CALLBACK1
2037ee25bc5SStella Laurenzo    loc.emit_error("foobar")
2047ee25bc5SStella Laurenzo
2057ee25bc5SStella Laurenzo
2067ee25bc5SStella Laurenzo# CHECK-LABEL: TEST: testDiagnosticReturnFalseDoesNotHandle
2077ee25bc5SStella Laurenzo@run
2087ee25bc5SStella Laurenzodef testDiagnosticReturnFalseDoesNotHandle():
2097ee25bc5SStella Laurenzo    ctx = Context()
210f9008e63STobias Hieta
2117ee25bc5SStella Laurenzo    def callback1(d):
2127ee25bc5SStella Laurenzo        print(f"CALLBACK1: {d}")
2137ee25bc5SStella Laurenzo        return True
214f9008e63STobias Hieta
2157ee25bc5SStella Laurenzo    def callback2(d):
2167ee25bc5SStella Laurenzo        print(f"CALLBACK2: {d}")
2177ee25bc5SStella Laurenzo        return False
218f9008e63STobias Hieta
2197ee25bc5SStella Laurenzo    ctx.attach_diagnostic_handler(callback1)
2207ee25bc5SStella Laurenzo    ctx.attach_diagnostic_handler(callback2)
2217ee25bc5SStella Laurenzo    loc = Location.unknown(ctx)
2227ee25bc5SStella Laurenzo    # CHECK: CALLBACK2: foobar
2237ee25bc5SStella Laurenzo    # CHECK: CALLBACK1: foobar
2247ee25bc5SStella Laurenzo    loc.emit_error("foobar")
225