|
10 | 10 | import liquidjava.diagnostics.errors.InvalidRefinementError; |
11 | 11 | import liquidjava.diagnostics.errors.LJError; |
12 | 12 | import liquidjava.diagnostics.errors.SMTUnknownError; |
| 13 | +import liquidjava.diagnostics.errors.StateErrorContext; |
13 | 14 | import liquidjava.diagnostics.hints.Hint; |
14 | 15 | import liquidjava.diagnostics.hints.StateHints; |
15 | 16 | import liquidjava.processor.context.*; |
@@ -661,8 +662,11 @@ private static void changeState(TypeChecker tc, VariableInstance vi, RefinedFunc |
661 | 662 | List<Hint> hints = deciding.isPresent() |
662 | 663 | ? receiverOf(invocation).map(r -> StateHints.decidingArgument(deciding.get(), r)).stream().toList() |
663 | 664 | : states.map(r -> stateHints(r, function, category, invocation)).orElse(List.of()); |
| 665 | + StateErrorContext context = states |
| 666 | + .map(r -> StateErrorContext.of(r.machine(), function, r.current(), writtenReceiver(invocation))) |
| 667 | + .orElse(null); |
664 | 668 | tc.throwStateRefinementError(invocation.getPosition(), declarationPosition, prevState, |
665 | | - expectedStatesDisjunction, message, hints, category); |
| 669 | + expectedStatesDisjunction, message, hints, category, context); |
666 | 670 | } |
667 | 671 | } |
668 | 672 |
|
@@ -718,13 +722,18 @@ private static Optional<String> receiverOf(CtElement invocation) { |
718 | 722 | if (!(invocation instanceof CtInvocation<?> call)) |
719 | 723 | return Optional.empty(); |
720 | 724 | CtExpression<?> target = call.getTarget(); |
721 | | - if (target == null || target.isImplicit()) |
722 | | - return Optional.of(Keys.THIS); |
723 | | - if (target instanceof CtVariableRead<?> || target instanceof CtThisAccess<?>) |
724 | | - return Optional.of(target.toString()); |
| 725 | + if (target == null || target.isImplicit() || target instanceof CtVariableRead<?> |
| 726 | + || target instanceof CtThisAccess<?>) |
| 727 | + return Optional.of(writtenReceiver(invocation)); |
725 | 728 | return Optional.empty(); |
726 | 729 | } |
727 | 730 |
|
| 731 | + /** The receiver of {@code invocation} as written in the code, {@code this} if it is implicit */ |
| 732 | + private static String writtenReceiver(CtElement invocation) { |
| 733 | + CtExpression<?> target = invocation instanceof CtInvocation<?> call ? call.getTarget() : null; |
| 734 | + return target == null || target.isImplicit() ? Keys.THIS : target.toString(); |
| 735 | + } |
| 736 | + |
728 | 737 | private static Predicate checkOldMentions(Predicate transitionedState, String instanceName, |
729 | 738 | String newInstanceName) { |
730 | 739 | return transitionedState.changeOldMentions(instanceName, newInstanceName); |
|
0 commit comments