[
  {
    "path": ".editorconfig",
    "content": "root = true\n\n[*]\ncharset = utf-8\nindent_style = space\ninsert_final_newline = true\ntrim_trailing_whitespace = true\ndotnet_separate_import_directive_groups = true\ndotnet_sort_system_directives_first = true\nindent_size = 4\n\n[{*.csproj,*.json,*.yml,*.xml,*.props,*.nuspec,*.config}]\nindent_size = 2\n"
  },
  {
    "path": ".gitattributes",
    "content": "###############################################################################\n# Set default behavior to automatically normalize line endings.\n###############################################################################\n* text=auto\n\n###############################################################################\n# Set default behavior for command prompt diff.\n#\n# This is need for earlier builds of msysgit that does not have it on by\n# default for csharp files.\n# Note: This is only used by command line\n###############################################################################\n#*.cs     diff=csharp\n\n###############################################################################\n# Set the merge driver for project and solution files\n#\n# Merging from the command prompt will add diff markers to the files if there\n# are conflicts (Merging from VS is not affected by the settings below, in VS\n# the diff markers are never inserted). Diff markers may cause the following \n# file extensions to fail to load in VS. An alternative would be to treat\n# these files as binary and thus will always conflict and require user\n# intervention with every merge. To do so, just uncomment the entries below\n###############################################################################\n#*.sln       merge=binary\n#*.csproj    merge=binary\n#*.vbproj    merge=binary\n#*.vcxproj   merge=binary\n#*.vcproj    merge=binary\n#*.dbproj    merge=binary\n#*.fsproj    merge=binary\n#*.lsproj    merge=binary\n#*.wixproj   merge=binary\n#*.modelproj merge=binary\n#*.sqlproj   merge=binary\n#*.wwaproj   merge=binary\n\n###############################################################################\n# behavior for image files\n#\n# image files are treated as binary by default.\n###############################################################################\n#*.jpg   binary\n#*.png   binary\n#*.gif   binary\n\n###############################################################################\n# diff behavior for common document formats\n# \n# Convert binary document formats to text before diffing them. This feature\n# is only available from the command line. Turn it on by uncommenting the \n# entries below.\n###############################################################################\n#*.doc   diff=astextplain\n#*.DOC   diff=astextplain\n#*.docx  diff=astextplain\n#*.DOCX  diff=astextplain\n#*.dot   diff=astextplain\n#*.DOT   diff=astextplain\n#*.pdf   diff=astextplain\n#*.PDF   diff=astextplain\n#*.rtf   diff=astextplain\n#*.RTF   diff=astextplain\n"
  },
  {
    "path": ".github/dependabot.yml",
    "content": "version: 2\nupdates:\n  - package-ecosystem: \"gradle\"\n    directory: \"/\"\n    schedule:\n      interval: \"monthly\"\n\n  - package-ecosystem: \"nuget\"\n    directory: \"/build/\"\n    schedule:\n      interval: \"monthly\"\n"
  },
  {
    "path": ".gitignore",
    "content": "## Ignore Visual Studio temporary files, build results, and\n## files generated by popular Visual Studio add-ons.\n##\n## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore\n\n# User-specific files\n*.suo\n*.user\n*.userosscache\n*.sln.docstates\n\n# User-specific files (MonoDevelop/Xamarin Studio)\n*.userprefs\n\n# Build results\n[Dd]ebug/\n[Dd]ebugPublic/\n[Rr]elease/\n[Rr]eleases/\nx64/\nx86/\nbld/\n[Bb]in/\n[Oo]bj/\n[Ll]og/\n\n# Visual Studio 2015/2017 cache/options directory\n.vs/\n# Uncomment if you have tasks that create the project's static files in wwwroot\n#wwwroot/\n\n# Visual Studio 2017 auto generated files\nGenerated\\ Files/\n\n# MSTest test Results\n[Tt]est[Rr]esult*/\n[Bb]uild[Ll]og.*\n\n# NUNIT\n*.VisualState.xml\nTestResult.xml\n\n# Build Results of an ATL Project\n[Dd]ebugPS/\n[Rr]eleasePS/\ndlldata.c\n\n# Benchmark Results\nBenchmarkDotNet.Artifacts/\n\n# .NET Core\nproject.lock.json\nproject.fragment.lock.json\nartifacts/\n**/Properties/launchSettings.json\n\n# StyleCop\nStyleCopReport.xml\n\n# Files built by Visual Studio\n*_i.c\n*_p.c\n*_i.h\n*.ilk\n*.meta\n*.obj\n*.iobj\n*.pch\n*.pdb\n*.ipdb\n*.pgc\n*.pgd\n*.rsp\n*.sbr\n*.tlb\n*.tli\n*.tlh\n*.tmp\n*.tmp_proj\n*.log\n*.vspscc\n*.vssscc\n.builds\n*.pidb\n*.svclog\n*.scc\n\n# Chutzpah Test files\n_Chutzpah*\n\n# Visual C++ cache files\nipch/\n*.aps\n*.ncb\n*.opendb\n*.opensdf\n*.sdf\n*.cachefile\n*.VC.db\n*.VC.VC.opendb\n\n# Visual Studio profiler\n*.psess\n*.vsp\n*.vspx\n*.sap\n\n# Visual Studio Trace Files\n*.e2e\n\n# TFS 2012 Local Workspace\n$tf/\n\n# Guidance Automation Toolkit\n*.gpState\n\n# ReSharper is a .NET coding add-in\n_ReSharper*/\n*.[Rr]e[Ss]harper\n*.DotSettings.user\n\n# JustCode is a .NET coding add-in\n.JustCode\n\n# TeamCity is a build add-in\n_TeamCity*\n\n# DotCover is a Code Coverage Tool\n*.dotCover\n\n# AxoCover is a Code Coverage Tool\n.axoCover/*\n!.axoCover/settings.json\n\n# Visual Studio code coverage results\n*.coverage\n*.coveragexml\n\n# NCrunch\n_NCrunch_*\n.*crunch*.local.xml\nnCrunchTemp_*\n\n# MightyMoose\n*.mm.*\nAutoTest.Net/\n\n# Web workbench (sass)\n.sass-cache/\n\n# Installshield output folder\n[Ee]xpress/\n\n# DocProject is a documentation generator add-in\nDocProject/buildhelp/\nDocProject/Help/*.HxT\nDocProject/Help/*.HxC\nDocProject/Help/*.hhc\nDocProject/Help/*.hhk\nDocProject/Help/*.hhp\nDocProject/Help/Html2\nDocProject/Help/html\n\n# Click-Once directory\npublish/\n\n# Publish Web Output\n*.[Pp]ublish.xml\n*.azurePubxml\n# Note: Comment the next line if you want to checkin your web deploy settings,\n# but database connection strings (with potential passwords) will be unencrypted\n*.pubxml\n*.publishproj\n\n# Microsoft Azure Web App publish settings. Comment the next line if you want to\n# checkin your Azure Web App publish settings, but sensitive information contained\n# in these scripts will be unencrypted\nPublishScripts/\n\n# NuGet Packages\n*.nupkg\n\n# Rider Plugins\n*.zip\n\n# The packages folder can be ignored because of Package Restore\n**/[Pp]ackages/*\n# except build/, which is used as an MSBuild target.\n!**/[Pp]ackages/build/\n# Uncomment if necessary however generally it will be regenerated when needed\n#!**/[Pp]ackages/repositories.config\n# NuGet v3's project.json files produces more ignorable files\n*.nuget.props\n*.nuget.targets\n\n# Microsoft Azure Build Output\ncsx/\n*.build.csdef\n\n# Microsoft Azure Emulator\necf/\nrcf/\n\n# Windows Store app package directories and files\nAppPackages/\nBundleArtifacts/\nPackage.StoreAssociation.xml\n_pkginfo.txt\n*.appx\n\n# Visual Studio cache files\n# files ending in .cache can be ignored\n*.[Cc]ache\n# but keep track of directories ending in .cache\n!*.[Cc]ache/\n\n# Others\nClientBin/\n~$*\n*~\n*.dbmdl\n*.dbproj.schemaview\n*.jfm\n*.pfx\n*.publishsettings\norleans.codegen.cs\n\n# Including strong name files can present a security risk\n# (https://github.com/github/gitignore/pull/2483#issue-259490424)\n#*.snk\n\n# Since there are multiple workflows, uncomment next line to ignore bower_components\n# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)\n#bower_components/\n\n# RIA/Silverlight projects\nGenerated_Code/\n\n# Backup & report files from converting an old project file\n# to a newer Visual Studio version. Backup files are not needed,\n# because we have git ;-)\n_UpgradeReport_Files/\nBackup*/\nUpgradeLog*.XML\nUpgradeLog*.htm\nServiceFabricBackup/\n*.rptproj.bak\n\n# SQL Server files\n*.mdf\n*.ldf\n*.ndf\n\n# Business Intelligence projects\n*.rdl.data\n*.bim.layout\n*.bim_*.settings\n*.rptproj.rsuser\n\n# Microsoft Fakes\nFakesAssemblies/\n\n# GhostDoc plugin setting file\n*.GhostDoc.xml\n\n# Node.js Tools for Visual Studio\n.ntvs_analysis.dat\nnode_modules/\n\n# Visual Studio 6 build log\n*.plg\n\n# Visual Studio 6 workspace options file\n*.opt\n\n# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)\n*.vbw\n\n# Visual Studio LightSwitch build output\n**/*.HTMLClient/GeneratedArtifacts\n**/*.DesktopClient/GeneratedArtifacts\n**/*.DesktopClient/ModelManifest.xml\n**/*.Server/GeneratedArtifacts\n**/*.Server/ModelManifest.xml\n_Pvt_Extensions\n\n# Paket dependency manager\n.paket/paket.exe\npaket-files/\n\n# FAKE - F# Make\n.fake/\n\n# CodeRush\n.cr/\n\n# Python Tools for Visual Studio (PTVS)\n__pycache__/\n*.pyc\n\n# Cake - Uncomment if you are using it\n# tools/**\n# !tools/packages.config\n\n# Tabs Studio\n*.tss\n\n# Telerik's JustMock configuration file\n*.jmconfig\n\n# BizTalk build output\n*.btp.cs\n*.btm.cs\n*.odx.cs\n*.xsd.cs\n\n# OpenCover UI analysis results\nOpenCover/\n\n# Azure Stream Analytics local run output\nASALocalRun/\n\n# MSBuild Binary and Structured Log\n*.binlog\n\n# NVidia Nsight GPU debugger configuration file\n*.nvuser\n\n# MFractors (Xamarin productivity tool) working folder\n.mfractor/\n\n# SonarQube\n.sonarqube/\n\n# Cake\ntools/\n\n# Temp build folder\ntemp/\n\n# Nuke temp files\n.nuke/temp\n\n# Gradle\n.gradle/\ngradle-build/\nbuild/classes/\n\n# Test data\n/test/data/NuGetLocks/\n"
  },
  {
    "path": ".nuke/build.schema.json",
    "content": "{\n  \"$schema\": \"http://json-schema.org/draft-04/schema#\",\n  \"definitions\": {\n    \"Host\": {\n      \"type\": \"string\",\n      \"enum\": [\n        \"AppVeyor\",\n        \"AzurePipelines\",\n        \"Bamboo\",\n        \"Bitbucket\",\n        \"Bitrise\",\n        \"GitHubActions\",\n        \"GitLab\",\n        \"Jenkins\",\n        \"Rider\",\n        \"SpaceAutomation\",\n        \"TeamCity\",\n        \"Terminal\",\n        \"TravisCI\",\n        \"VisualStudio\",\n        \"VSCode\"\n      ]\n    },\n    \"ExecutableTarget\": {\n      \"type\": \"string\",\n      \"enum\": [\n        \"Clean\",\n        \"Compile\",\n        \"Pack\",\n        \"PackRiderPlugin\",\n        \"Sonar\",\n        \"SonarBegin\",\n        \"Test\",\n        \"UpdateBuildVersion\",\n        \"UploadReSharperArtifact\",\n        \"UploadRiderArtifact\"\n      ]\n    },\n    \"Verbosity\": {\n      \"type\": \"string\",\n      \"description\": \"\",\n      \"enum\": [\n        \"Verbose\",\n        \"Normal\",\n        \"Minimal\",\n        \"Quiet\"\n      ]\n    },\n    \"NukeBuild\": {\n      \"properties\": {\n        \"Continue\": {\n          \"type\": \"boolean\",\n          \"description\": \"Indicates to continue a previously failed build attempt\"\n        },\n        \"Help\": {\n          \"type\": \"boolean\",\n          \"description\": \"Shows the help text for this build assembly\"\n        },\n        \"Host\": {\n          \"description\": \"Host for execution. Default is 'automatic'\",\n          \"$ref\": \"#/definitions/Host\"\n        },\n        \"NoLogo\": {\n          \"type\": \"boolean\",\n          \"description\": \"Disables displaying the NUKE logo\"\n        },\n        \"Partition\": {\n          \"type\": \"string\",\n          \"description\": \"Partition to use on CI\"\n        },\n        \"Plan\": {\n          \"type\": \"boolean\",\n          \"description\": \"Shows the execution plan (HTML)\"\n        },\n        \"Profile\": {\n          \"type\": \"array\",\n          \"description\": \"Defines the profiles to load\",\n          \"items\": {\n            \"type\": \"string\"\n          }\n        },\n        \"Root\": {\n          \"type\": \"string\",\n          \"description\": \"Root directory during build execution\"\n        },\n        \"Skip\": {\n          \"type\": \"array\",\n          \"description\": \"List of targets to be skipped. Empty list skips all dependencies\",\n          \"items\": {\n            \"$ref\": \"#/definitions/ExecutableTarget\"\n          }\n        },\n        \"Target\": {\n          \"type\": \"array\",\n          \"description\": \"List of targets to be invoked. Default is '{default_target}'\",\n          \"items\": {\n            \"$ref\": \"#/definitions/ExecutableTarget\"\n          }\n        },\n        \"Verbosity\": {\n          \"description\": \"Logging verbosity during build execution. Default is 'Normal'\",\n          \"$ref\": \"#/definitions/Verbosity\"\n        }\n      }\n    }\n  },\n  \"allOf\": [\n    {\n      \"properties\": {\n        \"Configuration\": {\n          \"type\": \"string\"\n        },\n        \"IsRiderHost\": {\n          \"type\": \"boolean\"\n        },\n        \"Solution\": {\n          \"type\": \"string\",\n          \"description\": \"Path to a solution file that is automatically loaded\"\n        }\n      }\n    },\n    {\n      \"$ref\": \"#/definitions/NukeBuild\"\n    }\n  ]\n}\n"
  },
  {
    "path": ".nuke/parameters.json",
    "content": "{\n  \"$schema\": \"./build.schema.json\",\n  \"Solution\": \"src/ReSharper.Structured.Logging.sln\"\n}"
  },
  {
    "path": "Directory.Build.props",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n\n<Project ToolsVersion=\"4.0\" DefaultTargets=\"Build\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <PropertyGroup>\n    <SdkVersion>2025.1.0</SdkVersion>\n  </PropertyGroup>\n  <!-- https://jetbrains.slack.com/archives/CBZ36NH7C/p1628090127002200 -->\n  <PropertyGroup>\n    <MSBuildWarningsAsMessages>$(MSBuildWarningsAsMessages);MSB3277;MSB3270</MSBuildWarningsAsMessages>\n  </PropertyGroup>\n</Project>\n"
  },
  {
    "path": "LICENSE",
    "content": "MIT License\n\nCopyright (c) 2019 Oleg Shevchenko\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "# ReSharper Structured Logging\n[![Build status](https://ci.appveyor.com/api/projects/status/c4riih64hbd4sebw?svg=true)](https://ci.appveyor.com/project/olsh/resharper-structured-logging)\n[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=resharper-structured-logging&metric=alert_status)](https://sonarcloud.io/dashboard?id=resharper-structured-logging)\n\nAn extension for ReSharper and Rider IDE that highlights structured logging templates and contains some useful analyzers\n\n> [The highlighting is a built-in feature starting from R#/Rider 2021.2](https://github.com/olsh/resharper-structured-logging/issues/35#issuecomment-900883583),\n> but the extension still contains some useful analyzers that are not (yet) implemented by JetBrains team\n\nAt the moment it supports Serilog, NLog, Microsoft.Extensions.Logging and ZLogger\n\n## Installation ReSharper\n\nLook for `Structured Logging` in ReSharper -> Extension manager.\n[JetBrains Plugins Repository](https://plugins.jetbrains.com/plugin/12083-structured-logging)\n\n## Installation Rider\n\nLook for `Structured Logging` in Settings -> Plugins -> Browse repositories.\n[JetBrains Plugins Repository](https://plugins.jetbrains.com/plugin/12832-structured-logging)\n\n## Highlighting\n\n![Highlighting](https://github.com/olsh/resharper-structured-logging/raw/master/images/highlighting.png)\n\n## Analyzers\n\n* [Anonymous object is not destructured](rules/AnonymousObjectDestructuringProblem.md)\n* [Complex object is not destructured](rules/ComplexObjectDestructuringProblem.md)\n* [Complex object is not destructured in context](rules/ComplexObjectInContextDestructuringProblem.md)\n* [Contextual logger mismatch](rules/ContextualLoggerProblem.md)\n* [Exception passed as a template argument](rules/ExceptionPassedAsTemplateArgumentProblem.md)\n* [Duplicate properties in a template](rules/TemplateDuplicatePropertyProblem.md)\n* [Template should be a compile-time constant](rules/TemplateIsNotCompileTimeConstantProblem.md)\n* [Prefer named properties instead of positional ones](rules/PositionalPropertyUsedProblem.md)\n* [Inconsistent log property naming](rules/InconsistentLogPropertyNaming.md)\n* [Inconsistent log property naming in context](rules/InconsistentContextLogPropertyNaming.md)\n* [Log event messages should be fragments, not sentences](rules/LogMessageIsSentenceProblem.md)\n\n## Turning Off Analyzers\n\nIndividual analyzers can be disabled as needed either through code comments or by adding a line to a project's\n`.editorconfig` file.\n\n### Turning Off Via Comments\n\nThe analyzer name can be used as-is in a ReSharper comment to disable an analyzer on a per-file or per-line basis.\nFor example:\n\n```csharp\n// ReSharper disable once TemplateIsNotCompileTimeConstantProblem\n```\n\n### Turning Off Via `.editorconfig`\n\nTo disable an analyzer for an entire directory, you can add a line to a `.editorconfig` file\n([learn more](https://editorconfig.org)). In this case, the analyzer name needs to be converted to `snake_case`, prefixed\nwith `resharper_` and suffixed with `_highlighting`. For example:\n\n```editorconfig\nresharper_template_is_not_compile_time_constant_problem_highlighting = none\n```\n\n## Credits\n\nInspired by [SerilogAnalyzer](https://github.com/Suchiman/SerilogAnalyzer)\n"
  },
  {
    "path": "appveyor.yml",
    "content": "image: Visual Studio 2022\n\nskip_branch_with_pr: true\nskip_tags: true\n\ninstall:\n  - SET JAVA_HOME=C:\\Program Files\\Java\\jdk17\n  - SET PATH=%JAVA_HOME%\\bin;%PATH%\nbuild_script:\n- cmd: >-\n    build.cmd update-build-version\n\n    build.cmd upload-resharper-artifact --configuration Release\n\n    build.cmd upload-rider-artifact --configuration Release --is-rider-host\n\n    build.cmd sonar --configuration Release\ntest: false\n\ncache:\n  - '%USERPROFILE%\\.sonar\\cache'\n  - '.gradle -> build.gradle'\n"
  },
  {
    "path": "build/.editorconfig",
    "content": "[*.cs]\ndotnet_style_qualification_for_field = false:warning\ndotnet_style_qualification_for_property = false:warning\ndotnet_style_qualification_for_method = false:warning\ndotnet_style_qualification_for_event = false:warning\ndotnet_style_require_accessibility_modifiers = never:warning\n\ncsharp_style_expression_bodied_methods = true:silent\ncsharp_style_expression_bodied_properties = true:warning\ncsharp_style_expression_bodied_indexers = true:warning\ncsharp_style_expression_bodied_accessors = true:warning\n"
  },
  {
    "path": "build/Build.cs",
    "content": "using System.Text.RegularExpressions;\n\nusing Nuke.Common;\nusing Nuke.Common.CI;\nusing Nuke.Common.CI.AppVeyor;\nusing Nuke.Common.IO;\nusing Nuke.Common.ProjectModel;\nusing Nuke.Common.Tooling;\nusing Nuke.Common.Tools.DotNet;\nusing Nuke.Common.Tools.NuGet;\nusing Nuke.Common.Tools.NUnit;\nusing Nuke.Common.Tools.SonarScanner;\n\nusing static Nuke.Common.EnvironmentInfo;\nusing static Nuke.Common.Tools.NUnit.NUnitTasks;\nusing static Nuke.Common.Tools.DotNet.DotNetTasks;\nusing static Nuke.Common.Tools.SonarScanner.SonarScannerTasks;\nusing static Nuke.Common.Tools.NuGet.NuGetTasks;\n\n[ShutdownDotNetAfterServerBuild]\nclass Build : NukeBuild\n{\n    public static int Main() => Execute<Build>(x => x.Pack);\n\n    protected override void OnBuildInitialized()\n    {\n        SdkVersion = Project.GetProperty(\"SdkVersion\");\n        SdkVersion.NotNull(\"Unable to detect SDK version\");\n\n        var versionMatch = Regex.Match(SdkVersion, @\"(?<version>[\\d\\.]+)(?<suffix>-.*)?\");\n\n        SdkVersionWithoutSuffix = versionMatch.Groups[\"version\"].ToString();\n        SdkVersionSuffix = versionMatch.Groups[\"suffix\"].ToString();\n\n        ExtensionVersion = AppVeyor == null ? SdkVersion : $\"{versionMatch.Groups[\"version\"]}.{AppVeyor.BuildNumber}{versionMatch.Groups[\"suffix\"]}\";\n        var sdkMatch = Regex.Match(SdkVersion, @\"\\d{2}(\\d{2}).(\\d).*\");\n        WaveMajorVersion = int.Parse(sdkMatch.Groups[1]\n            .Value + sdkMatch.Groups[2]\n            .Value);\n        WaveVersionsRange = $\"{WaveMajorVersion}.0\";\n\n        base.OnBuildInitialized();\n    }\n\n    [CI] readonly AppVeyor AppVeyor;\n\n    [Parameter] readonly string Configuration = \"Release\";\n\n    [Parameter] readonly bool IsRiderHost;\n\n    [Solution] readonly Solution Solution;\n\n    [LocalPath(\"./gradlew.bat\")] readonly Tool Gradle;\n\n    [NuGetPackage(\n        packageId: \"dotnet-cleanup\",\n        packageExecutable: \"cleanup.dll\")]\n    readonly Tool DotNetCleanup;\n\n    string NuGetPackageFileName => $\"{Project.Name}.{ExtensionVersion}.nupkg\";\n\n    string NuGetPackagePath => RootDirectory / NuGetPackageFileName;\n\n    string RiderPackagePath => RootDirectory / \"rider-structured-logging.zip\";\n\n    string SonarQubeApiKey => GetVariable<string>(\"sonar:apikey\");\n\n    Project Project => IsRiderHost\n        ? Solution.GetProject(\"ReSharper.Structured.Logging.Rider\")\n        : Solution.GetProject(\"ReSharper.Structured.Logging\");\n\n    Project TestProject => Solution.GetProject($\"{Project.Name}.Tests\");\n\n    AbsolutePath OutputDirectory => Project.Directory / \"bin\" / Project.Name / Configuration;\n\n    AbsolutePath TestProjectOutputDirectory => TestProject.Directory / \"bin\" / TestProject.Name / Configuration;\n\n    string ExtensionVersion { get; set; }\n\n    string SdkVersion { get; set; }\n\n    string SdkVersionSuffix { get; set; }\n\n    string SdkVersionWithoutSuffix { get; set; }\n\n    string WaveVersionsRange { get; set; }\n\n    int WaveMajorVersion { get; set; }\n\n    Target UpdateBuildVersion => _ => _\n        .Requires(() => AppVeyor)\n        .Executes(() =>\n        {\n            AppVeyor.Instance.UpdateBuildVersion(ExtensionVersion);\n        });\n\n    Target Clean => _ => _\n        .Executes(() =>\n        {\n            DotNetCleanup($\"{Solution.Path} -y -v\");\n        });\n\n    Target Compile => _ => _\n        .DependsOn()\n        .Executes(() =>\n        {\n            DotNetBuild(s => s\n                .SetProjectFile(Project.Path)\n                .SetConfiguration(Configuration)\n                .SetVersionPrefix(ExtensionVersion)\n                .SetOutputDirectory(OutputDirectory));\n        });\n\n    Target Test => _ => _\n        .Executes(() =>\n        {\n            DotNetBuild(s => s\n                .SetProjectFile(TestProject.Path)\n                .SetConfiguration(Configuration)\n                .SetOutputDirectory(TestProjectOutputDirectory));\n\n            NUnit3(s => s.SetInputFiles(TestProjectOutputDirectory / $\"{TestProject.Name}.dll\"));\n        });\n\n    Target Pack => _ => _\n        .DependsOn(Compile)\n        .Requires(() => !IsRiderHost)\n        .Executes(() =>\n        {\n            NuGetPack(s => s\n                .SetTargetPath(BuildProjectDirectory / \"ReSharper.Structured.Logging.nuspec\")\n                .SetVersion(ExtensionVersion)\n                .SetBasePath(OutputDirectory)\n                .AddProperty(\"project\", Project.Name)\n                .AddProperty(\"waveVersion\", WaveVersionsRange)\n                .SetOutputDirectory(RootDirectory));\n        });\n\n    Target PackRiderPlugin => _ => _\n        .DependsOn(Compile)\n        .Requires(() => IsRiderHost)\n        .Executes(() =>\n        {\n            // JetBrains is not very consistent in versioning\n            // https://github.com/olsh/resharper-structured-logging/issues/35#issuecomment-892764206\n            var productVersion = SdkVersionWithoutSuffix.TrimEnd('.', '0');\n            if (!string.IsNullOrEmpty(SdkVersionSuffix))\n            {\n                productVersion += $\"{SdkVersionSuffix.Replace(\"0\", string.Empty).ToUpper()}-SNAPSHOT\";\n            }\n\n            Gradle($\"buildPlugin -PPluginVersion={ExtensionVersion} -PProductVersion={productVersion} -PDotNetOutputDirectory={OutputDirectory} -PDotNetProjectName={Project.Name}\", logger:\n                (_, s) =>\n                {\n                    // Gradle writes warnings to stderr\n                    // By default logger will write stderr as errors\n                    // AppVeyor writes errors as special messages and stops the build if such messages more than 500\n                    // ReSharper disable once TemplateIsNotCompileTimeConstantProblem\n                    Serilog.Log.Debug(s);\n                });\n\n            (RootDirectory / \"gradle-build\" / \"distributions\" / $\"rider-structured-logging-{ExtensionVersion}.zip\").Copy(RiderPackagePath, ExistsPolicy.FileOverwrite);\n        });\n\n    Target SonarBegin => _ => _\n        .Unlisted()\n        .Before(Compile)\n        .Executes(() =>\n        {\n            SonarScannerBegin(s =>\n            {\n                s = s\n                    .SetServer(\"https://sonarcloud.io\")\n                    .SetFramework(\"net5.0\")\n                    .SetLogin(SonarQubeApiKey)\n                    .SetProjectKey(\"resharper-structured-logging\")\n                    .SetName(\"ReSharper Structured Logging\")\n                    .SetOrganization(\"olsh\")\n                    .SetVersion(\"1.0.0.0\");\n\n                if (AppVeyor != null)\n                {\n                    if (AppVeyor.PullRequestNumber != null)\n                    {\n                        s = s\n                            .SetPullRequestKey(AppVeyor.PullRequestNumber.ToString())\n                            .SetPullRequestBase(AppVeyor.RepositoryBranch)\n                            .SetPullRequestBranch(AppVeyor.PullRequestHeadRepositoryBranch);\n                    }\n                    else\n                    {\n                        s = s\n                            .SetBranchName(AppVeyor.RepositoryBranch);\n                    }\n                }\n\n                return s;\n            });\n        });\n\n    Target Sonar => _ => _\n        .DependsOn(SonarBegin, Compile)\n        .Requires(() => !IsRiderHost)\n        .Executes(() =>\n        {\n            SonarScannerEnd(s => s\n                .SetLogin(SonarQubeApiKey)\n                .SetFramework(\"net5.0\"));\n        });\n\n    Target UploadReSharperArtifact => _ => _\n        .DependsOn(Test, Pack)\n        .Requires(() => AppVeyor)\n        .Requires(() => !IsRiderHost)\n        .Executes(() =>\n        {\n            AppVeyor.PushArtifact(NuGetPackagePath);\n        });\n\n    Target UploadRiderArtifact => _ => _\n        .DependsOn(Test, PackRiderPlugin)\n        .Requires(() => AppVeyor)\n        .Requires(() => IsRiderHost)\n        .Executes(() =>\n        {\n            AppVeyor.PushArtifact(RiderPackagePath);\n        });\n}\n"
  },
  {
    "path": "build/Directory.Build.props",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"4.0\" DefaultTargets=\"Build\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n\n  <!-- This file prevents unintended imports of unrelated MSBuild files -->\n  <!-- Uncomment to include parent Directory.Build.props file -->\n  <!--<Import Project=\"$([MSBuild]::GetPathOfFileAbove('Directory.Build.props', '$(MSBuildThisFileDirectory)../'))\" />-->\n\n</Project>\n"
  },
  {
    "path": "build/Directory.Build.targets",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"4.0\" DefaultTargets=\"Build\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n\n  <!-- This file prevents unintended imports of unrelated MSBuild files -->\n  <!-- Uncomment to include parent Directory.Build.targets file -->\n  <!--<Import Project=\"$([MSBuild]::GetPathOfFileAbove('Directory.Build.targets', '$(MSBuildThisFileDirectory)../'))\" />-->\n\n</Project>\n"
  },
  {
    "path": "build/ReSharper.Structured.Logging.nuspec",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n\n<package>\n  <metadata>\n    <id>$project$</id>\n    <version>1.0.0</version>\n    <title>Structured Logging</title>\n    <authors>Oleg Shevchenko</authors>\n    <requireLicenseAcceptance>false</requireLicenseAcceptance>\n    <license type=\"expression\">MIT</license>\n    <projectUrl>https://github.com/olsh/resharper-structured-logging</projectUrl>\n    <description>Contains some useful analyzers for structured logging. Supports Serilog, NLog, and Microsoft.Extensions.Logging.</description>\n    <releaseNotes>https://github.com/olsh/resharper-structured-logging/releases</releaseNotes>\n    <tags>resharper serilog nlog templates logging structuredlogging</tags>\n    <dependencies>\n      <dependency id=\"Wave\" version=\"$waveVersion$\" />\n    </dependencies>\n  </metadata>\n\n  <files>\n    <file src=\"$project$.dll\" target=\"dotFiles\" />\n    <file src=\"$project$.pdb\" target=\"dotFiles\" />\n  </files>\n</package>\n"
  },
  {
    "path": "build/_build.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk\">\n\n  <PropertyGroup>\n    <OutputType>Exe</OutputType>\n    <TargetFramework>net8.0</TargetFramework>\n    <RootNamespace></RootNamespace>\n    <NoWarn>CS0649;CS0169</NoWarn>\n    <NukeRootDirectory>..</NukeRootDirectory>\n    <NukeScriptDirectory>..</NukeScriptDirectory>\n    <NukeTelemetryVersion>1</NukeTelemetryVersion>\n  </PropertyGroup>\n\n  <ItemGroup>\n    <PackageReference Include=\"Nuke.Common\" Version=\"9.0.4\" />\n  </ItemGroup>\n\n  <ItemGroup>\n    <PackageDownload Include=\"dotnet-sonarscanner\" Version=\"[6.2.0]\" />\n    <PackageDownload Include=\"NuGet.CommandLine\" Version=\"[6.9.1]\" />\n    <PackageDownload Include=\"NUnit.ConsoleRunner\" Version=\"[3.17.0]\" />\n    <PackageDownload Include=\"dotnet-cleanup\" Version=\"[0.6.1]\" />\n  </ItemGroup>\n\n</Project>\n"
  },
  {
    "path": "build/_build.csproj.DotSettings",
    "content": "﻿<wpf:ResourceDictionary xml:space=\"preserve\" xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\" xmlns:s=\"clr-namespace:System;assembly=mscorlib\" xmlns:ss=\"urn:shemas-jetbrains-com:settings-storage-xaml\" xmlns:wpf=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\">\n\t<s:String x:Key=\"/Default/CodeInspection/Highlighting/InspectionSeverities/=HeapView_002EDelegateAllocation/@EntryIndexedValue\">DO_NOT_SHOW</s:String>\n\t<s:String x:Key=\"/Default/CodeInspection/Highlighting/InspectionSeverities/=VariableHidesOuterVariable/@EntryIndexedValue\">DO_NOT_SHOW</s:String>\n\t<s:String x:Key=\"/Default/CodeInspection/Highlighting/InspectionSeverities/=ClassNeverInstantiated_002EGlobal/@EntryIndexedValue\">DO_NOT_SHOW</s:String>\n\t<s:String x:Key=\"/Default/CodeInspection/Highlighting/InspectionSeverities/=MemberCanBeMadeStatic_002ELocal/@EntryIndexedValue\">DO_NOT_SHOW</s:String>\n\t<s:String x:Key=\"/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/DEFAULT_INTERNAL_MODIFIER/@EntryValue\">Implicit</s:String>\n\t<s:String x:Key=\"/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/DEFAULT_PRIVATE_MODIFIER/@EntryValue\">Implicit</s:String>\n\t<s:String x:Key=\"/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/METHOD_OR_OPERATOR_BODY/@EntryValue\">ExpressionBody</s:String>\n\t<s:String x:Key=\"/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/ThisQualifier/INSTANCE_MEMBERS_QUALIFY_MEMBERS/@EntryValue\">0</s:String>\n\t<s:String x:Key=\"/Default/CodeStyle/CodeFormatting/CSharpFormat/ANONYMOUS_METHOD_DECLARATION_BRACES/@EntryValue\">NEXT_LINE</s:String>\n\t<s:Boolean x:Key=\"/Default/CodeStyle/CodeFormatting/CSharpFormat/KEEP_USER_LINEBREAKS/@EntryValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_AFTER_INVOCATION_LPAR/@EntryValue\">False</s:Boolean>\n\t<s:Int64 x:Key=\"/Default/CodeStyle/CodeFormatting/CSharpFormat/MAX_ATTRIBUTE_LENGTH_FOR_SAME_LINE/@EntryValue\">120</s:Int64>\n\t<s:String x:Key=\"/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_FIELD_ATTRIBUTE_ON_SAME_LINE_EX/@EntryValue\">IF_OWNER_IS_SINGLE_LINE</s:String>\n\t<s:String x:Key=\"/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_ARGUMENTS_STYLE/@EntryValue\">WRAP_IF_LONG</s:String>\n\t<s:Boolean x:Key=\"/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_SIMPLE_ANONYMOUSMETHOD_ON_SINGLE_LINE/@EntryValue\">False</s:Boolean>\n\t<s:String x:Key=\"/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PrivateInstanceFields/@EntryIndexedValue\">&lt;Policy Inspect=\"True\" Prefix=\"\" Suffix=\"\" Style=\"AaBb\" /&gt;</s:String>\n\t<s:String x:Key=\"/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PrivateStaticFields/@EntryIndexedValue\">&lt;Policy Inspect=\"True\" Prefix=\"\" Suffix=\"\" Style=\"AaBb\" /&gt;</s:String>\n\t<s:String x:Key=\"/Default/CodeStyle/Naming/CSharpNaming/UserRules/=4a98fdf6_002D7d98_002D4f5a_002Dafeb_002Dea44ad98c70c/@EntryIndexedValue\">&lt;Policy&gt;&lt;Descriptor Staticness=\"Instance\" AccessRightKinds=\"Private\" Description=\"Instance fields (private)\"&gt;&lt;ElementKinds&gt;&lt;Kind Name=\"FIELD\" /&gt;&lt;Kind Name=\"READONLY_FIELD\" /&gt;&lt;/ElementKinds&gt;&lt;/Descriptor&gt;&lt;Policy Inspect=\"True\" Prefix=\"\" Suffix=\"\" Style=\"AaBb\" /&gt;&lt;/Policy&gt;</s:String>\n\t<s:String x:Key=\"/Default/CodeStyle/Naming/CSharpNaming/UserRules/=f9fce829_002De6f4_002D4cb2_002D80f1_002D5497c44f51df/@EntryIndexedValue\">&lt;Policy&gt;&lt;Descriptor Staticness=\"Static\" AccessRightKinds=\"Private\" Description=\"Static fields (private)\"&gt;&lt;ElementKinds&gt;&lt;Kind Name=\"FIELD\" /&gt;&lt;/ElementKinds&gt;&lt;/Descriptor&gt;&lt;Policy Inspect=\"True\" Prefix=\"\" Suffix=\"\" Style=\"AaBb\" /&gt;&lt;/Policy&gt;</s:String>\n\t<s:Boolean x:Key=\"/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpAttributeForSingleLineMethodUpgrade/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpKeepExistingMigration/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpPlaceEmbeddedOnSameLineMigration/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpRenamePlacementToArrangementMigration/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpUseContinuousIndentInsideBracesMigration/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EAddAccessorOwnerDeclarationBracesMigration/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002ECSharpPlaceAttributeOnSameLineMigration/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateBlankLinesAroundFieldToBlankLinesAroundProperty/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateThisQualifierSettings/@EntryIndexedValue\">True</s:Boolean>\n\t<s:Boolean x:Key=\"/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EPredefinedNamingRulesToUserRulesUpgrade/@EntryIndexedValue\">True</s:Boolean></wpf:ResourceDictionary>\n"
  },
  {
    "path": "build.cmd",
    "content": ":; set -eo pipefail\n:; SCRIPT_DIR=$(cd \"$( dirname \"${BASH_SOURCE[0]}\" )\" && pwd)\n:; ${SCRIPT_DIR}/build.sh \"$@\"\n:; exit $?\n\n@ECHO OFF\npowershell -ExecutionPolicy ByPass -NoProfile \"%~dp0build.ps1\" %*\n"
  },
  {
    "path": "build.gradle",
    "content": "plugins {\n     id 'org.jetbrains.kotlin.jvm'        version '2.3.10'\n     id 'org.jetbrains.intellij.platform' version '2.11.0'\n}\n\nbuildDir = 'gradle-build'\nversion = ext.PluginVersion\n\ncompileKotlin {\n    kotlinOptions {\n        jvmTarget = \"17\"\n    }\n}\n\nsourceSets {\n    main {\n        java.srcDir      'src/rider/main/kotlin'\n        resources.srcDir 'src/rider/main/resources'\n    }\n}\n\nrepositories {\n    mavenCentral()\n    intellijPlatform {\n        defaultRepositories()\n        jetbrainsRuntime()\n    }\n}\n\ndependencies {\n    intellijPlatform {\n        rider(ProductVersion, false)\n        jetbrainsRuntime()\n    }\n}\n\nintellijPlatform {\n    pluginConfiguration {\n        name = rootProject.name\n    }\n}\n\nprepareSandbox {\n    def dotNetFiles = [\n        \"${DotNetOutputDirectory}/${DotNetProjectName}.dll\",\n        \"${DotNetOutputDirectory}/${DotNetProjectName}.pdb\",\n    ]\n\n    dotNetFiles.forEach { f ->\n        def file = file(f)\n        from(file) {\n            into \"${rootProject.name}/dotnet\"\n        }\n    }\n\n    doLast {\n        dotNetFiles.forEach { f ->\n            if (!file(f).exists()) {\n                throw new RuntimeException(\"File $f does not exist\")\n            }\n        }\n    }\n}\n\nwrapper {\n    gradleVersion    = '8.13'\n    distributionType = Wrapper.DistributionType.ALL\n    distributionUrl  = \"https://cache-redirector.jetbrains.com/services.gradle.org/distributions/gradle-${gradleVersion}-all.zip\"\n}\n"
  },
  {
    "path": "build.ps1",
    "content": "[CmdletBinding()]\nParam(\n    [Parameter(Position=0,Mandatory=$false,ValueFromRemainingArguments=$true)]\n    [string[]]$BuildArguments\n)\n\nWrite-Output \"PowerShell $($PSVersionTable.PSEdition) version $($PSVersionTable.PSVersion)\"\n\nSet-StrictMode -Version 2.0; $ErrorActionPreference = \"Stop\"; $ConfirmPreference = \"None\"; trap { Write-Error $_ -ErrorAction Continue; exit 1 }\n$PSScriptRoot = Split-Path $MyInvocation.MyCommand.Path -Parent\n\n###########################################################################\n# CONFIGURATION\n###########################################################################\n\n$BuildProjectFile = \"$PSScriptRoot\\build\\_build.csproj\"\n$TempDirectory = \"$PSScriptRoot\\\\.nuke\\temp\"\n\n$DotNetGlobalFile = \"$PSScriptRoot\\\\global.json\"\n$DotNetInstallUrl = \"https://dot.net/v1/dotnet-install.ps1\"\n$DotNetChannel = \"Current\"\n\n$env:DOTNET_SKIP_FIRST_TIME_EXPERIENCE = 1\n$env:DOTNET_CLI_TELEMETRY_OPTOUT = 1\n$env:DOTNET_MULTILEVEL_LOOKUP = 0\n\n###########################################################################\n# EXECUTION\n###########################################################################\n\nfunction ExecSafe([scriptblock] $cmd) {\n    & $cmd\n    if ($LASTEXITCODE) { exit $LASTEXITCODE }\n}\n\n# If dotnet CLI is installed globally and it matches requested version, use for execution\nif ($null -ne (Get-Command \"dotnet\" -ErrorAction SilentlyContinue) -and `\n     $(dotnet --version) -and $LASTEXITCODE -eq 0) {\n    $env:DOTNET_EXE = (Get-Command \"dotnet\").Path\n}\nelse {\n    # Download install script\n    $DotNetInstallFile = \"$TempDirectory\\dotnet-install.ps1\"\n    New-Item -ItemType Directory -Path $TempDirectory -Force | Out-Null\n    [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12\n    (New-Object System.Net.WebClient).DownloadFile($DotNetInstallUrl, $DotNetInstallFile)\n\n    # If global.json exists, load expected version\n    if (Test-Path $DotNetGlobalFile) {\n        $DotNetGlobal = $(Get-Content $DotNetGlobalFile | Out-String | ConvertFrom-Json)\n        if ($DotNetGlobal.PSObject.Properties[\"sdk\"] -and $DotNetGlobal.sdk.PSObject.Properties[\"version\"]) {\n            $DotNetVersion = $DotNetGlobal.sdk.version\n        }\n    }\n\n    # Install by channel or version\n    $DotNetDirectory = \"$TempDirectory\\dotnet-win\"\n    if (!(Test-Path variable:DotNetVersion)) {\n        ExecSafe { & $DotNetInstallFile -InstallDir $DotNetDirectory -Channel $DotNetChannel -NoPath }\n    } else {\n        ExecSafe { & $DotNetInstallFile -InstallDir $DotNetDirectory -Version $DotNetVersion -NoPath }\n    }\n    $env:DOTNET_EXE = \"$DotNetDirectory\\dotnet.exe\"\n}\n\nWrite-Output \"Microsoft (R) .NET Core SDK version $(& $env:DOTNET_EXE --version)\"\n\nExecSafe { & $env:DOTNET_EXE build $BuildProjectFile /nodeReuse:false /p:UseSharedCompilation=false -nologo -clp:NoSummary --verbosity quiet }\nExecSafe { & $env:DOTNET_EXE run --project $BuildProjectFile --no-build -- $BuildArguments }\n"
  },
  {
    "path": "build.sh",
    "content": "#!/usr/bin/env bash\n\nbash --version 2>&1 | head -n 1\n\nset -eo pipefail\nSCRIPT_DIR=$(cd \"$( dirname \"${BASH_SOURCE[0]}\" )\" && pwd)\n\n###########################################################################\n# CONFIGURATION\n###########################################################################\n\nBUILD_PROJECT_FILE=\"$SCRIPT_DIR/build/_build.csproj\"\nTEMP_DIRECTORY=\"$SCRIPT_DIR//.nuke/temp\"\n\nDOTNET_GLOBAL_FILE=\"$SCRIPT_DIR//global.json\"\nDOTNET_INSTALL_URL=\"https://dot.net/v1/dotnet-install.sh\"\nDOTNET_CHANNEL=\"Current\"\n\nexport DOTNET_CLI_TELEMETRY_OPTOUT=1\nexport DOTNET_SKIP_FIRST_TIME_EXPERIENCE=1\nexport DOTNET_MULTILEVEL_LOOKUP=0\n\n###########################################################################\n# EXECUTION\n###########################################################################\n\nfunction FirstJsonValue {\n    perl -nle 'print $1 if m{\"'\"$1\"'\": \"([^\"]+)\",?}' <<< \"${@:2}\"\n}\n\n# If dotnet CLI is installed globally and it matches requested version, use for execution\nif [ -x \"$(command -v dotnet)\" ] && dotnet --version &>/dev/null; then\n    export DOTNET_EXE=\"$(command -v dotnet)\"\nelse\n    # Download install script\n    DOTNET_INSTALL_FILE=\"$TEMP_DIRECTORY/dotnet-install.sh\"\n    mkdir -p \"$TEMP_DIRECTORY\"\n    curl -Lsfo \"$DOTNET_INSTALL_FILE\" \"$DOTNET_INSTALL_URL\"\n    chmod +x \"$DOTNET_INSTALL_FILE\"\n\n    # If global.json exists, load expected version\n    if [[ -f \"$DOTNET_GLOBAL_FILE\" ]]; then\n        DOTNET_VERSION=$(FirstJsonValue \"version\" \"$(cat \"$DOTNET_GLOBAL_FILE\")\")\n        if [[ \"$DOTNET_VERSION\" == \"\"  ]]; then\n            unset DOTNET_VERSION\n        fi\n    fi\n\n    # Install by channel or version\n    DOTNET_DIRECTORY=\"$TEMP_DIRECTORY/dotnet-unix\"\n    if [[ -z ${DOTNET_VERSION+x} ]]; then\n        \"$DOTNET_INSTALL_FILE\" --install-dir \"$DOTNET_DIRECTORY\" --channel \"$DOTNET_CHANNEL\" --no-path\n    else\n        \"$DOTNET_INSTALL_FILE\" --install-dir \"$DOTNET_DIRECTORY\" --version \"$DOTNET_VERSION\" --no-path\n    fi\n    export DOTNET_EXE=\"$DOTNET_DIRECTORY/dotnet\"\nfi\n\necho \"Microsoft (R) .NET Core SDK version $(\"$DOTNET_EXE\" --version)\"\n\n\"$DOTNET_EXE\" build \"$BUILD_PROJECT_FILE\" /nodeReuse:false /p:UseSharedCompilation=false -nologo -clp:NoSummary --verbosity quiet\n\"$DOTNET_EXE\" run --project \"$BUILD_PROJECT_FILE\" --no-build -- \"$@\"\n"
  },
  {
    "path": "gradle/wrapper/gradle-wrapper.properties",
    "content": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://cache-redirector.jetbrains.com/services.gradle.org/distributions/gradle-8.13-all.zip\nnetworkTimeout=10000\nvalidateDistributionUrl=true\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\n"
  },
  {
    "path": "gradle.properties",
    "content": "# Any property can be overwritten from command-line via\n#   -P<propertyName>=<value>\n\nPluginVersion=_PLACEHOLDER_\nProductVersion=_PLACEHOLDER_\nDotNetOutputDirectory=./src/ReSharper.Structured.Logging/bin/ReSharper.Structured.Logging.Rider/Debug\nDotNetProjectName=ReSharper.Structured.Logging.Rider\n\n# We need to disable Gradle daemon after build otherwise the build hangs on build server\n# https://github.com/appveyor/ci/issues/1745\norg.gradle.daemon=false\n\n# We need it to avoid bundle Kotlin jars into plugin\nkotlin.stdlib.default.dependency=false\n"
  },
  {
    "path": "gradlew",
    "content": "#!/bin/sh\n\n#\n# Copyright © 2015-2021 the original authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n##############################################################################\n#\n#   Gradle start up script for POSIX generated by Gradle.\n#\n#   Important for running:\n#\n#   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is\n#       noncompliant, but you have some other compliant shell such as ksh or\n#       bash, then to run this script, type that shell name before the whole\n#       command line, like:\n#\n#           ksh Gradle\n#\n#       Busybox and similar reduced shells will NOT work, because this script\n#       requires all of these POSIX shell features:\n#         * functions;\n#         * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,\n#           «${var#prefix}», «${var%suffix}», and «$( cmd )»;\n#         * compound commands having a testable exit status, especially «case»;\n#         * various built-in commands including «command», «set», and «ulimit».\n#\n#   Important for patching:\n#\n#   (2) This script targets any POSIX shell, so it avoids extensions provided\n#       by Bash, Ksh, etc; in particular arrays are avoided.\n#\n#       The \"traditional\" practice of packing multiple parameters into a\n#       space-separated string is a well documented source of bugs and security\n#       problems, so this is (mostly) avoided, by progressively accumulating\n#       options in \"$@\", and eventually passing that to Java.\n#\n#       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,\n#       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;\n#       see the in-line comments for details.\n#\n#       There are tweaks for specific operating systems such as AIX, CygWin,\n#       Darwin, MinGW, and NonStop.\n#\n#   (3) This script is generated from the Groovy template\n#       https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt\n#       within the Gradle project.\n#\n#       You can find Gradle at https://github.com/gradle/gradle/.\n#\n##############################################################################\n\n# Attempt to set APP_HOME\n\n# Resolve links: $0 may be a link\napp_path=$0\n\n# Need this for daisy-chained symlinks.\nwhile\n    APP_HOME=${app_path%\"${app_path##*/}\"}  # leaves a trailing /; empty if no leading path\n    [ -h \"$app_path\" ]\ndo\n    ls=$( ls -ld \"$app_path\" )\n    link=${ls#*' -> '}\n    case $link in             #(\n      /*)   app_path=$link ;; #(\n      *)    app_path=$APP_HOME$link ;;\n    esac\ndone\n\n# This is normally unused\n# shellcheck disable=SC2034\nAPP_BASE_NAME=${0##*/}\nAPP_HOME=$( cd \"${APP_HOME:-./}\" && pwd -P ) || exit\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=maximum\n\nwarn () {\n    echo \"$*\"\n} >&2\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n} >&2\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"$( uname )\" in                #(\n  CYGWIN* )         cygwin=true  ;; #(\n  Darwin* )         darwin=true  ;; #(\n  MSYS* | MINGW* )  msys=true    ;; #(\n  NONSTOP* )        nonstop=true ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=$JAVA_HOME/jre/sh/java\n    else\n        JAVACMD=$JAVA_HOME/bin/java\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=java\n    if ! command -v java >/dev/null 2>&1\n    then\n        die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nfi\n\n# Increase the maximum file descriptors if we can.\nif ! \"$cygwin\" && ! \"$darwin\" && ! \"$nonstop\" ; then\n    case $MAX_FD in #(\n      max*)\n        # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC3045\n        MAX_FD=$( ulimit -H -n ) ||\n            warn \"Could not query maximum file descriptor limit\"\n    esac\n    case $MAX_FD in  #(\n      '' | soft) :;; #(\n      *)\n        # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC3045\n        ulimit -n \"$MAX_FD\" ||\n            warn \"Could not set maximum file descriptor limit to $MAX_FD\"\n    esac\nfi\n\n# Collect all arguments for the java command, stacking in reverse order:\n#   * args from the command line\n#   * the main class name\n#   * -classpath\n#   * -D...appname settings\n#   * --module-path (only if needed)\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.\n\n# For Cygwin or MSYS, switch paths to Windows format before running java\nif \"$cygwin\" || \"$msys\" ; then\n    APP_HOME=$( cygpath --path --mixed \"$APP_HOME\" )\n    CLASSPATH=$( cygpath --path --mixed \"$CLASSPATH\" )\n\n    JAVACMD=$( cygpath --unix \"$JAVACMD\" )\n\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    for arg do\n        if\n            case $arg in                                #(\n              -*)   false ;;                            # don't mess with options #(\n              /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX filepath\n                    [ -e \"$t\" ] ;;                      #(\n              *)    false ;;\n            esac\n        then\n            arg=$( cygpath --path --ignore --mixed \"$arg\" )\n        fi\n        # Roll the args list around exactly as many times as the number of\n        # args, so each arg winds up back in the position where it started, but\n        # possibly modified.\n        #\n        # NB: a `for` loop captures its iteration list before it begins, so\n        # changing the positional parameters here affects neither the number of\n        # iterations, nor the values presented in `arg`.\n        shift                   # remove old arg\n        set -- \"$@\" \"$arg\"      # push replacement arg\n    done\nfi\n\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS='\"-Xmx64m\" \"-Xms64m\"'\n\n# Collect all arguments for the java command;\n#   * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of\n#     shell script including quotes and variable substitutions, so put them in\n#     double quotes to make sure that they get re-expanded; and\n#   * put everything else in single quotes, so that it's not re-expanded.\n\nset -- \\\n        \"-Dorg.gradle.appname=$APP_BASE_NAME\" \\\n        -classpath \"$CLASSPATH\" \\\n        org.gradle.wrapper.GradleWrapperMain \\\n        \"$@\"\n\n# Stop when \"xargs\" is not available.\nif ! command -v xargs >/dev/null 2>&1\nthen\n    die \"xargs is not available\"\nfi\n\n# Use \"xargs\" to parse quoted args.\n#\n# With -n1 it outputs one arg per line, with the quotes and backslashes removed.\n#\n# In Bash we could simply go:\n#\n#   readarray ARGS < <( xargs -n1 <<<\"$var\" ) &&\n#   set -- \"${ARGS[@]}\" \"$@\"\n#\n# but POSIX shell has neither arrays nor command substitution, so instead we\n# post-process each arg (as a line of input to sed) to backslash-escape any\n# character that might be a shell metacharacter, then use eval to reverse\n# that process (while maintaining the separation between arguments), and wrap\n# the whole thing up as a single \"set\" statement.\n#\n# This will of course break if any of these variables contains a newline or\n# an unmatched quote.\n#\n\neval \"set -- $(\n        printf '%s\\n' \"$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\" |\n        xargs -n1 |\n        sed ' s~[^-[:alnum:]+,./:=@_]~\\\\&~g; ' |\n        tr '\\n' ' '\n    )\" '\"$@\"'\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "gradlew.bat",
    "content": "@rem\n@rem Copyright 2015 the original author or authors.\n@rem\n@rem Licensed under the Apache License, Version 2.0 (the \"License\");\n@rem you may not use this file except in compliance with the License.\n@rem You may obtain a copy of the License at\n@rem\n@rem      https://www.apache.org/licenses/LICENSE-2.0\n@rem\n@rem Unless required by applicable law or agreed to in writing, software\n@rem distributed under the License is distributed on an \"AS IS\" BASIS,\n@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n@rem See the License for the specific language governing permissions and\n@rem limitations under the License.\n@rem\n\n@if \"%DEBUG%\"==\"\" @echo off\n@rem ##########################################################################\n@rem\n@rem  Gradle startup script for Windows\n@rem\n@rem ##########################################################################\n\n@rem Set local scope for the variables with windows NT shell\nif \"%OS%\"==\"Windows_NT\" setlocal\n\nset DIRNAME=%~dp0\nif \"%DIRNAME%\"==\"\" set DIRNAME=.\n@rem This is normally unused\nset APP_BASE_NAME=%~n0\nset APP_HOME=%DIRNAME%\n\n@rem Resolve any \".\" and \"..\" in APP_HOME to make it shorter.\nfor %%i in (\"%APP_HOME%\") do set APP_HOME=%%~fi\n\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nset DEFAULT_JVM_OPTS=\"-Xmx64m\" \"-Xms64m\"\n\n@rem Find java.exe\nif defined JAVA_HOME goto findJavaFromJavaHome\n\nset JAVA_EXE=java.exe\n%JAVA_EXE% -version >NUL 2>&1\nif %ERRORLEVEL% equ 0 goto execute\n\necho.\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:findJavaFromJavaHome\nset JAVA_HOME=%JAVA_HOME:\"=%\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\n\nif exist \"%JAVA_EXE%\" goto execute\n\necho.\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:execute\n@rem Setup the command line\n\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\n\n\n@rem Execute Gradle\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %*\n\n:end\n@rem End local scope for the variables with windows NT shell\nif %ERRORLEVEL% equ 0 goto mainEnd\n\n:fail\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\nrem the _cmd.exe /c_ return code!\nset EXIT_CODE=%ERRORLEVEL%\nif %EXIT_CODE% equ 0 set EXIT_CODE=1\nif not \"\"==\"%GRADLE_EXIT_CONSOLE%\" exit %EXIT_CODE%\nexit /b %EXIT_CODE%\n\n:mainEnd\nif \"%OS%\"==\"Windows_NT\" endlocal\n\n:omega\n"
  },
  {
    "path": "rules/AnonymousObjectDestructuringProblem.md",
    "content": "#### Anonymous objects must be destructured\n\nNoncompliant Code Examples:\n```csharp\nLog.Error(\"Processed {Position}\", new { x = 4, y = 2});\n```\n\nCompliant Solution:\n```csharp\nLog.Error(\"Processed {@Position}\", new { x = 4, y = 2});\n```\n"
  },
  {
    "path": "rules/ComplexObjectDestructuringProblem.md",
    "content": "#### Complex objects with default `ToString()` implementation probably need to be destructured \n\nNoncompliant Code Example:\n```csharp\nclass User\n{\n    public int Age { get; set; }\n}\n\n...\n\nLog.Information(\"The user is {MyUser}\", new User());\n```\n\nCompliant Solution:\n```csharp\nclass User\n{\n    public int Age { get; set; }\n}\n\n...\n\nLog.Information(\"The user is {@MyUser}\", new User());\n\n// or\n\nLog.Information(\"The user is {$MyUser}\", new User());\n```\n"
  },
  {
    "path": "rules/ComplexObjectInContextDestructuringProblem.md",
    "content": "#### Complex objects with default `ToString()` implementation probably need to be destructured\n\nNoncompliant Code Example:\n```csharp\nclass User\n{\n    public int Age { get; set; }\n}\n\n...\n\nLogContext.PushProperty(\"User\", new User());\n```\n\nCompliant Solution:\n```csharp\nclass User\n{\n    public int Age { get; set; }\n}\n\n...\n\nLogContext.PushProperty(\"User\", new User(), true);\n\n// or\n\nLogContext.PushProperty(\"User\", new User(), false);\n```\n"
  },
  {
    "path": "rules/ContextualLoggerProblem.md",
    "content": "#### Incorrect type is used for contextual logger\n\nNoncompliant Code Examples:\n```csharp\nclass A\n{\n    private static readonly ILogger Logger = Logger.ForContext<B>();\n}\n\nclass B {} \n```\n\n```csharp\nclass A\n{\n\tILogger<B> _log;\n\t\n\tpublic A(ILogger<B> log)\n\t{\n\t\t_log = log;\n\t}\n}\n\nclass B { } \n```\n\nCompliant Solution:\n```csharp\nclass A\n{\n    private static readonly ILogger Logger = Logger.ForContext<A>();\n}\n\nclass B {} \n```\n\n```csharp\nclass A\n{\n\tILogger<A> _log;\n\t\n\tpublic A(ILogger<A> log)\n\t{\n\t\t_log = log;\n\t}\n}\n\nclass B {} \n```\n"
  },
  {
    "path": "rules/ExceptionPassedAsTemplateArgumentProblem.md",
    "content": "#### Exception passed as a template argument\n\nNoncompliant Code Example:\n```csharp\ncatch (Exception exception)\n{\n   Log.Error(ex, \"Disk quota {Quota} MB exceeded {Exception}\", quota, exception);\n}\n```\n\nCompliant Solution:\n```csharp\ncatch (Exception exception)\n{\n   Log.Error(exception, \"Disk quota {Quota} MB exceeded\", quota);\n}\n```\n"
  },
  {
    "path": "rules/InconsistentContextLogPropertyNaming.md",
    "content": "#### Inconsistent log property naming in context (can be configured in the extension settings)\n\nNoncompliant Code Examples:\n```csharp\nLogContext.PushProperty(\"property_name\", 1);\n```\n\nCompliant Solution:\n```csharp\nLogContext.PushProperty(\"PropertyName\", 1);\n```\n"
  },
  {
    "path": "rules/InconsistentLogPropertyNaming.md",
    "content": "#### Inconsistent log property naming (can be configured in the extension settings)\n\nNoncompliant Code Examples:\n```csharp\nLog.Error(\"Processed {property_name}\", 1);\n```\n\nCompliant Solution:\n```csharp\nLog.Error(\"Processed {PropertyName}\", 1);\n```\n"
  },
  {
    "path": "rules/LogMessageIsSentenceProblem.md",
    "content": "#### Log event messages should be fragments, not sentences\n\n[https://benfoster.io/blog/serilog-best-practices/#message-template-recommendations](https://benfoster.io/blog/serilog-best-practices/#message-template-recommendations)\n\nNoncompliant Code Examples:\n```csharp\nLog.Error(\"Disk quota {Quota} MB exceeded by {User}.\", quota, user);\n```\n\n\nCompliant Solution:\n```csharp\nLog.Error(\"Disk quota {Quota} MB exceeded by {User}\", quota, user);\n```\n"
  },
  {
    "path": "rules/PositionalPropertyUsedProblem.md",
    "content": "#### Prefer named properties instead of positional ones\n\nNoncompliant Code Examples:\n```csharp\nLog.Error(\"Disk quota {0} MB exceeded by {1}\", quota, user);\n```\n\n\nCompliant Solution:\n```csharp\nLog.Error(\"Disk quota {Quota} MB exceeded by {User}\", quota, user);\n```\n"
  },
  {
    "path": "rules/TemplateDuplicatePropertyProblem.md",
    "content": "#### Duplicate template property \n\nNoncompliant Code Example:\n```csharp\nLog.Error(\"Disk quota {Quota} MB exceeded by {Quota}\", quota, user);\n```\n\nCompliant Solution:\n```csharp\nLog.Error(\"Disk quota {Quota} MB exceeded by {User}\", quota, user);\n```\n"
  },
  {
    "path": "rules/TemplateIsNotCompileTimeConstantProblem.md",
    "content": "#### Message template is not a compile time constant\n\nNoncompliant Code Examples:\n```csharp\nLog.Error($\"Disk quota {quota} MB exceeded by {user}\");\n```\n\n```csharp\nLog.Error(string.Format(\"Disk quota {0} MB exceeded by {1}\", quota, user));\n```\n\n\nCompliant Solution:\n```csharp\nLog.Error(\"Disk quota {Quota} MB exceeded by {User}\", quota, user);\n```\n"
  },
  {
    "path": "settings.gradle",
    "content": "rootProject.name = 'rider-structured-logging'\n"
  },
  {
    "path": "src/.idea/.idea.ReSharper.Structured.Logging/.idea/.gitignore",
    "content": "﻿# Default ignored files\n/shelf/\n/workspace.xml\n# Rider ignored files\n/modules.xml\n/contentModel.xml\n/projectSettingsUpdater.xml\n/.idea.ReSharper.Structured.Logging.iml\n# Editor-based HTTP Client requests\n/httpRequests/\n# Datasource local storage ignored files\n/dataSources/\n/dataSources.local.xml\n# GitHub Copilot persisted chat sessions\n/copilot/chatSessions\n"
  },
  {
    "path": "src/.idea/.idea.ReSharper.Structured.Logging/.idea/.name",
    "content": "ReSharper.Structured.Logging"
  },
  {
    "path": "src/.idea/.idea.ReSharper.Structured.Logging/.idea/encodings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"Encoding\" addBOMForNewFiles=\"with BOM under Windows, with no BOM otherwise\" />\n</project>"
  },
  {
    "path": "src/.idea/.idea.ReSharper.Structured.Logging/.idea/indexLayout.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"UserContentModel\">\n    <attachedFolders />\n    <explicitIncludes />\n    <explicitExcludes />\n  </component>\n</project>"
  },
  {
    "path": "src/.idea/.idea.ReSharper.Structured.Logging/.idea/vcs.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"VcsDirectoryMappings\">\n    <mapping directory=\"$PROJECT_DIR$/..\" vcs=\"Git\" />\n  </component>\n</project>"
  },
  {
    "path": "src/.run/Pack ReSharper.run.xml",
    "content": "﻿<component name=\"ProjectRunConfigurationManager\">\n  <configuration default=\"false\" name=\"Pack ReSharper\" type=\"NukeBuildTarget\" factoryName=\".NET Project\">\n    <option name=\"EXE_PATH\" value=\"$PROJECT_DIR$/../build/bin/Debug/_build.exe\" />\n    <option name=\"PROGRAM_PARAMETERS\" value=\"Pack\" />\n    <option name=\"WORKING_DIRECTORY\" value=\"$PROJECT_DIR$/../\" />\n    <option name=\"PASS_PARENT_ENVS\" value=\"1\" />\n    <option name=\"USE_EXTERNAL_CONSOLE\" value=\"0\" />\n    <option name=\"USE_MONO\" value=\"0\" />\n    <option name=\"RUNTIME_ARGUMENTS\" value=\"\" />\n    <option name=\"PROJECT_PATH\" value=\"$PROJECT_DIR$/../build/_build.csproj\" />\n    <option name=\"PROJECT_EXE_PATH_TRACKING\" value=\"1\" />\n    <option name=\"PROJECT_ARGUMENTS_TRACKING\" value=\"1\" />\n    <option name=\"PROJECT_WORKING_DIRECTORY_TRACKING\" value=\"0\" />\n    <option name=\"PROJECT_KIND\" value=\"DotNetCore\" />\n    <option name=\"PROJECT_TFM\" value=\"net6.0\" />\n    <method v=\"2\">\n      <option name=\"Build\" />\n    </method>\n  </configuration>\n</component>"
  },
  {
    "path": "src/.run/Pack Rider.run.xml",
    "content": "﻿<component name=\"ProjectRunConfigurationManager\">\n  <configuration default=\"false\" name=\"Pack Rider\" type=\"NukeBuildTarget\" factoryName=\".NET Project\">\n    <option name=\"EXE_PATH\" value=\"$PROJECT_DIR$/../build/bin/Debug/_build.exe\" />\n    <option name=\"PROGRAM_PARAMETERS\" value=\"PackRiderPlugin --is-rider-host\" />\n    <option name=\"WORKING_DIRECTORY\" value=\"$PROJECT_DIR$/../\" />\n    <option name=\"PASS_PARENT_ENVS\" value=\"1\" />\n    <option name=\"USE_EXTERNAL_CONSOLE\" value=\"0\" />\n    <option name=\"USE_MONO\" value=\"0\" />\n    <option name=\"RUNTIME_ARGUMENTS\" value=\"\" />\n    <option name=\"PROJECT_PATH\" value=\"$PROJECT_DIR$/../build/_build.csproj\" />\n    <option name=\"PROJECT_EXE_PATH_TRACKING\" value=\"1\" />\n    <option name=\"PROJECT_ARGUMENTS_TRACKING\" value=\"1\" />\n    <option name=\"PROJECT_WORKING_DIRECTORY_TRACKING\" value=\"0\" />\n    <option name=\"PROJECT_KIND\" value=\"DotNetCore\" />\n    <option name=\"PROJECT_TFM\" value=\"net6.0\" />\n    <method v=\"2\">\n      <option name=\"Build\" />\n    </method>\n  </configuration>\n</component>"
  },
  {
    "path": "src/.run/Test ReSharper.run.xml",
    "content": "﻿<component name=\"ProjectRunConfigurationManager\">\n  <configuration default=\"false\" name=\"Test ReSharper\" type=\"NukeBuildTarget\" factoryName=\".NET Project\">\n    <option name=\"EXE_PATH\" value=\"$PROJECT_DIR$/../build/bin/Debug/_build.exe\" />\n    <option name=\"PROGRAM_PARAMETERS\" value=\"Test\" />\n    <option name=\"WORKING_DIRECTORY\" value=\"$PROJECT_DIR$/../\" />\n    <option name=\"PASS_PARENT_ENVS\" value=\"1\" />\n    <option name=\"USE_EXTERNAL_CONSOLE\" value=\"0\" />\n    <option name=\"USE_MONO\" value=\"0\" />\n    <option name=\"RUNTIME_ARGUMENTS\" value=\"\" />\n    <option name=\"PROJECT_PATH\" value=\"$PROJECT_DIR$/../build/_build.csproj\" />\n    <option name=\"PROJECT_EXE_PATH_TRACKING\" value=\"1\" />\n    <option name=\"PROJECT_ARGUMENTS_TRACKING\" value=\"1\" />\n    <option name=\"PROJECT_WORKING_DIRECTORY_TRACKING\" value=\"0\" />\n    <option name=\"PROJECT_KIND\" value=\"DotNetCore\" />\n    <option name=\"PROJECT_TFM\" value=\"net6.0\" />\n    <method v=\"2\">\n      <option name=\"Build\" />\n    </method>\n  </configuration>\n</component>"
  },
  {
    "path": "src/.run/Test Rider.run.xml",
    "content": "﻿<component name=\"ProjectRunConfigurationManager\">\n  <configuration default=\"false\" name=\"Test Rider\" type=\"NukeBuildTarget\" factoryName=\".NET Project\">\n    <option name=\"EXE_PATH\" value=\"$PROJECT_DIR$/../build/bin/Debug/_build.exe\" />\n    <option name=\"PROGRAM_PARAMETERS\" value=\"Test --is-rider-host\" />\n    <option name=\"WORKING_DIRECTORY\" value=\"$PROJECT_DIR$/../\" />\n    <option name=\"PASS_PARENT_ENVS\" value=\"1\" />\n    <option name=\"USE_EXTERNAL_CONSOLE\" value=\"0\" />\n    <option name=\"USE_MONO\" value=\"0\" />\n    <option name=\"RUNTIME_ARGUMENTS\" value=\"\" />\n    <option name=\"PROJECT_PATH\" value=\"$PROJECT_DIR$/../build/_build.csproj\" />\n    <option name=\"PROJECT_EXE_PATH_TRACKING\" value=\"1\" />\n    <option name=\"PROJECT_ARGUMENTS_TRACKING\" value=\"1\" />\n    <option name=\"PROJECT_WORKING_DIRECTORY_TRACKING\" value=\"0\" />\n    <option name=\"PROJECT_KIND\" value=\"DotNetCore\" />\n    <option name=\"PROJECT_TFM\" value=\"net6.0\" />\n    <method v=\"2\">\n      <option name=\"Build\" />\n    </method>\n  </configuration>\n</component>"
  },
  {
    "path": "src/ReSharper.Structured.Logging/Analyzer/AnonymousTypeDestructureAnalyzer.cs",
    "content": "using System;\nusing System.Linq;\n\nusing JetBrains.ReSharper.Feature.Services.Daemon;\nusing JetBrains.ReSharper.Psi;\nusing JetBrains.ReSharper.Psi.CodeAnnotations;\nusing JetBrains.ReSharper.Psi.CSharp.Tree;\n\nusing ReSharper.Structured.Logging.Caching;\nusing ReSharper.Structured.Logging.Extensions;\nusing ReSharper.Structured.Logging.Highlighting;\nusing ReSharper.Structured.Logging.Serilog.Parsing;\n\nnamespace ReSharper.Structured.Logging.Analyzer\n{\n    [ElementProblemAnalyzer(typeof(IInvocationExpression))]\n    public class AnonymousTypeDestructureAnalyzer : ElementProblemAnalyzer<IInvocationExpression>\n    {\n        private readonly MessageTemplateParser _messageTemplateParser;\n\n        private readonly Lazy<TemplateParameterNameAttributeProvider> _templateParameterNameAttributeProvider;\n\n        public AnonymousTypeDestructureAnalyzer(MessageTemplateParser messageTemplateParser, CodeAnnotationsCache codeAnnotationsCache)\n        {\n            _messageTemplateParser = messageTemplateParser;\n            _templateParameterNameAttributeProvider = codeAnnotationsCache.GetLazyProvider<TemplateParameterNameAttributeProvider>();\n        }\n\n        protected override void Run(\n            IInvocationExpression element,\n            ElementProblemAnalyzerData data,\n            IHighlightingConsumer consumer)\n        {\n            var templateArgument = element.GetTemplateArgument(_templateParameterNameAttributeProvider.Value);\n            if (templateArgument == null)\n            {\n                return;\n            }\n\n            var anonymousObjectsArguments = element.ArgumentList.Arguments\n                .Where(a => a.Value is IAnonymousObjectCreationExpression)\n                .ToArray();\n            if (anonymousObjectsArguments.Length == 0)\n            {\n                return;\n            }\n\n            var templateText = templateArgument.TryGetTemplateText();\n            if (templateText == null)\n            {\n                return;\n            }\n\n            var messageTemplate = _messageTemplateParser.Parse(templateText);\n            if (messageTemplate.NamedProperties == null)\n            {\n                return;\n            }\n\n            var templateArgumentIndex = templateArgument.IndexOf();\n            foreach (var argument in anonymousObjectsArguments)\n            {\n                var index = argument.IndexOf() - templateArgumentIndex - 1;\n                if (index < messageTemplate.NamedProperties.Length)\n                {\n                    var namedProperty = messageTemplate.NamedProperties[index];\n                    if (namedProperty.Destructuring != Destructuring.Default)\n                    {\n                        continue;\n                    }\n\n                    var tokenInformation = templateArgument.GetTokenInformation(namedProperty);\n                    consumer.AddHighlighting(new AnonymousObjectDestructuringWarning(tokenInformation));\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/ReSharper.Structured.Logging/Analyzer/CompileTimeConstantTemplateAnalyzer.cs",
    "content": "using System;\n\nusing JetBrains.ReSharper.Feature.Services.Daemon;\nusing JetBrains.ReSharper.Psi.CodeAnnotations;\nusing JetBrains.ReSharper.Psi.CSharp.Tree;\n\nusing ReSharper.Structured.Logging.Caching;\nusing ReSharper.Structured.Logging.Extensions;\nusing ReSharper.Structured.Logging.Highlighting;\n\nnamespace ReSharper.Structured.Logging.Analyzer\n{\n    [ElementProblemAnalyzer(typeof(IInvocationExpression))]\n    public class CompileTimeConstantTemplateAnalyzer : ElementProblemAnalyzer<IInvocationExpression>\n    {\n        private readonly Lazy<TemplateParameterNameAttributeProvider> _templateParameterNameAttributeProvider;\n\n        public CompileTimeConstantTemplateAnalyzer(CodeAnnotationsCache codeAnnotationsCache)\n        {\n            _templateParameterNameAttributeProvider = codeAnnotationsCache.GetLazyProvider<TemplateParameterNameAttributeProvider>();\n        }\n\n        protected override void Run(\n            IInvocationExpression element,\n            ElementProblemAnalyzerData data,\n            IHighlightingConsumer consumer)\n        {\n            var templateArgument = element.GetTemplateArgument(_templateParameterNameAttributeProvider.Value);\n            if (templateArgument?.Value == null)\n            {\n                return;\n            }\n\n            if (templateArgument.Value.IsConstantValue())\n            {\n                return;\n            }\n\n            consumer.AddHighlighting(new TemplateIsNotCompileTimeConstantWarning(element, templateArgument));\n        }\n    }\n}\n"
  },
  {
    "path": "src/ReSharper.Structured.Logging/Analyzer/ComplexObjectDestructureAnalyzer.cs",
    "content": "using System;\nusing System.Linq;\n\nusing JetBrains.Metadata.Reader.API;\nusing JetBrains.Metadata.Reader.Impl;\nusing JetBrains.ReSharper.Feature.Services.Daemon;\nusing JetBrains.ReSharper.Psi;\nusing JetBrains.ReSharper.Psi.CodeAnnotations;\nusing JetBrains.ReSharper.Psi.CSharp.Tree;\nusing JetBrains.ReSharper.Psi.Util;\n\nusing ReSharper.Structured.Logging.Caching;\nusing ReSharper.Structured.Logging.Extensions;\nusing ReSharper.Structured.Logging.Highlighting;\nusing ReSharper.Structured.Logging.Serilog.Parsing;\n\nnamespace ReSharper.Structured.Logging.Analyzer\n{\n    [ElementProblemAnalyzer(typeof(IInvocationExpression))]\n    public class ComplexObjectDestructureAnalyzer : ElementProblemAnalyzer<IInvocationExpression>\n    {\n        private static readonly IClrTypeName GenericDictionaryFqn = new ClrTypeName(\"System.Collections.Generic.Dictionary`2\");\n\n        private readonly MessageTemplateParser _messageTemplateParser;\n\n        private readonly Lazy<TemplateParameterNameAttributeProvider> _templateParameterNameAttributeProvider;\n\n        public ComplexObjectDestructureAnalyzer(MessageTemplateParser messageTemplateParser, CodeAnnotationsCache codeAnnotationsCache)\n        {\n            _messageTemplateParser = messageTemplateParser;\n            _templateParameterNameAttributeProvider = codeAnnotationsCache.GetLazyProvider<TemplateParameterNameAttributeProvider>();\n        }\n\n        protected override void Run(\n            IInvocationExpression element,\n            ElementProblemAnalyzerData data,\n            IHighlightingConsumer consumer)\n        {\n            CheckComplexObjectInTemplate(element, consumer);\n            CheckComplexObjectInContext(element, consumer);\n        }\n\n        private void CheckComplexObjectInContext(IInvocationExpression element, IHighlightingConsumer consumer)\n        {\n            if (!element.IsSerilogContextPushPropertyMethod())\n            {\n                return;\n            }\n\n            // Skip the analysis if explicit destructuring specified > 2 parameters\n            if (element.ArgumentList.Arguments.Count != 2)\n            {\n                return;\n            }\n\n            var valueArgument = element.ArgumentList.Arguments[1];\n            if (!CheckIfDestructureNeeded(valueArgument))\n            {\n                return;\n            }\n\n            consumer.AddHighlighting(new ComplexObjectDestructuringInContextWarning(element));\n        }\n\n        private void CheckComplexObjectInTemplate(IInvocationExpression element, IHighlightingConsumer consumer)\n        {\n            var templateArgument = element.GetTemplateArgument(_templateParameterNameAttributeProvider.Value);\n            if (templateArgument == null)\n            {\n                return;\n            }\n\n            var templateText = templateArgument.TryGetTemplateText();\n            if (templateText == null)\n            {\n                return;\n            }\n\n            var messageTemplate = _messageTemplateParser.Parse(templateText);\n            if (messageTemplate.NamedProperties == null)\n            {\n                return;\n            }\n\n            var templateArgumentIndex = templateArgument.IndexOf();\n            var complexObject = element.ArgumentList.Arguments\n                .Where(a => a.IndexOf() > templateArgumentIndex)\n                .Where(CheckIfDestructureNeeded)\n                .ToArray();\n\n            if (complexObject.Length == 0)\n            {\n                return;\n            }\n\n            foreach (var argument in complexObject)\n            {\n                var index = argument.IndexOf() - templateArgumentIndex - 1;\n                if (index < messageTemplate.NamedProperties.Length)\n                {\n                    var namedProperty = messageTemplate.NamedProperties[index];\n                    if (namedProperty.Destructuring != Destructuring.Default)\n                    {\n                        continue;\n                    }\n\n                    consumer.AddHighlighting(\n                        new ComplexObjectDestructuringWarning(templateArgument.GetTokenInformation(namedProperty)));\n                }\n            }\n        }\n\n        // ReSharper disable once CognitiveComplexity\n        private static bool CheckIfDestructureNeeded(ICSharpArgument argument)\n        {\n            bool CheckIfBaseToStringUsed(IType type, bool initialCheck = true)\n            {\n                // If we go through entire hierarchy and if didn't find overriden `ToString()` then this is an issue.\n                // But if the analyzed class is `object` itself, then this is not an issue.\n                if (type.IsObject())\n                {\n                    return !initialCheck;\n                }\n\n                if (type.IsPredefinedNumeric())\n                {\n                    return false;\n                }\n\n                if (type.IsString())\n                {\n                    return false;\n                }\n\n                if (type.IsGuid())\n                {\n                    return false;\n                }\n\n                var classType = type.GetClassType();\n                if (classType == null)\n                {\n                    return false;\n                }\n\n                if (classType.Methods.Any(m => m.IsOverridesObjectToString()))\n                {\n                    return false;\n                }\n\n                return CheckIfBaseToStringUsed(classType.GetBaseClassType(), false);\n            }\n\n            // ReSharper disable once StyleCop.SA1305\n            var iType = argument.GetExpressionType().ToIType();\n            if (iType == null)\n            {\n                return false;\n            }\n\n            if (iType.IsNullable())\n            {\n                var nullable = iType.GetNullableUnderlyingType();\n                if (nullable == null)\n                {\n                    return false;\n                }\n\n                return CheckIfBaseToStringUsed(nullable);\n            }\n\n            if (iType is IDeclaredType declaredType)\n            {\n                if (Equals(declaredType.GetClrName(), GenericDictionaryFqn))\n                {\n                    var argumentType = declaredType.GetFirstGenericArgumentType();\n\n                    return argumentType != null && CheckIfBaseToStringUsed(argumentType);\n                }\n\n                var genericType = CollectionTypeUtil.GetElementTypesForGenericEnumerable(declaredType, false);\n                if (genericType.Count == 1)\n                {\n                    return CheckIfBaseToStringUsed(genericType.Single());\n                }\n            }\n\n            return CheckIfBaseToStringUsed(iType);\n        }\n    }\n}\n"
  },
  {
    "path": "src/ReSharper.Structured.Logging/Analyzer/ContextualLoggerConstructorAnalyzer.cs",
    "content": "﻿using JetBrains.ReSharper.Feature.Services.Daemon;\nusing JetBrains.ReSharper.Psi;\nusing JetBrains.ReSharper.Psi.CSharp.Tree;\nusing JetBrains.ReSharper.Psi.Tree;\nusing JetBrains.ReSharper.Psi.Util;\n\nusing ReSharper.Structured.Logging.Extensions;\nusing ReSharper.Structured.Logging.Highlighting;\n\nnamespace ReSharper.Structured.Logging.Analyzer\n{\n    [ElementProblemAnalyzer(typeof(IConstructorDeclaration))]\n    public class ContextualLoggerConstructorAnalyzer : ElementProblemAnalyzer<IConstructorDeclaration>\n    {\n        // ReSharper disable once CognitiveComplexity\n        protected override void Run(IConstructorDeclaration element, ElementProblemAnalyzerData data, IHighlightingConsumer consumer)\n        {\n            if (element.Params?.ParameterDeclarations == null)\n            {\n                return;\n            }\n\n            foreach (var declaration in element.Params.ParameterDeclarations)\n            {\n                if (!(declaration.Type is IDeclaredType declaredType))\n                {\n                    continue;\n                }\n\n                if (!declaredType.IsGenericMicrosoftExtensionsLogger())\n                {\n                    continue;\n                }\n\n                var argumentType = declaredType.GetFirstGenericArgumentType();\n                if (argumentType == null)\n                {\n                    continue;\n                }\n\n                var containingType = element.DeclaredElement?.GetContainingType();\n                var className = containingType?.GetClrName().FullName;\n                if (className == null)\n                {\n                    continue;\n                }\n\n                if (className.Equals(argumentType.GetClassType()?.GetClrName().FullName))\n                {\n                    continue;\n                }\n\n                consumer.AddHighlighting(new ContextualLoggerWarning(declaration.TypeUsage.GetDocumentRange()));\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/ReSharper.Structured.Logging/Analyzer/ContextualLoggerSerilogFactoryAnalyzer.cs",
    "content": "﻿using JetBrains.ReSharper.Feature.Services.Daemon;\nusing JetBrains.ReSharper.Psi.CSharp.Tree;\nusing JetBrains.ReSharper.Psi.Tree;\n\nusing ReSharper.Structured.Logging.Extensions;\nusing ReSharper.Structured.Logging.Highlighting;\n\nnamespace ReSharper.Structured.Logging.Analyzer\n{\n    [ElementProblemAnalyzer(typeof(IInvocationExpression))]\n    public class ContextualLoggerSerilogFactoryAnalyzer : ElementProblemAnalyzer<IInvocationExpression>\n    {\n        protected override void Run(IInvocationExpression element, ElementProblemAnalyzerData data, IHighlightingConsumer consumer)\n        {\n            if (!element.IsSerilogContextFactoryLogger())\n            {\n                return;\n            }\n\n            var containingNode = element.GetContainingNode<ITypeDeclaration>();\n            if (containingNode == null)\n            {\n                return;\n            }\n\n            var invocationTypeArgument = element.TypeArguments[0]?.GetScalarType()?.GetClrName();\n            if (invocationTypeArgument?.FullName == containingNode.CLRName)\n            {\n                return;\n            }\n\n            consumer.AddHighlighting(new ContextualLoggerWarning(element.GetDocumentRange()));\n        }\n    }\n}\n"
  },
  {
    "path": "src/ReSharper.Structured.Logging/Analyzer/CorrectExceptionPassingAnalyzer.cs",
    "content": "using System;\nusing System.Linq;\nusing JetBrains.Metadata.Reader.API;\nusing JetBrains.ReSharper.Feature.Services.Daemon;\nusing JetBrains.ReSharper.Psi;\nusing JetBrains.ReSharper.Psi.CodeAnnotations;\nusing JetBrains.ReSharper.Psi.CSharp.Tree;\nusing JetBrains.ReSharper.Psi.Util;\n\nusing ReSharper.Structured.Logging.Caching;\nusing ReSharper.Structured.Logging.Extensions;\nusing ReSharper.Structured.Logging.Highlighting;\n\nnamespace ReSharper.Structured.Logging.Analyzer\n{\n    [ElementProblemAnalyzer(typeof(IInvocationExpression))]\n    public class CorrectExceptionPassingAnalyzer : ElementProblemAnalyzer<IInvocationExpression>\n    {\n        private readonly Lazy<TemplateParameterNameAttributeProvider> _templateParameterNameAttributeProvider;\n\n        public CorrectExceptionPassingAnalyzer(CodeAnnotationsCache codeAnnotationsCache)\n        {\n            _templateParameterNameAttributeProvider = codeAnnotationsCache.GetLazyProvider<TemplateParameterNameAttributeProvider>();\n        }\n\n        // ReSharper disable once CognitiveComplexity\n        protected override void Run(\n            IInvocationExpression element,\n            ElementProblemAnalyzerData data,\n            IHighlightingConsumer consumer)\n        {\n            var templateArgument = element.GetTemplateArgument(_templateParameterNameAttributeProvider.Value);\n            if (templateArgument == null)\n            {\n                return;\n            }\n\n            var exceptionType = element.PsiModule.GetPredefinedType().TryGetType(PredefinedType.EXCEPTION_FQN, NullableAnnotation.Unknown);\n            if (exceptionType == null)\n            {\n                return;\n            }\n\n            ICSharpArgument invalidExceptionArgument = FindInvalidExceptionArgument(element, templateArgument, exceptionType);\n            if (invalidExceptionArgument == null)\n            {\n                return;\n            }\n\n            var overloadAvailable = false;\n            var candidates = element.InvocationExpressionReference.GetCandidates().ToArray();\n            var invalidArgumentIndex = invalidExceptionArgument.IndexOf();\n            foreach (var candidate in candidates)\n            {\n                if (!(candidate.GetDeclaredElement() is IMethod declaredElement))\n                {\n                    continue;\n                }\n\n                foreach (var parameter in declaredElement.Parameters)\n                {\n                    if (invalidArgumentIndex <= parameter.IndexOf())\n                    {\n                        break;\n                    }\n\n                    if (parameter.Type.IsSubtypeOf(exceptionType))\n                    {\n                        overloadAvailable = true;\n                        break;\n                    }\n                }\n\n                if (overloadAvailable)\n                {\n                    break;\n                }\n            }\n\n            if (!overloadAvailable)\n            {\n                return;\n            }\n\n            consumer.AddHighlighting(new ExceptionPassedAsTemplateArgumentWarning(invalidExceptionArgument.GetDocumentRange()));\n        }\n\n        private ICSharpArgument FindInvalidExceptionArgument(IInvocationExpression invocationExpression, ICSharpArgument templateArgument, IDeclaredType exceptionType)\n        {\n            var templateArgumentIndex = templateArgument.IndexOf();\n            foreach (var argument in invocationExpression.ArgumentList.Arguments)\n            {\n                var argumentType = argument.Value?.Type();\n                if (!(argumentType is IDeclaredType declaredType))\n                {\n                    continue;\n                }\n\n                if (!declaredType.IsSubtypeOf(exceptionType))\n                {\n                    continue;\n                }\n\n                if (templateArgumentIndex > argument.IndexOf())\n                {\n                    return null;\n                }\n\n                return argument;\n            }\n\n            return null;\n        }\n    }\n}\n"
  },
  {
    "path": "src/ReSharper.Structured.Logging/Analyzer/DuplicatePropertiesTemplateAnalyzer.cs",
    "content": "using System;\nusing System.Linq;\n\nusing JetBrains.ReSharper.Feature.Services.Daemon;\nusing JetBrains.ReSharper.Psi.CodeAnnotations;\nusing JetBrains.ReSharper.Psi.CSharp.Tree;\n\nusing ReSharper.Structured.Logging.Caching;\nusing ReSharper.Structured.Logging.Extensions;\nusing ReSharper.Structured.Logging.Highlighting;\nusing ReSharper.Structured.Logging.Serilog.Parsing;\n\nnamespace ReSharper.Structured.Logging.Analyzer\n{\n    [ElementProblemAnalyzer(typeof(IInvocationExpression))]\n    public class DuplicatePropertiesTemplateAnalyzer : ElementProblemAnalyzer<IInvocationExpression>\n    {\n        private readonly MessageTemplateParser _messageTemplateParser;\n\n        private readonly Lazy<TemplateParameterNameAttributeProvider> _templateParameterNameAttributeProvider;\n\n        public DuplicatePropertiesTemplateAnalyzer(MessageTemplateParser messageTemplateParser, CodeAnnotationsCache codeAnnotationsCache)\n        {\n            _messageTemplateParser = messageTemplateParser;\n            _templateParameterNameAttributeProvider = codeAnnotationsCache.GetLazyProvider<TemplateParameterNameAttributeProvider>();\n        }\n\n        protected override void Run(\n            IInvocationExpression element,\n            ElementProblemAnalyzerData data,\n            IHighlightingConsumer consumer)\n        {\n            var templateArgument = element.GetTemplateArgument(_templateParameterNameAttributeProvider.Value);\n            var templateText = templateArgument?.TryGetTemplateText();\n            if (templateText == null)\n            {\n                return;\n            }\n\n            var messageTemplate = _messageTemplateParser.Parse(templateText);\n            if (messageTemplate.NamedProperties == null)\n            {\n                return;\n            }\n\n            foreach (var duplicates in messageTemplate.NamedProperties\n                .GroupBy(n => n.PropertyName)\n                .Where(g => g.Count() > 1))\n            {\n                foreach (var token in duplicates)\n                {\n                    consumer.AddHighlighting(new DuplicateTemplatePropertyWarning(templateArgument.GetTokenInformation(token)));\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/ReSharper.Structured.Logging/Analyzer/LogMessageIsSentenceAnalyzer.cs",
    "content": "using System;\nusing System.Text.RegularExpressions;\n\nusing JetBrains.ReSharper.Feature.Services.Daemon;\nusing JetBrains.ReSharper.Psi.CodeAnnotations;\nusing JetBrains.ReSharper.Psi.CSharp.Tree;\nusing JetBrains.ReSharper.Psi.Util;\n\nusing ReSharper.Structured.Logging.Caching;\nusing ReSharper.Structured.Logging.Extensions;\nusing ReSharper.Structured.Logging.Highlighting;\n\nnamespace ReSharper.Structured.Logging.Analyzer\n{\n    [ElementProblemAnalyzer(typeof(IInvocationExpression), HighlightingTypes = new[] { typeof(LogMessageIsSentenceWarning) })]\n    public class LogMessageIsSentenceAnalyzer : ElementProblemAnalyzer<IInvocationExpression>\n    {\n        private readonly Lazy<TemplateParameterNameAttributeProvider> _templateParameterNameAttributeProvider;\n\n        private static readonly Regex DotAtTheEnd = new Regex(@\"(?<!\\.)\\.$\", RegexOptions.Compiled);\n\n        public LogMessageIsSentenceAnalyzer(CodeAnnotationsCache codeAnnotationsCache)\n        {\n            _templateParameterNameAttributeProvider = codeAnnotationsCache.GetLazyProvider<TemplateParameterNameAttributeProvider>();\n        }\n\n        protected override void Run(IInvocationExpression element, ElementProblemAnalyzerData data, IHighlightingConsumer consumer)\n        {\n            var templateArgument = element.GetTemplateArgument(_templateParameterNameAttributeProvider.Value);\n            var lastFragmentExpression = templateArgument?.TryCreateLastTemplateFragmentExpression();\n            if (lastFragmentExpression == null)\n            {\n                return;\n            }\n\n            var unquotedText = lastFragmentExpression.Expression.GetUnquotedText();\n            if (!DotAtTheEnd.IsMatch(unquotedText))\n            {\n                return;\n            }\n\n            consumer.AddHighlighting(new LogMessageIsSentenceWarning(lastFragmentExpression, DotAtTheEnd));\n        }\n    }\n}\n"
  },
  {
    "path": "src/ReSharper.Structured.Logging/Analyzer/PositionalPropertiesUsageAnalyzer.cs",
    "content": "using System;\n\nusing JetBrains.ReSharper.Feature.Services.Daemon;\nusing JetBrains.ReSharper.Psi.CodeAnnotations;\nusing JetBrains.ReSharper.Psi.CSharp.Tree;\n\nusing ReSharper.Structured.Logging.Caching;\nusing ReSharper.Structured.Logging.Extensions;\nusing ReSharper.Structured.Logging.Highlighting;\nusing ReSharper.Structured.Logging.Serilog.Parsing;\n\nnamespace ReSharper.Structured.Logging.Analyzer\n{\n    [ElementProblemAnalyzer(typeof(IInvocationExpression))]\n    public class PositionalPropertiesUsageAnalyzer : ElementProblemAnalyzer<IInvocationExpression>\n    {\n        private readonly MessageTemplateParser _messageTemplateParser;\n\n        private readonly Lazy<TemplateParameterNameAttributeProvider> _templateParameterNameAttributeProvider;\n\n        public PositionalPropertiesUsageAnalyzer(MessageTemplateParser messageTemplateParser, CodeAnnotationsCache codeAnnotationsCache)\n        {\n            _messageTemplateParser = messageTemplateParser;\n            _templateParameterNameAttributeProvider = codeAnnotationsCache.GetLazyProvider<TemplateParameterNameAttributeProvider>();\n        }\n\n        protected override void Run(\n            IInvocationExpression element,\n            ElementProblemAnalyzerData data,\n            IHighlightingConsumer consumer)\n        {\n            var templateArgument = element.GetTemplateArgument(_templateParameterNameAttributeProvider.Value);\n            var templateText = templateArgument?.TryGetTemplateText();\n            if (templateText == null)\n            {\n                return;\n            }\n\n            var messageTemplate = _messageTemplateParser.Parse(templateText);\n            if (messageTemplate.PositionalProperties == null)\n            {\n                return;\n            }\n\n            foreach (var property in messageTemplate.PositionalProperties)\n            {\n                consumer.AddHighlighting(new PositionalPropertyUsedWarning(templateArgument.GetTokenInformation(property)));\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/ReSharper.Structured.Logging/Analyzer/PropertiesNamingAnalyzer.cs",
    "content": "using System;\nusing System.Text.RegularExpressions;\n\nusing JetBrains.Application.Settings;\nusing JetBrains.ProjectModel;\nusing JetBrains.ReSharper.Feature.Services.Daemon;\nusing JetBrains.ReSharper.Psi.CodeAnnotations;\nusing JetBrains.ReSharper.Psi.CSharp.Tree;\nusing JetBrains.ReSharper.Psi.Tree;\n\nusing ReSharper.Structured.Logging.Caching;\nusing ReSharper.Structured.Logging.Extensions;\nusing ReSharper.Structured.Logging.Highlighting;\nusing ReSharper.Structured.Logging.Serilog.Parsing;\nusing ReSharper.Structured.Logging.Services;\nusing ReSharper.Structured.Logging.Settings;\n\nnamespace ReSharper.Structured.Logging.Analyzer;\n\n[ElementProblemAnalyzer(typeof(IInvocationExpression))]\npublic class PropertiesNamingAnalyzer : ElementProblemAnalyzer<IInvocationExpression>\n{\n    private readonly MessageTemplateParser _messageTemplateParser;\n\n    private readonly Lazy<TemplateParameterNameAttributeProvider> _templateParameterNameAttributeProvider;\n\n    public PropertiesNamingAnalyzer(MessageTemplateParser messageTemplateParser, CodeAnnotationsCache codeAnnotationsCache)\n    {\n        _messageTemplateParser = messageTemplateParser;\n        _templateParameterNameAttributeProvider = codeAnnotationsCache.GetLazyProvider<TemplateParameterNameAttributeProvider>();\n    }\n\n    protected override void Run(\n        IInvocationExpression element,\n        ElementProblemAnalyzerData data,\n        IHighlightingConsumer consumer)\n    {\n        var settingsStore = element.GetProject()\n            ?.GetSolution()\n            .GetSettingsStore();\n\n        var ignoreRegexString = settingsStore?.GetValue(StructuredLoggingSettingsAccessor.IgnoredPropertiesRegex);\n        var ignoredPropertiesRegex = string.IsNullOrWhiteSpace(ignoreRegexString) ? null : new Regex(ignoreRegexString);\n\n        CheckPropertiesInTemplate(element, consumer, settingsStore, ignoredPropertiesRegex);\n        CheckPropertiesInContext(element, consumer, settingsStore, ignoredPropertiesRegex);\n    }\n\n    private void CheckPropertiesInTemplate(\n        IInvocationExpression element,\n        IHighlightingConsumer consumer,\n        IContextBoundSettingsStore settingsStore,\n        Regex ignoredPropertiesRegex)\n    {\n        var templateArgument = element.GetTemplateArgument(_templateParameterNameAttributeProvider.Value);\n        var templateText = templateArgument?.TryGetTemplateText();\n        if (templateText == null)\n        {\n            return;\n        }\n\n        var messageTemplate = _messageTemplateParser.Parse(templateText);\n        if (messageTemplate.NamedProperties == null)\n        {\n            return;\n        }\n\n        foreach (var property in messageTemplate.NamedProperties)\n        {\n            if (string.IsNullOrEmpty(property.PropertyName))\n            {\n                continue;\n            }\n\n            var suggestedName = GetSuggestedName(property.PropertyName, settingsStore, ignoredPropertiesRegex);\n            if (string.Equals(suggestedName, property.PropertyName))\n            {\n                continue;\n            }\n\n            consumer.AddHighlighting(\n                new InconsistentLogPropertyNamingWarning(templateArgument.GetTokenInformation(property), property,\n                    suggestedName));\n        }\n    }\n\n    private void CheckPropertiesInContext(\n        IInvocationExpression element,\n        IHighlightingConsumer consumer,\n        IContextBoundSettingsStore settingsStore,\n        Regex ignoredPropertiesRegex)\n    {\n        if (!element.IsSerilogContextPushPropertyMethod())\n        {\n            return;\n        }\n\n        if (element.ArgumentList.Arguments.Count < 1)\n        {\n            return;\n        }\n\n        var propertyArgument = element.ArgumentList.Arguments[0];\n\n        var propertyName = string.Empty;\n        propertyArgument.Value?.ConstantValue.IsString(out propertyName);\n        if (string.IsNullOrEmpty(propertyName))\n        {\n            return;\n        }\n\n        var suggestedName = GetSuggestedName(propertyName, settingsStore, ignoredPropertiesRegex);\n        if (string.Equals(propertyName, suggestedName))\n        {\n            return;\n        }\n\n        consumer.AddHighlighting(new InconsistentContextLogPropertyNamingWarning(propertyArgument, propertyName, suggestedName));\n    }\n\n    private string GetSuggestedName(string propertyName, IContextBoundSettingsStore settingsStore, Regex ignoredPropertiesRegex)\n    {\n        if (ignoredPropertiesRegex != null && ignoredPropertiesRegex.IsMatch(propertyName))\n        {\n            return propertyName;\n        }\n\n        return PropertyNameProvider.GetSuggestedName(propertyName, settingsStore);\n    }\n}\n"
  },
  {
    "path": "src/ReSharper.Structured.Logging/Caching/TemplateParameterNameAttributeProvider.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\n\nusing JetBrains.Application.Parts;\nusing JetBrains.ReSharper.Psi;\nusing JetBrains.ReSharper.Psi.CodeAnnotations;\n\nnamespace ReSharper.Structured.Logging.Caching;\n\n[CodeAnnotationProvider(Instantiation.DemandAnyThreadUnsafe)]\npublic class TemplateParameterNameAttributeProvider(\n    AttributeInstancesProvider attributeInstancesProvider,\n    CodeAnnotationsConfiguration codeAnnotationsConfiguration)\n    : CodeAnnotationInfoProvider<ITypeMember, string>(attributeInstancesProvider, codeAnnotationsConfiguration, true)\n{\n    private const string MessageTemplateFormatMethodAttribute = \"MessageTemplateFormatMethodAttribute\";\n\n    protected override string CalculateInfo(ITypeMember attributesOwner, IEnumerable<IAttributeInstance> attributeInstances)\n    {\n        var templateFormatAttribute = attributeInstances\n            .FirstOrDefault(a => string.Equals(a.GetAttributeShortName(), MessageTemplateFormatMethodAttribute, StringComparison.Ordinal));\n\n        if (templateFormatAttribute != null)\n        {\n            return templateFormatAttribute.PositionParameters()\n                .FirstOrDefault()\n                ?.ConstantValue.StringValue;\n        }\n\n        var className = attributesOwner.ContainingType?.GetClrName().FullName;\n        if (className == \"Microsoft.Extensions.Logging.LoggerExtensions\")\n        {\n            return attributesOwner.ShortName == \"BeginScope\" ? \"messageFormat\" : \"message\";\n        }\n\n        if (className == \"ZLogger.ZLoggerExtensions\")\n        {\n            return \"format\";\n        }\n\n        return null;\n    }\n\n    protected override string GetDefaultInfo(ITypeMember attributesOwner)\n    {\n        return null;\n    }\n}\n"
  },
  {
    "path": "src/ReSharper.Structured.Logging/Extensions/PsiExtensions.cs",
    "content": "using System.Collections.Generic;\nusing System.Linq;\n\nusing JetBrains.Annotations;\nusing JetBrains.DocumentModel;\nusing JetBrains.Metadata.Reader.API;\nusing JetBrains.Metadata.Reader.Impl;\nusing JetBrains.ReSharper.Psi;\nusing JetBrains.ReSharper.Psi.CSharp.Impl.Resolve;\nusing JetBrains.ReSharper.Psi.CSharp.Parsing;\nusing JetBrains.ReSharper.Psi.CSharp.Tree;\nusing JetBrains.ReSharper.Psi.Tree;\nusing JetBrains.ReSharper.Psi.Util;\nusing JetBrains.Util;\n\nusing ReSharper.Structured.Logging.Caching;\nusing ReSharper.Structured.Logging.Models;\nusing ReSharper.Structured.Logging.Serilog.Parsing;\n\nnamespace ReSharper.Structured.Logging.Extensions\n{\n    public static class PsiExtensions\n    {\n        private static readonly IClrTypeName LogContextFqn = new ClrTypeName(\"Serilog.Context.LogContext\");\n\n        [CanBeNull]\n        public static ICSharpArgument GetTemplateArgument(this IInvocationExpression invocationExpression, TemplateParameterNameAttributeProvider templateParameterNameAttributeProvider)\n        {\n            if (!(invocationExpression.Reference.Resolve().DeclaredElement is ITypeMember typeMember))\n            {\n                return null;\n            }\n\n            var templateParameterName = templateParameterNameAttributeProvider.GetInfo(typeMember);\n            if (string.IsNullOrEmpty(templateParameterName))\n            {\n                return null;\n            }\n\n            foreach (var argument in invocationExpression.ArgumentList.Arguments)\n            {\n                if (argument.MatchingParameter?.Element.ShortName == templateParameterName)\n                {\n                    return argument;\n                }\n            }\n\n            return null;\n        }\n\n        public static MessageTemplateTokenInformation GetTokenInformation(this ICSharpArgument argument, MessageTemplateToken token)\n        {\n            var (tokenTextRange, tokenArgument) = FindTokenTextRange(argument, token);\n            var tokenDocument = argument.GetDocumentRange().Document;\n            var documentRange = new DocumentRange(tokenDocument, tokenTextRange);\n\n            return new MessageTemplateTokenInformation(documentRange, tokenArgument);\n        }\n\n        // ReSharper disable once CognitiveComplexity\n        private static (TextRange, IStringLiteralAlterer) FindTokenTextRange(this ICSharpArgument argument, MessageTemplateToken token)\n        {\n            if (argument.Value is IAdditiveExpression additiveExpression && additiveExpression.ConstantValue.IsString())\n            {\n                var arguments = new LinkedList<ExpressionArgumentInfo>();\n                FlattenAdditiveExpression(additiveExpression, arguments);\n\n                var globalOffset = 0;\n                foreach (var additiveArgument in arguments)\n                {\n                    var range = additiveArgument.GetDocumentRange();\n                    var start = range.StartOffset.Offset;\n                    var end = range.EndOffset.Offset;\n\n                    // Usually there are two quotes in the string expression\n                    // But if it's a verbatim string, we should count @ symbol as well\n                    var isVerbatimString = additiveArgument.Expression.IsVerbatimString();\n                    var nonTemplateTokenCount = isVerbatimString ? 3 : 2;\n\n                    // The token index is zero-based so we need to subtract 1\n                    if (token.StartIndex < end - start - 1 - nonTemplateTokenCount + globalOffset)\n                    {\n                        var tokenStartIndex = start + token.StartIndex - globalOffset + 1;\n                        if (isVerbatimString)\n                        {\n                            tokenStartIndex++;\n                        }\n\n                        var tokenEndIndex = tokenStartIndex + token.Length;\n\n                        return (new TextRange(tokenStartIndex, end > tokenEndIndex ? tokenEndIndex : end), StringLiteralAltererUtil.TryCreateStringLiteralByExpression(additiveArgument.Expression));\n                    }\n\n                    globalOffset += end - start - nonTemplateTokenCount;\n                }\n            }\n\n            var startOffset = argument.GetDocumentRange().TextRange.StartOffset + token.StartIndex + 1;\n            if (argument.Expression.IsVerbatimString())\n            {\n                startOffset++;\n            }\n\n            // ReSharper disable once AssignNullToNotNullAttribute\n            return (new TextRange(startOffset, startOffset + token.Length), StringLiteralAltererUtil.TryCreateStringLiteralByExpression(argument.Expression));\n        }\n\n        public static string TryGetTemplateText(this ICSharpArgument argument)\n        {\n            if (argument.Value is IAdditiveExpression additiveExpression && additiveExpression.ConstantValue.IsString())\n            {\n                var linkedList = new LinkedList<ExpressionArgumentInfo>();\n                FlattenAdditiveExpression(additiveExpression, linkedList);\n\n                return string.Join(string.Empty, linkedList.Select(l => l.Expression.GetExpressionText()));\n            }\n\n            return argument.Value.GetExpressionText();\n        }\n\n        [CanBeNull]\n        public static IStringLiteralAlterer TryCreateLastTemplateFragmentExpression(this ICSharpArgument argument)\n        {\n            if (argument.Value is IAdditiveExpression additiveExpression && additiveExpression.ConstantValue.IsString())\n            {\n                var argumentInfo = additiveExpression.Arguments.Last();\n                if (argumentInfo is ExpressionArgumentInfo expressionArgumentInfo)\n                {\n                    return StringLiteralAltererUtil.TryCreateStringLiteralByExpression(expressionArgumentInfo.Expression);\n                }\n\n                return null;\n            }\n\n            return argument.Value == null ? null : StringLiteralAltererUtil.TryCreateStringLiteralByExpression(argument.Value);\n        }\n\n        public static bool IsGenericMicrosoftExtensionsLogger([NotNull]this IDeclaredType declared)\n        {\n            return declared.GetClrName().FullName == \"Microsoft.Extensions.Logging.ILogger`1\";\n        }\n\n        public static bool IsSerilogContextFactoryLogger([NotNull]this IInvocationExpression invocationExpression)\n        {\n            if (invocationExpression.TypeArguments.Count != 1)\n            {\n                return false;\n            }\n\n            var declaredElement = invocationExpression.Reference.Resolve().DeclaredElement as IClrDeclaredElement;\n            var containingType = declaredElement?.GetContainingType();\n            if (containingType == null)\n            {\n                return false;\n            }\n\n            if (containingType.GetClrName().FullName == \"Serilog.ILogger\" && declaredElement.ShortName == \"ForContext\")\n            {\n                return true;\n            }\n\n            return false;\n        }\n\n        public static bool IsSerilogContextPushPropertyMethod(this IInvocationExpression invocationExpression)\n        {\n            var typeMember = invocationExpression.Reference.Resolve().DeclaredElement as ITypeMember;\n            var containingType = typeMember?.GetContainingType();\n            if (containingType == null)\n            {\n                return false;\n            }\n\n            return LogContextFqn.Equals(containingType.GetClrName()) && typeMember.ShortName == \"PushProperty\";\n        }\n\n        [CanBeNull]\n        public static IType GetFirstGenericArgumentType([NotNull]this IDeclaredType declared)\n        {\n            var substitution = declared.GetSubstitution();\n            var typeParameter = substitution.Domain.FirstOrDefault();\n            if (typeParameter == null)\n            {\n                return null;\n            }\n\n            return substitution.Apply(typeParameter);\n        }\n\n        private static bool IsVerbatimString([CanBeNull]this IExpression expression)\n        {\n            return expression?.FirstChild?.NodeType == CSharpTokenType.STRING_LITERAL_VERBATIM;\n        }\n\n        private static string GetExpressionText(this ICSharpExpression expression)\n        {\n            if (expression == null)\n            {\n                return null;\n            }\n\n            var stringLiteral = StringLiteralAltererUtil.TryCreateStringLiteralByExpression(expression);\n            if (stringLiteral == null)\n            {\n                return null;\n            }\n\n            var expressionText = stringLiteral.Expression.GetText();\n            if (expressionText.StartsWith(\"@\"))\n            {\n                expressionText = expressionText.Substring(1);\n            }\n\n            return StringUtil.Unquote(expressionText);\n        }\n\n        private static void FlattenAdditiveExpression(IAdditiveExpression additiveExpression, LinkedList<ExpressionArgumentInfo> list)\n        {\n            foreach (var argumentInfo in additiveExpression.Arguments)\n            {\n                if (argumentInfo is ExpressionArgumentInfo expressionArgumentInfo && expressionArgumentInfo.Expression is IAdditiveExpression additive)\n                {\n                    FlattenAdditiveExpression(additive, list);\n\n                    continue;\n                }\n\n                list.AddLast((ExpressionArgumentInfo)argumentInfo);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/ReSharper.Structured.Logging/Highlighting/AnonymousObjectWithoutDestructuringWarning.cs",
    "content": "using JetBrains.DocumentModel;\nusing JetBrains.ReSharper.Feature.Services.Daemon;\nusing JetBrains.ReSharper.Psi.CSharp;\n\nusing ReSharper.Structured.Logging.Models;\nusing ReSharper.Structured.Logging.Settings;\n\nnamespace ReSharper.Structured.Logging.Highlighting\n{\n    [RegisterConfigurableSeverity(\n        SeverityId,\n        null,\n        StructuredLoggingGroup.Id,\n        Message,\n        Message,\n        Severity.WARNING)]\n    [ConfigurableSeverityHighlighting(\n        SeverityId,\n        CSharpLanguage.Name,\n        OverlapResolve = OverlapResolveKind.WARNING,\n        ToolTipFormatString = Message)]\n    public class AnonymousObjectDestructuringWarning : IHighlighting\n    {\n        private const string Message = \"Anonymous objects must be destructured\";\n\n        public const string SeverityId = \"AnonymousObjectDestructuringProblem\";\n\n        public AnonymousObjectDestructuringWarning(MessageTemplateTokenInformation tokenInformation)\n        {\n            TokenInformation = tokenInformation;\n        }\n\n        public string ErrorStripeToolTip => ToolTip;\n\n        public MessageTemplateTokenInformation TokenInformation { get; }\n\n        public string ToolTip => Message;\n\n        public DocumentRange CalculateRange()\n        {\n            return TokenInformation.DocumentRange;\n        }\n\n        public bool IsValid()\n        {\n            return TokenInformation.DocumentRange.IsValid();\n        }\n    }\n}\n"
  },
  {
    "path": "src/ReSharper.Structured.Logging/Highlighting/ComplexObjectDestructuringInContextWarning.cs",
    "content": "using JetBrains.DocumentModel;\nusing JetBrains.ReSharper.Feature.Services.Daemon;\nusing JetBrains.ReSharper.Psi.CSharp;\nusing JetBrains.ReSharper.Psi.CSharp.Tree;\nusing JetBrains.ReSharper.Psi.Tree;\n\nusing ReSharper.Structured.Logging.Settings;\n\nnamespace ReSharper.Structured.Logging.Highlighting\n{\n    [RegisterConfigurableSeverity(\n        SeverityId,\n        null,\n        StructuredLoggingGroup.Id,\n        Message,\n        Message,\n        Severity.WARNING)]\n    [ConfigurableSeverityHighlighting(\n        SeverityId,\n        CSharpLanguage.Name,\n        OverlapResolve = OverlapResolveKind.WARNING,\n        ToolTipFormatString = Message)]\n    public class ComplexObjectDestructuringInContextWarning : ComplexObjectDestructuringWarningBase, IHighlighting\n    {\n        public const string SeverityId = \"ComplexObjectInContextDestructuringProblem\";\n\n        private readonly IInvocationExpression _invocationExpression;\n\n        public ComplexObjectDestructuringInContextWarning(IInvocationExpression invocationExpression)\n        {\n            _invocationExpression = invocationExpression;\n        }\n\n        public string ErrorStripeToolTip => ToolTip;\n\n        public string ToolTip => Message;\n\n        public DocumentRange CalculateRange()\n        {\n            return _invocationExpression.GetDocumentRange();\n        }\n\n        public bool IsValid()\n        {\n            return _invocationExpression.GetDocumentRange().IsValid();\n        }\n    }\n}\n"
  },
  {
    "path": "src/ReSharper.Structured.Logging/Highlighting/ComplexObjectDestructuringWarning.cs",
    "content": "using JetBrains.DocumentModel;\nusing JetBrains.ReSharper.Feature.Services.Daemon;\nusing JetBrains.ReSharper.Psi.CSharp;\n\nusing ReSharper.Structured.Logging.Models;\nusing ReSharper.Structured.Logging.Settings;\n\nnamespace ReSharper.Structured.Logging.Highlighting\n{\n    [RegisterConfigurableSeverity(\n        SeverityId,\n        null,\n        StructuredLoggingGroup.Id,\n        Message,\n        Message,\n        Severity.WARNING)]\n    [ConfigurableSeverityHighlighting(\n        SeverityId,\n        CSharpLanguage.Name,\n        OverlapResolve = OverlapResolveKind.WARNING,\n        ToolTipFormatString = Message)]\n    public class ComplexObjectDestructuringWarning : ComplexObjectDestructuringWarningBase, IHighlighting\n    {\n        public const string SeverityId = \"ComplexObjectDestructuringProblem\";\n\n        public ComplexObjectDestructuringWarning(MessageTemplateTokenInformation tokenInformation)\n        {\n            TokenInformation = tokenInformation;\n        }\n\n        public string ErrorStripeToolTip => ToolTip;\n\n        public MessageTemplateTokenInformation TokenInformation { get; }\n\n        public string ToolTip => Message;\n\n        public DocumentRange CalculateRange()\n        {\n            return TokenInformation.DocumentRange;\n        }\n\n        public bool IsValid()\n        {\n            return TokenInformation.DocumentRange.IsValid();\n        }\n    }\n}\n"
  },
  {
    "path": "src/ReSharper.Structured.Logging/Highlighting/ComplexObjectDestructuringWarningBase.cs",
    "content": "namespace ReSharper.Structured.Logging.Highlighting\n{\n    public abstract class ComplexObjectDestructuringWarningBase\n    {\n        protected const string Message = \"Complex objects with default ToString() implementation probably need to be destructured\";\n    }\n}\n"
  },
  {
    "path": "src/ReSharper.Structured.Logging/Highlighting/ContextualLoggerWarning.cs",
    "content": "using JetBrains.DocumentModel;\nusing JetBrains.ReSharper.Feature.Services.Daemon;\nusing JetBrains.ReSharper.Psi.CSharp;\n\nusing ReSharper.Structured.Logging.Settings;\n\nnamespace ReSharper.Structured.Logging.Highlighting\n{\n    [RegisterConfigurableSeverity(\n        SeverityId,\n        null,\n        StructuredLoggingGroup.Id,\n        Message,\n        Message,\n        Severity.WARNING)]\n    [ConfigurableSeverityHighlighting(\n        SeverityId,\n        CSharpLanguage.Name,\n        OverlapResolve = OverlapResolveKind.WARNING,\n        ToolTipFormatString = Message)]\n    public class ContextualLoggerWarning : IHighlighting\n    {\n        private const string Message = \"Incorrect type is used for contextual logger\";\n\n        public const string SeverityId = \"ContextualLoggerProblem\";\n\n        private readonly DocumentRange _range;\n\n        public ContextualLoggerWarning(DocumentRange documentRange)\n        {\n            _range = documentRange;\n        }\n\n        public string ErrorStripeToolTip => ToolTip;\n\n        public string ToolTip => Message;\n\n        public DocumentRange CalculateRange()\n        {\n            return _range;\n        }\n\n        public bool IsValid()\n        {\n            return _range.IsValid();\n        }\n    }\n}\n"
  },
  {
    "path": "src/ReSharper.Structured.Logging/Highlighting/DuplicateTemplatePropertyWarning.cs",
    "content": "using JetBrains.DocumentModel;\nusing JetBrains.ReSharper.Feature.Services.Daemon;\nusing JetBrains.ReSharper.Psi.CSharp;\n\nusing ReSharper.Structured.Logging.Models;\nusing ReSharper.Structured.Logging.Settings;\n\nnamespace ReSharper.Structured.Logging.Highlighting\n{\n    [RegisterConfigurableSeverity(\n        SeverityId,\n        null,\n        StructuredLoggingGroup.Id,\n        Message,\n        Message,\n        Severity.WARNING)]\n    [ConfigurableSeverityHighlighting(\n        SeverityId,\n        CSharpLanguage.Name,\n        OverlapResolve = OverlapResolveKind.WARNING,\n        ToolTipFormatString = Message)]\n    public class DuplicateTemplatePropertyWarning : IHighlighting\n    {\n        private const string Message = \"Duplicate properties in message template\";\n\n        public const string SeverityId = \"TemplateDuplicatePropertyProblem\";\n\n        private readonly DocumentRange _documentRange;\n\n        public DuplicateTemplatePropertyWarning(MessageTemplateTokenInformation tokenInformation)\n        {\n            _documentRange = tokenInformation.DocumentRange;\n        }\n\n        public string ErrorStripeToolTip => ToolTip;\n\n        public string ToolTip => Message;\n\n        public DocumentRange CalculateRange()\n        {\n            return _documentRange;\n        }\n\n        public bool IsValid()\n        {\n            return _documentRange.IsValid();\n        }\n    }\n}\n"
  },
  {
    "path": "src/ReSharper.Structured.Logging/Highlighting/ExceptionPassedAsTemplateArgumentWarning.cs",
    "content": "using JetBrains.DocumentModel;\nusing JetBrains.ReSharper.Feature.Services.Daemon;\nusing JetBrains.ReSharper.Psi.CSharp;\n\nusing ReSharper.Structured.Logging.Settings;\n\nnamespace ReSharper.Structured.Logging.Highlighting\n{\n    [RegisterConfigurableSeverity(\n        SeverityId,\n        null,\n        StructuredLoggingGroup.Id,\n        Message,\n        Message,\n        Severity.WARNING)]\n    [ConfigurableSeverityHighlighting(\n        SeverityId,\n        CSharpLanguage.Name,\n        OverlapResolve = OverlapResolveKind.WARNING,\n        ToolTipFormatString = Message)]\n    public class ExceptionPassedAsTemplateArgumentWarning : IHighlighting\n    {\n        public const string SeverityId = \"ExceptionPassedAsTemplateArgumentProblem\";\n\n        private const string Message = \"Exception should be passed to the exception argument\";\n\n        private readonly DocumentRange _documentRange;\n\n        public ExceptionPassedAsTemplateArgumentWarning(DocumentRange documentRange)\n        {\n            _documentRange = documentRange;\n        }\n\n        public string ErrorStripeToolTip => ToolTip;\n\n        public string ToolTip => Message;\n\n        public DocumentRange CalculateRange()\n        {\n            return _documentRange;\n        }\n\n        public bool IsValid()\n        {\n            return _documentRange.IsValid();\n        }\n    }\n}\n"
  },
  {
    "path": "src/ReSharper.Structured.Logging/Highlighting/InconsistentContextLogPropertyNamingWarning.cs",
    "content": "using JetBrains.DocumentModel;\nusing JetBrains.ReSharper.Feature.Services.Daemon;\nusing JetBrains.ReSharper.Psi.CSharp;\nusing JetBrains.ReSharper.Psi.CSharp.Tree;\n\nusing ReSharper.Structured.Logging.Settings;\n\nnamespace ReSharper.Structured.Logging.Highlighting\n{\n    [RegisterConfigurableSeverity(\n        SeverityId,\n        null,\n        StructuredLoggingGroup.Id,\n        Message,\n        Message,\n        Severity.WARNING)]\n    [ConfigurableSeverityHighlighting(\n        SeverityId,\n        CSharpLanguage.Name,\n        OverlapResolve = OverlapResolveKind.WARNING,\n        ToolTipFormatString = Message)]\n    public class InconsistentContextLogPropertyNamingWarning : InconsistentLogPropertyNamingWarningBase, IHighlighting\n    {\n        private readonly string _propertyName;\n\n        public const string SeverityId = \"InconsistentContextLogPropertyNaming\";\n\n        public InconsistentContextLogPropertyNamingWarning(ICSharpArgument argument, string propertyName, string suggestedName)\n        {\n            _propertyName = propertyName;\n            Argument = argument;\n            SuggestedName = suggestedName;\n        }\n\n        public string ErrorStripeToolTip => ToolTip;\n\n        public ICSharpArgument Argument { get; }\n\n\n        public string SuggestedName { get; }\n\n        public string ToolTip => GetToolTipMessage(_propertyName, SuggestedName);\n\n        public DocumentRange CalculateRange()\n        {\n            return Argument.GetDocumentRange();\n        }\n\n        public bool IsValid()\n        {\n            return Argument.GetDocumentRange().IsValid();\n        }\n    }\n}\n"
  },
  {
    "path": "src/ReSharper.Structured.Logging/Highlighting/InconsistentLogPropertyNamingWarning.cs",
    "content": "using JetBrains.DocumentModel;\nusing JetBrains.ReSharper.Feature.Services.Daemon;\nusing JetBrains.ReSharper.Psi.CSharp;\n\nusing ReSharper.Structured.Logging.Models;\nusing ReSharper.Structured.Logging.Serilog.Parsing;\nusing ReSharper.Structured.Logging.Settings;\n\nnamespace ReSharper.Structured.Logging.Highlighting\n{\n    [RegisterConfigurableSeverity(\n        SeverityId,\n        null,\n        StructuredLoggingGroup.Id,\n        Message,\n        Message,\n        Severity.WARNING)]\n    [ConfigurableSeverityHighlighting(\n        SeverityId,\n        CSharpLanguage.Name,\n        OverlapResolve = OverlapResolveKind.WARNING,\n        ToolTipFormatString = Message)]\n    public class InconsistentLogPropertyNamingWarning : InconsistentLogPropertyNamingWarningBase, IHighlighting\n    {\n        public const string SeverityId = \"InconsistentLogPropertyNaming\";\n\n        public InconsistentLogPropertyNamingWarning(\n            MessageTemplateTokenInformation tokenInformation,\n            PropertyToken namedProperty,\n            string suggestedName)\n        {\n            TokenInformation = tokenInformation;\n            NamedProperty = namedProperty;\n            SuggestedName = suggestedName;\n        }\n\n        public string ErrorStripeToolTip => ToolTip;\n\n        public MessageTemplateTokenInformation TokenInformation { get; }\n\n        public PropertyToken NamedProperty { get; }\n\n        public string SuggestedName { get; }\n\n        public string ToolTip => GetToolTipMessage(NamedProperty.PropertyName, SuggestedName);\n\n        public DocumentRange CalculateRange()\n        {\n            return TokenInformation.DocumentRange;\n        }\n\n        public bool IsValid()\n        {\n            return TokenInformation.DocumentRange.IsValid();\n        }\n    }\n}\n"
  },
  {
    "path": "src/ReSharper.Structured.Logging/Highlighting/InconsistentLogPropertyNamingWarningBase.cs",
    "content": "namespace ReSharper.Structured.Logging.Highlighting\n{\n    public class InconsistentLogPropertyNamingWarningBase\n    {\n        protected const string Message = \"Property name '{0}' does not match naming rules. Suggested name is '{1}'.\";\n\n        protected string GetToolTipMessage(string propertyName, string suggestedName)\n        {\n            return $\"Property name '{propertyName}' does not match naming rules. Suggested name is '{suggestedName}'.\";\n        }\n    }\n}\n"
  },
  {
    "path": "src/ReSharper.Structured.Logging/Highlighting/LogMessageIsSentenceWarning.cs",
    "content": "using System.Text.RegularExpressions;\n\nusing JetBrains.DocumentModel;\nusing JetBrains.ReSharper.Feature.Services.Daemon;\nusing JetBrains.ReSharper.Psi.CSharp;\nusing JetBrains.ReSharper.Psi.Tree;\nusing JetBrains.ReSharper.Psi.Util;\n\nusing ReSharper.Structured.Logging.Settings;\n\nnamespace ReSharper.Structured.Logging.Highlighting\n{\n    [RegisterConfigurableSeverity(\n        SeverityId,\n        null,\n        StructuredLoggingGroup.Id,\n        Message,\n        Message,\n        Severity.WARNING)]\n    [ConfigurableSeverityHighlighting(\n        SeverityId,\n        CSharpLanguage.Name,\n        OverlapResolve = OverlapResolveKind.WARNING,\n        ToolTipFormatString = Message)]\n    public class LogMessageIsSentenceWarning : IHighlighting\n    {\n        private const string Message = \"Log event messages should be fragments, not sentences. Avoid a trailing period/full stop.\";\n\n        public const string SeverityId = \"LogMessageIsSentenceProblem\";\n\n        private readonly DocumentRange _documentRange;\n\n        public LogMessageIsSentenceWarning(IStringLiteralAlterer stringLiteral, Regex regex)\n        {\n            StringLiteral = stringLiteral;\n            Regex = regex;\n            _documentRange = stringLiteral.Expression.GetDocumentRange();\n        }\n\n        public string ErrorStripeToolTip => ToolTip;\n\n        public string ToolTip => Message;\n\n        public IStringLiteralAlterer StringLiteral { get; }\n\n        public Regex Regex { get; }\n\n        public DocumentRange CalculateRange()\n        {\n            return _documentRange;\n        }\n\n        public bool IsValid()\n        {\n            return _documentRange.IsValid();\n        }\n    }\n}\n"
  },
  {
    "path": "src/ReSharper.Structured.Logging/Highlighting/PositionalPropertyUsedWarning.cs",
    "content": "using JetBrains.DocumentModel;\nusing JetBrains.ReSharper.Feature.Services.Daemon;\nusing JetBrains.ReSharper.Psi.CSharp;\n\nusing ReSharper.Structured.Logging.Models;\nusing ReSharper.Structured.Logging.Settings;\n\nnamespace ReSharper.Structured.Logging.Highlighting\n{\n    [RegisterConfigurableSeverity(\n        SeverityId,\n        null,\n        StructuredLoggingGroup.Id,\n        Message,\n        Message,\n        Severity.WARNING)]\n    [ConfigurableSeverityHighlighting(\n        SeverityId,\n        CSharpLanguage.Name,\n        OverlapResolve = OverlapResolveKind.WARNING,\n        ToolTipFormatString = Message)]\n    public class PositionalPropertyUsedWarning : IHighlighting\n    {\n        private readonly MessageTemplateTokenInformation _tokenInformation;\n\n        private const string Message = \"Prefer named properties instead of positional ones\";\n\n        public const string SeverityId = \"PositionalPropertyUsedProblem\";\n\n        public PositionalPropertyUsedWarning(MessageTemplateTokenInformation tokenInformation)\n        {\n            _tokenInformation = tokenInformation;\n        }\n\n        public string ErrorStripeToolTip => ToolTip;\n\n        public string ToolTip => Message;\n\n        public DocumentRange CalculateRange()\n        {\n            return _tokenInformation.DocumentRange;\n        }\n\n        public bool IsValid()\n        {\n            return _tokenInformation.DocumentRange.IsValid();\n        }\n    }\n}\n"
  },
  {
    "path": "src/ReSharper.Structured.Logging/Highlighting/TemplateFormatStringNonExistingArgumentWarning.cs",
    "content": "using JetBrains.DocumentModel;\nusing JetBrains.ReSharper.Feature.Services.Daemon;\nusing JetBrains.ReSharper.Psi.CSharp;\n\nusing ReSharper.Structured.Logging.Settings;\n\nnamespace ReSharper.Structured.Logging.Highlighting\n{\n    [RegisterConfigurableSeverity(\n        SeverityId,\n        null,\n        StructuredLoggingGroup.Id,\n        Message,\n        Message,\n        Severity.WARNING)]\n    [ConfigurableSeverityHighlighting(\n        SeverityId,\n        CSharpLanguage.Name,\n        OverlapResolve = OverlapResolveKind.WARNING,\n        ToolTipFormatString = Message)]\n    public class TemplateFormatStringNonExistingArgumentWarning : IHighlighting\n    {\n        private const string SeverityId = \"TemplateFormatStringProblem\";\n\n        private const string Message = \"Non-existing argument in message template\";\n\n        private readonly DocumentRange _documentRange;\n\n        public TemplateFormatStringNonExistingArgumentWarning(DocumentRange documentRange)\n        {\n            _documentRange = documentRange;\n        }\n\n        public string ErrorStripeToolTip => ToolTip;\n\n        public string ToolTip => Message;\n\n        public DocumentRange CalculateRange()\n        {\n            return _documentRange;\n        }\n\n        public bool IsValid()\n        {\n            return _documentRange.IsValid();\n        }\n    }\n}\n"
  },
  {
    "path": "src/ReSharper.Structured.Logging/Highlighting/TemplateIsNotCompileTimeConstantWarning.cs",
    "content": "using JetBrains.DocumentModel;\nusing JetBrains.ReSharper.Feature.Services.Daemon;\nusing JetBrains.ReSharper.Psi.CSharp;\nusing JetBrains.ReSharper.Psi.CSharp.Tree;\nusing JetBrains.ReSharper.Psi.Tree;\n\nusing ReSharper.Structured.Logging.Settings;\n\nnamespace ReSharper.Structured.Logging.Highlighting\n{\n    [RegisterConfigurableSeverity(\n        SeverityId,\n        null,\n        StructuredLoggingGroup.Id,\n        Message,\n        Message,\n        Severity.WARNING)]\n    [ConfigurableSeverityHighlighting(\n        SeverityId,\n        CSharpLanguage.Name,\n        OverlapResolve = OverlapResolveKind.WARNING,\n        ToolTipFormatString = Message)]\n    public class TemplateIsNotCompileTimeConstantWarning : IHighlighting\n    {\n        public const string SeverityId = \"TemplateIsNotCompileTimeConstantProblem\";\n\n        private const string Message = \"Message template should be compile time constant\";\n\n        public TemplateIsNotCompileTimeConstantWarning(\n            IInvocationExpression invocationExpression,\n            ICSharpArgument messageTemplateArgument)\n        {\n            InvocationExpression = invocationExpression;\n            MessageTemplateArgument = messageTemplateArgument;\n        }\n\n        public IInvocationExpression InvocationExpression { get; }\n        public ICSharpArgument MessageTemplateArgument { get; }\n\n        public string ErrorStripeToolTip => ToolTip;\n\n        public string ToolTip => Message;\n\n        public DocumentRange CalculateRange()\n        {\n            return MessageTemplateArgument.Expression.GetDocumentRange();\n        }\n\n        public bool IsValid()\n        {\n            return MessageTemplateArgument.IsValid();\n        }\n    }\n}\n"
  },
  {
    "path": "src/ReSharper.Structured.Logging/Models/MessageTemplateTokenInformation.cs",
    "content": "using JetBrains.DocumentModel;\nusing JetBrains.ReSharper.Psi.Tree;\nusing JetBrains.ReSharper.Psi.Util;\n\nnamespace ReSharper.Structured.Logging.Models\n{\n    public class MessageTemplateTokenInformation\n    {\n        public MessageTemplateTokenInformation(\n            DocumentRange documentRange,\n            IStringLiteralAlterer stringLiteral)\n        {\n            DocumentRange = documentRange;\n            StringLiteral = stringLiteral;\n        }\n\n        public DocumentRange DocumentRange { get; }\n\n        public IStringLiteralAlterer StringLiteral { get; }\n\n        public int RelativeStartIndex => DocumentRange.StartOffset - StringLiteral.Expression.GetDocumentRange().StartOffset - 1;\n    }\n}\n"
  },
  {
    "path": "src/ReSharper.Structured.Logging/QuickFixes/AddDestructuringToMessageTemplatePropertyFix.cs",
    "content": "using System;\n\nusing JetBrains.Annotations;\nusing JetBrains.Application.Progress;\nusing JetBrains.ProjectModel;\nusing JetBrains.ReSharper.Feature.Services.QuickFixes;\nusing JetBrains.ReSharper.Psi.CSharp;\nusing JetBrains.ReSharper.Psi.ExtensionsAPI.Tree;\nusing JetBrains.ReSharper.Psi.Util;\nusing JetBrains.ReSharper.Resources.Shell;\nusing JetBrains.TextControl;\nusing JetBrains.Util;\n\nusing ReSharper.Structured.Logging.Highlighting;\nusing ReSharper.Structured.Logging.Models;\n\nnamespace ReSharper.Structured.Logging.QuickFixes\n{\n    [QuickFix]\n    public class AddDestructuringToMessageTemplatePropertyFix : QuickFixBase\n    {\n        private readonly MessageTemplateTokenInformation _tokenInformation;\n\n        public AddDestructuringToMessageTemplatePropertyFix([NotNull] AnonymousObjectDestructuringWarning error)\n        {\n            _tokenInformation = error.TokenInformation;\n        }\n\n        public AddDestructuringToMessageTemplatePropertyFix([NotNull] ComplexObjectDestructuringWarning error)\n        {\n            _tokenInformation = error.TokenInformation;\n        }\n\n        public override string Text => \"Add destructuring to property\";\n\n        public override bool IsAvailable(IUserDataHolder cache)\n        {\n            return _tokenInformation.DocumentRange.IsValid();\n        }\n\n        protected override Action<ITextControl> ExecutePsiTransaction(ISolution solution, IProgressIndicator progress)\n        {\n            using (WriteLockCookie.Create())\n            {\n                var factory = CSharpElementFactory.GetInstance(_tokenInformation.StringLiteral.Expression, false);\n                var startIndex = _tokenInformation.RelativeStartIndex;\n                var expression = factory.CreateExpression(\n                    $\"\\\"{_tokenInformation.StringLiteral.Expression.GetUnquotedText().Insert(startIndex + 1, \"@\")}\\\"\");\n\n                // ReSharper disable once AssignNullToNotNullAttribute\n                ModificationUtil.ReplaceChild(_tokenInformation.StringLiteral.Expression, expression);\n            }\n\n            return null;\n        }\n    }\n}\n"
  },
  {
    "path": "src/ReSharper.Structured.Logging/QuickFixes/RemoveTrailingPeriodFix.cs",
    "content": "using System;\nusing System.Text.RegularExpressions;\n\nusing JetBrains.Annotations;\nusing JetBrains.Application.Progress;\nusing JetBrains.ProjectModel;\nusing JetBrains.ReSharper.Feature.Services.QuickFixes;\nusing JetBrains.ReSharper.Psi.CSharp;\nusing JetBrains.ReSharper.Psi.ExtensionsAPI.Tree;\nusing JetBrains.ReSharper.Psi.Tree;\nusing JetBrains.ReSharper.Psi.Util;\nusing JetBrains.ReSharper.Resources.Shell;\nusing JetBrains.TextControl;\nusing JetBrains.Util;\n\nusing ReSharper.Structured.Logging.Highlighting;\n\nnamespace ReSharper.Structured.Logging.QuickFixes\n{\n    [QuickFix]\n    public class RemoveTrailingPeriodFix : ScopedQuickFixBase\n    {\n        private readonly IStringLiteralAlterer _stringLiteral;\n\n        private readonly Regex _regex;\n\n        public RemoveTrailingPeriodFix([NotNull] LogMessageIsSentenceWarning error)\n        {\n            _stringLiteral = error.StringLiteral;\n            _regex = error.Regex;\n        }\n\n        public override string Text => \"Remove period\";\n\n        public override bool IsAvailable(IUserDataHolder cache)\n        {\n            return _stringLiteral.Expression.GetDocumentRange().IsValid();\n        }\n\n        /// <inheritdoc />\n        protected override ITreeNode TryGetContextTreeNode()\n        {\n            return _stringLiteral.Expression;\n        }\n\n        protected override Action<ITextControl> ExecutePsiTransaction(ISolution solution, IProgressIndicator progress)\n        {\n            using (WriteLockCookie.Create())\n            {\n                var factory = CSharpElementFactory.GetInstance(_stringLiteral.Expression, false);\n                var expression = factory.CreateExpression(\n                    $\"\\\"{_regex.Replace(_stringLiteral.Expression.GetUnquotedText(), string.Empty)}\\\"\");\n\n                ModificationUtil.ReplaceChild(_stringLiteral.Expression, expression);\n            }\n\n            return null;\n        }\n    }\n}\n"
  },
  {
    "path": "src/ReSharper.Structured.Logging/QuickFixes/RenameContextLogPropertyFix.cs",
    "content": "using System;\n\nusing JetBrains.Annotations;\nusing JetBrains.Application.Progress;\nusing JetBrains.ProjectModel;\nusing JetBrains.ReSharper.Feature.Services.QuickFixes;\nusing JetBrains.ReSharper.Psi.CSharp;\nusing JetBrains.ReSharper.Psi.CSharp.Tree;\nusing JetBrains.ReSharper.Psi.ExtensionsAPI.Tree;\nusing JetBrains.ReSharper.Resources.Shell;\nusing JetBrains.TextControl;\nusing JetBrains.Util;\n\nusing ReSharper.Structured.Logging.Highlighting;\n\nnamespace ReSharper.Structured.Logging.QuickFixes\n{\n    [QuickFix]\n    public class RenameContextLogPropertyFix : QuickFixBase\n    {\n        private readonly ICSharpArgument _argument;\n\n        private readonly string _suggestedName;\n\n        public RenameContextLogPropertyFix([NotNull] InconsistentContextLogPropertyNamingWarning error)\n        {\n            _suggestedName = error.SuggestedName;\n            _argument = error.Argument;\n        }\n\n        public override string Text => $\"Rename property to '{_suggestedName}'\";\n\n        public override bool IsAvailable(IUserDataHolder cache)\n        {\n            return _argument.IsValid();\n        }\n\n        protected override Action<ITextControl> ExecutePsiTransaction(ISolution solution, IProgressIndicator progress)\n        {\n            using (WriteLockCookie.Create())\n            {\n                // ReSharper disable once AssignNullToNotNullAttribute\n                var factory = CSharpElementFactory.GetInstance(_argument.Expression, false);\n\n                var expression = factory.CreateExpression($\"\\\"{_suggestedName}\\\"\");\n                ModificationUtil.ReplaceChild(_argument.Expression, expression);\n            }\n\n            return null;\n        }\n    }\n}\n"
  },
  {
    "path": "src/ReSharper.Structured.Logging/QuickFixes/RenameLogPropertyFix.cs",
    "content": "using System;\n\nusing JetBrains.Annotations;\nusing JetBrains.Application.Progress;\nusing JetBrains.ProjectModel;\nusing JetBrains.ReSharper.Feature.Services.QuickFixes;\nusing JetBrains.ReSharper.Psi.CSharp;\nusing JetBrains.ReSharper.Psi.ExtensionsAPI.Tree;\nusing JetBrains.ReSharper.Psi.Util;\nusing JetBrains.ReSharper.Resources.Shell;\nusing JetBrains.TextControl;\nusing JetBrains.Util;\n\nusing ReSharper.Structured.Logging.Highlighting;\nusing ReSharper.Structured.Logging.Models;\nusing ReSharper.Structured.Logging.Serilog.Parsing;\n\nnamespace ReSharper.Structured.Logging.QuickFixes\n{\n    [QuickFix]\n    public class RenameLogPropertyFix : QuickFixBase\n    {\n        private readonly PropertyToken _namedProperty;\n\n        private readonly MessageTemplateTokenInformation _tokenInformation;\n\n        private readonly string _suggestedName;\n\n        public RenameLogPropertyFix([NotNull] InconsistentLogPropertyNamingWarning error)\n        {\n            _namedProperty = error.NamedProperty;\n            _suggestedName = error.SuggestedName;\n            _tokenInformation = error.TokenInformation;\n        }\n\n        public override string Text => $\"Rename property to '{_suggestedName}'\";\n\n        public override bool IsAvailable(IUserDataHolder cache)\n        {\n            return _tokenInformation.DocumentRange.IsValid();\n        }\n\n        protected override Action<ITextControl> ExecutePsiTransaction(ISolution solution, IProgressIndicator progress)\n        {\n            using (WriteLockCookie.Create())\n            {\n                var factory = CSharpElementFactory.GetInstance(_tokenInformation.StringLiteral.Expression, false);\n                var relativeStartIndex = _tokenInformation.RelativeStartIndex;\n                var startIndex = _namedProperty.Destructuring == Destructuring.Default\n                                     ? relativeStartIndex + 1\n                                     : relativeStartIndex + 2;\n                var length = _namedProperty.Destructuring == Destructuring.Default\n                                 ? _namedProperty.Length - 2\n                                 : _namedProperty.Length - 3;\n\n                var expression = factory.CreateExpression(\n                    $\"\\\"{_tokenInformation.StringLiteral.Expression.GetUnquotedText().Remove(startIndex, length).Insert(startIndex, _suggestedName)}\\\"\");\n                ModificationUtil.ReplaceChild(_tokenInformation.StringLiteral.Expression, expression);\n            }\n\n            return null;\n        }\n    }\n}\n"
  },
  {
    "path": "src/ReSharper.Structured.Logging/QuickFixes/TemplateIsNotCompileTimeConstantFix.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing JetBrains.Annotations;\nusing JetBrains.Application.Progress;\nusing JetBrains.DocumentModel;\nusing JetBrains.ProjectModel;\nusing JetBrains.ReSharper.Feature.Services.Bulbs;\nusing JetBrains.ReSharper.Feature.Services.LiveTemplates.Hotspots;\nusing JetBrains.ReSharper.Feature.Services.QuickFixes;\nusing JetBrains.ReSharper.Psi;\nusing JetBrains.ReSharper.Psi.CSharp;\nusing JetBrains.ReSharper.Psi.CSharp.Parsing;\nusing JetBrains.ReSharper.Psi.CSharp.Tree;\nusing JetBrains.ReSharper.Psi.Naming;\nusing JetBrains.ReSharper.Psi.Naming.Elements;\nusing JetBrains.ReSharper.Psi.Naming.Extentions;\nusing JetBrains.ReSharper.Psi.Naming.Impl;\nusing JetBrains.ReSharper.Psi.Naming.Settings;\nusing JetBrains.ReSharper.Psi.Tree;\nusing JetBrains.ReSharper.Resources.Shell;\nusing JetBrains.ReSharper.TestRunner.Abstractions.Extensions;\nusing JetBrains.TextControl;\nusing JetBrains.Util;\nusing ReSharper.Structured.Logging.Highlighting;\nusing ReSharper.Structured.Logging.Services;\n\nnamespace ReSharper.Structured.Logging.QuickFixes\n{\n    [QuickFix]\n    public class TemplateIsNotCompileTimeConstantFix : QuickFixBase\n    {\n        public TemplateIsNotCompileTimeConstantFix([NotNull] TemplateIsNotCompileTimeConstantWarning error)\n        {\n            InvocationExpression = error.InvocationExpression;\n            MessageTemplateArgument = error.MessageTemplateArgument;\n        }\n\n        public override string Text => \"Convert to compile-time constant message template\";\n        public IInvocationExpression InvocationExpression { get; set; }\n        public ICSharpArgument MessageTemplateArgument { get; set; }\n\n        public override bool IsAvailable(IUserDataHolder cache)\n        {\n            return InvocationExpression.IsValid() && MessageTemplateArgument.Expression is IInterpolatedStringExpression;\n        }\n\n        // ReSharper disable once CognitiveComplexity\n        protected override Action<ITextControl> ExecutePsiTransaction(ISolution solution, IProgressIndicator progress)\n        {\n            var interpolatedExpression = (IInterpolatedStringExpression)MessageTemplateArgument.Expression.NotNull();\n            var elementFactory = CSharpElementFactory.GetInstance(interpolatedExpression);\n            var hotspots = new List<(int Start, int End, List<string> Suggestions)>();\n\n            var namingManager = solution.GetPsiServices().Naming;\n            var nameSuggestionManager = namingManager.Suggestion;\n            var namingLanguageService = NamingManager.GetNamingLanguageService(interpolatedExpression.Language);\n            var entryOptions = new EntryOptions(\n                PluralityKinds.Unknown,\n                SubrootPolicy.Decompose,\n                PredefinedPrefixPolicy.Remove);\n            var settingsStore = interpolatedExpression.GetSettingsStoreWithEditorConfig();\n            var suggestionOptions = new SuggestionOptions();\n            var sourceFile = interpolatedExpression.GetSourceFile()\n                .NotNull(\"interpolatedExpression.GetSourceFile() != null\");\n\n            using (WriteLockCookie.Create())\n            {\n                var hotspotsRegistry = new HotspotsRegistry(interpolatedExpression.GetPsiServices());\n\n                var builder = new StringBuilder();\n                foreach (var treeNode in interpolatedExpression.Children())\n                {\n                    if (treeNode is ITokenNode token)\n                    {\n                        if (treeNode.GetTokenType() == CSharpTokenType.INTERPOLATED_STRING_REGULAR_START)\n                            builder.Append(token.GetText().Substring(2));\n                        else if (treeNode.GetTokenType() == CSharpTokenType.INTERPOLATED_STRING_VERBATIM_START)\n                            builder.Append(token.GetText().Substring(3));\n                        else if (treeNode.GetTokenType() == CSharpTokenType.INTERPOLATED_STRING_REGULAR_END ||\n                                 treeNode.GetTokenType() == CSharpTokenType.INTERPOLATED_STRING_VERBATIM_END)\n                            builder.Append(token.GetText().Substring(0, token.GetText().Length - 1));\n                        else\n                            builder.Append(token.GetText());\n                        continue;\n                    }\n\n                    var insert = (IInterpolatedStringInsert)treeNode;\n\n                    var namesCollection = nameSuggestionManager.CreateEmptyCollection(\n                        PluralityKinds.Unknown,\n                        treeNode.Language,\n                        longerNamesFirst: true,\n                        sourceFile);\n                    var suggestRoots = namingLanguageService.SuggestRoots(\n                        insert.Expression,\n                        useExpectedTypes: false,\n                        namesCollection.PolicyProvider);\n\n                    foreach (var suggestRoot in suggestRoots)\n                        namesCollection.Add(suggestRoot, entryOptions);\n\n                    var defaultRule = namingManager.Policy.GetDefaultRule(\n                        sourceFile,\n                        interpolatedExpression.Language,\n                        settingsStore,\n                        NamedElementKinds.Property,\n                        ElementKindOfElementType.PROPERTY);\n                    var namesSuggestion = namesCollection.Prepare(defaultRule, ScopeKind.Common, suggestionOptions);\n                    var firstName = PropertyNameProvider.GetSuggestedName(namesSuggestion.FirstName(), settingsStore);\n\n                    hotspots.Add((\n                        builder.Length + 1,\n                        builder.Length + 1 + firstName.Length,\n                        namesSuggestion.AllNames().Select(c => PropertyNameProvider.GetSuggestedName(c, settingsStore)).ToList()));\n                    builder.Append(firstName);\n\n                    var argument = elementFactory.CreateArgument(ParameterKind.VALUE, insert.Expression);\n                    InvocationExpression.AddArgumentAfter(argument, InvocationExpression.Arguments.Last());\n                }\n\n                var literalExpression = elementFactory.CreateStringLiteralExpression(builder.ToString());\n                var literalExpressionArgument = InvocationExpression.AddArgumentAfter(\n                    elementFactory.CreateArgument(ParameterKind.VALUE, literalExpression),\n                    MessageTemplateArgument);\n                InvocationExpression.RemoveArgument(MessageTemplateArgument);\n\n                foreach (var (start, end, suggestions) in hotspots)\n                {\n                    var documentRange = new DocumentRange(\n                        literalExpressionArgument.GetDocumentStartOffset().Shift(start),\n                        literalExpressionArgument.GetDocumentStartOffset().Shift(end));\n                    hotspotsRegistry.Register(documentRange.CreateRangeMarker(), new TextHotspotExpression(suggestions));\n                }\n\n                var endSelectionRange = ExpressionStatementNavigator.GetByExpression(\n                    InvocationExpressionNavigator.GetByArgument(literalExpressionArgument))\n                    .GetDocumentEndOffset();\n                return BulbActionUtils.ExecuteHotspotSession(hotspotsRegistry, endSelectionRange);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/ReSharper.Structured.Logging/ReSharper.Structured.Logging.Rider.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk\">\n  <PropertyGroup>\n    <TargetFramework>net472</TargetFramework>\n    <AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>\n    <LangVersion>latest</LangVersion>\n  </PropertyGroup>\n  <PropertyGroup>\n    <!-- Exclude the project from analysis to prvent duplications -->\n    <SonarQubeExclude>true</SonarQubeExclude>\n    <SonarQubeTestProject>false</SonarQubeTestProject>\n    <RootNamespace>ReSharper.Structured.Logging</RootNamespace>\n  </PropertyGroup>\n  <ItemGroup>\n    <PackageReference Include=\"JetBrains.Rider.SDK\" Version=\"$(SdkVersion)\" PrivateAssets=\"all\" />\n  </ItemGroup>\n</Project>\n"
  },
  {
    "path": "src/ReSharper.Structured.Logging/ReSharper.Structured.Logging.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk\">\n  <PropertyGroup>\n    <TargetFramework>net472</TargetFramework>\n    <AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>\n    <LangVersion>latest</LangVersion>\n  </PropertyGroup>\n  <PropertyGroup>\n    <SonarQubeTestProject>false</SonarQubeTestProject>\n  </PropertyGroup>\n  <ItemGroup>\n    <PackageReference Include=\"JetBrains.ReSharper.SDK\" Version=\"$(SdkVersion)\" PrivateAssets=\"all\" />\n  </ItemGroup>\n  <ItemGroup>\n    <Folder Include=\"Utils\\\" />\n  </ItemGroup>\n  <PropertyGroup>\n    <OutputPath>bin\\$(MSBuildProjectName)\\$(Configuration)\\</OutputPath>\n  </PropertyGroup>\n</Project>\n"
  },
  {
    "path": "src/ReSharper.Structured.Logging/Serilog/Core/IMessageTemplateParser.cs",
    "content": "// Copyright 2013-2015 Serilog Contributors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nusing ReSharper.Structured.Logging.Serilog.Events;\n\nnamespace ReSharper.Structured.Logging.Serilog.Core\n{\n    public interface IMessageTemplateParser\n    {\n        MessageTemplate Parse(string messageTemplate);\n    }\n}"
  },
  {
    "path": "src/ReSharper.Structured.Logging/Serilog/Events/MessageTemplate.cs",
    "content": "// Copyright 2013-2015 Serilog Contributors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\n\nusing ReSharper.Structured.Logging.Serilog.Parsing;\n\nnamespace ReSharper.Structured.Logging.Serilog.Events\n{\n    /// <summary>\n    /// Represents a message template passed to a log method. The template\n    /// can subsequently render the template in textual form given the list\n    /// of properties.\n    /// </summary>\n    public class MessageTemplate\n    {\n        /// <summary>\n        /// Represents the empty message template.\n        /// </summary>\n        public static MessageTemplate Empty { get; } = new MessageTemplate(Enumerable.Empty<MessageTemplateToken>());\n\n        readonly MessageTemplateToken[] _tokens;\n\n        /// <summary>\n        /// Construct a message template using manually-defined text and property tokens.\n        /// </summary>\n        /// <param name=\"tokens\">The text and property tokens defining the template.</param>\n        public MessageTemplate(IEnumerable<MessageTemplateToken> tokens)\n            // ReSharper disable PossibleMultipleEnumeration\n            : this(string.Join(\"\", tokens), tokens)\n            // ReSharper enable PossibleMultipleEnumeration\n        {\n        }\n\n        /// <summary>\n        /// Construct a message template using manually-defined text and property tokens.\n        /// </summary>\n        /// <param name=\"text\">The full text of the template; used by Serilog internally to avoid unneeded\n        /// string concatenation.</param>\n        /// <param name=\"tokens\">The text and property tokens defining the template.</param>\n        public MessageTemplate(string text, IEnumerable<MessageTemplateToken> tokens)\n        {\n            if (text == null) throw new ArgumentNullException(nameof(text));\n            if (tokens == null) throw new ArgumentNullException(nameof(tokens));\n\n            Text = text;\n            _tokens = tokens.ToArray();\n\n            var propertyTokens = GetElementsOfTypeToArray<PropertyToken>(_tokens);\n            if (propertyTokens.Length != 0)\n            {\n                var allPositional = true;\n                var anyPositional = false;\n                foreach (var propertyToken in propertyTokens)\n                {\n                    if (propertyToken.IsPositional)\n                        anyPositional = true;\n                    else\n                        allPositional = false;\n                }\n\n                if (allPositional)\n                {\n                    PositionalProperties = propertyTokens;\n                }\n                else\n                {\n                    if (anyPositional)\n                        IsMixedTemplate = true;\n\n                    NamedProperties = propertyTokens;\n                }\n            }\n        }\n\n        /// <summary>\n        /// Similar to <see cref=\"Enumerable.OfType{TResult}\"/>, but faster.\n        /// </summary>\n        static TResult[] GetElementsOfTypeToArray<TResult>(MessageTemplateToken[] tokens)\n            where TResult: class\n        {\n            var result = new List<TResult>(tokens.Length / 2);\n            for (var i = 0; i < tokens.Length; i++)\n            {\n                var token = tokens[i] as TResult;\n                if (token != null)\n                {\n                    result.Add(token);\n                }\n            }\n            return result.ToArray();\n        }\n\n        /// <summary>\n        /// The raw text describing the template.\n        /// </summary>\n        public string Text { get; }\n\n        /// <summary>\n        /// Render the template as a string.\n        /// </summary>\n        /// <returns>The string representation of the template.</returns>\n        public override string ToString()\n        {\n            return Text;\n        }\n\n        /// <summary>\n        /// The tokens parsed from the template.\n        /// </summary>\n        public IEnumerable<MessageTemplateToken> Tokens => _tokens;\n\n        internal MessageTemplateToken[] TokenArray => _tokens;\n\n        internal PropertyToken[] NamedProperties { get; }\n\n        internal PropertyToken[] PositionalProperties { get; }\n\n        public bool IsMixedTemplate { get; }\n    }\n}\n"
  },
  {
    "path": "src/ReSharper.Structured.Logging/Serilog/Parsing/Alignment.cs",
    "content": "﻿// Copyright 2013-2015 Serilog Contributors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nnamespace ReSharper.Structured.Logging.Serilog.Parsing\n{\n    /// <summary>\n    /// A structure representing the alignment settings to apply when rendering a property.\n    /// </summary>\n    public struct Alignment\n    {\n        /// <summary>\n        /// Initializes a new instance of <see cref=\"Alignment\"/>.\n        /// </summary>\n        /// <param name=\"direction\">The text alignment direction.</param>\n        /// <param name=\"width\">The width of the text, in characters.</param>\n        public Alignment(AlignmentDirection direction, int width)\n        {\n            Direction = direction;\n            Width = width;\n        }\n\n        /// <summary>\n        /// The text alignment direction.\n        /// </summary>\n        public AlignmentDirection Direction { get; }\n\n        /// <summary>\n        /// The width of the text.\n        /// </summary>\n        public int Width { get; }\n    }\n}\n"
  },
  {
    "path": "src/ReSharper.Structured.Logging/Serilog/Parsing/AlignmentDirection.cs",
    "content": "﻿// Copyright 2013-2015 Serilog Contributors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nnamespace ReSharper.Structured.Logging.Serilog.Parsing\n{\n    /// <summary>\n    /// Defines the direction of the alignment.\n    /// </summary>\n    public enum AlignmentDirection\n    {\n        /// <summary>\n        /// Text will be left-aligned.\n        /// </summary>\n        Left,\n        /// <summary>\n        /// Text will be right-aligned.\n        /// </summary>\n        Right\n    }\n}"
  },
  {
    "path": "src/ReSharper.Structured.Logging/Serilog/Parsing/Destructuring.cs",
    "content": "﻿// Copyright 2013-2015 Serilog Contributors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nnamespace ReSharper.Structured.Logging.Serilog.Parsing\n{\n    /// <summary>\n    /// Instructs the logger on how to store information about provided\n    /// parameters.\n    /// </summary>\n    public enum Destructuring\n    {\n        /// <summary>\n        /// Convert known types and objects to scalars, arrays to sequences.\n        /// </summary>\n        Default,\n\n        /// <summary>\n        /// Convert all types to scalar strings. Prefix name with '$'.\n        /// </summary>\n        Stringify,\n\n        /// <summary>\n        /// Convert known types to scalars, destructure objects and collections\n        /// into sequences and structures. Prefix name with '@'.\n        /// </summary>\n        Destructure\n    }\n}"
  },
  {
    "path": "src/ReSharper.Structured.Logging/Serilog/Parsing/MessageTemplateParser.cs",
    "content": "// Copyright 2013-2015 Serilog Contributors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Text;\n\nusing JetBrains.Application.Parts;\nusing JetBrains.ProjectModel;\n\nusing ReSharper.Structured.Logging.Serilog.Core;\nusing ReSharper.Structured.Logging.Serilog.Events;\n\nnamespace ReSharper.Structured.Logging.Serilog.Parsing\n{\n    /// <summary>\n    /// Parses message template strings into sequences of text or property\n    /// tokens.\n    /// </summary>\n    #if RIDER\n    [SolutionComponent]\n    #else\n    [SolutionComponent(Instantiation.DemandAnyThreadSafe)]\n    #endif\n    public class MessageTemplateParser : IMessageTemplateParser\n    {\n        /// <summary>\n        /// Parse the supplied message template.\n        /// </summary>\n        /// <param name=\"messageTemplate\">The message template to parse.</param>\n        /// <returns>A sequence of text or property tokens. Where the template\n        /// is not syntactically valid, text tokens will be returned. The parser\n        /// will make a best effort to extract valid property tokens even in the\n        /// presence of parsing issues.</returns>\n        /// <exception cref=\"ArgumentNullException\">When <paramref name=\"messageTemplate\"/> is <code>null</code></exception>\n        public MessageTemplate Parse(string messageTemplate)\n        {\n            if (messageTemplate == null) throw new ArgumentNullException(nameof(messageTemplate));\n\n            return new MessageTemplate(messageTemplate, Tokenize(messageTemplate));\n        }\n\n        static IEnumerable<MessageTemplateToken> Tokenize(string messageTemplate)\n        {\n            if (messageTemplate.Length == 0)\n            {\n                yield return new TextToken(\"\", 0);\n                yield break;\n            }\n\n            var nextIndex = 0;\n            while (true)\n            {\n                var beforeText = nextIndex;\n                var tt = ParseTextToken(nextIndex, messageTemplate, out nextIndex);\n                if (nextIndex > beforeText)\n                    yield return tt;\n\n                if (nextIndex == messageTemplate.Length)\n                    yield break;\n\n                var beforeProp = nextIndex;\n                var pt = ParsePropertyToken(nextIndex, messageTemplate, out nextIndex);\n                if (beforeProp < nextIndex)\n                    yield return pt;\n\n                if (nextIndex == messageTemplate.Length)\n                    yield break;\n            }\n        }\n\n        // ReSharper disable once CognitiveComplexity\n        static MessageTemplateToken ParsePropertyToken(int startAt, string messageTemplate, out int next)\n        {\n            var first = startAt;\n            startAt++;\n            while (startAt < messageTemplate.Length && IsValidInPropertyTag(messageTemplate[startAt]))\n                startAt++;\n\n            if (startAt == messageTemplate.Length || messageTemplate[startAt] != '}')\n            {\n                next = startAt;\n                return new TextToken(messageTemplate.Substring(first, next - first), first);\n            }\n\n            next = startAt + 1;\n\n            var rawText = messageTemplate.Substring(first, next - first);\n            var tagContent = rawText.Substring(1, next - (first + 2));\n            if (tagContent.Length == 0)\n                return new TextToken(rawText, first);\n\n            if (!TrySplitTagContent(tagContent, out var propertyNameAndDestructuring, out var format, out var alignment))\n                return new TextToken(rawText, first);\n\n            var propertyName = propertyNameAndDestructuring;\n            var destructuring = Destructuring.Default;\n            if (propertyName.Length != 0 && TryGetDestructuringHint(propertyName[0], out destructuring))\n                propertyName = propertyName.Substring(1);\n\n            if (propertyName.Length == 0)\n                return new TextToken(rawText, first);\n\n            for (var i = 0; i < propertyName.Length; ++i)\n            {\n                var c = propertyName[i];\n                if (!IsValidInPropertyName(c))\n                    return new TextToken(rawText, first);\n            }\n\n            if (format != null)\n            {\n                for (var i = 0; i < format.Length; ++i)\n                {\n                    var c = format[i];\n                    if (!IsValidInFormat(c))\n                        return new TextToken(rawText, first);\n                }\n            }\n\n            Alignment? alignmentValue = null;\n            if (alignment != null)\n            {\n                for (var i = 0; i < alignment.Length; ++i)\n                {\n                    var c = alignment[i];\n                    if (!IsValidInAlignment(c))\n                        return new TextToken(rawText, first);\n                }\n\n                var lastDash = alignment.LastIndexOf('-');\n                if (lastDash > 0)\n                    return new TextToken(rawText, first);\n\n                if (!int.TryParse(lastDash == -1 ? alignment : alignment.Substring(1), out var width) || width == 0)\n                    return new TextToken(rawText, first);\n\n                var direction = lastDash == -1 ?\n                    AlignmentDirection.Right :\n                    AlignmentDirection.Left;\n\n                alignmentValue = new Alignment(direction, width);\n            }\n\n            return new PropertyToken(\n                propertyName,\n                rawText,\n                format,\n                alignmentValue,\n                destructuring,\n                first);\n        }\n\n        // ReSharper disable once CognitiveComplexity\n        static bool TrySplitTagContent(string tagContent, out string propertyNameAndDestructuring, out string format, out string alignment)\n        {\n            var formatDelim = tagContent.IndexOf(':');\n            var alignmentDelim = tagContent.IndexOf(',');\n            if (formatDelim == -1 && alignmentDelim == -1)\n            {\n                propertyNameAndDestructuring = tagContent;\n                format = null;\n                alignment = null;\n            }\n            else\n            {\n                if (alignmentDelim == -1 || (formatDelim != -1 && alignmentDelim > formatDelim))\n                {\n                    propertyNameAndDestructuring = tagContent.Substring(0, formatDelim);\n                    format = formatDelim == tagContent.Length - 1 ?\n                        null :\n                        tagContent.Substring(formatDelim + 1);\n                    alignment = null;\n                }\n                else\n                {\n                    propertyNameAndDestructuring = tagContent.Substring(0, alignmentDelim);\n                    if (formatDelim == -1)\n                    {\n                        if (alignmentDelim == tagContent.Length - 1)\n                        {\n                            alignment = format = null;\n                            return false;\n                        }\n\n                        format = null;\n                        alignment = tagContent.Substring(alignmentDelim + 1);\n                    }\n                    else\n                    {\n                        if (alignmentDelim == formatDelim - 1)\n                        {\n                            alignment = format = null;\n                            return false;\n                        }\n\n                        alignment = tagContent.Substring(alignmentDelim + 1, formatDelim - alignmentDelim - 1);\n                        format = formatDelim == tagContent.Length - 1 ?\n                            null :\n                            tagContent.Substring(formatDelim + 1);\n                    }\n                }\n            }\n\n            return true;\n        }\n\n        static bool IsValidInPropertyTag(char c)\n        {\n            return IsValidInDestructuringHint(c) ||\n                IsValidInPropertyName(c) ||\n                IsValidInFormat(c) ||\n                c == ':';\n        }\n\n        static bool IsValidInPropertyName(char c) => char.IsLetterOrDigit(c) || c == '_' || c == '.' || c == ' ';\n\n        static bool TryGetDestructuringHint(char c, out Destructuring destructuring)\n        {\n            switch (c)\n            {\n                case '@':\n                    {\n                        destructuring = Destructuring.Destructure;\n                        return true;\n                    }\n                case '$':\n                    {\n                        destructuring = Destructuring.Stringify;\n                        return true;\n                    }\n                default:\n                    {\n                        destructuring = Destructuring.Default;\n                        return false;\n                    }\n            }\n        }\n\n        static bool IsValidInDestructuringHint(char c)\n        {\n            return c == '@' ||\n                   c == '$';\n        }\n\n        static bool IsValidInAlignment(char c)\n        {\n            return char.IsDigit(c) ||\n                   c == '-';\n        }\n\n        static bool IsValidInFormat(char c)\n        {\n            return c != '}' &&\n                (char.IsLetterOrDigit(c) ||\n                 char.IsPunctuation(c) ||\n                 c == ' ' ||\n                 c == '+');\n        }\n\n        // ReSharper disable once CognitiveComplexity\n        private static TextToken ParseTextToken(int startAt, string messageTemplate, out int next)\n        {\n            var first = startAt;\n\n            var accum = new StringBuilder();\n            do\n            {\n                var nc = messageTemplate[startAt];\n                if (nc == '{')\n                {\n                    if (startAt + 1 < messageTemplate.Length &&\n                        messageTemplate[startAt + 1] == '{')\n                    {\n                        accum.Append(nc);\n                        startAt++;\n                    }\n                    else\n                    {\n                        break;\n                    }\n                }\n                else\n                {\n                    accum.Append(nc);\n                    if (nc == '}')\n                    {\n                        if (startAt + 1 < messageTemplate.Length &&\n                            messageTemplate[startAt + 1] == '}')\n                        {\n                            startAt++;\n                        }\n                    }\n                }\n\n                startAt++;\n            } while (startAt < messageTemplate.Length);\n\n            next = startAt;\n            return new TextToken(accum.ToString(), first);\n        }\n    }\n}\n"
  },
  {
    "path": "src/ReSharper.Structured.Logging/Serilog/Parsing/MessageTemplateToken.cs",
    "content": "﻿// Copyright 2013-2015 Serilog Contributors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nnamespace ReSharper.Structured.Logging.Serilog.Parsing\n{\n    /// <summary>\n    /// An element parsed from a message template string.\n    /// </summary>\n    public abstract class MessageTemplateToken\n    {\n        /// <summary>\n        /// Construct a <see cref=\"MessageTemplateToken\"/>.\n        /// </summary>\n        /// <param name=\"startIndex\">The token's start index in the template.</param>\n        protected MessageTemplateToken(int startIndex)\n        {\n            StartIndex = startIndex;\n        }\n\n        /// <summary>\n        /// The token's start index in the template.\n        /// </summary>\n        // ReSharper disable once UnusedAutoPropertyAccessor.Global\n        public int StartIndex { get; }\n\n        /// <summary>\n        /// The token's length.\n        /// </summary>\n        public abstract int Length { get; }\n    }\n}"
  },
  {
    "path": "src/ReSharper.Structured.Logging/Serilog/Parsing/PropertyToken.cs",
    "content": "﻿// Copyright 2013-2015 Serilog Contributors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nusing System;\nusing System.ComponentModel;\nusing System.Globalization;\n\nnamespace ReSharper.Structured.Logging.Serilog.Parsing\n{\n    /// <summary>\n    /// A message template token representing a log event property.\n    /// </summary>\n    public sealed class PropertyToken : MessageTemplateToken\n    {\n        readonly string _rawText;\n        readonly int? _position;\n\n        /// <summary>\n        /// Construct a <see cref=\"PropertyToken\"/>.\n        /// </summary>\n        /// <param name=\"propertyName\">The name of the property.</param>\n        /// <param name=\"rawText\">The token as it appears in the message template.</param>\n        /// <param name=\"formatObsolete\">The format applied to the property, if any.</param>\n        /// <param name=\"destructuringObsolete\">The destructuring strategy applied to the property, if any.</param>\n        /// <exception cref=\"ArgumentNullException\"></exception>\n        [Obsolete(\"Use named arguments with this method to guarantee forwards-compatibility.\"), EditorBrowsable(EditorBrowsableState.Never)]\n        public PropertyToken(string propertyName, string rawText, string formatObsolete, Destructuring destructuringObsolete)\n            : this(propertyName, rawText, formatObsolete, null, destructuringObsolete)\n        {\n        }\n\n        /// <summary>\n        /// Construct a <see cref=\"PropertyToken\"/>.\n        /// </summary>\n        /// <param name=\"propertyName\">The name of the property.</param>\n        /// <param name=\"rawText\">The token as it appears in the message template.</param>\n        /// <param name=\"format\">The format applied to the property, if any.</param>\n        /// <param name=\"alignment\">The alignment applied to the property, if any.</param>\n        /// <param name=\"destructuring\">The destructuring strategy applied to the property, if any.</param>\n        /// <param name=\"startIndex\">The token's start index in the template.</param>\n        /// <exception cref=\"ArgumentNullException\"></exception>\n        public PropertyToken(string propertyName, string rawText, string format = null, Alignment? alignment = null, Destructuring destructuring = Destructuring.Default, int startIndex = -1)\n            : base(startIndex)\n        {\n            PropertyName = propertyName ?? throw new ArgumentNullException(nameof(propertyName));\n            Format = format;\n            Destructuring = destructuring;\n            _rawText = rawText ?? throw new ArgumentNullException(nameof(rawText));\n            Alignment = alignment;\n\n            int position;\n            if (int.TryParse(PropertyName, NumberStyles.None, CultureInfo.InvariantCulture, out position) &&\n                position >= 0)\n            {\n                _position = position;\n            }\n        }\n\n        /// <summary>\n        /// The token's length.\n        /// </summary>\n        public override int Length => _rawText.Length;\n\n        /// <summary>\n        /// The property name.\n        /// </summary>\n        public string PropertyName { get; }\n\n        /// <summary>\n        /// Destructuring strategy applied to the property.\n        /// </summary>\n        public Destructuring Destructuring { get; }\n\n        /// <summary>\n        /// Format applied to the property.\n        /// </summary>\n        public string Format { get; }\n\n        /// <summary>\n        /// Alignment applied to the property.\n        /// </summary>\n        public Alignment? Alignment { get; }\n\n        /// <summary>\n        /// True if the property name is a positional index; otherwise, false.\n        /// </summary>\n        public bool IsPositional => _position.HasValue;\n\n        internal string RawText => _rawText;\n\n        /// <summary>\n        /// Try to get the integer value represented by the property name.\n        /// </summary>\n        /// <param name=\"position\">The integer value, if present.</param>\n        /// <returns>True if the property is positional, otherwise false.</returns>\n        public bool TryGetPositionalValue(out int position)\n        {\n            if (_position == null)\n            {\n                position = 0;\n                return false;\n            }\n\n            position = _position.Value;\n            return true;\n        }\n\n        /// <summary>\n        /// Determines whether the specified <see cref=\"T:System.Object\"/> is equal to the current <see cref=\"T:System.Object\"/>.\n        /// </summary>\n        /// <returns>\n        /// true if the specified object  is equal to the current object; otherwise, false.\n        /// </returns>\n        /// <param name=\"obj\">The object to compare with the current object. </param><filterpriority>2</filterpriority>\n        public override bool Equals(object obj)\n        {\n            var pt = obj as PropertyToken;\n            return pt != null &&\n                pt.Destructuring == Destructuring &&\n                pt.Format == Format &&\n                pt.PropertyName == PropertyName &&\n                pt._rawText == _rawText;\n        }\n\n        /// <summary>\n        /// Serves as a hash function for a particular type.\n        /// </summary>\n        /// <returns>\n        /// A hash code for the current <see cref=\"T:System.Object\"/>.\n        /// </returns>\n        /// <filterpriority>2</filterpriority>\n        public override int GetHashCode() => PropertyName.GetHashCode();\n\n        /// <summary>\n        /// Returns a string that represents the current object.\n        /// </summary>\n        /// <returns>\n        /// A string that represents the current object.\n        /// </returns>\n        /// <filterpriority>2</filterpriority>\n        public override string ToString() => _rawText;\n    }\n}"
  },
  {
    "path": "src/ReSharper.Structured.Logging/Serilog/Parsing/TextToken.cs",
    "content": "﻿// Copyright 2013-2015 Serilog Contributors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nusing System;\n\nnamespace ReSharper.Structured.Logging.Serilog.Parsing\n{\n    /// <summary>\n    /// A message template token representing literal text.\n    /// </summary>\n    public sealed class TextToken : MessageTemplateToken\n    {\n        /// <summary>\n        /// Construct a <see cref=\"TextToken\"/>.\n        /// </summary>\n        /// <param name=\"text\">The text of the token.</param>\n        /// <param name=\"startIndex\">The token's start index in the template.</param>\n        /// <exception cref=\"ArgumentNullException\"></exception>\n        public TextToken(string text, int startIndex = -1) : base(startIndex)\n        {\n            Text = text ?? throw new ArgumentNullException(nameof(text));\n        }\n\n        /// <summary>\n        /// The token's length.\n        /// </summary>\n        public override int Length => Text.Length;\n\n        /// <summary>\n        /// Determines whether the specified <see cref=\"T:System.Object\"/> is equal to the current <see cref=\"T:System.Object\"/>.\n        /// </summary>\n        /// <returns>\n        /// true if the specified object  is equal to the current object; otherwise, false.\n        /// </returns>\n        /// <param name=\"obj\">The object to compare with the current object. </param><filterpriority>2</filterpriority>\n        public override bool Equals(object obj)\n        {\n            var tt = obj as TextToken;\n            return tt != null && tt.Text == Text;\n        }\n\n        /// <summary>\n        /// Serves as a hash function for a particular type.\n        /// </summary>\n        /// <returns>\n        /// A hash code for the current <see cref=\"T:System.Object\"/>.\n        /// </returns>\n        /// <filterpriority>2</filterpriority>\n        public override int GetHashCode() => Text.GetHashCode();\n\n        /// <summary>\n        /// Returns a string that represents the current object.\n        /// </summary>\n        /// <returns>\n        /// A string that represents the current object.\n        /// </returns>\n        /// <filterpriority>2</filterpriority>\n        public override string ToString() => Text;\n\n        /// <summary>\n        /// The text of the token.\n        /// </summary>\n        public string Text { get; }\n    }\n}"
  },
  {
    "path": "src/ReSharper.Structured.Logging/Settings/PropertyNamingType.cs",
    "content": "namespace ReSharper.Structured.Logging.Settings\n{\n    public enum PropertyNamingType\n    {\n        PascalCase,\n\n        CamelCase,\n\n        SnakeCase,\n\n        /// <summary>\n        /// The elastic naming convention.\n        /// </summary>\n        /// <remarks>\n        /// https://www.elastic.co/guide/en/beats/devguide/current/event-conventions.html\n        /// </remarks>\n        ElasticNaming\n    }\n}\n"
  },
  {
    "path": "src/ReSharper.Structured.Logging/Settings/StructuredLoggingGroup.cs",
    "content": "using JetBrains.ReSharper.Feature.Services.Daemon;\n\nnamespace ReSharper.Structured.Logging.Settings\n{\n    [RegisterConfigurableHighlightingsGroup(Id, Name)]\n    public static class StructuredLoggingGroup\n    {\n        public const string Id = \"StructuredLogging\";\n\n        private const string Name = \"Structured Logging Misuse\";\n    }\n}\n"
  },
  {
    "path": "src/ReSharper.Structured.Logging/Settings/StructuredLoggingOptionsPage.cs",
    "content": "using System;\n\nusing JetBrains.Application.Settings;\nusing JetBrains.Application.UI.Options;\nusing JetBrains.Application.UI.Options.OptionPages;\nusing JetBrains.Application.UI.Options.OptionsDialog;\nusing JetBrains.IDE.UI.Extensions;\nusing JetBrains.IDE.UI.Options;\nusing JetBrains.Lifetimes;\nusing JetBrains.ReSharper.Feature.Services.Resources;\n\nnamespace ReSharper.Structured.Logging.Settings\n{\n    [OptionsPage(Pid, \"Structured Logging\", typeof(FeaturesEnvironmentOptionsThemedIcons.StringFormat), ParentId = EnvironmentPage.Pid)]\n    public class StructuredLoggingOptionsPage : BeSimpleOptionsPage\n    {\n        private const string Pid = \"StructuredLogging\";\n\n        public StructuredLoggingOptionsPage(\n            Lifetime lifetime,\n            OptionsPageContext optionsPageContext,\n            OptionsSettingsSmartContext optionsSettingsSmartContext,\n            bool wrapInScrollablePanel = false)\n            : base(lifetime, optionsPageContext, optionsSettingsSmartContext, wrapInScrollablePanel)\n        {\n            AddHeader(\"Log properties naming style\");\n            AddComboOptionFromEnum(\n                (StructuredLoggingSettings settings) => settings.PropertyNamingType,\n                type =>\n                    {\n                        switch (type)\n                        {\n                            case PropertyNamingType.PascalCase:\n                                return \"PascalCase\";\n                            case PropertyNamingType.CamelCase:\n                                return \"camelCase\";\n                            case PropertyNamingType.SnakeCase:\n                                return \"snake_case\";\n                            case PropertyNamingType.ElasticNaming:\n                                return \"elastic.naming\";\n                            default:\n                                throw new ArgumentOutOfRangeException(nameof(type), type, null);\n                        }\n                    });\n\n            AddHeader(\"Ignored properties naming\");\n            AddCommentText(\"You may specify a regular expression here and if a property matches this expression, then it will be skipped during naming analysis.\");\n            var ignoredRegex = OptionsSettingsSmartContext\n                .GetValueProperty(lifetime, StructuredLoggingSettingsAccessor.IgnoredPropertiesRegex);\n            AddControl(ignoredRegex.GetBeTextBox(lifetime));\n        }\n    }\n}\n"
  },
  {
    "path": "src/ReSharper.Structured.Logging/Settings/StructuredLoggingSettings.cs",
    "content": "using JetBrains.Application.Settings;\nusing JetBrains.Application.Settings.WellKnownRootKeys;\n\nnamespace ReSharper.Structured.Logging.Settings\n{\n    [SettingsKey(typeof(EnvironmentSettings), \"Settings for Structured Logging\")]\n    public class StructuredLoggingSettings\n    {\n        [SettingsEntry(PropertyNamingType.PascalCase, \"Properties naming case\")]\n        public PropertyNamingType PropertyNamingType { get; set; }\n\n        [SettingsEntry(\"\", \"Ignored properties RegEx\")]\n        public string IgnoredPropertiesRegex { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/ReSharper.Structured.Logging/Settings/StructuredLoggingSettingsAccessor.cs",
    "content": "using System;\nusing System.Linq.Expressions;\n\nusing JetBrains.Annotations;\n\nnamespace ReSharper.Structured.Logging.Settings\n{\n    public static class StructuredLoggingSettingsAccessor\n    {\n        [NotNull]\n        public static readonly Expression<Func<StructuredLoggingSettings, PropertyNamingType>> PropertyNamingType = x => x.PropertyNamingType;\n\n        [NotNull]\n        public static readonly Expression<Func<StructuredLoggingSettings, string>> IgnoredPropertiesRegex = x => x.IgnoredPropertiesRegex;\n    }\n}\n"
  },
  {
    "path": "src/ReSharper.Structured.Logging/Utils/PropertyNameProvider.cs",
    "content": "using JetBrains.Annotations;\nusing JetBrains.Application.Settings;\nusing JetBrains.Util;\n\nusing ReSharper.Structured.Logging.Settings;\n\nnamespace ReSharper.Structured.Logging.Services;\n\npublic static class PropertyNameProvider\n{\n    public static string GetSuggestedName([NotNull]string propertyName, [CanBeNull]IContextBoundSettingsStore settingsStore)\n    {\n        var namingType = settingsStore\n                             ?.GetValue(StructuredLoggingSettingsAccessor.PropertyNamingType)\n                         ?? PropertyNamingType.PascalCase;\n\n        switch (namingType)\n        {\n            case PropertyNamingType.PascalCase:\n                return StringUtil.MakeUpperCamelCaseName(propertyName);\n            case PropertyNamingType.CamelCase:\n                return StringUtil.MakeUpperCamelCaseName(propertyName).Decapitalize();\n            case PropertyNamingType.SnakeCase:\n                return StringUtil.MakeUnderscoreCaseName(propertyName);\n            case PropertyNamingType.ElasticNaming:\n                return StringUtil.MakeUnderscoreCaseName(propertyName).Replace('_', '.');\n            default:\n                return propertyName;\n        }\n    }\n}\n"
  },
  {
    "path": "src/ReSharper.Structured.Logging/Wiki/StructuredLoggingWikiDataProvider.cs",
    "content": "using System.Collections.Generic;\n\nusing JetBrains.Application;\nusing JetBrains.Application.Parts;\nusing JetBrains.ReSharper.Feature.Services.Explanatory;\n\nusing ReSharper.Structured.Logging.Highlighting;\n\nnamespace ReSharper.Structured.Logging.Wiki\n{\n    [ShellComponent(Instantiation.DemandAnyThreadSafe)]\n    public class StructuredLoggingWikiDataProvider : ICodeInspectionWikiDataProvider\n    {\n        private static readonly IDictionary<string, string> AttributeUrlMap = new Dictionary<string, string>\n                                                                                  {\n                                                                                      {\n                                                                                          DuplicateTemplatePropertyWarning.SeverityId,\n                                                                                          CreateSeverityUrl(DuplicateTemplatePropertyWarning.SeverityId)\n                                                                                      },\n                                                                                      {\n                                                                                          ExceptionPassedAsTemplateArgumentWarning.SeverityId,\n                                                                                          CreateSeverityUrl(ExceptionPassedAsTemplateArgumentWarning.SeverityId)\n                                                                                      },\n                                                                                      {\n                                                                                          TemplateIsNotCompileTimeConstantWarning.SeverityId,\n                                                                                          CreateSeverityUrl(TemplateIsNotCompileTimeConstantWarning.SeverityId)\n                                                                                      },\n                                                                                      {\n                                                                                          AnonymousObjectDestructuringWarning.SeverityId,\n                                                                                          CreateSeverityUrl(AnonymousObjectDestructuringWarning.SeverityId)\n                                                                                      },\n                                                                                      {\n                                                                                          ContextualLoggerWarning.SeverityId,\n                                                                                          CreateSeverityUrl(ContextualLoggerWarning.SeverityId)\n                                                                                      },\n                                                                                      {\n                                                                                          ComplexObjectDestructuringWarning.SeverityId,\n                                                                                          CreateSeverityUrl(ComplexObjectDestructuringWarning.SeverityId)\n                                                                                      },\n                                                                                      {\n                                                                                          PositionalPropertyUsedWarning.SeverityId,\n                                                                                          CreateSeverityUrl(PositionalPropertyUsedWarning.SeverityId)\n                                                                                      },\n                                                                                      {\n                                                                                          InconsistentLogPropertyNamingWarning.SeverityId,\n                                                                                          CreateSeverityUrl(InconsistentLogPropertyNamingWarning.SeverityId)\n                                                                                      },\n                                                                                      {\n                                                                                          LogMessageIsSentenceWarning.SeverityId,\n                                                                                          CreateSeverityUrl(LogMessageIsSentenceWarning.SeverityId)\n                                                                                      },\n                                                                                      {\n                                                                                          ComplexObjectDestructuringInContextWarning.SeverityId,\n                                                                                          CreateSeverityUrl(ComplexObjectDestructuringInContextWarning.SeverityId)\n                                                                                      },\n                                                                                      {\n                                                                                          InconsistentContextLogPropertyNamingWarning.SeverityId,\n                                                                                          CreateSeverityUrl(InconsistentContextLogPropertyNamingWarning.SeverityId)\n                                                                                      }\n                                                                                  };\n\n        public bool TryGetValue(string attributeId, out string url)\n        {\n            return AttributeUrlMap.TryGetValue(attributeId, out url);\n        }\n\n        private static string CreateSeverityUrl(string severityId)\n        {\n            return $\"https://github.com/olsh/resharper-structured-logging/blob/master/rules/{severityId}.md\";\n        }\n    }\n}\n"
  },
  {
    "path": "src/ReSharper.Structured.Logging/ZoneMarker.cs",
    "content": "﻿using JetBrains.Application.BuildScript.Application.Zones;\nusing JetBrains.ReSharper.Psi.CSharp;\n\nnamespace ReSharper.Structured.Logging\n{\n    [ZoneMarker]\n    public class ZoneMarker : IRequire<ILanguageCSharpZone>\n    {\n    }\n}\n"
  },
  {
    "path": "src/ReSharper.Structured.Logging/app.config",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<configuration>\n  <runtime>\n    <assemblyBinding xmlns=\"urn:schemas-microsoft-com:asm.v1\">\n      <dependentAssembly>\n        <assemblyIdentity name=\"System.ValueTuple\" publicKeyToken=\"cc7b13ffcd2ddd51\" culture=\"neutral\" />\n        <bindingRedirect oldVersion=\"0.0.0.0-4.0.3.0\" newVersion=\"4.0.3.0\" />\n      </dependentAssembly>\n      <dependentAssembly>\n        <assemblyIdentity name=\"System.IO.FileSystem\" publicKeyToken=\"b03f5f7f11d50a3a\" culture=\"neutral\" />\n        <bindingRedirect oldVersion=\"0.0.0.0-4.0.2.0\" newVersion=\"4.0.2.0\" />\n      </dependentAssembly>\n      <dependentAssembly>\n        <assemblyIdentity name=\"System.Security.Cryptography.Primitives\" publicKeyToken=\"b03f5f7f11d50a3a\" culture=\"neutral\" />\n        <bindingRedirect oldVersion=\"0.0.0.0-4.0.1.0\" newVersion=\"4.0.1.0\" />\n      </dependentAssembly>\n      <dependentAssembly>\n        <assemblyIdentity name=\"System.IO.FileSystem.Primitives\" publicKeyToken=\"b03f5f7f11d50a3a\" culture=\"neutral\" />\n        <bindingRedirect oldVersion=\"0.0.0.0-4.0.2.0\" newVersion=\"4.0.2.0\" />\n      </dependentAssembly>\n    </assemblyBinding>\n  </runtime>\n</configuration>"
  },
  {
    "path": "src/ReSharper.Structured.Logging.sln",
    "content": "﻿\nMicrosoft Visual Studio Solution File, Format Version 12.00\n# Visual Studio Version 17\nVisualStudioVersion = 17.0.32126.317\nMinimumVisualStudioVersion = 10.0.40219.1\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"ReSharper.Structured.Logging\", \"ReSharper.Structured.Logging\\ReSharper.Structured.Logging.csproj\", \"{0B29307F-4E38-4611-BA0D-408A4B4F4E15}\"\nEndProject\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"ReSharper.Structured.Logging.Tests\", \"..\\test\\src\\ReSharper.Structured.Logging.Tests.csproj\", \"{D07C40A7-39BE-4725-889F-FF2F2B781442}\"\nEndProject\nProject(\"{2150E333-8FDC-42A3-9474-1A3956D46DE8}\") = \"Solution Items\", \"Solution Items\", \"{8F7509A6-86AF-48A9-BD71-464ED879D8FA}\"\n\tProjectSection(SolutionItems) = preProject\n\t\t..\\.editorconfig = ..\\.editorconfig\n\t\t..\\appveyor.yml = ..\\appveyor.yml\n\t\t..\\build.gradle = ..\\build.gradle\n\t\t..\\Directory.Build.props = ..\\Directory.Build.props\n\t\trider\\main\\resources\\META-INF\\plugin.xml = rider\\main\\resources\\META-INF\\plugin.xml\n\t\t..\\README.md = ..\\README.md\n\t\t..\\.gitignore = ..\\.gitignore\n\t\t..\\.github\\dependabot.yml = ..\\.github\\dependabot.yml\n\tEndProjectSection\nEndProject\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"ReSharper.Structured.Logging.Rider\", \"ReSharper.Structured.Logging\\ReSharper.Structured.Logging.Rider.csproj\", \"{81C42342-6FD5-48D0-B45F-FD364B170FC1}\"\nEndProject\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"ReSharper.Structured.Logging.Rider.Tests\", \"..\\test\\src\\ReSharper.Structured.Logging.Rider.Tests.csproj\", \"{6BC99E0B-6362-4A62-84F1-103B93896294}\"\nEndProject\nProject(\"{2150E333-8FDC-42A3-9474-1A3956D46DE8}\") = \"Rules\", \"Rules\", \"{D93C6901-5685-495B-A790-6C1467978205}\"\n\tProjectSection(SolutionItems) = preProject\n\t\t..\\rules\\AnonymousObjectDestructuringProblem.md = ..\\rules\\AnonymousObjectDestructuringProblem.md\n\t\t..\\rules\\ComplexObjectDestructuringProblem.md = ..\\rules\\ComplexObjectDestructuringProblem.md\n\t\t..\\rules\\ComplexObjectInContextDestructuringProblem.md = ..\\rules\\ComplexObjectInContextDestructuringProblem.md\n\t\t..\\rules\\ContextualLoggerProblem.md = ..\\rules\\ContextualLoggerProblem.md\n\t\t..\\rules\\ExceptionPassedAsTemplateArgumentProblem.md = ..\\rules\\ExceptionPassedAsTemplateArgumentProblem.md\n\t\t..\\rules\\InconsistentContextLogPropertyNaming.md = ..\\rules\\InconsistentContextLogPropertyNaming.md\n\t\t..\\rules\\InconsistentLogPropertyNaming.md = ..\\rules\\InconsistentLogPropertyNaming.md\n\t\t..\\rules\\LogMessageIsSentenceProblem.md = ..\\rules\\LogMessageIsSentenceProblem.md\n\t\t..\\rules\\PositionalPropertyUsedProblem.md = ..\\rules\\PositionalPropertyUsedProblem.md\n\t\t..\\rules\\TemplateDuplicatePropertyProblem.md = ..\\rules\\TemplateDuplicatePropertyProblem.md\n\t\t..\\rules\\TemplateIsNotCompileTimeConstantProblem.md = ..\\rules\\TemplateIsNotCompileTimeConstantProblem.md\n\tEndProjectSection\nEndProject\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"_build\", \"..\\build\\_build.csproj\", \"{A7717BDB-133B-433E-97CF-624B746FDDC8}\"\nEndProject\nGlobal\n\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n\t\tDebug|Any CPU = Debug|Any CPU\n\t\tRelease|Any CPU = Release|Any CPU\n\tEndGlobalSection\n\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\n\t\t{0B29307F-4E38-4611-BA0D-408A4B4F4E15}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{0B29307F-4E38-4611-BA0D-408A4B4F4E15}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{0B29307F-4E38-4611-BA0D-408A4B4F4E15}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{0B29307F-4E38-4611-BA0D-408A4B4F4E15}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{D07C40A7-39BE-4725-889F-FF2F2B781442}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{D07C40A7-39BE-4725-889F-FF2F2B781442}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{D07C40A7-39BE-4725-889F-FF2F2B781442}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{D07C40A7-39BE-4725-889F-FF2F2B781442}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{81C42342-6FD5-48D0-B45F-FD364B170FC1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{81C42342-6FD5-48D0-B45F-FD364B170FC1}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{81C42342-6FD5-48D0-B45F-FD364B170FC1}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{81C42342-6FD5-48D0-B45F-FD364B170FC1}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{6BC99E0B-6362-4A62-84F1-103B93896294}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{6BC99E0B-6362-4A62-84F1-103B93896294}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{6BC99E0B-6362-4A62-84F1-103B93896294}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{6BC99E0B-6362-4A62-84F1-103B93896294}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{A7717BDB-133B-433E-97CF-624B746FDDC8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{A7717BDB-133B-433E-97CF-624B746FDDC8}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\tEndGlobalSection\n\tGlobalSection(SolutionProperties) = preSolution\n\t\tHideSolutionNode = FALSE\n\tEndGlobalSection\n\tGlobalSection(ExtensibilityGlobals) = postSolution\n\t\tSolutionGuid = {2861CBD1-55F1-4AF9-8F6D-F2C345E8BB03}\n\tEndGlobalSection\nEndGlobal\n"
  },
  {
    "path": "src/rider/main/kotlin/com/jetbrains/rider/settings/StructuredLoggingBundle.kt",
    "content": "package com.jetbrains.rider.settings\n\nimport com.intellij.DynamicBundle\nimport org.jetbrains.annotations.Nls\nimport org.jetbrains.annotations.NonNls\nimport org.jetbrains.annotations.PropertyKey\n\nclass StructuredLoggingBundle : DynamicBundle(BUNDLE) {\n    companion object {\n        @NonNls\n        private const val BUNDLE = \"messages.StructuredLoggingBundle\"\n        private val INSTANCE: StructuredLoggingBundle = StructuredLoggingBundle()\n\n        @Nls\n        fun message(\n            @PropertyKey(resourceBundle = BUNDLE) key: String,\n            vararg params: Any\n        ): String {\n            return INSTANCE.getMessage(key, *params)\n        }\n    }\n}\n"
  },
  {
    "path": "src/rider/main/kotlin/com/jetbrains/rider/settings/StructuredLoggingPluginOptionsPage.kt",
    "content": "package com.jetbrains.rider.settings\n\nimport com.jetbrains.rider.settings.simple.SimpleOptionsPage\nimport com.jetbrains.rider.settings.StructuredLoggingBundle\n\nclass StructuredLoggingPluginOptionsPage : SimpleOptionsPage(\n    name = StructuredLoggingBundle.message(\"configurable.name.structuredlogging.title\"),\n    pageId = \"StructuredLogging\")\n{\n    override fun getId(): String {\n        return \"StructuredLogging\"\n    }\n}\n"
  },
  {
    "path": "src/rider/main/resources/META-INF/plugin.xml",
    "content": "<idea-plugin require-restart=\"true\">\n  <id>com.intellij.resharper.StructuredLogging</id>\n  <name>Structured Logging</name>\n  <description><![CDATA[\n    Contains some useful analyzers for structured logging. Supports Serilog, NLog, and Microsoft.Extensions.Logging.\n    <br/>\n    For more information visit the <a href=\"https://github.com/olsh/resharper-structured-logging#readme\">project repository</a>.\n\n    <br/>\n    <br/>\n    <a href=\"https://github.com/olsh/resharper-structured-logging/releases\">Release notes</a>\n  ]]></description>\n  <change-notes>https://github.com/olsh/resharper-structured-logging/releases</change-notes>\n  <version></version>\n  <vendor url=\"https://github.com/olsh/resharper-structured-logging\">Oleg Shevchenko</vendor>\n  <idea-version since-build=\"\" until-build=\"\"/>\n  <resource-bundle>messages.StructuredLoggingBundle</resource-bundle>\n  <extensions defaultExtensionNs=\"com.intellij\" >\n    <applicationConfigurable \n      groupId=\"language\" \n      instance=\"com.jetbrains.rider.settings.StructuredLoggingPluginOptionsPage\" \n      id=\"StructuredLogging\"\n      bundle=\"messages.StructuredLoggingBundle\"\n      key=\"configurable.name.structuredlogging.title\" />\n  </extensions>\n  <depends>com.intellij.modules.rider</depends>\n</idea-plugin>\n"
  },
  {
    "path": "src/rider/main/resources/messages/StructuredLoggingBundle.properties",
    "content": "configurable.name.structuredlogging.title=Structured Logging\n"
  },
  {
    "path": "test/data/Analyzers/AnonymousTypeDestructure/SerilogWithComplexPropertyWithoutDestructure.cs",
    "content": "using Serilog;\nusing System;\n\nnamespace ConsoleApp\n{\n    public static class Program\n    {\n        public static void Main()\n        {\n            Log.Logger.Information(\"{MyProperty}\", new { Test = 1, Complex = new Random() });\n        }\n    }\n}\n"
  },
  {
    "path": "test/data/Analyzers/AnonymousTypeDestructure/SerilogWithComplexPropertyWithoutDestructure.cs.gold",
    "content": "﻿using Serilog;\nusing System;\n\nnamespace ConsoleApp\n{\n    public static class Program\n    {\n        public static void Main()\n        {\n            Log.Logger.Information(\"|{MyProperty}|(0)\", new { Test = 1, Complex = new Random() });\n        }\n    }\n}\n\n---------------------------------------------------------\n(0): ReSharper Warning: Anonymous objects must be destructured\n"
  },
  {
    "path": "test/data/Analyzers/AnonymousTypeDestructure/SerilogWithoutDestructure.cs",
    "content": "using Serilog;\n\nnamespace ConsoleApp\n{\n    public static class Program\n    {\n        public static void Main()\n        {\n            Log.Logger.Information(\"{MyProperty}\", new { Test = 1 });\n        }\n    }\n}\n"
  },
  {
    "path": "test/data/Analyzers/AnonymousTypeDestructure/SerilogWithoutDestructure.cs.gold",
    "content": "﻿using Serilog;\n\nnamespace ConsoleApp\n{\n    public static class Program\n    {\n        public static void Main()\n        {\n            Log.Logger.Information(\"|{MyProperty}|(0)\", new { Test = 1 });\n        }\n    }\n}\n\n---------------------------------------------------------\n(0): ReSharper Warning: Anonymous objects must be destructured\n"
  },
  {
    "path": "test/data/Analyzers/ComplexTypeDestructure/SerilogContextExplicitDestructure.cs",
    "content": "using System;\nusing Serilog;\nusing Serilog.Context;\n\nnamespace ConsoleApp\n{\n    public static class Program\n    {\n        public static void Main()\n        {\n            LogContext.PushProperty(\"Test\", new Random(), true);\n        }\n    }\n}\n"
  },
  {
    "path": "test/data/Analyzers/ComplexTypeDestructure/SerilogContextExplicitDestructure.cs.gold",
    "content": "﻿using System;\nusing Serilog;\nusing Serilog.Context;\n\nnamespace ConsoleApp\n{\n    public static class Program\n    {\n        public static void Main()\n        {\n            LogContext.PushProperty(\"Test\", new Random(), true);\n        }\n    }\n}\n\n---------------------------------------------------------\n"
  },
  {
    "path": "test/data/Analyzers/ComplexTypeDestructure/SerilogContextNumericWithoutDestructure.cs",
    "content": "using System;\nusing Serilog;\nusing Serilog.Context;\n\nnamespace ConsoleApp\n{\n    public static class Program\n    {\n        public static void Main()\n        {\n            LogContext.PushProperty(\"Test\", 1);\n        }\n    }\n}\n"
  },
  {
    "path": "test/data/Analyzers/ComplexTypeDestructure/SerilogContextNumericWithoutDestructure.cs.gold",
    "content": "﻿using System;\nusing Serilog;\nusing Serilog.Context;\n\nnamespace ConsoleApp\n{\n    public static class Program\n    {\n        public static void Main()\n        {\n            LogContext.PushProperty(\"Test\", 1);\n        }\n    }\n}\n\n---------------------------------------------------------\n"
  },
  {
    "path": "test/data/Analyzers/ComplexTypeDestructure/SerilogContextWithoutDestructure.cs",
    "content": "using System;\nusing Serilog;\nusing Serilog.Context;\n\nnamespace ConsoleApp\n{\n    public static class Program\n    {\n        public static void Main()\n        {\n            LogContext.PushProperty(\"Test\", new Random());\n        }\n    }\n}\n"
  },
  {
    "path": "test/data/Analyzers/ComplexTypeDestructure/SerilogContextWithoutDestructure.cs.gold",
    "content": "﻿using System;\nusing Serilog;\nusing Serilog.Context;\n\nnamespace ConsoleApp\n{\n    public static class Program\n    {\n        public static void Main()\n        {\n            |LogContext.PushProperty(\"Test\", new Random())|(0);\n        }\n    }\n}\n\n---------------------------------------------------------\n(0): ReSharper Warning: Complex objects with default ToString() implementation probably need to be destructured\n"
  },
  {
    "path": "test/data/Analyzers/ComplexTypeDestructure/SerilogCustomExceptionWithoutDestructure.cs",
    "content": "using System;\nusing Serilog;\n\nnamespace ConsoleApp\n{\n    public static class Program\n    {\n        public static void Main()\n        {\n            Log.Logger.Error(new MyException(), \"{MyProperty}\", new Random());\n        }\n    }\n\n    public class MyException : Exception\n    {\n    }\n}\n"
  },
  {
    "path": "test/data/Analyzers/ComplexTypeDestructure/SerilogCustomExceptionWithoutDestructure.cs.gold",
    "content": "﻿using System;\nusing Serilog;\n\nnamespace ConsoleApp\n{\n    public static class Program\n    {\n        public static void Main()\n        {\n            Log.Logger.Error(new MyException(), \"|{MyProperty}|(0)\", new Random());\n        }\n    }\n\n    public class MyException : Exception\n    {\n    }\n}\n\n---------------------------------------------------------\n(0): ReSharper Warning: Complex objects with default ToString() implementation probably need to be destructured\n"
  },
  {
    "path": "test/data/Analyzers/ComplexTypeDestructure/SerilogDictionaryWithoutDestructure.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing Serilog;\n\nnamespace ConsoleApp\n{\n    public static class Program\n    {\n        public static void Main()\n        {\n            Log.Logger.Information(\"{$MyProperty}\", new Dictionary<int, string>());\n        }\n    }\n}\n"
  },
  {
    "path": "test/data/Analyzers/ComplexTypeDestructure/SerilogDictionaryWithoutDestructure.cs.gold",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing Serilog;\n\nnamespace ConsoleApp\n{\n    public static class Program\n    {\n        public static void Main()\n        {\n            Log.Logger.Information(\"{$MyProperty}\", new Dictionary<int, string>());\n        }\n    }\n}\n\n---------------------------------------------------------\n"
  },
  {
    "path": "test/data/Analyzers/ComplexTypeDestructure/SerilogEnumerableWithoutDestructure.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing Serilog;\n\nnamespace ConsoleApp\n{\n    public static class Program\n    {\n\t\tpublic static void Main()\n\t\t{\n\t\t\tIEnumerable list = new List<string>() { \"test\" };\n\t\t\tLog.Logger.Information(\"{MyProperty}\", list);\n\t\t}\n    }\n}\n"
  },
  {
    "path": "test/data/Analyzers/ComplexTypeDestructure/SerilogEnumerableWithoutDestructure.cs.gold",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing Serilog;\n\nnamespace ConsoleApp\n{\n    public static class Program\n    {\n\t\tpublic static void Main()\n\t\t{\n\t\t\tIEnumerable list = new List<string>() { \"test\" };\n\t\t\tLog.Logger.Information(\"{MyProperty}\", list);\n\t\t}\n    }\n}\n\n---------------------------------------------------------\n"
  },
  {
    "path": "test/data/Analyzers/ComplexTypeDestructure/SerilogForceStringWithoutDestructure.cs",
    "content": "using System;\nusing Serilog;\n\nnamespace ConsoleApp\n{\n    public static class Program\n    {\n        public static void Main()\n        {\n            Log.Logger.Information(\"{$MyProperty}\", new Random());\n        }\n    }\n}\n"
  },
  {
    "path": "test/data/Analyzers/ComplexTypeDestructure/SerilogForceStringWithoutDestructure.cs.gold",
    "content": "﻿using System;\nusing Serilog;\n\nnamespace ConsoleApp\n{\n    public static class Program\n    {\n        public static void Main()\n        {\n            Log.Logger.Information(\"{$MyProperty}\", new Random());\n        }\n    }\n}\n\n---------------------------------------------------------\n"
  },
  {
    "path": "test/data/Analyzers/ComplexTypeDestructure/SerilogNullableWithoutDestructure.cs",
    "content": "using System;\nusing Serilog;\n\nnamespace ConsoleApp\n{\n    public static class Program\n    {\n        public static void Main()\n        {\n        \tint? a = 1;\n            Log.Logger.Information(\"{$MyProperty}\", a);\n        }\n    }\n}\n"
  },
  {
    "path": "test/data/Analyzers/ComplexTypeDestructure/SerilogNullableWithoutDestructure.cs.gold",
    "content": "﻿using System;\nusing Serilog;\n\nnamespace ConsoleApp\n{\n    public static class Program\n    {\n        public static void Main()\n        {\n        \tint? a = 1;\n            Log.Logger.Information(\"{$MyProperty}\", a);\n        }\n    }\n}\n\n---------------------------------------------------------\n"
  },
  {
    "path": "test/data/Analyzers/ComplexTypeDestructure/SerilogNumericWithoutDestructure.cs",
    "content": "using System;\nusing Serilog;\n\nnamespace ConsoleApp\n{\n    public static class Program\n    {\n        public static void Main()\n        {\n            Log.Logger.Information(\"{$MyProperty}\", 3);\n        }\n    }\n}\n"
  },
  {
    "path": "test/data/Analyzers/ComplexTypeDestructure/SerilogNumericWithoutDestructure.cs.gold",
    "content": "﻿using System;\nusing Serilog;\n\nnamespace ConsoleApp\n{\n    public static class Program\n    {\n        public static void Main()\n        {\n            Log.Logger.Information(\"{$MyProperty}\", 3);\n        }\n    }\n}\n\n---------------------------------------------------------\n"
  },
  {
    "path": "test/data/Analyzers/ComplexTypeDestructure/SerilogParentWithOverriddenToString.cs",
    "content": "using System;\nusing Serilog;\n\nnamespace ConsoleApp\n{\n    public static class Program\n    {\n        public static void Main()\n        {\n            Log.Logger.Information(\"{MyProperty}\", new B());\n        }\n    }\n\n    public class A\n    {\n        public override string ToString() => \"Custom ToString\";\n    }\n\n    public class B: A { }\n}\n"
  },
  {
    "path": "test/data/Analyzers/ComplexTypeDestructure/SerilogParentWithOverriddenToString.cs.gold",
    "content": "﻿using System;\nusing Serilog;\n\nnamespace ConsoleApp\n{\n    public static class Program\n    {\n        public static void Main()\n        {\n            Log.Logger.Information(\"{MyProperty}\", new B());\n        }\n    }\n\n    public class A\n    {\n        public override string ToString() => \"Custom ToString\";\n    }\n\n    public class B: A { }\n}\n\n---------------------------------------------------------\n"
  },
  {
    "path": "test/data/Analyzers/ComplexTypeDestructure/SerilogWithoutDestructure.cs",
    "content": "using System;\nusing Serilog;\n\nnamespace ConsoleApp\n{\n    public static class Program\n    {\n        public static void Main()\n        {\n            Log.Logger.Information(\"{MyProperty}\", new Random());\n        }\n    }\n}\n"
  },
  {
    "path": "test/data/Analyzers/ComplexTypeDestructure/SerilogWithoutDestructure.cs.gold",
    "content": "﻿using System;\nusing Serilog;\n\nnamespace ConsoleApp\n{\n    public static class Program\n    {\n        public static void Main()\n        {\n            Log.Logger.Information(\"|{MyProperty}|(0)\", new Random());\n        }\n    }\n}\n\n---------------------------------------------------------\n(0): ReSharper Warning: Complex objects with default ToString() implementation probably need to be destructured\n"
  },
  {
    "path": "test/data/Analyzers/ContextualLoggerConstructor/MicrosoftCorrectContextType.cs",
    "content": "using Microsoft.Extensions.Logging;\n\nclass A\n{\n\tILogger<A> _log;\n\t\n\tpublic A(ILogger<A> log)\n\t{\n\t\t_log = log;\n\t}\n}\n"
  },
  {
    "path": "test/data/Analyzers/ContextualLoggerConstructor/MicrosoftCorrectContextType.cs.gold",
    "content": "﻿using Microsoft.Extensions.Logging;\n\nclass A\n{\n\tILogger<A> _log;\n\t\n\tpublic A(ILogger<A> log)\n\t{\n\t\t_log = log;\n\t}\n}\n\n---------------------------------------------------------\n"
  },
  {
    "path": "test/data/Analyzers/ContextualLoggerConstructor/MicrosoftWrongContextType.cs",
    "content": "using Microsoft.Extensions.Logging;\n\nclass A\n{\n\tILogger<B> _log;\n\t\n\tpublic A(ILogger<B> log)\n\t{\n\t\t_log = log;\n\t}\n}\n\nclass B { }\n"
  },
  {
    "path": "test/data/Analyzers/ContextualLoggerConstructor/MicrosoftWrongContextType.cs.gold",
    "content": "﻿using Microsoft.Extensions.Logging;\n\nclass A\n{\n\tILogger<B> _log;\n\t\n\tpublic A(|ILogger<B>|(0) log)\n\t{\n\t\t_log = log;\n\t}\n}\n\nclass B { }\n\n---------------------------------------------------------\n(0): ReSharper Warning: Incorrect type is used for contextual logger\n"
  },
  {
    "path": "test/data/Analyzers/ContextualLoggerConstructor/MicrosoftWrongContextTypeMultipleNamespaces.cs",
    "content": "using Microsoft.Extensions.Logging;\n\nnamespace X\n{\n\tclass A { }\n}\n\nnamespace Y\n{\n\tclass A\n\t{\n\t\tILogger<X.A> _log;\n\t\t\n\t\tpublic A(ILogger<X.A> log)\n\t\t{\n\t\t\t_log = log;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "test/data/Analyzers/ContextualLoggerConstructor/MicrosoftWrongContextTypeMultipleNamespaces.cs.gold",
    "content": "﻿using Microsoft.Extensions.Logging;\n\nnamespace X\n{\n\tclass A { }\n}\n\nnamespace Y\n{\n\tclass A\n\t{\n\t\tILogger<X.A> _log;\n\t\t\n\t\tpublic A(|ILogger<X.A>|(0) log)\n\t\t{\n\t\t\t_log = log;\n\t\t}\n\t}\n}\n\n---------------------------------------------------------\n(0): ReSharper Warning: Incorrect type is used for contextual logger\n"
  },
  {
    "path": "test/data/Analyzers/ContextualLoggerConstructor/MicrosoftWrongContextTypeMultipleParameters.cs",
    "content": "using Microsoft.Extensions.Logging;\n\nclass A\n{\n\tILogger<B> _log;\n\t\n\tpublic A(int a, ILogger<B> log)\n\t{\n\t\t_log = log;\n\t}\n}\n\nclass B { }\n"
  },
  {
    "path": "test/data/Analyzers/ContextualLoggerConstructor/MicrosoftWrongContextTypeMultipleParameters.cs.gold",
    "content": "﻿using Microsoft.Extensions.Logging;\n\nclass A\n{\n\tILogger<B> _log;\n\t\n\tpublic A(int a, |ILogger<B>|(0) log)\n\t{\n\t\t_log = log;\n\t}\n}\n\nclass B { }\n\n---------------------------------------------------------\n(0): ReSharper Warning: Incorrect type is used for contextual logger\n"
  },
  {
    "path": "test/data/Analyzers/ContextualLoggerSerilogFactory/SerilogCorrectContextType.cs",
    "content": "using Serilog;\n\nclass A\n{\n    private static readonly ILogger Logger = Logger.ForContext<A>();\n}\n\nclass B {} \n"
  },
  {
    "path": "test/data/Analyzers/ContextualLoggerSerilogFactory/SerilogCorrectContextType.cs.gold",
    "content": "﻿using Serilog;\n\nclass A\n{\n    private static readonly ILogger Logger = Logger.ForContext<A>();\n}\n\nclass B {} \n\n---------------------------------------------------------\n"
  },
  {
    "path": "test/data/Analyzers/ContextualLoggerSerilogFactory/SerilogWrongContextType.cs",
    "content": "using Serilog;\n\nclass A\n{\n    private static readonly ILogger Logger = Logger.ForContext<B>();\n}\n\nclass B {} \n"
  },
  {
    "path": "test/data/Analyzers/ContextualLoggerSerilogFactory/SerilogWrongContextType.cs.gold",
    "content": "﻿using Serilog;\n\nclass A\n{\n    private static readonly ILogger Logger = |Logger.ForContext<B>()|(0);\n}\n\nclass B {} \n\n---------------------------------------------------------\n(0):<overlapped> ReSharper Warning: Incorrect type is used for contextual logger\n"
  },
  {
    "path": "test/data/Analyzers/CorrectExceptionPassing/SerilogCorrectExceptionPassing.cs",
    "content": "﻿using System;\nusing Serilog;\n\nnamespace ConsoleApp\n{\n    public static class Program\n    {\n        public static void Main()\n        {\n            Log.Logger.Information(new Exception(), \"{One}\", 1);\n        }\n    }\n}\n"
  },
  {
    "path": "test/data/Analyzers/CorrectExceptionPassing/SerilogCorrectExceptionPassing.cs.gold",
    "content": "﻿using System;\nusing Serilog;\n\nnamespace ConsoleApp\n{\n    public static class Program\n    {\n        public static void Main()\n        {\n            Log.Logger.Information(new Exception(), \"{One}\", 1);\n        }\n    }\n}\n\n---------------------------------------------------------\n"
  },
  {
    "path": "test/data/Analyzers/CorrectExceptionPassing/SerilogIncorrectExceptionPassing.cs",
    "content": "﻿using System;\nusing Serilog;\n\nnamespace ConsoleApp\n{\n    public static class Program\n    {\n        public static void Main()\n        {\n            Log.Logger.Information(\"{One} {Exc}\", 1, new Exception());\n        }\n    }\n}\n"
  },
  {
    "path": "test/data/Analyzers/CorrectExceptionPassing/SerilogIncorrectExceptionPassing.cs.gold",
    "content": "﻿using System;\nusing Serilog;\n\nnamespace ConsoleApp\n{\n    public static class Program\n    {\n        public static void Main()\n        {\n            Log.Logger.Information(\"{One} {Exc}\", 1, |new Exception()|(0));\n        }\n    }\n}\n\n---------------------------------------------------------\n(0): ReSharper Warning: Exception should be passed to the exception argument\n"
  },
  {
    "path": "test/data/Analyzers/CorrectExceptionPassing/SerilogIncorrectExceptionPassingDynamicTemplate.cs",
    "content": "﻿using System;\nusing Serilog;\n\nnamespace ConsoleApp\n{\n    public static class Program\n    {\n        public static void Main()\n        {\n            Log.Logger.Information($\"{DateTime.Now} {{Error}}\", new Exception());\n        }\n    }\n}\n"
  },
  {
    "path": "test/data/Analyzers/CorrectExceptionPassing/SerilogIncorrectExceptionPassingDynamicTemplate.cs.gold",
    "content": "﻿using System;\nusing Serilog;\n\nnamespace ConsoleApp\n{\n    public static class Program\n    {\n        public static void Main()\n        {\n            Log.Logger.Information($\"{DateTime.Now} |{{|(0)Error|}}|(1)\", |new Exception()|(2));\n        }\n    }\n}\n\n---------------------------------------------------------\n(0): ReSharper C# Escape Character 1: \n(1): ReSharper C# Escape Character 1: \n(2): ReSharper Warning: Exception should be passed to the exception argument\n"
  },
  {
    "path": "test/data/Analyzers/CorrectExceptionPassing/SerilogMultipleExceptionPassing.cs",
    "content": "﻿using System;\nusing Serilog;\n\nnamespace ConsoleApp\n{\n    public static class Program\n    {\n        public static void Main()\n        {\n            Log.Logger.Information(new Exception(), \"{One} {OtherException}\", 1, new Exception());\n        }\n    }\n}\n"
  },
  {
    "path": "test/data/Analyzers/CorrectExceptionPassing/SerilogMultipleExceptionPassing.cs.gold",
    "content": "﻿using System;\nusing Serilog;\n\nnamespace ConsoleApp\n{\n    public static class Program\n    {\n        public static void Main()\n        {\n            Log.Logger.Information(new Exception(), \"{One} {OtherException}\", 1, new Exception());\n        }\n    }\n}\n\n---------------------------------------------------------\n"
  },
  {
    "path": "test/data/Analyzers/DuplicatePropertiesTemplate/SerilogDuplicateNamedProperty.cs",
    "content": "﻿using Serilog;\n\nnamespace ConsoleApp\n{\n    public static class Program\n    {\n        public static void Main()\n        {\n            Log.Logger.Information(\"{Test} {Test}\", 1, 2);\n        }\n    }\n}\n"
  },
  {
    "path": "test/data/Analyzers/DuplicatePropertiesTemplate/SerilogDuplicateNamedProperty.cs.gold",
    "content": "﻿using Serilog;\n\nnamespace ConsoleApp\n{\n    public static class Program\n    {\n        public static void Main()\n        {\n            Log.Logger.Information(\"|{Test}|(0) |{Test}|(1)\", 1, 2);\n        }\n    }\n}\n\n---------------------------------------------------------\n(0): ReSharper Warning: Duplicate properties in message template\n(1): ReSharper Warning: Duplicate properties in message template\n"
  },
  {
    "path": "test/data/Analyzers/LogMessageIsSentence/SerilogNotSentenceMessage.cs",
    "content": "using Serilog;\n\nnamespace ConsoleApp\n{\n    public static class Program\n    {\n        public static void Main()\n        {\n            Log.Logger.Information(\"Loading {Name}...\", \"World\");\n        }\n    }\n}\n"
  },
  {
    "path": "test/data/Analyzers/LogMessageIsSentence/SerilogNotSentenceMessage.cs.gold",
    "content": "﻿using Serilog;\n\nnamespace ConsoleApp\n{\n    public static class Program\n    {\n        public static void Main()\n        {\n            Log.Logger.Information(\"Loading {Name}...\", \"World\");\n        }\n    }\n}\n\n---------------------------------------------------------\n"
  },
  {
    "path": "test/data/Analyzers/LogMessageIsSentence/SerilogSentenceMessage.cs",
    "content": "using Serilog;\n\nnamespace ConsoleApp\n{\n    public static class Program\n    {\n        public static void Main()\n        {\n            Log.Logger.Information(\"Hello {Name}.\", \"World\");\n        }\n    }\n}\n"
  },
  {
    "path": "test/data/Analyzers/LogMessageIsSentence/SerilogSentenceMessage.cs.gold",
    "content": "﻿using Serilog;\n\nnamespace ConsoleApp\n{\n    public static class Program\n    {\n        public static void Main()\n        {\n            Log.Logger.Information(|\"Hello {Name}.\"|(0), \"World\");\n        }\n    }\n}\n\n---------------------------------------------------------\n(0): ReSharper Warning: Log event messages should be fragments, not sentences. Avoid a trailing period/full stop.\n"
  },
  {
    "path": "test/data/Analyzers/PositionalPropertiesUsage/SerilogPositionProperty.cs",
    "content": "﻿using Serilog;\n\nnamespace ConsoleApp\n{\n    public static class Program\n    {\n        public static void Main()\n        {\n            Log.Logger.Information(\"{0}\", 1);\n        }\n    }\n}\n"
  },
  {
    "path": "test/data/Analyzers/PositionalPropertiesUsage/SerilogPositionProperty.cs.gold",
    "content": "﻿using Serilog;\n\nnamespace ConsoleApp\n{\n    public static class Program\n    {\n        public static void Main()\n        {\n            Log.Logger.Information(\"|{0}|(0)\", 1);\n        }\n    }\n}\n\n---------------------------------------------------------\n(0): ReSharper Warning: Prefer named properties instead of positional ones\n"
  },
  {
    "path": "test/data/Analyzers/PropertiesNamingAnalyzer/SerilogContextInterpolatedStringProperty.cs",
    "content": "using Serilog;\nusing Serilog.Context;\n\nnamespace ConsoleApp\n{\n    public static class Program\n    {\n        public static void Main()\n        {\n            var s = \"world\";\n            LogContext.PushProperty($\"Hello{s}\", 1);\n        }\n    }\n}\n"
  },
  {
    "path": "test/data/Analyzers/PropertiesNamingAnalyzer/SerilogContextInterpolatedStringProperty.cs.gold",
    "content": "﻿using Serilog;\nusing Serilog.Context;\n\nnamespace ConsoleApp\n{\n    public static class Program\n    {\n        public static void Main()\n        {\n            var s = \"world\";\n            LogContext.PushProperty($\"Hello{s}\", 1);\n        }\n    }\n}\n\n---------------------------------------------------------\n"
  },
  {
    "path": "test/data/Analyzers/PropertiesNamingAnalyzer/SerilogContextInvalidNamedProperty.cs",
    "content": "using Serilog;\nusing Serilog.Context;\n\nnamespace ConsoleApp\n{\n    public static class Program\n    {\n        public static void Main()\n        {\n            LogContext.PushProperty(\"test\", 1);\n        }\n    }\n}\n"
  },
  {
    "path": "test/data/Analyzers/PropertiesNamingAnalyzer/SerilogContextInvalidNamedProperty.cs.gold",
    "content": "﻿using Serilog;\nusing Serilog.Context;\n\nnamespace ConsoleApp\n{\n    public static class Program\n    {\n        public static void Main()\n        {\n            LogContext.PushProperty(|\"test\"|(0), 1);\n        }\n    }\n}\n\n---------------------------------------------------------\n(0): ReSharper Warning: Property name 'test' does not match naming rules. Suggested name is 'Test'.\n"
  },
  {
    "path": "test/data/Analyzers/PropertiesNamingAnalyzer/SerilogIgnoredInvalidNamedProperty.cs",
    "content": "using Serilog;\n\nnamespace ConsoleApp\n{\n    public static class Program\n    {\n        public static void Main()\n        {\n            Log.Logger.Information(\"{MY_IGNORED.Property_}\", 1);\n        }\n    }\n}\n"
  },
  {
    "path": "test/data/Analyzers/PropertiesNamingAnalyzer/SerilogIgnoredInvalidNamedProperty.cs.gold",
    "content": "﻿using Serilog;\n\nnamespace ConsoleApp\n{\n    public static class Program\n    {\n        public static void Main()\n        {\n            Log.Logger.Information(\"{MY_IGNORED.Property_}\", 1);\n        }\n    }\n}\n\n---------------------------------------------------------\n"
  },
  {
    "path": "test/data/Analyzers/PropertiesNamingAnalyzer/SerilogInvalidElasticNamedProperty.cs",
    "content": "﻿using Serilog;\n\nnamespace ConsoleApp\n{\n    public static class Program\n    {\n        public static void Main()\n        {\n            Log.Logger.Information(\"{myProperty}\", 1);\n        }\n    }\n}\n"
  },
  {
    "path": "test/data/Analyzers/PropertiesNamingAnalyzer/SerilogInvalidElasticNamedProperty.cs.gold",
    "content": "﻿using Serilog;\n\nnamespace ConsoleApp\n{\n    public static class Program\n    {\n        public static void Main()\n        {\n            Log.Logger.Information(\"|{myProperty}|(0)\", 1);\n        }\n    }\n}\n\n---------------------------------------------------------\n(0): ReSharper Warning: Property name 'myProperty' does not match naming rules. Suggested name is 'my.property'.\n"
  },
  {
    "path": "test/data/Analyzers/PropertiesNamingAnalyzer/SerilogInvalidNamedProperty.cs",
    "content": "﻿using Serilog;\n\nnamespace ConsoleApp\n{\n    public static class Program\n    {\n        public static void Main()\n        {\n            Log.Logger.Information(\"{myProperty}\", 1);\n        }\n    }\n}\n"
  },
  {
    "path": "test/data/Analyzers/PropertiesNamingAnalyzer/SerilogInvalidNamedProperty.cs.gold",
    "content": "﻿using Serilog;\n\nnamespace ConsoleApp\n{\n    public static class Program\n    {\n        public static void Main()\n        {\n            Log.Logger.Information(\"|{myProperty}|(0)\", 1);\n        }\n    }\n}\n\n---------------------------------------------------------\n(0): ReSharper Warning: Property name 'myProperty' does not match naming rules. Suggested name is 'MyProperty'.\n"
  },
  {
    "path": "test/data/Analyzers/PropertiesNamingAnalyzer/SerilogInvalidNamedPropertyWithDot.cs",
    "content": "using Serilog;\n\nnamespace ConsoleApp\n{\n    public static class Program\n    {\n        public static void Main()\n        {\n            Log.Logger.Information(\"{My.Property}\", 1);\n        }\n    }\n}\n"
  },
  {
    "path": "test/data/Analyzers/PropertiesNamingAnalyzer/SerilogInvalidNamedPropertyWithDot.cs.gold",
    "content": "﻿using Serilog;\n\nnamespace ConsoleApp\n{\n    public static class Program\n    {\n        public static void Main()\n        {\n            Log.Logger.Information(\"|{My.Property}|(0)\", 1);\n        }\n    }\n}\n\n---------------------------------------------------------\n(0): ReSharper Warning: Property name 'My.Property' does not match naming rules. Suggested name is 'MyProperty'.\n"
  },
  {
    "path": "test/data/Analyzers/PropertiesNamingAnalyzer/SerilogInvalidNamedPropertyWithSpace.cs",
    "content": "using Serilog;\n\nnamespace ConsoleApp\n{\n    public static class Program\n    {\n        public static void Main()\n        {\n            Log.Logger.Information(\"{My Property}\", 1);\n        }\n    }\n}\n"
  },
  {
    "path": "test/data/Analyzers/PropertiesNamingAnalyzer/SerilogInvalidNamedPropertyWithSpace.cs.gold",
    "content": "﻿using Serilog;\n\nnamespace ConsoleApp\n{\n    public static class Program\n    {\n        public static void Main()\n        {\n            Log.Logger.Information(\"|{My Property}|(0)\", 1);\n        }\n    }\n}\n\n---------------------------------------------------------\n(0): ReSharper Warning: Property name 'My Property' does not match naming rules. Suggested name is 'MyProperty'.\n"
  },
  {
    "path": "test/data/Analyzers/PropertiesNamingAnalyzer/SerilogInvalidSyntax.cs",
    "content": "﻿using Serilog;\n\nnamespace ConsoleApp\n{\n    public static class Program\n    {\n        public static void Main()\n        {\n            Log.Logger.Information(%\"{MyProperty}\", 1);\n        }\n    }\n}\n"
  },
  {
    "path": "test/data/Analyzers/PropertiesNamingAnalyzer/SerilogInvalidSyntax.cs.gold",
    "content": "﻿using Serilog;\n\nnamespace ConsoleApp\n{\n    public static class Program\n    {\n        public static void Main()\n        {\n            Log.Logger.Information(%\"{MyProperty}\", 1);\n        }\n    }\n}\n\n---------------------------------------------------------\n"
  },
  {
    "path": "test/data/Analyzers/PropertiesNamingAnalyzer/SerilogValidDestructuredNamedProperty.cs",
    "content": "﻿using Serilog;\n\nnamespace ConsoleApp\n{\n    public static class Program\n    {\n        public static void Main()\n        {\n            Log.Logger.Information(\"{@MyProperty}\", 1);\n        }\n    }\n}\n"
  },
  {
    "path": "test/data/Analyzers/PropertiesNamingAnalyzer/SerilogValidDestructuredNamedProperty.cs.gold",
    "content": "﻿using Serilog;\n\nnamespace ConsoleApp\n{\n    public static class Program\n    {\n        public static void Main()\n        {\n            Log.Logger.Information(\"{@MyProperty}\", 1);\n        }\n    }\n}\n\n---------------------------------------------------------\n"
  },
  {
    "path": "test/data/Analyzers/PropertiesNamingAnalyzer/SerilogValidNamedProperty.cs",
    "content": "﻿using Serilog;\n\nnamespace ConsoleApp\n{\n    public static class Program\n    {\n        public static void Main()\n        {\n            Log.Logger.Information(\"{MyProperty}\", 1);\n        }\n    }\n}\n"
  },
  {
    "path": "test/data/Analyzers/PropertiesNamingAnalyzer/SerilogValidNamedProperty.cs.gold",
    "content": "﻿using Serilog;\n\nnamespace ConsoleApp\n{\n    public static class Program\n    {\n        public static void Main()\n        {\n            Log.Logger.Information(\"{MyProperty}\", 1);\n        }\n    }\n}\n\n---------------------------------------------------------\n"
  },
  {
    "path": "test/data/Analyzers/PropertiesNamingAnalyzerDotNet6/ZLoggerInvalidNamedProperty.cs",
    "content": "﻿using Microsoft.Extensions.Logging;\nusing ZLogger;\n\nnamespace ConsoleApp\n{\n    class A\n    {\n        public A(ILogger<A> log)\n        {\n            log.ZLogInformation(\"{myProperty}\", 1);\n        }\n    }\n}\n"
  },
  {
    "path": "test/data/Analyzers/PropertiesNamingAnalyzerDotNet6/ZLoggerInvalidNamedProperty.cs.gold",
    "content": "﻿using Microsoft.Extensions.Logging;\nusing ZLogger;\n\nnamespace ConsoleApp\n{\n    class A\n    {\n        public A(ILogger<A> log)\n        {\n            log.ZLogInformation(\"|{myProperty}|(0)\", 1);\n        }\n    }\n}\n\n---------------------------------------------------------\n(0): ReSharper Warning: Property name 'myProperty' does not match naming rules. Suggested name is 'MyProperty'.\n"
  },
  {
    "path": "test/data/QuickFixes/AddDestructuringFix/SerilogEscapedString.cs",
    "content": "﻿using Serilog;\n\nnamespace ConsoleApp\n{\n    public static class Program\n    {\n        public static void Main()\n        {\n            Log.Logger.Information(\"Escaped \\r\\n {MyPro{caret}perty} \\r\\n string\", new { Test = 1 });\n        }\n    }\n}\n"
  },
  {
    "path": "test/data/QuickFixes/AddDestructuringFix/SerilogEscapedString.cs.gold",
    "content": "﻿using Serilog;\n\nnamespace ConsoleApp\n{\n    public static class Program\n    {\n        public static void Main()\n        {\n            Log.Logger.Information(\"Escaped \\r\\n {@MyPro{caret}perty} \\r\\n string\", new { Test = 1 });\n        }\n    }\n}\n"
  },
  {
    "path": "test/data/QuickFixes/AddDestructuringFix/SerilogNewAnonymousObject.cs",
    "content": "﻿using Serilog;\n\nnamespace ConsoleApp\n{\n    public static class Program\n    {\n        public static void Main()\n        {\n            Log.Logger.Information(\"{MyPro{caret}perty}\", new { Test = 1 });\n        }\n    }\n}\n"
  },
  {
    "path": "test/data/QuickFixes/AddDestructuringFix/SerilogNewAnonymousObject.cs.gold",
    "content": "﻿using Serilog;\n\nnamespace ConsoleApp\n{\n    public static class Program\n    {\n        public static void Main()\n        {\n            Log.Logger.Information(\"{@MyPro{caret}perty}\", new { Test = 1 });\n        }\n    }\n}\n"
  },
  {
    "path": "test/data/QuickFixes/AddDestructuringFix/SerilogNewComplexObject.cs",
    "content": "﻿using Serilog;\nusing System;\n\nnamespace ConsoleApp\n{\n    public static class Program\n    {\n        public static void Main()\n        {\n            Log.Logger.Information(\"{MyPro{caret}perty}\", new Random());\n        }\n    }\n}\n"
  },
  {
    "path": "test/data/QuickFixes/AddDestructuringFix/SerilogNewComplexObject.cs.gold",
    "content": "﻿using Serilog;\nusing System;\n\nnamespace ConsoleApp\n{\n    public static class Program\n    {\n        public static void Main()\n        {\n            Log.Logger.Information(\"{@MyPro{caret}perty}\", new Random());\n        }\n    }\n}\n"
  },
  {
    "path": "test/data/QuickFixes/RemoveTrailingPeriodFix/SerilogTrailingPeriod.cs",
    "content": "using Serilog;\n\nnamespace ConsoleApp\n{\n    public static class Program\n    {\n        public static void Main()\n        {\n            Log.Logger.Information(\"Test {caret}{Property} prop.\", 1);\n        }\n    }\n}\n"
  },
  {
    "path": "test/data/QuickFixes/RemoveTrailingPeriodFix/SerilogTrailingPeriod.cs.gold",
    "content": "﻿using Serilog;\n\nnamespace ConsoleApp\n{\n    public static class Program\n    {\n        public static void Main()\n        {\n            Log.Logger.Information(\"Test {caret}{Property} prop\", 1);\n        }\n    }\n}\n"
  },
  {
    "path": "test/data/QuickFixes/RenameContextLogPropertyFix/SerilogContextProperty.cs",
    "content": "using Serilog;\nusing Serilog.Context;\n\nnamespace ConsoleApp\n{\n    public static class Program\n    {\n        public static void Main()\n        {\n            LogContext.PushProperty(\"{caret}test\", 1);\n        }\n    }\n}\n"
  },
  {
    "path": "test/data/QuickFixes/RenameContextLogPropertyFix/SerilogContextProperty.cs.gold",
    "content": "﻿using Serilog;\nusing Serilog.Context;\n\nnamespace ConsoleApp\n{\n    public static class Program\n    {\n        public static void Main()\n        {\n            LogContext.PushProperty(\"T{caret}est\", 1);\n        }\n    }\n}\n"
  },
  {
    "path": "test/data/QuickFixes/RenameLogPropertyFix/SerilogDestructuredProperty.cs",
    "content": "﻿using Serilog;\n\nnamespace ConsoleApp\n{\n    public static class Program\n    {\n        public static void Main()\n        {\n            Log.Logger.Information(\"Test {@my{caret}Property} prop\", 1);\n        }\n    }\n}\n"
  },
  {
    "path": "test/data/QuickFixes/RenameLogPropertyFix/SerilogDestructuredProperty.cs.gold",
    "content": "﻿using Serilog;\n\nnamespace ConsoleApp\n{\n    public static class Program\n    {\n        public static void Main()\n        {\n            Log.Logger.Information(\"Test {@My{caret}Property} prop\", 1);\n        }\n    }\n}\n"
  },
  {
    "path": "test/data/QuickFixes/RenameLogPropertyFix/SerilogProperty.cs",
    "content": "﻿using Serilog;\n\nnamespace ConsoleApp\n{\n    public static class Program\n    {\n        public static void Main()\n        {\n            Log.Logger.Information(\"Test {my{caret}Property} prop\", 1);\n        }\n    }\n}\n"
  },
  {
    "path": "test/data/QuickFixes/RenameLogPropertyFix/SerilogProperty.cs.gold",
    "content": "﻿using Serilog;\n\nnamespace ConsoleApp\n{\n    public static class Program\n    {\n        public static void Main()\n        {\n            Log.Logger.Information(\"Test {My{caret}Property} prop\", 1);\n        }\n    }\n}\n"
  },
  {
    "path": "test/data/QuickFixes/RenameLogPropertyFix/SerilogPropertyConcatenated.cs",
    "content": "using Serilog;\n\nnamespace ConsoleApp\n{\n    public static class Program\n    {\n        public static void Main()\n        {\n            Log.Logger.Information(\"Test\" + \" {my{caret}Property} prop\", 1);\n        }\n    }\n}\n"
  },
  {
    "path": "test/data/QuickFixes/RenameLogPropertyFix/SerilogPropertyConcatenated.cs.gold",
    "content": "﻿using Serilog;\n\nnamespace ConsoleApp\n{\n    public static class Program\n    {\n        public static void Main()\n        {\n            Log.Logger.Information(\"Test\" + \" {My{caret}Property} prop\", 1);\n        }\n    }\n}\n"
  },
  {
    "path": "test/data/nuget.config",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<configuration>\n  <config>\n    <add key=\"repositorypath\" value=\"./packages\" />\n  </config>\n  <packageSources>\n    <clear />\n    <add key=\"jb-gallery\" value=\"http://jb-gallery.azurewebsites.net/api/v2/\" />\n    <add key=\"nuget.org\" value=\"http://www.nuget.org/api/v2/\" />\n  </packageSources>\n  <disabledPackageSources>\n    <clear />\n  </disabledPackageSources>\n  <packageRestore>\n    <!-- Allow NuGet to download missing packages -->\n    <add key=\"enabled\" value=\"True\" />\n\n    <!-- Automatically check for missing packages during build in Visual Studio -->\n    <add key=\"automatic\" value=\"True\" />\n  </packageRestore>\n</configuration>\n"
  },
  {
    "path": "test/src/Analyzer/AnonymousTypeDestructureAnalyzerTests.cs",
    "content": "﻿using NUnit.Framework;\n\nnamespace ReSharper.Structured.Logging.Tests.Analyzer\n{\n    public class AnonymousTypeDestructureAnalyzerTests : MessageTemplateAnalyzerTestBase\n    {\n        protected override string SubPath => \"AnonymousTypeDestructure\";\n\n        [Test] public void TestSerilogWithoutDestructure() => DoNamedTest2();\n\n        [Test] public void TestSerilogWithComplexPropertyWithoutDestructure() => DoNamedTest2();\n    }\n}\n"
  },
  {
    "path": "test/src/Analyzer/ComplexObjectDestructureAnalyzerTests.cs",
    "content": "using NUnit.Framework;\n\nnamespace ReSharper.Structured.Logging.Tests.Analyzer\n{\n    public class ComplexObjectDestructureAnalyzerTests : MessageTemplateAnalyzerTestBase\n    {\n        protected override string SubPath => \"ComplexTypeDestructure\";\n\n        [Test] public void TestSerilogWithoutDestructure() => DoNamedTest2();\n\n        [Test] public void TestSerilogForceStringWithoutDestructure() => DoNamedTest2();\n\n        [Test] public void TestSerilogNumericWithoutDestructure() => DoNamedTest2();\n\n        [Test] public void TestSerilogEnumerableWithoutDestructure() => DoNamedTest2();\n\n        [Test] public void TestSerilogNullableWithoutDestructure() => DoNamedTest2();\n\n        [Test] public void TestSerilogDictionaryWithoutDestructure() => DoNamedTest2();\n\n        [Test] public void TestSerilogContextWithoutDestructure() => DoNamedTest2();\n\n        [Test] public void TestSerilogContextNumericWithoutDestructure() => DoNamedTest2();\n\n        [Test] public void TestSerilogContextExplicitDestructure() => DoNamedTest2();\n\n        [Test] public void TestSerilogCustomExceptionWithoutDestructure() => DoNamedTest2();\n\n        [Test] public void TestSerilogParentWithOverriddenToString() => DoNamedTest2();\n    }\n}\n"
  },
  {
    "path": "test/src/Analyzer/ContextualLoggerConstructorAnalyzerTests.cs",
    "content": "﻿using JetBrains.ReSharper.TestFramework;\n\nusing NUnit.Framework;\n\nnamespace ReSharper.Structured.Logging.Tests.Analyzer\n{\n    [TestNet60]\n    public class ContextualLoggerConstructorAnalyzerTests : MessageTemplateAnalyzerTestBase\n    {\n        protected override string SubPath => \"ContextualLoggerConstructor\";\n\n        [Test] public void TestMicrosoftCorrectContextType() => DoNamedTest2();\n\n        [Test] public void TestMicrosoftWrongContextType() => DoNamedTest2();\n\n        [Test] public void TestMicrosoftWrongContextTypeMultipleNamespaces() => DoNamedTest2();\n\n        [Test] public void TestMicrosoftWrongContextTypeMultipleParameters() => DoNamedTest2();\n    }\n}\n"
  },
  {
    "path": "test/src/Analyzer/ContextualLoggerSerilogFactoryAnalyzerTests.cs",
    "content": "﻿using NUnit.Framework;\n\nnamespace ReSharper.Structured.Logging.Tests.Analyzer\n{\n    public class ContextualLoggerSerilogFactoryAnalyzerTests : MessageTemplateAnalyzerTestBase\n    {\n        protected override string SubPath => \"ContextualLoggerSerilogFactory\";\n\n        [Test] public void TestSerilogCorrectContextType() => DoNamedTest2();\n\n        [Test] public void TestSerilogWrongContextType() => DoNamedTest2();\n    }\n}\n"
  },
  {
    "path": "test/src/Analyzer/CorrectExceptionPassingAnalyzerTests.cs",
    "content": "﻿using NUnit.Framework;\n\nnamespace ReSharper.Structured.Logging.Tests.Analyzer\n{\n    public class CorrectExceptionPassingAnalyzerTests : MessageTemplateAnalyzerTestBase\n    {\n        protected override string SubPath => \"CorrectExceptionPassing\";\n\n        [Test] public void TestSerilogCorrectExceptionPassing() => DoNamedTest2();\n\n        [Test] public void TestSerilogIncorrectExceptionPassing() => DoNamedTest2();\n\n        [Test] public void TestSerilogIncorrectExceptionPassingDynamicTemplate() => DoNamedTest2();\n\n        [Test] public void TestSerilogMultipleExceptionPassing() => DoNamedTest2();\n    }\n}\n"
  },
  {
    "path": "test/src/Analyzer/DuplicatePropertiesTemplateAnalyzerTests.cs",
    "content": "﻿using NUnit.Framework;\n\nnamespace ReSharper.Structured.Logging.Tests.Analyzer\n{\n    public class DuplicatePropertiesTemplateAnalyzerTests : MessageTemplateAnalyzerTestBase\n    {\n        protected override string SubPath => \"DuplicatePropertiesTemplate\";\n\n        [Test] public void TestSerilogDuplicateNamedProperty() => DoNamedTest2();\n    }\n}\n"
  },
  {
    "path": "test/src/Analyzer/LogMessageIsSentenceAnalyzerTests.cs",
    "content": "using NUnit.Framework;\n\nnamespace ReSharper.Structured.Logging.Tests.Analyzer\n{\n    public class LogMessageIsSentenceAnalyzerTests : MessageTemplateAnalyzerTestBase\n    {\n        protected override string SubPath => \"LogMessageIsSentence\";\n\n        [Test] public void TestSerilogSentenceMessage() => DoNamedTest2();\n\n        [Test] public void TestSerilogNotSentenceMessage() => DoNamedTest2();\n    }\n}\n"
  },
  {
    "path": "test/src/Analyzer/MessageTemplateTests.cs",
    "content": "using JetBrains.Annotations;\nusing JetBrains.Application.Settings;\nusing JetBrains.ReSharper.Daemon.StringAnalysis;\nusing JetBrains.ReSharper.Feature.Services.Daemon;\nusing JetBrains.ReSharper.FeaturesTestFramework.Daemon;\nusing JetBrains.ReSharper.Psi;\nusing JetBrains.ReSharper.TestFramework;\n\nusing ReSharper.Structured.Logging.Highlighting;\nusing ReSharper.Structured.Logging.Tests.Constants;\n\nnamespace ReSharper.Structured.Logging.Tests.Analyzer\n{\n    [TestPackages(\n        NugetPackages.SerilogNugetPackage,\n        NugetPackages.MicrosoftLoggingPackage,\n        NugetPackages.NlogLoggingPackage,\n        Inherits = true)]\n    public abstract class MessageTemplateAnalyzerTestBase : CSharpHighlightingTestBase\n    {\n        protected abstract string SubPath { get; }\n\n        protected override string RelativeTestDataPath => @\"Analyzers\\\" + SubPath;\n\n        protected override void DoTestSolution([NotNull] params string[] fileSet)\n        {\n            ExecuteWithinSettingsTransaction(\n                settingsStore =>\n                    {\n                        RunGuarded(() => MutateSettings(settingsStore));\n                        base.DoTestSolution(fileSet);\n                    });\n        }\n\n        protected override bool HighlightingPredicate(\n            IHighlighting highlighting,\n            IPsiSourceFile sourceFile,\n            IContextBoundSettingsStore settingsStore)\n        {\n            return highlighting is TemplateFormatStringNonExistingArgumentWarning\n                   || highlighting is StringEscapeCharacterHighlighting\n                   || highlighting is DuplicateTemplatePropertyWarning\n                   || highlighting is AnonymousObjectDestructuringWarning\n                   || highlighting is ContextualLoggerWarning\n                   || highlighting is ExceptionPassedAsTemplateArgumentWarning\n                   || highlighting is ComplexObjectDestructuringWarning\n                   || highlighting is ComplexObjectDestructuringInContextWarning\n                   || highlighting is PositionalPropertyUsedWarning\n                   || highlighting is InconsistentLogPropertyNamingWarning\n                   || highlighting is InconsistentContextLogPropertyNamingWarning\n                   || highlighting is LogMessageIsSentenceWarning;\n        }\n\n        protected virtual void MutateSettings([NotNull] IContextBoundSettingsStore settingsStore)\n        {\n        }\n    }\n}\n"
  },
  {
    "path": "test/src/Analyzer/PositionalPropertiesUsageAnalyzerTests.cs",
    "content": "﻿using NUnit.Framework;\n\nnamespace ReSharper.Structured.Logging.Tests.Analyzer\n{\n    public class PositionalPropertiesUsageAnalyzerTests : MessageTemplateAnalyzerTestBase\n    {\n        protected override string SubPath => \"PositionalPropertiesUsage\";\n\n        [Test] public void TestSerilogPositionProperty() => DoNamedTest2();\n    }\n}\n"
  },
  {
    "path": "test/src/Analyzer/PropertiesElasticNamingAnalyzerTests.cs",
    "content": "using JetBrains.Application.Settings;\n\nusing NUnit.Framework;\n\nusing ReSharper.Structured.Logging.Settings;\n\nnamespace ReSharper.Structured.Logging.Tests.Analyzer\n{\n    // ReSharper disable once TestFileNameWarning\n    public class PropertiesElasticNamingAnalyzerTests : MessageTemplateAnalyzerTestBase\n    {\n        protected override string SubPath => \"PropertiesNamingAnalyzer\";\n\n        [Test] public void TestSerilogInvalidElasticNamedProperty() => DoNamedTest2();\n\n        protected override void MutateSettings(IContextBoundSettingsStore settingsStore)\n        {\n            settingsStore.SetValue<StructuredLoggingSettings, PropertyNamingType>(settings => settings.PropertyNamingType, PropertyNamingType.ElasticNaming);\n        }\n    }\n}\n"
  },
  {
    "path": "test/src/Analyzer/PropertiesIgnoredRegexNamingAnalyzerTests.cs",
    "content": "using JetBrains.Application.Settings;\n\nusing NUnit.Framework;\n\nusing ReSharper.Structured.Logging.Settings;\n\nnamespace ReSharper.Structured.Logging.Tests.Analyzer\n{\n    // ReSharper disable once TestFileNameWarning\n    public class PropertiesIgnoredRegexNamingAnalyzerTests : MessageTemplateAnalyzerTestBase\n    {\n        protected override string SubPath => \"PropertiesNamingAnalyzer\";\n\n        [Test] public void TestSerilogIgnoredInvalidNamedProperty() => DoNamedTest2();\n\n        protected override void MutateSettings(IContextBoundSettingsStore settingsStore)\n        {\n            settingsStore.SetValue<StructuredLoggingSettings, string>(settings => settings.IgnoredPropertiesRegex,\"MY_.*\");\n        }\n    }\n}\n"
  },
  {
    "path": "test/src/Analyzer/PropertiesNamingAnalyzerDotNet6Tests.cs",
    "content": "﻿using JetBrains.ReSharper.TestFramework;\n\nusing NUnit.Framework;\n\nusing ReSharper.Structured.Logging.Tests.Constants;\n\nnamespace ReSharper.Structured.Logging.Tests.Analyzer\n{\n    [TestNet60]\n    [TestPackages(\n        NugetPackages.ZLoggerLoggingPackage,\n        Inherits = true)]\n    public class PropertiesNamingAnalyzerDotNet6Tests : MessageTemplateAnalyzerTestBase\n    {\n        protected override string SubPath => \"PropertiesNamingAnalyzerDotNet6\";\n\n        [Test] public void TestZLoggerInvalidNamedProperty() => DoNamedTest2();\n    }\n}\n"
  },
  {
    "path": "test/src/Analyzer/PropertiesNamingAnalyzerTests.cs",
    "content": "using NUnit.Framework;\n\nnamespace ReSharper.Structured.Logging.Tests.Analyzer\n{\n    public class PropertiesNamingAnalyzerTests : MessageTemplateAnalyzerTestBase\n    {\n        protected override string SubPath => \"PropertiesNamingAnalyzer\";\n\n        [Test] public void TestSerilogInvalidNamedProperty() => DoNamedTest2();\n\n        [Test] public void TestSerilogValidNamedProperty() => DoNamedTest2();\n\n        [Test] public void TestSerilogValidDestructuredNamedProperty() => DoNamedTest2();\n\n        [Test] public void TestSerilogContextInvalidNamedProperty() => DoNamedTest2();\n\n        [Test] public void TestSerilogContextInterpolatedStringProperty() => DoNamedTest2();\n\n        [Test] public void TestSerilogInvalidNamedPropertyWithDot() => DoNamedTest2();\n\n        [Test] public void TestSerilogInvalidSyntax() => DoNamedTest2();\n\n        [Test] public void TestSerilogInvalidNamedPropertyWithSpace() => DoNamedTest2();\n    }\n}\n"
  },
  {
    "path": "test/src/Constants/NugetPackages.cs",
    "content": "namespace ReSharper.Structured.Logging.Tests.Constants\n{\n    internal static class NugetPackages\n    {\n        public const string SerilogNugetPackage = \"Serilog/2.7.1\";\n\n        public const string MicrosoftLoggingPackage = \"Microsoft.Extensions.Logging/6.0.0\";\n\n        public const string NlogLoggingPackage = \"NLog/4.5.11\";\n\n        public const string ZLoggerLoggingPackage = \"ZLogger/1.7.0\";\n    }\n}\n"
  },
  {
    "path": "test/src/QuickFixes/AddDestructuringToMessageTemplatePropertyFixTests.cs",
    "content": "﻿using NUnit.Framework;\nusing ReSharper.Structured.Logging.QuickFixes;\n\nnamespace ReSharper.Structured.Logging.Tests.QuickFixes\n{\n    public class AddDestructuringToMessageTemplatePropertyFixTests : QuickFixTestBase<AddDestructuringToMessageTemplatePropertyFix>\n    {\n        protected override string SubPath => \"AddDestructuringFix\";\n\n        [Test] public void TestSerilogEscapedString() => DoNamedTest2();\n\n        [Test] public void TestSerilogNewAnonymousObject() => DoNamedTest2();\n\n        [Test] public void TestSerilogNewComplexObject() => DoNamedTest2();\n    }\n}\n"
  },
  {
    "path": "test/src/QuickFixes/QuickFixTestBase.cs",
    "content": "﻿using JetBrains.ReSharper.Feature.Services.QuickFixes;\nusing JetBrains.ReSharper.FeaturesTestFramework.Intentions;\nusing JetBrains.ReSharper.TestFramework;\n\nusing NUnit.Framework;\n\nusing ReSharper.Structured.Logging.Tests.Constants;\n\nnamespace ReSharper.Structured.Logging.Tests.QuickFixes\n{\n    [TestFixture]\n    [TestNetFramework46]\n    [TestPackages(\n        NugetPackages.SerilogNugetPackage,\n        NugetPackages.MicrosoftLoggingPackage,\n        NugetPackages.NlogLoggingPackage,\n        Inherits = true)]\n\n    // ReSharper disable once TestClassNameSuffixWarning\n    public abstract class QuickFixTestBase<TQuickFix> : CSharpQuickFixTestBase<TQuickFix>\n        where TQuickFix : IQuickFix\n    {\n        protected override string RelativeTestDataPath => @\"QuickFixes\\\" + SubPath;\n\n        protected abstract string SubPath { get; }\n    }\n}\n"
  },
  {
    "path": "test/src/QuickFixes/RemoveTrailingPeriodFixTests.cs",
    "content": "using NUnit.Framework;\n\nusing ReSharper.Structured.Logging.QuickFixes;\n\nnamespace ReSharper.Structured.Logging.Tests.QuickFixes\n{\n    public class RemoveTrailingPeriodFixTests : QuickFixTestBase<RemoveTrailingPeriodFix>\n    {\n        protected override string SubPath => \"RemoveTrailingPeriodFix\";\n\n        [Test] public void TestSerilogTrailingPeriod() => DoNamedTest2();\n    }\n}\n"
  },
  {
    "path": "test/src/QuickFixes/RenameContextLogPropertyFixTests.cs",
    "content": "using NUnit.Framework;\n\nusing ReSharper.Structured.Logging.QuickFixes;\n\nnamespace ReSharper.Structured.Logging.Tests.QuickFixes\n{\n    public class RenameContextLogPropertyFixTests : QuickFixTestBase<RenameContextLogPropertyFix>\n    {\n        protected override string SubPath => \"RenameContextLogPropertyFix\";\n\n        [Test] public void TestSerilogContextProperty() => DoNamedTest2();\n    }\n}\n"
  },
  {
    "path": "test/src/QuickFixes/RenameLogPropertyFixTests.cs",
    "content": "using NUnit.Framework;\n\nusing ReSharper.Structured.Logging.QuickFixes;\n\nnamespace ReSharper.Structured.Logging.Tests.QuickFixes\n{\n    public class RenameLogPropertyFixTests : QuickFixTestBase<RenameLogPropertyFix>\n    {\n        protected override string SubPath => \"RenameLogPropertyFix\";\n\n        [Test] public void TestSerilogProperty() => DoNamedTest2();\n\n        [Test] public void TestSerilogDestructuredProperty() => DoNamedTest2();\n\n        [Test] public void TestSerilogPropertyConcatenated() => DoNamedTest2();\n    }\n}\n"
  },
  {
    "path": "test/src/ReSharper.Structured.Logging.Rider.Tests.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk\">\n  <PropertyGroup>\n    <TargetFramework>net472</TargetFramework>\n    <AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>\n  </PropertyGroup>\n  <ItemGroup>\n    <PackageReference Include=\"JetBrains.Rider.SDK.Tests\" Version=\"$(SdkVersion)\" PrivateAssets=\"all\" />\n  </ItemGroup>\n  <ItemGroup>\n    <ProjectReference Include=\"..\\..\\src\\ReSharper.Structured.Logging\\ReSharper.Structured.Logging.Rider.csproj\" />\n  </ItemGroup>\n  <PropertyGroup>\n    <!-- Exclude the project from analysis to prvent duplications -->\n    <SonarQubeExclude>true</SonarQubeExclude>\n    <RootNamespace>ReSharper.Structured.Logging.Tests</RootNamespace>\n  </PropertyGroup>\n  <PropertyGroup>\n    <DefineConstants>RIDER</DefineConstants>\n    <OutputPath>bin\\$(MSBuildProjectName)\\$(Configuration)\\</OutputPath>\n  </PropertyGroup>\n</Project>\n"
  },
  {
    "path": "test/src/ReSharper.Structured.Logging.Tests.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk\">\n  <PropertyGroup>\n    <TargetFramework>net472</TargetFramework>\n    <AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>\n  </PropertyGroup>\n  <ItemGroup>\n    <PackageReference Include=\"JetBrains.ReSharper.SDK.Tests\" Version=\"$(SdkVersion)\" PrivateAssets=\"all\" />\n  </ItemGroup>\n  <ItemGroup>\n    <ProjectReference Include=\"..\\..\\src\\ReSharper.Structured.Logging\\ReSharper.Structured.Logging.csproj\" />\n  </ItemGroup>\n  <PropertyGroup>\n    <OutputPath>bin\\$(MSBuildProjectName)\\$(Configuration)\\</OutputPath>\n  </PropertyGroup>\n</Project>\n"
  },
  {
    "path": "test/src/TestEnvironment.cs",
    "content": "using JetBrains.Application.BuildScript.Application.Zones;\nusing JetBrains.ReSharper.TestFramework;\nusing JetBrains.TestFramework;\nusing JetBrains.TestFramework.Application.Zones;\n\nusing NUnit.Framework;\n\n#if RIDER\nusing JetBrains.Rider.Backend.Env;\n#endif\n\n[assembly: RequiresThread(System.Threading.ApartmentState.STA)]\n\nnamespace ReSharper.Structured.Logging.Tests\n{\n    [ZoneDefinition]\n    public interface IReSharperSerilog : ITestsEnvZone, IRequire<PsiFeatureTestZone>\n#if RIDER\n                                         , IRequire<IRiderPlatformZone>\n#endif\n    {\n    }\n\n    [SetUpFixture]\n    public class TestEnvironment : ExtensionTestEnvironmentAssembly<IReSharperSerilog>\n    {\n    }\n}\n"
  },
  {
    "path": "test/src/app.config",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<configuration>\n  <runtime>\n    <assemblyBinding xmlns=\"urn:schemas-microsoft-com:asm.v1\">\n      <dependentAssembly>\n        <assemblyIdentity name=\"System.ValueTuple\" publicKeyToken=\"cc7b13ffcd2ddd51\" culture=\"neutral\" />\n        <bindingRedirect oldVersion=\"0.0.0.0-4.0.3.0\" newVersion=\"4.0.3.0\" />\n      </dependentAssembly>\n      <dependentAssembly>\n        <assemblyIdentity name=\"System.IO.FileSystem\" publicKeyToken=\"b03f5f7f11d50a3a\" culture=\"neutral\" />\n        <bindingRedirect oldVersion=\"0.0.0.0-4.0.2.0\" newVersion=\"4.0.2.0\" />\n      </dependentAssembly>\n      <dependentAssembly>\n        <assemblyIdentity name=\"System.Security.Cryptography.Primitives\" publicKeyToken=\"b03f5f7f11d50a3a\" culture=\"neutral\" />\n        <bindingRedirect oldVersion=\"0.0.0.0-4.0.1.0\" newVersion=\"4.0.1.0\" />\n      </dependentAssembly>\n      <dependentAssembly>\n        <assemblyIdentity name=\"System.IO.FileSystem.Primitives\" publicKeyToken=\"b03f5f7f11d50a3a\" culture=\"neutral\" />\n        <bindingRedirect oldVersion=\"0.0.0.0-4.0.2.0\" newVersion=\"4.0.2.0\" />\n      </dependentAssembly>\n      <dependentAssembly>\n        <assemblyIdentity name=\"System.Collections.Immutable\" publicKeyToken=\"b03f5f7f11d50a3a\" culture=\"neutral\" />\n        <bindingRedirect oldVersion=\"0.0.0.0-1.2.1.0\" newVersion=\"1.2.1.0\" />\n      </dependentAssembly>\n      <dependentAssembly>\n        <assemblyIdentity name=\"Microsoft.CodeAnalysis\" publicKeyToken=\"31bf3856ad364e35\" culture=\"neutral\" />\n        <bindingRedirect oldVersion=\"0.0.0.0-42.42.42.42\" newVersion=\"42.42.42.42\" />\n      </dependentAssembly>\n      <dependentAssembly>\n        <assemblyIdentity name=\"Microsoft.CodeAnalysis.Workspaces\" publicKeyToken=\"31bf3856ad364e35\" culture=\"neutral\" />\n        <bindingRedirect oldVersion=\"0.0.0.0-42.42.42.42\" newVersion=\"42.42.42.42\" />\n      </dependentAssembly>\n      <dependentAssembly>\n        <assemblyIdentity name=\"Microsoft.CodeAnalysis.CSharp\" publicKeyToken=\"31bf3856ad364e35\" culture=\"neutral\" />\n        <bindingRedirect oldVersion=\"0.0.0.0-42.42.42.42\" newVersion=\"42.42.42.42\" />\n      </dependentAssembly>\n      <dependentAssembly>\n        <assemblyIdentity name=\"Microsoft.VisualStudio.TestPlatform.ObjectModel\" publicKeyToken=\"b03f5f7f11d50a3a\" culture=\"neutral\" />\n        <bindingRedirect oldVersion=\"0.0.0.0-15.0.0.0\" newVersion=\"15.0.0.0\" />\n      </dependentAssembly>\n      <dependentAssembly>\n        <assemblyIdentity name=\"System.Runtime.CompilerServices.Unsafe\" publicKeyToken=\"b03f5f7f11d50a3a\" culture=\"neutral\" />\n        <bindingRedirect oldVersion=\"0.0.0.0-4.0.4.1\" newVersion=\"6.0.0.0\" />\n      </dependentAssembly>\n    </assemblyBinding>\n  </runtime>\n</configuration>\n"
  }
]