diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index 3962299d..00000000 --- a/.gitmodules +++ /dev/null @@ -1,4 +0,0 @@ -[submodule "external/FluentIL"] - path = external/FluentIL - url = git@github.com:pamidur/fluent-il.git - branch = master diff --git a/AspectInjector.sln b/AspectInjector.sln index 33e3ebf4..a9448183 100644 --- a/AspectInjector.sln +++ b/AspectInjector.sln @@ -1,307 +1,307 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 17 -VisualStudioVersion = 17.0.32112.339 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "_solution", "_solution", "{AEB111CE-8C1F-49F8-8282-6BBA13C05C2E}" - ProjectSection(SolutionItems) = preProject - .github\workflows\application.yml = .github\workflows\application.yml - LICENSE = LICENSE - package.png = package.png - README.md = README.md - .github\workflows\samples.yml = .github\workflows\samples.yml - EndProjectSection -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AspectInjector.Core", "src\AspectInjector.Core\AspectInjector.Core.csproj", "{ACCC10D0-D079-4B9C-8269-71796A0EF822}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{2DAB661A-26B2-440A-BC54-59F2C8404F12}" - ProjectSection(SolutionItems) = preProject - tests\Directory.Build.props = tests\Directory.Build.props - tests\Directory.Build.targets = tests\Directory.Build.targets - EndProjectSection -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AspectInjector.Core.Mixin", "src\AspectInjector.Core.Mixin\AspectInjector.Core.Mixin.csproj", "{3FBD73F5-6098-45A8-A236-6CC2F093B804}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AspectInjector.Core.Advice", "src\AspectInjector.Core.Advice\AspectInjector.Core.Advice.csproj", "{1A96AA51-2CBC-4901-91D1-53208AD5E6B6}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AspectInjector.Broker", "src\AspectInjector.Broker\AspectInjector.Broker.csproj", "{0926FE28-73BA-4F73-9188-B196FBBC9410}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AspectInjector.Package", "nuget\AspectInjector.Package.csproj", "{29DB956E-AC8F-4A2C-BBEF-71DDE91602FC}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{8F9E5ECE-A6EB-4DC7-B3E2-20319BF21607}" - ProjectSection(SolutionItems) = preProject - src\Directory.Build.props = src\Directory.Build.props - EndProjectSection -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AspectInjector.Tests.RuntimeAssets", "tests\AspectInjector.Tests.RuntimeAssets\AspectInjector.Tests.RuntimeAssets.csproj", "{A4BDB41D-096A-42E7-953E-99F7680141B0}" - ProjectSection(ProjectDependencies) = postProject - {FC862191-9081-4A58-96FF-B57F17AC40A9} = {FC862191-9081-4A58-96FF-B57F17AC40A9} - EndProjectSection -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AspectInjector", "src\AspectInjector\AspectInjector.csproj", "{FC862191-9081-4A58-96FF-B57F17AC40A9}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AspectInjector.Tests.Runtime", "tests\AspectInjector.Tests.Runtime\AspectInjector.Tests.Runtime.csproj", "{6431E891-8E90-4510-AC8F-581536757EA0}" - ProjectSection(ProjectDependencies) = postProject - {FC862191-9081-4A58-96FF-B57F17AC40A9} = {FC862191-9081-4A58-96FF-B57F17AC40A9} - EndProjectSection -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AspectInjector.Analyzer", "src\AspectInjector.Analyzer\AspectInjector.Analyzer.csproj", "{8A2E5556-55A4-4A1C-BE82-7603BEFA1A19}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AspectInjector.Analyzer.Tests", "tests\AspectInjector.Analyzer.Tests\AspectInjector.Analyzer.Tests.csproj", "{ACEE719B-B932-4B41-84AE-0F0CA0CE37E0}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AspectInjector.Analyzer.Vsix", "src\AspectInjector.Analyzer.Vsix\AspectInjector.Analyzer.Vsix.csproj", "{06F6709E-56E5-41ED-9BC1-55A8F648DD72}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AspectInjector.Rules", "src\AspectInjector.Rules\AspectInjector.Rules.csproj", "{20ED44A4-9D35-41F2-A317-C1EB9923379E}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FluentIL", "external\FluentIL\src\FluentIL\FluentIL.csproj", "{E8F7FB9B-4FF0-4195-B064-D41A96E41918}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FluentIL.Common", "external\FluentIL\src\FluentIL.Common\FluentIL.Common.csproj", "{7BD22418-F4A9-422B-9FDE-A20708BA0648}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AspectInjector.Tests.Integrity", "tests\AspectInjector.Tests.Integrity\AspectInjector.Tests.Integrity.csproj", "{230C6FAF-11A1-4318-A482-69C7252652B1}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AspectInjector.Tests.Generics", "tests\AspectInjector.Tests.Generics\AspectInjector.Tests.Generics.csproj", "{BF019B75-CECE-46E7-9E3D-620B2CAB6A96}" - ProjectSection(ProjectDependencies) = postProject - {FC862191-9081-4A58-96FF-B57F17AC40A9} = {FC862191-9081-4A58-96FF-B57F17AC40A9} - EndProjectSection -EndProject -Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "AspectInjector.Tests.VBRuntime", "tests\AspectInjector.Tests.VBRuntime\AspectInjector.Tests.VBRuntime.vbproj", "{1C5CC61E-3080-42D8-BEE0-6113C8C57D5D}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Debug|x86 = Debug|x86 - DebugTests|Any CPU = DebugTests|Any CPU - DebugTests|x86 = DebugTests|x86 - Release|Any CPU = Release|Any CPU - Release|x86 = Release|x86 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {ACCC10D0-D079-4B9C-8269-71796A0EF822}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {ACCC10D0-D079-4B9C-8269-71796A0EF822}.Debug|Any CPU.Build.0 = Debug|Any CPU - {ACCC10D0-D079-4B9C-8269-71796A0EF822}.Debug|x86.ActiveCfg = Debug|Any CPU - {ACCC10D0-D079-4B9C-8269-71796A0EF822}.Debug|x86.Build.0 = Debug|Any CPU - {ACCC10D0-D079-4B9C-8269-71796A0EF822}.DebugTests|Any CPU.ActiveCfg = Debug|Any CPU - {ACCC10D0-D079-4B9C-8269-71796A0EF822}.DebugTests|Any CPU.Build.0 = Debug|Any CPU - {ACCC10D0-D079-4B9C-8269-71796A0EF822}.DebugTests|x86.ActiveCfg = Debug|Any CPU - {ACCC10D0-D079-4B9C-8269-71796A0EF822}.DebugTests|x86.Build.0 = Debug|Any CPU - {ACCC10D0-D079-4B9C-8269-71796A0EF822}.Release|Any CPU.ActiveCfg = Release|Any CPU - {ACCC10D0-D079-4B9C-8269-71796A0EF822}.Release|Any CPU.Build.0 = Release|Any CPU - {ACCC10D0-D079-4B9C-8269-71796A0EF822}.Release|x86.ActiveCfg = Release|Any CPU - {ACCC10D0-D079-4B9C-8269-71796A0EF822}.Release|x86.Build.0 = Release|Any CPU - {3FBD73F5-6098-45A8-A236-6CC2F093B804}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {3FBD73F5-6098-45A8-A236-6CC2F093B804}.Debug|Any CPU.Build.0 = Debug|Any CPU - {3FBD73F5-6098-45A8-A236-6CC2F093B804}.Debug|x86.ActiveCfg = Debug|Any CPU - {3FBD73F5-6098-45A8-A236-6CC2F093B804}.Debug|x86.Build.0 = Debug|Any CPU - {3FBD73F5-6098-45A8-A236-6CC2F093B804}.DebugTests|Any CPU.ActiveCfg = Debug|Any CPU - {3FBD73F5-6098-45A8-A236-6CC2F093B804}.DebugTests|Any CPU.Build.0 = Debug|Any CPU - {3FBD73F5-6098-45A8-A236-6CC2F093B804}.DebugTests|x86.ActiveCfg = Debug|Any CPU - {3FBD73F5-6098-45A8-A236-6CC2F093B804}.DebugTests|x86.Build.0 = Debug|Any CPU - {3FBD73F5-6098-45A8-A236-6CC2F093B804}.Release|Any CPU.ActiveCfg = Release|Any CPU - {3FBD73F5-6098-45A8-A236-6CC2F093B804}.Release|Any CPU.Build.0 = Release|Any CPU - {3FBD73F5-6098-45A8-A236-6CC2F093B804}.Release|x86.ActiveCfg = Release|Any CPU - {3FBD73F5-6098-45A8-A236-6CC2F093B804}.Release|x86.Build.0 = Release|Any CPU - {1A96AA51-2CBC-4901-91D1-53208AD5E6B6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {1A96AA51-2CBC-4901-91D1-53208AD5E6B6}.Debug|Any CPU.Build.0 = Debug|Any CPU - {1A96AA51-2CBC-4901-91D1-53208AD5E6B6}.Debug|x86.ActiveCfg = Debug|Any CPU - {1A96AA51-2CBC-4901-91D1-53208AD5E6B6}.Debug|x86.Build.0 = Debug|Any CPU - {1A96AA51-2CBC-4901-91D1-53208AD5E6B6}.DebugTests|Any CPU.ActiveCfg = Debug|Any CPU - {1A96AA51-2CBC-4901-91D1-53208AD5E6B6}.DebugTests|Any CPU.Build.0 = Debug|Any CPU - {1A96AA51-2CBC-4901-91D1-53208AD5E6B6}.DebugTests|x86.ActiveCfg = Debug|Any CPU - {1A96AA51-2CBC-4901-91D1-53208AD5E6B6}.DebugTests|x86.Build.0 = Debug|Any CPU - {1A96AA51-2CBC-4901-91D1-53208AD5E6B6}.Release|Any CPU.ActiveCfg = Release|Any CPU - {1A96AA51-2CBC-4901-91D1-53208AD5E6B6}.Release|Any CPU.Build.0 = Release|Any CPU - {1A96AA51-2CBC-4901-91D1-53208AD5E6B6}.Release|x86.ActiveCfg = Release|Any CPU - {1A96AA51-2CBC-4901-91D1-53208AD5E6B6}.Release|x86.Build.0 = Release|Any CPU - {0926FE28-73BA-4F73-9188-B196FBBC9410}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {0926FE28-73BA-4F73-9188-B196FBBC9410}.Debug|Any CPU.Build.0 = Debug|Any CPU - {0926FE28-73BA-4F73-9188-B196FBBC9410}.Debug|x86.ActiveCfg = Debug|Any CPU - {0926FE28-73BA-4F73-9188-B196FBBC9410}.Debug|x86.Build.0 = Debug|Any CPU - {0926FE28-73BA-4F73-9188-B196FBBC9410}.DebugTests|Any CPU.ActiveCfg = Debug|Any CPU - {0926FE28-73BA-4F73-9188-B196FBBC9410}.DebugTests|Any CPU.Build.0 = Debug|Any CPU - {0926FE28-73BA-4F73-9188-B196FBBC9410}.DebugTests|x86.ActiveCfg = Debug|Any CPU - {0926FE28-73BA-4F73-9188-B196FBBC9410}.DebugTests|x86.Build.0 = Debug|Any CPU - {0926FE28-73BA-4F73-9188-B196FBBC9410}.Release|Any CPU.ActiveCfg = Release|Any CPU - {0926FE28-73BA-4F73-9188-B196FBBC9410}.Release|Any CPU.Build.0 = Release|Any CPU - {0926FE28-73BA-4F73-9188-B196FBBC9410}.Release|x86.ActiveCfg = Release|Any CPU - {0926FE28-73BA-4F73-9188-B196FBBC9410}.Release|x86.Build.0 = Release|Any CPU - {29DB956E-AC8F-4A2C-BBEF-71DDE91602FC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {29DB956E-AC8F-4A2C-BBEF-71DDE91602FC}.Debug|Any CPU.Build.0 = Debug|Any CPU - {29DB956E-AC8F-4A2C-BBEF-71DDE91602FC}.Debug|x86.ActiveCfg = Debug|Any CPU - {29DB956E-AC8F-4A2C-BBEF-71DDE91602FC}.Debug|x86.Build.0 = Debug|Any CPU - {29DB956E-AC8F-4A2C-BBEF-71DDE91602FC}.DebugTests|Any CPU.ActiveCfg = Debug|Any CPU - {29DB956E-AC8F-4A2C-BBEF-71DDE91602FC}.DebugTests|Any CPU.Build.0 = Debug|Any CPU - {29DB956E-AC8F-4A2C-BBEF-71DDE91602FC}.DebugTests|x86.ActiveCfg = Debug|Any CPU - {29DB956E-AC8F-4A2C-BBEF-71DDE91602FC}.DebugTests|x86.Build.0 = Debug|Any CPU - {29DB956E-AC8F-4A2C-BBEF-71DDE91602FC}.Release|Any CPU.ActiveCfg = Release|Any CPU - {29DB956E-AC8F-4A2C-BBEF-71DDE91602FC}.Release|Any CPU.Build.0 = Release|Any CPU - {29DB956E-AC8F-4A2C-BBEF-71DDE91602FC}.Release|x86.ActiveCfg = Release|Any CPU - {29DB956E-AC8F-4A2C-BBEF-71DDE91602FC}.Release|x86.Build.0 = Release|Any CPU - {A4BDB41D-096A-42E7-953E-99F7680141B0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {A4BDB41D-096A-42E7-953E-99F7680141B0}.Debug|Any CPU.Build.0 = Debug|Any CPU - {A4BDB41D-096A-42E7-953E-99F7680141B0}.Debug|x86.ActiveCfg = Debug|Any CPU - {A4BDB41D-096A-42E7-953E-99F7680141B0}.Debug|x86.Build.0 = Debug|Any CPU - {A4BDB41D-096A-42E7-953E-99F7680141B0}.DebugTests|Any CPU.ActiveCfg = DebugTests|Any CPU - {A4BDB41D-096A-42E7-953E-99F7680141B0}.DebugTests|Any CPU.Build.0 = DebugTests|Any CPU - {A4BDB41D-096A-42E7-953E-99F7680141B0}.DebugTests|x86.ActiveCfg = DebugTests|Any CPU - {A4BDB41D-096A-42E7-953E-99F7680141B0}.DebugTests|x86.Build.0 = DebugTests|Any CPU - {A4BDB41D-096A-42E7-953E-99F7680141B0}.Release|Any CPU.ActiveCfg = Release|Any CPU - {A4BDB41D-096A-42E7-953E-99F7680141B0}.Release|Any CPU.Build.0 = Release|Any CPU - {A4BDB41D-096A-42E7-953E-99F7680141B0}.Release|x86.ActiveCfg = Release|Any CPU - {A4BDB41D-096A-42E7-953E-99F7680141B0}.Release|x86.Build.0 = Release|Any CPU - {FC862191-9081-4A58-96FF-B57F17AC40A9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {FC862191-9081-4A58-96FF-B57F17AC40A9}.Debug|Any CPU.Build.0 = Debug|Any CPU - {FC862191-9081-4A58-96FF-B57F17AC40A9}.Debug|x86.ActiveCfg = Debug|Any CPU - {FC862191-9081-4A58-96FF-B57F17AC40A9}.Debug|x86.Build.0 = Debug|Any CPU - {FC862191-9081-4A58-96FF-B57F17AC40A9}.DebugTests|Any CPU.ActiveCfg = Debug|Any CPU - {FC862191-9081-4A58-96FF-B57F17AC40A9}.DebugTests|Any CPU.Build.0 = Debug|Any CPU - {FC862191-9081-4A58-96FF-B57F17AC40A9}.DebugTests|x86.ActiveCfg = Debug|Any CPU - {FC862191-9081-4A58-96FF-B57F17AC40A9}.DebugTests|x86.Build.0 = Debug|Any CPU - {FC862191-9081-4A58-96FF-B57F17AC40A9}.Release|Any CPU.ActiveCfg = Release|Any CPU - {FC862191-9081-4A58-96FF-B57F17AC40A9}.Release|Any CPU.Build.0 = Release|Any CPU - {FC862191-9081-4A58-96FF-B57F17AC40A9}.Release|x86.ActiveCfg = Release|Any CPU - {FC862191-9081-4A58-96FF-B57F17AC40A9}.Release|x86.Build.0 = Release|Any CPU - {6431E891-8E90-4510-AC8F-581536757EA0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {6431E891-8E90-4510-AC8F-581536757EA0}.Debug|Any CPU.Build.0 = Debug|Any CPU - {6431E891-8E90-4510-AC8F-581536757EA0}.Debug|x86.ActiveCfg = Debug|Any CPU - {6431E891-8E90-4510-AC8F-581536757EA0}.Debug|x86.Build.0 = Debug|Any CPU - {6431E891-8E90-4510-AC8F-581536757EA0}.DebugTests|Any CPU.ActiveCfg = DebugTests|Any CPU - {6431E891-8E90-4510-AC8F-581536757EA0}.DebugTests|Any CPU.Build.0 = DebugTests|Any CPU - {6431E891-8E90-4510-AC8F-581536757EA0}.DebugTests|x86.ActiveCfg = DebugTests|Any CPU - {6431E891-8E90-4510-AC8F-581536757EA0}.DebugTests|x86.Build.0 = DebugTests|Any CPU - {6431E891-8E90-4510-AC8F-581536757EA0}.Release|Any CPU.ActiveCfg = Release|Any CPU - {6431E891-8E90-4510-AC8F-581536757EA0}.Release|Any CPU.Build.0 = Release|Any CPU - {6431E891-8E90-4510-AC8F-581536757EA0}.Release|x86.ActiveCfg = Release|Any CPU - {6431E891-8E90-4510-AC8F-581536757EA0}.Release|x86.Build.0 = Release|Any CPU - {8A2E5556-55A4-4A1C-BE82-7603BEFA1A19}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {8A2E5556-55A4-4A1C-BE82-7603BEFA1A19}.Debug|Any CPU.Build.0 = Debug|Any CPU - {8A2E5556-55A4-4A1C-BE82-7603BEFA1A19}.Debug|x86.ActiveCfg = Debug|Any CPU - {8A2E5556-55A4-4A1C-BE82-7603BEFA1A19}.Debug|x86.Build.0 = Debug|Any CPU - {8A2E5556-55A4-4A1C-BE82-7603BEFA1A19}.DebugTests|Any CPU.ActiveCfg = Debug|Any CPU - {8A2E5556-55A4-4A1C-BE82-7603BEFA1A19}.DebugTests|Any CPU.Build.0 = Debug|Any CPU - {8A2E5556-55A4-4A1C-BE82-7603BEFA1A19}.DebugTests|x86.ActiveCfg = Debug|Any CPU - {8A2E5556-55A4-4A1C-BE82-7603BEFA1A19}.DebugTests|x86.Build.0 = Debug|Any CPU - {8A2E5556-55A4-4A1C-BE82-7603BEFA1A19}.Release|Any CPU.ActiveCfg = Release|Any CPU - {8A2E5556-55A4-4A1C-BE82-7603BEFA1A19}.Release|Any CPU.Build.0 = Release|Any CPU - {8A2E5556-55A4-4A1C-BE82-7603BEFA1A19}.Release|x86.ActiveCfg = Release|Any CPU - {8A2E5556-55A4-4A1C-BE82-7603BEFA1A19}.Release|x86.Build.0 = Release|Any CPU - {ACEE719B-B932-4B41-84AE-0F0CA0CE37E0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {ACEE719B-B932-4B41-84AE-0F0CA0CE37E0}.Debug|Any CPU.Build.0 = Debug|Any CPU - {ACEE719B-B932-4B41-84AE-0F0CA0CE37E0}.Debug|x86.ActiveCfg = Debug|Any CPU - {ACEE719B-B932-4B41-84AE-0F0CA0CE37E0}.Debug|x86.Build.0 = Debug|Any CPU - {ACEE719B-B932-4B41-84AE-0F0CA0CE37E0}.DebugTests|Any CPU.ActiveCfg = Debug|Any CPU - {ACEE719B-B932-4B41-84AE-0F0CA0CE37E0}.DebugTests|Any CPU.Build.0 = Debug|Any CPU - {ACEE719B-B932-4B41-84AE-0F0CA0CE37E0}.DebugTests|x86.ActiveCfg = Debug|Any CPU - {ACEE719B-B932-4B41-84AE-0F0CA0CE37E0}.DebugTests|x86.Build.0 = Debug|Any CPU - {ACEE719B-B932-4B41-84AE-0F0CA0CE37E0}.Release|Any CPU.ActiveCfg = Release|Any CPU - {ACEE719B-B932-4B41-84AE-0F0CA0CE37E0}.Release|Any CPU.Build.0 = Release|Any CPU - {ACEE719B-B932-4B41-84AE-0F0CA0CE37E0}.Release|x86.ActiveCfg = Release|Any CPU - {ACEE719B-B932-4B41-84AE-0F0CA0CE37E0}.Release|x86.Build.0 = Release|Any CPU - {06F6709E-56E5-41ED-9BC1-55A8F648DD72}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {06F6709E-56E5-41ED-9BC1-55A8F648DD72}.Debug|Any CPU.Build.0 = Debug|Any CPU - {06F6709E-56E5-41ED-9BC1-55A8F648DD72}.Debug|x86.ActiveCfg = Debug|x86 - {06F6709E-56E5-41ED-9BC1-55A8F648DD72}.Debug|x86.Build.0 = Debug|x86 - {06F6709E-56E5-41ED-9BC1-55A8F648DD72}.DebugTests|Any CPU.ActiveCfg = Debug|Any CPU - {06F6709E-56E5-41ED-9BC1-55A8F648DD72}.DebugTests|Any CPU.Build.0 = Debug|Any CPU - {06F6709E-56E5-41ED-9BC1-55A8F648DD72}.DebugTests|x86.ActiveCfg = Debug|x86 - {06F6709E-56E5-41ED-9BC1-55A8F648DD72}.DebugTests|x86.Build.0 = Debug|x86 - {06F6709E-56E5-41ED-9BC1-55A8F648DD72}.Release|Any CPU.ActiveCfg = Release|Any CPU - {06F6709E-56E5-41ED-9BC1-55A8F648DD72}.Release|x86.ActiveCfg = Release|x86 - {06F6709E-56E5-41ED-9BC1-55A8F648DD72}.Release|x86.Build.0 = Release|x86 - {20ED44A4-9D35-41F2-A317-C1EB9923379E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {20ED44A4-9D35-41F2-A317-C1EB9923379E}.Debug|Any CPU.Build.0 = Debug|Any CPU - {20ED44A4-9D35-41F2-A317-C1EB9923379E}.Debug|x86.ActiveCfg = Debug|Any CPU - {20ED44A4-9D35-41F2-A317-C1EB9923379E}.Debug|x86.Build.0 = Debug|Any CPU - {20ED44A4-9D35-41F2-A317-C1EB9923379E}.DebugTests|Any CPU.ActiveCfg = Debug|Any CPU - {20ED44A4-9D35-41F2-A317-C1EB9923379E}.DebugTests|Any CPU.Build.0 = Debug|Any CPU - {20ED44A4-9D35-41F2-A317-C1EB9923379E}.DebugTests|x86.ActiveCfg = Debug|Any CPU - {20ED44A4-9D35-41F2-A317-C1EB9923379E}.DebugTests|x86.Build.0 = Debug|Any CPU - {20ED44A4-9D35-41F2-A317-C1EB9923379E}.Release|Any CPU.ActiveCfg = Release|Any CPU - {20ED44A4-9D35-41F2-A317-C1EB9923379E}.Release|Any CPU.Build.0 = Release|Any CPU - {20ED44A4-9D35-41F2-A317-C1EB9923379E}.Release|x86.ActiveCfg = Release|Any CPU - {20ED44A4-9D35-41F2-A317-C1EB9923379E}.Release|x86.Build.0 = Release|Any CPU - {E8F7FB9B-4FF0-4195-B064-D41A96E41918}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {E8F7FB9B-4FF0-4195-B064-D41A96E41918}.Debug|Any CPU.Build.0 = Debug|Any CPU - {E8F7FB9B-4FF0-4195-B064-D41A96E41918}.Debug|x86.ActiveCfg = Debug|Any CPU - {E8F7FB9B-4FF0-4195-B064-D41A96E41918}.Debug|x86.Build.0 = Debug|Any CPU - {E8F7FB9B-4FF0-4195-B064-D41A96E41918}.DebugTests|Any CPU.ActiveCfg = Debug|Any CPU - {E8F7FB9B-4FF0-4195-B064-D41A96E41918}.DebugTests|Any CPU.Build.0 = Debug|Any CPU - {E8F7FB9B-4FF0-4195-B064-D41A96E41918}.DebugTests|x86.ActiveCfg = Debug|Any CPU - {E8F7FB9B-4FF0-4195-B064-D41A96E41918}.DebugTests|x86.Build.0 = Debug|Any CPU - {E8F7FB9B-4FF0-4195-B064-D41A96E41918}.Release|Any CPU.ActiveCfg = Release|Any CPU - {E8F7FB9B-4FF0-4195-B064-D41A96E41918}.Release|Any CPU.Build.0 = Release|Any CPU - {E8F7FB9B-4FF0-4195-B064-D41A96E41918}.Release|x86.ActiveCfg = Release|Any CPU - {E8F7FB9B-4FF0-4195-B064-D41A96E41918}.Release|x86.Build.0 = Release|Any CPU - {7BD22418-F4A9-422B-9FDE-A20708BA0648}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {7BD22418-F4A9-422B-9FDE-A20708BA0648}.Debug|Any CPU.Build.0 = Debug|Any CPU - {7BD22418-F4A9-422B-9FDE-A20708BA0648}.Debug|x86.ActiveCfg = Debug|Any CPU - {7BD22418-F4A9-422B-9FDE-A20708BA0648}.Debug|x86.Build.0 = Debug|Any CPU - {7BD22418-F4A9-422B-9FDE-A20708BA0648}.DebugTests|Any CPU.ActiveCfg = Debug|Any CPU - {7BD22418-F4A9-422B-9FDE-A20708BA0648}.DebugTests|Any CPU.Build.0 = Debug|Any CPU - {7BD22418-F4A9-422B-9FDE-A20708BA0648}.DebugTests|x86.ActiveCfg = Debug|Any CPU - {7BD22418-F4A9-422B-9FDE-A20708BA0648}.DebugTests|x86.Build.0 = Debug|Any CPU - {7BD22418-F4A9-422B-9FDE-A20708BA0648}.Release|Any CPU.ActiveCfg = Release|Any CPU - {7BD22418-F4A9-422B-9FDE-A20708BA0648}.Release|Any CPU.Build.0 = Release|Any CPU - {7BD22418-F4A9-422B-9FDE-A20708BA0648}.Release|x86.ActiveCfg = Release|Any CPU - {7BD22418-F4A9-422B-9FDE-A20708BA0648}.Release|x86.Build.0 = Release|Any CPU - {230C6FAF-11A1-4318-A482-69C7252652B1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {230C6FAF-11A1-4318-A482-69C7252652B1}.Debug|Any CPU.Build.0 = Debug|Any CPU - {230C6FAF-11A1-4318-A482-69C7252652B1}.Debug|x86.ActiveCfg = Debug|Any CPU - {230C6FAF-11A1-4318-A482-69C7252652B1}.Debug|x86.Build.0 = Debug|Any CPU - {230C6FAF-11A1-4318-A482-69C7252652B1}.DebugTests|Any CPU.ActiveCfg = Debug|Any CPU - {230C6FAF-11A1-4318-A482-69C7252652B1}.DebugTests|Any CPU.Build.0 = Debug|Any CPU - {230C6FAF-11A1-4318-A482-69C7252652B1}.DebugTests|x86.ActiveCfg = Debug|Any CPU - {230C6FAF-11A1-4318-A482-69C7252652B1}.DebugTests|x86.Build.0 = Debug|Any CPU - {230C6FAF-11A1-4318-A482-69C7252652B1}.Release|Any CPU.ActiveCfg = Release|Any CPU - {230C6FAF-11A1-4318-A482-69C7252652B1}.Release|Any CPU.Build.0 = Release|Any CPU - {230C6FAF-11A1-4318-A482-69C7252652B1}.Release|x86.ActiveCfg = Release|Any CPU - {230C6FAF-11A1-4318-A482-69C7252652B1}.Release|x86.Build.0 = Release|Any CPU - {BF019B75-CECE-46E7-9E3D-620B2CAB6A96}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {BF019B75-CECE-46E7-9E3D-620B2CAB6A96}.Debug|Any CPU.Build.0 = Debug|Any CPU - {BF019B75-CECE-46E7-9E3D-620B2CAB6A96}.Debug|x86.ActiveCfg = Debug|Any CPU - {BF019B75-CECE-46E7-9E3D-620B2CAB6A96}.Debug|x86.Build.0 = Debug|Any CPU - {BF019B75-CECE-46E7-9E3D-620B2CAB6A96}.DebugTests|Any CPU.ActiveCfg = DebugTests|Any CPU - {BF019B75-CECE-46E7-9E3D-620B2CAB6A96}.DebugTests|Any CPU.Build.0 = DebugTests|Any CPU - {BF019B75-CECE-46E7-9E3D-620B2CAB6A96}.DebugTests|x86.ActiveCfg = DebugTests|Any CPU - {BF019B75-CECE-46E7-9E3D-620B2CAB6A96}.DebugTests|x86.Build.0 = DebugTests|Any CPU - {BF019B75-CECE-46E7-9E3D-620B2CAB6A96}.Release|Any CPU.ActiveCfg = Release|Any CPU - {BF019B75-CECE-46E7-9E3D-620B2CAB6A96}.Release|Any CPU.Build.0 = Release|Any CPU - {BF019B75-CECE-46E7-9E3D-620B2CAB6A96}.Release|x86.ActiveCfg = Release|Any CPU - {BF019B75-CECE-46E7-9E3D-620B2CAB6A96}.Release|x86.Build.0 = Release|Any CPU - {1C5CC61E-3080-42D8-BEE0-6113C8C57D5D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {1C5CC61E-3080-42D8-BEE0-6113C8C57D5D}.Debug|Any CPU.Build.0 = Debug|Any CPU - {1C5CC61E-3080-42D8-BEE0-6113C8C57D5D}.Debug|x86.ActiveCfg = Debug|Any CPU - {1C5CC61E-3080-42D8-BEE0-6113C8C57D5D}.Debug|x86.Build.0 = Debug|Any CPU - {1C5CC61E-3080-42D8-BEE0-6113C8C57D5D}.DebugTests|Any CPU.ActiveCfg = DebugTests|Any CPU - {1C5CC61E-3080-42D8-BEE0-6113C8C57D5D}.DebugTests|Any CPU.Build.0 = DebugTests|Any CPU - {1C5CC61E-3080-42D8-BEE0-6113C8C57D5D}.DebugTests|x86.ActiveCfg = Debug|Any CPU - {1C5CC61E-3080-42D8-BEE0-6113C8C57D5D}.DebugTests|x86.Build.0 = Debug|Any CPU - {1C5CC61E-3080-42D8-BEE0-6113C8C57D5D}.Release|Any CPU.ActiveCfg = Release|Any CPU - {1C5CC61E-3080-42D8-BEE0-6113C8C57D5D}.Release|Any CPU.Build.0 = Release|Any CPU - {1C5CC61E-3080-42D8-BEE0-6113C8C57D5D}.Release|x86.ActiveCfg = Release|Any CPU - {1C5CC61E-3080-42D8-BEE0-6113C8C57D5D}.Release|x86.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(NestedProjects) = preSolution - {ACCC10D0-D079-4B9C-8269-71796A0EF822} = {8F9E5ECE-A6EB-4DC7-B3E2-20319BF21607} - {3FBD73F5-6098-45A8-A236-6CC2F093B804} = {8F9E5ECE-A6EB-4DC7-B3E2-20319BF21607} - {1A96AA51-2CBC-4901-91D1-53208AD5E6B6} = {8F9E5ECE-A6EB-4DC7-B3E2-20319BF21607} - {0926FE28-73BA-4F73-9188-B196FBBC9410} = {8F9E5ECE-A6EB-4DC7-B3E2-20319BF21607} - {A4BDB41D-096A-42E7-953E-99F7680141B0} = {2DAB661A-26B2-440A-BC54-59F2C8404F12} - {FC862191-9081-4A58-96FF-B57F17AC40A9} = {8F9E5ECE-A6EB-4DC7-B3E2-20319BF21607} - {6431E891-8E90-4510-AC8F-581536757EA0} = {2DAB661A-26B2-440A-BC54-59F2C8404F12} - {8A2E5556-55A4-4A1C-BE82-7603BEFA1A19} = {8F9E5ECE-A6EB-4DC7-B3E2-20319BF21607} - {ACEE719B-B932-4B41-84AE-0F0CA0CE37E0} = {2DAB661A-26B2-440A-BC54-59F2C8404F12} - {06F6709E-56E5-41ED-9BC1-55A8F648DD72} = {8F9E5ECE-A6EB-4DC7-B3E2-20319BF21607} - {20ED44A4-9D35-41F2-A317-C1EB9923379E} = {8F9E5ECE-A6EB-4DC7-B3E2-20319BF21607} - {E8F7FB9B-4FF0-4195-B064-D41A96E41918} = {8F9E5ECE-A6EB-4DC7-B3E2-20319BF21607} - {7BD22418-F4A9-422B-9FDE-A20708BA0648} = {8F9E5ECE-A6EB-4DC7-B3E2-20319BF21607} - {230C6FAF-11A1-4318-A482-69C7252652B1} = {2DAB661A-26B2-440A-BC54-59F2C8404F12} - {BF019B75-CECE-46E7-9E3D-620B2CAB6A96} = {2DAB661A-26B2-440A-BC54-59F2C8404F12} - {1C5CC61E-3080-42D8-BEE0-6113C8C57D5D} = {2DAB661A-26B2-440A-BC54-59F2C8404F12} - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {B153C707-A96B-404C-B0E6-2225AE14B304} - EndGlobalSection -EndGlobal + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.0.32112.339 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "_solution", "_solution", "{AEB111CE-8C1F-49F8-8282-6BBA13C05C2E}" + ProjectSection(SolutionItems) = preProject + .github\workflows\application.yml = .github\workflows\application.yml + LICENSE = LICENSE + package.png = package.png + README.md = README.md + .github\workflows\samples.yml = .github\workflows\samples.yml + EndProjectSection +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AspectInjector.Core", "src\AspectInjector.Core\AspectInjector.Core.csproj", "{ACCC10D0-D079-4B9C-8269-71796A0EF822}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{2DAB661A-26B2-440A-BC54-59F2C8404F12}" + ProjectSection(SolutionItems) = preProject + tests\Directory.Build.props = tests\Directory.Build.props + tests\Directory.Build.targets = tests\Directory.Build.targets + EndProjectSection +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AspectInjector.Core.Mixin", "src\AspectInjector.Core.Mixin\AspectInjector.Core.Mixin.csproj", "{3FBD73F5-6098-45A8-A236-6CC2F093B804}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AspectInjector.Core.Advice", "src\AspectInjector.Core.Advice\AspectInjector.Core.Advice.csproj", "{1A96AA51-2CBC-4901-91D1-53208AD5E6B6}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AspectInjector.Broker", "src\AspectInjector.Broker\AspectInjector.Broker.csproj", "{0926FE28-73BA-4F73-9188-B196FBBC9410}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AspectInjector.Package", "nuget\AspectInjector.Package.csproj", "{29DB956E-AC8F-4A2C-BBEF-71DDE91602FC}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{8F9E5ECE-A6EB-4DC7-B3E2-20319BF21607}" + ProjectSection(SolutionItems) = preProject + src\Directory.Build.props = src\Directory.Build.props + EndProjectSection +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AspectInjector.Tests.RuntimeAssets", "tests\AspectInjector.Tests.RuntimeAssets\AspectInjector.Tests.RuntimeAssets.csproj", "{A4BDB41D-096A-42E7-953E-99F7680141B0}" + ProjectSection(ProjectDependencies) = postProject + {FC862191-9081-4A58-96FF-B57F17AC40A9} = {FC862191-9081-4A58-96FF-B57F17AC40A9} + EndProjectSection +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AspectInjector", "src\AspectInjector\AspectInjector.csproj", "{FC862191-9081-4A58-96FF-B57F17AC40A9}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AspectInjector.Tests.Runtime", "tests\AspectInjector.Tests.Runtime\AspectInjector.Tests.Runtime.csproj", "{6431E891-8E90-4510-AC8F-581536757EA0}" + ProjectSection(ProjectDependencies) = postProject + {FC862191-9081-4A58-96FF-B57F17AC40A9} = {FC862191-9081-4A58-96FF-B57F17AC40A9} + EndProjectSection +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AspectInjector.Analyzer", "src\AspectInjector.Analyzer\AspectInjector.Analyzer.csproj", "{8A2E5556-55A4-4A1C-BE82-7603BEFA1A19}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AspectInjector.Analyzer.Tests", "tests\AspectInjector.Analyzer.Tests\AspectInjector.Analyzer.Tests.csproj", "{ACEE719B-B932-4B41-84AE-0F0CA0CE37E0}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AspectInjector.Analyzer.Vsix", "src\AspectInjector.Analyzer.Vsix\AspectInjector.Analyzer.Vsix.csproj", "{06F6709E-56E5-41ED-9BC1-55A8F648DD72}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AspectInjector.Rules", "src\AspectInjector.Rules\AspectInjector.Rules.csproj", "{20ED44A4-9D35-41F2-A317-C1EB9923379E}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FluentIL", "src\FluentIL\FluentIL.csproj", "{E8F7FB9B-4FF0-4195-B064-D41A96E41918}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FluentIL.Common", "src\FluentIL.Common\FluentIL.Common.csproj", "{7BD22418-F4A9-422B-9FDE-A20708BA0648}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AspectInjector.Tests.Integrity", "tests\AspectInjector.Tests.Integrity\AspectInjector.Tests.Integrity.csproj", "{230C6FAF-11A1-4318-A482-69C7252652B1}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AspectInjector.Tests.Generics", "tests\AspectInjector.Tests.Generics\AspectInjector.Tests.Generics.csproj", "{BF019B75-CECE-46E7-9E3D-620B2CAB6A96}" + ProjectSection(ProjectDependencies) = postProject + {FC862191-9081-4A58-96FF-B57F17AC40A9} = {FC862191-9081-4A58-96FF-B57F17AC40A9} + EndProjectSection +EndProject +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "AspectInjector.Tests.VBRuntime", "tests\AspectInjector.Tests.VBRuntime\AspectInjector.Tests.VBRuntime.vbproj", "{1C5CC61E-3080-42D8-BEE0-6113C8C57D5D}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Debug|x86 = Debug|x86 + DebugTests|Any CPU = DebugTests|Any CPU + DebugTests|x86 = DebugTests|x86 + Release|Any CPU = Release|Any CPU + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {ACCC10D0-D079-4B9C-8269-71796A0EF822}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {ACCC10D0-D079-4B9C-8269-71796A0EF822}.Debug|Any CPU.Build.0 = Debug|Any CPU + {ACCC10D0-D079-4B9C-8269-71796A0EF822}.Debug|x86.ActiveCfg = Debug|Any CPU + {ACCC10D0-D079-4B9C-8269-71796A0EF822}.Debug|x86.Build.0 = Debug|Any CPU + {ACCC10D0-D079-4B9C-8269-71796A0EF822}.DebugTests|Any CPU.ActiveCfg = Debug|Any CPU + {ACCC10D0-D079-4B9C-8269-71796A0EF822}.DebugTests|Any CPU.Build.0 = Debug|Any CPU + {ACCC10D0-D079-4B9C-8269-71796A0EF822}.DebugTests|x86.ActiveCfg = Debug|Any CPU + {ACCC10D0-D079-4B9C-8269-71796A0EF822}.DebugTests|x86.Build.0 = Debug|Any CPU + {ACCC10D0-D079-4B9C-8269-71796A0EF822}.Release|Any CPU.ActiveCfg = Release|Any CPU + {ACCC10D0-D079-4B9C-8269-71796A0EF822}.Release|Any CPU.Build.0 = Release|Any CPU + {ACCC10D0-D079-4B9C-8269-71796A0EF822}.Release|x86.ActiveCfg = Release|Any CPU + {ACCC10D0-D079-4B9C-8269-71796A0EF822}.Release|x86.Build.0 = Release|Any CPU + {3FBD73F5-6098-45A8-A236-6CC2F093B804}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3FBD73F5-6098-45A8-A236-6CC2F093B804}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3FBD73F5-6098-45A8-A236-6CC2F093B804}.Debug|x86.ActiveCfg = Debug|Any CPU + {3FBD73F5-6098-45A8-A236-6CC2F093B804}.Debug|x86.Build.0 = Debug|Any CPU + {3FBD73F5-6098-45A8-A236-6CC2F093B804}.DebugTests|Any CPU.ActiveCfg = Debug|Any CPU + {3FBD73F5-6098-45A8-A236-6CC2F093B804}.DebugTests|Any CPU.Build.0 = Debug|Any CPU + {3FBD73F5-6098-45A8-A236-6CC2F093B804}.DebugTests|x86.ActiveCfg = Debug|Any CPU + {3FBD73F5-6098-45A8-A236-6CC2F093B804}.DebugTests|x86.Build.0 = Debug|Any CPU + {3FBD73F5-6098-45A8-A236-6CC2F093B804}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3FBD73F5-6098-45A8-A236-6CC2F093B804}.Release|Any CPU.Build.0 = Release|Any CPU + {3FBD73F5-6098-45A8-A236-6CC2F093B804}.Release|x86.ActiveCfg = Release|Any CPU + {3FBD73F5-6098-45A8-A236-6CC2F093B804}.Release|x86.Build.0 = Release|Any CPU + {1A96AA51-2CBC-4901-91D1-53208AD5E6B6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1A96AA51-2CBC-4901-91D1-53208AD5E6B6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1A96AA51-2CBC-4901-91D1-53208AD5E6B6}.Debug|x86.ActiveCfg = Debug|Any CPU + {1A96AA51-2CBC-4901-91D1-53208AD5E6B6}.Debug|x86.Build.0 = Debug|Any CPU + {1A96AA51-2CBC-4901-91D1-53208AD5E6B6}.DebugTests|Any CPU.ActiveCfg = Debug|Any CPU + {1A96AA51-2CBC-4901-91D1-53208AD5E6B6}.DebugTests|Any CPU.Build.0 = Debug|Any CPU + {1A96AA51-2CBC-4901-91D1-53208AD5E6B6}.DebugTests|x86.ActiveCfg = Debug|Any CPU + {1A96AA51-2CBC-4901-91D1-53208AD5E6B6}.DebugTests|x86.Build.0 = Debug|Any CPU + {1A96AA51-2CBC-4901-91D1-53208AD5E6B6}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1A96AA51-2CBC-4901-91D1-53208AD5E6B6}.Release|Any CPU.Build.0 = Release|Any CPU + {1A96AA51-2CBC-4901-91D1-53208AD5E6B6}.Release|x86.ActiveCfg = Release|Any CPU + {1A96AA51-2CBC-4901-91D1-53208AD5E6B6}.Release|x86.Build.0 = Release|Any CPU + {0926FE28-73BA-4F73-9188-B196FBBC9410}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0926FE28-73BA-4F73-9188-B196FBBC9410}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0926FE28-73BA-4F73-9188-B196FBBC9410}.Debug|x86.ActiveCfg = Debug|Any CPU + {0926FE28-73BA-4F73-9188-B196FBBC9410}.Debug|x86.Build.0 = Debug|Any CPU + {0926FE28-73BA-4F73-9188-B196FBBC9410}.DebugTests|Any CPU.ActiveCfg = Debug|Any CPU + {0926FE28-73BA-4F73-9188-B196FBBC9410}.DebugTests|Any CPU.Build.0 = Debug|Any CPU + {0926FE28-73BA-4F73-9188-B196FBBC9410}.DebugTests|x86.ActiveCfg = Debug|Any CPU + {0926FE28-73BA-4F73-9188-B196FBBC9410}.DebugTests|x86.Build.0 = Debug|Any CPU + {0926FE28-73BA-4F73-9188-B196FBBC9410}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0926FE28-73BA-4F73-9188-B196FBBC9410}.Release|Any CPU.Build.0 = Release|Any CPU + {0926FE28-73BA-4F73-9188-B196FBBC9410}.Release|x86.ActiveCfg = Release|Any CPU + {0926FE28-73BA-4F73-9188-B196FBBC9410}.Release|x86.Build.0 = Release|Any CPU + {29DB956E-AC8F-4A2C-BBEF-71DDE91602FC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {29DB956E-AC8F-4A2C-BBEF-71DDE91602FC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {29DB956E-AC8F-4A2C-BBEF-71DDE91602FC}.Debug|x86.ActiveCfg = Debug|Any CPU + {29DB956E-AC8F-4A2C-BBEF-71DDE91602FC}.Debug|x86.Build.0 = Debug|Any CPU + {29DB956E-AC8F-4A2C-BBEF-71DDE91602FC}.DebugTests|Any CPU.ActiveCfg = Debug|Any CPU + {29DB956E-AC8F-4A2C-BBEF-71DDE91602FC}.DebugTests|Any CPU.Build.0 = Debug|Any CPU + {29DB956E-AC8F-4A2C-BBEF-71DDE91602FC}.DebugTests|x86.ActiveCfg = Debug|Any CPU + {29DB956E-AC8F-4A2C-BBEF-71DDE91602FC}.DebugTests|x86.Build.0 = Debug|Any CPU + {29DB956E-AC8F-4A2C-BBEF-71DDE91602FC}.Release|Any CPU.ActiveCfg = Release|Any CPU + {29DB956E-AC8F-4A2C-BBEF-71DDE91602FC}.Release|Any CPU.Build.0 = Release|Any CPU + {29DB956E-AC8F-4A2C-BBEF-71DDE91602FC}.Release|x86.ActiveCfg = Release|Any CPU + {29DB956E-AC8F-4A2C-BBEF-71DDE91602FC}.Release|x86.Build.0 = Release|Any CPU + {A4BDB41D-096A-42E7-953E-99F7680141B0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A4BDB41D-096A-42E7-953E-99F7680141B0}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A4BDB41D-096A-42E7-953E-99F7680141B0}.Debug|x86.ActiveCfg = Debug|Any CPU + {A4BDB41D-096A-42E7-953E-99F7680141B0}.Debug|x86.Build.0 = Debug|Any CPU + {A4BDB41D-096A-42E7-953E-99F7680141B0}.DebugTests|Any CPU.ActiveCfg = DebugTests|Any CPU + {A4BDB41D-096A-42E7-953E-99F7680141B0}.DebugTests|Any CPU.Build.0 = DebugTests|Any CPU + {A4BDB41D-096A-42E7-953E-99F7680141B0}.DebugTests|x86.ActiveCfg = DebugTests|Any CPU + {A4BDB41D-096A-42E7-953E-99F7680141B0}.DebugTests|x86.Build.0 = DebugTests|Any CPU + {A4BDB41D-096A-42E7-953E-99F7680141B0}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A4BDB41D-096A-42E7-953E-99F7680141B0}.Release|Any CPU.Build.0 = Release|Any CPU + {A4BDB41D-096A-42E7-953E-99F7680141B0}.Release|x86.ActiveCfg = Release|Any CPU + {A4BDB41D-096A-42E7-953E-99F7680141B0}.Release|x86.Build.0 = Release|Any CPU + {FC862191-9081-4A58-96FF-B57F17AC40A9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {FC862191-9081-4A58-96FF-B57F17AC40A9}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FC862191-9081-4A58-96FF-B57F17AC40A9}.Debug|x86.ActiveCfg = Debug|Any CPU + {FC862191-9081-4A58-96FF-B57F17AC40A9}.Debug|x86.Build.0 = Debug|Any CPU + {FC862191-9081-4A58-96FF-B57F17AC40A9}.DebugTests|Any CPU.ActiveCfg = Debug|Any CPU + {FC862191-9081-4A58-96FF-B57F17AC40A9}.DebugTests|Any CPU.Build.0 = Debug|Any CPU + {FC862191-9081-4A58-96FF-B57F17AC40A9}.DebugTests|x86.ActiveCfg = Debug|Any CPU + {FC862191-9081-4A58-96FF-B57F17AC40A9}.DebugTests|x86.Build.0 = Debug|Any CPU + {FC862191-9081-4A58-96FF-B57F17AC40A9}.Release|Any CPU.ActiveCfg = Release|Any CPU + {FC862191-9081-4A58-96FF-B57F17AC40A9}.Release|Any CPU.Build.0 = Release|Any CPU + {FC862191-9081-4A58-96FF-B57F17AC40A9}.Release|x86.ActiveCfg = Release|Any CPU + {FC862191-9081-4A58-96FF-B57F17AC40A9}.Release|x86.Build.0 = Release|Any CPU + {6431E891-8E90-4510-AC8F-581536757EA0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6431E891-8E90-4510-AC8F-581536757EA0}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6431E891-8E90-4510-AC8F-581536757EA0}.Debug|x86.ActiveCfg = Debug|Any CPU + {6431E891-8E90-4510-AC8F-581536757EA0}.Debug|x86.Build.0 = Debug|Any CPU + {6431E891-8E90-4510-AC8F-581536757EA0}.DebugTests|Any CPU.ActiveCfg = DebugTests|Any CPU + {6431E891-8E90-4510-AC8F-581536757EA0}.DebugTests|Any CPU.Build.0 = DebugTests|Any CPU + {6431E891-8E90-4510-AC8F-581536757EA0}.DebugTests|x86.ActiveCfg = DebugTests|Any CPU + {6431E891-8E90-4510-AC8F-581536757EA0}.DebugTests|x86.Build.0 = DebugTests|Any CPU + {6431E891-8E90-4510-AC8F-581536757EA0}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6431E891-8E90-4510-AC8F-581536757EA0}.Release|Any CPU.Build.0 = Release|Any CPU + {6431E891-8E90-4510-AC8F-581536757EA0}.Release|x86.ActiveCfg = Release|Any CPU + {6431E891-8E90-4510-AC8F-581536757EA0}.Release|x86.Build.0 = Release|Any CPU + {8A2E5556-55A4-4A1C-BE82-7603BEFA1A19}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8A2E5556-55A4-4A1C-BE82-7603BEFA1A19}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8A2E5556-55A4-4A1C-BE82-7603BEFA1A19}.Debug|x86.ActiveCfg = Debug|Any CPU + {8A2E5556-55A4-4A1C-BE82-7603BEFA1A19}.Debug|x86.Build.0 = Debug|Any CPU + {8A2E5556-55A4-4A1C-BE82-7603BEFA1A19}.DebugTests|Any CPU.ActiveCfg = Debug|Any CPU + {8A2E5556-55A4-4A1C-BE82-7603BEFA1A19}.DebugTests|Any CPU.Build.0 = Debug|Any CPU + {8A2E5556-55A4-4A1C-BE82-7603BEFA1A19}.DebugTests|x86.ActiveCfg = Debug|Any CPU + {8A2E5556-55A4-4A1C-BE82-7603BEFA1A19}.DebugTests|x86.Build.0 = Debug|Any CPU + {8A2E5556-55A4-4A1C-BE82-7603BEFA1A19}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8A2E5556-55A4-4A1C-BE82-7603BEFA1A19}.Release|Any CPU.Build.0 = Release|Any CPU + {8A2E5556-55A4-4A1C-BE82-7603BEFA1A19}.Release|x86.ActiveCfg = Release|Any CPU + {8A2E5556-55A4-4A1C-BE82-7603BEFA1A19}.Release|x86.Build.0 = Release|Any CPU + {ACEE719B-B932-4B41-84AE-0F0CA0CE37E0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {ACEE719B-B932-4B41-84AE-0F0CA0CE37E0}.Debug|Any CPU.Build.0 = Debug|Any CPU + {ACEE719B-B932-4B41-84AE-0F0CA0CE37E0}.Debug|x86.ActiveCfg = Debug|Any CPU + {ACEE719B-B932-4B41-84AE-0F0CA0CE37E0}.Debug|x86.Build.0 = Debug|Any CPU + {ACEE719B-B932-4B41-84AE-0F0CA0CE37E0}.DebugTests|Any CPU.ActiveCfg = Debug|Any CPU + {ACEE719B-B932-4B41-84AE-0F0CA0CE37E0}.DebugTests|Any CPU.Build.0 = Debug|Any CPU + {ACEE719B-B932-4B41-84AE-0F0CA0CE37E0}.DebugTests|x86.ActiveCfg = Debug|Any CPU + {ACEE719B-B932-4B41-84AE-0F0CA0CE37E0}.DebugTests|x86.Build.0 = Debug|Any CPU + {ACEE719B-B932-4B41-84AE-0F0CA0CE37E0}.Release|Any CPU.ActiveCfg = Release|Any CPU + {ACEE719B-B932-4B41-84AE-0F0CA0CE37E0}.Release|Any CPU.Build.0 = Release|Any CPU + {ACEE719B-B932-4B41-84AE-0F0CA0CE37E0}.Release|x86.ActiveCfg = Release|Any CPU + {ACEE719B-B932-4B41-84AE-0F0CA0CE37E0}.Release|x86.Build.0 = Release|Any CPU + {06F6709E-56E5-41ED-9BC1-55A8F648DD72}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {06F6709E-56E5-41ED-9BC1-55A8F648DD72}.Debug|Any CPU.Build.0 = Debug|Any CPU + {06F6709E-56E5-41ED-9BC1-55A8F648DD72}.Debug|x86.ActiveCfg = Debug|x86 + {06F6709E-56E5-41ED-9BC1-55A8F648DD72}.Debug|x86.Build.0 = Debug|x86 + {06F6709E-56E5-41ED-9BC1-55A8F648DD72}.DebugTests|Any CPU.ActiveCfg = Debug|Any CPU + {06F6709E-56E5-41ED-9BC1-55A8F648DD72}.DebugTests|Any CPU.Build.0 = Debug|Any CPU + {06F6709E-56E5-41ED-9BC1-55A8F648DD72}.DebugTests|x86.ActiveCfg = Debug|x86 + {06F6709E-56E5-41ED-9BC1-55A8F648DD72}.DebugTests|x86.Build.0 = Debug|x86 + {06F6709E-56E5-41ED-9BC1-55A8F648DD72}.Release|Any CPU.ActiveCfg = Release|Any CPU + {06F6709E-56E5-41ED-9BC1-55A8F648DD72}.Release|x86.ActiveCfg = Release|x86 + {06F6709E-56E5-41ED-9BC1-55A8F648DD72}.Release|x86.Build.0 = Release|x86 + {20ED44A4-9D35-41F2-A317-C1EB9923379E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {20ED44A4-9D35-41F2-A317-C1EB9923379E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {20ED44A4-9D35-41F2-A317-C1EB9923379E}.Debug|x86.ActiveCfg = Debug|Any CPU + {20ED44A4-9D35-41F2-A317-C1EB9923379E}.Debug|x86.Build.0 = Debug|Any CPU + {20ED44A4-9D35-41F2-A317-C1EB9923379E}.DebugTests|Any CPU.ActiveCfg = Debug|Any CPU + {20ED44A4-9D35-41F2-A317-C1EB9923379E}.DebugTests|Any CPU.Build.0 = Debug|Any CPU + {20ED44A4-9D35-41F2-A317-C1EB9923379E}.DebugTests|x86.ActiveCfg = Debug|Any CPU + {20ED44A4-9D35-41F2-A317-C1EB9923379E}.DebugTests|x86.Build.0 = Debug|Any CPU + {20ED44A4-9D35-41F2-A317-C1EB9923379E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {20ED44A4-9D35-41F2-A317-C1EB9923379E}.Release|Any CPU.Build.0 = Release|Any CPU + {20ED44A4-9D35-41F2-A317-C1EB9923379E}.Release|x86.ActiveCfg = Release|Any CPU + {20ED44A4-9D35-41F2-A317-C1EB9923379E}.Release|x86.Build.0 = Release|Any CPU + {E8F7FB9B-4FF0-4195-B064-D41A96E41918}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E8F7FB9B-4FF0-4195-B064-D41A96E41918}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E8F7FB9B-4FF0-4195-B064-D41A96E41918}.Debug|x86.ActiveCfg = Debug|Any CPU + {E8F7FB9B-4FF0-4195-B064-D41A96E41918}.Debug|x86.Build.0 = Debug|Any CPU + {E8F7FB9B-4FF0-4195-B064-D41A96E41918}.DebugTests|Any CPU.ActiveCfg = Debug|Any CPU + {E8F7FB9B-4FF0-4195-B064-D41A96E41918}.DebugTests|Any CPU.Build.0 = Debug|Any CPU + {E8F7FB9B-4FF0-4195-B064-D41A96E41918}.DebugTests|x86.ActiveCfg = Debug|Any CPU + {E8F7FB9B-4FF0-4195-B064-D41A96E41918}.DebugTests|x86.Build.0 = Debug|Any CPU + {E8F7FB9B-4FF0-4195-B064-D41A96E41918}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E8F7FB9B-4FF0-4195-B064-D41A96E41918}.Release|Any CPU.Build.0 = Release|Any CPU + {E8F7FB9B-4FF0-4195-B064-D41A96E41918}.Release|x86.ActiveCfg = Release|Any CPU + {E8F7FB9B-4FF0-4195-B064-D41A96E41918}.Release|x86.Build.0 = Release|Any CPU + {7BD22418-F4A9-422B-9FDE-A20708BA0648}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7BD22418-F4A9-422B-9FDE-A20708BA0648}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7BD22418-F4A9-422B-9FDE-A20708BA0648}.Debug|x86.ActiveCfg = Debug|Any CPU + {7BD22418-F4A9-422B-9FDE-A20708BA0648}.Debug|x86.Build.0 = Debug|Any CPU + {7BD22418-F4A9-422B-9FDE-A20708BA0648}.DebugTests|Any CPU.ActiveCfg = Debug|Any CPU + {7BD22418-F4A9-422B-9FDE-A20708BA0648}.DebugTests|Any CPU.Build.0 = Debug|Any CPU + {7BD22418-F4A9-422B-9FDE-A20708BA0648}.DebugTests|x86.ActiveCfg = Debug|Any CPU + {7BD22418-F4A9-422B-9FDE-A20708BA0648}.DebugTests|x86.Build.0 = Debug|Any CPU + {7BD22418-F4A9-422B-9FDE-A20708BA0648}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7BD22418-F4A9-422B-9FDE-A20708BA0648}.Release|Any CPU.Build.0 = Release|Any CPU + {7BD22418-F4A9-422B-9FDE-A20708BA0648}.Release|x86.ActiveCfg = Release|Any CPU + {7BD22418-F4A9-422B-9FDE-A20708BA0648}.Release|x86.Build.0 = Release|Any CPU + {230C6FAF-11A1-4318-A482-69C7252652B1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {230C6FAF-11A1-4318-A482-69C7252652B1}.Debug|Any CPU.Build.0 = Debug|Any CPU + {230C6FAF-11A1-4318-A482-69C7252652B1}.Debug|x86.ActiveCfg = Debug|Any CPU + {230C6FAF-11A1-4318-A482-69C7252652B1}.Debug|x86.Build.0 = Debug|Any CPU + {230C6FAF-11A1-4318-A482-69C7252652B1}.DebugTests|Any CPU.ActiveCfg = Debug|Any CPU + {230C6FAF-11A1-4318-A482-69C7252652B1}.DebugTests|Any CPU.Build.0 = Debug|Any CPU + {230C6FAF-11A1-4318-A482-69C7252652B1}.DebugTests|x86.ActiveCfg = Debug|Any CPU + {230C6FAF-11A1-4318-A482-69C7252652B1}.DebugTests|x86.Build.0 = Debug|Any CPU + {230C6FAF-11A1-4318-A482-69C7252652B1}.Release|Any CPU.ActiveCfg = Release|Any CPU + {230C6FAF-11A1-4318-A482-69C7252652B1}.Release|Any CPU.Build.0 = Release|Any CPU + {230C6FAF-11A1-4318-A482-69C7252652B1}.Release|x86.ActiveCfg = Release|Any CPU + {230C6FAF-11A1-4318-A482-69C7252652B1}.Release|x86.Build.0 = Release|Any CPU + {BF019B75-CECE-46E7-9E3D-620B2CAB6A96}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {BF019B75-CECE-46E7-9E3D-620B2CAB6A96}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BF019B75-CECE-46E7-9E3D-620B2CAB6A96}.Debug|x86.ActiveCfg = Debug|Any CPU + {BF019B75-CECE-46E7-9E3D-620B2CAB6A96}.Debug|x86.Build.0 = Debug|Any CPU + {BF019B75-CECE-46E7-9E3D-620B2CAB6A96}.DebugTests|Any CPU.ActiveCfg = DebugTests|Any CPU + {BF019B75-CECE-46E7-9E3D-620B2CAB6A96}.DebugTests|Any CPU.Build.0 = DebugTests|Any CPU + {BF019B75-CECE-46E7-9E3D-620B2CAB6A96}.DebugTests|x86.ActiveCfg = DebugTests|Any CPU + {BF019B75-CECE-46E7-9E3D-620B2CAB6A96}.DebugTests|x86.Build.0 = DebugTests|Any CPU + {BF019B75-CECE-46E7-9E3D-620B2CAB6A96}.Release|Any CPU.ActiveCfg = Release|Any CPU + {BF019B75-CECE-46E7-9E3D-620B2CAB6A96}.Release|Any CPU.Build.0 = Release|Any CPU + {BF019B75-CECE-46E7-9E3D-620B2CAB6A96}.Release|x86.ActiveCfg = Release|Any CPU + {BF019B75-CECE-46E7-9E3D-620B2CAB6A96}.Release|x86.Build.0 = Release|Any CPU + {1C5CC61E-3080-42D8-BEE0-6113C8C57D5D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1C5CC61E-3080-42D8-BEE0-6113C8C57D5D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1C5CC61E-3080-42D8-BEE0-6113C8C57D5D}.Debug|x86.ActiveCfg = Debug|Any CPU + {1C5CC61E-3080-42D8-BEE0-6113C8C57D5D}.Debug|x86.Build.0 = Debug|Any CPU + {1C5CC61E-3080-42D8-BEE0-6113C8C57D5D}.DebugTests|Any CPU.ActiveCfg = DebugTests|Any CPU + {1C5CC61E-3080-42D8-BEE0-6113C8C57D5D}.DebugTests|Any CPU.Build.0 = DebugTests|Any CPU + {1C5CC61E-3080-42D8-BEE0-6113C8C57D5D}.DebugTests|x86.ActiveCfg = Debug|Any CPU + {1C5CC61E-3080-42D8-BEE0-6113C8C57D5D}.DebugTests|x86.Build.0 = Debug|Any CPU + {1C5CC61E-3080-42D8-BEE0-6113C8C57D5D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1C5CC61E-3080-42D8-BEE0-6113C8C57D5D}.Release|Any CPU.Build.0 = Release|Any CPU + {1C5CC61E-3080-42D8-BEE0-6113C8C57D5D}.Release|x86.ActiveCfg = Release|Any CPU + {1C5CC61E-3080-42D8-BEE0-6113C8C57D5D}.Release|x86.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {ACCC10D0-D079-4B9C-8269-71796A0EF822} = {8F9E5ECE-A6EB-4DC7-B3E2-20319BF21607} + {3FBD73F5-6098-45A8-A236-6CC2F093B804} = {8F9E5ECE-A6EB-4DC7-B3E2-20319BF21607} + {1A96AA51-2CBC-4901-91D1-53208AD5E6B6} = {8F9E5ECE-A6EB-4DC7-B3E2-20319BF21607} + {0926FE28-73BA-4F73-9188-B196FBBC9410} = {8F9E5ECE-A6EB-4DC7-B3E2-20319BF21607} + {A4BDB41D-096A-42E7-953E-99F7680141B0} = {2DAB661A-26B2-440A-BC54-59F2C8404F12} + {FC862191-9081-4A58-96FF-B57F17AC40A9} = {8F9E5ECE-A6EB-4DC7-B3E2-20319BF21607} + {6431E891-8E90-4510-AC8F-581536757EA0} = {2DAB661A-26B2-440A-BC54-59F2C8404F12} + {8A2E5556-55A4-4A1C-BE82-7603BEFA1A19} = {8F9E5ECE-A6EB-4DC7-B3E2-20319BF21607} + {ACEE719B-B932-4B41-84AE-0F0CA0CE37E0} = {2DAB661A-26B2-440A-BC54-59F2C8404F12} + {06F6709E-56E5-41ED-9BC1-55A8F648DD72} = {8F9E5ECE-A6EB-4DC7-B3E2-20319BF21607} + {20ED44A4-9D35-41F2-A317-C1EB9923379E} = {8F9E5ECE-A6EB-4DC7-B3E2-20319BF21607} + {E8F7FB9B-4FF0-4195-B064-D41A96E41918} = {8F9E5ECE-A6EB-4DC7-B3E2-20319BF21607} + {7BD22418-F4A9-422B-9FDE-A20708BA0648} = {8F9E5ECE-A6EB-4DC7-B3E2-20319BF21607} + {230C6FAF-11A1-4318-A482-69C7252652B1} = {2DAB661A-26B2-440A-BC54-59F2C8404F12} + {BF019B75-CECE-46E7-9E3D-620B2CAB6A96} = {2DAB661A-26B2-440A-BC54-59F2C8404F12} + {1C5CC61E-3080-42D8-BEE0-6113C8C57D5D} = {2DAB661A-26B2-440A-BC54-59F2C8404F12} + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {B153C707-A96B-404C-B0E6-2225AE14B304} + EndGlobalSection +EndGlobal diff --git a/src/AspectInjector.Analyzer.Vsix/AspectInjector.Analyzer.Vsix.csproj b/src/AspectInjector.Analyzer.Vsix/AspectInjector.Analyzer.Vsix.csproj old mode 100644 new mode 100755 index 0060da76..507c34a7 --- a/src/AspectInjector.Analyzer.Vsix/AspectInjector.Analyzer.Vsix.csproj +++ b/src/AspectInjector.Analyzer.Vsix/AspectInjector.Analyzer.Vsix.csproj @@ -60,7 +60,7 @@ - + {7bd22418-f4a9-422b-9fde-a20708ba0648} FluentIL.Common diff --git a/src/AspectInjector.Analyzer/AspectInjector.Analyzer.csproj b/src/AspectInjector.Analyzer/AspectInjector.Analyzer.csproj old mode 100644 new mode 100755 index 76930355..610e107e --- a/src/AspectInjector.Analyzer/AspectInjector.Analyzer.csproj +++ b/src/AspectInjector.Analyzer/AspectInjector.Analyzer.csproj @@ -1,4 +1,4 @@ - + netstandard2.0 @@ -18,7 +18,7 @@ - + diff --git a/src/AspectInjector.Core/AspectInjector.Core.csproj b/src/AspectInjector.Core/AspectInjector.Core.csproj index bb2eee81..5ee09647 100755 --- a/src/AspectInjector.Core/AspectInjector.Core.csproj +++ b/src/AspectInjector.Core/AspectInjector.Core.csproj @@ -1,4 +1,4 @@ - + netstandard2.0 This is core library of Aspect Injector. @@ -9,7 +9,7 @@ - + diff --git a/src/AspectInjector.Rules/AspectInjector.Rules.csproj b/src/AspectInjector.Rules/AspectInjector.Rules.csproj old mode 100644 new mode 100755 index 1942b9f0..c8583d2e --- a/src/AspectInjector.Rules/AspectInjector.Rules.csproj +++ b/src/AspectInjector.Rules/AspectInjector.Rules.csproj @@ -1,9 +1,9 @@ - + netstandard2.0 - + diff --git a/src/AspectInjector/AspectInjector.csproj b/src/AspectInjector/AspectInjector.csproj index e71a4ad9..07394508 100755 --- a/src/AspectInjector/AspectInjector.csproj +++ b/src/AspectInjector/AspectInjector.csproj @@ -20,7 +20,6 @@ true false false - link none diff --git a/src/FluentIL.Common/FluentIL.Common.csproj b/src/FluentIL.Common/FluentIL.Common.csproj new file mode 100644 index 00000000..f736fc41 --- /dev/null +++ b/src/FluentIL.Common/FluentIL.Common.csproj @@ -0,0 +1,5 @@ + + + netstandard2.0 + + diff --git a/src/FluentIL.Common/Rule.cs b/src/FluentIL.Common/Rule.cs new file mode 100644 index 00000000..efa918b9 --- /dev/null +++ b/src/FluentIL.Common/Rule.cs @@ -0,0 +1,31 @@ +namespace FluentIL.Common +{ + public enum RuleSeverity + { + Hidden, + Info, + Warning, + Error + } + + public class Rule + { + + public Rule(string id, string title, string message, RuleSeverity severity, string description, string helpLinkUri) + { + Id = id; + Title = title; + Message = message; + Severity = severity; + Description = description; + HelpLinkUri = helpLinkUri; + } + + public string Id { get; } + public string Title { get; } + public string Message { get; } + public RuleSeverity Severity { get; } + public string Description { get; } + public string HelpLinkUri { get; } + } +} diff --git a/src/FluentIL/Cuts/Arrays.cs b/src/FluentIL/Cuts/Arrays.cs new file mode 100644 index 00000000..03b1ff00 --- /dev/null +++ b/src/FluentIL/Cuts/Arrays.cs @@ -0,0 +1,94 @@ +using FluentIL.Extensions; +using Mono.Cecil; +using Mono.Cecil.Cil; +using System; + +namespace FluentIL +{ + public static class Arrays + { + public static Cut CreateArray(this in Cut cut, TypeReference elementType, params PointCut[] elements) + { + var pc = cut + .Write(OpCodes.Ldc_I4, elements.Length) + .Write(OpCodes.Newarr, elementType); + + for (var i = 0; i < elements.Length; i++) + { + pc = pc.Write(OpCodes.Dup); + pc = SetByIndex(pc, elementType, i, elements[i]); + } + + return pc; + } + + public static Cut GetByIndex(this in Cut pc, TypeReference elementType, int index) + { + return pc + .Write(OpCodes.Ldc_I4, index) + .Write(GetLoadOpcode(elementType)); + } + + public static Cut SetByIndex(this in Cut pc, TypeReference elementType, int index, PointCut value) + { + return pc + .Write(OpCodes.Ldc_I4, index) + .Here(value) + .Write(GetStoreOpcode(elementType)); + } + + private static OpCode GetLoadOpcode(TypeReference elementType) + { + switch (elementType.MetadataType) + { + case MetadataType.Class: return OpCodes.Ldelem_Ref; + case MetadataType.Object: return OpCodes.Ldelem_Ref; + case MetadataType.Double: return OpCodes.Ldelem_R8; + case MetadataType.Single: return OpCodes.Ldelem_R4; + case MetadataType.Int64: return OpCodes.Ldelem_I8; + case MetadataType.UInt64: return OpCodes.Ldelem_I8; + case MetadataType.Int32: return OpCodes.Ldelem_I4; + case MetadataType.UInt32: return OpCodes.Ldelem_U4; + case MetadataType.Int16: return OpCodes.Ldelem_I2; + case MetadataType.UInt16: return OpCodes.Ldelem_U2; + case MetadataType.Byte: return OpCodes.Ldelem_U1; + case MetadataType.SByte: return OpCodes.Ldelem_I1; + case MetadataType.Boolean: return OpCodes.Ldelem_I1; + case MetadataType.String: return OpCodes.Ldelem_Ref; + } + + throw new NotSupportedException($"No instruction for {elementType.MetadataType}"); + } + + + private static OpCode GetStoreOpcode(TypeReference elementType) + { + if(elementType.IsValueType && !elementType.IsPrimitive) + { + var r = elementType.Resolve(); + if (r.IsEnum) + elementType = r.GetEnumType(); + } + + switch (elementType.MetadataType) + { + case MetadataType.Class: return OpCodes.Stelem_Ref; + case MetadataType.Object: return OpCodes.Stelem_Ref; + case MetadataType.Double: return OpCodes.Stelem_R8; + case MetadataType.Single: return OpCodes.Stelem_R4; + case MetadataType.Int64: return OpCodes.Stelem_I8; + case MetadataType.UInt64: return OpCodes.Stelem_I8; + case MetadataType.Int32: return OpCodes.Stelem_I4; + case MetadataType.UInt32: return OpCodes.Stelem_I4; + case MetadataType.Int16: return OpCodes.Stelem_I2; + case MetadataType.UInt16: return OpCodes.Stelem_I2; + case MetadataType.Byte: return OpCodes.Stelem_I1; + case MetadataType.SByte: return OpCodes.Stelem_I1; + case MetadataType.Boolean: return OpCodes.Stelem_I1; + case MetadataType.String: return OpCodes.Stelem_Ref; + } + + throw new NotSupportedException($"No instruction for {elementType.MetadataType}"); + } + } +} diff --git a/src/FluentIL/Cuts/Statements.cs b/src/FluentIL/Cuts/Statements.cs new file mode 100644 index 00000000..1c9dc5b0 --- /dev/null +++ b/src/FluentIL/Cuts/Statements.cs @@ -0,0 +1,79 @@ +using FluentIL.Extensions; +using Mono.Cecil; +using Mono.Cecil.Cil; +using System; + +namespace FluentIL +{ + public static class Statements + { + public static Cut Return(this in Cut cut) + { + return cut.Write(OpCodes.Ret); + } + + public static Cut Call(this in Cut cut, MethodReference method, PointCut args = null) + { + var cur_cut = cut; + + if (!method.IsCallCompatible()) + throw new ArgumentException($"Uninitialized generic call reference: {method}"); + + if (args != null) cur_cut = cur_cut.Here(args); + + var methodDef = method.Resolve(); + + var code = OpCodes.Call; + if (methodDef.IsConstructor) code = OpCodes.Newobj; + else if (methodDef.IsVirtual) code = OpCodes.Callvirt; + + return cur_cut.Write(code, method); + } + + public static Cut IfEqual(this in Cut pc, PointCut left, PointCut right, PointCut pos = null, PointCut neg = null) + { + if (pos != null && neg != null) + return Compare(pc, left, right, OpCodes.Ceq, pos, neg); + + if (pos != null) + return Compare(pc, left, right, OpCodes.Ceq, OpCodes.Brfalse, pos); + + if (neg != null) + return Compare(pc, left, right, OpCodes.Ceq, OpCodes.Brtrue, neg); + + return pc; + } + + private static Cut Compare(in Cut cut, PointCut left, PointCut right, OpCode cmp, PointCut pos, PointCut neg) + { + var pc = cut + .Here(left) + .Here(right) + .Write(cmp); + + var pe = pc.Here(pos); + var ne = pe.Here(neg); + + var exit = ne.Write(OpCodes.Nop); + + pc.Write(OpCodes.Brfalse, pe.Next()); + pe.Write(OpCodes.Br, exit); + + return exit; + } + + private static Cut Compare(in Cut cut, PointCut left, PointCut right, OpCode cmp, OpCode brexit, PointCut action) + { + var pc = cut + .Here(left) + .Here(right) + .Write(cmp); + + var exit = pc.Write(OpCodes.Nop); + + pc.Write(brexit, exit).Here(action); + + return exit; + } + } +} diff --git a/src/FluentIL/Cuts/TypeMembers.cs b/src/FluentIL/Cuts/TypeMembers.cs new file mode 100644 index 00000000..06d8a162 --- /dev/null +++ b/src/FluentIL/Cuts/TypeMembers.cs @@ -0,0 +1,86 @@ +using FluentIL.Extensions; +using Mono.Cecil; +using Mono.Cecil.Cil; +using System; + +namespace FluentIL +{ + public static class TypeMembers + { + public static Cut ThisOrStatic(this in Cut cut) => + cut.Method.HasThis ? cut.This() : cut; + + public static Cut ThisOrNull(this in Cut cut) => + cut.Method.HasThis ? cut.This() : cut.Null(); + + public static Cut This(this in Cut cut) + { + if (cut.Method.HasThis) return cut.Write(OpCodes.Ldarg_0); + else throw new InvalidOperationException("Attempt to load 'this' on static method."); + } + + public static Cut Load(this in Cut cut, VariableDefinition variable) => cut + .Write(OpCodes.Ldloc, variable); + + public static Cut Load(this in Cut cut, ParameterReference par) => cut + .Write(OpCodes.Ldarg, par.Resolve()); + + public static Cut Load(this in Cut cut, FieldReference field) + { + if(!field.IsCallCompatible()) + throw new ArgumentException($"Uninitialized generic call reference: {field}"); + + var fieldDef = field.Resolve(); + + return cut.Write(fieldDef.IsStatic ? OpCodes.Ldsfld : OpCodes.Ldfld, field); + } + + public static Cut LoadRef(this in Cut cut, VariableDefinition variable) => cut + .Write(OpCodes.Ldloca, variable); + + public static Cut LoadRef(this in Cut cut, ParameterReference par) => cut + .Write(OpCodes.Ldarga, par.Resolve()); + + public static Cut LoadRef(this in Cut cut, FieldReference field) + { + if (!field.IsCallCompatible()) + throw new ArgumentException($"Uninitialized generic call reference: {field}"); + + var fieldDef = field.Resolve(); + + return cut.Write(fieldDef.IsStatic ? OpCodes.Ldsflda : OpCodes.Ldflda, field); + } + + public static Cut Store(this in Cut cut, FieldReference field, PointCut value = null) + { + if (!field.IsCallCompatible()) + throw new ArgumentException($"Uninitialized generic call reference: {field}"); + + var fieldDef = field.Resolve(); + + return cut + .Here(value) + .Write(fieldDef.IsStatic ? OpCodes.Stsfld : OpCodes.Stfld, field); + } + + public static Cut Store(this in Cut cut, VariableDefinition variable, PointCut value = null) => cut + .Here(value) + .Write(OpCodes.Stloc, variable); + + public static Cut Store(this in Cut cut, ParameterReference par, PointCut value = null) + { + if (par.ParameterType.IsByReference) + { + return cut + .Load(par) + .Here(value); + } + else + { + return cut + .Here(value) + .Write(OpCodes.Starg, par.Resolve()); + } + } + } +} diff --git a/src/FluentIL/Cuts/Values.cs b/src/FluentIL/Cuts/Values.cs new file mode 100644 index 00000000..161ad898 --- /dev/null +++ b/src/FluentIL/Cuts/Values.cs @@ -0,0 +1,219 @@ +using FluentIL.Extensions; +using Mono.Cecil; +using Mono.Cecil.Cil; +using System; +using System.Linq; + +namespace FluentIL +{ + public static class Values + { + public static Cut Pop(this in Cut pc) => pc + .Write(OpCodes.Pop); + + public static Cut Null(this in Cut pc) => pc + .Write(OpCodes.Ldnull); + + public static Cut Dup(this in Cut pc) => pc + .Write(OpCodes.Dup); + + public static Cut Delegate(this in Cut cut, MethodReference method) => cut + .Write(OpCodes.Ldftn, method); + + public static Cut TypeOf(this in Cut cut, TypeReference type) => cut + .Write(OpCodes.Ldtoken, type) + .Write(OpCodes.Call, GetTypeFromHandleMethod_Ref(cut)); + + public static Cut MethodOf(this in Cut cut, MethodReference method) => cut + .Write(OpCodes.Ldtoken, method) + .Write(OpCodes.Ldtoken, method.DeclaringType) + .Write(OpCodes.Call, GetMethodFromHandleMethod_Ref(cut)); + + public static Cut Value(this in Cut pc, object value) + { + if (value == null) + return Null(pc); + + var valueType = value.GetType(); + + if (value is CustomAttributeArgument argument) + return AttributeArgument(pc, argument); + else if (value is TypeReference tr) + return TypeOf(pc, tr); + else if (valueType.IsValueType) + return Primitive(pc, value); + else if (value is string str) + return pc.Write(OpCodes.Ldstr, str); + else + throw new NotSupportedException(valueType.ToString()); + } + + public static Cut Primitive(this in Cut pc, object value) + { + var valueType = value.GetType(); + + switch (value) + { +#pragma warning disable S2583 // Conditionally executed code should be reachable + case bool bo: return pc.Write(bo ? OpCodes.Ldc_I4_1 : OpCodes.Ldc_I4_0); +#pragma warning restore S2583 // Conditionally executed code should be reachable + case long l: return pc.Write(OpCodes.Ldc_I8, l); + case ulong ul: return pc.Write(OpCodes.Ldc_I8, unchecked((long)ul)); + case double d: return pc.Write(OpCodes.Ldc_R8, d); + case int i: return pc.Write(OpCodes.Ldc_I4, i); + case uint ui: return pc.Write(OpCodes.Ldc_I4, unchecked((int)ui)); + case float fl: return pc.Write(OpCodes.Ldc_R4, fl); + case sbyte sb: return pc.Write(OpCodes.Ldc_I4, (int)sb); + case byte b: return pc.Write(OpCodes.Ldc_I4, (int)b); + case ushort us: return pc.Write(OpCodes.Ldc_I4, us); + case short s: return pc.Write(OpCodes.Ldc_I4, s); + case char c: return pc.Write(OpCodes.Ldc_I4, c); + + default: throw new NotSupportedException(valueType.ToString()); + } + } + + public static Cut Cast(this in Cut cut, TypeReference typeOnStack, TypeReference expectedType) + { + var result = cut; + + if (typeOnStack.Match(expectedType)) + return result; + + if (expectedType.IsByReference) + { + var elementType = ((ByReferenceType)expectedType).ElementType; + result = result.Cast(typeOnStack, elementType); + return StoreByReference(result, elementType); + } + + if (typeOnStack.IsByReference) + { + typeOnStack = ((ByReferenceType)typeOnStack).ElementType; + result = LoadByReference(result, typeOnStack); + } + + if (typeOnStack.Match(expectedType)) + return result; + + if (expectedType.IsValueType || expectedType.IsGenericParameter) + { + if (!typeOnStack.IsValueType) + return result.Write(OpCodes.Unbox_Any, expectedType); + } + else + { + if (typeOnStack.IsValueType || typeOnStack.IsGenericParameter) + return result.Write(OpCodes.Box, typeOnStack); + else if (!expectedType.Match(cut.TypeSystem.Object)) + return result.Write(OpCodes.Castclass, expectedType); + else + return result; + } + + throw new InvalidCastException($"Cannot cast '{typeOnStack}' to '{expectedType}'"); + } + + private static Cut StoreByReference(in Cut pc, TypeReference elemType) + { + switch (elemType.MetadataType) + { + case MetadataType.Class: return pc.Write(OpCodes.Stind_Ref); + case MetadataType.Object: return pc.Write(OpCodes.Stind_Ref); + case MetadataType.String: return pc.Write(OpCodes.Stind_Ref); + case MetadataType.Array: return pc.Write(OpCodes.Stind_Ref); + case MetadataType.MVar: return pc.Write(OpCodes.Stobj, elemType); + case MetadataType.Var: return pc.Write(OpCodes.Stobj, elemType); + case MetadataType.ValueType: return pc.Write(OpCodes.Stobj, elemType); + case MetadataType.GenericInstance: return pc.Write(OpCodes.Stobj, elemType); + case MetadataType.Double: return pc.Write(OpCodes.Stind_R8); + case MetadataType.Single: return pc.Write(OpCodes.Stind_R4); + case MetadataType.Int64: return pc.Write(OpCodes.Stind_I8); + case MetadataType.UInt64: return pc.Write(OpCodes.Stind_I8); + case MetadataType.Int32: return pc.Write(OpCodes.Stind_I4); + case MetadataType.UInt32: return pc.Write(OpCodes.Stind_I4); + case MetadataType.Int16: return pc.Write(OpCodes.Stind_I2); + case MetadataType.UInt16: return pc.Write(OpCodes.Stind_I2); + case MetadataType.Byte: return pc.Write(OpCodes.Stind_I1); + case MetadataType.SByte: return pc.Write(OpCodes.Stind_I1); + case MetadataType.Boolean: return pc.Write(OpCodes.Stind_I1); + case MetadataType.Char: return pc.Write(OpCodes.Stind_I2); + case MetadataType.UIntPtr: return pc.Write(OpCodes.Stind_I); + case MetadataType.IntPtr: return pc.Write(OpCodes.Stind_I); + } + + throw new NotSupportedException($"No instruction for {elemType.MetadataType}"); + } + + private static Cut LoadByReference(in Cut pc, TypeReference elemType) + { + switch (elemType.MetadataType) + { + case MetadataType.Class: return pc.Write(OpCodes.Ldind_Ref); + case MetadataType.Object: return pc.Write(OpCodes.Ldind_Ref); + case MetadataType.String: return pc.Write(OpCodes.Ldind_Ref); + case MetadataType.Array: return pc.Write(OpCodes.Ldind_Ref); + case MetadataType.MVar: return pc.Write(OpCodes.Ldobj, elemType); + case MetadataType.Var: return pc.Write(OpCodes.Ldobj, elemType); + case MetadataType.ValueType: return pc.Write(OpCodes.Ldobj, elemType); + case MetadataType.GenericInstance: return pc.Write(OpCodes.Ldobj, elemType); + case MetadataType.Double: return pc.Write(OpCodes.Ldind_R8); + case MetadataType.Single: return pc.Write(OpCodes.Ldind_R4); + case MetadataType.Int64: return pc.Write(OpCodes.Ldind_I8); + case MetadataType.UInt64: return pc.Write(OpCodes.Ldind_I8); + case MetadataType.Int32: return pc.Write(OpCodes.Ldind_I4); + case MetadataType.UInt32: return pc.Write(OpCodes.Ldind_U4); + case MetadataType.Int16: return pc.Write(OpCodes.Ldind_I2); + case MetadataType.UInt16: return pc.Write(OpCodes.Ldind_U2); + case MetadataType.Byte: return pc.Write(OpCodes.Ldind_U1); + case MetadataType.SByte: return pc.Write(OpCodes.Ldind_I1); + case MetadataType.Boolean: return pc.Write(OpCodes.Ldind_U1); + case MetadataType.Char: return pc.Write(OpCodes.Ldind_U2); + case MetadataType.UIntPtr: return pc.Write(OpCodes.Ldind_I); + case MetadataType.IntPtr: return pc.Write(OpCodes.Ldind_I); + } + + throw new NotSupportedException($"No instruction for {elemType.MetadataType}"); + } + + private static Cut AttributeArgument(in Cut cut, CustomAttributeArgument argument) + { + var val = argument.Value; + + var pc = cut; + + if (val != null && val.GetType().IsArray) + pc = pc.CreateArray( + argument.Type.GetElementType(), + ((Array)val).Cast().Select(v => (in Cut il) => il.Value(v)).ToArray() + ); + else + { + pc = pc.Value(val); + + if (val is CustomAttributeArgument next) + pc = pc.Cast(next.Type, argument.Type); + } + + return pc; + } + + private static MethodReference GetTypeFromHandleMethod_Ref(in Cut cut) + { + var tref = cut.Import(StandardType.Type); + var mr = new MethodReference("GetTypeFromHandle", tref, tref); + mr.Parameters.Add(new ParameterDefinition(cut.Import(StandardType.RuntimeTypeHandle))); + + return mr; + } + + private static MethodReference GetMethodFromHandleMethod_Ref(in Cut cut) + { + var mbref = cut.Import(StandardType.MethodBase); + var mr = new MethodReference("GetMethodFromHandle", mbref, mbref); + mr.Parameters.Add(new ParameterDefinition(cut.Import(StandardType.RuntimeMethodHandle))); + mr.Parameters.Add(new ParameterDefinition(cut.Import(StandardType.RuntimeTypeHandle))); + return mr; + } + } +} diff --git a/src/FluentIL/Extensions/CecilReferenceExtensions.cs b/src/FluentIL/Extensions/CecilReferenceExtensions.cs new file mode 100644 index 00000000..1cbb4089 --- /dev/null +++ b/src/FluentIL/Extensions/CecilReferenceExtensions.cs @@ -0,0 +1,71 @@ +using Mono.Cecil; +using System; +using System.Linq; + +namespace FluentIL.Extensions +{ + public static class CecilReferenceExtensions + { + public static bool Match(this TypeReference tr1, TypeReference tr2) + { + if (tr1 == null || tr2 == null) + return false; + + if (tr1 == tr2) return true; + + return tr1.FullName == tr2.FullName; + } + + public static bool Match(this TypeReference tr1, StandardType type) + { + if (tr1 == null || type == null) + return false; + + return tr1.FullName == type.ToString(); + } + + public static bool Implements(this TypeReference tr, TypeReference @interface) + { + var td = tr.Resolve(); + var ti = @interface; + + return td.Interfaces.Any(i => i.InterfaceType.Match(ti)) || (td.BaseType != null && td.BaseType.Implements(ti)); + } + + public static bool IsAsync(this MethodDefinition m) + { + return m.CustomAttributes.Any(a => a.AttributeType.Match(StandardType.AsyncStateMachineAttribute)); + } + + public static bool IsIterator(this MethodDefinition m) + { + return m.CustomAttributes.Any(a => a.AttributeType.Match(StandardType.IteratorStateMachineAttribute)); + } + + public static bool IsUnsafe(this MethodDefinition m) + { + return m.ReturnType.IsPointer || m.Parameters.Any(p => p.ParameterType.IsPointer); + } + + public static bool IsNormalMethod(this MethodDefinition m) + { + return !m.IsAddOn && !m.IsRemoveOn && !m.IsSetter && !m.IsGetter && !m.IsConstructor; + } + + public static bool IsExplicitImplementationOf(this MethodDefinition m, MethodReference ifaceMethod) + { + if (m.Overrides.Any(o => o.FullName == ifaceMethod.FullName)) + return true; + + return false; + } + + public static TypeReference GetEnumType(this TypeDefinition enumtype) + { + if (!enumtype.IsEnum) + throw new InvalidOperationException($"{enumtype.Name} is not enum"); + + return enumtype.Fields.First(f => f.Name == "value__").FieldType; + } + } +} \ No newline at end of file diff --git a/src/FluentIL/Extensions/GenericsExtensions.cs b/src/FluentIL/Extensions/GenericsExtensions.cs new file mode 100644 index 00000000..0efe45f2 --- /dev/null +++ b/src/FluentIL/Extensions/GenericsExtensions.cs @@ -0,0 +1,29 @@ +using Mono.Cecil; +using Mono.Collections.Generic; + +namespace FluentIL.Extensions +{ + public static class GenericsExtensions + { + public static void CloneTo(this Collection from, IGenericParameterProvider to) + { + foreach (var from_param in from) + { + to.GenericParameters.Add(new GenericParameter(from_param.Name, to) + { + Attributes = from_param.Attributes, + IsValueType = from_param.IsValueType + }); + } + + foreach (var from_param in from) + { + var to_param = to.GenericParameters[from_param.Position]; + foreach (var from_constraint in from_param.Constraints) + { + to_param.Constraints.Add(new GenericParameterConstraint(to.Module.ImportReference(from_constraint.ConstraintType, to))); + } + } + } + } +} diff --git a/src/FluentIL/Extensions/MemberDefinitionExtensions.cs b/src/FluentIL/Extensions/MemberDefinitionExtensions.cs new file mode 100644 index 00000000..4df94ebc --- /dev/null +++ b/src/FluentIL/Extensions/MemberDefinitionExtensions.cs @@ -0,0 +1,107 @@ +using Mono.Cecil; +using Mono.Cecil.Rocks; +using System; +using System.Linq; + +namespace FluentIL.Extensions +{ + public static class MemberDefinitionExtensions + { + public static PropertyDefinition FindProperty(this TypeDefinition typeDef, string name) + { + var result = typeDef.Properties.FirstOrDefault(p => p.Name == name); + + if(result == null && typeDef.BaseType != null) + { + result = typeDef.BaseType.Resolve().FindProperty(name); + } + + return result; + } + + public static FieldDefinition FindField(this TypeDefinition typeDef, string name) + { + var result = typeDef.Fields.FirstOrDefault(p => p.Name == name); + + if (result == null && typeDef.BaseType != null) + { + result = typeDef.BaseType.Resolve().FindField(name); + } + + return result; + } + + public static bool IsCallCompatible(this MemberReference member) + { + if (member is TypeReference typeRef) + return !typeRef.HasGenericParameters; + + if (member is MethodReference methodRef) + return !methodRef.HasGenericParameters && + methodRef.DeclaringType.IsCallCompatible(); + + if (member is FieldReference fieldRef) + return fieldRef.DeclaringType.IsCallCompatible(); + + throw new NotSupportedException($"{member.GetType().Name} is not callable"); + } + + public static TypeReference MakeSelfReference(this TypeDefinition definition) + { + TypeReference reference = definition; + if (definition.HasGenericParameters) + reference = definition.MakeGenericInstanceType(definition.GenericParameters.ToArray()); + return reference; + } + + public static FieldReference MakeReference(this FieldDefinition definition, TypeReference ownerTypeRef) + { + if (!ownerTypeRef.IsCallCompatible()) + throw new ArgumentException($"Owner type is not call compatible", nameof(ownerTypeRef)); + + return new FieldReference(definition.Name, ownerTypeRef.Module.ImportReference(definition.FieldType), ownerTypeRef); + } + + public static MethodReference MakeReference(this MethodReference definition, TypeReference ownerTypeRef) + { + if (!ownerTypeRef.IsCallCompatible()) + throw new ArgumentException($"Owner type is not call compatible", nameof(ownerTypeRef)); + + var reference = new MethodReference(definition.Name, ownerTypeRef.Module.ImportReference(definition.ReturnType), ownerTypeRef); + + reference.HasThis = definition.HasThis; + reference.ExplicitThis = definition.ExplicitThis; + reference.CallingConvention = definition.CallingConvention; + + definition.GenericParameters.CloneTo(reference); + + foreach (var par in definition.Parameters) + reference.Parameters.Add(par); + + return reference; + } + + public static GenericInstanceMethod MakeGenericInstanceMethod(this MethodReference self, params TypeReference[] arguments) + { + if (self == null) + throw new ArgumentNullException(nameof(self)); + + if (arguments == null) + throw new ArgumentNullException(nameof(arguments)); + + if (arguments.Length == 0) + throw new ArgumentException("Expected non-zero arguments"); + + if (self.GenericParameters.Count != arguments.Length) + throw new ArgumentException("Expected arguments == method.genericparams.count"); + + var genericInstanceMethod = new GenericInstanceMethod(self); + foreach (TypeReference item in arguments) + { + genericInstanceMethod.GenericArguments.Add(item); + } + + return genericInstanceMethod; + } + } +} diff --git a/src/FluentIL/Extensions/PointCutExtensions.cs b/src/FluentIL/Extensions/PointCutExtensions.cs new file mode 100644 index 00000000..d7ffbd00 --- /dev/null +++ b/src/FluentIL/Extensions/PointCutExtensions.cs @@ -0,0 +1,19 @@ +using Mono.Cecil; +using Mono.Cecil.Cil; + +namespace FluentIL.Extensions +{ + public static class PointCutExtensions + { + public static Cut Write(this in Cut pc, OpCode opCode, object operand) => pc.Write(pc.Emit(opCode, operand)); + public static Cut Write(this in Cut pc, OpCode opCode) => pc.Write(pc.Emit(opCode)); + + public static Cut Replace(this in Cut pc, OpCode opCode, object operand) => pc.Replace(pc.Emit(opCode, operand)); + public static Cut Replace(this in Cut pc, OpCode opCode) => pc.Replace(pc.Emit(opCode)); + + public static TypeReference Import(this in Cut cut, TypeReference tr) => cut.Method.Module.ImportReference(tr); + public static TypeReference Import(this in Cut cut, StandardType st) => cut.Method.Module.ImportStandardType(st); + public static MethodReference Import(this in Cut cut, MethodReference mr) => cut.Method.Module.ImportReference(mr); + public static FieldReference Import(this in Cut cut, FieldReference fr) => cut.Method.Module.ImportReference(fr); + } +} diff --git a/src/FluentIL/Extensions/TypeSystemExtension.cs b/src/FluentIL/Extensions/TypeSystemExtension.cs new file mode 100644 index 00000000..866d1300 --- /dev/null +++ b/src/FluentIL/Extensions/TypeSystemExtension.cs @@ -0,0 +1,101 @@ +using Mono.Cecil; +using Mono.Cecil.Rocks; +using System; +using System.Collections.Generic; +using System.Linq; + +namespace FluentIL.Extensions +{ + public static class TypeSystemExtension + { + private static readonly Dictionary<(StandardType, ModuleDefinition), TypeReference> _typeCache = new Dictionary<(StandardType, ModuleDefinition), TypeReference>(); + private static readonly List<(string, ModuleDefinition)> _invalidHints = new List<(string, ModuleDefinition)>(); + public static TypeReference ImportStandardType(this ModuleDefinition module, StandardType standardType) + { + var tr = GetTypeRef(standardType, module); + return module.ImportReference(tr); + } + + private static TypeReference GetTypeRef(StandardType type, ModuleDefinition module) + { + if (!_typeCache.TryGetValue((type, module), out var tr)) + { + var lib = GetMetadataScope(module, type); + tr = new TypeReference(type.Namespace, type.Name, module, lib, type.IsValueType); + + if (type.Elements.Count > 0) + { + for (int i = 0; i < type.Elements.Count; i++) + { + tr.GenericParameters.Add(new GenericParameter(tr)); + } + + tr = module.ImportReference(tr); + tr = tr.MakeGenericInstanceType(type.Elements.Select(e => GetTypeRef(e, module)).ToArray()); + } + + tr = module.ImportReference(tr); + if (tr.Resolve() == null) + throw new InvalidOperationException($"'{type}' not a part of standard lib."); + + if (type.IsArray) + tr = new ArrayType(tr); + + _typeCache[(type, module)] = tr; + } + + return tr; + } + + private static IMetadataScope GetMetadataScope(ModuleDefinition module, StandardType type) + { + if (type.AssemblyHints.Count == 0) + return module.TypeSystem.CoreLibrary; + + foreach (var hint in type.AssemblyHints) + { + if (_invalidHints.Contains((hint, module))) + continue; + + var assmName = new AssemblyNameReference(hint, new Version()); + + AssemblyDefinition assm = null; + try + { + assm = module.AssemblyResolver.Resolve(assmName); + } + catch + { + _invalidHints.Add((hint, module)); + continue; + } + + var reftype = assm.MainModule.GetTypes().FirstOrDefault(t => t.Namespace == type.Namespace && t.Name == type.Name); + if (reftype == null) continue; + + assmName = AssemblyNameReference.Parse(assm.FullName); + + if (!module.AssemblyReferences.Contains(assmName, AssemblyNameReferenceComparer.Instance)) + module.AssemblyReferences.Add(assmName); + + return assmName; + } + + return module.TypeSystem.CoreLibrary; + } + } + + internal class AssemblyNameReferenceComparer : IEqualityComparer + { + public static readonly AssemblyNameReferenceComparer Instance = new AssemblyNameReferenceComparer(); + public bool Equals(AssemblyNameReference x, AssemblyNameReference y) + { + return x.FullName == y.FullName; + } + + public int GetHashCode(AssemblyNameReference obj) + { + return obj.Name.GetHashCode(); + } + } +} diff --git a/src/FluentIL/FluentIL.csproj b/src/FluentIL/FluentIL.csproj new file mode 100644 index 00000000..d8e84a5a --- /dev/null +++ b/src/FluentIL/FluentIL.csproj @@ -0,0 +1,17 @@ + + + + netstandard2.0 + 7.3 + + + + + + + + + + + + diff --git a/src/FluentIL/Logging/ILogger.cs b/src/FluentIL/Logging/ILogger.cs new file mode 100644 index 00000000..6055375e --- /dev/null +++ b/src/FluentIL/Logging/ILogger.cs @@ -0,0 +1,11 @@ +using FluentIL.Common; +using Mono.Cecil.Cil; + +namespace FluentIL.Logging +{ + public interface ILogger + { + bool IsErrorThrown { get; } + void Log(Rule rule, SequencePoint sp, params string[] messages); + } +} \ No newline at end of file diff --git a/src/FluentIL/Logging/Logger.cs b/src/FluentIL/Logging/Logger.cs new file mode 100644 index 00000000..df007293 --- /dev/null +++ b/src/FluentIL/Logging/Logger.cs @@ -0,0 +1,48 @@ +using FluentIL.Common; +using Mono.Cecil.Cil; +using System; + +namespace FluentIL.Logging +{ + public class ConsoleLogger : ILogger + { + private readonly string _toolName; + + public ConsoleLogger(string toolName) + { + _toolName = toolName; + } + + public virtual bool IsErrorThrown { get; private set; } + + public void Log(Rule rule, SequencePoint sp, params string[] messages) + { + var location = sp?.Document == null ? _toolName : + $"{sp.Document.Url}({sp.StartLine},{sp.StartColumn},{sp.EndLine},{sp.EndColumn})"; + + var message = string.Format(rule.Message.ToString(), messages ?? new string[] { }); + + switch (rule.Severity) + { + case RuleSeverity.Error: WriteError(rule.Id, location, message); IsErrorThrown = true; break; + case RuleSeverity.Warning: WriteWarning(rule.Id, location, message); break; + case RuleSeverity.Info: WriteInfo(location, message); break; + } + } + + private void WriteInfo(string location, string message) + { + Console.WriteLine($"{location}: {message}"); + } + + private void WriteWarning(string id, string location, string message) + { + Console.WriteLine($"{location}: warning {id}: {message}"); + } + + private void WriteError(string id, string location, string message) + { + Console.WriteLine($"{location}: error {id}: {message}"); + } + } +} \ No newline at end of file diff --git a/src/FluentIL/Logging/LoggerExtensions.cs b/src/FluentIL/Logging/LoggerExtensions.cs new file mode 100644 index 00000000..481f59a0 --- /dev/null +++ b/src/FluentIL/Logging/LoggerExtensions.cs @@ -0,0 +1,48 @@ +using FluentIL.Common; +using Mono.Cecil; +using Mono.Cecil.Cil; +using System.Linq; + +namespace FluentIL.Logging +{ + public static class LoggerExtensions + { + public static void Log(this ILogger log, Rule rule, params string[] messages) + { + log.Log(rule, null, messages); + } + + public static void Log(this ILogger log, Rule rule, ICustomAttributeProvider ap, params string[] messages) + { + if (ap is IMemberDefinition md) Log(log, rule, md, messages); + else log.Log(rule, null, messages); + } + + public static void Log(this ILogger log, Rule rule, IMemberDefinition md, params string[] messages) + { + switch (md) + { + case MethodDefinition method: Log(log, rule, method, messages); break; + case TypeDefinition type: Log(log, rule, type, messages); break; + + default: log.Log(rule, null, messages); break; + } + } + + public static void Log(this ILogger log, Rule rule, MethodDefinition md, params string[] messages) + { + log.Log(rule, GetSPFromMethod(md), messages); + } + + public static void Log(this ILogger log, Rule rule, TypeDefinition td, params string[] messages) + { + var sp = td.Methods.Select(GetSPFromMethod).FirstOrDefault(s => s != null); + log.Log(rule, sp, messages); + } + + private static SequencePoint GetSPFromMethod(MethodDefinition md) + { + return md.DebugInformation.SequencePoints.FirstOrDefault(s => s.Document != null); + } + } +} diff --git a/src/FluentIL/MethodEditor.cs b/src/FluentIL/MethodEditor.cs new file mode 100644 index 00000000..cfee377c --- /dev/null +++ b/src/FluentIL/MethodEditor.cs @@ -0,0 +1,149 @@ +using FluentIL.Extensions; +using Mono.Cecil; +using Mono.Cecil.Cil; +using System; +using System.Linq; + +namespace FluentIL +{ + public static class MethodEditor + { + public static void BeforeInstruction(this MethodBody body, Instruction instruction, PointCut action) + { + new Cut(body, instruction) + .Prev() + .Here(action); + } + + public static void AfterInstruction(this MethodBody body, Instruction instruction, PointCut action) + { + new Cut(body, instruction) + .Here(action); + } + public static void AfterEntry(this MethodBody body, PointCut action) + { + new Cut(body, GetCodeStart(body)) + .Prev() + .Here(action); + } + + public static void BeforeExit(this MethodBody body, PointCut action) + { + foreach (var ret in body.Instructions.Where(i => i.OpCode == OpCodes.Ret).ToList()) + { + var cut = new Cut(body, ret); + cut.Here(action).Write(OpCodes.Ret); + cut.Remove(); + } + } + + public static void Append(this MethodBody body, PointCut action) + { + var cut = new Cut(body, entry: false, exit: true); + cut.Here(action); + } + + public static void Before(this MethodBody body, Instruction instruction, PointCut action) + { + if (!body.Instructions.Contains(instruction)) + throw new ArgumentException("Wrong instruction."); + + new Cut(body, instruction) + .SkipNops() + .Prev() + .Here(action); + } + + public static void Instead(this MethodBody body, PointCut action) + { + body.Instructions.Clear(); + body.Variables.Clear(); + body.ExceptionHandlers.Clear(); + + new Cut(body, true, true) + .Here(action); + } + + public static void Mark(this MethodDefinition method, TypeReference attribute) + { + if (method.CustomAttributes.Any(ca => ca.AttributeType.FullName == attribute.FullName)) + return; + + var constructor = method.Module.ImportReference(attribute).Resolve() + .Methods.First(m => m.IsConstructor && !m.IsStatic); + + method.CustomAttributes.Add(new CustomAttribute(method.Module.ImportReference(constructor))); + } + + public static Instruction GetCodeStart(this MethodBody body) + { + if (body.Method.DeclaringType.IsValueType || !body.Method.IsConstructor || body.Method.IsStatic) + return body.Method.Body.Instructions.First(); + + var point = body.Instructions.FirstOrDefault( + i => i != null && + i.OpCode == OpCodes.Call && + i.Operand is MethodReference methodReference && + IsOwnConstructor(methodReference, body.Method.DeclaringType)); + + if (point == null) + throw new InvalidOperationException("Cannot find base class ctor call"); + + return point.Next; + } + + private static bool IsOwnConstructor(MethodReference methodReference, TypeDefinition owner) + { + var methodDef = methodReference.Resolve(); + return methodDef.IsConstructor && + (methodDef.DeclaringType.Match(owner) || methodDef.DeclaringType.Match(owner.BaseType?.Resolve())); + } + + public static void OnLoadField(this MethodBody body, FieldReference field, PointCut pc, Instruction startingFrom = null) + { + var fieldDef = field.Resolve(); + + if (fieldDef.IsStatic) + body.OnEveryOccasionOf(i => + (i.OpCode == OpCodes.Ldsfld || i.OpCode == OpCodes.Ldsflda) && i.Operand is FieldReference f && f.DeclaringType.Match(field.DeclaringType) && f.Resolve() == fieldDef + , pc, startingFrom); + else + body.OnEveryOccasionOf(i => + (i.OpCode == OpCodes.Ldfld || i.OpCode == OpCodes.Ldflda) && i.Operand is FieldReference f && f.DeclaringType.Match(field.DeclaringType) && f.Resolve() == fieldDef + , pc, startingFrom); + } + + public static void OnStoreVar(this MethodBody body, VariableReference variable, PointCut pc, Instruction startingFrom = null) + { + body.OnEveryOccasionOf(i => + ((i.OpCode == OpCodes.Stloc || i.OpCode == OpCodes.Stloc_S) && ((i.Operand is int n && n == variable.Index) || (i.Operand is VariableDefinition v && v.Index == variable.Index))) || + (variable.Index == 0 && i.OpCode == OpCodes.Stloc_0) || + (variable.Index == 1 && i.OpCode == OpCodes.Stloc_1) || + (variable.Index == 2 && i.OpCode == OpCodes.Stloc_2) || + (variable.Index == 3 && i.OpCode == OpCodes.Stloc_3) + , pc, startingFrom); + } + + public static void OnCall(this MethodBody body, MethodReference method, PointCut pc, Instruction startingFrom = null) + { + body.OnEveryOccasionOf(i => + (i.OpCode == OpCodes.Call || i.OpCode == OpCodes.Calli || i.OpCode == OpCodes.Callvirt || i.OpCode == OpCodes.Newobj) + && i.Operand is MethodReference mref && mref.DeclaringType.Match(method.DeclaringType) && mref.Resolve() == method.Resolve() + , pc, startingFrom); + } + + public static void OnEveryOccasionOf(this MethodBody body, Func predicate, PointCut pc, Instruction startingFrom = null) + { + var insts = body.Instructions; + var start = startingFrom == null ? 0 : insts.IndexOf(startingFrom); + + var icol = insts.Skip(start).Where(predicate).ToArray(); + + if (icol.Length == 0) + throw new InvalidOperationException("Expected sequence is not found even once. Unsupported language/version ?"); + + foreach (var curi in icol) + new Cut(body, curi).Here(pc); + } + } +} \ No newline at end of file diff --git a/src/FluentIL/PatcherBase.cs b/src/FluentIL/PatcherBase.cs new file mode 100644 index 00000000..0ac0b528 --- /dev/null +++ b/src/FluentIL/PatcherBase.cs @@ -0,0 +1,130 @@ +using FluentIL.Common; +using FluentIL.Logging; +using FluentIL.Resolvers; +using Mono.Cecil; +using System.Collections.Generic; +using System.IO; + +namespace FluentIL +{ + public abstract class PatcherBase + { + protected readonly ILogger _log; + + protected PatcherBase( + ILogger logger) + { + _log = logger; + } + + public void Process(string assemblyFile, IReadOnlyList references, bool optimize, bool verbose) + { + var resolver = GetResolver(assemblyFile, references); + if (_log.IsErrorThrown) return; + + Process(assemblyFile, resolver, optimize, verbose); + } + + public void Process(string assemblyFile, IAssemblyResolver resolver, bool optimize, bool verbose) + { + if (!File.Exists(assemblyFile)) + { + _log.Log(GenericErrorRule, $"Target not found: '{assemblyFile}'"); + return; + } + + if (verbose) _log.Log(GenericInfoRule, $"Started for {Path.GetFileName(assemblyFile)}"); + + var pdbPresent = AreSymbolsFound(assemblyFile); + var assembly = ReadAssembly(assemblyFile, resolver, pdbPresent, verbose); + + var modified = PatchAssembly(assembly, optimize, verbose); + + if (!_log.IsErrorThrown) + { + if (modified) + { + if (verbose) _log.Log(GenericInfoRule, "Assembly has been patched."); + WriteAssembly(assembly, pdbPresent, verbose); + } + else if (verbose) _log.Log(GenericInfoRule, "No patching required."); + } + } + + protected virtual IAssemblyResolver GetResolver(string assemblyFile, IReadOnlyList references) + { + var resolver = new KnownReferencesAssemblyResolver(); + + if (!File.Exists(assemblyFile)) _log.Log(GenericErrorRule, $"Target not found: '{assemblyFile}'"); + else resolver.AddSearchDirectory(Path.GetDirectoryName(assemblyFile)); + + foreach (var refr in references) + { + if (!File.Exists(refr)) _log.Log(GenericErrorRule, $"Reference not found: '{refr}'"); + else resolver.AddReference(refr); + } + + return resolver; + } + + private AssemblyDefinition ReadAssembly(string assemblyFile, IAssemblyResolver resolver, bool readSymbols,bool verbose) + { + var assembly = AssemblyDefinition.ReadAssembly(assemblyFile, + new ReaderParameters + { + ReadingMode = ReadingMode.Deferred + }); + + assembly.Dispose(); + + assembly = resolver.Resolve(assembly.Name, new ReaderParameters + { + ReadingMode = ReadingMode.Immediate, + ReadWrite = true, + AssemblyResolver = resolver, + ReadSymbols = readSymbols + }); + + if (verbose) _log.Log(GenericInfoRule, "Assembly has been read."); + + return assembly; + } + + private void WriteAssembly(AssemblyDefinition assembly, bool writeSymbols, bool verbose) + { + var param = new WriterParameters(); + + if (writeSymbols) + { + param.WriteSymbols = true; + } + + assembly.Write(param); + + if (assembly.MainModule.SymbolReader != null) + assembly.MainModule.SymbolReader.Dispose(); + + assembly.Dispose(); + + if (verbose) _log.Log(GenericInfoRule, "Assembly has been written."); + } + + private bool AreSymbolsFound(string dllPath) + { + var pdbPath = Path.Combine(Path.GetDirectoryName(dllPath), Path.GetFileNameWithoutExtension(dllPath) + ".pdb"); + + if (File.Exists(pdbPath)) + { + return true; + } + + _log.Log(GenericInfoRule, $"Symbols not found on {pdbPath}. Proceeding without..."); + return false; + } + + protected abstract Rule GenericInfoRule { get; } + protected abstract Rule GenericErrorRule { get; } + + protected abstract bool PatchAssembly(AssemblyDefinition assembly, bool optimize, bool verbose); + } +} \ No newline at end of file diff --git a/src/FluentIL/PointCut.cs b/src/FluentIL/PointCut.cs new file mode 100644 index 00000000..19b8720d --- /dev/null +++ b/src/FluentIL/PointCut.cs @@ -0,0 +1,198 @@ +using Mono.Cecil; +using Mono.Cecil.Cil; +using Mono.Collections.Generic; +using System; +using System.Collections.Generic; +using System.Linq; + +namespace FluentIL +{ + public delegate Cut PointCut(in Cut cut); + + public static class CutEvents + { + public static Action OnModify { get; set; } = m => { }; + } + + public readonly struct Cut + { + private readonly bool _entry; + private readonly bool _exit; + private readonly Instruction _refInst; + private readonly MethodBody _body; + + public MethodDefinition Method => _body.Method; + public TypeSystem TypeSystem => _body.Method.Module.TypeSystem; + + private Collection Instructions => _body.Instructions; + + public Cut(MethodBody body, bool entry, bool exit) + { + if (!entry && !exit) throw new ArgumentException("Should be either entry or exit"); + + _body = body; + _entry = entry; + _exit = exit; + _refInst = null; + } + + public Cut(MethodBody body, Instruction instruction) + { + _refInst = instruction ?? throw new ArgumentNullException(nameof(instruction)); + _body = body ?? throw new ArgumentNullException(nameof(body)); + + _entry = false; + _exit = false; + } + + public Cut Next() + { + if (_entry) return this; + if (Instructions[Instructions.Count - 1] == _refInst) return new Cut(_body, false, true); + return new Cut(_body, _refInst.Next); + } + + public Cut Prev() + { + if (_exit) return this; + if (Instructions.Count != 0 && Instructions[0] == _refInst) return new Cut(_body, true, false); + return new Cut(_body, _refInst.Previous); + } + + public Cut SkipNops() + { + if (_exit) return this; + var i = _entry ? _body.Instructions[0] : _refInst; + while (i.OpCode == OpCodes.Nop) + i = i.Next; + return new Cut(_body, i); + } + + public Cut Here(PointCut pc) + { + if (pc == null) return this; + return pc(this); + } + + public Cut Write(Instruction instruction) + { + CutEvents.OnModify(_body); + + if (_entry) + { + Instructions.Insert(0, instruction); + + foreach (var handler in _body.ExceptionHandlers.Where(h => h.HandlerStart == null).ToList()) + handler.HandlerStart = _refInst; + } + else if (_exit || _refInst == Instructions[Instructions.Count - 1]) + { + Instructions.Add(instruction); + + if (!_exit) + foreach (var handler in _body.ExceptionHandlers.Where(h => h.HandlerEnd == null).ToList()) + handler.HandlerEnd = _refInst; + } + else + { + var index = Instructions.IndexOf(_refInst) + 1; + Instructions.Insert(index, instruction); + } + + return new Cut(_body, instruction); + } + + public Instruction Emit(OpCode opCode, object operand) + { + switch (operand) + { + case Cut pc: return Instruction.Create(opCode, pc._refInst ?? throw new InvalidOperationException()); + case TypeReference tr: return Instruction.Create(opCode, Method.Module.ImportReference(tr)); + case MethodReference mr: return Instruction.Create(opCode, Method.Module.ImportReference(mr)); + case CallSite cs: return Instruction.Create(opCode, cs); + case FieldReference fr: return Instruction.Create(opCode, Method.Module.ImportReference(fr)); + case string str: return Instruction.Create(opCode, str); + case char c: return Instruction.Create(opCode, c); + case byte b: return Instruction.Create(opCode, b); + case sbyte sb: return Instruction.Create(opCode, sb); + case int i: return Instruction.Create(opCode, i); + case short i: return Instruction.Create(opCode, i); + case ushort i: return Instruction.Create(opCode, i); + case long l: return Instruction.Create(opCode, l); + case float f: return Instruction.Create(opCode, f); + case double d: return Instruction.Create(opCode, d); + case Instruction inst: return Instruction.Create(opCode, inst); + case Instruction[] insts: return Instruction.Create(opCode, insts); + case VariableDefinition vd: return Instruction.Create(opCode, vd); + case ParameterDefinition pd: return Instruction.Create(opCode, pd); + + default: throw new NotSupportedException($"Not supported operand type '{operand.GetType()}'"); + } + } + + public Instruction Emit(OpCode opCode) + { + return Instruction.Create(opCode); + } + + public Cut Replace(Instruction instruction) + { + CutEvents.OnModify(_body); + + if (_exit || _entry) return Write(instruction); + + Redirect(_refInst, instruction, instruction); + Instructions[Instructions.IndexOf(_refInst)] = instruction; + + return new Cut(_body, instruction); + } + + public Cut Remove() + { + CutEvents.OnModify(_body); + + var prevCut = Prev(); + + var next = _refInst.Next; + var prev = _refInst.Previous; + + Redirect(_refInst, next, prev); + Instructions.Remove(_refInst); + + return prevCut; + } + + private void Redirect(Instruction source, Instruction next, Instruction prev) + { + var refs = Instructions.Where(i => i.Operand == source).ToList(); + + if (refs.Any()) + { + if (next == null) + throw new InvalidOperationException("Cannot redirect to non existing instruction"); + + foreach (var rref in refs) + rref.Operand = next; + } + + foreach (var handler in _body.ExceptionHandlers) + { + if (handler.FilterStart == source) + handler.FilterStart = prev ?? throw new InvalidOperationException(); + + if (handler.HandlerEnd == source) + handler.HandlerEnd = next ?? throw new InvalidOperationException(); + + if (handler.HandlerStart == source) + handler.HandlerStart = prev ?? throw new InvalidOperationException(); + + if (handler.TryEnd == source) + handler.TryEnd = next ?? throw new InvalidOperationException(); + + if (handler.TryStart == source) + handler.TryStart = prev ?? throw new InvalidOperationException(); + } + } + + } +} \ No newline at end of file diff --git a/src/FluentIL/Resolvers/CachedAssemblyResolver.cs b/src/FluentIL/Resolvers/CachedAssemblyResolver.cs new file mode 100644 index 00000000..53c91d61 --- /dev/null +++ b/src/FluentIL/Resolvers/CachedAssemblyResolver.cs @@ -0,0 +1,41 @@ +using Mono.Cecil; +using System; +using System.Collections.Generic; + +namespace FluentIL.Resolvers +{ + public class CachedAssemblyResolver : BaseAssemblyResolver + { + private readonly Dictionary _cache = new Dictionary(); + + public override AssemblyDefinition Resolve(AssemblyNameReference name, ReaderParameters parameters) + { + var result = _cache.ContainsKey(name.FullName) ? _cache[name.FullName] : null; + + if (result == null) + { + result = LookupAssembly(name, parameters); + _cache[name.FullName] = result; + } + + return result; + } + + protected virtual AssemblyDefinition LookupAssembly(AssemblyNameReference name, ReaderParameters parameters) + { + return base.Resolve(name, parameters); + } + + protected internal void RegisterAssembly(AssemblyDefinition assembly) + { + if (assembly == null) + throw new ArgumentNullException("assembly"); + + var name = assembly.Name.FullName; + if (_cache.ContainsKey(name)) + return; + + _cache[name] = assembly; + } + } +} \ No newline at end of file diff --git a/src/FluentIL/Resolvers/KnownReferencesAssemblyResolver.cs b/src/FluentIL/Resolvers/KnownReferencesAssemblyResolver.cs new file mode 100644 index 00000000..9b475f88 --- /dev/null +++ b/src/FluentIL/Resolvers/KnownReferencesAssemblyResolver.cs @@ -0,0 +1,48 @@ +using Mono.Cecil; +using System.Collections.Generic; +using System.IO; +using System.Linq; + +namespace FluentIL.Resolvers +{ + + public class KnownReferencesAssemblyResolver : CachedAssemblyResolver + { + private readonly List _references = new List(); + + public void AddReference(string assemblyPath) + { + _references.Add(assemblyPath); + } + + protected override AssemblyDefinition LookupAssembly(AssemblyNameReference name, ReaderParameters parameters) + { + var extensions = name.IsWindowsRuntime ? new[] { ".winmd", ".dll" } : new[] { ".exe", ".dll" }; + + foreach (var extension in extensions) + { + string file = _references.FirstOrDefault(r => Path.GetFileName(r) == name.Name + extension); + if (file == null || !File.Exists(file)) + continue; + try + { + return GetAssembly(file, parameters); + } + catch (System.BadImageFormatException) + { + //skip assemblies we cannot load + } + } + + return base.LookupAssembly(name, parameters); + } + + private AssemblyDefinition GetAssembly(string file, ReaderParameters parameters) + { + if (parameters.AssemblyResolver == null) + parameters.AssemblyResolver = this; + + return ModuleDefinition.ReadModule(file, parameters).Assembly; + } + } +} \ No newline at end of file diff --git a/src/FluentIL/StandardTypes.cs b/src/FluentIL/StandardTypes.cs new file mode 100644 index 00000000..af8a3845 --- /dev/null +++ b/src/FluentIL/StandardTypes.cs @@ -0,0 +1,63 @@ +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace FluentIL +{ + public class StandardType + { + public static readonly StandardType MethodBase = new StandardType("System.Reflection", "MethodBase"); + public static readonly StandardType Attribute = new StandardType("System", "Attribute"); + public static readonly StandardType Type = new StandardType("System", "Type"); + public static readonly StandardType RuntimeTypeHandle = new StandardType("System", "RuntimeTypeHandle", isValueType: true); + public static readonly StandardType RuntimeMethodHandle = new StandardType("System", "RuntimeMethodHandle", isValueType: true); + public static readonly StandardType AsyncStateMachineAttribute = new StandardType("System.Runtime.CompilerServices", "AsyncStateMachineAttribute"); + public static readonly StandardType IteratorStateMachineAttribute = new StandardType("System.Runtime.CompilerServices", "IteratorStateMachineAttribute"); + public StandardType(string @namespace, string name, + bool isValueType = false, bool isArray = false, + IReadOnlyList elements = null, + IReadOnlyList assemblyHints = null + ) + { + Namespace = @namespace; + Name = name; + IsValueType = isValueType; + IsArray = isArray; + Elements = elements ?? new StandardType[] { }; + AssemblyHints = assemblyHints ?? new string[] { }; + } + + public string Namespace { get; } + public string Name { get; } + public bool IsValueType { get; } + public bool IsArray { get; } + public IReadOnlyList Elements { get; } + public IReadOnlyList AssemblyHints { get; } + + public override string ToString() + { + var fullname = new StringBuilder().Append(Namespace).Append(".").Append(Name); + if (Elements.Count > 0) + { + fullname.Append("<"); + var last = Elements.Last(); + foreach (var element in Elements) + { + fullname.Append(element.ToString()); + if (element != last) + fullname.Append(","); + } + fullname.Append(">"); + } + if (IsArray) + fullname.Append("[]"); + + return fullname.ToString(); + } + + public StandardType MakeArray() + { + return new StandardType(Namespace, Name, IsValueType, true, Elements, AssemblyHints); + } + } +} \ No newline at end of file