Skip to content

Add support for source generators in Razor compiler #29916

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

Merged
merged 2 commits into from
Feb 6, 2021
Merged

Conversation

captainsafia
Copy link
Member

  • Update the version of Microsoft.CodeAnalysis.CSharp that we consume otherwise we get some downstream assembly resolution issues in the version of Microsoft.AspNetCore.Razor.Extensions that we use in the SDK repo.
  • Add IVT info for M.NET.Sdk.Razor.SourceGenerators assembly. I'm working around this for now by giving the source generators package an rzc assembly name over in the sdk repo.
  • Read from source document in project item. I'm working around this by implementing a Read method that returns a text stream from the string of a SourceText object but that's not ideal.

Part of #26902

Copy link
Contributor

@pranavkm pranavkm left a comment

Choose a reason for hiding this comment

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

I think the new compiler introduces some additional nullability warnings that you would need to address. But otherwise this looks good.

FYI @NTaylorMullen

@@ -130,9 +130,11 @@ public string FilePathWithoutExtension
}
}

internal RazorSourceDocument SourceDocument { get; set; }

Choose a reason for hiding this comment

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

Hmm, this is concerning. The intent of RazorProjectItem is to be decoupled from a SourceDocument entirely. Why do you need this here? Typically we just re-create a project item.

Copy link
Contributor

Choose a reason for hiding this comment

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

One of the things that helped with perf was having a RazorSourceLineCollection that was backed by the Roslyn SourceText document (because that's what we're provided in a source generator). Here's what that looks like: https://github.com/dotnet/aspnetcore/pull/28807/files#diff-04e8fa11176d9e8cdfa5d0edeeb3ba7c1c6d20683201775277a3215a1fcb1a3f.

If I'm not mistaken, there isn't an API that lets you affect how a RazorProjectItem gets turned in to a RazorSourceDocument. We could create one where the default implementation reads from the stream and produces a source document and the source generator configures it with a custom provider. This one felt easier to implement as we did not have to introduce yet another concept, but you have more context here, so open to suggestions.

@@ -193,6 +193,11 @@ public static RazorSourceDocument ReadFrom(RazorProjectItem projectItem)
filePath = projectItem.FilePath;
}

if (projectItem.SourceDocument is not null)

Choose a reason for hiding this comment

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

Why not just re-create a source document?

Copy link
Member Author

@captainsafia captainsafia Feb 5, 2021

Choose a reason for hiding this comment

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

This and the change above are designed to work in conjunction with some work we've done to support source generators.

We have a new SourceGeneratorProjectItem (ref) type that gets constructed from the list of files that Roslyn provides in a generator's compilation context (ref).

These additional files are provided as SourceTexts. We have a SourceTextRazorSourceDocument type (ref) that we create from the SourceText.

Here we are updating the ReadFrom method to directly use the SourceDocument that we compute from the SourceText provided by Roslyn instead of reading in the file contents from a stream.

You can view a hacky workaround I used to get around this here by reading the string of the SourceText into a stream but this isn't ideal.

Hope this explanation was clear. Thoughts?

Choose a reason for hiding this comment

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

Thanks for the clarification, definitely helps piece it all together a bit more. It's been a while since I've dug through the code but why can't we have the project item read directly from the Roslyn source text?

Copy link
Member Author

Choose a reason for hiding this comment

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

We did create a ProjectItem implementation that reads directly from the Roslyn source text (ref). But currently, the project engine computes the source document (ref) from a project item by reading from a stream (ref).

We can try implementing an overload of ReadFrom that takes in a SourceGeneratorProjectItem

public static RazorSourceDocument ReadFrom(SourceGeneratorProjectItem projectItem)
{
   return new SourceGeneratorSourceDocument(projectItem.AdditionalText); // or similiar
}

But that would add source generator-specific logic in the compiler.

An alternative is to create some sort of abstraction where in a custom ProjectItem can define how source documents should be read from it similar to @pranavkm's recommendation above.

Choose a reason for hiding this comment

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

An alternative is to create some sort of abstraction where in a custom ProjectItem can define how source documents should be read from it similar to @pranavkm's recommendation above.

Ya I think that'd be better. It'd be a more defined route of translating from one type to another.

Copy link
Member Author

Choose a reason for hiding this comment

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

Yep! Will create an issue to track this. We want to get the initial E2E with source generators working then refine things.

@captainsafia captainsafia requested a review from a team as a code owner February 5, 2021 01:30
@captainsafia
Copy link
Member Author

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 2 pipeline(s).

@dougbu
Copy link
Contributor

dougbu commented Feb 5, 2021

@captainsafia what in particular would you like me to review❔ If it's just the CODEOWNERS file, no objections from me

/fyi dotnet/install-scripts#136 is blocking this PR at the moment

@Pilchie Pilchie added the area-mvc Includes: MVC, Actions and Controllers, Localization, CORS, most templates label Feb 5, 2021
@captainsafia captainsafia requested a review from a team as a code owner February 5, 2021 19:24
@dougbu
Copy link
Contributor

dougbu commented Feb 5, 2021

Turns out we have to make some updates to the PublicShipped.API.txt files under both the Component and Ignitor project since we compile include source files from the components project in the ignitor project.

Changing the PublicAPI.Shipped.txt files outside an X.Y.0 release is never the right idea. @JunTaoLuo is scrambling to fix up the places where we've made this mistake. Please don't make it worse.

If necessary, change the PublicAPI.Unshipped.txt files to remove changed APIs. The syntax is to copy the line from PublicAPI.Shipped.txt (again, not changing that file) into PublicAPI.Unshipped.txt and add a *Removed* prefix.

@pranavkm
Copy link
Contributor

pranavkm commented Feb 5, 2021

@dougbu in this case it's changing the nullability annotation on a shipped API. We've made a number of those so far - aspnet/Announcements#444.

@dougbu
Copy link
Contributor

dougbu commented Feb 5, 2021

We've made a number of those so far - aspnet/Announcements#444.

I know. The problem isn't the nullabiltity changes but how they were handled in the API baseline files. PublicAPI.Shipped.txt files should change only immediately after X.Y.0 ships.

@captainsafia captainsafia merged commit 307e107 into main Feb 6, 2021
@captainsafia captainsafia deleted the safia/rsg2 branch February 6, 2021 02:31
dougbu pushed a commit to dougbu/razor-compiler that referenced this pull request Nov 17, 2021
…e#29916)

* Add support for source generators in Razor compiler
* Fix PublicAPI text files

Commit migrated from dotnet/aspnetcore@307e1072b62a
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-mvc Includes: MVC, Actions and Controllers, Localization, CORS, most templates
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants