Skip to content

Don't generate a nearly empty file - #76835

Merged
AaronRobinsonMSFT merged 1 commit into
dotnet:mainfrom
jasonmalinowski:avoid-generating-nearly-empty-files
Oct 18, 2022
Merged

Don't generate a nearly empty file#76835
AaronRobinsonMSFT merged 1 commit into
dotnet:mainfrom
jasonmalinowski:avoid-generating-nearly-empty-files

Conversation

@jasonmalinowski

@jasonmalinowskijasonmalinowski commented Oct 10, 2022

Copy link
Copy Markdown
Member

When generators are running in the Visual Studio IDE, there's some overhead to having to manage a project that actually has generated output. It requires us to maintain two Roslyn Compilation objects, each which have their own symbol information. These interop generators are producing a file that's effectively empty (just an comment on the top), and since they're installed in all .NET 7.0 applications, they are the reason we'll be having to manage more memory than before. Since the fix is simple enough to only generate the output if necessary, we should do so.

This also will help with telemetry, since we have telemetry that lets us tracking in the wild which generators are producing how many files; if we're always producing exactly one file we won't know how many sessions out there are actually using this generator in a meaningful way.

Fixes#76298

@ghost

Copy link
Copy Markdown

Tagging subscribers to this area: @dotnet/interop-contrib
See info in area-owners.md if you want to be subscribed.

Issue Details

When generators are running in the Visual Studio IDE, there's some overhead to having to manage a project that actually has generated output. It requires us to maintain two Roslyn Compilation objects, each which have their own symbol information. These interop generators are producing a file that's effectively empty (just an comment on the top), and since they're installed in all .NET 7.0 applications, they are the reason we'll be having to manage more memory than before. Since the fix is simple enough to only generate the output if necessary, we should do so.

This also will help with telemetry, since we have telemetry that lets us tracking in the wild which generators are producing how many files; if we're always producing exactly one file we won't know how many sessions out there are actually using this generator in a meaningful way.

Author:jasonmalinowski
Assignees:jasonmalinowski
Labels:

area-System.Runtime.InteropServices

Milestone:-

@AaronRobinsonMSFTAaronRobinsonMSFT left a comment

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.

Thanks!

@jasonmalinowski
jasonmalinowski marked this pull request as draft October 10, 2022 19:23
@AaronRobinsonMSFT

Copy link
Copy Markdown
Member

@pavelsavara I think we might also need a fix in the JavaScript interop source generator, right?

@jasonmalinowski

Copy link
Copy Markdown
MemberAuthor

@AaronRobinsonMSFT: as far as I can tell, this is a common helper used for everything, but unless there's another copy somewhere else I don't know about?

@jasonmalinowski

Copy link
Copy Markdown
MemberAuthor

Marking as draft since I presume this broke some tests, but I don't know where they are yet.

@jkoritzinskyjkoritzinsky left a comment

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.

LGTM. I believe the JS generator uses the same extension methods to build out the generated sources, so this should cover the JS generators as well.

@jasonmalinowski

Copy link
Copy Markdown
MemberAuthor

@jkoritzinsky@AaronRobinsonMSFT I assumed this would have broken a test somewhere but I guess there's no negative test asserting no files are produced if nothing is needed. Where should one be added?

@AaronRobinsonMSFT

Copy link
Copy Markdown
Member

I guess there's no negative test asserting no files are produced if nothing is needed

Likely not. I think the most appropriate place would be after the following tests or integrated into them. These are confirming we compile even though unsafe isn't enabled on the project. You could add a bool that indicates if a file should be generated. @elinor-fung do you have any thoughts on location?

publicstaticIEnumerable<object[]>CodeSnippetsToCompileToValidateAllowUnsafeBlocks()
{
yieldreturnnewobject[]{ID(),CodeSnippets.TrivialClassDeclarations,TestTargetFramework.Net,true};
{
stringsource=@"
using System.Runtime.InteropServices;
public class Basic { }
";
yieldreturnnewobject[]{ID(),source,TestTargetFramework.Standard,false};
yieldreturnnewobject[]{ID(),source,TestTargetFramework.Framework,false};
yieldreturnnewobject[]{ID(),source,TestTargetFramework.Net,false};
}
}
[Theory]
[MemberData(nameof(CodeSnippetsToCompileToValidateAllowUnsafeBlocks))]
publicasyncTaskValidateRequireAllowUnsafeBlocksDiagnosticNoTrigger(stringid,stringsource,TestTargetFrameworkframework,boolallowUnsafe)
{
TestUtils.Use(id);
Compilationcomp=awaitTestUtils.CreateCompilation(source,framework,allowUnsafe:allowUnsafe);
TestUtils.AssertPreSourceGeneratorCompilation(comp);
varnewComp=TestUtils.RunGenerators(comp,outvargeneratorDiags,newMicrosoft.Interop.LibraryImportGenerator());
Assert.Empty(generatorDiags);
TestUtils.AssertPostSourceGeneratorCompilation(newComp);
}

@elinor-fung

Copy link
Copy Markdown
Member

I think integrating with the one Aaron pointed at makes sense. I would:

  • Remove the case with CodeSnippets.TrivialClassDeclarations and allowUnsafe=true
    • This is already covered by ValidateSnippets
  • Rename to something like ValidateNoLibraryImport and then always create the compilation with allowUnsafe=false and add a check that no source is generated.

When generators are running in the Visual Studio IDE, there's some
overhead to having to manage a project that actually has generated
output. It requires us to maintain two Roslyn Compilation objects,
each which have their own symbol information. These interop generators
are producing a file that's effectively empty (just an <auto-generated>
comment on the top), and since they're installed in all .NET 7.0
applications, they are the reason we'll be having to manage more memory
than before. Since the fix is simple enough to only generate the output
if necessary, we should do so.
This also will help with telemetry, since we have telemetry that lets us
tracking in the wild which generators are producing how many files;
if we're always producing exactly one file we won't know how many
sessions out there are actually using this generator in a meaningful
way.
@jasonmalinowski

Copy link
Copy Markdown
MemberAuthor

@jkoritzinsky@AaronRobinsonMSFT@elinor-fung Test added, so this would need a small re-review. Otherwise I think it's ready to go?

@AaronRobinsonMSFT
AaronRobinsonMSFT merged commit ba99b91 into dotnet:mainOct 18, 2022
@AaronRobinsonMSFT

Copy link
Copy Markdown
Member

/backport to release/7.0

@github-actions

Copy link
Copy Markdown
Contributor

Started backporting to release/7.0: https://github.com/dotnet/runtime/actions/runs/3277608142

@jasonmalinowski
jasonmalinowski deleted the avoid-generating-nearly-empty-files branch November 3, 2022 23:20
@ghostghost locked as resolved and limited conversation to collaborators Dec 4, 2022
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

The interop source generators generate an empty file if unused.

4 participants

@jasonmalinowski@AaronRobinsonMSFT@elinor-fung@jkoritzinsky