-
Notifications
You must be signed in to change notification settings - Fork 280
Add tooltip on assertions that shows which functions are hidden #5929
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
Changes from 9 commits
2a92810
ea4cbb0
8dedb49
a6e2f8f
3bf7ab4
6293a27
2b63912
f68416e
b2daf87
45a6b9d
9e0feff
ea82f96
6e0dbfc
6f2abe4
eecb794
5c074df
d8eb6cd
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
[submodule "boogie"] | ||
path = boogie | ||
url = git@github.com:keyboardDrummer/boogie.git |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
using System; | ||
using System.Text; | ||
|
||
namespace Microsoft.Dafny; | ||
|
||
public class RangeToken : TokenWrapper { | ||
public IToken StartToken => WrappedToken; | ||
|
||
public IToken EndToken => endToken ?? StartToken; | ||
|
||
public bool InclusiveEnd => endToken != null; | ||
|
||
public override bool Equals(object obj) { | ||
if (obj is RangeToken other) { | ||
return StartToken.Equals(other.StartToken) && EndToken.Equals(other.EndToken); | ||
} | ||
return false; | ||
} | ||
|
||
public override int GetHashCode() { | ||
return HashCode.Combine(StartToken.GetHashCode(), EndToken.GetHashCode()); | ||
} | ||
|
||
public DafnyRange ToDafnyRange(bool includeTrailingWhitespace = false) { | ||
var startLine = StartToken.line - 1; | ||
var startColumn = StartToken.col - 1; | ||
var endLine = EndToken.line - 1; | ||
int whitespaceOffset = 0; | ||
if (includeTrailingWhitespace) { | ||
string trivia = EndToken.TrailingTrivia; | ||
// Don't want to remove newlines or comments -- just spaces and tabs | ||
while (whitespaceOffset < trivia.Length && (trivia[whitespaceOffset] == ' ' || trivia[whitespaceOffset] == '\t')) { | ||
whitespaceOffset++; | ||
} | ||
} | ||
|
||
var endColumn = EndToken.col + (InclusiveEnd ? EndToken.val.Length : 0) + whitespaceOffset - 1; | ||
return new DafnyRange( | ||
new DafnyPosition(startLine, startColumn), | ||
new DafnyPosition(endLine, endColumn)); | ||
} | ||
|
||
public RangeToken(IToken startToken, IToken endToken) : base(startToken) { | ||
this.endToken = endToken; | ||
} | ||
|
||
public string PrintOriginal() { | ||
var token = StartToken; | ||
var originalString = new StringBuilder(); | ||
originalString.Append(token.val); | ||
while (token.Next != null && token.pos < EndToken.pos) { | ||
originalString.Append(token.TrailingTrivia); | ||
token = token.Next; | ||
originalString.Append(token.LeadingTrivia); | ||
originalString.Append(token.val); | ||
} | ||
|
||
return originalString.ToString(); | ||
} | ||
|
||
public int Length() { | ||
return EndToken.pos - StartToken.pos; | ||
} | ||
|
||
public RangeToken MakeAutoGenerated() { | ||
return new RangeToken(new AutoGeneratedToken(StartToken), EndToken); | ||
} | ||
|
||
public RangeToken MakeRefined(ModuleDefinition module) { | ||
return new RangeToken(new RefinementToken(StartToken, module), EndToken); | ||
} | ||
|
||
// TODO rename to Generated, and Token.NoToken to Token.Generated, and remove AutoGeneratedToken. | ||
public static RangeToken NoToken = new(Token.NoToken, Token.NoToken); | ||
private readonly IToken endToken; | ||
|
||
public override IToken WithVal(string newVal) { | ||
throw new NotImplementedException(); | ||
} | ||
|
||
public override bool IsSourceToken => this != NoToken; | ||
|
||
public BoogieRangeToken ToToken() { | ||
return new BoogieRangeToken(StartToken, EndToken, null); | ||
} | ||
|
||
public bool Contains(IToken otherToken) { | ||
return StartToken.Uri == otherToken.Uri && | ||
StartToken.pos <= otherToken.pos && | ||
(EndToken == null || otherToken.pos <= EndToken.pos); | ||
} | ||
|
||
public bool Intersects(RangeToken other) { | ||
return !(other.EndToken.pos + other.EndToken.val.Length <= StartToken.pos | ||
|| EndToken.pos + EndToken.val.Length <= other.StartToken.pos); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change | ||
---|---|---|---|---|
|
@@ -356,15 +356,29 @@ private async Task VerifyUnverifiedSymbol(bool onlyPrepareVerificationForGutterT | |||
return result; | ||||
}); | ||||
if (updated || randomSeed != null) { | ||||
updates.OnNext(new CanVerifyPartsIdentified(canVerify, | ||||
tasksPerVerifiable[canVerify].ToList())); | ||||
updates.OnNext(new CanVerifyPartsIdentified(canVerify, tasks)); | ||||
} | ||||
|
||||
// When multiple calls to VerifyUnverifiedSymbol are made, the order in which they pass this await matches the call order. | ||||
await ticket; | ||||
|
||||
if (!onlyPrepareVerificationForGutterTests) { | ||||
var groups = tasks.GroupBy(t => | ||||
// We unwrap so that we group on tokens as they are displayed to the user by Reporter.Info | ||||
TokenWrapper.Unwrap(BoogieGenerator.ToDafnyToken(true, t.Token))). | ||||
OrderBy(g => g.Key); | ||||
foreach (var tokenTasks in groups) { | ||||
var functions = tokenTasks.SelectMany(t => t.Split.HiddenFunctions.Select(f => f.tok). | ||||
OfType<FromDafnyNode>().Select(n => n.Node). | ||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Wrapping tokens to filter functions is not ideal. There are multi competing token wrapping strategies that will end up failing this test in the future. For example, refinement tokens will wrap your FromDafnyNode token making them not pass this test. There are other wrapped tokens types, like auto-generated tokens, nested tokens, override tokens for traits, etc. I'm not expecting you to do this refactoring, so in the meantime, please use something like There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Here the wrapping happens right before handing the token to Boogie, so Dafny won't do any further wrapper, and Boogie might do some wrapping on tokens but only use that for nodes that it creates, so not on the nodes that I'm interested in. I don't think there's a potential issue here. If there is one, how can we test for it? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ok, good to know that the risk is mitigated. I think that we still have the risk that later, someone will wrap your token after your own wrapping and their test cases will be orthogonal to yours, so both won't be tested together. |
||||
OfType<Function>()).Distinct().OrderBy(f => f.tok); | ||||
var hiddenFunctions = string.Join(", ", functions.Select(f => f.FullDafnyName)); | ||||
if (!string.IsNullOrEmpty(hiddenFunctions)) { | ||||
Reporter.Info(MessageSource.Verifier, tokenTasks.Key, $"hidden functions: {hiddenFunctions}"); | ||||
} | ||||
} | ||||
|
||||
foreach (var task in tasks.Where(taskFilter)) { | ||||
|
||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||
var seededTask = randomSeed == null ? task : task.FromSeed(randomSeed.Value); | ||||
VerifyTask(canVerify, seededTask); | ||||
} | ||||
|
Uh oh!
There was an error while loading. Please reload this page.