AddType - Support compiling with /unsafe C# code (#79853)

* AddType - Support compiling with /unsafe C# code

* Update Ansible version in docstring
pull/79859/head
Jordan Borean 1 year ago committed by GitHub
parent d16ec2455d
commit 652a74e087
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -0,0 +1,2 @@
minor_changes:
- Ansible.ModuleUtils.AddType - Add support for compiling ``unsafe`` code with the ``//AllowUnsafe`` directive

@ -65,6 +65,10 @@ Function Add-CSharpType {
* Create automatic type accelerators to simplify long namespace names (Ansible 2.9+)
//TypeAccelerator -Name <AcceleratorName> -TypeName <Name of compiled type>
* Compile with unsafe support (Ansible 2.15+)
//AllowUnsafe
#>
param(
[Parameter(Mandatory = $true)][AllowEmptyCollection()][String[]]$References,
@ -117,6 +121,7 @@ Function Add-CSharpType {
$assembly_pattern = [Regex]"//\s*AssemblyReference\s+-(?<Parameter>(Name)|(Type))\s+(?<Name>[\w.]*)(\s+-CLR\s+(?<CLR>Core|Framework))?"
$no_warn_pattern = [Regex]"//\s*NoWarn\s+-Name\s+(?<Name>[\w\d]*)(\s+-CLR\s+(?<CLR>Core|Framework))?"
$type_pattern = [Regex]"//\s*TypeAccelerator\s+-Name\s+(?<Name>[\w.]*)\s+-TypeName\s+(?<TypeName>[\w.]*)"
$allow_unsafe_pattern = [Regex]"//\s*AllowUnsafe?"
# PSCore vs PSDesktop use different methods to compile the code,
# PSCore uses Roslyn and can compile the code purely in memory
@ -142,11 +147,13 @@ Function Add-CSharpType {
$ignore_warnings = New-Object -TypeName 'System.Collections.Generic.Dictionary`2[[String], [Microsoft.CodeAnalysis.ReportDiagnostic]]'
$parse_options = ([Microsoft.CodeAnalysis.CSharp.CSharpParseOptions]::Default).WithPreprocessorSymbols($defined_symbols)
$syntax_trees = [System.Collections.Generic.List`1[Microsoft.CodeAnalysis.SyntaxTree]]@()
$allow_unsafe = $false
foreach ($reference in $References) {
# scan through code and add any assemblies that match
# //AssemblyReference -Name ... [-CLR Core]
# //NoWarn -Name ... [-CLR Core]
# //TypeAccelerator -Name ... -TypeName ...
# //AllowUnsafe
$assembly_matches = $assembly_pattern.Matches($reference)
foreach ($match in $assembly_matches) {
$clr = $match.Groups["CLR"].Value
@ -180,6 +187,10 @@ Function Add-CSharpType {
foreach ($match in $type_matches) {
$type_accelerators.Add(@{Name = $match.Groups["Name"].Value; TypeName = $match.Groups["TypeName"].Value })
}
if ($allow_unsafe_pattern.Matches($reference).Count) {
$allow_unsafe = $true
}
}
# Release seems to contain the correct line numbers compared to
@ -194,6 +205,10 @@ Function Add-CSharpType {
$compiler_options = $compiler_options.WithSpecificDiagnosticOptions($ignore_warnings)
}
if ($allow_unsafe) {
$compiler_options = $compiler_options.WithAllowUnsafe($true)
}
# create compilation object
$compilation = [Microsoft.CodeAnalysis.CSharp.CSharpCompilation]::Create(
[System.Guid]::NewGuid().ToString(),
@ -297,6 +312,7 @@ Function Add-CSharpType {
# //AssemblyReference -Name ... [-CLR Framework]
# //NoWarn -Name ... [-CLR Framework]
# //TypeAccelerator -Name ... -TypeName ...
# //AllowUnsafe
$assembly_matches = $assembly_pattern.Matches($reference)
foreach ($match in $assembly_matches) {
$clr = $match.Groups["CLR"].Value
@ -330,6 +346,10 @@ Function Add-CSharpType {
foreach ($match in $type_matches) {
$type_accelerators.Add(@{Name = $match.Groups["Name"].Value; TypeName = $match.Groups["TypeName"].Value })
}
if ($allow_unsafe_pattern.Matches($reference).Count) {
$compiler_options.Add("/unsafe") > $null
}
}
if ($ignore_warnings.Count -gt 0) {
$compiler_options.Add("/nowarn:" + ([String]::Join(",", $ignore_warnings.ToArray()))) > $null

@ -328,5 +328,73 @@ finally {
}
Assert-Equal -actual ([Namespace12.Class12]::GetString()) -expected "b"
$unsafe_code_fail = @'
using System;
namespace Namespace13
{
public class Class13
{
public static int GetNumber()
{
int num = 2;
int* numPtr = &num;
DoubleNumber(numPtr);
return num;
}
private unsafe static void DoubleNumber(int* num)
{
*num = *num * 3;
}
}
}
'@
$failed = $false
try {
Add-CSharpType -Reference $unsafe_code_fail
}
catch {
$failed = $true
$actual = $_.Exception.Message.Contains("error CS0227: Unsafe code may only appear if compiling with /unsafe")
Assert-Equal -actual $actual -expected $true
}
Assert-Equal -actual $failed -expected $true
$unsafe_code = @'
using System;
//AllowUnsafe
namespace Namespace13
{
public class Class13
{
public static int GetNumber()
{
int num = 2;
unsafe
{
int* numPtr = &num;
DoubleNumber(numPtr);
}
return num;
}
private unsafe static void DoubleNumber(int* num)
{
*num = *num * 2;
}
}
}
'@
Add-CSharpType -Reference $unsafe_code
Assert-Equal -actual ([Namespace13.Class13]::GetNumber()) -expected 4
$result.res = "success"
Exit-Json -obj $result

Loading…
Cancel
Save