Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -141,8 +141,6 @@ public async Task Publish_WithScopedCss_Works()
serviceWorkerPath: Path.Combine("serviceworkers", "my-service-worker.js"),
serviceWorkerContent: "// This is the production service worker",
assetsManifestPath: "custom-service-worker-assets.js");

VerifyTypeGranularTrimming(result, blazorPublishDirectory);
}

[Fact]
Expand Down Expand Up @@ -906,16 +904,17 @@ static string ParseWebFormattedHash(string webFormattedHash)

private void VerifyTypeGranularTrimming(MSBuildResult result, string blazorPublishDirectory)
{
var loggingAssemblyPath = Path.Combine(blazorPublishDirectory, "_framework", "Microsoft.Extensions.Logging.Abstractions.dll");
Assert.FileExists(result, loggingAssemblyPath);
var componentsShimAssemblyPath = Path.Combine(blazorPublishDirectory, "_framework", "Microsoft.AspNetCore.Razor.Test.ComponentShim.dll");
Assert.FileExists(result, componentsShimAssemblyPath);

// RouteView is referenced by the app, so we expect it to be preserved
Assert.AssemblyContainsType(result, componentsShimAssemblyPath, "Microsoft.AspNetCore.Components.RouteView");

// ILogger is referenced by the app, so we expect it to be preserved
Assert.AssemblyContainsType(result, loggingAssemblyPath, "Microsoft.Extensions.Logging.ILogger");
// LogLevel is referenced by ILogger and therefore must be preserved.
Assert.AssemblyContainsType(result, loggingAssemblyPath, "Microsoft.Extensions.Logging.LogLevel");
// RouteData is referenced by RouteView so we expect it to be preserved.
Assert.AssemblyContainsType(result, componentsShimAssemblyPath, "Microsoft.AspNetCore.Components.RouteData");

// NullLogger is not referenced by the app, and should be trimmed.
Assert.AssemblyDoesNotContainType(result, loggingAssemblyPath, "Microsoft.Extensions.Logging.Abstractions.NullLogger");
// CascadingParameterAttribute is not referenced by the app, and should be trimmed.
Assert.AssemblyDoesNotContainType(result, componentsShimAssemblyPath, "Microsoft.AspNetCore.Components.CascadingParameterAttribute");
}

private static BootJsonData ReadBootJsonData(MSBuildResult result, string path)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,12 @@ Copyright (c) .NET Foundation. All rights reserved.

</PropertyGroup>

<ItemGroup>
<!-- Configuration for the platform compatibility analyzer. See https://github.com/dotnet/designs/blob/master/accepted/2020/platform-exclusion/platform-exclusion.md#build-configuration-for-platforms -->
<SupportedPlatform Remove="@(SupportedPlatform)" />
<SupportedPlatform Include="browser" />
</ItemGroup>

<Import Project="Microsoft.NET.Sdk.BlazorWebAssembly.ServiceWorkerAssetsManifest.targets" Condition="'$(ServiceWorkerAssetsManifest)' != ''" />

<Target Name="_ScrambleDotnetJsFileName" AfterTargets="ResolveRuntimePackAssets">
Expand Down Expand Up @@ -395,7 +401,7 @@ Copyright (c) .NET Foundation. All rights reserved.
<ItemGroup>
<_BlazorTypeGranularAssembly
Include="@(ManagedAssemblyToLink)"
Condition="'%(Extension)' == '.dll' AND ($([System.String]::Copy('%(Filename)').StartsWith('Microsoft.AspNetCore.')) or $([System.String]::Copy('%(Filename)').StartsWith('Microsoft.Extensions.')))">
Condition="'%(Extension)' == '.dll' AND $([System.String]::Copy('%(Filename)').StartsWith('Microsoft.AspNetCore.'))">
<Required>false</Required>
<Preserve>all</Preserve>
</_BlazorTypeGranularAssembly>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ public static void Main(string[] args)
{
GC.KeepAlive(typeof(System.Text.Json.JsonSerializer));
GC.KeepAlive(typeof(RazorClassLibrary.Class1));
GC.KeepAlive(typeof(Microsoft.Extensions.Logging.ILogger));
#if REFERENCE_classlibrarywithsatelliteassemblies
GC.KeepAlive(typeof(classlibrarywithsatelliteassemblies.Class1));
#endif
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ internal static void ValidateChildrenAndSetParent(ManifestEntry[] children, Mani

private ManifestEntry[] CopyChildren()
{
var list = new List<ManifestEntry>();
var list = new List<ManifestEntry>(Children.Count);
for (int i = 0; i < Children.Count; i++)
{
var child = Children[i];
Expand Down
2 changes: 1 addition & 1 deletion src/Http/Http/src/Features/RequestCookiesFeature.cs
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ public IRequestCookieCollection Cookies
}
else
{
var headers = new List<string>();
var headers = new List<string>(_parsedValues.Count);
foreach (var pair in _parsedValues)
{
headers.Add(new CookieHeaderValue(pair.Key, pair.Value).ToString());
Expand Down
2 changes: 1 addition & 1 deletion src/Http/Routing/src/Patterns/RoutePatternFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -497,7 +497,7 @@ RoutePatternPart VisitPart(RoutePatternPart part)
updatedParameterPolicies = new Dictionary<string, List<RoutePatternParameterPolicyReference>>(StringComparer.OrdinalIgnoreCase);
}

parameterConstraints = new List<RoutePatternParameterPolicyReference>();
parameterConstraints = new List<RoutePatternParameterPolicyReference>(parameter.ParameterPolicies.Count);
updatedParameterPolicies.Add(parameter.Name, parameterConstraints);
}

Expand Down
23 changes: 15 additions & 8 deletions src/Identity/Core/src/SignInManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -169,16 +169,22 @@ public virtual async Task<bool> CanSignInAsync(TUser user)
public virtual async Task RefreshSignInAsync(TUser user)
{
var auth = await Context.AuthenticateAsync(IdentityConstants.ApplicationScheme);
var claims = new List<Claim>();
IList<Claim> claims = Array.Empty<Claim>();

var authenticationMethod = auth?.Principal?.FindFirst(ClaimTypes.AuthenticationMethod);
if (authenticationMethod != null)
{
claims.Add(authenticationMethod);
}
var amr = auth?.Principal?.FindFirst("amr");
if (amr != null)

if (authenticationMethod != null || amr != null)
{
claims.Add(amr);
claims = new List<Claim>();
if (authenticationMethod != null)
{
claims.Add(authenticationMethod);
}
if (amr != null)
{
claims.Add(amr);
}
}

await SignInWithClaimsAsync(user, auth?.Properties, claims);
Expand All @@ -203,9 +209,10 @@ public virtual Task SignInAsync(TUser user, bool isPersistent, string authentica
/// <returns>The task object representing the asynchronous operation.</returns>
public virtual Task SignInAsync(TUser user, AuthenticationProperties authenticationProperties, string authenticationMethod = null)
{
var additionalClaims = new List<Claim>();
IList<Claim> additionalClaims = Array.Empty<Claim>();
if (authenticationMethod != null)
{
additionalClaims = new List<Claim>();
additionalClaims.Add(new Claim(ClaimTypes.AuthenticationMethod, authenticationMethod));
}
return SignInWithClaimsAsync(user, authenticationProperties, additionalClaims);
Expand Down
4 changes: 2 additions & 2 deletions src/Middleware/Localization/src/RequestLocalizationOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ public RequestCulture DefaultRequestCulture
/// <returns>The <see cref="RequestLocalizationOptions"/>.</returns>
public RequestLocalizationOptions AddSupportedCultures(params string[] cultures)
{
var supportedCultures = new List<CultureInfo>();
var supportedCultures = new List<CultureInfo>(cultures.Length);

foreach (var culture in cultures)
{
Expand All @@ -140,7 +140,7 @@ public RequestLocalizationOptions AddSupportedCultures(params string[] cultures)
/// <returns>The <see cref="RequestLocalizationOptions"/>.</returns>
public RequestLocalizationOptions AddSupportedUICultures(params string[] uiCultures)
{
var supportedUICultures = new List<CultureInfo>();
var supportedUICultures = new List<CultureInfo>(uiCultures.Length);
foreach (var culture in uiCultures)
{
supportedUICultures.Add(new CultureInfo(culture));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,7 @@ private static string CreateMixedRoutedActionDescriptorsErrorMessage(
// Text to show as the attribute route template for conventionally routed actions.
var nullTemplate = Resources.AttributeRoute_NullTemplateRepresentation;

var actionDescriptions = new List<string>();
var actionDescriptions = new List<string>(actions.Count);
for (var i = 0; i < actions.Count; i++)
{
var (action, selector) = actions[i];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ private static void AddControllerPropertyDescriptors(ActionDescriptor actionDesc

private static void AddParameterDescriptors(ActionDescriptor actionDescriptor, ActionModel action)
{
var parameterDescriptors = new List<ParameterDescriptor>();
var parameterDescriptors = new List<ParameterDescriptor>(action.Parameters.Count);
foreach (var parameter in action.Parameters)
{
var parameterDescriptor = CreateParameterDescriptor(parameter);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -352,7 +352,7 @@ internal ActionModel CreateActionModel(

// This is fairly complicated so that we maintain referential equality between items in
// ActionModel.Attributes and ActionModel.Attributes[*].Attribute.
var applicableAttributes = new List<object>();
var applicableAttributes = new List<object>(routeAttributes.Length);
foreach (var attribute in attributes)
{
if (attribute is IRouteTemplateProvider)
Expand Down
2 changes: 1 addition & 1 deletion src/Mvc/Mvc.Core/src/BindAttribute.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public class BindAttribute : Attribute, IModelNameProvider, IPropertyFilterProvi
/// <param name="include">Names of parameters to include in binding.</param>
public BindAttribute(params string[] include)
{
var items = new List<string>();
var items = new List<string>(include.Length);
foreach (var item in include)
{
items.AddRange(SplitString(item));
Expand Down
2 changes: 1 addition & 1 deletion src/Mvc/Mvc.Core/src/ConsumesAttribute.cs
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ private bool IsApplicable(ActionDescriptor actionDescriptor)

private MediaTypeCollection GetContentTypes(string firstArg, string[] args)
{
var completeArgs = new List<string>();
var completeArgs = new List<string>(args.Length + 1);
completeArgs.Add(firstArg);
completeArgs.AddRange(args);
var contentTypes = new MediaTypeCollection();
Expand Down
2 changes: 1 addition & 1 deletion src/Mvc/Mvc.Core/src/Formatters/InputFormatter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ public virtual IReadOnlyList<string> GetSupportedContentTypes(string contentType
{
if (mediaTypes == null)
{
mediaTypes = new List<string>();
mediaTypes = new List<string>(SupportedMediaTypes.Count);
}

mediaTypes.Add(mediaType);
Expand Down
4 changes: 2 additions & 2 deletions src/Mvc/Mvc.Core/src/Formatters/OutputFormatter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ public virtual IReadOnlyList<string> GetSupportedContentTypes(
{
if (mediaTypes == null)
{
mediaTypes = new List<string>();
mediaTypes = new List<string>(SupportedMediaTypes.Count);
}

mediaTypes.Add(contentType);
Expand All @@ -81,7 +81,7 @@ public virtual IReadOnlyList<string> GetSupportedContentTypes(
{
if (mediaTypes == null)
{
mediaTypes = new List<string>();
mediaTypes = new List<string>(SupportedMediaTypes.Count);
}

mediaTypes.Add(mediaType);
Expand Down
10 changes: 6 additions & 4 deletions src/Mvc/Mvc.Core/src/Infrastructure/ActionSelector.cs
Original file line number Diff line number Diff line change
Expand Up @@ -135,10 +135,11 @@ private IReadOnlyList<ActionDescriptor> EvaluateActionConstraints(
RouteContext context,
IReadOnlyList<ActionDescriptor> actions)
{
var candidates = new List<ActionSelectorCandidate>();
var actionsCount = actions.Count;
var candidates = new List<ActionSelectorCandidate>(actionsCount);

// Perf: Avoid allocations
for (var i = 0; i < actions.Count; i++)
for (var i = 0; i < actionsCount; i++)
{
var action = actions[i];
var constraints = _actionConstraintCache.GetActionConstraints(context.HttpContext, action);
Expand All @@ -150,9 +151,10 @@ private IReadOnlyList<ActionDescriptor> EvaluateActionConstraints(
List<ActionDescriptor> results = null;
if (matches != null)
{
results = new List<ActionDescriptor>(matches.Count);
var matchesCount = matches.Count;
results = new List<ActionDescriptor>(matchesCount);
// Perf: Avoid allocations
for (var i = 0; i < matches.Count; i++)
for (var i = 0; i < matchesCount; i++)
{
var candidate = matches[i];
results.Add(candidate.Action);
Expand Down
2 changes: 1 addition & 1 deletion src/Mvc/Mvc.Core/src/ProducesAttribute.cs
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ public void SetContentTypes(MediaTypeCollection contentTypes)

private MediaTypeCollection GetContentTypes(string firstArg, string[] args)
{
var completeArgs = new List<string>();
var completeArgs = new List<string>(args.Length + 1);
completeArgs.Add(firstArg);
completeArgs.AddRange(args);
var contentTypes = new MediaTypeCollection();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ private IReadOnlyList<MetadataReference> GetCompilationReferences()
// For unit testing
internal IEnumerable<string> GetReferencePaths()
{
var referencePaths = new List<string>();
var referencePaths = new List<string>(_options.AdditionalReferencePaths.Count);

foreach (var part in _partManager.ApplicationParts)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,8 @@ private IDictionary<string, object> DeserializeDictionary(JsonElement rootElemen

private static object DeserializeArray(in JsonElement arrayElement)
{
if (arrayElement.GetArrayLength() == 0)
int arrayLength = arrayElement.GetArrayLength();
if (arrayLength == 0)
{
// We have to infer the type of the array by inspecting it's elements.
// If there's nothing to inspect, return a null value since we do not know
Expand All @@ -93,7 +94,7 @@ private static object DeserializeArray(in JsonElement arrayElement)

if (arrayElement[0].ValueKind == JsonValueKind.String)
{
var array = new List<string>();
var array = new List<string>(arrayLength);

foreach (var item in arrayElement.EnumerateArray())
{
Expand All @@ -104,7 +105,7 @@ private static object DeserializeArray(in JsonElement arrayElement)
}
else if (arrayElement[0].ValueKind == JsonValueKind.Number)
{
var array = new List<int>();
var array = new List<int>(arrayLength);

foreach (var item in arrayElement.EnumerateArray())
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ private IntermediateNode RewriteUsage(IntermediateNode parent, TagHelperDirectiv
// This method is overloaded on string and T, which means that it will put the code in the
// correct context for intellisense when typing in the attribute.
var eventArgsType = node.TagHelper.GetEventArgsType();
var tokens = new List<IntermediateToken>()
var tokens = new List<IntermediateToken>(original.Count + 2)
{
new IntermediateToken()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ private string GetInformationalVersion()

private static string[] ExpandResponseFiles(string[] args)
{
var expandedArgs = new List<string>();
var expandedArgs = new List<string>(args.Length);
foreach (var arg in args)
{
if (!arg.StartsWith("@", StringComparison.Ordinal))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ private void HandleCancellation()
/// </summary>
private void WaitForAnyCompletion(CancellationToken cancellationToken)
{
var all = new List<Task>();
var all = new List<Task>(_connections.Count + 3);
all.AddRange(_connections);
all.Add(_timeoutTask);
all.Add(_listenTask);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ internal static AssemblyIdentity GetAssemblyIdentity(this MetadataReader reader)

internal static AssemblyIdentity[] GetReferencedAssembliesOrThrow(this MetadataReader reader)
{
var references = new List<AssemblyIdentity>();
var references = new List<AssemblyIdentity>(reader.AssemblyReferences.Count);

foreach (var referenceHandle in reader.AssemblyReferences)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public class FindAssembliesWithReferencesTo : Task

public override bool Execute()
{
var referenceItems = new List<AssemblyItem>();
var referenceItems = new List<AssemblyItem>(Assemblies.Length);
foreach (var item in Assemblies)
{
const string FusionNameKey = "FusionName";
Expand Down
2 changes: 1 addition & 1 deletion src/Razor/Microsoft.NET.Sdk.Razor/src/ReferenceResolver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ protected virtual IReadOnlyList<AssemblyItem> GetReferences(string file)

var metadataReader = peReader.GetMetadataReader();

var references = new List<AssemblyItem>();
var references = new List<AssemblyItem>(metadataReader.AssemblyReferences.Count);
foreach (var handle in metadataReader.AssemblyReferences)
{
var reference = metadataReader.GetAssemblyReference(handle);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@ namespace Microsoft.AspNetCore.Razor.TagHelpers
/// </summary>
public abstract class ReadOnlyTagHelperAttributeList : ReadOnlyCollection<TagHelperAttribute>
{
private static readonly IReadOnlyList<TagHelperAttribute> EmptyList = new TagHelperAttribute[0];

/// <summary>
/// Instantiates a new instance of <see cref="ReadOnlyTagHelperAttributeList"/> with an empty
/// collection.
Expand Down Expand Up @@ -146,7 +144,7 @@ public bool TryGetAttributes(string name, out IReadOnlyList<TagHelperAttribute>
matchedAttributes.Add(attribute);
}
}
attributes = matchedAttributes ?? EmptyList;
attributes = matchedAttributes ?? (IReadOnlyList<TagHelperAttribute>)Array.Empty<TagHelperAttribute>();

return matchedAttributes != null;
}
Expand Down Expand Up @@ -198,4 +196,4 @@ protected static bool NameEquals(string name, TagHelperAttribute attribute)
return string.Equals(name, attribute.Name, StringComparison.OrdinalIgnoreCase);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@ namespace Microsoft.AspNetCore.Razor.TagHelpers
/// </summary>
public abstract class ReadOnlyTagHelperAttributeList : ReadOnlyCollection<TagHelperAttribute>
{
private static readonly IReadOnlyList<TagHelperAttribute> EmptyList = new TagHelperAttribute[0];

/// <summary>
/// Instantiates a new instance of <see cref="ReadOnlyTagHelperAttributeList"/> with an empty
/// collection.
Expand Down Expand Up @@ -138,7 +136,7 @@ public bool TryGetAttributes(string name, out IReadOnlyList<TagHelperAttribute>
matchedAttributes.Add(Items[i]);
}
}
attributes = matchedAttributes ?? EmptyList;
attributes = matchedAttributes ?? Array.Empty<TagHelperAttribute>() as IReadOnlyList<TagHelperAttribute>;

return matchedAttributes != null;
}
Expand Down
Loading