Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Compilation events #4732

Merged
merged 86 commits into from
Nov 14, 2023
Merged

Conversation

keyboardDrummer
Copy link
Member

@keyboardDrummer keyboardDrummer commented Nov 1, 2023

Description

Updates

CompilationManager.CompilationUpdates is renamed to Updates, and its type has been changed from Observable<Compilation> to IObservable<ICompilationEvent>. This means that the updates are now deltas that describe how the state of compilation has changed, instead of describing the full state of compilation. The full state of the compilation can still be queried through CompilationManager.Program and CompilationManager.Resolution, so the interface is strictly more powerful now.

Having a stream of deltas available in the interface is important for being able to use it for the CLI, since the CLI wants to immediately print diagnostics as they're found, which CompilationManager couldn't handle well without this change.

Gutter icons

All processing of gutter related data is now done based on CompilationManager.CompilationUpdates, instead of inside CompilationManager, which makes it possible to use CompilationManager for the CLI without computing gutter icons. This happens to also fix #4656 for which a test was added.

Renames

  • Rename Compilation to CompilationInput, CompilationManager to Compilation,
  • Rename CompilationAfterResolution to Resolution, remove its inheritance, move the mutable fields to CompilationManager and change it into a record

How has this been tested?

Most of it is a refactoring, but also added the test GitIssue4656GutterIconsResolutionError

By submitting this pull request, I confirm that my contribution is made under the terms of the MIT license.

Copy link
Member

@MikaelMayer MikaelMayer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well done! It seems that the codebase is more maintainable with these refactorings, immutable records, renamings. A few suggestions and questions

Task<IReadOnlyList<IImplementationTask>> GetVerificationTasksAsync(ExecutionEngine engine,
CompilationAfterResolution compilation,
Resolution resolution,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I felt a bit weird about "Compilation" to describe an object, but now I feel a bit weirder about "Resolution", since Resolution is a process. I would have named it rather "Resolver", "ResolverOutput", "ResolutionOutput" depending on the meaning

NotificationPublisher.Combine(PublishedVerificationStatus.Stale, PublishedVerificationStatus.Queued));
Assert.Equal(PublishedVerificationStatus.Stale,
NotificationPublisher.Combine(PublishedVerificationStatus.Stale, PublishedVerificationStatus.Error));
Assert.Equal(PublishedVerificationStatus.Running,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How much did you weight this one against PublishedVerificationStatus.Error? I understand why it's running, but for example in the gutter icons, errors prevail above everything, including running.

Copy link
Member Author

@keyboardDrummer keyboardDrummer Nov 9, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I considered it. I think both have downsides:

  • If you show running, then someone who's only watching the status bar to see whether errors are found, will wait longer than they have too.
  • If you show error, then someone might be surprised when new errors appear after it already went from running to error.

I think it's a bit scary if the IDE is consuming resources through verification, and not indicating this. A user might think there's a bug or wonder why the IDE is lying to them, so I prefer to show running.


var state = await projectManager.GetIdeStateAfterVerificationAsync();
var state = await projectManager.States.Select(s => s.Value).Where(s =>
s.Status == CompilationStatus.ResolutionSucceeded &&
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel like this could be written

s.EverythingFinished() // needs to be refactored.

what do you think?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure what you mean but I extracted some code into a method to make it more clear what it does.

@@ -28,21 +28,20 @@ public class DafnyProgramVerifier : IProgramVerifier {
}

public async Task<IReadOnlyList<IImplementationTask>> GetVerificationTasksAsync(ExecutionEngine boogieEngine,
CompilationAfterResolution compilation,
Resolution resolution,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm a bit hesitant about the "Resolution" name. Resolution is a process, while class names are usually objects.
What about:

  • ResolutionOutput
  • ResolutionResult
  • ResolutionOutcome
    ?

// When multiple calls to VerifyUnverifiedSymbol are made, the order in which they pass this await matches the call order.
await ticket;

if (!onlyPrepareVerificationForGutterTests) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Switch condition to reduce nesting.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see how it's possible to reduce nesting here by inverting, but I'll extract something to a separate method.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was thinking of

if (onlyPrepareVerificationForGutterTests) {
  DecrementJobs();
  return;
}
<previously indented cod>
DecrementJobs();

but refactoring is a good idea as well.

}
// TODO: https://github.com/dafny-lang/dafny/issues/3415
return new TextEditContainer(new TextEdit[] {
// TODO end position doesn't take into account trailing trivia
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Move this comment up with the other TODO

Status = status,
ResolvedProgram = ResolvedProgram,
SymbolTable = SymbolTable
?? previousState.SymbolTable, // TODO migration seems missing
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO: Can you please create an issue and link the issue to that todo, or fix it?

Copy link
Member

@MikaelMayer MikaelMayer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for taking my comments into account, it looks better. Two optional small improvements


private void StatusUpdateHandlerFinally() {
try {
var remainingJobs = Interlocked.Decrement(ref runningVerificationJobs);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A statement not expected to create an exception should generally not be in the try portion of a try catch statement if possible.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have removed this method in a branch I will publish after this PR is merged

@@ -290,18 +290,18 @@ public class ProjectManager : IDisposable {
compilation.IncrementJobs();
var resolution = await compilation.Resolution;

var verifiables = resolution.CanVerifies?.ToList();
if (verifiables == null) {
var canVerifies = resolution.CanVerifies?.ToList();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seem like a weird name after all. Did you mean "VerifiableDeclarations"?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is what it means. CanVerifies is meant to the pural of CanVerify. Earlier I named these Verifiable and Verifiables. I'm OK with changing to VerifiableDeclarations although it is two words instead of one.

@keyboardDrummer keyboardDrummer merged commit 843a4e8 into dafny-lang:master Nov 14, 2023
20 checks passed
@keyboardDrummer keyboardDrummer deleted the compilationEvents branch November 14, 2023 11:08
@keyboardDrummer keyboardDrummer restored the compilationEvents branch November 14, 2023 13:18
@keyboardDrummer keyboardDrummer deleted the compilationEvents branch November 14, 2023 13:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Resolution errors no longer appearing in the gutter
2 participants