Skip to content

Commit

Permalink
Fix: Formatting on VSCode for multi-file projects with project file (#…
Browse files Browse the repository at this point in the history
…4918)

I fixed the fact that the formatter was trying to incorporate every file
in the DafnyFile project instead of considering only the file being
viewed. I also updated the tests to reflect this new parameter.
I tested manually, and when formatting a file part of a project file,
the formatting now works seamlessly (fixes
#4836)


<small>By submitting this pull request, I confirm that my contribution
is made under the terms of the [MIT
license](https://github.com/dafny-lang/dafny/blob/master/LICENSE.txt).</small>
  • Loading branch information
MikaelMayer authored Jan 8, 2024
1 parent 880ba3f commit 2998296
Show file tree
Hide file tree
Showing 5 changed files with 16 additions and 10 deletions.
8 changes: 6 additions & 2 deletions Source/DafnyCore/AST/Grammar/IndentationFormatter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,15 @@ public IndentationFormatter(TokenNewIndentCollector formatter) {
/// Creates an IndentationFormatter for the given program,
/// by immediately processing all nodes and assigning indentations to most structural tokens
/// </summary>
public static IndentationFormatter ForProgram(Program program, bool reduceBlockiness = true) {
var tokenNewIndentCollector = new TokenNewIndentCollector(program) {
public static IndentationFormatter ForProgram(Program program, Uri fileToFormat, bool reduceBlockiness = true) {
var tokenNewIndentCollector = new TokenNewIndentCollector(program, fileToFormat) {
ReduceBlockiness = reduceBlockiness
};
foreach (var child in program.DefaultModuleDef.PreResolveChildren) {
var isPhysicalToken = child.Tok.line != 0;
if (isPhysicalToken && child.Tok.Uri != fileToFormat) {
continue;
}
if (child is TopLevelDecl topLevelDecl) {
tokenNewIndentCollector.SetDeclIndentation(topLevelDecl, 0);
} else if (child is Include include) {
Expand Down
6 changes: 4 additions & 2 deletions Source/DafnyCore/AST/Grammar/TokenNewIndentCollector.cs
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,9 @@ private Indentations PosToIndentations(int pos) {
public int binOpIndent = -1;
public int binOpArgIndent = -1;

internal TokenNewIndentCollector(Program program) {
internal TokenNewIndentCollector(Program program, Uri fileToFormat) {
this.program = program;
this.fileToFormat = fileToFormat;
preResolve = true;
}

Expand Down Expand Up @@ -222,6 +223,7 @@ public int GetRightAlignIndentAfter(IToken token, int indentFallback) {
}

private static readonly Regex FollowedByNewlineRegex = new Regex("^[ \t]*([\r\n]|//)");
private readonly Uri fileToFormat;

public static bool IsFollowedByNewline(IToken token) {
return FollowedByNewlineRegex.IsMatch(token.TrailingTrivia);
Expand All @@ -231,7 +233,7 @@ public static bool IsFollowedByNewline(IToken token) {
// 'inline' is the hypothetical indentation of this token if it was on its own line
// 'below' is the hypothetical indentation of a comment after that token, and of the next token if it does not have a set indentation
public void SetIndentations(IToken token, int above = -1, int inline = -1, int below = -1) {
if (token.FromIncludeDirective(program) || (token.line == 0 && token.col == 0)) {
if (token.Uri != fileToFormat || (token.line == 0 && token.col == 0)) {
// Just ignore this token.
return;
}
Expand Down
2 changes: 1 addition & 1 deletion Source/DafnyDriver/Commands/FormatCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ public static async Task<ExitValue> DoFormatting(DafnyOptions options) {
var result = originalText;
if (firstToken != null) {
result = Formatting.__default.ReindentProgramFromFirstToken(firstToken,
IndentationFormatter.ForProgram(dafnyProgram));
IndentationFormatter.ForProgram(dafnyProgram, file.Uri));
if (result != originalText) {
neededFormatting += 1;
if (doCheck) {
Expand Down
2 changes: 1 addition & 1 deletion Source/DafnyLanguageServer/Workspace/Compilation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -428,7 +428,7 @@ public void CancelPendingUpdates() {
firstToken = firstToken.Prev;
}
var result = Formatting.__default.ReindentProgramFromFirstToken(firstToken,
IndentationFormatter.ForProgram(program));
IndentationFormatter.ForProgram(program, firstToken.Uri));

var lastToken = firstToken;
while (lastToken.Next != null) {
Expand Down
8 changes: 4 additions & 4 deletions Source/DafnyPipeline.Test/FormatterBaseTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ protected void FormatterWorksFor(string testCase, string? expectedProgramString

var reprinted = firstToken != null && firstToken.line > 0
? Formatting.__default.ReindentProgramFromFirstToken(firstToken,
IndentationFormatter.ForProgram(dafnyProgram, reduceBlockiness))
IndentationFormatter.ForProgram(dafnyProgram, firstToken.Uri, reduceBlockiness))
: programString;
EnsureEveryTokenIsOwned(uri, programNotIndented, dafnyProgram);
if (expectedProgram != reprinted) {
Expand All @@ -100,7 +100,7 @@ protected void FormatterWorksFor(string testCase, string? expectedProgramString
});
var reprintedCloned = firstToken != null && firstToken.line > 0
? Formatting.__default.ReindentProgramFromFirstToken(firstToken,
IndentationFormatter.ForProgram(dafnyProgram, reduceBlockiness))
IndentationFormatter.ForProgram(dafnyProgram, firstToken.Uri, reduceBlockiness))
: programString;
EnsureEveryTokenIsOwned(uri, programNotIndented, dafnyProgram);
if (expectedProgram != reprintedCloned) {
Expand All @@ -112,7 +112,7 @@ protected void FormatterWorksFor(string testCase, string? expectedProgramString
DafnyMain.Resolve(dafnyProgram);
reprinted = firstToken != null && firstToken.line > 0
? Formatting.__default.ReindentProgramFromFirstToken(firstToken,
IndentationFormatter.ForProgram(dafnyProgram, reduceBlockiness))
IndentationFormatter.ForProgram(dafnyProgram, firstToken.Uri, reduceBlockiness))
: programString;
if (expectedProgram != reprinted) {
options.ErrorWriter.WriteLine("Formatting after resolution generates an error:");
Expand All @@ -131,7 +131,7 @@ protected void FormatterWorksFor(string testCase, string? expectedProgramString
firstToken = dafnyProgram.GetFirstTokenForUri(uri);
var reprinted2 = firstToken != null && firstToken.line > 0
? Formatting.__default.ReindentProgramFromFirstToken(firstToken,
IndentationFormatter.ForProgram(dafnyProgram, reduceBlockiness))
IndentationFormatter.ForProgram(dafnyProgram, firstToken.Uri, reduceBlockiness))
: reprinted;
if (reprinted != reprinted2) {
Console.Write("Double formatting is not stable:\n");
Expand Down

0 comments on commit 2998296

Please sign in to comment.