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>
|
||||||
117
README.md
Normal file
117
README.md
Normal file
@@ -0,0 +1,117 @@
|
|||||||
|
# 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.
|
||||||
|
|
||||||
|
> [!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