├── .config
└── dotnet-tools.json
├── .devcontainer
└── devcontainer.json
├── .editorconfig
├── .github
└── workflows
│ └── build.yml
├── .gitignore
├── .husky
├── .gitattributes
└── pre-commit
├── .vscode
├── extensions.json
└── spellright.dict
├── Directory.Build.props
├── Directory.Packages.props
├── LICENSE
├── README.md
├── Zomp.SyncMethodGenerator.sln
├── codecov.yml
├── cspell.json
├── package.json
├── src
├── Directory.Build.props
├── Zomp.SyncMethodGenerator
│ ├── AnalyzerReleases.Shipped.md
│ ├── AnalyzerReleases.Unshipped.md
│ ├── AsyncToSyncRewriter.cs
│ ├── DiagnosticMessages.cs
│ ├── Extensions.cs
│ ├── Helpers
│ │ └── EquatableArray.cs
│ ├── MethodParent.cs
│ ├── MethodParentDeclaration.cs
│ ├── MethodToGenerate.cs
│ ├── Models
│ │ └── ReportedDiagnostic.cs
│ ├── Operation.cs
│ ├── SourceGenerationHelper.cs
│ ├── SyncMethodSourceGenerator.cs
│ ├── Zomp.SyncMethodGenerator.csproj
│ └── tools
│ │ ├── install.ps1
│ │ └── uninstall.ps1
└── images
│ └── icon.png
├── stylecop.json
├── tests
├── GenerationSandbox.Tests
│ ├── AsyncExtensions.GenericMath.cs
│ ├── AsyncExtensions.cs
│ ├── AsyncWithIProgress.cs
│ ├── GenerationSandbox.Tests.csproj
│ └── SyncTests.cs
├── Generator.Tests
│ ├── ArgumentTests.cs
│ ├── ConditionalExtensionTests.cs
│ ├── DelegateTests.cs
│ ├── ExtensionMethodTests.cs
│ ├── ExternalLibraryTests.cs
│ ├── FileNameTests.cs
│ ├── Generator.Tests.csproj
│ ├── GenericMathTests.cs
│ ├── IncrementalGeneratorTests.cs
│ ├── IntegrationTesting.cs
│ ├── InterpolatedStringTests.cs
│ ├── IsCancellationRequestedTests.cs
│ ├── MemoryTests.cs
│ ├── ModuleInitializer.cs
│ ├── NullabilityTests.cs
│ ├── ParentTests.cs
│ ├── PreprocessorTests.cs
│ ├── Snapshots
│ │ ├── ArgumentTests.DropNamedArgument#CallProgressMethodAsync.g.verified.cs
│ │ ├── ArgumentTests.DropNullArgument#CallProgressMethodAsync.g.verified.cs
│ │ ├── ConditionalExtensionTests.CheckArrayNullability#g.verified.cs
│ │ ├── ConditionalExtensionTests.ConditionalToExtension#g.verified.cs
│ │ ├── ConditionalExtensionTests.HandleCastForArray#g.verified.cs
│ │ ├── ConditionalExtensionTests.HandleCastForNull#g.verified.cs
│ │ ├── ConditionalExtensionTests.KeepTypeParameters#g.verified.cs
│ │ ├── ConditionalExtensionTests.LongChained#g.verified.cs
│ │ ├── ConditionalExtensionTests.NullConditionalExtension#g.verified.cs
│ │ ├── ConditionalExtensionTests.NullConditionalExtensionChained#g.verified.cs
│ │ ├── ConditionalExtensionTests.NullConditionalWithoutExtension#g.verified.cs
│ │ ├── ConditionalExtensionTests.StartWithExpression#g.verified.cs
│ │ ├── DelegateTests.AsyncDelegate#g.verified.cs
│ │ ├── DelegateTests.AsyncDelegateExplicit#g.verified.cs
│ │ ├── DelegateTests.AsyncDelegateWithCancellationToken#g.verified.cs
│ │ ├── DelegateTests.AsyncDelegateWithIProgress#g.verified.cs
│ │ ├── DelegateTests.AsyncDelegateWithNullableIProgress#g.verified.cs
│ │ ├── DelegateTests.AsyncDelegateWithParameter#g.verified.cs
│ │ ├── DelegateTests.AsyncVarDelegateWithParameter#g.verified.cs
│ │ ├── DelegateTests.AsyncVarDelegateWithParameterAndReturnType#g.verified.cs
│ │ ├── DelegateTests.DropCompletedTaskFromLambda#g.verified.cs
│ │ ├── DelegateTests.FuncToActionInParameter#g.verified.cs
│ │ ├── DelegateTests.FuncToActionInParameterExplicitInvoke#g.verified.cs
│ │ ├── DelegateTests.FuncToActionInParameterTwice#g.verified.cs
│ │ ├── DelegateTests.FuncToActionInParameterTwiceExplicitInvoke#g.verified.cs
│ │ ├── DelegateTests.FuncToActionInParameterTwiceWithArgument#g.verified.cs
│ │ ├── ExtensionMethodTests.LeftOfTheDotTest#Tests.Class.MethodAsync.g.verified.cs
│ │ ├── ExtensionMethodTests.UnwrapGenericExtensionMethod#Zomp.SyncMethodGenerator.IntegrationTests.Extensions.HasGeneric2ExtensionAsync.g.verified.cs
│ │ ├── ExtensionMethodTests.UnwrapGenericExtensionMethod#Zomp.SyncMethodGenerator.IntegrationTests.Extensions.HasGenericExtensionAsync.g.verified.cs
│ │ ├── ExternalLibraryTests.ToListAsync#g.verified.cs
│ │ ├── FileNameTests.DoNotCollideClassNames#Test.Class{T,T2}.MethodAsync.g.verified.cs
│ │ ├── FileNameTests.DoNotCollideClassNames#Test.Class{T}.MethodAsync.g.verified.cs
│ │ ├── FileNameTests.DoNotCollideClassNames#g.verified.cs
│ │ ├── GenericMathTests.GeneratesWithIProgressCorrectly.DotNet8_0#Test.EnumerableExtensions.IndexOfMaxSoFarAsync.g.verified.cs
│ │ ├── IntegrationTesting.ChecksumRead#ChecksumReadAsync.g.verified.cs
│ │ ├── IntegrationTesting.ChecksumRead#HalfCheckSumAsync.g.verified.cs
│ │ ├── IntegrationTesting.CombineTwoLists#CombineAsync.g.verified.cs
│ │ ├── IntegrationTesting.EagerPreconditionInIteratorBlock#ReadLineByLineAsync.g.verified.cs
│ │ ├── IntegrationTesting.EagerPreconditionsInAsyncMethod#GetAllTextAsync.g.verified.cs
│ │ ├── IntegrationTesting.GeneratesSyncMethodCorrectly#Test.EnumerableExtensions.GetAveragesAsync.g.verified.cs
│ │ ├── IntegrationTesting.WithIAsyncEnumerator#EnumeratorTestAsync.g.verified.cs
│ │ ├── InterpolatedStringTests.EnsureParentheses#g.verified.cs
│ │ ├── InterpolatedStringTests.HandleFormatString#g.verified.cs
│ │ ├── IsCancellationRequestedTests.IfCancelled#g.verified.cs
│ │ ├── IsCancellationRequestedTests.IfNotCancelled#g.verified.cs
│ │ ├── IsCancellationRequestedTests.WhileNotCancelled#g.verified.cs
│ │ ├── MemoryTests.ConvertMemoryToSpan#g.verified.cs
│ │ ├── MemoryTests.ConvertMemoryToSpanAfterPropertyAccess#g.verified.cs
│ │ ├── MemoryTests.DropSpanAfterAsMemory#MakeArrayAsync.g.verified.cs
│ │ ├── MemoryTests.DropSpanAfterAsMemoryWithWhitespace#MakeArrayAsync.g.verified.cs
│ │ ├── MemoryTests.MemorySpanProperty_explicitType=False#MakeArray.g.verified.cs
│ │ ├── MemoryTests.MemorySpanProperty_explicitType=True#MakeArray.g.verified.cs
│ │ ├── MemoryTests.MemoryToSpan#ReadAsMemoryAsync.g.verified.cs
│ │ ├── MemoryTests.NonPredefinedTypes#N1.Class.FillAsync.g.verified.cs
│ │ ├── MemoryTests.PreserveUnrelatedSpan#HasMemoryAsync.g.verified.cs
│ │ ├── MemoryTests.ReadOnlyMemoryToReadOnlySpan#WriteAsync.g.verified.cs
│ │ ├── NullabilityTests.ConditionalNullable#Test.MyClass.MethodAsync.g.verified.cs
│ │ ├── NullabilityTests.ConditionalNullableStructTwice#Test.MyClass.MethodAsync.g.verified.cs
│ │ ├── NullabilityTests.ConditionalNullableTwice#Test.MyClass.MethodAsync.g.verified.cs
│ │ ├── NullabilityTests.NoNullableSupport#Test.WithNullableDisabled.MethodAsync.g.verified.cs
│ │ ├── NullabilityTests.NullableDisable#Test.WithNullableDisabled.DoNothingAsync.g.verified.cs
│ │ ├── NullabilityTests.NullableOmitExplicit#Test.MyClass.MethodAsync.g.verified.cs
│ │ ├── ParentTests.Record#Test.Record.MethodAsync.g.verified.cs
│ │ ├── ParentTests.RecordClass#Test.Record.MethodAsync.g.verified.cs
│ │ ├── ParentTests.RecordStruct#Test.RecordStruct.MethodAsync.g.verified.cs
│ │ ├── ParentTests.Struct#Test.Struct.MethodAsync.g.verified.cs
│ │ ├── PreprocessorTests.MacrosAroundBraces#g.verified.cs
│ │ ├── SpecialMethodsTests.DropMethodsWithSpecialNamesInUserClass#g.verified.cs
│ │ ├── SpecialMethodsTests.FromTaskResultCheck#g.verified.cs
│ │ ├── SpecialMethodsTests.FromValueTaskResultCheck#g.verified.cs
│ │ ├── SpecialMethodsTests.TaskDelayToThreadSleepWithInt#g.verified.cs
│ │ ├── SpecialMethodsTests.TaskDelayToThreadSleepWithSpan#g.verified.cs
│ │ ├── SyncOnlyTests.DoNotMixSymbols.verified.txt
│ │ ├── SyncOnlyTests.DoNotRemove#g.verified.cs
│ │ ├── SyncOnlyTests.DoNotRemoveInsideSyncOnly#g.verified.cs
│ │ ├── SyncOnlyTests.InsideEmptyIf#g.verified.cs
│ │ ├── SyncOnlyTests.InsideParameter#IsNullAsync.g.verified.cs
│ │ ├── SyncOnlyTests.LastParameter#IsNullAsync.g.verified.cs
│ │ ├── SyncOnlyTests.MultipleBlocksArentInterfering#g.verified.cs
│ │ ├── SyncOnlyTests.NestedSyncOnly#g.verified.cs
│ │ ├── SyncOnlyTests.NotSyncOnly#g.verified.cs
│ │ ├── SyncOnlyTests.NotSyncOnlyFollowedBySyncOnly#g.verified.cs
│ │ ├── SyncOnlyTests.NotSyncOnlyInsideSyncOnly.verified.txt
│ │ ├── SyncOnlyTests.ProhibitElif.verified.txt
│ │ ├── SyncOnlyTests.SimpleMacro#ExecAsync.g.verified.cs
│ │ ├── SyncOnlyTests.StatementAtTheEnd#g.verified.cs
│ │ ├── SyncOnlyTests.SwitchStatementProcessesDirectives#g.verified.cs
│ │ ├── SyncOnlyTests.SyncOnlyBeforeMethodBody#MethodWithObsoleteSyncAsync.g.verified.cs
│ │ ├── SystemAsyncExtensionsTests.AsyncForEachDeconstruct#SumAsync.g.verified.cs
│ │ ├── SystemAsyncExtensionsTests.AsyncForEachQualified#SumAsync.g.verified.cs
│ │ ├── SystemAsyncExtensionsTests.ConfiguredCancelableAsyncEnumerable#g.verified.cs
│ │ ├── SystemAsyncExtensionsTests.ConfiguredCancelableAsyncEnumerableExtension#GetConfiguredEnumeratorAsync.g.verified.cs
│ │ ├── SystemAsyncExtensionsTests.ConfiguredCancelableAsyncEnumerableExtensionUsingStatic#Test.Extensions.GetConfiguredAsyncEnumerator.g.verified.cs
│ │ ├── SystemAsyncExtensionsTests.DropConfigureAwaitExtensions#InvokeAsync.g.verified.cs
│ │ ├── SystemAsyncExtensionsTests.DropConfiguredCancelableAsyncEnumerable#Iterate.g.verified.cs
│ │ ├── SystemAsyncExtensionsTests.DropConfiguredCancelableAsyncEnumerableExtensionInvocation#Test.Extensions.MethodAsync.g.verified.cs
│ │ ├── SystemAsyncExtensionsTests.DropWithCancellation#Iterate.g.verified.cs
│ │ ├── TypeTests.ArrayParameter#g.verified.cs
│ │ ├── TypeTests.BinaryPattern#g.verified.cs
│ │ ├── TypeTests.CastFullyQualifiedType#GetCustomObjectAsync.g.verified.cs
│ │ ├── TypeTests.CastFullyQualifiedTypeTwice#GetCustomObjectAsync.g.verified.cs
│ │ ├── TypeTests.ConvertExceptionType#g.verified.cs
│ │ ├── TypeTests.ConvertForeachType#g.verified.cs
│ │ ├── TypeTests.CreateNullableType#g.verified.cs
│ │ ├── TypeTests.DeclarationExpression#g.verified.cs
│ │ ├── TypeTests.EnumPattern#g.verified.cs
│ │ ├── TypeTests.EnumPatternName#.Class.ReturnTrueAsync.g.verified.cs
│ │ ├── TypeTests.EventHandlerType#g.verified.cs
│ │ ├── TypeTests.FullyQualifiedArray#g.verified.cs
│ │ ├── TypeTests.GenericClassWithGenericInnerClass#Test.Class{T}.FooAsync.g.verified.cs
│ │ ├── TypeTests.HandleAsCast#g.verified.cs
│ │ ├── TypeTests.HandleDiscardSymbol#g.verified.cs
│ │ ├── TypeTests.HandleNameOf#g.verified.cs
│ │ ├── TypeTests.HandleNameOfGenericTuple#g.verified.cs
│ │ ├── TypeTests.HandleNullableTuple#g.verified.cs
│ │ ├── TypeTests.HandleTuple#g.verified.cs
│ │ ├── TypeTests.HandleTypeOf#g.verified.cs
│ │ ├── TypeTests.NestedGenerics#g.verified.cs
│ │ ├── TypeTests.NotPattern#g.verified.cs
│ │ ├── TypeTests.NullableDeclarationExpression#g.verified.cs
│ │ ├── TypeTests.NullableForeach#g.verified.cs
│ │ ├── TypeTests.PatternIsEnumMember#g.verified.cs
│ │ ├── TypeTests.PatternIsNotLiteral#g.verified.cs
│ │ ├── TypeTests.PatternMatchingWithConstant#g.verified.cs
│ │ ├── TypeTests.QualifiedGenericName#g.verified.cs
│ │ ├── TypeTests.QualifiedNonGenericName#System.Class.MethodAsync.g.verified.cs
│ │ ├── TypeTests.SwitchType#SwitchAsync.g.verified.cs
│ │ ├── TypeTests.TestTypes#g.verified.cs
│ │ ├── TypeTests.UseFullyQualifiedTypeInIsExpression#HasIsExpressionAsync.g.verified.cs
│ │ ├── TypeTests.VariableDeclaration#g.verified.cs
│ │ ├── TypeTests.VariableDeclarationRedundant#g.verified.cs
│ │ ├── UnitTests.BasicEvent#g.verified.cs
│ │ ├── UnitTests.BasicInterface#Test.IMyInterface.MethodAsync.g.verified.cs
│ │ ├── UnitTests.BrokenIfStatement#g.verified.cs
│ │ ├── UnitTests.CallPropertiesReturningTasksWithAsync#MyMethodAsync.g.verified.cs
│ │ ├── UnitTests.CallWithTypeParameters#MyFuncAsync.g.verified.cs
│ │ ├── UnitTests.ConvertAsyncDelegateToDelegate#g.verified.cs
│ │ ├── UnitTests.ConvertAsyncDelegateToSync#g.verified.cs
│ │ ├── UnitTests.DefaultParameter#GetColorAsync.g.verified.cs
│ │ ├── UnitTests.DeleteIfBetweenPreprocessorDirectives#g.verified.cs
│ │ ├── UnitTests.DoNotCallPropertiesReturningGenericTasks#MyMethodAsync.g.verified.cs
│ │ ├── UnitTests.DoNotCallPropertiesReturningGenericTasksExpression#MyMethodAsync.g.verified.cs
│ │ ├── UnitTests.DoNotCallPropertiesReturningTasks#MyMethodAsync.g.verified.cs
│ │ ├── UnitTests.DoNotDropInvocationChainThatHasAsyncAnywhere#WriteAllTextAsync.g.verified.cs
│ │ ├── UnitTests.DropBrackets#GetIntAsync.g.verified.cs
│ │ ├── UnitTests.DropCompletedTask#ExecAsync.g.verified.cs
│ │ ├── UnitTests.DropIProgressExpressionArgument#CallWithIProgressAsync.g.verified.cs
│ │ ├── UnitTests.DropIProgressStatement#CallWithIProgressAsync.g.verified.cs
│ │ ├── UnitTests.DropUnawaitedCompletedTask#DoSomethingAsync.g.verified.cs
│ │ ├── UnitTests.DropUnawaitedCompletedValueTask#DoSomethingAsync.g.verified.cs
│ │ ├── UnitTests.FindsASpan#GetMemoryOrSpanAsync.g.verified.cs
│ │ ├── UnitTests.FullyQualifiedAndNullable#g.verified.cs
│ │ ├── UnitTests.GenericAsyncCall#Test.GenericClass{T}.FooAsync.g.verified.cs
│ │ ├── UnitTests.GenericClass#Test.GenericClass{T1,T2}.EmptyAsync.g.verified.cs
│ │ ├── UnitTests.GenericClassMemberAccess#Test.GenericClass{T}.MethodAsync.g.verified.cs
│ │ ├── UnitTests.HandleAsTask#g.verified.cs
│ │ ├── UnitTests.HandleAsTaskOnParameter#g.verified.cs
│ │ ├── UnitTests.HandleAttribute#ReadSomeBytesAsync.g.verified.cs
│ │ ├── UnitTests.HandleAttributeOnLocalFunction#g.verified.cs
│ │ ├── UnitTests.KeepDefaultValueTaskWithResult#ReturnDefault.g.verified.cs
│ │ ├── UnitTests.LocalFunction#InternalExampleAsync.g.verified.cs
│ │ ├── UnitTests.LocalFunctionDelegateWithEndingAsync#DoItAsync.g.verified.cs
│ │ ├── UnitTests.LocalFunctionNonGeneric#InternalExampleAsync.g.verified.cs
│ │ ├── UnitTests.MemoryToSpanWithBody#ReadAsMemoryAsync.g.verified.cs
│ │ ├── UnitTests.MultipleClasses#NsOne.C1.C2.C3.C4.EmptyAsync.g.verified.cs
│ │ ├── UnitTests.MultipleInitializers#g.verified.cs
│ │ ├── UnitTests.MultipleNamespaces#NsOne.NsTwo.NsThree.NsFour.MultipleNamespaces.EmptyAsync.g.verified.cs
│ │ ├── UnitTests.Overloads#ReadAsMemoryAsync.g.verified.cs
│ │ ├── UnitTests.Overloads#ReadAsMemoryAsync_2.g.verified.cs
│ │ ├── UnitTests.PassIAsyncDisposable#g.verified.cs
│ │ ├── UnitTests.Preprocessor#WrappedAsync.g.verified.cs
│ │ ├── UnitTests.ReturnDefaultValueTask#ReturnAsync.g.verified.cs
│ │ ├── UnitTests.ReturnTask#ReturnAsync.g.verified.cs
│ │ ├── UnitTests.ReturnTaskNoBody#ReturnAsync.g.verified.cs
│ │ ├── UnitTests.ReturnValueTask#ReturnAsync.g.verified.cs
│ │ ├── UnitTests.ReturnValueTaskConditional#ReturnAsync.g.verified.cs
│ │ ├── UnitTests.ReturnValueTaskConditionalFalse#ReturnFalseAsync.g.verified.cs
│ │ ├── UnitTests.ReturnValueTaskConditionalTrue#ReturnTrueAsync.g.verified.cs
│ │ ├── UnitTests.ReturnValueTaskInstance#ReturnAsync.g.verified.cs
│ │ ├── UnitTests.ReturnValueTaskNoBody#ReturnAsync.g.verified.cs
│ │ ├── UnitTests.StaticUsings#N1.C1.MethodAsync.g.verified.cs
│ │ ├── UnitTests.TaskOfArrayOfGeneric#GetArrayOfTAsync.g.verified.cs
│ │ ├── UnitTests.TaskOfT#GetPointAsync.g.verified.cs
│ │ ├── UnitTests.TaskOfT2IList#GetArrayOfTAsync.g.verified.cs
│ │ ├── UnitTests.TaskOfTArray#GetPointAsync.g.verified.cs
│ │ ├── UnitTests.TaskOfTIList#GetPointAsync.g.verified.cs
│ │ ├── UnitTests.UnwrapExtensionMethod#Zomp.SyncMethodGenerator.IntegrationTests.ExtensionMethods.OneParamsAsync.g.verified.cs
│ │ ├── UnitTests.UnwrapExtensionMethod#Zomp.SyncMethodGenerator.IntegrationTests.ExtensionMethods.TwoParamsAsync.g.verified.cs
│ │ ├── UnitTests.UnwrapExtensionMethod#Zomp.SyncMethodGenerator.IntegrationTests.ExtensionMethods.ZeroParamsAsync.g.verified.cs
│ │ ├── UnitTests.VerifyAsyncParamHandling#g.verified.cs
│ │ ├── UnitTests.VerifyParamHandling#g.verified.cs
│ │ ├── UnitTests.WhenDroppingStatementLeaveTrivia#g.verified.cs
│ │ ├── UnitTests.WithAction#WithAction.g.verified.cs
│ │ └── UnitTests.WithPreprocessor#WithPreprocessorAsync.g.verified.cs
│ ├── SourceType.cs
│ ├── SpecialMethodsTests.cs
│ ├── SyncOnlyTests.cs
│ ├── SystemAsyncExtensionsTests.cs
│ ├── TestHelper.cs
│ ├── TypeTests.cs
│ └── UnitTests.cs
└── coverlet.runsettings
├── version.json
└── yarn.lock
/.config/dotnet-tools.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": 1,
3 | "isRoot": true,
4 | "tools": {
5 | "dotnet-reportgenerator-globaltool": {
6 | "version": "5.4.4",
7 | "commands": [
8 | "reportgenerator"
9 | ]
10 | }
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/.devcontainer/devcontainer.json:
--------------------------------------------------------------------------------
1 | // For format details, see https://aka.ms/devcontainer.json. For config options, see the
2 | // README at: https://github.com/devcontainers/templates/tree/main/src/dotnet
3 | {
4 | "name": "Zomp Sync Method Generator",
5 | // Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile
6 | "image": "mcr.microsoft.com/devcontainers/dotnet:8.0-jammy",
7 | // Features to add to the dev container. More info: https://containers.dev/features.
8 | // "features": {},
9 | // Configure tool-specific properties.
10 | "customizations": {
11 | // Configure properties specific to VS Code.
12 | "vscode": {
13 | "settings": {},
14 | "extensions": []
15 | }
16 | },
17 | "features": {
18 | "ghcr.io/devcontainers/features/dotnet:2": {
19 | "version": "6.0",
20 | "additionalVersions": "8.0, 9.0"
21 | },
22 | "ghcr.io/devcontainers/features/sshd:1": {
23 | "version": "latest"
24 | }
25 | },
26 | "mounts": [
27 | "source=/var/run/docker.sock,target=/var/run/docker.sock,type=bind"
28 | ],
29 | "postCreateCommand": "dotnet tool restore && dotnet restore"
30 | // Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root.
31 | // "remoteUser": "root"
32 | }
33 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | [*]
2 | end_of_line = crlf
3 | indent_style = space
4 | indent_size = 2
5 | insert_final_newline = true
6 | spelling_exclusion_path = .\.vscode\spellright.dict
7 |
8 | # Xml project files
9 | [*.{csproj,props}]
10 | indent_size = 2
11 |
12 | # C# files
13 | [*.cs]
14 | csharp_style_namespace_declarations = file_scoped
15 | dotnet_diagnostic.SA1101.severity = none
16 | dotnet_diagnostic.SA1633.severity = none
17 | # https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/3540
18 | dotnet_diagnostic.SA1118.severity = none
19 | indent_size = 4
20 | csharp_style_expression_bodied_methods = true:silent
21 | csharp_style_namespace_declarations = file_scoped
22 | csharp_style_expression_bodied_operators = true
23 | csharp_style_expression_bodied_local_functions = true
24 |
25 | # SA1005: Single line comments should begin with single space
26 | dotnet_diagnostic.SA1005.severity = none
27 |
28 | csharp_style_var_for_built_in_types = true:error
29 | csharp_style_var_when_type_is_apparent = true:error
30 | csharp_style_var_elsewhere = true:error
31 |
32 | [tests/**.cs]
33 | # CS1591: Missing XML comment for publicly visible type or member
34 | dotnet_diagnostic.CS1591.severity = none
35 | dotnet_diagnostic.CA1819.severity = none
36 | dotnet_diagnostic.CA2255.severity = none
37 |
38 | # SA1005: Single line comments should begin with single space
39 | dotnet_diagnostic.SA1005.severity = none
40 |
41 | # SA1512: Single-line comments should not be followed by blank line
42 | dotnet_diagnostic.SA1512.severity = none
43 |
44 | dotnet_diagnostic.IDE0305.severity = error
45 | dotnet_diagnostic.IDE0340.severity = error
46 |
47 | [*.sh]
48 | end_of_line = lf
49 |
--------------------------------------------------------------------------------
/.husky/.gitattributes:
--------------------------------------------------------------------------------
1 | * text eol=lf
2 |
--------------------------------------------------------------------------------
/.husky/pre-commit:
--------------------------------------------------------------------------------
1 | formatLevel=minimal
2 | if [ -n "$1" ]; then
3 | formatLevel=$1
4 | fi
5 |
6 | EXIT_STATUS=0
7 | dotnet format --verify-no-changes Zomp.SyncMethodGenerator.sln --exclude tests/Generator.Tests/Snapshots/*g.verified.cs -v $formatLevel whitespace || EXIT_STATUS=$?
8 | exit $EXIT_STATUS
9 |
--------------------------------------------------------------------------------
/.vscode/extensions.json:
--------------------------------------------------------------------------------
1 | {
2 | "recommendations": [
3 | "ban.spellright",
4 | "DavidAnson.vscode-markdownlint",
5 | "streetsidesoftware.code-spell-checker",
6 | "foxundermoon.shell-format",
7 | "GitHub.vscode-github-actions",
8 | "ms-dotnettools.csharp"
9 | ],
10 | "unwantedRecommendations": ["ban.spellright"]
11 | }
12 |
--------------------------------------------------------------------------------
/.vscode/spellright.dict:
--------------------------------------------------------------------------------
1 | awaitable
2 | codecov
3 | equatable
4 | extensi
5 | impl
6 | func
7 | Nuget
8 | numerics
9 | retval
10 | zomp
11 |
--------------------------------------------------------------------------------
/Directory.Build.props:
--------------------------------------------------------------------------------
1 |
2 |
3 | © Zomp Inc. All rights reserved.
4 | Zomp
5 | Victor Irzak
6 | false
7 | $(MSBuildThisFileDirectory)artifacts
8 | preview
9 | enable
10 | enable
11 | true
12 | true
13 | true
14 | true
15 | True
16 | true
17 | latest
18 | true
19 | AllEnabledByDefault
20 |
21 |
22 |
23 |
24 | /tmp/$(USER)/project/obj/
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 | $(NoWarn);CA1810
35 |
36 |
37 | $(NoWarn);CA1848
38 |
39 |
40 | $(NoWarn);CA1711;CA1707
41 |
42 |
43 | $(NoWarn);CA2007
44 |
45 |
46 | $(NoWarn);SA1502
47 |
48 |
49 | $(NoWarn);SA1600
50 |
51 |
52 |
53 |
--------------------------------------------------------------------------------
/Directory.Packages.props:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2022 Victor Irzak
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
--------------------------------------------------------------------------------
/Zomp.SyncMethodGenerator.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 17
4 | VisualStudioVersion = 17.4.32916.344
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Zomp.SyncMethodGenerator", "src\Zomp.SyncMethodGenerator\Zomp.SyncMethodGenerator.csproj", "{9C4836A5-FD48-4563-AFAF-EC32AD1859BD}"
7 | EndProject
8 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{120EB42D-886C-4640-9C40-89104F84BABE}"
9 | ProjectSection(SolutionItems) = preProject
10 | src\Directory.Build.props = src\Directory.Build.props
11 | EndProjectSection
12 | EndProject
13 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{AE4C95B5-1D26-4B3F-9459-4D0F70099FD5}"
14 | ProjectSection(SolutionItems) = preProject
15 | tests\coverlet.runsettings = tests\coverlet.runsettings
16 | EndProjectSection
17 | EndProject
18 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{0504B10E-4B5F-45E9-8661-05057A232157}"
19 | ProjectSection(SolutionItems) = preProject
20 | .editorconfig = .editorconfig
21 | .gitignore = .gitignore
22 | Directory.Build.props = Directory.Build.props
23 | Directory.Packages.props = Directory.Packages.props
24 | NuGet.Config = NuGet.Config
25 | package.json = package.json
26 | version.json = version.json
27 | EndProjectSection
28 | EndProject
29 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Generator.Tests", "tests\Generator.Tests\Generator.Tests.csproj", "{DEB7DF97-43ED-49D6-8C05-6B2681208610}"
30 | EndProject
31 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GenerationSandbox.Tests", "tests\GenerationSandbox.Tests\GenerationSandbox.Tests.csproj", "{BDEA21AD-6081-44AC-AD85-63803FDBED89}"
32 | EndProject
33 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".github", ".github", "{12C22879-AE16-4BD4-ADE5-1F97DDEF9E11}"
34 | EndProject
35 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{1C91E12D-2680-4E7D-9A8F-8E4548F49C62}"
36 | ProjectSection(SolutionItems) = preProject
37 | .github\workflows\build.yml = .github\workflows\build.yml
38 | EndProjectSection
39 | EndProject
40 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".husky", ".husky", "{D10EEA31-447A-4D33-A305-E5274E1B4240}"
41 | ProjectSection(SolutionItems) = preProject
42 | .husky\pre-commit = .husky\pre-commit
43 | EndProjectSection
44 | EndProject
45 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".config", ".config", "{F40847A8-EF57-4E9F-8AF6-CAB2CC20B45E}"
46 | ProjectSection(SolutionItems) = preProject
47 | .config\dotnet-tools.json = .config\dotnet-tools.json
48 | EndProjectSection
49 | EndProject
50 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".vscode", ".vscode", "{356FB7F3-77F6-4DF7-95CC-25EA735F4755}"
51 | ProjectSection(SolutionItems) = preProject
52 | .vscode\spellright.dict = .vscode\spellright.dict
53 | EndProjectSection
54 | EndProject
55 | Global
56 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
57 | Debug|Any CPU = Debug|Any CPU
58 | Release|Any CPU = Release|Any CPU
59 | EndGlobalSection
60 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
61 | {9C4836A5-FD48-4563-AFAF-EC32AD1859BD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
62 | {9C4836A5-FD48-4563-AFAF-EC32AD1859BD}.Debug|Any CPU.Build.0 = Debug|Any CPU
63 | {9C4836A5-FD48-4563-AFAF-EC32AD1859BD}.Release|Any CPU.ActiveCfg = Release|Any CPU
64 | {9C4836A5-FD48-4563-AFAF-EC32AD1859BD}.Release|Any CPU.Build.0 = Release|Any CPU
65 | {DEB7DF97-43ED-49D6-8C05-6B2681208610}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
66 | {DEB7DF97-43ED-49D6-8C05-6B2681208610}.Debug|Any CPU.Build.0 = Debug|Any CPU
67 | {DEB7DF97-43ED-49D6-8C05-6B2681208610}.Release|Any CPU.ActiveCfg = Release|Any CPU
68 | {DEB7DF97-43ED-49D6-8C05-6B2681208610}.Release|Any CPU.Build.0 = Release|Any CPU
69 | {BDEA21AD-6081-44AC-AD85-63803FDBED89}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
70 | {BDEA21AD-6081-44AC-AD85-63803FDBED89}.Debug|Any CPU.Build.0 = Debug|Any CPU
71 | {BDEA21AD-6081-44AC-AD85-63803FDBED89}.Release|Any CPU.ActiveCfg = Release|Any CPU
72 | {BDEA21AD-6081-44AC-AD85-63803FDBED89}.Release|Any CPU.Build.0 = Release|Any CPU
73 | EndGlobalSection
74 | GlobalSection(SolutionProperties) = preSolution
75 | HideSolutionNode = FALSE
76 | EndGlobalSection
77 | GlobalSection(NestedProjects) = preSolution
78 | {9C4836A5-FD48-4563-AFAF-EC32AD1859BD} = {120EB42D-886C-4640-9C40-89104F84BABE}
79 | {DEB7DF97-43ED-49D6-8C05-6B2681208610} = {AE4C95B5-1D26-4B3F-9459-4D0F70099FD5}
80 | {BDEA21AD-6081-44AC-AD85-63803FDBED89} = {AE4C95B5-1D26-4B3F-9459-4D0F70099FD5}
81 | {12C22879-AE16-4BD4-ADE5-1F97DDEF9E11} = {0504B10E-4B5F-45E9-8661-05057A232157}
82 | {1C91E12D-2680-4E7D-9A8F-8E4548F49C62} = {12C22879-AE16-4BD4-ADE5-1F97DDEF9E11}
83 | {D10EEA31-447A-4D33-A305-E5274E1B4240} = {0504B10E-4B5F-45E9-8661-05057A232157}
84 | {F40847A8-EF57-4E9F-8AF6-CAB2CC20B45E} = {0504B10E-4B5F-45E9-8661-05057A232157}
85 | {356FB7F3-77F6-4DF7-95CC-25EA735F4755} = {0504B10E-4B5F-45E9-8661-05057A232157}
86 | EndGlobalSection
87 | GlobalSection(ExtensibilityGlobals) = postSolution
88 | SolutionGuid = {0CDD8FAE-3E18-41AF-8A3B-3E12A09E0E41}
89 | EndGlobalSection
90 | EndGlobal
91 |
--------------------------------------------------------------------------------
/codecov.yml:
--------------------------------------------------------------------------------
1 | coverage:
2 | status:
3 | project:
4 | default:
5 | threshold: 10%
6 | patch:
7 | default:
8 | threshold: 10%
9 |
--------------------------------------------------------------------------------
/cspell.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://raw.githubusercontent.com/streetsidesoftware/cspell/main/cspell.schema.json",
3 | "version": "0.2",
4 | // Enable your dictionary by adding it to the list of `dictionaries`
5 | "dictionaries": ["csharp", "custom-words"],
6 | "language": "en,en-CA,softwareTerms",
7 | "languageSettings": [
8 | {
9 | "languageId": "markdown",
10 | "ignoreRegExpList": ["/`[\\s\\S]*?`/g"]
11 | }
12 | ],
13 |
14 | // Tell CSpell about your dictionary
15 | "dictionaryDefinitions": [
16 | {
17 | // The name of the dictionary is used to look it up.
18 | "name": "custom-words",
19 | // Path to the custom word file. Relative to this `cspell.json` file.
20 | "path": "./.vscode/spellright.dict",
21 | // Some editor extensions will use `addWords` for adding words to your
22 | // personal dictionary.
23 | "addWords": true
24 | }
25 | ]
26 | }
27 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "devDependencies": {
3 | "husky": "^9.1.7"
4 | },
5 | "license": "SEE LICENSE IN LICENSE",
6 | "scripts": {
7 | "prepare": "husky install"
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/src/Directory.Build.props:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Sync Method Generator
6 | git
7 | https://github.com/zompinc/sync-method-generator.git
8 | https://github.com/zompinc/sync-method-generator
9 | false
10 | snupkg
11 | true
12 | nullablePublicOnly
13 | true
14 | icon.png
15 | true
16 | true
17 | README.md
18 | MIT
19 |
20 |
21 |
22 | true
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/src/Zomp.SyncMethodGenerator/AnalyzerReleases.Shipped.md:
--------------------------------------------------------------------------------
1 | ; Shipped analyzer releases
2 | ; https://github.com/dotnet/roslyn-analyzers/blob/main/src/Microsoft.CodeAnalysis.Analyzers/ReleaseTrackingAnalyzers.Help.md
3 |
4 |
--------------------------------------------------------------------------------
/src/Zomp.SyncMethodGenerator/AnalyzerReleases.Unshipped.md:
--------------------------------------------------------------------------------
1 | ; Unshipped analyzer release
2 | ; https://github.com/dotnet/roslyn-analyzers/blob/main/src/Microsoft.CodeAnalysis.Analyzers/ReleaseTrackingAnalyzers.Help.md
3 |
4 | ### New Rules
5 |
6 | Rule ID | Category | Severity | Notes
7 | --------|----------|----------|-------
8 | ZSMGEN001 | Preprocessor | Error | DiagnosticMessages
9 | ZSMGEN002 | Preprocessor | Error | DiagnosticMessages
10 | ZSMGEN003 | Preprocessor | Error | DiagnosticMessages
11 |
--------------------------------------------------------------------------------
/src/Zomp.SyncMethodGenerator/DiagnosticMessages.cs:
--------------------------------------------------------------------------------
1 | namespace Zomp.SyncMethodGenerator;
2 |
3 | internal static class DiagnosticMessages
4 | {
5 | internal static readonly DiagnosticDescriptor InvalidNesting = new(
6 | id: "ZSMGEN001",
7 | title: $"{AsyncToSyncRewriter.SyncOnly} and !{AsyncToSyncRewriter.SyncOnly} cannot be nested inside each other",
8 | messageFormat: $"Couldn't process directive '{{0}}'. {AsyncToSyncRewriter.SyncOnly} and !{AsyncToSyncRewriter.SyncOnly} cannot be nested inside each other.",
9 | category: Preprocessor,
10 | DiagnosticSeverity.Error,
11 | isEnabledByDefault: true);
12 |
13 | internal static readonly DiagnosticDescriptor InvalidCondition = new(
14 | id: "ZSMGEN002",
15 | title: $"{AsyncToSyncRewriter.SyncOnly} and other symbols must not be in the same condition",
16 | messageFormat: $"Couldn't process condition '{{0}}'. {AsyncToSyncRewriter.SyncOnly} and other symbols must not be in the same condition.",
17 | category: Preprocessor,
18 | DiagnosticSeverity.Error,
19 | isEnabledByDefault: true);
20 |
21 | internal static readonly DiagnosticDescriptor InvalidElif = new(
22 | id: "ZSMGEN003",
23 | title: $"{AsyncToSyncRewriter.SyncOnly} cannot be used with #elif",
24 | messageFormat: $"Couldn't process directive '{{0}}'. {AsyncToSyncRewriter.SyncOnly} cannot be used with #elif.",
25 | category: Preprocessor,
26 | DiagnosticSeverity.Error,
27 | isEnabledByDefault: true);
28 |
29 | private const string Preprocessor = "Preprocessor";
30 | }
31 |
--------------------------------------------------------------------------------
/src/Zomp.SyncMethodGenerator/Extensions.cs:
--------------------------------------------------------------------------------
1 | using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory;
2 |
3 | namespace Zomp.SyncMethodGenerator;
4 |
5 | internal static class Extensions
6 | {
7 | ///
8 | /// Gets array of indices that match a predicate.
9 | ///
10 | /// The type.
11 | /// Original elements.
12 | /// The predicate.
13 | /// Array of indices that match a predicate.
14 | internal static int[] GetIndices(this IEnumerable elements, Func predicate)
15 | => elements.Select((ps, i) => (ps, i))
16 | .Where((elem, i) => predicate(elem.ps, i))
17 | .Select(t => t.i)
18 | .ToArray();
19 |
20 | internal static int[] GetIndices(this IEnumerable elements, Func predicate)
21 | => elements.GetIndices((e, _) => predicate(e));
22 |
23 | internal static bool EndsWithAsync(this string str)
24 | => str.EndsWith("Async", StringComparison.Ordinal);
25 |
26 | internal static SyntaxToken PrependSpace(this SyntaxToken token)
27 | => token.WithLeadingTrivia(Space);
28 |
29 | internal static SyntaxToken AppendSpace(this SyntaxToken token)
30 | => token.WithTrailingTrivia(Space);
31 |
32 | internal static T PrependSpace(this T syntax)
33 | where T : ExpressionSyntax
34 | => syntax.WithLeadingTrivia(Space);
35 |
36 | internal static T AppendSpace(this T syntax)
37 | where T : ExpressionSyntax
38 | => syntax.WithTrailingTrivia(Space);
39 |
40 | internal static SimpleNameSyntax ChangeIdentifier(this MemberAccessExpressionSyntax mae, string id)
41 | {
42 | return mae is { Name: GenericNameSyntax gns }
43 | ? GenericName(Identifier(id), gns.TypeArgumentList)
44 | : IdentifierName(Identifier(id));
45 | }
46 |
47 | internal static SimpleNameSyntax ChangeIdentifier(this MemberBindingExpressionSyntax mae, string id)
48 | {
49 | return mae is { Name: GenericNameSyntax gns }
50 | ? GenericName(Identifier(id), gns.TypeArgumentList)
51 | : IdentifierName(Identifier(id));
52 | }
53 |
54 | internal static BlockSyntax CreateBlock(this ICollection statements, int indentationLevel = 0)
55 | {
56 | var list = new List();
57 |
58 | var i = 0;
59 | foreach (var statement in statements)
60 | {
61 | var leading = new List();
62 | var trailing = new List() { CarriageReturnLineFeed };
63 |
64 | if (i == 0)
65 | {
66 | leading.Add(CarriageReturnLineFeed);
67 | }
68 |
69 | if (statement is IfStatementSyntax && i < statements.Count - 1)
70 | {
71 | trailing.Add(CarriageReturnLineFeed);
72 | }
73 |
74 | if (i == statements.Count - 1)
75 | {
76 | trailing.Add(Whitespace(new string(' ', 4 * indentationLevel)));
77 | }
78 |
79 | if (indentationLevel > 0)
80 | {
81 | leading.Add(Whitespace(new string(' ', 4 * (indentationLevel + 1))));
82 | }
83 |
84 | list.Add(statement.WithTrailingTrivia(trailing)
85 | .WithLeadingTrivia(leading));
86 | ++i;
87 | }
88 |
89 | return Block(List(list))
90 | .WithLeadingTrivia(CarriageReturnLineFeed, Whitespace(new string(' ', 4 * indentationLevel)));
91 | }
92 | }
93 |
--------------------------------------------------------------------------------
/src/Zomp.SyncMethodGenerator/Helpers/EquatableArray.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 |
4 | using System.Collections;
5 | using System.Diagnostics.CodeAnalysis;
6 |
7 | namespace Zomp.SyncMethodGenerator.Helpers;
8 |
9 | ///
10 | /// An immutable, equatable array. This is equivalent to but with value equality support.
11 | ///
12 | /// The type of values in the array.
13 | ///
14 | /// Modified from: https://github.com/dotnet/runtime/issues/77183#issuecomment-1284577055.
15 | /// Remove this struct when the issue above is resolved.
16 | ///
17 | ///
18 | /// Initializes a new instance of the struct.
19 | ///
20 | /// The input to wrap.
21 | [ExcludeFromCodeCoverage]
22 | internal readonly struct EquatableArray(ImmutableArray array) : IEquatable>, IEnumerable
23 | where T : IEquatable
24 | {
25 | ///
26 | /// The underlying array.
27 | ///
28 | private readonly T[]? array = Unsafe.As, T[]?>(ref array);
29 |
30 | ///
31 | /// Gets a value indicating whether the current array is empty.
32 | ///
33 | public bool IsEmpty
34 | {
35 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
36 | get => AsImmutableArray().IsEmpty;
37 | }
38 |
39 | ///
40 | /// Gets a reference to an item at a specified position within the array.
41 | ///
42 | /// The index of the item to retrieve a reference to.
43 | /// A reference to an item at a specified position within the array.
44 | public ref readonly T this[int index]
45 | {
46 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
47 | get => ref AsImmutableArray().ItemRef(index);
48 | }
49 |
50 | ///
51 | /// Implicitly converts an to .
52 | ///
53 | /// An instance from a given .
54 | public static implicit operator EquatableArray(ImmutableArray array) => FromImmutableArray(array);
55 |
56 | ///
57 | /// Implicitly converts an to .
58 | ///
59 | /// An instance from a given .
60 | public static implicit operator ImmutableArray(EquatableArray array) => array.AsImmutableArray();
61 |
62 | ///
63 | /// Checks whether two values are the same.
64 | ///
65 | /// The first value.
66 | /// The second value.
67 | /// Whether and are equal.
68 | public static bool operator ==(EquatableArray left, EquatableArray right) => left.Equals(right);
69 |
70 | ///
71 | /// Checks whether two values are not the same.
72 | ///
73 | /// The first value.
74 | /// The second value.
75 | /// Whether and are not equal.
76 | public static bool operator !=(EquatableArray left, EquatableArray right) => !left.Equals(right);
77 |
78 | ///
79 | /// Creates an instance from a given .
80 | ///
81 | /// The input instance.
82 | /// An instance from a given .
83 | public static EquatableArray FromImmutableArray(ImmutableArray array)
84 | {
85 | return new(array);
86 | }
87 |
88 | ///
89 | public bool Equals(EquatableArray array)
90 | {
91 | return AsSpan().SequenceEqual(array.AsSpan());
92 | }
93 |
94 | ///
95 | public override bool Equals([NotNullWhen(true)] object? obj)
96 | {
97 | return obj is EquatableArray array && Equals(this, array);
98 | }
99 |
100 | ///
101 | public override int GetHashCode()
102 | {
103 | if (this.array is not T[] array)
104 | {
105 | return 0;
106 | }
107 |
108 | HashCode hashCode = default;
109 |
110 | foreach (var item in array)
111 | {
112 | hashCode.Add(item);
113 | }
114 |
115 | return hashCode.ToHashCode();
116 | }
117 |
118 | ///
119 | /// Gets an instance from the current .
120 | ///
121 | /// The from the current .
122 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
123 | public ImmutableArray AsImmutableArray()
124 | {
125 | return Unsafe.As>(ref Unsafe.AsRef(in array));
126 | }
127 |
128 | ///
129 | /// Returns a wrapping the current items.
130 | ///
131 | /// A wrapping the current items.
132 | public ReadOnlySpan AsSpan()
133 | {
134 | return AsImmutableArray().AsSpan();
135 | }
136 |
137 | ///
138 | /// Copies the contents of this instance to a mutable array.
139 | ///
140 | /// The newly instantiated array.
141 | public T[] ToArray()
142 | {
143 | return [.. AsImmutableArray()];
144 | }
145 |
146 | ///
147 | /// Gets an value to traverse items in the current array.
148 | ///
149 | /// An value to traverse items in the current array.
150 | public ImmutableArray.Enumerator GetEnumerator()
151 | {
152 | return AsImmutableArray().GetEnumerator();
153 | }
154 |
155 | ///
156 | IEnumerator IEnumerable.GetEnumerator()
157 | {
158 | return ((IEnumerable)AsImmutableArray()).GetEnumerator();
159 | }
160 |
161 | ///
162 | IEnumerator IEnumerable.GetEnumerator()
163 | {
164 | return ((IEnumerable)AsImmutableArray()).GetEnumerator();
165 | }
166 | }
167 |
168 | ///
169 | /// Extensions for .
170 | ///
171 | [ExcludeFromCodeCoverage]
172 | internal static class EquatableArray
173 | {
174 | ///
175 | /// Creates an instance from a given .
176 | ///
177 | /// The type of items in the input array.
178 | /// The input instance.
179 | /// An instance from a given .
180 | public static EquatableArray AsEquatableArray(this ImmutableArray array)
181 | where T : IEquatable
182 | {
183 | return new(array);
184 | }
185 | }
186 |
--------------------------------------------------------------------------------
/src/Zomp.SyncMethodGenerator/MethodParent.cs:
--------------------------------------------------------------------------------
1 | namespace Zomp.SyncMethodGenerator;
2 |
3 | internal enum MethodParent
4 | {
5 | Class,
6 | Struct,
7 | Record,
8 | Interface,
9 | }
10 |
--------------------------------------------------------------------------------
/src/Zomp.SyncMethodGenerator/MethodParentDeclaration.cs:
--------------------------------------------------------------------------------
1 | namespace Zomp.SyncMethodGenerator;
2 |
3 | ///
4 | /// Represents a class a belongs to.
5 | ///
6 | /// Type of container.
7 | /// Class name.
8 | /// A list of modifiers.
9 | /// A list of type parameters.
10 | /// Indicates whether struct or class are explicitly specified for a record.
11 | internal sealed record MethodParentDeclaration(MethodParent MethodParent, string ParentName, EquatableArray Modifiers, EquatableArray TypeParameterListSyntax, SyntaxToken ClassOrStructKeyword)
12 | {
13 | public MethodParentDeclaration(MethodParent methodParent, SyntaxToken parentName, SyntaxTokenList modifiers, TypeParameterListSyntax? typeParameterList, SyntaxToken classOrStructKeyword = default)
14 | : this(
15 | methodParent,
16 | parentName.ValueText,
17 | modifiers.Select(z => (ushort)z.RawKind).Where(z => z != (ushort)SyntaxKind.PartialKeyword).ToImmutableArray(),
18 | (typeParameterList is null ? [] : typeParameterList.Parameters.Select(z => z.Identifier.ValueText)).ToImmutableArray(),
19 | classOrStructKeyword)
20 | {
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/Zomp.SyncMethodGenerator/MethodToGenerate.cs:
--------------------------------------------------------------------------------
1 | namespace Zomp.SyncMethodGenerator;
2 |
3 | ///
4 | /// Represents a sync method to generate from its async version.
5 | ///
6 | /// Index of the method in the source file.
7 | /// List of namespaces this method is under.
8 | /// True if namespace is file scoped.
9 | /// List of classes/structs/records this method belongs to starting from the outer-most class.
10 | /// Name of the method.
11 | /// Implementation.
12 | /// Disables nullable for the method.
13 | /// Diagnostics.
14 | /// True if there are errors in .
15 | internal sealed record MethodToGenerate(
16 | int Index,
17 | EquatableArray Namespaces,
18 | bool IsNamespaceFileScoped,
19 | EquatableArray Parents,
20 | string MethodName,
21 | string Implementation,
22 | bool DisableNullable,
23 | EquatableArray Diagnostics,
24 | bool HasErrors);
25 |
--------------------------------------------------------------------------------
/src/Zomp.SyncMethodGenerator/Models/ReportedDiagnostic.cs:
--------------------------------------------------------------------------------
1 | namespace Zomp.SyncMethodGenerator.Models;
2 |
3 | ///
4 | /// Basic diagnostic description for reporting diagnostic inside the incremental pipeline.
5 | ///
6 | /// Diagnostic descriptor.
7 | /// File path.
8 | /// Text span.
9 | /// Line span.
10 | /// Trivia.
11 | ///
12 | internal sealed record ReportedDiagnostic(DiagnosticDescriptor Descriptor, string FilePath, TextSpan TextSpan, LinePositionSpan LineSpan, string Trivia)
13 | {
14 | ///
15 | /// Implicitly converts to .
16 | ///
17 | /// Diagnostic to convert.
18 | public static implicit operator Diagnostic(ReportedDiagnostic diagnostic)
19 | => Diagnostic.Create(
20 | descriptor: diagnostic.Descriptor,
21 | location: Location.Create(diagnostic.FilePath, diagnostic.TextSpan, diagnostic.LineSpan),
22 | messageArgs: [diagnostic.Trivia]);
23 |
24 | ///
25 | /// Creates a new from and .
26 | ///
27 | /// Descriptor.
28 | /// Location.
29 | /// Trivia.
30 | /// A new .
31 | public static ReportedDiagnostic Create(DiagnosticDescriptor descriptor, Location location, string trivia)
32 | {
33 | return new(descriptor, location.SourceTree?.FilePath ?? string.Empty, location.SourceSpan, location.GetLineSpan().Span, trivia);
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/Zomp.SyncMethodGenerator/Operation.cs:
--------------------------------------------------------------------------------
1 | namespace Zomp.SyncMethodGenerator;
2 |
3 | [N.SourceGenerators.UnionTypes.UnionType(typeof(List), "NewStatements")]
4 | [N.SourceGenerators.UnionTypes.UnionType(typeof(bool), "RemoveLeadingEndIf")]
5 | internal sealed partial class Operation
6 | {
7 | }
8 |
--------------------------------------------------------------------------------
/src/Zomp.SyncMethodGenerator/SourceGenerationHelper.cs:
--------------------------------------------------------------------------------
1 | namespace Zomp.SyncMethodGenerator;
2 |
3 | ///
4 | /// Contains routines to construct a generated source file with a synchronized method.
5 | ///
6 | public static class SourceGenerationHelper
7 | {
8 | internal const string CreateSyncVersionAttributeSource = $$"""
9 | //
10 | namespace Zomp.SyncMethodGenerator
11 | {
12 | #if !SYNC_METHOD_GENERATOR_DISABLE_ATTRIBUTE_GENERATION
13 | ///
14 | /// An attribute that can be used to automatically generate a synchronous version of an async method. Must be used in a partial class.
15 | ///
16 | [System.AttributeUsage(System.AttributeTargets.Method)]
17 | internal class {{SyncMethodSourceGenerator.CreateSyncVersionAttribute}} : System.Attribute
18 | {
19 | ///
20 | /// Gets or sets a value indicating whether "#nullable enable" directive will be omitted from generated code. False by default.
21 | ///
22 | public bool {{SyncMethodSourceGenerator.OmitNullableDirective}} { get; set; }
23 | }
24 | #endif
25 | }
26 | """;
27 |
28 | [System.Diagnostics.CodeAnalysis.SuppressMessage("Style", "IDE0072:Add missing cases", Justification = "Only deal with selected SyntaxKinds")]
29 | internal static string GenerateExtensionClass(MethodToGenerate methodToGenerate)
30 | {
31 | static string GetKeyword(SyntaxKind sk) => sk switch
32 | {
33 | SyntaxKind.PublicKeyword => "public",
34 | SyntaxKind.InternalKeyword => "internal",
35 | SyntaxKind.PrivateKeyword => "private",
36 | SyntaxKind.SealedKeyword => "sealed",
37 | SyntaxKind.ProtectedKeyword => "protected",
38 | SyntaxKind.StaticKeyword => "static",
39 | SyntaxKind.AbstractKeyword => "abstract",
40 | _ => throw new InvalidOperationException($"{sk} is not supported"),
41 | };
42 |
43 | // Handle namespaces
44 | var sbBegin = new StringBuilder();
45 | var sbEnd = new StringBuilder();
46 | var i = 0;
47 |
48 | if (!methodToGenerate.IsNamespaceFileScoped)
49 | {
50 | foreach (var @namespace in methodToGenerate.Namespaces)
51 | {
52 | var indent = new string(' ', 4 * i);
53 | _ = sbBegin.Append($$"""
54 | {{indent}}namespace {{@namespace}}
55 | {{indent}}{
56 |
57 | """);
58 | _ = sbEnd.Insert(0, $$"""
59 | {{indent}}}
60 |
61 | """);
62 | ++i;
63 | }
64 | }
65 |
66 | // Handle classes
67 | foreach (var parent in methodToGenerate.Parents)
68 | {
69 | var indent = new string(' ', 4 * i);
70 |
71 | var modifiers = string.Join(string.Empty, parent.Modifiers.Select(z => GetKeyword((SyntaxKind)z) + " "));
72 | var parentType = parent.MethodParent switch
73 | {
74 | MethodParent.Class => "class",
75 | MethodParent.Interface => "interface",
76 | MethodParent.Struct => "struct",
77 | MethodParent.Record => "record"
78 | + parent.ClassOrStructKeyword.Kind() switch
79 | {
80 | SyntaxKind.StructKeyword => " struct",
81 | SyntaxKind.ClassKeyword => " class",
82 | _ => string.Empty,
83 | },
84 | _ => throw new NotImplementedException("Cannot handle the parent of the method"),
85 | };
86 |
87 | var classDeclarationLine = $"{modifiers}partial {parentType} {parent.ParentName}{(parent.TypeParameterListSyntax.IsEmpty ? string.Empty
88 | : "<" + string.Join(", ", parent.TypeParameterListSyntax) + ">")}";
89 |
90 | _ = sbBegin.Append($$"""
91 | {{indent}}{{classDeclarationLine}}
92 | {{indent}}{
93 |
94 | """);
95 | _ = sbEnd.Insert(0, $$"""
96 | {{indent}}}
97 |
98 | """);
99 | ++i;
100 | }
101 |
102 | var beforeNamespace = $"""
103 | // {(methodToGenerate.DisableNullable ? string.Empty : """
104 |
105 | #nullable enable
106 | """)}
107 | """;
108 |
109 | return methodToGenerate.IsNamespaceFileScoped ? $$"""
110 | {{beforeNamespace}}
111 | namespace {{methodToGenerate.Namespaces.First()}};
112 | {{sbBegin}}{{new string(' ', 4 * i)}}{{methodToGenerate.Implementation.Trim()}}
113 | {{sbEnd}}
114 | """
115 | : $$"""
116 | {{beforeNamespace}}
117 | {{sbBegin}}{{new string(' ', 4 * i)}}{{methodToGenerate.Implementation.Trim()}}
118 | {{sbEnd}}
119 | """;
120 | }
121 | }
122 |
--------------------------------------------------------------------------------
/src/Zomp.SyncMethodGenerator/Zomp.SyncMethodGenerator.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | git
5 | netstandard2.0
6 | false
7 | preview
8 | Generates synchronized method from async method
9 | enable
10 | true
11 | enable
12 | © Zomp Inc. All rights reserved.
13 | Zomp
14 | Victor Irzak
15 | true
16 | true
17 | $(TargetsForTfmSpecificBuildOutput);CopyProjectReferencesToPackage
18 | async sync csharp source generator
19 | true
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 | <_ReferenceCopyLocalPaths Include="@(ReferenceCopyLocalPaths->WithMetadataValue('ReferenceSourceTarget', 'ProjectReference')->WithMetadataValue('PrivateAssets', 'All'))" />
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
--------------------------------------------------------------------------------
/src/Zomp.SyncMethodGenerator/tools/install.ps1:
--------------------------------------------------------------------------------
1 | param($installPath, $toolsPath, $package, $project)
2 |
3 | $analyzersDir = Join-Path (Split-Path -Path $toolsPath -Parent) "analyzers"
4 | if (-Not (Test-Path $analyzersDir))
5 | {
6 | return
7 | }
8 |
9 | $analyzersPaths = Join-Path ( $analyzersDir ) * -Resolve
10 |
11 | foreach($analyzersPath in $analyzersPaths)
12 | {
13 | # Install the language agnostic analyzers.
14 | if (Test-Path $analyzersPath)
15 | {
16 | foreach ($analyzerFilePath in Get-ChildItem $analyzersPath -Filter *.dll)
17 | {
18 | if($project.Object.AnalyzerReferences)
19 | {
20 | $project.Object.AnalyzerReferences.Add($analyzerFilePath.FullName)
21 | }
22 | }
23 | }
24 | }
25 |
26 | # $project.Type gives the language name like (C# or VB.NET)
27 | $languageFolder = ""
28 | if($project.Type -eq "C#")
29 | {
30 | $languageFolder = "cs"
31 | }
32 | if($project.Type -eq "VB.NET")
33 | {
34 | $languageFolder = "vb"
35 | }
36 | if($languageFolder -eq "")
37 | {
38 | return
39 | }
40 |
41 | foreach($analyzersPath in $analyzersPaths)
42 | {
43 | # Install language specific analyzers.
44 | $languageAnalyzersPath = join-path $analyzersPath $languageFolder
45 | if (Test-Path $languageAnalyzersPath)
46 | {
47 | foreach ($analyzerFilePath in Get-ChildItem $languageAnalyzersPath -Filter *.dll)
48 | {
49 | if($project.Object.AnalyzerReferences)
50 | {
51 | $project.Object.AnalyzerReferences.Add($analyzerFilePath.FullName)
52 | }
53 | }
54 | }
55 | }
--------------------------------------------------------------------------------
/src/Zomp.SyncMethodGenerator/tools/uninstall.ps1:
--------------------------------------------------------------------------------
1 | param($installPath, $toolsPath, $package, $project)
2 |
3 | $analyzersDir = Join-Path (Split-Path -Path $toolsPath -Parent) "analyzers"
4 | if (-Not (Test-Path $analyzersDir))
5 | {
6 | return
7 | }
8 |
9 | $analyzersPaths = Join-Path ( $analyzersDir ) * -Resolve
10 |
11 | foreach($analyzersPath in $analyzersPaths)
12 | {
13 | # Uninstall the language agnostic analyzers.
14 | if (Test-Path $analyzersPath)
15 | {
16 | foreach ($analyzerFilePath in Get-ChildItem $analyzersPath -Filter *.dll)
17 | {
18 | if($project.Object.AnalyzerReferences)
19 | {
20 | $project.Object.AnalyzerReferences.Remove($analyzerFilePath.FullName)
21 | }
22 | }
23 | }
24 | }
25 |
26 | # $project.Type gives the language name like (C# or VB.NET)
27 | $languageFolder = ""
28 | if($project.Type -eq "C#")
29 | {
30 | $languageFolder = "cs"
31 | }
32 | if($project.Type -eq "VB.NET")
33 | {
34 | $languageFolder = "vb"
35 | }
36 | if($languageFolder -eq "")
37 | {
38 | return
39 | }
40 |
41 | foreach($analyzersPath in $analyzersPaths)
42 | {
43 | # Uninstall language specific analyzers.
44 | $languageAnalyzersPath = join-path $analyzersPath $languageFolder
45 | if (Test-Path $languageAnalyzersPath)
46 | {
47 | foreach ($analyzerFilePath in Get-ChildItem $languageAnalyzersPath -Filter *.dll)
48 | {
49 | if($project.Object.AnalyzerReferences)
50 | {
51 | try
52 | {
53 | $project.Object.AnalyzerReferences.Remove($analyzerFilePath.FullName)
54 | }
55 | catch
56 | {
57 |
58 | }
59 | }
60 | }
61 | }
62 | }
--------------------------------------------------------------------------------
/src/images/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zompinc/sync-method-generator/c4f2f3a4b173be94fc88a8977caa40c37e72b674/src/images/icon.png
--------------------------------------------------------------------------------
/stylecop.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://raw.githubusercontent.com/DotNetAnalyzers/StyleCopAnalyzers/master/StyleCop.Analyzers/StyleCop.Analyzers/Settings/stylecop.schema.json",
3 | "settings": {
4 | "documentationRules": {
5 | "companyName": "Zomp",
6 | "documentInternalElements": false
7 | },
8 | "orderingRules": {
9 | "usingDirectivesPlacement": "outsideNamespace",
10 | "systemUsingDirectivesFirst": false
11 | },
12 | "readabilityRules": {
13 | }
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/tests/GenerationSandbox.Tests/AsyncExtensions.GenericMath.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Threading;
4 |
5 | namespace GenerationSandbox.Tests;
6 |
7 | ///
8 | /// Test class.
9 | ///
10 | public static partial class AsyncExtensions
11 | {
12 | ///
13 | /// Finds maximum value so far and returns its 0 based index.
14 | ///
15 | /// Numeric type.
16 | /// Items to scan.
17 | /// The progress.
18 | /// Cancellation token.
19 | /// Max indices.
20 | [Zomp.SyncMethodGenerator.CreateSyncVersion]
21 | public static async IAsyncEnumerable IndexOfMaxSoFarAsync(this IAsyncEnumerable items, IProgress? progress = null, [EnumeratorCancellation] CancellationToken ct = default)
22 | where T : IComparisonOperators
23 | {
24 | ArgumentNullException.ThrowIfNull(items);
25 |
26 | var i = 0;
27 |
28 | T? largestSoFar = default;
29 | await foreach (var item in items)
30 | {
31 | ct.ThrowIfCancellationRequested();
32 |
33 | if ((i & 0x3ff) == 0)
34 | {
35 | progress?.Report(i);
36 | }
37 |
38 | if (largestSoFar is null || largestSoFar < item)
39 | {
40 | largestSoFar = item;
41 | yield return i;
42 | }
43 |
44 | ++i;
45 | }
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/tests/GenerationSandbox.Tests/AsyncExtensions.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Threading;
5 |
6 | namespace GenerationSandbox.Tests;
7 |
8 | ///
9 | /// Test class.
10 | ///
11 | public static partial class AsyncExtensions
12 | {
13 | ///
14 | /// Calculates rolling average.
15 | ///
16 | /// Items to average.
17 | /// Size of averaging window.
18 | /// Reports progress.
19 | /// Cancellation token.
20 | /// Moving averages.
21 | ///
22 | /// Credit: modified from https://www.codeguru.co.in/2021/06/moving-average-in-c-using-linq.html.
23 | ///
24 | [Zomp.SyncMethodGenerator.CreateSyncVersion]
25 | public static async IAsyncEnumerable MovingAverageAsync(this IAsyncEnumerable source, int windowSize, IProgress? progress = null, [EnumeratorCancellation] CancellationToken ct = default)
26 | {
27 | #if NETFRAMEWORK
28 | if (source is null)
29 | {
30 | throw new ArgumentNullException(nameof(source));
31 | }
32 | #else
33 | ArgumentNullException.ThrowIfNull(source);
34 | #endif
35 |
36 | var queue = new Queue(windowSize);
37 |
38 | var i = 0;
39 | await foreach (var d in source)
40 | {
41 | ct.ThrowIfCancellationRequested();
42 |
43 | // report progress every 4 iterations
44 | if ((i & 0x3) == 0)
45 | {
46 | progress?.Report(i);
47 | }
48 |
49 | if (queue.Count == windowSize)
50 | {
51 | queue.Dequeue();
52 | }
53 |
54 | queue.Enqueue(d);
55 | yield return queue.Average();
56 | ++i;
57 | }
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/tests/GenerationSandbox.Tests/AsyncWithIProgress.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Threading.Tasks;
3 |
4 | namespace GenerationSandbox.Tests;
5 |
6 | internal sealed partial class AsyncWithIProgress
7 | {
8 | public static async Task WithIProgressAsync(IProgress? progress = null)
9 | {
10 | await Task.CompletedTask;
11 | }
12 |
13 | public static void WithIProgress()
14 | {
15 | }
16 |
17 | [Zomp.SyncMethodGenerator.CreateSyncVersion]
18 | public static async Task CallWithIProgressAsync()
19 | {
20 | CustomProgress progress = new();
21 |
22 | if (true)
23 | {
24 | progress++;
25 | }
26 |
27 | await WithIProgressAsync(progress);
28 | }
29 |
30 | private sealed class CustomProgress : IProgress
31 | {
32 | public static CustomProgress operator ++(CustomProgress a) => a;
33 |
34 | public void Report(float value) => throw new NotImplementedException();
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/tests/GenerationSandbox.Tests/GenerationSandbox.Tests.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | $(NoWarn);CA1062;CA1303;CA1508;CA1515;CA1812;CA1815;CA1822;CA1829;CA1852;CA2000;CA5394
6 | $(NoWarn);CS0219;CS0162;CS1998;CS8603;CS8619
7 | $(NoWarn);IDE0004;IDE0005;IDE0007;IDE0011;IDE0035;IDE0040;IDE0041;IDE0058;IDE0060;IDE0065
8 | $(NoWarn);RS1035
9 | $(NoWarn);SA1200;SA1201;SA1202;SA1204;SA1400;SA1402;SA1403;SA1404;SA1601
10 | false
11 | net8.0
12 | $(TargetFrameworks);net472
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/tests/GenerationSandbox.Tests/SyncTests.cs:
--------------------------------------------------------------------------------
1 | #if NET8_0_OR_GREATER
2 | using System.Linq;
3 | #endif
4 | using Xunit;
5 |
6 | namespace GenerationSandbox.Tests;
7 |
8 | public class SyncTests
9 | {
10 | [Fact]
11 | public void TestGeneratedAverageRoutine()
12 | {
13 | var expected = new double[] { 9, 9.5, 8, 7.333333333333333, 5, 4, 2 };
14 | var myNumbers = new double[] { 9, 10, 5, 7, 3, 2, 1 };
15 | var result = myNumbers.MovingAverage(3);
16 | Assert.Equal(expected, result);
17 | }
18 |
19 | [Fact]
20 | public void TestStaticAsyncWithIProgress()
21 | => AsyncWithIProgress.CallWithIProgress();
22 |
23 | #if NET8_0_OR_GREATER
24 | [Fact]
25 | public void TestIndexOfMaxSoFar()
26 | {
27 | var expected = new int[] { 0, 1, 4 };
28 | var myNumbers = new int[] { 9, 10, 5, 7, 11, 2, 1 };
29 | var result = myNumbers.IndexOfMaxSoFar().ToArray();
30 | Assert.Equal(expected, result);
31 | }
32 | #endif
33 | }
34 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/ArgumentTests.cs:
--------------------------------------------------------------------------------
1 | namespace Generator.Tests;
2 |
3 | public class ArgumentTests
4 | {
5 | [Fact]
6 | public Task DropNullArgument() => """
7 | public void ProgressMethodAsync() { }
8 |
9 | public async Task ProgressMethodAsync(IProgress? a) => await Task.CompletedTask;
10 |
11 | [Zomp.SyncMethodGenerator.CreateSyncVersion]
12 | public async Task CallProgressMethodAsync()
13 | {
14 | await ProgressMethodAsync(null);
15 | }
16 | """.Verify();
17 |
18 | [Fact]
19 | public Task DropNamedArgument() => """
20 | public void ProgressMethod(int p1 = 0, int p2 = 0) { }
21 |
22 | public async Task ProgressMethodAsync(int p1 = 0, int p2 = 0, IProgress? progress = null) => await Task.CompletedTask;
23 |
24 | [Zomp.SyncMethodGenerator.CreateSyncVersion]
25 | public async Task CallProgressMethodAsync()
26 | {
27 | await ProgressMethodAsync(progress: null);
28 | }
29 | """.Verify();
30 | }
31 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/ConditionalExtensionTests.cs:
--------------------------------------------------------------------------------
1 | namespace Generator.Tests;
2 |
3 | public class ConditionalExtensionTests
4 | {
5 | [Fact]
6 | public Task NullConditionalWithoutExtension() => """
7 | Assembly? a = null;
8 | _ = a?.ToString();
9 | """.Verify(sourceType: SourceType.MethodBody);
10 |
11 | [Fact]
12 | public Task NullConditionalExtension() => """
13 | Assembly? a = null;
14 | _ = a?.GetCustomAttributes();
15 | """.Verify(sourceType: SourceType.MethodBody);
16 |
17 | [Fact]
18 | public Task StartWithExpression() => """
19 | _ = GetType().Assembly?.GetCustomAttributes();
20 | """.Verify(sourceType: SourceType.MethodBody);
21 |
22 | [Fact]
23 | public Task NullConditionalExtensionChained() => """
24 | Assembly? a = null;
25 | _ = a?.GetCustomAttributes()?.ToList();
26 | """.Verify(sourceType: SourceType.MethodBody);
27 |
28 | [Fact]
29 | public Task LongChained() => """
30 | Assembly? a = null;
31 | _ = a?.GetCustomAttributes()
32 | ?.ToList()
33 | ?.Where(z => 1 == 0)
34 | ?.Where(z => 2 == 0)
35 | ?.Where(z => 3 == 0);
36 | """.Verify(sourceType: SourceType.MethodBody);
37 |
38 | [Fact]
39 | public Task CheckArrayNullability() => """
40 | int[]? array = null;
41 | var z = array?.Single();
42 | """.Verify(sourceType: SourceType.MethodBody);
43 |
44 | [Fact]
45 | public Task KeepTypeParameters() => """
46 | string[]? arr = [];
47 | _ = arr?.Select(z => null);
48 | """.Verify(sourceType: SourceType.MethodBody);
49 |
50 | [Fact]
51 | public Task HandleCastForNull()
52 | => "_ = ((string[]?)null)?.Select(z => null);"
53 | .Verify(sourceType: SourceType.MethodBody);
54 |
55 | [Fact]
56 | public Task HandleCastForArray()
57 | => "_ = ((string[]?)[])?.Select(z => null);"
58 | .Verify(sourceType: SourceType.MethodBody);
59 |
60 | #if NET8_0_OR_GREATER
61 | [Fact]
62 | public Task ConditionalToExtension() => """
63 | [CreateSyncVersion]
64 | public static async Task MethodAsync(IEnumerable? integers)
65 | {
66 | var res = integers?.Chunk(2).First();
67 | }
68 | """.Verify();
69 | #endif
70 | }
71 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/DelegateTests.cs:
--------------------------------------------------------------------------------
1 | namespace Generator.Tests;
2 |
3 | public class DelegateTests
4 | {
5 | [Theory]
6 | [InlineData("await Task.CompletedTask;")]
7 | [InlineData("{ await Task.CompletedTask; };")]
8 | public Task DropCompletedTaskFromLambda(string statements)
9 | => $"var delAsync = async () => {statements}"
10 | .Verify(disableUnique: true, sourceType: SourceType.MethodBody);
11 |
12 | [Fact]
13 | public Task AsyncDelegate() => """
14 | var delAsync = async () => await Task.CompletedTask;
15 | await delAsync();
16 | """.Verify(sourceType: SourceType.MethodBody);
17 |
18 | [Fact]
19 | public Task FuncToActionInParameter() => """
20 | [CreateSyncVersion]
21 | async Task MethodAsync(Func bar)
22 | {
23 | await bar(5);
24 | }
25 | """.Verify();
26 |
27 | [Fact]
28 | public Task FuncToActionInParameterExplicitInvoke() => """
29 | [CreateSyncVersion]
30 | async Task MethodAsync(Func bar)
31 | {
32 | await bar.Invoke();
33 | }
34 | """.Verify();
35 |
36 | [Fact]
37 | public Task FuncToActionInParameterTwice() => """
38 | [CreateSyncVersion]
39 | async Task MethodAsync(Func> bar)
40 | {
41 | await bar()();
42 | }
43 | """.Verify();
44 |
45 | [Fact]
46 | public Task FuncToActionInParameterTwiceExplicitInvoke() => """
47 | [CreateSyncVersion]
48 | async Task MethodAsync(Func> bar)
49 | {
50 | await bar().Invoke();
51 | }
52 | """.Verify();
53 |
54 | [Fact]
55 | public Task FuncToActionInParameterTwiceWithArgument() => """
56 | [CreateSyncVersion]
57 | async Task MethodAsync(Func> bar)
58 | {
59 | await bar(9)();
60 | }
61 | """.Verify();
62 |
63 | [Theory]
64 | [InlineData(true)]
65 | [InlineData(false)]
66 | public Task AsyncDelegateWithCancellationToken(bool explicitParameter)
67 | {
68 | var @explicit = explicitParameter ? "CancellationToken " : string.Empty;
69 | return $"""
70 | Func> delAsync = async ({@explicit}ct) => await Task.FromResult(2);
71 | var result = await delAsync(CancellationToken.None);
72 | """.Verify(disableUnique: true, sourceType: SourceType.MethodBody);
73 | }
74 |
75 | [Fact]
76 | public Task AsyncDelegateWithParameter()
77 | => "Func delAsync = async (p, s) => await Task.CompletedTask;"
78 | .Verify(sourceType: SourceType.MethodBody);
79 |
80 | [Fact]
81 | public Task AsyncVarDelegateWithParameter()
82 | => "var delAsync = async (Point p, Size s) => await Task.CompletedTask;"
83 | .Verify(sourceType: SourceType.MethodBody);
84 |
85 | [Fact]
86 | public Task AsyncVarDelegateWithParameterAndReturnType()
87 | => "var delAsync = async (Point p, Size s) => await Task.FromResult(p);"
88 | .Verify(sourceType: SourceType.MethodBody);
89 |
90 | [Theory]
91 | [InlineData("null!")]
92 | [InlineData("new Progress()")]
93 | public Task AsyncDelegateWithIProgress(string iProgressArg) => $"""
94 | Func, CancellationToken, Task> delAsync = async (p, ct) => await Task.FromResult(2);
95 | var result = await delAsync({iProgressArg}, CancellationToken.None);
96 | """.Verify(disableUnique: true, sourceType: SourceType.MethodBody);
97 |
98 | [Theory]
99 |
100 | [InlineData("null")]
101 | [InlineData("new Progress()")]
102 | public Task AsyncDelegateWithNullableIProgress(string iProgressArg) => $"""
103 | Func?, CancellationToken, Task> delAsync = async (p, ct) => await Task.FromResult(2);
104 | var result = await delAsync({iProgressArg}, CancellationToken.None);
105 | """.Verify(disableUnique: true, sourceType: SourceType.MethodBody);
106 |
107 | [Fact]
108 | public Task AsyncDelegateExplicit() => """
109 | Func delAsync = async () => await Task.CompletedTask;
110 | await delAsync();
111 | """.Verify(sourceType: SourceType.MethodBody);
112 | }
113 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/ExtensionMethodTests.cs:
--------------------------------------------------------------------------------
1 | namespace Generator.Tests;
2 |
3 | public class ExtensionMethodTests
4 | {
5 | [Fact]
6 | public Task UnwrapGenericExtensionMethod() => """
7 | using System.Drawing;
8 | using System.Threading;
9 | using System.Threading.Tasks;
10 |
11 | namespace Zomp.SyncMethodGenerator.IntegrationTests
12 | {
13 | using Extensi.ons123;
14 | partial class Extensions
15 | {
16 | [CreateSyncVersion]
17 | public static async Task HasGenericExtensionAsync(object o, CancellationToken ct)
18 | {
19 | var z = o.TryGetValue(out var item);
20 | }
21 |
22 | [CreateSyncVersion]
23 | public static async Task HasGeneric2ExtensionAsync(object o, CancellationToken ct)
24 | {
25 | var z = o.TryGetValue(out var _, out var _1);
26 | }
27 | }
28 | }
29 |
30 | namespace Extensi.ons123
31 | {
32 | internal static class MyExtensionClass
33 | {
34 | public static bool TryGetValue(this object _, out T? item)
35 | {
36 | item = default;
37 | return false;
38 | }
39 |
40 | public static bool TryGetValue(this object _, out T1? item1, out T2? item2)
41 | {
42 | item1 = default;
43 | item2 = default;
44 | return false;
45 | }
46 | }
47 | }
48 | """.Verify(sourceType: SourceType.Full);
49 |
50 | [Fact]
51 | public Task LeftOfTheDotTest() => """
52 | namespace Tests;
53 |
54 | internal class Bar
55 | {
56 | public static Bar Create() => new Bar();
57 | }
58 |
59 | partial class Class
60 | {
61 | [Zomp.SyncMethodGenerator.CreateSyncVersion]
62 | public async Task MethodAsync()
63 | {
64 | _ = Bar.Create()?.DoSomething();
65 | }
66 | }
67 |
68 | internal static class BarExtension
69 | {
70 | public static Bar DoSomething(this Bar bar) => bar;
71 | }
72 | """.Verify(sourceType: SourceType.Full);
73 | }
74 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/ExternalLibraryTests.cs:
--------------------------------------------------------------------------------
1 | namespace Generator.Tests;
2 |
3 | public class ExternalLibraryTests
4 | {
5 | #if NETCOREAPP1_0_OR_GREATER
6 | [Fact]
7 | public Task ToListAsync() => """
8 | [CreateSyncVersion]
9 | public async Task MethodAsync(IAsyncEnumerable @enum)
10 | {
11 | _ = await @enum.ToListAsync();
12 | }
13 | """.Verify();
14 | #endif
15 | }
16 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/FileNameTests.cs:
--------------------------------------------------------------------------------
1 | namespace Generator.Tests;
2 |
3 | public class FileNameTests
4 | {
5 | [Fact]
6 | public Task DoNotCollideClassNames() => """
7 | namespace Test;
8 |
9 | public partial class Class
10 | {
11 | [CreateSyncVersion]
12 | public async Task MethodAsync()
13 | {
14 | }
15 | }
16 |
17 | public partial class Class
18 | {
19 | [CreateSyncVersion]
20 | public async Task MethodAsync()
21 | {
22 | }
23 | }
24 |
25 | public partial class Class
26 | {
27 | [CreateSyncVersion]
28 | public async Task MethodAsync()
29 | {
30 | }
31 | }
32 | """.Verify(sourceType: SourceType.Full);
33 | }
34 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Generator.Tests.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net8.0
5 | $(TargetFrameworks);net472
6 | false
7 | preview
8 | $(NoWarn);CA1515;RS1035
9 |
10 |
11 | true
12 | true
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 | all
22 | runtime; build; native; contentfiles; analyzers; buildtransitive
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/GenericMathTests.cs:
--------------------------------------------------------------------------------
1 | namespace Generator.Tests;
2 |
3 | public class GenericMathTests
4 | {
5 | [Fact]
6 | public Task GeneratesWithIProgressCorrectly() => $$"""
7 | namespace Test
8 | {
9 | public static partial class EnumerableExtensions
10 | {
11 | ///
12 | /// Finds maximum value so far and returns its 0 based index
13 | ///
14 | /// Numeric type
15 | /// Items to scan.
16 | /// The progress
17 | /// Cancellation token
18 | /// Max indices
19 | [CreateSyncVersion]
20 | public static async IAsyncEnumerable IndexOfMaxSoFarAsync(this IAsyncEnumerable items, IProgress? progress = null, [EnumeratorCancellation] CancellationToken ct = default)
21 | #if NET8_0_OR_GREATER
22 | where T : IComparisonOperators
23 | #else
24 | where T : IComparisonOperators
25 | #endif
26 | {
27 | var i = 0;
28 |
29 | T? largestSoFar = default;
30 | await foreach (var item in items)
31 | {
32 | ct.ThrowIfCancellationRequested();
33 |
34 | if ((i & 0x3ff) == 0)
35 | {
36 | progress?.Report(i);
37 | }
38 |
39 | if (largestSoFar is null || largestSoFar < item)
40 | {
41 | largestSoFar = item;
42 | yield return i;
43 | }
44 |
45 | ++i;
46 | }
47 | }
48 | }
49 | }
50 | """.Verify(true, sourceType: SourceType.Full);
51 | }
52 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/IncrementalGeneratorTests.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using Zomp.SyncMethodGenerator;
3 |
4 | namespace Generator.Tests;
5 |
6 | public class IncrementalGeneratorTests
7 | {
8 | [Theory]
9 | [InlineData(
10 | IncrementalStepRunReason.Cached,
11 | IncrementalStepRunReason.Unchanged,
12 | IncrementalStepRunReason.Cached,
13 | """
14 | using System;
15 | using System.Threading.Tasks;
16 |
17 | class Test
18 | {
19 | public void ProgressMethod() { }
20 | public Task ProgressMethodAsync() => Task.CompletedTask;
21 |
22 | [Zomp.SyncMethodGenerator.CreateSyncVersion]
23 | public async Task CallProgressMethodAsync()
24 | {
25 | await ProgressMethodAsync();
26 | }
27 | }
28 | """,
29 | """
30 | using System;
31 | using System.Threading.Tasks;
32 |
33 | class Test
34 | {
35 | public void ProgressMethod() { }
36 | public Task ProgressMethodAsync() => Task.Yield();
37 |
38 | [Zomp.SyncMethodGenerator.CreateSyncVersion]
39 | public async Task CallProgressMethodAsync()
40 | {
41 | await ProgressMethodAsync();
42 | }
43 | }
44 | """)]
45 | [InlineData(
46 | IncrementalStepRunReason.Modified,
47 | IncrementalStepRunReason.Modified,
48 | IncrementalStepRunReason.Modified,
49 | """
50 | using System;
51 | using System.Threading.Tasks;
52 |
53 | class Test
54 | {
55 | public void ProgressMethod() { }
56 | public Task ProgressMethodAsync() => Task.CompletedTask;
57 |
58 | [Zomp.SyncMethodGenerator.CreateSyncVersion]
59 | public async Task CallProgressMethodAsync()
60 | {
61 | }
62 | }
63 | """,
64 | """
65 | using System;
66 | using System.Threading.Tasks;
67 |
68 | class Test
69 | {
70 | public void ProgressMethod() { }
71 | public Task ProgressMethodAsync() => Task.CompletedTask;
72 |
73 | [Zomp.SyncMethodGenerator.CreateSyncVersion]
74 | public async Task CallProgressMethodAsync()
75 | {
76 | await ProgressMethodAsync();
77 | }
78 | }
79 | """)]
80 | public void CheckGeneratorIsIncremental(
81 | IncrementalStepRunReason sourceStepReason,
82 | IncrementalStepRunReason executeStepReason,
83 | IncrementalStepRunReason combineStepReason,
84 | string source,
85 | string sourceUpdated)
86 | {
87 | var baseSyntaxTree = CSharpSyntaxTree.ParseText(source);
88 |
89 | Compilation compilation = CSharpCompilation.Create(
90 | "compilation",
91 | [baseSyntaxTree],
92 | [MetadataReference.CreateFromFile(typeof(Binder).GetTypeInfo().Assembly.Location)],
93 | new CSharpCompilationOptions(OutputKind.ConsoleApplication));
94 |
95 | var sourceGenerator = new SyncMethodSourceGenerator().AsSourceGenerator();
96 |
97 | GeneratorDriver driver = CSharpGeneratorDriver.Create(
98 | generators: [sourceGenerator],
99 | driverOptions: new GeneratorDriverOptions(default, trackIncrementalGeneratorSteps: true));
100 |
101 | // Run the generator
102 | driver = driver.RunGenerators(compilation);
103 |
104 | // Update the compilation and rerun the generator
105 | compilation = compilation.ReplaceSyntaxTree(baseSyntaxTree, CSharpSyntaxTree.ParseText(sourceUpdated));
106 | driver = driver.RunGenerators(compilation);
107 |
108 | var result = driver.GetRunResult().Results.Single();
109 | var sourceOutputs =
110 | result.TrackedOutputSteps.SelectMany(outputStep => outputStep.Value).SelectMany(output => output.Outputs);
111 | var (value, reason) = Assert.Single(sourceOutputs);
112 | Assert.Equal(sourceStepReason, reason);
113 | Assert.Equal(executeStepReason, result.TrackedSteps["GetMethodToGenerate"].Single().Outputs[0].Reason);
114 | Assert.Equal(combineStepReason, result.TrackedSteps["GenerateSource"].Single().Outputs[0].Reason);
115 | }
116 | }
117 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/IntegrationTesting.cs:
--------------------------------------------------------------------------------
1 | namespace Generator.Tests;
2 |
3 | public class IntegrationTesting
4 | {
5 | #if NETCOREAPP1_0_OR_GREATER
6 | [Fact]
7 | public Task GeneratesSyncMethodCorrectly() => """
8 | namespace Test
9 | {
10 | public static partial class EnumerableExtensions
11 | {
12 | [CreateSyncVersion]
13 | public static async IAsyncEnumerable GetAveragesAsync(this IAsyncEnumerable list, int adjacentCount, [EnumeratorCancellation] CancellationToken ct = default)
14 | where T : IConvertible
15 | {
16 | double total = 0;
17 |
18 | int avgCount = adjacentCount * 2 + 1;
19 |
20 | var meanQueue = new Queue();
21 | await foreach (var o in list.WithCancellation(ct).ConfigureAwait(false))
22 | {
23 | var item = o.ToDouble(null);
24 | if (meanQueue.Count == avgCount)
25 | {
26 | total -= meanQueue.Dequeue();
27 | }
28 | meanQueue.Enqueue(item);
29 | total += item;
30 |
31 | if (meanQueue.Count == avgCount)
32 | {
33 | yield return total / avgCount;
34 | }
35 | }
36 | }
37 | }
38 | }
39 | """.Verify(sourceType: SourceType.Full);
40 | #endif
41 |
42 | [Fact]
43 | public Task WithIAsyncEnumerator() => """
44 | [CreateSyncVersion]
45 | async Task EnumeratorTestAsync(IAsyncEnumerable range, CancellationToken ct)
46 | {
47 | IAsyncEnumerator e = range.GetAsyncEnumerator(ct);
48 | try
49 | {
50 | while (await e.MoveNextAsync().ConfigureAwait(false)) Console.Write(e.Current + " ");
51 | }
52 | finally { if (e != null) await e.DisposeAsync(); }
53 | }
54 | """.Verify();
55 |
56 | [Fact]
57 | public Task CombineTwoLists() => """
58 | [CreateSyncVersion]
59 | public static async IAsyncEnumerable<(TLeft Left, TRight Right)> CombineAsync(this IAsyncEnumerable list1, IAsyncEnumerable list2, [EnumeratorCancellation] CancellationToken ct = default)
60 | {
61 | await using var enumerator2 = list2.GetAsyncEnumerator(ct);
62 | await foreach (var item in list1.WithCancellation(ct).ConfigureAwait(false))
63 | {
64 | if (!(await enumerator2.MoveNextAsync().ConfigureAwait(false)))
65 | {
66 | throw new InvalidOperationException("Must have the same size");
67 | }
68 | yield return (item, enumerator2.Current);
69 | }
70 | }
71 | """.Verify();
72 |
73 | #if NETCOREAPP1_0_OR_GREATER
74 | [Fact]
75 | public Task ChecksumRead() => """
76 | [CreateSyncVersion]
77 | static async Task HalfCheckSumAsync(Memory buffer, Stream stream, CancellationToken ct)
78 | => (await ChecksumReadAsync(buffer, stream, ct).ConfigureAwait(false)) / 2;
79 |
80 | [CreateSyncVersion]
81 | static async Task ChecksumReadAsync(Memory buffer, Stream stream, CancellationToken ct)
82 | {
83 | int bytesRead = await stream.ReadAsync(buffer, ct).ConfigureAwait(true);
84 | return Checksum(buffer.Span.Slice(0, bytesRead));
85 | }
86 | static int Checksum(Span buffer) => 0;
87 | """.Verify();
88 |
89 | // From: https://devblogs.microsoft.com/premier-developer/dissecting-the-local-functions-in-c-7/#use-case-2-eager-preconditions-in-async-methods
90 | [Fact]
91 | public Task EagerPreconditionsInAsyncMethod() => """
92 | [CreateSyncVersion]
93 | public static Task GetAllTextAsync(string fileName)
94 | {
95 | // Eager argument validation
96 | if (string.IsNullOrEmpty(fileName)) throw new ArgumentNullException(nameof(fileName));
97 | return GetAllTextAsync();
98 |
99 | async Task GetAllTextAsync()
100 | {
101 | var result = await File.ReadAllTextAsync(fileName);
102 | return result;
103 | }
104 | }
105 | """.Verify();
106 | #endif
107 |
108 | // Modified from: https://devblogs.microsoft.com/premier-developer/dissecting-the-local-functions-in-c-7/#use-case-1-eager-preconditions-in-iterator-blocks
109 | [Fact]
110 | public Task EagerPreconditionInIteratorBlock() => """
111 | [CreateSyncVersion]
112 | public static IAsyncEnumerable ReadLineByLineAsync(string fileName)
113 | {
114 | if (string.IsNullOrEmpty(fileName)) throw new ArgumentNullException(nameof(fileName));
115 |
116 | return ReadLineByLineImpl();
117 |
118 | async IAsyncEnumerable ReadLineByLineImpl()
119 | {
120 | await foreach (var line in CreateAsyncEnumerable())
121 | {
122 | yield return line;
123 | }
124 | }
125 |
126 | async IAsyncEnumerable CreateAsyncEnumerable()
127 | {
128 | foreach (var i in new[] { "a", "b" })
129 | {
130 | yield return await Task.FromResult(i);
131 | }
132 | }
133 | }
134 | """.Verify();
135 | }
136 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/InterpolatedStringTests.cs:
--------------------------------------------------------------------------------
1 | namespace Generator.Tests;
2 |
3 | public class InterpolatedStringTests
4 | {
5 | [Theory]
6 | [InlineData("await File.ReadAllTextAsync(\"123\")")]
7 | [InlineData("(await File.ReadAllTextAsync(\"123\"))")]
8 | public Task EnsureParentheses(string call) => $$"""
9 | var z = $"123{{{call}}}456";
10 | """.Verify(false, true, sourceType: SourceType.MethodBody);
11 |
12 | [Theory]
13 | [InlineData("await File.ReadAllTextAsync(\"123\")")]
14 | [InlineData("(await File.ReadAllTextAsync(\"123\"))")]
15 | public Task HandleFormatString(string call) => $$"""
16 | var z = $"123{{{call}}:hh}456";
17 | """.Verify(false, true, sourceType: SourceType.MethodBody);
18 | }
19 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/IsCancellationRequestedTests.cs:
--------------------------------------------------------------------------------
1 | namespace Generator.Tests;
2 |
3 | public class IsCancellationRequestedTests
4 | {
5 | [Fact]
6 | public Task WhileNotCancelled() => $$"""
7 | while (((!((ct.IsCancellationRequested)))))
8 | {
9 | await Task.Delay(120000, ct);
10 | }
11 | """.Verify(sourceType: SourceType.MethodBody);
12 |
13 | [Fact]
14 | public Task IfCancelled() => $$"""
15 | if (((((ct.IsCancellationRequested)))))
16 | {
17 | await Task.Delay(120000, ct);
18 | }
19 | """.Verify(sourceType: SourceType.MethodBody);
20 |
21 | [Fact]
22 | public Task IfNotCancelled() => $$"""
23 | if (((!((ct.IsCancellationRequested)))))
24 | {
25 | await Task.Delay(120000, ct);
26 | }
27 | """.Verify(sourceType: SourceType.MethodBody);
28 | }
29 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/MemoryTests.cs:
--------------------------------------------------------------------------------
1 | namespace Generator.Tests;
2 |
3 | public class MemoryTests
4 | {
5 | #if NETCOREAPP1_0_OR_GREATER
6 | [Fact]
7 | public Task MemoryToSpan() => """
8 | [CreateSyncVersion]
9 | private async Task ReadAsMemoryAsync(Stream stream, byte[] sampleBytes, CancellationToken ct = default)
10 | => await stream.ReadAsync(sampleBytes.AsMemory(0, 123), ct).ConfigureAwait(false);
11 | """.Verify();
12 |
13 | [InlineData(false)]
14 | [InlineData(true)]
15 | [Theory]
16 | public Task MemorySpanProperty(bool explicitType)
17 | {
18 | var typeName = explicitType ? "Memory" : "var";
19 |
20 | return $$"""
21 | [CreateSyncVersion]
22 | private async Task MakeArray(byte[] sampleBytes, CancellationToken ct = default)
23 | {
24 | {{typeName}} mem = sampleBytes.AsMemory(0, 123);
25 | var arr = mem.Span.ToArray();
26 | }
27 | """.Verify(false, false, parameters: explicitType);
28 | }
29 |
30 | [Fact]
31 | public Task ReadOnlyMemoryToReadOnlySpan() => """
32 | [CreateSyncVersion]
33 | static async Task WriteAsync(ReadOnlyMemory buffer, Stream stream, CancellationToken ct)
34 | => await stream.WriteAsync(buffer, ct).ConfigureAwait(true);
35 | """.Verify();
36 | #endif
37 |
38 | [Fact]
39 | public Task DropSpanAfterAsMemory() => """
40 | [CreateSyncVersion]
41 | public async Task MakeArrayAsync(byte[] sampleBytes, CancellationToken ct = default)
42 | {
43 | var arr = sampleBytes.AsMemory(0, 123).Span.ToArray();
44 | }
45 | """.Verify();
46 |
47 | [Fact]
48 | public Task DropSpanAfterAsMemoryWithWhitespace() => """
49 | [CreateSyncVersion]
50 | public async Task MakeArrayAsync(byte[] sampleBytes, CancellationToken ct = default)
51 | {
52 | var arr =
53 | sampleBytes.AsMemory(0, 123).Span.ToArray();
54 | }
55 | """.Verify();
56 |
57 | [Fact]
58 | public Task PreserveUnrelatedSpan() => """
59 | [CreateSyncVersion]
60 | public async Task HasMemoryAsync(Memory mem)
61 | {
62 | void Inner()
63 | {
64 | Unrelated mem = new();
65 | int shouldBeInt = mem.Span;
66 | }
67 | }
68 |
69 | class Unrelated
70 | {
71 | public int Span { get; set; }
72 | }
73 | """.Verify();
74 |
75 | [Fact]
76 | public Task NonPredefinedTypes() => """
77 | using N2;
78 | using static N2.C1;
79 |
80 | namespace N1
81 | {
82 | partial class Class
83 | {
84 | [CreateSyncVersion]
85 | async Task FillAsync(Memory accelerometers)
86 | {
87 | C2.Accelerometer a = new(1, 2, 3);
88 | accelerometers.Span[0] = a;
89 | }
90 | }
91 | }
92 |
93 | namespace N2
94 | {
95 | internal class C1
96 | {
97 | public class C2
98 | {
99 | public record struct Accelerometer(short X, short Y, short Z);
100 | }
101 | }
102 | }
103 | """.Verify(sourceType: SourceType.Full);
104 |
105 | [Fact]
106 | public Task ConvertMemoryToSpan() => """
107 | Memory GetMemory() => MemoryPool.Shared.Rent().Memory;
108 |
109 | [CreateSyncVersion]
110 | async Task MethodAsync()
111 | {
112 | var m = GetMemory();
113 | }
114 | """.Verify();
115 |
116 | [Fact]
117 | public Task ConvertMemoryToSpanAfterPropertyAccess() => """
118 | var m = MemoryPool.Shared.Rent().Memory;
119 | """.Verify(sourceType: SourceType.MethodBody);
120 | }
121 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/ModuleInitializer.cs:
--------------------------------------------------------------------------------
1 | using System.Text.RegularExpressions;
2 |
3 | namespace Generator.Tests;
4 |
5 | ///
6 | /// Module initializer.
7 | ///
8 | public static partial class ModuleInitializer
9 | {
10 | private const string MethodTestCasePattern = "void Method\\(\\)\\s*{\\r\\n(.*)}";
11 | private const string SimpleTestCasePattern = "// \\s*#nullable enable\\s*namespace Test;\\s*partial class Class\\s*{\\r\\n(.*)}";
12 | private const string DefaultTestPathPattern = "Test\\.Class\\.(MethodAsync\\.)?";
13 |
14 | [System.Runtime.CompilerServices.ModuleInitializer]
15 | public static void Initialize()
16 | {
17 | VerifySourceGenerators.Initialize();
18 | VerifierSettings.RegisterFileConverter(Convert);
19 | }
20 |
21 | // From https://github.com/VerifyTests/Verify.SourceGenerators/issues/67#issuecomment-1536710180
22 | private static ConversionResult Convert(RunResultWithIgnoreList target, IReadOnlyDictionary context)
23 | {
24 | var exceptions = new List();
25 | var targets = new List();
26 | foreach (var result in target.Result.Results)
27 | {
28 | if (result.Exception != null)
29 | {
30 | exceptions.Add(result.Exception);
31 | }
32 |
33 | var collection = result.GeneratedSources
34 | .Where(x => !target.IgnoredFiles.Contains(x.HintName))
35 | .OrderBy(x => x.HintName)
36 | .Select(SourceToTarget);
37 | targets.AddRange(collection);
38 | }
39 |
40 | if (exceptions.Count == 1)
41 | {
42 | throw exceptions.First();
43 | }
44 |
45 | if (exceptions.Count > 1)
46 | {
47 | throw new AggregateException(exceptions);
48 | }
49 |
50 | if (target.Result.Diagnostics.Any())
51 | {
52 | var info = new
53 | {
54 | target.Result.Diagnostics,
55 | };
56 | return new(info, targets);
57 | }
58 |
59 | return new(null, targets);
60 | }
61 |
62 | private static Target SourceToTarget(GeneratedSourceResult source)
63 | {
64 | #if NET8_0_OR_GREATER
65 | var r = DefaultTestRegex();
66 | #else
67 | var r = new Regex(SimpleTestCasePattern, RegexOptions.Singleline | RegexOptions.Compiled);
68 | #endif
69 | var sourceText = source.SourceText.ToString();
70 | var match = r.Match(source.SourceText.ToString());
71 |
72 | var sourceToStore = sourceText;
73 | if (match.Success)
74 | {
75 | sourceToStore = TestHelper.ChangeIndentation(match.Groups[1].Value, TestHelper.RemoveIndentation);
76 |
77 | #if NET8_0_OR_GREATER
78 | var methodMatch = DefaultMethodTestRegex();
79 | #else
80 | var methodMatch = new Regex(MethodTestCasePattern, RegexOptions.Singleline | RegexOptions.Compiled);
81 | #endif
82 | match = methodMatch.Match(sourceToStore);
83 |
84 | if (match.Success)
85 | {
86 | sourceToStore = TestHelper.ChangeIndentation(match.Groups[1].Value, TestHelper.RemoveIndentation);
87 | }
88 | }
89 |
90 | var data = $"""
91 | //HintName: {source.HintName}
92 | {sourceToStore}
93 | """;
94 |
95 | var path = Path.GetFileNameWithoutExtension(source.HintName);
96 | #if NET8_0_OR_GREATER
97 | var r2 = DefaultTestPathRegex();
98 | #else
99 | var r2 = new Regex(DefaultTestPathPattern, RegexOptions.Singleline | RegexOptions.Compiled);
100 | #endif
101 | path = r2.Replace(path, string.Empty);
102 | return new("cs", data, path);
103 | }
104 |
105 | #if NET8_0_OR_GREATER
106 | [GeneratedRegex(SimpleTestCasePattern, RegexOptions.Singleline | RegexOptions.Compiled)]
107 | private static partial Regex DefaultTestRegex();
108 |
109 | [GeneratedRegex(MethodTestCasePattern, RegexOptions.Singleline | RegexOptions.Compiled)]
110 | private static partial Regex DefaultMethodTestRegex();
111 |
112 | [GeneratedRegex(DefaultTestPathPattern)]
113 | private static partial Regex DefaultTestPathRegex();
114 | #endif
115 |
116 | internal sealed class RunResultWithIgnoreList
117 | {
118 | public required GeneratorDriverRunResult Result { get; init; }
119 |
120 | public List IgnoredFiles { get; init; } = [];
121 | }
122 | }
123 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/NullabilityTests.cs:
--------------------------------------------------------------------------------
1 | namespace Generator.Tests;
2 |
3 | public class NullabilityTests
4 | {
5 | [Fact(Skip = "Execute when resolved: https://github.com/dotnet/roslyn/issues/49555")]
6 | public Task NullableDisable() => """
7 | #nullable disable
8 |
9 | namespace Test;
10 |
11 | internal partial class WithNullableDisabled
12 | {
13 | [CreateSyncVersion]
14 | public async Task DoNothingAsync(string l)
15 | {
16 | l = null;
17 | await Task.CompletedTask;
18 | }
19 | }
20 | """.Verify(sourceType: SourceType.Full);
21 |
22 | [Fact]
23 | public Task NullableOmitExplicit() => """
24 | #nullable disable
25 |
26 | namespace Test;
27 |
28 | partial class MyClass
29 | {
30 | [Obsolete]
31 | [CreateSyncVersion(OmitNullableDirective = true)]
32 | public async Task MethodAsync()
33 | {
34 | string f = null;
35 | }
36 | }
37 | """.Verify(sourceType: SourceType.Full);
38 |
39 | [Fact]
40 | public Task ConditionalNullable() => """
41 | #nullable disable
42 |
43 | namespace Test;
44 |
45 | partial class MyClass
46 | {
47 | [CreateSyncVersion(OmitNullableDirective = true)]
48 | public async Task MethodAsync(Stream stream)
49 | {
50 | _ = stream?.DoSomething();
51 | }
52 | }
53 |
54 | internal static class Extension
55 | {
56 | public static Stream DoSomething(this Stream stream) => stream;
57 | }
58 | """.Verify(sourceType: SourceType.Full);
59 |
60 | [Fact]
61 | public Task ConditionalNullableTwice() => """
62 | #nullable disable
63 |
64 | namespace Test;
65 |
66 | partial class MyClass
67 | {
68 | [CreateSyncVersion(OmitNullableDirective = true)]
69 | public async Task MethodAsync(Stream stream)
70 | {
71 | _ = stream?.DoSomething()?.DoSomething();
72 | }
73 | }
74 |
75 | internal static class Extension
76 | {
77 | public static Stream DoSomething(this Stream stream) => stream;
78 | }
79 | """.Verify(sourceType: SourceType.Full);
80 |
81 | [Fact]
82 | public Task ConditionalNullableStructTwice() => """
83 | #nullable disable
84 |
85 | namespace Test;
86 |
87 | partial class MyClass
88 | {
89 | [CreateSyncVersion(OmitNullableDirective = true)]
90 | public async Task MethodAsync(int? myInt)
91 | {
92 | _ = myInt?.DoSomething().DoSomething2();
93 | }
94 | }
95 |
96 | internal static class Extension
97 | {
98 | public static int DoSomething(this int myInt) => myInt;
99 | public static int DoSomething2(this int myInt) => myInt;
100 | }
101 | """.Verify(sourceType: SourceType.Full);
102 |
103 | [Fact]
104 | public Task NoNullableSupport() => """
105 | namespace Test;
106 |
107 | partial class WithNullableDisabled
108 | {
109 | [CreateSyncVersion]
110 | public async Task MethodAsync(string l) => await Task.CompletedTask;
111 | }
112 | """.Verify(sourceType: SourceType.Full, languageVersion: LanguageVersion.CSharp7_3);
113 | }
114 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/ParentTests.cs:
--------------------------------------------------------------------------------
1 | namespace Generator.Tests;
2 |
3 | public class ParentTests
4 | {
5 | [Fact]
6 | public Task Struct() => """
7 | namespace Test;
8 | public partial struct Struct
9 | {
10 | [CreateSyncVersion]
11 | public readonly async Task MethodAsync() => await Task.Delay(1000);
12 | }
13 | """.Verify(sourceType: SourceType.Full);
14 |
15 | [Fact]
16 | public Task Record() => """
17 | namespace Test;
18 | public partial record Record
19 | {
20 | [CreateSyncVersion]
21 | public async Task MethodAsync() => await Task.Delay(1000);
22 | }
23 | """.Verify(sourceType: SourceType.Full);
24 |
25 | [Fact]
26 | public Task RecordStruct() => """
27 | namespace Test;
28 | public partial record struct RecordStruct
29 | {
30 | [CreateSyncVersion]
31 | public readonly async Task MethodAsync() => await Task.Delay(1000);
32 | }
33 | """.Verify(sourceType: SourceType.Full);
34 |
35 | [Fact]
36 | public Task RecordClass() => """
37 | namespace Test;
38 | public partial record class Record
39 | {
40 | [CreateSyncVersion]
41 | public async Task MethodAsync() => await Task.Delay(1000);
42 | }
43 | """.Verify(sourceType: SourceType.Full);
44 | }
45 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/PreprocessorTests.cs:
--------------------------------------------------------------------------------
1 | namespace Generator.Tests;
2 |
3 | public class PreprocessorTests
4 | {
5 | [Fact]
6 | public Task MacrosAroundBraces() => $$"""
7 | #if !BLA
8 | {
9 | #endif
10 |
11 | #if !BLA
12 | }
13 | #endif
14 | """.Verify(sourceType: SourceType.MethodBody);
15 | }
16 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/ArgumentTests.DropNamedArgument#CallProgressMethodAsync.g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.CallProgressMethodAsync.g.cs
2 | public void CallProgressMethod()
3 | {
4 | ProgressMethod();
5 | }
6 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/ArgumentTests.DropNullArgument#CallProgressMethodAsync.g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.CallProgressMethodAsync.g.cs
2 | public void CallProgressMethod()
3 | {
4 | ProgressMethod();
5 | }
6 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/ConditionalExtensionTests.CheckArrayNullability#g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.MethodAsync.g.cs
2 | int[]? array = null;
3 | var z = ((object?)array == null ? (int?)null : global::System.Linq.Enumerable.Single(array));
4 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/ConditionalExtensionTests.ConditionalToExtension#g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.MethodAsync.g.cs
2 | public static void Method(global::System.Collections.Generic.IEnumerable? integers)
3 | {
4 | var res = ((object?)integers == null ? (int[]?)null : global::System.Linq.Enumerable.First(global::System.Linq.Enumerable.Chunk(integers, 2)));
5 | }
6 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/ConditionalExtensionTests.HandleCastForArray#g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.MethodAsync.g.cs
2 | _ = ((global::System.Func?>)((param)=>(object?)param == null ? (global::System.Collections.Generic.IEnumerable?)null : global::System.Linq.Enumerable.Select(param, z => null)))(((string[]?)[]));
3 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/ConditionalExtensionTests.HandleCastForNull#g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.MethodAsync.g.cs
2 | _ = ((global::System.Func?>)((param)=>(object?)param == null ? (global::System.Collections.Generic.IEnumerable?)null : global::System.Linq.Enumerable.Select(param, z => null)))(((string[]?)null));
3 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/ConditionalExtensionTests.KeepTypeParameters#g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.MethodAsync.g.cs
2 | string[]? arr = [];
3 | _ = ((object?)arr == null ? (global::System.Collections.Generic.IEnumerable?)null : global::System.Linq.Enumerable.Select(arr, z => null));
4 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/ConditionalExtensionTests.LongChained#g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.MethodAsync.g.cs
2 | global::System.Reflection.Assembly? a = null;
3 | _ = ((global::System.Func?>)((param)=>
4 | {
5 | if ((object?)param == null)
6 | {
7 | return null;
8 | }
9 |
10 | global::System.Collections.Generic.IEnumerable check0 = global::System.Reflection.CustomAttributeExtensions.GetCustomAttributes(param);
11 | if ((object?)check0 == null)
12 | {
13 | return null;
14 | }
15 |
16 | global::System.Collections.Generic.List check1 = global::System.Linq.Enumerable.ToList(check0);
17 | if ((object?)check1 == null)
18 | {
19 | return null;
20 | }
21 |
22 | global::System.Collections.Generic.IEnumerable check2 = global::System.Linq.Enumerable.Where(check1, z => 1 == 0);
23 | if ((object?)check2 == null)
24 | {
25 | return null;
26 | }
27 |
28 | global::System.Collections.Generic.IEnumerable check3 = global::System.Linq.Enumerable.Where(check2, z => 2 == 0);
29 | return (object?)check3 == null ? (global::System.Collections.Generic.IEnumerable?)null : global::System.Linq.Enumerable.Where(check3, z => 3 == 0);
30 | }))(a);
31 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/ConditionalExtensionTests.NullConditionalExtension#g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.MethodAsync.g.cs
2 | global::System.Reflection.Assembly? a = null;
3 | _ = ((object?)a == null ? (global::System.Collections.Generic.IEnumerable?)null : global::System.Reflection.CustomAttributeExtensions.GetCustomAttributes(a));
4 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/ConditionalExtensionTests.NullConditionalExtensionChained#g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.MethodAsync.g.cs
2 | global::System.Reflection.Assembly? a = null;
3 | _ = ((global::System.Func?>)((param)=>
4 | {
5 | if ((object?)param == null)
6 | {
7 | return null;
8 | }
9 |
10 | global::System.Collections.Generic.IEnumerable check0 = global::System.Reflection.CustomAttributeExtensions.GetCustomAttributes(param);
11 | return (object?)check0 == null ? (global::System.Collections.Generic.List?)null : global::System.Linq.Enumerable.ToList(check0);
12 | }))(a);
13 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/ConditionalExtensionTests.NullConditionalWithoutExtension#g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.MethodAsync.g.cs
2 | global::System.Reflection.Assembly? a = null;
3 | _ = a?.ToString();
4 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/ConditionalExtensionTests.StartWithExpression#g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.MethodAsync.g.cs
2 | _ = ((global::System.Func?>)((param)=>(object?)param == null ? (global::System.Collections.Generic.IEnumerable?)null : global::System.Reflection.CustomAttributeExtensions.GetCustomAttributes(param)))(GetType().Assembly);
3 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/DelegateTests.AsyncDelegate#g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.MethodAsync.g.cs
2 | var del = () => { };
3 | del();
4 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/DelegateTests.AsyncDelegateExplicit#g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.MethodAsync.g.cs
2 | global::System.Action del = () => { };
3 | del();
4 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/DelegateTests.AsyncDelegateWithCancellationToken#g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.MethodAsync.g.cs
2 | global::System.Func del = () => 2;
3 | var result = del();
4 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/DelegateTests.AsyncDelegateWithIProgress#g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.MethodAsync.g.cs
2 | global::System.Func del = () => 2;
3 | var result = del();
4 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/DelegateTests.AsyncDelegateWithNullableIProgress#g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.MethodAsync.g.cs
2 | global::System.Func del = () => 2;
3 | var result = del();
4 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/DelegateTests.AsyncDelegateWithParameter#g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.MethodAsync.g.cs
2 | global::System.Action del = (p, s) => { };
3 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/DelegateTests.AsyncVarDelegateWithParameter#g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.MethodAsync.g.cs
2 | var del = (global::System.Drawing.Point p, global::System.Drawing.Size s) => { };
3 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/DelegateTests.AsyncVarDelegateWithParameterAndReturnType#g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.MethodAsync.g.cs
2 | var del = (global::System.Drawing.Point p, global::System.Drawing.Size s) => p;
3 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/DelegateTests.DropCompletedTaskFromLambda#g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.MethodAsync.g.cs
2 | var del = () => { };
3 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/DelegateTests.FuncToActionInParameter#g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.MethodAsync.g.cs
2 | void Method(global::System.Action bar)
3 | {
4 | bar(5);
5 | }
6 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/DelegateTests.FuncToActionInParameterExplicitInvoke#g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.MethodAsync.g.cs
2 | void Method(global::System.Action bar)
3 | {
4 | bar.Invoke();
5 | }
6 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/DelegateTests.FuncToActionInParameterTwice#g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.MethodAsync.g.cs
2 | void Method(global::System.Func bar)
3 | {
4 | bar()();
5 | }
6 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/DelegateTests.FuncToActionInParameterTwiceExplicitInvoke#g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.MethodAsync.g.cs
2 | void Method(global::System.Func bar)
3 | {
4 | bar().Invoke();
5 | }
6 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/DelegateTests.FuncToActionInParameterTwiceWithArgument#g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.MethodAsync.g.cs
2 | void Method(global::System.Func bar)
3 | {
4 | bar(9)();
5 | }
6 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/ExtensionMethodTests.LeftOfTheDotTest#Tests.Class.MethodAsync.g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Tests.Class.MethodAsync.g.cs
2 | //
3 | #nullable enable
4 | namespace Tests;
5 | partial class Class
6 | {
7 | public void Method()
8 | {
9 | _ = ((global::System.Func)((param)=>(object?)param == null ? (global::Tests.Bar?)null : global::Tests.BarExtension.DoSomething(param)))(global::Tests.Bar.Create());
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/ExtensionMethodTests.UnwrapGenericExtensionMethod#Zomp.SyncMethodGenerator.IntegrationTests.Extensions.HasGeneric2ExtensionAsync.g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Zomp.SyncMethodGenerator.IntegrationTests.Extensions.HasGeneric2ExtensionAsync.g.cs
2 | //
3 | #nullable enable
4 | namespace Zomp.SyncMethodGenerator.IntegrationTests
5 | {
6 | partial class Extensions
7 | {
8 | public static void HasGeneric2Extension(object o)
9 | {
10 | var z = global::Extensi.ons123.MyExtensionClass.TryGetValue(o, out var _, out var _1);
11 | }
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/ExtensionMethodTests.UnwrapGenericExtensionMethod#Zomp.SyncMethodGenerator.IntegrationTests.Extensions.HasGenericExtensionAsync.g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Zomp.SyncMethodGenerator.IntegrationTests.Extensions.HasGenericExtensionAsync.g.cs
2 | //
3 | #nullable enable
4 | namespace Zomp.SyncMethodGenerator.IntegrationTests
5 | {
6 | partial class Extensions
7 | {
8 | public static void HasGenericExtension(object o)
9 | {
10 | var z = global::Extensi.ons123.MyExtensionClass.TryGetValue(o, out var item);
11 | }
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/ExternalLibraryTests.ToListAsync#g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.MethodAsync.g.cs
2 | public void Method(global::System.Collections.Generic.IEnumerable @enum)
3 | {
4 | _ = global::System.Linq.Enumerable.ToList(@enum);
5 | }
6 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/FileNameTests.DoNotCollideClassNames#Test.Class{T,T2}.MethodAsync.g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class{T,T2}.MethodAsync.g.cs
2 | //
3 | #nullable enable
4 | namespace Test;
5 | public partial class Class
6 | {
7 | public void Method()
8 | {
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/FileNameTests.DoNotCollideClassNames#Test.Class{T}.MethodAsync.g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class{T}.MethodAsync.g.cs
2 | //
3 | #nullable enable
4 | namespace Test;
5 | public partial class Class
6 | {
7 | public void Method()
8 | {
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/FileNameTests.DoNotCollideClassNames#g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.MethodAsync.g.cs
2 | //
3 | #nullable enable
4 | namespace Test;
5 | public partial class Class
6 | {
7 | public void Method()
8 | {
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/GenericMathTests.GeneratesWithIProgressCorrectly.DotNet8_0#Test.EnumerableExtensions.IndexOfMaxSoFarAsync.g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.EnumerableExtensions.IndexOfMaxSoFarAsync.g.cs
2 | //
3 | #nullable enable
4 | namespace Test
5 | {
6 | public static partial class EnumerableExtensions
7 | {
8 | ///
9 | /// Finds maximum value so far and returns its 0 based index
10 | ///
11 | /// Numeric type
12 | /// Items to scan.
13 | /// Max indices
14 | public static global::System.Collections.Generic.IEnumerable IndexOfMaxSoFar(this global::System.Collections.Generic.IEnumerable items)
15 | #if NET8_0_OR_GREATER
16 | where T : global::System.Numerics.IComparisonOperators
17 | #else
18 | where T : IComparisonOperators
19 | #endif
20 | {
21 | var i = 0;
22 |
23 | T? largestSoFar = default;
24 | foreach (var item in items)
25 | {
26 |
27 | if (largestSoFar is null || largestSoFar < item)
28 | {
29 | largestSoFar = item;
30 | yield return i;
31 | }
32 |
33 | ++i;
34 | }
35 | }
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/IntegrationTesting.ChecksumRead#ChecksumReadAsync.g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.ChecksumReadAsync.g.cs
2 | static int ChecksumRead(global::System.Span buffer, global::System.IO.Stream stream)
3 | {
4 | int bytesRead = stream.Read(buffer);
5 | return Checksum(buffer.Slice(0, bytesRead));
6 | }
7 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/IntegrationTesting.ChecksumRead#HalfCheckSumAsync.g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.HalfCheckSumAsync.g.cs
2 | static int HalfCheckSum(global::System.Span buffer, global::System.IO.Stream stream)
3 | => ChecksumRead(buffer, stream) / 2;
4 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/IntegrationTesting.CombineTwoLists#CombineAsync.g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.CombineAsync.g.cs
2 | public static global::System.Collections.Generic.IEnumerable<(TLeft Left, TRight Right)> Combine(this global::System.Collections.Generic.IEnumerable list1, global::System.Collections.Generic.IEnumerable list2)
3 | {
4 | using var enumerator2 = list2.GetEnumerator();
5 | foreach (var item in list1)
6 | {
7 | if (!enumerator2.MoveNext())
8 | {
9 | throw new global::System.InvalidOperationException("Must have the same size");
10 | }
11 | yield return (item, enumerator2.Current);
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/IntegrationTesting.EagerPreconditionInIteratorBlock#ReadLineByLineAsync.g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.ReadLineByLineAsync.g.cs
2 | public static global::System.Collections.Generic.IEnumerable ReadLineByLine(string fileName)
3 | {
4 | if (string.IsNullOrEmpty(fileName)) throw new global::System.ArgumentNullException(nameof(fileName));
5 |
6 | return ReadLineByLineImpl();
7 |
8 | global::System.Collections.Generic.IEnumerable ReadLineByLineImpl()
9 | {
10 | foreach (var line in CreateAsyncEnumerable())
11 | {
12 | yield return line;
13 | }
14 | }
15 |
16 | global::System.Collections.Generic.IEnumerable CreateAsyncEnumerable()
17 | {
18 | foreach (var i in new[] { "a", "b" })
19 | {
20 | yield return i;
21 | }
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/IntegrationTesting.EagerPreconditionsInAsyncMethod#GetAllTextAsync.g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.GetAllTextAsync.g.cs
2 | public static string GetAllText(string fileName)
3 | {
4 | // Eager argument validation
5 | if (string.IsNullOrEmpty(fileName)) throw new global::System.ArgumentNullException(nameof(fileName));
6 | return GetAllText();
7 |
8 | string GetAllText()
9 | {
10 | var result = global::System.IO.File.ReadAllText(fileName);
11 | return result;
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/IntegrationTesting.GeneratesSyncMethodCorrectly#Test.EnumerableExtensions.GetAveragesAsync.g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.EnumerableExtensions.GetAveragesAsync.g.cs
2 | //
3 | #nullable enable
4 | namespace Test
5 | {
6 | public static partial class EnumerableExtensions
7 | {
8 | public static global::System.Collections.Generic.IEnumerable GetAverages(this global::System.Collections.Generic.IEnumerable list, int adjacentCount)
9 | where T : global::System.IConvertible
10 | {
11 | double total = 0;
12 |
13 | int avgCount = adjacentCount * 2 + 1;
14 |
15 | var meanQueue = new global::System.Collections.Generic.Queue();
16 | foreach (var o in list)
17 | {
18 | var item = o.ToDouble(null);
19 | if (meanQueue.Count == avgCount)
20 | {
21 | total -= meanQueue.Dequeue();
22 | }
23 | meanQueue.Enqueue(item);
24 | total += item;
25 |
26 | if (meanQueue.Count == avgCount)
27 | {
28 | yield return total / avgCount;
29 | }
30 | }
31 | }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/IntegrationTesting.WithIAsyncEnumerator#EnumeratorTestAsync.g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.EnumeratorTestAsync.g.cs
2 | void EnumeratorTest(global::System.Collections.Generic.IEnumerable range)
3 | {
4 | global::System.Collections.Generic.IEnumerator e = range.GetEnumerator();
5 | try
6 | {
7 | while (e.MoveNext()) global::System.Console.Write(e.Current + " ");
8 | }
9 | finally { if (e != null) e.Dispose(); }
10 | }
11 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/InterpolatedStringTests.EnsureParentheses#g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.MethodAsync.g.cs
2 | var z = $"123{(global::System.IO.File.ReadAllText("123"))}456";
3 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/InterpolatedStringTests.HandleFormatString#g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.MethodAsync.g.cs
2 | var z = $"123{(global::System.IO.File.ReadAllText("123")):hh}456";
3 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/IsCancellationRequestedTests.IfCancelled#g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.MethodAsync.g.cs
2 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/IsCancellationRequestedTests.IfNotCancelled#g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.MethodAsync.g.cs
2 | if (true)
3 | {
4 | global::System.Threading.Thread.Sleep(120000);
5 | }
6 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/IsCancellationRequestedTests.WhileNotCancelled#g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.MethodAsync.g.cs
2 | while (true)
3 | {
4 | global::System.Threading.Thread.Sleep(120000);
5 | }
6 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/MemoryTests.ConvertMemoryToSpan#g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.MethodAsync.g.cs
2 | var m = GetMemory().Span;
3 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/MemoryTests.ConvertMemoryToSpanAfterPropertyAccess#g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.MethodAsync.g.cs
2 | var m = global::System.Buffers.MemoryPool.Shared.Rent().Memory.Span;
3 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/MemoryTests.DropSpanAfterAsMemory#MakeArrayAsync.g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.MakeArrayAsync.g.cs
2 | public void MakeArray(byte[] sampleBytes)
3 | {
4 | var arr = global::System.MemoryExtensions.AsSpan(sampleBytes, 0, 123).ToArray();
5 | }
6 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/MemoryTests.DropSpanAfterAsMemoryWithWhitespace#MakeArrayAsync.g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.MakeArrayAsync.g.cs
2 | public void MakeArray(byte[] sampleBytes)
3 | {
4 | var arr =
5 | global::System.MemoryExtensions.AsSpan(sampleBytes, 0, 123).ToArray();
6 | }
7 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/MemoryTests.MemorySpanProperty_explicitType=False#MakeArray.g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.MakeArray.g.cs
2 | private void MakeArray(byte[] sampleBytes)
3 | {
4 | var mem = global::System.MemoryExtensions.AsSpan(sampleBytes, 0, 123);
5 | var arr = mem.ToArray();
6 | }
7 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/MemoryTests.MemorySpanProperty_explicitType=True#MakeArray.g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.MakeArray.g.cs
2 | private void MakeArray(byte[] sampleBytes)
3 | {
4 | global::System.Span mem = global::System.MemoryExtensions.AsSpan(sampleBytes, 0, 123);
5 | var arr = mem.ToArray();
6 | }
7 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/MemoryTests.MemoryToSpan#ReadAsMemoryAsync.g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.ReadAsMemoryAsync.g.cs
2 | private void ReadAsMemory(global::System.IO.Stream stream, byte[] sampleBytes)
3 | => stream.Read(global::System.MemoryExtensions.AsSpan(sampleBytes, 0, 123));
4 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/MemoryTests.NonPredefinedTypes#N1.Class.FillAsync.g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: N1.Class.FillAsync.g.cs
2 | //
3 | #nullable enable
4 | namespace N1
5 | {
6 | partial class Class
7 | {
8 | void Fill(global::System.Span accelerometers)
9 | {
10 | global::N2.C1.C2.Accelerometer a = new(1, 2, 3);
11 | accelerometers[0] = a;
12 | }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/MemoryTests.PreserveUnrelatedSpan#HasMemoryAsync.g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.HasMemoryAsync.g.cs
2 | public void HasMemory(global::System.Span mem)
3 | {
4 | void Inner()
5 | {
6 | global::Test.Class.Unrelated mem = new();
7 | int shouldBeInt = mem.Span;
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/MemoryTests.ReadOnlyMemoryToReadOnlySpan#WriteAsync.g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.WriteAsync.g.cs
2 | static void Write(global::System.ReadOnlySpan buffer, global::System.IO.Stream stream)
3 | => stream.Write(buffer);
4 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/NullabilityTests.ConditionalNullable#Test.MyClass.MethodAsync.g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.MyClass.MethodAsync.g.cs
2 | //
3 | namespace Test;
4 | partial class MyClass
5 | {
6 | public void Method(global::System.IO.Stream stream)
7 | {
8 | _ = ((object)stream == null ? (global::System.IO.Stream)null : global::Test.Extension.DoSomething(stream));
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/NullabilityTests.ConditionalNullableStructTwice#Test.MyClass.MethodAsync.g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.MyClass.MethodAsync.g.cs
2 | //
3 | namespace Test;
4 | partial class MyClass
5 | {
6 | public void Method(int? myInt)
7 | {
8 | _ = (!myInt.HasValue ? (int?)null : global::Test.Extension.DoSomething2(global::Test.Extension.DoSomething(myInt.Value)));
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/NullabilityTests.ConditionalNullableTwice#Test.MyClass.MethodAsync.g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.MyClass.MethodAsync.g.cs
2 | //
3 | namespace Test;
4 | partial class MyClass
5 | {
6 | public void Method(global::System.IO.Stream stream)
7 | {
8 | _ = ((global::System.Func)((param)=>
9 | {
10 | if ((object)param == null)
11 | {
12 | return null;
13 | }
14 |
15 | global::System.IO.Stream check0 = global::Test.Extension.DoSomething(param);
16 | return (object)check0 == null ? (global::System.IO.Stream)null : global::Test.Extension.DoSomething(check0);
17 | }))(stream);
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/NullabilityTests.NoNullableSupport#Test.WithNullableDisabled.MethodAsync.g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.WithNullableDisabled.MethodAsync.g.cs
2 | //
3 | namespace Test;
4 | partial class WithNullableDisabled
5 | {
6 | public void Method(string l) { }
7 | }
8 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/NullabilityTests.NullableDisable#Test.WithNullableDisabled.DoNothingAsync.g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.WithNullableDisabled.DoNothingAsync.g.cs
2 | //
3 | #nullable disabled
4 | namespace Test;
5 | internal partial class WithNullableDisabled
6 | {
7 | public void DoNothing(string l)
8 | {
9 | l = null;
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/NullabilityTests.NullableOmitExplicit#Test.MyClass.MethodAsync.g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.MyClass.MethodAsync.g.cs
2 | //
3 | namespace Test;
4 | partial class MyClass
5 | {
6 | [global::System.ObsoleteAttribute]
7 | public void Method()
8 | {
9 | string f = null;
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/ParentTests.Record#Test.Record.MethodAsync.g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Record.MethodAsync.g.cs
2 | //
3 | #nullable enable
4 | namespace Test;
5 | public partial record Record
6 | {
7 | public void Method() => global::System.Threading.Thread.Sleep(1000);
8 | }
9 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/ParentTests.RecordClass#Test.Record.MethodAsync.g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Record.MethodAsync.g.cs
2 | //
3 | #nullable enable
4 | namespace Test;
5 | public partial record class Record
6 | {
7 | public void Method() => global::System.Threading.Thread.Sleep(1000);
8 | }
9 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/ParentTests.RecordStruct#Test.RecordStruct.MethodAsync.g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.RecordStruct.MethodAsync.g.cs
2 | //
3 | #nullable enable
4 | namespace Test;
5 | public partial record struct RecordStruct
6 | {
7 | public readonly void Method() => global::System.Threading.Thread.Sleep(1000);
8 | }
9 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/ParentTests.Struct#Test.Struct.MethodAsync.g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Struct.MethodAsync.g.cs
2 | //
3 | #nullable enable
4 | namespace Test;
5 | public partial struct Struct
6 | {
7 | public readonly void Method() => global::System.Threading.Thread.Sleep(1000);
8 | }
9 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/PreprocessorTests.MacrosAroundBraces#g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.MethodAsync.g.cs
2 | #if !BLA
3 | {
4 | #endif
5 |
6 | #if !BLA
7 | }
8 | #endif
9 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/SpecialMethodsTests.DropMethodsWithSpecialNamesInUserClass#g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.MethodAsync.g.cs
2 | public static int Method()
3 | {
4 | }
5 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/SpecialMethodsTests.FromTaskResultCheck#g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.MethodAsync.g.cs
2 | _ = 1;
3 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/SpecialMethodsTests.FromValueTaskResultCheck#g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.MethodAsync.g.cs
2 | _ = 1;
3 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/SpecialMethodsTests.TaskDelayToThreadSleepWithInt#g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.MethodAsync.g.cs
2 | global::System.Threading.Thread.Sleep(1);
3 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/SpecialMethodsTests.TaskDelayToThreadSleepWithSpan#g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.MethodAsync.g.cs
2 | global::System.Threading.Thread.Sleep(new global::System.TimeSpan(2, 3, 4));
3 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/SyncOnlyTests.DoNotMixSymbols.verified.txt:
--------------------------------------------------------------------------------
1 | {
2 | Diagnostics: [
3 | {
4 | Location: : (6,0)-(6,38),
5 | Message: Couldn't process condition '#if SYMBOL1 && !(SYNC_ONLY || SYMBOL2)'. SYNC_ONLY and other symbols must not be in the same condition.,
6 | Severity: Error,
7 | Descriptor: {
8 | Id: ZSMGEN002,
9 | Title: SYNC_ONLY and other symbols must not be in the same condition,
10 | MessageFormat: Couldn't process condition '{0}'. SYNC_ONLY and other symbols must not be in the same condition.,
11 | Category: Preprocessor,
12 | DefaultSeverity: Error,
13 | IsEnabledByDefault: true
14 | }
15 | }
16 | ]
17 | }
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/SyncOnlyTests.DoNotRemove#g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.MethodAsync.g.cs
2 | #if SYMBOL1
3 | ArgumentNullException.ThrowIfNull(source);
4 | #elif SYMBOL2
5 | ArgumentNullException.ThrowIfNull(source);
6 | #else
7 | global::System.ArgumentNullException.ThrowIfNull(source);
8 | #endif
9 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/SyncOnlyTests.DoNotRemoveInsideSyncOnly#g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.MethodAsync.g.cs
2 | #if SYMBOL
3 | throw new global::System.InvalidOperationException("Some exception");
4 | #endif
5 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/SyncOnlyTests.InsideEmptyIf#g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.MethodAsync.g.cs
2 | if (true)
3 | {
4 | throw new InvalidOperationException("Some exception");
5 | }
6 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/SyncOnlyTests.InsideParameter#IsNullAsync.g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.IsNullAsync.g.cs
2 | public bool IsNull(
3 | global::System.Data.IDataReader reader,
4 | int i)
5 | {
6 | return reader.IsDBNull(i);
7 | }
8 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/SyncOnlyTests.LastParameter#IsNullAsync.g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.IsNullAsync.g.cs
2 | public bool IsNull(
3 | global::System.Data.IDataReader reader
4 | )
5 | {
6 | return reader.IsDBNull(i);
7 | }
8 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/SyncOnlyTests.MultipleBlocksArentInterfering#g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.MethodAsync.g.cs
2 | string a = "";
3 | int b = 0;
4 |
5 | if (a != null)
6 | {
7 | b = 50;
8 | }
9 |
10 | _ = a + b;
11 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/SyncOnlyTests.NestedSyncOnly#g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.MethodAsync.g.cs
2 | System.Console.Write("Sync");
3 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/SyncOnlyTests.NotSyncOnly#g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.MethodAsync.g.cs
2 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/SyncOnlyTests.NotSyncOnlyFollowedBySyncOnly#g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.MethodAsync.g.cs
2 | System.Console.Write("Sync");
3 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/SyncOnlyTests.NotSyncOnlyInsideSyncOnly.verified.txt:
--------------------------------------------------------------------------------
1 | {
2 | Diagnostics: [
3 | {
4 | Location: : (8,0)-(8,14),
5 | Message: Couldn't process directive '#if !SYNC_ONLY'. SYNC_ONLY and !SYNC_ONLY cannot be nested inside each other.,
6 | Severity: Error,
7 | Descriptor: {
8 | Id: ZSMGEN001,
9 | Title: SYNC_ONLY and !SYNC_ONLY cannot be nested inside each other,
10 | MessageFormat: Couldn't process directive '{0}'. SYNC_ONLY and !SYNC_ONLY cannot be nested inside each other.,
11 | Category: Preprocessor,
12 | DefaultSeverity: Error,
13 | IsEnabledByDefault: true
14 | }
15 | }
16 | ]
17 | }
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/SyncOnlyTests.ProhibitElif.verified.txt:
--------------------------------------------------------------------------------
1 | {
2 | Diagnostics: [
3 | {
4 | Location: : (8,0)-(8,12),
5 | Message: Couldn't process directive '#elif Symbol'. SYNC_ONLY cannot be used with #elif.,
6 | Severity: Error,
7 | Descriptor: {
8 | Id: ZSMGEN003,
9 | Title: SYNC_ONLY cannot be used with #elif,
10 | MessageFormat: Couldn't process directive '{0}'. SYNC_ONLY cannot be used with #elif.,
11 | Category: Preprocessor,
12 | DefaultSeverity: Error,
13 | IsEnabledByDefault: true
14 | }
15 | }
16 | ]
17 | }
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/SyncOnlyTests.SimpleMacro#ExecAsync.g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.ExecAsync.g.cs
2 | public void Exec()
3 | {
4 | throw new InvalidOperationException("Some exception");
5 | }
6 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/SyncOnlyTests.StatementAtTheEnd#g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.MethodAsync.g.cs
2 |
3 | global::System.Console.Write("Done");
4 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/SyncOnlyTests.SwitchStatementProcessesDirectives#g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.MethodAsync.g.cs
2 | var i = 0;
3 | switch (i)
4 | {
5 | case 0:
6 | break;
7 | case 2:
8 | System.Console.Write("Sync");
9 | break;
10 | case 3:
11 | #if SYMBOL
12 | System.Console.Write("Symbol");
13 | #endif
14 | break;
15 | }
16 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/SyncOnlyTests.SyncOnlyBeforeMethodBody#MethodWithObsoleteSyncAsync.g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.MethodWithObsoleteSyncAsync.g.cs
2 | [global::System.Obsolete]
3 | [global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
4 | public void MethodWithObsoleteSync()
5 | {
6 | global::System.Threading.Thread.Sleep(1000);
7 | }
8 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/SystemAsyncExtensionsTests.AsyncForEachDeconstruct#SumAsync.g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.SumAsync.g.cs
2 | int Sum(global::System.Collections.Generic.IEnumerable<(int a, int b)> enumerable)
3 | {
4 | int sum = 0;
5 |
6 | foreach (var (a, b) in enumerable)
7 | {
8 | sum += a + b;
9 | }
10 |
11 | return sum;
12 | }
13 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/SystemAsyncExtensionsTests.AsyncForEachQualified#SumAsync.g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.SumAsync.g.cs
2 | int Sum(global::System.Collections.Generic.IEnumerable enumerable)
3 | {
4 | int sum = 0;
5 |
6 | foreach (int? i in enumerable)
7 | {
8 | if (i.HasValue)
9 | {
10 | sum += i.Value;
11 | }
12 | }
13 |
14 | return sum;
15 | }
16 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/SystemAsyncExtensionsTests.ConfiguredCancelableAsyncEnumerable#g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.MethodAsync.g.cs
2 | internal int Method(global::System.Collections.Generic.IEnumerable<(global::System.IO.Stream A, int B)> enumerable)
3 | {
4 | var enumerator = enumerable.GetEnumerator();
5 |
6 | int sum = 0;
7 | while (enumerator.MoveNext())
8 | {
9 | sum += (int)enumerator.Current.A.Length + enumerator.Current.B;
10 | }
11 |
12 | return sum;
13 | }
14 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/SystemAsyncExtensionsTests.ConfiguredCancelableAsyncEnumerableExtension#GetConfiguredEnumeratorAsync.g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.GetConfiguredEnumeratorAsync.g.cs
2 | // From https://github.com/dotnet/reactive/blob/5f831de0bc70bc660d21c3b9e04e581269691a2a/Ix.NET/Source/System.Linq.Async/System/Threading/Tasks/AsyncEnumerableExt.cs#L15
3 |
4 | public static System.Collections.Generic.IEnumerator GetConfiguredEnumerator(global::System.Collections.Generic.IEnumerable enumerable)
5 | {
6 | return enumerable.GetEnumerator();
7 | }
8 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/SystemAsyncExtensionsTests.ConfiguredCancelableAsyncEnumerableExtensionUsingStatic#Test.Extensions.GetConfiguredAsyncEnumerator.g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Extensions.GetConfiguredAsyncEnumerator.g.cs
2 | //
3 | #nullable enable
4 | namespace Test;
5 | internal static partial class Extensions
6 | {
7 | public static System.Collections.Generic.IEnumerator GetConfiguredEnumerator(global::System.Collections.Generic.IEnumerable enumerable)
8 | {
9 | return enumerable.GetEnumerator();
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/SystemAsyncExtensionsTests.DropConfigureAwaitExtensions#InvokeAsync.g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.InvokeAsync.g.cs
2 | public void Invoke()
3 | => _ = GetItem(4);
4 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/SystemAsyncExtensionsTests.DropConfiguredCancelableAsyncEnumerable#Iterate.g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.Iterate.g.cs
2 | public static void Iterate(this global::System.Collections.Generic.IEnumerable list1)
3 | {
4 | foreach (var item in list1)
5 | {
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/SystemAsyncExtensionsTests.DropConfiguredCancelableAsyncEnumerableExtensionInvocation#Test.Extensions.MethodAsync.g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Extensions.MethodAsync.g.cs
2 | //
3 | #nullable enable
4 | namespace Test;
5 | internal static partial class Extensions
6 | {
7 | internal static void Method(global::System.Collections.Generic.IEnumerable enumerable)
8 | {
9 | using System.Collections.Generic.IEnumerator enumerator = enumerable.GetEnumerator();
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/SystemAsyncExtensionsTests.DropWithCancellation#Iterate.g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.Iterate.g.cs
2 | public static void Iterate(this global::System.Collections.Generic.IEnumerable list1)
3 | {
4 | foreach (var item in list1)
5 | {
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/TypeTests.ArrayParameter#g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.MethodAsync.g.cs
2 | public void Method(int[] o)
3 | {
4 | }
5 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/TypeTests.BinaryPattern#g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.MethodAsync.g.cs
2 | _ = new object() is global::System.DBNull or global::System.IO.Stream;
3 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/TypeTests.CastFullyQualifiedType#GetCustomObjectAsync.g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.GetCustomObjectAsync.g.cs
2 | public object GetCustomObject(object o)
3 | {
4 | return (global::Test.Class.CustomClass)o;
5 | }
6 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/TypeTests.CastFullyQualifiedTypeTwice#GetCustomObjectAsync.g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.GetCustomObjectAsync.g.cs
2 | public object GetCustomObject(object o)
3 | {
4 | return (global::Test.Class.CustomClass)(object)(global::Test.Class.CustomClass)o;
5 | }
6 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/TypeTests.ConvertExceptionType#g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.MethodAsync.g.cs
2 | try
3 | {
4 | }
5 | catch (global::System.OperationCanceledException)
6 | {
7 | }
8 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/TypeTests.ConvertForeachType#g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.MethodAsync.g.cs
2 | foreach (int i in new int[] { 1 })
3 | {
4 | }
5 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/TypeTests.CreateNullableType#g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.MethodAsync.g.cs
2 | new global::System.Collections.Generic.Dictionary().TryGetValue(0, out (int I, global::System.IO.Stream? S)? a);
3 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/TypeTests.DeclarationExpression#g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.MethodAsync.g.cs
2 | new global::System.Collections.Generic.Dictionary().TryGetValue(0, out global::System.IO.Stream a);
3 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/TypeTests.EnumPattern#g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.MethodAsync.g.cs
2 | _ = global::System.Data.ConnectionState.Closed is global::System.Data.ConnectionState.Closed;
3 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/TypeTests.EnumPatternName#.Class.ReturnTrueAsync.g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: .Class.ReturnTrueAsync.g.cs
2 | //
3 | #nullable enable
4 | partial class Class
5 | {
6 | public bool ReturnTrue()
7 | {
8 | return global::Test.Test is global::Test.Test;
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/TypeTests.EventHandlerType#g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.MethodAsync.g.cs
2 | _ = new global::System.Diagnostics.DataReceivedEventHandler((s, e) => { });
3 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/TypeTests.FullyQualifiedArray#g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.MethodAsync.g.cs
2 | global::System.Text.RegularExpressions.Regex[] variable = null!;
3 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/TypeTests.GenericClassWithGenericInnerClass#Test.Class{T}.FooAsync.g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class{T}.FooAsync.g.cs
2 | //
3 | #nullable enable
4 | namespace Test;
5 | internal partial class Class
6 | {
7 | public void Foo(global::Test.Class.Int i) { }
8 | }
9 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/TypeTests.HandleAsCast#g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.MethodAsync.g.cs
2 | _ = new object() as global::System.IO.Stream;
3 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/TypeTests.HandleDiscardSymbol#g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.MethodAsync.g.cs
2 | _ = int.TryParse("2", out _);
3 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/TypeTests.HandleNameOf#g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.MethodAsync.g.cs
2 | _ = nameof(global::System.IO.Stream);
3 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/TypeTests.HandleNameOfGenericTuple#g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.MethodAsync.g.cs
2 | _ = nameof(global::System.Collections.Generic.IEnumerable<(global::System.IO.Stream? S, int I)>);
3 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/TypeTests.HandleNullableTuple#g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.MethodAsync.g.cs
2 | public void Method((global::System.IO.Stream? S, int I) z) { }
3 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/TypeTests.HandleTuple#g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.MethodAsync.g.cs
2 | public void Method((global::System.IO.Stream S, int I) z) { }
3 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/TypeTests.HandleTypeOf#g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.MethodAsync.g.cs
2 | _ = typeof(global::System.IO.Stream);
3 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/TypeTests.NestedGenerics#g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.MethodAsync.g.cs
2 | var dict = new global::System.Collections.Generic.Dictionary>();
3 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/TypeTests.NotPattern#g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.MethodAsync.g.cs
2 | _ = new object() is not global::System.DBNull;
3 |
4 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/TypeTests.NullableDeclarationExpression#g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.MethodAsync.g.cs
2 | new global::System.Collections.Generic.Dictionary().TryGetValue(0, out global::System.IO.Stream? a);
3 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/TypeTests.NullableForeach#g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.MethodAsync.g.cs
2 | foreach (global::System.IO.Stream? i in global::System.Array.Empty())
3 | {
4 | }
5 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/TypeTests.PatternIsEnumMember#g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.MethodAsync.g.cs
2 | _ = global::System.StringComparison.CurrentCulture is global::System.StringComparison.CurrentCulture;
3 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/TypeTests.PatternIsNotLiteral#g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.MethodAsync.g.cs
2 | _ = global::System.StringComparison.CurrentCulture is not global::System.StringComparison.CurrentCulture;
3 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/TypeTests.PatternMatchingWithConstant#g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.MethodAsync.g.cs
2 | _ = 1 is 2;
3 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/TypeTests.QualifiedGenericName#g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.MethodAsync.g.cs
2 | global::System.Collections.Generic.HashSet z = null!;
3 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/TypeTests.QualifiedNonGenericName#System.Class.MethodAsync.g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: System.Class.MethodAsync.g.cs
2 | //
3 | #nullable enable
4 | namespace System;
5 | public partial class Class
6 | {
7 | public void Method()
8 | {
9 | global::System.Security.Cryptography.CryptographicException z = null!;
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/TypeTests.SwitchType#SwitchAsync.g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.SwitchAsync.g.cs
2 | public void Switch(global::System.IO.Stream stream)
3 | {
4 | var s = stream switch
5 | {
6 | global::System.IO.FileStream fs => fs,
7 | _ => throw new global::System.InvalidOperationException("No"),
8 | };
9 | }
10 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/TypeTests.TestTypes#g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.MethodAsync.g.cs
2 | string myStr;
3 | string myStrPredefined;
4 | global::System.Exception ex;
5 | short myShort;
6 | short[] myShorts;
7 | long myLong;
8 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/TypeTests.UseFullyQualifiedTypeInIsExpression#HasIsExpressionAsync.g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.HasIsExpressionAsync.g.cs
2 | public void HasIsExpression(global::System.IO.Stream stream) => _ = stream is global::System.IO.FileStream;
3 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/TypeTests.VariableDeclaration#g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.MethodAsync.g.cs
2 | global::System.IO.MemoryStream ms = new();
3 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/TypeTests.VariableDeclarationRedundant#g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.MethodAsync.g.cs
2 | global::System.IO.MemoryStream ms = new global::System.IO.MemoryStream();
3 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/UnitTests.BasicEvent#g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.MethodAsync.g.cs
2 | MyEvent?.Invoke(this, global::System.EventArgs.Empty);
3 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/UnitTests.BasicInterface#Test.IMyInterface.MethodAsync.g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.IMyInterface.MethodAsync.g.cs
2 | //
3 | #nullable enable
4 | namespace Test;
5 | public partial interface IMyInterface
6 | {
7 | void Method()
8 | {
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/UnitTests.BrokenIfStatement#g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.MethodAsync.g.cs
2 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/UnitTests.CallPropertiesReturningTasksWithAsync#MyMethodAsync.g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.MyMethodAsync.g.cs
2 | public void MyMethod()
3 | {
4 | w.Action();
5 | }
6 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/UnitTests.CallWithTypeParameters#MyFuncAsync.g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.MyFuncAsync.g.cs
2 | public void MyFunc()
3 | {
4 | MyFunc();
5 | }
6 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/UnitTests.ConvertAsyncDelegateToDelegate#g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.MethodAsync.g.cs
2 | global::System.Action a = delegate () { global::System.Threading.Thread.Sleep(100); };
3 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/UnitTests.ConvertAsyncDelegateToSync#g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.MethodAsync.g.cs
2 | public int Method(global::System.Func task)
3 | {
4 | var r = task();
5 | return r;
6 | }
7 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/UnitTests.DefaultParameter#GetColorAsync.g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.GetColorAsync.g.cs
2 | public void GetColor(global::System.IO.FileAccess access = global::System.IO.FileAccess.Read) { }
3 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/UnitTests.DeleteIfBetweenPreprocessorDirectives#g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.MethodAsync.g.cs
2 | #if MY_SPECIAL_SYMBOL
3 | if (true)
4 | {
5 | }
6 | #else
7 | #endif
8 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/UnitTests.DoNotCallPropertiesReturningGenericTasks#MyMethodAsync.g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.MyMethodAsync.g.cs
2 | public void MyMethod()
3 | {
4 | }
5 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/UnitTests.DoNotCallPropertiesReturningGenericTasksExpression#MyMethodAsync.g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.MyMethodAsync.g.cs
2 | public void MyMethod()
3 | { }
4 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/UnitTests.DoNotCallPropertiesReturningTasks#MyMethodAsync.g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.MyMethodAsync.g.cs
2 | public void MyMethod()
3 | {
4 | }
5 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/UnitTests.DoNotDropInvocationChainThatHasAsyncAnywhere#WriteAllTextAsync.g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.WriteAllTextAsync.g.cs
2 | public static void WriteAllText(string file, string contents)
3 | {
4 | global::System.IO.File.WriteAllText(file, contents);
5 | }
6 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/UnitTests.DropBrackets#GetIntAsync.g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.GetIntAsync.g.cs
2 | public static int GetInt()
3 | {
4 | return new[] { 1, 2 }[0];
5 | }
6 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/UnitTests.DropCompletedTask#ExecAsync.g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.ExecAsync.g.cs
2 | public void Exec()
3 | {
4 | }
5 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/UnitTests.DropIProgressExpressionArgument#CallWithIProgressAsync.g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.CallWithIProgressAsync.g.cs
2 | public static void CallWithIProgress()
3 | {
4 | WithIProgress();
5 | }
6 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/UnitTests.DropIProgressStatement#CallWithIProgressAsync.g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.CallWithIProgressAsync.g.cs
2 | public static void CallWithIProgress()
3 | {
4 |
5 | WithIProgress();
6 | }
7 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/UnitTests.DropUnawaitedCompletedTask#DoSomethingAsync.g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.DoSomethingAsync.g.cs
2 | public static void DoSomething() { }
3 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/UnitTests.DropUnawaitedCompletedValueTask#DoSomethingAsync.g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.DoSomethingAsync.g.cs
2 | public static void DoSomething() { }
3 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/UnitTests.FindsASpan#GetMemoryOrSpanAsync.g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.GetMemoryOrSpanAsync.g.cs
2 | private void GetMemoryOrSpan()
3 | {
4 | var instance = new global::Test.Class.ClassThatReturnsMemoryAndSpan();
5 | global::System.Span mem = instance.GetSpan();
6 | var arr = mem.ToArray();
7 | }
8 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/UnitTests.FullyQualifiedAndNullable#g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.MethodAsync.g.cs
2 | string Method(global::System.Net.HttpStatusCode? bar)
3 | {
4 | return string.Empty;
5 | }
6 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/UnitTests.GenericAsyncCall#Test.GenericClass{T}.FooAsync.g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.GenericClass{T}.FooAsync.g.cs
2 | //
3 | #nullable enable
4 | namespace Test;
5 | partial class GenericClass
6 | {
7 | public T Foo()
8 | => this.InnerFoo();
9 | }
10 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/UnitTests.GenericClass#Test.GenericClass{T1,T2}.EmptyAsync.g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.GenericClass{T1,T2}.EmptyAsync.g.cs
2 | //
3 | #nullable enable
4 | namespace Test;
5 | partial class GenericClass
6 | {
7 | void Empty()
8 | {
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/UnitTests.GenericClassMemberAccess#Test.GenericClass{T}.MethodAsync.g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.GenericClass{T}.MethodAsync.g.cs
2 | //
3 | #nullable enable
4 | namespace Test;
5 | partial class GenericClass
6 | {
7 | public void Method()
8 | {
9 | _ = global::Test.GenericClass.Bar;
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/UnitTests.HandleAsTask#g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.MethodAsync.g.cs
2 | public void Method() => OtherMethod();
3 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/UnitTests.HandleAsTaskOnParameter#g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.MethodAsync.g.cs
2 | public int Method(int vt)
3 | {
4 | var r = vt;
5 | return r;
6 | }
7 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/UnitTests.HandleAttribute#ReadSomeBytesAsync.g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.ReadSomeBytesAsync.g.cs
2 | //
3 | #nullable enable
4 | namespace Test;
5 | public partial class Class
6 | {
7 | public int ReadSomeBytes(global::System.IO.Stream stream)
8 | {
9 | var buffer = new byte[100];
10 | return stream.Read(buffer, 0, 100);
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/UnitTests.HandleAttributeOnLocalFunction#g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.MethodAsync.g.cs
2 | void Local()
3 | {
4 | }
5 |
6 | Local();
7 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/UnitTests.KeepDefaultValueTaskWithResult#ReturnDefault.g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.ReturnDefault.g.cs
2 | public static int ReturnDefault() => default;
3 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/UnitTests.LocalFunction#InternalExampleAsync.g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.InternalExampleAsync.g.cs
2 | public static int InternalExample(global::System.IO.Stream stream)
3 | {
4 | static int Internal(global::System.IO.Stream stream)
5 | {
6 | var buf = new byte[1];
7 | return stream.Read(buf, 0, 1);
8 | }
9 | return Internal(stream);
10 | }
11 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/UnitTests.LocalFunctionDelegateWithEndingAsync#DoItAsync.g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.DoItAsync.g.cs
2 | public static void DoIt()
3 | {
4 | static int Local()
5 | {
6 | return 0;
7 | }
8 |
9 | _ = SomeMethod(Local);
10 | }
11 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/UnitTests.LocalFunctionNonGeneric#InternalExampleAsync.g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.InternalExampleAsync.g.cs
2 | public static int InternalExample(global::System.IO.Stream stream)
3 | {
4 | static void LocalFunc()
5 | {
6 | }
7 |
8 | LocalFunc();
9 | }
10 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/UnitTests.MemoryToSpanWithBody#ReadAsMemoryAsync.g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.ReadAsMemoryAsync.g.cs
2 | private void ReadAsMemory(global::System.IO.Stream stream, byte[] sampleBytes)
3 | {
4 | stream.Read(global::System.MemoryExtensions.AsSpan(sampleBytes, 0, 123));
5 | }
6 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/UnitTests.MultipleClasses#NsOne.C1.C2.C3.C4.EmptyAsync.g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: NsOne.C1.C2.C3.C4.EmptyAsync.g.cs
2 | //
3 | #nullable enable
4 | namespace NsOne
5 | {
6 | public partial class C1
7 | {
8 | partial class C2
9 | {
10 | private protected partial class C3
11 | {
12 | private partial class C4
13 | {
14 | void Empty()
15 | {
16 | }
17 | }
18 | }
19 | }
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/UnitTests.MultipleInitializers#g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.MethodAsync.g.cs
2 | int b = 2;
3 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/UnitTests.MultipleNamespaces#NsOne.NsTwo.NsThree.NsFour.MultipleNamespaces.EmptyAsync.g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: NsOne.NsTwo.NsThree.NsFour.MultipleNamespaces.EmptyAsync.g.cs
2 | //
3 | #nullable enable
4 | namespace NsOne
5 | {
6 | namespace NsTwo.NsThree
7 | {
8 | namespace NsFour
9 | {
10 | public partial class MultipleNamespaces
11 | {
12 | void Empty()
13 | {
14 | }
15 | }
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/UnitTests.Overloads#ReadAsMemoryAsync.g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.ReadAsMemoryAsync.g.cs
2 | void ReadAsMemory(global::System.IO.Stream stream, byte[] sampleBytes)
3 | => stream.Read(global::System.MemoryExtensions.AsSpan(sampleBytes, 0, 123));
4 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/UnitTests.Overloads#ReadAsMemoryAsync_2.g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.ReadAsMemoryAsync_2.g.cs
2 | void ReadAsMemory(global::System.IO.Stream stream, byte[] sampleBytes)
3 | => stream.Read(global::System.MemoryExtensions.AsSpan(sampleBytes, 0, 123));
4 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/UnitTests.PassIAsyncDisposable#g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.MethodAsync.g.cs
2 | void Method(global::Test.Class.ImplementsBothDisposables a)
3 | {
4 | using (a)
5 | {
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/UnitTests.Preprocessor#WrappedAsync.g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.WrappedAsync.g.cs
2 | //
3 | #nullable enable
4 | namespace Test;
5 | public partial class Class
6 | {
7 | ///
8 | /// A summary
9 | ///
10 | public void Wrapped() { }
11 | }
12 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/UnitTests.ReturnDefaultValueTask#ReturnAsync.g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.ReturnAsync.g.cs
2 | private void Return(bool input)
3 | {
4 | if (input)
5 | {
6 | return;
7 | }
8 | global::System.Console.WriteLine("123");
9 | }
10 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/UnitTests.ReturnTask#ReturnAsync.g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.ReturnAsync.g.cs
2 | private void Return(bool input)
3 | {
4 | if (input)
5 | {
6 | Return(); return;
7 | }
8 | Return();
9 | }
10 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/UnitTests.ReturnTaskNoBody#ReturnAsync.g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.ReturnAsync.g.cs
2 | private void Return(bool input)
3 | {
4 | if (input) { Return(); return; }
5 | Return();
6 | }
7 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/UnitTests.ReturnValueTask#ReturnAsync.g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.ReturnAsync.g.cs
2 | private void Return(bool input)
3 | {
4 | if (input)
5 | {
6 | Return(); return;
7 | }
8 | Return();
9 | }
10 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/UnitTests.ReturnValueTaskConditional#ReturnAsync.g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.ReturnAsync.g.cs
2 | private void Return(bool input)
3 | {
4 | if (input) Return(); else Return();
5 | }
6 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/UnitTests.ReturnValueTaskConditionalFalse#ReturnFalseAsync.g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.ReturnFalseAsync.g.cs
2 | private void ReturnFalse(bool input)
3 | {
4 | if (!input) Return();
5 | }
6 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/UnitTests.ReturnValueTaskConditionalTrue#ReturnTrueAsync.g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.ReturnTrueAsync.g.cs
2 | private void ReturnTrue(bool input)
3 | {
4 | if (input) Return();
5 | }
6 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/UnitTests.ReturnValueTaskInstance#ReturnAsync.g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.ReturnAsync.g.cs
2 | public static int Return() { return 1; }
3 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/UnitTests.ReturnValueTaskNoBody#ReturnAsync.g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.ReturnAsync.g.cs
2 | private void Return(bool input)
3 | {
4 | if (input) { Return(); return; }
5 | Return();
6 | }
7 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/UnitTests.StaticUsings#N1.C1.MethodAsync.g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: N1.C1.MethodAsync.g.cs
2 | //
3 | #nullable enable
4 | namespace N1
5 | {
6 | public partial class C1
7 | {
8 | public void Method()
9 | {
10 | _ = global::N2.C2.OtherConst;
11 | }
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/UnitTests.TaskOfArrayOfGeneric#GetArrayOfTAsync.g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.GetArrayOfTAsync.g.cs
2 | public static global::System.Collections.Generic.LinkedListNode[] GetArrayOfT() where T : new()
3 | {
4 | return new global::System.Collections.Generic.LinkedListNode[] { };
5 | }
6 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/UnitTests.TaskOfT#GetPointAsync.g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.GetPointAsync.g.cs
2 | public static global::System.Drawing.Point GetPoint()
3 | {
4 | return new global::System.Drawing.Point(1, 2);
5 | }
6 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/UnitTests.TaskOfT2IList#GetArrayOfTAsync.g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.GetArrayOfTAsync.g.cs
2 | public static global::System.Collections.Generic.IList GetArrayOfT() where T: new()
3 | {
4 | return new T[] { new T() };
5 | }
6 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/UnitTests.TaskOfTArray#GetPointAsync.g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.GetPointAsync.g.cs
2 | public static global::System.Drawing.Point[] GetPoint()
3 | {
4 | return new[] { new global::System.Drawing.Point(1, 2) };
5 | }
6 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/UnitTests.TaskOfTIList#GetPointAsync.g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.GetPointAsync.g.cs
2 | public static global::System.Collections.Generic.IList GetPoint()
3 | {
4 | return new[] { new global::System.Drawing.Point(1, 2) };
5 | }
6 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/UnitTests.UnwrapExtensionMethod#Zomp.SyncMethodGenerator.IntegrationTests.ExtensionMethods.OneParamsAsync.g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Zomp.SyncMethodGenerator.IntegrationTests.ExtensionMethods.OneParamsAsync.g.cs
2 | //
3 | #nullable enable
4 | namespace Zomp.SyncMethodGenerator.IntegrationTests
5 | {
6 | partial class ExtensionMethods
7 | {
8 | public static void OneParams(object o, string s) => global::Extensi.ons123.MyExtensionClass.SomeMethod(o, s);
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/UnitTests.UnwrapExtensionMethod#Zomp.SyncMethodGenerator.IntegrationTests.ExtensionMethods.TwoParamsAsync.g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Zomp.SyncMethodGenerator.IntegrationTests.ExtensionMethods.TwoParamsAsync.g.cs
2 | //
3 | #nullable enable
4 | namespace Zomp.SyncMethodGenerator.IntegrationTests
5 | {
6 | partial class ExtensionMethods
7 | {
8 | public static void TwoParams(object o, string s, int i) => global::Extensi.ons123.MyExtensionClass.SomeMethod(o, s, i);
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/UnitTests.UnwrapExtensionMethod#Zomp.SyncMethodGenerator.IntegrationTests.ExtensionMethods.ZeroParamsAsync.g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Zomp.SyncMethodGenerator.IntegrationTests.ExtensionMethods.ZeroParamsAsync.g.cs
2 | //
3 | #nullable enable
4 | namespace Zomp.SyncMethodGenerator.IntegrationTests
5 | {
6 | partial class ExtensionMethods
7 | {
8 | public static void ZeroParams(object o) => global::Extensi.ons123.MyExtensionClass.SomeMethod(o);
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/UnitTests.VerifyAsyncParamHandling#g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.MethodAsync.g.cs
2 | static byte[] HelperMethod(params int[] myParams) => null;
3 | _ = HelperMethod(1, 2);
4 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/UnitTests.VerifyParamHandling#g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.MethodAsync.g.cs
2 | static byte[] HelperMethod(params int[] myParams) => null;
3 | _ = HelperMethod(1, 2);
4 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/UnitTests.WhenDroppingStatementLeaveTrivia#g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.MethodAsync.g.cs
2 | #if !MY_SPECIAL_SYMBOL
3 | #endif
4 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/UnitTests.WithAction#WithAction.g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.WithAction.g.cs
2 | public static void WithAction(global::System.Action>? action) { }
3 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/Snapshots/UnitTests.WithPreprocessor#WithPreprocessorAsync.g.verified.cs:
--------------------------------------------------------------------------------
1 | //HintName: Test.Class.WithPreprocessorAsync.g.cs
2 | //
3 | namespace Test;
4 | public partial class Class
5 | {
6 | #if NET8_0_OR_GREATER
7 | private void WithPreprocessor() { }
8 | }
9 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/SourceType.cs:
--------------------------------------------------------------------------------
1 | namespace Generator.Tests;
2 |
3 | public enum SourceType
4 | {
5 | ///
6 | /// Listing of a body of a block method. A single parameter is passed: CancellationToken ct.
7 | ///
8 | MethodBody,
9 |
10 | ///
11 | /// Listing of a body of a class.
12 | ///
13 | ClassBody,
14 |
15 | ///
16 | /// Listing for the file in full.
17 | ///
18 | Full,
19 | }
20 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/SpecialMethodsTests.cs:
--------------------------------------------------------------------------------
1 | namespace Generator.Tests;
2 |
3 | public class SpecialMethodsTests
4 | {
5 | [Theory]
6 | [InlineData(false)]
7 | [InlineData(true)]
8 | public Task TaskDelayToThreadSleepWithInt(bool caf) =>
9 | $"await Task.Delay(1){Caf(caf)};"
10 | .Verify(disableUnique: true, sourceType: SourceType.MethodBody);
11 |
12 | [Fact]
13 | public Task TaskDelayToThreadSleepWithSpan() =>
14 | "await Task.Delay(new TimeSpan(2, 3, 4));"
15 | .Verify(sourceType: SourceType.MethodBody);
16 |
17 | [Theory]
18 | [InlineData(false)]
19 | [InlineData(true)]
20 | public Task FromTaskResultCheck(bool caf) =>
21 | $"_ = await Task.FromResult(1){Caf(caf)};"
22 | .Verify(disableUnique: true, sourceType: SourceType.MethodBody);
23 |
24 | #if NETCOREAPP1_0_OR_GREATER
25 | [Theory]
26 | [InlineData(false)]
27 | [InlineData(true)]
28 | public Task FromValueTaskResultCheck(bool caf) =>
29 | $"_ = await ValueTask.FromResult(1){Caf(caf)};"
30 | .Verify(disableUnique: true, sourceType: SourceType.MethodBody);
31 | #endif
32 |
33 | [Theory]
34 | [InlineData("await PrivateClass.Delay(2, 5);")]
35 | [InlineData("var z = await PrivateClass.FromResult(2, 6);")]
36 | public Task DropMethodsWithSpecialNamesInUserClass(string invocation) => $$"""
37 | [CreateSyncVersion]
38 | public static async Task MethodAsync(CancellationToken ct)
39 | {
40 | {{invocation}}
41 | }
42 |
43 | private class PrivateClass
44 | {
45 | public static Task Delay(int delay, int unrelated) => Task.CompletedTask;
46 |
47 | public static Task FromResult(TResult delay, int unrelated) => Task.FromResult(delay);
48 | }
49 | """.Verify(disableUnique: true);
50 |
51 | private static string Caf(bool apply) => apply ? ".ConfigureAwait(false)" : string.Empty;
52 | }
53 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/SyncOnlyTests.cs:
--------------------------------------------------------------------------------
1 | namespace Generator.Tests;
2 |
3 | public class SyncOnlyTests
4 | {
5 | [Theory]
6 | [InlineData(true, "")]
7 | [InlineData(true, "if (!await component.AsyncDump(ct)) { }\n")]
8 | [InlineData(false, "\nif (!await component.AsyncDump(ct)) { }")]
9 | [InlineData(false, "\nif (!await component.AsyncDump(ct)) throw new InvalidOperationException(\"async exception\");")]
10 | public Task SimpleMacro(bool before, string additionalIgnorableCommands) => $$"""
11 | Component component = new();
12 |
13 | [CreateSyncVersion]
14 | public async Task ExecAsync(CancellationToken ct)
15 | {
16 | {{(before ? additionalIgnorableCommands : string.Empty)}}#if SYNC_ONLY
17 | throw new InvalidOperationException("Some exception");
18 | #endif{{(before ? string.Empty : additionalIgnorableCommands)}}
19 | }
20 |
21 | class Component
22 | {
23 | internal async Task AsyncDump(CancellationToken token) {
24 | return await Task.FromResult(false);
25 | }
26 | }
27 | """.Verify(false, true);
28 |
29 | [Fact]
30 | public Task InsideEmptyIf() => $$"""
31 | if (true)
32 | {
33 | #if SYNC_ONLY
34 | throw new InvalidOperationException("Some exception");
35 | #endif
36 | }
37 | """.Verify(false, true, sourceType: SourceType.MethodBody);
38 |
39 | [Fact]
40 | public Task StatementAtTheEnd() => $$"""
41 |
42 | #if SYNC_ONLY
43 | #endif
44 | Console.Write("Done");
45 | """.Verify(false, true, sourceType: SourceType.MethodBody);
46 |
47 | [Fact]
48 | public Task DoNotRemove() => """
49 | #if SYMBOL1
50 | ArgumentNullException.ThrowIfNull(source);
51 | #elif SYMBOL2
52 | ArgumentNullException.ThrowIfNull(source);
53 | #else
54 | ArgumentNullException.ThrowIfNull(source);
55 | #endif
56 | """.Verify(sourceType: SourceType.MethodBody);
57 |
58 | [Fact]
59 | public Task DoNotRemoveInsideSyncOnly() => """
60 | #if SYNC_ONLY
61 | #if SYMBOL
62 | throw new global::System.InvalidOperationException("Some exception");
63 | #endif
64 | #endif
65 | await Task.CompletedTask;
66 | """.Verify(sourceType: SourceType.MethodBody);
67 |
68 | [Fact]
69 | public Task NotSyncOnly() => """
70 | #if !SYNC_ONLY
71 | Console.Write("Async");
72 | #endif
73 | await Task.CompletedTask;
74 | """.Verify(sourceType: SourceType.MethodBody);
75 |
76 | [Theory]
77 | [InlineData(false)]
78 | [InlineData(true)]
79 | public Task NotSyncOnlyInsideSyncOnly(bool atLastToken)
80 | {
81 | var lastStatement = string.Empty;
82 | if (!atLastToken)
83 | {
84 | lastStatement = "await Task.CompletedTask;";
85 | }
86 |
87 | return $$"""
88 | if (true) { }
89 | #if SYNC_ONLY
90 | #if !SYNC_ONLY
91 | Console.Write("Async");
92 | #endif
93 | #endif
94 | {{lastStatement}}
95 | """.Verify(disableUnique: true, sourceType: SourceType.MethodBody);
96 | }
97 |
98 | [Fact]
99 | public Task NestedSyncOnly() => """
100 | #if SYNC_ONLY
101 | #if SYNC_ONLY
102 | System.Console.Write("Sync");
103 | #endif
104 | #endif
105 | await Task.CompletedTask;
106 | """.Verify(sourceType: SourceType.MethodBody);
107 |
108 | [Theory]
109 | [InlineData(false)]
110 | [InlineData(true)]
111 | public Task SyncOnlyBeforeMethodBody(bool beforeDeclaration) => $$"""
112 | {{(beforeDeclaration ? "[CreateSyncVersion]\n" : string.Empty)}}#if SYNC_ONLY
113 | [global::System.Obsolete]
114 | [global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
115 | #endif{{(beforeDeclaration ? string.Empty : "\n[CreateSyncVersion]")}}
116 | public async Task MethodWithObsoleteSyncAsync()
117 | {
118 | await Task.Delay(1000);
119 | }
120 | """.Verify(disableUnique: true);
121 |
122 | [Fact]
123 | public Task InsideParameter() => $$"""
124 | [CreateSyncVersion]
125 | public async Task IsNullAsync(
126 | #if SYNC_ONLY
127 | global::System.Data.IDataReader reader,
128 | #else
129 | DbDataReader reader,
130 | #endif
131 | int i)
132 | {
133 | return await reader.IsDBNullAsync(i);
134 | }
135 | """.Verify(disableUnique: true);
136 |
137 | [Fact]
138 | public Task LastParameter() => $$"""
139 | [CreateSyncVersion]
140 | public async Task IsNullAsync(
141 | #if SYNC_ONLY
142 | global::System.Data.IDataReader reader
143 | #else
144 | DbDataReader reader
145 | #endif
146 | )
147 | {
148 | return await reader.IsDBNullAsync(i);
149 | }
150 | """.Verify(disableUnique: true);
151 |
152 | [Theory]
153 | [InlineData(false, false)]
154 | [InlineData(false, true)]
155 | [InlineData(true, false)]
156 | [InlineData(true, true)]
157 | public Task NotSyncOnlyFollowedBySyncOnly(bool syncFirst, bool useElse)
158 | {
159 | var conditions = syncFirst switch
160 | {
161 | true when useElse => """
162 | #if SYNC_ONLY
163 | System.Console.Write("Sync");
164 | #else
165 | Console.Write("Async");
166 | #endif
167 | """,
168 | true when !useElse => """
169 | #if SYNC_ONLY
170 | System.Console.Write("Sync");
171 | #endif
172 | #if !SYNC_ONLY
173 | Console.Write("Async");
174 | #endif
175 | """,
176 | false when useElse => """
177 | #if !SYNC_ONLY
178 | Console.Write("Async");
179 | #else
180 | System.Console.Write("Sync");
181 | #endif
182 | """,
183 | _ => """
184 | #if SYNC_ONLY
185 | System.Console.Write("Sync");
186 | #endif
187 | #if !SYNC_ONLY
188 | Console.Write("Async");
189 | #endif
190 | """,
191 | };
192 |
193 | return $$"""
194 | {{conditions}}
195 | await Task.CompletedTask;
196 | """.Verify(disableUnique: true, sourceType: SourceType.MethodBody);
197 | }
198 |
199 | [Fact]
200 | public Task ProhibitElif() => """
201 | #if SYNC_ONLY
202 | Console.Write("Async");
203 | #elif Symbol
204 | Console.Write("Whatevs");
205 | #endif
206 | await Task.CompletedTask;
207 | """.Verify(sourceType: SourceType.MethodBody);
208 |
209 | [Fact]
210 | public Task DoNotMixSymbols() => """
211 | #if SYMBOL1 && !(SYNC_ONLY || SYMBOL2)
212 | System.Console.Write("Sync");
213 | #endif
214 | """.Verify(sourceType: SourceType.MethodBody);
215 |
216 | [Fact]
217 | public Task SwitchStatementProcessesDirectives() => """
218 | var i = 0;
219 | switch (i)
220 | {
221 | case 0:
222 | #if !SYNC_ONLY
223 | Console.Write("Async");
224 | #endif
225 | break;
226 | case 2:
227 | #if SYNC_ONLY
228 | System.Console.Write("Sync");
229 | #endif
230 | break;
231 | case 3:
232 | #if SYMBOL
233 | System.Console.Write("Symbol");
234 | #endif
235 | break;
236 | }
237 |
238 | await Task.CompletedTask;
239 | """.Verify(sourceType: SourceType.MethodBody);
240 |
241 | [Fact]
242 | public Task MultipleBlocksArentInterfering() => """
243 | string a = await Task.FromResult("");
244 | int b = 0;
245 |
246 | if (a != null)
247 | {
248 | b = 50;
249 | }
250 |
251 | #if SYNC_ONLY
252 | _ = a + b;
253 | #else
254 | _ = a + b + await Task.FromResult(30);
255 | #endif
256 | """.Verify(sourceType: SourceType.MethodBody);
257 | }
258 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/SystemAsyncExtensionsTests.cs:
--------------------------------------------------------------------------------
1 | namespace Generator.Tests;
2 |
3 | public class SystemAsyncExtensionsTests
4 | {
5 | [Fact]
6 | public Task DropConfiguredCancelableAsyncEnumerable() => """
7 | [CreateSyncVersion]
8 | public static async Task Iterate(this IAsyncEnumerable list1, [EnumeratorCancellation] CancellationToken ct = default)
9 | {
10 | await foreach (var item in list1.ConfigureAwait(false))
11 | {
12 | }
13 | }
14 | """.Verify();
15 |
16 | [Fact]
17 | public Task DropWithCancellation() => """
18 | [CreateSyncVersion]
19 | public static async Task Iterate(this IAsyncEnumerable list1, [EnumeratorCancellation] CancellationToken ct = default)
20 | {
21 | await foreach (var item in list1.WithCancellation(ct))
22 | {
23 | }
24 | }
25 | """.Verify();
26 |
27 | [Theory]
28 | [InlineData(true, true)]
29 | [InlineData(true, false)]
30 | [InlineData(false, true)]
31 | [InlineData(false, false)]
32 | public Task DropConfigureAwaitExtensions(bool isGeneric, bool isValueTask)
33 | {
34 | var taskPart = isValueTask ? "ValueTask" : "Task";
35 | var genericPart = isGeneric ? "" : string.Empty;
36 | var genericTaskPart = taskPart + genericPart;
37 | var variablePart = isGeneric ? "T" : "int";
38 | return $$"""
39 | namespace Test;
40 |
41 | public static class AwaitHelper
42 | {
43 | public static Configured{{taskPart}}Awaitable{{genericPart}} Caf{{genericPart}}(this {{genericTaskPart}} task)
44 | {
45 | return task.ConfigureAwait(false);
46 | }
47 | }
48 |
49 | partial class Class
50 | {
51 | {{variablePart}} GetItem{{genericPart}}({{variablePart}} z) => default;
52 |
53 | async {{genericTaskPart}} GetItemAsync{{genericPart}}({{variablePart}} z) => default;
54 |
55 | [Zomp.SyncMethodGenerator.CreateSyncVersion]
56 | public async Task InvokeAsync()
57 | => _ = await GetItemAsync(4).Caf();
58 | }
59 | """.Verify(disableUnique: true, sourceType: SourceType.Full);
60 | }
61 |
62 | [Fact]
63 | public Task AsyncForEachQualified() => """
64 | [CreateSyncVersion]
65 | async Task SumAsync(IAsyncEnumerable enumerable)
66 | {
67 | int sum = 0;
68 |
69 | await foreach (int? i in enumerable)
70 | {
71 | if (i.HasValue)
72 | {
73 | sum += i.Value;
74 | }
75 | }
76 |
77 | return sum;
78 | }
79 | """.Verify();
80 |
81 | [Fact]
82 | public Task AsyncForEachDeconstruct() => """
83 | [CreateSyncVersion]
84 | async Task SumAsync(IAsyncEnumerable<(int a, int b)> enumerable)
85 | {
86 | int sum = 0;
87 |
88 | await foreach (var (a, b) in enumerable)
89 | {
90 | sum += a + b;
91 | }
92 |
93 | return sum;
94 | }
95 | """.Verify();
96 |
97 | [Fact]
98 | public Task ConfiguredCancelableAsyncEnumerable() => """
99 | [CreateSyncVersion]
100 | internal async Task MethodAsync(IAsyncEnumerable<(Stream A, int B)> enumerable, CancellationToken ct)
101 | {
102 | var enumerator = enumerable.WithCancellation(ct).ConfigureAwait(false).GetAsyncEnumerator();
103 |
104 | int sum = 0;
105 | while (await enumerator.MoveNextAsync())
106 | {
107 | sum += (int)enumerator.Current.A.Length + enumerator.Current.B;
108 | }
109 |
110 | return sum;
111 | }
112 | """.Verify();
113 |
114 | [Fact]
115 | public Task ConfiguredCancelableAsyncEnumerableExtension() => """
116 | // From https://github.com/dotnet/reactive/blob/5f831de0bc70bc660d21c3b9e04e581269691a2a/Ix.NET/Source/System.Linq.Async/System/Threading/Tasks/AsyncEnumerableExt.cs#L15
117 |
118 | [CreateSyncVersion]
119 | public static ConfiguredCancelableAsyncEnumerable.Enumerator GetConfiguredEnumeratorAsync(IAsyncEnumerable enumerable, CancellationToken ct)
120 | {
121 | return enumerable.ConfigureAwait(false).WithCancellation(ct).GetAsyncEnumerator();
122 | }
123 | """.Verify();
124 |
125 | [Fact]
126 | public Task ConfiguredCancelableAsyncEnumerableExtensionUsingStatic() => """
127 | using static System.Runtime.CompilerServices.ConfiguredCancelableAsyncEnumerable;
128 | namespace Test;
129 |
130 | internal static partial class Extensions
131 | {
132 | [CreateSyncVersion]
133 | public static Enumerator GetConfiguredAsyncEnumerator(IAsyncEnumerable enumerable, CancellationToken ct)
134 | {
135 | return enumerable.ConfigureAwait(false).WithCancellation(ct).GetAsyncEnumerator();
136 | }
137 | }
138 | """.Verify(sourceType: SourceType.Full);
139 |
140 | [Fact]
141 | public Task DropConfiguredCancelableAsyncEnumerableExtensionInvocation() => """
142 | namespace Test;
143 |
144 | internal static partial class Extensions
145 | {
146 | // From https://github.com/dotnet/reactive/blob/5f831de0bc70bc660d21c3b9e04e581269691a2a/Ix.NET/Source/System.Linq.Async/System/Threading/Tasks/AsyncEnumerableExt.cs#L15
147 | internal static ConfiguredCancelableAsyncEnumerable.Enumerator GetConfiguredAsyncEnumerator(this IAsyncEnumerable enumerable, CancellationToken ct)
148 | {
149 | return enumerable.ConfigureAwait(false).WithCancellation(ct).GetAsyncEnumerator();
150 | }
151 |
152 | [CreateSyncVersion]
153 | internal static async Task MethodAsync(IAsyncEnumerable enumerable, CancellationToken ct)
154 | {
155 | await using ConfiguredCancelableAsyncEnumerable.Enumerator enumerator = enumerable.GetConfiguredAsyncEnumerator(ct);
156 | }
157 | }
158 | """.Verify(sourceType: SourceType.Full);
159 | }
160 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/TestHelper.cs:
--------------------------------------------------------------------------------
1 | using System.Data.Common;
2 | using System.Diagnostics;
3 | using System.Text.RegularExpressions;
4 | using Zomp.SyncMethodGenerator;
5 | using static Generator.Tests.ModuleInitializer;
6 |
7 | namespace Generator.Tests;
8 |
9 | ///
10 | /// Helps set up the test cases.
11 | ///
12 | internal static partial class TestHelper
13 | {
14 | private const string GlobalUsingsSource = """
15 | global using global::System;
16 | global using global::System.Buffers;
17 | global using global::System.Collections.Generic;
18 | global using global::System.Data;
19 | global using global::System.Data.Common;
20 | global using global::System.Diagnostics;
21 | global using global::System.Drawing;
22 | global using global::System.IO;
23 | global using global::System.Linq;
24 | #if NET8_0_OR_GREATER
25 | global using global::System.Numerics;
26 | #endif
27 | global using global::System.Reflection;
28 | global using global::System.Runtime.CompilerServices;
29 | global using global::System.Threading;
30 | global using global::System.Threading.Tasks;
31 | global using global::Zomp.SyncMethodGenerator;
32 | """;
33 |
34 | private static readonly string[] PreprocessorSymbols
35 | #if NETFRAMEWORK
36 | = [];
37 | #else
38 | =
39 | [
40 | #if NET8_0
41 | "NET8_0",
42 | #endif
43 | #if NET8_0_OR_GREATER
44 | "NET8_0_OR_GREATER",
45 | #endif
46 | ];
47 | #endif
48 |
49 | internal static Task Verify(
50 | this string source,
51 | bool uniqueForFramework = false,
52 | bool disableUnique = false,
53 | SourceType sourceType = SourceType.ClassBody,
54 | LanguageVersion languageVersion = LanguageVersion.Preview,
55 | params object?[] parameters)
56 | {
57 | var parseOptions = CSharpParseOptions.Default
58 | .WithLanguageVersion(languageVersion)
59 | .WithPreprocessorSymbols(PreprocessorSymbols);
60 |
61 | if (sourceType != SourceType.Full)
62 | {
63 | if (sourceType == SourceType.MethodBody)
64 | {
65 | source = $$"""
66 | [CreateSyncVersion]
67 | async Task MethodAsync(CancellationToken ct)
68 | {
69 | {{ChangeIndentation(source, InsertIndentation)}}
70 | }
71 | """;
72 | }
73 |
74 | source = ChangeIndentation(source, InsertIndentation);
75 | source = $$"""
76 | namespace Test;
77 | partial class Class
78 | {
79 | {{source}}
80 | }
81 | """;
82 | }
83 |
84 | var syntaxTree = CSharpSyntaxTree.ParseText(source, parseOptions);
85 | var globalUsings = CSharpSyntaxTree.ParseText(GlobalUsingsSource, parseOptions);
86 |
87 | // SyntaxTree syntaxTree = CSharpSyntaxTree.ParseText(source);
88 | var linqAssembly = typeof(Enumerable).Assembly.Location;
89 | var locations = new List
90 | {
91 | typeof(IAsyncEnumerable<>).Assembly.Location,
92 | typeof(DataReceivedEventHandler).Assembly.Location,
93 | typeof(DbDataReader).Assembly.Location,
94 | typeof(ValueTask<>).Assembly.Location,
95 | typeof(System.Drawing.Point).Assembly.Location,
96 | typeof(object).Assembly.Location,
97 | typeof(Console).Assembly.Location,
98 | typeof(Memory<>).Assembly.Location,
99 | typeof(System.Buffers.MemoryPool<>).Assembly.Location,
100 | typeof(Queue<>).Assembly.Location,
101 | typeof(LinkedListNode<>).Assembly.Location,
102 | #if NET8_0_OR_GREATER
103 | typeof(AsyncEnumerable).Assembly.Location,
104 | #endif
105 | linqAssembly,
106 | };
107 |
108 | var directory = Path.GetDirectoryName(linqAssembly);
109 | var runtimeLocation = directory is null ? null : Path.Combine(directory, "System.Runtime.dll");
110 | if (runtimeLocation is not null && File.Exists(runtimeLocation))
111 | {
112 | locations.Add(runtimeLocation);
113 | }
114 |
115 | var distinct = locations.Distinct().ToArray();
116 |
117 | var references = distinct
118 | .Select(l => MetadataReference.CreateFromFile(l));
119 |
120 | var compilation = CSharpCompilation.Create(
121 | assemblyName: "Tests",
122 | options: new(OutputKind.DynamicallyLinkedLibrary),
123 | syntaxTrees: [syntaxTree, globalUsings],
124 | references: references);
125 |
126 | var generator = new SyncMethodSourceGenerator();
127 |
128 | var driver = CSharpGeneratorDriver.Create(generator).WithUpdatedParseOptions(parseOptions);
129 |
130 | driver = driver.RunGenerators(compilation);
131 |
132 | // Ensure that at least two sources are generated
133 | var results = driver.GetRunResult();
134 | if (results.Diagnostics.Length == 0 && results.GeneratedTrees.Length < 2)
135 | {
136 | throw new InvalidOperationException("Nothing generated");
137 | }
138 |
139 | var target = new RunResultWithIgnoreList
140 | {
141 | Result = driver.GetRunResult(),
142 | IgnoredFiles = { $"{SyncMethodSourceGenerator.CreateSyncVersionAttribute}.g.cs" },
143 | };
144 |
145 | var verifier = Verifier
146 | .Verify(target)
147 | .UseDirectory("Snapshots");
148 |
149 | if (uniqueForFramework)
150 | {
151 | verifier = verifier.UniqueForTargetFrameworkAndVersion();
152 | }
153 |
154 | if (disableUnique)
155 | {
156 | verifier = verifier.DisableRequireUniquePrefix();
157 | }
158 |
159 | if (parameters is { Length: > 0 })
160 | {
161 | verifier = verifier.UseParameters(parameters);
162 | }
163 |
164 | return verifier;
165 | }
166 |
167 | internal static string InsertIndentation(string s) => s.Length == 0 || s[0] == '#' ? s : $" {s}";
168 |
169 | internal static string RemoveIndentation(string s) => s.StartsWith(" ", StringComparison.Ordinal) ? s[4..] : s;
170 |
171 | internal static string ChangeIndentation(string source, Func func)
172 | {
173 | #if NET8_0_OR_GREATER
174 | var lines = NewLineRegex().Split(source);
175 | #else
176 | var lines = Regex.Split(source, "\r\n");
177 | #endif
178 | var linesWithIndentation = string.Join("\r\n", lines.Select(func));
179 | return linesWithIndentation;
180 | }
181 |
182 | #if NET8_0_OR_GREATER
183 | [GeneratedRegex("\r\n")]
184 | private static partial Regex NewLineRegex();
185 | #endif
186 | }
187 |
--------------------------------------------------------------------------------
/tests/Generator.Tests/TypeTests.cs:
--------------------------------------------------------------------------------
1 | namespace Generator.Tests;
2 |
3 | public class TypeTests
4 | {
5 | [Fact]
6 | public Task ConvertExceptionType() => $$"""
7 | try
8 | {
9 | await Task.CompletedTask;
10 | }
11 | catch (OperationCanceledException)
12 | {
13 | }
14 | """.Verify(false, true, sourceType: SourceType.MethodBody);
15 |
16 | [Fact]
17 | public Task NotPattern() =>
18 | "_ = new object() is not DBNull;"
19 | .Verify(false, true, sourceType: SourceType.MethodBody);
20 |
21 | [Fact]
22 | public Task PatternMatchingWithConstant() =>
23 | "_ = 1 is 2;"
24 | .Verify(sourceType: SourceType.MethodBody);
25 |
26 | [Fact]
27 | public Task PatternIsNotLiteral() =>
28 | "_ = StringComparison.CurrentCulture is not StringComparison.CurrentCulture;"
29 | .Verify(sourceType: SourceType.MethodBody);
30 |
31 | [Fact]
32 | public Task PatternIsEnumMember() =>
33 | "_ = StringComparison.CurrentCulture is StringComparison.CurrentCulture;"
34 | .Verify(sourceType: SourceType.MethodBody);
35 |
36 | [Fact]
37 | public Task VariableDeclarationRedundant() =>
38 | "MemoryStream ms = new MemoryStream();"
39 | .Verify(false, true, sourceType: SourceType.MethodBody);
40 |
41 | [Fact]
42 | public Task VariableDeclaration() =>
43 | "MemoryStream ms = new();"
44 | .Verify(false, true, sourceType: SourceType.MethodBody);
45 |
46 | [Fact]
47 | public Task BinaryPattern() =>
48 | "_ = new object() is DBNull or Stream;"
49 | .Verify(false, true, sourceType: SourceType.MethodBody);
50 |
51 | [Theory]
52 | [InlineData(true)]
53 | [InlineData(false)]
54 | public Task EnumPattern(bool isQualified) =>
55 | $$"""
56 | using static System.Data.ConnectionState;
57 | namespace Test;
58 |
59 | partial class Class
60 | {
61 | [CreateSyncVersion]
62 | public Task MethodAsync()
63 | {
64 | _ = {{(isQualified ? "System.Data.ConnectionState." : string.Empty)}}Closed is System.Data.ConnectionState.Closed;
65 | }
66 | }
67 | """
68 | .Verify(false, true, sourceType: SourceType.Full);
69 |
70 | [Fact]
71 | public Task EnumPatternName() =>
72 | """
73 | enum Test { Test }
74 |
75 | partial class Class
76 | {
77 | [Zomp.SyncMethodGenerator.CreateSyncVersion]
78 | public Task ReturnTrueAsync()
79 | {
80 | return Task.FromResult(Test.Test is Test.Test);
81 | }
82 | }
83 | """
84 | .Verify(false, true, sourceType: SourceType.Full);
85 |
86 | [Fact]
87 | public Task DeclarationExpression() =>
88 | "new Dictionary().TryGetValue(0, out Stream a);"
89 | .Verify(false, true, sourceType: SourceType.MethodBody);
90 |
91 | [Fact]
92 | public Task NullableDeclarationExpression() =>
93 | "new Dictionary().TryGetValue(0, out Stream? a);"
94 | .Verify(false, true, sourceType: SourceType.MethodBody);
95 |
96 | [Fact]
97 | public Task ConvertForeachType() => $$"""
98 | foreach (Int32 i in new Int32[] { 1 })
99 | {
100 | }
101 |
102 | await Task.CompletedTask;
103 | """.Verify(false, true, sourceType: SourceType.MethodBody);
104 |
105 | [Fact]
106 | public Task NullableForeach()
107 | => """
108 | foreach (Stream? i in Array.Empty())
109 | {
110 | }
111 | """
112 | .Verify(sourceType: SourceType.MethodBody);
113 |
114 | [Fact]
115 | public Task NestedGenerics()
116 | => "var dict = new Dictionary>();"
117 | .Verify(sourceType: SourceType.MethodBody);
118 |
119 | [Fact]
120 | public Task TestTypes() => $$"""
121 | String myStr;
122 | string myStrPredefined;
123 | Exception ex;
124 | Int16 myShort;
125 | Int16[] myShorts;
126 | long myLong;
127 |
128 | await Task.CompletedTask;
129 | """.Verify(false, true, sourceType: SourceType.MethodBody);
130 |
131 | [Fact]
132 | public Task ArrayParameter() => """
133 | [CreateSyncVersion]
134 | public async Task MethodAsync(Int32[] o)
135 | {
136 | }
137 | """.Verify();
138 |
139 | [Fact]
140 | public Task CastFullyQualifiedType() => """
141 | class CustomClass { }
142 |
143 | [CreateSyncVersion]
144 | public async Task