Skip to content

Commit

Permalink
Enable types from templates to support net35
Browse files Browse the repository at this point in the history
  • Loading branch information
jnm2 committed Sep 23, 2021
1 parent e0d1a27 commit 5a7338e
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 10 deletions.
12 changes: 7 additions & 5 deletions src/Microsoft.Windows.CsWin32/templates/PCSTR.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,12 @@ internal int Length
/// <returns>A <see langword="string"/>, or <see langword="null"/> if <see cref="Value"/> is <see langword="null"/>.</returns>
public override string ToString() => this.Value is null ? null : new string((sbyte*)this.Value, 0, this.Length, global::System.Text.Encoding.UTF8);

/// <summary>
/// Returns a span of the characters in this string.
/// </summary>
internal ReadOnlySpan<byte> AsSpan() => this.Value is null ? default(ReadOnlySpan<byte>) : new ReadOnlySpan<byte>(this.Value, this.Length);
#if !NETFRAMEWORK || NET45_OR_GREATER // Match .NET Framework versions supported by the System.Memory NuGet package
/// <summary>
/// Returns a span of the characters in this string.
/// </summary>
internal ReadOnlySpan<byte> AsSpan() => this.Value is null ? default(ReadOnlySpan<byte>) : new ReadOnlySpan<byte>(this.Value, this.Length);
#endif

private string DebuggerDisplay => this.ToString();
private string DebuggerDisplay => this.ToString();
}
12 changes: 7 additions & 5 deletions src/Microsoft.Windows.CsWin32/templates/PCWSTR.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,12 @@ internal int Length
/// <returns>A <see langword="string"/>, or <see langword="null"/> if <see cref="Value"/> is <see langword="null"/>.</returns>
public override string ToString() => this.Value is null ? null : new string(this.Value);

/// <summary>
/// Returns a span of the characters in this string.
/// </summary>
internal ReadOnlySpan<char> AsSpan() => this.Value is null ? default(ReadOnlySpan<char>) : new ReadOnlySpan<char>(this.Value, this.Length);
#if !NETFRAMEWORK || NET45_OR_GREATER // Match .NET Framework versions supported by the System.Memory NuGet package
/// <summary>
/// Returns a span of the characters in this string.
/// </summary>
internal ReadOnlySpan<char> AsSpan() => this.Value is null ? default(ReadOnlySpan<char>) : new ReadOnlySpan<char>(this.Value, this.Length);
#endif

private string DebuggerDisplay => this.ToString();
private string DebuggerDisplay => this.ToString();
}
47 changes: 47 additions & 0 deletions test/Microsoft.Windows.CsWin32.Tests/GeneratorTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -791,6 +791,28 @@ internal enum FILE_CREATE_FLAGS
this.AssertNoDiagnostics();
}

[Theory]
[InlineData("PCSTR")]
[InlineData("PCWSTR")]
public async Task CommonTemplatesWorkOnOldNetFramework(string templatedTypeName)
{
this.compilation = await this.CreateCompilationAsync(MyReferenceAssemblies.NetFramework.Net35);
this.generator = this.CreateGenerator(new GeneratorOptions { WideCharOnly = false });

// TryGenerate returns false for PCSTR and PCWSTR
var apiName = templatedTypeName switch
{
"PCSTR" => "CreateFileA",
"PCWSTR" => "CreateFileW",
_ => templatedTypeName,
};

Assert.True(this.generator.TryGenerate(apiName, CancellationToken.None));
this.CollectGeneratedCode(this.generator);
this.AssertNoDiagnostics();
Assert.Single(this.FindGeneratedType(templatedTypeName));
}

/// <summary>
/// Validates that where MemoryMarshal.CreateSpan isn't available, a substitute indexer is offered.
/// </summary>
Expand Down Expand Up @@ -2347,6 +2369,16 @@ private async Task<CSharpCompilation> CreateCompilationAsync(ReferenceAssemblies
references: metadataReferences,
options: new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary, platform: platform, allowUnsafe: true));

this.parseOptions = this.parseOptions.WithPreprocessorSymbols(references.TargetFramework switch
{
"net20" => ImmutableArray.Create("NETFRAMEWORK", "NET20", "NET20_OR_GREATER"),
"net35" => ImmutableArray.Create("NETFRAMEWORK", "NET35", "NET35_OR_GREATER", "NET30_OR_GREATER", "NET20_OR_GREATER"),
"net40" => ImmutableArray.Create("NETFRAMEWORK", "NET40", "NET40_OR_GREATER", "NET35_OR_GREATER", "NET30_OR_GREATER", "NET20_OR_GREATER"),
"netstandard2.0" => ImmutableArray.Create("NETSTANDARD", "NETSTANDARD2_0", "NETSTANDARD2_0_OR_GREATER", "NETSTANDARD1_6_OR_GREATER", "NETSTANDARD1_5_OR_GREATER", "NETSTANDARD1_4_OR_GREATER", "NETSTANDARD1_3_OR_GREATER", "NETSTANDARD1_2_OR_GREATER", "NETSTANDARD1_1_OR_GREATER", "NETSTANDARD1_0_OR_GREATER"),
"net5.0" => ImmutableArray.Create("NET", "NETCOREAPP", "NET5_0", "NET5_0_OR_GREATER", "NETCOREAPP3_1_OR_GREATER", "NETCOREAPP3_0_OR_GREATER", "NETCOREAPP2_2_OR_GREATER", "NETCOREAPP2_1_OR_GREATER", "NETCOREAPP2_0_OR_GREATER", "NETCOREAPP1_1_OR_GREATER", "NETCOREAPP1_0_OR_GREATER"),
_ => throw new NotImplementedException("Set up SDK-defined preprocessor symbols for " + references.TargetFramework),
});

// Add namespaces that projects may define to ensure we prefix types with "global::" everywhere.
compilation = compilation.AddSyntaxTrees(
CSharpSyntaxTree.ParseText("namespace Microsoft.System { }", this.parseOptions, path: "Microsoft.System.cs"),
Expand All @@ -2368,6 +2400,21 @@ private static class MyReferenceAssemblies

internal static class NetFramework
{
// .NET Framework 3.5 is the only version < 4.5.1 still in support by Microsoft. Support for .NET Framework 3.5
// ends on Jan 9, 2029. (https://docs.microsoft.com/en-us/lifecycle/products/microsoft-net-framework)

// Currently missing in https://github.com/dotnet/roslyn-sdk/blob/main/src/Microsoft.CodeAnalysis.Testing/Microsoft.CodeAnalysis.Analyzer.Testing/ReferenceAssemblies.cs
// since https://www.nuget.org/packages/Microsoft.NETFramework.ReferenceAssemblies.net35 has been published.
internal static readonly ReferenceAssemblies Net35 = new ReferenceAssemblies(
"net35",
new PackageIdentity("Microsoft.NETFramework.ReferenceAssemblies.net35", "1.0.2"),
Path.Combine("build", ".NETFramework", "v3.5"))
.WithAssemblyIdentityComparer(DesktopAssemblyIdentityComparer.Default)
.AddAssemblies(ImmutableArray.Create("mscorlib", "System", "System.Core", "System.Data", "System.Data.DataSetExtensions", "System.Xml", "System.Xml.Linq"))
.AddLanguageSpecificAssemblies(LanguageNames.CSharp, ImmutableArray.Create("Microsoft.CSharp"))
.AddLanguageSpecificAssemblies(LanguageNames.VisualBasic, ImmutableArray.Create("Microsoft.VisualBasic"))
.AddPackages(AdditionalPackages);

internal static readonly ReferenceAssemblies Net40 = ReferenceAssemblies.NetFramework.Net40.Default.AddPackages(AdditionalPackages);
}

Expand Down

0 comments on commit 5a7338e

Please sign in to comment.