17ee25bc5SStella Laurenzo# RUN: %PYTHON %s | FileCheck %s
27ee25bc5SStella Laurenzo
37ee25bc5SStella Laurenzoimport gc
47ee25bc5SStella Laurenzofrom mlir.ir import *
57ee25bc5SStella Laurenzo
67ee25bc5SStella Laurenzodef run(f):
77ee25bc5SStella Laurenzo  print("\nTEST:", f.__name__)
87ee25bc5SStella Laurenzo  f()
97ee25bc5SStella Laurenzo  gc.collect()
107ee25bc5SStella Laurenzo  assert Context._get_live_count() == 0
117ee25bc5SStella Laurenzo  return f
127ee25bc5SStella Laurenzo
137ee25bc5SStella Laurenzo
147ee25bc5SStella Laurenzo@run
157ee25bc5SStella Laurenzodef testLifecycleContextDestroy():
167ee25bc5SStella Laurenzo  ctx = Context()
177ee25bc5SStella Laurenzo  def callback(foo): ...
187ee25bc5SStella Laurenzo  handler = ctx.attach_diagnostic_handler(callback)
197ee25bc5SStella Laurenzo  assert handler.attached
207ee25bc5SStella Laurenzo  # If context is destroyed before the handler, it should auto-detach.
217ee25bc5SStella Laurenzo  ctx = None
227ee25bc5SStella Laurenzo  gc.collect()
237ee25bc5SStella Laurenzo  assert not handler.attached
247ee25bc5SStella Laurenzo
257ee25bc5SStella Laurenzo  # And finally collecting the handler should be fine.
267ee25bc5SStella Laurenzo  handler = None
277ee25bc5SStella Laurenzo  gc.collect()
287ee25bc5SStella Laurenzo
297ee25bc5SStella Laurenzo
307ee25bc5SStella Laurenzo@run
317ee25bc5SStella Laurenzodef testLifecycleExplicitDetach():
327ee25bc5SStella Laurenzo  ctx = Context()
337ee25bc5SStella Laurenzo  def callback(foo): ...
347ee25bc5SStella Laurenzo  handler = ctx.attach_diagnostic_handler(callback)
357ee25bc5SStella Laurenzo  assert handler.attached
367ee25bc5SStella Laurenzo  handler.detach()
377ee25bc5SStella Laurenzo  assert not handler.attached
387ee25bc5SStella Laurenzo
397ee25bc5SStella Laurenzo
407ee25bc5SStella Laurenzo@run
417ee25bc5SStella Laurenzodef testLifecycleWith():
427ee25bc5SStella Laurenzo  ctx = Context()
437ee25bc5SStella Laurenzo  def callback(foo): ...
447ee25bc5SStella Laurenzo  with ctx.attach_diagnostic_handler(callback) as handler:
457ee25bc5SStella Laurenzo    assert handler.attached
467ee25bc5SStella Laurenzo  assert not handler.attached
477ee25bc5SStella Laurenzo
487ee25bc5SStella Laurenzo
497ee25bc5SStella Laurenzo@run
507ee25bc5SStella Laurenzodef testLifecycleWithAndExplicitDetach():
517ee25bc5SStella Laurenzo  ctx = Context()
527ee25bc5SStella Laurenzo  def callback(foo): ...
537ee25bc5SStella Laurenzo  with ctx.attach_diagnostic_handler(callback) as handler:
547ee25bc5SStella Laurenzo    assert handler.attached
557ee25bc5SStella Laurenzo    handler.detach()
567ee25bc5SStella Laurenzo  assert not handler.attached
577ee25bc5SStella Laurenzo
587ee25bc5SStella Laurenzo
597ee25bc5SStella Laurenzo# CHECK-LABEL: TEST: testDiagnosticCallback
607ee25bc5SStella Laurenzo@run
617ee25bc5SStella Laurenzodef testDiagnosticCallback():
627ee25bc5SStella Laurenzo  ctx = Context()
637ee25bc5SStella Laurenzo  def callback(d):
647ee25bc5SStella Laurenzo    # CHECK: DIAGNOSTIC: message='foobar', severity=DiagnosticSeverity.ERROR, loc=loc(unknown)
657ee25bc5SStella Laurenzo    print(f"DIAGNOSTIC: message='{d.message}', severity={d.severity}, loc={d.location}")
667ee25bc5SStella Laurenzo    return True
677ee25bc5SStella Laurenzo  handler = ctx.attach_diagnostic_handler(callback)
687ee25bc5SStella Laurenzo  loc = Location.unknown(ctx)
697ee25bc5SStella Laurenzo  loc.emit_error("foobar")
707ee25bc5SStella Laurenzo  assert not handler.had_error
717ee25bc5SStella Laurenzo
727ee25bc5SStella Laurenzo
737ee25bc5SStella Laurenzo# CHECK-LABEL: TEST: testDiagnosticEmptyNotes
747ee25bc5SStella Laurenzo# TODO: Come up with a way to inject a diagnostic with notes from this API.
757ee25bc5SStella Laurenzo@run
767ee25bc5SStella Laurenzodef testDiagnosticEmptyNotes():
777ee25bc5SStella Laurenzo  ctx = Context()
787ee25bc5SStella Laurenzo  def callback(d):
797ee25bc5SStella Laurenzo    # CHECK: DIAGNOSTIC: notes=()
807ee25bc5SStella Laurenzo    print(f"DIAGNOSTIC: notes={d.notes}")
817ee25bc5SStella Laurenzo    return True
827ee25bc5SStella Laurenzo  handler = ctx.attach_diagnostic_handler(callback)
837ee25bc5SStella Laurenzo  loc = Location.unknown(ctx)
847ee25bc5SStella Laurenzo  loc.emit_error("foobar")
857ee25bc5SStella Laurenzo  assert not handler.had_error
867ee25bc5SStella Laurenzo
877ee25bc5SStella Laurenzo
88*65aedd33Srkayaith# CHECK-LABEL: TEST: testDiagnosticNonEmptyNotes
89*65aedd33Srkayaith@run
90*65aedd33Srkayaithdef testDiagnosticNonEmptyNotes():
91*65aedd33Srkayaith  ctx = Context()
92*65aedd33Srkayaith  def callback(d):
93*65aedd33Srkayaith    # CHECK: DIAGNOSTIC:
94*65aedd33Srkayaith    # CHECK:   message='arith.addi' op requires one result
95*65aedd33Srkayaith    # CHECK:   notes=['see current operation: "arith.addi"() : () -> ()']
96*65aedd33Srkayaith    print(f"DIAGNOSTIC:")
97*65aedd33Srkayaith    print(f"  message={d.message}")
98*65aedd33Srkayaith    print(f"  notes={list(map(str, d.notes))}")
99*65aedd33Srkayaith    return True
100*65aedd33Srkayaith  handler = ctx.attach_diagnostic_handler(callback)
101*65aedd33Srkayaith  loc = Location.unknown(ctx)
102*65aedd33Srkayaith  Operation.create('arith.addi', loc=loc).verify()
103*65aedd33Srkayaith  assert not handler.had_error
104*65aedd33Srkayaith
1057ee25bc5SStella Laurenzo# CHECK-LABEL: TEST: testDiagnosticCallbackException
1067ee25bc5SStella Laurenzo@run
1077ee25bc5SStella Laurenzodef testDiagnosticCallbackException():
1087ee25bc5SStella Laurenzo  ctx = Context()
1097ee25bc5SStella Laurenzo  def callback(d):
1107ee25bc5SStella Laurenzo    raise ValueError("Error in handler")
1117ee25bc5SStella Laurenzo  handler = ctx.attach_diagnostic_handler(callback)
1127ee25bc5SStella Laurenzo  loc = Location.unknown(ctx)
1137ee25bc5SStella Laurenzo  loc.emit_error("foobar")
1147ee25bc5SStella Laurenzo  assert handler.had_error
1157ee25bc5SStella Laurenzo
1167ee25bc5SStella Laurenzo
1177ee25bc5SStella Laurenzo# CHECK-LABEL: TEST: testEscapingDiagnostic
1187ee25bc5SStella Laurenzo@run
1197ee25bc5SStella Laurenzodef testEscapingDiagnostic():
1207ee25bc5SStella Laurenzo  ctx = Context()
1217ee25bc5SStella Laurenzo  diags = []
1227ee25bc5SStella Laurenzo  def callback(d):
1237ee25bc5SStella Laurenzo    diags.append(d)
1247ee25bc5SStella Laurenzo    return True
1257ee25bc5SStella Laurenzo  handler = ctx.attach_diagnostic_handler(callback)
1267ee25bc5SStella Laurenzo  loc = Location.unknown(ctx)
1277ee25bc5SStella Laurenzo  loc.emit_error("foobar")
1287ee25bc5SStella Laurenzo  assert not handler.had_error
1297ee25bc5SStella Laurenzo
1307ee25bc5SStella Laurenzo  # CHECK: DIAGNOSTIC: <Invalid Diagnostic>
1317ee25bc5SStella Laurenzo  print(f"DIAGNOSTIC: {str(diags[0])}")
1327ee25bc5SStella Laurenzo  try:
1337ee25bc5SStella Laurenzo    diags[0].severity
1347ee25bc5SStella Laurenzo    raise RuntimeError("expected exception")
1357ee25bc5SStella Laurenzo  except ValueError:
1367ee25bc5SStella Laurenzo    pass
1377ee25bc5SStella Laurenzo  try:
1387ee25bc5SStella Laurenzo    diags[0].location
1397ee25bc5SStella Laurenzo    raise RuntimeError("expected exception")
1407ee25bc5SStella Laurenzo  except ValueError:
1417ee25bc5SStella Laurenzo    pass
1427ee25bc5SStella Laurenzo  try:
1437ee25bc5SStella Laurenzo    diags[0].message
1447ee25bc5SStella Laurenzo    raise RuntimeError("expected exception")
1457ee25bc5SStella Laurenzo  except ValueError:
1467ee25bc5SStella Laurenzo    pass
1477ee25bc5SStella Laurenzo  try:
1487ee25bc5SStella Laurenzo    diags[0].notes
1497ee25bc5SStella Laurenzo    raise RuntimeError("expected exception")
1507ee25bc5SStella Laurenzo  except ValueError:
1517ee25bc5SStella Laurenzo    pass
1527ee25bc5SStella Laurenzo
1537ee25bc5SStella Laurenzo
1547ee25bc5SStella Laurenzo
1557ee25bc5SStella Laurenzo# CHECK-LABEL: TEST: testDiagnosticReturnTrueHandles
1567ee25bc5SStella Laurenzo@run
1577ee25bc5SStella Laurenzodef testDiagnosticReturnTrueHandles():
1587ee25bc5SStella Laurenzo  ctx = Context()
1597ee25bc5SStella Laurenzo  def callback1(d):
1607ee25bc5SStella Laurenzo    print(f"CALLBACK1: {d}")
1617ee25bc5SStella Laurenzo    return True
1627ee25bc5SStella Laurenzo  def callback2(d):
1637ee25bc5SStella Laurenzo    print(f"CALLBACK2: {d}")
1647ee25bc5SStella Laurenzo    return True
1657ee25bc5SStella Laurenzo  ctx.attach_diagnostic_handler(callback1)
1667ee25bc5SStella Laurenzo  ctx.attach_diagnostic_handler(callback2)
1677ee25bc5SStella Laurenzo  loc = Location.unknown(ctx)
1687ee25bc5SStella Laurenzo  # CHECK-NOT: CALLBACK1
1697ee25bc5SStella Laurenzo  # CHECK: CALLBACK2: foobar
1707ee25bc5SStella Laurenzo  # CHECK-NOT: CALLBACK1
1717ee25bc5SStella Laurenzo  loc.emit_error("foobar")
1727ee25bc5SStella Laurenzo
1737ee25bc5SStella Laurenzo
1747ee25bc5SStella Laurenzo# CHECK-LABEL: TEST: testDiagnosticReturnFalseDoesNotHandle
1757ee25bc5SStella Laurenzo@run
1767ee25bc5SStella Laurenzodef testDiagnosticReturnFalseDoesNotHandle():
1777ee25bc5SStella Laurenzo  ctx = Context()
1787ee25bc5SStella Laurenzo  def callback1(d):
1797ee25bc5SStella Laurenzo    print(f"CALLBACK1: {d}")
1807ee25bc5SStella Laurenzo    return True
1817ee25bc5SStella Laurenzo  def callback2(d):
1827ee25bc5SStella Laurenzo    print(f"CALLBACK2: {d}")
1837ee25bc5SStella Laurenzo    return False
1847ee25bc5SStella Laurenzo  ctx.attach_diagnostic_handler(callback1)
1857ee25bc5SStella Laurenzo  ctx.attach_diagnostic_handler(callback2)
1867ee25bc5SStella Laurenzo  loc = Location.unknown(ctx)
1877ee25bc5SStella Laurenzo  # CHECK: CALLBACK2: foobar
1887ee25bc5SStella Laurenzo  # CHECK: CALLBACK1: foobar
1897ee25bc5SStella Laurenzo  loc.emit_error("foobar")
190