chore: initial commit
Signed-off-by: Alan Brault <alan.brault@visus.io>
This commit is contained in:
218
.editorconfig
Normal file
218
.editorconfig
Normal file
@@ -0,0 +1,218 @@
|
||||
# Remove the line below if you want to inherit .editorconfig settings from higher directories
|
||||
root = true
|
||||
|
||||
[*]
|
||||
#### Core EditorConfig Options ####
|
||||
|
||||
# Indentation and spacing
|
||||
indent_size = 4
|
||||
indent_style = space
|
||||
tab_width = 4
|
||||
|
||||
# New line preferences
|
||||
end_of_line = lf
|
||||
insert_final_newline = true
|
||||
|
||||
# Razor files
|
||||
[*.{cs,razor}]
|
||||
dotnet_diagnostic.CA2007.severity = none
|
||||
|
||||
# C# files
|
||||
[*.cs]
|
||||
#### .NET Coding Conventions ####
|
||||
|
||||
# this. and Me. preferences
|
||||
dotnet_style_qualification_for_event = false
|
||||
dotnet_style_qualification_for_field = false
|
||||
dotnet_style_qualification_for_method = false
|
||||
dotnet_style_qualification_for_property = false
|
||||
|
||||
# Language keywords vs BCL types preferences
|
||||
dotnet_style_predefined_type_for_locals_parameters_members = true
|
||||
dotnet_style_predefined_type_for_member_access = true
|
||||
|
||||
# Parentheses preferences
|
||||
dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity
|
||||
dotnet_style_parentheses_in_other_binary_operators = always_for_clarity
|
||||
dotnet_style_parentheses_in_other_operators = never_if_unnecessary
|
||||
dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity
|
||||
|
||||
# Modifier preferences
|
||||
dotnet_style_require_accessibility_modifiers = for_non_interface_members
|
||||
|
||||
# Expression-level preferences
|
||||
csharp_style_deconstructed_variable_declaration = true:suggestion
|
||||
csharp_style_inlined_variable_declaration = true:suggestion
|
||||
csharp_style_throw_expression = true:suggestion
|
||||
dotnet_style_coalesce_expression = true:suggestion
|
||||
dotnet_style_collection_initializer = true:suggestion
|
||||
dotnet_style_explicit_tuple_names = true:suggestion
|
||||
dotnet_style_null_propagation = true:suggestion
|
||||
dotnet_style_object_initializer = true:suggestion
|
||||
dotnet_style_prefer_auto_properties = true
|
||||
dotnet_style_prefer_compound_assignment = true:suggestion
|
||||
dotnet_style_prefer_conditional_expression_over_assignment = true
|
||||
dotnet_style_prefer_conditional_expression_over_return = true
|
||||
dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion
|
||||
dotnet_style_prefer_inferred_tuple_names = true:suggestion
|
||||
dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion
|
||||
|
||||
# Field preferences
|
||||
dotnet_style_readonly_field = true:suggestion
|
||||
|
||||
# Parameter preferences
|
||||
dotnet_code_quality_unused_parameters = all:suggestion
|
||||
|
||||
#### C# Coding Conventions ####
|
||||
|
||||
# var preferences
|
||||
csharp_style_var_elsewhere = false:warning
|
||||
csharp_style_var_for_built_in_types = false:warning
|
||||
csharp_style_var_when_type_is_apparent = false:warning
|
||||
|
||||
# Expression-bodied members
|
||||
csharp_style_expression_bodied_accessors = true
|
||||
csharp_style_expression_bodied_constructors = false
|
||||
csharp_style_expression_bodied_indexers = true
|
||||
csharp_style_expression_bodied_lambdas = true
|
||||
csharp_style_expression_bodied_local_functions = false
|
||||
csharp_style_expression_bodied_methods = false
|
||||
csharp_style_expression_bodied_operators = false
|
||||
csharp_style_expression_bodied_properties = true
|
||||
|
||||
# Pattern matching preferences
|
||||
csharp_style_pattern_matching_over_as_with_null_check = true:suggestion
|
||||
csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion
|
||||
|
||||
# Null-checking preferences
|
||||
csharp_style_conditional_delegate_call = true:suggestion
|
||||
|
||||
# Modifier preferences
|
||||
csharp_preferred_modifier_order = public, private, protected, internal, static, extern, new, virtual, abstract, sealed, override, readonly, unsafe, volatile, async
|
||||
|
||||
# Code-block preferences
|
||||
csharp_prefer_braces = true
|
||||
|
||||
# Expression-level preferences
|
||||
csharp_prefer_simple_default_expression = true:suggestion
|
||||
csharp_style_pattern_local_over_anonymous_function = true:suggestion
|
||||
csharp_style_prefer_index_operator = true:suggestion
|
||||
csharp_style_prefer_range_operator = true:suggestion
|
||||
csharp_style_unused_value_assignment_preference = discard_variable:suggestion
|
||||
csharp_style_unused_value_expression_statement_preference = discard_variable
|
||||
|
||||
# 'using' directive preferences
|
||||
csharp_using_directive_placement = inside_namespace
|
||||
|
||||
# Constructor Preferences
|
||||
csharp_style_prefer_primary_constructors = false
|
||||
dotnet_diagnostic.IDE0290.severity = none
|
||||
resharper_convert_to_primary_constructor_highlighting = none
|
||||
|
||||
#### C# Formatting Rules ####
|
||||
|
||||
# New line preferences
|
||||
csharp_new_line_before_open_brace = methods, properties, control_blocks, types
|
||||
csharp_new_line_before_catch = true
|
||||
csharp_new_line_before_else = true
|
||||
csharp_new_line_before_finally = true
|
||||
csharp_new_line_before_members_in_anonymous_types = true
|
||||
csharp_new_line_before_members_in_object_initializers = true
|
||||
csharp_new_line_between_query_expression_clauses = true
|
||||
|
||||
# Indentation preferences
|
||||
csharp_indent_block_contents = true
|
||||
csharp_indent_braces = false
|
||||
csharp_indent_case_contents = true
|
||||
csharp_indent_case_contents_when_block = true
|
||||
csharp_indent_labels = one_less_than_current
|
||||
csharp_indent_switch_labels = true
|
||||
|
||||
# Space preferences
|
||||
csharp_space_after_cast = true
|
||||
csharp_space_after_colon_in_inheritance_clause = true
|
||||
csharp_space_after_comma = true
|
||||
csharp_space_after_dot = false
|
||||
csharp_space_after_keywords_in_control_flow_statements = true
|
||||
csharp_space_after_semicolon_in_for_statement = true
|
||||
csharp_space_around_binary_operators = before_and_after
|
||||
csharp_space_around_declaration_statements = false
|
||||
csharp_space_before_colon_in_inheritance_clause = true
|
||||
csharp_space_before_comma = false
|
||||
csharp_space_before_dot = false
|
||||
csharp_space_before_open_square_brackets = false
|
||||
csharp_space_before_semicolon_in_for_statement = false
|
||||
csharp_space_between_empty_square_brackets = false
|
||||
csharp_space_between_method_call_empty_parameter_list_parentheses = false
|
||||
csharp_space_between_method_call_name_and_opening_parenthesis = false
|
||||
csharp_space_between_method_call_parameter_list_parentheses = false
|
||||
csharp_space_between_method_declaration_empty_parameter_list_parentheses = false
|
||||
csharp_space_between_method_declaration_name_and_open_parenthesis = false
|
||||
csharp_space_between_method_declaration_parameter_list_parentheses = false
|
||||
csharp_space_between_parentheses = control_flow_statements, expressions
|
||||
csharp_space_between_square_brackets = false
|
||||
|
||||
# Wrapping preferences
|
||||
csharp_preserve_single_line_blocks = true
|
||||
csharp_preserve_single_line_statements = true
|
||||
|
||||
#### Resharper Formatting Rules ####
|
||||
|
||||
resharper_csharp_accessor_declaration_braces = next_line
|
||||
resharper_csharp_accessor_owner_declaration_braces = next_line
|
||||
resharper_csharp_align_first_arg_by_paren = true
|
||||
resharper_csharp_align_linq_query = true
|
||||
resharper_csharp_align_multiline_argument = true
|
||||
resharper_csharp_align_multiline_array_and_object_initializer = false
|
||||
resharper_csharp_align_multiline_binary_expressions_chain = true
|
||||
resharper_csharp_align_multiline_binary_patterns = true
|
||||
resharper_csharp_align_multiline_calls_chain = true
|
||||
resharper_csharp_align_multiline_expression = true
|
||||
resharper_csharp_align_multiline_extends_list = true
|
||||
resharper_csharp_align_multiline_parameter = true
|
||||
resharper_csharp_align_multiline_property_pattern = true
|
||||
resharper_csharp_align_multiline_statement_conditions = true
|
||||
resharper_csharp_align_multiline_switch_expression = false
|
||||
resharper_csharp_align_multiple_declaration = true
|
||||
resharper_csharp_align_multline_type_parameter_constrains = true
|
||||
resharper_csharp_align_multline_type_parameter_list = true
|
||||
resharper_csharp_align_tuple_components = true
|
||||
resharper_csharp_alignment_tab_fill_style = optimal_fill
|
||||
resharper_csharp_allow_far_alignment = true
|
||||
resharper_csharp_brace_style = next_line
|
||||
resharper_csharp_case_block_braces = next_line
|
||||
resharper_csharp_continuous_indent_multiplier = 1
|
||||
resharper_csharp_indent_anonymous_method_block = true
|
||||
resharper_csharp_indent_braces_inside_statement_conditions = true
|
||||
resharper_csharp_indent_inside_namespace = true
|
||||
resharper_csharp_indent_nested_fixed_stmt = false
|
||||
resharper_csharp_indent_nested_for_stmt = false
|
||||
resharper_csharp_indent_nested_foreach_stmt = false
|
||||
resharper_csharp_indent_nested_lock_stmt = false
|
||||
resharper_csharp_indent_nested_usings_stmt = false
|
||||
resharper_csharp_indent_nested_while_stmt = false
|
||||
resharper_csharp_indent_preprocessor_if = no_indent
|
||||
resharper_csharp_indent_preprocessor_other = usual_indent
|
||||
resharper_csharp_indent_preprocessor_region = no_indent
|
||||
resharper_csharp_indent_type_constraints = true
|
||||
resharper_csharp_initializer_braces = next_line
|
||||
resharper_csharp_invocable_declaration_braces = next_line
|
||||
resharper_csharp_keep_existing_attribute_arrangement = false
|
||||
resharper_csharp_keep_existing_initializer_arrangement = false
|
||||
resharper_csharp_max_attribute_length_for_same_line = 120
|
||||
resharper_csharp_max_initializer_elements_on_line = 1
|
||||
resharper_csharp_naming_rule.enum_member = AaBb
|
||||
resharper_csharp_other_braces = next_line
|
||||
resharper_csharp_outdent_binary_ops = true
|
||||
resharper_csharp_outdent_binary_pattern_ops = true
|
||||
resharper_csharp_outdent_dots = true
|
||||
resharper_csharp_place_attribute_on_same_line = false
|
||||
resharper_csharp_place_record_field_attribute_on_same_line = true
|
||||
resharper_csharp_place_simple_initializer_on_single_line = true
|
||||
resharper_csharp_type_declaration_braces = next_line
|
||||
resharper_csharp_wrap_object_and_collection_initializer_style = chop_always
|
||||
|
||||
dotnet_diagnostic.CA2007.severity = error
|
||||
|
||||
# warning suppressions
|
||||
dotnet_diagnostic.CA2255.severity = none
|
||||
406
.gitignore
vendored
Normal file
406
.gitignore
vendored
Normal file
@@ -0,0 +1,406 @@
|
||||
## Ignore Visual Studio temporary files, build results, and
|
||||
## files generated by popular Visual Studio add-ons.
|
||||
##
|
||||
## Get latest from https://github.com/github/gitignore/blob/main/VisualStudio.gitignore
|
||||
|
||||
# User-specific files
|
||||
*.rsuser
|
||||
*.suo
|
||||
*.user
|
||||
*.userosscache
|
||||
*.sln.docstates
|
||||
|
||||
# User-specific files (MonoDevelop/Xamarin Studio)
|
||||
*.userprefs
|
||||
|
||||
# Mono auto generated files
|
||||
mono_crash.*
|
||||
|
||||
# Build results
|
||||
[Dd]ebug/
|
||||
[Dd]ebugPublic/
|
||||
[Rr]elease/
|
||||
[Rr]eleases/
|
||||
x64/
|
||||
x86/
|
||||
[Ww][Ii][Nn]32/
|
||||
[Aa][Rr][Mm]/
|
||||
[Aa][Rr][Mm]64/
|
||||
bld/
|
||||
[Bb]in/
|
||||
[Oo]bj/
|
||||
[Ll]og/
|
||||
[Ll]ogs/
|
||||
|
||||
# Visual Studio 2015/2017 cache/options directory
|
||||
.vs/
|
||||
# Uncomment if you have tasks that create the project's static files in wwwroot
|
||||
#wwwroot/
|
||||
|
||||
# Visual Studio 2017 auto generated files
|
||||
Generated\ Files/
|
||||
|
||||
# MSTest test Results
|
||||
[Tt]est[Rr]esult*/
|
||||
[Bb]uild[Ll]og.*
|
||||
|
||||
# NUnit
|
||||
*.VisualState.xml
|
||||
TestResult.xml
|
||||
nunit-*.xml
|
||||
|
||||
# Build Results of an ATL Project
|
||||
[Dd]ebugPS/
|
||||
[Rr]eleasePS/
|
||||
dlldata.c
|
||||
|
||||
# Benchmark Results
|
||||
BenchmarkDotNet.Artifacts/
|
||||
|
||||
# .NET Core
|
||||
project.lock.json
|
||||
project.fragment.lock.json
|
||||
artifacts/
|
||||
|
||||
# ASP.NET Scaffolding
|
||||
ScaffoldingReadMe.txt
|
||||
|
||||
# StyleCop
|
||||
StyleCopReport.xml
|
||||
|
||||
# Files built by Visual Studio
|
||||
*_i.c
|
||||
*_p.c
|
||||
*_h.h
|
||||
*.ilk
|
||||
*.meta
|
||||
*.obj
|
||||
*.iobj
|
||||
*.pch
|
||||
*.pdb
|
||||
*.ipdb
|
||||
*.pgc
|
||||
*.pgd
|
||||
*.rsp
|
||||
*.sbr
|
||||
*.tlb
|
||||
*.tli
|
||||
*.tlh
|
||||
*.tmp
|
||||
*.tmp_proj
|
||||
*_wpftmp.csproj
|
||||
*.log
|
||||
*.tlog
|
||||
*.vspscc
|
||||
*.vssscc
|
||||
.builds
|
||||
*.pidb
|
||||
*.svclog
|
||||
*.scc
|
||||
|
||||
# Chutzpah Test files
|
||||
_Chutzpah*
|
||||
|
||||
# Visual C++ cache files
|
||||
ipch/
|
||||
*.aps
|
||||
*.ncb
|
||||
*.opendb
|
||||
*.opensdf
|
||||
*.sdf
|
||||
*.cachefile
|
||||
*.VC.db
|
||||
*.VC.VC.opendb
|
||||
|
||||
# Visual Studio profiler
|
||||
*.psess
|
||||
*.vsp
|
||||
*.vspx
|
||||
*.sap
|
||||
|
||||
# Visual Studio Trace Files
|
||||
*.e2e
|
||||
|
||||
# TFS 2012 Local Workspace
|
||||
$tf/
|
||||
|
||||
# Guidance Automation Toolkit
|
||||
*.gpState
|
||||
|
||||
# ReSharper is a .NET coding add-in
|
||||
_ReSharper*/
|
||||
*.[Rr]e[Ss]harper
|
||||
*.DotSettings.user
|
||||
|
||||
# TeamCity is a build add-in
|
||||
_TeamCity*
|
||||
|
||||
# DotCover is a Code Coverage Tool
|
||||
*.dotCover
|
||||
|
||||
# AxoCover is a Code Coverage Tool
|
||||
.axoCover/*
|
||||
!.axoCover/settings.json
|
||||
|
||||
# Coverlet is a free, cross platform Code Coverage Tool
|
||||
coverage*.json
|
||||
coverage*.xml
|
||||
coverage*.info
|
||||
|
||||
# Visual Studio code coverage results
|
||||
*.coverage
|
||||
*.coveragexml
|
||||
|
||||
# NCrunch
|
||||
_NCrunch_*
|
||||
.*crunch*.local.xml
|
||||
nCrunchTemp_*
|
||||
|
||||
# MightyMoose
|
||||
*.mm.*
|
||||
AutoTest.Net/
|
||||
|
||||
# Web workbench (sass)
|
||||
.sass-cache/
|
||||
|
||||
# Installshield output folder
|
||||
[Ee]xpress/
|
||||
|
||||
# DocProject is a documentation generator add-in
|
||||
DocProject/buildhelp/
|
||||
DocProject/Help/*.HxT
|
||||
DocProject/Help/*.HxC
|
||||
DocProject/Help/*.hhc
|
||||
DocProject/Help/*.hhk
|
||||
DocProject/Help/*.hhp
|
||||
DocProject/Help/Html2
|
||||
DocProject/Help/html
|
||||
|
||||
# Click-Once directory
|
||||
publish/
|
||||
|
||||
# Publish Web Output
|
||||
*.[Pp]ublish.xml
|
||||
*.azurePubxml
|
||||
# Note: Comment the next line if you want to checkin your web deploy settings,
|
||||
# but database connection strings (with potential passwords) will be unencrypted
|
||||
*.pubxml
|
||||
*.publishproj
|
||||
|
||||
# Microsoft Azure Web App publish settings. Comment the next line if you want to
|
||||
# checkin your Azure Web App publish settings, but sensitive information contained
|
||||
# in these scripts will be unencrypted
|
||||
PublishScripts/
|
||||
|
||||
# NuGet Packages
|
||||
*.nupkg
|
||||
# NuGet Symbol Packages
|
||||
*.snupkg
|
||||
# The packages folder can be ignored because of Package Restore
|
||||
**/[Pp]ackages/*
|
||||
# except build/, which is used as an MSBuild target.
|
||||
!**/[Pp]ackages/build/
|
||||
# Uncomment if necessary however generally it will be regenerated when needed
|
||||
#!**/[Pp]ackages/repositories.config
|
||||
# NuGet v3's project.json files produces more ignorable files
|
||||
*.nuget.props
|
||||
*.nuget.targets
|
||||
|
||||
# Microsoft Azure Build Output
|
||||
csx/
|
||||
*.build.csdef
|
||||
|
||||
# Microsoft Azure Emulator
|
||||
ecf/
|
||||
rcf/
|
||||
|
||||
# Windows Store app package directories and files
|
||||
AppPackages/
|
||||
BundleArtifacts/
|
||||
Package.StoreAssociation.xml
|
||||
_pkginfo.txt
|
||||
*.appx
|
||||
*.appxbundle
|
||||
*.appxupload
|
||||
|
||||
# Visual Studio cache files
|
||||
# files ending in .cache can be ignored
|
||||
*.[Cc]ache
|
||||
# but keep track of directories ending in .cache
|
||||
!?*.[Cc]ache/
|
||||
|
||||
# Others
|
||||
ClientBin/
|
||||
~$*
|
||||
*~
|
||||
*.dbmdl
|
||||
*.dbproj.schemaview
|
||||
*.jfm
|
||||
*.pfx
|
||||
*.publishsettings
|
||||
orleans.codegen.cs
|
||||
|
||||
# Including strong name files can present a security risk
|
||||
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
|
||||
#*.snk
|
||||
|
||||
# Since there are multiple workflows, uncomment next line to ignore bower_components
|
||||
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
|
||||
#bower_components/
|
||||
|
||||
# RIA/Silverlight projects
|
||||
Generated_Code/
|
||||
|
||||
# Backup & report files from converting an old project file
|
||||
# to a newer Visual Studio version. Backup files are not needed,
|
||||
# because we have git ;-)
|
||||
_UpgradeReport_Files/
|
||||
Backup*/
|
||||
UpgradeLog*.XML
|
||||
UpgradeLog*.htm
|
||||
ServiceFabricBackup/
|
||||
*.rptproj.bak
|
||||
|
||||
# SQL Server files
|
||||
*.mdf
|
||||
*.ldf
|
||||
*.ndf
|
||||
|
||||
# Business Intelligence projects
|
||||
*.rdl.data
|
||||
*.bim.layout
|
||||
*.bim_*.settings
|
||||
*.rptproj.rsuser
|
||||
*- [Bb]ackup.rdl
|
||||
*- [Bb]ackup ([0-9]).rdl
|
||||
*- [Bb]ackup ([0-9][0-9]).rdl
|
||||
|
||||
# Microsoft Fakes
|
||||
FakesAssemblies/
|
||||
|
||||
# GhostDoc plugin setting file
|
||||
*.GhostDoc.xml
|
||||
|
||||
# Node.js Tools for Visual Studio
|
||||
.ntvs_analysis.dat
|
||||
node_modules/
|
||||
|
||||
# Visual Studio 6 build log
|
||||
*.plg
|
||||
|
||||
# Visual Studio 6 workspace options file
|
||||
*.opt
|
||||
|
||||
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
|
||||
*.vbw
|
||||
|
||||
# Visual Studio 6 auto-generated project file (contains which files were open etc.)
|
||||
*.vbp
|
||||
|
||||
# Visual Studio 6 workspace and project file (working project files containing files to include in project)
|
||||
*.dsw
|
||||
*.dsp
|
||||
|
||||
# Visual Studio 6 technical files
|
||||
*.ncb
|
||||
*.aps
|
||||
|
||||
# Visual Studio LightSwitch build output
|
||||
**/*.HTMLClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/ModelManifest.xml
|
||||
**/*.Server/GeneratedArtifacts
|
||||
**/*.Server/ModelManifest.xml
|
||||
_Pvt_Extensions
|
||||
|
||||
# Paket dependency manager
|
||||
.paket/paket.exe
|
||||
paket-files/
|
||||
|
||||
# FAKE - F# Make
|
||||
.fake/
|
||||
|
||||
# CodeRush personal settings
|
||||
.cr/personal
|
||||
|
||||
# Python Tools for Visual Studio (PTVS)
|
||||
__pycache__/
|
||||
*.pyc
|
||||
|
||||
# Cake - Uncomment if you are using it
|
||||
tools/**
|
||||
!tools/packages.config
|
||||
|
||||
# Tabs Studio
|
||||
*.tss
|
||||
|
||||
# Telerik's JustMock configuration file
|
||||
*.jmconfig
|
||||
|
||||
# BizTalk build output
|
||||
*.btp.cs
|
||||
*.btm.cs
|
||||
*.odx.cs
|
||||
*.xsd.cs
|
||||
|
||||
# OpenCover UI analysis results
|
||||
OpenCover/
|
||||
|
||||
# Azure Stream Analytics local run output
|
||||
ASALocalRun/
|
||||
|
||||
# MSBuild Binary and Structured Log
|
||||
*.binlog
|
||||
|
||||
# NVidia Nsight GPU debugger configuration file
|
||||
*.nvuser
|
||||
|
||||
# MFractors (Xamarin productivity tool) working folder
|
||||
.mfractor/
|
||||
|
||||
# Local History for Visual Studio
|
||||
.localhistory/
|
||||
|
||||
# Visual Studio History (VSHistory) files
|
||||
.vshistory/
|
||||
|
||||
# BeatPulse healthcheck temp database
|
||||
healthchecksdb
|
||||
|
||||
# Backup folder for Package Reference Convert tool in Visual Studio 2017
|
||||
MigrationBackup/
|
||||
|
||||
# Ionide (cross platform F# VS Code tools) working folder
|
||||
.ionide/
|
||||
|
||||
# Fody - auto-generated XML schema
|
||||
FodyWeavers.xsd
|
||||
|
||||
# VS Code files for those working on multiple tools
|
||||
.vscode/*
|
||||
!.vscode/settings.json
|
||||
!.vscode/tasks.json
|
||||
!.vscode/launch.json
|
||||
!.vscode/extensions.json
|
||||
*.code-workspace
|
||||
|
||||
# Rider
|
||||
.idea/*
|
||||
|
||||
# Local History for Visual Studio Code
|
||||
.history/
|
||||
|
||||
# Windows Installer files from build outputs
|
||||
*.cab
|
||||
*.msi
|
||||
*.msix
|
||||
*.msm
|
||||
*.msp
|
||||
|
||||
# JetBrains Rider
|
||||
*.sln.iml
|
||||
|
||||
.DS_Store
|
||||
|
||||
# SonarQube
|
||||
.sonarqube
|
||||
49
Directory.Build.props
Normal file
49
Directory.Build.props
Normal file
@@ -0,0 +1,49 @@
|
||||
<Project>
|
||||
|
||||
<PropertyGroup>
|
||||
<Authors>Alan Brault</Authors>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<IsTrimmable>false</IsTrimmable>
|
||||
<LangVersion>12</LangVersion>
|
||||
<NeutralLanguage>en-US</NeutralLanguage>
|
||||
<Nullable>enable</Nullable>
|
||||
<RestorePackagesWithLockFile>true</RestorePackagesWithLockFile>
|
||||
<Version>0.0.1</Version>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<EnforceCodeStyleInBuild>true</EnforceCodeStyleInBuild>
|
||||
<CodeAnalysisTreatWarningsAsErrors>false</CodeAnalysisTreatWarningsAsErrors>
|
||||
<AnalysisMode>AllEnabledByDefault</AnalysisMode>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<DebugType>embedded</DebugType>
|
||||
<EmbedUntrackedSources>true</EmbedUntrackedSources>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
|
||||
<PackageProjectUrl>https://git.visus.io/alan.brault/MapperSourceGenSample</PackageProjectUrl>
|
||||
<PublishRepositoryUrl>true</PublishRepositoryUrl>
|
||||
<RepositoryType>git</RepositoryType>
|
||||
<RepositoryUrl>https://git.visus.io/alan.brault/MapperSourceGenSample.git</RepositoryUrl>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(CI)' == 'true'">
|
||||
<ContinuousIntegrationBuild>true</ContinuousIntegrationBuild>
|
||||
<RestoreLockedMode>true</RestoreLockedMode>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<BeforePack>$(BeforePack);IncludeAnalyzersInPackage</BeforePack>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<AssemblyAttribute Include="System.Runtime.CompilerServices.InternalsVisibleToAttribute">
|
||||
<_Parameter1>$(AssemblyName).Tests</_Parameter1>
|
||||
</AssemblyAttribute>
|
||||
<AssemblyAttribute Include="System.Runtime.CompilerServices.InternalsVisibleToAttribute">
|
||||
<_Parameter1>DynamicProxyGenAssembly2</_Parameter1>
|
||||
</AssemblyAttribute>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
47
Directory.Build.targets
Normal file
47
Directory.Build.targets
Normal file
@@ -0,0 +1,47 @@
|
||||
<Project>
|
||||
<PropertyGroup>
|
||||
<GeneratorProjectBaseTargetPath>analyzers/dotnet</GeneratorProjectBaseTargetPath>
|
||||
<GeneratorProjectBaseTargetPath Condition="'$(AnalyzerLanguage)' != ''">$(GeneratorProjectBaseTargetPath)/$(AnalyzerLanguage)</GeneratorProjectBaseTargetPath>
|
||||
<NoWarn Condition="'$(TargetFrameworkIdentifier)' == '.NETCoreApp'">$(NoWarn);RS1041</NoWarn>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemDefinitionGroup>
|
||||
<TargetPathWithTargetPlatformMoniker>
|
||||
<GeneratorProjectBaseTargetPath>$(GeneratorProjectBaseTargetPath)</GeneratorProjectBaseTargetPath>
|
||||
</TargetPathWithTargetPlatformMoniker>
|
||||
</ItemDefinitionGroup>
|
||||
|
||||
<Target Name="IncludeAnalyzersInPackage"
|
||||
Condition="'@(ProjectReference)' != '' and @(ProjectReference->AnyHaveMetadataValue('PackAsAnalyzer', 'true'))">
|
||||
<MSBuild Projects="@(ProjectReference->WithMetadataValue('PackAsAnalyzer', 'true'))"
|
||||
Targets="GetAnalyzerPackFiles"
|
||||
RemoveProperties="SetTargetFramework">
|
||||
<Output TaskParameter="TargetOutputs" ItemName="_AnalyzerFile"/>
|
||||
</MSBuild>
|
||||
|
||||
<ItemGroup>
|
||||
<Content Include="@(_AnalyzerFile)" Pack="True" Condition="!%(_AnalyzerFile.IsSymbol)" />
|
||||
<_TargetPathsToSymbols Include="@(_AnalyzerFile)" TargetPath="/%(_AnalyzerFile.PackagePath)" Condition="%(_AnalyzerFile.IsSymbol)" />
|
||||
</ItemGroup>
|
||||
</Target>
|
||||
|
||||
<Target Name="GetAnalyzerPackFiles"
|
||||
DependsOnTargets="$(GenerateNuspecDependsOn)"
|
||||
Returns="@(_AnalyzerPackFile)">
|
||||
|
||||
<PropertyGroup>
|
||||
<_AnalyzerPath>analyzers/dotnet</_AnalyzerPath>
|
||||
<_AnalyzerPath Condition="'$(AnalyzerRoslynVersion)' != ''">$(_AnalyzerPath)/roslyn$(AnalyzerRoslynVersion)</_AnalyzerPath>
|
||||
<_AnalyzerPath Condition="'$(AnalyzerLanguage)' != ''">$(_AnalyzerPath)/$(AnalyzerLanguage)</_AnalyzerPath>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<_AnalyzerPackFile Include="@(_BuildOutputInPackage->WithMetadataValue('TargetFramework', 'netstandard2.0'))" IsSymbol="false" />
|
||||
<_AnalyzerPackFile Include="@(_TargetPathsToSymbols->WithMetadataValue('TargetFramework', 'netstandard2.0'))" IsSymbol="true" />
|
||||
<_AnalyzerPackFile PackagePath="$(_AnalyzerPath)/%(TargetPath)" />
|
||||
</ItemGroup>
|
||||
|
||||
<Error Text="Analyzers must target netstandard2.0 since they run in the compiler which targets netstandard2.0. $(MSBuildProjectFullPath) targets '$([MSBuild]::ValueOrDefault('$(TargetFrameworks)', '$(TargetFramework)'))' instead."
|
||||
Condition="'@(_AnalyzerPackFile)' == ''" />
|
||||
</Target>
|
||||
</Project>
|
||||
19
Directory.Packages.props
Normal file
19
Directory.Packages.props
Normal file
@@ -0,0 +1,19 @@
|
||||
<Project>
|
||||
<PropertyGroup>
|
||||
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
|
||||
<CentralPackageTransitivePinningEnabled>true</CentralPackageTransitivePinningEnabled>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageVersion Include="coverlet.collector" Version="6.0.4" />
|
||||
<PackageVersion Include="coverlet.msbuild" Version="6.0.4" />
|
||||
<PackageVersion Include="JunitXml.TestLogger" Version="6.1.0" />
|
||||
<PackageVersion Include="Microsoft.CodeAnalysis.Common" Version="4.11.0" />
|
||||
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp" Version="[4.11.0]" />
|
||||
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.14.1" />
|
||||
<PackageVersion Include="Verify.DiffPlex" Version="3.1.2" />
|
||||
<PackageVersion Include="Verify.SourceGenerators" Version="2.5.0" />
|
||||
<PackageVersion Include="Verify.Xunit" Version="30.5.0" />
|
||||
<PackageVersion Include="xunit" Version="2.9.3" />
|
||||
<PackageVersion Include="xunit.runner.visualstudio" Version="3.1.3" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
57
MapperSourceGenSample.sln
Normal file
57
MapperSourceGenSample.sln
Normal file
@@ -0,0 +1,57 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{36DCA314-4C08-44D2-BE6B-4AD5ACD38A35}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
Directory.Packages.props = Directory.Packages.props
|
||||
Directory.Build.props = Directory.Build.props
|
||||
Directory.Build.targets = Directory.Build.targets
|
||||
README.md = README.md
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "01. Foundation", "01. Foundation", "{F327E906-C84C-4C79-9FDC-A8BA45ADCA7D}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MapperSourceGen.SourceGenerator", "src\MapperSourceGen.SourceGenerator\MapperSourceGen.SourceGenerator.csproj", "{A2AA5839-C781-4E1A-B0AF-67F5BDD5C394}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "02. Sample", "02. Sample", "{62B5A0CF-AB5F-4BF1-8D29-E22AB7DC6348}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "03. Unit Tests", "03. Unit Tests", "{9E52F931-B3B3-4F6B-9EDF-89CFE8DC031C}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
tests\Directory.Build.props = tests\Directory.Build.props
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MapperSourceGen", "src\MapperSourceGen\MapperSourceGen.csproj", "{16ADA529-B8A5-43EB-957C-699BF654F894}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MapperSourceGen.Sample", "sample\MapperSourceGen.Sample\MapperSourceGen.Sample.csproj", "{9ECCD86F-9E77-41C3-9494-A8E2C40BF5B4}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MapperSourceGen.SourceGenerator.Tests", "tests\MapperSourceGen.SourceGenerator.Tests\MapperSourceGen.SourceGenerator.Tests.csproj", "{0B318171-7E7A-4283-9B40-EA97E7ECB728}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(NestedProjects) = preSolution
|
||||
{A2AA5839-C781-4E1A-B0AF-67F5BDD5C394} = {F327E906-C84C-4C79-9FDC-A8BA45ADCA7D}
|
||||
{16ADA529-B8A5-43EB-957C-699BF654F894} = {F327E906-C84C-4C79-9FDC-A8BA45ADCA7D}
|
||||
{9ECCD86F-9E77-41C3-9494-A8E2C40BF5B4} = {62B5A0CF-AB5F-4BF1-8D29-E22AB7DC6348}
|
||||
{0B318171-7E7A-4283-9B40-EA97E7ECB728} = {9E52F931-B3B3-4F6B-9EDF-89CFE8DC031C}
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{A2AA5839-C781-4E1A-B0AF-67F5BDD5C394}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{A2AA5839-C781-4E1A-B0AF-67F5BDD5C394}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{A2AA5839-C781-4E1A-B0AF-67F5BDD5C394}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{A2AA5839-C781-4E1A-B0AF-67F5BDD5C394}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{16ADA529-B8A5-43EB-957C-699BF654F894}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{16ADA529-B8A5-43EB-957C-699BF654F894}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{16ADA529-B8A5-43EB-957C-699BF654F894}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{16ADA529-B8A5-43EB-957C-699BF654F894}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{9ECCD86F-9E77-41C3-9494-A8E2C40BF5B4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{9ECCD86F-9E77-41C3-9494-A8E2C40BF5B4}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{9ECCD86F-9E77-41C3-9494-A8E2C40BF5B4}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{9ECCD86F-9E77-41C3-9494-A8E2C40BF5B4}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{0B318171-7E7A-4283-9B40-EA97E7ECB728}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{0B318171-7E7A-4283-9B40-EA97E7ECB728}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{0B318171-7E7A-4283-9B40-EA97E7ECB728}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{0B318171-7E7A-4283-9B40-EA97E7ECB728}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
316
MapperSourceGenSample.sln.DotSettings
Normal file
316
MapperSourceGenSample.sln.DotSettings
Normal file
@@ -0,0 +1,316 @@
|
||||
<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">
|
||||
<s:Boolean x:Key="/Default/CodeInspection/Roslyn/LegacySeveritiesMigrated/@EntryValue">True</s:Boolean>
|
||||
<s:String x:Key="/Default/CodeStyle/CodeCleanup/RecentlyUsedProfile/@EntryValue">Built-in: Full Cleanup</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/CodeCleanup/SilentCleanupProfile/@EntryValue">Built-in: Full Cleanup</s:String>
|
||||
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_LINES/@EntryValue">False</s:Boolean>
|
||||
<s:String x:Key="/Default/CodeStyle/CSharpFileLayoutPatterns/Pattern/@EntryValue"><?xml version="1.0" encoding="utf-16"?>
|
||||
<Patterns xmlns="urn:schemas-jetbrains-com:member-reordering-patterns">
|
||||
<TypePattern DisplayName="Non-reorderable types">
|
||||
<TypePattern.Match>
|
||||
<Or>
|
||||
<And>
|
||||
<Kind Is="Interface" />
|
||||
<Or>
|
||||
<HasAttribute Name="System.Runtime.InteropServices.InterfaceTypeAttribute" />
|
||||
<HasAttribute Name="System.Runtime.InteropServices.ComImport" />
|
||||
</Or>
|
||||
</And>
|
||||
<Kind Is="Struct" />
|
||||
<HasAttribute Name="JetBrains.Annotations.NoReorderAttribute" />
|
||||
<HasAttribute Name="JetBrains.Annotations.NoReorder" />
|
||||
</Or>
|
||||
</TypePattern.Match>
|
||||
</TypePattern>
|
||||
<TypePattern DisplayName="xUnit.net Test Classes" RemoveRegions="All">
|
||||
<TypePattern.Match>
|
||||
<And>
|
||||
<Kind Is="Class" />
|
||||
<HasMember>
|
||||
<And>
|
||||
<Kind Is="Method" />
|
||||
<HasAttribute Name="Xunit.FactAttribute" Inherited="True" />
|
||||
</And>
|
||||
</HasMember>
|
||||
</And>
|
||||
</TypePattern.Match>
|
||||
<Entry DisplayName="Setup/Teardown Methods">
|
||||
<Entry.Match>
|
||||
<Or>
|
||||
<Kind Is="Constructor" />
|
||||
<And>
|
||||
<Kind Is="Method" />
|
||||
<ImplementsInterface Name="System.IDisposable" />
|
||||
</And>
|
||||
</Or>
|
||||
</Entry.Match>
|
||||
<Entry.SortBy>
|
||||
<Kind Order="Constructor" />
|
||||
</Entry.SortBy>
|
||||
</Entry>
|
||||
<Entry DisplayName="All other members" />
|
||||
<Entry DisplayName="Test Methods" Priority="100">
|
||||
<Entry.Match>
|
||||
<And>
|
||||
<Kind Is="Method" />
|
||||
<HasAttribute Name="Xunit.FactAttribute" />
|
||||
</And>
|
||||
</Entry.Match>
|
||||
<Entry.SortBy>
|
||||
<Name />
|
||||
</Entry.SortBy>
|
||||
</Entry>
|
||||
</TypePattern>
|
||||
<TypePattern DisplayName="NUnit Test Fixtures" RemoveRegions="All">
|
||||
<TypePattern.Match>
|
||||
<And>
|
||||
<Kind Is="Class" />
|
||||
<HasAttribute Name="NUnit.Framework.TestFixtureAttribute" Inherited="True" />
|
||||
</And>
|
||||
</TypePattern.Match>
|
||||
<Entry DisplayName="Setup/Teardown Methods">
|
||||
<Entry.Match>
|
||||
<And>
|
||||
<Kind Is="Method" />
|
||||
<Or>
|
||||
<HasAttribute Name="NUnit.Framework.SetUpAttribute" Inherited="True" />
|
||||
<HasAttribute Name="NUnit.Framework.TearDownAttribute" Inherited="True" />
|
||||
<HasAttribute Name="NUnit.Framework.FixtureSetUpAttribute" Inherited="True" />
|
||||
<HasAttribute Name="NUnit.Framework.FixtureTearDownAttribute" Inherited="True" />
|
||||
</Or>
|
||||
</And>
|
||||
</Entry.Match>
|
||||
</Entry>
|
||||
<Entry DisplayName="All other members" />
|
||||
<Entry DisplayName="Test Methods" Priority="100">
|
||||
<Entry.Match>
|
||||
<And>
|
||||
<Kind Is="Method" />
|
||||
<HasAttribute Name="NUnit.Framework.TestAttribute" />
|
||||
</And>
|
||||
</Entry.Match>
|
||||
<Entry.SortBy>
|
||||
<Name />
|
||||
</Entry.SortBy>
|
||||
</Entry>
|
||||
</TypePattern>
|
||||
<TypePattern DisplayName="Default Pattern" RemoveRegions="All" Priority="150">
|
||||
<Group DisplayName="Group by Access">
|
||||
<Group.GroupBy>
|
||||
<Access />
|
||||
</Group.GroupBy>
|
||||
<Entry DisplayName="Constant or Field Constant">
|
||||
<Entry.Match>
|
||||
<Or>
|
||||
<Kind Is="Constant" />
|
||||
<And>
|
||||
<Static />
|
||||
<Kind Is="Field" />
|
||||
</And>
|
||||
</Or>
|
||||
</Entry.Match>
|
||||
<Entry.SortBy>
|
||||
<Static />
|
||||
<Readonly />
|
||||
<Name />
|
||||
</Entry.SortBy>
|
||||
</Entry>
|
||||
</Group>
|
||||
<Group DisplayName="Group by Access">
|
||||
<Group.GroupBy>
|
||||
<Access />
|
||||
</Group.GroupBy>
|
||||
<Entry DisplayName="Field">
|
||||
<Entry.Match>
|
||||
<Kind Is="Field" />
|
||||
</Entry.Match>
|
||||
<Entry.SortBy>
|
||||
<Static />
|
||||
<Readonly />
|
||||
<Name />
|
||||
</Entry.SortBy>
|
||||
</Entry>
|
||||
</Group>
|
||||
<Group DisplayName="Group by Access">
|
||||
<Group.GroupBy>
|
||||
<Access />
|
||||
</Group.GroupBy>
|
||||
<Entry DisplayName="Constructor">
|
||||
<Entry.Match>
|
||||
<Kind Is="Constructor" />
|
||||
</Entry.Match>
|
||||
<Entry.SortBy>
|
||||
<Static />
|
||||
<Name />
|
||||
</Entry.SortBy>
|
||||
</Entry>
|
||||
</Group>
|
||||
<Group DisplayName="Group by Access">
|
||||
<Group.GroupBy>
|
||||
<Access />
|
||||
</Group.GroupBy>
|
||||
<Entry DisplayName="Destructor">
|
||||
<Entry.Match>
|
||||
<Kind Is="Destructor" />
|
||||
</Entry.Match>
|
||||
<Entry.SortBy>
|
||||
<Static />
|
||||
<Name />
|
||||
</Entry.SortBy>
|
||||
</Entry>
|
||||
</Group>
|
||||
<Group DisplayName="Group by Access">
|
||||
<Group.GroupBy>
|
||||
<Access />
|
||||
</Group.GroupBy>
|
||||
<Entry DisplayName="Delegate">
|
||||
<Entry.Match>
|
||||
<Kind Is="Delegate" />
|
||||
</Entry.Match>
|
||||
<Entry.SortBy>
|
||||
<Static />
|
||||
<Name />
|
||||
</Entry.SortBy>
|
||||
</Entry>
|
||||
</Group>
|
||||
<Group DisplayName="Group by Access">
|
||||
<Group.GroupBy>
|
||||
<Access />
|
||||
</Group.GroupBy>
|
||||
<Entry DisplayName="Event">
|
||||
<Entry.Match>
|
||||
<Kind Is="Event" />
|
||||
</Entry.Match>
|
||||
<Entry.SortBy>
|
||||
<Static />
|
||||
<Name />
|
||||
</Entry.SortBy>
|
||||
</Entry>
|
||||
</Group>
|
||||
<Group DisplayName="Group by Access">
|
||||
<Group.GroupBy>
|
||||
<Access />
|
||||
</Group.GroupBy>
|
||||
<Entry DisplayName="Enum">
|
||||
<Entry.Match>
|
||||
<Kind Is="Enum" />
|
||||
</Entry.Match>
|
||||
<Entry.SortBy>
|
||||
<Name />
|
||||
</Entry.SortBy>
|
||||
</Entry>
|
||||
</Group>
|
||||
<Group DisplayName="Group by Access">
|
||||
<Group.GroupBy>
|
||||
<Access />
|
||||
</Group.GroupBy>
|
||||
<Entry DisplayName="Interface">
|
||||
<Entry.Match>
|
||||
<Kind Is="Interface" />
|
||||
</Entry.Match>
|
||||
<Entry.SortBy>
|
||||
<Name />
|
||||
</Entry.SortBy>
|
||||
</Entry>
|
||||
</Group>
|
||||
<Group DisplayName="Group by Access">
|
||||
<Group.GroupBy>
|
||||
<Access />
|
||||
</Group.GroupBy>
|
||||
<Entry DisplayName="Property">
|
||||
<Entry.Match>
|
||||
<Kind Is="Property" />
|
||||
</Entry.Match>
|
||||
<Entry.SortBy>
|
||||
<Static />
|
||||
<Readonly />
|
||||
<Name />
|
||||
</Entry.SortBy>
|
||||
</Entry>
|
||||
</Group>
|
||||
<Group DisplayName="Group by Access">
|
||||
<Group.GroupBy>
|
||||
<Access />
|
||||
</Group.GroupBy>
|
||||
<Entry DisplayName="Indexer">
|
||||
<Entry.Match>
|
||||
<Kind Is="Indexer" />
|
||||
</Entry.Match>
|
||||
<Entry.SortBy>
|
||||
<Static />
|
||||
<Name />
|
||||
</Entry.SortBy>
|
||||
</Entry>
|
||||
</Group>
|
||||
<Group DisplayName="Group by Access">
|
||||
<Group.GroupBy>
|
||||
<Access />
|
||||
</Group.GroupBy>
|
||||
<Entry DisplayName="Method">
|
||||
<Entry.Match>
|
||||
<Kind Is="Method" />
|
||||
</Entry.Match>
|
||||
<Entry.SortBy>
|
||||
<Static />
|
||||
<Name />
|
||||
</Entry.SortBy>
|
||||
</Entry>
|
||||
</Group>
|
||||
<Group DisplayName="Group by Access">
|
||||
<Group.GroupBy>
|
||||
<Access />
|
||||
</Group.GroupBy>
|
||||
<Entry DisplayName="Struct">
|
||||
<Entry.Match>
|
||||
<Kind Is="Struct" />
|
||||
</Entry.Match>
|
||||
<Entry.SortBy>
|
||||
<Name />
|
||||
</Entry.SortBy>
|
||||
</Entry>
|
||||
</Group>
|
||||
<Group DisplayName="Group by Access">
|
||||
<Group.GroupBy>
|
||||
<Access />
|
||||
</Group.GroupBy>
|
||||
<Entry DisplayName="Class">
|
||||
<Entry.Match>
|
||||
<Kind Is="Class" />
|
||||
</Entry.Match>
|
||||
<Entry.SortBy>
|
||||
<Static />
|
||||
<Sealed />
|
||||
<Name />
|
||||
</Entry.SortBy>
|
||||
</Entry>
|
||||
<Entry DisplayName="Record">
|
||||
<Entry.Match>
|
||||
<Kind Is="Record" />
|
||||
</Entry.Match>
|
||||
<Entry.SortBy>
|
||||
<Readonly />
|
||||
<Name />
|
||||
</Entry.SortBy>
|
||||
</Entry>
|
||||
</Group>
|
||||
</TypePattern>
|
||||
</Patterns></s:String>
|
||||
<s:Boolean x:Key="/Default/CodeStyle/Generate/=EqualityMembers/@KeyIndexDefined">True</s:Boolean>
|
||||
<s:String x:Key="/Default/CodeStyle/Generate/=EqualityMembers/Options/=EqualityOperators/@EntryIndexedValue">True</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Generate/=EqualityMembers/Options/=UseSystemHashCode/@EntryIndexedValue">True</s:String>
|
||||
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpKeepExistingMigration/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpPlaceEmbeddedOnSameLineMigration/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpUseContinuousIndentInsideBracesMigration/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002EMemberReordering_002EMigrations_002ECSharpFileLayoutPatternRemoveIsAttributeUpgrade/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EAlwaysTreatStructAsNotReorderableMigration/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateBlankLinesAroundFieldToBlankLinesAroundProperty/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=bowes/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=CHANNELADVISOR/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=datetimeoffset/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=efcoregen/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Fulfillments/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Multipack/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=namespaceanddescendants/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=pitney/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=smallmoney/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=usings/@EntryIndexedValue">True</s:Boolean>
|
||||
</wpf:ResourceDictionary>
|
||||
119
README.md
Normal file
119
README.md
Normal file
@@ -0,0 +1,119 @@
|
||||
# Mapper Source Generator Example
|
||||
|
||||
This project demonstrates how you can use incremental source generators in C# to generate domain transfer objects (DTOs)
|
||||
and mapping classes from a POCO.
|
||||
|
||||
> [!WARNING]
|
||||
> This is a sample project and not intended for production use. It is meant to illustrate the concept of using source generators.
|
||||
> Please look into using either [mapster's](https://github.com/MapsterMapper/Mapster) code generator or [mapperly](https://github.com/riok/mapperly) instead.
|
||||
|
||||
## Requirements
|
||||
- .NET 8.0 SDK
|
||||
|
||||
## What's Included
|
||||
- `MapperSourceGen`: The main project that contains the attributes for decorating classes and properties for the source generator.
|
||||
- `MapperSourceGen.Sample`: A sample class library that demonstrates the use of the source generator.
|
||||
- `MapperSourceGen.SourceGenerator`: The source generator that generates DTOs and mapping classes.
|
||||
- `MapperSourceGen.SourceGenerator.Tests`: Unit tests for the source generator to ensure it works as expected (snapshot testing).
|
||||
|
||||
Feel free to inspect the `.csproj` files for the projects to see how they are set up and how the source generator is integrated.
|
||||
|
||||
Additionally, a `launchSettings.json` file is included so that you can run the source generator in debug mode and step through the code. Simply execute `Source Generator`.
|
||||
|
||||
> [!NOTE]
|
||||
> The source files emitted by the source generator will be under `Dependencies -> .NET 8.0 -> Source Generators` in the `MapperSourceGen.Sample` project if using Rider.
|
||||
|
||||
## Purpose
|
||||
|
||||
As projects grow, the need for transferring data between layers (like from a database to a UI) becomes essential.
|
||||
However, with that comes the additional complexity of maintaining DTOs and mapping classes. One of the ways this can be
|
||||
solved is by using source generators to automate the creation of these classes.
|
||||
|
||||
Source generators provide the ability to generate code at compile time, which can help reduce boilerplate code and improve maintainability
|
||||
and reduce the reliance on expensive reflection-based mapping.
|
||||
|
||||
## How It Works
|
||||
|
||||
The project **MapperSourceGen.SourceGenerator** contains a source generator that scans for classes decorated with the `GenerateMapperAttribute`.
|
||||
When it finds such a class, it generates a DTO and a mapping class for it.
|
||||
|
||||
### Example
|
||||
|
||||
Let's say you have a class `Order` that you want to generate a DTO and mapping class for. You would decorate it with the `GenerateMapperAttribute` like this:
|
||||
|
||||
**Order.cs**
|
||||
```csharp
|
||||
[Mapper]
|
||||
public sealed class Order
|
||||
{
|
||||
[MapAlias("EntityId")] // renames Id to EntityId in the DTO
|
||||
public Guid Id { get; set; }
|
||||
|
||||
public Guid? CustomerId { get; set; }
|
||||
|
||||
[MapAlias("OrderId")] // renames IncrementId to OrderId in the DTO
|
||||
public int IncrementId { get; set;}
|
||||
|
||||
public DateTimeOffset Created { get; set;}
|
||||
|
||||
public DateTimeOffset? Updated { get; set; }
|
||||
|
||||
[MapIgnore] // this property will not be included in the DTO or mapper
|
||||
public string TransactionId { get; set; }
|
||||
}
|
||||
```
|
||||
|
||||
The source generator will then generate a DTO class `OrderDto` and a mapping class `OrderMapper` that looks like this:
|
||||
|
||||
**OrderMapper.g.cs**
|
||||
```csharp
|
||||
public sealed partial class OrderMapper
|
||||
{
|
||||
public static Order ToModel(OrderDto source)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(source);
|
||||
|
||||
return new Order()
|
||||
{
|
||||
Id = source.EntityId,
|
||||
CustomerId = source.CustomerId,
|
||||
IncrementId = source.OrderId
|
||||
Created = source.Created,
|
||||
Updated = source.Updated
|
||||
}
|
||||
}
|
||||
|
||||
public static OrderDto ToDto(Order source)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(source);
|
||||
|
||||
return new OrderDto()
|
||||
{
|
||||
EntityId = source.Id,
|
||||
CustomerId = source.CustomerId,
|
||||
OrderId = source.IncrementId,
|
||||
Created = source.Created,
|
||||
Updated = source.Updated
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**OrderDto.g.cs**
|
||||
```csharp
|
||||
public sealed partial class OrderDto
|
||||
{
|
||||
public Guid? CustomerId { get; set; }
|
||||
|
||||
public Guid EntityId { get; set; }
|
||||
|
||||
public int OrderId { get; set; }
|
||||
|
||||
public DateTimeOffset Created { get; set; }
|
||||
|
||||
public DateTimeOffset? Updated { get; set; }
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
8
global.json
Normal file
8
global.json
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"sdk": {
|
||||
"version": "8.0.412",
|
||||
"rollForward": "latestFeature",
|
||||
"allowPrerelease": false
|
||||
}
|
||||
}
|
||||
|
||||
67
sample/MapperSourceGen.Sample/Domain/Customers/Customer.cs
Normal file
67
sample/MapperSourceGen.Sample/Domain/Customers/Customer.cs
Normal file
@@ -0,0 +1,67 @@
|
||||
namespace MapperSourceGen.Sample.Domain.Customers;
|
||||
|
||||
/// <summary>
|
||||
/// Model representing a customer in the system.
|
||||
/// </summary>
|
||||
[Mapper]
|
||||
public sealed class Customer
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the address lines of the customer.
|
||||
/// </summary>
|
||||
public IReadOnlyList<string> AddressLines { get; set; } = [];
|
||||
|
||||
/// <summary>
|
||||
/// Represents the country of the customer.
|
||||
/// </summary>
|
||||
public string Country { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Represents the date and time when the customer was created.
|
||||
/// </summary>
|
||||
[MapIgnore]
|
||||
public DateTimeOffset Created { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Represents the unique identifier for the customer.
|
||||
/// </summary>
|
||||
public Guid CustomerId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Represents the email address of the customer.
|
||||
/// </summary>
|
||||
public string Email { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Represents the first name of the customer.
|
||||
/// </summary>
|
||||
public string FirstName { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Represents the last name of the customer.
|
||||
/// </summary>
|
||||
public string LastName { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Represents the phone number of the customer.
|
||||
/// </summary>
|
||||
public string Phone { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Represents the postal code of the customer.
|
||||
/// </summary>
|
||||
[MapAlias("ZipCode")]
|
||||
public string PostalCode { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Represents the state or province of the customer.
|
||||
/// </summary>
|
||||
[MapAlias("State")]
|
||||
public string StateOrProvince { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Represents the date and time when the customer was last updated (nullable).
|
||||
/// </summary>
|
||||
[MapIgnore]
|
||||
public DateTimeOffset? Updated { get; set; }
|
||||
}
|
||||
36
sample/MapperSourceGen.Sample/Domain/Orders/Order.cs
Normal file
36
sample/MapperSourceGen.Sample/Domain/Orders/Order.cs
Normal file
@@ -0,0 +1,36 @@
|
||||
namespace MapperSourceGen.Sample.Domain.Orders;
|
||||
|
||||
/// <summary>
|
||||
/// Model representing an order in the system.
|
||||
/// </summary>
|
||||
[Mapper]
|
||||
public sealed class Order
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the date and time when the order was created.
|
||||
/// </summary>
|
||||
public DateTimeOffset Created { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Represents the unique identifier for the customer associated with the order (nullable).
|
||||
/// </summary>
|
||||
public Guid? CustomerId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Represents the unique identifier for the order (private).
|
||||
/// </summary>
|
||||
[MapAlias("EntityId")]
|
||||
public Guid Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Represents the unique identifier integer for the order (public).
|
||||
/// </summary>
|
||||
[MapAlias("OrderId")]
|
||||
public int IncrementId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Represents the date and time when the order was last updated.
|
||||
/// </summary>
|
||||
[MapIgnore]
|
||||
public DateTimeOffset? Updated { get; set; }
|
||||
}
|
||||
23
sample/MapperSourceGen.Sample/MapperSourceGen.Sample.csproj
Normal file
23
sample/MapperSourceGen.Sample/MapperSourceGen.Sample.csproj
Normal file
@@ -0,0 +1,23 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\src\MapperSourceGen\MapperSourceGen.csproj"/>
|
||||
|
||||
<!--
|
||||
When referencing a source generator that is part of the solution, ensure that the following properties are set:
|
||||
|
||||
- OutputItemType="Analyzer" to treat it as an analyzer.
|
||||
- SetTargetFramework="TargetFramework=netstandard2.0" to ensure compatibility with the source generator.
|
||||
- ReferenceOutputAssembly="false" to prevent the source generator from being treated as a regular assembly.
|
||||
-->
|
||||
<ProjectReference Include="..\..\src\MapperSourceGen.SourceGenerator\MapperSourceGen.SourceGenerator.csproj"
|
||||
OutputItemType="Analyzer"
|
||||
SetTargetFramework="TargetFramework=netstandard2.0"
|
||||
ReferenceOutputAssembly="false"/>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
10
sample/MapperSourceGen.Sample/packages.lock.json
Normal file
10
sample/MapperSourceGen.Sample/packages.lock.json
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"version": 2,
|
||||
"dependencies": {
|
||||
"net8.0": {
|
||||
"mappersourcegen": {
|
||||
"type": "Project"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
namespace MapperSourceGen.SourceGenerator.Extensions;
|
||||
|
||||
using System.Runtime.CompilerServices;
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.CSharp;
|
||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||
|
||||
/// <summary>
|
||||
/// Extension methods for <see cref="ITypeSymbol" />.
|
||||
/// </summary>
|
||||
internal static class TypeSymbolExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Converts an <see cref="ITypeSymbol" /> to a <see cref="TypeSyntax" />.
|
||||
/// </summary>
|
||||
/// <param name="source">The source <see cref="ITypeSymbol" /> instance to convert.</param>
|
||||
/// <returns>An instance of <see cref="TypeSyntax" />.</returns>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static TypeSyntax ToTypeSyntax(this ITypeSymbol source)
|
||||
{
|
||||
string typeName = source.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat);
|
||||
return SyntaxFactory.ParseTypeName(typeName);
|
||||
}
|
||||
}
|
||||
215
src/MapperSourceGen.SourceGenerator/MapperGenerator.cs
Normal file
215
src/MapperSourceGen.SourceGenerator/MapperGenerator.cs
Normal file
@@ -0,0 +1,215 @@
|
||||
namespace MapperSourceGen.SourceGenerator;
|
||||
|
||||
using System.Collections.Immutable;
|
||||
using System.Text;
|
||||
using Extensions;
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.CSharp;
|
||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||
using Model;
|
||||
using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory;
|
||||
|
||||
/// <summary>
|
||||
/// Incremental source generator that is responsible for generating domain transfer objects (DTOs) and mapper from a
|
||||
/// class decorated with the <c>MapperAttribute</c>.
|
||||
/// </summary>
|
||||
[Generator]
|
||||
public sealed class MapperGenerator : IIncrementalGenerator
|
||||
{
|
||||
private const string MapIgnoreAttributeName = "MapperSourceGen.MapIgnoreAttribute";
|
||||
|
||||
private const string MapperAttributeName = "MapperSourceGen.MapperAttribute";
|
||||
|
||||
private const string Source = "source";
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Initialize(IncrementalGeneratorInitializationContext context)
|
||||
{
|
||||
// This configures the generator pipeline to look for classes decorated with the MapperAttribute which will then extract
|
||||
// the hierarchy information and properties to generate DTOs and mapping methods.
|
||||
IncrementalValuesProvider<(HierarchyInfo Hierarchy, ImmutableArray<PropertyInfo> Properties)> items =
|
||||
context.SyntaxProvider
|
||||
.ForAttributeWithMetadataName(MapperAttributeName,
|
||||
static (node, _) => node is ClassDeclarationSyntax { AttributeLists.Count: > 0 },
|
||||
static (ctx, _) =>
|
||||
{
|
||||
if ( ctx.TargetSymbol is not INamedTypeSymbol classSymbol )
|
||||
{
|
||||
return default;
|
||||
}
|
||||
|
||||
HierarchyInfo hierarchy = HierarchyInfo.From(classSymbol);
|
||||
ImmutableArray<PropertyInfo> properties =
|
||||
[
|
||||
..classSymbol.GetMembers()
|
||||
.OfType<IPropertySymbol>()
|
||||
.Where(w => !w.IsIndexer
|
||||
&& w is { IsAbstract: false, DeclaredAccessibility: Accessibility.Public }
|
||||
&& !w.GetAttributes().Any(a => a.AttributeClass?.ToDisplayString() == MapIgnoreAttributeName))
|
||||
.Select(s => new PropertyInfo(s))
|
||||
];
|
||||
|
||||
|
||||
return ( hierarchy, properties );
|
||||
});
|
||||
|
||||
// This registers the source output for generating the domain transfer object (DTO).
|
||||
context.RegisterSourceOutput(items,
|
||||
static (ctx, item) =>
|
||||
{
|
||||
ImmutableArray<MemberDeclarationSyntax> properties = [..GenerateAutoProperties(item.Properties)];
|
||||
|
||||
CompilationUnitSyntax? compilationUnit = item.Hierarchy.GetCompilationUnit(properties, suffix: "Dto");
|
||||
if ( compilationUnit is not null )
|
||||
{
|
||||
ctx.AddSource($"{item.Hierarchy.FileNameHint}Dto.g", compilationUnit.GetText(Encoding.UTF8));
|
||||
}
|
||||
});
|
||||
|
||||
// This registers the source output for generating the mapper class with mapping methods.
|
||||
context.RegisterSourceOutput(items,
|
||||
static (ctx, item) =>
|
||||
{
|
||||
ImmutableArray<MemberDeclarationSyntax> declarations =
|
||||
[
|
||||
GenerateMapFromMethod(item.Hierarchy, item.Properties),
|
||||
GenerateMapToMethod(item.Hierarchy, item.Properties)
|
||||
];
|
||||
|
||||
CompilationUnitSyntax? compilationUnit = item.Hierarchy.GetCompilationUnit(declarations, suffix: "Mapper");
|
||||
if ( compilationUnit is not null )
|
||||
{
|
||||
ctx.AddSource($"{item.Hierarchy.FileNameHint}Mapper.g", compilationUnit.GetText(Encoding.UTF8));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generates an expression statement that validates the argument for null.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// An expression statement that will output <code>ArgumentNullException.ThrowIfNull(nameof(source));</code>
|
||||
/// </returns>
|
||||
private static ExpressionStatementSyntax GenerateArgumentValidator()
|
||||
{
|
||||
MemberAccessExpressionSyntax member = MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression,
|
||||
IdentifierName("ArgumentNullException"),
|
||||
IdentifierName("ThrowIfNull"));
|
||||
|
||||
IdentifierNameSyntax nameofIdentifier = IdentifierName(Identifier(TriviaList(),
|
||||
SyntaxKind.NameOfKeyword,
|
||||
"nameof",
|
||||
"nameof",
|
||||
TriviaList()));
|
||||
|
||||
ArgumentSyntax argument = Argument(InvocationExpression(nameofIdentifier)
|
||||
.WithArgumentList(ArgumentList(SingletonSeparatedList(Argument(IdentifierName(Source))))));
|
||||
|
||||
return ExpressionStatement(InvocationExpression(member)
|
||||
.WithArgumentList(ArgumentList(SingletonSeparatedList(argument))));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generates auto properties used in the domain transfer object (DTO).
|
||||
/// </summary>
|
||||
/// <param name="properties">An <see cref="IEnumerable{T}" /> collection of properties to generate auto-properties for.</param>
|
||||
/// <returns>
|
||||
/// An <see cref="IEnumerable{T}" /> of <see cref="MemberDeclarationSyntax" /> items that will output auto-properties:
|
||||
/// <code>
|
||||
/// public string Name { get; set;
|
||||
/// </code>
|
||||
/// </returns>
|
||||
private static IEnumerable<MemberDeclarationSyntax> GenerateAutoProperties(IEnumerable<PropertyInfo> properties)
|
||||
{
|
||||
return properties.Select(property => PropertyDeclaration(property.PropertyType.ToTypeSyntax(), property.TargetPropertyName)
|
||||
.AddModifiers(Token(SyntaxKind.PublicKeyword))
|
||||
.AddAccessorListAccessors(
|
||||
AccessorDeclaration(SyntaxKind.GetAccessorDeclaration)
|
||||
.WithSemicolonToken(Token(SyntaxKind.SemicolonToken)),
|
||||
AccessorDeclaration(SyntaxKind.SetAccessorDeclaration)
|
||||
.WithSemicolonToken(Token(SyntaxKind.SemicolonToken))
|
||||
));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generates a method that maps a DTO to a model.
|
||||
/// </summary>
|
||||
/// <param name="hierarchy">An <see cref="HierarchyInfo" /> instance that contains information about the model.</param>
|
||||
/// <param name="properties">An <see cref="IEnumerable{T}" /> of properties to be used in mapping the DTO to the model.</param>
|
||||
/// <returns>
|
||||
/// An instance of <see cref="MemberDeclarationSyntax" /> containing the method that returns an instance of the
|
||||
/// model.
|
||||
/// </returns>
|
||||
/// <remarks>Properties that are decorated with the <c>MapIgnoreAttribute</c> will not be included in the mapping.</remarks>
|
||||
private static MethodDeclarationSyntax GenerateMapFromMethod(HierarchyInfo hierarchy, ImmutableArray<PropertyInfo> properties)
|
||||
{
|
||||
ParameterSyntax parameter = Parameter(Identifier(Source))
|
||||
.WithType(ParseTypeName($"{hierarchy.FileNameHint}Dto"));
|
||||
|
||||
ReturnStatementSyntax returnStatement = ReturnStatement(GenerateMappingMethod(hierarchy, properties, isSource: false));
|
||||
|
||||
return MethodDeclaration(ParseTypeName($"{hierarchy.FileNameHint}"), "ToModel")
|
||||
.AddModifiers(Token(SyntaxKind.PublicKeyword), Token(SyntaxKind.StaticKeyword))
|
||||
.AddParameterListParameters(parameter)
|
||||
.WithBody(Block(GenerateArgumentValidator(), returnStatement));
|
||||
}
|
||||
|
||||
private static ObjectCreationExpressionSyntax GenerateMappingMethod(HierarchyInfo hierarchy,
|
||||
ImmutableArray<PropertyInfo> properties,
|
||||
string? suffix = null,
|
||||
bool isSource = true)
|
||||
{
|
||||
return ObjectCreationExpression(IdentifierName(ParseTypeName($"{hierarchy.FileNameHint}{suffix}").ToString()))
|
||||
.WithArgumentList(ArgumentList())
|
||||
.WithInitializer(InitializerExpression(SyntaxKind.ObjectInitializerExpression,
|
||||
SeparatedList<ExpressionSyntax>(GeneratePropertyAssignments(properties, isSource))));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generates a method that maps a model to a DTO.
|
||||
/// </summary>
|
||||
/// <param name="hierarchy">An <see cref="HierarchyInfo" /> instance that contains information about the model.</param>
|
||||
/// <param name="properties">An <see cref="IEnumerable{T}" /> of properties to be used in mapping the model to the DTO.</param>
|
||||
/// <returns>
|
||||
/// An instance of <see cref="MemberDeclarationSyntax" /> containing the method that returns an instance of the
|
||||
/// DTO.
|
||||
/// </returns>
|
||||
/// <remarks>Properties that are decorated with the <c>MapIgnoreAttribute</c> will not be included in the mapping.</remarks>
|
||||
private static MethodDeclarationSyntax GenerateMapToMethod(HierarchyInfo hierarchy, ImmutableArray<PropertyInfo> properties)
|
||||
{
|
||||
ParameterSyntax parameter = Parameter(Identifier(Source))
|
||||
.WithType(ParseTypeName(hierarchy.FileNameHint));
|
||||
|
||||
ReturnStatementSyntax returnStatement = ReturnStatement(GenerateMappingMethod(hierarchy, properties, "Dto"));
|
||||
|
||||
return MethodDeclaration(ParseTypeName($"{hierarchy.FileNameHint}Dto"), "ToDto")
|
||||
.AddModifiers(Token(SyntaxKind.PublicKeyword), Token(SyntaxKind.StaticKeyword))
|
||||
.AddParameterListParameters(parameter)
|
||||
.WithBody(Block(GenerateArgumentValidator(), returnStatement));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generates property assignments for the object initializer in the mapping methods.
|
||||
/// </summary>
|
||||
/// <param name="properties">An <see cref="IEnumerable{T}" /> of properties that are to be included in the initializer.</param>
|
||||
/// <param name="isSource">
|
||||
/// Determines whether the <c>MapAliasAttribute</c> is to be used on the left or right side of
|
||||
/// assignment.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// An <see cref="IEnumerable{T}" /> containing <see cref="SyntaxNodeOrToken" /> instances for property
|
||||
/// assignment.
|
||||
/// </returns>
|
||||
private static IEnumerable<SyntaxNodeOrToken> GeneratePropertyAssignments(IEnumerable<PropertyInfo> properties, bool isSource = true)
|
||||
{
|
||||
return properties.SelectMany(s => new SyntaxNodeOrToken[]
|
||||
{
|
||||
AssignmentExpression(SyntaxKind.SimpleAssignmentExpression,
|
||||
IdentifierName(!isSource ? s.SourcePropertyName : s.TargetPropertyName),
|
||||
MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression,
|
||||
IdentifierName(Source),
|
||||
IdentifierName(isSource ? s.SourcePropertyName : s.TargetPropertyName))),
|
||||
Token(SyntaxKind.CommaToken)
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<!--
|
||||
Source generator projects must target .NET Standard 2.0 as the Roslyn SDK Compiler only supports this version
|
||||
for compiler addons.
|
||||
-->
|
||||
<TargetFramework>netstandard2.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<!-- AnalyzerLanguage is set to cs to denote that only C# is supported by the source generator. -->
|
||||
<AnalyzerLanguage>cs</AnalyzerLanguage>
|
||||
|
||||
<!-- EmitCompilerGeneratedFiles is set to true to ensure that the source generator can emit artifacts. -->
|
||||
<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
|
||||
|
||||
<!-- EnforceExtendedAnalyzerRules is set to true to enable additional rules for analyzers. -->
|
||||
<EnforceExtendedAnalyzerRules>true</EnforceExtendedAnalyzerRules>
|
||||
|
||||
<!-- IsRoslynComponent is set to true to indicate that this project is a Roslyn component. -->
|
||||
<IsRoslynComponent>true</IsRoslynComponent>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<!-- Microsoft.CodeAnalysis.CSharp is required for C# source generators. -->
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.CSharp"/>
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,71 @@
|
||||
// This file is ported and adapted from CommunityToolkit.Mvvm (CommunityToolkit/dotnet)
|
||||
|
||||
namespace MapperSourceGen.SourceGenerator.Model;
|
||||
|
||||
using System.Collections.Immutable;
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.CSharp;
|
||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||
using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory;
|
||||
|
||||
internal partial class HierarchyInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets a <see cref="CompilationUnitSyntax" /> representing the type hierarchy with the specified member declarations.
|
||||
/// </summary>
|
||||
/// <param name="memberDeclarations">
|
||||
/// The <see cref="MemberDeclarationSyntax" /> instances to include in the
|
||||
/// <see cref="CompilationUnitSyntax" />.
|
||||
/// </param>
|
||||
/// <param name="prefix">The prefix to prepend to the file and class name.</param>
|
||||
/// <param name="suffix">The suffix to append to the file and class name.</param>
|
||||
/// <returns>An instance of <see cref="CompilationUnitSyntax" /> used for generating the final output.</returns>
|
||||
public CompilationUnitSyntax GetCompilationUnit(ImmutableArray<MemberDeclarationSyntax> memberDeclarations, string? prefix = null, string? suffix = null)
|
||||
{
|
||||
TypeDeclarationSyntax typeDeclarationSyntax =
|
||||
Hierarchy[0].GetSyntax(prefix, suffix)
|
||||
.AddModifiers(Token(TriviaList(Comment("/// <inheritdoc/>")),
|
||||
Hierarchy[0].AccessibilityKind,
|
||||
TriviaList()))
|
||||
.AddModifiers(GetKeywordModifierTokens(Hierarchy[0]))
|
||||
.AddMembers([.. memberDeclarations])
|
||||
.NormalizeWhitespace();
|
||||
|
||||
foreach ( TypeInfo parentType in Hierarchy.AsSpan().Slice(1) )
|
||||
{
|
||||
typeDeclarationSyntax =
|
||||
parentType.GetSyntax(prefix, suffix)
|
||||
.AddModifiers(Token(TriviaList(Comment("/// <inheritdoc/>")),
|
||||
parentType.AccessibilityKind,
|
||||
TriviaList()))
|
||||
.AddModifiers(GetKeywordModifierTokens(parentType))
|
||||
.AddMembers(typeDeclarationSyntax)
|
||||
.NormalizeWhitespace();
|
||||
}
|
||||
|
||||
SyntaxTriviaList syntaxTriviaList = TriviaList(
|
||||
Comment("// <auto-generated/>"),
|
||||
Trivia(PragmaWarningDirectiveTrivia(Token(SyntaxKind.DisableKeyword), true)),
|
||||
Trivia(NullableDirectiveTrivia(Token(SyntaxKind.EnableKeyword), true)));
|
||||
|
||||
return CompilationUnit()
|
||||
.AddMembers(NamespaceDeclaration(IdentifierName(Namespace))
|
||||
.WithLeadingTrivia(syntaxTriviaList)
|
||||
.AddMembers(typeDeclarationSyntax))
|
||||
.NormalizeWhitespace();
|
||||
}
|
||||
|
||||
private static SyntaxToken[] GetKeywordModifierTokens(TypeInfo typeInfo)
|
||||
{
|
||||
HashSet<SyntaxToken> tokens = [];
|
||||
|
||||
if ( typeInfo.IsSealed )
|
||||
{
|
||||
tokens.Add(Token(SyntaxKind.SealedKeyword));
|
||||
}
|
||||
|
||||
tokens.Add(Token(SyntaxKind.PartialKeyword));
|
||||
|
||||
return [.. tokens];
|
||||
}
|
||||
}
|
||||
115
src/MapperSourceGen.SourceGenerator/Model/HierarchyInfo.cs
Normal file
115
src/MapperSourceGen.SourceGenerator/Model/HierarchyInfo.cs
Normal file
@@ -0,0 +1,115 @@
|
||||
// This file is ported and adapted from CommunityToolkit.Mvvm (CommunityToolkit/dotnet)
|
||||
|
||||
namespace MapperSourceGen.SourceGenerator.Model;
|
||||
|
||||
using System.Collections.Immutable;
|
||||
using Microsoft.CodeAnalysis;
|
||||
using static Microsoft.CodeAnalysis.SymbolDisplayTypeQualificationStyle;
|
||||
|
||||
/// <summary>
|
||||
/// Represents information about a type hierarchy in a source code file.
|
||||
/// </summary>
|
||||
internal sealed partial class HierarchyInfo : IEquatable<HierarchyInfo>
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="HierarchyInfo" /> class.
|
||||
/// </summary>
|
||||
/// <param name="fileNameHint">The filename hint for the type (including namespace) without extension.</param>
|
||||
/// <param name="namespace">The containing namespace for the type.</param>
|
||||
/// <param name="hierarchy">The current hierarchy for the type.</param>
|
||||
/// <exception cref="ArgumentException"><paramref name="fileNameHint" /> is <c>null</c> or empty.</exception>
|
||||
private HierarchyInfo(string fileNameHint, string @namespace, ImmutableArray<TypeInfo> hierarchy)
|
||||
{
|
||||
if ( string.IsNullOrWhiteSpace(fileNameHint) )
|
||||
{
|
||||
throw new ArgumentException($"'{nameof(fileNameHint)}' cannot be null or empty.", nameof(fileNameHint));
|
||||
}
|
||||
|
||||
FileNameHint = fileNameHint;
|
||||
Hierarchy = hierarchy;
|
||||
Namespace = @namespace;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the file name hint (including full namespace) for the type hierarchy.
|
||||
/// </summary>
|
||||
public string FileNameHint { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a collection of <see cref="TypeInfo" /> representing the hierarchy of types.
|
||||
/// </summary>
|
||||
public ImmutableArray<TypeInfo> Hierarchy { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the namespace of the type hierarchy.
|
||||
/// </summary>
|
||||
public string Namespace { get; }
|
||||
|
||||
public static HierarchyInfo From(INamedTypeSymbol typeSymbol)
|
||||
{
|
||||
if ( typeSymbol is null )
|
||||
{
|
||||
throw new ArgumentNullException(nameof(typeSymbol));
|
||||
}
|
||||
|
||||
LinkedList<TypeInfo> hierarchy = [];
|
||||
|
||||
for ( INamedTypeSymbol? parent = typeSymbol;
|
||||
parent is not null;
|
||||
parent = parent.ContainingType )
|
||||
{
|
||||
hierarchy.AddLast(new TypeInfo(parent.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat),
|
||||
parent.TypeKind,
|
||||
parent.DeclaredAccessibility,
|
||||
parent.IsRecord,
|
||||
parent.IsSealed));
|
||||
}
|
||||
|
||||
return new HierarchyInfo(typeSymbol.ToDisplayString(new SymbolDisplayFormat(typeQualificationStyle: NameAndContainingTypesAndNamespaces)),
|
||||
typeSymbol.ContainingNamespace.ToDisplayString(new SymbolDisplayFormat(typeQualificationStyle: NameAndContainingTypesAndNamespaces)),
|
||||
[..hierarchy]);
|
||||
}
|
||||
|
||||
public static bool operator ==(HierarchyInfo? left, HierarchyInfo? right)
|
||||
{
|
||||
return Equals(left, right);
|
||||
}
|
||||
|
||||
public static bool operator !=(HierarchyInfo? left, HierarchyInfo? right)
|
||||
{
|
||||
return !Equals(left, right);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool Equals(HierarchyInfo? other)
|
||||
{
|
||||
if ( other is null )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( ReferenceEquals(this, other) )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return string.Equals(FileNameHint, other.FileNameHint, StringComparison.OrdinalIgnoreCase)
|
||||
&& string.Equals(Namespace, other.Namespace, StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool Equals(object? obj)
|
||||
{
|
||||
return ReferenceEquals(this, obj) || ( obj is HierarchyInfo other && Equals(other) );
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override int GetHashCode()
|
||||
{
|
||||
unchecked
|
||||
{
|
||||
return ( StringComparer.OrdinalIgnoreCase.GetHashCode(FileNameHint) * 397 )
|
||||
^ StringComparer.OrdinalIgnoreCase.GetHashCode(Namespace);
|
||||
}
|
||||
}
|
||||
}
|
||||
105
src/MapperSourceGen.SourceGenerator/Model/PropertyInfo.cs
Normal file
105
src/MapperSourceGen.SourceGenerator/Model/PropertyInfo.cs
Normal file
@@ -0,0 +1,105 @@
|
||||
namespace MapperSourceGen.SourceGenerator.Model;
|
||||
|
||||
using Microsoft.CodeAnalysis;
|
||||
|
||||
/// <summary>
|
||||
/// Represents information about a property in a source code file.
|
||||
/// </summary>
|
||||
internal readonly struct PropertyInfo : IEquatable<PropertyInfo>
|
||||
{
|
||||
private const string MapAliasAttributeName = "MapperSourceGen.MapAliasAttribute";
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="PropertyInfo" /> struct.
|
||||
/// </summary>
|
||||
/// <param name="propertySymbol">instance of <see cref="IPropertySymbol" />.</param>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="propertySymbol" /> is <c>null</c>.</exception>
|
||||
public PropertyInfo(IPropertySymbol propertySymbol)
|
||||
{
|
||||
if ( propertySymbol is null )
|
||||
{
|
||||
throw new ArgumentNullException(nameof(propertySymbol));
|
||||
}
|
||||
|
||||
SourcePropertyName = TargetPropertyName = propertySymbol.Name;
|
||||
|
||||
if ( !propertySymbol.GetAttributes().IsEmpty )
|
||||
{
|
||||
AttributeData? attribute = propertySymbol
|
||||
.GetAttributes()
|
||||
.FirstOrDefault(f => f.AttributeClass?.ToDisplayString() == MapAliasAttributeName);
|
||||
|
||||
if ( attribute is not null )
|
||||
{
|
||||
TargetPropertyName = attribute.ConstructorArguments[0].Value!.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
PropertyType = propertySymbol.Type;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the type of the property.
|
||||
/// </summary>
|
||||
public ITypeSymbol PropertyType { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the name of the source property.
|
||||
/// </summary>
|
||||
public string SourcePropertyName { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the name of the target property (if different from the source).
|
||||
/// </summary>
|
||||
public string TargetPropertyName { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether two <see cref="PropertyInfo" /> instances are equal based on their properties.
|
||||
/// </summary>
|
||||
/// <param name="left">the first instance to compare</param>
|
||||
/// <param name="right">the second instance to compare</param>
|
||||
/// <returns><c>true</c> if both instances are equal, otherwise <c>false</c>.</returns>
|
||||
public static bool operator ==(PropertyInfo left, PropertyInfo right)
|
||||
{
|
||||
return left.Equals(right);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether two <see cref="PropertyInfo" /> instances are not equal based on their properties.
|
||||
/// </summary>
|
||||
/// <param name="left">the first instance to compare</param>
|
||||
/// <param name="right">the second instance to compare</param>
|
||||
/// <returns><c>true</c> if both instances are not equal, otherwise <c>false</c>.</returns>
|
||||
public static bool operator !=(PropertyInfo left, PropertyInfo right)
|
||||
{
|
||||
return !left.Equals(right);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool Equals(PropertyInfo other)
|
||||
{
|
||||
return SymbolEqualityComparer.Default.Equals(PropertyType, other.PropertyType)
|
||||
&& string.Equals(SourcePropertyName, other.SourcePropertyName, StringComparison.OrdinalIgnoreCase)
|
||||
&& string.Equals(TargetPropertyName, other.TargetPropertyName, StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool Equals(object? obj)
|
||||
{
|
||||
return obj is PropertyInfo other && Equals(other);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override int GetHashCode()
|
||||
{
|
||||
unchecked
|
||||
{
|
||||
int hashCode = SymbolEqualityComparer.Default.GetHashCode(PropertyType);
|
||||
|
||||
hashCode = ( hashCode * 397 ) ^ StringComparer.OrdinalIgnoreCase.GetHashCode(SourcePropertyName);
|
||||
hashCode = ( hashCode * 397 ) ^ StringComparer.OrdinalIgnoreCase.GetHashCode(TargetPropertyName);
|
||||
|
||||
return hashCode;
|
||||
}
|
||||
}
|
||||
}
|
||||
48
src/MapperSourceGen.SourceGenerator/Model/TypeInfo.cs
Normal file
48
src/MapperSourceGen.SourceGenerator/Model/TypeInfo.cs
Normal file
@@ -0,0 +1,48 @@
|
||||
// This file is ported and adapted from CommunityToolkit.Mvvm (CommunityToolkit/dotnet)
|
||||
|
||||
namespace MapperSourceGen.SourceGenerator.Model;
|
||||
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.CSharp;
|
||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||
using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory;
|
||||
|
||||
internal sealed record TypeInfo(
|
||||
string QualifiedName,
|
||||
TypeKind Kind,
|
||||
Accessibility DeclaredAccessibility,
|
||||
bool IsRecord,
|
||||
bool IsSealed)
|
||||
{
|
||||
public SyntaxKind AccessibilityKind =>
|
||||
DeclaredAccessibility switch
|
||||
{
|
||||
Accessibility.Public => SyntaxKind.PublicKeyword,
|
||||
Accessibility.Internal => SyntaxKind.InternalKeyword,
|
||||
Accessibility.Private => SyntaxKind.PrivateKeyword,
|
||||
Accessibility.Protected => SyntaxKind.ProtectedKeyword,
|
||||
_ => SyntaxKind.None
|
||||
};
|
||||
|
||||
public Accessibility DeclaredAccessibility { get; } = DeclaredAccessibility;
|
||||
|
||||
public bool IsRecord { get; } = IsRecord;
|
||||
|
||||
public bool IsSealed { get; } = IsSealed;
|
||||
|
||||
public TypeKind Kind { get; } = Kind;
|
||||
|
||||
public string QualifiedName { get; } = QualifiedName;
|
||||
|
||||
public TypeDeclarationSyntax GetSyntax(string? prefix = null, string? suffix = null)
|
||||
{
|
||||
return Kind switch
|
||||
{
|
||||
TypeKind.Class when IsRecord =>
|
||||
RecordDeclaration(Token(SyntaxKind.RecordKeyword), $"{prefix}{QualifiedName}{suffix}")
|
||||
.WithOpenBraceToken(Token(SyntaxKind.OpenBraceToken))
|
||||
.WithCloseBraceToken(Token(SyntaxKind.CloseBraceToken)),
|
||||
_ => ClassDeclaration($"{prefix}{QualifiedName}{suffix}")
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"$schema": "http://json.schemastore.org/launchsettings.json",
|
||||
"profiles": {
|
||||
"SourceGenerator": {
|
||||
"commandName": "DebugRoslynComponent",
|
||||
"targetProject": "../../sample/MapperSourceGen.Sample/MapperSourceGen.Sample.csproj"
|
||||
}
|
||||
}
|
||||
}
|
||||
121
src/MapperSourceGen.SourceGenerator/packages.lock.json
Normal file
121
src/MapperSourceGen.SourceGenerator/packages.lock.json
Normal file
@@ -0,0 +1,121 @@
|
||||
{
|
||||
"version": 2,
|
||||
"dependencies": {
|
||||
".NETStandard,Version=v2.0": {
|
||||
"Microsoft.CodeAnalysis.CSharp": {
|
||||
"type": "Direct",
|
||||
"requested": "[4.11.0, 4.11.0]",
|
||||
"resolved": "4.11.0",
|
||||
"contentHash": "6XYi2EusI8JT4y2l/F3VVVS+ISoIX9nqHsZRaG6W5aFeJ5BEuBosHfT/ABb73FN0RZ1Z3cj2j7cL28SToJPXOw==",
|
||||
"dependencies": {
|
||||
"Microsoft.CodeAnalysis.Analyzers": "3.3.4",
|
||||
"Microsoft.CodeAnalysis.Common": "[4.11.0]",
|
||||
"System.Buffers": "4.5.1",
|
||||
"System.Collections.Immutable": "8.0.0",
|
||||
"System.Memory": "4.5.5",
|
||||
"System.Numerics.Vectors": "4.5.0",
|
||||
"System.Reflection.Metadata": "8.0.0",
|
||||
"System.Runtime.CompilerServices.Unsafe": "6.0.0",
|
||||
"System.Text.Encoding.CodePages": "7.0.0",
|
||||
"System.Threading.Tasks.Extensions": "4.5.4"
|
||||
}
|
||||
},
|
||||
"NETStandard.Library": {
|
||||
"type": "Direct",
|
||||
"requested": "[2.0.3, )",
|
||||
"resolved": "2.0.3",
|
||||
"contentHash": "st47PosZSHrjECdjeIzZQbzivYBJFv6P2nv4cj2ypdI204DO+vZ7l5raGMiX4eXMJ53RfOIg+/s4DHVZ54Nu2A==",
|
||||
"dependencies": {
|
||||
"Microsoft.NETCore.Platforms": "1.1.0"
|
||||
}
|
||||
},
|
||||
"Microsoft.CodeAnalysis.Analyzers": {
|
||||
"type": "Transitive",
|
||||
"resolved": "3.3.4",
|
||||
"contentHash": "AxkxcPR+rheX0SmvpLVIGLhOUXAKG56a64kV9VQZ4y9gR9ZmPXnqZvHJnmwLSwzrEP6junUF11vuc+aqo5r68g=="
|
||||
},
|
||||
"Microsoft.NETCore.Platforms": {
|
||||
"type": "Transitive",
|
||||
"resolved": "1.1.0",
|
||||
"contentHash": "kz0PEW2lhqygehI/d6XsPCQzD7ff7gUJaVGPVETX611eadGsA3A877GdSlU0LRVMCTH/+P3o2iDTak+S08V2+A=="
|
||||
},
|
||||
"System.Buffers": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.5.1",
|
||||
"contentHash": "Rw7ijyl1qqRS0YQD/WycNst8hUUMgrMH4FCn1nNm27M4VxchZ1js3fVjQaANHO5f3sN4isvP4a+Met9Y4YomAg=="
|
||||
},
|
||||
"System.Collections.Immutable": {
|
||||
"type": "Transitive",
|
||||
"resolved": "8.0.0",
|
||||
"contentHash": "AurL6Y5BA1WotzlEvVaIDpqzpIPvYnnldxru8oXJU2yFxFUy3+pNXjXd1ymO+RA0rq0+590Q8gaz2l3Sr7fmqg==",
|
||||
"dependencies": {
|
||||
"System.Memory": "4.5.5",
|
||||
"System.Runtime.CompilerServices.Unsafe": "6.0.0"
|
||||
}
|
||||
},
|
||||
"System.Memory": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.5.5",
|
||||
"contentHash": "XIWiDvKPXaTveaB7HVganDlOCRoj03l+jrwNvcge/t8vhGYKvqV+dMv6G4SAX2NoNmN0wZfVPTAlFwZcZvVOUw==",
|
||||
"dependencies": {
|
||||
"System.Buffers": "4.5.1",
|
||||
"System.Numerics.Vectors": "4.4.0",
|
||||
"System.Runtime.CompilerServices.Unsafe": "4.5.3"
|
||||
}
|
||||
},
|
||||
"System.Numerics.Vectors": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.5.0",
|
||||
"contentHash": "QQTlPTl06J/iiDbJCiepZ4H//BVraReU4O4EoRw1U02H5TLUIT7xn3GnDp9AXPSlJUDyFs4uWjWafNX6WrAojQ=="
|
||||
},
|
||||
"System.Reflection.Metadata": {
|
||||
"type": "Transitive",
|
||||
"resolved": "8.0.0",
|
||||
"contentHash": "ptvgrFh7PvWI8bcVqG5rsA/weWM09EnthFHR5SCnS6IN+P4mj6rE1lBDC4U8HL9/57htKAqy4KQ3bBj84cfYyQ==",
|
||||
"dependencies": {
|
||||
"System.Collections.Immutable": "8.0.0",
|
||||
"System.Memory": "4.5.5"
|
||||
}
|
||||
},
|
||||
"System.Runtime.CompilerServices.Unsafe": {
|
||||
"type": "Transitive",
|
||||
"resolved": "6.0.0",
|
||||
"contentHash": "/iUeP3tq1S0XdNNoMz5C9twLSrM/TH+qElHkXWaPvuNOt+99G75NrV0OS2EqHx5wMN7popYjpc8oTjC1y16DLg=="
|
||||
},
|
||||
"System.Text.Encoding.CodePages": {
|
||||
"type": "Transitive",
|
||||
"resolved": "7.0.0",
|
||||
"contentHash": "LSyCblMpvOe0N3E+8e0skHcrIhgV2huaNcjUUEa8hRtgEAm36aGkRoC8Jxlb6Ra6GSfF29ftduPNywin8XolzQ==",
|
||||
"dependencies": {
|
||||
"System.Memory": "4.5.5",
|
||||
"System.Runtime.CompilerServices.Unsafe": "6.0.0"
|
||||
}
|
||||
},
|
||||
"System.Threading.Tasks.Extensions": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.5.4",
|
||||
"contentHash": "zteT+G8xuGu6mS+mzDzYXbzS7rd3K6Fjb9RiZlYlJPam2/hU7JCBZBVEcywNuR+oZ1ncTvc/cq0faRr3P01OVg==",
|
||||
"dependencies": {
|
||||
"System.Runtime.CompilerServices.Unsafe": "4.5.3"
|
||||
}
|
||||
},
|
||||
"Microsoft.CodeAnalysis.Common": {
|
||||
"type": "CentralTransitive",
|
||||
"requested": "[4.11.0, )",
|
||||
"resolved": "4.11.0",
|
||||
"contentHash": "djf8ujmqYImFgB04UGtcsEhHrzVqzHowS+EEl/Yunc5LdrYrZhGBWUTXoCF0NzYXJxtfuD+UVQarWpvrNc94Qg==",
|
||||
"dependencies": {
|
||||
"Microsoft.CodeAnalysis.Analyzers": "3.3.4",
|
||||
"System.Buffers": "4.5.1",
|
||||
"System.Collections.Immutable": "8.0.0",
|
||||
"System.Memory": "4.5.5",
|
||||
"System.Numerics.Vectors": "4.5.0",
|
||||
"System.Reflection.Metadata": "8.0.0",
|
||||
"System.Runtime.CompilerServices.Unsafe": "6.0.0",
|
||||
"System.Text.Encoding.CodePages": "7.0.0",
|
||||
"System.Threading.Tasks.Extensions": "4.5.4"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
27
src/MapperSourceGen/MapAliasAttribute.cs
Normal file
27
src/MapperSourceGen/MapAliasAttribute.cs
Normal file
@@ -0,0 +1,27 @@
|
||||
namespace MapperSourceGen;
|
||||
|
||||
/// <summary>
|
||||
/// Specifies that the target property should appear in the domain transfer object with a different name.
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Property)]
|
||||
public sealed class MapAliasAttribute : Attribute
|
||||
{
|
||||
private MapAliasAttribute()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="MapAliasAttribute" /> class with the specified name.
|
||||
/// </summary>
|
||||
/// <param name="name">The name to use instead of the property name.</param>
|
||||
public MapAliasAttribute(string name)
|
||||
{
|
||||
ArgumentException.ThrowIfNullOrWhiteSpace(name);
|
||||
Name = name;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The name of the property in the domain transfer object.
|
||||
/// </summary>
|
||||
public string? Name { get; }
|
||||
}
|
||||
9
src/MapperSourceGen/MapIgnoreAttribute.cs
Normal file
9
src/MapperSourceGen/MapIgnoreAttribute.cs
Normal file
@@ -0,0 +1,9 @@
|
||||
namespace MapperSourceGen;
|
||||
|
||||
/// <summary>
|
||||
/// Specifies that the target property should not be included in the domain transfer object or mapper.
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Property)]
|
||||
public sealed class MapIgnoreAttribute : Attribute
|
||||
{
|
||||
}
|
||||
9
src/MapperSourceGen/MapperAttribute.cs
Normal file
9
src/MapperSourceGen/MapperAttribute.cs
Normal file
@@ -0,0 +1,9 @@
|
||||
namespace MapperSourceGen;
|
||||
|
||||
/// <summary>
|
||||
/// Specifies that the target class is a candidate for DTO and mapper generation.
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Class)]
|
||||
public sealed class MapperAttribute : Attribute
|
||||
{
|
||||
}
|
||||
19
src/MapperSourceGen/MapperSourceGen.csproj
Normal file
19
src/MapperSourceGen/MapperSourceGen.csproj
Normal file
@@ -0,0 +1,19 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<!--
|
||||
When referencing a source generator that is to part of the nuget package as an analyzer, ensure that the following properties are set:
|
||||
|
||||
- ReferenceOutputAssembly="false" to prevent the source generator from being treated as a regular assembly.
|
||||
- PackAsAnalyzer="true" to include the source generator as an analyzer in the NuGet package.
|
||||
-->
|
||||
<ProjectReference Include="..\MapperSourceGen.SourceGenerator\MapperSourceGen.SourceGenerator.csproj"
|
||||
ReferenceOutputAssembly="false"
|
||||
PackAsAnalyzer="true"/>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
6
src/MapperSourceGen/packages.lock.json
Normal file
6
src/MapperSourceGen/packages.lock.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"version": 2,
|
||||
"dependencies": {
|
||||
"net8.0": {}
|
||||
}
|
||||
}
|
||||
9
tests/.editorconfig
Normal file
9
tests/.editorconfig
Normal file
@@ -0,0 +1,9 @@
|
||||
# C# files
|
||||
[*.cs]
|
||||
|
||||
#### C# Coding Conventions ####
|
||||
|
||||
# var preferences
|
||||
csharp_style_var_elsewhere = true:suggestion
|
||||
csharp_style_var_for_built_in_types = true:suggestion
|
||||
csharp_style_var_when_type_is_apparent = true:suggestion
|
||||
16
tests/Directory.Build.props
Normal file
16
tests/Directory.Build.props
Normal file
@@ -0,0 +1,16 @@
|
||||
<Project>
|
||||
<PropertyGroup>
|
||||
<IsPackable>false</IsPackable>
|
||||
<GenerateDocumentationFile>false</GenerateDocumentationFile>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>true</ImplicitUsings>
|
||||
<IsPackable>false</IsPackable>
|
||||
<RestorePackagesWithLockFile>true</RestorePackagesWithLockFile>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(CI)' == 'true'">
|
||||
<ContinuousIntegrationBuild>true</ContinuousIntegrationBuild>
|
||||
<RestoreLockedMode>true</RestoreLockedMode>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
||||
16
tests/MapperSourceGen.SourceGenerator.Tests/Constants.cs
Normal file
16
tests/MapperSourceGen.SourceGenerator.Tests/Constants.cs
Normal file
@@ -0,0 +1,16 @@
|
||||
namespace MapperSourceGen.SourceGenerator.Tests;
|
||||
|
||||
internal static class Constants
|
||||
{
|
||||
public const string AutoGeneratedStatement = """
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
""";
|
||||
}
|
||||
39
tests/MapperSourceGen.SourceGenerator.Tests/Fixture.cs
Normal file
39
tests/MapperSourceGen.SourceGenerator.Tests/Fixture.cs
Normal file
@@ -0,0 +1,39 @@
|
||||
namespace MapperSourceGen.SourceGenerator.Tests;
|
||||
|
||||
using System.Reflection;
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.CSharp;
|
||||
|
||||
internal static class Fixture
|
||||
{
|
||||
private static readonly Type[] RequiredAssemblies =
|
||||
[
|
||||
typeof(Binder),
|
||||
typeof(MapperAttribute)
|
||||
];
|
||||
|
||||
private static IEnumerable<MetadataReference> AssemblyReferencesForCodeGen =>
|
||||
AppDomain.CurrentDomain
|
||||
.GetAssemblies()
|
||||
.Concat(RequiredAssemblies.Select(s => s.Assembly))
|
||||
.Distinct()
|
||||
.Where(w => !w.IsDynamic)
|
||||
.Select(s => MetadataReference.CreateFromFile(s.Location));
|
||||
|
||||
public static Task VerifyGenerateSourcesAsync(string source, params IIncrementalGenerator[] generators)
|
||||
{
|
||||
var syntaxTree = CSharpSyntaxTree.ParseText(source, CSharpParseOptions.Default);
|
||||
|
||||
var compilation = CSharpCompilation.Create(
|
||||
"compilation",
|
||||
[syntaxTree],
|
||||
AssemblyReferencesForCodeGen,
|
||||
new CSharpCompilationOptions(OutputKind.ConsoleApplication));
|
||||
|
||||
var driver = CSharpGeneratorDriver.Create(generators);
|
||||
var runner = driver.RunGenerators(compilation);
|
||||
var verify = Verify(runner);
|
||||
|
||||
return verify;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
namespace MapperSourceGen.SourceGenerator.Tests;
|
||||
|
||||
public sealed class MapperGeneratorFacts
|
||||
{
|
||||
[Fact]
|
||||
public Task Should_Emit_Dto_And_Mapper()
|
||||
{
|
||||
const string source = """
|
||||
namespace MapperSourceGen.SourceGenerator.Tests;
|
||||
|
||||
[Mapper]
|
||||
partial class MyEntity
|
||||
{
|
||||
public int Id { get; set; }
|
||||
}
|
||||
""";
|
||||
|
||||
return Fixture.VerifyGenerateSourcesAsync(source, new MapperGenerator());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<IsTestProject>true</IsTestProject>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="coverlet.collector">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="coverlet.msbuild">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="JunitXml.TestLogger" />
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.Common" />
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" />
|
||||
<PackageReference Include="Verify.DiffPlex" />
|
||||
<PackageReference Include="Verify.SourceGenerators" />
|
||||
<PackageReference Include="Verify.Xunit" />
|
||||
<PackageReference Include="xunit" />
|
||||
<PackageReference Include="xunit.runner.visualstudio">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Using Include="Xunit"/>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\src\MapperSourceGen\MapperSourceGen.csproj"/>
|
||||
|
||||
<!--
|
||||
When referencing a source generator that is part of the solution for tests, ensure that the following properties are set:
|
||||
|
||||
- OutputItemType="Analyzer" to treat it as an analyzer.
|
||||
- SetTargetFramework="TargetFramework=netstandard2.0" to ensure compatibility with the source generator.
|
||||
-->
|
||||
<ProjectReference Include="..\..\src\MapperSourceGen.SourceGenerator\MapperSourceGen.SourceGenerator.csproj"
|
||||
OutputItemType="Analyzer"
|
||||
SetTargetFramework="TargetFramework=netstandard2.0"/>
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,18 @@
|
||||
namespace MapperSourceGen.SourceGenerator.Tests;
|
||||
|
||||
using System.Runtime.CompilerServices;
|
||||
using VerifyTests.DiffPlex;
|
||||
|
||||
public static class ModuleInitializer
|
||||
{
|
||||
#pragma warning disable CA2255
|
||||
[ModuleInitializer]
|
||||
#pragma warning restore CA2255
|
||||
public static void Initialize()
|
||||
{
|
||||
DerivePathInfo((file, _, type, method) => new PathInfo(Path.Combine(Path.GetDirectoryName(file)!, "ref"), type.Name, method.Name));
|
||||
|
||||
VerifySourceGenerators.Initialize();
|
||||
VerifyDiffPlex.Initialize(OutputType.Compact);
|
||||
}
|
||||
}
|
||||
254
tests/MapperSourceGen.SourceGenerator.Tests/packages.lock.json
Normal file
254
tests/MapperSourceGen.SourceGenerator.Tests/packages.lock.json
Normal file
@@ -0,0 +1,254 @@
|
||||
{
|
||||
"version": 2,
|
||||
"dependencies": {
|
||||
"net8.0": {
|
||||
"coverlet.collector": {
|
||||
"type": "Direct",
|
||||
"requested": "[6.0.4, )",
|
||||
"resolved": "6.0.4",
|
||||
"contentHash": "lkhqpF8Pu2Y7IiN7OntbsTtdbpR1syMsm2F3IgX6ootA4ffRqWL5jF7XipHuZQTdVuWG/gVAAcf8mjk8Tz0xPg=="
|
||||
},
|
||||
"coverlet.msbuild": {
|
||||
"type": "Direct",
|
||||
"requested": "[6.0.4, )",
|
||||
"resolved": "6.0.4",
|
||||
"contentHash": "Qa7Hg+wrOMDKpXVn2dw4Wlun490bIWsFW0fdNJQFJLZnbU27MCP0HJ2mPgS+3EQBQUb0zKlkwiQzP+j38Hc3Iw=="
|
||||
},
|
||||
"JunitXml.TestLogger": {
|
||||
"type": "Direct",
|
||||
"requested": "[6.1.0, )",
|
||||
"resolved": "6.1.0",
|
||||
"contentHash": "a3ciawoHOzqcry7yS5z9DerNyF9QZi6fEZZJPILSy6Noj6+r8Ydma+cENA6wvivXDCblpXxw72wWT9QApNy/0w=="
|
||||
},
|
||||
"Microsoft.CodeAnalysis.Common": {
|
||||
"type": "Direct",
|
||||
"requested": "[4.11.0, )",
|
||||
"resolved": "4.11.0",
|
||||
"contentHash": "djf8ujmqYImFgB04UGtcsEhHrzVqzHowS+EEl/Yunc5LdrYrZhGBWUTXoCF0NzYXJxtfuD+UVQarWpvrNc94Qg==",
|
||||
"dependencies": {
|
||||
"Microsoft.CodeAnalysis.Analyzers": "3.3.4",
|
||||
"System.Collections.Immutable": "8.0.0",
|
||||
"System.Reflection.Metadata": "8.0.0"
|
||||
}
|
||||
},
|
||||
"Microsoft.CodeAnalysis.CSharp": {
|
||||
"type": "Direct",
|
||||
"requested": "[4.11.0, 4.11.0]",
|
||||
"resolved": "4.11.0",
|
||||
"contentHash": "6XYi2EusI8JT4y2l/F3VVVS+ISoIX9nqHsZRaG6W5aFeJ5BEuBosHfT/ABb73FN0RZ1Z3cj2j7cL28SToJPXOw==",
|
||||
"dependencies": {
|
||||
"Microsoft.CodeAnalysis.Analyzers": "3.3.4",
|
||||
"Microsoft.CodeAnalysis.Common": "[4.11.0]",
|
||||
"System.Collections.Immutable": "8.0.0",
|
||||
"System.Reflection.Metadata": "8.0.0"
|
||||
}
|
||||
},
|
||||
"Microsoft.NET.Test.Sdk": {
|
||||
"type": "Direct",
|
||||
"requested": "[17.14.1, )",
|
||||
"resolved": "17.14.1",
|
||||
"contentHash": "HJKqKOE+vshXra2aEHpi2TlxYX7Z9VFYkr+E5rwEvHC8eIXiyO+K9kNm8vmNom3e2rA56WqxU+/N9NJlLGXsJQ==",
|
||||
"dependencies": {
|
||||
"Microsoft.CodeCoverage": "17.14.1",
|
||||
"Microsoft.TestPlatform.TestHost": "17.14.1"
|
||||
}
|
||||
},
|
||||
"Verify.DiffPlex": {
|
||||
"type": "Direct",
|
||||
"requested": "[3.1.2, )",
|
||||
"resolved": "3.1.2",
|
||||
"contentHash": "ySaQ+MffcDfGWzBXB9UHppEGBqzl0L+2CxZcT04xQ3gugsN5AAjBPHkt75Ca61PlAeZCyty/p/Q9ZwaQjNOoTg==",
|
||||
"dependencies": {
|
||||
"DiffPlex": "1.7.2",
|
||||
"Verify": "27.0.0"
|
||||
}
|
||||
},
|
||||
"Verify.SourceGenerators": {
|
||||
"type": "Direct",
|
||||
"requested": "[2.5.0, )",
|
||||
"resolved": "2.5.0",
|
||||
"contentHash": "XhAg+fJDPXDH7Ajv/J4Hv8ls0zoeK0LqjZIiOT+quwxOqdplcTuqdPx1+4p1qvYzpTdwkLxyGiIA76MzCljyAQ==",
|
||||
"dependencies": {
|
||||
"Verify": "26.5.0"
|
||||
}
|
||||
},
|
||||
"Verify.Xunit": {
|
||||
"type": "Direct",
|
||||
"requested": "[30.5.0, )",
|
||||
"resolved": "30.5.0",
|
||||
"contentHash": "S+vPvbWgcZSR/eF5O8OAlz8uXhB2Dr2uKjUKbPLa9FtC5ay0hueYGzKshHmRZJ1jay88VE1Kd2ECPNhb8p3Uyg==",
|
||||
"dependencies": {
|
||||
"Argon": "0.30.1",
|
||||
"DiffEngine": "16.2.3",
|
||||
"SimpleInfoName": "3.1.2",
|
||||
"Verify": "30.5.0",
|
||||
"xunit.abstractions": "2.0.3",
|
||||
"xunit.extensibility.execution": "2.9.3"
|
||||
}
|
||||
},
|
||||
"xunit": {
|
||||
"type": "Direct",
|
||||
"requested": "[2.9.3, )",
|
||||
"resolved": "2.9.3",
|
||||
"contentHash": "TlXQBinK35LpOPKHAqbLY4xlEen9TBafjs0V5KnA4wZsoQLQJiirCR4CbIXvOH8NzkW4YeJKP5P/Bnrodm0h9Q==",
|
||||
"dependencies": {
|
||||
"xunit.analyzers": "1.18.0",
|
||||
"xunit.assert": "2.9.3",
|
||||
"xunit.core": "[2.9.3]"
|
||||
}
|
||||
},
|
||||
"xunit.runner.visualstudio": {
|
||||
"type": "Direct",
|
||||
"requested": "[3.1.3, )",
|
||||
"resolved": "3.1.3",
|
||||
"contentHash": "go7e81n/UI3LeNqoJIJ3thkS4JfJtiQnDbAxLh09JkJqoHthnfbLS5p68s4/Bm12B9umkoYSB5SaDr68hZNleg=="
|
||||
},
|
||||
"Argon": {
|
||||
"type": "Transitive",
|
||||
"resolved": "0.30.1",
|
||||
"contentHash": "kjKnBzxJ1Xp4Sh9B7inrP1YjefXH4X8hV4/J5EoDKloog09Kp4KUVoJS8xxYfUbUzJ+Xe5PKZm3hj5pi4ZuCZw=="
|
||||
},
|
||||
"DiffEngine": {
|
||||
"type": "Transitive",
|
||||
"resolved": "16.2.3",
|
||||
"contentHash": "QWnG0MR3//Ss0G0N9mIfe1HLOrOIRZqau0AOiLt9Gm53ZQf/TLvzoccTkczEW5ACkbhRY5m+p+W7bzFVln2GDw==",
|
||||
"dependencies": {
|
||||
"EmptyFiles": "8.10.1",
|
||||
"System.Management": "8.0.0"
|
||||
}
|
||||
},
|
||||
"DiffPlex": {
|
||||
"type": "Transitive",
|
||||
"resolved": "1.7.2",
|
||||
"contentHash": "qJEjdxEDBWSFZGB8paBB9HDeJXHGlHlOXeGX3kbTuXWuOsgv2iSAEOOzo5V1/B39Vcxr9IVVrNKewRcX+rsn4g=="
|
||||
},
|
||||
"EmptyFiles": {
|
||||
"type": "Transitive",
|
||||
"resolved": "8.10.1",
|
||||
"contentHash": "vhLPAqdKuo2qjVkrJbCyacGXO9XTha7G1R5amw44m877FDR/gqFjCfdncj8VyHAC6eNqrCXgYTbHJGO5+l3TJg=="
|
||||
},
|
||||
"Microsoft.CodeAnalysis.Analyzers": {
|
||||
"type": "Transitive",
|
||||
"resolved": "3.3.4",
|
||||
"contentHash": "AxkxcPR+rheX0SmvpLVIGLhOUXAKG56a64kV9VQZ4y9gR9ZmPXnqZvHJnmwLSwzrEP6junUF11vuc+aqo5r68g=="
|
||||
},
|
||||
"Microsoft.CodeCoverage": {
|
||||
"type": "Transitive",
|
||||
"resolved": "17.14.1",
|
||||
"contentHash": "pmTrhfFIoplzFVbhVwUquT+77CbGH+h4/3mBpdmIlYtBi9nAB+kKI6dN3A/nV4DFi3wLLx/BlHIPK+MkbQ6Tpg=="
|
||||
},
|
||||
"Microsoft.TestPlatform.ObjectModel": {
|
||||
"type": "Transitive",
|
||||
"resolved": "17.14.1",
|
||||
"contentHash": "xTP1W6Mi6SWmuxd3a+jj9G9UoC850WGwZUps1Wah9r1ZxgXhdJfj1QqDLJkFjHDCvN42qDL2Ps5KjQYWUU0zcQ==",
|
||||
"dependencies": {
|
||||
"System.Reflection.Metadata": "8.0.0"
|
||||
}
|
||||
},
|
||||
"Microsoft.TestPlatform.TestHost": {
|
||||
"type": "Transitive",
|
||||
"resolved": "17.14.1",
|
||||
"contentHash": "d78LPzGKkJwsJXAQwsbJJ7LE7D1wB+rAyhHHAaODF+RDSQ0NgMjDFkSA1Djw18VrxO76GlKAjRUhl+H8NL8Z+Q==",
|
||||
"dependencies": {
|
||||
"Microsoft.TestPlatform.ObjectModel": "17.14.1",
|
||||
"Newtonsoft.Json": "13.0.3"
|
||||
}
|
||||
},
|
||||
"Newtonsoft.Json": {
|
||||
"type": "Transitive",
|
||||
"resolved": "13.0.3",
|
||||
"contentHash": "HrC5BXdl00IP9zeV+0Z848QWPAoCr9P3bDEZguI+gkLcBKAOxix/tLEAAHC+UvDNPv4a2d18lOReHMOagPa+zQ=="
|
||||
},
|
||||
"SimpleInfoName": {
|
||||
"type": "Transitive",
|
||||
"resolved": "3.1.2",
|
||||
"contentHash": "/OoEZQxSW6DeTJ9nfrg8BLCOCWpxBiWHV4NkG3t+Xpe8tvzm7yCwKwxkhpauMl3fg9OjlIjJMKX61H6VavLkrw=="
|
||||
},
|
||||
"System.CodeDom": {
|
||||
"type": "Transitive",
|
||||
"resolved": "8.0.0",
|
||||
"contentHash": "WTlRjL6KWIMr/pAaq3rYqh0TJlzpouaQ/W1eelssHgtlwHAH25jXTkUphTYx9HaIIf7XA6qs/0+YhtLEQRkJ+Q=="
|
||||
},
|
||||
"System.Collections.Immutable": {
|
||||
"type": "Transitive",
|
||||
"resolved": "8.0.0",
|
||||
"contentHash": "AurL6Y5BA1WotzlEvVaIDpqzpIPvYnnldxru8oXJU2yFxFUy3+pNXjXd1ymO+RA0rq0+590Q8gaz2l3Sr7fmqg=="
|
||||
},
|
||||
"System.Management": {
|
||||
"type": "Transitive",
|
||||
"resolved": "8.0.0",
|
||||
"contentHash": "jrK22i5LRzxZCfGb+tGmke2VH7oE0DvcDlJ1HAKYU8cPmD8XnpUT0bYn2Gy98GEhGjtfbR/sxKTVb+dE770pfA==",
|
||||
"dependencies": {
|
||||
"System.CodeDom": "8.0.0"
|
||||
}
|
||||
},
|
||||
"System.Reflection.Metadata": {
|
||||
"type": "Transitive",
|
||||
"resolved": "8.0.0",
|
||||
"contentHash": "ptvgrFh7PvWI8bcVqG5rsA/weWM09EnthFHR5SCnS6IN+P4mj6rE1lBDC4U8HL9/57htKAqy4KQ3bBj84cfYyQ==",
|
||||
"dependencies": {
|
||||
"System.Collections.Immutable": "8.0.0"
|
||||
}
|
||||
},
|
||||
"Verify": {
|
||||
"type": "Transitive",
|
||||
"resolved": "30.5.0",
|
||||
"contentHash": "AO3l7Rmw8Ry8rpVMQ98Q3MVO2G0KGiXlxyOPAYuE7NeN33JzNLJSjri/fMQDo3sm4aIwBjWbomssy2EbyJBdrg==",
|
||||
"dependencies": {
|
||||
"Argon": "0.30.1",
|
||||
"DiffEngine": "16.2.3",
|
||||
"SimpleInfoName": "3.1.2"
|
||||
}
|
||||
},
|
||||
"xunit.abstractions": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.0.3",
|
||||
"contentHash": "pot1I4YOxlWjIb5jmwvvQNbTrZ3lJQ+jUGkGjWE3hEFM0l5gOnBWS+H3qsex68s5cO52g+44vpGzhAt+42vwKg=="
|
||||
},
|
||||
"xunit.analyzers": {
|
||||
"type": "Transitive",
|
||||
"resolved": "1.18.0",
|
||||
"contentHash": "OtFMHN8yqIcYP9wcVIgJrq01AfTxijjAqVDy/WeQVSyrDC1RzBWeQPztL49DN2syXRah8TYnfvk035s7L95EZQ=="
|
||||
},
|
||||
"xunit.assert": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.9.3",
|
||||
"contentHash": "/Kq28fCE7MjOV42YLVRAJzRF0WmEqsmflm0cfpMjGtzQ2lR5mYVj1/i0Y8uDAOLczkL3/jArrwehfMD0YogMAA=="
|
||||
},
|
||||
"xunit.core": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.9.3",
|
||||
"contentHash": "BiAEvqGvyme19wE0wTKdADH+NloYqikiU0mcnmiNyXaF9HyHmE6sr/3DC5vnBkgsWaE6yPyWszKSPSApWdRVeQ==",
|
||||
"dependencies": {
|
||||
"xunit.extensibility.core": "[2.9.3]",
|
||||
"xunit.extensibility.execution": "[2.9.3]"
|
||||
}
|
||||
},
|
||||
"xunit.extensibility.core": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.9.3",
|
||||
"contentHash": "kf3si0YTn2a8J8eZNb+zFpwfoyvIrQ7ivNk5ZYA5yuYk1bEtMe4DxJ2CF/qsRgmEnDr7MnW1mxylBaHTZ4qErA==",
|
||||
"dependencies": {
|
||||
"xunit.abstractions": "2.0.3"
|
||||
}
|
||||
},
|
||||
"xunit.extensibility.execution": {
|
||||
"type": "Transitive",
|
||||
"resolved": "2.9.3",
|
||||
"contentHash": "yMb6vMESlSrE3Wfj7V6cjQ3S4TXdXpRqYeNEI3zsX31uTsGMJjEw6oD5F5u1cHnMptjhEECnmZSsPxB6ChZHDQ==",
|
||||
"dependencies": {
|
||||
"xunit.extensibility.core": "[2.9.3]"
|
||||
}
|
||||
},
|
||||
"mappersourcegen": {
|
||||
"type": "Project"
|
||||
},
|
||||
"mappersourcegen.sourcegenerator": {
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Microsoft.CodeAnalysis.CSharp": "[4.11.0, 4.11.0]"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
//HintName: MapperSourceGen.SourceGenerator.Tests.MyEntityDto.g.cs
|
||||
// <auto-generated/>
|
||||
#pragma warning disable
|
||||
#nullable enable
|
||||
namespace MapperSourceGen.SourceGenerator.Tests
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
internal partial class MyEntityDto
|
||||
{
|
||||
public int Id { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
//HintName: MapperSourceGen.SourceGenerator.Tests.MyEntityMapper.g.cs
|
||||
// <auto-generated/>
|
||||
#pragma warning disable
|
||||
#nullable enable
|
||||
namespace MapperSourceGen.SourceGenerator.Tests
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
internal partial class MyEntityMapper
|
||||
{
|
||||
public static MapperSourceGen.SourceGenerator.Tests.MyEntity ToModel(MapperSourceGen.SourceGenerator.Tests.MyEntityDto source)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(nameof(source));
|
||||
return new MapperSourceGen.SourceGenerator.Tests.MyEntity()
|
||||
{
|
||||
Id = source.Id,
|
||||
};
|
||||
}
|
||||
|
||||
public static MapperSourceGen.SourceGenerator.Tests.MyEntityDto ToDto(MapperSourceGen.SourceGenerator.Tests.MyEntity source)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(nameof(source));
|
||||
return new MapperSourceGen.SourceGenerator.Tests.MyEntityDto()
|
||||
{
|
||||
Id = source.Id,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user