From ae6fc265c93e306192fde697d8470d3881b5330e Mon Sep 17 00:00:00 2001 From: Jordan Borean Date: Tue, 17 Dec 2019 09:06:54 +1000 Subject: [PATCH] Add-Type - Added a way to reference assemblies by type name (#65866) * Add-Type - Added a way to reference assemblies by type name * Also add architecture symbols during compile time * Fix stray output values --- changelogs/fragments/add-type-typename.yaml | 3 + .../module_utils/csharp/Ansible.Basic.cs | 11 ++-- .../Ansible.ModuleUtils.AddType.psm1 | 57 +++++++++++++++++-- .../library/add_type_test.ps1 | 23 ++++++++ 4 files changed, 83 insertions(+), 11 deletions(-) create mode 100644 changelogs/fragments/add-type-typename.yaml diff --git a/changelogs/fragments/add-type-typename.yaml b/changelogs/fragments/add-type-typename.yaml new file mode 100644 index 00000000000..6fcd35d911f --- /dev/null +++ b/changelogs/fragments/add-type-typename.yaml @@ -0,0 +1,3 @@ +minor_changes: +- PowerShell Add-Type - Add an easier way to reference extra types when compiling C# code on PowerShell Core +- PowerShell Add-Type - Added the ``X86`` and ``AMD64`` preprocessor symbols for conditional compiling diff --git a/lib/ansible/module_utils/csharp/Ansible.Basic.cs b/lib/ansible/module_utils/csharp/Ansible.Basic.cs index 629e4fdcf26..f0d10207669 100644 --- a/lib/ansible/module_utils/csharp/Ansible.Basic.cs +++ b/lib/ansible/module_utils/csharp/Ansible.Basic.cs @@ -20,12 +20,11 @@ using System.Web.Script.Serialization; // loaded in PSCore, ignore CS1702 so the code will ignore this warning //NoWarn -Name CS1702 -CLR Core -//AssemblyReference -Name Newtonsoft.Json.dll -CLR Core -//AssemblyReference -Name System.ComponentModel.Primitives.dll -CLR Core -//AssemblyReference -Name System.Diagnostics.EventLog.dll -CLR Core -//AssemblyReference -Name System.IO.FileSystem.AccessControl.dll -CLR Core -//AssemblyReference -Name System.Security.Principal.Windows.dll -CLR Core -//AssemblyReference -Name System.Security.AccessControl.dll -CLR Core +//AssemblyReference -Type Newtonsoft.Json.JsonConvert -CLR Core +//AssemblyReference -Type System.Diagnostics.EventLog -CLR Core +//AssemblyReference -Type System.Security.AccessControl.NativeObjectSecurity -CLR Core +//AssemblyReference -Type System.Security.AccessControl.DirectorySecurity -CLR Core +//AssemblyReference -Type System.Security.Principal.IdentityReference -CLR Core //AssemblyReference -Name System.Web.Extensions.dll -CLR Framework diff --git a/lib/ansible/module_utils/powershell/Ansible.ModuleUtils.AddType.psm1 b/lib/ansible/module_utils/powershell/Ansible.ModuleUtils.AddType.psm1 index 19dec32d9cc..ba38159d5f1 100644 --- a/lib/ansible/module_utils/powershell/Ansible.ModuleUtils.AddType.psm1 +++ b/lib/ansible/module_utils/powershell/Ansible.ModuleUtils.AddType.psm1 @@ -38,6 +38,33 @@ Function Add-CSharpType { [String[]] A list of symbols to be defined during compile time. These are added to the existing symbols, 'CORECLR', 'WINDOWS', 'UNIX' that are set conditionalls in this cmdlet. + + .NOTES + The following features were added to control the compiling options from the + code itself. + + * Predefined compiler SYMBOLS + + * CORECLR - Added when running on PowerShell Core. + * WINDOWS - Added when running on Windows. + * UNIX - Added when running on non-Windows. + * X86 - Added when running on a 32-bit process (Ansible 2.10+) + * AMD64 - Added when running on a 64-bit process (Ansible 2.10+) + + * Ignore compiler warnings inline with the following comment inline + + //NoWarn -Name [-CLR Core|Framework] + + * Specify custom assembly references inline + + //AssemblyReference -Name Dll.Location.dll [-CLR Core|Framework] + + # Added in Ansible 2.10 + //AssemblyReference -Type System.Type.Name [-CLR Core|Framework] + + * Create automatic type accelerators to simplify long namespace names (Ansible 2.9+) + + //TypeAccelerator -Name -TypeName #> param( [Parameter(Mandatory=$true)][AllowEmptyCollection()][String[]]$References, @@ -56,6 +83,13 @@ Function Add-CSharpType { # the Is* variables are defined on PSCore, if absent we assume an # older version of PowerShell under .NET Framework and Windows $defined_symbols = [System.Collections.ArrayList]$CompileSymbols + + if ([System.IntPtr]::Size -eq 4) { + $defined_symbols.Add('X86') > $null + } else { + $defined_symbols.Add('AMD64') > $null + } + $is_coreclr = Get-Variable -Name IsCoreCLR -ErrorAction SilentlyContinue if ($null -ne $is_coreclr) { if ($is_coreclr.Value) { @@ -77,7 +111,7 @@ Function Add-CSharpType { $type_accelerators = [System.Collections.Generic.List`1[Hashtable]]@() # pattern used to find referenced assemblies in the code - $assembly_pattern = [Regex]"//\s*AssemblyReference\s+-Name\s+(?[\w.]*)(\s+-CLR\s+(?Core|Framework))?" + $assembly_pattern = [Regex]"//\s*AssemblyReference\s+-(?(Name)|(Type))\s+(?[\w.]*)(\s+-CLR\s+(?Core|Framework))?" $no_warn_pattern = [Regex]"//\s*NoWarn\s+-Name\s+(?[\w\d]*)(\s+-CLR\s+(?Core|Framework))?" $type_pattern = [Regex]"//\s*TypeAccelerator\s+-Name\s+(?[\w.]*)\s+-TypeName\s+(?[\w.]*)" @@ -116,9 +150,15 @@ Function Add-CSharpType { if ($clr -and $clr -ne "Core") { continue } - $assembly_path = $match.Groups["Name"] - if (-not ([System.IO.Path]::IsPathRooted($assembly_path))) { - $assembly_path = Join-Path -Path $lib_assembly_location -ChildPath $assembly_path + + $parameter_type = $match.Groups["Parameter"].Value + $assembly_path = $match.Groups["Name"].Value + if ($parameter_type -eq "Type") { + $assembly_path = ([Type]$assembly_path).Assembly.Location + } else { + if (-not ([System.IO.Path]::IsPathRooted($assembly_path))) { + $assembly_path = Join-Path -Path $lib_assembly_location -ChildPath $assembly_path + } } $assemblies.Add([Microsoft.CodeAnalysis.MetadataReference]::CreateFromFile($assembly_path)) > $null } @@ -256,7 +296,13 @@ Function Add-CSharpType { if ($clr -and $clr -ne "Framework") { continue } - $assemblies.Add($match.Groups["Name"].Value) > $null + + $parameter_type = $match.Groups["Parameter"].Value + $assembly_path = $match.Groups["Name"].Value + if ($parameter_type -eq "Type") { + $assembly_path = ([Type]$assembly_path).Assembly.Location + } + $assemblies.Add($assembly_path) > $null } $warn_matches = $no_warn_pattern.Matches($reference) foreach ($match in $warn_matches) { @@ -321,3 +367,4 @@ Function Add-CSharpType { } Export-ModuleMember -Function Add-CSharpType + diff --git a/test/integration/targets/win_module_utils/library/add_type_test.ps1 b/test/integration/targets/win_module_utils/library/add_type_test.ps1 index c8d947bc1fc..d89f99b79a4 100644 --- a/test/integration/targets/win_module_utils/library/add_type_test.ps1 +++ b/test/integration/targets/win_module_utils/library/add_type_test.ps1 @@ -272,5 +272,28 @@ try { } Assert-Equals -actual $failed -expected $true +$arch_class = @' +using System; + +namespace Namespace11 +{ + public class Class11 + { + public static int GetIntPtrSize() + { +#if X86 + return 4; +#elif AMD64 + return 8; +#else + return 0; +#endif + } + } +} +'@ +Add-CSharpType -Reference $arch_class +Assert-Equals -actual ([Namespace11.Class11]::GetIntPtrSize()) -expected ([System.IntPtr]::Size) + $result.res = "success" Exit-Json -obj $result