-
Notifications
You must be signed in to change notification settings - Fork 206
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Update to consolidate parameter validation logic (#3581)
Fixes #3486
- Loading branch information
Showing
60 changed files
with
893 additions
and
588 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
172 changes: 172 additions & 0 deletions
172
...s/http-client-csharp/generator/Microsoft.Generator.CSharp/perf/MethodProviderBenchmark.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,172 @@ | ||
// Copyright (c) Microsoft Corporation. All rights reserved. | ||
// Licensed under the MIT License. | ||
|
||
using System.Collections.Generic; | ||
using BenchmarkDotNet.Attributes; | ||
using Microsoft.Generator.CSharp.Providers; | ||
using Microsoft.Generator.CSharp.Statements; | ||
using static Microsoft.Generator.CSharp.Snippets.Snippet; | ||
|
||
namespace Microsoft.Generator.CSharp.Perf | ||
{ | ||
public class MethodProviderBenchmark | ||
{ | ||
private MethodSignature Signature { get; } | ||
private MethodBodyStatement BodyStatement = new(); | ||
private Dictionary<ParameterValidationType, List<ParameterProvider>>? ParamHash; | ||
|
||
public MethodProviderBenchmark() | ||
{ | ||
var parameters = new List<ParameterProvider> | ||
{ | ||
new ParameterProvider("param1", $"param1", typeof(int)) { Validation = ParameterValidationType.None }, | ||
new ParameterProvider("param2", $"param2", typeof(string)) { Validation = ParameterValidationType.AssertNotNull } | ||
}; | ||
Signature = new MethodSignature("name", null, null, MethodSignatureModifiers.Public, null, null, parameters); | ||
ParamHash = GetParamhash(false); | ||
} | ||
|
||
[GlobalSetup] | ||
public void GlobalSetup() | ||
{ | ||
PluginInitializer.Initialize(); | ||
} | ||
|
||
[Benchmark] | ||
[BenchmarkCategory("ValidationStatements")] | ||
public void Yieldreturn() | ||
{ | ||
List<MethodBodyStatement> statements = [.. GetValidationStatementsWithYield()]; | ||
statements.Add(BodyStatement); | ||
} | ||
|
||
[Benchmark] | ||
[BenchmarkCategory("ValidationStatements")] | ||
public void UseList() | ||
{ | ||
List<MethodBodyStatement> statements = [.. GetValidationStatements()]; | ||
statements.Add(BodyStatement); | ||
} | ||
|
||
[Benchmark] | ||
[BenchmarkCategory("ValidationStatements")] | ||
public void UseSingleList() | ||
{ | ||
MethodBodyStatement statements = GetStatementsAsSingleList(BodyStatement); | ||
} | ||
|
||
[Benchmark] | ||
[BenchmarkCategory("ValidationStatements")] | ||
public void UseArray() | ||
{ | ||
MethodBodyStatement statements = GetStatementsWithHash(BodyStatement, ParamHash); | ||
} | ||
|
||
private Dictionary<ParameterValidationType, List<ParameterProvider>>? GetParamhash(bool skipParamValidation) | ||
{ | ||
Dictionary<ParameterValidationType, List<ParameterProvider>>? paramHash = null; | ||
if (!skipParamValidation) | ||
{ | ||
paramHash = new(); | ||
foreach (var parameter in Signature.Parameters) | ||
{ | ||
if (parameter.Validation == ParameterValidationType.None) | ||
continue; | ||
|
||
if (!paramHash.ContainsKey(parameter.Validation)) | ||
paramHash[parameter.Validation] = new List<ParameterProvider>(); | ||
paramHash[parameter.Validation].Add(parameter); | ||
} | ||
} | ||
return paramHash; | ||
} | ||
|
||
private MethodBodyStatement GetStatementsWithHash(MethodBodyStatement bodyStatements, Dictionary<ParameterValidationType, List<ParameterProvider>>? paramHash) | ||
{ | ||
if (paramHash is null) | ||
return bodyStatements; | ||
|
||
int count = 0; | ||
foreach (var kvp in paramHash) | ||
{ | ||
if (kvp.Key == ParameterValidationType.None) | ||
continue; | ||
count += kvp.Value.Count; | ||
} | ||
|
||
if (count == 0) | ||
{ | ||
throw new System.Exception("count is 0"); | ||
//return bodyStatements; | ||
} | ||
|
||
MethodBodyStatement[] statements = new MethodBodyStatement[count + 2]; | ||
int index = 0; | ||
foreach (var parameter in Signature.Parameters) | ||
{ | ||
if (parameter.Validation != ParameterValidationType.None) | ||
{ | ||
statements[index] = Argument.ValidateParameter(parameter); | ||
index++; | ||
} | ||
} | ||
statements[index] = EmptyLineStatement; | ||
index++; | ||
|
||
statements[index] = bodyStatements; | ||
|
||
return statements; | ||
} | ||
|
||
private MethodBodyStatement GetStatementsAsSingleList(MethodBodyStatement original) | ||
{ | ||
bool wroteValidation = false; | ||
List<MethodBodyStatement> statements = new(); | ||
foreach (var parameter in Signature.Parameters) | ||
{ | ||
if (parameter.Validation != ParameterValidationType.None) | ||
{ | ||
statements.Add(Argument.ValidateParameter(parameter)); | ||
wroteValidation = true; | ||
} | ||
} | ||
if (wroteValidation) | ||
statements.Add(EmptyLineStatement); | ||
|
||
statements.Add(original); | ||
return statements; | ||
} | ||
|
||
private IEnumerable<MethodBodyStatement> GetValidationStatementsWithYield() | ||
{ | ||
bool wroteValidation = false; | ||
foreach (var parameter in Signature.Parameters) | ||
{ | ||
if (parameter.Validation != ParameterValidationType.None) | ||
{ | ||
yield return Argument.ValidateParameter(parameter); | ||
wroteValidation = true; | ||
} | ||
} | ||
if (wroteValidation) | ||
yield return EmptyLineStatement; | ||
} | ||
|
||
private IReadOnlyList<MethodBodyStatement> GetValidationStatements() | ||
{ | ||
bool wroteValidation = false; | ||
List<MethodBodyStatement> statements = new(); | ||
foreach (var parameter in Signature.Parameters) | ||
{ | ||
if (parameter.Validation != ParameterValidationType.None) | ||
{ | ||
statements.Add(Argument.ValidateParameter(parameter)); | ||
wroteValidation = true; | ||
} | ||
} | ||
if (wroteValidation) | ||
statements.Add(EmptyLineStatement); | ||
return statements; | ||
} | ||
} | ||
} |
17 changes: 17 additions & 0 deletions
17
packages/http-client-csharp/generator/Microsoft.Generator.CSharp/perf/PluginInitializer.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
// Copyright (c) Microsoft Corporation. All rights reserved. | ||
// Licensed under the MIT License. | ||
|
||
using System.IO; | ||
using System.Reflection; | ||
|
||
namespace Microsoft.Generator.CSharp.Perf | ||
{ | ||
internal static class PluginInitializer | ||
{ | ||
public static void Initialize() | ||
{ | ||
PluginHandler pluginHandler = new PluginHandler(); | ||
pluginHandler.LoadPlugin(Path.Combine(Directory.GetParent(Assembly.GetExecutingAssembly().Location)!.FullName, "Projects", "Model")); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
73 changes: 0 additions & 73 deletions
73
...p-client-csharp/generator/Microsoft.Generator.CSharp/src/OutputTypes/CSharpMethodKinds.cs
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.