diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index c5d209fb1fda5..5bd1db04eb95e 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -6,16 +6,4 @@ FROM mcr.microsoft.com/vscode/devcontainers/dotnet:0-${VARIANT} # Set up machine requirements to build the repo RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \ - && apt-get -y install --no-install-recommends cmake llvm-9 clang-9 \ - build-essential python curl git lldb-6.0 liblldb-6.0-dev \ - libunwind8 libunwind8-dev gettext libicu-dev liblttng-ust-dev \ - libssl-dev libnuma-dev libkrb5-dev zlib1g-dev ninja-build - -# Install V8 Engine -SHELL ["/bin/bash", "-c"] - -RUN curl -sSL "https://netcorenativeassets.blob.core.windows.net/resource-packages/external/linux/chromium-v8/v8-linux64-rel-8.5.183.zip" -o ./v8.zip \ - && unzip ./v8.zip -d /usr/local/v8 \ - && echo $'#!/usr/bin/env bash\n\ -"/usr/local/v8/d8" --snapshot_blob="/usr/local/v8/snapshot_blob.bin" "$@"\n' > /usr/local/bin/v8 \ - && chmod +x /usr/local/bin/v8 \ No newline at end of file + && apt-get -y install --no-install-recommends curl git diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 8be9f768ee90d..942a2b624491e 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -40,3 +40,5 @@ src/Compilers/**/PublicAPI.Unshipped.txt @dotnet/roslyn-api-owners src/Workspaces/**/PublicAPI.Unshipped.txt @dotnet/roslyn-api-owners src/Features/**/PublicAPI.Unshipped.txt @dotnet/roslyn-api-owners src/EditorFeatures/**/PublicAPI.Unshipped.txt @dotnet/roslyn-api-owners + +src/Tools/ExternalAccess/OmniSharp*/ @333fred @joerobich diff --git a/.vscode/settings.json b/.vscode/settings.json index 30d1af265a8ec..33f395601404b 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -26,7 +26,6 @@ "omnisharp.disableMSBuildDiagnosticWarning": true, "omnisharp.enableEditorConfigSupport": true, "omnisharp.enableImportCompletion": true, - "omnisharp.enableRoslynAnalyzers": true, "omnisharp.useModernNet": true, "omnisharp.enableAsyncCompletion": true, // ms-vscode.powershell settings @@ -35,4 +34,4 @@ "powershell.startAutomatically": false, // ms-azure-devops.azure-pipelines settings "azure-pipelines.customSchemaFile": ".vscode/dnceng-schema.json" -} \ No newline at end of file +} diff --git a/NuGet.config b/NuGet.config index 8c879770d5df4..a26b4ca869d72 100644 --- a/NuGet.config +++ b/NuGet.config @@ -7,6 +7,8 @@ + + diff --git a/Roslyn.sln b/Roslyn.sln index b90c9e295369f..475b330043b1c 100644 --- a/Roslyn.sln +++ b/Roslyn.sln @@ -220,20 +220,14 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Build.Tasks.CodeA EndProject Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "BasicResultProvider", "src\ExpressionEvaluator\VisualBasic\Source\ResultProvider\BasicResultProvider.shproj", "{3140FE61-0856-4367-9AA3-8081B9A80E35}" EndProject -Project("{778DAE3C-4631-46EA-AA77-85C1314464D9}") = "BasicResultProvider.NetFX20", "src\ExpressionEvaluator\VisualBasic\Source\ResultProvider\NetFX20\BasicResultProvider.NetFX20.vbproj", "{76242A2D-2600-49DD-8C15-FEA07ECB1842}" -EndProject Project("{778DAE3C-4631-46EA-AA77-85C1314464D9}") = "Microsoft.CodeAnalysis.VisualBasic.ResultProvider", "src\ExpressionEvaluator\VisualBasic\Source\ResultProvider\Portable\Microsoft.CodeAnalysis.VisualBasic.ResultProvider.vbproj", "{76242A2D-2600-49DD-8C15-FEA07ECB1843}" EndProject Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "CSharpResultProvider", "src\ExpressionEvaluator\CSharp\Source\ResultProvider\CSharpResultProvider.shproj", "{3140FE61-0856-4367-9AA3-8081B9A80E36}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CSharpResultProvider.NetFX20", "src\ExpressionEvaluator\CSharp\Source\ResultProvider\NetFX20\CSharpResultProvider.NetFX20.csproj", "{BF9DAC1E-3A5E-4DC3-BB44-9A64E0D4E9D3}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.CodeAnalysis.CSharp.ResultProvider", "src\ExpressionEvaluator\CSharp\Source\ResultProvider\Portable\Microsoft.CodeAnalysis.CSharp.ResultProvider.csproj", "{BF9DAC1E-3A5E-4DC3-BB44-9A64E0D4E9D4}" EndProject Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "ResultProvider", "src\ExpressionEvaluator\Core\Source\ResultProvider\ResultProvider.shproj", "{BB3CA047-5D00-48D4-B7D3-233C1265C065}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ResultProvider.NetFX20", "src\ExpressionEvaluator\Core\Source\ResultProvider\NetFX20\ResultProvider.NetFX20.csproj", "{BEDC5A4A-809E-4017-9CFD-6C8D4E1847F0}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.CodeAnalysis.ResultProvider", "src\ExpressionEvaluator\Core\Source\ResultProvider\Portable\Microsoft.CodeAnalysis.ResultProvider.csproj", "{FA0E905D-EC46-466D-B7B2-3B5557F9428C}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "vbc", "src\Compilers\VisualBasic\vbc\vbc.csproj", "{E58EE9D7-1239-4961-A0C1-F9EC3952C4C1}" @@ -540,7 +534,6 @@ Global src\Workspaces\SharedUtilitiesAndExtensions\Workspace\Core\WorkspaceExtensions.projitems*{5ff1e493-69cc-4d0b-83f2-039f469a04e1}*SharedItemsImports = 5 src\ExpressionEvaluator\CSharp\Source\ResultProvider\CSharpResultProvider.projitems*{60db272a-21c9-4e8d-9803-ff4e132392c8}*SharedItemsImports = 5 src\Workspaces\SharedUtilitiesAndExtensions\Compiler\CSharp\CSharpCompilerExtensions.projitems*{699fea05-aea7-403d-827e-53cf4e826955}*SharedItemsImports = 13 - src\ExpressionEvaluator\VisualBasic\Source\ResultProvider\BasicResultProvider.projitems*{76242a2d-2600-49dd-8c15-fea07ecb1842}*SharedItemsImports = 5 src\ExpressionEvaluator\VisualBasic\Source\ResultProvider\BasicResultProvider.projitems*{76242a2d-2600-49dd-8c15-fea07ecb1843}*SharedItemsImports = 5 src\Analyzers\Core\Analyzers\Analyzers.projitems*{76e96966-4780-4040-8197-bde2879516f4}*SharedItemsImports = 13 src\Compilers\Core\CommandLine\CommandLine.projitems*{7ad4fe65-9a30-41a6-8004-aa8f89bcb7f3}*SharedItemsImports = 5 @@ -562,8 +555,6 @@ Global src\Compilers\Core\CommandLine\CommandLine.projitems*{ad6f474e-e6d4-4217-91f3-b7af1be31ccc}*SharedItemsImports = 13 src\Compilers\CSharp\CSharpAnalyzerDriver\CSharpAnalyzerDriver.projitems*{b501a547-c911-4a05-ac6e-274a50dff30e}*SharedItemsImports = 5 src\ExpressionEvaluator\Core\Source\ResultProvider\ResultProvider.projitems*{bb3ca047-5d00-48d4-b7d3-233c1265c065}*SharedItemsImports = 13 - src\ExpressionEvaluator\Core\Source\ResultProvider\ResultProvider.projitems*{bedc5a4a-809e-4017-9cfd-6c8d4e1847f0}*SharedItemsImports = 5 - src\ExpressionEvaluator\CSharp\Source\ResultProvider\CSharpResultProvider.projitems*{bf9dac1e-3a5e-4dc3-bb44-9a64e0d4e9d3}*SharedItemsImports = 5 src\ExpressionEvaluator\CSharp\Source\ResultProvider\CSharpResultProvider.projitems*{bf9dac1e-3a5e-4dc3-bb44-9a64e0d4e9d4}*SharedItemsImports = 5 src\Dependencies\PooledObjects\Microsoft.CodeAnalysis.PooledObjects.projitems*{c1930979-c824-496b-a630-70f5369a636f}*SharedItemsImports = 13 src\Workspaces\SharedUtilitiesAndExtensions\Compiler\VisualBasic\VisualBasicCompilerExtensions.projitems*{cec0dce7-8d52-45c3-9295-fc7b16bd2451}*SharedItemsImports = 13 @@ -912,26 +903,14 @@ Global {1DFEA9C5-973C-4179-9B1B-0F32288E1EF2}.Debug|Any CPU.Build.0 = Debug|Any CPU {1DFEA9C5-973C-4179-9B1B-0F32288E1EF2}.Release|Any CPU.ActiveCfg = Release|Any CPU {1DFEA9C5-973C-4179-9B1B-0F32288E1EF2}.Release|Any CPU.Build.0 = Release|Any CPU - {76242A2D-2600-49DD-8C15-FEA07ECB1842}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {76242A2D-2600-49DD-8C15-FEA07ECB1842}.Debug|Any CPU.Build.0 = Debug|Any CPU - {76242A2D-2600-49DD-8C15-FEA07ECB1842}.Release|Any CPU.ActiveCfg = Release|Any CPU - {76242A2D-2600-49DD-8C15-FEA07ECB1842}.Release|Any CPU.Build.0 = Release|Any CPU {76242A2D-2600-49DD-8C15-FEA07ECB1843}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {76242A2D-2600-49DD-8C15-FEA07ECB1843}.Debug|Any CPU.Build.0 = Debug|Any CPU {76242A2D-2600-49DD-8C15-FEA07ECB1843}.Release|Any CPU.ActiveCfg = Release|Any CPU {76242A2D-2600-49DD-8C15-FEA07ECB1843}.Release|Any CPU.Build.0 = Release|Any CPU - {BF9DAC1E-3A5E-4DC3-BB44-9A64E0D4E9D3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {BF9DAC1E-3A5E-4DC3-BB44-9A64E0D4E9D3}.Debug|Any CPU.Build.0 = Debug|Any CPU - {BF9DAC1E-3A5E-4DC3-BB44-9A64E0D4E9D3}.Release|Any CPU.ActiveCfg = Release|Any CPU - {BF9DAC1E-3A5E-4DC3-BB44-9A64E0D4E9D3}.Release|Any CPU.Build.0 = Release|Any CPU {BF9DAC1E-3A5E-4DC3-BB44-9A64E0D4E9D4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {BF9DAC1E-3A5E-4DC3-BB44-9A64E0D4E9D4}.Debug|Any CPU.Build.0 = Debug|Any CPU {BF9DAC1E-3A5E-4DC3-BB44-9A64E0D4E9D4}.Release|Any CPU.ActiveCfg = Release|Any CPU {BF9DAC1E-3A5E-4DC3-BB44-9A64E0D4E9D4}.Release|Any CPU.Build.0 = Release|Any CPU - {BEDC5A4A-809E-4017-9CFD-6C8D4E1847F0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {BEDC5A4A-809E-4017-9CFD-6C8D4E1847F0}.Debug|Any CPU.Build.0 = Debug|Any CPU - {BEDC5A4A-809E-4017-9CFD-6C8D4E1847F0}.Release|Any CPU.ActiveCfg = Release|Any CPU - {BEDC5A4A-809E-4017-9CFD-6C8D4E1847F0}.Release|Any CPU.Build.0 = Release|Any CPU {FA0E905D-EC46-466D-B7B2-3B5557F9428C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {FA0E905D-EC46-466D-B7B2-3B5557F9428C}.Debug|Any CPU.Build.0 = Debug|Any CPU {FA0E905D-EC46-466D-B7B2-3B5557F9428C}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -1400,13 +1379,10 @@ Global {FCFA8808-A1B6-48CC-A1EA-0B8CA8AEDA8E} = {32A48625-F0AD-419D-828B-A50BDABA38EA} {1DFEA9C5-973C-4179-9B1B-0F32288E1EF2} = {A41D1B99-F489-4C43-BBDF-96D61B19A6B9} {3140FE61-0856-4367-9AA3-8081B9A80E35} = {151F6994-AEB3-4B12-B746-2ACFF26C7BBB} - {76242A2D-2600-49DD-8C15-FEA07ECB1842} = {151F6994-AEB3-4B12-B746-2ACFF26C7BBB} {76242A2D-2600-49DD-8C15-FEA07ECB1843} = {151F6994-AEB3-4B12-B746-2ACFF26C7BBB} {3140FE61-0856-4367-9AA3-8081B9A80E36} = {913A4C08-898E-49C7-9692-0EF9DC56CF6E} - {BF9DAC1E-3A5E-4DC3-BB44-9A64E0D4E9D3} = {913A4C08-898E-49C7-9692-0EF9DC56CF6E} {BF9DAC1E-3A5E-4DC3-BB44-9A64E0D4E9D4} = {913A4C08-898E-49C7-9692-0EF9DC56CF6E} {BB3CA047-5D00-48D4-B7D3-233C1265C065} = {998CAFE8-06E4-4683-A151-0F6AA4BFF6C6} - {BEDC5A4A-809E-4017-9CFD-6C8D4E1847F0} = {998CAFE8-06E4-4683-A151-0F6AA4BFF6C6} {FA0E905D-EC46-466D-B7B2-3B5557F9428C} = {998CAFE8-06E4-4683-A151-0F6AA4BFF6C6} {E58EE9D7-1239-4961-A0C1-F9EC3952C4C1} = {C65C6143-BED3-46E6-869E-9F0BE6E84C37} {6FD1CC3E-6A99-4736-9B8D-757992DDE75D} = {38940C5F-97FD-4B2A-B2CD-C4E4EF601B05} diff --git a/azure-pipelines-official.yml b/azure-pipelines-official.yml index e43cb5206ac23..78a1a6cd59207 100644 --- a/azure-pipelines-official.yml +++ b/azure-pipelines-official.yml @@ -1,3 +1,15 @@ +trigger: + branches: + include: + - main + - main-vs-deps + - release/dev16.*-vs-deps + - release/dev17.* + exclude: + - release/dev17.0 + - release/dev17.1 +pr: none + resources: - repo: self clean: true @@ -180,6 +192,8 @@ stages: /p:DotnetPublishUsingPipelines=true /p:IgnoreIbcMergeErrors=true condition: succeeded() + + - template: eng\common\templates\steps\generate-sbom.yml - task: PowerShell@2 displayName: Publish Assets diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 6e0c9a95799d7..9375997c9956b 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -146,7 +146,7 @@ jobs: testArtifactName: Transport_Artifacts_Unix_Debug configuration: Debug testArguments: --testCoreClr - queueName: 'Build.Ubuntu.1804.amd64.Open' + queueName: Build.Ubuntu.1804.Amd64.Open - template: eng/pipelines/test-unix-job.yml parameters: @@ -209,6 +209,16 @@ jobs: publishLocation: Container condition: succeeded() +- job: Correctness_TodoCheck + pool: + vmImage: ubuntu-20.04 + timeoutInMinutes: 10 + steps: + - template: eng/pipelines/checkout-unix-task.yml + + - pwsh: eng/todo-check.ps1 + displayName: Validate TODO/PROTOTYPE comments are not present + - job: Correctness_Rebuild pool: name: NetCore1ESPool-Public diff --git a/docs/Language Feature Status.md b/docs/Language Feature Status.md index c64def30e833b..f1908ed8ac47d 100644 --- a/docs/Language Feature Status.md +++ b/docs/Language Feature Status.md @@ -21,14 +21,14 @@ efforts behind them. | [Default in deconstruction](https://github.com/dotnet/roslyn/pull/25562) | [decon-default](https://github.com/dotnet/roslyn/tree/features/decon-default) | [Implemented](https://github.com/dotnet/roslyn/issues/25559) | [jcouv](https://github.com/jcouv) | [gafter](https://github.com/gafter) | [jcouv](https://github.com/jcouv) | | [Semi-auto-properties](https://github.com/dotnet/csharplang/issues/140) | [semi-auto-props](https://github.com/dotnet/roslyn/tree/features/semi-auto-props) | [In Progress](https://github.com/dotnet/roslyn/issues/57012) | [Youssef1313](https://github.com/Youssef1313) | [333fred](https://github.com/333fred), [RikkiGibson](https://github.com/RikkiGibson) | [CyrusNajmabadi](https://github.com/CyrusNajmabadi) | | [Required members](https://github.com/dotnet/csharplang/issues/3630) | [required-members](https://github.com/dotnet/roslyn/tree/features/required-members) | [In Progress](https://github.com/dotnet/roslyn/issues/57046) | [333fred](https://github.com/333fred) | [jcouv](https://github.com/jcouv), [RikkiGibson](https://github.com/RikkiGibson) | [333fred](https://github.com/333fred) | -| [Top Level statement attribute specifiers](https://github.com/dotnet/csharplang/issues/5045) | [main-attributes](https://github.com/dotnet/roslyn/tree/features/main-attributes) | [In Progress](https://github.com/dotnet/roslyn/issues/57047) | [chsienki](https://github.com/chsienki) | TBD | [jaredpar](https://github.com/jaredpar) | +| [Top Level statement attribute specifiers](https://github.com/dotnet/csharplang/issues/5045) | [main-attributes](https://github.com/dotnet/roslyn/tree/features/main-attributes) | [In Progress](https://github.com/dotnet/roslyn/issues/57047) | [chsienki](https://github.com/chsienki) | [cston](https://github.com/cston), [333fred](https://github.com/333fred) | [jaredpar](https://github.com/jaredpar) | | [Primary Constructors](https://github.com/dotnet/csharplang/issues/2691) | [primary-constructors](https://github.com/dotnet/roslyn/tree/features/primary-constructors) | [In Progress](https://github.com/dotnet/roslyn/issues/57048) | TBD | TBD | [MadsTorgersen](https://github.com/MadsTorgersen) | | [Params Span\ + Stackalloc any array type](https://github.com/dotnet/csharplang/issues/1757) | [params-span](https://github.com/dotnet/roslyn/tree/features/params-span) | [In Progress](https://github.com/dotnet/roslyn/issues/57049) | [cston](https://github.com/cston) | TBD | [jaredpar](https://github.com/jaredpar) | -| [Switch on ReadOnlySpan](https://github.com/dotnet/csharplang/issues/1881) | main | [In Progress](https://github.com/dotnet/roslyn/issues/59191) | [YairHalberstadt ](https://github.com/YairHalberstadt) | [cston](https://github.com/cston), [RikkiGibson](https://github.com/RikkiGibson) | [jcouv](https://github.com/jcouv) | +| [Pattern matching on `ReadOnlySpan`](https://github.com/dotnet/csharplang/issues/1881) | [patterns-span-char](https://github.com/dotnet/roslyn/tree/features/patterns-span-char) | [In Progress](https://github.com/dotnet/roslyn/issues/59191) | [YairHalberstadt ](https://github.com/YairHalberstadt) | [cston](https://github.com/cston), [RikkiGibson](https://github.com/RikkiGibson) | [jcouv](https://github.com/jcouv) | | [nameof accessing instance members](https://github.com/dotnet/roslyn/issues/40229) | main | [In Progress](https://github.com/dotnet/roslyn/pull/48754) | [YairHalberstadt ](https://github.com/YairHalberstadt) | [333fred](https://github.com/333fred), [AlekseyTs](https://github.com/AlekseyTs) | [333fred](https://github.com/333fred) | | [Utf8 String Literals](https://github.com/dotnet/csharplang/issues/184) | [Utf8StringLiterals](https://github.com/dotnet/roslyn/tree/features/Utf8StringLiterals) | [In Progress](https://github.com/dotnet/roslyn/issues/58848) | [AlekseyTs](https://github.com/AlekseyTs) | [cston](https://github.com/cston), [RikkiGibson](https://github.com/RikkiGibson) | [MadsTorgersen](https://github.com/MadsTorgersen) | -| [ref fields](https://github.com/dotnet/csharplang/blob/main/proposals/low-level-struct-improvements.md) | TBD | [In Progress](https://github.com/dotnet/roslyn/issues/59194) | TBD | TBD | [jaredpar](https://github.com/jaredpar) | -| [checked operators](https://github.com/dotnet/csharplang/issues/4665) | TBD | [In Progress](https://github.com/dotnet/roslyn/issues/59196) | TBD | TBD | [AlekseyTs](https://github.com/AlekseyTs) | +| [ref fields](https://github.com/dotnet/csharplang/blob/main/proposals/low-level-struct-improvements.md) | [ref-fields](https://github.com/dotnet/roslyn/tree/features/ref-fields) | [In Progress](https://github.com/dotnet/roslyn/issues/59194) | [cston](https://github.com/cston) | [RikkiGibson](https://github.com/RikkiGibson), [AlekseyTs](https://github.com/AlekseyTs) | [jaredpar](https://github.com/jaredpar) | +| [checked operators](https://github.com/dotnet/csharplang/issues/4665) | [CheckedUserDefinedOperators](https://github.com/dotnet/roslyn/tree/features/CheckedUserDefinedOperators) | [In Progress](https://github.com/dotnet/roslyn/issues/59458) | [AlekseyTs](https://github.com/AlekseyTs) | [333fred](https://github.com/333fred), [chsienki](https://github.com/chsienki) | [AlekseyTs](https://github.com/AlekseyTs) | # C# 10.0 diff --git a/docs/compilers/CSharp/CodeGen Differences.md b/docs/compilers/CSharp/CodeGen Differences.md index ab0223c040be2..6af7c5c746539 100644 --- a/docs/compilers/CSharp/CodeGen Differences.md +++ b/docs/compilers/CSharp/CodeGen Differences.md @@ -19,15 +19,15 @@ When efficiency and debuggability are at conflict, Release and Debug make differ **== Release (optimized)** -• The async codegen was for the most part redone in Roslyn. +β€’ The async codegen was for the most part redone in Roslyn. - The capturing is smarter now when optimizations are enabled since it relies on precise data flow analysis. Basically only locals that cross awaits need to be lifted. Old compiler used more conservative approach and would often capture locals unnecessarily. - The stack spilling is completely different. Instead of always present object array slot, we generate strongly typed reusable slots, but only if needed. -• Iterators - the genral principle is the same, but there were some minor refinements in the state machine. +β€’ Iterators - the genral principle is the same, but there were some minor refinements in the state machine. - Local capturing is based on precise data flow analysis and may result in fewer local lifted into iterator class. Generally only locals whose values are alive across yield statements need to be captured. - Valid states are now all positive and invalid states are negative. The common path in the iterator body switches on valid states and there are benefits from the set of those states being contiguous. -• Lambdas had some minor changes in caching strategy and a change in representation of non-lifting lambdas. +β€’ Lambdas had some minor changes in caching strategy and a change in representation of non-lifting lambdas. - The caching strategy has changed to a more compact pattern that also results in fewer accesses to the caching field (in case JIT does not optimize multiple reads). Instead of an equivalent of @@ -47,28 +47,28 @@ return cacheField ?? (cacheFiled = {allocate new lambdaDelegate}); - non-lifting Lambda expressions are now implemented as an instance methods on singleton display classes. Since the entry point to the delegate is the instance "Invoke" method, it is cheaper at runtime to dispatch delegate invocations to the underlying implementing method if such method is also an instance method with exactly same formal signature as "Invoke". - delegates for non-lifting Lambdas in generic methods can now be cached by Roslyn. That is mostly a welcome sideeffect of the change above. -• The string switch codegen in Rolsyn is completely new. Roslyn does not use dictionaries to avoid allocations and a potentially huge penalty when a string switch is execute for the first time. Roslyn uses a private function that maps strings to hash codes and a numeric switch. In some sense this is a partial inlining of the former technic that used static dictionaries. +β€’ The string switch codegen in Roslyn is completely new. Roslyn does not use dictionaries to avoid allocations and a potentially huge penalty when a string switch is execute for the first time. Roslyn uses a private function that maps strings to hash codes and a numeric switch. In some sense this is a partial inlining of the former technic that used static dictionaries. -• Array initializers are slightly more compact – in most cases extra temporary for the array instance is avoided and dup is used instead. (I think VB always did this, but this is new for C#) +β€’ Array initializers are slightly more compact – in most cases extra temporary for the array instance is avoided and dup is used instead. (I think VB always did this, but this is new for C#) -• Leaves from nested try in many cases would not cascade through outer regions and just leave directly to the outmost region. (VB was doing that always, now C# does this too since this part of codegen is in shared library and it is also more compact) +β€’ Leaves from nested try in many cases would not cascade through outer regions and just leave directly to the outmost region. (VB was doing that always, now C# does this too since this part of codegen is in shared library and it is also more compact) Branch threading in general may handle few more cases compared to the old compiler. Leave-to-leave case is probably the most noticeable. -• Numeric switches – +β€’ Numeric switches – - some minor changes in re-biasing and range checking in switches with nonzero smallest key. - Slightly different strategy in choosing between binary search and computed switch buckets. At high level switch codegen follows the same pattern as with old compiler, but we fixed some off-by-one errors that could result in unbalanced decision trees in some cases. The end result is that overall IL could be different. Hopefully better. -• Some unnecessary locals could be eliminated or used on the stack when compiled with /o+. +β€’ Some unnecessary locals could be eliminated or used on the stack when compiled with /o+. This is not new, old compiled did this as well, but implementation of this optimization has changed. -There are few cases where old compiler was “smarter” since it did this optimization earlier (and caused numerous inconveniences to later stages). +There are few cases where old compiler was β€œsmarter” since it did this optimization earlier (and caused numerous inconveniences to later stages). Generally the new approach handles more scenarios, so you may notice in some cases more dups used and fewer locals. -**Cascading optimizations** – note that it is possible for one optimization to enable another that may not be by itself new. +**Cascading optimizations** – note that it is possible for one optimization to enable another that may not be by itself new. **== Debug (not optimized)** -TBW \ No newline at end of file +TBW diff --git a/docs/compilers/CSharp/Compiler Breaking Changes - DotNet 6.md b/docs/compilers/CSharp/Compiler Breaking Changes - DotNet 6.md index 478fca0892c81..2c4fb0e2cd1ee 100644 --- a/docs/compilers/CSharp/Compiler Breaking Changes - DotNet 6.md +++ b/docs/compilers/CSharp/Compiler Breaking Changes - DotNet 6.md @@ -1,6 +1,7 @@ ο»Ώ## This document lists known breaking changes in Roslyn in C# 10.0 which will be introduced with .NET 6. -1. Beginning with C# 10.0, null suppression operator is no longer allowed in patterns. +1. Beginning with C# 10.0, null suppression operator is no longer allowed in patterns. + ```csharp void M(object o) { @@ -8,7 +9,7 @@ } ``` -2. In C# 10, lambda expressions and method groups with inferred type are implicitly convertible to `System.MulticastDelegate`, and bases classes and interfaces of `System.MulticastDelegate` including `object`, +2. In C# 10, lambda expressions and method groups with inferred type are implicitly convertible to `System.MulticastDelegate`, and bases classes and interfaces of `System.MulticastDelegate` including `object`, and lambda expressions and method groups are implicitly convertible to `System.Linq.Expressions.Expression` and `System.Linq.Expressions.LambdaExpression`. These are _function_type_conversions_. @@ -92,7 +93,7 @@ These are _function_type_conversions_. } ``` -3. In C#10, a lambda expression with inferred type may contribute an argument type that affects overload resolution. +3. In C#10, a lambda expression with inferred type may contribute an argument type that affects overload resolution. ```csharp using System; @@ -109,18 +110,43 @@ These are _function_type_conversions_. } ``` -4. In Visual Studio 17.1, `struct` type declarations with field initializers must include an explicitly declared constructor. Additionally, all fields must be definitely assigned in `struct` instance constructors that do not have a `: this()` initializer so any previously unassigned fields must be assigned from the added constructor or from field initializers. +4. In Visual Studio 17.0.7, an error is reported in a `record struct` with a primary constructor if an explicit constructor has a `this()` initializer that invokes the implicit parameterless constructor. See [roslyn#58339](https://github.com/dotnet/roslyn/pull/58339). - For instance, the following results in an error in 17.1: + For instance, the following results in an error: ```csharp - struct S + record struct R(int X, int Y) { - int X = 1; // error: struct with field initializers must include an explicitly declared constructor + // error CS8982: A constructor declared in a 'record struct' with parameter list must have a 'this' + // initializer that calls the primary constructor or an explicitly declared constructor. + public R(int x) : this() { X = x; Y = 0; } + } + ``` + + The error could be resolved by invoking the primary constructor (as below) from the `this()` initializer, or by declaring a parameterless constructor that invokes the primary constructor. + ```csharp + record struct R(int X, int Y) + { + public R(int x) : this(x, 0) { } // ok + } + ``` + +5. In Visual Studio 17.0.7, if a `struct` type declaration with no constructors includes initializers for some but not all fields, the compiler will report an error that all fields must be assigned. + + Earlier builds of 17.0 skipped _definite assignment analysis_ for the parameterless constructor synthesized by the compiler in this scenario and did not report unassigned fields, potentially resulting in instances with uninitialized fields. The updated analysis and error reporting is consistent with explicitly declared constructors. See [roslyn#57925](https://github.com/dotnet/roslyn/pull/57925). + + For instance, the following results in an error: + ```csharp + struct S // error CS0171: Field 'S.Y' must be fully assigned before control is returned to the caller + { + int X = 1; int Y; } ``` - The error could be resolved by adding a constructor and assigning the other field. + To resolve the errors, declare a parameterless constructor and assign the fields that do not have initializers, or remove the existing field initializers so the compiler does not synthesize a parameterless constructor. + (For compatibility with Visual Studio 17.1 which requires a `struct` with field initializers to [include an explicitly declared constructor](https://github.com/dotnet/roslyn/blob/main/docs/compilers/CSharp/Compiler%20Breaking%20Changes%20-%20DotNet%207.md#6), avoid adding initializers to the remaining fields without also declaring a constructor.) + + For instance, the error in the example above can be resolved by adding a constructor and assigning `Y`: ```csharp struct S { @@ -129,3 +155,4 @@ These are _function_type_conversions_. public S() { Y = 0; } // ok } ``` + diff --git a/docs/compilers/CSharp/Compiler Breaking Changes - DotNet 7.md b/docs/compilers/CSharp/Compiler Breaking Changes - DotNet 7.md index acfba8bddc569..15ed9a97a5f4f 100644 --- a/docs/compilers/CSharp/Compiler Breaking Changes - DotNet 7.md +++ b/docs/compilers/CSharp/Compiler Breaking Changes - DotNet 7.md @@ -1,6 +1,6 @@ ## This document lists known breaking changes in Roslyn after .NET 6 all the way to .NET 7. -1. In Visual Studio 17.1, the contextual keyword `var` cannot be used as an explicit lambda return type. +1. In Visual Studio 17.1, the contextual keyword `var` cannot be used as an explicit lambda return type. ```csharp using System; @@ -13,7 +13,7 @@ class var { } ``` -2. In Visual Studio 17.1, indexers that take an interpolated string handler and require the receiver as an input for the constructor cannot be used in an object initializer. +2. In Visual Studio 17.1, indexers that take an interpolated string handler and require the receiver as an input for the constructor cannot be used in an object initializer. ```cs using System.Runtime.CompilerServices; @@ -35,7 +35,7 @@ } ``` -3. In Visual Studio 17.1, `ref`/`ref readonly`/`in`/`out` are not allowed to be used on return/parameters of a method attributed with `UnmanagedCallersOnly`. +3. In Visual Studio 17.1, `ref`/`ref readonly`/`in`/`out` are not allowed to be used on return/parameters of a method attributed with `UnmanagedCallersOnly`. https://github.com/dotnet/roslyn/issues/57025 ```cs @@ -56,7 +56,7 @@ https://github.com/dotnet/roslyn/issues/57025 static void M5(out int o) => throw null; // error CS8977: Cannot use 'ref', 'in', or 'out' in a method attributed with 'UnmanagedCallersOnly'. ``` -4. Beginning with C# 11.0, `Length` and `Count` properties on countable and indexable types +4. Beginning with C# 11.0, `Length` and `Count` properties on countable and indexable types are assumed to be non-negative for purpose of subsumption and exhaustiveness analysis of patterns and switches. Those types can be used with implicit Index indexer and list patterns. @@ -67,7 +67,7 @@ Those types can be used with implicit Index indexer and list patterns. } ``` -5. Starting with Visual Studio 17.1, format specifiers in interpolated strings can not contain curly braces (either `{` or `}`). In previous versions `{{` was interpreted as an escaped `{` and `}}` was interpreted as an escaped `}` char in the format specifier. Now the first `}` char in a format specifier ends the interpolation, and any `{` char is an error. +5. Starting with Visual Studio 17.1, format specifiers in interpolated strings can not contain curly braces (either `{` or `}`). In previous versions `{{` was interpreted as an escaped `{` and `}}` was interpreted as an escaped `}` char in the format specifier. Now the first `}` char in a format specifier ends the interpolation, and any `{` char is an error. https://github.com/dotnet/roslyn/issues/57750 ```csharp @@ -77,3 +77,32 @@ https://github.com/dotnet/roslyn/issues/57750 //prints now: "{C}" - not "{X}}" ``` + +6. In Visual Studio 17.1, `struct` type declarations with field initializers must include an explicitly declared constructor. Additionally, all fields must be definitely assigned in `struct` instance constructors that do not have a `: this()` initializer so any previously unassigned fields must be assigned from the added constructor or from field initializers. See [csharplang#5552](https://github.com/dotnet/csharplang/issues/5552), [roslyn#58581](https://github.com/dotnet/roslyn/pull/58581). + + For instance, the following results in an error in 17.1: + ```csharp + struct S + { + int X = 1; // error CS8983: A 'struct' with field initializers must include an explicitly declared constructor. + int Y; + } + ``` + + The error could be resolved by adding a constructor and assigning the other field. + ```csharp + struct S + { + int X = 1; + int Y; + public S() { Y = 0; } // ok + } + ``` + +7. Before Visual Studio 17.2, the C# compiler would accept incorrect default argument values involving a reference conversion of a string constant, and would emit `null` as the constant value instead of the default value specified in source. In Visual Studio 17.2, this becomes an error. See [roslyn#59806](https://github.com/dotnet/roslyn/pull/59806). + + For instance, the following results in an error in 17.2: + ```csharp + void M(IEnumerable s = "hello") + ``` + diff --git a/docs/contributing/Building, Debugging, and Testing on Windows.md b/docs/contributing/Building, Debugging, and Testing on Windows.md index aa8bd58444844..f3f6be666bf54 100644 --- a/docs/contributing/Building, Debugging, and Testing on Windows.md +++ b/docs/contributing/Building, Debugging, and Testing on Windows.md @@ -15,9 +15,8 @@ The minimal required version of .NET Framework is 4.7.2. ## Developing with Visual Studio 2022 -1. [Visual Studio 2022 17.0 Preview](https://visualstudio.microsoft.com/vs/preview/vs2022/) +1. Use latest [Visual Studio 2022 Preview](https://visualstudio.microsoft.com/vs/preview/vs2022/) - Ensure C#, VB, MSBuild, .NET Core and Visual Studio Extensibility are included in the selected work loads - - Ensure Visual Studio is on Version "17.0" or greater - Ensure "Use previews of the .NET Core SDK" is checked in Tools -> Options -> Environment -> Preview Features - Restart Visual Studio 1. [.NET 6.0 SDK](https://dotnet.microsoft.com/download/dotnet-core/6.0) [Windows x64 installer](https://dotnet.microsoft.com/download/dotnet/thank-you/sdk-6.0.100-windows-x64-installer) diff --git a/docs/contributing/Compiler Test Plan.md b/docs/contributing/Compiler Test Plan.md index 2abe570bdef9c..fd9cb54a66c2c 100644 --- a/docs/contributing/Compiler Test Plan.md +++ b/docs/contributing/Compiler Test Plan.md @@ -2,7 +2,8 @@ This document provides guidance for thinking about language interactions and tes # General concerns: - Completeness of the specification as a guide for testing (is the spec complete enough to suggest what the compiler should do in each scenario?) -- Other external documentation +- *Ping* for new breaking changes and general ping for partner teams (Bill, Kathleen, Mads, IDE, Razor) +- Help review external documentation - Backward and forward compatibility (interoperation with previous and future compilers, each in both directions) - Error handling/recovery (missing libraries, including missing types in mscorlib; errors in parsing, ambiguous lookup, inaccessible lookup, wrong kind of thing found, instance vs static thing found, wrong type for the context, value vs variable) - BCL (including mono) and other customer impact @@ -133,8 +134,8 @@ Interaction with IDE, Debugger, and EnC should be worked out with relevant teams - Compiling expressions in Immediate/Watch windows or hovering over an expression - Compiling expressions in [DebuggerDisplay("...")] - Assigning values in Locals/Autos/Watch windows - -- Edit-and-continue + +- [Edit-and-continue](https://github.com/dotnet/roslyn/blob/main/docs/contributing/Testing%20for%20Interactive%20readiness.md) - Live Unit Testing (instrumentation) diff --git a/docs/contributing/Documentation for IDE CodeStyle analyzers.md b/docs/contributing/Documentation for IDE CodeStyle analyzers.md index a1c727b1a0ef6..657235ec39ee7 100644 --- a/docs/contributing/Documentation for IDE CodeStyle analyzers.md +++ b/docs/contributing/Documentation for IDE CodeStyle analyzers.md @@ -7,7 +7,7 @@ 2. Each IDE diagnostic ID has a dedicated documentation page. For example: 1. Diagnostic with code style option: 2. Diagnostic without code style option: - 3. Multiple diagnostic IDs sharing the same option(s): + 3. Multiple diagnostic IDs sharing the same option(s): . In this case, a [redirection](https://github.com/dotnet/docs/blob/7ae7272d643aa1c6db96cad8d09d4c2332855960/.openpublishing.redirection.fundamentals.json#L11-L14) for all diagnostic IDs must be added. 3. We have tabular indices for IDE diagnostic IDs and code style options for easier reference and navigation: 1. Primary index (rule ID + code style options): @@ -20,9 +20,9 @@ Roslyn IDE team (@dotnet/roslyn-ide) is responsible for ensuring that the documentation for IDE analyzers is up-to-date. Whenever we add a new IDE analyzer, add new code style option(s) OR update semantics of existing IDE analyzers the following needs to be done: -1. **Action required in [dotnet\docs](https://github.com/dotnet/docs) repo**: +1. **Action required in [dotnet/docs](https://github.com/dotnet/docs) repo**: 1. If you _creating a Roslyn PR for an IDE analyzer_: - 1. Please follow the steps at [Contribute docs for 'IDExxxx' rules](https://docs.microsoft.com/contribute/dotnet/dotnet-contribute-code-analysis#contribute-docs-for-idexxxx-rules) to add documentation for IDE analyzers to [dotnet\docs](https://github.com/dotnet/docs) repo. + 1. Please follow the steps at [Contribute docs for 'IDExxxx' rules](https://docs.microsoft.com/contribute/dotnet/dotnet-contribute-code-analysis#contribute-docs-for-idexxxx-rules) to add documentation for IDE analyzers to [dotnet/docs](https://github.com/dotnet/docs) repo. 2. Ideally, the documentation PR should be created in parallel to the Roslyn PR or immediately following the approval/merge of Roslyn PR. 2. If you are _reviewing a Roslyn PR for an IDE analyzer_: 1. Please ensure that the analyzer author is made aware of the above doc contribution requirements, especially if it is a community PR. @@ -30,4 +30,4 @@ Roslyn IDE team (@dotnet/roslyn-ide) is responsible for ensuring that the docume 2. **No action required in Roslyn repo**: Help links have been hooked up to IDE code style analyzers in Roslyn repo in the base analyzer types, so every new IDE analyzer diagnostic ID will automatically have `https://docs.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ideXXXX` as its help link. There is no action required on the Roslyn PR to ensure this linking. -If you feel any of the existing IDE rule docs have insufficient or incorrect information, please submit a PR to [dotnet\docs](https://github.com/dotnet/docs) repo to update the documentation. +If you feel any of the existing IDE rule docs have insufficient or incorrect information, please submit a PR to [dotnet/docs](https://github.com/dotnet/docs) repo to update the documentation. diff --git a/docs/contributing/Testing for Interactive readiness.md b/docs/contributing/Testing for Interactive readiness.md new file mode 100644 index 0000000000000..dd90c7b982692 --- /dev/null +++ b/docs/contributing/Testing for Interactive readiness.md @@ -0,0 +1,46 @@ + +# Compiler debugging/EnC checklist + +1. Sequence points are emitted correctly and corresponding syntax nodes are recognized as breakpoint spans by the IDE + - Verify manually by launching VS with the new compiler bits and step through and place breakpoints on all syntax nodes that should allow breakpoint + - Add regression compiler tests that check emitted IL with sequence points (`VerifyIL` with `sequencePoints`) + - Add IDE test via `src\EditorFeatures\CSharpTest\EditAndContinue\BreakpointSpansTests.cs` (implementation `src\Features\CSharp\Portable\EditAndContinue\BreakpointSpans.cs`, which deals with mapping syntax to sequence points) +2. Sequence points in relationship with closure allocations and other hidden code (for any syntax that produces sequence points) + - The debugger supports manually moving the current IP (instruction pointer) using β€œSet Next Statement Ctlr+Shift+F10” command. + - The statement can be set to any sequence point in the current method. + - Need to make sure that sequence points are emitted so that the right hidden code gets executed. + - For example, the sequence point on an opening brace of a block that allocates a closure needs to precede the closure allocation instructions, so that when the IP is set to this sequence point the closure is properly allocated. +``` +{ // closure allocated here + var x = 1; + F(() => x); +} +``` +3. Conditional branching has to use stloc/ldloc pattern in DEBUG build + - Check the instructions and sequence points emitted for e.g. an if statement in debug build. Instead of straightforward brtrue/brfalse we allocate a temp local, store the result of the condition evaluation to that local, emit hidden sequence point, load the result from the local and then branch. This supports EnC function remapping. Only need to think about this when implementing a feature that emits conditional branches with conditions that may contain arbitrary expressions. I believe there are helpers in the lowering phase that emit conditions in general, so it should be done automatically as long as the right helpers are used. But something to be aware of. +4. Closure and lambda scopes (PDB info) + - If new syntax is introduced that represents some kind of lambda (anonymous methods, local functions, LINQ queries, etc.) update helpers in `src\Compilers\CSharp\Portable\Syntax\LambdaUtilities.cs` accordingly + - If a new scope is introduce that can declare variables that can be lifted into a closure + - The bound node that represents the scope needs to be associated with syntax node recognized by helpers in `src\Compilers\CSharp\Portable\Syntax\LambdaUtilities.cs` (specifically `IsClosureScope`). + - This requirement is enforced by an assertion in `SynthesizedClosureEnvironment` constructor. + - Lambda and closure syntax offsets must be emitted to the PDB (encLambdaMap custom debug information) + - The offset attribute of closure identifies the syntax node that's associated with the closure. This offset must be unique. +5. When a new symbol is introduced symbol matcher might need to be updated + - Symbol matcher maps a symbol from one compilation to another. + - Synthesized symbols like closures, state machines, anonymous types, lambdas, etc. also has to be mapped. + - Impl: `src\Compilers\CSharp\Portable\Emitter\EditAndContinue\CSharpSymbolMatcher.cs` + - Tests: `src\Compilers\CSharp\Test\Emit\Emit\EditAndContinue\SymbolMatcherTests.cs` +6. When a new syntax is introduced that may declare a user local variable or emits long lived synthesized variables (ie. state that survives between breakpoints, not just a temp within expression) + - Validate that the variable slots can be mapped from new to previous compilation + - This is implemented by `EncVariableSlotAllocator` using syntax offsets stored in PDB (`encLocalSlotMap` and `encLambdaMap` custom debug info). + - The current mechanism might not be sufficient to support the mapping, in which case raise the issue with the IDE team to design additional PDB info to support the mapping. +7. Each new language feature should be covered by a test in Emit tests under Emit/EditAndContinue. + - Some features might just need a single test others multiple tests depending on impact on EnC. + - PDB tests validate these scopes. (look for `` in PDB XML). `LocalsTests.cs` EE tests also validate the scoping. +8. When a new syntax is introduced that may declare a scope for local variables the corresponding IL scopes need to be emitted correctly in the PDB + - These are used by the EE to determine which variables are in scope. +9. Test debugging experience of the feature + - Is useful info displayed in Watch window? + - Can I evaluate expressions using this feature in Watch window? + - Some features might require adding more custom PDB information to make the debug experience good (e.g. async, iterators, dynamic, etc). + - Design experience improvement and custom PDB info with IDE team. diff --git a/docs/features/incremental-generators.md b/docs/features/incremental-generators.md index c5ea5513c0b34..5009d395ef7a5 100644 --- a/docs/features/incremental-generators.md +++ b/docs/features/incremental-generators.md @@ -2,7 +2,7 @@ ## Summary -Incremental generators are intended to be a new API that exists alongside +Incremental generators are a new API that exists alongside [source generators](generators.md) to allow users to specify generation strategies that can be applied in a high performance way by the hosting layer. @@ -14,6 +14,40 @@ strategies that can be applied in a high performance way by the hosting layer. - Support generating more items that just source texts - Exist alongside `ISourceGenerator` based implementations +## Simple Example + +We begin by defining a simple incremental generator that extracts the contents +of additional text files and makes their contents available as compile time +`const`s. In the following section we'll go into more depth around the concepts +shown. + +```csharp +[Generator] +public class Generator : IIncrementalGenerator +{ + public void Initialize(IncrementalGeneratorInitializationContext initContext) + { + // define the execution pipeline here via a series of transformations: + + // find all additional files that end with .txt + IncrementalValuesProvider textFiles = context.AdditionalTextsProvider.Where(static file => file.Path.EndsWith(".txt")); + + // read their contents and save their name + IncrementalValuesProvider<(string name, string content)> namesAndContents = textFiles.Select((text, cancellationToken) => (name: Path.GetFileNameWithoutExtension(text.Path), content: text.GetText(cancellationToken)!.ToString())); + + // generate a class that contains their values as const strings + context.RegisterSourceOutput(namesAndContents, (spc, nameAndContent) => + { + spc.AddSource($"ConstStrings.{nameAndContent.name}", $@" + public static partial class ConstStrings + {{ + public const string {nameAndContent.name} = ""{nameAndContent.content}""; + }}"); + }); + } +} +``` + ## Implementation An incremental generator is an implementation of `Microsoft.CodeAnalysis.IIncrementalGenerator`. @@ -42,234 +76,801 @@ public class MyGenerator : IIncrementalGenerator { ... } An assembly can contain a mix of diagnostic analyzers, source generators and incremental generators. -### Initialization - -`IIncrementalGenerator` has an `Initialize` method that is called by the host -(either the IDE or the command-line compiler) exactly once, regardless of the -number of further compilations that may occur. `Initialize` passes an instance -of `IncrementalGeneratorInitializationContext` which can be used by the -generator to register a set of callbacks that affect how future generation -passes will occur. - -Currently `IncrementalGeneratorInitializationContext` supports two callbacks: +### Pipeline based execution -- `RegisterForPostInitialization(GeneratorPostInitializationContext)`: the same - callback in shape and function as supported by Source Generators today -- `RegisterExecutionPipeline(IncrementalGeneratorPipelineContext)`: replaces Execute, described below +`IIncrementalGenerator` has an `Initialize` method that is called by the +host[^1] exactly once, regardless of the number of further compilations that may +occur. For instance a host with multiple loaded projects may share the same +generator instance across multiple projects, and will only call `Initialize` a +single time for the lifetime of the host. -### Pipeline based execution +[^1]: Such as the IDE or the command-line compiler Rather than a dedicated `Execute` method, an Incremental Generator instead -creates an execution 'pipeline' as part of the initialization process via the -`RegisterExecutionPipeline` method: +defines an immutable execution pipeline as part of initialization. The +`Initialize` method receives an instance of +`IncrementalGeneratorInitializationContext`which is used by the generator to +define a set of transformations. + ```csharp public void Initialize(IncrementalGeneratorInitializationContext initContext) { - initContext.RegisterExecutionPipeline(context => - { - // build the pipeline... - }); + // define the execution pipeline here via a series of transformations: } ``` -This pipeline is not directly executed, but instead consists of a set of steps -that are executed on demand as the input data to the pipeline changes. Between -each step the data produced is cached, allowing previously calculated values to -be reused in later computations when applicable, reducing the overall -computation required between compilations. +The defined transformations are not executed directly at initialization, and +instead are deferred until the data they are using changes. Conceptually this is +similar to LINQ, where a lambda expression might not be executed until the +enumerable is actually iterated over: + +**IEnumerable**: + +```csharp + var squares = Enumerable.Range(1, 10).Select(i => i * 2); + + // the code inside select is not executed until we iterate the collection + foreach (var square in squares) { ... } +``` + +These transformations are used to form a directed graph of actions that can be +executed on demand later, as the input data changes. + +**Incremental Generators**: + +```csharp + IncrementalValuesProvider textFiles = context.AdditionalTextsProvider.Where(static file => file.Path.EndsWith(".txt")); + // the code in the Where(...) above will not be executed until the value of the additional texts actually changes +``` + +Between each transformation, the data produced is cached, allowing previously calculated +values to be re-used where applicable. This caching reduces the computation +required for subsequent compilations. See [caching](#caching) for more details. -### IncrementalValueSource<T> +### IncrementalValue\[s\]Provider<T> -Input data is available to the pipeline in the form of an opaque data source, -modelled as an `IncrementalValueSource` where _T_ is the type of data that -can be accessed in the pipeline. +Input data is available to the pipeline in the form of opaque data sources, +either an `IncrementalValueProvider` or `IncrementalValuesProvider` (note +the plural _values_) where _T_ is the type of input data that is provided. -These sources are defined up front by the compiler, and can be accessed from the -`Values` property of the `context` passed as part of the -`RegisterExecutionPipeline` callback. Example values sources include +An initial set of providers are created by the host, and can be accessed from the +`IncrementalGeneratorInitializationContext` provided during initialization. -- Compilation -- AdditionalTexts -- AnalyzerConfigOptions -- MetadataReferences -- ParseOptions +The currently available providers are: -Value sources have 'zero-or-more' potential values that can be produced. For -example, the `Compilation` will always produce a single value, whereas the -`AdditionalTexts` will produce a variable number of values, depending on how -many additional texts where passed to the compiler. +- CompilationProvider +- AdditionalTextsProvider +- AnalyzerConfigOptionsProvider +- MetadataReferencesProvider +- ParseOptionsProvider -An execution pipeline cannot access these values directly. Instead it supplies a -set of transforms that will be applied to the data as it changes. Transforms are -applied through a set of extension methods: +*Note*: there is no provider for accessing syntax nodes. This is handled +in a slightly different way. See [SyntaxValueProvider](#syntaxvalueprovider) for details. + +A value provider can be thought of as a 'box' that holds the value itself. An +execution pipeline does not access the values in a value provider directly. + +```ascii +IValueProvider + β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” + | | + β”‚ TSource β”‚ + | | + β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ +``` + +Instead, the generator supplies a set of transformations that ar to be applied to the +data contained within the provider, which in turn creates a new value provider. + +### Select + +The simplest transformation is `Select`. This maps the value in one provider +into a new provider by applying a transform to it. + +```ascii + IValueProvider IValueProvider + β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” + β”‚ β”‚ Select β”‚ β”‚ + β”‚ TSource β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Ίβ”‚ TResult β”‚ + β”‚ β”‚ β”‚ β”‚ + β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ +``` + +Generator transformations can be thought of as being conceptually somewhat similar to +LINQ, with the value provider taking the place of `IEnumerable`. +Transforms are created through a set of extension methods: ```csharp public static partial class IncrementalValueSourceExtensions { // 1 => 1 transform - public static IncrementalValueSource Transform(this IncrementalValueSource source, Func func) => ... + public static IncrementalValueProvider Select(this IncrementalValueProvider source, Func selector); + public static IncrementalValuesProvider Select(this IncrementalValuesProvider source, Func selector); } ``` -These extension methods allow the user to perform a series of transforms, -conceptually somewhat similar to LINQ, over the values coming from the data -source: +Note how the return type of these methods are also an instance of +`IncrementalValue[s]Provider`. This allows the generator to chain multiple +transformations together: + +```ascii + IValueProvider IValueProvider IValueProvider + β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” + β”‚ β”‚ Select β”‚ β”‚ Select β”‚ β”‚ + β”‚ TSource β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Ίβ”‚ TResult1 │──────────────────────────►│ TResult2 β”‚ + β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ + β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ +``` + +Consider the following simple example: ```csharp -initContext.RegisterExecutionPipeline(context => +initContext.RegisterExecutionPipeline(static context => { - // get the additional text source - IncrementalValueSource additionalTexts = context.Sources.AdditionalTexts; + // get the additional text provider + IncrementalValuesProvider additionalTexts = context.AdditionalTextsProvider; // apply a 1-to-1 transform on each text, which represents extracting the path - IncrementalValueSource transformed = additionalTexts.Transform(static text => text.Path); + IncrementalValuesProvider transformed = additionalTexts.Select(static (text, _) => text.Path); + + // transform each extracted path into something else + IncrementalValuesProvider prefixTransform = transformed.Select(static (path, _) => "prefix_" + path); }); ``` -Note that `transformed` is similarly opaque. It represents the outcome of the -transformation being applied to the data, but cannot be accessed directly. +Note how `transformed` and `prefixTransform` are themselves an +`IncrementalValuesProvider`. They represent the outcome of the transformation +that will be applied, rather than the resulting data. + +### Multi Valued providers + +An `IncrementalValueProvider` will always provide a single value, whereas an +`IncrementalValuesProvider` may provide zero or more values. For example the +`CompilationProvider` will always produce a single compilation instance, whereas +the `AdditionalTextsProvider` will produce a variable number of values, +depending on how many additional texts where passed to the compiler. + +Conceptually it is simple to think about the transformation of a single item +from an `IncrementalValueProvider`: the single item has the selector function +applied to it which produces a single value of `TResult`. + +For an `IncrementalValuesProvider` however, this transformation is more +subtle. The selector function is applied multiple times, one to each item in the +values provider. The results of each transformation are then used to create the +values for the resulting values provider: + +```ascii + Select + ....................................... + . β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” . + . selector(Item1) β”‚ β”‚ . + . β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Ίβ”‚ Result1 β”œβ”€β”€β”€β” . + . β”‚ β”‚ β”‚ β”‚ . +IncrementalValuesProvider . β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ . IncrementalValuesProvider + β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” . β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ . β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” + β”‚ β”‚ . β”‚ selector(Item2) β”‚ β”‚ β”‚ . β”‚ β”‚ + β”‚ TSource β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Ίβ”‚ Result2 β”œβ”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β–Ίβ”‚ TResult β”‚ + β”‚ β”‚ . β”‚ β”‚ β”‚ β”‚ . β”‚ β”‚ + β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ . β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ . β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + 3 items . β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ . 3 items + [Item1, Item2, Item3] . β”‚ selector(Item3) β”‚ β”‚ β”‚ . [Result1, Result2, Result3] + . └────────────────►│ Result3 β”œβ”€β”€β”€β”˜ . + . β”‚ β”‚ . + . β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ . + ....................................... +``` -The transformed steps can be further transformed, and it is also valid to -perform multiple transformations on the same input node, essentially 'splitting' -the pipeline into multiple streams of processing. +It is this item-wise transformation that allows the caching to be particularly +powerful in this model. Consider when the values inside +`IncrementalValueProvider` change. Its likely that any given change +will only change one item at a time rather than the whole collection (for example +a user typing in an additional text only changes the given text, leaving the +other additional texts unmodified). -```csharp - // apply a 1-to-1 transform on each text, extracting the path - IncrementalValueSource transformed = additionalTexts.Transform(static text => text.Path); +When this occurs the generator driver can compare the input items with the ones +that were used previously. If they are considered to be equal then the +transformations for those items can be skipped and the previously computed +versions used instead. See [Comparing Items](#comparing-items) for more details. - // split the processing into two streams of derived data - IncrementalValueSource prefixTransform = transformed.Transform(static path => "prefix_" + path); - IncrementalValueSource postfixTransform = transformed.Transform(static path => path + "_postfixed"); -``` +In the above diagram if `Item2` were to change we would execute the selector on +the modified value producing a new value for `Result2`. As `Item1`and `Item3` +are unchanged the driver is free to skip executing the selector and just use the +cached values of `Result1` and `Result3` from the previous execution. -### Batching +### Select Many -In addition to the 1-to-1 transform shown above, there are also extension -methods for producing and consuming batches of data. For instance a given -transform may want to produce more than one value for each input, or want to -view all the data in a single collected view in order to make cross data -decisions. +In addition to the 1-to-1 transform shown above, there are also transformations +that produce batches of data. For instance a given transformation may want to +produce multiple values for each input. There are a set of `SelectMany` methods that allow a transformation of 1 to +many, or many to many items: + +**1 to many:** ``` csharp public static partial class IncrementalValueSourceExtensions { - // 1 => many (or none) - public static IncrementalValueSource TransformMany(this IncrementalValueSource source, Func> func) => ... + public static IncrementalValuesProvider SelectMany(this IncrementalValueProvider source, Func> selector); +} +``` + +```ascii + SelectMany + ....................................... + . β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” . + . β”‚ β”‚ . + . β”Œβ”€β”€β–Ίβ”‚ Result1 β”œβ”€β”€β”€β” . + . β”‚ β”‚ β”‚ β”‚ . + IncrementalValueProvider . β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ . IncrementalValuesProvider + β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” . β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ . β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” + β”‚ β”‚ . selector(Item)β”‚ β”‚ β”‚ β”‚ . β”‚ β”‚ + β”‚ TSource β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β–Ίβ”‚ Result2 β”œβ”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β–Ίβ”‚ TResult β”‚ + β”‚ β”‚ . β”‚ β”‚ β”‚ β”‚ . β”‚ β”‚ + β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ . β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ . β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + Item . β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ . 3 items + . β”‚ β”‚ β”‚ β”‚ . [Result1, Result2, Result3] + . └──►│ Result3 β”œβ”€β”€β”€β”˜ . + . β”‚ β”‚ . + . β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ . + ....................................... +``` - // many => 1 - public static IncrementalValueSource BatchTransform(this IncrementalValueSource source, Func, U> func) => ... +**Many to many:** - // many => many (or none) - public static IncrementalValueSource BatchTransformMany(this IncrementalValueSource source, Func, IEnumerable> func) => ... +``` csharp +public static partial class IncrementalValueSourceExtensions +{ + public static IncrementalValuesProvider SelectMany(this IncrementalValuesProvider source, Func> selector); } ``` -In our above example we could use `BatchTransform` to collect the individual -file paths collected, and convert them into a single collection: +```ascii + SelectMany + ............................................... + . β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β” . + . β”‚ β”‚ . + . β”Œβ”€β”€β”€β”€β–Ίβ”‚ Result1 β”œβ”€β”€β”€β”€β”€β”€β”€β” . + . β”‚ β”‚ β”‚ β”‚ . + . β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ . + . selector(Item1) β”‚ β”‚ . + .β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ . + .β”‚ β”‚ β”‚ β”‚ . + IncrementalValuesProvider.β”‚ β”Œβ”€β”€β”€β”€β–Ίβ”‚ Result2 β”œβ”€β”€β”€β”€β”€β”€β”€β”€ . IncrementalValuesProvider + β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” .β”‚ β”‚ β”‚ β”‚ β”‚ . β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” + β”‚ β”‚ .β”‚ selector(Item2) β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ . β”‚ β”‚ + β”‚ TSource β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Ίβ”‚ TResult β”‚ + β”‚ β”‚ .β”‚ β”‚ β”‚ β”‚ β”‚ . β”‚ β”‚ + β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ .β”‚ └────►│ Result3 β”œβ”€β”€β”€β”€β”€β”€β”€β”€ . β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + 3 items .β”‚ β”‚ β”‚ β”‚ . 7 items + [Item1, Item2, Item3] .β”‚ selector(Item3) β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ . [Result1, Result2, Result3, Result4, + .└─────────────────┐ β”‚ . Result5, Result6, Result7 ] + . β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ . + . β”‚ β”‚ β”‚ β”‚ . + . β”œβ”€β”€β”€β”€β–Ίβ”‚ Result4 β”œβ”€β”€β”€β”€β”€β”€β”€β”€ . + . β”‚ β”‚ β”‚ β”‚ . + . β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ . + . β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ . + . β”‚ β”‚ β”‚ β”‚ . + . β”œβ”€β”€β”€β”€β–Ίβ”‚ Result5 β”œβ”€β”€β”€β”€β”€β”€β”€β”€ . + . β”‚ β”‚ β”‚ β”‚ . + . β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ . + . β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ . + . β”‚ β”‚ β”‚ β”‚ . + . └────►│ Result6 β”œβ”€β”€β”€β”€β”€β”€β”€β”˜ . + . β”‚ β”‚ . + . β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ . + ............................................... +``` + +For example, consider a set of additional XML files that contain multiple +elements of the same type. The generator may want to treat each element as a +distinct item for generation, effectively splitting a single additional file +into multiple sub-items. ``` csharp - // apply a 1-to-1 transform on each text, which represents extracting the path - IncrementalValueSource transformed = additionalTexts.Transform(static text => text.Path); +initContext.RegisterExecutionPipeline(static context => +{ + // get the additional text provider + IncrementalValuesProvider additionalTexts = context.AdditionalTextsProvider; - // batch the collected file paths into a single collection - IncrementalValueSource> batched = transformed.BatchTransform(static paths => paths); + // extract each element from each additional file + IncrementalValuesProvider elements = additionalTexts.SelectMany(static (text, _) => /*transform text into an array of MyElementType*/); + + // now the generator can consider the union of elements in all additional texts, without needing to consider multiple files + IncrementalValuesProvider transformed = elements.Select(static (element, _) => /*transform the individual element*/); +} ``` -The author could have equally combined these two steps into a single operation -that utilizes LINQ: +### Where + +Where allows the author to filter the values in a value provider by a given +predicate. Where is actually a specific form of select many, where each input +transforms to exactly 1 or 0 outputs. However, as it is such a common operation +it is provided as a primitive transformation directly. ``` csharp - // using System.Linq; - IncrementalValueSource> singleOp = additionalTexts.BatchTransform(static texts => texts.Select(text => text.Path)); +public static partial class IncrementalValueSourceExtensions +{ + public static IncrementalValuesProvider Where(this IncrementalValuesProvider source, Func predicate); +} +``` + +```ascii + Select + ....................................... + . β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” . + . predicate(Item1)β”‚ β”‚ . + . β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Ίβ”‚ Item1 β”œβ”€β”€β”€β” . + . β”‚ β”‚ β”‚ β”‚ . +IncrementalValuesProvider . β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ . IncrementalValuesProvider + β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” . β”‚ β”‚ . β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” + β”‚ β”‚ . β”‚ predicate(Item2) β”‚ . β”‚ β”‚ + β”‚ TSource β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€X β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β–Ίβ”‚ TResult β”‚ + β”‚ β”‚ . β”‚ β”‚ . β”‚ β”‚ + β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ . β”‚ β”‚ . β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + 3 Items . β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ . 2 Items + . β”‚ predicate(Item3)β”‚ β”‚ β”‚ . + . └────────────────►│ Item3 β”œβ”€β”€β”€β”˜ . + . β”‚ β”‚ . + . β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ . + ....................................... ``` -**OPEN QUESTION** Should there be versions of -`BatchTransform`/`BatchTransformMany` that take no transformation, and just -perform the identity function as specified above? +An obvious use case is to filter out inputs the generator knows it isn't +interested in. For example, the generator will likely want to filter additional +texts on file extensions: -### Outputting values +```csharp +initContext.RegisterExecutionPipeline(static context => +{ + // get the additional text provider + IncrementalValuesProvider additionalTexts = context.AdditionalTextsProvider; -At some point in the pipeline the author will want to actually use the -transformed data to produce an output, such as a `SourceText`. For this purpose -there are 'terminating' extension methods that allow the author to provide the -resulting data the generator produces. The set of terminating extensions -include: + // filter additional texts by extension + IncrementalValuesProvider xmlFiles = additionalTexts.Where(static (text, _) => text.Path.EndsWith(".xml", StringComparison.OrdinalIgnoreCase)); +} +``` -- GenerateSource -- GenerateEmbeddedFile -- GenerateArtifact +### Collect -GenerateSource for example looks like: +When performing transformations on a value provider with multiple items, it can +often be useful to view the items as a single collection rather than one item at +a time. For this there is the `Collect` transformation. -``` csharp -static partial class IncrementalValueSourceExtensions +`Collect` transforms an `IncrementalValuesProvider` to an +`IncrementalValueProvider>`. Essentially it transforms a multi-valued source +into a single value source with an array of all the items. + +```csharp +public static partial class IncrementalValueSourceExtensions { - public internal static IncrementalGeneratorOutput GenerateSource(this IncrementalValueSource source, Action action) => ... + IncrementalValueProvider> Collect(this IncrementalValuesProvider source); } ``` -That can be used by the author to supply `SourceText` to be appended to the -compilation via the passed in `SourceProductionContext`: +```ascii +IncrementalValuesProvider IncrementalValueProvider> + β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” + β”‚ β”‚ Collect β”‚ β”‚ + β”‚ TSource β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Ίβ”‚ ImmutableArray β”‚ + β”‚ β”‚ β”‚ β”‚ + β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + 3 Items Single Item + + Item1 [Item1, Item2, Item3] + Item2 + Item3 +``` -``` csharp - // take the file paths from the above batch and make some user visible syntax - batched.GenerateSource(static (sourceProductionContext, filePaths) => - { - sourceProductionContext.AddSource("additionalFiles.cs", @" -namespace Generated +```csharp +initContext.RegisterExecutionPipeline(static context => { - public class AdditionalTextList + // get the additional text provider + IncrementalValuesProvider additionalTexts = context.AdditionalTextsProvider; + + // collect the additional texts into a single item + IncrementalValueProvider collected = context.AdditionalTexts.Collect(); + + // perform a transformation where you can access all texts at once + var transform = collected.Select(static (texts, _) => /* ... */); +} + +``` + +### Multi-path pipelines + +The transformations described so far are all effectively single-path operations: +while there may be multiple items in a given provider, each transformation +operates on a single input value provider and produce a single derived output +provider. + +While sufficient for simple operations, it is often necessary to combine the +values from multiple input providers or use the results of a transformation +multiple times. For this there are a set of transformations that split and +combine a single path of transformations into a multi-path pipeline. + +### Split + +It is possible to split the output of a transformations into multiple +parallel inputs. Rather than having a dedicated transformation this can be +achieved by simply using the same value provider as the input to multiple +transforms. + +```ascii + + IncrementalValueProvider + β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” + Select β”‚ β”‚ + IncrementalValueProvider β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Ίβ”‚ TResult β”‚ + β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”‚ + β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ TSource β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ + β”‚ β”‚ β”‚ + β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ IncrementalValuesProvider + β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” + β”‚ SelectMany β”‚ β”‚ + └─────────────────────────────►│ TResult2 β”‚ + β”‚ β”‚ + β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ +``` + +Those transforms can then be used as the inputs to new single path transforms, independent of one another. + +For example: + +```csharp +initContext.RegisterExecutionPipeline(static context => +{ + // get the additional text provider + IncrementalValuesProvider additionalTexts = context.AdditionalTextsProvider; + + // apply a 1-to-1 transform on each text, extracting the path + IncrementalValuesProvider transformed = additionalTexts.Select(static (text, _) => text.Path); + + // split the processing into two paths of derived data + IncrementalValuesProvider nameTransform = transformed.Select(static (path, _) => "prefix_" + path); + IncrementalValuesProvider extensionTransform = transformed.Select(static (path, _) => Path.ChangeExtension(path, ".new")); +} +``` + +`nameTransform` and `extensionTransform` produce different values for the same +set of additional text inputs. For example if there was an additional file +called `file.txt` then `nameTransform` would produce the string +`prefix_file.txt` where `extensionTransform` would produce the string +`file.new`. + +When the value of the additional file changes, the subsequent values produced +may or may not differ. For example if the name of the additional file was +changed to `file.xml` then `nameTransform` would now produce `prefix_file.xml` +whereas `extensionTransform` would still produce `file.new`. Any child transform +with input from `nameTransform` would be re-run with the new value, but any +child of `extensionTransform` would use the previously cached version as it's +input hasn't changed. + +### Combine + +Combine is the most powerful, but also most complicated transformation. It +allows a generator to take two input providers and create a single unified +output provider. + +**Single-value to single-value**: + +```csharp +public static partial class IncrementalValueSourceExtensions +{ + IncrementalValueProvider<(TLeft Left, TRight Right)> Combine(this IncrementalValueProvider provider1, IncrementalValueProvider provider2); +} +``` + +When combining two single value providers, the resulting node is conceptually +easy to understand: a new value provider that contains a `Tuple` of the two +input items. + +```ascii + +IncrementalValueProvider + β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” + β”‚ β”‚ + β”‚ TSource1 β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” + β”‚ β”‚ β”‚ IncrementalValueProvider<(TSource1, TSource2)> + β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ + Single Item β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” + β”‚ Combine β”‚ β”‚ + Item1 β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Ίβ”‚ (TSource1, TSource2) β”‚ + β”‚ β”‚ β”‚ +IncrementalValueProvider β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ Single Item + β”‚ β”‚ β”‚ + β”‚ TSource2 β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ (Item1, Item2) + β”‚ β”‚ + β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + Single Item + + Item2 + +``` + +**Multi-value to single-value:** + +```csharp +public static partial class IncrementalValueSourceExtensions +{ + IncrementalValuesProvider<(TLeft Left, TRight Right)> Combine(this IncrementalValuesProvider provider1, IncrementalValueProvider provider2); +} +``` + +When combining a multi value provider to a single value provider, however, the +semantics are a little more complicated. The resulting multi-valued provider +produces a series of tuples: the left hand side of each tuple is the value +produced from the multi-value input, while the right hand side is always the +same single value from the single value provider input. + +```ascii + IncrementalValuesProvider + β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” + β”‚ β”‚ + β”‚ TSource1 β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” + β”‚ β”‚ β”‚ + β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ + 3 Items β”‚ IncrementalValuesProvider<(TSource1, TSource2)> + β”‚ + LeftItem1 β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” + LeftItem2 β”‚ Combine β”‚ β”‚ + LeftItem3 β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Ίβ”‚ (TSource1, TSource2) β”‚ + β”‚ β”‚ β”‚ + β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + IncrementalValueProvider β”‚ 3 Items + β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ + β”‚ β”‚ β”‚ (LeftItem1, RightItem) + β”‚ TSource2 β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ (LeftItem2, RightItem) + β”‚ β”‚ (LeftItem3, RightItem) + β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + Single Item + + RightItem +``` + +**Multi-value to multi-value:** + +As shown by the definitions above it is not possible to combine a multi-value +source to another multi-value source. The resulting cross join would potentially +contain a large number of values, so the operation is not provided by default. + +Instead, an author can call `Collect()` on one of the input multi-value providers +to produce a single-value provider that can be combined as above. + +```ascii + IncrementalValuesProvider + β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” + β”‚ β”‚ + β”‚ TSource1 β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” + β”‚ β”‚ β”‚ + β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ + 3 Items β”‚ IncrementalValuesProvider<(TSource1, TSource2[])> + β”‚ + LeftItem1 β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” + LeftItem2 β”‚ Combine β”‚ β”‚ + LeftItem3 β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Ίβ”‚ (TSource1, TSource2) β”‚ + β”‚ β”‚ β”‚ + β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ +IncrementalValuesProvider IncrementalValueProvider β”‚ 3 Items + β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ + β”‚ β”‚ Collect β”‚ β”‚ β”‚ (LeftItem1, [RightItem1, RightItem2, RightItem3]) + β”‚ TSource2 β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ TSource2[] β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ (LeftItem2, [RightItem1, RightItem2, RightItem3]) + β”‚ β”‚ β”‚ β”‚ (LeftItem3, [RightItem1, RightItem2, RightItem3]) + β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + 3 Items Single Item + + RightItem1 [RightItem1, RightItem2, RightItem3] + RightItem2 + RightItem3 +``` + +With the above transformations the generator author can now take one or more +inputs and combine them into a single source of data. For example: + +```csharp +initContext.RegisterExecutionPipeline(static context => +{ + // get the additional text provider + IncrementalValuesProvider additionalTexts = context.AdditionalTextsProvider; + + // combine each additional text with the parse options + IncrementalValuesProvider<(AdditionalText, ParseOptions)> combined = context.AdditionalTextsProvider.Combine(context.ParseOptionsProvider); + + // perform a transform on each text, with access to the options + var transformed = combined.Select(static (pair, _) => { - public static void PrintTexts() - { - System.Console.WriteLine(""Additional Texts were: " + string.Join(", ", filePaths) + @" ""); - } - } -}"); + AdditionalText text = pair.Left; + ParseOptions parseOptions = pair.Right; + + // do the actual transform ... }); +} +``` + +If either of the inputs to a combine change, then subsequent transformation will +re-run. However, the caching is considered on a pairwise basis for each output +tuple. For instance, in the above example, if only additional text changes the +subsequent transform will only be run for the text that changed. The other text +and parse options pairs are skipped and their previously computed value are +used. If the single value changes, such as the parse options in the example, +then the transformation is executed for every tuple. + +### SyntaxValueProvider + +Syntax Nodes are not available directly through a value provider. Instead, a +generator author uses the special `SyntaxValueProvider` (provided via the +`IncrementalGeneratorInitializationContext.SyntaxProvider`) to create a +dedicated input node that instead exposes a sub-set of the syntax they are +interested in. The syntax provider is specialized in this way to achieve a +desired level of performance. + +**CreateSyntaxProvider**: + +Currently the provider exposes a single method `CreateSyntaxProvider` that +allows the author to construct an input node. + +```csharp + public readonly struct SyntaxValueProvider + { + public IncrementalValuesProvider CreateSyntaxProvider(Func predicate, Func transform); + } ``` -A generator may create and register multiple output nodes as part of the -pipeline, but an output cannot be further transformed once it is created. +Note how this takes _two_ lambda parameters: one that examines a `SyntaxNode` in +isolation, and a second one that can then use the `GeneratorSyntaxContext` to +access a semantic model and transform the node for downstream usage. + +It is because of this split that performance can be achieved: as the driver is +aware of which nodes are chosen for examination, it can safely skip the first +`predicate` lambda when a syntax tree remains unchanged. The driver will still +re-run the second `transform` lambda even for nodes in unchanged files, as a +change in one file can impact the semantic meaning of a node in another file. -Splitting the outputs by type produced allows the host (such as the IDE) to not -run outputs that are not required. For instance artifacts are only produced as -part of a command line build, so the IDE has no need to run the artifact based -outputs or steps that feed into it. +Consider the following syntax trees: -**OPEN QUESTION** Should we have `GenerateBatch...` versions of the output -methods? This can already be achieved by the author calling `BatchTransform` -before calling `Generate...` so would just be a helper, but seems common enough -that it could be useful. +```csharp +// file1.cs +public class Class1 +{ + public int Method1() => 0; +} -### Simple example +// file2.cs +public class Class2 +{ + public Class1 Method2() => null; +} -Putting together the various steps outlined above, an example incremental -generator might look like the following: +// file3.cs +public class Class3 {} +``` + +As an author I can make an input node that extracts the return type information + +```csharp +initContext.RegisterExecutionPipeline(static context => +{ + // create a syntax provider that extracts the return type kind of method symbols + var returnKinds = context.SyntaxProvider.CreateSyntaxProvider(static (n, _) => n is MethodDeclarationSyntax, + static (n, _) => ((IMethodSymbol)n.SemanticModel.GetDeclaredSymbol(n.Node)).ReturnType.Kind); +} +``` + +Initially the `predicate` will run for all syntax nodes, and select the two +`MethodDeclarationSyntax` nodes `Method1()` and `Method2()`. These are then +passed to the `transform` where the semantic model is used to obtain the method +symbol and extract the kind of the return type for the method. `returnKinds` +will contain two values, both `NamedType`. + +Now imagine that `file3.cs` is edited: + +```csharp +// file3.cs +public class Class3 { + public int field; +} +``` + +The `predicate` will only be run for syntax nodes inside `file3.cs`, and will +not return any as it still doesn't contain any method symbols. The `transform` +however will still be run again for the two methods from `Class1` and `Class2`. + +To see why it was necessary to re-run the `transform` consider the following +edit to `file1.cs` where we change the classes name: + +```csharp +// file1.cs +public class Class4 +{ + public int Method1() => 0; +} +``` + +The `predicate` will be re-run for `file1.cs` as it has changed, and will pick +out the method symbol `Method1()` again. Next, because the `transform` is +re-run for _all_ the methods, the return type kind for `Method2()` is correctly +changed to `Error` as `Class1` no longer exists. + +Note that we didn't need to run the `predicate` over for nodes in `file2.cs` +even though they referenced something in `file1.cs`. Because the first check is +purely _syntactic_ we can be sure the results for `file2.cs` would be the same. + +While it may seem unfortunate that the driver must run the `transform` for all +selected syntax nodes, if it did not it could up producing incorrect data +due to cross file dependencies. Because the initial syntactic check +allows the driver to substantially filter the number of nodes on which the +semantic checks have to be re-run, significantly improved performance +characteristics are still observed when editing a syntax tree. + +## Outputting values + +At some point in the pipeline the author will want to actually use the +transformed data to produce an output, such as a `SourceText`. There are a set +of `Register...Output` methods on the +`IncrementalGeneratorInitializationContext` that allow the generator author to +construct an output from a series of transformations. + +These output registrations are terminal, in that the they do not return a value +provider and can have no further transformations applied to them. However an +author is free to register multiple outputs of the same type with different +input transformations. + +The set of output methods are + +- RegisterSourceOutput +- RegisterImplementationSourceOutput +- RegisterPostInitializationOutput + +**RegisterSourceOutput**: + +RegisterSourceOutput allows a generator author to produce source files and +diagnostics that will be included in the users compilation. As input, it takes a +`Value[s]Provider` and an `Action` that will +be invoked for every value in the value provider. ``` csharp -[Generator(LanguageNames.CSharp)] -public class MyGenerator : IIncrementalGenerator +public static partial class IncrementalValueSourceExtensions { - public void Initialize(IncrementalGeneratorInitializationContext initContext) - { - initContext.RegisterExecutionPipeline(context => - { - // get the additional text source - IncrementalValueSource additionalTexts = context.Sources.AdditionalTexts; + public void RegisterSourceOutput(IncrementalValueProvider source, Action action); + public void RegisterSourceOutput(IncrementalValuesProvider source, Action action); +} +``` + +The provided `SourceProductionContext` can be used to add source files and report diagnostics: + +```csharp +public readonly struct SourceProductionContext +{ + public CancellationToken CancellationToken { get; } + + public void AddSource(string hintName, string source); + + public void ReportDiagnostic(Diagnostic diagnostic); +} +``` + +For example, a generator can extract out the set of paths for the additional +files and create a method that prints them out: - // apply a 1-to-1 transform on each text, extracting the path - IncrementalValueSource transformed = additionalTexts.Transform(static text => text.Path); +``` csharp +initContext.RegisterExecutionPipeline(static context => +{ + // get the additional text provider + IncrementalValuesProvider additionalTexts = context.AdditionalTextsProvider; - // batch the collected file paths into a single collection - IncrementalValueSource> batched = transformed.BatchTransform(static paths => paths); + // apply a 1-to-1 transform on each text, extracting the path + IncrementalValuesProvider transformed = additionalTexts.Select(static (text, _) => text.Path); - // take the file paths from the above batch and make some user visible syntax - batched.GenerateSource(static (sourceContext, filePaths) => - { - sourceContext.AddSource("additionalFiles.cs", @" + // collect the paths into a batch + IncrementalValueProvider> collected = transformed.Collect(); + + // take the file paths from the above batch and make some user visible syntax + initContext.RegisterSourceOutput(collected, static (sourceProductionContext, filePaths) => + { + sourceProductionContext.AddSource("additionalFiles.cs", @" namespace Generated { public class AdditionalTextList @@ -280,85 +881,88 @@ namespace Generated } } }"); - }); - }); - } + }); } ``` -## Advanced Implementation +**RegisterImplementationSourceOutput**: -### Combining and filtering +`RegisterImplementationSourceOutput` works in the same way as +`RegisterSourceOutput` but declares that the source produced has no semantic +impact on user code from the point of view of code analysis. This allows a host +such as the IDE, to chose not to run these outputs as a performance +optimization. A host that produces executable code will always run these +outputs. -While the transformation steps outlined above allow a user to create simple -generators from a single source of data, in reality it is expected that an -author will need a way to take multiple sources of data and combine them. +**RegisterPostInitializationOutput**: -There exists an extension method `Combine` that allows the author to take one -data source and merge it with another, for example, extracting a set of types -from the compilation and using them to generate something on a per additional -file basis. +`RegisterPostInitializationOutput` allows a generator author to provide source +code immediately after initialization has run. It takes no inputs, and so cannot +refer to any source code written by the user, or any other compiler inputs. -```csharp -public static partial class IncrementalValueSourceExtensions -{ - // join 1 => many ((source1[0], source2), (source1[1], source2), (source1[2], source2), ...) - public static IncrementalValueSource<(T source1Item, IEnumerable source2Batch)> Combine(this IncrementalValueSource source1, IncrementalValueSource source2) => ... -} -``` +Post initialization source is included in the Compilation before any other +transformations are run, meaning that it will be visible as part of the rest of +the regular execution pipeline, and an author may ask semantic questions about +it. -The second data source is batched, and the resulting step has a value type of -`(T, IEnumerable)`. That is, a tuple where each element consists of a single -item of data from `source1` combined with the entire batch of data from -`source2`. While this is somewhat low-level, when combined with subsequent -transforms, it gives the author the ability to combine an arbitrary number of -data sources into any shape they require. +It is particularly useful for adding attributes to the users source code. These +can then be added by the user their code, and the generator may find the +attributed code via the semantic model. -In the following example the author combines the additional text source with the -compilation: +## Handling Cancellation -```csharp -IncrementalValueSource<(AdditionalText source1Item, IEnumerable source2Batch)> combined = context.Sources.AdditionalTexts.Combine(context.Sources.Compilation); -``` +Incremental generators are designed to be used in interactive hosts such as an +IDE. As such, it is critically important that generators respect and respond to +the passed in cancellation tokens. -The type of combined is an -`IncrementalValueSource<(AdditionalText, IEnumerable)>`. For each -additional text, there is a tuple with the text, and the batched data of the -compilation source. As the author knows that there is only ever a single -compilation, they are free to transform the data to select the single -compilation object: +In general, it is likely that the amount of user computation performed per +transformation is low, but often will be calling into Roslyn APIs that may have +a significant performance impact. As such the author should always forward the +provided cancellation token to any Roslyn APIs that accept it. -```csharp -IncrementalValueSource<(AdditionalText, Compilation)> transformed = combined.Transform(static pair => (pair.source1Item, pair.source2Batch.Single())); -``` - -Similarly a cross join can be achieved by first combining two value sources, -then batch transforming the resulting value source. +For example, when retrieving the contents of an additional file, the token +should be passed into `GetText(...)`: ```csharp -IncrementalValueSource<(AdditionalText, MetadataReference)> combined = context.Sources.AdditionalTexts - .Combine(context.Sources.MetadataReference) - .TransformMany(static pair => pair.source2Batch.Select(static metadataRef => (pair.source1Item, metadataRef)); +public void Initialize(IncrementalGeneratorInitializationContext context) +{ + var txtFiles = context.AdditionalTextsProvider.Where(static f => f.Path.EndsWith(".txt", StringComparison.OrdinalIgnoreCase)); + + // ensure we forward the cancellation token to GeText + var fileContents = txtFiles.Select(static (file, cancellationToken) => file.GetText(cancellationToken)); +} ``` -**OPEN QUESTION**: Combine is pretty low level, but does allow you to do -everything needed when used in conjunction with transform. Should we provide -some higher level extension methods that chain together combine and transform -out of the box for common operations? +This will ensure that an incremental generator correctly and quickly responds to +cancellation requests and does not cause delays in the host. -While filtering can be easily enough implement by the user as a transform step, -it seems common and useful enough that we provide an implementation directly for -the user to consume +If the generator author is doing something expensive, such as looping over +values, they should regularly check for cancellation themselves. It is recommend +that the author use `CancellationToken.ThrowIfCancellationRequested()` at +regular intervals, and allow the host to re-run them, rather than attempting to +save partially generated results which can be extremely difficult to author +correctly. ```csharp -static partial class IncrementalValueSourceExtensions +public void Initialize(IncrementalGeneratorInitializationContext context) { - // helper for filtering values - public static IncrementalValueSource Filter(this IncrementalValueSource source, Func filter) => ... + var txtFilesArray = context.AdditionalTextsProvider.Where(static f => f.Path.EndsWith(".txt", StringComparison.OrdinalIgnoreCase)).Collect(); + + var expensive = txtFilesArray.Select(static (files, cancellationToken) => + { + foreach (var file in files) + { + // check for cancellation so we don't hang the host + cancellationToken.ThrowIfCancellationRequested(); + + // perform some expensive operation (ideally passing in the token as well) + ExpensiveOperation(file, cancellationToken); + } + }); } ``` -### Caching +## Caching While the finer grained steps allow for some coarse control of output types via the generator host, the performance benefits are only really seen when the @@ -369,21 +973,20 @@ true. When calculating the required transformations to be applied as part of a step, the generator driver is free to look at inputs it has seen before and used -previous computed and cached values of the transformation for these inputs. When -using non batch transforms it can do this on an element by element basis. +previous computed and cached values of the transformation for these inputs. -Consider the following transform: +Consider the following transformation: ```csharp -IValueSource transform = context.Sources.AdditionalTexts - .Transform(static t => t.Path) - .Transform(static p => "prefix_" + p); +IValuesProvider transform = context.AdditionalTextsProvider + .Select(static (t, _) => t.Path) + .Select(static (p, _) => "prefix_" + p); ``` During the first execution of the pipeline each of the two lambdas will be executed for each additional file: -AdditionalText | Transform1 | Transform2 +AdditionalText | Select1 | Select2 ------------------------|------------|----------------- Text{ Path: "abc.txt" } | "abc.txt" | "prefix_abc.txt" Text{ Path: "def.txt" } | "def.txt" | "prefix_def.txt" @@ -393,86 +996,157 @@ Now consider the case where in some future iteration, the first additional file has changed and has a different path, and the second file has changed, but kept its path the same. -AdditionalText | Transform1 | Transform2 +AdditionalText | Select1 | Select2 -----------------------------|------------|----------- **Text{ Path: "diff.txt" }** | | **Text{ Path: "def.txt" }** | | Text{ Path: "ghi.txt" } | | -The generator would run transform1 on the first and second files, producing +The generator would run select1 on the first and second files, producing "diff.txt" and "def.txt" respectively. However, it would not need to re-run the -transform for the third file, as the input has not changed. It can just use the +select for the third file, as the input has not changed. It can just use the previously cached value. -AdditionalText | Transform1 | Transform2 +AdditionalText | Select1 | Select2 -----------------------------|----------------|----------- **Text{ Path: "diff.txt" }** | **"diff.txt"** | **Text{ Path: "def.txt" }** | **"def.txt"** | Text{ Path: "ghi.txt" } | "ghi.txt" | -Next the driver would look to run Transform2. It would operate on `"diff.txt"` +Next the driver would look to run Select2. It would operate on `"diff.txt"` producing `"prefix_diff.txt"`, but when it comes to `"def.txt"` it can observe that the item produced was the same as the last iteration. Even though the -original input (`Text{ Path: "def.txt" }`) was changed, the result of Transform1 -on it was the same. Thus there is no need to re-run Transform2 on `"def.txt"` as +original input (`Text{ Path: "def.txt" }`) was changed, the result of Select1 +on it was the same. Thus there is no need to re-run Select2 on `"def.txt"` as it can just use the cached value from before. Similarly the cached state of "ghi.txt" can be used. -AdditionalText | Transform1 | Transform2 +AdditionalText | Select1 | Select2 -----------------------------|----------------|---------------------- **Text{ Path: "diff.txt" }** | **"diff.txt"** | **"prefix_diff.txt"** -**Text{ Path: "def.txt" }** | **"def.txt"** | "prefix_diff.txt" +**Text{ Path: "def.txt" }** | **"def.txt"** | "prefix_def.txt" Text{ Path: "ghi.txt" } | "ghi.txt" | "prefix_ghi.txt" In this way, only changes that are consequential flow through the pipeline, and duplicate work is avoided. If a generator only relies on `AdditionalTexts` then the driver knows there can be no work to be done when a `SyntaxTree` changes. -### WithComparer +### Comparing Items -For a user provided result to be comparable across iterations, there needs to be some concept of equivalence. Rather than requiring types returned from transformations implement `IEquatable`, there exists an extension method that allows the author to supply a comparer that should be used when comparing values for the given transformation: +For a user provided result to be comparable across iterations, there needs to be +some concept of equivalence. By default the host will use `EqualityComparer` +to determine equivalence. There are obviously times where this is insufficient, +and there exists an extension method that allows the author to supply a comparer +that should be used when comparing values for the given transformation: ```csharp -public static partial class IncrementalValueSourceExtensions +public static partial class IncrementalValueProviderExtensions { - public static IncrementalValueSource WithComparer(IEqualityComparer comparer) => ... + public static IncrementalValueProvider WithComparer(this IncrementalValueProvider source, IEqualityComparer comparer); + + public static IncrementalValuesProvider WithComparer(this IncrementalValuesProvider source, IEqualityComparer comparer); } ``` -Allowing the user to specify a given comparer. +Allowing the generator author to specify a given comparer. ```csharp -var withComparer = context.Sources.AdditionalTexts - .Transform(t => t.Path) - .WithComparer(myComparer); +var withComparer = context.AdditionalTextsProvider + .Select(static t => t.Path) + .WithComparer(myComparer); ``` -Note that the comparer is on a per-transformation basis, meaning an author can specify different comparers for different parts of the pipeline. +Note that the comparer is on a per-transformation basis, meaning an author can +specify different comparers for different parts of the pipeline. ```csharp -var transform = context.Sources.AdditionalTexts.Transform(t => t.Path); +var select = context.AdditionalTextsProvider.Select(static t => t.Path); -var noCompareTransform = transform.Transform(...); -var compareTransform = transform.WithComparer(myComparer).Transform(...); +var noCompareSelect = select.Select(...); +var compareSelect = select.WithComparer(myComparer).Select(...); ``` -The same transform node can have no comparer when acting as input to one step, -and still provide one when acting as input to a different step. +The same select node can have no comparer when acting as input to one transformation, +and still provide one when acting as input to a different transformation. + +The host will only invoke the given comparer when the item it is derived from +has been modified. When the input value is new or being removed, or the input +transformation was determined to be cached (possibly by a provided comparer) the +given comparer is not considered. + +### Authoring a cache friendly generator + +Much of the success of an incremental generator will depend on creating an +optimal pipeline that is amenable to caching. This section includes some general +tips and best practices to achieve that -**OPEN QUESTION**: This again gives maximal flexibility, but might be annoying -if you have lots of custom data structures that you use in multiple places. Should -we consider allowing the author to specify a set of 'default' comparers that -apply to all transforms unless overridden? +**Extract out information early**: It is best to get the information out of the +inputs as early as possible in the pipeline. This ensures the host is not +caching large, expensive object such as symbols. -**OPEN QUESTION**: `IValueComparer` seems like the correct type to use, but -can be less ergonomic as it requires the author to define a type not inline and -reference it here. Should we provided a 'functional' overload that creates the -equality comparer for the author under the hood given a lambda? +**Use value types where possible**: Value types are more amenable to caching and +usually have well defined and easy to understand comparison semantics. -### Syntax Trees +**Use multiple transformations**: The more transformations you break the +operations into, the more opportunities there are to cache. Think of +transformations as being 'check points' in the execution graph. The more check +points the more chances there are to match a cached value and skip any remaining +work. -## Internal Implementation +**Build a data model**: Rather than trying to pass each input item into a +`Register...Output` method, consider building a data model to be the final item +passed to the output. Use the transformations to manipulate the data model, and +have well defined equality that allows you to correctly compare between +revisions of the model. This also makes testing the final `Register...Outputs` +significantly simpler: you can just call the method with a dummy data model and +check the generated code, rather than trying to emulate the incremental +transformations. -TK: compiler specific implementation. StateTables etc. +**Consider the order of combines**: Ensure that you are only combining the +minimal amount of information needed (this comes back to 'Extract out +information early'). + +Consider the following (incorrect) combine where the basic inputs are combined, +then used to generate some source: + +```csharp +public void Initialize(IncrementalGeneratorInitializationContext context) +{ + var compilation = context.CompilationProvider; + var texts = context.AdditionalTextsProvider; + + // Don't do this! + var combined = texts.Combine(compilation); + + context.RegisterSourceOutput(combined, static (spc, pair) => + { + var assemblyName = pair.Right.AssemblyName; + // produce source ... + }); +``` + +Any time the compilation changes, which it will frequently as the user is typing +in the IDE, then `RegisterSourceOutput` will get re-run. Instead, look up the +compilation dependant information first, then combine _that_ with the additional +files: + +```csharp +public void Initialize(IncrementalGeneratorInitializationContext context) +{ + var assemblyName = context.CompilationProvider.Select(static (c, _) => c.AssemblyName); + var texts = context.AdditionalTextsProvider; + + var combined = texts.Combine(assemblyName); + + context.RegisterSourceOutput(combined, (spc, pair) => + { + var assemblyName = pair.Right; + // produce source ... + }); +} +``` -### Hosting ISourceGenerator on the new APIs \ No newline at end of file +Now, as the user types in the IDE, the `assemblyName` transform will re-run, but +is very cheap and quickly returns what is likely the same value each time. That +means that unless the additional texts have also changed, the host does not need +to re-run the combine or re-generate any of the source. diff --git a/dotnet-tools.json b/dotnet-tools.json index c232231ac428f..b8d5a0aada491 100644 --- a/dotnet-tools.json +++ b/dotnet-tools.json @@ -2,7 +2,7 @@ "isRoot": true, "tools": { "dotnet-format": { - "version": "6.0.257007", + "version": "6.2.315104", "commands": [ "dotnet-format" ] diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 646f210ed6971..3574bd4fa43fd 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -6,25 +6,25 @@ 7e80445ee82adbf9a8e6ae601ac5e239d982afaa - - https://github.com/dotnet/source-build - 90bdf447e1b97605f109b34243ab8c9f215308e9 - + + https://github.com/dotnet/source-build-externals + c349f5f0326edcd47b302a8c6731fc3c7ae7a1ef + - + https://github.com/dotnet/arcade - 4d6406fa2e84c8516a338694be3a4097e6e1f104 + 68a9b6dc9c0f375893fcdab74b7dd2538afb1c4b - + https://github.com/dotnet/roslyn - 592501cbb9c9394072a245c15b3458ff88155d85 + 5d10d428050c0d6afef30a072c4ae68776621877 - + https://github.com/dotnet/arcade - 4d6406fa2e84c8516a338694be3a4097e6e1f104 + 68a9b6dc9c0f375893fcdab74b7dd2538afb1c4b diff --git a/eng/Versions.props b/eng/Versions.props index bb7a9a0e7202f..60d60c3db2bdc 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -8,28 +8,28 @@ 4 2 0 - 2 + 3 $(MajorVersion).$(MinorVersion).$(PatchVersion) $(MajorVersion).$(MinorVersion).0.0 - 4.1.0-3.22075.3 + 4.1.0-5.22128.4 3.3.3-beta1.21105.3 6.0.0-rc1.21366.2 - 1.1.1-beta1.22081.4 - 0.1.124-beta + 1.1.2-beta1.22122.4 + 0.1.132-beta - 4.0.1 + 4.1.0 16.10.230 17.0.487 5.0.0-alpha1.19409.1 5.0.0-preview.1.20112.8 - 17.1.11 + 17.2.3 17.0.31723.112 16.5.0 3.8.0 + 7.0.0-alpha.1.22060.1 - - false - true - false - CurrentRuntime - - - true - - diff --git a/eng/targets/Services.props b/eng/targets/Services.props index c4421f0d7a042..316192a92ea15 100644 --- a/eng/targets/Services.props +++ b/eng/targets/Services.props @@ -38,7 +38,7 @@ - + - - - 1.0.3 - $(RoslynSemanticVersion) - Release - - \ No newline at end of file diff --git a/src/Dependencies/Microsoft.NetFX20/mscorlib.dll b/src/Dependencies/Microsoft.NetFX20/mscorlib.dll deleted file mode 100644 index 675c0df084a6f..0000000000000 Binary files a/src/Dependencies/Microsoft.NetFX20/mscorlib.dll and /dev/null differ diff --git a/src/Dependencies/PooledObjects/ObjectPool`1.cs b/src/Dependencies/PooledObjects/ObjectPool`1.cs index 8e99345c053ea..d9dca9dfb14f8 100644 --- a/src/Dependencies/PooledObjects/ObjectPool`1.cs +++ b/src/Dependencies/PooledObjects/ObjectPool`1.cs @@ -22,10 +22,6 @@ namespace Microsoft.CodeAnalysis.PooledObjects { -#if NET20 - internal delegate TReturn Func(TArg arg); -#endif - /// /// Generic implementation of object pooling pattern with predefined pool size limit. The main /// purpose is that limited number of frequently used objects can be kept in the pool for diff --git a/src/EditorFeatures/CSharp/AddImports/CSharpAddImportsPasteCommandHandler.cs b/src/EditorFeatures/CSharp/AddImports/CSharpAddImportsPasteCommandHandler.cs index 9ba110442a275..7404845619259 100644 --- a/src/EditorFeatures/CSharp/AddImports/CSharpAddImportsPasteCommandHandler.cs +++ b/src/EditorFeatures/CSharp/AddImports/CSharpAddImportsPasteCommandHandler.cs @@ -4,7 +4,7 @@ using System; using System.ComponentModel.Composition; -using Microsoft.CodeAnalysis.Editor.Implementation.AddImports; +using Microsoft.CodeAnalysis.AddImport; using Microsoft.CodeAnalysis.Editor.Shared.Utilities; using Microsoft.CodeAnalysis.Host.Mef; using Microsoft.CodeAnalysis.Options; diff --git a/src/EditorFeatures/CSharp/AutomaticCompletion/AutomaticLineEnderCommandHandler.cs b/src/EditorFeatures/CSharp/AutomaticCompletion/AutomaticLineEnderCommandHandler.cs index 0962222aa5239..c143f5359a16d 100644 --- a/src/EditorFeatures/CSharp/AutomaticCompletion/AutomaticLineEnderCommandHandler.cs +++ b/src/EditorFeatures/CSharp/AutomaticCompletion/AutomaticLineEnderCommandHandler.cs @@ -11,7 +11,7 @@ using Microsoft.CodeAnalysis.CSharp.Extensions; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.CSharp.Utilities; -using Microsoft.CodeAnalysis.Editor.Implementation.AutomaticCompletion; +using Microsoft.CodeAnalysis.AutomaticCompletion; using Microsoft.CodeAnalysis.Editor.Shared.Extensions; using Microsoft.CodeAnalysis.Editor.Shared.Utilities; using Microsoft.CodeAnalysis.Formatting; diff --git a/src/EditorFeatures/CSharp/AutomaticCompletion/CSharpBraceCompletionServiceFactory.cs b/src/EditorFeatures/CSharp/AutomaticCompletion/CSharpBraceCompletionServiceFactory.cs index 7dbf4a7d2c99b..923494039a630 100644 --- a/src/EditorFeatures/CSharp/AutomaticCompletion/CSharpBraceCompletionServiceFactory.cs +++ b/src/EditorFeatures/CSharp/AutomaticCompletion/CSharpBraceCompletionServiceFactory.cs @@ -6,7 +6,7 @@ using System.Collections.Generic; using System.Composition; using Microsoft.CodeAnalysis.BraceCompletion; -using Microsoft.CodeAnalysis.Editor.Implementation.AutomaticCompletion; +using Microsoft.CodeAnalysis.AutomaticCompletion; using Microsoft.CodeAnalysis.Editor.Shared.Utilities; using Microsoft.CodeAnalysis.Host.Mef; diff --git a/src/EditorFeatures/CSharp/BraceMatching/AbstractCSharpBraceMatcher.cs b/src/EditorFeatures/CSharp/BraceMatching/AbstractCSharpBraceMatcher.cs index 155357c4bd6e6..d8f72ea040d82 100644 --- a/src/EditorFeatures/CSharp/BraceMatching/AbstractCSharpBraceMatcher.cs +++ b/src/EditorFeatures/CSharp/BraceMatching/AbstractCSharpBraceMatcher.cs @@ -4,8 +4,8 @@ #nullable disable +using Microsoft.CodeAnalysis.BraceMatching; using Microsoft.CodeAnalysis.CSharp; -using Microsoft.CodeAnalysis.Editor.Implementation.BraceMatching; namespace Microsoft.CodeAnalysis.Editor.CSharp.BraceMatching { diff --git a/src/EditorFeatures/CSharp/BraceMatching/CSharpEmbeddedLanguageBraceMatcher.cs b/src/EditorFeatures/CSharp/BraceMatching/CSharpEmbeddedLanguageBraceMatcher.cs index 8a479e5b36120..c423a5e88cb55 100644 --- a/src/EditorFeatures/CSharp/BraceMatching/CSharpEmbeddedLanguageBraceMatcher.cs +++ b/src/EditorFeatures/CSharp/BraceMatching/CSharpEmbeddedLanguageBraceMatcher.cs @@ -6,7 +6,7 @@ using System; using System.ComponentModel.Composition; -using Microsoft.CodeAnalysis.Editor.Implementation.BraceMatching; +using Microsoft.CodeAnalysis.BraceMatching; using Microsoft.CodeAnalysis.Host.Mef; namespace Microsoft.CodeAnalysis.Editor.CSharp.BraceMatching diff --git a/src/EditorFeatures/CSharp/ChangeSignature/CSharpChangeSignatureCommandHandler.cs b/src/EditorFeatures/CSharp/ChangeSignature/CSharpChangeSignatureCommandHandler.cs index f6b300c18feb9..cdd64710822b8 100644 --- a/src/EditorFeatures/CSharp/ChangeSignature/CSharpChangeSignatureCommandHandler.cs +++ b/src/EditorFeatures/CSharp/ChangeSignature/CSharpChangeSignatureCommandHandler.cs @@ -6,7 +6,7 @@ using System; using System.ComponentModel.Composition; -using Microsoft.CodeAnalysis.Editor.Implementation.ChangeSignature; +using Microsoft.CodeAnalysis.ChangeSignature; using Microsoft.CodeAnalysis.Editor.Shared.Utilities; using Microsoft.CodeAnalysis.Host.Mef; using Microsoft.VisualStudio.Commanding; diff --git a/src/EditorFeatures/CSharp/CodeCleanup/CSharpCodeCleanupService.cs b/src/EditorFeatures/CSharp/CodeCleanup/CSharpCodeCleanupService.cs new file mode 100644 index 0000000000000..c4a28fd2f1197 --- /dev/null +++ b/src/EditorFeatures/CSharp/CodeCleanup/CSharpCodeCleanupService.cs @@ -0,0 +1,284 @@ +ο»Ώ// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Collections.Immutable; +using System.Composition; +using Microsoft.CodeAnalysis.CodeCleanup; +using Microsoft.CodeAnalysis.CodeFixes; +using Microsoft.CodeAnalysis.CSharp.RemoveUnusedVariable; +using Microsoft.CodeAnalysis.Diagnostics; +using Microsoft.CodeAnalysis.Host.Mef; + +namespace Microsoft.CodeAnalysis.CSharp.CodeCleanup +{ + [ExportLanguageService(typeof(ICodeCleanupService), LanguageNames.CSharp), Shared] + internal class CSharpCodeCleanupService : AbstractCodeCleanupService + { + /// + /// Maps format document code cleanup options to DiagnosticId[] + /// + private static readonly ImmutableArray s_diagnosticSets = + ImmutableArray.Create( + // Organize usings + // dotnet_separate_import_directive_groups + // dotnet_sort_system_directives_first + new DiagnosticSet(FeaturesResources.Apply_using_directive_placement_preferences, + IDEDiagnosticIds.MoveMisplacedUsingDirectivesDiagnosticId), + // file_header_template + new DiagnosticSet(FeaturesResources.Apply_file_header_preferences, + IDEDiagnosticIds.FileHeaderMismatch), + + // this. preferences + // dotnet_style_qualification_for_event + // dotnet_style_qualification_for_field + // dotnet_style_qualification_for_method + // dotnet_style_qualification_for_property + new DiagnosticSet(AnalyzersResources.Add_this_or_Me_qualification, + IDEDiagnosticIds.AddQualificationDiagnosticId, + IDEDiagnosticIds.RemoveQualificationDiagnosticId), + + // Language keywords vs BCL types preferences + // dotnet_style_predefined_type_for_locals_parameters_members + // dotnet_style_predefined_type_for_member_access + new DiagnosticSet(FeaturesResources.Apply_language_framework_type_preferences, + IDEDiagnosticIds.PreferBuiltInOrFrameworkTypeDiagnosticId), + + // Parentheses preferences + // dotnet_style_parentheses_in_arithmetic_binary_operators + // dotnet_style_parentheses_in_other_binary_operators + // dotnet_style_parentheses_in_other_operators + // dotnet_style_parentheses_in_relational_binary_operators + new DiagnosticSet(FeaturesResources.Apply_parentheses_preferences, + IDEDiagnosticIds.RemoveUnnecessaryParenthesesDiagnosticId, + IDEDiagnosticIds.AddRequiredParenthesesDiagnosticId), + + // Modifier preferences + // dotnet_style_require_accessibility_modifiers + new DiagnosticSet(AnalyzersResources.Add_accessibility_modifiers, + IDEDiagnosticIds.AddAccessibilityModifiersDiagnosticId), + + // Expression-level preferences + // dotnet_style_coalesce_expression + new DiagnosticSet(FeaturesResources.Apply_coalesce_expression_preferences, + IDEDiagnosticIds.UseCoalesceExpressionDiagnosticId), + // dotnet_style_collection_initializer + new DiagnosticSet(FeaturesResources.Apply_object_collection_initialization_preferences, + IDEDiagnosticIds.UseCollectionInitializerDiagnosticId), + // dotnet_style_explicit_tuple_names + new DiagnosticSet(FeaturesResources.Apply_tuple_name_preferences, + IDEDiagnosticIds.UseExplicitTupleNameDiagnosticId), + // dotnet_style_namespace_match_folder + new DiagnosticSet(FeaturesResources.Apply_namespace_matches_folder_preferences, + IDEDiagnosticIds.MatchFolderAndNamespaceDiagnosticId), + // dotnet_style_null_propagation + new DiagnosticSet(FeaturesResources.Apply_null_propagation_preferences, + IDEDiagnosticIds.UseNullPropagationDiagnosticId), + // dotnet_style_object_initializer + new DiagnosticSet(FeaturesResources.Apply_object_initializer_preferences, + IDEDiagnosticIds.UseObjectInitializerDiagnosticId), + // dotnet_style_prefer_auto_properties + new DiagnosticSet(FeaturesResources.Apply_auto_property_preferences, + IDEDiagnosticIds.UseAutoPropertyDiagnosticId), + // dotnet_style_prefer_compound_assignment + new DiagnosticSet(FeaturesResources.Apply_compound_assignment_preferences, + IDEDiagnosticIds.UseCoalesceCompoundAssignmentDiagnosticId, + IDEDiagnosticIds.UseCompoundAssignmentDiagnosticId), + new DiagnosticSet(FeaturesResources.Apply_conditional_expression_preferences, + // dotnet_style_prefer_conditional_expression_over_assignment + IDEDiagnosticIds.UseConditionalExpressionForAssignmentDiagnosticId, + // dotnet_style_prefer_conditional_expression_over_return + IDEDiagnosticIds.UseConditionalExpressionForReturnDiagnosticId), + // dotnet_style_prefer_inferred_anonymous_type_member_names + // dotnet_style_prefer_inferred_tuple_names + new DiagnosticSet(FeaturesResources.Apply_inferred_anonymous_type_member_names_preferences, + IDEDiagnosticIds.UseInferredMemberNameDiagnosticId), + // dotnet_style_prefer_is_null_check_over_reference_equality_method + new DiagnosticSet(FeaturesResources.Apply_null_checking_preferences, + IDEDiagnosticIds.UseIsNullCheckDiagnosticId), + // dotnet_style_prefer_simplified_boolean_expressions + new DiagnosticSet(FeaturesResources.Apply_simplify_boolean_expression_preferences, + IDEDiagnosticIds.SimplifyConditionalExpressionDiagnosticId), + // dotnet_style_prefer_simplified_interpolation + new DiagnosticSet(FeaturesResources.Apply_string_interpolation_preferences, + IDEDiagnosticIds.SimplifyInterpolationId), + + // Field preferences + // dotnet_style_readonly_field + new DiagnosticSet(CSharpFeaturesResources.Make_private_field_readonly_when_possible, + IDEDiagnosticIds.MakeFieldReadonlyDiagnosticId), + + // Parameter preferences + // dotnet_code_quality_unused_parameters + new DiagnosticSet(FeaturesResources.Remove_unused_parameters, + IDEDiagnosticIds.UnusedParameterDiagnosticId), + + // Suppression preferences + // dotnet_remove_unnecessary_suppression_exclusions + new DiagnosticSet(FeaturesResources.Remove_unused_suppressions, + IDEDiagnosticIds.RemoveUnnecessarySuppressionDiagnosticId), + + // New line preferences + // dotnet_style_allow_multiple_blank_lines_experimental + new DiagnosticSet(FeaturesResources.Apply_blank_line_preferences_experimental, + IDEDiagnosticIds.MultipleBlankLinesDiagnosticId), + // dotnet_style_allow_statement_immediately_after_block_experimental + new DiagnosticSet(FeaturesResources.Apply_statement_after_block_preferences_experimental, + IDEDiagnosticIds.ConsecutiveStatementPlacementDiagnosticId), + + // C# Coding Conventions + + // var preferences + // csharp_style_var_elsewhere + // csharp_style_var_for_built_in_types + // csharp_style_var_when_type_is_apparent + new DiagnosticSet(CSharpFeaturesResources.Apply_var_preferences, + IDEDiagnosticIds.UseImplicitTypeDiagnosticId, + IDEDiagnosticIds.UseExplicitTypeDiagnosticId), + + // Expression-bodied members + new DiagnosticSet(CSharpFeaturesResources.Apply_expression_block_body_preferences, + // csharp_style_expression_bodied_accessors + IDEDiagnosticIds.UseExpressionBodyForAccessorsDiagnosticId, + // csharp_style_expression_bodied_constructors + IDEDiagnosticIds.UseExpressionBodyForConstructorsDiagnosticId, + // csharp_style_expression_bodied_indexers + IDEDiagnosticIds.UseExpressionBodyForIndexersDiagnosticId, + // csharp_style_expression_bodied_lambdas + IDEDiagnosticIds.UseExpressionBodyForLambdaExpressionsDiagnosticId, + // csharp_style_expression_bodied_local_functions + IDEDiagnosticIds.UseExpressionBodyForLocalFunctionsDiagnosticId, + // csharp_style_expression_bodied_methods + IDEDiagnosticIds.UseExpressionBodyForMethodsDiagnosticId, + // csharp_style_expression_bodied_operators + IDEDiagnosticIds.UseExpressionBodyForOperatorsDiagnosticId, + IDEDiagnosticIds.UseExpressionBodyForConversionOperatorsDiagnosticId, + // csharp_style_expression_bodied_properties + IDEDiagnosticIds.UseExpressionBodyForPropertiesDiagnosticId), + + // Pattern matching preferences + new DiagnosticSet(CSharpFeaturesResources.Apply_pattern_matching_preferences, + // csharp_style_pattern_matching_over_as_with_null_check + IDEDiagnosticIds.InlineAsTypeCheckId, + // csharp_style_pattern_matching_over_is_with_cast_check + IDEDiagnosticIds.InlineIsTypeCheckId, + // csharp_style_prefer_extended_property_pattern + IDEDiagnosticIds.SimplifyPropertyPatternDiagnosticId, + // csharp_style_prefer_not_pattern + IDEDiagnosticIds.UseNotPatternDiagnosticId, + // csharp_style_prefer_pattern_matching + IDEDiagnosticIds.UsePatternCombinatorsDiagnosticId, + // csharp_style_prefer_switch_expression + IDEDiagnosticIds.ConvertSwitchStatementToExpressionDiagnosticId, + // csharp_style_prefer_null_check_over_type_check + IDEDiagnosticIds.UseNullCheckOverTypeCheckDiagnosticId), + + // Null-checking preferences + // csharp_style_conditional_delegate_call + new DiagnosticSet(CSharpFeaturesResources.Apply_conditional_delegate_call_preferences, + IDEDiagnosticIds.InvokeDelegateWithConditionalAccessId), + // csharp_style_prefer_parameter_null_checking + new DiagnosticSet(CSharpFeaturesResources.Apply_parameter_null_preferences, + IDEDiagnosticIds.UseParameterNullCheckingId), + + // Modifier preferences + // csharp_prefer_static_local_function + new DiagnosticSet(CSharpFeaturesResources.Apply_static_local_function_preferences, + IDEDiagnosticIds.MakeLocalFunctionStaticDiagnosticId), + // csharp_preferred_modifier_order + new DiagnosticSet(FeaturesResources.Sort_accessibility_modifiers, + IDEDiagnosticIds.OrderModifiersDiagnosticId, + "CS0267"), + + // Code-block preferences + // csharp_prefer_braces + new DiagnosticSet(CSharpFeaturesResources.Add_required_braces_for_single_line_control_statements, + IDEDiagnosticIds.AddBracesDiagnosticId), + + // csharp_prefer_simple_using_statement + new DiagnosticSet(CSharpFeaturesResources.Apply_using_statement_preferences, + IDEDiagnosticIds.UseSimpleUsingStatementDiagnosticId), + + // csharp_style_namespace_declarations + new DiagnosticSet(CSharpFeaturesResources.Apply_namespace_preferences, + IDEDiagnosticIds.UseFileScopedNamespaceDiagnosticId), + + // csharp_style_prefer_method_group_conversion + new DiagnosticSet(CSharpFeaturesResources.Apply_method_group_conversion_preferences, + IDEDiagnosticIds.RemoveUnnecessaryLambdaExpressionDiagnosticId), + + // Expression-level preferences + // csharp_prefer_simple_default_expression + new DiagnosticSet(CSharpFeaturesResources.Apply_default_T_preferences, + IDEDiagnosticIds.UseDefaultLiteralDiagnosticId), + + new DiagnosticSet(CSharpFeaturesResources.Apply_deconstruct_preferences, + // csharp_style_deconstructed_variable_declaration + IDEDiagnosticIds.UseDeconstructionDiagnosticId, + // csharp_style_prefer_tuple_swap + IDEDiagnosticIds.UseTupleSwapDiagnosticId), + + // csharp_style_implicit_object_creation_when_type_is_apparent + new DiagnosticSet(CSharpFeaturesResources.Apply_new_preferences, + IDEDiagnosticIds.UseImplicitObjectCreationDiagnosticId), + + // csharp_style_inlined_variable_declaration + new DiagnosticSet(CSharpFeaturesResources.Apply_inline_out_variable_preferences, + IDEDiagnosticIds.InlineDeclarationDiagnosticId), + + new DiagnosticSet(CSharpFeaturesResources.Apply_range_preferences, + // csharp_style_prefer_index_operator + IDEDiagnosticIds.UseIndexOperatorDiagnosticId, + // csharp_style_prefer_range_operator + IDEDiagnosticIds.UseRangeOperatorDiagnosticId), + + // csharp_style_prefer_local_over_anonymous_function + new DiagnosticSet(CSharpFeaturesResources.Apply_local_over_anonymous_function_preferences, + IDEDiagnosticIds.UseLocalFunctionDiagnosticId), + + // csharp_style_throw_expression + new DiagnosticSet(CSharpFeaturesResources.Apply_throw_expression_preferences, + IDEDiagnosticIds.UseThrowExpressionDiagnosticId), + + // csharp_style_unused_value_assignment_preference + // csharp_style_unused_value_expression_statement_preference + new DiagnosticSet(FeaturesResources.Apply_unused_value_preferences, + IDEDiagnosticIds.ExpressionValueIsUnusedDiagnosticId, + IDEDiagnosticIds.ValueAssignedIsUnusedDiagnosticId), + + // New line preferences + // csharp_style_allow_blank_line_after_colon_in_constructor_initializer_experimental + new DiagnosticSet(CSharpFeaturesResources.Apply_blank_line_after_colon_in_constructor_initializer_preferences_experimental, + IDEDiagnosticIds.ConstructorInitializerPlacementDiagnosticId), + // csharp_style_allow_blank_lines_between_consecutive_braces_experimental + new DiagnosticSet(CSharpFeaturesResources.Apply_blank_lines_between_consecutive_braces_preferences_experimental, + IDEDiagnosticIds.ConsecutiveBracePlacementDiagnosticId), + // csharp_style_allow_embedded_statements_on_same_line_experimental + new DiagnosticSet(CSharpFeaturesResources.Apply_embedded_statements_on_same_line_preferences_experimental, + IDEDiagnosticIds.EmbeddedStatementPlacementDiagnosticId), + + // Simplification rules + + new DiagnosticSet(FeaturesResources.Remove_unnecessary_casts, + IDEDiagnosticIds.RemoveUnnecessaryCastDiagnosticId), + + new DiagnosticSet(FeaturesResources.Remove_unused_variables, + CSharpRemoveUnusedVariableCodeFixProvider.CS0168, + CSharpRemoveUnusedVariableCodeFixProvider.CS0219) + ); + + [ImportingConstructor] + [Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] + public CSharpCodeCleanupService(ICodeFixService codeFixService) + : base(codeFixService) + { + } + + protected override string OrganizeImportsDescription + => CSharpFeaturesResources.Organize_Usings; + + protected override ImmutableArray GetDiagnosticSets() + => s_diagnosticSets; + } +} diff --git a/src/EditorFeatures/CSharp/CommentSelection/CSharpToggleBlockCommentCommandHandler.cs b/src/EditorFeatures/CSharp/CommentSelection/CSharpToggleBlockCommentCommandHandler.cs index c76616cebf669..d8f4eebc7bb31 100644 --- a/src/EditorFeatures/CSharp/CommentSelection/CSharpToggleBlockCommentCommandHandler.cs +++ b/src/EditorFeatures/CSharp/CommentSelection/CSharpToggleBlockCommentCommandHandler.cs @@ -12,7 +12,6 @@ using System.Threading.Tasks; using Microsoft.CodeAnalysis.CommentSelection; using Microsoft.CodeAnalysis.CSharp; -using Microsoft.CodeAnalysis.Editor.Implementation.CommentSelection; using Microsoft.CodeAnalysis.Host.Mef; using Microsoft.CodeAnalysis.Text; using Microsoft.VisualStudio.Commanding; diff --git a/src/EditorFeatures/CSharp/CompleteStatement/CompleteStatementCommandHandler.cs b/src/EditorFeatures/CSharp/CompleteStatement/CompleteStatementCommandHandler.cs index 81f053ad3f23d..db541fb1b5988 100644 --- a/src/EditorFeatures/CSharp/CompleteStatement/CompleteStatementCommandHandler.cs +++ b/src/EditorFeatures/CSharp/CompleteStatement/CompleteStatementCommandHandler.cs @@ -11,7 +11,7 @@ using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Extensions; using Microsoft.CodeAnalysis.CSharp.Syntax; -using Microsoft.CodeAnalysis.Editor.Implementation.AutomaticCompletion; +using Microsoft.CodeAnalysis.AutomaticCompletion; using Microsoft.CodeAnalysis.Editor.Shared.Extensions; using Microsoft.CodeAnalysis.Editor.Shared.Options; using Microsoft.CodeAnalysis.Editor.Shared.Utilities; @@ -253,6 +253,11 @@ private static bool CanHaveSemicolon(SyntaxNode currentNode) return true; } + if (currentNode.IsKind(SyntaxKind.EqualsValueClause) && currentNode.IsParentKind(SyntaxKind.PropertyDeclaration)) + { + return true; + } + if (currentNode is RecordDeclarationSyntax { OpenBraceToken: { IsMissing: true } }) { return true; @@ -340,6 +345,7 @@ private static bool TryGetCaretPositionToMove(SyntaxNode statementNode, Snapshot case SyntaxKind.ArrowExpressionClause: case SyntaxKind.MethodDeclaration: case SyntaxKind.RecordDeclaration: + case SyntaxKind.EqualsValueClause: case SyntaxKind.RecordStructDeclaration: // These statement types end in a semicolon. // if the original caret was inside any delimiters, `caret` will be after the outermost delimiter diff --git a/src/EditorFeatures/CSharp/ConvertNamespace/ConvertNamespaceCommandHandler.cs b/src/EditorFeatures/CSharp/ConvertNamespace/ConvertNamespaceCommandHandler.cs index 3b0cba7fa8cf0..4b49ddcb28b6d 100644 --- a/src/EditorFeatures/CSharp/ConvertNamespace/ConvertNamespaceCommandHandler.cs +++ b/src/EditorFeatures/CSharp/ConvertNamespace/ConvertNamespaceCommandHandler.cs @@ -11,7 +11,7 @@ using Microsoft.CodeAnalysis.CSharp.CodeStyle; using Microsoft.CodeAnalysis.CSharp.ConvertNamespace; using Microsoft.CodeAnalysis.CSharp.Syntax; -using Microsoft.CodeAnalysis.Editor.Implementation.AutomaticCompletion; +using Microsoft.CodeAnalysis.AutomaticCompletion; using Microsoft.CodeAnalysis.Editor.Shared.Extensions; using Microsoft.CodeAnalysis.Editor.Shared.Options; using Microsoft.CodeAnalysis.Editor.Shared.Utilities; diff --git a/src/EditorFeatures/CSharp/DecompiledSource/CSharpDecompiledSourceService.cs b/src/EditorFeatures/CSharp/DecompiledSource/CSharpDecompiledSourceService.cs index 8aa9d86ee763f..895a8b284b3d6 100644 --- a/src/EditorFeatures/CSharp/DecompiledSource/CSharpDecompiledSourceService.cs +++ b/src/EditorFeatures/CSharp/DecompiledSource/CSharpDecompiledSourceService.cs @@ -48,11 +48,13 @@ public async Task AddSourceToAsync(Document document, Compilation symb var containingOrThis = symbol.GetContainingTypeOrThis(); var fullName = GetFullReflectionName(containingOrThis); - MetadataReference metadataReference = null; - string assemblyLocation = null; + var metadataReference = symbolCompilation.GetMetadataReference(symbol.ContainingAssembly); + var assemblyLocation = (metadataReference as PortableExecutableReference)?.FilePath; + var isReferenceAssembly = symbol.ContainingAssembly.GetAttributes().Any(attribute => attribute.AttributeClass.Name == nameof(ReferenceAssemblyAttribute) && attribute.AttributeClass.ToNameDisplayString() == typeof(ReferenceAssemblyAttribute).FullName); - if (isReferenceAssembly) + if (isReferenceAssembly && + !MetadataAsSourceHelpers.TryGetImplementationAssemblyPath(assemblyLocation, out assemblyLocation)) { try { @@ -64,12 +66,6 @@ public async Task AddSourceToAsync(Document document, Compilation symb } } - if (assemblyLocation == null) - { - metadataReference = symbolCompilation.GetMetadataReference(symbol.ContainingAssembly); - assemblyLocation = (metadataReference as PortableExecutableReference)?.FilePath; - } - // Decompile document = PerformDecompilation(document, fullName, symbolCompilation, metadataReference, assemblyLocation); @@ -110,7 +106,7 @@ private static Document PerformDecompilation(Document document, string fullName, if (file is null && assemblyLocation is null) { - throw new NotSupportedException(EditorFeaturesResources.Cannot_navigate_to_the_symbol_under_the_caret); + throw new NotSupportedException(FeaturesResources.Cannot_navigate_to_the_symbol_under_the_caret); } file ??= new PEFile(assemblyLocation, PEStreamOptions.PrefetchEntireImage); diff --git a/src/EditorFeatures/CSharp/DocumentationComments/DocumentationCommentCommandHandler.cs b/src/EditorFeatures/CSharp/DocumentationComments/DocumentationCommentCommandHandler.cs index ecd33f848fd00..ab1bd395c9d52 100644 --- a/src/EditorFeatures/CSharp/DocumentationComments/DocumentationCommentCommandHandler.cs +++ b/src/EditorFeatures/CSharp/DocumentationComments/DocumentationCommentCommandHandler.cs @@ -5,8 +5,8 @@ using System; using System.ComponentModel.Composition; using Microsoft.CodeAnalysis.CSharp.Syntax; +using Microsoft.CodeAnalysis.DocumentationComments; using Microsoft.CodeAnalysis.Editor.Host; -using Microsoft.CodeAnalysis.Editor.Implementation.DocumentationComments; using Microsoft.CodeAnalysis.Host.Mef; using Microsoft.VisualStudio.Commanding; using Microsoft.VisualStudio.Language.Intellisense.AsyncCompletion; diff --git a/src/EditorFeatures/CSharp/DocumentationComments/XmlTagCompletionCommandHandler.cs b/src/EditorFeatures/CSharp/DocumentationComments/XmlTagCompletionCommandHandler.cs index 643d286ef3af5..8e44628e6fa91 100644 --- a/src/EditorFeatures/CSharp/DocumentationComments/XmlTagCompletionCommandHandler.cs +++ b/src/EditorFeatures/CSharp/DocumentationComments/XmlTagCompletionCommandHandler.cs @@ -10,7 +10,7 @@ using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Extensions; using Microsoft.CodeAnalysis.CSharp.Syntax; -using Microsoft.CodeAnalysis.Editor.Implementation.DocumentationComments; +using Microsoft.CodeAnalysis.DocumentationComments; using Microsoft.CodeAnalysis.Host.Mef; using Microsoft.CodeAnalysis.Shared.Extensions; using Microsoft.VisualStudio.Commanding; diff --git a/src/EditorFeatures/CSharp/EncapsulateField/EncapsulateFieldCommandHandler.cs b/src/EditorFeatures/CSharp/EncapsulateField/EncapsulateFieldCommandHandler.cs index 4501dbaac21f9..2323f3ce78a98 100644 --- a/src/EditorFeatures/CSharp/EncapsulateField/EncapsulateFieldCommandHandler.cs +++ b/src/EditorFeatures/CSharp/EncapsulateField/EncapsulateFieldCommandHandler.cs @@ -6,8 +6,8 @@ using System; using System.ComponentModel.Composition; -using Microsoft.CodeAnalysis.Editor.Implementation.EncapsulateField; using Microsoft.CodeAnalysis.Editor.Shared.Utilities; +using Microsoft.CodeAnalysis.EncapsulateField; using Microsoft.CodeAnalysis.Host.Mef; using Microsoft.CodeAnalysis.Shared.TestHooks; using Microsoft.VisualStudio.Commanding; diff --git a/src/EditorFeatures/CSharp/ExtractInterface/ExtractInterfaceCommandHandler.cs b/src/EditorFeatures/CSharp/ExtractInterface/ExtractInterfaceCommandHandler.cs index d950c096287ff..928c9af2440d8 100644 --- a/src/EditorFeatures/CSharp/ExtractInterface/ExtractInterfaceCommandHandler.cs +++ b/src/EditorFeatures/CSharp/ExtractInterface/ExtractInterfaceCommandHandler.cs @@ -6,13 +6,14 @@ using System; using System.ComponentModel.Composition; -using Microsoft.CodeAnalysis.Editor.Implementation.ExtractInterface; +using Microsoft.CodeAnalysis.Editor; using Microsoft.CodeAnalysis.Editor.Shared.Utilities; +using Microsoft.CodeAnalysis.ExtractInterface; using Microsoft.CodeAnalysis.Host.Mef; using Microsoft.VisualStudio.Commanding; using Microsoft.VisualStudio.Utilities; -namespace Microsoft.CodeAnalysis.Editor.CSharp.ExtractInterface +namespace Microsoft.CodeAnalysis.CSharp.ExtractInterface { [Export(typeof(ICommandHandler))] [ContentType(ContentTypeNames.CSharpContentType)] diff --git a/src/EditorFeatures/CSharp/ExtractMethod/ExtractMethodCommandHandler.cs b/src/EditorFeatures/CSharp/ExtractMethod/ExtractMethodCommandHandler.cs index 538a825537709..64ac5347727bc 100644 --- a/src/EditorFeatures/CSharp/ExtractMethod/ExtractMethodCommandHandler.cs +++ b/src/EditorFeatures/CSharp/ExtractMethod/ExtractMethodCommandHandler.cs @@ -6,15 +6,16 @@ using System; using System.ComponentModel.Composition; -using Microsoft.CodeAnalysis.Editor.Implementation.ExtractMethod; +using Microsoft.CodeAnalysis.Editor; using Microsoft.CodeAnalysis.Editor.Shared.Utilities; +using Microsoft.CodeAnalysis.ExtractMethod; using Microsoft.CodeAnalysis.Host.Mef; using Microsoft.CodeAnalysis.Options; using Microsoft.VisualStudio.Commanding; using Microsoft.VisualStudio.Text.Operations; using Microsoft.VisualStudio.Utilities; -namespace Microsoft.CodeAnalysis.Editor.CSharp.ExtractMethod +namespace Microsoft.CodeAnalysis.CSharp.ExtractMethod { [Export(typeof(ICommandHandler))] [ContentType(ContentTypeNames.CSharpContentType)] diff --git a/src/EditorFeatures/CSharp/FindUsages/CSharpFindUsagesLSPService.cs b/src/EditorFeatures/CSharp/FindUsages/CSharpFindUsagesLSPService.cs index 65c94d977d0fa..129b740698032 100644 --- a/src/EditorFeatures/CSharp/FindUsages/CSharpFindUsagesLSPService.cs +++ b/src/EditorFeatures/CSharp/FindUsages/CSharpFindUsagesLSPService.cs @@ -2,15 +2,12 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -#nullable disable - using System; using System.Composition; -using Microsoft.CodeAnalysis.Editor.FindUsages; -using Microsoft.CodeAnalysis.Editor.Shared.Utilities; +using Microsoft.CodeAnalysis.FindUsages; using Microsoft.CodeAnalysis.Host.Mef; -namespace Microsoft.CodeAnalysis.Editor.CSharp.FindUsages +namespace Microsoft.CodeAnalysis.CSharp.FindUsages { [ExportLanguageService(typeof(IFindUsagesLSPService), LanguageNames.CSharp), Shared] internal class CSharpFindUsagesLSPService : AbstractFindUsagesService diff --git a/src/EditorFeatures/CSharp/FindUsages/CSharpFindUsagesService.cs b/src/EditorFeatures/CSharp/FindUsages/CSharpFindUsagesService.cs index 1fedd08ae3d7c..72a2df52c457d 100644 --- a/src/EditorFeatures/CSharp/FindUsages/CSharpFindUsagesService.cs +++ b/src/EditorFeatures/CSharp/FindUsages/CSharpFindUsagesService.cs @@ -4,10 +4,10 @@ using System; using System.Composition; -using Microsoft.CodeAnalysis.Editor.FindUsages; +using Microsoft.CodeAnalysis.FindUsages; using Microsoft.CodeAnalysis.Host.Mef; -namespace Microsoft.CodeAnalysis.Editor.CSharp.FindUsages +namespace Microsoft.CodeAnalysis.CSharp.FindUsages { [ExportLanguageService(typeof(IFindUsagesService), LanguageNames.CSharp), Shared] internal class CSharpFindUsagesService : AbstractFindUsagesService diff --git a/src/EditorFeatures/CSharp/GoToBase/CSharpGoToBaseService.cs b/src/EditorFeatures/CSharp/GoToBase/CSharpGoToBaseService.cs index 18a2f218ea74f..bb742d54361d7 100644 --- a/src/EditorFeatures/CSharp/GoToBase/CSharpGoToBaseService.cs +++ b/src/EditorFeatures/CSharp/GoToBase/CSharpGoToBaseService.cs @@ -2,21 +2,21 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -#nullable disable - using System; using System.Composition; -using Microsoft.CodeAnalysis.Editor.GoToBase; +using Microsoft.CodeAnalysis.GoToBase; using Microsoft.CodeAnalysis.Host.Mef; +using Microsoft.CodeAnalysis.Options; -namespace Microsoft.CodeAnalysis.Editor.CSharp.GoToBase +namespace Microsoft.CodeAnalysis.CSharp.GoToBase { [ExportLanguageService(typeof(IGoToBaseService), LanguageNames.CSharp), Shared] - internal class CSharpGoToBaseService : AbstractGoToBaseService + internal sealed class CSharpGoToBaseService : AbstractGoToBaseService { [ImportingConstructor] [Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] public CSharpGoToBaseService() + : base() { } } diff --git a/src/EditorFeatures/CSharp/GoToDefinition/CSharpGoToDefinitionService.cs b/src/EditorFeatures/CSharp/GoToDefinition/CSharpGoToDefinitionService.cs index 80294aad2ccbd..bf189c8a8f9f0 100644 --- a/src/EditorFeatures/CSharp/GoToDefinition/CSharpGoToDefinitionService.cs +++ b/src/EditorFeatures/CSharp/GoToDefinition/CSharpGoToDefinitionService.cs @@ -4,10 +4,11 @@ using System.Composition; using System.Diagnostics.CodeAnalysis; -using Microsoft.CodeAnalysis.Editor.GoToDefinition; using Microsoft.CodeAnalysis.Editor.Host; using Microsoft.CodeAnalysis.Editor.Shared.Utilities; +using Microsoft.CodeAnalysis.GoToDefinition; using Microsoft.CodeAnalysis.Host.Mef; +using Microsoft.CodeAnalysis.Options; namespace Microsoft.CodeAnalysis.Editor.CSharp.GoToDefinition { diff --git a/src/EditorFeatures/CSharp/GoToDefinition/CSharpGoToSymbolService.cs b/src/EditorFeatures/CSharp/GoToDefinition/CSharpGoToSymbolService.cs index cb7c9793e0b98..01cfb11f72d2c 100644 --- a/src/EditorFeatures/CSharp/GoToDefinition/CSharpGoToSymbolService.cs +++ b/src/EditorFeatures/CSharp/GoToDefinition/CSharpGoToSymbolService.cs @@ -4,14 +4,15 @@ using System; using System.Composition; -using Microsoft.CodeAnalysis.Editor.GoToDefinition; using Microsoft.CodeAnalysis.Editor.Shared.Utilities; +using Microsoft.CodeAnalysis.GoToDefinition; using Microsoft.CodeAnalysis.Host.Mef; +using Microsoft.CodeAnalysis.Options; namespace Microsoft.CodeAnalysis.Editor.CSharp.GoToDefinition { [ExportLanguageService(typeof(IGoToSymbolService), LanguageNames.CSharp), Shared] - internal class CSharpGoToSymbolService : AbstractGoToSymbolService + internal sealed class CSharpGoToSymbolService : AbstractGoToSymbolService { [ImportingConstructor] [Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] diff --git a/src/EditorFeatures/CSharp/Interactive/CSharpInteractiveEvaluatorLanguageInfoProvider.cs b/src/EditorFeatures/CSharp/Interactive/CSharpInteractiveEvaluatorLanguageInfoProvider.cs index 35fd5917fbe83..2bda5f3b5ed34 100644 --- a/src/EditorFeatures/CSharp/Interactive/CSharpInteractiveEvaluatorLanguageInfoProvider.cs +++ b/src/EditorFeatures/CSharp/Interactive/CSharpInteractiveEvaluatorLanguageInfoProvider.cs @@ -7,7 +7,7 @@ using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Scripting; using Microsoft.CodeAnalysis.CSharp.Scripting.Hosting; -using Microsoft.CodeAnalysis.Editor.Interactive; +using Microsoft.CodeAnalysis.Interactive; namespace Microsoft.CodeAnalysis.Editor.CSharp.Interactive { diff --git a/src/EditorFeatures/CSharp/Interactive/CSharpSendToInteractiveSubmissionProvider.cs b/src/EditorFeatures/CSharp/Interactive/CSharpSendToInteractiveSubmissionProvider.cs index 5c6fa20416fcc..0a2cf45eee45c 100644 --- a/src/EditorFeatures/CSharp/Interactive/CSharpSendToInteractiveSubmissionProvider.cs +++ b/src/EditorFeatures/CSharp/Interactive/CSharpSendToInteractiveSubmissionProvider.cs @@ -10,8 +10,8 @@ using System.Linq; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; -using Microsoft.CodeAnalysis.Editor.Interactive; using Microsoft.CodeAnalysis.Host.Mef; +using Microsoft.CodeAnalysis.Interactive; using Microsoft.CodeAnalysis.Shared.Extensions; using Microsoft.CodeAnalysis.Text; diff --git a/src/EditorFeatures/CSharp/RawStringLiteral/RawStringLiteralCommandHandler_Return.cs b/src/EditorFeatures/CSharp/RawStringLiteral/RawStringLiteralCommandHandler_Return.cs index a9c515e5b7d86..7429ddfdb13e4 100644 --- a/src/EditorFeatures/CSharp/RawStringLiteral/RawStringLiteralCommandHandler_Return.cs +++ b/src/EditorFeatures/CSharp/RawStringLiteral/RawStringLiteralCommandHandler_Return.cs @@ -58,14 +58,18 @@ public bool ExecuteCommand(ReturnKeyCommandArgs args, CommandExecutionContext co for (int i = position, n = currentSnapshot.Length; i < n; i++) { - if (currentSnapshot[i] == '"') - quotesAfter++; + if (currentSnapshot[i] != '"') + break; + + quotesAfter++; } for (var i = position - 1; i >= 0; i--) { - if (currentSnapshot[i] == '"') - quotesBefore++; + if (currentSnapshot[i] != '"') + break; + + quotesBefore++; } if (quotesAfter != quotesBefore) diff --git a/src/EditorFeatures/CSharp/TextStructureNavigation/TextStructureNavigatorProvider.cs b/src/EditorFeatures/CSharp/TextStructureNavigation/CSharpTextStructureNavigatorProvider.cs similarity index 64% rename from src/EditorFeatures/CSharp/TextStructureNavigation/TextStructureNavigatorProvider.cs rename to src/EditorFeatures/CSharp/TextStructureNavigation/CSharpTextStructureNavigatorProvider.cs index e55bbc6760482..8cef5deb3a2b4 100644 --- a/src/EditorFeatures/CSharp/TextStructureNavigation/TextStructureNavigatorProvider.cs +++ b/src/EditorFeatures/CSharp/TextStructureNavigation/CSharpTextStructureNavigatorProvider.cs @@ -2,13 +2,10 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -#nullable disable - using System; using System.ComponentModel.Composition; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Extensions; -using Microsoft.CodeAnalysis.Editor.Host; using Microsoft.CodeAnalysis.Editor.Implementation.TextStructureNavigation; using Microsoft.CodeAnalysis.Host.Mef; using Microsoft.VisualStudio.Text; @@ -19,11 +16,11 @@ namespace Microsoft.CodeAnalysis.Editor.CSharp.TextStructureNavigation { [Export(typeof(ITextStructureNavigatorProvider))] [ContentType(ContentTypeNames.CSharpContentType)] - internal class TextStructureNavigatorProvider : AbstractTextStructureNavigatorProvider + internal class CSharpTextStructureNavigatorProvider : AbstractTextStructureNavigatorProvider { [ImportingConstructor] [Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] - public TextStructureNavigatorProvider( + public CSharpTextStructureNavigatorProvider( ITextStructureNavigatorSelectorService selectorService, IContentTypeRegistryService contentTypeService, IUIThreadOperationExecutor uIThreadOperationExecutor) @@ -41,13 +38,17 @@ protected override bool IsWithinNaturalLanguage(SyntaxToken token, int position) case SyntaxKind.StringLiteralToken: // This, in combination with the override of GetExtentOfWordFromToken() below, treats the closing // quote as a separate token. This maintains behavior with VS2013. - if (position == token.Span.End - 1 && token.Text.EndsWith("\"", StringComparison.Ordinal)) + return !IsAtClosingQuote(token, position); + + case SyntaxKind.SingleLineRawStringLiteralToken: + case SyntaxKind.MultiLineRawStringLiteralToken: { - return false; + // Like with normal string literals, treat the closing quotes as as the end of the string so that + // navigation ends there and doesn't go past them. + var end = GetStartOfRawStringLiteralEndDelimiter(token); + return position < end; } - return true; - case SyntaxKind.CharacterLiteralToken: // Before the ' is considered outside the character return position != token.SpanStart; @@ -60,9 +61,26 @@ protected override bool IsWithinNaturalLanguage(SyntaxToken token, int position) return false; } + private static int GetStartOfRawStringLiteralEndDelimiter(SyntaxToken token) + { + var text = token.ToString(); + var start = 0; + var end = text.Length; + while (start < end && text[start] == '"') + start++; + + while (end > start && text[end - 1] == '"') + end--; + + return token.SpanStart + end; + } + + private static bool IsAtClosingQuote(SyntaxToken token, int position) + => position == token.Span.End - 1 && token.Text[^1] == '"'; + protected override TextExtent GetExtentOfWordFromToken(SyntaxToken token, SnapshotPoint position) { - if (token.Kind() == SyntaxKind.StringLiteralToken && position.Position == token.Span.End - 1 && token.Text.EndsWith("\"", StringComparison.Ordinal)) + if (token.Kind() == SyntaxKind.StringLiteralToken && IsAtClosingQuote(token, position.Position)) { // Special case to treat the closing quote of a string literal as a separate token. This allows the // cursor to stop during word navigation (Ctrl+LeftArrow, etc.) immediately before AND after the @@ -70,6 +88,11 @@ protected override TextExtent GetExtentOfWordFromToken(SyntaxToken token, Snapsh var span = new Span(position.Position, 1); return new TextExtent(new SnapshotSpan(position.Snapshot, span), isSignificant: true); } + else if (token.Kind() is SyntaxKind.SingleLineRawStringLiteralToken or SyntaxKind.MultiLineRawStringLiteralToken) + { + var delimiterStart = GetStartOfRawStringLiteralEndDelimiter(token); + return new TextExtent(new SnapshotSpan(position.Snapshot, Span.FromBounds(delimiterStart, token.Span.End)), isSignificant: true); + } else { return base.GetExtentOfWordFromToken(token, position); diff --git a/src/EditorFeatures/CSharpTest/AddAnonymousTypeMemberName/AddAnonymousTypeMemberNameTests.cs b/src/EditorFeatures/CSharpTest/AddAnonymousTypeMemberName/AddAnonymousTypeMemberNameTests.cs index 84578536cf1f6..868dbaea8a625 100644 --- a/src/EditorFeatures/CSharpTest/AddAnonymousTypeMemberName/AddAnonymousTypeMemberNameTests.cs +++ b/src/EditorFeatures/CSharpTest/AddAnonymousTypeMemberName/AddAnonymousTypeMemberNameTests.cs @@ -86,7 +86,7 @@ class C { void M() { - var v = new { P = new { Type = this.GetType(), V = this.ToString() } }; + var v = new { Value = new { Type = this.GetType(), V = this.ToString() } }; } }"); } @@ -108,7 +108,7 @@ class C { void M() { - var v = new { P = new { Type = this.GetType(), V = this.ToString() } }; + var v = new { Value = new { Type = this.GetType(), V = this.ToString() } }; } }"); } @@ -130,7 +130,7 @@ class C { void M() { - var v = new { P = new { Type = this.GetType(), Type1 = this.GetType() } }; + var v = new { Value = new { Type = this.GetType(), Type1 = this.GetType() } }; } }"); } diff --git a/src/EditorFeatures/CSharpTest/AddParameter/AddParameterTests.cs b/src/EditorFeatures/CSharpTest/AddParameter/AddParameterTests.cs index d3961df775dbc..958cf1812f78b 100644 --- a/src/EditorFeatures/CSharpTest/AddParameter/AddParameterTests.cs +++ b/src/EditorFeatures/CSharpTest/AddParameter/AddParameterTests.cs @@ -493,7 +493,7 @@ void M() @" class C { - public C(object p, int i) { } + public C(object value, int i) { } } class D @@ -1068,7 +1068,6 @@ void M2() M1(1, 2); } }"); - //Should fix to: void M1(T arg, T v) { } } [WorkItem(21446, "https://github.com/dotnet/roslyn/issues/21446")] @@ -1199,7 +1198,7 @@ void M2() @" class C1 { - void M1((int, int) t1, (int, string) p) + void M1((int, int) t1, (int, string) value) { } void M2() diff --git a/src/EditorFeatures/CSharpTest/AddUsing/AddUsingNuGetTests.cs b/src/EditorFeatures/CSharpTest/AddUsing/AddUsingNuGetTests.cs index 1a163db1b3ff6..899397848d526 100644 --- a/src/EditorFeatures/CSharpTest/AddUsing/AddUsingNuGetTests.cs +++ b/src/EditorFeatures/CSharpTest/AddUsing/AddUsingNuGetTests.cs @@ -14,6 +14,7 @@ using Microsoft.CodeAnalysis.CSharp.AddImport; using Microsoft.CodeAnalysis.Diagnostics; using Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces; +using Microsoft.CodeAnalysis.Options; using Microsoft.CodeAnalysis.Packaging; using Microsoft.CodeAnalysis.Shared.Utilities; using Microsoft.CodeAnalysis.SymbolSearch; @@ -35,9 +36,8 @@ public class AddUsingNuGetTests : AbstractAddUsingTests protected override void InitializeWorkspace(TestWorkspace workspace, TestParameters parameters) { - workspace.TryApplyChanges(workspace.CurrentSolution.WithOptions(workspace.Options - .WithChangedOption(SymbolSearchOptions.SuggestForTypesInNuGetPackages, LanguageNames.CSharp, true) - .WithChangedOption(SymbolSearchOptions.SuggestForTypesInReferenceAssemblies, LanguageNames.CSharp, true))); + workspace.GlobalOptions.SetGlobalOption(new OptionKey(SymbolSearchOptionsStorage.SearchNuGetPackages, LanguageNames.CSharp), true); + workspace.GlobalOptions.SetGlobalOption(new OptionKey(SymbolSearchOptionsStorage.SearchReferenceAssemblies, LanguageNames.CSharp), true); } internal override (DiagnosticAnalyzer, CodeFixProvider) CreateDiagnosticProviderAndFixer( diff --git a/src/EditorFeatures/CSharpTest/AutomaticCompletion/AutomaticBracketCompletionTests.cs b/src/EditorFeatures/CSharpTest/AutomaticCompletion/AutomaticBracketCompletionTests.cs index 8f3f2fc8b7b83..e07e1c348a77c 100644 --- a/src/EditorFeatures/CSharpTest/AutomaticCompletion/AutomaticBracketCompletionTests.cs +++ b/src/EditorFeatures/CSharpTest/AutomaticCompletion/AutomaticBracketCompletionTests.cs @@ -4,7 +4,7 @@ #nullable disable -using Microsoft.CodeAnalysis.Editor.Implementation.AutomaticCompletion; +using Microsoft.CodeAnalysis.AutomaticCompletion; using Microsoft.CodeAnalysis.Editor.UnitTests.AutomaticCompletion; using Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces; using Microsoft.CodeAnalysis.Test.Utilities; @@ -258,7 +258,16 @@ class C { void M(object o) { - _ = o is $$ + _ = o is$$ + } +} +"; + var expectedBeforeReturn = @" +class C +{ + void M(object o) + { + _ = o is [] } } "; @@ -267,17 +276,17 @@ class C { void M(object o) { - _ = o is [ -] + _ = o is + [ + + ] } } "; using var session = CreateSession(code); CheckStart(session.Session); - // Open bracket probably should be moved to new line - // Close bracket probably should be aligned with open bracket - // Tracked by https://github.com/dotnet/roslyn/issues/57244 - CheckReturn(session.Session, 0, expected); + CheckText(session.Session, expectedBeforeReturn); + CheckReturn(session.Session, 12, expected); } internal static Holder CreateSession(string code) diff --git a/src/EditorFeatures/CSharpTest/AutomaticCompletion/AutomaticLessAndGreaterThanCompletionTests.cs b/src/EditorFeatures/CSharpTest/AutomaticCompletion/AutomaticLessAndGreaterThanCompletionTests.cs index ca4810a0575af..67227b294738d 100644 --- a/src/EditorFeatures/CSharpTest/AutomaticCompletion/AutomaticLessAndGreaterThanCompletionTests.cs +++ b/src/EditorFeatures/CSharpTest/AutomaticCompletion/AutomaticLessAndGreaterThanCompletionTests.cs @@ -4,7 +4,7 @@ #nullable disable -using Microsoft.CodeAnalysis.Editor.Implementation.AutomaticCompletion; +using Microsoft.CodeAnalysis.AutomaticCompletion; using Microsoft.CodeAnalysis.Editor.UnitTests.AutomaticCompletion; using Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces; using Microsoft.CodeAnalysis.Test.Utilities; diff --git a/src/EditorFeatures/CSharpTest/AutomaticCompletion/AutomaticLiteralCompletionTests.cs b/src/EditorFeatures/CSharpTest/AutomaticCompletion/AutomaticLiteralCompletionTests.cs index 96c6f4b160add..cb7076a293295 100644 --- a/src/EditorFeatures/CSharpTest/AutomaticCompletion/AutomaticLiteralCompletionTests.cs +++ b/src/EditorFeatures/CSharpTest/AutomaticCompletion/AutomaticLiteralCompletionTests.cs @@ -4,7 +4,7 @@ #nullable disable -using Microsoft.CodeAnalysis.Editor.Implementation.AutomaticCompletion; +using Microsoft.CodeAnalysis.AutomaticCompletion; using Microsoft.CodeAnalysis.Editor.UnitTests.AutomaticCompletion; using Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces; using Microsoft.CodeAnalysis.Test.Utilities; diff --git a/src/EditorFeatures/CSharpTest/AutomaticCompletion/AutomaticParenthesisCompletionTests.cs b/src/EditorFeatures/CSharpTest/AutomaticCompletion/AutomaticParenthesisCompletionTests.cs index d9be3c712af3c..fa7614f564ed0 100644 --- a/src/EditorFeatures/CSharpTest/AutomaticCompletion/AutomaticParenthesisCompletionTests.cs +++ b/src/EditorFeatures/CSharpTest/AutomaticCompletion/AutomaticParenthesisCompletionTests.cs @@ -4,7 +4,7 @@ #nullable disable -using Microsoft.CodeAnalysis.Editor.Implementation.AutomaticCompletion; +using Microsoft.CodeAnalysis.AutomaticCompletion; using Microsoft.CodeAnalysis.Editor.UnitTests.AutomaticCompletion; using Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces; using Microsoft.CodeAnalysis.Test.Utilities; diff --git a/src/EditorFeatures/CSharpTest/BraceHighlighting/BraceHighlightingTests.cs b/src/EditorFeatures/CSharpTest/BraceHighlighting/BraceHighlightingTests.cs index 05171cee84a20..3416cb73fd1b0 100644 --- a/src/EditorFeatures/CSharpTest/BraceHighlighting/BraceHighlightingTests.cs +++ b/src/EditorFeatures/CSharpTest/BraceHighlighting/BraceHighlightingTests.cs @@ -475,6 +475,20 @@ void Goo() await TestBraceHighlightingAsync(input); } + [WpfFact, Trait(Traits.Feature, Traits.Features.BraceHighlighting)] + public async Task TestJsonBracket_RawStrings() + { + var input = @" +class C +{ + void Goo() + { + var r = /*lang=json*/ """"""new Json[|$$(|]1, 2, 3[|)|]""""""; + } +}"; + await TestBraceHighlightingAsync(input); + } + [WpfFact, Trait(Traits.Feature, Traits.Features.BraceHighlighting)] public async Task TestUnmatchedJsonBracket1() { @@ -485,6 +499,34 @@ void Goo() { var r = /*lang=json*/ @""new Json$$(1, 2, 3""; } +}"; + await TestBraceHighlightingAsync(input); + } + + [WpfFact, Trait(Traits.Feature, Traits.Features.BraceHighlighting)] + public async Task TestJsonBracket_NoComment_NotLikelyJson() + { + var input = @" +class C +{ + void Goo() + { + var r = @""$$[ 1, 2, 3 ]""; + } +}"; + await TestBraceHighlightingAsync(input); + } + + [WpfFact, Trait(Traits.Feature, Traits.Features.BraceHighlighting)] + public async Task TestJsonBracket_NoComment_LikelyJson() + { + var input = @" +class C +{ + void Goo() + { + var r = @""[ { prop: 0 }, new Json[|$$(|]1, 2, 3[|)|], 3 ]""; + } }"; await TestBraceHighlightingAsync(input); } diff --git a/src/EditorFeatures/CSharpTest/Classification/CopyPasteAndPrintingClassifierTests.cs b/src/EditorFeatures/CSharpTest/Classification/CopyPasteAndPrintingClassifierTests.cs index 62457ed87a60a..0f7795b03df51 100644 --- a/src/EditorFeatures/CSharpTest/Classification/CopyPasteAndPrintingClassifierTests.cs +++ b/src/EditorFeatures/CSharpTest/Classification/CopyPasteAndPrintingClassifierTests.cs @@ -7,7 +7,7 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; -using Microsoft.CodeAnalysis.Editor.Implementation.Classification; +using Microsoft.CodeAnalysis.Classification; using Microsoft.CodeAnalysis.Editor.Shared.Utilities; using Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces; using Microsoft.CodeAnalysis.Shared.Extensions; @@ -32,12 +32,13 @@ public async Task TestGetTagsOnBufferTagger() using var workspace = TestWorkspace.CreateCSharp("class C { C c; }"); var document = workspace.Documents.First(); - var listenerProvider = workspace.ExportProvider.GetExportedValue(); + var listenerProvider = workspace.GetService(); var provider = new CopyPasteAndPrintingClassificationBufferTaggerProvider( - workspace.ExportProvider.GetExportedValue(), - workspace.ExportProvider.GetExportedValue(), - listenerProvider); + workspace.GetService(), + workspace.GetService(), + listenerProvider, + workspace.GlobalOptions); var tagger = provider.CreateTagger(document.GetTextBuffer())!; using var disposable = (IDisposable)tagger; diff --git a/src/EditorFeatures/CSharpTest/Classification/SemanticClassifierTests.cs b/src/EditorFeatures/CSharpTest/Classification/SemanticClassifierTests.cs index 9b3b9c3b4c8e5..4a850c1f2818c 100644 --- a/src/EditorFeatures/CSharpTest/Classification/SemanticClassifierTests.cs +++ b/src/EditorFeatures/CSharpTest/Classification/SemanticClassifierTests.cs @@ -3422,6 +3422,62 @@ class Program Regex.Grouping(")")); } + [Theory] + [CombinatorialData] + public async Task TestRegexSingleLineRawStringLiteral(TestHost testHost) + { + await TestAsync( +@" +using System.Text.RegularExpressions; + +class Program +{ + void Goo() + { + var r = /* lang=regex */ """"""$\a(?#comment)""""""; + } +}", +testHost, Namespace("System"), +Namespace("Text"), +Namespace("RegularExpressions"), +Keyword("var"), +Regex.Anchor("$"), +Regex.OtherEscape("\\"), +Regex.OtherEscape("a"), +Regex.Comment("(?#comment)")); + } + + [Theory] + [CombinatorialData] + public async Task TestRegexMultiLineRawStringLiteral(TestHost testHost) + { + await TestAsync( +@" +using System.Text.RegularExpressions; + +class Program +{ + void Goo() + { + var r = /* lang=regex */ """""" + $\a(?#comment) + """"""; + } +}", +testHost, Namespace("System"), +Namespace("Text"), +Namespace("RegularExpressions"), +Keyword("var"), +Regex.Text(@" + "), +Regex.Anchor("$"), +Regex.OtherEscape("\\"), +Regex.OtherEscape("a"), +Regex.Comment("(?#comment)"), +Regex.Text(@" + ")); + } + [Theory, WorkItem(47079, "https://github.com/dotnet/roslyn/issues/47079")] [CombinatorialData] public async Task TestRegexWithSpecialCSharpCharLiterals(TestHost testHost) @@ -3528,6 +3584,149 @@ void Goo() Regex.Comment("(?#comment)")); } + [Theory] + [CombinatorialData] + public async Task TestRegexOnApiWithStringSyntaxAttribute_ParamsArgument(TestHost testHost) + { + await TestAsync( +@" +using System.Diagnostics.CodeAnalysis; +using System.Text.RegularExpressions; + +class Program +{ + private void M([StringSyntax(StringSyntaxAttribute.Regex)] params string[] p) + { + } + + void Goo() + { + [|M(@""$\a(?#comment)"");|] + } +}" + EmbeddedLanguagesTestConstants.StringSyntaxAttributeCodeCSharp, +testHost, +Method("M"), +Regex.Anchor("$"), +Regex.OtherEscape("\\"), +Regex.OtherEscape("a"), +Regex.Comment("(?#comment)")); + } + + [Theory] + [CombinatorialData] + public async Task TestRegexOnApiWithStringSyntaxAttribute_ArrayArgument(TestHost testHost) + { + await TestAsync( +@" +using System.Diagnostics.CodeAnalysis; +using System.Text.RegularExpressions; + +class Program +{ + private void M([StringSyntax(StringSyntaxAttribute.Regex)] string[] p) + { + } + + void Goo() + { + [|M(new string[] { @""$\a(?#comment)"" });|] + } +}" + EmbeddedLanguagesTestConstants.StringSyntaxAttributeCodeCSharp, +testHost, +Method("M"), +Regex.Anchor("$"), +Regex.OtherEscape("\\"), +Regex.OtherEscape("a"), +Regex.Comment("(?#comment)")); + } + + [Theory] + [CombinatorialData] + public async Task TestRegexOnApiWithStringSyntaxAttribute_ImplicitArrayArgument(TestHost testHost) + { + await TestAsync( +@" +using System.Diagnostics.CodeAnalysis; +using System.Text.RegularExpressions; + +class Program +{ + private void M([StringSyntax(StringSyntaxAttribute.Regex)] string[] p) + { + } + + void Goo() + { + [|M(new[] { @""$\a(?#comment)"" });|] + } +}" + EmbeddedLanguagesTestConstants.StringSyntaxAttributeCodeCSharp, +testHost, +Method("M"), +Regex.Anchor("$"), +Regex.OtherEscape("\\"), +Regex.OtherEscape("a"), +Regex.Comment("(?#comment)")); + } + + [Theory] + [CombinatorialData] + public async Task TestRegexOnApiWithStringSyntaxAttribute_CollectionArgument(TestHost testHost) + { + await TestAsync( +@" +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Text.RegularExpressions; + +class Program +{ + private void M([StringSyntax(StringSyntaxAttribute.Regex)] List p) + { + } + + void Goo() + { + [|M(new List { @""$\a(?#comment)"" });|] + } +}" + EmbeddedLanguagesTestConstants.StringSyntaxAttributeCodeCSharp, +testHost, +Method("M"), +Class("List"), +Regex.Anchor("$"), +Regex.OtherEscape("\\"), +Regex.OtherEscape("a"), +Regex.Comment("(?#comment)")); + } + + [Theory] + [CombinatorialData] + public async Task TestRegexOnApiWithStringSyntaxAttribute_ImplicitCollectionArgument(TestHost testHost) + { + await TestAsync( +@" +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Text.RegularExpressions; + +class Program +{ + private void M([StringSyntax(StringSyntaxAttribute.Regex)] List p) + { + } + + void Goo() + { + [|M(new() { @""$\a(?#comment)"" });|] + } +}" + EmbeddedLanguagesTestConstants.StringSyntaxAttributeCodeCSharp, +testHost, +Method("M"), +Regex.Anchor("$"), +Regex.OtherEscape("\\"), +Regex.OtherEscape("a"), +Regex.Comment("(?#comment)")); + } + [Theory] [CombinatorialData] public async Task TestRegexOnApiWithStringSyntaxAttribute_Argument_Options(TestHost testHost) @@ -3588,6 +3787,93 @@ class Program Regex.Comment("(?#comment)")); } + [Theory] + [CombinatorialData] + public async Task TestRegexOnApiWithStringSyntaxAttribute_ParamsAttribute(TestHost testHost) + { + await TestAsync( +@" +using System; +using System.Diagnostics.CodeAnalysis; +using System.Text.RegularExpressions; + +[AttributeUsage(AttributeTargets.Field)] +class RegexTestAttribute : Attribute +{ + public RegexTestAttribute([StringSyntax(StringSyntaxAttribute.Regex)] params string[] value) { } +} + +class Program +{ + [|[RegexTest(@""$\a(?#comment)"")]|] + private string field; +}" + EmbeddedLanguagesTestConstants.StringSyntaxAttributeCodeCSharp, +testHost, +Class("RegexTest"), +Regex.Anchor("$"), +Regex.OtherEscape("\\"), +Regex.OtherEscape("a"), +Regex.Comment("(?#comment)")); + } + + [Theory] + [CombinatorialData] + public async Task TestRegexOnApiWithStringSyntaxAttribute_ArrayAttribute(TestHost testHost) + { + await TestAsync( +@" +using System; +using System.Diagnostics.CodeAnalysis; +using System.Text.RegularExpressions; + +[AttributeUsage(AttributeTargets.Field)] +class RegexTestAttribute : Attribute +{ + public RegexTestAttribute([StringSyntax(StringSyntaxAttribute.Regex)] string[] value) { } +} + +class Program +{ + [|[RegexTest(new string[] { @""$\a(?#comment)"" })]|] + private string field; +}" + EmbeddedLanguagesTestConstants.StringSyntaxAttributeCodeCSharp, +testHost, +Class("RegexTest"), +Regex.Anchor("$"), +Regex.OtherEscape("\\"), +Regex.OtherEscape("a"), +Regex.Comment("(?#comment)")); + } + + [Theory] + [CombinatorialData] + public async Task TestRegexOnApiWithStringSyntaxAttribute_ImplicitArrayAttribute(TestHost testHost) + { + await TestAsync( +@" +using System; +using System.Diagnostics.CodeAnalysis; +using System.Text.RegularExpressions; + +[AttributeUsage(AttributeTargets.Field)] +class RegexTestAttribute : Attribute +{ + public RegexTestAttribute([StringSyntax(StringSyntaxAttribute.Regex)] string[] value) { } +} + +class Program +{ + [|[RegexTest(new[] { @""$\a(?#comment)"" })]|] + private string field; +}" + EmbeddedLanguagesTestConstants.StringSyntaxAttributeCodeCSharp, +testHost, +Class("RegexTest"), +Regex.Anchor("$"), +Regex.OtherEscape("\\"), +Regex.OtherEscape("a"), +Regex.Comment("(?#comment)")); + } + [Theory] [CombinatorialData] public async Task TestIncompleteRegexLeadingToStringInsideSkippedTokensInsideADirective(TestHost testHost) @@ -3661,6 +3947,32 @@ void Goo() Json.Comment("// comment")); } + [Theory] + [CombinatorialData] + public async Task TestJson_RawString(TestHost testHost) + { + await TestAsync( +@" +class Program +{ + void Goo() + { + // lang=json + var r = """"""[/*comment*/{ 'goo': 0 }]""""""; + } +}", +testHost, +Keyword("var"), +Json.Array("["), +Json.Comment("/*comment*/"), +Json.Object("{"), +Json.PropertyName("'goo'"), +Json.Punctuation(":"), +Json.Number("0"), +Json.Object("}"), +Json.Array("]")); + } + [Theory] [CombinatorialData] public async Task TestMultiLineJson1(TestHost testHost) @@ -3717,6 +4029,51 @@ void Goo() Json.Comment("// comment")); } + [Theory] + [CombinatorialData] + public async Task TestJson_NoComment_NotLikelyJson(TestHost testHost) + { + var input = @" +class C +{ + void Goo() + { + var r = @""[1, 2, 3]""; + } +}"; + await TestAsync(input, +testHost, +Keyword("var")); + } + + [Theory] + [CombinatorialData] + public async Task TestJson_NoComment_LikelyJson(TestHost testHost) + { + var input = @" +class C +{ + void Goo() + { + var r = @""[1, { prop: 0 }, 3]""; + } +}"; + await TestAsync(input, +testHost, +Keyword("var"), +Json.Array("["), +Json.Number("1"), +Json.Punctuation(","), +Json.Object("{"), +Json.PropertyName("prop"), +Json.Punctuation(":"), +Json.Number("0"), +Json.Object("}"), +Json.Punctuation(","), +Json.Number("3"), +Json.Array("]")); + } + [Theory] [CombinatorialData] public async Task TestJsonOnApiWithStringSyntaxAttribute_Field(TestHost testHost) @@ -3959,6 +4316,68 @@ public async Task TestStringEscape9(TestHost testHost) Escape(@"}}")); } + [Theory] + [CombinatorialData] + public async Task TestNotStringEscapeInRawLiteral1(TestHost testHost) + { + await TestInMethodAsync(@"var goo = """"""goo\r\nbar"""""";", + testHost, + Keyword("var")); + } + + [Theory] + [CombinatorialData] + public async Task TestNotStringEscapeInRawLiteral2(TestHost testHost) + { + await TestInMethodAsync(@"var goo = """""" + goo\r\nbar + """""";", + testHost, + Keyword("var")); + } + + [Theory] + [CombinatorialData] + public async Task TestNotStringEscapeInRawLiteral3(TestHost testHost) + { + await TestInMethodAsync(@"var goo = $"""""" + goo\r\nbar + """""";", + testHost, + Keyword("var")); + } + + [Theory] + [CombinatorialData] + public async Task TestNotStringEscapeInRawLiteral4(TestHost testHost) + { + await TestInMethodAsync(@"var goo = """"""\"""""";", + testHost, + Keyword("var")); + } + + [Theory] + [CombinatorialData] + public async Task TestNotStringEscapeInRawLiteral5(TestHost testHost) + { + await TestInMethodAsync(@"var goo = """""" + \ + """""";", + testHost, + Keyword("var")); + } + + [Theory] + [CombinatorialData] + public async Task TestNotStringEscapeInRawLiteral6(TestHost testHost) + { + await TestInMethodAsync(@"var goo = $"""""" + \ + """""";", + testHost, + Keyword("var")); + } + [WorkItem(31200, "https://github.com/dotnet/roslyn/issues/31200")] [Theory] [CombinatorialData] diff --git a/src/EditorFeatures/CSharpTest/Classification/SyntacticTaggerTests.cs b/src/EditorFeatures/CSharpTest/Classification/SyntacticTaggerTests.cs index b96ffd5624886..8d1135830acc7 100644 --- a/src/EditorFeatures/CSharpTest/Classification/SyntacticTaggerTests.cs +++ b/src/EditorFeatures/CSharpTest/Classification/SyntacticTaggerTests.cs @@ -9,7 +9,7 @@ using System.Diagnostics; using System.Linq; using System.Threading.Tasks; -using Microsoft.CodeAnalysis.Editor.Implementation.Classification; +using Microsoft.CodeAnalysis.Classification; using Microsoft.CodeAnalysis.Editor.Shared.Utilities; using Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces; using Microsoft.CodeAnalysis.Shared.TestHooks; diff --git a/src/EditorFeatures/CSharpTest/Classification/TotalClassifierTests.cs b/src/EditorFeatures/CSharpTest/Classification/TotalClassifierTests.cs index e35789c2a8a28..343c641ab89bd 100644 --- a/src/EditorFeatures/CSharpTest/Classification/TotalClassifierTests.cs +++ b/src/EditorFeatures/CSharpTest/Classification/TotalClassifierTests.cs @@ -2190,5 +2190,107 @@ public async Task TestStringEscape(TestHost testHost) Verbatim("\""), Punctuation.Semicolon); } + + [Theory] + [CombinatorialData] + [WorkItem(55313, "https://github.com/dotnet/roslyn/issues/55313")] + public async Task TestStaticConstructorClass(TestHost testHost) + { + await TestAsync( +@" +class C +{ + static C() { } +}", + testHost, +Keyword("class"), +Class("C"), +Punctuation.OpenCurly, +Keyword("static"), +Class("C"), +Static("C"), +Punctuation.OpenParen, +Punctuation.CloseParen, +Punctuation.OpenCurly, +Punctuation.CloseCurly, +Punctuation.CloseCurly); + } + + [Theory] + [CombinatorialData] + [WorkItem(55313, "https://github.com/dotnet/roslyn/issues/55313")] + public async Task TestStaticConstructorInterface(TestHost testHost) + { + await TestAsync( +@" +interface C +{ + static C() { } +}", + testHost, +Keyword("interface"), +Interface("C"), +Punctuation.OpenCurly, +Keyword("static"), +Interface("C"), +Static("C"), +Punctuation.OpenParen, +Punctuation.CloseParen, +Punctuation.OpenCurly, +Punctuation.CloseCurly, +Punctuation.CloseCurly); + } + + [Theory] + [CombinatorialData] + [WorkItem(59569, "https://github.com/dotnet/roslyn/issues/59569")] + public async Task TestArgsInTopLevel(TestHost testHost) + { + await TestAsync( +@" +[|foreach (var arg in args) +{ +}|]", + testHost, + parseOptions: null, +ControlKeyword("foreach"), +Punctuation.OpenParen, +Keyword("var"), +Local("arg"), +ControlKeyword("in"), +Keyword("args"), +Punctuation.CloseParen, +Punctuation.OpenCurly, +Punctuation.CloseCurly); + } + + [Theory] + [CombinatorialData] + [WorkItem(59569, "https://github.com/dotnet/roslyn/issues/59569")] + public async Task TestArgsInNormalProgram(TestHost testHost) + { + await TestAsync( +@" +class Program +{ + static void Main(string[] args) + { + [|foreach (var arg in args) + { + }|] + } +}", + testHost, + parseOptions: null, +ControlKeyword("foreach"), +Punctuation.OpenParen, +Keyword("var"), +Local("arg"), +ControlKeyword("in"), +Parameter("args"), +Punctuation.CloseParen, +Punctuation.OpenCurly, +Punctuation.CloseCurly); + } } } diff --git a/src/EditorFeatures/CSharpTest/CodeActions/ConvertLinq/ConvertForEachToLinqQueryTests.cs b/src/EditorFeatures/CSharpTest/CodeActions/ConvertLinq/ConvertForEachToLinqQueryTests.cs index a86fa1a4029e1..ab5c7aee6e1ea 100644 --- a/src/EditorFeatures/CSharpTest/CodeActions/ConvertLinq/ConvertForEachToLinqQueryTests.cs +++ b/src/EditorFeatures/CSharpTest/CodeActions/ConvertLinq/ConvertForEachToLinqQueryTests.cs @@ -4324,7 +4324,7 @@ void M(IEnumerable nums) /* 8*/// 9 /* 10 */ where/* 11 *//* 12 */n1 /* 13 */ > /* 14 */ 0/* 15 */// 16 - select n1/* 4 *//* 21 */// 22 + select n1/* 4 *//* 21 */// 22 /*23*//*24*/ ) { diff --git a/src/EditorFeatures/CSharpTest/CodeActions/ConvertLinq/ConvertLinqQueryToForEachTests.cs b/src/EditorFeatures/CSharpTest/CodeActions/ConvertLinq/ConvertLinqQueryToForEachTests.cs index 4d727c363173e..6d79e2d5ae2b3 100644 --- a/src/EditorFeatures/CSharpTest/CodeActions/ConvertLinq/ConvertLinqQueryToForEachTests.cs +++ b/src/EditorFeatures/CSharpTest/CodeActions/ConvertLinq/ConvertLinqQueryToForEachTests.cs @@ -172,13 +172,13 @@ static void Main(string[] args) { System.Collections.Generic.IEnumerable enumerable() { - var vs1 = new int[] { 1, 2 }; - var vs = new int[] { 3, 4 }; - foreach (var num in vs1) + var ints1 = new int[] { 1, 2 }; + var ints = new int[] { 3, 4 }; + foreach (var num in ints1) { foreach (var a in new int[] { 5, 6 }) { - foreach (var x1 in vs) + foreach (var x1 in ints) { if (object.Equals(num, x1)) { @@ -221,18 +221,18 @@ static void Main(string[] args) { System.Collections.Generic.IEnumerable enumerable() { - var vs2 = new int[] { 1, 2 }; - var vs1 = new int[] { 3, 4 }; - var vs = new int[] { 7, 8 }; - foreach (var num in vs2) + var ints2 = new int[] { 1, 2 }; + var ints1 = new int[] { 3, 4 }; + var ints = new int[] { 7, 8 }; + foreach (var num in ints2) { foreach (var a in new int[] { 5, 6 }) { - foreach (var x1 in vs1) + foreach (var x1 in ints1) { if (object.Equals(num, x1)) { - foreach (var x2 in vs) + foreach (var x2 in ints) { if (object.Equals(num, x2)) { diff --git a/src/EditorFeatures/CSharpTest/CodeActions/InlineTemporary/InlineTemporaryTests.cs b/src/EditorFeatures/CSharpTest/CodeActions/InlineTemporary/InlineTemporaryTests.cs index 1d26f92ade343..eccc90cec61fc 100644 --- a/src/EditorFeatures/CSharpTest/CodeActions/InlineTemporary/InlineTemporaryTests.cs +++ b/src/EditorFeatures/CSharpTest/CodeActions/InlineTemporary/InlineTemporaryTests.cs @@ -1368,9 +1368,9 @@ await TestFixOneAsync(@" { int #if true - y, + y, #endif - z; + z; int a = 1; }"); @@ -1395,7 +1395,7 @@ await TestFixOneAsync(@" #if true #endif - z; + z; int a = 1; }"); @@ -1418,9 +1418,9 @@ await TestFixOneAsync(@" { int y, #if true - z + z #endif - ; + ; int a = 1; }"); diff --git a/src/EditorFeatures/CSharpTest/CodeActions/IntroduceVariable/IntroduceVariableTests.cs b/src/EditorFeatures/CSharpTest/CodeActions/IntroduceVariable/IntroduceVariableTests.cs index 3ab4a4831464e..c801cb55216cf 100644 --- a/src/EditorFeatures/CSharpTest/CodeActions/IntroduceVariable/IntroduceVariableTests.cs +++ b/src/EditorFeatures/CSharpTest/CodeActions/IntroduceVariable/IntroduceVariableTests.cs @@ -117,8 +117,8 @@ class C { void M(Action action) { - Action {|Rename:p|} = () => { var x[||] = y; }; - M(p); + Action {|Rename:value|} = () => { var x[||] = y; }; + M(value); } }"); } @@ -1450,8 +1450,8 @@ void Main() { void Main() { - var {|Rename:p|} = new { A = 0 }; - var a = p; + var {|Rename:value|} = new { A = 0 }; + var a = value; } }"); } @@ -1474,8 +1474,8 @@ static void Main(string[] args) static void Main(string[] args) { int[] a = null; - var {|Rename:vs|} = a = new[] { 1, 2, 3 }; - int[] temp = checked(vs); + var {|Rename:ints|} = a = new[] { 1, 2, 3 }; + int[] temp = checked(ints); } }", options: ImplicitTypingEverywhere()); @@ -1516,8 +1516,8 @@ void Main() { void Main() { - var {|Rename:p|} = new { X = 1 }; - WriteLine(p); + var {|Rename:value|} = new { X = 1 }; + WriteLine(value); } }"); } @@ -2567,8 +2567,8 @@ static void Main(string[] args) { Func> f = x => { - Func {|Rename:p|} = y => y + 1; - return p; + Func {|Rename:value|} = y => y + 1; + return value; }; } }"); @@ -2596,8 +2596,8 @@ static void Main(string[] args) { Func> f = x => { - Func {|Rename:p|} = y => x + 1; - return p; + Func {|Rename:value|} = y => x + 1; + return value; }; } }"); @@ -3060,7 +3060,7 @@ void Goo() void Goo() { var {|Rename:v|} = int.Parse(""12345""); - var s = $""Alpha Beta { v } Gamma""; + var s = $""Alpha Beta {v} Gamma""; } }"; @@ -4964,8 +4964,8 @@ public async Task Tuple_TuplesDisabled() var expected = @"class C { - private static readonly (int, string) {|Rename:p|} = (1, ""hello""); - var i = p.ToString(); + private static readonly (int, string) {|Rename:value|} = (1, ""hello""); + var i = value.ToString(); }"; await TestAsync(code, expected, parseOptions: TestOptions.Regular.WithLanguageVersion(LanguageVersion.CSharp6)); @@ -5003,8 +5003,8 @@ public async Task Tuple_IntroduceConstant() var expected = @"class C { - private static readonly (int, string) {|Rename:p|} = (1, ""hello""); - var i = p.ToString(); + private static readonly (int, string) {|Rename:value|} = (1, ""hello""); + var i = value.ToString(); }"; await TestInRegularAndScriptAsync(code, expected); @@ -5022,8 +5022,8 @@ public async Task TupleWithNames_IntroduceConstant() var expected = @"class C { - private static readonly (int a, string b) {|Rename:p|} = (a: 1, b: ""hello""); - var i = p.ToString(); + private static readonly (int a, string b) {|Rename:value|} = (a: 1, b: ""hello""); + var i = value.ToString(); }"; await TestInRegularAndScriptAsync(code, expected); @@ -5041,8 +5041,8 @@ public async Task Tuple_IntroduceConstantForAllOccurrences() var expected = @"class C { - private static readonly (int, string) {|Rename:p|} = (1, ""hello""); - var i = p.ToString() + p.ToString(); + private static readonly (int, string) {|Rename:value|} = (1, ""hello""); + var i = value.ToString() + value.ToString(); }"; await TestInRegularAndScriptAsync(code, expected, index: 1); @@ -5060,8 +5060,8 @@ public async Task TupleWithNames_IntroduceConstantForAllOccurrences() var expected = @"class C { - private static readonly (int a, string b) {|Rename:p|} = (a: 1, b: ""hello""); - var i = p.ToString() + p.ToString(); + private static readonly (int a, string b) {|Rename:value|} = (a: 1, b: ""hello""); + var i = value.ToString() + value.ToString(); }"; await TestInRegularAndScriptAsync(code, expected, index: 1); @@ -5079,8 +5079,8 @@ public async Task TupleWithDifferentNames_IntroduceConstantForAllOccurrences() var expected = @"class C { - private static readonly (int a, string b) {|Rename:p|} = (a: 1, b: ""hello""); - var i = p.ToString() + (c: 1, d: ""hello"").ToString(); + private static readonly (int a, string b) {|Rename:value|} = (a: 1, b: ""hello""); + var i = value.ToString() + (c: 1, d: ""hello"").ToString(); }"; await TestInRegularAndScriptAsync(code, expected, index: 1); @@ -5098,8 +5098,8 @@ public async Task TupleWithOneName_IntroduceConstantForAllOccurrences() var expected = @"class C { - private static readonly (int a, string) {|Rename:p|} = (a: 1, ""hello""); - var i = p.ToString() + p.ToString(); + private static readonly (int a, string) {|Rename:value|} = (a: 1, ""hello""); + var i = value.ToString() + value.ToString(); }"; await TestInRegularAndScriptAsync(code, expected, index: 1); @@ -6074,8 +6074,8 @@ class C byte[] getArray() => null; void test() { - byte[] {|Rename:vs|} = getArray(); - var goo = vs[0]; + byte[] {|Rename:bytes|} = getArray(); + var goo = bytes[0]; } }"); } diff --git a/src/EditorFeatures/CSharpTest/CodeActions/Preview/PreviewExceptionTests.cs b/src/EditorFeatures/CSharpTest/CodeActions/Preview/PreviewExceptionTests.cs index 0279cde48884d..c9cb8ab98b1dd 100644 --- a/src/EditorFeatures/CSharpTest/CodeActions/Preview/PreviewExceptionTests.cs +++ b/src/EditorFeatures/CSharpTest/CodeActions/Preview/PreviewExceptionTests.cs @@ -13,6 +13,7 @@ using Microsoft.CodeAnalysis.Editor.Implementation.Suggestions; using Microsoft.CodeAnalysis.Editor.Shared.Utilities; using Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces; +using Microsoft.CodeAnalysis.ErrorReporting; using Microsoft.CodeAnalysis.Extensions; using Microsoft.CodeAnalysis.Test.Utilities; using Microsoft.CodeAnalysis.Text; diff --git a/src/EditorFeatures/CSharpTest/CodeActions/ReplaceMethodWithProperty/ReplaceMethodWithPropertyTests.cs b/src/EditorFeatures/CSharpTest/CodeActions/ReplaceMethodWithProperty/ReplaceMethodWithPropertyTests.cs index 91eb93138bfea..c716feadef23c 100644 --- a/src/EditorFeatures/CSharpTest/CodeActions/ReplaceMethodWithProperty/ReplaceMethodWithPropertyTests.cs +++ b/src/EditorFeatures/CSharpTest/CodeActions/ReplaceMethodWithProperty/ReplaceMethodWithPropertyTests.cs @@ -1937,7 +1937,7 @@ int Goo get { throw e + - e; + e; } } }", options: new OptionsCollection(GetLanguage()) diff --git a/src/EditorFeatures/CSharpTest/CodeRefactorings/UseRecursivePatterns/UseRecursivePatternsRefactoringTests.cs b/src/EditorFeatures/CSharpTest/CodeRefactorings/UseRecursivePatterns/UseRecursivePatternsRefactoringTests.cs index d72e97c3e8ab5..5eacb7a1a6708 100644 --- a/src/EditorFeatures/CSharpTest/CodeRefactorings/UseRecursivePatterns/UseRecursivePatternsRefactoringTests.cs +++ b/src/EditorFeatures/CSharpTest/CodeRefactorings/UseRecursivePatterns/UseRecursivePatternsRefactoringTests.cs @@ -17,11 +17,15 @@ namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.CodeRefactorings.UseRec [Trait(Traits.Feature, Traits.Features.CodeActionsUseRecursivePatterns)] public class UseRecursivePatternsRefactoringTests { - private static Task VerifyAsync(string initialMarkup, string expectedMarkup, bool skipCodeActionValidation = false) + private static Task VerifyAsync( + string initialMarkup, + string expectedMarkup, + bool skipCodeActionValidation = false, + LanguageVersion languageVersion = LanguageVersion.CSharp9) { return new VerifyCS.Test { - LanguageVersion = LanguageVersion.CSharp9, + LanguageVersion = languageVersion, TestCode = initialMarkup, FixedCode = expectedMarkup, CodeActionValidationMode = skipCodeActionValidation @@ -72,6 +76,15 @@ private static Task VerifyMissingAsync(string initialMarkup) [InlineData("a?.b?.c.d && b", "this is { a: { b: { c: { d: n } } }, b: n }")] [InlineData("a?.b?.c?.d && b", "this is { a: { b: { c: { d: n } } }, b: n }")] + [InlineData("a.b.c.d && b", "this is { a.b.c.d: n, b: n }", LanguageVersion.CSharp10)] + [InlineData("a?.b.c.d && b", "this is { a.b.c.d: n, b: n }", LanguageVersion.CSharp10)] + [InlineData("a.b?.c.d && b", "this is { a.b.c.d: n, b: n }", LanguageVersion.CSharp10)] + [InlineData("a.b.c?.d && b", "this is { a.b.c.d: n, b: n }", LanguageVersion.CSharp10)] + [InlineData("a.b?.c?.d && b", "this is { a.b.c.d: n, b: n }", LanguageVersion.CSharp10)] + [InlineData("a?.b.c?.d && b", "this is { a.b.c.d: n, b: n }", LanguageVersion.CSharp10)] + [InlineData("a?.b?.c.d && b", "this is { a.b.c.d: n, b: n }", LanguageVersion.CSharp10)] + [InlineData("a?.b?.c?.d && b", "this is { a.b.c.d: n, b: n }", LanguageVersion.CSharp10)] + [InlineData("a.b.m().d && a.b.m().a", "a.b.m() is { d: n, a: n }")] [InlineData("a.m().c.d && a.m().a", "a.m() is { c: { d: n }, a: n }")] [InlineData("a?.m().c.d && a?.m().a", "a?.m() is { c: { d: n }, a: n }")] @@ -81,9 +94,9 @@ private static Task VerifyMissingAsync(string initialMarkup) [InlineData("a?.m().c?.d && a?.m().a", "a?.m() is { c: { d: n }, a: n }")] [InlineData("a?.m()?.c.d && a?.m().a", "a?.m() is { c: { d: n }, a: n }")] [InlineData("a?.m()?.c?.d && a?.m().a", "a?.m() is { c: { d: n }, a: n }")] - public async Task TestLogicalAndExpression_Receiver(string actual, string expected) + public async Task TestLogicalAndExpression_Receiver(string actual, string expected, LanguageVersion languageVersion = LanguageVersion.CSharp9) { - await VerifyAsync(WrapInIfStatement("n == " + actual + " == n", "&&"), WrapInIfStatement(expected)); + await VerifyAsync(WrapInIfStatement("n == " + actual + " == n", "&&"), WrapInIfStatement(expected), languageVersion: languageVersion); } [Theory] diff --git a/src/EditorFeatures/CSharpTest/CommentSelection/CSharpCommentSelectionTests.cs b/src/EditorFeatures/CSharpTest/CommentSelection/CSharpCommentSelectionTests.cs index 4583c3792e712..dd3958e5036d8 100644 --- a/src/EditorFeatures/CSharpTest/CommentSelection/CSharpCommentSelectionTests.cs +++ b/src/EditorFeatures/CSharpTest/CommentSelection/CSharpCommentSelectionTests.cs @@ -7,7 +7,7 @@ using System.Collections.Generic; using System.Linq; using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.Editor.Implementation.CommentSelection; +using Microsoft.CodeAnalysis.CommentSelection; using Microsoft.CodeAnalysis.Editor.UnitTests.Utilities; using Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces; using Microsoft.CodeAnalysis.Test.Utilities; diff --git a/src/EditorFeatures/CSharpTest/CommentSelection/CSharpToggleBlockCommentCommandHandlerTests.cs b/src/EditorFeatures/CSharpTest/CommentSelection/CSharpToggleBlockCommentCommandHandlerTests.cs index aa3b343d0d81a..46cb4646e2091 100644 --- a/src/EditorFeatures/CSharpTest/CommentSelection/CSharpToggleBlockCommentCommandHandlerTests.cs +++ b/src/EditorFeatures/CSharpTest/CommentSelection/CSharpToggleBlockCommentCommandHandlerTests.cs @@ -6,8 +6,8 @@ using System; using System.Linq; +using Microsoft.CodeAnalysis.CommentSelection; using Microsoft.CodeAnalysis.Editor.CSharp.CommentSelection; -using Microsoft.CodeAnalysis.Editor.Implementation.CommentSelection; using Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces; using Microsoft.CodeAnalysis.Test.Utilities; using Microsoft.CodeAnalysis.Test.Utilities.CommentSelection; diff --git a/src/EditorFeatures/CSharpTest/CommentSelection/CSharpToggleLineCommentCommandHandlerTests.cs b/src/EditorFeatures/CSharpTest/CommentSelection/CSharpToggleLineCommentCommandHandlerTests.cs index 8aeecd61b933c..586a9090d4760 100644 --- a/src/EditorFeatures/CSharpTest/CommentSelection/CSharpToggleLineCommentCommandHandlerTests.cs +++ b/src/EditorFeatures/CSharpTest/CommentSelection/CSharpToggleLineCommentCommandHandlerTests.cs @@ -6,7 +6,7 @@ using System; using System.Linq; -using Microsoft.CodeAnalysis.Editor.Implementation.CommentSelection; +using Microsoft.CodeAnalysis.CommentSelection; using Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces; using Microsoft.CodeAnalysis.Test.Utilities; using Microsoft.CodeAnalysis.Test.Utilities.CommentSelection; diff --git a/src/EditorFeatures/CSharpTest/CompleteStatement/CSharpCompleteStatementCommandHandlerTests.cs b/src/EditorFeatures/CSharpTest/CompleteStatement/CSharpCompleteStatementCommandHandlerTests.cs index 2cbd4e5a2ac15..b5b127512bf97 100644 --- a/src/EditorFeatures/CSharpTest/CompleteStatement/CSharpCompleteStatementCommandHandlerTests.cs +++ b/src/EditorFeatures/CSharpTest/CompleteStatement/CSharpCompleteStatementCommandHandlerTests.cs @@ -1994,6 +1994,43 @@ public string Name VerifyNoSpecialSemicolonHandling(code); } + [WpfFact, Trait(Traits.Feature, Traits.Features.CompleteStatement)] + public void PropertyInitializer1() + { + var code = @" +public class C +{ + public static C MyProp { get; } = new C($$) +}"; + + var expected = @" +public class C +{ + public static C MyProp { get; } = new C();$$ +}"; + + VerifyTypingSemicolon(code, expected); + } + + [WpfFact, Trait(Traits.Feature, Traits.Features.CompleteStatement)] + public void PropertyAttribute1() + { + var code = @" +public class C +{ + public int P + { + [My(typeof(C$$))] + get + { + return 0; + } + } +}"; + + VerifyNoSpecialSemicolonHandling(code); + } + #endregion #region ParenthesizeExpression diff --git a/src/EditorFeatures/CSharpTest/Completion/CompletionProviders/AwaitCompletionProviderTests.cs b/src/EditorFeatures/CSharpTest/Completion/CompletionProviders/AwaitCompletionProviderTests.cs index 9a807f476f1e9..02dcf0f805cc6 100644 --- a/src/EditorFeatures/CSharpTest/Completion/CompletionProviders/AwaitCompletionProviderTests.cs +++ b/src/EditorFeatures/CSharpTest/Completion/CompletionProviders/AwaitCompletionProviderTests.cs @@ -897,5 +897,23 @@ public static async Task Main(params string[] args) }} ", dotAwait: true, dotAwaitf: true); } + + [Theory, CombinatorialData] + [WorkItem(58921, "https://github.com/dotnet/roslyn/issues/58921")] + public async Task TestInCastExpressionThatMightBeParenthesizedExpression(bool hasNewline) + { + var code = $@" +class C +{{ + void M() + {{ + var data = (n$$) {(hasNewline ? Environment.NewLine : string.Empty)} M(); + }} +}}"; + if (hasNewline) + await VerifyKeywordAsync(code); + else + await VerifyAbsenceAsync(code); + } } } diff --git a/src/EditorFeatures/CSharpTest/Completion/CompletionProviders/DeclarationNameCompletionProviderTests.cs b/src/EditorFeatures/CSharpTest/Completion/CompletionProviders/DeclarationNameCompletionProviderTests.cs index db26e17132aa7..66f70c8b796df 100644 --- a/src/EditorFeatures/CSharpTest/Completion/CompletionProviders/DeclarationNameCompletionProviderTests.cs +++ b/src/EditorFeatures/CSharpTest/Completion/CompletionProviders/DeclarationNameCompletionProviderTests.cs @@ -8,7 +8,6 @@ using System.Collections.Immutable; using System.Linq; using System.Threading.Tasks; -using Microsoft.CodeAnalysis.Completion; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Completion.Providers; using Microsoft.CodeAnalysis.Diagnostics.Analyzers.NamingStyles; @@ -691,6 +690,28 @@ void InnerGoo(DbContext $$) { } } } + [Fact, Trait(Traits.Feature, Traits.Features.Completion)] + [WorkItem(36248, "https://github.com/dotnet/roslyn/issues/36248")] + public async Task Parameter13() + { + using var workspaceFixture = GetOrCreateWorkspaceFixture(); + + var workspace = workspaceFixture.Target.GetWorkspace(ExportProvider); + workspace.TryApplyChanges(workspace.CurrentSolution.WithOptions(workspace.Options.WithChangedOption( + new OptionKey2(NamingStyleOptions.NamingPreferences, LanguageNames.CSharp), + ParameterCamelCaseWithPascalCaseFallback()))); + + var markup = @" +using System.Threading; +public class C +{ + void Goo(CancellationToken $$ +} +"; + await VerifyItemExistsAsync(markup, "cancellationToken", glyph: (int)Glyph.Parameter); + await VerifyItemIsAbsentAsync(markup, "CancellationToken"); + } + [Fact, Trait(Traits.Feature, Traits.Features.Completion)] [WorkItem(52534, "https://github.com/dotnet/roslyn/issues/52534")] public async Task SuggestParameterNamesFromExistingOverloads() @@ -2149,6 +2170,7 @@ public void Method() } [WorkItem(1220195, "https://developercommunity2.visualstudio.com/t/Regression-from-1675-Suggested-varia/1220195")] + [WorkItem(36364, "https://github.com/dotnet/roslyn/issues/36364")] [Fact, Trait(Traits.Feature, Traits.Features.Completion)] public async Task TypeIsNullableStructInLocalWithNullableTypeName() { @@ -2165,10 +2187,11 @@ public void Method() } } "; - await VerifyItemExistsAsync(markup, "vs"); + await VerifyItemExistsAsync(markup, "ints"); } [WorkItem(1220195, "https://developercommunity2.visualstudio.com/t/Regression-from-1675-Suggested-varia/1220195")] + [WorkItem(36364, "https://github.com/dotnet/roslyn/issues/36364")] [Fact, Trait(Traits.Feature, Traits.Features.Completion)] public async Task TypeIsNullableStructInLocalWithQuestionMark() { @@ -2185,10 +2208,11 @@ public void Method() } } "; - await VerifyItemExistsAsync(markup, "vs"); + await VerifyItemExistsAsync(markup, "ints"); } [WorkItem(1220195, "https://developercommunity2.visualstudio.com/t/Regression-from-1675-Suggested-varia/1220195")] + [WorkItem(36364, "https://github.com/dotnet/roslyn/issues/36364")] [Fact, Trait(Traits.Feature, Traits.Features.Completion)] public async Task TypeIsNullableReferenceInLocal() { @@ -2205,10 +2229,11 @@ public void Method() } } "; - await VerifyItemExistsAsync(markup, "vs"); + await VerifyItemExistsAsync(markup, "ints"); } [WorkItem(1220195, "https://developercommunity2.visualstudio.com/t/Regression-from-1675-Suggested-varia/1220195")] + [WorkItem(36364, "https://github.com/dotnet/roslyn/issues/36364")] [Fact, Trait(Traits.Feature, Traits.Features.Completion)] public async Task TypeIsNullableStructInParameterWithNullableTypeName() { @@ -2224,10 +2249,11 @@ public void Method(Nullable> $$) } } "; - await VerifyItemExistsAsync(markup, "vs"); + await VerifyItemExistsAsync(markup, "ints"); } [WorkItem(1220195, "https://developercommunity2.visualstudio.com/t/Regression-from-1675-Suggested-varia/1220195")] + [WorkItem(36364, "https://github.com/dotnet/roslyn/issues/36364")] [Fact, Trait(Traits.Feature, Traits.Features.Completion)] public async Task TypeIsNullableStructInParameterWithQuestionMark() { @@ -2241,10 +2267,11 @@ public void Method(ImmutableArray? $$) } } "; - await VerifyItemExistsAsync(markup, "vs"); + await VerifyItemExistsAsync(markup, "ints"); } [WorkItem(1220195, "https://developercommunity2.visualstudio.com/t/Regression-from-1675-Suggested-varia/1220195")] + [WorkItem(36364, "https://github.com/dotnet/roslyn/issues/36364")] [Fact, Trait(Traits.Feature, Traits.Features.Completion)] public async Task TypeIsNullableReferenceInParameter() { @@ -2260,7 +2287,126 @@ public void Method(IEnumerable? $$) } } "; - await VerifyItemExistsAsync(markup, "vs"); + await VerifyItemExistsAsync(markup, "ints"); + } + + [WorkItem(36364, "https://github.com/dotnet/roslyn/issues/36364")] + [Fact, Trait(Traits.Feature, Traits.Features.Completion)] + public async Task EnumerableParameterOfUnmanagedType() + { + var markup = @" +using System.Collections.Generic; + +public class Class1 +{ + public void Method(IEnumerable $$) + { + } +} +"; + await VerifyItemExistsAsync(markup, "ints"); + } + + [WorkItem(36364, "https://github.com/dotnet/roslyn/issues/36364")] + [Fact, Trait(Traits.Feature, Traits.Features.Completion)] + public async Task EnumerableParameterOfObject() + { + var markup = @" +using System.Collections.Generic; + +public class Class1 +{ + public void Method(IEnumerable $$) + { + } +} +"; + await VerifyItemExistsAsync(markup, "objects"); + } + + [WorkItem(36364, "https://github.com/dotnet/roslyn/issues/36364")] + [Fact, Trait(Traits.Feature, Traits.Features.Completion)] + public async Task EnumerableParameterOfString() + { + var markup = @" +using System.Collections.Generic; + +public class Class1 +{ + public void Method(IEnumerable $$) + { + } +} +"; + await VerifyItemExistsAsync(markup, "strings"); + } + + [WorkItem(36364, "https://github.com/dotnet/roslyn/issues/36364")] + [Fact, Trait(Traits.Feature, Traits.Features.Completion)] + public async Task EnumerableGenericTParameter() + { + var markup = @" +using System.Collections.Generic; + +public class Class1 +{ + public void Method(IEnumerable $$) + { + } +} +"; + await VerifyItemExistsAsync(markup, "values"); + } + + [WorkItem(36364, "https://github.com/dotnet/roslyn/issues/36364")] + [Fact, Trait(Traits.Feature, Traits.Features.Completion)] + public async Task EnumerableGenericTNameParameter() + { + var markup = @" +using System.Collections.Generic; + +public class Class1 +{ + public void Method(IEnumerable $$) + { + } +} +"; + await VerifyItemExistsAsync(markup, "results"); + } + + [WorkItem(36364, "https://github.com/dotnet/roslyn/issues/36364")] + [Fact, Trait(Traits.Feature, Traits.Features.Completion)] + public async Task EnumerableGenericUnexpectedlyNamedParameter() + { + var markup = @" +using System.Collections.Generic; + +public class Class1 +{ + public void Method(IEnumerable $$) + { + } +} +"; + await VerifyItemExistsAsync(markup, "args"); + } + + [WorkItem(36364, "https://github.com/dotnet/roslyn/issues/36364")] + [Fact, Trait(Traits.Feature, Traits.Features.Completion)] + public async Task EnumerableGenericUnexpectedlyNamedParameterBeginsWithT() + { + var markup = @" +using System.Collections.Generic; + +public class Class1 +{ + public void Method(IEnumerable $$) + { + } +} +"; + await VerifyItemExistsAsync(markup, "types"); } [Fact, Trait(Traits.Feature, Traits.Features.Completion)] @@ -2800,6 +2946,44 @@ private static NamingStylePreferences NamesEndWithSuffixPreferences() } } + private static NamingStylePreferences ParameterCamelCaseWithPascalCaseFallback() + { + var symbolSpecifications = ImmutableArray.Create( + new SymbolSpecification( + id: Guid.NewGuid(), + symbolSpecName: "parameters", + ImmutableArray.Create(new SymbolKindOrTypeKind(SymbolKind.Parameter)), + accessibilityList: default, + modifiers: default), + new SymbolSpecification( + id: Guid.NewGuid(), + symbolSpecName: "fallback", + ImmutableArray.Create(new SymbolKindOrTypeKind(SymbolKind.Parameter), new SymbolKindOrTypeKind(SymbolKind.Local)), + accessibilityList: default, + modifiers: default)); + var namingStyles = ImmutableArray.Create( + new NamingStyle( + Guid.NewGuid(), + name: "parameter", + capitalizationScheme: Capitalization.CamelCase, + prefix: "", + suffix: "", + wordSeparator: ""), + new NamingStyle( + Guid.NewGuid(), + name: "any_symbol", + capitalizationScheme: Capitalization.PascalCase, + prefix: "", + suffix: "", + wordSeparator: "")); + return new NamingStylePreferences( + symbolSpecifications, + namingStyles, + namingRules: ImmutableArray.Create( + CreateRule(symbolSpecifications[0], namingStyles[0]), + CreateRule(symbolSpecifications[1], namingStyles[1]))); + } + private static SerializableNamingRule CreateRule(SymbolSpecification specification, NamingStyle style) { return new SerializableNamingRule() diff --git a/src/EditorFeatures/CSharpTest/Completion/CompletionProviders/KeywordCompletionProviderTests.cs b/src/EditorFeatures/CSharpTest/Completion/CompletionProviders/KeywordCompletionProviderTests.cs index de1176e685356..d14fa2d8ddba7 100644 --- a/src/EditorFeatures/CSharpTest/Completion/CompletionProviders/KeywordCompletionProviderTests.cs +++ b/src/EditorFeatures/CSharpTest/Completion/CompletionProviders/KeywordCompletionProviderTests.cs @@ -2,8 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -#nullable disable - using System; using System.Threading.Tasks; using Microsoft.CodeAnalysis.Completion; @@ -540,5 +538,83 @@ public async Task SuggestReadonlyMethodInStruct() "; await VerifyItemExistsAsync(markup, "readonly"); } + + [WorkItem(58921, "https://github.com/dotnet/roslyn/issues/58921")] + [Theory, CombinatorialData, Trait(Traits.Feature, Traits.Features.KeywordRecommending)] + public async Task TestInCastExpressionThatMightBeParenthesizedExpression1(bool hasNewline) + { + + var markup = +$@" +class C +{{ + void M() + {{ + var data = (n$$) { (hasNewline ? Environment.NewLine : string.Empty) } M(); + }} +}}"; + + if (hasNewline) + { + await VerifyItemExistsAsync(markup, "new"); + await VerifyItemExistsAsync(markup, "this"); + await VerifyItemExistsAsync(markup, "null"); + await VerifyItemExistsAsync(markup, "base"); + await VerifyItemExistsAsync(markup, "true"); + await VerifyItemExistsAsync(markup, "false"); + await VerifyItemExistsAsync(markup, "typeof"); + await VerifyItemExistsAsync(markup, "sizeof"); + await VerifyItemExistsAsync(markup, "nameof"); + } + else + { + await VerifyItemIsAbsentAsync(markup, "new"); + await VerifyItemIsAbsentAsync(markup, "this"); + await VerifyItemIsAbsentAsync(markup, "null"); + await VerifyItemIsAbsentAsync(markup, "base"); + await VerifyItemIsAbsentAsync(markup, "true"); + await VerifyItemIsAbsentAsync(markup, "false"); + await VerifyItemIsAbsentAsync(markup, "typeof"); + await VerifyItemIsAbsentAsync(markup, "sizeof"); + await VerifyItemIsAbsentAsync(markup, "nameof"); + } + } + + [Theory, CombinatorialData, Trait(Traits.Feature, Traits.Features.KeywordRecommending)] + [WorkItem(57886, "https://github.com/dotnet/roslyn/issues/57886")] + public async Task TestInCastExpressionThatMightBeParenthesizedExpression2(bool hasExpression) + { + + var markup = +$@"class C +{{ + bool Prop => (t$$) { (hasExpression ? "n" : string.Empty) } + private int n; +}}"; + if (hasExpression) + { + await VerifyItemIsAbsentAsync(markup, "new"); + await VerifyItemIsAbsentAsync(markup, "this"); + await VerifyItemIsAbsentAsync(markup, "null"); + await VerifyItemIsAbsentAsync(markup, "base"); + await VerifyItemIsAbsentAsync(markup, "true"); + await VerifyItemIsAbsentAsync(markup, "false"); + await VerifyItemIsAbsentAsync(markup, "typeof"); + await VerifyItemIsAbsentAsync(markup, "sizeof"); + await VerifyItemIsAbsentAsync(markup, "nameof"); + } + else + { + await VerifyItemExistsAsync(markup, "new"); + await VerifyItemExistsAsync(markup, "this"); + await VerifyItemExistsAsync(markup, "null"); + await VerifyItemExistsAsync(markup, "base"); + await VerifyItemExistsAsync(markup, "true"); + await VerifyItemExistsAsync(markup, "false"); + await VerifyItemExistsAsync(markup, "typeof"); + await VerifyItemExistsAsync(markup, "sizeof"); + await VerifyItemExistsAsync(markup, "nameof"); + } + } } } diff --git a/src/EditorFeatures/CSharpTest/Completion/CompletionProviders/SymbolCompletionProviderTests.cs b/src/EditorFeatures/CSharpTest/Completion/CompletionProviders/SymbolCompletionProviderTests.cs index b01ce9c32bc6b..44a98dc4fc70a 100644 --- a/src/EditorFeatures/CSharpTest/Completion/CompletionProviders/SymbolCompletionProviderTests.cs +++ b/src/EditorFeatures/CSharpTest/Completion/CompletionProviders/SymbolCompletionProviderTests.cs @@ -2215,6 +2215,69 @@ void M(String parameter) await VerifyItemIsAbsentAsync(markup, "parameter"); } + [Fact, Trait(Traits.Feature, Traits.Features.Completion)] + [WorkItem(35178, "https://github.com/dotnet/roslyn/issues/35178")] + public async Task RefStructMembersEmptyByDefault() + { + var markup = @" +ref struct Test {} +class C +{ + void M() + { + var test = new Test(); + test.$$ + } +} +"; + await VerifyNoItemsExistAsync(markup); + } + + [Fact, Trait(Traits.Feature, Traits.Features.Completion)] + [WorkItem(35178, "https://github.com/dotnet/roslyn/issues/35178")] + public async Task RefStructMembersHasMethodIfItWasOverriden() + { + var markup = @" +ref struct Test +{ + public override string ToString() => string.Empty; +} +class C +{ + void M() + { + var test = new Test(); + test.$$ + } +} +"; + await VerifyItemExistsAsync(markup, "ToString"); + await VerifyItemIsAbsentAsync(markup, "GetType"); + await VerifyItemIsAbsentAsync(markup, "Equals"); + await VerifyItemIsAbsentAsync(markup, "GetHashCode"); + } + + [Fact, Trait(Traits.Feature, Traits.Features.Completion)] + [WorkItem(35178, "https://github.com/dotnet/roslyn/issues/35178")] + public async Task RefStructMembersHasMethodsForNameof() + { + var markup = @" +ref struct Test {} +class C +{ + void M() + { + var test = new Test(); + _ = nameof(test.$$); + } +} +"; + await VerifyItemExistsAsync(markup, "ToString"); + await VerifyItemExistsAsync(markup, "GetType"); + await VerifyItemExistsAsync(markup, "Equals"); + await VerifyItemExistsAsync(markup, "GetHashCode"); + } + [Fact, Trait(Traits.Feature, Traits.Features.Completion)] [WorkItem(53585, "https://github.com/dotnet/roslyn/issues/53585")] public async Task AfterStaticLocalFunction_TypeOnly() @@ -11532,5 +11595,342 @@ void M(T x) where T : I1, I2 await VerifyItemExistsAsync(source, "P1"); await VerifyItemExistsAsync(source, "E1"); } + + [Fact, Trait(Traits.Feature, Traits.Features.Completion)] + [WorkItem(58081, "https://github.com/dotnet/roslyn/issues/58081")] + public async Task CompletionOnPointerParameter() + { + var source = @" +struct TestStruct +{ + public int X; + public int Y { get; } + public void Method() { } +} + +unsafe class Test +{ + void TestMethod(TestStruct* a) + { + a->$$ + } +} +"; + await VerifyItemExistsAsync(source, "X"); + await VerifyItemExistsAsync(source, "Y"); + await VerifyItemExistsAsync(source, "Method"); + await VerifyItemExistsAsync(source, "ToString"); + } + + [Fact, Trait(Traits.Feature, Traits.Features.Completion)] + [WorkItem(58081, "https://github.com/dotnet/roslyn/issues/58081")] + public async Task CompletionOnAwaitedPointerParameter() + { + var source = @" +struct TestStruct +{ + public int X; + public int Y { get; } + public void Method() { } +} + +unsafe class Test +{ + async void TestMethod(TestStruct* a) + { + await a->$$ + } +} +"; + await VerifyItemExistsAsync(source, "X"); + await VerifyItemExistsAsync(source, "Y"); + await VerifyItemExistsAsync(source, "Method"); + await VerifyItemExistsAsync(source, "ToString"); + } + + [Fact, Trait(Traits.Feature, Traits.Features.Completion)] + [WorkItem(58081, "https://github.com/dotnet/roslyn/issues/58081")] + public async Task CompletionOnLambdaPointerParameter() + { + var source = @" +struct TestStruct +{ + public int X; + public int Y { get; } + public void Method() { } +} + +unsafe class Test +{ + delegate void TestLambda(TestStruct* a); + + TestLambda TestMethod() + { + return a => a->$$ + } +} +"; + await VerifyItemExistsAsync(source, "X"); + await VerifyItemExistsAsync(source, "Y"); + await VerifyItemExistsAsync(source, "Method"); + await VerifyItemExistsAsync(source, "ToString"); + } + + [Fact, Trait(Traits.Feature, Traits.Features.Completion)] + [WorkItem(58081, "https://github.com/dotnet/roslyn/issues/58081")] + public async Task CompletionOnOverloadedLambdaPointerParameter() + { + + var source = @" +struct TestStruct1 +{ + public int X; +} + +struct TestStruct2 +{ + public int Y; +} + +unsafe class Test +{ + delegate void TestLambda1(TestStruct1* a); + delegate void TestLambda2(TestStruct2* a); + + void Overloaded(TestLambda1 lambda) + { + } + + void Overloaded(TestLambda2 lambda) + { + } + + void TestMethod() + => Overloaded(a => a->$$); +} +"; + await VerifyItemExistsAsync(source, "X"); + await VerifyItemExistsAsync(source, "Y"); + } + + [Fact, Trait(Traits.Feature, Traits.Features.Completion)] + [WorkItem(58081, "https://github.com/dotnet/roslyn/issues/58081")] + public async Task CompletionOnOverloadedLambdaPointerParameterWithExplicitType() + { + + var source = @" +struct TestStruct1 +{ + public int X; +} + +struct TestStruct2 +{ + public int Y; +} + +unsafe class Test +{ + delegate void TestLambda1(TestStruct1* a); + delegate void TestLambda2(TestStruct2* a); + + void Overloaded(TestLambda1 lambda) + { + } + + void Overloaded(TestLambda2 lambda) + { + } + + void TestMethod() + => Overloaded((TestStruct1* a) => a->$$); +} +"; + await VerifyItemExistsAsync(source, "X"); + await VerifyItemIsAbsentAsync(source, "Y"); + } + + [Fact, Trait(Traits.Feature, Traits.Features.Completion)] + [WorkItem(58081, "https://github.com/dotnet/roslyn/issues/58081")] + public async Task CompletionOnPointerParameterWithSimpleMemberAccess() + { + var source = @" +struct TestStruct +{ + public int X; + public int Y { get; } + public void Method() { } +} + +unsafe class Test +{ + void TestMethod(TestStruct* a) + { + a.$$ + } +} +"; + await VerifyItemIsAbsentAsync(source, "X"); + } + + [Fact, Trait(Traits.Feature, Traits.Features.Completion)] + [WorkItem(58081, "https://github.com/dotnet/roslyn/issues/58081")] + public async Task CompletionOnOverloadedLambdaPointerParameterWithSimpleMemberAccess() + { + + var source = @" +struct TestStruct1 +{ + public int X; +} + +struct TestStruct2 +{ + public int Y; +} + +unsafe class Test +{ + delegate void TestLambda1(TestStruct1* a); + delegate void TestLambda2(TestStruct2* a); + + void Overloaded(TestLambda1 lambda) + { + } + + void Overloaded(TestLambda2 lambda) + { + } + + void TestMethod() + => Overloaded(a => a.$$); +} +"; + await VerifyItemIsAbsentAsync(source, "X"); + await VerifyItemIsAbsentAsync(source, "Y"); + } + + [Fact, Trait(Traits.Feature, Traits.Features.Completion)] + [WorkItem(58081, "https://github.com/dotnet/roslyn/issues/58081")] + public async Task CompletionOnOverloadedLambdaPointerParameterWithSimpleMemberAccessAndExplicitType() + { + + var source = @" +struct TestStruct1 +{ + public int X; +} + +struct TestStruct2 +{ + public int Y; +} + +unsafe class Test +{ + delegate void TestLambda1(TestStruct1* a); + delegate void TestLambda2(TestStruct2* a); + + void Overloaded(TestLambda1 lambda) + { + } + + void Overloaded(TestLambda2 lambda) + { + } + + void TestMethod() + => Overloaded((TestStruct1* a) => a.$$); +} +"; + await VerifyItemIsAbsentAsync(source, "X"); + await VerifyItemIsAbsentAsync(source, "Y"); + } + + [InlineData("m.MyObject?.$$MyValue!!()")] + [InlineData("m.MyObject?.$$MyObject!.MyValue!!()")] + [InlineData("m.MyObject?.MyObject!.$$MyValue!!()")] + [Theory, Trait(Traits.Feature, Traits.Features.Completion)] + [WorkItem(59714, "https://github.com/dotnet/roslyn/issues/59714")] + public async Task OptionalExclamationsAfterConditionalAccessShouldBeHandled(string conditionalAccessExpression) + { + var source = $@" +class MyClass +{{ + public MyClass? MyObject {{ get; set; }} + public MyClass? MyValue() => null; + + public static void F() + {{ + var m = new MyClass(); + {conditionalAccessExpression}; + }} +}}"; + await VerifyItemExistsAsync(source, "MyValue"); + } + + [Fact] + public async Task TopLevelSymbolsAvailableAtTopLevel() + { + var source = $@" +int goo; + +void Bar() +{{ +}} + +$$ + +class MyClass +{{ + public static void F() + {{ + }} +}}"; + await VerifyItemExistsAsync(source, "goo"); + await VerifyItemExistsAsync(source, "Bar"); + } + + [Fact] + public async Task TopLevelSymbolsAvailableInsideTopLevelFunction() + { + var source = $@" +int goo; + +void Bar() +{{ + $$ +}} + +class MyClass +{{ + public static void F() + {{ + }} +}}"; + await VerifyItemExistsAsync(source, "goo"); + await VerifyItemExistsAsync(source, "Bar"); + } + + [Fact] + public async Task TopLevelSymbolsNotAvailableInOtherTypes() + { + var source = $@" +int goo; + +void Bar() +{{ +}} + +class MyClass +{{ + public static void F() + {{ + $$ + }} +}}"; + await VerifyItemIsAbsentAsync(source, "goo"); + await VerifyItemIsAbsentAsync(source, "Bar"); + } } } diff --git a/src/EditorFeatures/CSharpTest/Completion/CompletionProviders/TypeImportCompletionProviderTests.cs b/src/EditorFeatures/CSharpTest/Completion/CompletionProviders/TypeImportCompletionProviderTests.cs index c638c5a3c6904..2dbe4c4df911a 100644 --- a/src/EditorFeatures/CSharpTest/Completion/CompletionProviders/TypeImportCompletionProviderTests.cs +++ b/src/EditorFeatures/CSharpTest/Completion/CompletionProviders/TypeImportCompletionProviderTests.cs @@ -1774,6 +1774,67 @@ static MyClass await VerifyProviderCommitAsync(markup, "MyClass", expectedCodeAfterCommit, commitChar: null, sourceCodeKind: kind); } + [Fact, Trait(Traits.Feature, Traits.Features.Completion)] + [WorkItem(58473, "https://github.com/dotnet/roslyn/issues/58473")] + public async Task TestGlobalUsingsInSdkAutoGeneratedFile() + { + var source = @" +using System; +$$"; + + var globalUsings = @" +global using global::System; +global using global::System.Collections.Generic; +global using global::System.IO; +global using global::System.Linq; +global using global::System.Net.Http; +global using global::System.Threading; +global using global::System.Threading.Tasks; +"; + + var markup = CreateMarkupForSingleProject(source, globalUsings, LanguageNames.CSharp, referencedFileName: "ProjectName.GlobalUsings.g.cs"); + await VerifyTypeImportItemIsAbsentAsync(markup, "Task", inlineDescription: "System.Threading.Tasks"); + await VerifyTypeImportItemIsAbsentAsync(markup, "Console", inlineDescription: "System"); + } + + [Fact, Trait(Traits.Feature, Traits.Features.Completion)] + [WorkItem(58473, "https://github.com/dotnet/roslyn/issues/58473")] + public async Task TestGlobalUsingsInSameFile() + { + var source = @" +global using global::System; +global using global::System.Threading.Tasks; + +$$"; + + var markup = CreateMarkupForSingleProject(source, "", LanguageNames.CSharp); + await VerifyTypeImportItemIsAbsentAsync(markup, "Console", inlineDescription: "System"); + await VerifyTypeImportItemIsAbsentAsync(markup, "Task", inlineDescription: "System.Threading.Tasks"); + } + + [Fact(Skip = "https://github.com/dotnet/roslyn/issues/59088")] + [Trait(Traits.Feature, Traits.Features.Completion)] + [WorkItem(58473, "https://github.com/dotnet/roslyn/issues/58473")] + public async Task TestGlobalUsingsInUserDocument() + { + var source = @" +$$"; + + var globalUsings = @" +global using global::System; +global using global::System.Collections.Generic; +global using global::System.IO; +global using global::System.Linq; +global using global::System.Net.Http; +global using global::System.Threading; +global using global::System.Threading.Tasks; +"; + + var markup = CreateMarkupForSingleProject(source, globalUsings, LanguageNames.CSharp, referencedFileName: "GlobalUsings.cs"); + await VerifyTypeImportItemIsAbsentAsync(markup, "Task", inlineDescription: "System.Threading.Tasks"); + await VerifyTypeImportItemIsAbsentAsync(markup, "Console", inlineDescription: "System"); + } + private Task VerifyTypeImportItemExistsAsync(string markup, string expectedItem, int glyph, string inlineDescription, string displayTextSuffix = null, string expectedDescriptionOrNull = null, CompletionItemFlags? flags = null) => VerifyItemExistsAsync(markup, expectedItem, displayTextSuffix: displayTextSuffix, glyph: glyph, inlineDescription: inlineDescription, expectedDescriptionOrNull: expectedDescriptionOrNull, isComplexTextEdit: true, flags: flags); diff --git a/src/EditorFeatures/CSharpTest/ConvertNamespace/ConvertNamespaceCommandHandlerTests.cs b/src/EditorFeatures/CSharpTest/ConvertNamespace/ConvertNamespaceCommandHandlerTests.cs index 42e05bdf1de6d..c9a278fbd8f5e 100644 --- a/src/EditorFeatures/CSharpTest/ConvertNamespace/ConvertNamespaceCommandHandlerTests.cs +++ b/src/EditorFeatures/CSharpTest/ConvertNamespace/ConvertNamespaceCommandHandlerTests.cs @@ -70,8 +70,7 @@ class C class C { -} -"); +}"); } [WpfFact] @@ -115,8 +114,7 @@ class C class C { -} -"); +}"); } [WpfFact] @@ -199,8 +197,7 @@ class C class C { -} -"); +}"); } [WpfFact] @@ -305,8 +302,7 @@ namespace N;$$ class C { -} -"); +}"); } [WpfFact] @@ -334,8 +330,7 @@ namespace N;$$ class C { -} -"); +}"); } [WpfFact] @@ -355,8 +350,7 @@ class C class C { -} -"); +}"); } } } diff --git a/src/EditorFeatures/CSharpTest/ConvertNamespace/ConvertToFileScopedNamespaceAnalyzerTests.cs b/src/EditorFeatures/CSharpTest/ConvertNamespace/ConvertToFileScopedNamespaceAnalyzerTests.cs index 2e1d7d2ee8b01..b35b1f88e270d 100644 --- a/src/EditorFeatures/CSharpTest/ConvertNamespace/ConvertToFileScopedNamespaceAnalyzerTests.cs +++ b/src/EditorFeatures/CSharpTest/ConvertNamespace/ConvertToFileScopedNamespaceAnalyzerTests.cs @@ -9,6 +9,7 @@ using Microsoft.CodeAnalysis.CSharp.ConvertNamespace; using Microsoft.CodeAnalysis.Editor.UnitTests.CodeActions; using Microsoft.CodeAnalysis.Testing; +using Roslyn.Test.Utilities; using Xunit; namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.ConvertNamespace @@ -716,6 +717,104 @@ class C { } ", }.RunAsync(); } + [Fact] + [WorkItem(59728, "https://github.com/dotnet/roslyn/issues/59728")] + public async Task TestConvertToFileScopedWithNoNewlineAtEnd() + { + await new VerifyCS.Test + { + TestCode = @" +[|namespace N|] +{ + class C + { + } +}", + FixedCode = @" +namespace $$N; + +class C +{ +}", + LanguageVersion = LanguageVersion.CSharp10, + Options = + { + { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.FileScoped } + } + }.RunAsync(); + } + + [Fact] + [WorkItem(59728, "https://github.com/dotnet/roslyn/issues/59728")] + public async Task TestConvertToFileScopedWithNoMembersAndNoNewlineAtEnd() + { + await new VerifyCS.Test + { + TestCode = @" +[|namespace N|] +{ +}", + FixedCode = @" +namespace $$N;", + LanguageVersion = LanguageVersion.CSharp10, + Options = + { + { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.FileScoped } + } + }.RunAsync(); + } + + [Fact] + [WorkItem(59728, "https://github.com/dotnet/roslyn/issues/59728")] + public async Task TestConvertToFileScopedPreserveNewlineAtEnd() + { + await new VerifyCS.Test + { + TestCode = @" +[|namespace N|] +{ + class C + { + } +} +", + FixedCode = @" +namespace $$N; + +class C +{ +} +", + LanguageVersion = LanguageVersion.CSharp10, + Options = + { + { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.FileScoped } + } + }.RunAsync(); + } + + [Fact] + [WorkItem(59728, "https://github.com/dotnet/roslyn/issues/59728")] + public async Task TestConvertToFileScopedWithNoMembersPreserveNewlineAtEnd() + { + await new VerifyCS.Test + { + TestCode = @" +[|namespace N|] +{ +} +", + FixedCode = @" +namespace $$N; +", + LanguageVersion = LanguageVersion.CSharp10, + Options = + { + { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.FileScoped } + } + }.RunAsync(); + } + #endregion } } diff --git a/src/EditorFeatures/CSharpTest/ConvertToInterpolatedString/ConvertPlaceholderToInterpolatedStringTests.cs b/src/EditorFeatures/CSharpTest/ConvertToInterpolatedString/ConvertPlaceholderToInterpolatedStringTests.cs index 277e602674dd5..4b18ceb6d3d42 100644 --- a/src/EditorFeatures/CSharpTest/ConvertToInterpolatedString/ConvertPlaceholderToInterpolatedStringTests.cs +++ b/src/EditorFeatures/CSharpTest/ConvertToInterpolatedString/ConvertPlaceholderToInterpolatedStringTests.cs @@ -286,7 +286,7 @@ class T { void M() { - var a = $""{ (object)new object}""; + var a = $""{(object)new object}""; } }"); } @@ -411,7 +411,7 @@ class T void M() { Decimal pricePerOunce = 17.36m; - String s = $""The current price is { pricePerOunce:C2} per ounce.""; + String s = $""The current price is {pricePerOunce:C2} per ounce.""; } }"); } @@ -490,7 +490,7 @@ class T { void M() { - var a = $""{ 126347.89m,-10:C}""; + var a = $""{126347.89m,-10:C}""; } }"); } diff --git a/src/EditorFeatures/CSharpTest/ConvertToInterpolatedString/ConvertRegularStringToInterpolatedStringTests.cs b/src/EditorFeatures/CSharpTest/ConvertToInterpolatedString/ConvertRegularStringToInterpolatedStringTests.cs index 7a5c8456bb63b..016ae90a91325 100644 --- a/src/EditorFeatures/CSharpTest/ConvertToInterpolatedString/ConvertRegularStringToInterpolatedStringTests.cs +++ b/src/EditorFeatures/CSharpTest/ConvertToInterpolatedString/ConvertRegularStringToInterpolatedStringTests.cs @@ -5,8 +5,10 @@ using System.Threading.Tasks; using Microsoft.CodeAnalysis.CodeRefactorings; using Microsoft.CodeAnalysis.ConvertToInterpolatedString; +using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.CodeRefactorings; using Microsoft.CodeAnalysis.Test.Utilities; +using Roslyn.Test.Utilities; using Xunit; namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.ConvertToInterpolatedString @@ -127,8 +129,9 @@ void M() }"); } + [WorkItem(52243, "https://github.com/dotnet/roslyn/issues/52243")] [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsConvertToInterpolatedString)] - public async Task TestMissingOnRegularStringWithBracesAssignedToConst() + public async Task TestMissingOnRegularStringWithBracesAssignedToConstBeforeCSharp10() { await TestMissingInRegularAndScriptAsync( @"public class C @@ -137,7 +140,28 @@ void M() { const string v = [||]""string {""; } -}"); +}", new(new CSharpParseOptions(LanguageVersion.CSharp9))); + } + + [WorkItem(52243, "https://github.com/dotnet/roslyn/issues/52243")] + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsConvertToInterpolatedString)] + public async Task TestOnRegularStringWithBracesAssignedToConstForCSharp10AndNewer() + { + await TestInRegularAndScriptAsync( +@"public class C +{ + void M() + { + const string v = [||]""string {""; + } +}", +@"public class C +{ + void M() + { + const string v = $""string {{""; + } +}", parseOptions: new CSharpParseOptions(LanguageVersion.CSharp10)); } [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsConvertToInterpolatedString)] @@ -153,8 +177,9 @@ void M() }"); } + [WorkItem(52243, "https://github.com/dotnet/roslyn/issues/52243")] [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsConvertToInterpolatedString)] - public async Task TestMissingOnAttributeStringParameterWithBraces() + public async Task TestMissingOnAttributeStringParameterWithBracesBeforeCSharp10() { await TestMissingInRegularAndScriptAsync( @"[System.Diagnostics.DebuggerDisplay([||]""FirstName={FirstName}, LastName={LastName}"")] @@ -162,7 +187,26 @@ public class C { public string FirstName { get; set; } public string LastName { get; set; } -}"); +}", new(new CSharpParseOptions(LanguageVersion.CSharp9))); + } + + [WorkItem(52243, "https://github.com/dotnet/roslyn/issues/52243")] + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsConvertToInterpolatedString)] + public async Task TestOnAttributeStringParameterWithBracesForCSharp10AndNewer() + { + await TestInRegularAndScriptAsync( +@"[System.Diagnostics.DebuggerDisplay([||]""FirstName={FirstName}, LastName={LastName}"")] +public class C +{ + public string FirstName { get; set; } + public string LastName { get; set; } +}", +@"[System.Diagnostics.DebuggerDisplay($""FirstName={{FirstName}}, LastName={{LastName}}"")] +public class C +{ + public string FirstName { get; set; } + public string LastName { get; set; } +}", parseOptions: new CSharpParseOptions(LanguageVersion.CSharp10)); } [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsConvertToInterpolatedString)] diff --git a/src/EditorFeatures/CSharpTest/Diagnostics/DiagnosticAnalyzerDriver/DiagnosticAnalyzerDriverTests.cs b/src/EditorFeatures/CSharpTest/Diagnostics/DiagnosticAnalyzerDriver/DiagnosticAnalyzerDriverTests.cs index 9294ae9a342c0..8859a6ac0efb4 100644 --- a/src/EditorFeatures/CSharpTest/Diagnostics/DiagnosticAnalyzerDriver/DiagnosticAnalyzerDriverTests.cs +++ b/src/EditorFeatures/CSharpTest/Diagnostics/DiagnosticAnalyzerDriver/DiagnosticAnalyzerDriverTests.cs @@ -341,7 +341,7 @@ public async Task TestDiagnosticSpan() var compilerEngineCompilation = (CSharpCompilation)(await compilerEngineWorkspace.CurrentSolution.Projects.Single().GetRequiredCompilationAsync(CancellationToken.None)); var diagnostics = compilerEngineCompilation.GetAnalyzerDiagnostics(new[] { analyzer }); - AssertEx.Any(diagnostics, d => d.Id == AnalyzerHelper.AnalyzerExceptionDiagnosticId); + AssertEx.Any(diagnostics, d => d.Id == DocumentAnalysisExecutor.AnalyzerExceptionDiagnosticId); } private class InvalidSpanAnalyzer : DiagnosticAnalyzer diff --git a/src/EditorFeatures/CSharpTest/Diagnostics/FixReturnType/FixReturnTypeTests.cs b/src/EditorFeatures/CSharpTest/Diagnostics/FixReturnType/FixReturnTypeTests.cs index ef8a7fe039cb8..a8ec7e99295cb 100644 --- a/src/EditorFeatures/CSharpTest/Diagnostics/FixReturnType/FixReturnTypeTests.cs +++ b/src/EditorFeatures/CSharpTest/Diagnostics/FixReturnType/FixReturnTypeTests.cs @@ -309,6 +309,48 @@ void M() { return Console.WriteLine()[||]; } +}"); + } + + [Fact] + [WorkItem(53574, "https://github.com/dotnet/roslyn/issues/53574")] + public async Task TestAnonymousTypeTopLevel() + { + await TestInRegularAndScript1Async( +@"class C +{ + public void Method() + { + [|return|] new { A = 0, B = 1 }; + } +}", +@"class C +{ + public object Method() + { + return new { A = 0, B = 1 }; + } +}"); + } + + [Fact] + [WorkItem(53574, "https://github.com/dotnet/roslyn/issues/53574")] + public async Task TestAnonymousTypeTopNested() + { + await TestInRegularAndScript1Async( +@"class C +{ + public void Method() + { + [|return|] new[] { new { A = 0, B = 1 } }; + } +}", +@"class C +{ + public object Method() + { + return new[] { new { A = 0, B = 1 } }; + } }"); } } diff --git a/src/EditorFeatures/CSharpTest/Diagnostics/GenerateMethod/GenerateDeconstructMethodTests.cs b/src/EditorFeatures/CSharpTest/Diagnostics/GenerateMethod/GenerateDeconstructMethodTests.cs index ff2c4baed80a9..a28b19e59e32f 100644 --- a/src/EditorFeatures/CSharpTest/Diagnostics/GenerateMethod/GenerateDeconstructMethodTests.cs +++ b/src/EditorFeatures/CSharpTest/Diagnostics/GenerateMethod/GenerateDeconstructMethodTests.cs @@ -162,11 +162,13 @@ void Method() (var x, var y) = [|this|]; } }", -@"class Class +@"using System; + +class Class { private void Deconstruct(out object x, out object y) { - throw new System.NotImplementedException(); + throw new NotImplementedException(); } void Method() diff --git a/src/EditorFeatures/CSharpTest/Diagnostics/GenerateMethod/GenerateMethodTests.cs b/src/EditorFeatures/CSharpTest/Diagnostics/GenerateMethod/GenerateMethodTests.cs index 1932f6c1aa04f..de333f782f2f5 100644 --- a/src/EditorFeatures/CSharpTest/Diagnostics/GenerateMethod/GenerateMethodTests.cs +++ b/src/EditorFeatures/CSharpTest/Diagnostics/GenerateMethod/GenerateMethodTests.cs @@ -6,14 +6,12 @@ using System.Threading.Tasks; using Microsoft.CodeAnalysis.CodeFixes; -using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.CodeFixes.GenerateMethod; using Microsoft.CodeAnalysis.CSharp.CodeStyle; using Microsoft.CodeAnalysis.CSharp.Test.Utilities; using Microsoft.CodeAnalysis.Diagnostics; using Microsoft.CodeAnalysis.Test.Utilities; using Roslyn.Test.Utilities; -using Roslyn.Utilities; using Xunit; using Xunit.Abstractions; @@ -873,7 +871,7 @@ void Method() Goo(null); } - private void Goo(object p) + private void Goo(object value) { throw new NotImplementedException(); } @@ -3574,7 +3572,9 @@ void M() v = [|Goo|](v); } }", -@"class C +@"using System; + +class C { void M() { @@ -3584,7 +3584,7 @@ void M() private int Goo(int v) { - throw new System.NotImplementedException(); + throw new NotImplementedException(); } }"); } @@ -4838,7 +4838,7 @@ static void Goo(List x) Bar(() => x); } - private static void Bar(Func> p) + private static void Bar(Func> value) { throw new NotImplementedException(); } @@ -5225,7 +5225,7 @@ void M() M(new { x = 1 }); } - private void M(object p) + private void M(object value) { throw new NotImplementedException(); } @@ -5685,7 +5685,7 @@ static void Main(string[] args) Main(args.Goo()); } - private static void Main(object p) + private static void Main(object value) { throw new NotImplementedException(); } @@ -5717,7 +5717,7 @@ void Baz(string[] args) Baz(() => { return true; }); } - private void Baz(Func p) + private void Baz(Func value) { throw new NotImplementedException(); } @@ -5884,7 +5884,7 @@ void TestMethod(IEnumerable c) new C().TestMethod((a,b) => c.Add) } - private void TestMethod(Func p) + private void TestMethod(Func value) { throw new NotImplementedException(); } @@ -6196,7 +6196,9 @@ void M() var x = nameof([|Z|]); } }", -@"class C +@"using System; + +class C { void M() { @@ -6205,7 +6207,7 @@ void M() private object Z() { - throw new System.NotImplementedException(); + throw new NotImplementedException(); } }"); } @@ -6222,7 +6224,9 @@ void M() var x = nameof([|Z.X|]); } }", -@"class C +@"using System; + +class C { void M() { @@ -6231,7 +6235,7 @@ void M() private object nameof(object x) { - throw new System.NotImplementedException(); + throw new NotImplementedException(); } }"); } @@ -6248,7 +6252,9 @@ void M() var x = nameof([|Z.X.Y|]); } }", -@"class C +@"using System; + +class C { void M() { @@ -6257,7 +6263,7 @@ void M() private object nameof(object y) { - throw new System.NotImplementedException(); + throw new NotImplementedException(); } }"); } @@ -6348,7 +6354,9 @@ void M() var x = [|nameof(y, z)|]; } }", -@"class C +@"using System; + +class C { void M() { @@ -6359,7 +6367,7 @@ void M() private object nameof(int y, string z) { - throw new System.NotImplementedException(); + throw new NotImplementedException(); } }"); } @@ -6406,7 +6414,9 @@ void M() var x = [|nameof|](y, z); } }", -@"class C +@"using System; + +class C { void M() { @@ -6415,7 +6425,7 @@ void M() private object nameof(object y, object z) { - throw new System.NotImplementedException(); + throw new NotImplementedException(); } }"); } @@ -6974,7 +6984,9 @@ public class E { } }", -@"class C +@"using System; + +class C { public E B { get; private set; } @@ -6987,7 +6999,7 @@ public class E { internal object C() { - throw new System.NotImplementedException(); + throw new NotImplementedException(); } } }"); @@ -7729,7 +7741,7 @@ void Method() (int, string) d = NewMethod((1, ""hello"")); } - private (int, string) NewMethod((int, string) p) + private (int, string) NewMethod((int, string) value) { throw new NotImplementedException(); } @@ -7756,7 +7768,7 @@ void Method() (int a, string b) d = NewMethod((c: 1, d: ""hello"")); } - private (int a, string b) NewMethod((int c, string d) p) + private (int a, string b) NewMethod((int c, string d) value) { throw new NotImplementedException(); } @@ -7783,7 +7795,7 @@ void Method() (int a, string) d = NewMethod((c: 1, ""hello"")); } - private (int a, string) NewMethod((int c, string) p) + private (int a, string) NewMethod((int c, string) value) { throw new NotImplementedException(); } @@ -7802,7 +7814,9 @@ void Method() [|Undefined|](out var c); } }", -@"class Class +@"using System; + +class Class { void Method() { @@ -7811,7 +7825,7 @@ void Method() private void Undefined(out object c) { - throw new System.NotImplementedException(); + throw new NotImplementedException(); } }"); } @@ -7856,7 +7870,9 @@ void Method() [|Undefined|](a: out var c); } }", -@"class Class +@"using System; + +class Class { void Method() { @@ -7865,7 +7881,7 @@ void Method() private void Undefined(out object a) { - throw new System.NotImplementedException(); + throw new NotImplementedException(); } }"); } @@ -7909,7 +7925,9 @@ void Method() [|Undefined|](out var c); } }", -@"class Class +@"using System; + +class Class { void Method() { @@ -7918,7 +7936,7 @@ void Method() private void Undefined(out object c) { - throw new System.NotImplementedException(); + throw new NotImplementedException(); } }", parseOptions: TestOptions.Regular.WithLanguageVersion(CodeAnalysis.CSharp.LanguageVersion.CSharp6)); @@ -7963,7 +7981,9 @@ void Method() [|Undefined|](a: out var c); } }", -@"class Class +@"using System; + +class Class { void Method() { @@ -7972,7 +7992,7 @@ void Method() private void Undefined(out object a) { - throw new System.NotImplementedException(); + throw new NotImplementedException(); } }", parseOptions: TestOptions.Regular.WithLanguageVersion(CodeAnalysis.CSharp.LanguageVersion.CSharp6)); @@ -8142,7 +8162,9 @@ void Method(int i) var v = [|IsPrime|](i); } }", -@"class Class +@"using System; + +class Class { void Method(int i) { @@ -8151,7 +8173,7 @@ void Method(int i) private bool IsPrime(int i) { - throw new System.NotImplementedException(); + throw new NotImplementedException(); } }"); } @@ -8168,7 +8190,9 @@ void Method(int i) var v = [|Issue|](i); } }", -@"class Class +@"using System; + +class Class { void Method(int i) { @@ -8177,7 +8201,7 @@ void Method(int i) private object Issue(int i) { - throw new System.NotImplementedException(); + throw new NotImplementedException(); } }"); } diff --git a/src/EditorFeatures/CSharpTest/Diagnostics/GenerateType/GenerateTypeTests.cs b/src/EditorFeatures/CSharpTest/Diagnostics/GenerateType/GenerateTypeTests.cs index 56a5df86e2ee6..4cbadb49c6f86 100644 --- a/src/EditorFeatures/CSharpTest/Diagnostics/GenerateType/GenerateTypeTests.cs +++ b/src/EditorFeatures/CSharpTest/Diagnostics/GenerateType/GenerateTypeTests.cs @@ -566,11 +566,11 @@ await TestInRegularAndScriptAsync( private class Generated { - private (int, int) p; + private (int, int) value; - public Generated((int, int) p) + public Generated((int, int) value) { - this.p = p; + this.value = value; } } }", @@ -591,11 +591,11 @@ await TestInRegularAndScriptAsync( private class Generated { - private (int a, int b, int) p; + private (int a, int b, int) value; - public Generated((int a, int b, int) p) + public Generated((int a, int b, int) value) { - this.p = p; + this.value = value; } } }", @@ -1579,13 +1579,13 @@ void M(int i, bool b) internal class T { private bool b; - private object p; + private object value; - public T(out int i, ref bool b, object p) + public T(out int i, ref bool b, object value) { i = 0; this.b = b; - this.p = p; + this.value = value; } }", index: 1); @@ -1951,11 +1951,11 @@ string M(int i) internal class T { - private Func p; + private Func value; - public T(Func p) + public T(Func value) { - this.p = p; + this.value = value; } }", index: 1); diff --git a/src/EditorFeatures/CSharpTest/EditAndContinue/ActiveStatementTests.Methods.cs b/src/EditorFeatures/CSharpTest/EditAndContinue/ActiveStatementTests.Methods.cs index 25fe14be271cc..459583268a338 100644 --- a/src/EditorFeatures/CSharpTest/EditAndContinue/ActiveStatementTests.Methods.cs +++ b/src/EditorFeatures/CSharpTest/EditAndContinue/ActiveStatementTests.Methods.cs @@ -67,7 +67,7 @@ public void Method_Body_Delete1() var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.ModifiersUpdate, "extern int M()", FeaturesResources.method)); } @@ -80,7 +80,7 @@ public void Method_ExpressionBody_Delete1() var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.ModifiersUpdate, "extern int M()", FeaturesResources.method)); } @@ -93,7 +93,7 @@ public void Method_ExpressionBodyToBlockBody1() var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -105,7 +105,7 @@ public void Method_BlockBodyToExpressionBody1() var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } // Generics @@ -151,7 +151,7 @@ void Swap(ref T lhs, ref T rhs) where T : System.IComparable var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.ActiveStatementUpdate, "c.Swap(ref b, ref a);")); } @@ -191,7 +191,7 @@ static void Swap(T lhs, T rhs) where T : System.IComparable var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.ActiveStatementUpdate, "Swap(null, null);")); } @@ -231,7 +231,7 @@ static void Swap(T lhs, T rhs) where T : System.IComparable var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.GenericMethodUpdate, "static void Swap(T lhs, T rhs)")); } @@ -273,7 +273,7 @@ public async Task WaitAsync() var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [WorkItem(749440, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/749440")] @@ -313,7 +313,7 @@ public async Task WaitAsync(int millis) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.ActiveStatementUpdate, "string result = f.WaitAsync(6).Result;")); } @@ -360,7 +360,7 @@ public int G() var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.ActiveStatementUpdate, "int a = G()")); } @@ -407,7 +407,7 @@ public int G() var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.ActiveStatementUpdate, "b = F()")); } @@ -457,7 +457,7 @@ public void Constructor_ExpressionBodyToBlockBody1() var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -469,7 +469,7 @@ public void Constructor_BlockBodyToExpressionBody1() var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -481,7 +481,7 @@ public void Constructor_BlockBodyToExpressionBody2() var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -493,7 +493,7 @@ public void Constructor_BlockBodyToExpressionBody3() var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } #endregion @@ -509,7 +509,7 @@ public void Property_ExpressionBodyToBlockBody1() var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -521,7 +521,9 @@ public void Property_ExpressionBodyToBlockBody2() var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics( + active, + capabilities: EditAndContinueCapabilities.AddMethodToExistingType); } [Fact] @@ -533,7 +535,9 @@ public void Property_ExpressionBodyToBlockBody3() var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics( + active, + capabilities: EditAndContinueCapabilities.AddMethodToExistingType); } [Fact] @@ -556,7 +560,7 @@ class C var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.DeleteActiveStatement, "get", FeaturesResources.code)); } @@ -580,7 +584,7 @@ class C var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -592,7 +596,7 @@ public void Property_BlockBodyToExpressionBody1() var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -604,7 +608,7 @@ public void Property_BlockBodyToExpressionBody2() var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.Delete, "int P", DeletedSymbolDisplay(CSharpFeaturesResources.property_setter, "P.set"))); } @@ -630,7 +634,7 @@ class C var active = GetActiveStatements(src1, src2); // Can be improved with https://github.com/dotnet/roslyn/issues/22696 - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.DeleteActiveStatement, "int P", FeaturesResources.code)); } @@ -647,7 +651,7 @@ public void Indexer_ExpressionBodyToBlockBody1() var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -659,7 +663,9 @@ public void Indexer_ExpressionBodyToBlockBody2() var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics( + active, + capabilities: EditAndContinueCapabilities.AddMethodToExistingType); } [Fact] @@ -671,7 +677,7 @@ public void Indexer_BlockBodyToExpressionBody1() var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -683,7 +689,7 @@ public void Indexer_BlockBodyToExpressionBody2() var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.Delete, "int this[int a]", DeletedSymbolDisplay(CSharpFeaturesResources.indexer_setter, "this[int a].set"))); } @@ -707,7 +713,7 @@ class C var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -756,7 +762,7 @@ public T this[int i] var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.GenericTypeUpdate, "set")); } @@ -810,7 +816,7 @@ public T this[int i] var active = GetActiveStatements(src1, src2); // Rude edits of active statements (AS:1) are not reported if the top-level edits are rude. - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.GenericTypeUpdate, "set"), Diagnostic(RudeEditKind.ActiveStatementUpdate, "stringCollection[1] = \"hello\";")); } @@ -861,7 +867,7 @@ public T this[int i] var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.GenericTypeUpdate, "get")); } @@ -913,7 +919,7 @@ public T this[int i] var active = GetActiveStatements(src1, src2); // Rude edits of active statements (AS:1) are not reported if the top-level edits are rude. - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.GenericTypeUpdate, "get"), Diagnostic(RudeEditKind.ActiveStatementUpdate, "Console.WriteLine(stringCollection[1]);")); } @@ -964,7 +970,7 @@ public T this[int i] var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.GenericTypeUpdate, "set")); } @@ -1013,7 +1019,7 @@ public T this[int i] var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.DeleteActiveStatement, "{", FeaturesResources.code)); } @@ -1063,7 +1069,7 @@ public T this[int i] var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.GenericTypeUpdate, "get")); } @@ -1112,7 +1118,7 @@ public T this[int i] var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.DeleteActiveStatement, "{", FeaturesResources.code)); } @@ -1129,7 +1135,7 @@ public void Operator_ExpressionBodyToBlockBody1() var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -1141,7 +1147,7 @@ public void Operator_ExpressionBodyToBlockBody2() var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -1153,7 +1159,7 @@ public void Operator_BlockBodyToExpressionBody1() var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -1165,7 +1171,7 @@ public void Operator_BlockBodyToExpressionBody2() var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [WorkItem(754274, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/754274")] @@ -1203,7 +1209,7 @@ static void Main(string[] args) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [WorkItem(754274, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/754274")] @@ -1249,7 +1255,7 @@ static void Main(string[] args) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.ActiveStatementUpdate, "Test t3 = t1 * t2;")); } diff --git a/src/EditorFeatures/CSharpTest/EditAndContinue/ActiveStatementTests.cs b/src/EditorFeatures/CSharpTest/EditAndContinue/ActiveStatementTests.cs index b0b9c401a3b0b..51425b7128d8a 100644 --- a/src/EditorFeatures/CSharpTest/EditAndContinue/ActiveStatementTests.cs +++ b/src/EditorFeatures/CSharpTest/EditAndContinue/ActiveStatementTests.cs @@ -59,7 +59,7 @@ static void Goo(int a) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.ActiveStatementUpdate, "Goo(2);")); } @@ -96,7 +96,7 @@ static void Goo(int a) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } /// @@ -140,7 +140,7 @@ static void Goo(int a) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.ActiveStatementUpdate, "Goo(2);")); } @@ -180,7 +180,7 @@ static void Goo(int a) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -216,7 +216,7 @@ static void Goo(int a) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } /// @@ -261,7 +261,7 @@ static void Goo(int a) var active = GetActiveStatements(src1, src2); edits.VerifySemantics(active, - expectedSemanticEdits: new[] + semanticEdits: new[] { SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C.Main"), preserveLocalVariables: true), SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C.Goo"), preserveLocalVariables: true) @@ -296,7 +296,7 @@ static void Main(string[] args) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } #endregion @@ -338,7 +338,7 @@ static void Goo(int a) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.DeleteActiveStatement, "{", FeaturesResources.code)); } @@ -463,7 +463,7 @@ static void Goo(int a) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.DeleteActiveStatement, "{", FeaturesResources.code), Diagnostic(RudeEditKind.DeleteActiveStatement, "{", FeaturesResources.code), Diagnostic(RudeEditKind.DeleteActiveStatement, "{", FeaturesResources.code), @@ -512,7 +512,7 @@ static void Goo(int a) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -544,7 +544,7 @@ static void Goo(int a) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -591,7 +591,7 @@ static void Goo(int a) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -650,7 +650,7 @@ static void Goo(int a) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -686,7 +686,7 @@ static void Goo(int a) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.DeleteActiveStatement, "{", FeaturesResources.code)); } @@ -724,7 +724,7 @@ static void Goo(int a) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -746,7 +746,7 @@ static void Main(String[] args) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.Delete, null, FeaturesResources.namespace_), Diagnostic(RudeEditKind.Delete, null, DeletedSymbolDisplay(FeaturesResources.class_, "N.C"))); } @@ -800,7 +800,7 @@ public Goo(int a) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.ActiveStatementUpdate, "Goo f = new Goo(5*2);")); } @@ -849,7 +849,7 @@ public Goo(int a) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [WorkItem(742334, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/742334")] @@ -951,7 +951,7 @@ class Goo var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.InitializerUpdate, "int a = 42", FeaturesResources.parameter)); } @@ -1002,7 +1002,7 @@ public A(int x, int y, int z) { } var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [WorkItem(742334, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/742334")] @@ -1052,7 +1052,7 @@ public A(int x, int y, int z) { } var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [WorkItem(742334, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/742334")] @@ -1086,7 +1086,7 @@ static void Main(string[] args) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -1143,7 +1143,7 @@ static void Main(string[] args) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.ActiveStatementUpdate, "this(false)")); } @@ -1193,7 +1193,7 @@ static void Main(string[] args) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.ActiveStatementUpdate, "public C()")); } @@ -1223,7 +1223,7 @@ public C() : base(1) {} var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.ActiveStatementUpdate, "base(1)")); } @@ -1263,7 +1263,7 @@ static void Main(string[] args) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -1304,7 +1304,7 @@ static void Main(string[] args) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -1345,7 +1345,7 @@ static void Main(string[] args) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -1364,7 +1364,7 @@ class C var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -1383,7 +1383,7 @@ class C var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -1402,7 +1402,7 @@ class C var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Theory] @@ -1416,7 +1416,7 @@ public void InstanceConstructor_DeleteParameterless(string typeKind) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.DeleteActiveStatement, "partial " + typeKind + " C", DeletedSymbolDisplay(FeaturesResources.constructor, "C()"))); } @@ -1456,7 +1456,7 @@ static void Main(string[] args) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Theory] @@ -1487,7 +1487,7 @@ static void Main(string[] args) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [WorkItem(742334, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/742334")] @@ -1524,7 +1524,7 @@ static void Main(string[] args) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Theory] @@ -1555,7 +1555,7 @@ static void Main(string[] args) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -1598,7 +1598,7 @@ static void Main(string[] args) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.ActiveStatementUpdate, "int a = F(2)")); } @@ -1642,7 +1642,7 @@ static void Main(string[] args) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.ActiveStatementUpdate, "b = F(3)")); } @@ -1664,7 +1664,7 @@ class C var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -1701,7 +1701,7 @@ static void Main(string[] args) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -1744,7 +1744,7 @@ static void Main(string[] args) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -1787,7 +1787,7 @@ static void Main(string[] args) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -1810,7 +1810,7 @@ class C var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -1847,7 +1847,7 @@ static void Main(string[] args) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -1890,7 +1890,7 @@ static void Main(string[] args) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -1919,7 +1919,7 @@ static void Main(string[] args) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -1948,7 +1948,7 @@ static void Main(string[] args) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -1977,7 +1977,7 @@ static void Main(string[] args) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -2006,7 +2006,7 @@ static void Main(string[] args) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -2033,7 +2033,7 @@ public C() {} var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.ModifiersUpdate, "const int a = 1", FeaturesResources.const_field)); } @@ -2059,7 +2059,7 @@ public void M() var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -2083,7 +2083,7 @@ public C() {} var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.ModifiersUpdate, "const int a = 1, b = 2", FeaturesResources.const_field), Diagnostic(RudeEditKind.ModifiersUpdate, "const int a = 1, b = 2", FeaturesResources.const_field)); } @@ -2110,7 +2110,7 @@ public void M() var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -2135,7 +2135,7 @@ public C() {} var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -2154,7 +2154,7 @@ class C var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -2181,7 +2181,7 @@ public C() {} var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -2210,7 +2210,7 @@ public void M() var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -2265,7 +2265,7 @@ public void M() var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -2292,7 +2292,7 @@ public C() {} var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -2319,7 +2319,7 @@ public C() {} var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -2344,7 +2344,7 @@ public C() {} var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -2400,7 +2400,7 @@ public void M() var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -2483,7 +2483,7 @@ static void Main(string[] args) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [WorkItem(755749, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/755749")] @@ -2514,7 +2514,7 @@ static void Main(string[] args) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.InsertAroundActiveStatement, "lock (lockThis)", CSharpFeaturesResources.lock_statement)); } @@ -2548,7 +2548,7 @@ static void Main(string[] args) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.InsertAroundActiveStatement, "lock (lockThis)", CSharpFeaturesResources.lock_statement)); } @@ -2583,7 +2583,7 @@ static void Main(string[] args) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -2641,7 +2641,7 @@ static void Main(string[] args) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.InsertAroundActiveStatement, "lock (d)", CSharpFeaturesResources.lock_statement), Diagnostic(RudeEditKind.InsertAroundActiveStatement, "lock (e)", CSharpFeaturesResources.lock_statement)); } @@ -2702,7 +2702,7 @@ static void Main(string[] args) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.UpdateAroundActiveStatement, "lock (d)", CSharpFeaturesResources.lock_statement)); } @@ -2737,7 +2737,7 @@ static void Main(string[] args) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.UpdateAroundActiveStatement, "lock (\"test\")", CSharpFeaturesResources.lock_statement)); } @@ -2773,7 +2773,7 @@ static void Main(string[] args) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -2803,7 +2803,7 @@ static void Main(string[] args) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -2836,7 +2836,7 @@ static void Main(string[] args) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -2869,7 +2869,7 @@ static void Main(string[] args) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.UpdateAroundActiveStatement, "lock (G(a => a))", CSharpFeaturesResources.lock_statement)); } @@ -2917,7 +2917,7 @@ static void Main(string[] args) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [WorkItem(755742, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/755742")] @@ -2956,7 +2956,7 @@ static void Main(string[] args) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.InsertAroundActiveStatement, "fixed (int* pj = &value)", CSharpFeaturesResources.fixed_statement)); } @@ -2994,7 +2994,7 @@ static void Main(string[] args) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [WorkItem(755742, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/755742")] @@ -3038,7 +3038,7 @@ static void Main(string[] args) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.InsertAroundActiveStatement, "fixed (int* pj = &value)", CSharpFeaturesResources.fixed_statement)); } @@ -3087,7 +3087,7 @@ static void Main(string[] args) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [WorkItem(755746, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/755746")] @@ -3129,7 +3129,7 @@ static void Main(string[] args) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.UpdateAroundActiveStatement, "fixed (int* p = &value)", CSharpFeaturesResources.fixed_statement)); } @@ -3189,7 +3189,7 @@ static void Main(string[] args) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.UpdateAroundActiveStatement, "fixed (int* a = &value2)", CSharpFeaturesResources.fixed_statement), Diagnostic(RudeEditKind.UpdateAroundActiveStatement, "fixed (int* d = &value1)", CSharpFeaturesResources.fixed_statement), Diagnostic(RudeEditKind.InsertAroundActiveStatement, "fixed (int* e = &value1)", CSharpFeaturesResources.fixed_statement)); @@ -3230,7 +3230,7 @@ static void Main(string[] args) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -3263,7 +3263,7 @@ static unsafe void Main(string[] args) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -3296,7 +3296,7 @@ static unsafe void Main(string[] args) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.UpdateAroundActiveStatement, "fixed (byte* p = &G(a => a))", CSharpFeaturesResources.fixed_statement)); } @@ -3336,7 +3336,7 @@ static void Main(string[] args) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -3371,7 +3371,7 @@ static void Main(string[] args) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -3406,7 +3406,7 @@ static void Main(string[] args) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -3441,7 +3441,7 @@ static void Main(string[] args) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -3476,7 +3476,7 @@ static void Main(string[] args) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -3511,7 +3511,7 @@ static void Main(string[] args) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -3546,7 +3546,7 @@ static void Main(string[] args) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -3581,7 +3581,7 @@ static void Main(string[] args) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -3617,7 +3617,7 @@ static void Main(string[] args) var active = GetActiveStatements(src1, src2); // not ideal, but good enough: - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.ActiveStatementUpdate, "object c"), Diagnostic(RudeEditKind.UpdateAroundActiveStatement, "foreach ( object c in F())", CSharpFeaturesResources.foreach_statement)); } @@ -3654,7 +3654,7 @@ static void Main(string[] args) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.ActiveStatementUpdate, "(int i, (var b, double d))"), Diagnostic(RudeEditKind.UpdateAroundActiveStatement, "foreach ( (int i, (var b, double d)) in F())", CSharpFeaturesResources.foreach_statement)); } @@ -3705,7 +3705,7 @@ static void Main(string[] args) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -3754,7 +3754,7 @@ static void Main(string[] args) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -3794,7 +3794,7 @@ static void Main(string[] args) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.InsertAroundActiveStatement, "foreach (var b in e1)", CSharpFeaturesResources.foreach_statement), Diagnostic(RudeEditKind.InsertAroundActiveStatement, "foreach (var c in e1)", CSharpFeaturesResources.foreach_statement), Diagnostic(RudeEditKind.InsertAroundActiveStatement, "foreach (var a in e1)", CSharpFeaturesResources.foreach_statement)); @@ -3837,7 +3837,7 @@ static void Main(string[] args) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.InsertAroundActiveStatement, "foreach (var c in e1)", CSharpFeaturesResources.foreach_statement), Diagnostic(RudeEditKind.InsertAroundActiveStatement, "foreach ((int b1, bool b2) in e1)", CSharpFeaturesResources.foreach_statement), Diagnostic(RudeEditKind.InsertAroundActiveStatement, "foreach ((var a1, var a2) in e1)", CSharpFeaturesResources.foreach_statement)); @@ -3886,7 +3886,7 @@ static void Main(string[] args) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -3932,7 +3932,7 @@ static void Main(string[] args) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -3978,7 +3978,7 @@ static void Main(string[] args) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -4024,7 +4024,7 @@ static void Main(string[] args) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -4070,7 +4070,7 @@ static void Main(string[] args) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -4116,7 +4116,7 @@ static void Main(string[] args) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -4166,7 +4166,7 @@ static void Main(string[] args) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.InsertAroundActiveStatement, "foreach (var a in e1)", CSharpFeaturesResources.foreach_statement), Diagnostic(RudeEditKind.InsertAroundActiveStatement, "foreach (var b in e1)", CSharpFeaturesResources.foreach_statement)); } @@ -4201,7 +4201,7 @@ static unsafe void Main(string[] args) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -4234,7 +4234,7 @@ static unsafe void Main(string[] args) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.UpdateAroundActiveStatement, "foreach (var a in G(a => a))", CSharpFeaturesResources.foreach_statement)); } @@ -4270,7 +4270,7 @@ static void F() var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -4297,7 +4297,7 @@ static void F() var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -4324,7 +4324,7 @@ static void F() var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } #endregion @@ -4365,7 +4365,7 @@ static void Main(string[] args) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.ActiveStatementUpdate, "i = F(2)")); } @@ -4403,7 +4403,7 @@ static void Main(string[] args) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -4440,7 +4440,7 @@ static void Main(string[] args) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.DeleteActiveStatement, "for (; i < 10 ; i++)", FeaturesResources.code)); } @@ -4476,7 +4476,7 @@ static void Main(string[] args) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.ActiveStatementUpdate, "var i = F(2)")); } @@ -4512,7 +4512,7 @@ static void Main(string[] args) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -4547,7 +4547,7 @@ static void Main(string[] args) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -4582,7 +4582,7 @@ static void Main(string[] args) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.ActiveStatementUpdate, "i < F(20)")); } @@ -4618,7 +4618,7 @@ static void Main(string[] args) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.DeleteActiveStatement, "for (int i = 1; ; i++ )", FeaturesResources.code)); } @@ -4654,7 +4654,7 @@ static void Main(string[] args) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -4689,7 +4689,7 @@ static void Main(string[] args) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.ActiveStatementUpdate, "F(2)")); } @@ -4725,7 +4725,7 @@ static void Main(string[] args) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -4760,7 +4760,7 @@ static void Main(string[] args) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } #endregion @@ -4815,7 +4815,7 @@ static void Main(string[] args) // Using with an expression generates code that stores the value of the expression in a compiler-generated temp. // This temp is not initialized when using is added around an active statement so the disposal is a no-op. // The user might expect that the object the field points to is disposed at the end of the using block, but it isn't. - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.InsertAroundActiveStatement, "using (c)", CSharpFeaturesResources.using_statement)); } @@ -4859,7 +4859,7 @@ static void Main(string[] args) // Unlike using with an expression, using with a declaration does not introduce compiler-generated temps. // As with other local declarations that are added but not executed, the variable is not initialized and thus // there should be no expectation (or need) for its disposal. Hence we do not report a rude edit. - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -4889,7 +4889,7 @@ static void Main(string[] args) // Unlike using with an expression, using local declaration does not introduce compiler-generated temps. // As with other local declarations that are added but not executed, the variable is not initialized and thus // there should be no expectation (or need) for its disposal. Hence we do not report a rude edit. - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -4922,7 +4922,7 @@ static void Main(string[] args) // Unlike using with an expression, using local declaration does not introduce compiler-generated temps. // As with other local declarations that are added but not executed, the variable is not initialized and thus // there should be no expectation (or need) for its disposal. Hence we do not report a rude edit. - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -4957,7 +4957,7 @@ static void Main(string[] args) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.ActiveStatementUpdate, "}")); } @@ -4993,7 +4993,7 @@ static void Main(string[] args) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.ActiveStatementUpdate, "}")); } @@ -5029,7 +5029,7 @@ static void Main(string[] args) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -5076,7 +5076,7 @@ static void Main(string[] args) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.ActiveStatementUpdate, "}")); } @@ -5134,7 +5134,7 @@ static void Main(string[] args) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -5194,7 +5194,7 @@ static void Main(string[] args) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.InsertAroundActiveStatement, "using (c)", CSharpFeaturesResources.using_statement)); } @@ -5228,7 +5228,7 @@ static unsafe void Main(string[] args) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -5261,7 +5261,7 @@ static unsafe void Main(string[] args) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.UpdateAroundActiveStatement, "using (G(a => a))", CSharpFeaturesResources.using_statement)); } @@ -5301,7 +5301,7 @@ public static void Main() var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -5336,7 +5336,7 @@ public static void Main() var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.ActiveStatementUpdate, "if (!B())")); } @@ -5372,7 +5372,7 @@ public static void Main() var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -5407,7 +5407,7 @@ public static void Main() var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -5442,7 +5442,7 @@ public static void Main() var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.ActiveStatementUpdate, "while (!B())")); } @@ -5478,7 +5478,7 @@ public static void Main() var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -5515,7 +5515,7 @@ public static void Main() var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -5552,7 +5552,7 @@ public static void Main() var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.ActiveStatementUpdate, "while (!B());")); } @@ -5590,7 +5590,7 @@ public static void Main() var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -5617,7 +5617,7 @@ static void F() var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -5654,7 +5654,7 @@ public static void Main() var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -5691,7 +5691,7 @@ public static void Main() var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } #endregion @@ -5758,7 +5758,7 @@ public static int Main() var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.UpdateAroundActiveStatement, "switch (F())", CSharpFeaturesResources.switch_statement_case_clause)); } @@ -5797,7 +5797,7 @@ public static int Main() var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.UpdateAroundActiveStatement, "switch (F())", CSharpFeaturesResources.switch_statement_case_clause)); } @@ -5836,7 +5836,7 @@ public static int Main() var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.UpdateAroundActiveStatement, "switch (F())", CSharpFeaturesResources.switch_statement_case_clause)); } @@ -5876,7 +5876,7 @@ public static int Main() var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.UpdateAroundActiveStatement, "switch (F())", CSharpFeaturesResources.switch_statement_case_clause)); } @@ -5916,7 +5916,7 @@ public static int Main() var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.UpdateAroundActiveStatement, "switch (F())", CSharpFeaturesResources.switch_statement_case_clause)); } @@ -5956,7 +5956,7 @@ public static int Main() var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -5995,7 +5995,7 @@ public static int Main() var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.UpdateAroundActiveStatement, "switch (F(2))", CSharpFeaturesResources.switch_statement)); } @@ -6037,7 +6037,7 @@ public static int F(object obj) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.ActiveStatementUpdate, "switch (obj)")); } @@ -6079,7 +6079,7 @@ public static int F(object obj) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.ActiveStatementUpdate, "switch (obj)")); } @@ -6127,7 +6127,7 @@ public static int F(object obj) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.ActiveStatementUpdate, "switch (G())")); } @@ -6169,7 +6169,7 @@ public static int F(object obj) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.ActiveStatementUpdate, "switch (G())")); } @@ -6211,7 +6211,7 @@ public static int F(object obj) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } #endregion @@ -6255,7 +6255,7 @@ public static int Main() var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -6275,7 +6275,7 @@ class C var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -6295,7 +6295,7 @@ class C var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -6315,7 +6315,7 @@ class C var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -6335,7 +6335,7 @@ class C var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -6367,7 +6367,7 @@ from a in new[] { 2 } var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -6387,7 +6387,7 @@ class C var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.ActiveStatementUpdate, "(G() switch { 0 => 10, _ => 20 }) switch { 10 => 100 , _ => 200 }")); } @@ -6416,7 +6416,7 @@ 1 when F2() switch { 0 => true, _ => false } => F3() switch { var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -6442,7 +6442,7 @@ public static int Main() var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -6468,7 +6468,7 @@ public static int Main() var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -6494,7 +6494,7 @@ public static int Main() var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } #endregion @@ -6540,7 +6540,7 @@ static void Goo() var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.InsertAroundActiveStatement, "try", CSharpFeaturesResources.try_block)); } @@ -6583,7 +6583,7 @@ static void Goo() var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -6625,7 +6625,7 @@ static void Goo() var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.DeleteAroundActiveStatement, "Goo();", CSharpFeaturesResources.try_block)); } @@ -6668,7 +6668,7 @@ static void Goo() var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -6716,7 +6716,7 @@ static void Goo() var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.UpdateAroundActiveStatement, "try", CSharpFeaturesResources.try_block)); } @@ -6765,7 +6765,7 @@ static void Goo() var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -6813,7 +6813,7 @@ static void Goo() var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -6861,7 +6861,7 @@ static void Goo() var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -6903,7 +6903,7 @@ static void Main() var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.DeleteActiveStatement, "{", FeaturesResources.code)); } @@ -6942,7 +6942,7 @@ static void Main(string[] args) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.UpdateAroundActiveStatement, "finally", CSharpFeaturesResources.finally_clause)); } @@ -6985,7 +6985,7 @@ static void Main() var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.DeleteActiveStatement, "{", FeaturesResources.code)); } @@ -7024,7 +7024,7 @@ static void Main() var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } #endregion @@ -7070,7 +7070,7 @@ static void Goo() var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.InsertAroundActiveStatement, "catch", CSharpFeaturesResources.catch_clause)); } @@ -7113,7 +7113,7 @@ static void Goo() var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.InsertAroundActiveStatement, "catch", CSharpFeaturesResources.catch_clause)); } @@ -7156,7 +7156,7 @@ static void Goo() var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.DeleteAroundActiveStatement, "Goo();", CSharpFeaturesResources.catch_clause)); } @@ -7199,7 +7199,7 @@ static void Goo() var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.DeleteAroundActiveStatement, "Console.WriteLine(1);", CSharpFeaturesResources.catch_clause)); } @@ -7248,7 +7248,7 @@ static void Goo() var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.UpdateAroundActiveStatement, "catch", CSharpFeaturesResources.catch_clause)); } @@ -7294,7 +7294,7 @@ static void Goo() var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.UpdateAroundActiveStatement, "catch", CSharpFeaturesResources.catch_clause)); } @@ -7343,7 +7343,7 @@ static void Goo() var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.UpdateAroundActiveStatement, "catch", CSharpFeaturesResources.catch_clause)); } @@ -7389,7 +7389,7 @@ static void Goo() var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.ActiveStatementUpdate, "when (Goo(2))"), Diagnostic(RudeEditKind.UpdateAroundActiveStatement, "catch", CSharpFeaturesResources.catch_clause)); } @@ -7426,7 +7426,7 @@ static void Main(string[] args) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.UpdateAroundActiveStatement, "catch", CSharpFeaturesResources.catch_clause)); } @@ -7462,7 +7462,7 @@ static void Main(string[] args) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.UpdateAroundActiveStatement, "catch", CSharpFeaturesResources.catch_clause)); } @@ -7509,7 +7509,7 @@ static void Goo() var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.InsertAroundActiveStatement, "finally", CSharpFeaturesResources.finally_clause)); } @@ -7552,7 +7552,7 @@ static void Goo() var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.InsertAroundActiveStatement, "finally", CSharpFeaturesResources.finally_clause)); } @@ -7595,7 +7595,7 @@ static void Goo() var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.DeleteAroundActiveStatement, "Goo();", CSharpFeaturesResources.finally_clause)); } @@ -7638,7 +7638,7 @@ static void Goo() var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.DeleteAroundActiveStatement, "Console.WriteLine(1);", CSharpFeaturesResources.finally_clause)); } @@ -7727,7 +7727,7 @@ static void Goo() var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.UpdateAroundActiveStatement, "catch", CSharpFeaturesResources.catch_clause), Diagnostic(RudeEditKind.UpdateAroundActiveStatement, "try", CSharpFeaturesResources.try_block), Diagnostic(RudeEditKind.DeleteAroundActiveStatement, "Goo();", CSharpFeaturesResources.try_block), @@ -7798,7 +7798,7 @@ static void Goo() var active = GetActiveStatements(src1, src2); // TODO: this is incorrect, we need to report a rude edit: - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact, WorkItem(23865, "https://github.com/dotnet/roslyn/issues/23865")] @@ -7894,7 +7894,7 @@ static void Goo() var active = GetActiveStatements(src1, src2); // TODO: this is incorrect, we need to report a rude edit since an ER span has been changed (empty line added): - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -7939,7 +7939,7 @@ static void Goo() var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -7984,7 +7984,7 @@ static void Goo() var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -8037,7 +8037,7 @@ static void Main() var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -8093,7 +8093,7 @@ static void Main() var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.DeleteAroundActiveStatement, "return 1 + Goo(x);", CSharpFeaturesResources.try_block)); } @@ -8144,7 +8144,7 @@ static void Main() var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } #endregion @@ -8178,7 +8178,7 @@ static void Main(string[] args) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -8216,7 +8216,7 @@ private static int M(int a, int b) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.InsertAroundActiveStatement, "checked", CSharpFeaturesResources.checked_statement)); } @@ -8255,7 +8255,7 @@ private static int M(int a, int b) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.DeleteAroundActiveStatement, "System.Console.WriteLine(5 * M(1, 2));", CSharpFeaturesResources.checked_statement)); } @@ -8297,7 +8297,7 @@ private static int M(int a, int b) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.UpdateAroundActiveStatement, "checked", CSharpFeaturesResources.checked_statement)); } @@ -8343,7 +8343,7 @@ private static int M(int a, int b) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.UpdateAroundActiveStatement, "checked", CSharpFeaturesResources.checked_statement)); } @@ -8397,7 +8397,7 @@ private static int M(int a, int b) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.UpdateAroundActiveStatement, "checked", CSharpFeaturesResources.checked_statement)); } @@ -8429,7 +8429,7 @@ static void Main(string[] args) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact, WorkItem(1359, "https://github.com/dotnet/roslyn/issues/1359")] @@ -8456,7 +8456,7 @@ static void Main(string[] args) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact, WorkItem(1359, "https://github.com/dotnet/roslyn/issues/1359")] @@ -8483,7 +8483,7 @@ static void Main(string[] args) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.ActiveStatementUpdate, "G(a => 2 )")); } @@ -8511,7 +8511,7 @@ static void Main(string[] args) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact, WorkItem(1359, "https://github.com/dotnet/roslyn/issues/1359")] @@ -8538,7 +8538,7 @@ static void Main(string[] args) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact, WorkItem(1359, "https://github.com/dotnet/roslyn/issues/1359")] @@ -8565,7 +8565,7 @@ static void Main(string[] args) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact, WorkItem(1359, "https://github.com/dotnet/roslyn/issues/1359")] @@ -8600,7 +8600,7 @@ static void Main(string[] args) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact, WorkItem(1359, "https://github.com/dotnet/roslyn/issues/1359")] @@ -8627,7 +8627,7 @@ static void Main(string[] args) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact, WorkItem(1359, "https://github.com/dotnet/roslyn/issues/1359")] @@ -8654,7 +8654,7 @@ static void Main(string[] args) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -8681,7 +8681,7 @@ static void Main(string[] args) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -8710,7 +8710,7 @@ static void Main() var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -8737,7 +8737,7 @@ static void Main(string[] args) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -8766,7 +8766,7 @@ static void Main() var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -8795,7 +8795,7 @@ static void Main() var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -8866,7 +8866,7 @@ static void Main(string[] args) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.ActiveStatementLambdaRemoved, "return b;", CSharpFeaturesResources.lambda)); } @@ -8899,7 +8899,7 @@ static void Main(string[] args) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.ActiveStatementLambdaRemoved, "(b)", CSharpFeaturesResources.lambda)); } @@ -8947,7 +8947,7 @@ static void Main(string[] args) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.ActiveStatementLambdaRemoved, "F(b);", CSharpFeaturesResources.lambda)); } @@ -8982,7 +8982,7 @@ static void Main(string[] args) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.ActiveStatementLambdaRemoved, "{", CSharpFeaturesResources.lambda), Diagnostic(RudeEditKind.ActiveStatementLambdaRemoved, "{", CSharpFeaturesResources.lambda)); } @@ -9012,7 +9012,7 @@ static void Main(string[] args) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.ActiveStatementLambdaRemoved, "from", CSharpFeaturesResources.where_clause)); } @@ -9041,7 +9041,7 @@ static void Main(string[] args) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.ActiveStatementLambdaRemoved, "from", CSharpFeaturesResources.let_clause)); } @@ -9073,7 +9073,7 @@ static void Main(string[] args) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.ActiveStatementLambdaRemoved, "from", CSharpFeaturesResources.join_clause)); } @@ -9105,7 +9105,7 @@ static void Main(string[] args) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.ActiveStatementLambdaRemoved, "from", CSharpFeaturesResources.orderby_clause)); } @@ -9137,7 +9137,7 @@ static void Main(string[] args) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.ActiveStatementLambdaRemoved, "from", CSharpFeaturesResources.orderby_clause)); } @@ -9169,7 +9169,7 @@ static void Main(string[] args) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.ActiveStatementLambdaRemoved, "from", CSharpFeaturesResources.orderby_clause)); } @@ -9200,7 +9200,7 @@ join y in ys on F() equals G() var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -9231,7 +9231,7 @@ group x by x.F() into g var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.ActiveStatementLambdaRemoved, "into", CSharpFeaturesResources.where_clause)); } @@ -9262,7 +9262,7 @@ static void Main() var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.ActiveStatementLambdaRemoved, "join", CSharpFeaturesResources.select_clause)); } @@ -9293,7 +9293,7 @@ where a > 0 var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.ActiveStatementLambdaRemoved, "select", CSharpFeaturesResources.select_clause)); } @@ -9324,7 +9324,7 @@ static void Main() var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.ActiveStatementUpdate, "F(from a in array where a > 0 select a);")); } @@ -9353,7 +9353,7 @@ static void Main() var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.ActiveStatementLambdaRemoved, "group", CSharpFeaturesResources.groupby_clause)); } @@ -9384,7 +9384,7 @@ static void Main() var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.ActiveStatementUpdate, "F(from a in array group a + 1 by a);")); } @@ -9418,7 +9418,7 @@ static IEnumerable F() var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.InsertAroundActiveStatement, "yield return 1;", CSharpFeaturesResources.yield_return_statement)); } @@ -9449,7 +9449,9 @@ static IEnumerable F() var active = GetActiveStatements(src1, src2); // should not contain RUDE_EDIT_INSERT_AROUND - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics( + active, + capabilities: EditAndContinueCapabilities.NewTypeDefinition); } [Fact] @@ -9478,7 +9480,9 @@ static IEnumerable F() var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics( + active, + capabilities: EditAndContinueCapabilities.NewTypeDefinition); } [Fact] @@ -9508,7 +9512,7 @@ static async Task F() var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.InsertAroundActiveStatement, "await", CSharpFeaturesResources.await_expression)); } @@ -9540,7 +9544,7 @@ static async Task F() var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.InsertAroundActiveStatement, "await foreach (var x in AsyncIter())", CSharpFeaturesResources.asynchronous_foreach_statement)); } @@ -9572,7 +9576,7 @@ static async Task F() var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.InsertAroundActiveStatement, "x = new AsyncDisposable()", CSharpFeaturesResources.asynchronous_using_declaration), Diagnostic(RudeEditKind.InsertAroundActiveStatement, "y = new AsyncDisposable()", CSharpFeaturesResources.asynchronous_using_declaration)); } @@ -9601,7 +9605,7 @@ static async void F() var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.UpdatingStateMachineMethodAroundActiveStatement, "static async void F()")); } @@ -9629,7 +9633,7 @@ static async void F() var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.UpdatingStateMachineMethodAroundActiveStatement, "static async void F()")); } @@ -9660,7 +9664,9 @@ static async Task F() var active = GetActiveStatements(src1, src2); // should not contain RUDE_EDIT_INSERT_AROUND - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics( + active, + capabilities: EditAndContinueCapabilities.NewTypeDefinition); } [Fact] @@ -9689,7 +9695,7 @@ static async void F() var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.UpdatingStateMachineMethodAroundActiveStatement, "static async void F()")); } @@ -9719,7 +9725,7 @@ static async void F() var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.UpdatingStateMachineMethodAroundActiveStatement, "static async void F()")); } @@ -9749,7 +9755,9 @@ static async Task F() var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics( + active, + capabilities: EditAndContinueCapabilities.NewTypeDefinition); } [Fact] @@ -9776,7 +9784,7 @@ static async void F() var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -9817,7 +9825,7 @@ static void F() var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.InsertAroundActiveStatement, "await", CSharpFeaturesResources.await_expression)); } @@ -9849,7 +9857,7 @@ static void F() var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.UpdatingStateMachineMethodAroundActiveStatement, "()")); } @@ -9877,7 +9885,7 @@ static void F() var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.UpdatingStateMachineMethodAroundActiveStatement, "a")); } @@ -9914,7 +9922,7 @@ async Task f() var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.InsertAroundActiveStatement, "await", CSharpFeaturesResources.await_expression)); } @@ -9943,7 +9951,7 @@ static void F() var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.InsertAroundActiveStatement, "await", CSharpFeaturesResources.await_expression)); } @@ -9975,7 +9983,7 @@ static async void F() var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.UpdatingStateMachineMethodAroundActiveStatement, FeaturesResources.delegate_)); } @@ -10122,7 +10130,7 @@ static void F() var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.ChangingFromAsynchronousToSynchronous, "static void F()", FeaturesResources.method)); } @@ -10154,7 +10162,7 @@ public static int F(int a) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -10177,7 +10185,7 @@ static void Main(string[] args) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -10200,7 +10208,7 @@ class C var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } #endregion @@ -10233,7 +10241,7 @@ static void F(object x) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -10262,7 +10270,7 @@ static void F(object x) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -10291,7 +10299,7 @@ static void F(object o) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -10320,7 +10328,7 @@ static void F(object o1, object o2) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -10349,7 +10357,7 @@ static void F(object o1, object o2) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -10378,7 +10386,7 @@ static void F(object o) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -10407,7 +10415,7 @@ static void F(object o) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -10436,7 +10444,7 @@ static void F() var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -10464,7 +10472,7 @@ static void F() var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -10493,7 +10501,7 @@ static void F() var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -10522,7 +10530,7 @@ static void F(object o1, object o2) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -10553,7 +10561,7 @@ static void F(object o1, object o2) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -10590,7 +10598,7 @@ static void F(object o1, object o2) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); edits.VerifySemanticDiagnostics(); } @@ -10622,7 +10630,7 @@ static void F() var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -10649,7 +10657,7 @@ static void F() var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } #endregion @@ -10731,7 +10739,7 @@ record C(int X) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -10760,7 +10768,7 @@ static void Main(string[] args) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -10789,7 +10797,7 @@ static void Main(string[] args) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } #endregion @@ -10843,7 +10851,7 @@ static void F() var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -10872,7 +10880,7 @@ static void F() var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.UpdateAroundActiveStatement, "B();", string.Format(FeaturesResources._0_directive, "line"))); } @@ -10922,7 +10930,7 @@ static void Main() var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact, WorkItem(52971, "https://github.com/dotnet/roslyn/issues/52971")] @@ -10972,7 +10980,7 @@ static void Main() var active = GetActiveStatements(src1, src2); // TODO: rude edit should be reported - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact(Skip = "https://github.com/dotnet/roslyn/issues/52971"), WorkItem(52971, "https://github.com/dotnet/roslyn/issues/52971")] @@ -11014,7 +11022,7 @@ static void Main() var active = GetActiveStatements(src1, src2); // TODO: rude edit? - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } #endregion @@ -11081,7 +11089,7 @@ public static void F() ActiveStatementFlags.NonLeafFrame | ActiveStatementFlags.LeafFrame }); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.PartiallyExecutedActiveStatementUpdate, "Console.WriteLine(10);"), Diagnostic(RudeEditKind.ActiveStatementUpdate, "Console.WriteLine(20);"), Diagnostic(RudeEditKind.ActiveStatementUpdate, "Console.WriteLine(40);"), @@ -11112,7 +11120,7 @@ public static void F() ActiveStatementFlags.PartiallyExecuted | ActiveStatementFlags.LeafFrame }); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.PartiallyExecutedActiveStatementDelete, "{", FeaturesResources.code)); } @@ -11140,7 +11148,7 @@ public static void F() ActiveStatementFlags.NonLeafFrame | ActiveStatementFlags.LeafFrame }); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.DeleteActiveStatement, "{", FeaturesResources.code)); } @@ -11172,7 +11180,7 @@ public static void F() var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Theory, CombinatorialData] @@ -11221,13 +11229,13 @@ public static void H(int x) { if (node.Parent is MethodDeclarationSyntax methodDecl && methodDecl.Identifier.Text == "G") { - throw outOfMemory ? new OutOfMemoryException() : new NullReferenceException("NullRef!"); + throw outOfMemory ? new OutOfMemoryException() : new SimpleToStringException(); } }); var expectedDiagnostic = outOfMemory ? Diagnostic(RudeEditKind.MemberBodyTooBig, "public static void G()", FeaturesResources.method) : - Diagnostic(RudeEditKind.MemberBodyInternalError, "public static void G()", FeaturesResources.method); + Diagnostic(RudeEditKind.MemberBodyInternalError, "public static void G()", FeaturesResources.method, SimpleToStringException.ToStringOutput); validator.VerifySemantics( new[] { edits }, @@ -11235,6 +11243,20 @@ public static void H(int x) new[] { DocumentResults(diagnostics: new[] { expectedDiagnostic }) }); } + /// + /// Custom exception class that has a fixed ToString so that tests aren't relying + /// on stack traces, which could make them flaky + /// + private class SimpleToStringException : Exception + { + public const string ToStringOutput = ""; + + public override string ToString() + { + return ToStringOutput; + } + } + #endregion #region Top Level Statements @@ -11257,7 +11279,7 @@ public void TopLevelStatements_UpdateAroundActiveStatement_LocalFunction() var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -11278,7 +11300,7 @@ public void TopLevelStatements_UpdateAroundActiveStatement_OutVar() var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -11310,7 +11332,7 @@ static void Goo(int a) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active, + edits.VerifySemanticDiagnostics(active, Diagnostic(RudeEditKind.ActiveStatementUpdate, "Goo(2);")); } diff --git a/src/EditorFeatures/CSharpTest/EditAndContinue/ActiveStatementTrackingServiceTests.cs b/src/EditorFeatures/CSharpTest/EditAndContinue/ActiveStatementTrackingServiceTests.cs index d62eb5443f7e8..6d51aec1cd24f 100644 --- a/src/EditorFeatures/CSharpTest/EditAndContinue/ActiveStatementTrackingServiceTests.cs +++ b/src/EditorFeatures/CSharpTest/EditAndContinue/ActiveStatementTrackingServiceTests.cs @@ -11,7 +11,6 @@ using Microsoft.CodeAnalysis.EditAndContinue; using Microsoft.CodeAnalysis.EditAndContinue.Contracts; using Microsoft.CodeAnalysis.EditAndContinue.UnitTests; -using Microsoft.CodeAnalysis.Editor.Implementation.EditAndContinue; using Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces; using Microsoft.CodeAnalysis.Test.Utilities; using Microsoft.CodeAnalysis.Text; @@ -52,7 +51,9 @@ static void Goo() var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics( + active, + capabilities: EditAndContinueCapabilities.AddMethodToExistingType); } [Fact] @@ -83,7 +84,9 @@ static void Goo() var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics( + active, + capabilities: EditAndContinueCapabilities.AddMethodToExistingType); } [Fact] @@ -110,7 +113,7 @@ static void Main(string[] args) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Fact] @@ -138,7 +141,7 @@ static void Main(string[] args) var edits = GetTopEdits(src1, src2); var active = GetActiveStatements(src1, src2); - edits.VerifyRudeDiagnostics(active); + edits.VerifySemanticDiagnostics(active); } [Theory] diff --git a/src/EditorFeatures/CSharpTest/EditAndContinue/BreakpointSpansTests.cs b/src/EditorFeatures/CSharpTest/EditAndContinue/BreakpointSpansTests.cs index 1c76d916543a3..c2dc451346204 100644 --- a/src/EditorFeatures/CSharpTest/EditAndContinue/BreakpointSpansTests.cs +++ b/src/EditorFeatures/CSharpTest/EditAndContinue/BreakpointSpansTests.cs @@ -255,6 +255,36 @@ class C }"); } + [Fact] + public void GetBreakpointSequence_InstanceContructor_NoBody() + { + VerifyAllSpansInDeclaration(@" +class Class +{ + [|Clas$$s()|] +}"); + } + + [Fact] + public void GetBreakpointSequence_StaticContructor_NoBody() + { + VerifyAllSpansInDeclaration(@" +class Class +{ + static Clas$$s() +}"); + } + + [Fact] + public void GetBreakpointSequence_Method_NoBody() + { + VerifyAllSpansInDeclaration(@" +class Class +{ + int F$$unction() +}"); + } + #region Switch Expression [Fact] @@ -4272,6 +4302,16 @@ public void InstanceConstructor_NoInitializer_BlockBody() }"); } + [Fact] + public void InstanceConstructor_NoBody() + { + TestSpan( +@"class Class +{ + [|Cla$$ss()|] +}"); + } + [Fact] public void InstanceConstructor_NoInitializer_ExpressionBody_All() { @@ -4510,6 +4550,16 @@ public void StaticConstructor_ExpressionBody() }"); } + [Fact] + public void StaticConstructor_NoBody() + { + TestMissing( +@"class Class +{ + static Cla$$ss() +}"); + } + [Fact] public void InstanceConstructorInitializer() { diff --git a/src/EditorFeatures/CSharpTest/EditAndContinue/Helpers/CSharpEditAndContinueTestHelpers.cs b/src/EditorFeatures/CSharpTest/EditAndContinue/Helpers/CSharpEditAndContinueTestHelpers.cs index 9e69b9b3ad552..e69d2782a50b4 100644 --- a/src/EditorFeatures/CSharpTest/EditAndContinue/Helpers/CSharpEditAndContinueTestHelpers.cs +++ b/src/EditorFeatures/CSharpTest/EditAndContinue/Helpers/CSharpEditAndContinueTestHelpers.cs @@ -2,16 +2,12 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -#nullable disable - using System; using System.Collections.Immutable; using Microsoft.CodeAnalysis.CSharp.Symbols; using Microsoft.CodeAnalysis.Differencing; using Microsoft.CodeAnalysis.EditAndContinue; using Microsoft.CodeAnalysis.EditAndContinue.UnitTests; -using Microsoft.CodeAnalysis.Text; -using Roslyn.Utilities; using Xunit; namespace Microsoft.CodeAnalysis.CSharp.EditAndContinue.UnitTests @@ -20,7 +16,7 @@ internal sealed class CSharpEditAndContinueTestHelpers : EditAndContinueTestHelp { private readonly CSharpEditAndContinueAnalyzer _analyzer; - public CSharpEditAndContinueTestHelpers(Action faultInjector = null) + public CSharpEditAndContinueTestHelpers(Action? faultInjector = null) { _analyzer = new CSharpEditAndContinueAnalyzer(faultInjector); } @@ -29,18 +25,6 @@ public CSharpEditAndContinueTestHelpers(Action faultInjector = null) public override string LanguageName => LanguageNames.CSharp; public override TreeComparer TopSyntaxComparer => SyntaxComparer.TopLevel; - public override SyntaxNode FindNode(SyntaxNode root, TextSpan span) - { - var result = root.FindToken(span.Start).Parent; - while (result.Span != span) - { - result = result.Parent; - Assert.NotNull(result); - } - - return result; - } - public override ImmutableArray GetDeclarators(ISymbol method) { Assert.True(method is MethodSymbol, "Only methods should have a syntax map."); diff --git a/src/EditorFeatures/CSharpTest/EditAndContinue/Helpers/EditAndContinueValidation.cs b/src/EditorFeatures/CSharpTest/EditAndContinue/Helpers/EditAndContinueValidation.cs index 82fc0c3d34d77..ec25566899242 100644 --- a/src/EditorFeatures/CSharpTest/EditAndContinue/Helpers/EditAndContinueValidation.cs +++ b/src/EditorFeatures/CSharpTest/EditAndContinue/Helpers/EditAndContinueValidation.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +using System; using System.Collections.Generic; using System.Collections.Immutable; using Microsoft.CodeAnalysis.Differencing; @@ -15,46 +16,12 @@ namespace Microsoft.CodeAnalysis.CSharp.EditAndContinue.UnitTests { internal static class EditAndContinueValidation { - internal static void VerifyRudeDiagnostics( - this EditScript editScript, - params RudeEditDiagnosticDescription[] expectedDiagnostics) - { - VerifySemanticDiagnostics( - editScript, - ActiveStatementsDescription.Empty, - capabilities: null, - expectedDiagnostics); - } - - internal static void VerifyRudeDiagnostics( - this EditScript editScript, - EditAndContinueCapabilities? capabilities = null, - params RudeEditDiagnosticDescription[] expectedDiagnostics) - { - VerifySemanticDiagnostics( - editScript, - ActiveStatementsDescription.Empty, - capabilities, - expectedDiagnostics); - } - - internal static void VerifyRudeDiagnostics( - this EditScript editScript, - ActiveStatementsDescription description, - params RudeEditDiagnosticDescription[] expectedDiagnostics) - { - VerifySemanticDiagnostics( - editScript, - description, - capabilities: null, - expectedDiagnostics); - } - internal static void VerifyLineEdits( this EditScript editScript, SourceLineUpdate[] lineEdits, SemanticEditDescription[]? semanticEdits = null, - RudeEditDiagnosticDescription[]? diagnostics = null) + RudeEditDiagnosticDescription[]? diagnostics = null, + EditAndContinueCapabilities? capabilities = null) { Assert.NotEmpty(lineEdits); @@ -62,90 +29,98 @@ internal static void VerifyLineEdits( editScript, new[] { new SequencePointUpdates(editScript.Match.OldRoot.SyntaxTree.FilePath, lineEdits.ToImmutableArray()) }, semanticEdits, - diagnostics); + diagnostics, + capabilities); } internal static void VerifyLineEdits( this EditScript editScript, SequencePointUpdates[] lineEdits, SemanticEditDescription[]? semanticEdits = null, - RudeEditDiagnosticDescription[]? diagnostics = null) + RudeEditDiagnosticDescription[]? diagnostics = null, + EditAndContinueCapabilities? capabilities = null) { new CSharpEditAndContinueTestHelpers().VerifyLineEdits( editScript, lineEdits, semanticEdits, - diagnostics); + diagnostics, + capabilities); } internal static void VerifySemanticDiagnostics( this EditScript editScript, - params RudeEditDiagnosticDescription[] expectedDiagnostics) + params RudeEditDiagnosticDescription[] diagnostics) { - VerifySemantics( - new[] { editScript }, - new[] { new DocumentAnalysisResultsDescription(diagnostics: expectedDiagnostics) }); + VerifySemanticDiagnostics(editScript, activeStatements: null, targetFrameworks: null, capabilities: null, diagnostics); } internal static void VerifySemanticDiagnostics( - this EditScript editScript, - ActiveStatementsDescription activeStatements, - params RudeEditDiagnosticDescription[] expectedDiagnostics) + this EditScript editScript, + ActiveStatementsDescription activeStatements, + params RudeEditDiagnosticDescription[] diagnostics) { - VerifySemanticDiagnostics(editScript, activeStatements, capabilities: null, expectedDiagnostics); + VerifySemanticDiagnostics(editScript, activeStatements, targetFrameworks: null, capabilities: null, diagnostics); } internal static void VerifySemanticDiagnostics( this EditScript editScript, - ActiveStatementsDescription activeStatements, - EditAndContinueCapabilities? capabilities = null, - params RudeEditDiagnosticDescription[] expectedDiagnostics) + RudeEditDiagnosticDescription[] diagnostics, + EditAndContinueCapabilities? capabilities) { - VerifySemantics( - new[] { editScript }, - new[] { new DocumentAnalysisResultsDescription(activeStatements: activeStatements, diagnostics: expectedDiagnostics) }, - capabilities: capabilities); + VerifySemanticDiagnostics(editScript, activeStatements: null, targetFrameworks: null, capabilities, diagnostics); } internal static void VerifySemanticDiagnostics( this EditScript editScript, - TargetFramework[] targetFrameworks, - params RudeEditDiagnosticDescription[] expectedDiagnostics) + ActiveStatementsDescription? activeStatements = null, + TargetFramework[]? targetFrameworks = null, + EditAndContinueCapabilities? capabilities = null, + params RudeEditDiagnosticDescription[] diagnostics) { VerifySemantics( new[] { editScript }, - new[] { new DocumentAnalysisResultsDescription(diagnostics: expectedDiagnostics) }, - targetFrameworks: targetFrameworks); + new[] { new DocumentAnalysisResultsDescription(activeStatements: activeStatements, diagnostics: diagnostics) }, + targetFrameworks, + capabilities); } internal static void VerifySemantics( this EditScript editScript, ActiveStatementsDescription activeStatements, - SemanticEditDescription[] expectedSemanticEdits, + SemanticEditDescription[] semanticEdits, EditAndContinueCapabilities? capabilities = null) { VerifySemantics( new[] { editScript }, - new[] { new DocumentAnalysisResultsDescription(activeStatements, semanticEdits: expectedSemanticEdits) }, + new[] { new DocumentAnalysisResultsDescription(activeStatements, semanticEdits: semanticEdits) }, capabilities: capabilities); } internal static void VerifySemantics( this EditScript editScript, - params SemanticEditDescription[] expectedSemanticEdits) + SemanticEditDescription[] semanticEdits, + EditAndContinueCapabilities capabilities) + { + VerifySemantics(editScript, ActiveStatementsDescription.Empty, semanticEdits, capabilities); + } + + internal static void VerifySemantics( + this EditScript editScript, + params SemanticEditDescription[] semanticEdits) { - VerifySemantics(editScript, ActiveStatementsDescription.Empty, expectedSemanticEdits, capabilities: null); + VerifySemantics(editScript, ActiveStatementsDescription.Empty, semanticEdits, capabilities: null); } internal static void VerifySemantics( EditScript[] editScripts, - DocumentAnalysisResultsDescription[] expected, + DocumentAnalysisResultsDescription[] results, TargetFramework[]? targetFrameworks = null, EditAndContinueCapabilities? capabilities = null) { foreach (var targetFramework in targetFrameworks ?? new[] { TargetFramework.NetStandard20, TargetFramework.NetCoreApp }) { - new CSharpEditAndContinueTestHelpers().VerifySemantics(editScripts, targetFramework, expected, capabilities); + new CSharpEditAndContinueTestHelpers().VerifySemantics(editScripts, targetFramework, results, capabilities); } } } diff --git a/src/EditorFeatures/CSharpTest/EditAndContinue/LineEditTests.cs b/src/EditorFeatures/CSharpTest/EditAndContinue/LineEditTests.cs index b8184f7eb6af4..cac033dd243f1 100644 --- a/src/EditorFeatures/CSharpTest/EditAndContinue/LineEditTests.cs +++ b/src/EditorFeatures/CSharpTest/EditAndContinue/LineEditTests.cs @@ -1103,7 +1103,8 @@ class C semanticEdits: new[] { SemanticEdit(SemanticEditKind.Replace, c => c.GetMember("C")) - }); + }, + capabilities: EditAndContinueCapabilities.NewTypeDefinition); } [Fact] @@ -1294,7 +1295,8 @@ class C semanticEdits: new[] { SemanticEdit(SemanticEditKind.Replace, c => c.GetMember("C")) - }); + }, + capabilities: EditAndContinueCapabilities.NewTypeDefinition); } #endregion diff --git a/src/EditorFeatures/CSharpTest/EditAndContinue/StatementEditingTests.cs b/src/EditorFeatures/CSharpTest/EditAndContinue/StatementEditingTests.cs index ee4df8c5e2fa4..1a507057e1f1d 100644 --- a/src/EditorFeatures/CSharpTest/EditAndContinue/StatementEditingTests.cs +++ b/src/EditorFeatures/CSharpTest/EditAndContinue/StatementEditingTests.cs @@ -4,6 +4,7 @@ #nullable disable +using System; using System.IO; using System.Linq; using Microsoft.CodeAnalysis.CSharp.UnitTests; @@ -402,7 +403,7 @@ class C edits.VerifyEdits("Update [static int F(int a) => a switch { 0 => 0, _ => 1 };]@18 -> [static int F(int a) => a switch { 0 => 0, _ => 2 };]@18"); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics(); } [Fact] @@ -422,7 +423,7 @@ class C edits.VerifyEdits("Update [static int F(int a) => a switch { 0 => 0, _ => 1 };]@18 -> [static int F(int a) => a switch { 1 => 0, _ => 2 };]@18"); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics(); } [Fact] @@ -442,7 +443,7 @@ class C edits.VerifyEdits("Update [static int F(int a) => a switch { 0 => 0, _ => 1 };]@18 -> [static int F(int a) => a switch { 0 => 0, 1 => 1, _ => 2 };]@18"); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics(); } #endregion @@ -1985,15 +1986,18 @@ public void Lambdas_AddAttribute() "Update [(a) => a]@21 -> [[A][return:A]([A]a) => a]@21", "Update [a]@22 -> [[A]a]@35"); - GetTopEdits(edits).VerifyRudeDiagnostics( - Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "([A]a)", FeaturesResources.method), - Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "([A]a)", FeaturesResources.method), - Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "([A]a)", FeaturesResources.parameter)); + GetTopEdits(edits).VerifySemanticDiagnostics( + new[] + { + Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "([A]a)", FeaturesResources.method), + Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "([A]a)", FeaturesResources.method), + Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "([A]a)", FeaturesResources.parameter) + }, + capabilities: EditAndContinueCapabilities.Baseline); GetTopEdits(edits).VerifySemantics( - ActiveStatementsDescription.Empty, new[] { SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C.F"), preserveLocalVariables: true) }, - capabilities: EditAndContinueTestHelpers.Net6RuntimeCapabilities); + capabilities: EditAndContinueCapabilities.ChangeCustomAttributes); } [Fact] @@ -2117,7 +2121,8 @@ void F() "; var edits = GetTopEdits(src1, src2); - edits.VerifySemanticDiagnostics(); + edits.VerifySemanticDiagnostics( + capabilities: EditAndContinueCapabilities.NewTypeDefinition | EditAndContinueCapabilities.AddMethodToExistingType); } [Fact] @@ -2151,7 +2156,8 @@ void F() "; var edits = GetTopEdits(src1, src2); - edits.VerifySemanticDiagnostics(); + edits.VerifySemanticDiagnostics( + capabilities: EditAndContinueCapabilities.AddMethodToExistingType); } [Fact] @@ -2814,9 +2820,8 @@ void F() var edits = GetTopEdits(src1, src2); edits.VerifySemanticDiagnostics( - activeStatements: ActiveStatementsDescription.Empty, - capabilities: EditAndContinueTestHelpers.BaselineCapabilities, - Diagnostic(RudeEditKind.InsertNotSupportedByRuntime, "a", CSharpFeaturesResources.lambda)); + new[] { Diagnostic(RudeEditKind.InsertNotSupportedByRuntime, "a", CSharpFeaturesResources.lambda) }, + capabilities: EditAndContinueTestHelpers.BaselineCapabilities); } [Fact] @@ -2850,9 +2855,8 @@ void F() var edits = GetTopEdits(src1, src2); edits.VerifySemanticDiagnostics( - activeStatements: ActiveStatementsDescription.Empty, - capabilities, - Diagnostic(RudeEditKind.InsertNotSupportedByRuntime, "b", CSharpFeaturesResources.lambda)); + new[] { Diagnostic(RudeEditKind.InsertNotSupportedByRuntime, "b", CSharpFeaturesResources.lambda) }, + capabilities); } [Fact] @@ -2879,16 +2883,13 @@ void F() } } "; - var capabilities = EditAndContinueCapabilities.Baseline | EditAndContinueCapabilities.NewTypeDefinition; - var edits = GetTopEdits(src1, src2); edits.VerifySemanticDiagnostics( - activeStatements: ActiveStatementsDescription.Empty, - capabilities, // TODO: https://github.com/dotnet/roslyn/issues/52759 // This is incorrect, there should be no rude edit reported - Diagnostic(RudeEditKind.InsertNotSupportedByRuntime, "b", CSharpFeaturesResources.lambda)); + new[] { Diagnostic(RudeEditKind.InsertNotSupportedByRuntime, "b", CSharpFeaturesResources.lambda) }, + capabilities: EditAndContinueCapabilities.NewTypeDefinition); } [Fact] @@ -3436,7 +3437,7 @@ void F() edits.VerifySemantics( ActiveStatementsDescription.Empty, - expectedSemanticEdits: new[] + semanticEdits: new[] { SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").GetMembers("F").Single(), preserveLocalVariables: true) }); @@ -3476,7 +3477,7 @@ void F() var edits = GetTopEdits(src1, src2); edits.VerifySemanticDiagnostics( - Diagnostic(RudeEditKind.ChangingLambdaParameters, "a", "lambda")); + Diagnostic(RudeEditKind.ChangingLambdaParameters, "a", CSharpFeaturesResources.lambda)); } [Fact] @@ -5231,7 +5232,8 @@ void F() "; var edits = GetTopEdits(src1, src2); - edits.VerifySemanticDiagnostics(); + edits.VerifySemanticDiagnostics( + capabilities: EditAndContinueCapabilities.AddMethodToExistingType); } [Fact] @@ -5268,7 +5270,8 @@ void F() "; var edits = GetTopEdits(src1, src2); - edits.VerifySemanticDiagnostics(); + edits.VerifySemanticDiagnostics( + capabilities: EditAndContinueCapabilities.AddMethodToExistingType); } [Fact] @@ -5305,7 +5308,8 @@ void F() "; var edits = GetTopEdits(src1, src2); - edits.VerifySemanticDiagnostics(); + edits.VerifySemanticDiagnostics( + capabilities: EditAndContinueCapabilities.AddMethodToExistingType); } [Fact] @@ -5838,9 +5842,8 @@ void M() var edits = GetTopEdits(src1, src2); edits.VerifySemanticDiagnostics( - activeStatements: ActiveStatementsDescription.Empty, - capabilities: EditAndContinueTestHelpers.BaselineCapabilities, - Diagnostic(RudeEditKind.InsertNotSupportedByRuntime, "M", FeaturesResources.local_function)); + new[] { Diagnostic(RudeEditKind.InsertNotSupportedByRuntime, "M", FeaturesResources.local_function) }, + capabilities: EditAndContinueCapabilities.Baseline); } [Fact, WorkItem(21499, "https://github.com/dotnet/roslyn/issues/21499")] @@ -6032,7 +6035,8 @@ void F() "; var edits = GetTopEdits(src1, src2); - edits.VerifySemanticDiagnostics(); + edits.VerifySemanticDiagnostics( + capabilities: EditAndContinueCapabilities.AddMethodToExistingType); } [Fact] @@ -7209,7 +7213,8 @@ public void LocalFunction_In_Parameter_InsertWhole() edits.VerifyEdits( "Update [void M() { }]@13 -> [void M() { void local(in int b) { throw null; } }]@13"); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics( + capabilities: EditAndContinueCapabilities.AddMethodToExistingType); } [Fact] @@ -7223,7 +7228,7 @@ public void LocalFunction_In_Parameter_InsertParameter() edits.VerifyEdits( "Update [void M() { void local() { throw null; } }]@13 -> [void M() { void local(in int b) { throw null; } }]@13"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.ChangingLambdaParameters, "local", CSharpFeaturesResources.local_function)); } @@ -7238,7 +7243,7 @@ public void LocalFunction_In_Parameter_Update() edits.VerifyEdits( "Update [void M() { void local(int b) { throw null; } }]@13 -> [void M() { void local(in int b) { throw null; } }]@13"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.ChangingLambdaParameters, "local", CSharpFeaturesResources.local_function)); } @@ -7253,7 +7258,8 @@ public void LocalFunction_ReadOnlyRef_ReturnType_Insert() edits.VerifyEdits( "Update [void M() { }]@13 -> [void M() { ref readonly int local() { throw null; } }]@13"); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics( + capabilities: EditAndContinueCapabilities.AddMethodToExistingType); } [Fact] @@ -7267,7 +7273,7 @@ public void LocalFunction_ReadOnlyRef_ReturnType_Update() edits.VerifyEdits( "Update [void M() { int local() { throw null; } }]@13 -> [void M() { ref readonly int local() { throw null; } }]@13"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.ChangingLambdaReturnType, "local", CSharpFeaturesResources.local_function)); } @@ -7312,11 +7318,11 @@ static void F() // lambdas are ok as they are emitted to a nested type edits.VerifySemanticDiagnostics( targetFrameworks: new[] { TargetFramework.NetCoreApp }, - expectedDiagnostics: new[] + diagnostics: new[] { - Diagnostic(RudeEditKind.InsertLocalFunctionIntoInterfaceMethod, "f1"), - Diagnostic(RudeEditKind.InsertLocalFunctionIntoInterfaceMethod, "f2"), - Diagnostic(RudeEditKind.InsertLocalFunctionIntoInterfaceMethod, "f3") + Diagnostic(RudeEditKind.InsertLocalFunctionIntoInterfaceMethod, "f1", CSharpFeaturesResources.local_function), + Diagnostic(RudeEditKind.InsertLocalFunctionIntoInterfaceMethod, "f2", CSharpFeaturesResources.local_function), + Diagnostic(RudeEditKind.InsertLocalFunctionIntoInterfaceMethod, "f3", CSharpFeaturesResources.local_function) }); } @@ -7331,7 +7337,7 @@ public void LocalFunction_AddStatic() edits.VerifyEdits( "Update [void M() { int local() { throw null; } }]@13 -> [void M() { static int local() { throw null; } }]@13"); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics(); } [Fact] @@ -7345,7 +7351,7 @@ public void LocalFunction_RemoveStatic() edits.VerifyEdits( "Update [void M() { static int local() { throw null; } }]@13 -> [void M() { int local() { throw null; } }]@13"); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics(); } [Fact] @@ -7359,7 +7365,7 @@ public void LocalFunction_AddUnsafe() edits.VerifyEdits( "Update [void M() { int local() { throw null; } }]@13 -> [void M() { unsafe int local() { throw null; } }]@13"); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics(); } [Fact] @@ -7373,7 +7379,7 @@ public void LocalFunction_RemoveUnsafe() edits.VerifyEdits( "Update [void M() { unsafe int local() { throw null; } }]@13 -> [void M() { int local() { throw null; } }]@13"); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics(); } [Fact] @@ -7384,7 +7390,7 @@ public void LocalFunction_AddAsync() var src2 = @"class Test { void M() { async Task local() => throw null; } }"; var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics(); } [Fact] @@ -7396,7 +7402,7 @@ public void LocalFunction_RemoveAsync() var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.ChangingFromAsynchronousToSynchronous, "local", FeaturesResources.local_function)); } @@ -7412,8 +7418,9 @@ public void LocalFunction_AddAttribute() "Update [void L() { }]@2 -> [[A]void L() { }]@2"); // Get top edits so we can validate rude edits - GetTopEdits(edits).VerifyRudeDiagnostics( - Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "L", FeaturesResources.local_function)); + GetTopEdits(edits).VerifySemanticDiagnostics( + new[] { Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "L", FeaturesResources.local_function) }, + capabilities: EditAndContinueCapabilities.Baseline); } [Fact] @@ -7428,8 +7435,9 @@ public void LocalFunction_RemoveAttribute() "Update [[A]void L() { }]@2 -> [void L() { }]@2"); // Get top edits so we can validate rude edits - GetTopEdits(edits).VerifyRudeDiagnostics( - Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "L", FeaturesResources.local_function)); + GetTopEdits(edits).VerifySemanticDiagnostics( + new[] { Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "L", FeaturesResources.local_function) }, + capabilities: EditAndContinueCapabilities.Baseline); } [Fact] @@ -7443,7 +7451,7 @@ public void LocalFunction_ReorderAttribute() edits.VerifyEdits("Update [[A, B]void L() { }]@2 -> [[B, A]void L() { }]@2"); // Get top edits so we can validate rude edits - GetTopEdits(edits).VerifyRudeDiagnostics(); + GetTopEdits(edits).VerifySemanticDiagnostics(); } [Fact] @@ -7457,7 +7465,7 @@ public void LocalFunction_CombineAttributeLists() edits.VerifyEdits( "Update [[A][B]void L() { }]@2 -> [[A, B]void L() { }]@2"); - GetTopEdits(edits).VerifyRudeDiagnostics(); + GetTopEdits(edits).VerifySemanticDiagnostics(); } [Fact] @@ -7471,7 +7479,7 @@ public void LocalFunction_SplitAttributeLists() edits.VerifyEdits( "Update [[A, B]void L() { }]@2 -> [[A][B]void L() { }]@2"); - GetTopEdits(edits).VerifyRudeDiagnostics(); + GetTopEdits(edits).VerifySemanticDiagnostics(); } [Fact] @@ -7484,9 +7492,13 @@ public void LocalFunction_ChangeAttributeListTarget1() edits.VerifyEdits("Update [[return: A]void L() { }]@2 -> [[A]void L() { }]@2"); - GetTopEdits(edits).VerifyRudeDiagnostics( - Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "L", FeaturesResources.local_function), - Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "L", FeaturesResources.local_function)); + GetTopEdits(edits).VerifySemanticDiagnostics( + new[] + { + Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "L", FeaturesResources.local_function), + Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "L", FeaturesResources.local_function) + }, + capabilities: EditAndContinueCapabilities.Baseline); } [Fact] @@ -7499,9 +7511,13 @@ public void LocalFunction_ChangeAttributeListTarget2() edits.VerifyEdits("Update [[A]void L() { }]@2 -> [[return: A]void L() { }]@2"); - GetTopEdits(edits).VerifyRudeDiagnostics( - Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "L", FeaturesResources.local_function), - Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "L", FeaturesResources.local_function)); + GetTopEdits(edits).VerifySemanticDiagnostics( + new[] + { + Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "L", FeaturesResources.local_function), + Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "L", FeaturesResources.local_function) + }, + capabilities: EditAndContinueCapabilities.Baseline); } [Fact] @@ -7515,8 +7531,9 @@ public void LocalFunction_ReturnType_AddAttribute() edits.VerifyEdits( "Update [int L() { return 1; }]@2 -> [[return: A]int L() { return 1; }]@2"); - GetTopEdits(edits).VerifyRudeDiagnostics( - Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "L", FeaturesResources.local_function)); + GetTopEdits(edits).VerifySemanticDiagnostics( + new[] { Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "L", FeaturesResources.local_function) }, + capabilities: EditAndContinueCapabilities.Baseline); } [Fact] @@ -7530,8 +7547,9 @@ public void LocalFunction_ReturnType_RemoveAttribute() edits.VerifyEdits( "Update [[return: A]int L() { return 1; }]@2 -> [int L() { return 1; }]@2"); - GetTopEdits(edits).VerifyRudeDiagnostics( - Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "L", FeaturesResources.local_function)); + GetTopEdits(edits).VerifySemanticDiagnostics( + new[] { Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "L", FeaturesResources.local_function) }, + capabilities: EditAndContinueCapabilities.Baseline); } [Fact] @@ -7544,7 +7562,7 @@ public void LocalFunction_ReturnType_ReorderAttribute() edits.VerifyEdits("Update [[return: A, B]int L() { return 1; }]@2 -> [[return: B, A]int L() { return 1; }]@2"); - GetTopEdits(edits).VerifyRudeDiagnostics(); + GetTopEdits(edits).VerifySemanticDiagnostics(); } [Fact] @@ -7558,8 +7576,9 @@ public void LocalFunction_Parameter_AddAttribute() edits.VerifyEdits( "Update [int i]@9 -> [[A]int i]@9"); - GetTopEdits(edits).VerifyRudeDiagnostics( - Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "L", FeaturesResources.parameter)); + GetTopEdits(edits).VerifySemanticDiagnostics( + new[] { Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "L", FeaturesResources.parameter) }, + capabilities: EditAndContinueCapabilities.Baseline); } [Fact] @@ -7573,8 +7592,9 @@ public void LocalFunction_Parameter_RemoveAttribute() edits.VerifyEdits( "Update [[A]int i]@9 -> [int i]@9"); - GetTopEdits(edits).VerifyRudeDiagnostics( - Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "L", FeaturesResources.parameter)); + GetTopEdits(edits).VerifySemanticDiagnostics( + new[] { Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "L", FeaturesResources.parameter) }, + capabilities: EditAndContinueCapabilities.Baseline); } [Fact] @@ -7587,7 +7607,7 @@ public void LocalFunction_Parameter_ReorderAttribute() edits.VerifyEdits("Update [[A, B]int i]@9 -> [[B, A]int i]@9"); - GetTopEdits(edits).VerifyRudeDiagnostics(); + GetTopEdits(edits).VerifySemanticDiagnostics(); } [Fact] @@ -7601,8 +7621,9 @@ public void LocalFunction_TypeParameter_AddAttribute() edits.VerifyEdits( "Update [T]@9 -> [[A] T]@9"); - GetTopEdits(edits).VerifyRudeDiagnostics( - Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "L", FeaturesResources.type_parameter)); + GetTopEdits(edits).VerifySemanticDiagnostics( + new[] { Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "L", FeaturesResources.type_parameter) }, + capabilities: EditAndContinueCapabilities.Baseline); } [Fact] @@ -7616,8 +7637,9 @@ public void LocalFunction_TypeParameter_RemoveAttribute() edits.VerifyEdits( "Update [[A] T]@9 -> [T]@9"); - GetTopEdits(edits).VerifyRudeDiagnostics( - Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "L", FeaturesResources.type_parameter)); + GetTopEdits(edits).VerifySemanticDiagnostics( + new[] { Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "L", FeaturesResources.type_parameter) }, + capabilities: EditAndContinueCapabilities.Baseline); } [Fact] @@ -7630,7 +7652,7 @@ public void LocalFunction_TypeParameter_ReorderAttribute() edits.VerifyEdits("Update [[A, B] T]@9 -> [[B, A] T]@9"); - GetTopEdits(edits).VerifyRudeDiagnostics(); + GetTopEdits(edits).VerifySemanticDiagnostics(); } [Fact] @@ -7644,7 +7666,7 @@ public void LocalFunctions_TypeParameter_Insert1() "Insert []@8", "Insert [A]@9"); - GetTopEdits(edits).VerifyRudeDiagnostics( + GetTopEdits(edits).VerifySemanticDiagnostics( Diagnostic(RudeEditKind.ChangingTypeParameters, "L", FeaturesResources.local_function)); } @@ -7659,7 +7681,7 @@ public void LocalFunctions_TypeParameter_Insert2() "Update []@8 -> []@8", "Insert [B]@11"); - GetTopEdits(edits).VerifyRudeDiagnostics( + GetTopEdits(edits).VerifySemanticDiagnostics( Diagnostic(RudeEditKind.ChangingTypeParameters, "L", FeaturesResources.local_function)); } @@ -7674,7 +7696,7 @@ public void LocalFunctions_TypeParameter_Delete1() "Delete []@8", "Delete [A]@9"); - GetTopEdits(edits).VerifyRudeDiagnostics( + GetTopEdits(edits).VerifySemanticDiagnostics( Diagnostic(RudeEditKind.ChangingTypeParameters, "L", FeaturesResources.local_function)); } @@ -7689,7 +7711,7 @@ public void LocalFunctions_TypeParameter_Delete2() "Update []@8 -> []@8", "Delete [A]@9"); - GetTopEdits(edits).VerifyRudeDiagnostics( + GetTopEdits(edits).VerifySemanticDiagnostics( Diagnostic(RudeEditKind.ChangingTypeParameters, "L", FeaturesResources.local_function)); } @@ -7703,7 +7725,7 @@ public void LocalFunctions_TypeParameter_Update() edits.VerifyEdits( "Update [A]@9 -> [B]@9"); - GetTopEdits(edits).VerifyRudeDiagnostics( + GetTopEdits(edits).VerifySemanticDiagnostics( Diagnostic(RudeEditKind.ChangingTypeParameters, "L", FeaturesResources.local_function)); } @@ -7720,7 +7742,7 @@ public void LocalFunctions_TypeParameter_Constraint_Clause_Update(string oldCons edits.VerifyEdits( "Update [where A : " + oldConstraint + "]@14 -> [where A : " + newConstraint + "]@14"); - GetTopEdits(edits).VerifyRudeDiagnostics( + GetTopEdits(edits).VerifySemanticDiagnostics( Diagnostic(RudeEditKind.ChangingTypeParameters, "L", FeaturesResources.local_function)); } @@ -7742,7 +7764,7 @@ public void LocalFunctions_TypeParameter_Constraint_Clause_Delete(string oldCons edits.VerifyEdits( "Delete [where A : " + oldConstraint + "]@14"); - GetTopEdits(edits).VerifyRudeDiagnostics( + GetTopEdits(edits).VerifySemanticDiagnostics( Diagnostic(RudeEditKind.ChangingTypeParameters, "L", FeaturesResources.local_function)); } @@ -7757,7 +7779,7 @@ public void LocalFunctions_TypeParameter_Constraint_Clause_Add() edits.VerifyEdits( "Insert [where B : System.IDisposable]@32"); - GetTopEdits(edits).VerifyRudeDiagnostics( + GetTopEdits(edits).VerifySemanticDiagnostics( Diagnostic(RudeEditKind.ChangingTypeParameters, "L", FeaturesResources.local_function)); } @@ -7771,7 +7793,7 @@ public void LocalFunctions_TypeParameter_Reorder() edits.VerifyEdits( "Reorder [B]@11 -> @9"); - GetTopEdits(edits).VerifyRudeDiagnostics( + GetTopEdits(edits).VerifySemanticDiagnostics( Diagnostic(RudeEditKind.ChangingTypeParameters, "L", FeaturesResources.local_function)); } @@ -7786,7 +7808,7 @@ public void LocalFunctions_TypeParameter_ReorderAndUpdate() "Reorder [B]@11 -> @9", "Update [A]@9 -> [C]@11"); - GetTopEdits(edits).VerifyRudeDiagnostics( + GetTopEdits(edits).VerifySemanticDiagnostics( Diagnostic(RudeEditKind.ChangingTypeParameters, "L", FeaturesResources.local_function)); } @@ -9149,7 +9171,8 @@ void F() } "; var edits = GetTopEdits(src1, src2); - edits.VerifySemanticDiagnostics(); + edits.VerifySemanticDiagnostics( + capabilities: EditAndContinueCapabilities.AddMethodToExistingType | EditAndContinueCapabilities.NewTypeDefinition); } #endregion @@ -9183,7 +9206,7 @@ static IEnumerable F() "; var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.ChangingStateMachineShape, "yield break;", CSharpFeaturesResources.yield_return_statement, CSharpFeaturesResources.yield_break_statement), Diagnostic(RudeEditKind.ChangingStateMachineShape, "yield return 4;", CSharpFeaturesResources.yield_break_statement, CSharpFeaturesResources.yield_return_statement)); } @@ -9233,7 +9256,7 @@ static IEnumerable F() "; var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.Delete, "{", CSharpFeaturesResources.yield_return_statement)); } @@ -9285,7 +9308,7 @@ static IEnumerable F() "; var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.Insert, "yield return 4;", CSharpFeaturesResources.yield_return_statement), Diagnostic(RudeEditKind.Insert, "yield return 2;", CSharpFeaturesResources.yield_return_statement)); } @@ -9319,7 +9342,10 @@ static IEnumerable F() edits.VerifySemanticDiagnostics( targetFrameworks: new[] { TargetFramework.Mscorlib40AndSystemCore }, - Diagnostic(RudeEditKind.UpdatingStateMachineMethodMissingAttribute, "static IEnumerable F()", "System.Runtime.CompilerServices.IteratorStateMachineAttribute")); + diagnostics: new[] + { + Diagnostic(RudeEditKind.UpdatingStateMachineMethodMissingAttribute, "static IEnumerable F()", "System.Runtime.CompilerServices.IteratorStateMachineAttribute") + }); } [Fact] @@ -9350,7 +9376,8 @@ static IEnumerable F() var edits = GetTopEdits(src1, src2); edits.VerifySemanticDiagnostics( - targetFrameworks: new[] { TargetFramework.Mscorlib40AndSystemCore }); + targetFrameworks: new[] { TargetFramework.Mscorlib40AndSystemCore }, + capabilities: EditAndContinueCapabilities.NewTypeDefinition); } #endregion @@ -9414,7 +9441,7 @@ static async Task F() } "; var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics(); } /// class Base { -}", new OptionsCollection(GetLanguage()), IDEDiagnosticIds.PreferBuiltInOrFrameworkTypeDiagnosticId, DiagnosticSeverity.Hidden); +}", IDEDiagnosticIds.PreferBuiltInOrFrameworkTypeDiagnosticId, DiagnosticSeverity.Hidden); } [WorkItem(40639, "https://github.com/dotnet/roslyn/issues/40639")] @@ -4856,7 +4856,7 @@ await TestDiagnosticInfoAsync( class Base { public void Foo(string s) { } -}", new OptionsCollection(GetLanguage()), IDEDiagnosticIds.PreferBuiltInOrFrameworkTypeDiagnosticId, DiagnosticSeverity.Hidden); +}", IDEDiagnosticIds.PreferBuiltInOrFrameworkTypeDiagnosticId, DiagnosticSeverity.Hidden); } [Theory, Trait(Traits.Feature, Traits.Features.CodeActionsSimplifyTypeNames)] @@ -6195,7 +6195,7 @@ void Goo() { var v = nameof([|System|].Int32); } -}", new OptionsCollection(GetLanguage()), IDEDiagnosticIds.SimplifyMemberAccessDiagnosticId, DiagnosticSeverity.Hidden); +}", IDEDiagnosticIds.SimplifyMemberAccessDiagnosticId, DiagnosticSeverity.Hidden); } [WorkItem(11380, "https://github.com/dotnet/roslyn/issues/11380")] diff --git a/src/EditorFeatures/CSharpTest/Squiggles/ErrorSquiggleProducerTests.cs b/src/EditorFeatures/CSharpTest/Squiggles/ErrorSquiggleProducerTests.cs index 599213a3cc41b..15e89613a0593 100644 --- a/src/EditorFeatures/CSharpTest/Squiggles/ErrorSquiggleProducerTests.cs +++ b/src/EditorFeatures/CSharpTest/Squiggles/ErrorSquiggleProducerTests.cs @@ -14,9 +14,7 @@ using Microsoft.CodeAnalysis.CSharp.Diagnostics.SimplifyTypeNames; using Microsoft.CodeAnalysis.CSharp.RemoveUnnecessaryImports; using Microsoft.CodeAnalysis.Diagnostics; -using Microsoft.CodeAnalysis.Editor.Implementation.Diagnostics; using Microsoft.CodeAnalysis.Editor.Implementation.IntelliSense.QuickInfo; -using Microsoft.CodeAnalysis.Editor.UnitTests; using Microsoft.CodeAnalysis.Editor.UnitTests.Diagnostics; using Microsoft.CodeAnalysis.Editor.UnitTests.Extensions; using Microsoft.CodeAnalysis.Editor.UnitTests.Squiggles; @@ -41,9 +39,15 @@ public class ErrorSquiggleProducerTests public async Task ErrorTagGeneratedForError() { var spans = await GetTagSpansAsync("class C {"); - Assert.Equal(1, spans.Count()); + var firstSpan = Assert.Single(spans); + Assert.Equal(PredefinedErrorTypeNames.SyntaxError, firstSpan.Tag.ErrorType); + } - var firstSpan = spans.First(); + [WpfFact, Trait(Traits.Feature, Traits.Features.ErrorSquiggles)] + public async Task ErrorTagGeneratedForErrorInSourceGeneratedDocument() + { + var spans = await GetTagSpansInSourceGeneratedDocumentAsync("class C {"); + var firstSpan = Assert.Single(spans); Assert.Equal(PredefinedErrorTypeNames.SyntaxError, firstSpan.Tag.ErrorType); } @@ -350,6 +354,20 @@ public LiveId() private static async Task>> GetTagSpansAsync(string content) { using var workspace = TestWorkspace.CreateCSharp(content, composition: SquiggleUtilities.CompositionWithSolutionCrawler); + return await GetTagSpansAsync(workspace); + } + + private static async Task>> GetTagSpansInSourceGeneratedDocumentAsync(string content) + { + using var workspace = TestWorkspace.CreateCSharp( + files: Array.Empty(), + sourceGeneratedFiles: new[] { content }, + composition: SquiggleUtilities.WpfCompositionWithSolutionCrawler); + return await GetTagSpansAsync(workspace); + } + + private static async Task>> GetTagSpansAsync(TestWorkspace workspace) + { return (await TestDiagnosticTagProducer.GetDiagnosticsAndErrorSpans(workspace)).Item2; } diff --git a/src/EditorFeatures/CSharpTest/Structure/MetadataAsSource/InvalidIdentifierStructureTests.cs b/src/EditorFeatures/CSharpTest/Structure/MetadataAsSource/InvalidIdentifierStructureTests.cs index 531afa24ce496..51eaa4d96c0af 100644 --- a/src/EditorFeatures/CSharpTest/Structure/MetadataAsSource/InvalidIdentifierStructureTests.cs +++ b/src/EditorFeatures/CSharpTest/Structure/MetadataAsSource/InvalidIdentifierStructureTests.cs @@ -29,7 +29,7 @@ public class InvalidIdentifierStructureTests : AbstractSyntaxStructureProviderTe internal override async Task> GetBlockSpansWorkerAsync(Document document, int position) { var outliningService = document.GetLanguageService(); - var options = BlockStructureOptions.From(document.Project); + var options = GetOptions(); return (await outliningService.GetBlockStructureAsync(document, options, CancellationToken.None)).Spans; } diff --git a/src/EditorFeatures/CSharpTest/SuggestionTags/SuggestionTagProducerTests.cs b/src/EditorFeatures/CSharpTest/SuggestionTags/SuggestionTagProducerTests.cs index 60a800bee0936..eca4d752ccc66 100644 --- a/src/EditorFeatures/CSharpTest/SuggestionTags/SuggestionTagProducerTests.cs +++ b/src/EditorFeatures/CSharpTest/SuggestionTags/SuggestionTagProducerTests.cs @@ -10,7 +10,6 @@ using System.Threading.Tasks; using Microsoft.CodeAnalysis.CSharp.UseObjectInitializer; using Microsoft.CodeAnalysis.Diagnostics; -using Microsoft.CodeAnalysis.Editor.Implementation.Diagnostics; using Microsoft.CodeAnalysis.Editor.Shared.Extensions; using Microsoft.CodeAnalysis.Editor.UnitTests.Squiggles; using Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces; diff --git a/src/EditorFeatures/CSharpTest/TextStructureNavigation/TextStructureNavigatorTests.cs b/src/EditorFeatures/CSharpTest/TextStructureNavigation/TextStructureNavigatorTests.cs index de37907b4c725..4c431f1d41e9a 100644 --- a/src/EditorFeatures/CSharpTest/TextStructureNavigation/TextStructureNavigatorTests.cs +++ b/src/EditorFeatures/CSharpTest/TextStructureNavigation/TextStructureNavigatorTests.cs @@ -2,14 +2,13 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -#nullable disable - using System; using System.Linq; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.Editor.CSharp.TextStructureNavigation; using Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces; using Microsoft.CodeAnalysis.Test.Utilities; +using Microsoft.CodeAnalysis.Test.Utilities.TextStructureNavigation; using Microsoft.VisualStudio.Text; using Microsoft.VisualStudio.Text.Operations; using Roslyn.Test.Utilities; @@ -18,356 +17,369 @@ namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.TextStructureNavigation { [UseExportProvider] - public class TextStructureNavigatorTests + public class TextStructureNavigatorTests : AbstractTextStructureNavigatorTests { + protected override string ContentType => ContentTypeNames.CSharpContentType; + + protected override TestWorkspace CreateWorkspace(string code) + => TestWorkspace.CreateCSharp(code); + [Fact, Trait(Traits.Feature, Traits.Features.TextStructureNavigator)] public void Empty() { - AssertExtent( - string.Empty, - pos: 0, - isSignificant: false, - start: 0, length: 0); + AssertExtent("$${|Insignificant:|}"); } [WpfFact, Trait(Traits.Feature, Traits.Features.TextStructureNavigator)] public void Whitespace() { AssertExtent( - " ", - pos: 0, - isSignificant: false, - start: 0, length: 3); + "$${|Insignificant: |}"); AssertExtent( - " ", - pos: 1, - isSignificant: false, - start: 0, length: 3); + "{|Insignificant: $$ |}"); AssertExtent( - " ", - pos: 3, - isSignificant: false, - start: 0, length: 3); + "{|Insignificant: $$|}"); } [WpfFact, Trait(Traits.Feature, Traits.Features.TextStructureNavigator)] public void EndOfFile() { AssertExtent( - "using System;", - pos: 13, - isSignificant: true, - start: 12, length: 1); + "using System{|Significant:;|}$$"); } [Fact, Trait(Traits.Feature, Traits.Features.TextStructureNavigator)] public void NewLine() { AssertExtent( - "class Class1 {\r\n\r\n}", - pos: 14, - isSignificant: false, - start: 14, length: 2); - - AssertExtent( - "class Class1 {\r\n\r\n}", - pos: 15, - isSignificant: false, - start: 14, length: 2); - - AssertExtent( - "class Class1 {\r\n\r\n}", - pos: 16, - isSignificant: false, - start: 16, length: 2); - + "class Class1 {$${|Insignificant:\r\n|}\r\n}"); AssertExtent( - "class Class1 {\r\n\r\n}", - pos: 17, - isSignificant: false, - start: 16, length: 2); + "class Class1 {\r\n$${|Insignificant:\r\n|}}"); } [WpfFact, Trait(Traits.Feature, Traits.Features.TextStructureNavigator)] public void SingleLineComment() { AssertExtent( - "// Comment ", - pos: 0, - isSignificant: true, - start: 0, length: 12); + "$${|Significant:// Comment |}"); // It is important that this returns just the comment banner. Returning the whole comment // means Ctrl+Right before the slash will cause it to jump across the entire comment AssertExtent( - "// Comment ", - pos: 1, - isSignificant: true, - start: 0, length: 2); + "{|Significant:/$$/|} Comment "); AssertExtent( - "// Comment ", - pos: 5, - isSignificant: true, - start: 3, length: 7); + "// {|Significant:Co$$mment|} "); AssertExtent( - "// () test", - pos: 4, - isSignificant: true, - start: 3, length: 2); + "// {|Significant:($$)|} test"); } [WpfFact, Trait(Traits.Feature, Traits.Features.TextStructureNavigator)] public void MultiLineComment() { AssertExtent( - "/* Comment */", - pos: 0, - isSignificant: true, - start: 0, length: 13); + @"{|Significant:$$/* Comment */|}"); // It is important that this returns just the comment banner. Returning the whole comment // means Ctrl+Right before the slash will cause it to jump across the entire comment AssertExtent( - "/* Comment */", - pos: 1, - isSignificant: true, - start: 0, length: 2); + @"{|Significant:/$$*|} Comment */"); AssertExtent( - "/* Comment */", - pos: 5, - isSignificant: true, - start: 3, length: 7); + @"/* {|Significant:Co$$mment|} */"); AssertExtent( - "/* () test */", - pos: 4, - isSignificant: true, - start: 3, length: 2); + @"/* {|Significant:($$)|} test */"); AssertExtent( - "/* () test */", - pos: 11, - isSignificant: true, - start: 11, length: 2); + @"/* () test {|Significant:$$*/|}"); // It is important that this returns just the comment banner. Returning the whole comment // means Ctrl+Left after the slash will cause it to jump across the entire comment AssertExtent( - "/* () test */", - pos: 12, - isSignificant: true, - start: 11, length: 2); + @"/* () test {|Significant:*$$/|}"); AssertExtent( - "/* () test */", - pos: 13, - isSignificant: true, - start: 11, length: 2); + @"/* () test {|Significant:*/|}$$"); } [WpfFact, Trait(Traits.Feature, Traits.Features.TextStructureNavigator)] public void Keyword() { - for (var i = 7; i <= 7 + 4; i++) - { - AssertExtent( - "public class Class1", - pos: i, - isSignificant: true, - start: 7, length: 5); - } + AssertExtent( + @"public {|Significant:$$class|} Class1"); + + AssertExtent( + @"public {|Significant:c$$lass|} Class1"); + + AssertExtent( + @"public {|Significant:cl$$ass|} Class1"); + + AssertExtent( + @"public {|Significant:cla$$ss|} Class1"); + + AssertExtent( + @"public {|Significant:clas$$s|} Class1"); } [WpfFact, Trait(Traits.Feature, Traits.Features.TextStructureNavigator)] public void Identifier() { - for (var i = 13; i <= 13 + 8; i++) - { - AssertExtent( - "public class SomeClass : IDisposable", - pos: i, - isSignificant: true, - start: 13, length: 9); - } + AssertExtent( + @"public class {|Significant:$$SomeClass|} : IDisposable"); + + AssertExtent( + @"public class {|Significant:S$$omeClass|} : IDisposable"); + + AssertExtent( + @"public class {|Significant:So$$meClass|} : IDisposable"); + + AssertExtent( + @"public class {|Significant:Som$$eClass|} : IDisposable"); + + AssertExtent( + @"public class {|Significant:Some$$Class|} : IDisposable"); + + AssertExtent( + @"public class {|Significant:SomeC$$lass|} : IDisposable"); + + AssertExtent( + @"public class {|Significant:SomeCl$$ass|} : IDisposable"); + + AssertExtent( + @"public class {|Significant:SomeCla$$ss|} : IDisposable"); + + AssertExtent( + @"public class {|Significant:SomeClas$$s|} : IDisposable"); } [WpfFact, Trait(Traits.Feature, Traits.Features.TextStructureNavigator)] public void EscapedIdentifier() { - for (var i = 12; i <= 12 + 9; i++) - { - AssertExtent( - "public enum @interface : int", - pos: i, - isSignificant: true, - start: 12, length: 10); - } + AssertExtent( + @"public enum {|Significant:$$@interface|} : int"); + + AssertExtent( + @"public enum {|Significant:@$$interface|} : int"); + + AssertExtent( + @"public enum {|Significant:@i$$nterface|} : int"); + + AssertExtent( + @"public enum {|Significant:@in$$terface|} : int"); + + AssertExtent( + @"public enum {|Significant:@int$$erface|} : int"); + + AssertExtent( + @"public enum {|Significant:@inte$$rface|} : int"); + + AssertExtent( + @"public enum {|Significant:@inter$$face|} : int"); + + AssertExtent( + @"public enum {|Significant:@interf$$ace|} : int"); + + AssertExtent( + @"public enum {|Significant:@interfa$$ce|} : int"); + + AssertExtent( + @"public enum {|Significant:@interfac$$e|} : int"); } [WpfFact, Trait(Traits.Feature, Traits.Features.TextStructureNavigator)] public void Number() { - for (var i = 37; i <= 37 + 10; i++) - { - AssertExtent( - "class Test { private double num = -1.234678e10; }", - pos: i, - isSignificant: true, - start: 37, length: 11); - } + AssertExtent( + @"class Test { private double num = -{|Significant:$$1.234678e10|}; }"); + + AssertExtent( + @"class Test { private double num = -{|Significant:1$$.234678e10|}; }"); + + AssertExtent( + @"class Test { private double num = -{|Significant:1.$$234678e10|}; }"); + + AssertExtent( + @"class Test { private double num = -{|Significant:1.2$$34678e10|}; }"); + + AssertExtent( + @"class Test { private double num = -{|Significant:1.23$$4678e10|}; }"); + + AssertExtent( + @"class Test { private double num = -{|Significant:1.234$$678e10|}; }"); + + AssertExtent( + @"class Test { private double num = -{|Significant:1.2346$$78e10|}; }"); + + AssertExtent( + @"class Test { private double num = -{|Significant:1.23467$$8e10|}; }"); + + AssertExtent( + @"class Test { private double num = -{|Significant:1.234678$$e10|}; }"); + + AssertExtent( + @"class Test { private double num = -{|Significant:1.234678e$$10|}; }"); + + AssertExtent( + @"class Test { private double num = -{|Significant:1.234678e1$$0|}; }"); } [WpfFact, Trait(Traits.Feature, Traits.Features.TextStructureNavigator)] public void String() { - const string TestString = "class Test { private string s1 = \" () test \"; }"; - var startOfString = TestString.IndexOf('"'); - var lengthOfStringIncludingQuotes = TestString.LastIndexOf('"') - startOfString + 1; - AssertExtent( - TestString, - pos: startOfString, - isSignificant: true, - start: startOfString, length: 1); + @"class Test { private string s1 = {|Significant:$$""|} () test ""; }"); - // Selects whitespace AssertExtent( - TestString, - pos: startOfString + 1, - isSignificant: false, - start: startOfString + 1, length: 1); + @"class Test { private string s1 = ""{|Insignificant:$$ |}() test ""; }"); AssertExtent( - TestString, - pos: startOfString + 2, - isSignificant: true, - start: startOfString + 2, length: 2); + @"class Test { private string s1 = "" {|Significant:$$()|} test ""; }"); AssertExtent( - TestString, - pos: TestString.IndexOf(" \"", StringComparison.Ordinal), - isSignificant: false, - start: TestString.IndexOf(" \"", StringComparison.Ordinal), length: 2); + @"class Test { private string s1 = "" () test{|Insignificant:$$ |}""; }"); AssertExtent( - TestString, - pos: TestString.LastIndexOf('"'), - isSignificant: true, - start: startOfString + lengthOfStringIncludingQuotes - 1, length: 1); + @"class Test { private string s1 = "" () test {|Significant:$$""|}; }"); AssertExtent( - TestString, - pos: TestString.LastIndexOf('"') + 1, - isSignificant: true, - start: TestString.LastIndexOf('"') + 1, length: 1); + @"class Test { private string s1 = "" () test ""{|Significant:$$;|} }"); } [WpfFact, Trait(Traits.Feature, Traits.Features.TextStructureNavigator)] public void InterpolatedString1() { - const string TestString = "class Test { string x = \"hello\"; string s = $\" { x } hello\"; }"; - - var startOfFirstString = TestString.IndexOf('"'); - var endOfFirstString = TestString.IndexOf('"', startOfFirstString + 1); - var startOfString = TestString.IndexOf("$\"", endOfFirstString + 1, StringComparison.Ordinal); - - // Selects interpolated string start token AssertExtent( - TestString, - pos: startOfString, - isSignificant: true, - start: startOfString, length: 2); + @"class Test { string x = ""hello""; string s = {|Significant:$$$""|} { x } hello""; }"); - // Selects whitespace AssertExtent( - TestString, - pos: startOfString + 2, - isSignificant: false, - start: startOfString + 2, length: 1); + @"class Test { string x = ""hello""; string s = $""{|Insignificant:$$ |}{ x } hello""; }"); - // Selects the opening curly brace AssertExtent( - TestString, - pos: startOfString + 3, - isSignificant: true, - start: startOfString + 3, length: 1); + @"class Test { string x = ""hello""; string s = $"" {|Significant:$${|} x } hello""; }"); - // Selects whitespace AssertExtent( - TestString, - pos: startOfString + 4, - isSignificant: false, - start: startOfString + 4, length: 1); + @"class Test { string x = ""hello""; string s = $"" {{|Insignificant:$$ |}x } hello""; }"); - // Selects identifier AssertExtent( - TestString, - pos: startOfString + 5, - isSignificant: true, - start: startOfString + 5, length: 1); + @"class Test { string x = ""hello""; string s = $"" { {|Significant:$$x|} } hello""; }"); - // Selects whitespace AssertExtent( - TestString, - pos: startOfString + 6, - isSignificant: false, - start: startOfString + 6, length: 1); + @"class Test { string x = ""hello""; string s = $"" { x{|Insignificant:$$ |}} hello""; }"); - // Selects the closing curly brace AssertExtent( - TestString, - pos: startOfString + 7, - isSignificant: true, - start: startOfString + 7, length: 1); + @"class Test { string x = ""hello""; string s = $"" { x {|Significant:$$}|} hello""; }"); - // Selects whitespace AssertExtent( - TestString, - pos: startOfString + 8, - isSignificant: false, - start: startOfString + 8, length: 1); + @"class Test { string x = ""hello""; string s = $"" { x }{|Insignificant:$$ |}hello""; }"); - // Selects hello AssertExtent( - TestString, - pos: startOfString + 9, - isSignificant: true, - start: startOfString + 9, length: 5); + @"class Test { string x = ""hello""; string s = $"" { x } {|Significant:$$hello|}""; }"); - // Selects closing quote AssertExtent( - TestString, - pos: startOfString + 14, - isSignificant: true, - start: startOfString + 14, length: 1); + @"class Test { string x = ""hello""; string s = $"" { x } hello{|Significant:$$""|}; }"); } - private static void AssertExtent(string code, int pos, bool isSignificant, int start, int length) + [WpfFact, Trait(Traits.Feature, Traits.Features.TextStructureNavigator)] + [WorkItem(59581, "https://github.com/dotnet/roslyn/issues/59581")] + public void TestRawStringContent() { - AssertExtent(code, pos, isSignificant, start, length, null); - AssertExtent(code, pos, isSignificant, start, length, Options.Script); + AssertExtent( + @"string s = """""" + Hello + {|Significant:$$World|}! + :) + """""";"); + + AssertExtent( + @"string s = """""" + Hello + {|Significant:W$$orld|}! + :) + """""";"); + + AssertExtent( + @"string s = """""" + Hello + {|Significant:Wo$$rld|}! + :) + """""";"); + + AssertExtent( + @"string s = """""" + Hello + {|Significant:Wor$$ld|}! + :) + """""";"); + + AssertExtent( + @"string s = """""" + Hello + {|Significant:Worl$$d|}! + :) + """""";"); + + AssertExtent( + @"string s = """""" + Hello + World{|Significant:$$!|} + :) + """""";"); } - private static void AssertExtent(string code, int pos, bool isSignificant, int start, int length, CSharpParseOptions options) + [WpfFact, Trait(Traits.Feature, Traits.Features.TextStructureNavigator)] + [WorkItem(59581, "https://github.com/dotnet/roslyn/issues/59581")] + public void TestRawStringDelimeter1() { - using var workspace = TestWorkspace.CreateCSharp(code, options); - var buffer = workspace.Documents.First().GetTextBuffer(); + AssertExtent( + @"string s = {|Significant:$$""""""|} + Hello + World! + :) + """""";"); - var provider = Assert.IsType( - workspace.GetService(ContentTypeNames.CSharpContentType)); + AssertExtent( + @"string s = {|Significant:""$$""""|} + Hello + World! + :) + """""";"); - var navigator = provider.CreateTextStructureNavigator(buffer); + AssertExtent( + @"string s = {|Significant:""""$$""|} + Hello + World! + :) + """""";"); + } - var extent = navigator.GetExtentOfWord(new SnapshotPoint(buffer.CurrentSnapshot, pos)); - Assert.Equal(isSignificant, extent.IsSignificant); + [WpfFact, Trait(Traits.Feature, Traits.Features.TextStructureNavigator)] + [WorkItem(59581, "https://github.com/dotnet/roslyn/issues/59581")] + public void TestRawStringDelimeter2() + { + AssertExtent( + @"string s = """""" + Hello + World! + :) + {|Significant:$$""""""|};"); - var expectedSpan = new SnapshotSpan(buffer.CurrentSnapshot, start, length); - Assert.Equal(expectedSpan, extent.Span); + AssertExtent( + @"string s = """""" + Hello + World! + :) + {|Significant:""$$""""|};"); + + AssertExtent( + @"string s = """""" + Hello + World! + :) + {|Significant:""""$$""|};"); } private static void TestNavigator( @@ -389,12 +401,12 @@ private static void TestNavigator( int startLength, int endPosition, int endLength, - CSharpParseOptions options) + CSharpParseOptions? options) { using var workspace = TestWorkspace.CreateCSharp(code, options); var buffer = workspace.Documents.First().GetTextBuffer(); - var provider = Assert.IsType( + var provider = Assert.IsType( workspace.GetService(ContentTypeNames.CSharpContentType)); var navigator = provider.CreateTextStructureNavigator(buffer); diff --git a/src/EditorFeatures/CSharpTest/TodoComment/NoCompilationTodoCommentTests.cs b/src/EditorFeatures/CSharpTest/TodoComment/NoCompilationTodoCommentTests.cs index 1c349c610f725..d2430d45c6f17 100644 --- a/src/EditorFeatures/CSharpTest/TodoComment/NoCompilationTodoCommentTests.cs +++ b/src/EditorFeatures/CSharpTest/TodoComment/NoCompilationTodoCommentTests.cs @@ -10,7 +10,6 @@ using System.Threading; using System.Threading.Tasks; using System.Xml.Linq; -using Microsoft.CodeAnalysis.Editor.Implementation.TodoComments; using Microsoft.CodeAnalysis.Editor.UnitTests; using Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces; using Microsoft.CodeAnalysis.Host.Mef; @@ -38,7 +37,6 @@ protected override TestWorkspace CreateWorkspace(string codeWithMarker) typeof(NoCompilationContentTypeLanguageService), typeof(NoCompilationTodoCommentService))); - workspace.SetOptions(workspace.Options.WithChangedOption(TodoCommentOptions.TokenList, DefaultTokenList)); return workspace; } diff --git a/src/EditorFeatures/CSharpTest/TodoComment/TodoCommentTests.cs b/src/EditorFeatures/CSharpTest/TodoComment/TodoCommentTests.cs index d0afce28ba083..ee8d13571d5d9 100644 --- a/src/EditorFeatures/CSharpTest/TodoComment/TodoCommentTests.cs +++ b/src/EditorFeatures/CSharpTest/TodoComment/TodoCommentTests.cs @@ -5,7 +5,6 @@ #nullable disable using System.Threading.Tasks; -using Microsoft.CodeAnalysis.Editor.Implementation.TodoComments; using Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces; using Microsoft.CodeAnalysis.Test.Utilities; using Microsoft.CodeAnalysis.Test.Utilities.TodoComments; @@ -17,11 +16,7 @@ namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.TodoComment public class TodoCommentTests : AbstractTodoCommentTests { protected override TestWorkspace CreateWorkspace(string codeWithMarker) - { - var workspace = TestWorkspace.CreateCSharp(codeWithMarker); - workspace.SetOptions(workspace.Options.WithChangedOption(TodoCommentOptions.TokenList, DefaultTokenList)); - return workspace; - } + => TestWorkspace.CreateCSharp(codeWithMarker); [Fact] public async Task SingleLineTodoComment_Colon() diff --git a/src/EditorFeatures/CSharpTest/TransposeRecordKeyword/TransposeRecordKeywordTests.cs b/src/EditorFeatures/CSharpTest/TransposeRecordKeyword/TransposeRecordKeywordTests.cs new file mode 100644 index 0000000000000..34552e7c45b06 --- /dev/null +++ b/src/EditorFeatures/CSharpTest/TransposeRecordKeyword/TransposeRecordKeywordTests.cs @@ -0,0 +1,172 @@ +ο»Ώ// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Threading.Tasks; +using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.CSharp.CodeFixes.TransposeRecordKeyword; +using Microsoft.CodeAnalysis.Editor.UnitTests.CodeActions; +using Microsoft.CodeAnalysis.Testing; +using Xunit; + +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.TransposeRecordKeyword +{ + using VerifyCS = CSharpCodeFixVerifier< + EmptyDiagnosticAnalyzer, + CSharpTransposeRecordKeywordCodeFixProvider>; + + public class TransposeRecordKeywordTests + { + [Fact] + public async Task TestStructRecord() + { + await new VerifyCS.Test + { + TestCode = @"struct {|CS9012:record|} C { }", + FixedCode = @"record struct C { }", + LanguageVersion = LanguageVersion.CSharp10 + }.RunAsync(); + } + + [Fact] + public async Task TestClassRecord() + { + await new VerifyCS.Test + { + TestCode = @"class {|CS9012:record|} C { }", + FixedCode = @"record class C { }", + LanguageVersion = LanguageVersion.CSharp10 + }.RunAsync(); + } + + [Fact] + public async Task TestWithModifiers() + { + await new VerifyCS.Test + { + TestCode = @"public struct {|CS9012:record|} C { }", + FixedCode = @"public record struct C { }", + LanguageVersion = LanguageVersion.CSharp10 + }.RunAsync(); + } + + [Fact] + public async Task TestWithComment() + { + await new VerifyCS.Test + { + TestCode = @" +// my struct +public struct {|CS9012:record|} C { }", + FixedCode = @" +// my struct +public record struct C { }", + LanguageVersion = LanguageVersion.CSharp10 + }.RunAsync(); + } + + [Fact] + public async Task TestWithDocComment() + { + await new VerifyCS.Test + { + TestCode = @" +/// +public struct {|CS9012:record|} C { }", + FixedCode = @" +/// +public record struct C { }", + LanguageVersion = LanguageVersion.CSharp10 + }.RunAsync(); + } + + [Fact] + public async Task TestWithAttributes1() + { + await new VerifyCS.Test + { + TestCode = @" +[System.CLSCompliant(false)] +struct {|CS9012:record|} C { }", + FixedCode = @" +[System.CLSCompliant(false)] +record struct C { }", + LanguageVersion = LanguageVersion.CSharp10 + }.RunAsync(); + } + + [Fact] + public async Task TestWithAttributes2() + { + await new VerifyCS.Test + { + TestCode = @" +[System.CLSCompliant(false)] struct {|CS9012:record|} C { }", + FixedCode = @" +[System.CLSCompliant(false)] record struct C { }", + LanguageVersion = LanguageVersion.CSharp10 + }.RunAsync(); + } + + [Fact] + public async Task TestNestedRecord() + { + await new VerifyCS.Test + { + TestCode = @" +class {|CS9012:record|} C +{ + struct {|CS9012:record|} D { } +}", + FixedCode = @" +record class C +{ + record struct D { } +}", + LanguageVersion = LanguageVersion.CSharp10 + }.RunAsync(); + } + + [Fact] + public async Task TestNestedRecordWithComments() + { + await new VerifyCS.Test + { + TestCode = @" +// my class +class {|CS9012:record|} C +{ + // my struct + struct {|CS9012:record|} D { } +}", + FixedCode = @" +// my class +record class C +{ + // my struct + record struct D { } +}", + LanguageVersion = LanguageVersion.CSharp10 + }.RunAsync(); + } + + [Fact] + public async Task TestTriviaBeforeAfter() + { + await new VerifyCS.Test + { + TestCode = @" +/*1*/ +class /**/ +/*3*/ +{|CS9012:record|} /*4*/ C { }", + FixedCode = @" +/*1*/ +record /**/ +/*3*/ +class /*4*/ C { }", + LanguageVersion = LanguageVersion.CSharp10 + }.RunAsync(); + } + } +} diff --git a/src/EditorFeatures/CSharpTest/UseExpressionBody/Refactoring/UseExpressionBodyForMethodsRefactoringTests.cs b/src/EditorFeatures/CSharpTest/UseExpressionBody/Refactoring/UseExpressionBodyForMethodsRefactoringTests.cs index 04c006bb5d3bf..38d3b172a24be 100644 --- a/src/EditorFeatures/CSharpTest/UseExpressionBody/Refactoring/UseExpressionBodyForMethodsRefactoringTests.cs +++ b/src/EditorFeatures/CSharpTest/UseExpressionBody/Refactoring/UseExpressionBodyForMethodsRefactoringTests.cs @@ -2,8 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -#nullable disable - using System.Threading.Tasks; using Microsoft.CodeAnalysis.CodeRefactorings; using Microsoft.CodeAnalysis.CodeStyle; @@ -223,5 +221,26 @@ void Goo() } }", parameters: new TestParameters(options: UseBlockBody)); } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseExpressionBody)] + [WorkItem(53532, "https://github.com/dotnet/roslyn/issues/53532")] + public async Task TestTriviaOnArrow1() + { + await TestInRegularAndScript1Async( +@"class C +{ + void M() + // Test + [||]=> Console.WriteLine(); +}", +@"class C +{ + void M() + { + // Test + Console.WriteLine(); + } +}", parameters: new TestParameters(options: UseExpressionBody)); + } } } diff --git a/src/EditorFeatures/CSharpTest/Workspaces/WorkspaceTests.cs b/src/EditorFeatures/CSharpTest/Workspaces/WorkspaceTests.cs index cf4a26490a9f3..fcd410160483d 100644 --- a/src/EditorFeatures/CSharpTest/Workspaces/WorkspaceTests.cs +++ b/src/EditorFeatures/CSharpTest/Workspaces/WorkspaceTests.cs @@ -6,17 +6,19 @@ using System; using System.Collections.Generic; +using System.Collections.Immutable; using System.Linq; using System.Threading; using System.Threading.Tasks; +using System.Xml.Linq; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Editor.UnitTests; using Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces; +using Microsoft.CodeAnalysis.Formatting; using Microsoft.CodeAnalysis.Options; using Microsoft.CodeAnalysis.Shared.Extensions; using Microsoft.CodeAnalysis.Shared.TestHooks; -using Microsoft.CodeAnalysis.SolutionCrawler; using Microsoft.CodeAnalysis.Test.Utilities; using Microsoft.CodeAnalysis.Text; using Microsoft.VisualStudio.Text; @@ -783,6 +785,75 @@ public async Task TestDocumentEvents() shortEventTimeout.Seconds)); } + [Fact] + public async Task TestSourceGeneratedDocumentEvents() + { + var doc1Text = "public class C { }"; + var workspaceElement = $@" + + {new XText(doc1Text)} + +"; + using var workspace = TestWorkspace.Create(workspaceElement, composition: EditorTestCompositions.EditorFeatures); + var document = workspace.Documents.Single(); + + var longEventTimeout = TimeSpan.FromMinutes(5); + var shortEventTimeout = TimeSpan.FromSeconds(5); + + // Creating two waiters that will allow us to know for certain if the events have fired. + using var closeWaiter = new EventWaiter(); + using var openWaiter = new EventWaiter(); + + // Wrapping event handlers so they can notify us on being called. + var documentOpenedEventHandler = openWaiter.Wrap( + (sender, args) => Assert.True(args.Document.Id == document.Id, + $"The source generated document given to the '{nameof(Workspace.DocumentOpened)}' event handler did not have the same id as the one created for the test.")); + + var documentClosedEventHandler = closeWaiter.Wrap( + (sender, args) => Assert.True(args.Document.Id == document.Id, + $"The source generated document given to the '{nameof(Workspace.DocumentClosed)}' event handler did not have the same id as the one created for the test.")); + + workspace.DocumentOpened += documentOpenedEventHandler; + workspace.DocumentClosed += documentClosedEventHandler; + + workspace.OpenSourceGeneratedDocument(document.Id); + var sourceGeneratedDocumentId = workspace.GetDocumentIdInCurrentContext(document.GetOpenTextContainer()); + Assert.Equal(document.Id, sourceGeneratedDocumentId); + + await workspace.CloseSourceGeneratedDocumentAsync(sourceGeneratedDocumentId); + + // Wait for all workspace tasks to finish. After this is finished executing, all handlers should have been notified. + await WaitForWorkspaceOperationsToComplete(workspace); + + // Wait to receive signal that events have fired. + Assert.True(openWaiter.WaitForEventToFire(longEventTimeout), + string.Format("event 'DocumentOpened' was not fired within {0} minutes.", + longEventTimeout.Minutes)); + + Assert.True(closeWaiter.WaitForEventToFire(longEventTimeout), + string.Format("event 'DocumentClosed' was not fired within {0} minutes.", + longEventTimeout.Minutes)); + + workspace.DocumentOpened -= documentOpenedEventHandler; + workspace.DocumentClosed -= documentClosedEventHandler; + + workspace.OpenSourceGeneratedDocument(document.Id); + await workspace.CloseSourceGeneratedDocumentAsync(document.Id); + + // Wait for all workspace tasks to finish. After this is finished executing, all handlers should have been notified. + await WaitForWorkspaceOperationsToComplete(workspace); + + // Verifying that an event has not been called is difficult to prove. + // All events should have already been called so we wait 5 seconds and then assume the event handler was removed correctly. + Assert.False(openWaiter.WaitForEventToFire(shortEventTimeout), + string.Format("event handler 'DocumentOpened' was called within {0} seconds though it was removed from the list.", + shortEventTimeout.Seconds)); + + Assert.False(closeWaiter.WaitForEventToFire(shortEventTimeout), + string.Format("event handler 'DocumentClosed' was called within {0} seconds though it was removed from the list.", + shortEventTimeout.Seconds)); + } + [Fact] public async Task TestAdditionalFile_Properties() { @@ -1207,20 +1278,20 @@ public void TestSolutionWithOptions() workspace.AddTestProject(project1); var solution = workspace.CurrentSolution; - var optionKey = new OptionKey2(SolutionCrawlerOptions.BackgroundAnalysisScopeOption, LanguageNames.CSharp); + var optionKey = new OptionKey2(FormattingOptions.SmartIndent, LanguageNames.CSharp); var optionValue = solution.Options.GetOption(optionKey); - Assert.Equal(BackgroundAnalysisScope.Default, optionValue); + Assert.Equal(FormattingOptions.IndentStyle.Smart, optionValue); - var newOptions = solution.Options.WithChangedOption(optionKey, BackgroundAnalysisScope.ActiveFile); + var newOptions = solution.Options.WithChangedOption(optionKey, FormattingOptions.IndentStyle.Block); var newSolution = solution.WithOptions(newOptions); var newOptionValue = newSolution.Options.GetOption(optionKey); - Assert.Equal(BackgroundAnalysisScope.ActiveFile, newOptionValue); + Assert.Equal(FormattingOptions.IndentStyle.Block, newOptionValue); var applied = workspace.TryApplyChanges(newSolution); Assert.True(applied); var currentOptionValue = workspace.CurrentSolution.Options.GetOption(optionKey); - Assert.Equal(BackgroundAnalysisScope.ActiveFile, currentOptionValue); + Assert.Equal(FormattingOptions.IndentStyle.Block, currentOptionValue); } [CombinatorialData] @@ -1241,9 +1312,9 @@ public void TestOptionChangedHandlerInvokedAfterCurrentSolutionChanged(bool test var beforeSolutionForPrimaryWorkspace = primaryWorkspace.CurrentSolution; var beforeSolutionForSecondaryWorkspace = secondaryWorkspace.CurrentSolution; - var optionKey = new OptionKey2(SolutionCrawlerOptions.BackgroundAnalysisScopeOption, LanguageNames.CSharp); - Assert.Equal(BackgroundAnalysisScope.Default, primaryWorkspace.Options.GetOption(optionKey)); - Assert.Equal(BackgroundAnalysisScope.Default, secondaryWorkspace.Options.GetOption(optionKey)); + var optionKey = new OptionKey2(FormattingOptions.SmartIndent, LanguageNames.CSharp); + Assert.Equal(FormattingOptions.IndentStyle.Smart, primaryWorkspace.Options.GetOption(optionKey)); + Assert.Equal(FormattingOptions.IndentStyle.Smart, secondaryWorkspace.Options.GetOption(optionKey)); // Hook up the option changed event handler. var optionService = primaryWorkspace.Services.GetRequiredService(); @@ -1253,12 +1324,12 @@ public void TestOptionChangedHandlerInvokedAfterCurrentSolutionChanged(bool test if (testDeprecatedOptionsSetter) { #pragma warning disable CS0618 // Type or member is obsolete - this test ensures that deprecated "Workspace.set_Options" API's functionality is preserved. - primaryWorkspace.Options = primaryWorkspace.Options.WithChangedOption(optionKey, BackgroundAnalysisScope.ActiveFile); + primaryWorkspace.Options = primaryWorkspace.Options.WithChangedOption(optionKey, FormattingOptions.IndentStyle.Block); #pragma warning restore CS0618 // Type or member is obsolete } else { - primaryWorkspace.SetOptions(primaryWorkspace.Options.WithChangedOption(optionKey, BackgroundAnalysisScope.ActiveFile)); + primaryWorkspace.SetOptions(primaryWorkspace.Options.WithChangedOption(optionKey, FormattingOptions.IndentStyle.Block)); } // Verify current solution and option change for both workspaces. @@ -1282,9 +1353,9 @@ static void VerifyCurrentSolutionAndOptionChange(Workspace workspace, Solution b Assert.NotEqual(beforeOptionChangedSolution, currentSolution); // Verify workspace.CurrentSolution has changed option. - var optionKey = new OptionKey2(SolutionCrawlerOptions.BackgroundAnalysisScopeOption, LanguageNames.CSharp); - Assert.Equal(BackgroundAnalysisScope.Default, beforeOptionChangedSolution.Options.GetOption(optionKey)); - Assert.Equal(BackgroundAnalysisScope.ActiveFile, currentSolution.Options.GetOption(optionKey)); + var optionKey = new OptionKey2(FormattingOptions.SmartIndent, LanguageNames.CSharp); + Assert.Equal(FormattingOptions.IndentStyle.Smart, beforeOptionChangedSolution.Options.GetOption(optionKey)); + Assert.Equal(FormattingOptions.IndentStyle.Block, currentSolution.Options.GetOption(optionKey)); } } } diff --git a/src/EditorFeatures/CSharpTest/Wrapping/AbstractWrappingTests.cs b/src/EditorFeatures/CSharpTest/Wrapping/AbstractWrappingTests.cs index 99210d479517f..3deec5f47d93a 100644 --- a/src/EditorFeatures/CSharpTest/Wrapping/AbstractWrappingTests.cs +++ b/src/EditorFeatures/CSharpTest/Wrapping/AbstractWrappingTests.cs @@ -9,7 +9,9 @@ using Microsoft.CodeAnalysis.CodeActions; using Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.CodeRefactorings; using Microsoft.CodeAnalysis.Editor.UnitTests.CodeActions; -using Microsoft.CodeAnalysis.Formatting; +using Microsoft.CodeAnalysis.ExtractMethod; +using Microsoft.CodeAnalysis.ImplementType; +using Microsoft.CodeAnalysis.SymbolSearch; namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Wrapping { @@ -18,17 +20,26 @@ public abstract class AbstractWrappingTests : AbstractCSharpCodeActionTest protected sealed override ImmutableArray MassageActions(ImmutableArray actions) => FlattenActions(actions); - private protected OptionsCollection GetIndentionColumn(int column) - => new OptionsCollection(GetLanguage()) - { - { FormattingOptions2.PreferredWrappingColumn, column } - }; + private protected static CodeActionOptions GetIndentionColumn(int column) + => new(SymbolSearchOptions.Default, + ImplementTypeOptions.Default, + ExtractMethodOptions.Default, + WrappingColumn: column); protected Task TestAllWrappingCasesAsync( string input, params string[] outputs) { - return TestAllWrappingCasesAsync(input, options: null, outputs); + return TestAllWrappingCasesAsync(input, options: CodeActionOptions.Default, outputs); + } + + private protected Task TestAllWrappingCasesAsync( + string input, + CodeActionOptions options, + params string[] outputs) + { + var parameters = new TestParameters(codeActionOptions: options); + return TestAllInRegularAndScriptAsync(input, parameters, outputs); } private protected Task TestAllWrappingCasesAsync( diff --git a/src/EditorFeatures/CSharpTest/Wrapping/InitializerExpressionWrappingTests.cs b/src/EditorFeatures/CSharpTest/Wrapping/InitializerExpressionWrappingTests.cs new file mode 100644 index 0000000000000..a50ebf963609e --- /dev/null +++ b/src/EditorFeatures/CSharpTest/Wrapping/InitializerExpressionWrappingTests.cs @@ -0,0 +1,577 @@ +ο»Ώ// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Threading.Tasks; +using Microsoft.CodeAnalysis.CodeRefactorings; +using Microsoft.CodeAnalysis.CSharp.Wrapping; +using Microsoft.CodeAnalysis.Test.Utilities; +using Roslyn.Test.Utilities; +using Xunit; + +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Wrapping +{ + public class IntializerExpressionWrappingTests : AbstractWrappingTests + { + protected override CodeRefactoringProvider CreateCodeRefactoringProvider(Workspace workspace, TestParameters parameters) + => new CSharpWrappingCodeRefactoringProvider(); + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsWrapping)] + public async Task TestNoWrappingSuggestions() + { + await TestMissingAsync( +@"class C { + void Bar() { + var test = new[] [||]{ 1 }; + } +}"); + } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsWrapping)] + [WorkItem(59624, "https://github.com/dotnet/roslyn/issues/59624")] + public async Task TestNoWrappingSuggestions_TrailingComma() + { + await TestMissingAsync( +@"class C { + void Bar() { + var test = new[] [||]{ 1, }; + } +}"); + } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsWrapping)] + public async Task TestWrappingShortInitializerExpression() + { + await TestAllWrappingCasesAsync( +@"class C { + void Bar() { + var test = new[] [||]{ 1, 2 }; + } +}", +@"class C { + void Bar() { + var test = new[] + { + 1, + 2 + }; + } +}", +@"class C { + void Bar() { + var test = new[] + { + 1, 2 + }; + } +}"); + } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsWrapping)] + [WorkItem(59624, "https://github.com/dotnet/roslyn/issues/59624")] + public async Task TestWrappingShortInitializerExpression_TrailingComma() + { + await TestAllWrappingCasesAsync( +@"class C { + void Bar() { + var test = new[] [||]{ 1, 2, }; + } +}", +@"class C { + void Bar() { + var test = new[] + { + 1, + 2, + }; + } +}", +@"class C { + void Bar() { + var test = new[] + { + 1, 2, + }; + } +}"); + } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsWrapping)] + public async Task TestWrappingLongIntializerExpression() + { + await TestAllWrappingCasesAsync( +@"class C { + void Bar() { + var test = new[] [||]{ ""the"", ""quick"", ""brown"", ""fox"", ""jumps"", ""over"", ""the"", ""lazy"", ""dog"" }; + } +}", +@"class C { + void Bar() { + var test = new[] + { + ""the"", + ""quick"", + ""brown"", + ""fox"", + ""jumps"", + ""over"", + ""the"", + ""lazy"", + ""dog"" + }; + } +}", +@"class C { + void Bar() { + var test = new[] + { + ""the"", ""quick"", ""brown"", ""fox"", ""jumps"", ""over"", ""the"", ""lazy"", ""dog"" + }; + } +}" +); + } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsWrapping)] + public async Task TestWrappingMultiLineLongIntializerExpression() + { + await TestAllWrappingCasesAsync( +@"class C { + void Bar() { + var test = new[] [||]{ ""the"", ""quick"", ""brown"", ""fox"", ""jumps"", ""over"", ""the"", ""lazy"", ""dog"", ""the"", ""quick"", ""brown"", ""fox"", ""jumps"", ""over"", ""the"", ""lazy"", ""dog"" }; + } +}", +@"class C { + void Bar() { + var test = new[] + { + ""the"", + ""quick"", + ""brown"", + ""fox"", + ""jumps"", + ""over"", + ""the"", + ""lazy"", + ""dog"", + ""the"", + ""quick"", + ""brown"", + ""fox"", + ""jumps"", + ""over"", + ""the"", + ""lazy"", + ""dog"" + }; + } +}", +@"class C { + void Bar() { + var test = new[] + { + ""the"", ""quick"", ""brown"", ""fox"", ""jumps"", ""over"", ""the"", ""lazy"", ""dog"", ""the"", ""quick"", ""brown"", ""fox"", + ""jumps"", ""over"", ""the"", ""lazy"", ""dog"" + }; + } +}" +); + } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsWrapping)] + public async Task TestShortInitializerExpressionRefactorings() + { + await TestAllWrappingCasesAsync( +@"class C { + void Bar() { + var test = new[] + [||]{ + 1, + 2 + }; + } +}", +@"class C { + void Bar() { + var test = new[] { 1, 2 }; + } +}", +@"class C { + void Bar() { + var test = new[] + { + 1, 2 + }; + } +}"); + } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsWrapping)] + public async Task TestLongIntializerExpressionRefactorings() + { + await TestAllWrappingCasesAsync( +@"class C { + void Bar() { + var test = new[] + [||]{ + ""the"", ""quick"", ""brown"", ""fox"", ""jumps"", ""over"", ""the"", ""lazy"", ""dog"" + }; + } +}", +@"class C { + void Bar() { + var test = new[] + { + ""the"", + ""quick"", + ""brown"", + ""fox"", + ""jumps"", + ""over"", + ""the"", + ""lazy"", + ""dog"" + }; + } +}", +@"class C { + void Bar() { + var test = new[] { ""the"", ""quick"", ""brown"", ""fox"", ""jumps"", ""over"", ""the"", ""lazy"", ""dog"" }; + } +}" +); + } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsWrapping)] + public async Task TestListWrappingIntializerExpression() + { + await TestAllWrappingCasesAsync( +@"class C { + void Bar() { + var test = new List [||]{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + } +}", +@"class C { + void Bar() { + var test = new List + { + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9 + }; + } +}", +@"class C { + void Bar() { + var test = new List + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 + }; + } +}" +); + } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsWrapping)] + public async Task TestWrappedListIntializerExpression() + { + await TestAllWrappingCasesAsync( +@"class C { + void Bar() { + var test = new List + [||]{ + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9 + }; + } +}", +@"class C { + void Bar() { + var test = new List { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + } +}", +@"class C { + void Bar() { + var test = new List + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 + }; + } +}" +); + } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsWrapping)] + public async Task TestObjectWrappingIntializerExpression() + { + await TestAllWrappingCasesAsync( +@"class C { + void Bar() { + var test = new List [||]{ new A { B = 1, C = 1 }, new A { B = 2, C = 2 }, new A { B = 3, C = 3 } }; + } +}", +@"class C { + void Bar() { + var test = new List + { + new A { B = 1, C = 1 }, + new A { B = 2, C = 2 }, + new A { B = 3, C = 3 } + }; + } +}", +@"class C { + void Bar() { + var test = new List + { + new A { B = 1, C = 1 }, new A { B = 2, C = 2 }, new A { B = 3, C = 3 } + }; + } +}" +); + } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsWrapping)] + public async Task TestWrappedObjectIntializerExpression() + { + await TestAllWrappingCasesAsync( +@"class C { + void Bar() { + var test = new List + [||]{ + new A { B = 1, C = 1 }, + new A { B = 2, C = 2 }, + new A { B = 3, C = 3 } + }; + } +}", +@"class C { + void Bar() { + var test = new List { new A { B = 1, C = 1 }, new A { B = 2, C = 2 }, new A { B = 3, C = 3 } }; + } +}", +@"class C { + void Bar() { + var test = new List + { + new A { B = 1, C = 1 }, new A { B = 2, C = 2 }, new A { B = 3, C = 3 } + }; + } +}" +); + } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsWrapping)] + public async Task TestReturnIntializerExpression() + { + await TestAllWrappingCasesAsync( +@"class C { + void Bar() { + return new List [||]{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + } +}", +@"class C { + void Bar() { + return new List + { + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9 + }; + } +}", +@"class C { + void Bar() { + return new List + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 + }; + } +}" +); + } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsWrapping)] + public async Task TestWrappedReturnIntializerExpression() + { + await TestAllWrappingCasesAsync( +@"class C { + void Bar() { + return new List + [||]{ + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9 + }; + } +}", +@"class C { + void Bar() { + return new List { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + } +}", +@"class C { + void Bar() { + return new List + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 + }; + } +}" +); + } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsWrapping)] + public async Task TestClassPropertyIntializerExpressionRefactorings() + { + await TestAllWrappingCasesAsync( +@"public class C { + public List B => new List [||]{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; +}", +@"public class C { + public List B => new List + { + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9 + }; +}", +@"public class C { + public List B => new List + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 + }; +}" +); + } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsWrapping)] + public async Task TestWrappedClassPropertyIntializerExpressionRefactorings() + { + await TestAllWrappingCasesAsync( +@"public class C { + public List B => new List + [||]{ + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9 + }; +}", +@"public class C { + public List B => new List { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; +}", +@"public class C { + public List B => new List + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 + }; +}" +); + } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsWrapping)] + public async Task TestArgumentIntializerExpressionRefactorings() + { + await TestAllWrappingCasesAsync( +@"public void F() { + var result = fakefunction(new List [||]{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }); +}", +@"public void F() { + var result = fakefunction(new List + { + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9 + }); +}", +@"public void F() { + var result = fakefunction(new List + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 + }); +}" +); + } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsWrapping)] + public async Task TestWrappedArgumentIntializerExpressionRefactorings() + { + await TestAllWrappingCasesAsync( +@"public void F() { + var result = fakefunction(new List + [||]{ + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9 + }); +}", +@"public void F() { + var result = fakefunction(new List { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }); +}", +@"public void F() { + var result = fakefunction(new List + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 + }); +}" +); + } + } +} diff --git a/src/EditorFeatures/CSharpTest/Wrapping/ParameterWrappingTests.cs b/src/EditorFeatures/CSharpTest/Wrapping/ParameterWrappingTests.cs index e6f1d1c514d27..d20d0c72cdbe2 100644 --- a/src/EditorFeatures/CSharpTest/Wrapping/ParameterWrappingTests.cs +++ b/src/EditorFeatures/CSharpTest/Wrapping/ParameterWrappingTests.cs @@ -9,6 +9,7 @@ using Microsoft.CodeAnalysis.CSharp.Test.Utilities; using Microsoft.CodeAnalysis.CSharp.Wrapping; using Microsoft.CodeAnalysis.Test.Utilities; +using Roslyn.Test.Utilities; using Xunit; namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Wrapping @@ -810,6 +811,22 @@ public C(int i, }"); } + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsWrapping)] + [WorkItem(38986, "https://github.com/dotnet/roslyn/issues/38986")] + public async Task TestInConstructorWithSyntaxErrorAfter() + { + await TestInRegularAndScript1Async( +@"class C { + public [||]C(int i, int j) : base(,) { + } +}", +@"class C { + public C(int i, + int j) : base(,) { + } +}"); + } + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsWrapping)] public async Task TestInIndexer() { diff --git a/src/EditorFeatures/CSharpTest2/EmbeddedLanguages/Json/CSharpJsonParserTests_BasicTests.cs b/src/EditorFeatures/CSharpTest2/EmbeddedLanguages/Json/CSharpJsonParserTests_BasicTests.cs index 84db8de6c6532..350f9bdec9ddd 100644 --- a/src/EditorFeatures/CSharpTest2/EmbeddedLanguages/Json/CSharpJsonParserTests_BasicTests.cs +++ b/src/EditorFeatures/CSharpTest2/EmbeddedLanguages/Json/CSharpJsonParserTests_BasicTests.cs @@ -1168,7 +1168,7 @@ public void TestMissingColon() ", @" - + ", @" @@ -1328,10 +1328,10 @@ public void TestNestedPropertyMissingColon() ", @" - + ", @" - + "); } @@ -1367,10 +1367,10 @@ public void TestMissingColon2() ", @" - + ", @" - + "); } diff --git a/src/EditorFeatures/CSharpTest2/EmbeddedLanguages/Json/CSharpJsonParserTests_NstTests.cs b/src/EditorFeatures/CSharpTest2/EmbeddedLanguages/Json/CSharpJsonParserTests_NstTests.cs index 579cc5e8eb4b9..673578b9e7e0a 100644 --- a/src/EditorFeatures/CSharpTest2/EmbeddedLanguages/Json/CSharpJsonParserTests_NstTests.cs +++ b/src/EditorFeatures/CSharpTest2/EmbeddedLanguages/Json/CSharpJsonParserTests_NstTests.cs @@ -3028,10 +3028,10 @@ public void n_object_comma_instead_of_colon_json() ", @" - + ", @" - + "); } @@ -3188,10 +3188,10 @@ public void n_object_missing_colon_json() ", @" - + ", @" - + "); } @@ -3250,10 +3250,10 @@ public void n_object_missing_semicolon_json() ", @" - + ", @" - + "); } @@ -3308,10 +3308,10 @@ public void n_object_no_colon_json() ", @" - + ", @" - + "); } @@ -3762,10 +3762,10 @@ public void n_object_with_single_string_json() ", @" - + ", @" - + "); } @@ -5299,10 +5299,10 @@ public void n_structure_open_object_string_with_apostrophes_json() ", @" - + ", @" - + "); } diff --git a/src/EditorFeatures/CSharpTest2/Recommendations/NewKeywordRecommenderTests.cs b/src/EditorFeatures/CSharpTest2/Recommendations/NewKeywordRecommenderTests.cs index 11d964af03cac..92b490759a4ed 100644 --- a/src/EditorFeatures/CSharpTest2/Recommendations/NewKeywordRecommenderTests.cs +++ b/src/EditorFeatures/CSharpTest2/Recommendations/NewKeywordRecommenderTests.cs @@ -699,7 +699,7 @@ await VerifyKeywordAsync(@"namespace N {} [Fact, Trait(Traits.Feature, Traits.Features.KeywordRecommending)] public async Task TestAfterFileScopedNamespace() { - await VerifyKeywordAsync( + await VerifyAbsenceAsync( @"namespace N; $$"); } diff --git a/src/EditorFeatures/Core.Cocoa/CommandHandlers/GoToMatchingBraceCommandHandler.cs b/src/EditorFeatures/Core.Cocoa/CommandHandlers/GoToMatchingBraceCommandHandler.cs index 3c333a5a2422b..932120bcdb19f 100644 --- a/src/EditorFeatures/Core.Cocoa/CommandHandlers/GoToMatchingBraceCommandHandler.cs +++ b/src/EditorFeatures/Core.Cocoa/CommandHandlers/GoToMatchingBraceCommandHandler.cs @@ -8,6 +8,7 @@ using System.ComponentModel.Composition; using Microsoft.CodeAnalysis.Editor.Shared.Extensions; using Microsoft.CodeAnalysis.Host.Mef; +using Microsoft.CodeAnalysis.Options; using Microsoft.CodeAnalysis.Text; using Microsoft.CodeAnalysis.Text.Shared.Extensions; using Microsoft.VisualStudio.Text.Editor.Commanding.Commands; @@ -23,13 +24,14 @@ namespace Microsoft.CodeAnalysis.Editor.Implementation.CommandHandlers internal class GoToMatchingBraceCommandHandler : VSCommanding.ICommandHandler { private readonly IBraceMatchingService _braceMatchingService; + private readonly IGlobalOptionService _globalOptions; [ImportingConstructor] [Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] - public GoToMatchingBraceCommandHandler(IBraceMatchingService braceMatchingService) + public GoToMatchingBraceCommandHandler(IBraceMatchingService braceMatchingService, IGlobalOptionService globalOptions) { - _braceMatchingService = braceMatchingService ?? - throw new ArgumentNullException(nameof(braceMatchingService)); + _braceMatchingService = braceMatchingService; + _globalOptions = globalOptions; } public string DisplayName => nameof(GoToMatchingBraceCommandHandler); @@ -38,7 +40,7 @@ public bool ExecuteCommand(GotoBraceCommandArgs args, VSCommanding.CommandExecut { var snapshot = args.SubjectBuffer.CurrentSnapshot; var document = snapshot.GetOpenDocumentInCurrentContextWithChanges(); - var options = BraceMatchingOptions.From(document.Project); + var options = _globalOptions.GetBraceMatchingOptions(document.Project.Language); var caretPosition = args.TextView.Caret.Position.BufferPosition.Position; var task = _braceMatchingService.FindMatchingSpanAsync(document, caretPosition, options, executionContext.OperationContext.UserCancellationToken); diff --git a/src/EditorFeatures/Core.Cocoa/Microsoft.CodeAnalysis.EditorFeatures.Cocoa.csproj b/src/EditorFeatures/Core.Cocoa/Microsoft.CodeAnalysis.EditorFeatures.Cocoa.csproj index ef02ec45167a3..43d7aa138874f 100644 --- a/src/EditorFeatures/Core.Cocoa/Microsoft.CodeAnalysis.EditorFeatures.Cocoa.csproj +++ b/src/EditorFeatures/Core.Cocoa/Microsoft.CodeAnalysis.EditorFeatures.Cocoa.csproj @@ -12,7 +12,7 @@ - + diff --git a/src/EditorFeatures/Core.Cocoa/NavigationCommandHandlers/FindBaseSymbolsCommandHandler.cs b/src/EditorFeatures/Core.Cocoa/NavigationCommandHandlers/FindBaseSymbolsCommandHandler.cs index 5e2185b61c07a..43a1e8789ef3c 100644 --- a/src/EditorFeatures/Core.Cocoa/NavigationCommandHandlers/FindBaseSymbolsCommandHandler.cs +++ b/src/EditorFeatures/Core.Cocoa/NavigationCommandHandlers/FindBaseSymbolsCommandHandler.cs @@ -6,11 +6,12 @@ using System.Collections.Generic; using System.ComponentModel.Composition; using System.Threading.Tasks; -using Microsoft.CodeAnalysis.Editor.FindUsages; using Microsoft.CodeAnalysis.Editor.Host; using Microsoft.CodeAnalysis.ErrorReporting; +using Microsoft.CodeAnalysis.FindUsages; using Microsoft.CodeAnalysis.Host.Mef; using Microsoft.CodeAnalysis.Internal.Log; +using Microsoft.CodeAnalysis.Options; using Microsoft.CodeAnalysis.Shared.Extensions; using Microsoft.CodeAnalysis.Shared.TestHooks; using Microsoft.VisualStudio.Commanding; @@ -28,6 +29,7 @@ internal sealed class FindBaseSymbolsCommandHandler : AbstractNavigationCommandHandler { private readonly IAsynchronousOperationListener _asyncListener; + private readonly IGlobalOptionService _globalOptions; public override string DisplayName => nameof(FindBaseSymbolsCommandHandler); @@ -35,12 +37,14 @@ internal sealed class FindBaseSymbolsCommandHandler : [Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] public FindBaseSymbolsCommandHandler( [ImportMany] IEnumerable> streamingPresenters, - IAsynchronousOperationListenerProvider listenerProvider) + IAsynchronousOperationListenerProvider listenerProvider, + IGlobalOptionService globalOptions) : base(streamingPresenters) { Contract.ThrowIfNull(listenerProvider); _asyncListener = listenerProvider.GetListener(FeatureAttribute.FindReferences); + _globalOptions = globalOptions; } protected override bool TryExecuteCommand(int caretPosition, Document document, CommandExecutionContext context) @@ -83,7 +87,7 @@ private async Task StreamingFindBaseSymbolsAsync( return; } - var definitionItem = overriddenSymbol.ToNonClassifiedDefinitionItem(document.Project.Solution, true); + var definitionItem = overriddenSymbol.ToNonClassifiedDefinitionItem(document.Project.Solution, includeHiddenLocations: true); await context.OnDefinitionFoundAsync(definitionItem, cancellationToken).ConfigureAwait(false); // try getting the next one diff --git a/src/EditorFeatures/Core.Cocoa/NavigationCommandHandlers/FindDerivedSymbolsCommandHandler.cs b/src/EditorFeatures/Core.Cocoa/NavigationCommandHandlers/FindDerivedSymbolsCommandHandler.cs index 6577d0200543a..7076795e0c28e 100644 --- a/src/EditorFeatures/Core.Cocoa/NavigationCommandHandlers/FindDerivedSymbolsCommandHandler.cs +++ b/src/EditorFeatures/Core.Cocoa/NavigationCommandHandlers/FindDerivedSymbolsCommandHandler.cs @@ -3,23 +3,23 @@ // See the LICENSE file in the project root for more information. using System; -using System.Linq; using System.Collections.Generic; using System.ComponentModel.Composition; using System.Threading; using System.Threading.Tasks; -using Microsoft.CodeAnalysis.Editor.FindUsages; using Microsoft.CodeAnalysis.Editor.Host; using Microsoft.CodeAnalysis.ErrorReporting; using Microsoft.CodeAnalysis.FindSymbols; +using Microsoft.CodeAnalysis.FindUsages; +using Microsoft.CodeAnalysis.Host.Mef; using Microsoft.CodeAnalysis.Internal.Log; +using Microsoft.CodeAnalysis.Options; using Microsoft.CodeAnalysis.Shared.TestHooks; using Microsoft.VisualStudio.Commanding; using Microsoft.VisualStudio.Text.Editor.Commanding.Commands.Navigation; using Microsoft.VisualStudio.Utilities; using Roslyn.Utilities; using VSCommanding = Microsoft.VisualStudio.Commanding; -using Microsoft.CodeAnalysis.Host.Mef; namespace Microsoft.CodeAnalysis.Editor.Implementation.NavigationCommandHandlers { @@ -105,7 +105,7 @@ private async Task FindDerivedSymbolsAsync( foreach (var candidate in candidates) { - var definitionItem = candidate.ToNonClassifiedDefinitionItem(document.Project.Solution, true); + var definitionItem = candidate.ToNonClassifiedDefinitionItem(document.Project.Solution, includeHiddenLocations: true); await context.OnDefinitionFoundAsync(definitionItem, cancellationToken).ConfigureAwait(false); } } diff --git a/src/EditorFeatures/Core.Cocoa/NavigationCommandHandlers/FindExtensionMethodsCommandHandler.cs b/src/EditorFeatures/Core.Cocoa/NavigationCommandHandlers/FindExtensionMethodsCommandHandler.cs index 843a5cecea69f..c56709e12897c 100644 --- a/src/EditorFeatures/Core.Cocoa/NavigationCommandHandlers/FindExtensionMethodsCommandHandler.cs +++ b/src/EditorFeatures/Core.Cocoa/NavigationCommandHandlers/FindExtensionMethodsCommandHandler.cs @@ -9,12 +9,13 @@ using System.ComponentModel.Composition; using System.Linq; using System.Threading.Tasks; -using Microsoft.CodeAnalysis.Editor.FindUsages; using Microsoft.CodeAnalysis.Editor.Host; using Microsoft.CodeAnalysis.ErrorReporting; using Microsoft.CodeAnalysis.FindSymbols; +using Microsoft.CodeAnalysis.FindUsages; using Microsoft.CodeAnalysis.Host.Mef; using Microsoft.CodeAnalysis.Internal.Log; +using Microsoft.CodeAnalysis.Options; using Microsoft.CodeAnalysis.Shared.Extensions; using Microsoft.CodeAnalysis.Shared.TestHooks; using Microsoft.VisualStudio.Commanding; @@ -32,6 +33,7 @@ internal sealed class FindExtensionMethodsCommandHandler : AbstractNavigationCommandHandler { private readonly IAsynchronousOperationListener _asyncListener; + private readonly IGlobalOptionService _globalOptions; public override string DisplayName => nameof(FindExtensionMethodsCommandHandler); @@ -39,12 +41,14 @@ internal sealed class FindExtensionMethodsCommandHandler : [Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] public FindExtensionMethodsCommandHandler( [ImportMany] IEnumerable> streamingPresenters, - IAsynchronousOperationListenerProvider listenerProvider) + IAsynchronousOperationListenerProvider listenerProvider, + IGlobalOptionService globalOptions) : base(streamingPresenters) { Contract.ThrowIfNull(listenerProvider); _asyncListener = listenerProvider.GetListener(FeatureAttribute.FindReferences); + _globalOptions = globalOptions; } protected override bool TryExecuteCommand(int caretPosition, Document document, CommandExecutionContext context) @@ -109,7 +113,7 @@ private async Task FindExtensionMethodsAsync( { var originatingProject = solution.GetProject(sourceDefinition.ContainingAssembly, cancellationToken); - var definitionItem = reducedMethod.ToNonClassifiedDefinitionItem(solution, true); + var definitionItem = reducedMethod.ToNonClassifiedDefinitionItem(solution, includeHiddenLocations: true); await context.OnDefinitionFoundAsync(definitionItem, cancellationToken).ConfigureAwait(false); } diff --git a/src/EditorFeatures/Core.Cocoa/NavigationCommandHandlers/FindImplementingMembersCommandHandler.cs b/src/EditorFeatures/Core.Cocoa/NavigationCommandHandlers/FindImplementingMembersCommandHandler.cs index 7e8998cfff489..52d5ed0de7671 100644 --- a/src/EditorFeatures/Core.Cocoa/NavigationCommandHandlers/FindImplementingMembersCommandHandler.cs +++ b/src/EditorFeatures/Core.Cocoa/NavigationCommandHandlers/FindImplementingMembersCommandHandler.cs @@ -9,12 +9,12 @@ using System.ComponentModel.Composition; using System.Threading; using System.Threading.Tasks; -using Microsoft.CodeAnalysis.Editor.FindUsages; using Microsoft.CodeAnalysis.Editor.Host; using Microsoft.CodeAnalysis.ErrorReporting; using Microsoft.CodeAnalysis.FindUsages; using Microsoft.CodeAnalysis.Host.Mef; using Microsoft.CodeAnalysis.Internal.Log; +using Microsoft.CodeAnalysis.Options; using Microsoft.CodeAnalysis.Shared.TestHooks; using Microsoft.VisualStudio.Commanding; using Microsoft.VisualStudio.Text.Editor.Commanding.Commands.Navigation; @@ -31,6 +31,7 @@ internal sealed class FindImplementingMembersCommandHandler : AbstractNavigationCommandHandler { private readonly IAsynchronousOperationListener _asyncListener; + private readonly IGlobalOptionService _globalOptions; public override string DisplayName => nameof(FindImplementingMembersCommandHandler); @@ -38,12 +39,14 @@ internal sealed class FindImplementingMembersCommandHandler : [Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] public FindImplementingMembersCommandHandler( [ImportMany] IEnumerable> streamingPresenters, - IAsynchronousOperationListenerProvider listenerProvider) + IAsynchronousOperationListenerProvider listenerProvider, + IGlobalOptionService globalOptions) : base(streamingPresenters) { Contract.ThrowIfNull(listenerProvider); _asyncListener = listenerProvider.GetListener(FeatureAttribute.FindReferences); + _globalOptions = globalOptions; } protected override bool TryExecuteCommand(int caretPosition, Document document, CommandExecutionContext context) @@ -143,7 +146,7 @@ private static async Task InspectInterfaceAsync( if (impl == null) continue; - var definitionItem = impl.ToNonClassifiedDefinitionItem(project.Solution, true); + var definitionItem = impl.ToNonClassifiedDefinitionItem(project.Solution, includeHiddenLocations: true); await context.OnDefinitionFoundAsync(definitionItem, cancellationToken).ConfigureAwait(false); } } diff --git a/src/EditorFeatures/Core.Cocoa/NavigationCommandHandlers/FindMemberOverloadsCommandHandler.cs b/src/EditorFeatures/Core.Cocoa/NavigationCommandHandlers/FindMemberOverloadsCommandHandler.cs index 2c6ac335cf584..a8a782ea2a5bd 100644 --- a/src/EditorFeatures/Core.Cocoa/NavigationCommandHandlers/FindMemberOverloadsCommandHandler.cs +++ b/src/EditorFeatures/Core.Cocoa/NavigationCommandHandlers/FindMemberOverloadsCommandHandler.cs @@ -3,13 +3,14 @@ // See the LICENSE file in the project root for more information. using System; -using System.Linq; using System.Collections.Generic; using System.ComponentModel.Composition; +using System.Linq; using System.Threading.Tasks; -using Microsoft.CodeAnalysis.Editor.FindUsages; using Microsoft.CodeAnalysis.Editor.Host; using Microsoft.CodeAnalysis.ErrorReporting; +using Microsoft.CodeAnalysis.FindUsages; +using Microsoft.CodeAnalysis.Host.Mef; using Microsoft.CodeAnalysis.Internal.Log; using Microsoft.CodeAnalysis.Shared.TestHooks; using Microsoft.VisualStudio.Commanding; @@ -17,8 +18,6 @@ using Microsoft.VisualStudio.Utilities; using Roslyn.Utilities; using VSCommanding = Microsoft.VisualStudio.Commanding; -using Microsoft.CodeAnalysis.Host.Mef; -using System.Threading; namespace Microsoft.CodeAnalysis.Editor.Implementation.NavigationCommandHandlers { diff --git a/src/EditorFeatures/Core.Cocoa/NavigationCommandHandlers/FindReferencesOfOverloadsCommandHandler.cs b/src/EditorFeatures/Core.Cocoa/NavigationCommandHandlers/FindReferencesOfOverloadsCommandHandler.cs index 5006710ae5adb..24e866d4ca58f 100644 --- a/src/EditorFeatures/Core.Cocoa/NavigationCommandHandlers/FindReferencesOfOverloadsCommandHandler.cs +++ b/src/EditorFeatures/Core.Cocoa/NavigationCommandHandlers/FindReferencesOfOverloadsCommandHandler.cs @@ -10,11 +10,11 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; -using Microsoft.CodeAnalysis.Editor.FindUsages; using Microsoft.CodeAnalysis.Editor.Host; using Microsoft.CodeAnalysis.Editor.Shared.Utilities; using Microsoft.CodeAnalysis.ErrorReporting; using Microsoft.CodeAnalysis.FindSymbols; +using Microsoft.CodeAnalysis.FindUsages; using Microsoft.CodeAnalysis.Host.Mef; using Microsoft.CodeAnalysis.Internal.Log; using Microsoft.CodeAnalysis.Shared.Extensions; diff --git a/src/EditorFeatures/Core.Cocoa/Preview/PreviewFactoryService.cs b/src/EditorFeatures/Core.Cocoa/Preview/PreviewFactoryService.cs index b3402fba90f38..eba52723824e3 100644 --- a/src/EditorFeatures/Core.Cocoa/Preview/PreviewFactoryService.cs +++ b/src/EditorFeatures/Core.Cocoa/Preview/PreviewFactoryService.cs @@ -8,6 +8,7 @@ using System.Threading.Tasks; using Microsoft.CodeAnalysis.Editor.Shared.Utilities; using Microsoft.CodeAnalysis.Host.Mef; +using Microsoft.CodeAnalysis.Options; using Microsoft.VisualStudio.Text; using Microsoft.VisualStudio.Text.Differencing; using Microsoft.VisualStudio.Text.Editor; @@ -33,7 +34,8 @@ public PreviewFactoryService( IEditorOptionsFactoryService editorOptionsFactoryService, ITextDifferencingSelectorService differenceSelectorService, IDifferenceBufferFactoryService differenceBufferService, - ICocoaDifferenceViewerFactoryService differenceViewerService) + ICocoaDifferenceViewerFactoryService differenceViewerService, + IGlobalOptionService globalOptions) : base(threadingContext, textBufferFactoryService, contentTypeRegistryService, @@ -42,7 +44,8 @@ public PreviewFactoryService( differenceSelectorService, differenceBufferService, textEditorFactoryService.CreateTextViewRoleSet( - TextViewRoles.PreviewRole, PredefinedTextViewRoles.Analyzable)) + TextViewRoles.PreviewRole, PredefinedTextViewRoles.Analyzable), + globalOptions) { _differenceViewerService = differenceViewerService; } diff --git a/src/EditorFeatures/Core.Wpf/Adornments/AbstractAdornmentManager.cs b/src/EditorFeatures/Core.Wpf/Adornments/AbstractAdornmentManager.cs index fdd62dda05303..ced60fb3c0f4b 100644 --- a/src/EditorFeatures/Core.Wpf/Adornments/AbstractAdornmentManager.cs +++ b/src/EditorFeatures/Core.Wpf/Adornments/AbstractAdornmentManager.cs @@ -277,7 +277,7 @@ protected bool ShouldDrawTag(SnapshotSpan snapshotSpan, IMappingTagSpan mappi protected SnapshotPoint? GetMappedPoint(SnapshotSpan snapshotSpan, IMappingTagSpan mappingTagSpan) { - var point = mappingTagSpan.Span.Start.GetPoint(snapshotSpan.Snapshot, PositionAffinity.Predecessor); + var point = mappingTagSpan.Span.End.GetPoint(snapshotSpan.Snapshot, PositionAffinity.Predecessor); if (point == null) { return null; diff --git a/src/EditorFeatures/Core.Wpf/BraceMatching/BraceMatchingTypeFormatDefinitions.cs b/src/EditorFeatures/Core.Wpf/BraceMatching/BraceMatchingTypeFormatDefinitions.cs index 0dce2638b6d40..0c6d5d26a1e43 100644 --- a/src/EditorFeatures/Core.Wpf/BraceMatching/BraceMatchingTypeFormatDefinitions.cs +++ b/src/EditorFeatures/Core.Wpf/BraceMatching/BraceMatchingTypeFormatDefinitions.cs @@ -7,6 +7,7 @@ using System; using System.ComponentModel.Composition; using System.Windows.Media; +using Microsoft.CodeAnalysis.BraceMatching; using Microsoft.CodeAnalysis.Host.Mef; using Microsoft.VisualStudio.Text.Classification; using Microsoft.VisualStudio.Utilities; diff --git a/src/EditorFeatures/Core.Wpf/Diagnostics/UnnecessaryCodeFormatDefinition.cs b/src/EditorFeatures/Core.Wpf/Diagnostics/UnnecessaryCodeFormatDefinition.cs index d6206f8e2c0d5..c7e847712ca55 100644 --- a/src/EditorFeatures/Core.Wpf/Diagnostics/UnnecessaryCodeFormatDefinition.cs +++ b/src/EditorFeatures/Core.Wpf/Diagnostics/UnnecessaryCodeFormatDefinition.cs @@ -10,7 +10,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; -using Microsoft.CodeAnalysis.Editor.Implementation.Diagnostics; +using Microsoft.CodeAnalysis.Diagnostics; using Microsoft.CodeAnalysis.Host.Mef; using Microsoft.VisualStudio.Text.Classification; using Microsoft.VisualStudio.Utilities; diff --git a/src/EditorFeatures/Core.Wpf/EditAndContinue/ActiveStatementTagFormatDefinition.cs b/src/EditorFeatures/Core.Wpf/EditAndContinue/ActiveStatementTagFormatDefinition.cs index 4a807131a49aa..907396d852675 100644 --- a/src/EditorFeatures/Core.Wpf/EditAndContinue/ActiveStatementTagFormatDefinition.cs +++ b/src/EditorFeatures/Core.Wpf/EditAndContinue/ActiveStatementTagFormatDefinition.cs @@ -8,6 +8,7 @@ using System.ComponentModel.Composition; using System.Diagnostics.CodeAnalysis; using System.Windows.Media; +using Microsoft.CodeAnalysis.EditAndContinue; using Microsoft.CodeAnalysis.Host.Mef; using Microsoft.VisualStudio.Text.Classification; using Microsoft.VisualStudio.Utilities; diff --git a/src/EditorFeatures/Core.Wpf/EditAndContinue/EditAndContinueErrorTypeFormatDefinition.cs b/src/EditorFeatures/Core.Wpf/EditAndContinue/EditAndContinueErrorTypeFormatDefinition.cs index 5b8f6e95c02da..fc3b97222027c 100644 --- a/src/EditorFeatures/Core.Wpf/EditAndContinue/EditAndContinueErrorTypeFormatDefinition.cs +++ b/src/EditorFeatures/Core.Wpf/EditAndContinue/EditAndContinueErrorTypeFormatDefinition.cs @@ -7,6 +7,7 @@ using System; using System.ComponentModel.Composition; using System.Windows.Media; +using Microsoft.CodeAnalysis.EditAndContinue; using Microsoft.CodeAnalysis.Host.Mef; using Microsoft.VisualStudio.Text.Classification; using Microsoft.VisualStudio.Utilities; diff --git a/src/EditorFeatures/Core.Wpf/EditorFeaturesWpfResources.resx b/src/EditorFeatures/Core.Wpf/EditorFeaturesWpfResources.resx index bb2fa6e202234..d5ce528bbe935 100644 --- a/src/EditorFeatures/Core.Wpf/EditorFeaturesWpfResources.resx +++ b/src/EditorFeatures/Core.Wpf/EditorFeaturesWpfResources.resx @@ -153,4 +153,7 @@ Interactive host process platform + + Enter to rename, Shift+Enter to preview + \ No newline at end of file diff --git a/src/EditorFeatures/Core.Wpf/InlineDiagnostics/InlineDiagnosticsAdornmentManager.cs b/src/EditorFeatures/Core.Wpf/InlineDiagnostics/InlineDiagnosticsAdornmentManager.cs index 929e599b576bb..e18c043e3052b 100644 --- a/src/EditorFeatures/Core.Wpf/InlineDiagnostics/InlineDiagnosticsAdornmentManager.cs +++ b/src/EditorFeatures/Core.Wpf/InlineDiagnostics/InlineDiagnosticsAdornmentManager.cs @@ -116,47 +116,6 @@ private TextFormattingRunProperties GetFormat(IClassificationType classification return _formatMap.GetTextProperties(classificationType); } - /// - /// Get the spans located on each line so that it can only display the first one that appears on the line - /// - private void AddSpansOnEachLine(NormalizedSnapshotSpanCollection changedSpanCollection, - Dictionary> map) - { - var viewLines = TextView.TextViewLines; - - foreach (var changedSpan in changedSpanCollection) - { - if (!viewLines.IntersectsBufferSpan(changedSpan)) - { - continue; - } - - var tagSpans = TagAggregator.GetTags(changedSpan); - foreach (var tagMappingSpan in tagSpans) - { - if (!ShouldDrawTag(changedSpan, tagMappingSpan, out var mappedPoint)) - { - continue; - } - - // mappedPoint is known to not be null here because it is checked in the ShouldDrawTag method call. - var lineNum = mappedPoint.GetContainingLine().LineNumber; - - // If the line does not have an associated tagMappingSpan and changedSpan, then add the first one. - if (!map.TryGetValue(lineNum, out var value)) - { - map.Add(lineNum, tagMappingSpan); - } - else if (value.Tag.ErrorType is not PredefinedErrorTypeNames.SyntaxError && tagMappingSpan.Tag.ErrorType is PredefinedErrorTypeNames.SyntaxError) - { - // Draw the first instance of an error, if what is stored in the map at a specific line is - // not an error, then replace it. Otherwise, just get the first warning on the line. - map[lineNum] = tagMappingSpan; - } - } - } - } - /// /// Iterates through the mapping of line number to span and draws the diagnostic in the appropriate position on the screen, /// as well as adding the tag to the adornment layer. @@ -220,6 +179,7 @@ protected override void AddAdornmentsToAdornmentLayer_CallOnlyOnUIThread(Normali // Only place the diagnostics if the diagnostic would not intersect with the editor window if (lineView.Right >= TextView.ViewportWidth - visualElement.DesiredSize.Width) { + graphicsResult.Dispose(); continue; } @@ -238,5 +198,46 @@ protected override void AddAdornmentsToAdornmentLayer_CallOnlyOnUIThread(Normali removedCallback: delegate { graphicsResult.Dispose(); }); } } + + /// + /// Get the spans located on each line so that it can only display the first one that appears on the line + /// + private void AddSpansOnEachLine(NormalizedSnapshotSpanCollection changedSpanCollection, + Dictionary> map) + { + var viewLines = TextView.TextViewLines; + + foreach (var changedSpan in changedSpanCollection) + { + if (!viewLines.IntersectsBufferSpan(changedSpan)) + { + continue; + } + + var tagSpans = TagAggregator.GetTags(changedSpan); + foreach (var tagMappingSpan in tagSpans) + { + if (!ShouldDrawTag(changedSpan, tagMappingSpan, out var mappedPoint)) + { + continue; + } + + // mappedPoint is known to not be null here because it is checked in the ShouldDrawTag method call. + var lineNum = mappedPoint.GetContainingLine().LineNumber; + + // If the line does not have an associated tagMappingSpan and changedSpan, then add the first one. + if (!map.TryGetValue(lineNum, out var value)) + { + map.Add(lineNum, tagMappingSpan); + } + else if (value.Tag.ErrorType is not PredefinedErrorTypeNames.SyntaxError && tagMappingSpan.Tag.ErrorType is PredefinedErrorTypeNames.SyntaxError) + { + // Draw the first instance of an error, if what is stored in the map at a specific line is + // not an error, then replace it. Otherwise, just get the first warning on the line. + map[lineNum] = tagMappingSpan; + } + } + } + } } } diff --git a/src/EditorFeatures/Core.Wpf/InlineDiagnostics/InlineDiagnosticsFormatDefinition.cs b/src/EditorFeatures/Core.Wpf/InlineDiagnostics/InlineDiagnosticsFormatDefinition.cs index 3d7eafb1c7e15..4f097ad026e32 100644 --- a/src/EditorFeatures/Core.Wpf/InlineDiagnostics/InlineDiagnosticsFormatDefinition.cs +++ b/src/EditorFeatures/Core.Wpf/InlineDiagnostics/InlineDiagnosticsFormatDefinition.cs @@ -7,7 +7,7 @@ using System; using System.ComponentModel.Composition; using System.Windows.Media; -using Microsoft.CodeAnalysis.Editor.Implementation.EditAndContinue; +using Microsoft.CodeAnalysis.EditAndContinue; using Microsoft.CodeAnalysis.Host.Mef; using Microsoft.VisualStudio.Language.StandardClassification; using Microsoft.VisualStudio.Text.Adornments; diff --git a/src/EditorFeatures/Core.Wpf/InlineDiagnostics/InlineDiagnosticsTag.cs b/src/EditorFeatures/Core.Wpf/InlineDiagnostics/InlineDiagnosticsTag.cs index 0b3582b3f6a5e..8d1dd3d88f723 100644 --- a/src/EditorFeatures/Core.Wpf/InlineDiagnostics/InlineDiagnosticsTag.cs +++ b/src/EditorFeatures/Core.Wpf/InlineDiagnostics/InlineDiagnosticsTag.cs @@ -9,8 +9,8 @@ using System.Windows.Documents; using System.Windows.Media; using Microsoft.CodeAnalysis.Diagnostics; +using Microsoft.CodeAnalysis.EditAndContinue; using Microsoft.CodeAnalysis.Editor.Implementation.Adornments; -using Microsoft.CodeAnalysis.Editor.Implementation.EditAndContinue; using Microsoft.VisualStudio.Imaging; using Microsoft.VisualStudio.Imaging.Interop; using Microsoft.VisualStudio.PlatformUI; @@ -122,7 +122,6 @@ public override GraphicsResult GetGraphics(IWpfTextView view, Geometry bounds, T ImageThemingUtilities.SetImageBackgroundColor(border, editorBackground); border.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity)); - view.ViewportWidthChanged += ViewportWidthChangedHandler; view.LayoutChanged += View_LayoutChanged; return new GraphicsResult(border, dispose: @@ -133,22 +132,9 @@ public override GraphicsResult GetGraphics(IWpfTextView view, Geometry bounds, T hyperlink.RequestNavigate -= HandleRequestNavigate; } - view.ViewportWidthChanged -= ViewportWidthChangedHandler; view.LayoutChanged -= View_LayoutChanged; }); - // The tag listens to the width changing to allow the diagnostic UI to move with - // the window as it gets moved. - // The InlineDiagnosticsAdornmentManager listens to the viewport width - // changing to deal with diagnostics intersecting with the text in the editor. - void ViewportWidthChangedHandler(object s, EventArgs e) - { - if (Location is InlineDiagnosticsLocations.PlacedAtEndOfEditor) - { - Canvas.SetLeft(border, view.ViewportRight - border.DesiredSize.Width); - } - } - void View_LayoutChanged(object sender, TextViewLayoutChangedEventArgs e) { if (Location is InlineDiagnosticsLocations.PlacedAtEndOfEditor) diff --git a/src/EditorFeatures/Core.Wpf/InlineDiagnostics/InlineDiagnosticsTaggerProvider.cs b/src/EditorFeatures/Core.Wpf/InlineDiagnostics/InlineDiagnosticsTaggerProvider.cs index 8f71dc18992b8..f6d8220d861ca 100644 --- a/src/EditorFeatures/Core.Wpf/InlineDiagnostics/InlineDiagnosticsTaggerProvider.cs +++ b/src/EditorFeatures/Core.Wpf/InlineDiagnostics/InlineDiagnosticsTaggerProvider.cs @@ -7,8 +7,7 @@ using System.ComponentModel.Composition; using System.Diagnostics; using Microsoft.CodeAnalysis.Diagnostics; -using Microsoft.CodeAnalysis.Editor.Implementation.Diagnostics; -using Microsoft.CodeAnalysis.Editor.Implementation.EditAndContinue; +using Microsoft.CodeAnalysis.EditAndContinue; using Microsoft.CodeAnalysis.Editor.Shared.Tagging; using Microsoft.CodeAnalysis.Editor.Shared.Utilities; using Microsoft.CodeAnalysis.Editor.Tagging; @@ -84,13 +83,13 @@ diagnostic.Severity is DiagnosticSeverity.Warning or DiagnosticSeverity.Error && return null; } - var document = workspace.CurrentSolution.GetDocument(diagnostic.DocumentId); - if (document is null) + var project = workspace.CurrentSolution.GetProject(diagnostic.DocumentId.ProjectId); + if (project is null) { return null; } - var locationOption = GlobalOptions.GetOption(InlineDiagnosticsOptions.Location, document.Project.Language); + var locationOption = GlobalOptions.GetOption(InlineDiagnosticsOptions.Location, project.Language); var navigateService = workspace.Services.GetRequiredService(); return new InlineDiagnosticsTag(errorType, diagnostic, _editorFormatMap, _classificationFormatMapService, _classificationTypeRegistryService, locationOption, navigateService); diff --git a/src/EditorFeatures/Core.Wpf/InlineHints/InlineHintsTag.cs b/src/EditorFeatures/Core.Wpf/InlineHints/InlineHintsTag.cs index 08d1d55eed9bb..a1cac5cc9174f 100644 --- a/src/EditorFeatures/Core.Wpf/InlineHints/InlineHintsTag.cs +++ b/src/EditorFeatures/Core.Wpf/InlineHints/InlineHintsTag.cs @@ -13,16 +13,14 @@ using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; -using Microsoft.CodeAnalysis.Editor.Host; +using Microsoft.CodeAnalysis.Classification; using Microsoft.CodeAnalysis.Editor.Implementation.IntelliSense.QuickInfo; using Microsoft.CodeAnalysis.Editor.Shared.Utilities; -using Microsoft.CodeAnalysis.Elfie.Diagnostics; using Microsoft.CodeAnalysis.InlineHints; using Microsoft.CodeAnalysis.Internal.Log; using Microsoft.CodeAnalysis.PooledObjects; using Microsoft.CodeAnalysis.Shared.Extensions; using Microsoft.CodeAnalysis.Text; -using Microsoft.CodeAnalysis.Text.Shared.Extensions; using Microsoft.VisualStudio.Text; using Microsoft.VisualStudio.Text.Adornments; using Microsoft.VisualStudio.Text.Classification; @@ -35,7 +33,7 @@ namespace Microsoft.CodeAnalysis.Editor.InlineHints /// This is the tag which implements the IntraTextAdornmentTag and is meant to create the UIElements that get shown /// in the editor /// - internal class InlineHintsTag : IntraTextAdornmentTag + internal sealed class InlineHintsTag : IntraTextAdornmentTag { public const string TagId = "inline hints"; @@ -101,6 +99,7 @@ public async Task> CreateDescriptionAsync(Cancellati { var context = new IntellisenseQuickInfoBuilderContext( document, + _taggerProvider.GlobalOptions.GetClassificationOptions(document.Project.Language), _taggerProvider.ThreadingContext, _taggerProvider.OperationExecutor, _taggerProvider.AsynchronousOperationListener, diff --git a/src/EditorFeatures/Core.Wpf/InlineRename/InlineRenameExperimentationOptions.cs b/src/EditorFeatures/Core.Wpf/InlineRename/InlineRenameExperimentationOptions.cs new file mode 100644 index 0000000000000..6db2688d26286 --- /dev/null +++ b/src/EditorFeatures/Core.Wpf/InlineRename/InlineRenameExperimentationOptions.cs @@ -0,0 +1,17 @@ +ο»Ώ// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Microsoft.CodeAnalysis.Options; + +namespace Microsoft.CodeAnalysis.Editor.InlineRename +{ + internal sealed class InlineRenameExperimentationOptions + { + public static readonly Option UseInlineAdornment = new( + feature: "InlineRenameExperimentation", + name: "UseInlineAdornment", + defaultValue: false, + storageLocation: new FeatureFlagStorageLocation("Roslyn.UseInlineAdornmentForRename")); + } +} diff --git a/src/EditorFeatures/Core.Wpf/InlineRename/UI/Adornment/InlineRenameAdornment.xaml b/src/EditorFeatures/Core.Wpf/InlineRename/UI/Adornment/InlineRenameAdornment.xaml new file mode 100644 index 0000000000000..14b476f384714 --- /dev/null +++ b/src/EditorFeatures/Core.Wpf/InlineRename/UI/Adornment/InlineRenameAdornment.xaml @@ -0,0 +1,119 @@ +ο»Ώ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/EditorFeatures/Core.Wpf/InlineRename/UI/Adornment/InlineRenameAdornment.xaml.cs b/src/EditorFeatures/Core.Wpf/InlineRename/UI/Adornment/InlineRenameAdornment.xaml.cs new file mode 100644 index 0000000000000..9138e5550fa4a --- /dev/null +++ b/src/EditorFeatures/Core.Wpf/InlineRename/UI/Adornment/InlineRenameAdornment.xaml.cs @@ -0,0 +1,143 @@ +ο»Ώ// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Input; +using Microsoft.VisualStudio.Text.Editor; + +namespace Microsoft.CodeAnalysis.Editor.InlineRename.Adornment +{ + /// + /// Interaction logic for InlineRenameAdornment.xaml + /// + internal partial class InlineRenameAdornment : UserControl, IDisposable + { + private readonly InlineRenameAdornmentViewModel _viewModel; + private readonly ITextView _textView; + + public InlineRenameAdornment(InlineRenameAdornmentViewModel viewModel, ITextView textView) + { + DataContext = _viewModel = viewModel; + _textView = textView; + + _textView.LayoutChanged += TextView_LayoutChanged; + _textView.ViewportHeightChanged += TextView_ViewPortChanged; + _textView.ViewportWidthChanged += TextView_ViewPortChanged; + _textView.LostAggregateFocus += TextView_LostFocus; + _textView.Caret.PositionChanged += TextView_CursorChanged; + + // On initialization focus the first tab target + Initialized += (s, e) => MoveFocus(new TraversalRequest(FocusNavigationDirection.First)); + + InitializeComponent(); + PositionAdornment(); + } + +#pragma warning disable CA1822 // Mark members as static - used in xaml + public string RenameOverloads => EditorFeaturesResources.Include_overload_s; + public string SearchInComments => EditorFeaturesResources.Include_comments; + public string SearchInStrings => EditorFeaturesResources.Include_strings; + public string ApplyRename => EditorFeaturesResources.Apply1; + public string CancelRename => EditorFeaturesResources.Cancel; + public string PreviewChanges => EditorFeaturesResources.Preview_changes1; + public string SubmitText => EditorFeaturesWpfResources.Enter_to_rename_shift_enter_to_preview; +#pragma warning restore CA1822 // Mark members as static + + private void TextView_CursorChanged(object sender, CaretPositionChangedEventArgs e) + => _viewModel.Cancel(); + + private void TextView_LostFocus(object sender, EventArgs e) + => _viewModel.Cancel(); + + private void TextView_ViewPortChanged(object sender, EventArgs e) + => PositionAdornment(); + + private void TextView_LayoutChanged(object sender, TextViewLayoutChangedEventArgs e) + => PositionAdornment(); + + private void PositionAdornment() + { + var top = _textView.Caret.Bottom + 5; + var left = _textView.Caret.Left - 5; + + Canvas.SetTop(this, top); + Canvas.SetLeft(this, left); + } + + public void Dispose() + { + _viewModel.Dispose(); + + _textView.LayoutChanged -= TextView_LayoutChanged; + _textView.ViewportHeightChanged -= TextView_ViewPortChanged; + _textView.ViewportWidthChanged -= TextView_ViewPortChanged; + _textView.LostAggregateFocus -= TextView_LostFocus; + _textView.Caret.PositionChanged -= TextView_CursorChanged; + } + + private void Submit_Click(object sender, RoutedEventArgs e) + { + _viewModel.Submit(); + } + + private void Adornment_KeyDown(object sender, KeyEventArgs e) + { + switch (e.Key) + { + case Key.Enter: + e.Handled = true; + _viewModel.Submit(); + break; + + case Key.Escape: + e.Handled = true; + _viewModel.Cancel(); + break; + + case Key.Tab: + // We don't want tab to lose focus for the adornment, so manually + // loop focus back to the first item that is focusable. + FrameworkElement lastItem = _viewModel.IsExpanded + ? FileRenameCheckbox + : IdentifierTextBox; + + if (lastItem.IsFocused) + { + e.Handled = true; + MoveFocus(new TraversalRequest(FocusNavigationDirection.First)); + } + + break; + } + } + + private void IdentifierTextBox_GotFocus(object sender, RoutedEventArgs e) + { + IdentifierTextBox.SelectAll(); + } + + private void Adornment_ConsumeMouseEvent(object sender, MouseButtonEventArgs e) + { + e.Handled = true; + } + + private void Adornment_GotKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e) + { + if (e.OldFocus == this) + { + return; + } + + IdentifierTextBox.Focus(); + e.Handled = true; + } + + private void ToggleExpand(object sender, RoutedEventArgs e) + { + _viewModel.IsExpanded = !_viewModel.IsExpanded; + } + } +} diff --git a/src/EditorFeatures/Core.Wpf/InlineRename/UI/Adornment/InlineRenameAdornmentViewModel.cs b/src/EditorFeatures/Core.Wpf/InlineRename/UI/Adornment/InlineRenameAdornmentViewModel.cs new file mode 100644 index 0000000000000..c9932ebf66ef6 --- /dev/null +++ b/src/EditorFeatures/Core.Wpf/InlineRename/UI/Adornment/InlineRenameAdornmentViewModel.cs @@ -0,0 +1,269 @@ +ο»Ώ// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Diagnostics; +using System.Runtime.CompilerServices; +using System.Windows.Interop; +using Microsoft.CodeAnalysis.Editor.Implementation.InlineRename; +using Microsoft.CodeAnalysis.InlineRename; +using Microsoft.CodeAnalysis.Options; +using Microsoft.CodeAnalysis.Rename; +using Microsoft.VisualStudio.PlatformUI.OleComponentSupport; + +namespace Microsoft.CodeAnalysis.Editor.InlineRename.Adornment +{ + internal class InlineRenameAdornmentViewModel : INotifyPropertyChanged, IDisposable + { + private readonly InlineRenameSession _session; + private OleComponent? _oleComponent; + private bool _disposedValue; + public event PropertyChangedEventHandler? PropertyChanged; + + public InlineRenameAdornmentViewModel(InlineRenameSession session) + { + _session = session; + _session.ReplacementTextChanged += OnReplacementTextChanged; + + _previewChangesFlag = _session.PreviewChanges; + _renameFileFlag = _session.Options.RenameFile; + _renameInStringsFlag = _session.Options.RenameInStrings; + _renameInCommentsFlag = _session.Options.RenameInComments; + _renameOverloadsFlag = _session.Options.RenameOverloads; + + RegisterOleComponent(); + } + + public string IdentifierText + { + get => _session.ReplacementText; + set + { + if (value != _session.ReplacementText) + { + _session.ApplyReplacementText(value, propagateEditImmediately: false); + NotifyPropertyChanged(nameof(IdentifierText)); + } + } + } + + public bool AllowFileRename => _session.FileRenameInfo == InlineRenameFileRenameInfo.Allowed; + public bool ShowFileRename => _session.FileRenameInfo != InlineRenameFileRenameInfo.NotAllowed; + + public string FileRenameString => _session.FileRenameInfo switch + { + InlineRenameFileRenameInfo.TypeDoesNotMatchFileName => EditorFeaturesResources.Rename_file_name_doesnt_match, + InlineRenameFileRenameInfo.TypeWithMultipleLocations => EditorFeaturesResources.Rename_file_partial_type, + _ => EditorFeaturesResources.Rename_symbols_file + }; + + private bool _renameInCommentsFlag; + public bool RenameInCommentsFlag + { + get => _renameInCommentsFlag; + set + { + if (Set(ref _renameInCommentsFlag, value)) + { + _session.RenameService.GlobalOptions.SetGlobalOption(new OptionKey(InlineRenameSessionOptionsStorage.RenameInComments), value); + _session.RefreshRenameSessionWithOptionsChanged(_session.Options with { RenameInComments = value }); + } + } + } + + private bool _renameInStringsFlag; + public bool RenameInStringsFlag + { + get => _renameInStringsFlag; + set + { + if (Set(ref _renameInStringsFlag, value)) + { + _session.RenameService.GlobalOptions.SetGlobalOption(new OptionKey(InlineRenameSessionOptionsStorage.RenameInStrings), value); + _session.RefreshRenameSessionWithOptionsChanged(_session.Options with { RenameInStrings = value }); + } + } + } + + private bool _renameFileFlag; + public bool RenameFileFlag + { + get => _renameFileFlag; + set + { + if (Set(ref _renameFileFlag, value)) + { + _session.RenameService.GlobalOptions.SetGlobalOption(new OptionKey(InlineRenameSessionOptionsStorage.RenameFile), value); + _session.RefreshRenameSessionWithOptionsChanged(_session.Options with { RenameFile = value }); + } + } + } + + private bool _previewChangesFlag; + public bool PreviewChangesFlag + { + get => _previewChangesFlag; + set + { + if (Set(ref _previewChangesFlag, value)) + { + _session.RenameService.GlobalOptions.SetGlobalOption(new OptionKey(InlineRenameSessionOptionsStorage.PreviewChanges), value); + _session.SetPreviewChanges(value); + } + } + } + + private bool _renameOverloadsFlag; + public bool RenameOverloadsFlag + { + get => _renameOverloadsFlag; + set + { + if (Set(ref _renameOverloadsFlag, value)) + { + _session.RenameService.GlobalOptions.SetGlobalOption(new OptionKey(InlineRenameSessionOptionsStorage.RenameOverloads), value); + _session.RefreshRenameSessionWithOptionsChanged(_session.Options with { RenameOverloads = value }); + } + } + } + + private bool _isCollapsed; + public bool IsCollapsed + { + get => _isCollapsed; + set + { + if (Set(ref _isCollapsed, value)) + { + NotifyPropertyChanged(nameof(IsExpanded)); + } + } + } + + public bool IsExpanded + { + get => !IsCollapsed; + set => IsCollapsed = !value; + } + + public bool IsRenameOverloadsEditable + => !_session.MustRenameOverloads; + + public void Submit() + { + _session.Commit(); + } + + public void Cancel() + { + _session.Cancel(); + } + + public void Dispose() + { + // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method + Dispose(disposing: true); + GC.SuppressFinalize(this); + } + + /// + /// Shell routes commands based on focused tool window. Since we're outside of a tool window, + /// Editor can end up intercepting commands and TYPECHARs sent to us, even when we're focused, + /// so hook in and intercept each message for WPF. + /// + public void RegisterOleComponent() + { + Debug.Assert(_oleComponent is null); + + _oleComponent = OleComponent.CreateHostedComponent("Microsoft CodeAnalysis Inline Rename"); + _oleComponent.PreTranslateMessage += OnPreTranslateMessage; + _oleComponent.BeginTracking(); + } + + private void UnregisterOleComponent() + { + if (_oleComponent is not null) + { + _oleComponent.EndTracking(); + _oleComponent.PreTranslateMessage -= OnPreTranslateMessage; + _oleComponent.Dispose(); + _oleComponent = null; + } + } + + private void OnPreTranslateMessage(object sender, PreTranslateMessageEventArgs e) + { + var msg = e.Message; + if (ComponentDispatcher.RaiseThreadMessage(ref msg) || IsSuppressedMessage(msg)) + { + e.MessageConsumed = true; + } + + // When the adornment is focused, we register an OleComponent to divert window messages + // away from the editor and back to WPF to enable proper handling of arrows, backspace, + // delete, etc. Unfortunately, anything not handled by WPF is then propagated back to the + // shell command system where it is handled by the open editor window. + // To avoid unhandled arrow commands from being handled by editor, + // we mark them as handled so long as the adornment is focused. + static bool IsSuppressedMessage(MSG msg) + => msg.message switch + { + 0x0100 or // WM_KEYDOWN + 0x0101 // WM_KEYUP + => msg.wParam.ToInt32() switch + { + >= 0x0025 and <= 0x0028 => true, // VK_LEFT, VK_UP, VK_RIGHT, and VK_DOWN + + 0x0021 or // VK_PRIOR (Page Up) + 0x0022 or // VK_NEXT (Page Down) + 0x0023 or // VK_END + 0x0024 or // VK_HOME + 0x0D00 or // VK_RETURN + 0x0009 => true, // VK_TAB + + _ => false + }, + + _ => false + }; + } + + protected virtual void Dispose(bool disposing) + { + if (!_disposedValue) + { + if (disposing) + { + _session.ReplacementTextChanged -= OnReplacementTextChanged; + + UnregisterOleComponent(); + } + + _disposedValue = true; + } + } + + private void OnReplacementTextChanged(object sender, EventArgs e) + { + NotifyPropertyChanged(nameof(IdentifierText)); + } + + private void NotifyPropertyChanged([CallerMemberName] string? name = null) + => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name)); + + private bool Set(ref T field, T newValue, [CallerMemberName] string? name = null) + { + if (EqualityComparer.Default.Equals(field, newValue)) + { + return false; + } + + field = newValue; + NotifyPropertyChanged(name); + return true; + } + } +} diff --git a/src/EditorFeatures/Core.Wpf/InlineRename/Dashboard/Dashboard.xaml b/src/EditorFeatures/Core.Wpf/InlineRename/UI/Dashboard/Dashboard.xaml similarity index 96% rename from src/EditorFeatures/Core.Wpf/InlineRename/Dashboard/Dashboard.xaml rename to src/EditorFeatures/Core.Wpf/InlineRename/UI/Dashboard/Dashboard.xaml index 18c0b5beaba69..f0a17489c9676 100644 --- a/src/EditorFeatures/Core.Wpf/InlineRename/Dashboard/Dashboard.xaml +++ b/src/EditorFeatures/Core.Wpf/InlineRename/UI/Dashboard/Dashboard.xaml @@ -24,15 +24,15 @@ - + - + @@ -9458,7 +9485,7 @@ static async Task F() var edits = GetTopEdits(src1, src2); // consider: these edits can be allowed if we get more sophisticated - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.AwaitStatementUpdate, "F(2, await F(1));"), Diagnostic(RudeEditKind.AwaitStatementUpdate, "F(1, await F(2));"), Diagnostic(RudeEditKind.AwaitStatementUpdate, "F(await F(2));"), @@ -9521,7 +9548,7 @@ static async Task F() "; var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.Delete, "F(2);", CSharpFeaturesResources.await_expression)); } @@ -9548,7 +9575,7 @@ static async Task F() "; var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.Delete, "await F(1);", CSharpFeaturesResources.await_expression)); } @@ -9569,7 +9596,7 @@ class C "; var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.Delete, "static async Task F()", CSharpFeaturesResources.await_expression)); } @@ -9590,7 +9617,7 @@ class C "; var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics(ActiveStatementsDescription.Empty, + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.Delete, "static async Task F()", CSharpFeaturesResources.await_expression)); } @@ -9617,7 +9644,7 @@ static async Task F() "; var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics(ActiveStatementsDescription.Empty, + edits.VerifySemanticDiagnostics(ActiveStatementsDescription.Empty, Diagnostic(RudeEditKind.ChangingFromAsynchronousToSynchronous, "foreach (var x in G())", CSharpFeaturesResources.foreach_statement)); } @@ -9644,7 +9671,7 @@ static async Task F() "; var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics(ActiveStatementsDescription.Empty, + edits.VerifySemanticDiagnostics(ActiveStatementsDescription.Empty, Diagnostic(RudeEditKind.ChangingFromAsynchronousToSynchronous, "foreach (var (x, y) in G())", CSharpFeaturesResources.foreach_statement)); } @@ -9670,7 +9697,7 @@ static async Task F() "; var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics(ActiveStatementsDescription.Empty, + edits.VerifySemanticDiagnostics(ActiveStatementsDescription.Empty, Diagnostic(RudeEditKind.Delete, "{", CSharpFeaturesResources.asynchronous_foreach_statement)); } @@ -9697,7 +9724,7 @@ static async Task F() "; var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics(ActiveStatementsDescription.Empty, + edits.VerifySemanticDiagnostics(ActiveStatementsDescription.Empty, Diagnostic(RudeEditKind.Delete, "await using", CSharpFeaturesResources.asynchronous_using_declaration)); } @@ -9724,7 +9751,7 @@ static async Task F() "; var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics(ActiveStatementsDescription.Empty, + edits.VerifySemanticDiagnostics(ActiveStatementsDescription.Empty, Diagnostic(RudeEditKind.Delete, "await using", CSharpFeaturesResources.asynchronous_using_declaration)); } @@ -9750,7 +9777,7 @@ static async Task F() "; var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics(ActiveStatementsDescription.Empty, + edits.VerifySemanticDiagnostics(ActiveStatementsDescription.Empty, Diagnostic(RudeEditKind.Delete, "{", CSharpFeaturesResources.asynchronous_using_declaration), Diagnostic(RudeEditKind.Delete, "{", CSharpFeaturesResources.asynchronous_using_declaration)); } @@ -9778,7 +9805,7 @@ static async Task F() "; var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics(ActiveStatementsDescription.Empty, + edits.VerifySemanticDiagnostics(ActiveStatementsDescription.Empty, Diagnostic(RudeEditKind.ChangingFromAsynchronousToSynchronous, "using", CSharpFeaturesResources.using_declaration), Diagnostic(RudeEditKind.ChangingFromAsynchronousToSynchronous, "using", CSharpFeaturesResources.using_declaration)); } @@ -9833,7 +9860,7 @@ static async IEnumerable F() "; var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.Insert, "await", CSharpFeaturesResources.await_expression), Diagnostic(RudeEditKind.Insert, "await", CSharpFeaturesResources.await_expression)); } @@ -9863,7 +9890,7 @@ static async IEnumerable F() "; var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.Delete, "await", CSharpFeaturesResources.await_expression), Diagnostic(RudeEditKind.Insert, "await", CSharpFeaturesResources.await_expression), Diagnostic(RudeEditKind.Insert, "await", CSharpFeaturesResources.await_expression), @@ -9887,7 +9914,7 @@ class C "; var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.Insert, "await", CSharpFeaturesResources.await_expression)); } @@ -9908,7 +9935,8 @@ class C "; var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics( + capabilities: EditAndContinueCapabilities.NewTypeDefinition); } [Fact] @@ -9935,7 +9963,8 @@ static async Task F() var edits = GetTopEdits(src1, src2); // ok to add awaits if there were none before and no active statements - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics( + capabilities: EditAndContinueCapabilities.NewTypeDefinition); } [Fact] @@ -9965,7 +9994,7 @@ static async Task F() "; var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.Insert, "await", "await")); } @@ -9992,7 +10021,7 @@ static async Task F() "; var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.Insert, "y = new D()", CSharpFeaturesResources.asynchronous_using_declaration)); } @@ -10021,7 +10050,7 @@ static async Task F() "; var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.Insert, "await", "await")); } @@ -10059,7 +10088,7 @@ static async IAsyncEnumerable F() "; var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.ChangingStateMachineShape, "await foreach (var x in G()) { }", CSharpFeaturesResources.await_expression, CSharpFeaturesResources.asynchronous_foreach_statement), Diagnostic(RudeEditKind.ChangingStateMachineShape, "x = new D()", CSharpFeaturesResources.await_expression, CSharpFeaturesResources.asynchronous_using_declaration), Diagnostic(RudeEditKind.ChangingStateMachineShape, "y = new D()", CSharpFeaturesResources.await_expression, CSharpFeaturesResources.asynchronous_using_declaration), @@ -10099,7 +10128,7 @@ static async Task F() edits.VerifySemanticDiagnostics( targetFrameworks: new[] { TargetFramework.MinimalAsync }, - expectedDiagnostics: new[] + diagnostics: new[] { Diagnostic(RudeEditKind.UpdatingStateMachineMethodMissingAttribute, "static async Task F()", "System.Runtime.CompilerServices.AsyncStateMachineAttribute") }); @@ -10134,7 +10163,8 @@ static async Task F() var edits = GetTopEdits(src1, src2); edits.VerifySemanticDiagnostics( - targetFrameworks: new[] { TargetFramework.MinimalAsync }); + targetFrameworks: new[] { TargetFramework.MinimalAsync }, + capabilities: EditAndContinueCapabilities.NewTypeDefinition); } [Fact] diff --git a/src/EditorFeatures/CSharpTest/EditAndContinue/TopLevelEditingTests.cs b/src/EditorFeatures/CSharpTest/EditAndContinue/TopLevelEditingTests.cs index 1b69ecd483209..2f3263f7ac372 100644 --- a/src/EditorFeatures/CSharpTest/EditAndContinue/TopLevelEditingTests.cs +++ b/src/EditorFeatures/CSharpTest/EditAndContinue/TopLevelEditingTests.cs @@ -39,7 +39,7 @@ public void Using_Global_Insert() "Insert [global using D = System.Diagnostics;]@2", "Insert [global using System.Collections;]@40"); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics(); } [Fact] @@ -73,7 +73,7 @@ public void Using_Delete2() "Delete [using D = System.Diagnostics;]@2", "Delete [using System.Collections;]@33"); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics(); } [Fact] @@ -93,7 +93,7 @@ public void Using_Insert() "Insert [using D = System.Diagnostics;]@2", "Insert [using System.Collections;]@33"); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics(); } [Fact] @@ -114,7 +114,7 @@ public void Using_Update1() edits.VerifyEdits( "Update [using System.Collections;]@29 -> [using X = System.Collections;]@29"); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics(); } [Fact] @@ -135,7 +135,7 @@ public void Using_Update2() edits.VerifyEdits( "Update [using X1 = System.Collections;]@29 -> [using X2 = System.Collections;]@29"); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics(); } [Fact] @@ -156,7 +156,7 @@ public void Using_Update3() edits.VerifyEdits( "Update [using System.Diagnostics;]@2 -> [using System;]@2"); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics(); } [Fact] @@ -394,7 +394,9 @@ void M2() }"; var edits = GetTopEdits(src1, src2); - edits.VerifySemantics(SemanticEdit(SemanticEditKind.Insert, c => c.GetMember("N.C.M2"))); + edits.VerifySemantics( + new[] { SemanticEdit(SemanticEditKind.Insert, c => c.GetMember("N.C.M2")) }, + capabilities: EditAndContinueCapabilities.AddMethodToExistingType); } #endregion @@ -412,7 +414,7 @@ public void ExternAliasUpdate() edits.VerifyEdits( "Update [extern alias X;]@0 -> [extern alias Y;]@0"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.Update, "extern alias Y;", CSharpFeaturesResources.extern_alias)); } @@ -427,7 +429,7 @@ public void ExternAliasInsert() edits.VerifyEdits( "Insert [extern alias Y;]@0"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.Insert, "extern alias Y;", CSharpFeaturesResources.extern_alias)); } @@ -442,7 +444,7 @@ public void ExternAliasDelete() edits.VerifyEdits( "Delete [extern alias Y;]@0"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.Delete, null, CSharpFeaturesResources.extern_alias)); } @@ -462,7 +464,7 @@ public void Insert_TopLevelAttribute() "Insert [[assembly: System.Obsolete(\"2\")]]@0", "Insert [System.Obsolete(\"2\")]@11"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.Insert, "[assembly: System.Obsolete(\"2\")]", FeaturesResources.attribute)); } @@ -478,7 +480,7 @@ public void Delete_TopLevelAttribute() "Delete [[assembly: System.Obsolete(\"2\")]]@0", "Delete [System.Obsolete(\"2\")]@11"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.Delete, null, FeaturesResources.attribute)); } @@ -494,7 +496,7 @@ public void Update_TopLevelAttribute() "Update [[assembly: System.Obsolete(\"1\")]]@0 -> [[assembly: System.Obsolete(\"2\")]]@0", "Update [System.Obsolete(\"1\")]@11 -> [System.Obsolete(\"2\")]@11"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.Update, "System.Obsolete(\"2\")", FeaturesResources.attribute)); } @@ -509,7 +511,7 @@ public void Reorder_TopLevelAttribute() edits.VerifyEdits( "Reorder [[assembly: System.Obsolete(\"2\")]]@32 -> @0"); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics(); } #endregion @@ -532,7 +534,7 @@ public void Type_Kind_Update(string oldKeyword, string newKeyword) edits.VerifyEdits( "Update [" + oldKeyword + " C { }]@0 -> [" + newKeyword + " C { }]@0"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.TypeKindUpdate, newKeyword + " C")); } @@ -553,7 +555,8 @@ public void Type_Kind_Update_Reloadable(string oldKeyword, string newKeyword) "Update [[CreateNewOnMetadataUpdate]" + oldKeyword + " C { }]@145 -> [[CreateNewOnMetadataUpdate]" + newKeyword + " C { }]@145"); edits.VerifySemantics( - SemanticEdit(SemanticEditKind.Replace, c => c.GetMember("C"))); + new[] { SemanticEdit(SemanticEditKind.Replace, c => c.GetMember("C")) }, + capabilities: EditAndContinueCapabilities.NewTypeDefinition); } [Fact] @@ -567,7 +570,7 @@ public void Type_Modifiers_Static_Remove() edits.VerifyEdits( "Update [public static class C { }]@0 -> [public class C { }]@0"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.ModifiersUpdate, "public class C", FeaturesResources.class_)); } @@ -587,7 +590,7 @@ public void Type_Modifiers_Accessibility_Change(string accessibility) edits.VerifyEdits( "Update [" + accessibility + " class C { }]@0 -> [class C { }]@0"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.ChangingAccessibility, "class C", FeaturesResources.class_)); } @@ -648,7 +651,8 @@ public void Type_Modifiers_Accessibility_Reloadable() "Update [[CreateNewOnMetadataUpdate]public class C { }]@145 -> [[CreateNewOnMetadataUpdate]internal class C { }]@145"); edits.VerifySemantics( - SemanticEdit(SemanticEditKind.Replace, c => c.GetMember("C"))); + new[] { SemanticEdit(SemanticEditKind.Replace, c => c.GetMember("C")) }, + capabilities: EditAndContinueCapabilities.NewTypeDefinition); } [Theory] @@ -663,7 +667,7 @@ public void Type_Modifiers_NestedPrivateInInterface_Remove(string keyword) var src2 = "interface C { " + keyword + " S { } }"; var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.ChangingAccessibility, keyword + " S", GetResource(keyword))); } @@ -708,7 +712,7 @@ public void Type_Modifiers_Unsafe_Add() edits.VerifyEdits( "Update [public class C { }]@0 -> [public unsafe class C { }]@0"); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics(); } [Fact, WorkItem(48628, "https://github.com/dotnet/roslyn/issues/48628")] @@ -755,7 +759,7 @@ public event Action A { add { } remove { } } "Update [unsafe C() {}]@218 -> [C() {}]@176", "Update [unsafe ~C() {}]@237 -> [~C() {}]@188"); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics(); } [Fact, WorkItem(48628, "https://github.com/dotnet/roslyn/issues/48628")] @@ -789,7 +793,7 @@ public void Type_Modifiers_Ref_Add() edits.VerifyEdits( "Update [public struct C { }]@0 -> [public ref struct C { }]@0"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.ModifiersUpdate, "public ref struct C", CSharpFeaturesResources.struct_)); } @@ -804,7 +808,7 @@ public void Type_Modifiers_Ref_Remove() edits.VerifyEdits( "Update [public ref struct C { }]@0 -> [public struct C { }]@0"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.ModifiersUpdate, "public struct C", CSharpFeaturesResources.struct_)); } @@ -819,7 +823,7 @@ public void Type_Modifiers_ReadOnly_Add() edits.VerifyEdits( "Update [public struct C { }]@0 -> [public readonly struct C { }]@0"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.ModifiersUpdate, "public readonly struct C", CSharpFeaturesResources.struct_)); } @@ -834,7 +838,7 @@ public void Type_Modifiers_ReadOnly_Remove() edits.VerifyEdits( "Update [public readonly struct C { }]@0 -> [public struct C { }]@0"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.ModifiersUpdate, "public struct C", CSharpFeaturesResources.struct_)); } @@ -877,9 +881,9 @@ public void Type_Attribute_Insert_SupportedByRuntime_NonCustomAttribute(string a edits.VerifyEdits( "Update [class C { public void M(int a) {} }]@0 -> [" + attributeType + "class C { public void M(int a) {} }]@0"); - edits.VerifyRudeDiagnostics( - capabilities: EditAndContinueTestHelpers.Net6RuntimeCapabilities, - Diagnostic(RudeEditKind.ChangingNonCustomAttribute, "class C", attributeName, FeaturesResources.class_)); + edits.VerifySemanticDiagnostics( + new[] { Diagnostic(RudeEditKind.ChangingNonCustomAttribute, "class C", attributeName, FeaturesResources.class_) }, + capabilities: EditAndContinueCapabilities.ChangeCustomAttributes); } [Fact] @@ -896,8 +900,9 @@ public void Type_Attribute_Update_NotSupportedByRuntime1() edits.VerifyEdits( "Update [[A1]class C { }]@98 -> [[A2]class C { }]@98"); - edits.VerifyRudeDiagnostics( - Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "class C", FeaturesResources.class_)); + edits.VerifySemanticDiagnostics( + new[] { Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "class C", FeaturesResources.class_) }, + capabilities: EditAndContinueCapabilities.Baseline); } [Fact] @@ -911,8 +916,9 @@ public void Type_Attribute_Update_NotSupportedByRuntime2() edits.VerifyEdits( "Update [[System.Obsolete(\"1\")]class C { }]@0 -> [[System.Obsolete(\"2\")]class C { }]@0"); - edits.VerifyRudeDiagnostics( - Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "class C", FeaturesResources.class_)); + edits.VerifySemanticDiagnostics( + new[] { Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "class C", FeaturesResources.class_) }, + capabilities: EditAndContinueCapabilities.Baseline); } [Fact] @@ -929,8 +935,9 @@ public void Type_Attribute_Delete_NotSupportedByRuntime1() edits.VerifyEdits( "Update [[A, B]class C { }]@96 -> [[A]class C { }]@96"); - edits.VerifyRudeDiagnostics( - Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "class C", FeaturesResources.class_)); + edits.VerifySemanticDiagnostics( + new[] { Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "class C", FeaturesResources.class_) }, + capabilities: EditAndContinueCapabilities.Baseline); } [Fact] @@ -947,8 +954,9 @@ public void Type_Attribute_Delete_NotSupportedByRuntime2() edits.VerifyEdits( "Update [[B, A]class C { }]@96 -> [[A]class C { }]@96"); - edits.VerifyRudeDiagnostics( - Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "class C", FeaturesResources.class_)); + edits.VerifySemanticDiagnostics( + new[] { Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "class C", FeaturesResources.class_) }, + capabilities: EditAndContinueCapabilities.Baseline); } [Fact] @@ -969,7 +977,8 @@ public class A3 : System.Attribute { } "Update [[CreateNewOnMetadataUpdate, A1, A2]class C { }]@267 -> [[CreateNewOnMetadataUpdate, A2, A3]class C { }]@267"); edits.VerifySemantics( - SemanticEdit(SemanticEditKind.Replace, c => c.GetMember("C"))); + new[] { SemanticEdit(SemanticEditKind.Replace, c => c.GetMember("C")) }, + capabilities: EditAndContinueCapabilities.NewTypeDefinition); } [Fact] @@ -981,7 +990,8 @@ public void Type_Attribute_ReloadableRemove() var edits = GetTopEdits(src1, src2); edits.VerifySemantics( - SemanticEdit(SemanticEditKind.Replace, c => c.GetMember("C"))); + new[] { SemanticEdit(SemanticEditKind.Replace, c => c.GetMember("C")) }, + capabilities: EditAndContinueCapabilities.NewTypeDefinition); } [Fact] @@ -995,7 +1005,7 @@ public void Type_Attribute_ReloadableAdd() edits.VerifySemantics( ActiveStatementsDescription.Empty, new[] { SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C")) }, - capabilities: EditAndContinueTestHelpers.Net6RuntimeCapabilities); + capabilities: EditAndContinueCapabilities.ChangeCustomAttributes); } [Fact] @@ -1007,7 +1017,8 @@ public void Type_Attribute_ReloadableBase() var edits = GetTopEdits(src1, src2); edits.VerifySemantics( - SemanticEdit(SemanticEditKind.Replace, c => c.GetMember("C"))); + new[] { SemanticEdit(SemanticEditKind.Replace, c => c.GetMember("C")) }, + capabilities: EditAndContinueCapabilities.NewTypeDefinition); } [Fact] @@ -1027,7 +1038,7 @@ public void Type_Attribute_Add() edits.VerifySemantics( ActiveStatementsDescription.Empty, new[] { SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C")) }, - capabilities: EditAndContinueTestHelpers.Net6RuntimeCapabilities); + capabilities: EditAndContinueCapabilities.ChangeCustomAttributes); } [Fact] @@ -1044,8 +1055,9 @@ public void Type_Attribute_Add_NotSupportedByRuntime1() edits.VerifyEdits( "Update [[A]class C { }]@96 -> [[A, B]class C { }]@96"); - edits.VerifyRudeDiagnostics( - Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "class C", FeaturesResources.class_)); + edits.VerifySemanticDiagnostics( + new[] { Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "class C", FeaturesResources.class_) }, + capabilities: EditAndContinueCapabilities.Baseline); } [Fact] @@ -1061,8 +1073,9 @@ public void Type_Attribute_Add_NotSupportedByRuntime2() edits.VerifyEdits( "Update [class C { }]@48 -> [[A]class C { }]@48"); - edits.VerifyRudeDiagnostics( - Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "class C", FeaturesResources.class_)); + edits.VerifySemanticDiagnostics( + new[] { Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "class C", FeaturesResources.class_) }, + capabilities: EditAndContinueCapabilities.Baseline); } [Fact] @@ -1076,7 +1089,7 @@ public void Type_Attribute_Reorder1() edits.VerifyEdits( "Update [[A(1), B(2), C(3)]class C { }]@0 -> [[C(3), A(1), B(2)]class C { }]@0"); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics(); } [Fact] @@ -1090,7 +1103,7 @@ public void Type_Attribute_Reorder2() edits.VerifyEdits( "Update [[A, B, C]class C { }]@0 -> [[B, C, A]class C { }]@0"); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics(); } [Fact] @@ -1107,8 +1120,9 @@ public void Type_Attribute_ReorderAndUpdate_NotSupportedByRuntime() edits.VerifyEdits( "Update [[System.Obsolete(\"1\"), A, B]class C { }]@96 -> [[A, B, System.Obsolete(\"2\")]class C { }]@96"); - edits.VerifyRudeDiagnostics( - Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "class C", FeaturesResources.class_)); + edits.VerifySemanticDiagnostics( + new[] { Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "class C", FeaturesResources.class_) }, + capabilities: EditAndContinueCapabilities.Baseline); } [Theory] @@ -1127,7 +1141,7 @@ public void Type_Rename(string keyword) edits.VerifyEdits( "Update [" + keyword + " C { }]@0 -> [" + keyword + " D { }]@0"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.Renamed, keyword + " D", GetResource(keyword))); } @@ -1147,7 +1161,7 @@ public void Type_Rename_AddAndDeleteMember() "Delete [int x = 1]@10", "Delete [x = 1]@14"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.Renamed, "class D", FeaturesResources.class_)); } @@ -1198,7 +1212,8 @@ public void Interface_NoModifiers_Insert() var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics( + capabilities: EditAndContinueCapabilities.NewTypeDefinition); } [Fact] @@ -1209,7 +1224,8 @@ public void Interface_NoModifiers_IntoNamespace_Insert() var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics( + capabilities: EditAndContinueCapabilities.NewTypeDefinition); } [Fact] @@ -1220,7 +1236,8 @@ public void Interface_NoModifiers_IntoType_Insert() var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics( + capabilities: EditAndContinueCapabilities.NewTypeDefinition); } [Fact] @@ -1231,7 +1248,8 @@ public void Class_NoModifiers_Insert() var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics( + capabilities: EditAndContinueCapabilities.NewTypeDefinition); } [Fact] @@ -1242,7 +1260,8 @@ public void Class_NoModifiers_IntoNamespace_Insert() var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics( + capabilities: EditAndContinueCapabilities.NewTypeDefinition); } [Fact] @@ -1253,7 +1272,8 @@ public void Class_NoModifiers_IntoType_Insert() var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics( + capabilities: EditAndContinueCapabilities.NewTypeDefinition); } [Fact] @@ -1264,7 +1284,8 @@ public void Struct_NoModifiers_Insert() var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics( + capabilities: EditAndContinueCapabilities.NewTypeDefinition); } [Fact] @@ -1275,7 +1296,8 @@ public void Struct_NoModifiers_IntoNamespace_Insert() var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics( + capabilities: EditAndContinueCapabilities.NewTypeDefinition); } [Fact] @@ -1286,7 +1308,7 @@ public void Struct_NoModifiers_IntoType_Insert() var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics(); } [Fact] @@ -1314,7 +1336,7 @@ public void Type_BaseType_Add_Changed() edits.VerifyEdits( "Update [class C { }]@0 -> [class C : D { }]@0"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.BaseTypeOrInterfaceUpdate, "class C", FeaturesResources.class_)); } @@ -1346,7 +1368,7 @@ public void Type_BaseType_Update_RuntimeTypeChanged(string oldType, string newTy var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.BaseTypeOrInterfaceUpdate, "class C", FeaturesResources.class_)); } @@ -1372,7 +1394,7 @@ public void Type_BaseInterface_Add() edits.VerifyEdits( "Update [class C { }]@0 -> [class C : IDisposable { }]@0"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.BaseTypeOrInterfaceUpdate, "class C", FeaturesResources.class_)); } @@ -1408,7 +1430,7 @@ public void Type_BaseInterface_Reorder() edits.VerifyEdits( "Update [class C : IGoo, IBar { }]@0 -> [class C : IBar, IGoo { }]@0"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.BaseTypeOrInterfaceUpdate, "class C", FeaturesResources.class_)); } @@ -1438,7 +1460,7 @@ public void Type_BaseInterface_Update_RuntimeTypeChanged(string oldType, string var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.BaseTypeOrInterfaceUpdate, "class C", FeaturesResources.class_)); } @@ -1529,9 +1551,9 @@ public class C }"; var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics( - capabilities: EditAndContinueTestHelpers.BaselineCapabilities, - Diagnostic(RudeEditKind.ChangingReloadableTypeNotSupportedByRuntime, "void F()", "CreateNewOnMetadataUpdateAttribute")); + edits.VerifySemanticDiagnostics( + new[] { Diagnostic(RudeEditKind.ChangingReloadableTypeNotSupportedByRuntime, "void F()", "CreateNewOnMetadataUpdateAttribute") }, + capabilities: EditAndContinueCapabilities.Baseline); } [Fact] @@ -1547,7 +1569,8 @@ public virtual void G() {} }"; var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics( + capabilities: EditAndContinueCapabilities.NewTypeDefinition); } [Fact] @@ -1576,9 +1599,9 @@ void M() }"; var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics( - capabilities: EditAndContinueTestHelpers.BaselineCapabilities, - Diagnostic(RudeEditKind.InsertNotSupportedByRuntime, "public class D", FeaturesResources.class_)); + edits.VerifySemanticDiagnostics( + new[] { Diagnostic(RudeEditKind.InsertNotSupportedByRuntime, "public class D", FeaturesResources.class_) }, + capabilities: EditAndContinueCapabilities.Baseline); } [Fact] @@ -1590,7 +1613,8 @@ public void Type_Insert_Reloadable() var edits = GetTopEdits(src1, src2); edits.VerifySemantics( - SemanticEdit(SemanticEditKind.Insert, c => c.GetMember("C"))); + new[] { SemanticEdit(SemanticEditKind.Insert, c => c.GetMember("C")) }, + capabilities: EditAndContinueCapabilities.NewTypeDefinition); } [Fact] @@ -1605,7 +1629,8 @@ static void G() {} }"; var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics( + capabilities: EditAndContinueCapabilities.NewTypeDefinition); } [Fact] @@ -1619,7 +1644,8 @@ public void RefStructInsert() edits.VerifyEdits( "Insert [ref struct X { }]@0"); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics( + capabilities: EditAndContinueCapabilities.NewTypeDefinition); } [Fact] @@ -1633,7 +1659,8 @@ public void Struct_ReadOnly_Insert() edits.VerifyEdits( "Insert [readonly struct X { }]@0"); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics( + capabilities: EditAndContinueCapabilities.NewTypeDefinition); } [Fact] @@ -1647,7 +1674,7 @@ public void Struct_RefModifier_Add() edits.VerifyEdits( "Update [struct X { }]@0 -> [ref struct X { }]@0"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.ModifiersUpdate, "ref struct X", CSharpFeaturesResources.struct_)); } @@ -1662,7 +1689,7 @@ public void Struct_ReadonlyModifier_Add() edits.VerifyEdits( "Update [struct X { }]@0 -> [readonly struct X { }]@0"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.ModifiersUpdate, "readonly struct X", SyntaxFacts.GetText(SyntaxKind.StructKeyword))); } @@ -1748,7 +1775,8 @@ public class SubClass : BaseClass, IConflict // Here we add a class implementing an interface and a method inside it with explicit interface specifier. // We want to be sure that adding the method will not tirgger a rude edit as it happens if adding a single method with explicit interface specifier. - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics( + capabilities: EditAndContinueCapabilities.NewTypeDefinition); } [WorkItem(37128, "https://github.com/dotnet/roslyn/issues/37128")] @@ -1945,7 +1973,8 @@ class D {} "; var edits = GetTopEdits(src1, src2); edits.VerifySemantics( - SemanticEdit(SemanticEditKind.Replace, c => c.GetMember("C"))); + new[] { SemanticEdit(SemanticEditKind.Replace, c => c.GetMember("C")) }, + capabilities: EditAndContinueCapabilities.NewTypeDefinition); } [Fact] @@ -2052,8 +2081,8 @@ public void Type_Partial_InsertFirstDeclaration() var src2 = "partial class C { void F() {} }"; GetTopEdits(src1, src2).VerifySemantics( - ActiveStatementsDescription.Empty, - new[] { SemanticEdit(SemanticEditKind.Insert, c => c.GetMember("C"), preserveLocalVariables: false) }); + new[] { SemanticEdit(SemanticEditKind.Insert, c => c.GetMember("C"), preserveLocalVariables: false) }, + capabilities: EditAndContinueCapabilities.NewTypeDefinition); } [Fact] @@ -2075,7 +2104,8 @@ public void Type_Partial_InsertSecondDeclaration() { SemanticEdit(SemanticEditKind.Insert, c => c.GetMember("C").GetMember("G"), preserveLocalVariables: false) }), - }); + }, + capabilities: EditAndContinueCapabilities.AddMethodToExistingType); } [Fact] @@ -2096,7 +2126,8 @@ public void Type_Partial_Reloadable() { SemanticEdit(SemanticEditKind.Replace, c => c.GetMember("C"), partialType: "C") }), - }); + }, + capabilities: EditAndContinueCapabilities.NewTypeDefinition); } [Fact] @@ -2147,7 +2178,8 @@ public void Type_DeleteInsert_Reloadable() { SemanticEdit(SemanticEditKind.Replace, c => c.GetMember("C")), }) - }); + }, + capabilities: EditAndContinueCapabilities.NewTypeDefinition); } [Fact] @@ -2246,7 +2278,7 @@ void F() {} SemanticEdit(SemanticEditKind.Update, c => c.GetMember("I").GetMember("F")), }) }, - capabilities: EditAndContinueTestHelpers.Net6RuntimeCapabilities); + capabilities: EditAndContinueCapabilities.ChangeCustomAttributes); } [Fact] @@ -2393,7 +2425,7 @@ partial record C { }"; edits.VerifySemantics(); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics(); } [Fact] @@ -2407,7 +2439,7 @@ public void Record_Name_Update() edits.VerifyEdits( "Update [record C { }]@0 -> [record D { }]@0"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.Renamed, "record D", CSharpFeaturesResources.record_)); } @@ -2419,7 +2451,8 @@ public void RecordStruct_NoModifiers_Insert() var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics( + capabilities: EditAndContinueCapabilities.NewTypeDefinition); } [Fact] @@ -2468,7 +2501,8 @@ public void Record_NoModifiers_Insert() var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics( + capabilities: EditAndContinueCapabilities.NewTypeDefinition); } [Fact] @@ -2479,7 +2513,8 @@ public void Record_NoModifiers_IntoNamespace_Insert() var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics( + capabilities: EditAndContinueCapabilities.NewTypeDefinition); } [Fact] @@ -2490,7 +2525,8 @@ public void Record_NoModifiers_IntoType_Insert() var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics( + capabilities: EditAndContinueCapabilities.NewTypeDefinition); } [Fact] @@ -2504,7 +2540,7 @@ public void Record_BaseTypeUpdate1() edits.VerifyEdits( "Update [record C { }]@0 -> [record C : D { }]@0"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.BaseTypeOrInterfaceUpdate, "record C", CSharpFeaturesResources.record_)); } @@ -2519,7 +2555,7 @@ public void Record_BaseTypeUpdate2() edits.VerifyEdits( "Update [record C : D1 { }]@0 -> [record C : D2 { }]@0"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.BaseTypeOrInterfaceUpdate, "record C", CSharpFeaturesResources.record_)); } @@ -2534,7 +2570,7 @@ public void Record_BaseInterfaceUpdate1() edits.VerifyEdits( "Update [record C { }]@0 -> [record C : IDisposable { }]@0"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.BaseTypeOrInterfaceUpdate, "record C", CSharpFeaturesResources.record_)); } @@ -2549,7 +2585,7 @@ public void Record_BaseInterfaceUpdate2() edits.VerifyEdits( "Update [record C : IGoo, IBar { }]@0 -> [record C : IGoo { }]@0"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.BaseTypeOrInterfaceUpdate, "record C", CSharpFeaturesResources.record_)); } @@ -2564,7 +2600,7 @@ public void Record_BaseInterfaceUpdate3() edits.VerifyEdits( "Update [record C : IGoo, IBar { }]@0 -> [record C : IBar, IGoo { }]@0"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.BaseTypeOrInterfaceUpdate, "record C", CSharpFeaturesResources.record_)); } @@ -2581,7 +2617,8 @@ public override void H() {} }"; var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics( + capabilities: EditAndContinueCapabilities.NewTypeDefinition); } [Fact] @@ -2601,7 +2638,7 @@ public C() edits.VerifySemantics( SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").InstanceConstructors.First(c => c.ToString() == "C.C()"), preserveLocalVariables: true)); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics(); } [Fact] @@ -2621,7 +2658,7 @@ public C() edits.VerifySemantics( SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").InstanceConstructors.First(c => c.ToString() == "C.C()"), preserveLocalVariables: true)); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics(); } [Fact] @@ -2642,7 +2679,7 @@ protected virtual bool PrintMembers(System.Text.StringBuilder builder) edits.VerifySemantics( SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C.PrintMembers"))); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics(); } [Fact] @@ -2663,7 +2700,7 @@ private readonly bool PrintMembers(System.Text.StringBuilder builder) edits.VerifySemantics( SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C.PrintMembers"))); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics(); } [Fact] @@ -2691,12 +2728,15 @@ protected C(C other) var edits = GetTopEdits(src1, src2); edits.VerifySemanticDiagnostics( - Diagnostic(RudeEditKind.ExplicitRecordMethodParameterNamesMustMatch, "protected virtual bool PrintMembers(System.Text.StringBuilder sb)", "PrintMembers(System.Text.StringBuilder builder)"), - Diagnostic(RudeEditKind.ExplicitRecordMethodParameterNamesMustMatch, "public virtual bool Equals(C rhs)", "Equals(C other)"), - Diagnostic(RudeEditKind.ExplicitRecordMethodParameterNamesMustMatch, "protected C(C other)", "C(C original)")); + new[] + { + Diagnostic(RudeEditKind.ExplicitRecordMethodParameterNamesMustMatch, "protected virtual bool PrintMembers(System.Text.StringBuilder sb)", "PrintMembers(System.Text.StringBuilder builder)"), + Diagnostic(RudeEditKind.ExplicitRecordMethodParameterNamesMustMatch, "public virtual bool Equals(C rhs)", "Equals(C other)"), + Diagnostic(RudeEditKind.ExplicitRecordMethodParameterNamesMustMatch, "protected C(C other)", "C(C original)") + }, + capabilities: EditAndContinueCapabilities.Baseline); edits.VerifySemantics( - ActiveStatementsDescription.Empty, new[] { SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C.PrintMembers")), @@ -2704,7 +2744,7 @@ protected C(C other) SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").Constructors.Single(c => c.Parameters.FirstOrDefault()?.Type.ToDisplayString() == "C"), preserveLocalVariables: true), SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").Constructors.Single(c => c.Parameters.Length == 0), preserveLocalVariables: true), }, - EditAndContinueTestHelpers.Net6RuntimeCapabilities); + capabilities: EditAndContinueCapabilities.UpdateParameters); } [Fact] @@ -2725,7 +2765,7 @@ public override string ToString() edits.VerifySemantics( SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C.ToString"))); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics(); } [Fact] @@ -2746,7 +2786,7 @@ public override string ToString() edits.VerifySemantics( SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C.ToString"))); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics(); } [Fact] @@ -2757,7 +2797,7 @@ public void Record_AddProperty_Primary() var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.Insert, "int Y", FeaturesResources.parameter)); } @@ -2778,7 +2818,7 @@ public C() edits.VerifySemantics( SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").InstanceConstructors.First(c => c.ToString() == "C.C()"), preserveLocalVariables: true)); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics(); } [Fact] @@ -2798,7 +2838,7 @@ public C() edits.VerifySemantics( SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").InstanceConstructors.First(c => c.ToString() == "C.C()"), preserveLocalVariables: true)); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics(); } [Fact] @@ -2814,14 +2854,16 @@ record C(int X) var edits = GetTopEdits(src1, src2); edits.VerifySemantics( - SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C.PrintMembers")), - SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").GetMembers("Equals").OfType().First(m => SymbolEqualityComparer.Default.Equals(m.Parameters[0].Type, m.ContainingType))), - SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C.GetHashCode")), - SemanticEdit(SemanticEditKind.Insert, c => c.GetMember("C.Y")), - SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").Constructors.Single(c => c.Parameters[0].Type.ToDisplayString() == "int"), preserveLocalVariables: true), - SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").Constructors.Single(c => c.Parameters[0].Type.ToDisplayString() == "C"))); - - edits.VerifyRudeDiagnostics(); + new[] + { + SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C.PrintMembers")), + SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").GetMembers("Equals").OfType().First(m => SymbolEqualityComparer.Default.Equals(m.Parameters[0].Type, m.ContainingType))), + SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C.GetHashCode")), + SemanticEdit(SemanticEditKind.Insert, c => c.GetMember("C.Y")), + SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").Constructors.Single(c => c.Parameters[0].Type.ToDisplayString() == "int"), preserveLocalVariables: true), + SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").Constructors.Single(c => c.Parameters[0].Type.ToDisplayString() == "C")) + }, + capabilities: EditAndContinueCapabilities.AddInstanceFieldToExistingType | EditAndContinueCapabilities.AddMethodToExistingType); } [Fact] @@ -2847,14 +2889,16 @@ public C(string fromAString) var edits = GetTopEdits(src1, src2); edits.VerifySemantics( - SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C.PrintMembers")), - SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").GetMembers("Equals").OfType().First(m => SymbolEqualityComparer.Default.Equals(m.Parameters[0].Type, m.ContainingType))), - SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C.GetHashCode")), - SemanticEdit(SemanticEditKind.Insert, c => c.GetMember("C.Y")), - SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").Constructors.Single(c => c.Parameters[0].Type.ToDisplayString() == "int"), preserveLocalVariables: true), - SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").Constructors.Single(c => c.Parameters[0].Type.ToDisplayString() == "C"))); - - edits.VerifyRudeDiagnostics(); + new[] + { + SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C.PrintMembers")), + SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").GetMembers("Equals").OfType().First(m => SymbolEqualityComparer.Default.Equals(m.Parameters[0].Type, m.ContainingType))), + SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C.GetHashCode")), + SemanticEdit(SemanticEditKind.Insert, c => c.GetMember("C.Y")), + SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").Constructors.Single(c => c.Parameters[0].Type.ToDisplayString() == "int"), preserveLocalVariables: true), + SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").Constructors.Single(c => c.Parameters[0].Type.ToDisplayString() == "C")) + }, + capabilities: EditAndContinueCapabilities.AddInstanceFieldToExistingType | EditAndContinueCapabilities.AddMethodToExistingType); } [Fact] @@ -2910,10 +2954,12 @@ public C(C original) var edits = GetTopEdits(src1, src2); edits.VerifySemantics( - SemanticEdit(SemanticEditKind.Insert, c => c.GetMember("C.Y")), - SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").Constructors.Single(c => c.Parameters[0].Type.ToDisplayString() == "int"), preserveLocalVariables: true)); - - edits.VerifyRudeDiagnostics(); + new[] + { + SemanticEdit(SemanticEditKind.Insert, c => c.GetMember("C.Y")), + SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").Constructors.Single(c => c.Parameters[0].Type.ToDisplayString() == "int"), preserveLocalVariables: true) + }, + capabilities: EditAndContinueCapabilities.AddInstanceFieldToExistingType | EditAndContinueCapabilities.AddMethodToExistingType); } [Fact] @@ -2930,14 +2976,16 @@ record C(int X) var syntaxMap = GetSyntaxMap(src1, src2); edits.VerifySemantics( - SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C.PrintMembers")), - SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").GetMembers("Equals").OfType().First(m => SymbolEqualityComparer.Default.Equals(m.Parameters[0].Type, m.ContainingType))), - SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C.GetHashCode")), - SemanticEdit(SemanticEditKind.Insert, c => c.GetMember("C.Y")), - SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").Constructors.Single(c => c.Parameters[0].Type.ToDisplayString() == "int"), preserveLocalVariables: true), - SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").Constructors.Single(c => c.Parameters[0].Type.ToDisplayString() == "C"))); - - edits.VerifyRudeDiagnostics(); + new[] + { + SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C.PrintMembers")), + SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").GetMembers("Equals").OfType().First(m => SymbolEqualityComparer.Default.Equals(m.Parameters[0].Type, m.ContainingType))), + SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C.GetHashCode")), + SemanticEdit(SemanticEditKind.Insert, c => c.GetMember("C.Y")), + SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").Constructors.Single(c => c.Parameters[0].Type.ToDisplayString() == "int"), preserveLocalVariables: true), + SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").Constructors.Single(c => c.Parameters[0].Type.ToDisplayString() == "C")) + }, + capabilities: EditAndContinueCapabilities.AddInstanceFieldToExistingType | EditAndContinueCapabilities.AddMethodToExistingType); } [Fact] @@ -2949,14 +2997,16 @@ public void Record_AddField() var edits = GetTopEdits(src1, src2); edits.VerifySemantics( - SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C.PrintMembers")), - SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").GetMembers("Equals").OfType().First(m => SymbolEqualityComparer.Default.Equals(m.Parameters[0].Type, m.ContainingType))), - SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C.GetHashCode")), - SemanticEdit(SemanticEditKind.Insert, c => c.GetMember("C._y")), - SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").Constructors.Single(c => c.Parameters[0].Type.ToDisplayString() == "int"), preserveLocalVariables: true), - SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").Constructors.Single(c => c.Parameters[0].Type.ToDisplayString() == "C"))); - - edits.VerifyRudeDiagnostics(); + new[] + { + SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C.PrintMembers")), + SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").GetMembers("Equals").OfType().First(m => SymbolEqualityComparer.Default.Equals(m.Parameters[0].Type, m.ContainingType))), + SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C.GetHashCode")), + SemanticEdit(SemanticEditKind.Insert, c => c.GetMember("C._y")), + SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").Constructors.Single(c => c.Parameters[0].Type.ToDisplayString() == "int"), preserveLocalVariables: true), + SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").Constructors.Single(c => c.Parameters[0].Type.ToDisplayString() == "C")) + }, + capabilities: EditAndContinueCapabilities.AddInstanceFieldToExistingType); } [Fact] @@ -2982,13 +3032,15 @@ public C(C other) var edits = GetTopEdits(src1, src2); edits.VerifySemantics( - SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C.PrintMembers")), - SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").GetMembers("Equals").OfType().First(m => SymbolEqualityComparer.Default.Equals(m.Parameters[0].Type, m.ContainingType))), - SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C.GetHashCode")), - SemanticEdit(SemanticEditKind.Insert, c => c.GetMember("C._y")), - SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").Constructors.Single(c => c.Parameters[0].Type.ToDisplayString() == "int"), preserveLocalVariables: true)); - - edits.VerifyRudeDiagnostics(); + new[] + { + SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C.PrintMembers")), + SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").GetMembers("Equals").OfType().First(m => SymbolEqualityComparer.Default.Equals(m.Parameters[0].Type, m.ContainingType))), + SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C.GetHashCode")), + SemanticEdit(SemanticEditKind.Insert, c => c.GetMember("C._y")), + SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").Constructors.Single(c => c.Parameters[0].Type.ToDisplayString() == "int"), preserveLocalVariables: true) + }, + capabilities: EditAndContinueCapabilities.AddInstanceFieldToExistingType); } [Fact] @@ -3001,14 +3053,16 @@ public void Record_AddField_WithInitializer() var edits = GetTopEdits(src1, src2); edits.VerifySemantics( - SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C.PrintMembers")), - SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").GetMembers("Equals").OfType().First(m => SymbolEqualityComparer.Default.Equals(m.Parameters[0].Type, m.ContainingType))), - SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C.GetHashCode")), - SemanticEdit(SemanticEditKind.Insert, c => c.GetMember("C._y")), - SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").Constructors.Single(c => c.Parameters[0].Type.ToDisplayString() == "int"), preserveLocalVariables: true), - SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").Constructors.Single(c => c.Parameters[0].Type.ToDisplayString() == "C"))); - - edits.VerifyRudeDiagnostics(); + new[] + { + SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C.PrintMembers")), + SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").GetMembers("Equals").OfType().First(m => SymbolEqualityComparer.Default.Equals(m.Parameters[0].Type, m.ContainingType))), + SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C.GetHashCode")), + SemanticEdit(SemanticEditKind.Insert, c => c.GetMember("C._y")), + SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").Constructors.Single(c => c.Parameters[0].Type.ToDisplayString() == "int"), preserveLocalVariables: true), + SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").Constructors.Single(c => c.Parameters[0].Type.ToDisplayString() == "C")) + }, + capabilities: EditAndContinueCapabilities.AddInstanceFieldToExistingType); } [Fact] @@ -3021,14 +3075,16 @@ public void Record_AddField_WithExistingInitializer() var syntaxMap = GetSyntaxMap(src1, src2); edits.VerifySemantics( - SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C.PrintMembers")), - SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").GetMembers("Equals").OfType().First(m => SymbolEqualityComparer.Default.Equals(m.Parameters[0].Type, m.ContainingType))), - SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C.GetHashCode")), - SemanticEdit(SemanticEditKind.Insert, c => c.GetMember("C._z")), - SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").Constructors.Single(c => c.Parameters[0].Type.ToDisplayString() == "int"), syntaxMap[0]), - SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").Constructors.Single(c => c.Parameters[0].Type.ToDisplayString() == "C"))); - - edits.VerifyRudeDiagnostics(); + new[] + { + SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C.PrintMembers")), + SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").GetMembers("Equals").OfType().First(m => SymbolEqualityComparer.Default.Equals(m.Parameters[0].Type, m.ContainingType))), + SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C.GetHashCode")), + SemanticEdit(SemanticEditKind.Insert, c => c.GetMember("C._z")), + SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").Constructors.Single(c => c.Parameters[0].Type.ToDisplayString() == "int"), syntaxMap[0]), + SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").Constructors.Single(c => c.Parameters[0].Type.ToDisplayString() == "C")) + }, + capabilities: EditAndContinueCapabilities.AddInstanceFieldToExistingType); } [Fact] @@ -3041,14 +3097,16 @@ public void Record_AddField_WithInitializerAndExistingInitializer() var syntaxMap = GetSyntaxMap(src1, src2); edits.VerifySemantics( - SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C.PrintMembers")), - SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").GetMembers("Equals").OfType().First(m => SymbolEqualityComparer.Default.Equals(m.Parameters[0].Type, m.ContainingType))), - SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C.GetHashCode")), - SemanticEdit(SemanticEditKind.Insert, c => c.GetMember("C._z")), - SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").Constructors.Single(c => c.Parameters[0].Type.ToDisplayString() == "int"), syntaxMap[0]), - SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").Constructors.Single(c => c.Parameters[0].Type.ToDisplayString() == "C"))); - - edits.VerifyRudeDiagnostics(); + new[] + { + SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C.PrintMembers")), + SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").GetMembers("Equals").OfType().First(m => SymbolEqualityComparer.Default.Equals(m.Parameters[0].Type, m.ContainingType))), + SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C.GetHashCode")), + SemanticEdit(SemanticEditKind.Insert, c => c.GetMember("C._z")), + SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").Constructors.Single(c => c.Parameters[0].Type.ToDisplayString() == "int"), syntaxMap[0]), + SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").Constructors.Single(c => c.Parameters[0].Type.ToDisplayString() == "C")) + }, + capabilities: EditAndContinueCapabilities.AddInstanceFieldToExistingType); } [Fact] @@ -3059,7 +3117,7 @@ public void Record_DeleteField() var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics(Diagnostic(RudeEditKind.Delete, "record C", DeletedSymbolDisplay(FeaturesResources.field, "_y"))); + edits.VerifySemanticDiagnostics(Diagnostic(RudeEditKind.Delete, "record C", DeletedSymbolDisplay(FeaturesResources.field, "_y"))); } [Fact] @@ -3070,7 +3128,7 @@ public void Record_DeleteProperty_Primary() var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics(Diagnostic(RudeEditKind.Delete, "record C", DeletedSymbolDisplay(FeaturesResources.parameter, "int Y"))); + edits.VerifySemanticDiagnostics(Diagnostic(RudeEditKind.Delete, "record C", DeletedSymbolDisplay(FeaturesResources.parameter, "int Y"))); } [Fact] @@ -3081,7 +3139,7 @@ public void Record_DeleteProperty_NotPrimary() var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.Delete, "record C", DeletedSymbolDisplay(FeaturesResources.auto_property, "P"))); } @@ -3100,7 +3158,7 @@ record C(int X) edits.VerifySemantics( SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").Constructors.Single(c => c.Parameters[0].Type.ToDisplayString() == "int"), preserveLocalVariables: true)); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics(); } [Fact] @@ -3134,7 +3192,7 @@ public int X SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").Constructors.Single(c => c.Parameters[0].Type.ToDisplayString() == "int"), preserveLocalVariables: true), SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").Constructors.Single(c => c.Parameters[0].Type.ToDisplayString() == "C"))); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics(); } [Fact] @@ -3158,7 +3216,7 @@ record C(int X) SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").Constructors.Single(c => c.Parameters[0].Type.ToDisplayString() == "int"), preserveLocalVariables: true), SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").Constructors.Single(c => c.Parameters[0].Type.ToDisplayString() == "C"))); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics(); } [Fact] @@ -3173,7 +3231,7 @@ record C(int X) var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.ImplementRecordParameterWithSet, "public int X", "X")); } @@ -3189,7 +3247,7 @@ record C(int X) var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.ImplementRecordParameterAsReadOnly, "public int X", "X")); } @@ -3208,7 +3266,7 @@ record C(int X) edits.VerifySemantics( SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").Constructors.Single(c => c.Parameters[0].Type.ToDisplayString() == "int"), preserveLocalVariables: true)); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics(); } [Fact] @@ -3232,7 +3290,7 @@ record C(int X) SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").Constructors.Single(c => c.Parameters[0].Type.ToDisplayString() == "int"), preserveLocalVariables: true), SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").Constructors.Single(c => c.Parameters[0].Type.ToDisplayString() == "C"))); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics(); } [Fact] @@ -3256,7 +3314,7 @@ record C(int X) SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").Constructors.Single(c => c.Parameters[0].Type.ToDisplayString() == "int"), preserveLocalVariables: true), SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").Constructors.Single(c => c.Parameters[0].Type.ToDisplayString() == "C"))); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics(); } [Fact] @@ -3442,7 +3500,7 @@ record C(int X) edits.VerifySemantics( SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").Constructors.Single(c => c.Parameters[0].Type.ToDisplayString() == "int"), preserveLocalVariables: true)); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics(); } [Fact] @@ -3460,7 +3518,7 @@ record C(int X) edits.VerifySemantics( SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").Constructors.Single(c => c.Parameters[0].Type.ToDisplayString() == "int"), preserveLocalVariables: true)); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics(); } [Fact] @@ -3475,7 +3533,7 @@ record C(int X) var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.Delete, "record C", DeletedSymbolDisplay(FeaturesResources.auto_property, "Y"))); } @@ -3515,7 +3573,8 @@ public void Enum_NoModifiers_Insert() var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics( + capabilities: EditAndContinueCapabilities.NewTypeDefinition); } [Fact] @@ -3526,7 +3585,8 @@ public void Enum_NoModifiers_IntoNamespace_Insert() var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics( + capabilities: EditAndContinueCapabilities.NewTypeDefinition); } [Fact] @@ -3537,7 +3597,7 @@ public void Enum_NoModifiers_IntoType_Insert() var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics(); } [Fact] @@ -3553,8 +3613,9 @@ public void Enum_Attribute_Insert() edits.VerifyEdits( "Update [enum E { }]@48 -> [[A]enum E { }]@48"); - edits.VerifyRudeDiagnostics( - Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "enum E", FeaturesResources.enum_)); + edits.VerifySemanticDiagnostics( + new[] { Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "enum E", FeaturesResources.enum_) }, + capabilities: EditAndContinueCapabilities.Baseline); } [Fact] @@ -3570,8 +3631,9 @@ public void Enum_Member_Attribute_Delete() edits.VerifyEdits( "Update [[A]X]@57 -> [X]@57"); - edits.VerifyRudeDiagnostics( - Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "X", FeaturesResources.enum_value)); + edits.VerifySemanticDiagnostics( + new[] { Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "X", FeaturesResources.enum_value) }, + capabilities: EditAndContinueCapabilities.Baseline); } [Fact] @@ -3587,8 +3649,9 @@ public void Enum_Member_Attribute_Insert() edits.VerifyEdits( "Update [X]@57 -> [[A]X]@57"); - edits.VerifyRudeDiagnostics( - Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "[A]X", FeaturesResources.enum_value)); + edits.VerifySemanticDiagnostics( + new[] { Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "[A]X", FeaturesResources.enum_value) }, + capabilities: EditAndContinueCapabilities.Baseline); } [Fact] @@ -3605,8 +3668,9 @@ public void Enum_Member_Attribute_Update() edits.VerifyEdits( "Update [[A1]X]@107 -> [[A2]X]@107"); - edits.VerifyRudeDiagnostics( - Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "[A2]X", FeaturesResources.enum_value)); + edits.VerifySemanticDiagnostics( + new[] { Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "[A2]X", FeaturesResources.enum_value) }, + capabilities: EditAndContinueCapabilities.Baseline); } [Fact] @@ -3627,7 +3691,7 @@ public void Enum_Member_Attribute_InsertDeleteAndUpdate() }), DocumentResults() }, - capabilities: EditAndContinueTestHelpers.Net6RuntimeCapabilities); + capabilities: EditAndContinueCapabilities.ChangeCustomAttributes); } [Fact] @@ -3641,7 +3705,7 @@ public void Enum_Rename() edits.VerifyEdits( "Update [enum Color { Red = 1, Blue = 2, }]@0 -> [enum Colors { Red = 1, Blue = 2, }]@0"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.Renamed, "enum Colors", FeaturesResources.enum_)); } @@ -3655,7 +3719,7 @@ public void Enum_BaseType_Add() edits.VerifyEdits("Update [enum Color { Red = 1, Blue = 2, }]@0 -> [enum Color : ushort { Red = 1, Blue = 2, }]@0"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.EnumUnderlyingTypeUpdate, "enum Color", FeaturesResources.enum_)); } @@ -3682,7 +3746,7 @@ public void Enum_BaseType_Update() edits.VerifyEdits("Update [enum Color : ushort { Red = 1, Blue = 2, }]@0 -> [enum Color : long { Red = 1, Blue = 2, }]@0"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.EnumUnderlyingTypeUpdate, "enum Color", FeaturesResources.enum_)); } @@ -3709,7 +3773,7 @@ public void Enum_BaseType_Delete_Changed() edits.VerifyEdits("Update [enum Color : ushort { Red = 1, Blue = 2, }]@0 -> [enum Color { Red = 1, Blue = 2, }]@0"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.EnumUnderlyingTypeUpdate, "enum Color", FeaturesResources.enum_)); } @@ -3724,7 +3788,7 @@ public void EnumAccessibilityChange() edits.VerifyEdits( "Update [public enum Color { Red = 1, Blue = 2, }]@0 -> [enum Color { Red = 1, Blue = 2, }]@0"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.ChangingAccessibility, "enum Color", FeaturesResources.enum_)); } @@ -3749,7 +3813,7 @@ public void EnumInitializerUpdate() edits.VerifyEdits( "Update [Blue = 2]@22 -> [Blue = 3]@22"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.InitializerUpdate, "Blue = 3", FeaturesResources.enum_value)); } @@ -3764,7 +3828,7 @@ public void EnumInitializerUpdate2() edits.VerifyEdits("Update [Red = 1]@13 -> [Red = 1 << 0]@13", "Update [Blue = 2]@22 -> [Blue = 2 << 1]@27"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.InitializerUpdate, "Blue = 2 << 1", FeaturesResources.enum_value)); } @@ -3778,7 +3842,7 @@ public void EnumInitializerUpdate3() edits.VerifyEdits("Update [Red = int.MinValue]@13 -> [Red = int.MaxValue]@13"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.InitializerUpdate, "Red = int.MaxValue", FeaturesResources.enum_value)); } @@ -3793,7 +3857,8 @@ public void EnumInitializerUpdate_Reloadable() edits.VerifyEdits("Update [Red = 1]@185 -> [Red = 2]@185"); edits.VerifySemantics( - SemanticEdit(SemanticEditKind.Replace, c => c.GetMember("Color"))); + new[] { SemanticEdit(SemanticEditKind.Replace, c => c.GetMember("Color")) }, + capabilities: EditAndContinueCapabilities.NewTypeDefinition); } [Fact] @@ -3807,7 +3872,7 @@ public void EnumInitializerAdd() edits.VerifyEdits( "Update [Red]@13 -> [Red = 1]@13"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.InitializerUpdate, "Red = 1", FeaturesResources.enum_value)); } @@ -3822,7 +3887,7 @@ public void EnumInitializerDelete() edits.VerifyEdits( "Update [Red = 1]@13 -> [Red]@13"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.InitializerUpdate, "Red", FeaturesResources.enum_value)); } @@ -3839,7 +3904,7 @@ public void EnumMemberAdd() "Update [enum Color { Red }]@0 -> [enum Color { Red, Blue}]@0", "Insert [Blue]@18"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.Insert, "Blue", FeaturesResources.enum_value)); } @@ -3853,7 +3918,7 @@ public void EnumMemberAdd2() edits.VerifyEdits("Insert [Blue]@18"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.Insert, "Blue", FeaturesResources.enum_value)); } @@ -3869,7 +3934,7 @@ public void EnumMemberAdd3() edits.VerifyEdits("Update [enum Color { Red, }]@0 -> [enum Color { Red, Blue,}]@0", "Insert [Blue]@18"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.Insert, "Blue", FeaturesResources.enum_value)); } @@ -3884,7 +3949,7 @@ public void EnumMemberUpdate() edits.VerifyEdits( "Update [Red]@13 -> [Orange]@13"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.Renamed, "Orange", FeaturesResources.enum_value)); } @@ -3901,7 +3966,7 @@ public void EnumMemberDelete() "Update [enum Color { Red, Blue}]@0 -> [enum Color { Red }]@0", "Delete [Blue]@18"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.Delete, "enum Color", DeletedSymbolDisplay(FeaturesResources.enum_value, "Blue"))); } @@ -3915,7 +3980,7 @@ public void EnumMemberDelete2() edits.VerifyEdits("Delete [Blue]@18"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.Delete, "enum Color", DeletedSymbolDisplay(FeaturesResources.enum_value, "Blue"))); } @@ -3989,7 +4054,8 @@ public void Delegates_NoModifiers_Insert() var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics( + capabilities: EditAndContinueCapabilities.NewTypeDefinition); } [Fact] @@ -4000,7 +4066,8 @@ public void Delegates_NoModifiers_IntoNamespace_Insert() var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics( + capabilities: EditAndContinueCapabilities.NewTypeDefinition); } [Fact] @@ -4011,7 +4078,8 @@ public void Delegates_NoModifiers_IntoType_Insert() var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics( + capabilities: EditAndContinueCapabilities.NewTypeDefinition); } [Fact] @@ -4026,7 +4094,8 @@ public void Delegates_Public_IntoType_Insert() "Insert [public delegate void D();]@10", "Insert [()]@32"); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics( + capabilities: EditAndContinueCapabilities.NewTypeDefinition); } [Fact] @@ -4044,7 +4113,8 @@ public void Delegates_Generic_Insert() "Insert [T]@34", "Insert [T a]@37"); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics( + capabilities: EditAndContinueCapabilities.NewTypeDefinition); } [Fact] @@ -4074,7 +4144,7 @@ public void Delegates_Rename() edits.VerifyEdits( "Update [public delegate void D();]@0 -> [public delegate void Z();]@0"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.Renamed, "public delegate void Z()", FeaturesResources.delegate_)); } @@ -4089,7 +4159,7 @@ public void Delegates_Accessibility_Update() edits.VerifyEdits( "Update [public delegate void D();]@0 -> [private delegate void D();]@0"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.ChangingAccessibility, "private delegate void D()", FeaturesResources.delegate_)); } @@ -4104,7 +4174,7 @@ public void Delegates_ReturnType_Update() edits.VerifyEdits( "Update [public delegate int D();]@0 -> [public delegate void D();]@0"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.TypeUpdate, "public delegate void D()", FeaturesResources.delegate_)); } @@ -4122,13 +4192,12 @@ public void Delegates_ReturnType_AddAttribute() "Update [public delegate int D(int a);]@39 -> [[return: A]public delegate int D(int a);]@39"); edits.VerifySemantics( - ActiveStatementsDescription.Empty, new[] { SemanticEdit(SemanticEditKind.Update, c => c.GetMember("D.Invoke")), SemanticEdit(SemanticEditKind.Update, c => c.GetMember("D.BeginInvoke")) }, - capabilities: EditAndContinueTestHelpers.Net6RuntimeCapabilities); + capabilities: EditAndContinueCapabilities.ChangeCustomAttributes); } [Fact] @@ -4142,7 +4211,7 @@ public void Delegates_Parameter_Insert() edits.VerifyEdits( "Insert [int a]@22"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.Insert, "int a", FeaturesResources.parameter)); } @@ -4155,7 +4224,8 @@ public void Delegates_Parameter_Insert_Reloadable() var edits = GetTopEdits(src1, src2); edits.VerifySemantics( - SemanticEdit(SemanticEditKind.Replace, c => c.GetMember("D"))); + new[] { SemanticEdit(SemanticEditKind.Replace, c => c.GetMember("D")) }, + capabilities: EditAndContinueCapabilities.NewTypeDefinition); } [Fact] @@ -4169,7 +4239,7 @@ public void Delegates_Parameter_Delete() edits.VerifyEdits( "Delete [int a]@22"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.Delete, "public delegate int D()", DeletedSymbolDisplay(FeaturesResources.parameter, "int a"))); } @@ -4184,17 +4254,17 @@ public void Delegates_Parameter_Rename() edits.VerifyEdits( "Update [int a]@22 -> [int b]@22"); - edits.VerifyRudeDiagnostics( - Diagnostic(RudeEditKind.RenamingNotSupportedByRuntime, "int b", FeaturesResources.parameter)); + edits.VerifySemanticDiagnostics( + new[] { Diagnostic(RudeEditKind.RenamingNotSupportedByRuntime, "int b", FeaturesResources.parameter) }, + capabilities: EditAndContinueCapabilities.Baseline); edits.VerifySemantics( - ActiveStatementsDescription.Empty, new[] { SemanticEdit(SemanticEditKind.Update, c => c.GetMember("D.Invoke")), SemanticEdit(SemanticEditKind.Update, c => c.GetMember("D.BeginInvoke")) }, - capabilities: EditAndContinueTestHelpers.Net6RuntimeCapabilities); + capabilities: EditAndContinueCapabilities.UpdateParameters); } [Fact] @@ -4208,7 +4278,7 @@ public void Delegates_Parameter_Update() edits.VerifyEdits( "Update [int a]@22 -> [byte a]@22"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.TypeUpdate, "byte a", FeaturesResources.parameter)); } @@ -4225,8 +4295,9 @@ public void Delegates_Parameter_AddAttribute_NotSupportedByRuntime() edits.VerifyEdits( "Update [int a]@70 -> [[A]int a]@70"); - edits.VerifyRudeDiagnostics( - Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "int a", FeaturesResources.parameter)); + edits.VerifySemanticDiagnostics( + new[] { Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "int a", FeaturesResources.parameter) }, + capabilities: EditAndContinueCapabilities.Baseline); } [Fact] @@ -4249,7 +4320,7 @@ public void Delegates_Parameter_AddAttribute() SemanticEdit(SemanticEditKind.Update, c => c.GetMember("D.Invoke")), SemanticEdit(SemanticEditKind.Update, c => c.GetMember("D.BeginInvoke")) }, - capabilities: EditAndContinueTestHelpers.Net6RuntimeCapabilities); + capabilities: EditAndContinueCapabilities.ChangeCustomAttributes); } [Fact] @@ -4264,7 +4335,7 @@ public void Delegates_TypeParameter_Insert() "Insert []@21", "Insert [T]@22"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.Insert, "T", FeaturesResources.type_parameter)); } @@ -4293,7 +4364,7 @@ public void Delegates_TypeParameter_Delete() "Delete []@21", "Delete [T]@22"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.Delete, "public delegate int D()", DeletedSymbolDisplay(FeaturesResources.type_parameter, "T"))); } @@ -4308,7 +4379,7 @@ public void Delegates_TypeParameter_Rename() edits.VerifyEdits( "Update [T]@22 -> [S]@22"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.Renamed, "S", FeaturesResources.type_parameter), Diagnostic(RudeEditKind.GenericTypeUpdate, "S")); } @@ -4324,7 +4395,7 @@ public void Delegates_TypeParameter_Variance1() edits.VerifyEdits( "Update [T]@22 -> [in T]@22"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.VarianceUpdate, "T", FeaturesResources.type_parameter), Diagnostic(RudeEditKind.GenericTypeUpdate, "T")); } @@ -4340,7 +4411,7 @@ public void Delegates_TypeParameter_Variance2() edits.VerifyEdits( "Update [out T]@22 -> [T]@22"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.VarianceUpdate, "T", FeaturesResources.type_parameter), Diagnostic(RudeEditKind.GenericTypeUpdate, "T")); } @@ -4356,7 +4427,7 @@ public void Delegates_TypeParameter_Variance3() edits.VerifyEdits( "Update [out T]@22 -> [in T]@22"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.VarianceUpdate, "T", FeaturesResources.type_parameter), Diagnostic(RudeEditKind.GenericTypeUpdate, "T")); } @@ -4374,9 +4445,9 @@ public void Delegates_TypeParameter_AddAttribute() edits.VerifyEdits( "Update [T]@70 -> [[A]T]@70"); - edits.VerifyRudeDiagnostics( - EditAndContinueTestHelpers.Net6RuntimeCapabilities, - Diagnostic(RudeEditKind.GenericTypeUpdate, "T")); + edits.VerifySemanticDiagnostics( + new[] { Diagnostic(RudeEditKind.GenericTypeUpdate, "T") }, + capabilities: EditAndContinueCapabilities.ChangeCustomAttributes); } [Fact] @@ -4392,8 +4463,9 @@ public void Delegates_Attribute_Add_NotSupportedByRuntime() edits.VerifyEdits( "Update [public delegate int D(int a);]@48 -> [[A]public delegate int D(int a);]@48"); - edits.VerifyRudeDiagnostics( - Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "public delegate int D(int a)", FeaturesResources.delegate_)); + edits.VerifySemanticDiagnostics( + new[] { Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "public delegate int D(int a)", FeaturesResources.delegate_) }, + capabilities: EditAndContinueCapabilities.Baseline); } [Fact] @@ -4410,9 +4482,8 @@ public void Delegates_Attribute_Add() "Update [public delegate int D(int a);]@48 -> [[A]public delegate int D(int a);]@48"); edits.VerifySemantics( - ActiveStatementsDescription.Empty, new[] { SemanticEdit(SemanticEditKind.Update, c => c.GetMember("D")) }, - capabilities: EditAndContinueTestHelpers.Net6RuntimeCapabilities); + capabilities: EditAndContinueCapabilities.ChangeCustomAttributes); } [Fact] @@ -4429,14 +4500,13 @@ public void Delegates_Attribute_Add_WithReturnTypeAttribute() "Update [public delegate int D(int a);]@48 -> [[return: A][A]public delegate int D(int a);]@48"); edits.VerifySemantics( - ActiveStatementsDescription.Empty, new[] { SemanticEdit(SemanticEditKind.Update, c => c.GetMember("D")), SemanticEdit(SemanticEditKind.Update, c => c.GetMember("D.Invoke")), SemanticEdit(SemanticEditKind.Update, c => c.GetMember("D.BeginInvoke")) }, - capabilities: EditAndContinueTestHelpers.Net6RuntimeCapabilities); + capabilities: EditAndContinueCapabilities.ChangeCustomAttributes); } [Fact] @@ -4452,7 +4522,8 @@ public void Delegates_ReadOnlyRef_Parameter_InsertWhole() "Insert [(in int b)]@21", "Insert [in int b]@22"); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics( + capabilities: EditAndContinueCapabilities.NewTypeDefinition); } [Fact] @@ -4466,7 +4537,7 @@ public void Delegates_ReadOnlyRef_Parameter_InsertParameter() edits.VerifyEdits( "Insert [in int b]@22"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.Insert, "in int b", FeaturesResources.parameter)); } @@ -4481,7 +4552,7 @@ public void Delegates_ReadOnlyRef_Parameter_Update() edits.VerifyEdits( "Update [int b]@22 -> [in int b]@22"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.ModifiersUpdate, "in int b", FeaturesResources.parameter)); } @@ -4497,7 +4568,8 @@ public void Delegates_ReadOnlyRef_ReturnType_Insert() "Insert [public delegate ref readonly int D();]@0", "Insert [()]@34"); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics( + capabilities: EditAndContinueCapabilities.NewTypeDefinition); } [Fact] @@ -4511,7 +4583,7 @@ public void Delegates_ReadOnlyRef_ReturnType_Update() edits.VerifyEdits( "Update [public delegate int D();]@0 -> [public delegate ref readonly int D();]@0"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.TypeUpdate, "public delegate ref readonly int D()", FeaturesResources.delegate_)); } @@ -4530,7 +4602,7 @@ public void NestedClass_ClassMove1() edits.VerifyEdits( "Move [class D { }]@10 -> @12"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.Move, "class D", FeaturesResources.class_)); } @@ -4545,7 +4617,7 @@ public void NestedClass_ClassMove2() edits.VerifyEdits( "Move [class E { }]@23 -> @37"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.Move, "class E", FeaturesResources.class_)); } @@ -4561,7 +4633,7 @@ public void NestedClass_ClassInsertMove1() "Insert [class E { class D { } }]@10", "Move [class D { }]@10 -> @20"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.Move, "class D", FeaturesResources.class_)); } @@ -4577,7 +4649,7 @@ public void NestedClass_Insert1() "Insert [class D { class E { } }]@10", "Insert [class E { }]@20"); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics(); } [Fact] @@ -4592,7 +4664,7 @@ public void NestedClass_Insert2() "Insert [protected class D { public class E { } }]@10", "Insert [public class E { }]@30"); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics(); } [Fact] @@ -4607,7 +4679,7 @@ public void NestedClass_Insert3() "Insert [private class D { public class E { } }]@10", "Insert [public class E { }]@28"); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics(); } [Fact] @@ -4629,7 +4701,7 @@ public void NestedClass_Insert4() "Insert [get;]@70", "Insert [set;]@75"); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics(); } [Fact] @@ -4641,7 +4713,8 @@ public void NestedClass_Insert_ReloadableIntoReloadable1() var edits = GetTopEdits(src1, src2); edits.VerifySemantics( - SemanticEdit(SemanticEditKind.Replace, c => c.GetMember("C"))); + new[] { SemanticEdit(SemanticEditKind.Replace, c => c.GetMember("C")) }, + capabilities: EditAndContinueCapabilities.NewTypeDefinition); } [Fact] @@ -4653,7 +4726,8 @@ public void NestedClass_Insert_ReloadableIntoReloadable2() var edits = GetTopEdits(src1, src2); edits.VerifySemantics( - SemanticEdit(SemanticEditKind.Replace, c => c.GetMember("C"))); + new[] { SemanticEdit(SemanticEditKind.Replace, c => c.GetMember("C")) }, + capabilities: EditAndContinueCapabilities.NewTypeDefinition); } [Fact] @@ -4665,7 +4739,8 @@ public void NestedClass_Insert_ReloadableIntoReloadable3() var edits = GetTopEdits(src1, src2); edits.VerifySemantics( - SemanticEdit(SemanticEditKind.Replace, c => c.GetMember("C"))); + new[] { SemanticEdit(SemanticEditKind.Replace, c => c.GetMember("C")) }, + capabilities: EditAndContinueCapabilities.NewTypeDefinition); } [Fact] @@ -4689,7 +4764,8 @@ public void NestedClass_Insert_Member_Reloadable() var edits = GetTopEdits(src1, src2); edits.VerifySemantics( - SemanticEdit(SemanticEditKind.Replace, c => c.GetMember("C.D"))); + new[] { SemanticEdit(SemanticEditKind.Replace, c => c.GetMember("C.D")) }, + capabilities: EditAndContinueCapabilities.NewTypeDefinition); } [Fact] @@ -4792,7 +4868,7 @@ public virtual event Action E { add { } remove { } } "; var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics(); } [Fact] @@ -4807,7 +4883,7 @@ public void NestedClass_TypeReorder1() "Reorder [struct E { }]@10 -> @56", "Reorder [interface I {}]@54 -> @22"); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics(); } [Fact] @@ -4841,7 +4917,7 @@ public void NestedClass_ClassDeleteInsert() "Insert [public class D { public class X {} }]@17", "Move [public class X {}]@17 -> @34"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.Move, "public class X", FeaturesResources.class_)); } @@ -4874,7 +4950,8 @@ class D } "; var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics( + capabilities: EditAndContinueCapabilities.NewTypeDefinition); } [Fact] @@ -4888,7 +4965,7 @@ public void NestedEnum_InsertMember() "Update [enum N { A = 1 }]@11 -> [enum N { A = 1, B = 2 }]@11", "Insert [B = 2]@27"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.Insert, "B = 2", FeaturesResources.enum_value)); } @@ -5105,7 +5182,7 @@ public void Type_Partial_AddMultiple() SemanticEdit(SemanticEditKind.Insert, c => c.GetMember("C"), partialType: "C") }), }, - capabilities: EditAndContinueTestHelpers.Net6RuntimeCapabilities); + capabilities: EditAndContinueCapabilities.NewTypeDefinition); } [Fact] @@ -5130,7 +5207,7 @@ public void Type_Partial_InsertDeleteAndChange_Attribute() }), DocumentResults(), }, - capabilities: EditAndContinueTestHelpers.Net6RuntimeCapabilities); + capabilities: EditAndContinueCapabilities.ChangeCustomAttributes); } [Fact] @@ -5159,7 +5236,8 @@ public void Type_Partial_InsertDeleteAndChange_TypeParameterAttribute_NotSupport }), DocumentResults(), - }); + }, + capabilities: EditAndContinueCapabilities.Baseline); } [Fact] @@ -5250,7 +5328,7 @@ class B : System.Attribute {} SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C"), partialType: "C") }), }, - capabilities: EditAndContinueTestHelpers.Net6RuntimeCapabilities); + capabilities: EditAndContinueCapabilities.ChangeCustomAttributes); } [Fact] @@ -5364,7 +5442,7 @@ public void Namespace_Insert() edits.VerifyEdits( "Insert [namespace C { }]@0"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.Insert, "namespace C", FeaturesResources.namespace_)); } @@ -5379,7 +5457,7 @@ public void Namespace_InsertNested() edits.VerifyEdits( "Insert [namespace D { }]@14"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.Insert, "namespace D", FeaturesResources.namespace_)); } @@ -5394,7 +5472,7 @@ public void Namespace_DeleteNested() edits.VerifyEdits( "Delete [namespace D { }]@14"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.Delete, "namespace C", FeaturesResources.namespace_)); } @@ -5409,7 +5487,7 @@ public void Namespace_Move() edits.VerifyEdits( "Move [namespace D { }]@14 -> @16"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.Move, "namespace D", FeaturesResources.namespace_)); } @@ -5425,7 +5503,7 @@ public void Namespace_Reorder1() "Reorder [class T { }]@30 -> @30", "Reorder [namespace E { }]@42 -> @14"); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics(); } [Fact] @@ -5440,7 +5518,7 @@ public void Namespace_Reorder2() "Reorder [class T { }]@65 -> @65", "Reorder [namespace E { }]@77 -> @14"); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics(); } [Fact] @@ -5454,7 +5532,7 @@ public void Namespace_FileScoped_Insert() edits.VerifyEdits( "Insert [namespace C;]@0"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.Insert, "namespace C", FeaturesResources.namespace_)); } @@ -5469,7 +5547,7 @@ public void Namespace_FileScoped_Delete() edits.VerifyEdits( "Delete [namespace C;]@0"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.Delete, null, FeaturesResources.namespace_)); } @@ -5756,8 +5834,8 @@ public void PartialMember_RenameInsertDelete() var srcB2 = "partial class C { void F1() {} }"; // current outcome: - GetTopEdits(srcA1, srcA2).VerifyRudeDiagnostics(Diagnostic(RudeEditKind.Renamed, "void F2()", FeaturesResources.method)); - GetTopEdits(srcB1, srcB2).VerifyRudeDiagnostics(Diagnostic(RudeEditKind.Renamed, "void F1()", FeaturesResources.method)); + GetTopEdits(srcA1, srcA2).VerifySemanticDiagnostics(Diagnostic(RudeEditKind.Renamed, "void F2()", FeaturesResources.method)); + GetTopEdits(srcB1, srcB2).VerifySemanticDiagnostics(Diagnostic(RudeEditKind.Renamed, "void F1()", FeaturesResources.method)); // correct outcome: //EditAndContinueValidation.VerifySemantics( @@ -6037,7 +6115,7 @@ public void Method_Modifiers_Update(string oldModifiers, string newModifiers = " edits.VerifyEdits("Update [" + oldModifiers + "int F() => 0;]@10 -> [" + newModifiers + "int F() => 0;]@10"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.ModifiersUpdate, newModifiers + "int F()", FeaturesResources.method)); } @@ -6085,7 +6163,7 @@ struct S public readonly int M() => 1; }"; var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.ModifiersUpdate, "public readonly int M()", FeaturesResources.method)); } @@ -6126,7 +6204,7 @@ struct S public readonly int M() => 1; }"; var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.ModifiersUpdate, "struct S", "struct")); } @@ -6150,7 +6228,7 @@ public Task WaitAsync() } }"; var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.ChangingFromAsynchronousToSynchronous, "public Task WaitAsync()", FeaturesResources.method)); } @@ -6175,7 +6253,8 @@ public async Task WaitAsync() } }"; var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics( + capabilities: EditAndContinueCapabilities.NewTypeDefinition); VerifyPreserveLocalVariables(edits, preserveLocalVariables: false); } @@ -6201,9 +6280,9 @@ public async Task WaitAsync() } }"; var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics( - capabilities: EditAndContinueTestHelpers.BaselineCapabilities, - Diagnostic(RudeEditKind.MakeMethodAsync, "public async Task WaitAsync()")); + edits.VerifySemanticDiagnostics( + new[] { Diagnostic(RudeEditKind.MakeMethodAsyncNotSupportedByRuntime, "public async Task WaitAsync()") }, + capabilities: EditAndContinueCapabilities.Baseline); } [Theory] @@ -6232,7 +6311,7 @@ public void Method_ReturnType_Update_RuntimeTypeChanged(string oldType, string n var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.TypeUpdate, newType + " M()", FeaturesResources.method)); } @@ -6275,7 +6354,7 @@ static void Main(string[] args) System.Console.WriteLine(a + b); }]@18"); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics(); edits.VerifySemantics( ActiveStatementsDescription.Empty, @@ -6303,7 +6382,7 @@ class C edits.VerifyEdits( @"Update [static int Main(string[] args) => F(1);]@18 -> [static int Main(string[] args) => F(2);]@18"); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics(); edits.VerifySemantics( ActiveStatementsDescription.Empty, @@ -6334,7 +6413,7 @@ class C edits.VerifyEdits( "Update [int M(int a) => new Func(() => a + 1)();]@35 -> [int M(int a) => new Func(() => 2)();]@35"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.NotCapturingVariable, "a", "a")); } @@ -6557,9 +6636,9 @@ public void MethodInsert_NotSupportedByRuntime() var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics( - capabilities: EditAndContinueTestHelpers.BaselineCapabilities, - Diagnostic(RudeEditKind.InsertNotSupportedByRuntime, "void goo()", FeaturesResources.method)); + edits.VerifySemanticDiagnostics( + new[] { Diagnostic(RudeEditKind.InsertNotSupportedByRuntime, "void goo()", FeaturesResources.method) }, + capabilities: EditAndContinueCapabilities.Baseline); } [Fact] @@ -6590,7 +6669,8 @@ static void Main(string[] args) "Insert [void goo() { }]@18", "Insert [()]@26"); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics( + capabilities: EditAndContinueCapabilities.AddMethodToExistingType); } [WorkItem(755784, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/755784")] @@ -6628,8 +6708,8 @@ static void Main(string[] args) "Insert [int a]@44"); edits.VerifySemantics( - ActiveStatementsDescription.Empty, - new[] { SemanticEdit(SemanticEditKind.Insert, c => c.GetMember("C.goo")) }); + new[] { SemanticEdit(SemanticEditKind.Insert, c => c.GetMember("C.goo")) }, + capabilities: EditAndContinueCapabilities.AddMethodToExistingType); } [WorkItem(755784, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/755784")] @@ -6664,7 +6744,8 @@ void goo(int a) { }]@18", "Insert [(int a)]@49", "Insert [int a]@50"); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics( + capabilities: EditAndContinueCapabilities.AddMethodToExistingType); } [Fact] @@ -6846,7 +6927,7 @@ class C SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C.puts")), }) }, - capabilities: EditAndContinueTestHelpers.Net6RuntimeCapabilities); + capabilities: EditAndContinueCapabilities.ChangeCustomAttributes); } [Fact] @@ -6901,7 +6982,7 @@ static void Main(string[] args) edits.VerifyEdits( "Insert [string[] args]@35"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.Insert, "string[] args", FeaturesResources.parameter)); } @@ -6929,16 +7010,16 @@ static void Main(string[] b) edits.VerifyEdits( "Update [string[] args]@35 -> [string[] b]@35"); - edits.VerifyRudeDiagnostics( - Diagnostic(RudeEditKind.RenamingNotSupportedByRuntime, "string[] b", FeaturesResources.parameter)); + edits.VerifySemanticDiagnostics( + new[] { Diagnostic(RudeEditKind.RenamingNotSupportedByRuntime, "string[] b", FeaturesResources.parameter) }, + capabilities: EditAndContinueCapabilities.Baseline); edits.VerifySemantics( - ActiveStatementsDescription.Empty, new[] { SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C.Main")) }, - capabilities: EditAndContinueTestHelpers.Net6RuntimeCapabilities); + capabilities: EditAndContinueCapabilities.UpdateParameters); } [Fact] @@ -6962,16 +7043,16 @@ static void Main(string[] b) }"; var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics( - Diagnostic(RudeEditKind.RenamingNotSupportedByRuntime, "string[] b", FeaturesResources.parameter)); + edits.VerifySemanticDiagnostics( + new[] { Diagnostic(RudeEditKind.RenamingNotSupportedByRuntime, "string[] b", FeaturesResources.parameter) }, + capabilities: EditAndContinueCapabilities.Baseline); edits.VerifySemantics( - ActiveStatementsDescription.Empty, new[] { SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C.Main")) }, - capabilities: EditAndContinueTestHelpers.Net6RuntimeCapabilities); + capabilities: EditAndContinueCapabilities.UpdateParameters); } [Fact] @@ -7005,7 +7086,7 @@ static void EntryPoint(string[] args) edits.VerifyEdits(expectedEdit); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.Renamed, "static void EntryPoint(string[] args)", FeaturesResources.method)); } @@ -7031,7 +7112,7 @@ public async Task WaitAsync() } }"; var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics(); VerifyPreserveLocalVariables(edits, preserveLocalVariables: true); } @@ -7082,7 +7163,7 @@ public async Task WaitAsync() edits.VerifyEdits(expectedEdit); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics(); } [Fact] @@ -7120,8 +7201,9 @@ static void Main(string[] args) System.Console.Write(5); }]@38"); - edits.VerifyRudeDiagnostics( - Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "static void Main(string[] args)", FeaturesResources.method)); + edits.VerifySemanticDiagnostics( + new[] { Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "static void Main(string[] args)", FeaturesResources.method) }, + capabilities: EditAndContinueCapabilities.Baseline); } [Fact] @@ -7159,8 +7241,9 @@ static void Main(string[] args) System.Console.Write(5); }]@38"); - edits.VerifyRudeDiagnostics( - Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "static void Main(string[] args)", FeaturesResources.method)); + edits.VerifySemanticDiagnostics( + new[] { Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "static void Main(string[] args)", FeaturesResources.method) }, + capabilities: EditAndContinueCapabilities.Baseline); } [Fact] @@ -7201,7 +7284,7 @@ static void Main(string[] args) edits.VerifySemantics( ActiveStatementsDescription.Empty, new[] { SemanticEdit(SemanticEditKind.Update, c => c.GetMember("Test.Main")) }, - capabilities: EditAndContinueTestHelpers.Net6RuntimeCapabilities); + capabilities: EditAndContinueCapabilities.ChangeCustomAttributes); } [Fact] @@ -7238,7 +7321,7 @@ void M() edits.VerifySemantics( ActiveStatementsDescription.Empty, new[] { SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C.M")) }, - capabilities: EditAndContinueTestHelpers.Net6RuntimeCapabilities); + capabilities: EditAndContinueCapabilities.ChangeCustomAttributes); } [Fact] @@ -7278,7 +7361,7 @@ void M() ActiveStatementsDescription.Empty, new[] { SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C.M")) }); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics(); } [Fact] @@ -7308,8 +7391,9 @@ static void Main(string[] args) }"; var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics( - Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "static void Main(string[] args)", FeaturesResources.method)); + edits.VerifySemanticDiagnostics( + new[] { Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "static void Main(string[] args)", FeaturesResources.method) }, + capabilities: EditAndContinueCapabilities.Baseline); } [Fact] @@ -7340,8 +7424,9 @@ static void Main(string[] args) }"; var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics( - Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "static void Main(string[] args)", FeaturesResources.method)); + edits.VerifySemanticDiagnostics( + new[] { Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "static void Main(string[] args)", FeaturesResources.method) }, + capabilities: EditAndContinueCapabilities.Baseline); } [Fact] @@ -7370,8 +7455,9 @@ static void Main(string[] args) }"; var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics( - Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "static void Main(string[] args)", FeaturesResources.method)); + edits.VerifySemanticDiagnostics( + new[] { Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "static void Main(string[] args)", FeaturesResources.method) }, + capabilities: EditAndContinueCapabilities.Baseline); } [Fact] @@ -7401,8 +7487,9 @@ static void Main(string[] args) }"; var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics( - Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "static void Main(string[] args)", FeaturesResources.method)); + edits.VerifySemanticDiagnostics( + new[] { Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "static void Main(string[] args)", FeaturesResources.method) }, + capabilities: EditAndContinueCapabilities.Baseline); } [WorkItem(754853, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/754853")] @@ -7432,8 +7519,9 @@ static void Main(string[] args) }"; var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics( - Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "static void Main(string[] args)", FeaturesResources.method)); + edits.VerifySemanticDiagnostics( + new[] { Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "static void Main(string[] args)", FeaturesResources.method) }, + capabilities: EditAndContinueCapabilities.Baseline); } [Fact] @@ -7463,8 +7551,9 @@ static void Main(string[] args) }"; var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics( - Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "static void Main(string[] args)", FeaturesResources.method)); + edits.VerifySemanticDiagnostics( + new[] { Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "static void Main(string[] args)", FeaturesResources.method) }, + capabilities: EditAndContinueCapabilities.Baseline); } [Fact] @@ -7495,8 +7584,9 @@ static void Main(string[] args) }"; var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics( - Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "static void Main(string[] args)", FeaturesResources.method)); + edits.VerifySemanticDiagnostics( + new[] { Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "static void Main(string[] args)", FeaturesResources.method) }, + capabilities: EditAndContinueCapabilities.Baseline); } [Fact] @@ -7520,7 +7610,7 @@ class C : I, J "Update [void I.Goo() { Console.WriteLine(2); }]@25 -> [void I.Goo() { Console.WriteLine(1); }]@25", "Update [void J.Goo() { Console.WriteLine(1); }]@69 -> [void J.Goo() { Console.WriteLine(2); }]@69"); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics(); } [Fact] @@ -7543,7 +7633,7 @@ class C : I, J edits.VerifyEdits( "Update [void I.Goo() { Console.WriteLine(1); }]@25 -> [void Goo() { Console.WriteLine(1); }]@25"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.Renamed, "void Goo()", FeaturesResources.method)); } @@ -7597,7 +7687,7 @@ static void Main(string[] args) edits.VerifyEdits(expectedEdit); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.StackAllocUpdate, "stackalloc", FeaturesResources.method)); } @@ -7613,7 +7703,7 @@ public void MethodUpdate_UpdateStackAlloc2(string stackallocDecl) var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.StackAllocUpdate, "stackalloc", FeaturesResources.method)); } @@ -7625,7 +7715,7 @@ public void MethodUpdate_UpdateStackAllocInLambda1() var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics(); } [Fact] @@ -7636,7 +7726,7 @@ public void MethodUpdate_UpdateStackAllocInLambda2() var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics(); } [Fact] @@ -7647,7 +7737,7 @@ public void MethodUpdate_UpdateStackAllocInAnonymousMethod() var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics(); } [Fact] @@ -7658,7 +7748,7 @@ public void MethodUpdate_UpdateStackAllocInLocalFunction() var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics(); } [Fact] @@ -7669,7 +7759,7 @@ public void MethodUpdate_SwitchExpressionInLambda1() var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics(); } [Fact] @@ -7680,7 +7770,7 @@ public void MethodUpdate_SwitchExpressionInLambda2() var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics(); } [Fact] @@ -7691,7 +7781,7 @@ public void MethodUpdate_SwitchExpressionInAnonymousMethod() var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics(); } [Fact] @@ -7702,7 +7792,7 @@ public void MethodUpdate_SwitchExpressionInLocalFunction() var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics(); } [Fact] @@ -7713,7 +7803,7 @@ public void MethodUpdate_SwitchExpressionInQuery() var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics(); } [Fact] @@ -7724,7 +7814,7 @@ public void MethodUpdate_UpdateAnonymousMethod() var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics(); } [Fact] @@ -7735,7 +7825,7 @@ public void MethodWithExpressionBody_Update_UpdateAnonymousMethod() var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics(); } [Fact] @@ -7746,7 +7836,7 @@ public void MethodUpdate_Query() var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics(); } [Fact] @@ -7757,7 +7847,7 @@ public void MethodWithExpressionBody_Update_Query() var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics(); } [Fact] @@ -7768,7 +7858,7 @@ public void MethodUpdate_AnonymousType() var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics(); } [Fact] @@ -7779,7 +7869,7 @@ public void MethodWithExpressionBody_Update_AnonymousType() var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics(); } [Fact] @@ -7790,7 +7880,7 @@ public void MethodUpdate_Iterator_YieldReturn() var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics(); VerifyPreserveLocalVariables(edits, preserveLocalVariables: true); } @@ -7803,7 +7893,8 @@ public void MethodUpdate_AddYieldReturn() var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics( + capabilities: EditAndContinueCapabilities.NewTypeDefinition); VerifyPreserveLocalVariables(edits, preserveLocalVariables: false); } @@ -7816,9 +7907,9 @@ public void MethodUpdate_AddYieldReturn_NotSupported() var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics( - capabilities: EditAndContinueTestHelpers.BaselineCapabilities, - Diagnostic(RudeEditKind.MakeMethodIterator, "IEnumerable M()")); + edits.VerifySemanticDiagnostics( + new[] { Diagnostic(RudeEditKind.MakeMethodIteratorNotSupportedByRuntime, "IEnumerable M()") }, + capabilities: EditAndContinueCapabilities.Baseline); } [Fact] @@ -7829,7 +7920,7 @@ public void MethodUpdate_Iterator_YieldBreak() var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics(); VerifyPreserveLocalVariables(edits, preserveLocalVariables: true); } @@ -7867,7 +7958,7 @@ static void Main(string[] args) var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics(); } [Fact] @@ -7905,7 +7996,8 @@ public void Method_ReadOnlyRef_Parameter_InsertWhole() "Insert [(in int b)]@18", "Insert [in int b]@19"); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics( + capabilities: EditAndContinueCapabilities.AddMethodToExistingType); } [Fact] @@ -7919,7 +8011,7 @@ public void Method_ReadOnlyRef_Parameter_InsertParameter() edits.VerifyEdits( "Insert [in int b]@19"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.Insert, "in int b", FeaturesResources.parameter)); } @@ -7934,7 +8026,7 @@ public void Method_ReadOnlyRef_Parameter_Update() edits.VerifyEdits( "Update [int b]@19 -> [in int b]@19"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.ModifiersUpdate, "in int b", FeaturesResources.parameter)); } @@ -7950,7 +8042,8 @@ public void Method_ReadOnlyRef_ReturnType_Insert() "Insert [ref readonly int M() => throw null;]@13", "Insert [()]@31"); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics( + capabilities: EditAndContinueCapabilities.AddMethodToExistingType); } [Fact] @@ -7964,7 +8057,7 @@ public void Method_ReadOnlyRef_ReturnType_Update() edits.VerifyEdits( "Update [int M() => throw null;]@13 -> [ref readonly int M() => throw null;]@13"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.TypeUpdate, "ref readonly int M()", FeaturesResources.method)); } @@ -8174,7 +8267,8 @@ public void Method_Partial_Insert() DocumentResults( semanticEdits: new[] { SemanticEdit(SemanticEditKind.Insert, c => c.GetMember("C").GetMember("F").PartialImplementationPart) }), - }); + }, + capabilities: EditAndContinueCapabilities.AddMethodToExistingType); } [Fact] @@ -8193,7 +8287,8 @@ public void Method_Partial_Insert_Reloadable() DocumentResults(), DocumentResults( semanticEdits: new[] { SemanticEdit(SemanticEditKind.Replace, c => c.GetMember("C"), partialType: "C") }), - }); + }, + capabilities: EditAndContinueCapabilities.NewTypeDefinition); } #endregion @@ -8212,7 +8307,7 @@ public void Operator_Modifiers_Update(string oldModifiers, string newModifiers) edits.VerifyEdits("Update [public static " + oldModifiers + " operator int (C c) => 0;]@10 -> [public static " + newModifiers + " operator int (C c) => 0;]@10"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.ModifiersUpdate, "public static " + newModifiers + " operator int (C c)", CSharpFeaturesResources.conversion_operator)); } @@ -8225,7 +8320,8 @@ public void Operator_Modifiers_Update_Reloadable() var edits = GetTopEdits(src1, src2); edits.VerifySemantics( - SemanticEdit(SemanticEditKind.Replace, c => c.GetMember("C"))); + new[] { SemanticEdit(SemanticEditKind.Replace, c => c.GetMember("C")) }, + capabilities: EditAndContinueCapabilities.NewTypeDefinition); } [Fact] @@ -8236,7 +8332,7 @@ public void Operator_Conversion_ExternModifiers_Add() var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.ModifiersUpdate, "extern public static implicit operator bool (C c)", CSharpFeaturesResources.conversion_operator)); } @@ -8248,7 +8344,7 @@ public void Operator_Conversion_ExternModifiers_Remove() var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.ModifiersUpdate, "public static implicit operator bool (C c)", CSharpFeaturesResources.conversion_operator)); } @@ -8462,7 +8558,7 @@ class C edits.VerifyEdits( "Reorder [public static implicit operator int (C c) { return 1; }]@84 -> @18"); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics(); } [Fact] @@ -8486,7 +8582,7 @@ class C edits.VerifyEdits( "Reorder [public static C operator -(C c, C d) { return d; }]@74 -> @18"); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics(); } [Fact] @@ -8517,7 +8613,7 @@ public void Operator_ReadOnlyRef_Parameter_Update() edits.VerifyEdits( "Update [Test b]@43 -> [in Test b]@43"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.ModifiersUpdate, "in Test b", FeaturesResources.parameter)); } @@ -8559,7 +8655,7 @@ public C([System.Obsolete]int a) { SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C..ctor")) }, - capabilities: EditAndContinueTestHelpers.Net6RuntimeCapabilities); + capabilities: EditAndContinueCapabilities.ChangeCustomAttributes); } [Fact] @@ -8576,7 +8672,7 @@ public void Constructor_ExternModifier_Add() "Insert [()]@25"); // This can be allowed as the compiler generates an empty constructor, but it's not worth the complexity. - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.ModifiersUpdate, "public extern C()", FeaturesResources.constructor)); } @@ -8598,7 +8694,7 @@ public C(int a) : base(a + 1) { } edits.VerifyEdits( "Update [public C(int a) : base(a) { }]@18 -> [public C(int a) : base(a + 1) { }]@18"); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics(); } [Fact] @@ -8619,7 +8715,7 @@ public C(int a) { } edits.VerifyEdits( "Update [public C(int a) : base(a) { }]@21 -> [public C(int a) { }]@21"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.GenericTypeUpdate, "public C(int a)")); } @@ -8641,7 +8737,7 @@ public C(int a) : base(a) { } edits.VerifyEdits( "Update [public C(int a) { }]@18 -> [public C(int a) : base(a) { }]@18"); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics(); } [Fact] @@ -8662,7 +8758,7 @@ public C(int a) : base(a + 1) { } edits.VerifyEdits( "Update [public C(int a) : base(a) { }]@21 -> [public C(int a) : base(a + 1) { }]@21"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.GenericTypeUpdate, "public C(int a)")); } @@ -8686,7 +8782,7 @@ public C(int a, int b) { } "Update [(int a)]@26 -> [(int a, int b)]@26", "Insert [int b]@34"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.Insert, "int b", FeaturesResources.parameter)); } @@ -8733,7 +8829,7 @@ public void ConstructorUpdate_AnonymousTypeInFieldInitializer() var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics(); } [Fact] @@ -8757,7 +8853,8 @@ public void Constructor_Static_Delete_Reloadable() var edits = GetTopEdits(src1, src2); edits.VerifySemantics( - SemanticEdit(SemanticEditKind.Replace, c => c.GetMember("C"))); + new[] { SemanticEdit(SemanticEditKind.Replace, c => c.GetMember("C")) }, + capabilities: EditAndContinueCapabilities.NewTypeDefinition); } [Fact] @@ -8769,8 +8866,8 @@ public void Constructor_Static_Insert() var edits = GetTopEdits(src1, src2); edits.VerifySemantics( - ActiveStatementsDescription.Empty, - new[] { SemanticEdit(SemanticEditKind.Insert, c => c.GetMember("C").StaticConstructors.Single()) }); + new[] { SemanticEdit(SemanticEditKind.Insert, c => c.GetMember("C").StaticConstructors.Single()) }, + EditAndContinueCapabilities.AddMethodToExistingType); } [Fact] @@ -8782,8 +8879,7 @@ public void InstanceCtorDelete_Public() var edits = GetTopEdits(src1, src2); edits.VerifySemantics( - ActiveStatementsDescription.Empty, - new[] { SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").InstanceConstructors.Single(), preserveLocalVariables: true) }); + SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").InstanceConstructors.Single(), preserveLocalVariables: true)); } [Theory] @@ -8801,8 +8897,12 @@ public void InstanceCtorDelete_NonPublic(string accessibility) var edits = GetTopEdits(src1, src2); edits.VerifySemanticDiagnostics( - Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "class C", DeletedSymbolDisplay(FeaturesResources.constructor, "C()")), - Diagnostic(RudeEditKind.ChangingAccessibility, "class C", DeletedSymbolDisplay(FeaturesResources.constructor, "C()"))); + new[] + { + Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "class C", DeletedSymbolDisplay(FeaturesResources.constructor, "C()")), + Diagnostic(RudeEditKind.ChangingAccessibility, "class C", DeletedSymbolDisplay(FeaturesResources.constructor, "C()")) + }, + capabilities: EditAndContinueCapabilities.Baseline); } [Fact] @@ -8869,11 +8969,11 @@ public void InstanceCtorInsert_Public_NoImplicit() var edits = GetTopEdits(src1, src2); edits.VerifySemantics( - ActiveStatementsDescription.Empty, - expectedSemanticEdits: new[] + semanticEdits: new[] { SemanticEdit(SemanticEditKind.Insert, c => c.GetMember("C").InstanceConstructors.Single(c => c.Parameters.IsEmpty)) - }); + }, + capabilities: EditAndContinueCapabilities.AddMethodToExistingType); } [Fact] @@ -8897,7 +8997,8 @@ public void InstanceCtorInsert_Partial_Public_NoImplicit() // no change in document B DocumentResults(), - }); + }, + capabilities: EditAndContinueCapabilities.AddMethodToExistingType); } [Fact] @@ -8969,11 +9070,7 @@ public void InstanceCtorUpdate_ProtectedImplicit() var edits = GetTopEdits(src1, src2); edits.VerifySemantics( - ActiveStatementsDescription.Empty, - new[] - { - SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").InstanceConstructors.Single(), preserveLocalVariables: true) - }); + SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").InstanceConstructors.Single(), preserveLocalVariables: true)); } [Fact] @@ -8985,12 +9082,12 @@ public void InstanceCtorInsert_Private_NoImplicit() var edits = GetTopEdits(src1, src2); edits.VerifySemantics( - ActiveStatementsDescription.Empty, new[] { SemanticEdit(SemanticEditKind.Insert, c => c.GetMember("C") .InstanceConstructors.Single(ctor => ctor.DeclaredAccessibility == Accessibility.Private)) - }); + }, + capabilities: EditAndContinueCapabilities.AddMethodToExistingType); } [Fact] @@ -9001,7 +9098,8 @@ public void InstanceCtorInsert_Internal_NoImplicit() var edits = GetTopEdits(src1, src2); - edits.VerifySemanticDiagnostics(); + edits.VerifySemanticDiagnostics( + capabilities: EditAndContinueCapabilities.AddMethodToExistingType); } [Fact] @@ -9012,7 +9110,8 @@ public void InstanceCtorInsert_Protected_NoImplicit() var edits = GetTopEdits(src1, src2); - edits.VerifySemanticDiagnostics(); + edits.VerifySemanticDiagnostics( + capabilities: EditAndContinueCapabilities.AddMethodToExistingType); } [Fact] @@ -9023,7 +9122,8 @@ public void InstanceCtorInsert_InternalProtected_NoImplicit() var edits = GetTopEdits(src1, src2); - edits.VerifySemanticDiagnostics(); + edits.VerifySemanticDiagnostics( + capabilities: EditAndContinueCapabilities.AddMethodToExistingType); } [Fact] @@ -9597,7 +9697,8 @@ partial class C SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").Constructors.Single(c => c.Parameters.Single().Type.Name == "UInt32"), partialType: "C", syntaxMap: syntaxMapB), SemanticEdit(SemanticEditKind.Insert, c => c.GetMember("C").Constructors.Single(c => c.Parameters.Single().Type.Name == "Byte"), syntaxMap: null), }) - }); + }, + capabilities: EditAndContinueCapabilities.AddMethodToExistingType); } [Fact] @@ -9734,10 +9835,8 @@ partial void C(int x) "; var edits = GetTopEdits(src1, src2); - edits.VerifySemantics(ActiveStatementsDescription.Empty, expectedSemanticEdits: new[] - { - SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").GetMember("C").PartialImplementationPart) - }); + edits.VerifySemantics( + SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").GetMember("C").PartialImplementationPart)); } [Fact] @@ -9813,7 +9912,8 @@ public void PartialDeclaration_Insert_Reloadable() { SemanticEdit(SemanticEditKind.Replace, c => c.GetMember("C"), partialType: "C") }), - }); + }, + capabilities: EditAndContinueCapabilities.NewTypeDefinition); } [Theory] @@ -10073,7 +10173,8 @@ public void Constructor_ReadOnlyRef_Parameter_InsertWhole() "Insert [(in int b)]@17", "Insert [in int b]@18"); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics( + capabilities: EditAndContinueCapabilities.AddMethodToExistingType); } [Fact] @@ -10087,7 +10188,7 @@ public void Constructor_ReadOnlyRef_Parameter_InsertParameter() edits.VerifyEdits( "Insert [in int b]@18"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.Insert, "in int b", FeaturesResources.parameter)); } @@ -10102,7 +10203,7 @@ public void Constructor_ReadOnlyRef_Parameter_Update() edits.VerifyEdits( "Update [int b]@18 -> [in int b]@18"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.ModifiersUpdate, "in int b", FeaturesResources.parameter)); } @@ -10157,7 +10258,7 @@ public void FieldInitializer_Update2() edits.VerifyEdits( "Update [a = 0]@14 -> [a]@14"); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics(); } [Fact] @@ -10278,8 +10379,12 @@ public void FieldInitializerUpdate_InstanceCtorUpdate_Private(string typeKind) var edits = GetTopEdits(src1, src2); edits.VerifySemanticDiagnostics( - Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, $"{typeKind} C", DeletedSymbolDisplay(FeaturesResources.constructor, "C()")), - Diagnostic(RudeEditKind.ChangingAccessibility, $"{typeKind} C", DeletedSymbolDisplay(FeaturesResources.constructor, "C()"))); + new[] + { + Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, $"{typeKind} C", DeletedSymbolDisplay(FeaturesResources.constructor, "C()")), + Diagnostic(RudeEditKind.ChangingAccessibility, $"{typeKind} C", DeletedSymbolDisplay(FeaturesResources.constructor, "C()")) + }, + capabilities: EditAndContinueCapabilities.Baseline); } [Theory] @@ -10558,8 +10663,8 @@ public void FieldInitializerUpdate_StaticCtorInsertExplicit() "Update [a]@21 -> [a = 0]@21"); edits.VerifySemantics( - ActiveStatementsDescription.Empty, - new[] { SemanticEdit(SemanticEditKind.Insert, c => c.GetMember("C").StaticConstructors.Single()) }); + new[] { SemanticEdit(SemanticEditKind.Insert, c => c.GetMember("C").StaticConstructors.Single()) }, + capabilities: EditAndContinueCapabilities.AddMethodToExistingType); } [Theory] @@ -10603,7 +10708,7 @@ public void FieldInitializerUpdate_GenericType() edits.VerifyEdits( "Update [a = 1]@17 -> [a = 2]@17"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.GenericTypeUpdate, "a = 2"), Diagnostic(RudeEditKind.GenericTypeUpdate, "class C")); } @@ -10616,7 +10721,7 @@ public void PropertyInitializerUpdate_GenericType() var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.GenericTypeUpdate, "int a"), Diagnostic(RudeEditKind.GenericTypeUpdate, "class C")); } @@ -10874,7 +10979,7 @@ public void FieldInitializerUpdate_ParenthesizedLambda() var src2 = "class C { int a = F(2, (x, y) => x + y); }"; var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics(); } [Fact] @@ -10885,7 +10990,7 @@ public void PropertyInitializerUpdate_ParenthesizedLambda() var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics(); } [Fact] @@ -10896,7 +11001,7 @@ public void FieldInitializerUpdate_SimpleLambda() var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics(); } [Fact] @@ -10907,7 +11012,7 @@ public void PropertyInitializerUpdate_SimpleLambda() var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics(); } [Fact] @@ -10918,7 +11023,7 @@ public void FieldInitializerUpdate_Query() var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics(); } [Fact] @@ -10929,7 +11034,7 @@ public void PropertyInitializerUpdate_Query() var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics(); } [Fact] @@ -10940,7 +11045,7 @@ public void FieldInitializerUpdate_AnonymousType() var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics(); } [Fact] @@ -10951,7 +11056,7 @@ public void PropertyInitializerUpdate_AnonymousType() var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics(); } [Fact] @@ -11648,11 +11753,9 @@ public C() { } "; var edits = GetTopEdits(src1, src2); - edits.VerifySemantics(ActiveStatementsDescription.Empty, expectedSemanticEdits: new[] - { + edits.VerifySemantics( SemanticEdit(SemanticEditKind.Update, c => ((IPropertySymbol)c.GetMember("C").GetMembers("P").First()).GetMethod), - SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").InstanceConstructors.Single(), preserveLocalVariables: true) - }); + SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").InstanceConstructors.Single(), preserveLocalVariables: true)); } [Fact] @@ -11714,7 +11817,7 @@ public void Field_Rename() edits.VerifyEdits( "Update [a = 0]@14 -> [b = 0]@14"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.Renamed, "b = 0", FeaturesResources.field)); } @@ -11729,7 +11832,7 @@ public void Field_Kind_Update() edits.VerifyEdits( "Update [Action a;]@10 -> [event Action a;]@10"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.FieldKindUpdate, "event Action a", FeaturesResources.event_)); } @@ -11756,7 +11859,7 @@ public void Field_Modifiers_Update(string oldModifiers, string newModifiers = "" edits.VerifyEdits("Update [" + oldModifiers + "int F = 0;]@10 -> [" + newModifiers + "int F = 0;]@10"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.ModifiersUpdate, newModifiers + "int F = 0", FeaturesResources.field)); } @@ -11804,7 +11907,7 @@ public void Field_Attribute_Add_InsertDelete() DocumentResults(), }, - capabilities: EditAndContinueTestHelpers.Net6RuntimeCapabilities); + capabilities: EditAndContinueCapabilities.ChangeCustomAttributes); } [Fact] @@ -11819,7 +11922,7 @@ public void Field_FixedSize_Update() "Update [a[1]]@36 -> [a[2]]@36", "Update [b[2]]@42 -> [b[3]]@42"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.FixedSizeFieldUpdate, "a[2]", FeaturesResources.field), Diagnostic(RudeEditKind.FixedSizeFieldUpdate, "b[3]", FeaturesResources.field)); } @@ -11835,7 +11938,7 @@ public void Field_Const_Update() edits.VerifyEdits("Update [x = 0]@20 -> [x = 1]@20"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.InitializerUpdate, "x = 1", FeaturesResources.const_field)); } @@ -11850,7 +11953,7 @@ public void Field_Event_VariableDeclarator_Update() edits.VerifyEdits( "Update [a]@23 -> [a = () => { }]@23"); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics(); } [Fact] @@ -11864,7 +11967,7 @@ public void Field_Reorder() edits.VerifyEdits( "Reorder [int c = 2;]@32 -> @10"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.Move, "int c = 2", FeaturesResources.field)); } @@ -11882,12 +11985,12 @@ public void Field_Insert() "Insert [a = 1]@14"); edits.VerifySemantics( - ActiveStatementsDescription.Empty, new[] { SemanticEdit(SemanticEditKind.Insert, c => c.GetMember("C.a")), SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").InstanceConstructors.Single(), preserveLocalVariables: true) - }); + }, + capabilities: EditAndContinueCapabilities.AddInstanceFieldToExistingType); } [Fact] @@ -11951,13 +12054,13 @@ class C var edits = GetTopEdits(src1, src2); edits.VerifySemantics( - ActiveStatementsDescription.Empty, new[] { SemanticEdit(SemanticEditKind.Insert, c => c.GetMember("C.b")), SemanticEdit(SemanticEditKind.Insert, c => c.GetMember("C.c")), SemanticEdit(SemanticEditKind.Insert, c => c.GetMember("C.d")), - }); + }, + capabilities: EditAndContinueCapabilities.AddInstanceFieldToExistingType | EditAndContinueCapabilities.AddStaticFieldToExistingType); } [Fact] @@ -12070,12 +12173,12 @@ public C() var syntaxMap = GetSyntaxMap(src1, src2); edits.VerifySemantics( - ActiveStatementsDescription.Empty, new[] { SemanticEdit(SemanticEditKind.Insert, c => c.GetMember("C.B")), SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").Constructors.Single(), syntaxMap[0]) - }); + }, + capabilities: EditAndContinueCapabilities.AddInstanceFieldToExistingType); } [Fact] @@ -12111,12 +12214,12 @@ class C var syntaxMap = GetSyntaxMap(src1, src2); edits.VerifySemantics( - ActiveStatementsDescription.Empty, new[] { SemanticEdit(SemanticEditKind.Insert, c => c.GetMember("C.B")), SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").Constructors.Single(), syntaxMap[0]) - }); + }, + capabilities: EditAndContinueCapabilities.AddInstanceFieldToExistingType | EditAndContinueCapabilities.AddMethodToExistingType); } [Fact, WorkItem(2504, "https://github.com/dotnet/roslyn/issues/2504")] @@ -12243,12 +12346,12 @@ class C var syntaxMap = GetSyntaxMap(src1, src2); edits.VerifySemantics( - ActiveStatementsDescription.Empty, new[] { SemanticEdit(SemanticEditKind.Insert, c => c.GetMember("C.B")), SemanticEdit(SemanticEditKind.Insert, c => c.GetMember("C").Constructors.Single()) - }); + }, + capabilities: EditAndContinueCapabilities.AddInstanceFieldToExistingType | EditAndContinueCapabilities.AddMethodToExistingType); } [Fact] @@ -12259,9 +12362,9 @@ public void Field_Insert_NotSupportedByRuntime() var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics( - capabilities: EditAndContinueTestHelpers.BaselineCapabilities | EditAndContinueCapabilities.AddStaticFieldToExistingType, - Diagnostic(RudeEditKind.InsertNotSupportedByRuntime, "a = 1", FeaturesResources.field)); + edits.VerifySemanticDiagnostics( + new[] { Diagnostic(RudeEditKind.InsertNotSupportedByRuntime, "a = 1", FeaturesResources.field) }, + capabilities: EditAndContinueCapabilities.AddStaticFieldToExistingType); } [Fact] @@ -12272,9 +12375,9 @@ public void Field_Insert_Static_NotSupportedByRuntime() var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics( - capabilities: EditAndContinueTestHelpers.BaselineCapabilities | EditAndContinueCapabilities.AddInstanceFieldToExistingType, - Diagnostic(RudeEditKind.InsertNotSupportedByRuntime, "a = 1", FeaturesResources.field)); + edits.VerifySemanticDiagnostics( + new[] { Diagnostic(RudeEditKind.InsertNotSupportedByRuntime, "a = 1", FeaturesResources.field) }, + capabilities: EditAndContinueCapabilities.AddInstanceFieldToExistingType); } [Fact] @@ -12296,9 +12399,13 @@ class C edits.VerifyEdits( "Update [public int a = 1, x = 1;]@18 -> [[System.Obsolete]public int a = 1, x = 1;]@18"); - edits.VerifyRudeDiagnostics( - Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "public int a = 1, x = 1", FeaturesResources.field), - Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "public int a = 1, x = 1", FeaturesResources.field)); + edits.VerifySemanticDiagnostics( + new[] + { + Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "public int a = 1, x = 1", FeaturesResources.field), + Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "public int a = 1, x = 1", FeaturesResources.field), + }, + capabilities: EditAndContinueCapabilities.Baseline); } [Fact] @@ -12324,7 +12431,7 @@ class C SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C.a")), SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C.b")) }, - capabilities: EditAndContinueTestHelpers.Net6RuntimeCapabilities); + capabilities: EditAndContinueCapabilities.ChangeCustomAttributes); } [Fact] @@ -12350,7 +12457,7 @@ class C SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C.a")), SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").InstanceConstructors.Single(), preserveLocalVariables: true), }, - capabilities: EditAndContinueTestHelpers.Net6RuntimeCapabilities); + capabilities: EditAndContinueCapabilities.ChangeCustomAttributes); } [Fact] @@ -12374,7 +12481,7 @@ public void Field_Attribute_DeleteInsertUpdate_WithInitializer() SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").InstanceConstructors.Single(), partialType: "C", preserveLocalVariables: true) }), }, - capabilities: EditAndContinueTestHelpers.Net6RuntimeCapabilities); + capabilities: EditAndContinueCapabilities.ChangeCustomAttributes); } [Fact] @@ -12404,7 +12511,7 @@ public void Field_UnsafeModifier_Update() edits.VerifyEdits("Update [unsafe Node* left;]@14 -> [Node* left;]@14"); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics(); } [Fact] @@ -12419,7 +12526,7 @@ public void Field_ModifierAndType_Update() "Update [unsafe Node* left;]@14 -> [Node left;]@14", "Update [Node* left]@21 -> [Node left]@14"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.TypeUpdate, "Node left", FeaturesResources.field)); } @@ -12450,7 +12557,7 @@ public void Field_Type_Update_RuntimeTypeChanged(string oldType, string newType) var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.TypeUpdate, newType + " F, G", FeaturesResources.field), Diagnostic(RudeEditKind.TypeUpdate, newType + " F, G", FeaturesResources.field)); } @@ -12482,7 +12589,7 @@ public void Field_Event_Type_Update_RuntimeTypeChanged(string oldType, string ne var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.TypeUpdate, "event System.Action<" + newType + "> F, G", FeaturesResources.event_), Diagnostic(RudeEditKind.TypeUpdate, "event System.Action<" + newType + "> F, G", FeaturesResources.event_)); } @@ -12502,7 +12609,7 @@ public void Field_Type_Update_ReorderRemoveAdd() "Insert [V]@30", "Delete [H]@20"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.Move, "G", FeaturesResources.field), Diagnostic(RudeEditKind.TypeUpdate, "string G, F", FeaturesResources.field), Diagnostic(RudeEditKind.TypeUpdate, "string G, F", FeaturesResources.field), @@ -12521,7 +12628,7 @@ public void Field_Event_Reorder() edits.VerifyEdits( "Reorder [event int c = 2;]@32 -> @10"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.Move, "event int c = 2", CSharpFeaturesResources.event_field)); } @@ -12577,7 +12684,7 @@ public void Property_Modifiers_Update(string oldModifiers, string newModifiers = edits.VerifyEdits("Update [" + oldModifiers + "int F => 0;]@10 -> [" + newModifiers + "int F => 0;]@10"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.ModifiersUpdate, newModifiers + "int F", FeaturesResources.property_)); } @@ -12589,7 +12696,7 @@ public void Property_ExpressionBody_Rename() var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.Renamed, "int Q", FeaturesResources.property_)); } @@ -12621,7 +12728,7 @@ public void Property_ExpressionBody_ModifierUpdate() edits.VerifyEdits("Update [int P => 1;]@10 -> [unsafe int P => 1;]@10"); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics(); } [Fact] @@ -12659,11 +12766,13 @@ public void Property_ExpressionBodyToBlockBody2() "Insert [set { }]@36", "Delete [=> 1]@16"); - edits.VerifySemantics(ActiveStatementsDescription.Empty, new[] - { - SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C.get_P"), preserveLocalVariables: false), - SemanticEdit(SemanticEditKind.Insert, c => c.GetMember("C.set_P"), preserveLocalVariables: false) - }); + edits.VerifySemantics( + new[] + { + SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C.get_P"), preserveLocalVariables: false), + SemanticEdit(SemanticEditKind.Insert, c => c.GetMember("C.set_P"), preserveLocalVariables: false) + }, + capabilities: EditAndContinueCapabilities.AddMethodToExistingType); } [Fact] @@ -12701,7 +12810,7 @@ public void Property_BlockBodyToExpressionBody2() "Delete [get { return 2; }]@18", "Delete [set { }]@36"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.Delete, "int P", DeletedSymbolDisplay(CSharpFeaturesResources.property_setter, "P.set"))); } @@ -12848,7 +12957,7 @@ public void Property_Rename1() var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.Renamed, "int Q", FeaturesResources.property_)); } @@ -12860,7 +12969,7 @@ public void Property_Rename2() var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.Renamed, "int J.P", FeaturesResources.property_)); } @@ -12872,7 +12981,7 @@ public void Property_RenameAndUpdate() var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.Renamed, "int Q", FeaturesResources.property_)); } @@ -12884,7 +12993,7 @@ public void PropertyDelete() var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.Delete, "class C", DeletedSymbolDisplay(FeaturesResources.property_, "P"))); } @@ -12900,7 +13009,7 @@ public void PropertyReorder1() "Reorder [int Q { get { return 1; } }]@38 -> @10"); // TODO: we can allow the move since the property doesn't have a backing field - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.Move, "int Q", FeaturesResources.property_)); } @@ -12915,7 +13024,7 @@ public void PropertyReorder2() edits.VerifyEdits( "Reorder [int Q { get; set; }]@30 -> @10"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.Move, "int Q", FeaturesResources.auto_property)); } @@ -12930,7 +13039,7 @@ public void PropertyAccessorReorder_GetSet() edits.VerifyEdits( "Reorder [set { }]@36 -> @18"); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics(); } [Fact] @@ -12944,7 +13053,7 @@ public void PropertyAccessorReorder_GetInit() edits.VerifyEdits( "Reorder [init { }]@36 -> @18"); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics(); } [Fact] @@ -12958,7 +13067,7 @@ public void PropertyTypeUpdate() edits.VerifyEdits( "Update [int P { get; set; }]@10 -> [char P { get; set; }]@10"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.TypeUpdate, "char P", FeaturesResources.property_)); } @@ -12970,8 +13079,9 @@ public void PropertyUpdate_AddAttribute() var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics( - Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "int P", FeaturesResources.property_)); + edits.VerifySemanticDiagnostics( + new[] { Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "int P", FeaturesResources.property_) }, + capabilities: EditAndContinueCapabilities.AddMethodToExistingType); } [Fact] @@ -12983,11 +13093,10 @@ public void PropertyUpdate_AddAttribute_SupportedByRuntime() var edits = GetTopEdits(src1, src2); edits.VerifySemantics( - ActiveStatementsDescription.Empty, new[] { SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C.P")) }, - capabilities: EditAndContinueTestHelpers.Net6RuntimeCapabilities); + capabilities: EditAndContinueCapabilities.ChangeCustomAttributes); } [Fact] @@ -12998,8 +13107,9 @@ public void PropertyAccessorUpdate_AddAttribute() var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics( - Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "get", CSharpFeaturesResources.property_getter)); + edits.VerifySemanticDiagnostics( + new[] { Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "get", CSharpFeaturesResources.property_getter) }, + capabilities: EditAndContinueCapabilities.AddMethodToExistingType); } [Fact] @@ -13010,8 +13120,9 @@ public void PropertyAccessorUpdate_AddAttribute2() var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics( - Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "set", CSharpFeaturesResources.property_setter)); + edits.VerifySemanticDiagnostics( + new[] { Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "set", CSharpFeaturesResources.property_setter) }, + capabilities: EditAndContinueCapabilities.AddMethodToExistingType); } [Fact] @@ -13023,9 +13134,8 @@ public void PropertyAccessorUpdate_AddAttribute_SupportedByRuntime() var edits = GetTopEdits(src1, src2); edits.VerifySemantics( - ActiveStatementsDescription.Empty, new[] { SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").GetMember("P").GetMethod) }, - capabilities: EditAndContinueTestHelpers.Net6RuntimeCapabilities); + capabilities: EditAndContinueCapabilities.ChangeCustomAttributes); } [Fact] @@ -13037,9 +13147,8 @@ public void PropertyAccessorUpdate_AddAttribute_SupportedByRuntime2() var edits = GetTopEdits(src1, src2); edits.VerifySemantics( - ActiveStatementsDescription.Empty, new[] { SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").GetMember("P").SetMethod) }, - capabilities: EditAndContinueTestHelpers.Net6RuntimeCapabilities); + capabilities: EditAndContinueCapabilities.ChangeCustomAttributes); } [Fact] @@ -13051,7 +13160,8 @@ public void PropertyInsert() var edits = GetTopEdits(src1, src2); edits.VerifySemantics( - SemanticEdit(SemanticEditKind.Insert, c => c.GetMember("C").GetMember("P"))); + new[] { SemanticEdit(SemanticEditKind.Insert, c => c.GetMember("C").GetMember("P")) }, + capabilities: EditAndContinueCapabilities.AddMethodToExistingType); } [Fact] @@ -13062,9 +13172,9 @@ public void PropertyInsert_NotSupportedByRuntime() var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics( - capabilities: EditAndContinueTestHelpers.BaselineCapabilities, - Diagnostic(RudeEditKind.InsertNotSupportedByRuntime, "int P", FeaturesResources.auto_property)); + edits.VerifySemanticDiagnostics( + new[] { Diagnostic(RudeEditKind.InsertNotSupportedByRuntime, "int P", FeaturesResources.auto_property) }, + capabilities: EditAndContinueCapabilities.Baseline); } [WorkItem(835827, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/835827")] @@ -13185,7 +13295,8 @@ public void PrivateProperty_AccessorAdd() edits.VerifyEdits("Insert [set { _p = value; }]@44"); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics( + capabilities: EditAndContinueCapabilities.AddMethodToExistingType); } [WorkItem(755975, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/755975")] @@ -13199,7 +13310,7 @@ public void PrivatePropertyAccessorDelete() edits.VerifyEdits("Delete [set { _p = value; }]@44"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.Delete, "int P", DeletedSymbolDisplay(CSharpFeaturesResources.property_setter, "P.set"))); } @@ -13213,7 +13324,8 @@ public void PrivateAutoPropertyAccessorAdd1() edits.VerifyEdits("Insert [set;]@23"); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics( + capabilities: EditAndContinueCapabilities.AddMethodToExistingType); } [Fact] @@ -13226,7 +13338,8 @@ public void PrivateAutoPropertyAccessorAdd2() edits.VerifyEdits("Insert [private set;]@30"); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics( + capabilities: EditAndContinueCapabilities.AddMethodToExistingType); } [Fact] @@ -13239,7 +13352,8 @@ public void PrivateAutoPropertyAccessorAdd4() edits.VerifyEdits("Insert [set;]@30"); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics( + capabilities: EditAndContinueCapabilities.AddMethodToExistingType); } [Fact] @@ -13252,7 +13366,8 @@ public void PrivateAutoPropertyAccessorAdd5() edits.VerifyEdits("Insert [internal set;]@30"); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics( + capabilities: EditAndContinueCapabilities.AddMethodToExistingType); } [Fact] @@ -13265,7 +13380,8 @@ public void PrivateAutoPropertyAccessorAdd6() edits.VerifyEdits("Insert [set;]@23"); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics( + capabilities: EditAndContinueCapabilities.AddMethodToExistingType); } [Fact] @@ -13278,7 +13394,8 @@ public void PrivateAutoPropertyAccessorAdd_Init() edits.VerifyEdits("Insert [init;]@23"); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics( + capabilities: EditAndContinueCapabilities.AddMethodToExistingType); } [WorkItem(755975, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/755975")] @@ -13292,7 +13409,7 @@ public void PrivateAutoPropertyAccessorDelete_Get() edits.VerifyEdits("Delete [get;]@18"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.Delete, "int P", DeletedSymbolDisplay(CSharpFeaturesResources.property_getter, "P.get"))); } @@ -13308,7 +13425,7 @@ public void AutoPropertyAccessor_SetToInit() "Update [set;]@23 -> [init;]@23"); // not allowed since it changes the backing field readonly-ness and the signature of the setter (modreq) - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.AccessorKindUpdate, "init", CSharpFeaturesResources.property_setter)); } @@ -13324,7 +13441,7 @@ public void AutoPropertyAccessor_InitToSet() "Update [init;]@23 -> [set;]@23"); // not allowed since it changes the backing field readonly-ness and the signature of the setter (modreq) - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.AccessorKindUpdate, "set", CSharpFeaturesResources.property_setter)); } @@ -13338,7 +13455,7 @@ public void PrivateAutoPropertyAccessorDelete_Set() edits.VerifyEdits("Delete [set;]@23"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.Delete, "int P", DeletedSymbolDisplay(CSharpFeaturesResources.property_setter, "P.set"))); } @@ -13352,7 +13469,7 @@ public void PrivateAutoPropertyAccessorDelete_Init() edits.VerifyEdits("Delete [init;]@23"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.Delete, "int P", DeletedSymbolDisplay(CSharpFeaturesResources.property_setter, "P.init"))); } @@ -13366,7 +13483,7 @@ public void AutoPropertyAccessorUpdate() edits.VerifyEdits("Update [get;]@18 -> [set;]@18"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.AccessorKindUpdate, "set", CSharpFeaturesResources.property_setter)); } @@ -13381,7 +13498,8 @@ public void InsertIncompleteProperty() edits.VerifyEdits("Insert [public int P { }]@10", "Insert [{ }]@23"); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics( + capabilities: EditAndContinueCapabilities.AddMethodToExistingType); } [Fact] @@ -13397,7 +13515,8 @@ public void Property_ReadOnlyRef_Insert() "Insert [{ get; }]@32", "Insert [get;]@34"); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics( + capabilities: EditAndContinueCapabilities.AddMethodToExistingType); } [Fact] @@ -13411,7 +13530,7 @@ public void Property_ReadOnlyRef_Update() edits.VerifyEdits( "Update [int P { get; }]@13 -> [ref readonly int P { get; }]@13"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.TypeUpdate, "ref readonly int P", FeaturesResources.property_)); } @@ -13574,7 +13693,7 @@ struct S readonly int P4 { get => 1; set {}} }"; var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.ModifiersUpdate, "readonly int P1", CSharpFeaturesResources.property_getter), Diagnostic(RudeEditKind.ModifiersUpdate, "readonly int P4", CSharpFeaturesResources.property_getter), Diagnostic(RudeEditKind.ModifiersUpdate, "readonly int P4", CSharpFeaturesResources.property_setter), @@ -13641,7 +13760,7 @@ public void Indexer_Modifiers_Update(string oldModifiers, string newModifiers = edits.VerifyEdits("Update [" + oldModifiers + "int this[int a] => 0;]@10 -> [" + newModifiers + "int this[int a] => 0;]@10"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.ModifiersUpdate, newModifiers + "int this[int a]", FeaturesResources.indexer_)); } @@ -13739,7 +13858,7 @@ class C "Update [int this[int a] => new Func(() => a + 1)() + 10;]@35 -> [int this[int a] => new Func(() => 2)() + 11;]@35", "Update [=> new Func(() => a + 1)() + 10]@51 -> [=> new Func(() => 2)() + 11]@51"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.NotCapturingVariable, "a", "a")); } @@ -13768,7 +13887,7 @@ class C "Update [int this[int a] => new Func(() => a + 1)();]@35 -> [int this[int a] => new Func(() => 2)();]@35", "Update [=> new Func(() => a + 1)()]@51 -> [=> new Func(() => 2)()]@51"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.NotCapturingVariable, "a", "a")); } @@ -13797,7 +13916,7 @@ class C "Update [int this[int a] => new Func(() => { return a + 1; })();]@35 -> [int this[int a] => new Func(() => { return 2; })();]@35", "Update [=> new Func(() => { return a + 1; })()]@51 -> [=> new Func(() => { return 2; })()]@51"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.NotCapturingVariable, "a", "a")); } @@ -13826,7 +13945,7 @@ class C "Update [int this[int a] => new Func(delegate { return a + 1; })();]@35 -> [int this[int a] => new Func(delegate { return 2; })();]@35", "Update [=> new Func(delegate { return a + 1; })()]@51 -> [=> new Func(delegate { return 2; })()]@51"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.NotCapturingVariable, "a", "a")); } @@ -13894,7 +14013,7 @@ public void Indexer_BlockBodyToGetterExpressionBody() var edits = GetTopEdits(src1, src2); edits.VerifyEdits("Update [get { return 1; }]@28 -> [get => 1;]@28"); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics(); } [Fact, WorkItem(17681, "https://github.com/dotnet/roslyn/issues/17681")] @@ -14017,7 +14136,7 @@ public void Indexer_GetterAndSetterBlockBodiesToExpressionBody() "Delete [get { return 1; }]@28", "Delete [set { Console.WriteLine(0); }]@46"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.Delete, "int this[int a]", DeletedSymbolDisplay(CSharpFeaturesResources.indexer_setter, "this[int a].set"))); } @@ -14036,11 +14155,13 @@ public void Indexer_ExpressionBodyToGetterAndSetterBlockBodies() "Insert [set { Console.WriteLine(0); }]@46", "Delete [=> 1]@26"); - edits.VerifySemantics(ActiveStatementsDescription.Empty, new[] - { - SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C.get_Item"), preserveLocalVariables: false), - SemanticEdit(SemanticEditKind.Insert, c => c.GetMember("C.set_Item"), preserveLocalVariables: false) - }); + edits.VerifySemantics( + new[] + { + SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C.get_Item"), preserveLocalVariables: false), + SemanticEdit(SemanticEditKind.Insert, c => c.GetMember("C.set_Item"), preserveLocalVariables: false) + }, + capabilities: EditAndContinueCapabilities.AddMethodToExistingType); } [Fact] @@ -14051,7 +14172,7 @@ public void Indexer_Rename() var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.Renamed, "int J.this[int a]", CSharpFeaturesResources.indexer)); } @@ -14066,7 +14187,7 @@ public void Indexer_Reorder1() edits.VerifyEdits( "Reorder [int this[string a] { get { return 1; } }]@48 -> @10"); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics(); } [Fact] @@ -14080,7 +14201,7 @@ public void Indexer_AccessorReorder() edits.VerifyEdits( "Reorder [set { }]@46 -> @28"); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics(); } [Fact] @@ -14094,7 +14215,7 @@ public void Indexer_TypeUpdate() edits.VerifyEdits( "Update [int this[int a] { get; set; }]@10 -> [string this[int a] { get; set; }]@10"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.TypeUpdate, "string this[int a]", CSharpFeaturesResources.indexer)); } @@ -14109,7 +14230,7 @@ public void Tuple_TypeUpdate() edits.VerifyEdits( "Update [(int, int) M() { throw new System.Exception(); }]@10 -> [(string, int) M() { throw new System.Exception(); }]@10"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.TypeUpdate, "(string, int) M()", FeaturesResources.method)); } @@ -14124,7 +14245,7 @@ public void TupleElementDelete() edits.VerifyEdits( "Update [(int, int, int a) M() { return (1, 2, 3); }]@10 -> [(int, int) M() { return (1, 2); }]@10"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.TypeUpdate, "(int, int) M()", FeaturesResources.method)); } @@ -14139,7 +14260,7 @@ public void TupleElementAdd() edits.VerifyEdits( "Update [(int, int) M() { return (1, 2); }]@10 -> [(int, int, int a) M() { return (1, 2, 3); }]@10"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.TypeUpdate, "(int, int, int a) M()", FeaturesResources.method)); } @@ -14151,7 +14272,7 @@ public void Indexer_ParameterUpdate() var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.TypeUpdate, "string a", FeaturesResources.parameter)); } @@ -14199,7 +14320,7 @@ public T this[int i] edits.VerifyEdits("Insert [get { return arr[i]; }]@304"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.InsertIntoGenericType, "get", CSharpFeaturesResources.indexer_getter)); } @@ -14221,7 +14342,8 @@ class C edits.VerifyEdits("Insert [set { }]@67"); edits.VerifySemantics( - SemanticEdit(SemanticEditKind.Insert, c => c.GetMember("C").GetMember("this[]").SetMethod)); + new[] { SemanticEdit(SemanticEditKind.Insert, c => c.GetMember("C").GetMember("this[]").SetMethod) }, + capabilities: EditAndContinueCapabilities.AddMethodToExistingType); } [Fact] @@ -14270,7 +14392,7 @@ public T this[int i] edits.VerifyEdits("Delete [get { return arr[i]; }]@58"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.Delete, "public T this[int i]", DeletedSymbolDisplay(CSharpFeaturesResources.indexer_getter, "this[int i].get"))); } @@ -14291,7 +14413,7 @@ class C edits.VerifyEdits("Delete [set { }]@61"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.Delete, "public int this[int i]", DeletedSymbolDisplay(CSharpFeaturesResources.indexer_setter, "this[int i].set"))); } @@ -14302,7 +14424,8 @@ public void Indexer_Insert() var src2 = "struct C { public int this[int x, int y] { get { return x + y; } } }"; var edits = GetTopEdits(src1, src2); - edits.VerifySemanticDiagnostics(); + edits.VerifySemanticDiagnostics( + capabilities: EditAndContinueCapabilities.AddMethodToExistingType); } [Fact] @@ -14319,7 +14442,8 @@ public void Indexer_ReadOnlyRef_Parameter_InsertWhole() "Insert [=> throw null]@32", "Insert [in int i]@22"); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics( + capabilities: EditAndContinueCapabilities.AddMethodToExistingType); } [Fact] @@ -14333,7 +14457,7 @@ public void Indexer_ReadOnlyRef_Parameter_Update() edits.VerifyEdits( "Update [int i]@22 -> [in int i]@22"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.ModifiersUpdate, "in int i", FeaturesResources.parameter)); } @@ -14351,7 +14475,8 @@ public void Indexer_ReadOnlyRef_ReturnType_Insert() "Insert [=> throw null]@42", "Insert [int i]@35"); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics( + capabilities: EditAndContinueCapabilities.AddMethodToExistingType); } [Fact] @@ -14365,7 +14490,7 @@ public void Indexer_ReadOnlyRef_ReturnType_Update() edits.VerifyEdits( "Update [int this[int i] => throw null;]@13 -> [ref readonly int this[int i] => throw null;]@13"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.TypeUpdate, "ref readonly int this[int i]", FeaturesResources.indexer_)); } @@ -14512,7 +14637,7 @@ struct S readonly int this[sbyte x] { get => 1; set {}} }"; var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.ModifiersUpdate, "readonly int this[int x]", CSharpFeaturesResources.indexer_getter), Diagnostic(RudeEditKind.ModifiersUpdate, "readonly int this[sbyte x]", CSharpFeaturesResources.indexer_getter), Diagnostic(RudeEditKind.ModifiersUpdate, "readonly int this[sbyte x]", CSharpFeaturesResources.indexer_setter), @@ -14580,7 +14705,7 @@ public void Event_Modifiers_Update(string oldModifiers, string newModifiers = "" edits.VerifyEdits("Update [" + oldModifiers + "event Action F { add {} remove {} }]@10 -> [" + newModifiers + "event Action F { add {} remove {} }]@10"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.ModifiersUpdate, newModifiers + "event Action F", FeaturesResources.event_)); } @@ -14595,7 +14720,7 @@ public void Event_Accessor_Reorder1() edits.VerifyEdits( "Reorder [remove { }]@32 -> @24"); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics(); } [Fact] @@ -14771,7 +14896,7 @@ struct S public readonly event Action E { add {} remove {} } }"; var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.ModifiersUpdate, "public readonly event Action E", FeaturesResources.event_)); } @@ -14815,16 +14940,16 @@ class C edits.VerifyEdits( "Update [event Action F;]@18 -> [[System.Obsolete]event Action F;]@18"); - edits.VerifyRudeDiagnostics( - Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "event Action F", FeaturesResources.event_)); + edits.VerifySemanticDiagnostics( + new[] { Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "event Action F", FeaturesResources.event_) }, + capabilities: EditAndContinueCapabilities.Baseline); edits.VerifySemantics( - ActiveStatementsDescription.Empty, new[] { SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C.F")) }, - capabilities: EditAndContinueTestHelpers.Net6RuntimeCapabilities); + capabilities: EditAndContinueCapabilities.ChangeCustomAttributes); } [Fact] @@ -14846,17 +14971,18 @@ [System.Obsolete]event Action F { add {} remove {} } edits.VerifyEdits( "Update [event Action F { add {} remove {} }]@18 -> [[System.Obsolete]event Action F { add {} remove {} }]@18"); - edits.VerifyRudeDiagnostics( - Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "event Action F", FeaturesResources.event_)); + edits.VerifySemanticDiagnostics( + new[] { Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "event Action F", FeaturesResources.event_) }, + capabilities: EditAndContinueCapabilities.Baseline); edits.VerifySemantics( - ActiveStatementsDescription.Empty, - new[] { + new[] + { SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C.F")), SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C.F").AddMethod), SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C.F").RemoveMethod) }, - capabilities: EditAndContinueTestHelpers.Net6RuntimeCapabilities); + capabilities: EditAndContinueCapabilities.ChangeCustomAttributes); } [Fact] @@ -14878,15 +15004,13 @@ event Action F { add {} [System.Obsolete]remove {} } edits.VerifyEdits( "Update [remove {}]@42 -> [[System.Obsolete]remove {}]@42"); - edits.VerifyRudeDiagnostics( - Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "remove", FeaturesResources.event_accessor)); + edits.VerifySemanticDiagnostics( + new[] { Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "remove", FeaturesResources.event_accessor) }, + capabilities: EditAndContinueCapabilities.Baseline); edits.VerifySemantics( - ActiveStatementsDescription.Empty, - new[] { - SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C.F").RemoveMethod) - }, - capabilities: EditAndContinueTestHelpers.Net6RuntimeCapabilities); + new[] { SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C.F").RemoveMethod) }, + capabilities: EditAndContinueCapabilities.ChangeCustomAttributes); } [Fact] @@ -14908,15 +15032,13 @@ class C edits.VerifyEdits( "Update [[System.Obsolete]event Action F;]@18 -> [event Action F;]@18"); - edits.VerifyRudeDiagnostics( - Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "event Action F", FeaturesResources.event_)); + edits.VerifySemanticDiagnostics( + new[] { Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "event Action F", FeaturesResources.event_) }, + capabilities: EditAndContinueCapabilities.Baseline); edits.VerifySemantics( - ActiveStatementsDescription.Empty, - new[] { - SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C.F")) - }, - capabilities: EditAndContinueTestHelpers.Net6RuntimeCapabilities); + new[] { SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C.F")) }, + capabilities: EditAndContinueCapabilities.ChangeCustomAttributes); } [Fact] @@ -14938,17 +15060,18 @@ event Action F { add {} remove {} } edits.VerifyEdits( "Update [[System.Obsolete]event Action F { add {} remove {} }]@18 -> [event Action F { add {} remove {} }]@18"); - edits.VerifyRudeDiagnostics( - Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "event Action F", FeaturesResources.event_)); + edits.VerifySemanticDiagnostics( + new[] { Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "event Action F", FeaturesResources.event_) }, + capabilities: EditAndContinueCapabilities.Baseline); edits.VerifySemantics( - ActiveStatementsDescription.Empty, - new[] { + new[] + { SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C.F")), SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C.F").AddMethod), SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C.F").RemoveMethod) }, - capabilities: EditAndContinueTestHelpers.Net6RuntimeCapabilities); + capabilities: EditAndContinueCapabilities.ChangeCustomAttributes); } [Fact] @@ -14970,15 +15093,16 @@ event Action F { add {} remove {} } edits.VerifyEdits( "Update [[System.Obsolete]remove {}]@42 -> [remove {}]@42"); - edits.VerifyRudeDiagnostics( - Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "remove", FeaturesResources.event_accessor)); + edits.VerifySemanticDiagnostics( + new[] { Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "remove", FeaturesResources.event_accessor) }, + capabilities: EditAndContinueCapabilities.Baseline); edits.VerifySemantics( - ActiveStatementsDescription.Empty, - new[] { + new[] + { SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C.F").RemoveMethod) }, - capabilities: EditAndContinueTestHelpers.Net6RuntimeCapabilities); + capabilities: EditAndContinueCapabilities.ChangeCustomAttributes); } #endregion @@ -15146,7 +15270,7 @@ public void Parameter_Type_Update_RuntimeTypeChanged(string oldType, string newT var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.TypeUpdate, newType + " a", FeaturesResources.parameter)); } @@ -15179,7 +15303,7 @@ public void Parameter_Modifier_Remove(string modifier) var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.ModifiersUpdate, "int[] a", FeaturesResources.parameter)); } @@ -15197,7 +15321,7 @@ public void Parameter_Initializer_Update(string oldParameter, string newParamete var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.InitializerUpdate, newParameter, FeaturesResources.parameter)); } @@ -15209,7 +15333,7 @@ public void Parameter_Initializer_NaN() var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics(); } [Fact] @@ -15248,9 +15372,8 @@ public void Parameter_Attribute_Insert() "Update [int a]@63 -> [[A]int a]@63"); edits.VerifySemantics( - ActiveStatementsDescription.Empty, new[] { SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C.M")) }, - capabilities: EditAndContinueTestHelpers.Net6RuntimeCapabilities); + capabilities: EditAndContinueCapabilities.ChangeCustomAttributes); } [Fact] @@ -15266,9 +15389,9 @@ public void Parameter_Attribute_Insert_SupportedByRuntime_SecurityAttribute1() edits.VerifyEdits( "Update [int a]@101 -> [[A]int a]@101"); - edits.VerifyRudeDiagnostics( - capabilities: EditAndContinueTestHelpers.Net6RuntimeCapabilities, - Diagnostic(RudeEditKind.ChangingNonCustomAttribute, "int a", "AAttribute", FeaturesResources.parameter)); + edits.VerifySemanticDiagnostics( + new[] { Diagnostic(RudeEditKind.ChangingNonCustomAttribute, "int a", "AAttribute", FeaturesResources.parameter) }, + capabilities: EditAndContinueCapabilities.ChangeCustomAttributes); } [Fact] @@ -15285,9 +15408,9 @@ public void Parameter_Attribute_Insert_SupportedByRuntime_SecurityAttribute2() edits.VerifyEdits( "Update [int a]@143 -> [[A]int a]@143"); - edits.VerifyRudeDiagnostics( - capabilities: EditAndContinueTestHelpers.Net6RuntimeCapabilities, - Diagnostic(RudeEditKind.ChangingNonCustomAttribute, "int a", "AAttribute", FeaturesResources.parameter)); + edits.VerifySemanticDiagnostics( + new[] { Diagnostic(RudeEditKind.ChangingNonCustomAttribute, "int a", "AAttribute", FeaturesResources.parameter) }, + capabilities: EditAndContinueCapabilities.ChangeCustomAttributes); } [Fact] @@ -15303,7 +15426,9 @@ public void Parameter_Attribute_Insert_NotSupportedByRuntime1() edits.VerifyEdits( "Update [int a]@72 -> [[A]int a]@72"); - edits.VerifyRudeDiagnostics(Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "int a", FeaturesResources.parameter)); + edits.VerifySemanticDiagnostics( + new[] { Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "int a", FeaturesResources.parameter) }, + capabilities: EditAndContinueCapabilities.Baseline); } [Fact] @@ -15320,7 +15445,9 @@ public void Parameter_Attribute_Insert_NotSupportedByRuntime2() edits.VerifyEdits( "Update [[A]int a]@120 -> [[A, B]int a]@120"); - edits.VerifyRudeDiagnostics(Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "int a", FeaturesResources.parameter)); + edits.VerifySemanticDiagnostics( + new[] { Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "int a", FeaturesResources.parameter) }, + capabilities: EditAndContinueCapabilities.Baseline); } [Fact] @@ -15336,7 +15463,9 @@ public void Parameter_Attribute_Delete_NotSupportedByRuntime() edits.VerifyEdits( "Update [[A]int a]@72 -> [int a]@72"); - edits.VerifyRudeDiagnostics(Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "int a", FeaturesResources.parameter)); + edits.VerifySemanticDiagnostics( + new[] { Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "int a", FeaturesResources.parameter) }, + capabilities: EditAndContinueCapabilities.Baseline); } [Fact] @@ -15353,8 +15482,9 @@ public void Parameter_Attribute_Update_NotSupportedByRuntime() edits.VerifyEdits( "Update [[System.Obsolete(\"1\"), B]int a]@120 -> [[System.Obsolete(\"2\"), A]int a]@120"); - edits.VerifyRudeDiagnostics( - Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "int a", FeaturesResources.parameter)); + edits.VerifySemanticDiagnostics( + new[] { Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "int a", FeaturesResources.parameter) }, + capabilities: EditAndContinueCapabilities.Baseline); } [Fact] @@ -15371,9 +15501,8 @@ public void Parameter_Attribute_Update() "Update [[A(0)]int a]@67 -> [[A(1)]int a]@67"); edits.VerifySemantics( - ActiveStatementsDescription.Empty, new[] { SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C.F")) }, - capabilities: EditAndContinueTestHelpers.Net6RuntimeCapabilities); + capabilities: EditAndContinueCapabilities.ChangeCustomAttributes); } [Fact] @@ -15391,9 +15520,8 @@ public void Parameter_Attribute_Update_WithBodyUpdate() "Update [[A(0)]int a]@67 -> [[A(1)]int a]@67"); edits.VerifySemantics( - ActiveStatementsDescription.Empty, new[] { SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C.F")) }, - capabilities: EditAndContinueTestHelpers.Net6RuntimeCapabilities); + capabilities: EditAndContinueCapabilities.ChangeCustomAttributes); } #endregion @@ -15495,10 +15623,14 @@ public void MethodTypeParameter_Attribute_Insert1() edits.VerifyEdits( "Update [T]@72 -> [[A]T]@72"); - edits.VerifyRudeDiagnostics( - Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "T", FeaturesResources.type_parameter), - Diagnostic(RudeEditKind.GenericMethodUpdate, "T"), - Diagnostic(RudeEditKind.GenericMethodTriviaUpdate, "", FeaturesResources.method)); + edits.VerifySemanticDiagnostics( + new[] + { + Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "T", FeaturesResources.type_parameter), + Diagnostic(RudeEditKind.GenericMethodUpdate, "T"), + Diagnostic(RudeEditKind.GenericMethodTriviaUpdate, "", FeaturesResources.method) + }, + capabilities: EditAndContinueCapabilities.Baseline); } [Fact] @@ -15515,10 +15647,14 @@ public void MethodTypeParameter_Attribute_Insert2() edits.VerifyEdits( "Update [[A]T]@120 -> [[A, B]T]@120"); - edits.VerifyRudeDiagnostics( - Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "T", FeaturesResources.type_parameter), - Diagnostic(RudeEditKind.GenericMethodUpdate, "T"), - Diagnostic(RudeEditKind.GenericMethodTriviaUpdate, "", FeaturesResources.method)); + edits.VerifySemanticDiagnostics( + new[] + { + Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "T", FeaturesResources.type_parameter), + Diagnostic(RudeEditKind.GenericMethodUpdate, "T"), + Diagnostic(RudeEditKind.GenericMethodTriviaUpdate, "", FeaturesResources.method) + }, + capabilities: EditAndContinueCapabilities.Baseline); } [Fact] @@ -15534,10 +15670,14 @@ public void MethodTypeParameter_Attribute_Delete() edits.VerifyEdits( "Update [[A]T]@72 -> [T]@72"); - edits.VerifyRudeDiagnostics( - Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "T", FeaturesResources.type_parameter), - Diagnostic(RudeEditKind.GenericMethodTriviaUpdate, "", FeaturesResources.method), - Diagnostic(RudeEditKind.GenericMethodUpdate, "T")); + edits.VerifySemanticDiagnostics( + new[] + { + Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "T", FeaturesResources.type_parameter), + Diagnostic(RudeEditKind.GenericMethodTriviaUpdate, "", FeaturesResources.method), + Diagnostic(RudeEditKind.GenericMethodUpdate, "T") + }, + capabilities: EditAndContinueCapabilities.Baseline); } [Fact] @@ -15554,9 +15694,13 @@ public void MethodTypeParameter_Attribute_Update_NotSupportedByRuntime() edits.VerifyEdits( "Update [[System.Obsolete(\"1\"), B]T]@120 -> [[System.Obsolete(\"2\"), A]T]@120"); - edits.VerifyRudeDiagnostics( - Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "T", FeaturesResources.type_parameter), - Diagnostic(RudeEditKind.GenericMethodUpdate, "T")); + edits.VerifySemanticDiagnostics( + new[] + { + Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "T", FeaturesResources.type_parameter), + Diagnostic(RudeEditKind.GenericMethodUpdate, "T") + }, + capabilities: EditAndContinueCapabilities.Baseline); } [Fact] @@ -15572,9 +15716,9 @@ public void MethodTypeParameter_Attribute_Update() edits.VerifyEdits( "Update [[A(0)]T]@67 -> [[A(1)]T]@67"); - edits.VerifyRudeDiagnostics( - EditAndContinueTestHelpers.Net6RuntimeCapabilities, - Diagnostic(RudeEditKind.GenericMethodUpdate, "T")); + edits.VerifySemanticDiagnostics( + new[] { Diagnostic(RudeEditKind.GenericMethodUpdate, "T") }, + capabilities: EditAndContinueCapabilities.ChangeCustomAttributes); } [Fact] @@ -15591,10 +15735,14 @@ public void MethodTypeParameter_Attribute_Update_WithBodyUpdate() "Update [void F<[A(0)]T>(T a) { F(0); }]@60 -> [void F<[A(1)]T>(T a) { F(1); }]@60", "Update [[A(0)]T]@67 -> [[A(1)]T]@67"); - edits.VerifyRudeDiagnostics( - Diagnostic(RudeEditKind.GenericMethodUpdate, "void F<[A(1)]T>(T a)"), - Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "T", FeaturesResources.type_parameter), - Diagnostic(RudeEditKind.GenericMethodUpdate, "T")); + edits.VerifySemanticDiagnostics( + new[] + { + Diagnostic(RudeEditKind.GenericMethodUpdate, "void F<[A(1)]T>(T a)"), + Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "T", FeaturesResources.type_parameter), + Diagnostic(RudeEditKind.GenericMethodUpdate, "T") + }, + capabilities: EditAndContinueCapabilities.Baseline); } #endregion @@ -15613,7 +15761,7 @@ public void TypeTypeParameterInsert1() "Insert []@7", "Insert [A]@8"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.Insert, "A", FeaturesResources.type_parameter)); } @@ -15629,7 +15777,7 @@ public void TypeTypeParameterInsert2() "Update []@7 -> []@7", "Insert [B]@10"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.Insert, "B", FeaturesResources.type_parameter)); } @@ -15657,7 +15805,7 @@ public void TypeTypeParameterDelete2() "Update []@7 -> []@7", "Delete [A]@8"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.Delete, "class C", DeletedSymbolDisplay(FeaturesResources.type_parameter, "A"))); } @@ -15672,7 +15820,7 @@ public void TypeTypeParameterUpdate() edits.VerifyEdits( "Update [A]@8 -> [B]@8"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.Renamed, "B", FeaturesResources.type_parameter), Diagnostic(RudeEditKind.GenericTypeUpdate, "B")); } @@ -15688,7 +15836,7 @@ public void TypeTypeParameterReorder() edits.VerifyEdits( "Reorder [B]@10 -> @8"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.Move, "B", FeaturesResources.type_parameter)); } @@ -15704,7 +15852,7 @@ public void TypeTypeParameterReorderAndUpdate() "Reorder [B]@10 -> @8", "Update [A]@8 -> [C]@10"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.Move, "B", FeaturesResources.type_parameter), Diagnostic(RudeEditKind.Renamed, "C", FeaturesResources.type_parameter), Diagnostic(RudeEditKind.GenericTypeUpdate, "C")); @@ -15723,9 +15871,13 @@ public void TypeTypeParameterAttributeInsert1() edits.VerifyEdits( "Update [T]@56 -> [[A]T]@56"); - edits.VerifyRudeDiagnostics( - Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "T", FeaturesResources.type_parameter), - Diagnostic(RudeEditKind.GenericTypeUpdate, "T")); + edits.VerifySemanticDiagnostics( + new[] + { + Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "T", FeaturesResources.type_parameter), + Diagnostic(RudeEditKind.GenericTypeUpdate, "T") + }, + capabilities: EditAndContinueCapabilities.Baseline); } [Fact] @@ -15742,9 +15894,13 @@ public void TypeTypeParameterAttributeInsert2() edits.VerifyEdits( "Update [[A]T]@104 -> [[A, B]T]@104"); - edits.VerifyRudeDiagnostics( - Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "T", FeaturesResources.type_parameter), - Diagnostic(RudeEditKind.GenericTypeUpdate, "T")); + edits.VerifySemanticDiagnostics( + new[] + { + Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "T", FeaturesResources.type_parameter), + Diagnostic(RudeEditKind.GenericTypeUpdate, "T") + }, + capabilities: EditAndContinueCapabilities.Baseline); } [Fact] @@ -15760,9 +15916,9 @@ public void TypeTypeParameterAttributeInsert_SupportedByRuntime() edits.VerifyEdits( "Update [T]@56 -> [[A]T]@56"); - edits.VerifyRudeDiagnostics( - EditAndContinueTestHelpers.Net6RuntimeCapabilities, - Diagnostic(RudeEditKind.GenericTypeUpdate, "T")); + edits.VerifySemanticDiagnostics( + new[] { Diagnostic(RudeEditKind.GenericTypeUpdate, "T") }, + capabilities: EditAndContinueCapabilities.ChangeCustomAttributes); } [Fact] @@ -15778,9 +15934,13 @@ public void TypeTypeParameterAttributeDelete() edits.VerifyEdits( "Update [[A]T]@56 -> [T]@56"); - edits.VerifyRudeDiagnostics( - Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "T", FeaturesResources.type_parameter), - Diagnostic(RudeEditKind.GenericTypeUpdate, "T")); + edits.VerifySemanticDiagnostics( + new[] + { + Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "T", FeaturesResources.type_parameter), + Diagnostic(RudeEditKind.GenericTypeUpdate, "T") + }, + capabilities: EditAndContinueCapabilities.Baseline); } [Fact] @@ -15797,9 +15957,13 @@ public void TypeTypeParameterAttributeUpdate() edits.VerifyEdits( "Update [[System.Obsolete(\"1\"), B]T]@104 -> [[System.Obsolete(\"2\"), A]T]@104"); - edits.VerifyRudeDiagnostics( - Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "T", FeaturesResources.type_parameter), - Diagnostic(RudeEditKind.GenericTypeUpdate, "T")); + edits.VerifySemanticDiagnostics( + new[] + { + Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "T", FeaturesResources.type_parameter), + Diagnostic(RudeEditKind.GenericTypeUpdate, "T") + }, + capabilities: EditAndContinueCapabilities.Baseline); } [Fact] @@ -15829,7 +15993,7 @@ class B : System.Attribute {} Diagnostic(RudeEditKind.GenericTypeUpdate, "T"), }), }, - capabilities: EditAndContinueTestHelpers.Net6RuntimeCapabilities); + capabilities: EditAndContinueCapabilities.ChangeCustomAttributes); } [Fact] @@ -15859,7 +16023,7 @@ class B : System.Attribute {} SemanticEdit(SemanticEditKind.Replace, c => c.GetMember("C"), partialType: "C") }), }, - capabilities: EditAndContinueTestHelpers.Net6RuntimeCapabilities); + capabilities: EditAndContinueCapabilities.NewTypeDefinition); } #endregion @@ -15884,7 +16048,7 @@ public void TypeConstraint_Insert(string newConstraint) edits.VerifyEdits( "Insert [where T : " + newConstraint + "]@13"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.ChangingConstraints, "where T : " + newConstraint, FeaturesResources.type_parameter), Diagnostic(RudeEditKind.GenericTypeUpdate, "where T : " + newConstraint)); } @@ -15907,7 +16071,7 @@ public void TypeConstraint_Delete(string oldConstraint) edits.VerifyEdits( "Delete [where T : " + oldConstraint + "]@13"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.ChangingConstraints, "T", FeaturesResources.type_parameter), Diagnostic(RudeEditKind.GenericTypeUpdate, "T")); } @@ -15923,7 +16087,7 @@ public void TypeConstraint_Update_RuntimeTypeUnchanged(string oldType, string ne var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.GenericTypeUpdate, "where T : System.Collections.Generic.List<" + newType + ">")); } @@ -15938,7 +16102,7 @@ public void TypeConstraint_Update_RuntimeTypeChanged(string oldType, string newT var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.ChangingConstraints, "where T : System.Collections.Generic.List<" + newType + ">", FeaturesResources.type_parameter), Diagnostic(RudeEditKind.GenericTypeUpdate, "where T : System.Collections.Generic.List<" + newType + ">")); } @@ -15951,7 +16115,7 @@ public void TypeConstraint_Delete_WithParameter() var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.Delete, "class C", DeletedSymbolDisplay(FeaturesResources.type_parameter, "T"))); } @@ -15966,7 +16130,7 @@ public void TypeConstraint_MultipleClauses_Insert() edits.VerifyEdits( "Insert [where S : unmanaged]@13"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.ChangingConstraints, "where S : unmanaged", FeaturesResources.type_parameter), Diagnostic(RudeEditKind.GenericTypeUpdate, "where S : unmanaged")); } @@ -15982,7 +16146,7 @@ public void TypeConstraint_MultipleClauses_Delete() edits.VerifyEdits( "Delete [where S : new()]@13"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.ChangingConstraints, "S", FeaturesResources.type_parameter), Diagnostic(RudeEditKind.GenericTypeUpdate, "S")); } @@ -15998,7 +16162,7 @@ public void TypeConstraint_MultipleClauses_Reorder() edits.VerifyEdits( "Reorder [where T : class]@30 -> @13"); - edits.VerifyRudeDiagnostics(); + edits.VerifySemanticDiagnostics(); } [Fact] @@ -16015,7 +16179,7 @@ public void TypeConstraint_MultipleClauses_UpdateAndReorder() "Update [where T : class]@29 -> [where T : class, I]@13", "Update [where S : new()]@13 -> [where S : class, new()]@32"); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.Move, "T", FeaturesResources.type_parameter), Diagnostic(RudeEditKind.ChangingConstraints, "where T : class, I", FeaturesResources.type_parameter), Diagnostic(RudeEditKind.GenericTypeUpdate, "where T : class, I"), @@ -16087,7 +16251,9 @@ public void TopLevelStatements_Insert_NoImplicitMain() edits.VerifyEdits("Insert [Console.WriteLine(\"Hello World\");]@19"); - edits.VerifySemantics(SemanticEdit(SemanticEditKind.Insert, c => c.GetMember("Program.
$"))); + edits.VerifySemantics( + new[] { SemanticEdit(SemanticEditKind.Insert, c => c.GetMember("Program.
$")) }, + capabilities: EditAndContinueCapabilities.NewTypeDefinition); } [Fact] @@ -16127,7 +16293,7 @@ public void TopLevelStatements_Delete_NoImplicitMain() edits.VerifyEdits("Delete [Console.WriteLine(\"Hello World\");]@19"); - edits.VerifyRudeDiagnostics(Diagnostic(RudeEditKind.Delete, null, CSharpFeaturesResources.global_statement)); + edits.VerifySemanticDiagnostics(Diagnostic(RudeEditKind.Delete, null, CSharpFeaturesResources.global_statement)); } [Fact] @@ -16159,7 +16325,7 @@ public void TopLevelStatements_StackAlloc() var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.StackAllocUpdate, "stackalloc", CSharpFeaturesResources.global_statement)); } @@ -16180,7 +16346,7 @@ public void TopLevelStatements_VoidToInt1() var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.ChangeImplicitMainReturnType, "return 1;")); } @@ -16203,7 +16369,7 @@ public void TopLevelStatements_VoidToInt2() var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.ChangeImplicitMainReturnType, "return 1;")); } @@ -16234,7 +16400,7 @@ int Goo() var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.ChangeImplicitMainReturnType, "return 1;")); } @@ -16255,7 +16421,7 @@ public void TopLevelStatements_AddAwait() var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.Insert, "await", CSharpFeaturesResources.await_expression)); } @@ -16276,7 +16442,7 @@ public void TopLevelStatements_DeleteAwait() var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.Delete, null, CSharpFeaturesResources.await_expression)); } @@ -16299,7 +16465,7 @@ public void TopLevelStatements_VoidToTask() var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.ChangeImplicitMainReturnType, "await Task.Delay(100);")); } @@ -16324,7 +16490,7 @@ public void TopLevelStatements_TaskToTaskInt() var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.ChangeImplicitMainReturnType, "return 1;")); } @@ -16352,7 +16518,7 @@ Task GetInt() var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.ChangeImplicitMainReturnType, "return await GetInt();")); } @@ -16374,7 +16540,7 @@ public void TopLevelStatements_IntToVoid1() var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.ChangeImplicitMainReturnType, "Console.Write(1);")); } @@ -16397,7 +16563,7 @@ public void TopLevelStatements_IntToVoid2() var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.ChangeImplicitMainReturnType, "return;")); } @@ -16428,7 +16594,7 @@ int Goo() var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.ChangeImplicitMainReturnType, "int Goo()\r\n{\r\n return 1;\r\n}")); } @@ -16465,7 +16631,7 @@ public int Goo() var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.ChangeImplicitMainReturnType, "Console.Write(1);")); } @@ -16488,7 +16654,7 @@ public void TopLevelStatements_TaskToVoid() var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.ChangeImplicitMainReturnType, "Console.Write(1);"), Diagnostic(RudeEditKind.Delete, null, CSharpFeaturesResources.await_expression)); } @@ -16514,7 +16680,7 @@ public void TopLevelStatements_TaskIntToTask() var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.ChangeImplicitMainReturnType, "Console.Write(1);")); } @@ -16542,7 +16708,7 @@ Task GetInt() var edits = GetTopEdits(src1, src2); - edits.VerifyRudeDiagnostics( + edits.VerifySemanticDiagnostics( Diagnostic(RudeEditKind.ChangeImplicitMainReturnType, "Console.Write(1);"), Diagnostic(RudeEditKind.Delete, null, CSharpFeaturesResources.await_expression)); } diff --git a/src/EditorFeatures/CSharpTest/EmbeddedLanguages/JsonStringDetectorTests.cs b/src/EditorFeatures/CSharpTest/EmbeddedLanguages/JsonStringDetectorTests.cs index cc95f9c181ea2..48c3e36c8967c 100644 --- a/src/EditorFeatures/CSharpTest/EmbeddedLanguages/JsonStringDetectorTests.cs +++ b/src/EditorFeatures/CSharpTest/EmbeddedLanguages/JsonStringDetectorTests.cs @@ -3,6 +3,7 @@ // See the LICENSE file in the project root for more information. using System.Threading.Tasks; +using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.EmbeddedLanguages; using Microsoft.CodeAnalysis.Editor.UnitTests.CodeActions; using Microsoft.CodeAnalysis.Test.Utilities; @@ -67,5 +68,68 @@ void Goo() }", }.RunAsync(); } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsDetectJsonString)] + public async Task TestNonStrictRawString() + { + await new VerifyCS.Test + { + TestCode = +@" +class C +{ + void Goo() + { + var j = [|""""""{ 'a': 00 }""""""|]; + } +}", + FixedCode = +@" +class C +{ + void Goo() + { + var j = /*lang=json*/ """"""{ 'a': 00 }""""""; + } +}", + LanguageVersion = LanguageVersion.Preview, + }.RunAsync(); + } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsDetectJsonString)] + public async Task TestNotWithExistingComment() + { + var code = @" +class C +{ + void Goo() + { + var j = /*lang=json,strict*/ ""{ \""a\"": 0 }""; + } +}"; + await new VerifyCS.Test + { + TestCode = code, + FixedCode = code, + }.RunAsync(); + } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsDetectJsonString)] + public async Task TestNotOnUnlikelyJson() + { + var code = @" +class C +{ + void Goo() + { + var j = ""[1, 2, 3]""; + } +}"; + await new VerifyCS.Test + { + TestCode = code, + FixedCode = code, + }.RunAsync(); + } } } diff --git a/src/EditorFeatures/CSharpTest/EmbeddedLanguages/ValidateJsonStringTests.cs b/src/EditorFeatures/CSharpTest/EmbeddedLanguages/ValidateJsonStringTests.cs index 20b424062f905..8b50c83eeb4e7 100644 --- a/src/EditorFeatures/CSharpTest/EmbeddedLanguages/ValidateJsonStringTests.cs +++ b/src/EditorFeatures/CSharpTest/EmbeddedLanguages/ValidateJsonStringTests.cs @@ -25,11 +25,8 @@ public ValidateJsonStringTests(ITestOutputHelper logger) : base(logger) internal override (DiagnosticAnalyzer, CodeFixProvider?) CreateDiagnosticProviderAndFixer(Workspace workspace) => (new CSharpJsonDiagnosticAnalyzer(), null); - private static OptionsCollection OptionOn() - => new(LanguageNames.CSharp) - { - { JsonFeatureOptions.ReportInvalidJsonPatterns, true } - }; + private static IdeAnalyzerOptions OptionOn() + => new(ReportInvalidJsonPatterns: true); [Fact, Trait(Traits.Feature, Traits.Features.ValidateJsonString)] public async Task TestWarning1() @@ -42,7 +39,24 @@ void Main() var r = /*lang=json,strict*/ ""[|new|] Json()""; } }", - options: OptionOn(), + ideAnalyzerOptions: OptionOn(), + diagnosticId: AbstractJsonDiagnosticAnalyzer.DiagnosticId, + diagnosticSeverity: DiagnosticSeverity.Warning, + diagnosticMessage: string.Format(FeaturesResources.JSON_issue_0, FeaturesResources.Constructors_not_allowed)); + } + + [Fact, Trait(Traits.Feature, Traits.Features.ValidateJsonString)] + public async Task TestWarningInRawString1() + { + await TestDiagnosticInfoAsync(@" +class Program +{ + void Main() + { + var r = /*lang=json,strict*/ """"""[|new|] Json()""""""; + } +}", + ideAnalyzerOptions: OptionOn(), diagnosticId: AbstractJsonDiagnosticAnalyzer.DiagnosticId, diagnosticSeverity: DiagnosticSeverity.Warning, diagnosticMessage: string.Format(FeaturesResources.JSON_issue_0, FeaturesResources.Constructors_not_allowed)); @@ -59,7 +73,7 @@ void Main() var r = /*lang=json*/ ""[|}|]""; } }", - options: OptionOn(), + ideAnalyzerOptions: OptionOn(), diagnosticId: AbstractJsonDiagnosticAnalyzer.DiagnosticId, diagnosticSeverity: DiagnosticSeverity.Warning, diagnosticMessage: string.Format(FeaturesResources.JSON_issue_0, @@ -84,7 +98,7 @@ void Main() ", - options: OptionOn(), + ideAnalyzerOptions: OptionOn(), diagnosticId: AbstractJsonDiagnosticAnalyzer.DiagnosticId, diagnosticSeverity: DiagnosticSeverity.Warning, diagnosticMessage: string.Format(FeaturesResources.JSON_issue_0, @@ -109,7 +123,7 @@ void Main() ", - options: OptionOn(), + ideAnalyzerOptions: OptionOn(), diagnosticId: AbstractJsonDiagnosticAnalyzer.DiagnosticId, diagnosticSeverity: DiagnosticSeverity.Warning, diagnosticMessage: string.Format(FeaturesResources.JSON_issue_0, @@ -174,7 +188,7 @@ void Main() ", - options: OptionOn(), + ideAnalyzerOptions: OptionOn(), diagnosticId: AbstractJsonDiagnosticAnalyzer.DiagnosticId, diagnosticSeverity: DiagnosticSeverity.Warning, diagnosticMessage: string.Format(FeaturesResources.JSON_issue_0, @@ -199,7 +213,7 @@ void Main() ", - options: OptionOn(), + ideAnalyzerOptions: OptionOn(), diagnosticId: AbstractJsonDiagnosticAnalyzer.DiagnosticId, diagnosticSeverity: DiagnosticSeverity.Warning, diagnosticMessage: string.Format(FeaturesResources.JSON_issue_0, @@ -270,7 +284,7 @@ void M([StringSyntax(StringSyntaxAttribute.Json)] string p) ", - options: OptionOn(), + ideAnalyzerOptions: OptionOn(), diagnosticId: AbstractJsonDiagnosticAnalyzer.DiagnosticId, diagnosticSeverity: DiagnosticSeverity.Warning, diagnosticMessage: string.Format(FeaturesResources.JSON_issue_0, @@ -301,7 +315,7 @@ void M([StringSyntax(StringSyntaxAttribute.Json)] string p, JsonDocumentOptions ", - options: OptionOn(), + ideAnalyzerOptions: OptionOn(), diagnosticId: AbstractJsonDiagnosticAnalyzer.DiagnosticId, diagnosticSeverity: DiagnosticSeverity.Warning, diagnosticMessage: string.Format(FeaturesResources.JSON_issue_0, @@ -331,6 +345,50 @@ void M([StringSyntax(StringSyntaxAttribute.Json)] string p, JsonDocumentOptions {EmbeddedLanguagesTestConstants.StringSyntaxAttributeCodeCSharpXml} +"); + } + + [Fact, Trait(Traits.Feature, Traits.Features.ValidateJsonString)] + public async Task TestNotOnUnlikelyJson() + { + await TestDiagnosticMissingAsync($@" + + + +using System.Diagnostics.CodeAnalysis; +using System.Text.Json; + +class Program +{{ + void Main() + {{ + var v = [|""[1, 2, 3]""|]; + }} +}} + + +"); + } + + [Fact, Trait(Traits.Feature, Traits.Features.ValidateJsonString)] + public async Task TestNotOnLikelyJson() + { + await TestDiagnosticMissingAsync($@" + + + +using System.Diagnostics.CodeAnalysis; +using System.Text.Json; + +class Program +{{ + void Main() + {{ + var v = [|""{{ prop: 0 }}""|]; + }} +}} + + "); } } diff --git a/src/EditorFeatures/CSharpTest/EmbeddedLanguages/ValidateRegexStringTests.cs b/src/EditorFeatures/CSharpTest/EmbeddedLanguages/ValidateRegexStringTests.cs index 2617c7eba0194..17c81160aac77 100644 --- a/src/EditorFeatures/CSharpTest/EmbeddedLanguages/ValidateRegexStringTests.cs +++ b/src/EditorFeatures/CSharpTest/EmbeddedLanguages/ValidateRegexStringTests.cs @@ -25,11 +25,8 @@ public ValidateRegexStringTests(ITestOutputHelper logger) internal override (DiagnosticAnalyzer, CodeFixProvider?) CreateDiagnosticProviderAndFixer(Workspace workspace) => (new CSharpRegexDiagnosticAnalyzer(), null); - private static OptionsCollection OptionOn() - => new(LanguageNames.CSharp) - { - { RegularExpressionsOptions.ReportInvalidRegexPatterns, true } - }; + private static IdeAnalyzerOptions OptionOn() + => new(ReportInvalidRegexPatterns: true); [Fact, Trait(Traits.Feature, Traits.Features.ValidateRegexString)] public async Task TestWarning1() @@ -44,7 +41,7 @@ void Main() var r = new Regex(@""[|)|]""); } }", - options: OptionOn(), + ideAnalyzerOptions: OptionOn(), diagnosticId: AbstractRegexDiagnosticAnalyzer.DiagnosticId, diagnosticSeverity: DiagnosticSeverity.Warning, diagnosticMessage: string.Format(FeaturesResources.Regex_issue_0, FeaturesResources.Too_many_close_parens)); @@ -63,7 +60,7 @@ void Main() var r = new Regex(""[|\u0029|]""); } }", - options: OptionOn(), + ideAnalyzerOptions: OptionOn(), diagnosticId: AbstractRegexDiagnosticAnalyzer.DiagnosticId, diagnosticSeverity: DiagnosticSeverity.Warning, diagnosticMessage: string.Format(FeaturesResources.Regex_issue_0, FeaturesResources.Too_many_close_parens)); diff --git a/src/EditorFeatures/CSharpTest/ExtractInterface/ExtractInterfaceTests.cs b/src/EditorFeatures/CSharpTest/ExtractInterface/ExtractInterfaceTests.cs index f44dbb79f780c..7948d86cd5920 100644 --- a/src/EditorFeatures/CSharpTest/ExtractInterface/ExtractInterfaceTests.cs +++ b/src/EditorFeatures/CSharpTest/ExtractInterface/ExtractInterfaceTests.cs @@ -9,7 +9,7 @@ using Microsoft.CodeAnalysis.CodeStyle; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.CodeStyle; -using Microsoft.CodeAnalysis.Editor.CSharp.ExtractInterface; +using Microsoft.CodeAnalysis.CSharp.ExtractInterface; using Microsoft.CodeAnalysis.Editor.UnitTests; using Microsoft.CodeAnalysis.Editor.UnitTests.Extensions; using Microsoft.CodeAnalysis.Editor.UnitTests.ExtractInterface; diff --git a/src/EditorFeatures/CSharpTest/ExtractMethod/ExtractMethodTests.cs b/src/EditorFeatures/CSharpTest/ExtractMethod/ExtractMethodTests.cs index bd8def4fe0906..8af873f1a8725 100644 --- a/src/EditorFeatures/CSharpTest/ExtractMethod/ExtractMethodTests.cs +++ b/src/EditorFeatures/CSharpTest/ExtractMethod/ExtractMethodTests.cs @@ -10,7 +10,6 @@ using System.Xml.Linq; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.ExtractMethod; -using Microsoft.CodeAnalysis.Editor.CSharp.ExtractMethod; using Microsoft.CodeAnalysis.Editor.UnitTests; using Microsoft.CodeAnalysis.Editor.UnitTests.Extensions; using Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces; diff --git a/src/EditorFeatures/CSharpTest/ExtractMethod/MiscTests.cs b/src/EditorFeatures/CSharpTest/ExtractMethod/MiscTests.cs index afcab6bd65fad..d8dbf2726b014 100644 --- a/src/EditorFeatures/CSharpTest/ExtractMethod/MiscTests.cs +++ b/src/EditorFeatures/CSharpTest/ExtractMethod/MiscTests.cs @@ -7,7 +7,6 @@ using System.Linq; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.ExtractMethod; -using Microsoft.CodeAnalysis.Editor.CSharp.ExtractMethod; using Microsoft.CodeAnalysis.Editor.UnitTests; using Microsoft.CodeAnalysis.Editor.UnitTests.Extensions; using Microsoft.CodeAnalysis.Editor.UnitTests.Utilities; diff --git a/src/EditorFeatures/CSharpTest/Formatting/CSharpNewDocumentFormattingServiceTests.cs b/src/EditorFeatures/CSharpTest/Formatting/CSharpNewDocumentFormattingServiceTests.cs index 7db1a4fe72cec..f6110306f8a22 100644 --- a/src/EditorFeatures/CSharpTest/Formatting/CSharpNewDocumentFormattingServiceTests.cs +++ b/src/EditorFeatures/CSharpTest/Formatting/CSharpNewDocumentFormattingServiceTests.cs @@ -36,8 +36,7 @@ namespace Goo; internal class C { -} -", +}", options: new[] { (CSharpCodeStyleOptions.NamespaceDeclarations, new CodeStyleOption2(NamespaceDeclarationPreference.FileScoped, NotificationOption2.Error)) @@ -188,8 +187,7 @@ class C namespace Goo; internal class C { -} -", +}", options: new (OptionKey, object)[] { (new OptionKey(CSharpCodeStyleOptions.NamespaceDeclarations), new CodeStyleOption2(NamespaceDeclarationPreference.FileScoped, NotificationOption2.Error)), diff --git a/src/EditorFeatures/CSharpTest/Formatting/CodeCleanupTests.cs b/src/EditorFeatures/CSharpTest/Formatting/CodeCleanupTests.cs index 5fb6fb0351e9b..d13b03d827391 100644 --- a/src/EditorFeatures/CSharpTest/Formatting/CodeCleanupTests.cs +++ b/src/EditorFeatures/CSharpTest/Formatting/CodeCleanupTests.cs @@ -5,6 +5,7 @@ #nullable disable using System.Linq; +using System.Reflection; using System.Threading; using System.Threading.Tasks; using Microsoft.CodeAnalysis.AddImport; @@ -81,7 +82,7 @@ internal class Program { private static void Main(string[] args) { - List list = new List(); + List list = new(); Console.WriteLine(list.Count); } } @@ -104,6 +105,7 @@ static async Task Main(string[] args) Barrier b = new Barrier(0); var list = new List(); Console.WriteLine(list.Count); + b.Dispose(); } } "; @@ -117,9 +119,10 @@ internal class Program { private static async Task Main(string[] args) { - Barrier b = new Barrier(0); - List list = new List(); + Barrier b = new(0); + List list = new(); Console.WriteLine(list.Count); + b.Dispose(); } } "; @@ -159,7 +162,7 @@ private static void Main(string[] args) { Console.WriteLine(""Hello World!""); - new Goo(); + _ = new Goo(); } } @@ -204,7 +207,7 @@ private static void Main(string[] args) { Console.WriteLine(""Hello World!""); - new Goo(); + _ = new Goo(); } } @@ -222,23 +225,27 @@ public Task FixAddRemoveBraces() { var code = @"class Program { - void Method() + int Method() { int a = 0; if (a > 0) a ++; + + return a; } } "; var expected = @"internal class Program { - private void Method() + private int Method() { int a = 0; if (a > 0) { a++; } + + return a; } } "; @@ -421,6 +428,7 @@ private void Method() { Console.WriteLine(); List list = new List(); + Console.WriteLine(list.Length); } } } @@ -436,7 +444,8 @@ internal class Program private void Method() { Console.WriteLine(); - List list = new List(); + List list = new(); + Console.WriteLine(list.Length); } } } @@ -460,7 +469,8 @@ internal class Program private void Method() { Console.WriteLine(); - List list = new List(); + List list = new(); + Console.WriteLine(list.Length); } } } @@ -477,7 +487,8 @@ internal class Program private void Method() { Console.WriteLine(); - List list = new List(); + List list = new(); + Console.WriteLine(list.Length); } } } @@ -501,7 +512,8 @@ internal class Program private void Method() { Console.WriteLine(); - List list = new List(); + List list = new(); + Console.WriteLine(list.Length); } } } @@ -527,7 +539,8 @@ internal class Program private void Method() { Console.WriteLine(); - List list = new List(); + List list = new(); + Console.WriteLine(list.Length); } } } @@ -538,6 +551,51 @@ private void Method() return AssertCodeCleanupResult(expected, code, OutsidePreferPreservationOption); } + [Theory] + [Trait(Traits.Feature, Traits.Features.CodeCleanup)] + [InlineData(LanguageNames.CSharp, 32)] + [InlineData(LanguageNames.VisualBasic, 67)] + public void VerifyAllVisualBasicCodeStyleFixersAreSupportedByCodeCleanup(string language, int expectedNumberOfUnsupportedDiagnosticIds) + { + var supportedDiagnostics = GetSupportedDiagnosticIdsForCodeCleanupService(language); + + // No Duplicates + Assert.Equal(supportedDiagnostics, supportedDiagnostics.Distinct()); + + // Exact Number of Unsupported Diagnostic Ids + var ideDiagnosticIds = typeof(IDEDiagnosticIds).GetFields().Select(f => f.GetValue(f) as string).ToArray(); + var unsupportedDiagnosticIds = ideDiagnosticIds.Except(supportedDiagnostics).ToArray(); + Assert.Equal(expectedNumberOfUnsupportedDiagnosticIds, unsupportedDiagnosticIds.Length); + } + + private static string[] GetSupportedDiagnosticIdsForCodeCleanupService(string language) + { + using var workspace = GetTestWorkspaceForLanguage(language); + var hostdoc = workspace.Documents.Single(); + var document = workspace.CurrentSolution.GetDocument(hostdoc.Id); + + var codeCleanupService = document.GetLanguageService(); + + var enabledDiagnostics = codeCleanupService.GetAllDiagnostics(); + var supportedDiagnostics = enabledDiagnostics.Diagnostics.SelectMany(x => x.DiagnosticIds).ToArray(); + return supportedDiagnostics; + + TestWorkspace GetTestWorkspaceForLanguage(string language) + { + if (language == LanguageNames.CSharp) + { + return TestWorkspace.CreateCSharp(string.Empty, composition: EditorTestCompositions.EditorFeaturesWpf); + } + + if (language == LanguageNames.VisualBasic) + { + return TestWorkspace.CreateVisualBasic(string.Empty, composition: EditorTestCompositions.EditorFeaturesWpf); + } + + return null; + } + } + /// /// Assert the expected code value equals the actual processed input . /// diff --git a/src/EditorFeatures/CSharpTest/Formatting/FormattingEngineTests.cs b/src/EditorFeatures/CSharpTest/Formatting/FormattingEngineTests.cs index 1808b63078880..65149d894dba2 100644 --- a/src/EditorFeatures/CSharpTest/Formatting/FormattingEngineTests.cs +++ b/src/EditorFeatures/CSharpTest/Formatting/FormattingEngineTests.cs @@ -4,17 +4,15 @@ #nullable disable +using System; using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; -using Microsoft.CodeAnalysis.BraceCompletion; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Formatting; using Microsoft.CodeAnalysis.CSharp.Test.Utilities; -using Microsoft.CodeAnalysis.Diagnostics; using Microsoft.CodeAnalysis.Editing; -using Microsoft.CodeAnalysis.Editor.Implementation.Formatting; using Microsoft.CodeAnalysis.Editor.UnitTests.Utilities; using Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces; using Microsoft.CodeAnalysis.Formatting; @@ -27,6 +25,7 @@ namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Formatting { + [Trait(Traits.Feature, Traits.Features.Formatting)] public class FormattingEngineTests : CSharpFormattingEngineTestBase { public FormattingEngineTests(ITestOutputHelper output) : base(output) { } @@ -43,7 +42,6 @@ private static Dictionary SmartIndentButDoNotFormatWhileTypi [WpfFact] [WorkItem(539682, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/539682")] - [Trait(Traits.Feature, Traits.Features.Formatting)] public void FormatDocumentCommandHandler() { var code = @"class Program @@ -71,7 +69,6 @@ static void Main(string[] args) [WpfFact] [WorkItem(539682, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/539682")] - [Trait(Traits.Feature, Traits.Features.Formatting)] public void FormatDocumentPasteCommandHandler() { var code = @"class Program @@ -99,7 +96,6 @@ static void Main(string[] args) [WpfFact] [WorkItem(547261, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/547261")] - [Trait(Traits.Feature, Traits.Features.Formatting)] public void FormatDocumentReadOnlyWorkspacePasteCommandHandler() { var code = @"class Program @@ -127,7 +123,6 @@ static void Main(string[] args) [WpfFact] [WorkItem(912965, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/912965")] - [Trait(Traits.Feature, Traits.Features.Formatting)] public void DoNotFormatUsingStatementOnReturn() { var code = @"class Program @@ -155,7 +150,6 @@ static void Main(string[] args) [WpfFact] [WorkItem(912965, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/912965")] - [Trait(Traits.Feature, Traits.Features.Formatting)] public void FormatUsingStatementWhenTypingCloseParen() { var code = @"class Program @@ -183,7 +177,6 @@ static void Main(string[] args) [WpfFact] [WorkItem(912965, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/912965")] - [Trait(Traits.Feature, Traits.Features.Formatting)] public void FormatNotUsingStatementOnReturn() { var code = @"class Program @@ -210,7 +203,7 @@ static void Main(string[] args) } [WorkItem(977133, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/977133")] - [WpfFact, Trait(Traits.Feature, Traits.Features.Formatting)] + [WpfFact] public void DoNotFormatRangeOrFormatTokenOnOpenBraceOnSameLine() { var code = @"class C @@ -231,7 +224,7 @@ public void M() } [WorkItem(14491, "https://github.com/dotnet/roslyn/pull/14491")] - [WpfFact, Trait(Traits.Feature, Traits.Features.Formatting)] + [WpfFact] public void DoNotFormatRangeButFormatTokenOnOpenBraceOnNextLine() { var code = @"class C @@ -254,7 +247,7 @@ public void M() } [WorkItem(1007071, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1007071")] - [WpfFact, Trait(Traits.Feature, Traits.Features.Formatting)] + [WpfFact] public void FormatPragmaWarningInbetweenDelegateDeclarationStatement() { var code = @"using System; @@ -287,7 +280,7 @@ static void Main(string[] args) } [WorkItem(771761, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/771761")] - [WpfFact, Trait(Traits.Feature, Traits.Features.Formatting)] + [WpfFact] public void FormatHashRegion() { var code = @"using System; @@ -312,7 +305,7 @@ static void Main(string[] args) } [WorkItem(771761, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/771761")] - [WpfFact, Trait(Traits.Feature, Traits.Features.Formatting)] + [WpfFact] public void FormatHashEndRegion() { var code = @"using System; @@ -339,7 +332,7 @@ static void Main(string[] args) } [WorkItem(987373, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/987373")] - [WpfFact, Trait(Traits.Feature, Traits.Features.Formatting)] + [WpfFact] public async Task FormatSpansIndividuallyWithoutCollapsing() { var code = @"class C @@ -432,7 +425,7 @@ public void M() } [WorkItem(1044118, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1044118")] - [WpfFact, Trait(Traits.Feature, Traits.Features.Formatting)] + [WpfFact] public void SemicolonInCommentOnLastLineDoesNotFormat() { var code = @"using System; @@ -459,7 +452,7 @@ static void Main(string[] args) [WorkItem(449, "https://github.com/dotnet/roslyn/issues/449")] [WorkItem(1077103, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1077103")] - [WpfFact, Trait(Traits.Feature, Traits.Features.Formatting)] + [WpfFact] public void NoFormattingInsideSingleLineRegularComment_1() { var code = @"class Program @@ -484,7 +477,7 @@ static void Main(int a, int b) [WorkItem(449, "https://github.com/dotnet/roslyn/issues/449")] [WorkItem(1077103, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1077103")] - [WpfFact, Trait(Traits.Feature, Traits.Features.Formatting)] + [WpfFact] public void NoFormattingInsideSingleLineRegularComment_2() { var code = @"class Program @@ -509,7 +502,7 @@ static void Main(int a, int b) [WorkItem(449, "https://github.com/dotnet/roslyn/issues/449")] [WorkItem(1077103, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1077103")] - [WpfFact, Trait(Traits.Feature, Traits.Features.Formatting)] + [WpfFact] public void NoFormattingInsideMultiLineRegularComment_1() { var code = @"class Program @@ -532,7 +525,7 @@ static void Main(int a/* { */, int b) [WorkItem(449, "https://github.com/dotnet/roslyn/issues/449")] [WorkItem(1077103, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1077103")] - [WpfFact, Trait(Traits.Feature, Traits.Features.Formatting)] + [WpfFact] public void NoFormattingInsideMultiLineRegularComment_2() { var code = @"class Program @@ -557,7 +550,7 @@ static void Main(int a/* { [WorkItem(449, "https://github.com/dotnet/roslyn/issues/449")] [WorkItem(1077103, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1077103")] - [WpfFact, Trait(Traits.Feature, Traits.Features.Formatting)] + [WpfFact] public void NoFormattingInsideMultiLineRegularComment_3() { var code = @"class Program @@ -582,7 +575,7 @@ static void Main(int a/* { [WorkItem(449, "https://github.com/dotnet/roslyn/issues/449")] [WorkItem(1077103, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1077103")] - [WpfFact, Trait(Traits.Feature, Traits.Features.Formatting)] + [WpfFact] public void NoFormattingInsideSingleLineDocComment_1() { var code = @"class Program @@ -607,7 +600,7 @@ static void Main(int a, int b) [WorkItem(449, "https://github.com/dotnet/roslyn/issues/449")] [WorkItem(1077103, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1077103")] - [WpfFact, Trait(Traits.Feature, Traits.Features.Formatting)] + [WpfFact] public void NoFormattingInsideSingleLineDocComment_2() { var code = @"class Program @@ -632,7 +625,7 @@ static void Main(int a, int b) [WorkItem(449, "https://github.com/dotnet/roslyn/issues/449")] [WorkItem(1077103, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1077103")] - [WpfFact, Trait(Traits.Feature, Traits.Features.Formatting)] + [WpfFact] public void NoFormattingInsideMultiLineDocComment_1() { var code = @"class Program @@ -657,7 +650,7 @@ static void Main(int a, int b) [WorkItem(449, "https://github.com/dotnet/roslyn/issues/449")] [WorkItem(1077103, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1077103")] - [WpfFact, Trait(Traits.Feature, Traits.Features.Formatting)] + [WpfFact] public void NoFormattingInsideMultiLineDocComment_2() { var code = @"class Program @@ -684,7 +677,7 @@ static void Main(int a, int b) [WorkItem(449, "https://github.com/dotnet/roslyn/issues/449")] [WorkItem(1077103, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1077103")] - [WpfFact, Trait(Traits.Feature, Traits.Features.Formatting)] + [WpfFact] public void NoFormattingInsideMultiLineDocComment_3() { var code = @"class Program @@ -711,7 +704,7 @@ static void Main(int a, int b) [WorkItem(449, "https://github.com/dotnet/roslyn/issues/449")] [WorkItem(1077103, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1077103")] - [WpfFact, Trait(Traits.Feature, Traits.Features.Formatting)] + [WpfFact] public void NoFormattingInsideInactiveCode() { var code = @"class Program @@ -742,7 +735,7 @@ static void Main(string[] args) [WorkItem(449, "https://github.com/dotnet/roslyn/issues/449")] [WorkItem(1077103, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1077103")] - [WpfFact, Trait(Traits.Feature, Traits.Features.Formatting)] + [WpfFact] public void NoFormattingInsideStringLiteral() { var code = @"class Program @@ -765,7 +758,7 @@ static void Main(string[] args) [WorkItem(449, "https://github.com/dotnet/roslyn/issues/449")] [WorkItem(1077103, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1077103")] - [WpfFact, Trait(Traits.Feature, Traits.Features.Formatting)] + [WpfFact] public void NoFormattingInsideCharLiteral() { var code = @"class Program @@ -788,7 +781,7 @@ static void Main(string[] args) [WorkItem(449, "https://github.com/dotnet/roslyn/issues/449")] [WorkItem(1077103, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1077103")] - [WpfFact, Trait(Traits.Feature, Traits.Features.Formatting)] + [WpfFact] public void NoFormattingInsideCommentsOfPreprocessorDirectives() { var code = @"class Program @@ -815,7 +808,7 @@ static void Main(string[] args) [WorkItem(464, "https://github.com/dotnet/roslyn/issues/464")] [WorkItem(908729, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/908729")] - [WpfFact, Trait(Traits.Feature, Traits.Features.Formatting)] + [WpfFact] public void ColonInSwitchCase() { var code = @"class Program @@ -846,7 +839,7 @@ static void Main(string[] args) [WorkItem(464, "https://github.com/dotnet/roslyn/issues/464")] [WorkItem(908729, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/908729")] - [WpfFact, Trait(Traits.Feature, Traits.Features.Formatting)] + [WpfFact] public void ColonInDefaultSwitchCase() { var code = @"class Program @@ -878,7 +871,7 @@ static void Main(string[] args) } [WorkItem(9097, "https://github.com/dotnet/roslyn/issues/9097")] - [WpfFact, Trait(Traits.Feature, Traits.Features.Formatting)] + [WpfFact] public void ColonInPatternSwitchCase01() { var code = @"class Program @@ -907,7 +900,7 @@ static void Main() [WorkItem(464, "https://github.com/dotnet/roslyn/issues/464")] [WorkItem(908729, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/908729")] - [WpfFact, Trait(Traits.Feature, Traits.Features.Formatting)] + [WpfFact] public void ColonInLabeledStatement() { var code = @"class Program @@ -930,7 +923,7 @@ static void Main(string[] args) [WorkItem(464, "https://github.com/dotnet/roslyn/issues/464")] [WorkItem(908729, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/908729")] - [WpfFact, Trait(Traits.Feature, Traits.Features.Formatting)] + [WpfFact] public void DoNotFormatColonInTargetAttribute() { var code = @"using System; @@ -949,7 +942,7 @@ class C : Attribute [WorkItem(464, "https://github.com/dotnet/roslyn/issues/464")] [WorkItem(908729, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/908729")] - [WpfFact, Trait(Traits.Feature, Traits.Features.Formatting)] + [WpfFact] public void DoNotFormatColonInBaseList() { var code = @"class C :$$ Attribute @@ -964,7 +957,7 @@ public void DoNotFormatColonInBaseList() [WorkItem(464, "https://github.com/dotnet/roslyn/issues/464")] [WorkItem(908729, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/908729")] - [WpfFact, Trait(Traits.Feature, Traits.Features.Formatting)] + [WpfFact] public void DoNotFormatColonInThisConstructor() { var code = @"class Goo @@ -993,7 +986,7 @@ public void DoNotFormatColonInThisConstructor() [WorkItem(464, "https://github.com/dotnet/roslyn/issues/464")] [WorkItem(908729, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/908729")] - [WpfFact, Trait(Traits.Feature, Traits.Features.Formatting)] + [WpfFact] public void DoNotFormatColonInConditionalOperator() { var code = @"class Program @@ -1016,7 +1009,7 @@ static void Main(string[] args) [WorkItem(464, "https://github.com/dotnet/roslyn/issues/464")] [WorkItem(908729, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/908729")] - [WpfFact, Trait(Traits.Feature, Traits.Features.Formatting)] + [WpfFact] public void DoNotFormatColonInArgument() { var code = @"class Program @@ -1039,7 +1032,7 @@ static void Main(string[] args) [WorkItem(464, "https://github.com/dotnet/roslyn/issues/464")] [WorkItem(908729, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/908729")] - [WpfFact, Trait(Traits.Feature, Traits.Features.Formatting)] + [WpfFact] public void DoNotFormatColonInTypeParameter() { var code = @"class Program @@ -1063,7 +1056,7 @@ class C1 } [WorkItem(2224, "https://github.com/dotnet/roslyn/issues/2224")] - [WpfFact, Trait(Traits.Feature, Traits.Features.Formatting)] + [WpfFact] public void DontSmartFormatBracesOnSmartIndentNone() { var code = @"class Program @@ -1318,7 +1311,7 @@ public int P AssertFormatAfterTypeChar(code, expected); } - [WpfFact, Trait(Traits.Feature, Traits.Features.Formatting)] + [WpfFact] public void DoNotFormatIncompleteBlockOnSingleLineIfNotTypingCloseCurly1() { var code = @"namespace ConsoleApplication1 @@ -1342,7 +1335,7 @@ static bool Property AssertFormatAfterTypeChar(code, expected); } - [WpfFact, Trait(Traits.Feature, Traits.Features.Formatting)] + [WpfFact] public void DoNotFormatIncompleteBlockOnSingleLineIfNotTypingCloseCurly2() { var code = @"namespace ConsoleApplication1 @@ -1362,7 +1355,7 @@ class Program AssertFormatAfterTypeChar(code, expected); } - [WpfFact, Trait(Traits.Feature, Traits.Features.Formatting)] + [WpfFact] public void DoNotFormatIncompleteBlockOnSingleLineIfNotTypingCloseCurly3() { var code = @"namespace ConsoleApplication1 @@ -1382,7 +1375,7 @@ class Program AssertFormatAfterTypeChar(code, expected); } - [WpfFact, Trait(Traits.Feature, Traits.Features.Formatting)] + [WpfFact] public void DoNotFormatCompleteBlockOnSingleLineIfTypingCloseCurly1() { var code = @"namespace ConsoleApplication1 @@ -1404,7 +1397,7 @@ static bool Property AssertFormatAfterTypeChar(code, expected); } - [WpfFact, Trait(Traits.Feature, Traits.Features.Formatting)] + [WpfFact] public void DoNotFormatCompleteBlockOnSingleLineIfTypingCloseCurly2() { var code = @"namespace ConsoleApplication1 @@ -1422,7 +1415,7 @@ class Program AssertFormatAfterTypeChar(code, expected); } - [WpfFact, Trait(Traits.Feature, Traits.Features.Formatting)] + [WpfFact] public void FormatIncompleteBlockOnMultipleLinesIfTypingCloseCurly1() { var code = @"namespace ConsoleApplication1 @@ -1448,7 +1441,7 @@ static bool Property AssertFormatAfterTypeChar(code, expected); } - [WpfFact, Trait(Traits.Feature, Traits.Features.Formatting)] + [WpfFact] public void FormatIncompleteBlockOnMultipleLinesIfTypingCloseCurly2() { var code = @"namespace ConsoleApplication1 @@ -1474,7 +1467,7 @@ static bool Property AssertFormatAfterTypeChar(code, expected); } - [WpfFact, Trait(Traits.Feature, Traits.Features.Formatting)] + [WpfFact] public void DoNotFormatCompleteBlockOnSingleLineIfTypingSemicolon() { var code = @@ -1500,7 +1493,7 @@ void M() AssertFormatAfterTypeChar(code, expected); } - [WpfFact, Trait(Traits.Feature, Traits.Features.Formatting)] + [WpfFact] public void FormatCompleteBlockOnSingleLineIfTypingCloseCurlyOnLaterLine() { var code = @@ -1531,7 +1524,7 @@ void M() } [WorkItem(7900, "https://github.com/dotnet/roslyn/issues/7900")] - [WpfFact, Trait(Traits.Feature, Traits.Features.Formatting)] + [WpfFact] public void FormatLockStatementWithEmbeddedStatementOnSemicolonDifferentLine() { var code = @"class C @@ -1556,7 +1549,7 @@ public void M() } [WorkItem(7900, "https://github.com/dotnet/roslyn/issues/7900")] - [WpfFact, Trait(Traits.Feature, Traits.Features.Formatting)] + [WpfFact] public void FormatLockStatementWithEmbeddedStatementOnSemicolonSameLine() { var code = @"class C @@ -1579,7 +1572,7 @@ public void M() } [WorkItem(11642, "https://github.com/dotnet/roslyn/issues/11642")] - [WpfFact, Trait(Traits.Feature, Traits.Features.Formatting)] + [WpfFact] public void FormatArbitraryNodeParenthesizedLambdaExpression() { // code equivalent to an expression synthesized like so: @@ -1590,8 +1583,75 @@ public void FormatArbitraryNodeParenthesizedLambdaExpression() AssertFormatOnArbitraryNode(node, expected); } + [WpfFact] + [WorkItem(57465, "https://github.com/dotnet/roslyn/issues/57465")] + public async Task FormatLambdaWithDirective() + { + var code = @"namespace N +{ + public class C + { + protected void Render() + { + if (outer) + { + M(() => + { +#nullable enable + if (inner) + { + } + } + ); + } + } + } +} +"; + var expected = @"namespace N +{ + public class C + { + protected void Render() + { + if (outer) + { + M(() => + { +#nullable enable + if (inner) + { + } + } + ); + } + } + } +} +"; + + await AssertFormatAsync(expected, code, spans: null); + } + + [WpfTheory] + [CombinatorialData] + [WorkItem(59637, "https://github.com/dotnet/roslyn/issues/59637")] + public async Task FormatAttributeAtEndOfFile(bool trailingNewLine) + { + var endOfFile = trailingNewLine ? Environment.NewLine : ""; + var code = $@"using System.Diagnostics.CodeAnalysis; + +[assembly:SuppressMessage(""Globalization"", ""CA1308: Normalize strings to uppercase"", Justification = ""My reason"", Scope = ""member"", Target = ""~M:Method"") ] {endOfFile}"; + var expected = $@"using System.Diagnostics.CodeAnalysis; + +[assembly: SuppressMessage(""Globalization"", ""CA1308: Normalize strings to uppercase"", Justification = ""My reason"", Scope = ""member"", Target = ""~M:Method"")]{endOfFile}"; + + await AssertFormatAsync(expected, code, spans: null); + await AssertFormatAsync(expected, expected, spans: null); + } + [WorkItem(30787, "https://github.com/dotnet/roslyn/issues/30787")] - [WpfFact, Trait(Traits.Feature, Traits.Features.Formatting)] + [WpfFact] public void DoSmartIndentOpenBraceEvenWithFormatWhileTypingOff1() { var code = @@ -1618,7 +1678,7 @@ void M() } [WorkItem(30787, "https://github.com/dotnet/roslyn/issues/30787")] - [WpfFact, Trait(Traits.Feature, Traits.Features.Formatting)] + [WpfFact] public void DoSmartIndentOpenBraceEvenWithFormatWhileTypingOff2() { var code = @@ -1645,7 +1705,7 @@ void M() } [WorkItem(30787, "https://github.com/dotnet/roslyn/issues/30787")] - [WpfFact, Trait(Traits.Feature, Traits.Features.Formatting)] + [WpfFact] public void DoSmartIndentOpenBraceEvenWithFormatWhileTypingOff3() { // We only smart indent the { if it's on it's own line. @@ -1671,7 +1731,7 @@ void M() } [WorkItem(30787, "https://github.com/dotnet/roslyn/issues/30787")] - [WpfFact, Trait(Traits.Feature, Traits.Features.Formatting)] + [WpfFact] public void DoSmartIndentOpenBraceEvenWithFormatWhileTypingOff4() { // We only smart indent the { if it's on it's own line. @@ -1697,7 +1757,7 @@ void M() } [WorkItem(30787, "https://github.com/dotnet/roslyn/issues/30787")] - [WpfFact, Trait(Traits.Feature, Traits.Features.Formatting)] + [WpfFact] public void DoSmartIndentOpenBraceEvenWithFormatWhileTypingOff5() { // Typing the { should not affect the formating of the preceding tokens. @@ -1725,7 +1785,7 @@ void M() } [WorkItem(30787, "https://github.com/dotnet/roslyn/issues/30787")] - [WpfFact, Trait(Traits.Feature, Traits.Features.Formatting)] + [WpfFact] public void DoSmartIndentOpenBraceEvenWithFormatWhileTypingOff6() { // Typing the { should not affect the formating of the preceding tokens. @@ -1751,7 +1811,7 @@ void M() } [WorkItem(30787, "https://github.com/dotnet/roslyn/issues/30787")] - [WpfFact, Trait(Traits.Feature, Traits.Features.Formatting)] + [WpfFact] public void DoSmartIndentOpenBraceEvenWithFormatWhileTypingOff7() { var code = @@ -1772,7 +1832,7 @@ void M() } [WorkItem(30787, "https://github.com/dotnet/roslyn/issues/30787")] - [WpfFact, Trait(Traits.Feature, Traits.Features.Formatting)] + [WpfFact] public void DoSmartIndentCloseBraceEvenWithFormatWhileTypingOff1() { var code = @@ -1801,7 +1861,7 @@ void M() } [WorkItem(30787, "https://github.com/dotnet/roslyn/issues/30787")] - [WpfFact, Trait(Traits.Feature, Traits.Features.Formatting)] + [WpfFact] public void DoSmartIndentCloseBraceEvenWithFormatWhileTypingOff2() { // Note that the { is not updated since we are not formatting. @@ -1829,7 +1889,7 @@ void M() } [WorkItem(30787, "https://github.com/dotnet/roslyn/issues/30787")] - [WpfFact, Trait(Traits.Feature, Traits.Features.Formatting)] + [WpfFact] public void DoSmartIndentCloseBraceEvenWithFormatWhileTypingOff3() { var code = @@ -1852,7 +1912,7 @@ void M() } [WorkItem(30787, "https://github.com/dotnet/roslyn/issues/30787")] - [WpfFact, Trait(Traits.Feature, Traits.Features.Formatting)] + [WpfFact] public void DoSmartIndentCloseBraceEvenWithFormatWhileTypingOff4() { // Should not affect formatting of open brace @@ -1874,7 +1934,6 @@ void M() { } [WpfFact] - [Trait(Traits.Feature, Traits.Features.Formatting)] [WorkItem(31907, "https://github.com/dotnet/roslyn/issues/31907")] public async Task NullableReferenceTypes() { @@ -1901,7 +1960,7 @@ void MyMethod() } [WorkItem(30518, "https://github.com/dotnet/roslyn/issues/30518")] - [WpfFact, Trait(Traits.Feature, Traits.Features.Formatting)] + [WpfFact] public void FormatGeneratedNodeInInitializer() { var code = @"new bool[] { @@ -1923,7 +1982,6 @@ public void FormatGeneratedNodeInInitializer() } [WpfFact] - [Trait(Traits.Feature, Traits.Features.Formatting)] [WorkItem(27268, "https://github.com/dotnet/roslyn/issues/27268")] public async Task PositionalPattern() { @@ -1958,7 +2016,6 @@ void MyMethod() } [WpfFact] - [Trait(Traits.Feature, Traits.Features.Formatting)] public async Task WithExpression() { var code = @"[| @@ -1984,7 +2041,6 @@ void M() } [WpfFact] - [Trait(Traits.Feature, Traits.Features.Formatting)] public async Task WithExpression_MultiLine() { var code = @"[| @@ -2018,7 +2074,6 @@ void M() } [WpfFact] - [Trait(Traits.Feature, Traits.Features.Formatting)] public async Task WithExpression_MultiLine_UserPositionedBraces() { var code = @"[| @@ -2052,7 +2107,7 @@ void M() } [WorkItem(25003, "https://github.com/dotnet/roslyn/issues/25003")] - [WpfFact, Trait(Traits.Feature, Traits.Features.Formatting)] + [WpfFact] public void SeparateGroups_KeepMultipleLinesBetweenGroups() { var code = @"$$ @@ -2077,7 +2132,7 @@ public void SeparateGroups_KeepMultipleLinesBetweenGroups() } [WorkItem(25003, "https://github.com/dotnet/roslyn/issues/25003")] - [WpfFact, Trait(Traits.Feature, Traits.Features.Formatting)] + [WpfFact] public void SeparateGroups_KeepMultipleLinesBetweenGroups_FileScopedNamespace() { var code = @"$$ @@ -2106,7 +2161,7 @@ namespace N; } [WorkItem(25003, "https://github.com/dotnet/roslyn/issues/25003")] - [WpfFact, Trait(Traits.Feature, Traits.Features.Formatting)] + [WpfFact] public void SeparateGroups_DoNotGroupIfNotSorted() { var code = @"$$ @@ -2127,7 +2182,7 @@ public void SeparateGroups_DoNotGroupIfNotSorted() } [WorkItem(25003, "https://github.com/dotnet/roslyn/issues/25003")] - [WpfFact, Trait(Traits.Feature, Traits.Features.Formatting)] + [WpfFact] public void SeparateGroups_GroupIfSorted() { var code = @"$$ @@ -2149,7 +2204,7 @@ public void SeparateGroups_GroupIfSorted() } [WorkItem(25003, "https://github.com/dotnet/roslyn/issues/25003")] - [WpfFact, Trait(Traits.Feature, Traits.Features.Formatting)] + [WpfFact] public void SeparateGroups_GroupIfSorted_RecognizeSystemNotFirst() { var code = @"$$ @@ -2170,6 +2225,38 @@ public void SeparateGroups_GroupIfSorted_RecognizeSystemNotFirst() AssertFormatWithView(expected, code, (GenerationOptions.SeparateImportDirectiveGroups, true)); } + [WpfFact] + [WorkItem(58157, "https://github.com/dotnet/roslyn/issues/58157")] + [Trait(Traits.Feature, Traits.Features.Formatting)] + public void FormatImplicitObjectCollection() + { + var code = @"class Program +{ + static void Main(string[] args) + { + $$List list = new() + { + 1, 2, 3, 4, + }; + } +} +"; + + var expected = @"class Program +{ + static void Main(string[] args) + { + $$List list = new() + { + 1, 2, 3, 4, + }; + } +} +"; + + AssertFormatWithView(expected, code); + } + [Fact, WorkItem(49492, "https://github.com/dotnet/roslyn/issues/49492")] public void PreserveAnnotationsOnMultiLineTrivia() { @@ -2224,7 +2311,7 @@ private static void AssertFormatAfterTypeChar(string code, string expected, Dict var newSnapshot = subjectDocument.GetTextBuffer().CurrentSnapshot; - Assert.Equal(expected, newSnapshot.GetText()); + AssertEx.EqualOrDiff(expected, newSnapshot.GetText()); } } } diff --git a/src/EditorFeatures/CSharpTest/Formatting/Indentation/SmartIndenterEnterOnTokenTests.cs b/src/EditorFeatures/CSharpTest/Formatting/Indentation/SmartIndenterEnterOnTokenTests.cs index c2479a5ff807f..f8d087ef82fef 100644 --- a/src/EditorFeatures/CSharpTest/Formatting/Indentation/SmartIndenterEnterOnTokenTests.cs +++ b/src/EditorFeatures/CSharpTest/Formatting/Indentation/SmartIndenterEnterOnTokenTests.cs @@ -1369,12 +1369,10 @@ void Main(object o) ] } }"; - // Expected indentation probably should be 12 instead - // Tracked by https://github.com/dotnet/roslyn/issues/57244 await AssertIndentNotUsingSmartTokenFormatterButUsingIndenterAsync( code, indentationLine: 7, - expectedIndentation: 8); + expectedIndentation: 12); } [Trait(Traits.Feature, Traits.Features.SmartIndent)] diff --git a/src/EditorFeatures/CSharpTest/Formatting/Indentation/SmartTokenFormatterFormatRangeTests.cs b/src/EditorFeatures/CSharpTest/Formatting/Indentation/SmartTokenFormatterFormatRangeTests.cs index 06aaee0c2cf8d..3f5ef74ec4eaf 100644 --- a/src/EditorFeatures/CSharpTest/Formatting/Indentation/SmartTokenFormatterFormatRangeTests.cs +++ b/src/EditorFeatures/CSharpTest/Formatting/Indentation/SmartTokenFormatterFormatRangeTests.cs @@ -13,7 +13,6 @@ using Microsoft.CodeAnalysis.CSharp.Indentation; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.CSharp.Utilities; -using Microsoft.CodeAnalysis.Editor.Implementation.Formatting; using Microsoft.CodeAnalysis.Editor.UnitTests.Utilities; using Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces; using Microsoft.CodeAnalysis.Formatting; diff --git a/src/EditorFeatures/CSharpTest/GenerateConstructor/GenerateConstructorTests.cs b/src/EditorFeatures/CSharpTest/GenerateConstructor/GenerateConstructorTests.cs index 064307be06e10..00e087e404775 100644 --- a/src/EditorFeatures/CSharpTest/GenerateConstructor/GenerateConstructorTests.cs +++ b/src/EditorFeatures/CSharpTest/GenerateConstructor/GenerateConstructorTests.cs @@ -2595,7 +2595,7 @@ enum A [AttributeUsage(AttributeTargets.Class)] class MyAttrAttribute : Attribute { - private int[] vs; + private int[] ints; private A a1; private bool v1; private byte v2; @@ -2607,9 +2607,9 @@ class MyAttrAttribute : Attribute private float v8; private string v9; - public MyAttrAttribute(int[] vs, A a1, bool v1, byte v2, char v3, short v4, int v5, long v6, double v7, float v8, string v9) + public MyAttrAttribute(int[] ints, A a1, bool v1, byte v2, char v3, short v4, int v5, long v6, double v7, float v8, string v9) { - this.vs = vs; + this.ints = ints; this.a1 = a1; this.v1 = v1; this.v2 = v2; @@ -2913,12 +2913,12 @@ void M() }", @"class C { - private (int, string) p; + private (int, string) value; private bool v; - public C((int, string) p, bool v) + public C((int, string) value, bool v) { - this.p = p; + this.value = value; this.v = v; } @@ -2942,11 +2942,11 @@ void M() }", @"class C { - private (int a, string b) p; + private (int a, string b) value; - public C((int a, string b) p) + public C((int a, string b) value) { - this.p = p; + this.value = value; } void M() @@ -2969,11 +2969,11 @@ void M() }", @"class C { - private (int a, string) p; + private (int a, string) value; - public C((int a, string) p) + public C((int a, string) value) { - this.p = p; + this.value = value; } void M() diff --git a/src/EditorFeatures/CSharpTest/GenerateFromMembers/AddConstructorParametersFromMembers/AddConstructorParametersFromMembersTests.cs b/src/EditorFeatures/CSharpTest/GenerateFromMembers/AddConstructorParametersFromMembers/AddConstructorParametersFromMembersTests.cs index d4a65a2d074dd..8bd5bac97f162 100644 --- a/src/EditorFeatures/CSharpTest/GenerateFromMembers/AddConstructorParametersFromMembers/AddConstructorParametersFromMembersTests.cs +++ b/src/EditorFeatures/CSharpTest/GenerateFromMembers/AddConstructorParametersFromMembers/AddConstructorParametersFromMembersTests.cs @@ -2,39 +2,59 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -#nullable disable - -using System.Collections.Immutable; using System.Threading.Tasks; using Microsoft.CodeAnalysis.AddConstructorParametersFromMembers; -using Microsoft.CodeAnalysis.CodeActions; -using Microsoft.CodeAnalysis.CodeRefactorings; using Microsoft.CodeAnalysis.CSharp; -using Microsoft.CodeAnalysis.CSharp.Test.Utilities; -using Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.CodeRefactorings; -using Microsoft.CodeAnalysis.Editor.UnitTests.Diagnostics.NamingStyles; using Microsoft.CodeAnalysis.Test.Utilities; using Roslyn.Test.Utilities; using Xunit; namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.GenerateFromMembers.AddConstructorParameters { - public class AddConstructorParametersFromMembersTests : AbstractCSharpCodeActionTest + using VerifyCS = Editor.UnitTests.CodeActions.CSharpCodeRefactoringVerifier; + + public class AddConstructorParametersFromMembersTests { - protected override CodeRefactoringProvider CreateCodeRefactoringProvider(Workspace workspace, TestParameters parameters) - => new AddConstructorParametersFromMembersCodeRefactoringProvider(); + private const string FieldNamesCamelCaseWithFieldUnderscorePrefixEditorConfig = @" +[*.cs] +dotnet_naming_style.field_camel_case.capitalization = camel_case +dotnet_naming_style.field_camel_case.required_prefix = field_ +dotnet_naming_symbols.fields.applicable_kinds = field +dotnet_naming_symbols.fields.applicable_accessibilities = * +dotnet_naming_rule.fields_should_be_camel_case.severity = error +dotnet_naming_rule.fields_should_be_camel_case.symbols = fields +dotnet_naming_rule.fields_should_be_camel_case.style = field_camel_case +"; - private readonly NamingStylesTestOptionSets options = new NamingStylesTestOptionSets(LanguageNames.CSharp); + private const string FieldNamesCamelCaseWithFieldUnderscorePrefixEndUnderscoreSuffixEditorConfig = + FieldNamesCamelCaseWithFieldUnderscorePrefixEditorConfig + @" +dotnet_naming_style.field_camel_case.required_suffix = _End +"; - protected override ImmutableArray MassageActions(ImmutableArray actions) - => FlattenActions(actions); + private const string ParameterNamesCamelCaseWithPUnderscorePrefixEditorConfig = @" +[*.cs] +dotnet_naming_style.p_camel_case.capitalization = camel_case +dotnet_naming_style.p_camel_case.required_prefix = p_ +dotnet_naming_symbols.parameters.applicable_kinds = parameter +dotnet_naming_symbols.parameters.applicable_accessibilities = * +dotnet_naming_rule.parameters_should_be_camel_case.severity = error +dotnet_naming_rule.parameters_should_be_camel_case.symbols = parameters +dotnet_naming_rule.parameters_should_be_camel_case.style = p_camel_case +"; + + private const string ParameterNamesCamelCaseWithPUnderscorePrefixEndUnderscoreSuffixEditorConfig = + ParameterNamesCamelCaseWithPUnderscorePrefixEditorConfig + @" +dotnet_naming_style.p_camel_case.required_suffix = _End +"; [WorkItem(308077, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/308077")] [WorkItem(33603, "https://github.com/dotnet/roslyn/issues/33603")] [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddConstructorParametersFromMembers)] public async Task TestAdd1() { - await TestInRegularAndScriptAsync( + await new VerifyCS.Test + { + TestCode = @"using System.Collections.Generic; class Program @@ -47,6 +67,7 @@ public Program(int i) this.i = i; } }", + FixedCode = @"using System.Collections.Generic; class Program @@ -59,7 +80,182 @@ public Program(int i, string s) this.i = i; this.s = s; } -}", title: string.Format(FeaturesResources.Add_parameters_to_0, "Program(int)")); +}", + CodeActionVerifier = (codeAction, verifier) => verifier.Equal(string.Format(FeaturesResources.Add_parameters_to_0, "Program(int)"), codeAction.Title) + }.RunAsync(); + } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddConstructorParametersFromMembers)] + [WorkItem(58040, "https://github.com/dotnet/roslyn/issues/58040")] + public async Task TestProperlyWrapParameters1() + { + await new VerifyCS.Test + { + TestCode = +@"using System.Collections.Generic; + +class Program +{ + [|int i; + string s;|] + + public Program( + int i) + { + this.i = i; + } +}", + FixedCode = +@"using System.Collections.Generic; + +class Program +{ + int i; + string s; + + public Program( + int i, string s) + { + this.i = i; + this.s = s; + } +}", + CodeActionVerifier = (codeAction, verifier) => verifier.Equal(string.Format(FeaturesResources.Add_parameters_to_0, "Program(int)"), codeAction.Title) + }.RunAsync(); + } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddConstructorParametersFromMembers)] + [WorkItem(58040, "https://github.com/dotnet/roslyn/issues/58040")] + public async Task TestProperlyWrapParameters2() + { + await new VerifyCS.Test + { + TestCode = +@"using System.Collections.Generic; + +class Program +{ + [|int i; + string s; + bool b;|] + + public Program( + int i, + string s) + { + this.i = i; + this.s = s; + } +}", + FixedCode = +@"using System.Collections.Generic; + +class Program +{ + int i; + string s; + bool b; + + public Program( + int i, + string s, + bool b) + { + this.i = i; + this.s = s; + this.b = b; + } +}", + CodeActionVerifier = (codeAction, verifier) => verifier.Equal(string.Format(FeaturesResources.Add_parameters_to_0, "Program(int, string)"), codeAction.Title) + }.RunAsync(); + } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddConstructorParametersFromMembers)] + [WorkItem(58040, "https://github.com/dotnet/roslyn/issues/58040")] + public async Task TestProperlyWrapParameters3() + { + await new VerifyCS.Test + { + TestCode = +@"using System.Collections.Generic; + +class Program +{ + [|int i; + string s; + bool b;|] + + public Program(int i, + string s) + { + this.i = i; + this.s = s; + } +}", + FixedCode = +@"using System.Collections.Generic; + +class Program +{ + int i; + string s; + bool b; + + public Program(int i, + string s, + bool b) + { + this.i = i; + this.s = s; + this.b = b; + } +}", + CodeActionVerifier = (codeAction, verifier) => verifier.Equal(string.Format(FeaturesResources.Add_parameters_to_0, "Program(int, string)"), codeAction.Title) + }.RunAsync(); + } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddConstructorParametersFromMembers)] + [WorkItem(58040, "https://github.com/dotnet/roslyn/issues/58040")] + public async Task TestProperlyWrapParameters4() + { + await new VerifyCS.Test + { + TestCode = +@"using System.Collections.Generic; + +class Program +{ + [|int i; + string s; + bool b;|] + + public Program(int i, + string s) + { + this.i = i; + this.s = s; + } +}", + FixedCode = +@"using System.Collections.Generic; + +class Program +{ + int i; + string s; + bool b; + + public Program(int i, + string s, + bool b) + { + this.i = i; + this.s = s; + this.b = b; + } +}", + CodeActionVerifier = (codeAction, verifier) => verifier.Equal(string.Format(FeaturesResources.Add_parameters_to_0, "Program(int, string)"), codeAction.Title) + }.RunAsync(); } [WorkItem(308077, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/308077")] @@ -67,7 +263,9 @@ public Program(int i, string s) [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddConstructorParametersFromMembers)] public async Task TestAddOptional1() { - await TestInRegularAndScriptAsync( + await new VerifyCS.Test() + { + TestCode = @"using System.Collections.Generic; class Program @@ -80,6 +278,7 @@ public Program(int i) this.i = i; } }", + FixedCode = @"using System.Collections.Generic; class Program @@ -92,7 +291,10 @@ public Program(int i, string s = null) this.i = i; this.s = s; } -}", index: 1, title: string.Format(FeaturesResources.Add_optional_parameters_to_0, "Program(int)")); +}", + CodeActionIndex = 1, + CodeActionVerifier = (codeAction, verifier) => verifier.Equal(string.Format(FeaturesResources.Add_optional_parameters_to_0, "Program(int)"), codeAction.Title) + }.RunAsync(); } [WorkItem(308077, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/308077")] @@ -101,7 +303,9 @@ public Program(int i, string s = null) public async Task TestAddToConstructorWithMostMatchingParameters1() { // behavior change with 33603, now all constructors offered - await TestInRegularAndScriptAsync( + await new VerifyCS.Test() + { + TestCode = @"using System.Collections.Generic; class Program @@ -120,6 +324,7 @@ public Program(int i, string s) : this(i) this.s = s; } }", + FixedCode = @"using System.Collections.Generic; class Program @@ -138,7 +343,10 @@ public Program(int i, string s, bool b) : this(i) this.s = s; this.b = b; } -}", index: 1, title: string.Format(FeaturesResources.Add_to_0, "Program(int, string)")); +}", + CodeActionIndex = 1, + CodeActionVerifier = (codeAction, verifier) => verifier.Equal(string.Format(FeaturesResources.Add_to_0, "Program(int, string)"), codeAction.Title) + }.RunAsync(); } [WorkItem(308077, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/308077")] @@ -147,7 +355,9 @@ public Program(int i, string s, bool b) : this(i) public async Task TestAddOptionalToConstructorWithMostMatchingParameters1() { // Behavior change with #33603, now all constructors are offered - await TestInRegularAndScriptAsync( + await new VerifyCS.Test() + { + TestCode = @"using System.Collections.Generic; class Program @@ -166,6 +376,7 @@ public Program(int i, string s) : this(i) this.s = s; } }", + FixedCode = @"using System.Collections.Generic; class Program @@ -184,13 +395,18 @@ public Program(int i, string s, bool b = false) : this(i) this.s = s; this.b = b; } -}", index: 3, title: string.Format(FeaturesResources.Add_to_0, "Program(int, string)")); +}", + CodeActionIndex = 3, + CodeActionVerifier = (codeAction, verifier) => verifier.Equal(string.Format(FeaturesResources.Add_to_0, "Program(int, string)"), codeAction.Title) + }.RunAsync(); } [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddConstructorParametersFromMembers)] public async Task TestSmartTagDisplayText1() { - await TestSmartTagTextAsync( + await new VerifyCS.Test + { + TestCode = @"using System.Collections.Generic; class Program @@ -203,13 +419,16 @@ public Program(bool b) this.b = b; } }", -string.Format(FeaturesResources.Add_parameters_to_0, "Program(bool)")); + CodeActionVerifier = (codeAction, verifier) => verifier.Equal(string.Format(FeaturesResources.Add_parameters_to_0, "Program(bool)"), codeAction.Title) + }.RunAsync(); } [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddConstructorParametersFromMembers)] public async Task TestSmartTagDisplayText2() { - await TestSmartTagTextAsync( + await new VerifyCS.Test + { + TestCode = @"using System.Collections.Generic; class Program @@ -222,14 +441,15 @@ public Program(bool b) this.b = b; } }", -string.Format(FeaturesResources.Add_optional_parameters_to_0, "Program(bool)"), -index: 1); + CodeActionIndex = 1, + CodeActionVerifier = (codeAction, verifier) => verifier.Equal(string.Format(FeaturesResources.Add_optional_parameters_to_0, "Program(bool)"), codeAction.Title) + }.RunAsync(); } [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddConstructorParametersFromMembers)] public async Task TestTuple() { - await TestInRegularAndScriptAsync( + await VerifyCS.VerifyRefactoringAsync( @"class Program { [|(int, string) i; @@ -256,7 +476,7 @@ public Program((int, string) i, (string, int) s) [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddConstructorParametersFromMembers)] public async Task TestTupleWithNames() { - await TestInRegularAndScriptAsync( + await VerifyCS.VerifyRefactoringAsync( @"class Program { [|(int a, string b) i; @@ -283,7 +503,7 @@ public Program((int a, string b) i, (string c, int d) s) [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddConstructorParametersFromMembers)] public async Task TestTupleWithDifferentNames() { - await TestInRegularAndScriptAsync( + await VerifyCS.VerifyRefactoringAsync( @"class Program { [|(int a, string b) i; @@ -310,7 +530,9 @@ public Program((int e, string f) i, (string c, int d) s) [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddConstructorParametersFromMembers)] public async Task TestTupleOptionalCSharp7() { - await TestAsync( + await new VerifyCS.Test + { + TestCode = @"class Program { [|(int, string) i; @@ -321,6 +543,7 @@ public Program((int, string) i) this.i = i; } }", + FixedCode = @"class Program { (int, string) i; @@ -332,13 +555,17 @@ public Program((int, string) i) this.s = s; } }", -index: 1, parseOptions: new CSharpParseOptions(LanguageVersion.CSharp7)); + CodeActionIndex = 1, + LanguageVersion = LanguageVersion.CSharp7 + }.RunAsync(); } [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddConstructorParametersFromMembers)] public async Task TestTupleOptional() { - await TestInRegularAndScriptAsync( + await new VerifyCS.Test + { + TestCode = @"class Program { [|(int, string) i; @@ -349,6 +576,7 @@ public Program((int, string) i) this.i = i; } }", + FixedCode = @"class Program { (int, string) i; @@ -360,13 +588,16 @@ public Program((int, string) i, (string, int) s = default) this.s = s; } }", -index: 1); + CodeActionIndex = 1 + }.RunAsync(); } [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddConstructorParametersFromMembers)] public async Task TestTupleOptionalWithNames_CSharp7() { - await TestInRegularAndScriptAsync( + await new VerifyCS.Test + { + TestCode = @"class Program { [|(int a, string b) i; @@ -377,6 +608,7 @@ public Program((int a, string b) i) this.i = i; } }", + FixedCode = @"class Program { (int a, string b) i; @@ -388,14 +620,17 @@ public Program((int a, string b) i) this.s = s; } }", -parseOptions: TestOptions.Regular7, -index: 1); + LanguageVersion = LanguageVersion.CSharp7, + CodeActionIndex = 1 + }.RunAsync(); } [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddConstructorParametersFromMembers)] public async Task TestTupleOptionalWithNamesCSharp7() { - await TestAsync( + await new VerifyCS.Test + { + TestCode = @"class Program { [|(int a, string b) i; @@ -406,6 +641,7 @@ public Program((int a, string b) i) this.i = i; } }", + FixedCode = @"class Program { (int a, string b) i; @@ -417,13 +653,17 @@ public Program((int a, string b) i) this.s = s; } }", -index: 1, parseOptions: new CSharpParseOptions(LanguageVersion.CSharp7)); + CodeActionIndex = 1, + LanguageVersion = LanguageVersion.CSharp7 + }.RunAsync(); } [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddConstructorParametersFromMembers)] public async Task TestTupleOptionalWithNames() { - await TestInRegularAndScriptAsync( + await new VerifyCS.Test + { + TestCode = @"class Program { [|(int a, string b) i; @@ -434,6 +674,7 @@ public Program((int a, string b) i) this.i = i; } }", + FixedCode = @"class Program { (int a, string b) i; @@ -445,13 +686,16 @@ public Program((int a, string b) i, (string c, int d) s = default) this.s = s; } }", -index: 1); + CodeActionIndex = 1 + }.RunAsync(); } [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddConstructorParametersFromMembers)] public async Task TestTupleOptionalWithDifferentNames() { - await TestInRegularAndScriptAsync( + await new VerifyCS.Test + { + TestCode = @"class Program { [|(int a, string b) i; @@ -462,6 +706,7 @@ public Program((int e, string f) i) this.i = i; } }", + FixedCode = @"class Program { [|(int a, string b) i; @@ -472,13 +717,15 @@ public Program((int e, string f) i, (string c, int d) s = default) this.i = i; this.s = s; } -}", index: 1); +}", + CodeActionIndex = 1 + }.RunAsync(); } [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddConstructorParametersFromMembers)] public async Task TestTupleWithNullable() { - await TestInRegularAndScriptAsync( + await VerifyCS.VerifyRefactoringAsync( @"class Program { [|(int?, bool?) i; @@ -505,8 +752,10 @@ public Program((int?, bool?) i, (byte?, long?) s) [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddConstructorParametersFromMembers)] public async Task TestTupleWithGenericss() { - await TestInRegularAndScriptAsync( -@"class Program + await VerifyCS.VerifyRefactoringAsync( +@"using System.Collections.Generic; + +class Program { [|(List, List) i; (List, List) s;|] @@ -516,7 +765,9 @@ public Program((List, List) i) this.i = i; } }", -@"class Program +@"using System.Collections.Generic; + +class Program { (List, List) i; (List, List) s; @@ -533,8 +784,9 @@ public Program((List, List) i, (List, List) s) [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddConstructorParametersFromMembers)] public async Task TestAddParamtersToConstructorBySelectOneMember() { - await TestInRegularAndScriptAsync( -@" + await VerifyCS.VerifyRefactoringAsync( +@"using System.Collections.Generic; + class C { int i; @@ -547,7 +799,8 @@ public C(int i, int j) this.j = j; } }", -@" +@"using System.Collections.Generic; + class C { int i; @@ -567,7 +820,7 @@ public C(int i, int j, (List, List) s) [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddConstructorParametersFromMembers)] public async Task TestParametersAreStillRightIfMembersAreOutOfOrder() { - await TestInRegularAndScriptAsync( + await VerifyCS.VerifyRefactoringAsync( @" class C { @@ -601,7 +854,7 @@ public C(int i, int j, int k) [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddConstructorParametersFromMembers)] public async Task TestMissingIfFieldsAlreadyExistingInConstructor() { - await TestMissingAsync( + var source = @" class C { @@ -610,15 +863,15 @@ class C public C(string barBar, int fooFoo) { } -}" - ); +}"; + await VerifyCS.VerifyRefactoringAsync(source, source); } [WorkItem(28775, "https://github.com/dotnet/roslyn/issues/28775")] [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddConstructorParametersFromMembers)] public async Task TestMissingIfPropertyAlreadyExistingInConstructor() { - await TestMissingAsync( + var source = @" class C { @@ -627,16 +880,15 @@ class C public C(string bar, int helloWorld) { } -}" - ); - +}"; + await VerifyCS.VerifyRefactoringAsync(source, source); } [WorkItem(28775, "https://github.com/dotnet/roslyn/issues/28775")] [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddConstructorParametersFromMembers)] public async Task TestNormalProperty() { - await TestInRegularAndScriptAsync( + await VerifyCS.VerifyRefactoringAsync( @" class C { @@ -663,7 +915,7 @@ public C(int i, int hello) [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddConstructorParametersFromMembers)] public async Task TestConstructorWithNoParameters() { - await TestInRegularAndScriptAsync( + await VerifyCS.VerifyRefactoringAsync( @" class C { @@ -691,20 +943,21 @@ public C(int i, int hello) [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddConstructorParametersFromMembers)] public async Task TestDefaultConstructor() { - await TestMissingAsync( + var source = @" class C { [|int i;|] int Hello { get; set; } -}"); +}"; + await VerifyCS.VerifyRefactoringAsync(source, source); } [WorkItem(33601, "https://github.com/dotnet/roslyn/issues/33601")] [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddConstructorParametersFromMembers)] public async Task TestPartialSelected() { - await TestInRegularAndScriptAsync( + await VerifyCS.VerifyRefactoringAsync( @" class C { @@ -731,7 +984,7 @@ public C(int i, int j) [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddConstructorParametersFromMembers)] public async Task TestPartialMultipleSelected() { - await TestInRegularAndScriptAsync( + await VerifyCS.VerifyRefactoringAsync( @" class C { @@ -761,7 +1014,7 @@ public C(int i, int j, int k) [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddConstructorParametersFromMembers)] public async Task TestPartialMultipleSelected2() { - await TestInRegularAndScriptAsync( + await VerifyCS.VerifyRefactoringAsync( @" class C { @@ -790,7 +1043,9 @@ public C(int i, int j) [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddConstructorParametersFromMembers)] public async Task TestMultipleConstructors_FirstofThree() { - var source = + await new VerifyCS.Test + { + TestCode = @" class C { @@ -804,8 +1059,8 @@ public C(int i, int j) public C(int i, int j, int k) { } -}"; - var expected = +}", + FixedCode = @" class C { @@ -814,14 +1069,15 @@ public C(int i, int l) { this.l = l; } - public C(int i, int j) + public {|CS0111:C|}(int i, int j) { } public C(int i, int j, int k) { } -}"; - await TestInRegularAndScriptAsync(source, expected, index: 0, title: string.Format(FeaturesResources.Add_to_0, "C(int)")); +}", + CodeActionVerifier = (codeAction, verifier) => verifier.Equal(string.Format(FeaturesResources.Add_to_0, "C(int)"), codeAction.Title) + }.RunAsync(); } [WorkItem(33603, "https://github.com/dotnet/roslyn/issues/33603")] @@ -855,11 +1111,17 @@ public C(int i, int j, int l) { this.l = l; } - public C(int i, int j, int k) + public {|CS0111:C|}(int i, int j, int k) { } }"; - await TestInRegularAndScriptAsync(source, expected, index: 1, title: string.Format(FeaturesResources.Add_to_0, "C(int, int)")); + await new VerifyCS.Test + { + TestCode = source, + FixedCode = expected, + CodeActionIndex = 1, + CodeActionVerifier = (codeAction, verifier) => verifier.Equal(string.Format(FeaturesResources.Add_to_0, "C(int, int)"), codeAction.Title) + }.RunAsync(); } [WorkItem(33603, "https://github.com/dotnet/roslyn/issues/33603")] @@ -898,7 +1160,13 @@ public C(int i, int j, int k, int l) this.l = l; } }"; - await TestInRegularAndScriptAsync(source, expected, index: 2, title: string.Format(FeaturesResources.Add_to_0, "C(int, int, int)")); + await new VerifyCS.Test + { + TestCode = source, + FixedCode = expected, + CodeActionIndex = 2, + CodeActionVerifier = (codeAction, verifier) => verifier.Equal(string.Format(FeaturesResources.Add_to_0, "C(int, int, int)"), codeAction.Title) + }.RunAsync(); } [WorkItem(33603, "https://github.com/dotnet/roslyn/issues/33603")] @@ -929,14 +1197,20 @@ public C(int i, int l = 0) { this.l = l; } - public C(int i, int j) + public {|CS0111:C|}(int i, int j) { } public C(int i, int j, int k) { } }"; - await TestInRegularAndScriptAsync(source, expected, index: 3, title: string.Format(FeaturesResources.Add_to_0, "C(int)")); + await new VerifyCS.Test + { + TestCode = source, + FixedCode = expected, + CodeActionIndex = 3, + CodeActionVerifier = (codeAction, verifier) => verifier.Equal(string.Format(FeaturesResources.Add_to_0, "C(int)"), codeAction.Title) + }.RunAsync(); } [WorkItem(33603, "https://github.com/dotnet/roslyn/issues/33603")] @@ -970,11 +1244,18 @@ public C(int i, int j, int l = 0) { this.l = l; } - public C(int i, int j, int k) + public {|CS0111:C|}(int i, int j, int k) { } }"; - await TestInRegularAndScriptAsync(source, expected, index: 4, title: string.Format(FeaturesResources.Add_to_0, "C(int, int)")); + + await new VerifyCS.Test + { + TestCode = source, + FixedCode = expected, + CodeActionIndex = 4, + CodeActionVerifier = (codeAction, verifier) => verifier.Equal(string.Format(FeaturesResources.Add_to_0, "C(int, int)"), codeAction.Title) + }.RunAsync(); } [WorkItem(33603, "https://github.com/dotnet/roslyn/issues/33603")] @@ -1012,7 +1293,13 @@ public C(int i, int j, int k, int l = 0) this.l = l; } }"; - await TestInRegularAndScriptAsync(source, expected, index: 5, title: string.Format(FeaturesResources.Add_to_0, "C(int, int, int)")); + await new VerifyCS.Test + { + TestCode = source, + FixedCode = expected, + CodeActionIndex = 5, + CodeActionVerifier = (codeAction, verifier) => verifier.Equal(string.Format(FeaturesResources.Add_to_0, "C(int, int, int)"), codeAction.Title) + }.RunAsync(); } [WorkItem(33603, "https://github.com/dotnet/roslyn/issues/33603")] @@ -1066,7 +1353,13 @@ public C(int i, double j, int k, int l) this.l = l; } }"; - await TestInRegularAndScriptAsync(source, expected, index: 1, title: string.Format(FeaturesResources.Add_to_0, "C(int, double, int)")); + await new VerifyCS.Test + { + TestCode = source, + FixedCode = expected, + CodeActionIndex = 1, + CodeActionVerifier = (codeAction, verifier) => verifier.Equal(string.Format(FeaturesResources.Add_to_0, "C(int, double, int)"), codeAction.Title) + }.RunAsync(); } [WorkItem(33603, "https://github.com/dotnet/roslyn/issues/33603")] @@ -1112,19 +1405,27 @@ public C(int i, double j = 0, int l = 0) } // index 1, and 4 as optional - public C(int i, double j, int k) + public {|CS0111:C|}(int i, double j, int k) { } }"; - await TestInRegularAndScriptAsync(source, expected, index: 3, title: string.Format(FeaturesResources.Add_to_0, "C(int, double)")); + await new VerifyCS.Test + { + TestCode = source, + FixedCode = expected, + CodeActionIndex = 3, + CodeActionVerifier = (codeAction, verifier) => verifier.Equal(string.Format(FeaturesResources.Add_to_0, "C(int, double)"), codeAction.Title) + }.RunAsync(); } [WorkItem(33603, "https://github.com/dotnet/roslyn/issues/33603")] [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddConstructorParametersFromMembers)] public async Task TestMultipleConstructors_AllMustBeOptional() { - var source = -@" + await new VerifyCS.Test + { + TestCode = + @" class C { int [|p|]; @@ -1137,8 +1438,8 @@ public C(double j, int k = 0) public C(int l, double m, int n = 0) { } -}"; - var expected = +}", + FixedCode = @" class C { @@ -1153,8 +1454,9 @@ public C(double j, int k = 0) public C(int l, double m, int n = 0) { } -}"; - await TestInRegularAndScriptAsync(source, expected, index: 0, title: string.Format(FeaturesResources.Add_to_0, "C(int)")); +}", + CodeActionVerifier = (codeAction, verifier) => verifier.Equal(string.Format(FeaturesResources.Add_to_0, "C(int)"), codeAction.Title) + }.RunAsync(); } [WorkItem(33603, "https://github.com/dotnet/roslyn/issues/33603")] @@ -1192,19 +1494,25 @@ public C(int l, double m, int n = 0, int p = 0) this.p = p; } }"; - await TestInRegularAndScriptAsync(source, expected, index: 2, title: string.Format(FeaturesResources.Add_to_0, "C(int, double, int)")); + await new VerifyCS.Test + { + TestCode = source, + FixedCode = expected, + CodeActionIndex = 2, + CodeActionVerifier = (codeAction, verifier) => verifier.Equal(string.Format(FeaturesResources.Add_to_0, "C(int, double, int)"), codeAction.Title) + }.RunAsync(); } [WorkItem(33623, "https://github.com/dotnet/roslyn/issues/33623")] [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddConstructorParametersFromMembers)] public async Task TestDeserializationConstructor() { - await TestMissingAsync( + var source = @" using System; using System.Runtime.Serialization; -class C : ISerializable +class C : {|CS0535:ISerializable|} { int [|i|]; @@ -1212,7 +1520,8 @@ private C(SerializationInfo info, StreamingContext context) { } } -"); +"; + await VerifyCS.VerifyRefactoringAsync(source, source); } [WorkItem(35775, "https://github.com/dotnet/roslyn/issues/35775")] @@ -1241,7 +1550,12 @@ public C(int p_v_End) } } "; - await TestInRegularAndScriptAsync(source, expected, index: 0, options: options.ParameterNamesAreCamelCaseWithPUnderscorePrefixAndUnderscoreEndSuffix); + await new VerifyCS.Test + { + TestCode = source, + FixedCode = expected, + EditorConfig = ParameterNamesCamelCaseWithPUnderscorePrefixEndUnderscoreSuffixEditorConfig + }.RunAsync(); } [WorkItem(35775, "https://github.com/dotnet/roslyn/issues/35775")] @@ -1270,7 +1584,12 @@ public C(int p_v) } } "; - await TestInRegularAndScriptAsync(source, expected, index: 0, options: options.ParameterNamesAreCamelCaseWithPUnderscorePrefix); + await new VerifyCS.Test + { + TestCode = source, + FixedCode = expected, + EditorConfig = ParameterNamesCamelCaseWithPUnderscorePrefixEditorConfig + }.RunAsync(); } [WorkItem(35775, "https://github.com/dotnet/roslyn/issues/35775")] @@ -1299,8 +1618,12 @@ public C(int p_v) } } "; - await TestInRegularAndScriptAsync(source, expected, index: 0, options: options.MergeStyles( - options.FieldNamesAreCamelCaseWithFieldUnderscorePrefix, options.ParameterNamesAreCamelCaseWithPUnderscorePrefix)); + await new VerifyCS.Test + { + TestCode = source, + FixedCode = expected, + EditorConfig = FieldNamesCamelCaseWithFieldUnderscorePrefixEditorConfig + ParameterNamesCamelCaseWithPUnderscorePrefixEditorConfig + }.RunAsync(); } [WorkItem(35775, "https://github.com/dotnet/roslyn/issues/35775")] @@ -1329,8 +1652,13 @@ public C(int p_v) } } "; - await TestInRegularAndScriptAsync(source, expected, index: 0, options: options.MergeStyles( - options.FieldNamesAreCamelCaseWithFieldUnderscorePrefix, options.ParameterNamesAreCamelCaseWithPUnderscorePrefix)); + + await new VerifyCS.Test + { + TestCode = source, + FixedCode = expected, + EditorConfig = FieldNamesCamelCaseWithFieldUnderscorePrefixEditorConfig + ParameterNamesCamelCaseWithPUnderscorePrefixEditorConfig + }.RunAsync(); } [WorkItem(35775, "https://github.com/dotnet/roslyn/issues/35775")] @@ -1359,8 +1687,12 @@ public C(int p_v) } } "; - await TestInRegularAndScriptAsync(source, expected, index: 0, options: options.MergeStyles( - options.FieldNamesAreCamelCaseWithFieldUnderscorePrefix, options.ParameterNamesAreCamelCaseWithPUnderscorePrefix)); + await new VerifyCS.Test + { + TestCode = source, + FixedCode = expected, + EditorConfig = FieldNamesCamelCaseWithFieldUnderscorePrefixEditorConfig + ParameterNamesCamelCaseWithPUnderscorePrefixEditorConfig + }.RunAsync(); } [WorkItem(35775, "https://github.com/dotnet/roslyn/issues/35775")] @@ -1377,7 +1709,13 @@ public C() } } "; - await TestMissingAsync(source, parameters: new TestParameters(options: options.FieldNamesAreCamelCaseWithFieldUnderscorePrefixAndUnderscoreEndSuffix)); + + await new VerifyCS.Test + { + TestCode = source, + FixedCode = source, + EditorConfig = FieldNamesCamelCaseWithFieldUnderscorePrefixEndUnderscoreSuffixEditorConfig + }.RunAsync(); } [WorkItem(35775, "https://github.com/dotnet/roslyn/issues/35775")] @@ -1408,8 +1746,13 @@ public C(int p_test) } } "; - await TestInRegularAndScriptAsync(source, expected, index: 0, options: options.MergeStyles( - options.FieldNamesAreCamelCaseWithFieldUnderscorePrefixAndUnderscoreEndSuffix, options.ParameterNamesAreCamelCaseWithPUnderscorePrefix)); + + await new VerifyCS.Test + { + TestCode = source, + FixedCode = expected, + EditorConfig = FieldNamesCamelCaseWithFieldUnderscorePrefixEndUnderscoreSuffixEditorConfig + ParameterNamesCamelCaseWithPUnderscorePrefixEditorConfig + }.RunAsync(); } [WorkItem(35775, "https://github.com/dotnet/roslyn/issues/35775")] @@ -1438,14 +1781,22 @@ public C(int p_test) } } "; - await TestInRegularAndScriptAsync(source, expected, index: 0, options: options.ParameterNamesAreCamelCaseWithPUnderscorePrefix); + + await new VerifyCS.Test + { + TestCode = source, + FixedCode = expected, + EditorConfig = ParameterNamesCamelCaseWithPUnderscorePrefixEditorConfig + }.RunAsync(); } [WorkItem(23271, "https://github.com/dotnet/roslyn/issues/23271")] [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddConstructorParametersFromMembers)] public async Task TestNonSelection1() { - await TestInRegularAndScriptAsync( + await new VerifyCS.Test + { + TestCode = @"using System.Collections.Generic; class Program @@ -1458,6 +1809,7 @@ public Program(int i) this.i = i; } }", + FixedCode = @"using System.Collections.Generic; class Program @@ -1470,14 +1822,18 @@ public Program(int i, string s) this.i = i; this.s = s; } -}", title: string.Format(FeaturesResources.Add_parameters_to_0, "Program(int)")); +}", + CodeActionVerifier = (codeAction, verifier) => verifier.Equal(string.Format(FeaturesResources.Add_parameters_to_0, "Program(int)"), codeAction.Title) + }.RunAsync(); } [WorkItem(23271, "https://github.com/dotnet/roslyn/issues/23271")] [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddConstructorParametersFromMembers)] public async Task TestNonSelection2() { - await TestInRegularAndScriptAsync( + await new VerifyCS.Test + { + TestCode = @"using System.Collections.Generic; class Program @@ -1490,6 +1846,7 @@ public Program(int i) this.i = i; } }", + FixedCode = @"using System.Collections.Generic; class Program @@ -1502,14 +1859,18 @@ public Program(int i, string s) this.i = i; this.s = s; } -}", title: string.Format(FeaturesResources.Add_parameters_to_0, "Program(int)")); +}", + CodeActionVerifier = (codeAction, verifier) => verifier.Equal(string.Format(FeaturesResources.Add_parameters_to_0, "Program(int)"), codeAction.Title) + }.RunAsync(); } [WorkItem(23271, "https://github.com/dotnet/roslyn/issues/23271")] [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddConstructorParametersFromMembers)] public async Task TestNonSelection3() { - await TestInRegularAndScriptAsync( + await new VerifyCS.Test + { + TestCode = @"using System.Collections.Generic; class Program @@ -1522,6 +1883,7 @@ public Program(int i) this.i = i; } }", + FixedCode = @"using System.Collections.Generic; class Program @@ -1534,14 +1896,18 @@ public Program(int i, string s) this.i = i; this.s = s; } -}", title: string.Format(FeaturesResources.Add_parameters_to_0, "Program(int)")); +}", + CodeActionVerifier = (codeAction, verifier) => verifier.Equal(string.Format(FeaturesResources.Add_parameters_to_0, "Program(int)"), codeAction.Title) + }.RunAsync(); } [WorkItem(23271, "https://github.com/dotnet/roslyn/issues/23271")] [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddConstructorParametersFromMembers)] public async Task TestNonSelection4() { - await TestInRegularAndScriptAsync( + await new VerifyCS.Test + { + TestCode = @"using System.Collections.Generic; class Program @@ -1554,6 +1920,7 @@ public Program(int i) this.i = i; } }", + FixedCode = @"using System.Collections.Generic; class Program @@ -1566,14 +1933,18 @@ public Program(int i, string s) this.i = i; this.s = s; } -}", title: string.Format(FeaturesResources.Add_parameters_to_0, "Program(int)")); +}", + CodeActionVerifier = (codeAction, verifier) => verifier.Equal(string.Format(FeaturesResources.Add_parameters_to_0, "Program(int)"), codeAction.Title) + }.RunAsync(); } [WorkItem(23271, "https://github.com/dotnet/roslyn/issues/23271")] [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddConstructorParametersFromMembers)] public async Task TestNonSelection5() { - await TestInRegularAndScriptAsync( + await new VerifyCS.Test + { + TestCode = @"using System.Collections.Generic; class Program @@ -1586,6 +1957,7 @@ public Program(int i) this.i = i; } }", + FixedCode = @"using System.Collections.Generic; class Program @@ -1598,14 +1970,18 @@ public Program(int i, string s) this.i = i; this.s = s; } -}", title: string.Format(FeaturesResources.Add_parameters_to_0, "Program(int)")); +}", + CodeActionVerifier = (codeAction, verifier) => verifier.Equal(string.Format(FeaturesResources.Add_parameters_to_0, "Program(int)"), codeAction.Title) + }.RunAsync(); } [WorkItem(23271, "https://github.com/dotnet/roslyn/issues/23271")] [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddConstructorParametersFromMembers)] public async Task TestNonSelection6() { - await TestInRegularAndScriptAsync( + await new VerifyCS.Test + { + TestCode = @"using System.Collections.Generic; class Program @@ -1618,6 +1994,7 @@ public Program(int i) this.i = i; } }", + FixedCode = @"using System.Collections.Generic; class Program @@ -1630,14 +2007,18 @@ public Program(int i, string s) this.i = i; this.s = s; } -}", title: string.Format(FeaturesResources.Add_parameters_to_0, "Program(int)")); +}", + CodeActionVerifier = (codeAction, verifier) => verifier.Equal(string.Format(FeaturesResources.Add_parameters_to_0, "Program(int)"), codeAction.Title) + }.RunAsync(); } [WorkItem(23271, "https://github.com/dotnet/roslyn/issues/23271")] [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddConstructorParametersFromMembers)] public async Task TestNonSelectionMultiVar1() { - await TestInRegularAndScriptAsync( + await new VerifyCS.Test + { + TestCode = @"using System.Collections.Generic; class Program @@ -1650,6 +2031,7 @@ public Program(int i) this.i = i; } }", + FixedCode = @"using System.Collections.Generic; class Program @@ -1663,14 +2045,18 @@ public Program(int i, string s, string t) this.s = s; this.t = t; } -}", title: string.Format(FeaturesResources.Add_parameters_to_0, "Program(int)")); +}", + CodeActionVerifier = (codeAction, verifier) => verifier.Equal(string.Format(FeaturesResources.Add_parameters_to_0, "Program(int)"), codeAction.Title) + }.RunAsync(); } [WorkItem(23271, "https://github.com/dotnet/roslyn/issues/23271")] [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddConstructorParametersFromMembers)] public async Task TestNonSelectionMultiVar2() { - await TestInRegularAndScriptAsync( + await new VerifyCS.Test + { + TestCode = @"using System.Collections.Generic; class Program @@ -1683,6 +2069,7 @@ public Program(int i) this.i = i; } }", + FixedCode = @"using System.Collections.Generic; class Program @@ -1696,14 +2083,18 @@ public Program(int i, string s, string t) this.s = s; this.t = t; } -}", title: string.Format(FeaturesResources.Add_parameters_to_0, "Program(int)")); +}", + CodeActionVerifier = (codeAction, verifier) => verifier.Equal(string.Format(FeaturesResources.Add_parameters_to_0, "Program(int)"), codeAction.Title) + }.RunAsync(); } [WorkItem(23271, "https://github.com/dotnet/roslyn/issues/23271")] [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddConstructorParametersFromMembers)] public async Task TestNonSelectionMultiVar3() { - await TestInRegularAndScriptAsync( + await new VerifyCS.Test + { + TestCode = @"using System.Collections.Generic; class Program @@ -1716,6 +2107,7 @@ public Program(int i) this.i = i; } }", + FixedCode = @"using System.Collections.Generic; class Program @@ -1728,14 +2120,18 @@ public Program(int i, string s) this.i = i; this.s = s; } -}", title: string.Format(FeaturesResources.Add_parameters_to_0, "Program(int)")); +}", + CodeActionVerifier = (codeAction, verifier) => verifier.Equal(string.Format(FeaturesResources.Add_parameters_to_0, "Program(int)"), codeAction.Title) + }.RunAsync(); } [WorkItem(23271, "https://github.com/dotnet/roslyn/issues/23271")] [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddConstructorParametersFromMembers)] public async Task TestNonSelectionMultiVar4() { - await TestInRegularAndScriptAsync( + await new VerifyCS.Test + { + TestCode = @"using System.Collections.Generic; class Program @@ -1748,6 +2144,7 @@ public Program(int i) this.i = i; } }", + FixedCode = @"using System.Collections.Generic; class Program @@ -1760,14 +2157,18 @@ public Program(int i, string s) this.i = i; this.s = s; } -}", title: string.Format(FeaturesResources.Add_parameters_to_0, "Program(int)")); +}", + CodeActionVerifier = (codeAction, verifier) => verifier.Equal(string.Format(FeaturesResources.Add_parameters_to_0, "Program(int)"), codeAction.Title) + }.RunAsync(); } [WorkItem(23271, "https://github.com/dotnet/roslyn/issues/23271")] [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddConstructorParametersFromMembers)] public async Task TestNonSelectionMultiVar5() { - await TestInRegularAndScriptAsync( + await new VerifyCS.Test + { + TestCode = @"using System.Collections.Generic; class Program @@ -1780,6 +2181,7 @@ public Program(int i) this.i = i; } }", + FixedCode = @"using System.Collections.Generic; class Program @@ -1792,14 +2194,18 @@ public Program(int i, string t) this.i = i; this.t = t; } -}", title: string.Format(FeaturesResources.Add_parameters_to_0, "Program(int)")); +}", + CodeActionVerifier = (codeAction, verifier) => verifier.Equal(string.Format(FeaturesResources.Add_parameters_to_0, "Program(int)"), codeAction.Title) + }.RunAsync(); } [WorkItem(23271, "https://github.com/dotnet/roslyn/issues/23271")] [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddConstructorParametersFromMembers)] public async Task TestNonSelectionMultiVar6() { - await TestInRegularAndScriptAsync( + await new VerifyCS.Test + { + TestCode = @"using System.Collections.Generic; class Program @@ -1812,6 +2218,7 @@ public Program(int i) this.i = i; } }", + FixedCode = @"using System.Collections.Generic; class Program @@ -1824,14 +2231,16 @@ public Program(int i, string t) this.i = i; this.t = t; } -}", title: string.Format(FeaturesResources.Add_parameters_to_0, "Program(int)")); +}", + CodeActionVerifier = (codeAction, verifier) => verifier.Equal(string.Format(FeaturesResources.Add_parameters_to_0, "Program(int)"), codeAction.Title) + }.RunAsync(); } [WorkItem(23271, "https://github.com/dotnet/roslyn/issues/23271")] [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddConstructorParametersFromMembers)] public async Task TestNonSelectionMissing1() { - await TestMissingInRegularAndScriptAsync( + var source = @"using System.Collections.Generic; class Program @@ -1844,14 +2253,15 @@ public Program(int i) { this.i = i; } -}"); +}"; + await VerifyCS.VerifyRefactoringAsync(source, source); } [WorkItem(23271, "https://github.com/dotnet/roslyn/issues/23271")] [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddConstructorParametersFromMembers)] public async Task TestNonSelectionMissing2() { - await TestMissingInRegularAndScriptAsync( + var source = @"using System.Collections.Generic; class Program @@ -1863,14 +2273,15 @@ public Program(int i) { this.i = i; } -}"); +}"; + await VerifyCS.VerifyRefactoringAsync(source, source); } [WorkItem(23271, "https://github.com/dotnet/roslyn/issues/23271")] [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddConstructorParametersFromMembers)] public async Task TestNonSelectionMissing3() { - await TestMissingInRegularAndScriptAsync( + var source = @"using System.Collections.Generic; class Program @@ -1882,14 +2293,15 @@ public Program(int i) { this.i = i; } -}"); +}"; + await VerifyCS.VerifyRefactoringAsync(source, source); } [WorkItem(23271, "https://github.com/dotnet/roslyn/issues/23271")] [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddConstructorParametersFromMembers)] public async Task TestNonSelectionMissing4() { - await TestMissingInRegularAndScriptAsync( + var source = @"using System.Collections.Generic; class Program @@ -1901,7 +2313,156 @@ public Program(int i) { this.i = i; } -}"); +}"; + await VerifyCS.VerifyRefactoringAsync(source, source); + } + + [WorkItem(59292, "https://github.com/dotnet/roslyn/issues/59292")] + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddConstructorParametersFromMembers)] + public async Task TestPartialClass1() + { + await new VerifyCS.Test + { + TestState = + { + Sources = + { +@" +partial class C +{ + private int [|_v|]; +}", +@" +partial class C +{ + public C() + { + } +}" + } + }, + FixedState = + { + Sources = + { +@" +partial class C +{ + private int _v; +}", +@" +partial class C +{ + public C(int v) + { + _v = v; + } +}" + } + } + }.RunAsync(); + } + + [WorkItem(59292, "https://github.com/dotnet/roslyn/issues/59292")] + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddConstructorParametersFromMembers)] + public async Task TestPartialClass2() + { + await new VerifyCS.Test + { + TestState = + { + Sources = + { +@" +partial class C +{ + private int [|_v|]; + + public C() + { + } +}", +@" +partial class C +{ + public C(object goo) + { + } +}" + } + }, + FixedState = + { + Sources = + { +@" +partial class C +{ + private int _v; + + public C() + { + } +}", +@" +partial class C +{ + public C(object goo, int v) + { + _v = v; + } +}" + } + }, + CodeActionIndex = 1 + }.RunAsync(); + } + + [WorkItem(59292, "https://github.com/dotnet/roslyn/issues/59292")] + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddConstructorParametersFromMembers)] + public async Task TestPartialClass3() + { + await new VerifyCS.Test + { + TestState = + { + Sources = + { +@" +partial class C +{ + private int [|_v|]; +}", +@" +partial class C +{ + public C() + { + } +}" + } + }, + FixedState = + { + Sources = + { +@" +partial class C +{ + private int _v; +}", +@" +partial class C +{ + public C(int v = 0) + { + _v = v; + } +}" + } + }, + CodeActionIndex = 1 + }.RunAsync(); } } } diff --git a/src/EditorFeatures/CSharpTest/ImplementAbstractClass/ImplementAbstractClassTests.cs b/src/EditorFeatures/CSharpTest/ImplementAbstractClass/ImplementAbstractClassTests.cs index 2022170660e07..d6624d0d75a81 100644 --- a/src/EditorFeatures/CSharpTest/ImplementAbstractClass/ImplementAbstractClassTests.cs +++ b/src/EditorFeatures/CSharpTest/ImplementAbstractClass/ImplementAbstractClassTests.cs @@ -5,6 +5,7 @@ #nullable disable using System.Threading.Tasks; +using Microsoft.CodeAnalysis.CodeActions; using Microsoft.CodeAnalysis.CodeFixes; using Microsoft.CodeAnalysis.CodeStyle; using Microsoft.CodeAnalysis.CSharp; @@ -1468,6 +1469,11 @@ class T : A [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsImplementAbstractClass)] public async Task TestWithGroupingOff1() { + var options = CodeActionOptions.Default with + { + ImplementTypeOptions = new ImplementTypeOptions(InsertionBehavior: ImplementTypeInsertionBehavior.AtTheEnd) + }; + await TestInRegularAndScriptAsync( @"abstract class Base { @@ -1488,7 +1494,7 @@ class Derived : Base void Goo() { } public override int Prop => throw new System.NotImplementedException(); -}", options: Option(ImplementTypeOptions.Metadata.InsertionBehavior, ImplementTypeInsertionBehavior.AtTheEnd)); +}", codeActionOptions: options); } [WorkItem(17274, "https://github.com/dotnet/roslyn/issues/17274")] @@ -1641,6 +1647,11 @@ public override void M2(T? i = null) [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsImplementAbstractClass)] public async Task TestAutoProperties() { + var options = CodeActionOptions.Default with + { + ImplementTypeOptions = new ImplementTypeOptions(PropertyGenerationBehavior: ImplementTypePropertyGenerationBehavior.PreferAutoProperties) + }; + await TestInRegularAndScript1Async( @"abstract class AbstractClass { @@ -1664,9 +1675,7 @@ class C : AbstractClass public override int ReadOnlyProp { get; } public override int ReadWriteProp { get; set; } public override int WriteOnlyProp { set => throw new System.NotImplementedException(); } -}", parameters: new TestParameters(options: Option( - ImplementTypeOptions.Metadata.PropertyGenerationBehavior, - ImplementTypePropertyGenerationBehavior.PreferAutoProperties))); +}", parameters: new TestParameters(codeActionOptions: options)); } [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsImplementAbstractClass)] diff --git a/src/EditorFeatures/CSharpTest/ImplementInterface/ImplementExplicitlyTests.cs b/src/EditorFeatures/CSharpTest/ImplementInterface/ImplementExplicitlyTests.cs index 511f26564b02e..03428526a0cab 100644 --- a/src/EditorFeatures/CSharpTest/ImplementInterface/ImplementExplicitlyTests.cs +++ b/src/EditorFeatures/CSharpTest/ImplementInterface/ImplementExplicitlyTests.cs @@ -2,8 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -#nullable disable - using System.Collections.Immutable; using System.Threading.Tasks; using Microsoft.CodeAnalysis.CodeActions; @@ -11,6 +9,7 @@ using Microsoft.CodeAnalysis.CSharp.ImplementInterface; using Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.CodeRefactorings; using Microsoft.CodeAnalysis.Test.Utilities; +using Roslyn.Test.Utilities; using Xunit; namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.ImplementInterface @@ -562,5 +561,160 @@ int IBar.M(int i) } }", index: SingleMember); } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsImplementInterface)] + [WorkItem(52020, "https://github.com/dotnet/roslyn/issues/52020")] + public async Task TestWithContraints() + { + await TestInRegularAndScriptAsync( +@" +interface IRepro +{ + void A(int value) where T : class; +} + +class Repro : IRepro +{ + public void [||]A(int value) where T : class + { + } +}", +@" +interface IRepro +{ + void A(int value) where T : class; +} + +class Repro : IRepro +{ + void IRepro.A(int value) + { + } +}"); + } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsImplementInterface)] + [WorkItem(52020, "https://github.com/dotnet/roslyn/issues/52020")] + public async Task TestWithDefaultParameterValues() + { + await TestInRegularAndScriptAsync( +@" +interface IRepro +{ + void A(int value = 0); +} + +class Repro : IRepro +{ + public void [||]A(int value = 0) + { + } +}", +@" +interface IRepro +{ + void A(int value = 0); +} + +class Repro : IRepro +{ + void IRepro.A(int value) + { + } +}"); + } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsImplementInterface)] + [WorkItem(52020, "https://github.com/dotnet/roslyn/issues/52020")] + public async Task TestWithMismatchedDefaultParameterValues() + { + await TestInRegularAndScriptAsync( +@" +interface IRepro +{ + void A(int value = 0); +} + +class Repro : IRepro +{ + public void [||]A(int value = 1) + { + } +}", +@" +interface IRepro +{ + void A(int value = 0); +} + +class Repro : IRepro +{ + void IRepro.A(int value = 1) + { + } +}"); + } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsImplementInterface)] + [WorkItem(52020, "https://github.com/dotnet/roslyn/issues/52020")] + public async Task TestWithMismatchedDefault1() + { + await TestInRegularAndScriptAsync( + @" +interface IRepro +{ + void A(int value); +} + +class Repro : IRepro +{ + public void [||]A(int value = 1) + { + } +}", + @" +interface IRepro +{ + void A(int value); +} + +class Repro : IRepro +{ + void IRepro.A(int value = 1) + { + } +}"); + } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsImplementInterface)] + [WorkItem(52020, "https://github.com/dotnet/roslyn/issues/52020")] + public async Task TestWithMismatchedDefault2() + { + await TestInRegularAndScriptAsync( + @" +interface IRepro +{ + void A(int value = 0); +} + +class Repro : IRepro +{ + public void [||]A(int value) + { + } +}", + @" +interface IRepro +{ + void A(int value = 0); +} + +class Repro : IRepro +{ + void IRepro.A(int value) + { + } +}"); + } } } diff --git a/src/EditorFeatures/CSharpTest/ImplementInterface/ImplementInterfaceTests.cs b/src/EditorFeatures/CSharpTest/ImplementInterface/ImplementInterfaceTests.cs index f072bdc5b8417..093dd5c8b8500 100644 --- a/src/EditorFeatures/CSharpTest/ImplementInterface/ImplementInterfaceTests.cs +++ b/src/EditorFeatures/CSharpTest/ImplementInterface/ImplementInterfaceTests.cs @@ -3,6 +3,7 @@ // See the LICENSE file in the project root for more information. using System.Threading.Tasks; +using Microsoft.CodeAnalysis.CodeActions; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.CodeStyle; using Microsoft.CodeAnalysis.Editor.UnitTests.CodeActions; @@ -7286,10 +7287,10 @@ void M() { } public int Prop => throw new System.NotImplementedException(); }", - Options = + CodeActionOptions = CodeActionOptions.Default with { - { ImplementTypeOptions.Metadata.InsertionBehavior, ImplementTypeInsertionBehavior.AtTheEnd }, - }, + ImplementTypeOptions = new ImplementTypeOptions(InsertionBehavior: ImplementTypeInsertionBehavior.AtTheEnd) + } }.RunAsync(); } @@ -7461,10 +7462,10 @@ class Class : IInterface public int ReadWriteProp { get; set; } public int WriteOnlyProp { set => throw new System.NotImplementedException(); } }", - Options = + CodeActionOptions = CodeActionOptions.Default with { - { ImplementTypeOptions.Metadata.PropertyGenerationBehavior, ImplementTypePropertyGenerationBehavior.PreferAutoProperties }, - }, + ImplementTypeOptions = new ImplementTypeOptions(PropertyGenerationBehavior: ImplementTypePropertyGenerationBehavior.PreferAutoProperties) + } }.RunAsync(); } diff --git a/src/EditorFeatures/CSharpTest/InitializeParameter/AddParameterCheckTests.cs b/src/EditorFeatures/CSharpTest/InitializeParameter/AddParameterCheckTests.cs index 2f1327b4fb05a..6c2f63b18d9a0 100644 --- a/src/EditorFeatures/CSharpTest/InitializeParameter/AddParameterCheckTests.cs +++ b/src/EditorFeatures/CSharpTest/InitializeParameter/AddParameterCheckTests.cs @@ -2,23 +2,23 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -#nullable disable - using System.Threading.Tasks; using Microsoft.CodeAnalysis.CodeStyle; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.CodeStyle; +using Microsoft.CodeAnalysis.CSharp.InitializeParameter; using Microsoft.CodeAnalysis.CSharp.Shared.Extensions; +using Microsoft.CodeAnalysis.Editor.UnitTests.CodeActions; using Microsoft.CodeAnalysis.Test.Utilities; using Microsoft.CodeAnalysis.Testing; using Roslyn.Test.Utilities; using Xunit; -using VerifyCS = Microsoft.CodeAnalysis.Editor.UnitTests.CodeActions.CSharpCodeRefactoringVerifier< - Microsoft.CodeAnalysis.CSharp.InitializeParameter.CSharpAddParameterCheckCodeRefactoringProvider>; - namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.InitializeParameter { + using VerifyCS = CSharpCodeRefactoringVerifier< + CSharpAddParameterCheckCodeRefactoringProvider>; + public class AddParameterCheckTests { [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsInitializeParameter)] @@ -29,8 +29,10 @@ public async Task TestEmptyFile() await VerifyCS.VerifyRefactoringAsync(code, code); } - [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsInitializeParameter)] - public async Task TestSimpleReferenceType() + [Theory, Trait(Traits.Feature, Traits.Features.CodeActionsInitializeParameter)] + [InlineData("csharp_style_prefer_parameter_null_checking = true")] + [InlineData("")] + public async Task TestSimpleReferenceType(string editorConfig) { await new VerifyCS.Test { @@ -52,7 +54,46 @@ class C public C(string s!!) { } -}" +}", + EditorConfig = $@" +[*] +{editorConfig} +" + }.RunAsync(); + } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsInitializeParameter)] + public async Task TestDoNotPreferParameterNullChecking() + { + await new VerifyCS.Test + { + LanguageVersion = LanguageVersionExtensions.CSharpNext, + TestCode = @" +using System; + +class C +{ + public C([||]string s) + { + } +}", + FixedCode = @" +using System; + +class C +{ + public C(string s) + { + if (s is null) + { + throw new ArgumentNullException(nameof(s)); + } + } +}", + EditorConfig = @" +[*] +csharp_style_prefer_parameter_null_checking = false +", }.RunAsync(); } @@ -76,27 +117,6 @@ public C([||]string s!!) }.RunAsync(); } - [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsInitializeParameter)] - public async Task TestRecordPrimaryConstructor() - { - // https://github.com/dotnet/roslyn/issues/58779 - // Note: we declare a field within the record to work around missing IsExternalInit errors - await new VerifyCS.Test - { - LanguageVersion = LanguageVersionExtensions.CSharpNext, - TestCode = @" -using System; - -record Rec([||]string s) { public string s = s; } -", - FixedCode = @" -using System; - -record Rec(string s) { public string s = s; } -" - }.RunAsync(); - } - [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsInitializeParameter)] public async Task TestSimpleReferenceType_AlreadyNullChecked2() { @@ -2859,5 +2879,48 @@ public C(string s, [||] {|CS1031:{|CS1001:)|}|} }"; await VerifyCS.VerifyRefactoringAsync(source, source); } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsInitializeParameter)] + [WorkItem(58779, "https://github.com/dotnet/roslyn/issues/58779")] + public async Task TestNotInRecordBeforeCSharp11() + { + var code = @" +record C([||]string s) { public string s; }"; + await new VerifyCS.Test + { + LanguageVersion = LanguageVersion.CSharp10, + TestCode = code, + FixedCode = code, + }.RunAsync(); + } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsInitializeParameter)] + [WorkItem(58779, "https://github.com/dotnet/roslyn/issues/58779")] + public async Task TestInRecordAfterCSharp11() + { + await new VerifyCS.Test + { + LanguageVersion = LanguageVersionExtensions.CSharpNext, + TestCode = @" +record C([||]string s) { public string s; }", + FixedCode = @" +record C(string s!!) { public string s; }", + }.RunAsync(); + } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsInitializeParameter)] + [WorkItem(58779, "https://github.com/dotnet/roslyn/issues/58779")] + public async Task TestInRecordWithMultipleParametersAfterCSharp11() + { + await new VerifyCS.Test + { + LanguageVersion = LanguageVersionExtensions.CSharpNext, + TestCode = @" +record C([||]string s, string t) { public string s, t; }", + FixedCode = @" +record C(string s!!, string t!!) { public string s, t; }", + CodeActionIndex = 1, + }.RunAsync(); + } } } diff --git a/src/EditorFeatures/CSharpTest/InlineDiagnostics/InlineDiagnosticsTaggerProviderTests.cs b/src/EditorFeatures/CSharpTest/InlineDiagnostics/InlineDiagnosticsTaggerProviderTests.cs index fcbb5b673911a..4fb1e8e6dfd76 100644 --- a/src/EditorFeatures/CSharpTest/InlineDiagnostics/InlineDiagnosticsTaggerProviderTests.cs +++ b/src/EditorFeatures/CSharpTest/InlineDiagnostics/InlineDiagnosticsTaggerProviderTests.cs @@ -2,8 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +using System; using System.Collections.Immutable; -using System.Linq; using System.Threading.Tasks; using Microsoft.CodeAnalysis.Editor.InlineDiagnostics; using Microsoft.CodeAnalysis.Editor.UnitTests.Extensions; @@ -26,9 +26,15 @@ public class InlineDiagnosticsTaggerProviderTests public async Task ErrorTagGeneratedForError() { var spans = await GetTagSpansAsync("class C {"); - Assert.Equal(1, spans.Count()); + var firstSpan = Assert.Single(spans); + Assert.Equal(PredefinedErrorTypeNames.SyntaxError, firstSpan.Tag.ErrorType); + } - var firstSpan = spans.First(); + [WpfFact, Trait(Traits.Feature, Traits.Features.ErrorSquiggles)] + public async Task ErrorTagGeneratedForErrorInSourceGeneratedDocument() + { + var spans = await GetTagSpansInSourceGeneratedDocumentAsync("class C {"); + var firstSpan = Assert.Single(spans); Assert.Equal(PredefinedErrorTypeNames.SyntaxError, firstSpan.Tag.ErrorType); } @@ -38,6 +44,15 @@ private static async Task>> GetTag return await GetTagSpansAsync(workspace); } + private static async Task>> GetTagSpansInSourceGeneratedDocumentAsync(string content) + { + using var workspace = TestWorkspace.CreateCSharp( + files: Array.Empty(), + sourceGeneratedFiles: new[] { content }, + composition: SquiggleUtilities.WpfCompositionWithSolutionCrawler); + return await GetTagSpansAsync(workspace); + } + private static async Task>> GetTagSpansAsync(TestWorkspace workspace) { workspace.ApplyOptions(new[] { KeyValuePairUtil.Create(new OptionKey2(InlineDiagnosticsOptions.EnableInlineDiagnostics, LanguageNames.CSharp), (object)true) }); diff --git a/src/EditorFeatures/CSharpTest/Intents/AddConstructorParameterIntentTests.cs b/src/EditorFeatures/CSharpTest/Intents/AddConstructorParameterIntentTests.cs index 348eb69da703b..293202482a1ed 100644 --- a/src/EditorFeatures/CSharpTest/Intents/AddConstructorParameterIntentTests.cs +++ b/src/EditorFeatures/CSharpTest/Intents/AddConstructorParameterIntentTests.cs @@ -162,5 +162,31 @@ await VerifyExpectedTextAsync(WellKnownIntents.AddConstructorParameter, initialT { CodeStyleOptions2.QualifyFieldAccess, true } }).ConfigureAwait(false); } + + [Fact] + public async Task AddConstructorParameterUsesExistingAccessibility() + { + var initialText = +@"class C +{ + private readonly int _someInt;{|priorSelection:|} + + protected C({|typed:int som|}) + { + } +}"; + var expectedText = +@"class C +{ + private readonly int _someInt; + + protected C(int someInt) + { + _someInt = someInt; + } +}"; + + await VerifyExpectedTextAsync(WellKnownIntents.AddConstructorParameter, initialText, expectedText).ConfigureAwait(false); + } } } diff --git a/src/EditorFeatures/CSharpTest/Intents/GenerateConstructorIntentTests.cs b/src/EditorFeatures/CSharpTest/Intents/GenerateConstructorIntentTests.cs index e6b1e316369ae..c436a7137e624 100644 --- a/src/EditorFeatures/CSharpTest/Intents/GenerateConstructorIntentTests.cs +++ b/src/EditorFeatures/CSharpTest/Intents/GenerateConstructorIntentTests.cs @@ -39,7 +39,7 @@ public C(int someInt) } [Fact] - public async Task GenerateConstructorTypedPrivate() + public async Task GenerateConstructorTypedPrivateWithoutIntentData() { var initialText = @"class C @@ -62,6 +62,60 @@ public C(int someInt) await VerifyExpectedTextAsync(WellKnownIntents.GenerateConstructor, initialText, expectedText).ConfigureAwait(false); } + [Fact] + public async Task GenerateConstructorTypedPrivateWithIntentData() + { + var initialText = +@"class C +{ + private readonly int _someInt; + + {|typed:private C|} +}"; + var expectedText = +@"class C +{ + private readonly int _someInt; + + private C(int someInt) + { + _someInt = someInt; + } +}"; + + // lang=json + var intentData = @"{ ""accessibility"": ""Private""}"; + + await VerifyExpectedTextAsync(WellKnownIntents.GenerateConstructor, initialText, expectedText, intentData: intentData).ConfigureAwait(false); + } + + [Fact] + public async Task GenerateConstructorTypedPrivateProtectedWithIntentData() + { + var initialText = +@"class C +{ + private readonly int _someInt; + + {|typed:private protected C|} +}"; + var expectedText = +@"class C +{ + private readonly int _someInt; + + private protected C(int someInt) + { + _someInt = someInt; + } +}"; + + // lang=json + var intentData = @"{ ""accessibility"": ""ProtectedAndInternal""}"; + + await VerifyExpectedTextAsync(WellKnownIntents.GenerateConstructor, initialText, expectedText, intentData: intentData).ConfigureAwait(false); + } + [Fact] public async Task GenerateConstructorWithFieldsInPartial() { diff --git a/src/EditorFeatures/CSharpTest/Intents/IntentTestsBase.cs b/src/EditorFeatures/CSharpTest/Intents/IntentTestsBase.cs index 0ce21b0f20430..54a6d6db3e962 100644 --- a/src/EditorFeatures/CSharpTest/Intents/IntentTestsBase.cs +++ b/src/EditorFeatures/CSharpTest/Intents/IntentTestsBase.cs @@ -30,10 +30,10 @@ internal static Task VerifyExpectedTextAsync( string markup, string expectedText, OptionsCollection? options = null, - string? serializedData = null, + string? intentData = null, string? priorText = null) { - return VerifyExpectedTextAsync(intentName, markup, new string[] { }, new string[] { expectedText }, options, serializedData, priorText); + return VerifyExpectedTextAsync(intentName, markup, new string[] { }, new string[] { expectedText }, options, intentData, priorText); } internal static async Task VerifyExpectedTextAsync( @@ -42,7 +42,7 @@ internal static async Task VerifyExpectedTextAsync( string[] additionalDocuments, string[] expectedTexts, OptionsCollection? options = null, - string? serializedData = null, + string? intentData = null, string? priorText = null) { var documentSet = additionalDocuments.Prepend(activeDocument).ToArray(); @@ -75,7 +75,7 @@ internal static async Task VerifyExpectedTextAsync( currentSnapshot, ImmutableArray.Create(rewindTextChange), priorSelection, - serializedData); + intentData: intentData); var results = await intentSource.ComputeIntentsAsync(intentContext, CancellationToken.None).ConfigureAwait(false); // For now, we're just taking the first result to match intellicode behavior. diff --git a/src/EditorFeatures/CSharpTest/Intents/RenameIntentTests.cs b/src/EditorFeatures/CSharpTest/Intents/RenameIntentTests.cs index abf7017193549..3a915102f2d3b 100644 --- a/src/EditorFeatures/CSharpTest/Intents/RenameIntentTests.cs +++ b/src/EditorFeatures/CSharpTest/Intents/RenameIntentTests.cs @@ -150,11 +150,11 @@ void M() private static Task VerifyExpectedRenameAsync(string initialText, string expectedText, string priorText, string newName) { - return VerifyExpectedTextAsync(WellKnownIntents.Rename, initialText, expectedText, serializedData: $"{{ \"newName\": \"{newName}\" }}", priorText: priorText); + return VerifyExpectedTextAsync(WellKnownIntents.Rename, initialText, expectedText, intentData: $"{{ \"newName\": \"{newName}\" }}", priorText: priorText); } private static Task VerifyExpectedRenameAsync(string initialText, string[] additionalText, string[] expectedTexts, string priorText, string newName) { - return VerifyExpectedTextAsync(WellKnownIntents.Rename, initialText, additionalText, expectedTexts, serializedData: $"{{ \"newName\": \"{newName}\" }}", priorText: priorText); + return VerifyExpectedTextAsync(WellKnownIntents.Rename, initialText, additionalText, expectedTexts, intentData: $"{{ \"newName\": \"{newName}\" }}", priorText: priorText); } } diff --git a/src/EditorFeatures/CSharpTest/Interactive/BraceMatching/InteractiveBraceHighlightingTests.cs b/src/EditorFeatures/CSharpTest/Interactive/BraceMatching/InteractiveBraceHighlightingTests.cs index 8a8b2be06ad0a..e977e57d074da 100644 --- a/src/EditorFeatures/CSharpTest/Interactive/BraceMatching/InteractiveBraceHighlightingTests.cs +++ b/src/EditorFeatures/CSharpTest/Interactive/BraceMatching/InteractiveBraceHighlightingTests.cs @@ -7,7 +7,7 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; -using Microsoft.CodeAnalysis.Editor.Implementation.BraceMatching; +using Microsoft.CodeAnalysis.BraceMatching; using Microsoft.CodeAnalysis.Editor.Shared.Utilities; using Microsoft.CodeAnalysis.Editor.Tagging; using Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces; diff --git a/src/EditorFeatures/CSharpTest/IntroduceUsingStatement/IntroduceUsingStatementTests.cs b/src/EditorFeatures/CSharpTest/IntroduceUsingStatement/IntroduceUsingStatementTests.cs index 6c981b1683ab2..3b5a76c08bd61 100644 --- a/src/EditorFeatures/CSharpTest/IntroduceUsingStatement/IntroduceUsingStatementTests.cs +++ b/src/EditorFeatures/CSharpTest/IntroduceUsingStatement/IntroduceUsingStatementTests.cs @@ -143,6 +143,7 @@ void M(System.IDisposable disposable) using (var name = disposable) { } + var ignore = disposable; } }"); @@ -167,6 +168,7 @@ void M(System.IDisposable disposable) using (var name = disposable) { } + var ignore = disposable; } }"); @@ -417,6 +419,7 @@ void M(System.IDisposable disposable) M(null); M(x); } + M(null); } }"); @@ -478,6 +481,7 @@ void M(System.IDisposable disposable) { M(x); } + break; } } @@ -549,6 +553,7 @@ void M() var buffer = reader.GetBuffer(); buffer.Clone(); } + var a = 1; } }"); @@ -592,6 +597,7 @@ void M() var a = number; var b = a; } + var c = 1; } }"); @@ -635,6 +641,7 @@ void M() var a = number; var b = a; } + var c = 1; } }"); @@ -670,6 +677,7 @@ void M() int a = buffer[0], b = a; var c = b; } + var d = 1; } }"); diff --git a/src/EditorFeatures/CSharpTest/InvertIf/InvertIfTests.Elseless.cs b/src/EditorFeatures/CSharpTest/InvertIf/InvertIfTests.Elseless.cs index 106c03b2ab453..821b6b6843eba 100644 --- a/src/EditorFeatures/CSharpTest/InvertIf/InvertIfTests.Elseless.cs +++ b/src/EditorFeatures/CSharpTest/InvertIf/InvertIfTests.Elseless.cs @@ -2,8 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -#nullable disable - using System.Threading.Tasks; using Microsoft.CodeAnalysis.Test.Utilities; using Roslyn.Test.Utilities; diff --git a/src/EditorFeatures/CSharpTest/InvertIf/InvertIfTests.cs b/src/EditorFeatures/CSharpTest/InvertIf/InvertIfTests.cs index fcbab10496bcc..117a43131bd33 100644 --- a/src/EditorFeatures/CSharpTest/InvertIf/InvertIfTests.cs +++ b/src/EditorFeatures/CSharpTest/InvertIf/InvertIfTests.cs @@ -2,10 +2,9 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -#nullable disable - using System.Threading.Tasks; using Microsoft.CodeAnalysis.CodeRefactorings; +using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.InvertIf; using Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.CodeRefactorings; using Microsoft.CodeAnalysis.Test.Utilities; @@ -1132,5 +1131,183 @@ void M(string s) } }"); } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsInvertIf)] + [WorkItem(51359, "https://github.com/dotnet/roslyn/issues/51359")] + public async Task TestIsCheck_CSharp6() + { + await TestInRegularAndScriptAsync( +@"class C +{ + int M() + { + [||]if (c is object) + { + return 1; + } + else + { + return 2; + } + } +}", +@"class C +{ + int M() + { + if (!(c is object)) + { + return 2; + } + else + { + return 1; + } + } +}", parseOptions: CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp6)); + } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsInvertIf)] + [WorkItem(51359, "https://github.com/dotnet/roslyn/issues/51359")] + public async Task TestIsCheck_CSharp8() + { + await TestInRegularAndScriptAsync( +@"class C +{ + int M() + { + [||]if (c is object) + { + return 1; + } + else + { + return 2; + } + } +}", +@"class C +{ + int M() + { + if (c is null) + { + return 2; + } + else + { + return 1; + } + } +}", parseOptions: CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp8)); + } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsInvertIf)] + [WorkItem(51359, "https://github.com/dotnet/roslyn/issues/51359")] + public async Task TestIsCheck_CSharp9() + { + await TestInRegularAndScriptAsync( +@"class C +{ + int M() + { + [||]if (c is object) + { + return 1; + } + else + { + return 2; + } + } +}", +@"class C +{ + int M() + { + if (c is null) + { + return 2; + } + else + { + return 1; + } + } +}", parseOptions: CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp9)); + } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsInvertIf)] + [WorkItem(51359, "https://github.com/dotnet/roslyn/issues/51359")] + public async Task TestIsNotObjectCheck_CSharp8() + { + // Not terrific. But the starting code is not legal C#8 either. In this case because we don't even support + // 'not' patterns wee dont' bother diving into the pattern to negate it, and we instead just negate the + // expression. + await TestInRegularAndScriptAsync( +@"class C +{ + int M() + { + [||]if (c is not object) + { + return 1; + } + else + { + return 2; + } + } +}", +@"class C +{ + int M() + { + if (c is object) + { + return 2; + } + else + { + return 1; + } + } +}", parseOptions: CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp8)); + } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsInvertIf)] + [WorkItem(51359, "https://github.com/dotnet/roslyn/issues/51359")] + public async Task TestIsNotObjectCheck_CSharp9() + { + await TestInRegularAndScriptAsync( +@"class C +{ + int M() + { + [||]if (c is not object) + { + return 1; + } + else + { + return 2; + } + } +}", +@"class C +{ + int M() + { + if (c is not null) + { + return 2; + } + else + { + return 1; + } + } +}", parseOptions: CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp9)); + } } } diff --git a/src/EditorFeatures/CSharpTest/InvertLogical/InvertLogicalTests.cs b/src/EditorFeatures/CSharpTest/InvertLogical/InvertLogicalTests.cs index 25df7fa4ecb7b..3e62a030336c7 100644 --- a/src/EditorFeatures/CSharpTest/InvertLogical/InvertLogicalTests.cs +++ b/src/EditorFeatures/CSharpTest/InvertLogical/InvertLogicalTests.cs @@ -2,13 +2,10 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -#nullable disable - using System.Threading.Tasks; using Microsoft.CodeAnalysis.CodeRefactorings; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.InvertLogical; -using Microsoft.CodeAnalysis.CSharp.Shared.Extensions; using Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.CodeRefactorings; using Microsoft.CodeAnalysis.Test.Utilities; using Roslyn.Test.Utilities; @@ -18,6 +15,7 @@ namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.InvertLogical { public partial class InvertLogicalTests : AbstractCSharpCodeActionTest { + private static readonly ParseOptions CSharp6 = CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp6); private static readonly ParseOptions CSharp8 = CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp8); private static readonly ParseOptions CSharp9 = CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp9); @@ -355,7 +353,7 @@ void M(bool x, int a, object b) { void M(bool x, int a, object b) { - var c = !(a <= 10 || !(b is not string)); + var c = !(a <= 10 || b is string); } }", parseOptions: CSharp8); } @@ -423,6 +421,28 @@ void M(bool x, int a, object b) }", parseOptions: CSharp9); } + [WorkItem(42368, "https://github.com/dotnet/roslyn/issues/42368")] + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsInvertLogical)] + public async Task InvertIsNotNullPattern1_CSharp6() + { + // Result is illegal (uses a constant pattern in c# 6), but the original code was illegal as well. + await TestInRegularAndScriptAsync( +@"class C +{ + void M(bool x, int a, object b) + { + var c = a > 10 [||]&& b is not null; + } +}", +@"class C +{ + void M(bool x, int a, object b) + { + var c = !(a <= 10 || b is null); + } +}", parseOptions: CSharp6); + } + [WorkItem(42368, "https://github.com/dotnet/roslyn/issues/42368")] [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsInvertLogical)] public async Task InvertIsNotNullPattern1_CSharp8() @@ -439,7 +459,7 @@ void M(bool x, int a, object b) { void M(bool x, int a, object b) { - var c = !(a <= 10 || !(b is not null)); + var c = !(a <= 10 || b is null); } }", parseOptions: CSharp8); } @@ -670,7 +690,7 @@ void M(bool x, int a, object b) { void M(bool x, int a, object b) { - var c = !(a <= 10 || !(b is string s)); + var c = !(a <= 10 || b is not string s); } }", parseOptions: CSharp9); } diff --git a/src/EditorFeatures/CSharpTest/NavigateTo/NavigateToTests.cs b/src/EditorFeatures/CSharpTest/NavigateTo/NavigateToTests.cs index ac5f4e8a5ebad..7f9280b87f71c 100644 --- a/src/EditorFeatures/CSharpTest/NavigateTo/NavigateToTests.cs +++ b/src/EditorFeatures/CSharpTest/NavigateTo/NavigateToTests.cs @@ -1521,6 +1521,53 @@ public void Method( { var item = (await _aggregator.GetItemsAsync("Method")).Single(); VerifyNavigateToResultItem(item, "Method", "[|Method|]((int x, Dictionary y), (bool b, global::System.Int32 c))", PatternMatchKind.Exact, NavigateToItemKind.Method, Glyph.MethodPublic, string.Format(FeaturesResources.in_0_project_1, "Goo", "Test")); +}); + } + + [Theory] + [CombinatorialData] + [WorkItem(57873, "https://github.com/dotnet/roslyn/issues/57873")] + public async Task FindRecordMember1(TestHost testHost, Composition composition) + { + await TestAsync( +testHost, composition, @"record Goo(int Member) +{ +}", async w => +{ + var item = (await _aggregator.GetItemsAsync("Member")).Single(x => x.Kind == NavigateToItemKind.Property); + VerifyNavigateToResultItem(item, "Member", "[|Member|]", PatternMatchKind.Exact, NavigateToItemKind.Property, Glyph.PropertyPublic); +}); + } + + [Theory] + [CombinatorialData] + [WorkItem(57873, "https://github.com/dotnet/roslyn/issues/57873")] + public async Task FindRecordMember2(TestHost testHost, Composition composition) + { + await TestAsync( +testHost, composition, @"record Goo(int Member) +{ + public int Member { get; } = Member; +}", async w => +{ + var item = (await _aggregator.GetItemsAsync("Member")).Single(x => x.Kind == NavigateToItemKind.Property); + VerifyNavigateToResultItem(item, "Member", "[|Member|]", PatternMatchKind.Exact, NavigateToItemKind.Property, Glyph.PropertyPublic); +}); + } + + [Theory] + [CombinatorialData] + [WorkItem(57873, "https://github.com/dotnet/roslyn/issues/57873")] + public async Task FindRecordMember3(TestHost testHost, Composition composition) + { + await TestAsync( +testHost, composition, @"record Goo(int Member) +{ + public int Member = Member; +}", async w => +{ + var item = (await _aggregator.GetItemsAsync("Member")).Single(x => x.Kind == NavigateToItemKind.Field); + VerifyNavigateToResultItem(item, "Member", "[|Member|]", PatternMatchKind.Exact, NavigateToItemKind.Field, Glyph.FieldPublic); }); } } diff --git a/src/EditorFeatures/CSharpTest/Organizing/OrganizeTypeDeclarationTests.cs b/src/EditorFeatures/CSharpTest/Organizing/OrganizeTypeDeclarationTests.cs index 99ca6817b62fd..2f66d79bfcfb2 100644 --- a/src/EditorFeatures/CSharpTest/Organizing/OrganizeTypeDeclarationTests.cs +++ b/src/EditorFeatures/CSharpTest/Organizing/OrganizeTypeDeclarationTests.cs @@ -8,7 +8,6 @@ using System.Threading.Tasks; using System.Xml.Linq; using Microsoft.CodeAnalysis.Editor.Commanding.Commands; -using Microsoft.CodeAnalysis.Editor.Implementation.Interactive; using Microsoft.CodeAnalysis.Editor.Implementation.Organizing; using Microsoft.CodeAnalysis.Editor.Shared.Utilities; using Microsoft.CodeAnalysis.Editor.UnitTests; diff --git a/src/EditorFeatures/CSharpTest/PdbSourceDocument/AbstractPdbSourceDocumentTests.cs b/src/EditorFeatures/CSharpTest/PdbSourceDocument/AbstractPdbSourceDocumentTests.cs index 3655a1a69ac16..1e1d5182f492d 100644 --- a/src/EditorFeatures/CSharpTest/PdbSourceDocument/AbstractPdbSourceDocumentTests.cs +++ b/src/EditorFeatures/CSharpTest/PdbSourceDocument/AbstractPdbSourceDocumentTests.cs @@ -15,6 +15,7 @@ using Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces; using Microsoft.CodeAnalysis.Emit; using Microsoft.CodeAnalysis.Host; +using Microsoft.CodeAnalysis.Host.Mef; using Microsoft.CodeAnalysis.MetadataAsSource; using Microsoft.CodeAnalysis.PdbSourceDocument; using Microsoft.CodeAnalysis.Shared.Extensions; @@ -159,6 +160,12 @@ protected static async Task GenerateFileAndVerifyAsync( Assert.Equal(document.FilePath, file.FilePath); + // Mapping the project from the generated document should map back to the original project + var provider = workspace.ExportProvider.GetExportedValues().OfType().Single(); + var mappedProject = provider.MapDocument(document); + Assert.NotNull(mappedProject); + Assert.Equal(project.Id, mappedProject!.Id); + var actual = await document.GetTextAsync(); var actualSpan = file!.IdentifierLocation.SourceSpan; @@ -247,7 +254,11 @@ protected static void CompileTestSource(string path, SourceText source, Project .AddReferences(project.MetadataReferences); IEnumerable? embeddedTexts; - if (sourceLocation == Location.OnDisk) + if (buildReferenceAssembly) + { + embeddedTexts = null; + } + else if (sourceLocation == Location.OnDisk) { embeddedTexts = null; File.WriteAllText(sourceCodePath, source.ToString(), source.Encoding); diff --git a/src/EditorFeatures/CSharpTest/PdbSourceDocument/PdbSourceDocumentTests.cs b/src/EditorFeatures/CSharpTest/PdbSourceDocument/PdbSourceDocumentTests.cs index 81549ce6025f8..b361fffb803e8 100644 --- a/src/EditorFeatures/CSharpTest/PdbSourceDocument/PdbSourceDocumentTests.cs +++ b/src/EditorFeatures/CSharpTest/PdbSourceDocument/PdbSourceDocumentTests.cs @@ -383,6 +383,35 @@ public event System.EventHandler [|E|] { add { } remove { } } await TestAsync(Location.OnDisk, Location.OnDisk, source, c => c.GetMember("C.E"), buildReferenceAssembly: true, expectNullResult: true); } + [Fact] + public async Task ReferenceAssembly_WithImplementation() + { + var source = @" +public class C +{ + // A change + public event System.EventHandler [|E|] { add { } remove { } } +}"; + + await RunTestAsync(async path => + { + MarkupTestFile.GetSpan(source, out var metadataSource, out var expectedSpan); + + // Laziest. Nuget package directory layout. Ever. + Directory.CreateDirectory(Path.Combine(path, "ref")); + Directory.CreateDirectory(Path.Combine(path, "lib")); + + // Compile reference assembly + var sourceText = SourceText.From(metadataSource, encoding: Encoding.UTF8); + var (project, symbol) = await CompileAndFindSymbolAsync(Path.Combine(path, "ref"), Location.Embedded, Location.OnDisk, sourceText, c => c.GetMember("C.E"), buildReferenceAssembly: true); + + // Compile implementation assembly + CompileTestSource(Path.Combine(path, "lib"), sourceText, project, Location.Embedded, Location.Embedded, buildReferenceAssembly: false, windowsPdb: false); + + await GenerateFileAndVerifyAsync(project, symbol, Location.Embedded, metadataSource.ToString(), expectedSpan, expectNullResult: false); + }); + } + [Fact] public async Task NoPdb_NullResult() { diff --git a/src/EditorFeatures/CSharpTest/PullMemberUp/CSharpPullMemberUpTests.cs b/src/EditorFeatures/CSharpTest/PullMemberUp/CSharpPullMemberUpTests.cs index 2623c19486ad4..efbded2ae8309 100644 --- a/src/EditorFeatures/CSharpTest/PullMemberUp/CSharpPullMemberUpTests.cs +++ b/src/EditorFeatures/CSharpTest/PullMemberUp/CSharpPullMemberUpTests.cs @@ -35,13 +35,13 @@ protected override CodeRefactoringProvider CreateCodeRefactoringProvider(Workspa private async Task TestQuickActionNotProvidedAsync( string initialMarkup, - TestParameters parameters = default) + TestParameters? parameters = null) { var service = new TestPullMemberUpService(null, null); - parameters = parameters.WithFixProviderData(service); + var parametersValue = (parameters ?? TestParameters.Default).WithFixProviderData(service); - using var workspace = CreateWorkspaceFromOptions(initialMarkup, parameters); - var (actions, _) = await GetCodeActionsAsync(workspace, parameters); + using var workspace = CreateWorkspaceFromOptions(initialMarkup, parametersValue); + var (actions, _) = await GetCodeActionsAsync(workspace, parametersValue); if (actions.Length == 1) { // The dialog shows up, not quick action @@ -4272,15 +4272,14 @@ internal Task TestWithPullMemberDialogAsync( IEnumerable<(string name, bool makeAbstract)> selection = null, string destinationName = null, int index = 0, - TestParameters parameters = default, + TestParameters? parameters = null, OptionsCollection options = null) { var service = new TestPullMemberUpService(selection, destinationName); return TestInRegularAndScript1Async( initialMarkUp, expectedResult, - index, - parameters.WithFixProviderData(service).WithOptions(options)); + (parameters ?? TestParameters.Default).WithFixProviderData(service).WithOptions(options).WithIndex(index)); } [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsPullMemberUp)] diff --git a/src/EditorFeatures/CSharpTest/QuickInfo/DiagnosticAnalyzerQuickInfoSourceTests.cs b/src/EditorFeatures/CSharpTest/QuickInfo/DiagnosticAnalyzerQuickInfoSourceTests.cs index 2ab0a601f225d..59ee0d46f5c76 100644 --- a/src/EditorFeatures/CSharpTest/QuickInfo/DiagnosticAnalyzerQuickInfoSourceTests.cs +++ b/src/EditorFeatures/CSharpTest/QuickInfo/DiagnosticAnalyzerQuickInfoSourceTests.cs @@ -193,8 +193,7 @@ private static async Task GetQuickinfo(TestWorkspace workspace, D { var diagnosticAnalyzerService = workspace.ExportProvider.GetExportedValue(); var provider = new CSharpDiagnosticAnalyzerQuickInfoProvider(diagnosticAnalyzerService); - var options = SymbolDescriptionOptions.From(document.Project); - var info = await provider.GetQuickInfoAsync(new QuickInfoContext(document, position, options, CancellationToken.None)); + var info = await provider.GetQuickInfoAsync(new QuickInfoContext(document, position, SymbolDescriptionOptions.Default, CancellationToken.None)); return info; } diff --git a/src/EditorFeatures/CSharpTest/QuickInfo/SemanticQuickInfoSourceTests.cs b/src/EditorFeatures/CSharpTest/QuickInfo/SemanticQuickInfoSourceTests.cs index 046a3fe451a93..e1401aad99e31 100644 --- a/src/EditorFeatures/CSharpTest/QuickInfo/SemanticQuickInfoSourceTests.cs +++ b/src/EditorFeatures/CSharpTest/QuickInfo/SemanticQuickInfoSourceTests.cs @@ -8192,5 +8192,40 @@ Hello world Hello world """"""")); } + + [Fact, Trait(Traits.Feature, Traits.Features.QuickInfo)] + public async Task TestArgsInTopLevel() + { + var markup = +@" +forach (var arg in $$args) +{ +} +"; + + await TestWithOptionsAsync( + Options.Regular, markup, + MainDescription($"({FeaturesResources.parameter}) string[] args")); + } + + [Fact, Trait(Traits.Feature, Traits.Features.QuickInfo)] + public async Task TestArgsInNormalProgram() + { + var markup = +@" +class Program +{ + static void Main(string[] args) + { + foreach (var arg in $$args) + { + } + } +} +"; + + await TestAsync(markup, + MainDescription($"({FeaturesResources.parameter}) string[] args")); + } } } diff --git a/src/EditorFeatures/CSharpTest/QuickInfo/SyntacticQuickInfoSourceTests.cs b/src/EditorFeatures/CSharpTest/QuickInfo/SyntacticQuickInfoSourceTests.cs index d7e1c836f5b25..0bb441b549c46 100644 --- a/src/EditorFeatures/CSharpTest/QuickInfo/SyntacticQuickInfoSourceTests.cs +++ b/src/EditorFeatures/CSharpTest/QuickInfo/SyntacticQuickInfoSourceTests.cs @@ -7,6 +7,7 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; +using Microsoft.CodeAnalysis.Classification; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.QuickInfo; using Microsoft.CodeAnalysis.Editor.Host; @@ -568,8 +569,7 @@ protected override async Task AssertNoContentAsync( int position) { var provider = CreateProvider(); - var options = SymbolDescriptionOptions.From(document.Project); - Assert.Null(await provider.GetQuickInfoAsync(new QuickInfoContext(document, position, options, CancellationToken.None))); + Assert.Null(await provider.GetQuickInfoAsync(new QuickInfoContext(document, position, SymbolDescriptionOptions.Default, CancellationToken.None))); } protected override async Task AssertContentIsAsync( @@ -580,8 +580,7 @@ protected override async Task AssertContentIsAsync( string expectedDocumentationComment = null) { var provider = CreateProvider(); - var options = SymbolDescriptionOptions.From(document.Project); - var info = await provider.GetQuickInfoAsync(new QuickInfoContext(document, position, options, CancellationToken.None)); + var info = await provider.GetQuickInfoAsync(new QuickInfoContext(document, position, SymbolDescriptionOptions.Default, CancellationToken.None)); Assert.NotNull(info); Assert.NotEqual(0, info.RelatedSpans.Length); @@ -591,7 +590,7 @@ protected override async Task AssertContentIsAsync( var streamingPresenter = workspace.ExportProvider.GetExport(); var quickInfoItem = await IntellisenseQuickInfoBuilder.BuildItemAsync( trackingSpan.Object, info, document, - threadingContext, operationExecutor, + ClassificationOptions.Default, threadingContext, operationExecutor, AsynchronousOperationListenerProvider.NullListener, streamingPresenter, CancellationToken.None); var containerElement = quickInfoItem.Item as ContainerElement; diff --git a/src/EditorFeatures/CSharpTest/RawStringLiteral/RawStringLiteralCommandHandlerTests.cs b/src/EditorFeatures/CSharpTest/RawStringLiteral/RawStringLiteralCommandHandlerTests.cs index f03f8829765f1..6d5763ad601b9 100644 --- a/src/EditorFeatures/CSharpTest/RawStringLiteral/RawStringLiteralCommandHandlerTests.cs +++ b/src/EditorFeatures/CSharpTest/RawStringLiteral/RawStringLiteralCommandHandlerTests.cs @@ -4,9 +4,7 @@ using System.Linq; using System.Xml.Linq; -using Microsoft.CodeAnalysis.Editor.CSharp.CompleteStatement; using Microsoft.CodeAnalysis.Editor.CSharp.RawStringLiteral; -using Microsoft.CodeAnalysis.Editor.Shared.Options; using Microsoft.CodeAnalysis.Editor.UnitTests; using Microsoft.CodeAnalysis.Test.Utilities; using Microsoft.VisualStudio.Commanding; @@ -120,6 +118,105 @@ public void TestReturnInSixQuotes_Interpolated() """""""); } + [WpfFact] + public void TestReturnInSixQuotesMoreQuotesLaterOn() + { + using var testState = RawStringLiteralTestState.CreateTestState( +@"var v = """"""$$""""""; +Console.WriteLine(""Goo"");"); + + testState.SendReturn(handled: true); + testState.AssertCodeIs( +@"var v = """""" +$${|VirtualSpaces-4:|} + """"""; +Console.WriteLine(""Goo"");"); + } + + [WpfFact] + public void TestReturnInSixQuotesAsArgument1() + { + using var testState = RawStringLiteralTestState.CreateTestState( +@"var v = WriteLine(""""""$$"""""""); + + testState.SendReturn(handled: true); + testState.AssertCodeIs( +@"var v = WriteLine("""""" +$${|VirtualSpaces-4:|} + """""""); + } + + [WpfFact] + public void TestReturnInSixQuotesAsArgument2() + { + using var testState = RawStringLiteralTestState.CreateTestState( +@"var v = WriteLine(""""""$$"""""")"); + + testState.SendReturn(handled: true); + testState.AssertCodeIs( +@"var v = WriteLine("""""" +$${|VirtualSpaces-4:|} + """""")"); + } + + [WpfFact] + public void TestReturnInSixQuotesAsArgument3() + { + using var testState = RawStringLiteralTestState.CreateTestState( +@"var v = WriteLine(""""""$$"""""");"); + + testState.SendReturn(handled: true); + testState.AssertCodeIs( +@"var v = WriteLine("""""" +$${|VirtualSpaces-4:|} + """""");"); + } + + [WpfFact] + public void TestReturnInSixQuotesAsArgument4() + { + using var testState = RawStringLiteralTestState.CreateTestState( +@"var v = WriteLine( + """"""$$"""""""); + + testState.SendReturn(handled: true); + testState.AssertCodeIs( +@"var v = WriteLine( + """""" +$${|VirtualSpaces-4:|} + """""""); + } + + [WpfFact] + public void TestReturnInSixQuotesAsArgument5() + { + using var testState = RawStringLiteralTestState.CreateTestState( +@"var v = WriteLine( + """"""$$"""""")"); + + testState.SendReturn(handled: true); + testState.AssertCodeIs( +@"var v = WriteLine( + """""" +$${|VirtualSpaces-4:|} + """""")"); + } + + [WpfFact] + public void TestReturnInSixQuotesAsArgument6() + { + using var testState = RawStringLiteralTestState.CreateTestState( +@"var v = WriteLine( + """"""$$"""""");"); + + testState.SendReturn(handled: true); + testState.AssertCodeIs( +@"var v = WriteLine( + """""" +$${|VirtualSpaces-4:|} + """""");"); + } + [WpfFact] public void TestReturnInSixQuotesWithSemicolonAfter_Interpolated() { diff --git a/src/EditorFeatures/CSharpTest/SimplifyTypeNames/SimplifyTypeNamesTests.cs b/src/EditorFeatures/CSharpTest/SimplifyTypeNames/SimplifyTypeNamesTests.cs index e10f174cc8304..d0613a9d41ad1 100644 --- a/src/EditorFeatures/CSharpTest/SimplifyTypeNames/SimplifyTypeNamesTests.cs +++ b/src/EditorFeatures/CSharpTest/SimplifyTypeNames/SimplifyTypeNamesTests.cs @@ -4842,7 +4842,7 @@ await TestDiagnosticInfoAsync( ///