Skip to content

Conversation

@SteveSandersonMS
Copy link
Member

@SteveSandersonMS SteveSandersonMS commented Aug 27, 2020

This fixes a regression that was introduced in 5.0-preview8, reported by customers at #25267

What caused the regression

As part of perf work, in #23703 I had added an optimization whereby, for minimized attributes, we called a new RenderTreeBuilder.AddAttribute overload specialized to minimized attributes that was able to skip a series of checks and housekeeping steps that were unnecessary for minimized attributes. The Razor compiler was updated to use this new AddAttribute overload for all minimized attributes.

The optimization is particularly valuable because, with CSS scoping, components have a lot more minimized attributes than they used to. Every HTML element within a CSS-scoped component has at least one minimized attribute to represent the scope ID.

Why there's a regression

The above works great when targeting 5.0+ libraries. However if you're using the 5.0 SDK and targeting the 3.x libraries, then you have a problem because the new AddAttribute overload doesn't exist there, but the 5.0 compiler generates calls to it.

How the fix works

As of this PR, for RazorLanguageVersion < 5.0, the compiler doesn't call the new method but instead generates the same AddAttribute call it used to.

Risks

There's no new risk as long as the updated code actually works as intended.

Alternate workaround

Customers who want a workaround before 5.0-RC1 ships can either not install 5.0-preview8, or if they already have done, they can tell dotnet to continue using the 3.x SDK for their project by adding a global.json file, for example as suggested at #25267 (comment)

@ghost ghost added the area-mvc Includes: MVC, Actions and Controllers, Localization, CORS, most templates label Aug 27, 2020
@SteveSandersonMS SteveSandersonMS requested review from a team, NTaylorMullen and ajaybhargavb and removed request for NTaylorMullen August 27, 2020 11:58
@SteveSandersonMS SteveSandersonMS self-assigned this Aug 27, 2020
#nullable disable
);
__builder.AddAttribute(2, "minimized-attr", true);
__builder.AddAttribute(3, "empty-string-atttr", true);
Copy link
Member Author

Choose a reason for hiding this comment

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

The above two lines show the compiler output for 3.x language version.

#nullable disable
);
__builder.AddAttribute(2, "minimized-attr");
__builder.AddAttribute(3, "empty-string-atttr");
Copy link
Member Author

Choose a reason for hiding this comment

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

The above two lines show the compiler output for 5.0+ language version.

// Add the 'temp' compilation as a metadata reference
var references = BaseCompilation.References.Concat(new[] { tempAssembly.Compilation.ToMetadataReference() }).ToArray();
projectEngine = CreateProjectEngine(RazorConfiguration.Default, references);
projectEngine = CreateProjectEngine(Configuration, references);
Copy link
Member Author

Choose a reason for hiding this comment

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

The two changes in this file from RazorConfiguration.Default to Configuration are to make the test behavior consistent. If a test subclass overrides the pre-existing Configuration property (which defaults to RazorConfiguration.Default) then we really should use that override instead of certain bits of code being hardcoded to use RazorConfiguration.Default directly.

This change is needed for the test that demonstrates the output on 3.x.


public override bool SuppressNullabilityEnforcement { get; }

public override bool OmitMinimizedComponentAttributeValues { get; }
Copy link
Member Author

@SteveSandersonMS SteveSandersonMS Aug 27, 2020

Choose a reason for hiding this comment

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

I've defined this new option, instead of using the RazorLanguageVersion directly inside the code writer, because:

  1. It seems like the existing philosophy is that the language version should be used to trigger the values for options, rather than code doing things directly based on the language version, so this is consistent.
  2. The code writer has no existing way of knowing the RazorLanguageVersion (perhaps because of the philosophy mentioned above), and threading it through many layers would be quite disruptive, including to some public APIs

Copy link
Contributor

Choose a reason for hiding this comment

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

Don't have to address in this PR but might want to add a new CodeGenerationFeatureFlags property to contain these similar to this. That makes it cleaner if we introduce more code generation features in the future.

@Pilchie Pilchie added the Servicing-approved Shiproom has approved the issue label Aug 27, 2020
@Pilchie
Copy link
Member

Pilchie commented Aug 27, 2020

Approved for RC1, pending CI completion.


public override bool SuppressNullabilityEnforcement { get; }

public override bool OmitMinimizedComponentAttributeValues { get; }
Copy link
Contributor

Choose a reason for hiding this comment

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

Don't have to address in this PR but might want to add a new CodeGenerationFeatureFlags property to contain these similar to this. That makes it cleaner if we introduce more code generation features in the future.

@mkArtakMSFT mkArtakMSFT merged commit ebaaa0f into release/5.0 Aug 28, 2020
@mkArtakMSFT mkArtakMSFT deleted the stevesa/fix-minimized-attributes-with-3x-target branch August 28, 2020 15:37
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 Servicing-approved Shiproom has approved the issue

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Compilation error in in .NET 5 Preview 8 with attributes without value, in some cases

5 participants