Skip to content

Ensure generated trees have a full path #60095

Closed
chsienki wants to merge 4 commits intodotnet:mainfrom
chsienki:source-generators/full-syntax-tree-path
Closed

Ensure generated trees have a full path #60095
chsienki wants to merge 4 commits intodotnet:mainfrom
chsienki:source-generators/full-syntax-tree-path

Conversation

@chsienki
Copy link
Copy Markdown
Member

  • Use GeneratedFilesOutputDirectory as the base if provided
  • Fallback to OutputDirectory when not
  • Add tests and fix full PDB verification

Fixes #51998
Fixes #51773

- Use GeneratedFilesOutputDirectory as the base if provided
- Fallback to OutputDirectory when not
- Add tests and fix full PDB verification
@chsienki chsienki requested a review from a team as a code owner March 10, 2022 23:05
@chsienki
Copy link
Copy Markdown
Member Author

@dotnet/roslyn-compiler for review please

}
}
catch
finally
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Turns out we were silently ignoring failures, but this function was not actually being used anyway :/

[InlineData("abc/a.txt", "./../ABC/a.txt", 2)]
public void TestDuplicateAdditionalFiles_Linux(string additionalFilePath1, string additionalFilePath2, int expectedCount) => TestDuplicateAdditionalFiles(additionalFilePath1, additionalFilePath2, expectedCount);


Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

How does this behavior interact with [CallerFilePath] optional arguments? Now that the source file has a full path would expect some interaction with this feature.

driver = driver.RunGenerators(input);
var results = driver.GetRunResult();

var treeRoot = this.Arguments.GeneratedFilesOutputDirectory ?? Arguments.OutputDirectory;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This makes me nervous because toggling $(EmitCompilerGeneratedFiles) will end up impacting which directory we use here. That ends up impacting determinism because it's possible /pathmap accounts for these directories differently.

Not sure how do this better though. Only thought I had is should we only give them full paths if GeneratedFilesOutputDirectory is set? Basically if the user wants full paths they have to help us out here.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Yeah, this is the crux of the issue really, but @tmat was fairly explicit that they should always have full paths as that's whats causing downstream tooling breaks.

We do have a test in this PR that validates /pathmap is working as expected for GeneratedFilesOutputDirectory, so we should be good on that front. If the user turns on $(EmitCompilerGeneratedFiles) then yes the user will have to also path map the directory we use there (which is user controllable too)

Copy link
Copy Markdown
Member

@tmat tmat Feb 6, 2023

Choose a reason for hiding this comment

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

Seems like a logical requirement for /pathmap that it needs to cover the directory specified in GeneratedFilesOutputDirectory. In practice, it will likely be some subdirectory of the project directory.

var results = driver.GetRunResult();

var treeRoot = this.Arguments.GeneratedFilesOutputDirectory ?? Arguments.OutputDirectory;
var compilationOut = input.AddSyntaxTrees(results.GeneratedTrees.Select(t => t.WithFilePath(Path.Combine(treeRoot, t.FilePath))));
Copy link
Copy Markdown
Contributor

@cston cston Mar 14, 2022

Choose a reason for hiding this comment

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

AddSyntaxTrees

Do we need to update PostInitTrees as well? #Closed

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

if (Directory.Exists(Arguments.GeneratedFilesOutputDirectory))
{
Directory.CreateDirectory(Path.GetDirectoryName(path)!);
Directory.CreateDirectory(Path.GetDirectoryName(tree.FilePath)!);
Copy link
Copy Markdown
Contributor

@cston cston Mar 14, 2022

Choose a reason for hiding this comment

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

tree.FilePath

Minor: Consider extracting a path local - in part, to minimize the changes here. #Closed

// validate that *no* sources were written
Assert.Empty(Directory.GetDirectories(generatedDir.Path));

// but we still have full paths (using output dir) in the PDBs
Copy link
Copy Markdown
Contributor

@cston cston Mar 14, 2022

Choose a reason for hiding this comment

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

Should we verify the files were written to the expected directory?

ValidateWrittenSources(new() { { generatedDir.Path, new() { { "generatedSource.cs", generatedSource } } } });
``` #Closed

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

So we're not actually emitting any files here, which we check that on line 14384.

// validate that *no* sources were written
Assert.Empty(Directory.GetDirectories(generatedDir.Path));

// but we still have full paths (using output dir) in the PDBs
Copy link
Copy Markdown
Contributor

@cston cston Mar 14, 2022

Choose a reason for hiding this comment

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

Should we verify the files were written to the expected directory?

ValidateWrittenSources(new() { { Path.Combine(mappedPath, generatorPrefix), new() { { "generatedSource.cs", generatedSource } } } });
``` #Closed

}

var sourceStr = Encoding.UTF8.GetString(sourceBlob.Array, sourceBlob.Offset, sourceBlob.Count);
// offset by 3 to skip the BOM
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Odd to do this unconditionally. What if there is no BOM?

@tmat
Copy link
Copy Markdown
Member

tmat commented Feb 6, 2023

Issue #51998 also mentions potential problem with #line directives using full paths in source-generated files. Seems like that still needs to be addressed, right?

@jaredpar
Copy link
Copy Markdown
Member

@chsienki this PR is essentially one year stale now. If we're not actively working on it can we move it to draft?

@chsienki chsienki marked this pull request as draft March 30, 2023 18:34
@chsienki chsienki closed this Oct 2, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Improve file locations in the Roslyn Sarif reports for source generator files Source files produced by source generators should have absolute paths

4 participants