Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Nullable annotation for System.Windows.Extensions #57896

Merged
merged 12 commits into from
Nov 24, 2021
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,6 @@ internal static partial class Crypt32
internal const uint CERT_STORE_PROV_MEMORY = 2;

[DllImport(Interop.Libraries.Crypt32, CharSet = CharSet.Unicode, SetLastError = true)]
internal static extern SafeCertStoreHandle CertOpenStore(IntPtr lpszStoreProvider, uint dwMsgAndCertEncodingType, IntPtr hCryptProv, uint dwFlags, string pvPara);
internal static extern SafeCertStoreHandle CertOpenStore(IntPtr lpszStoreProvider, uint dwMsgAndCertEncodingType, IntPtr hCryptProv, uint dwFlags, string? pvPara);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ internal sealed class CRYPTUI_VIEWCERTIFICATE_STRUCTW
internal uint dwSize;
internal IntPtr hwndParent;
internal uint dwFlags;
internal string szTitle;
internal string? szTitle;
internal IntPtr pCertContext;
internal IntPtr rgszPurposes;
internal uint cPurposes;
Expand All @@ -38,9 +38,9 @@ internal sealed class CRYPTUI_SELECTCERTIFICATE_STRUCTW
internal uint dwSize;
internal IntPtr hwndParent;
internal uint dwFlags;
internal string szTitle;
internal string? szTitle;
internal uint dwDontUseColumn;
internal string szDisplayString;
internal string? szDisplayString;
internal IntPtr pFilterCallback;
internal IntPtr pDisplayCallback;
internal IntPtr pvCallbackData;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,6 @@ internal static partial class WinMM
internal static extern bool PlaySound(string soundName, IntPtr hmod, int soundFlags);

[DllImport(Libraries.WinMM, ExactSpelling = true, EntryPoint = "PlaySoundW")]
internal static extern bool PlaySound(byte[] soundName, IntPtr hmod, int soundFlags);
internal static extern bool PlaySound(byte[]? soundName, IntPtr hmod, int soundFlags);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ internal static partial class WinMM
[DllImport(Libraries.WinMM)]
internal static extern int mmioDescend(IntPtr hMIO,
[MarshalAs(UnmanagedType.LPStruct)] MMCKINFO lpck,
[MarshalAs(UnmanagedType.LPStruct)] MMCKINFO lcpkParent,
[MarshalAs(UnmanagedType.LPStruct)] MMCKINFO? lcpkParent,
int flags);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,16 @@ public partial class SoundPlayer : System.ComponentModel.Component, System.Runti
public SoundPlayer() { }
public SoundPlayer(System.IO.Stream stream) { }
huoyaoyuan marked this conversation as resolved.
Show resolved Hide resolved
protected SoundPlayer(System.Runtime.Serialization.SerializationInfo serializationInfo, System.Runtime.Serialization.StreamingContext context) { }
public SoundPlayer(string soundLocation) { }
public SoundPlayer(string? soundLocation) { }
huoyaoyuan marked this conversation as resolved.
Show resolved Hide resolved
public bool IsLoadCompleted { get { throw null; } }
public int LoadTimeout { get { throw null; } set { } }
[System.Diagnostics.CodeAnalysis.AllowNullAttribute]
huoyaoyuan marked this conversation as resolved.
Show resolved Hide resolved
public string SoundLocation { get { throw null; } set { } }
public System.IO.Stream Stream { get { throw null; } set { } }
public object Tag { get { throw null; } set { } }
public event System.ComponentModel.AsyncCompletedEventHandler LoadCompleted { add { } remove { } }
public event System.EventHandler SoundLocationChanged { add { } remove { } }
public event System.EventHandler StreamChanged { add { } remove { } }
public System.IO.Stream? Stream { get { throw null; } set { } }
public object? Tag { get { throw null; } set { } }
public event System.ComponentModel.AsyncCompletedEventHandler? LoadCompleted { add { } remove { } }
public event System.EventHandler? SoundLocationChanged { add { } remove { } }
public event System.EventHandler? StreamChanged { add { } remove { } }
huoyaoyuan marked this conversation as resolved.
Show resolved Hide resolved
public void Load() { }
public void LoadAsync() { }
protected virtual void OnLoadCompleted(System.ComponentModel.AsyncCompletedEventArgs e) { }
Expand Down Expand Up @@ -68,7 +69,7 @@ public partial class XamlAccessLevel
{
internal XamlAccessLevel() { }
public System.Reflection.AssemblyName AssemblyAccessToAssemblyName { get { throw null; } }
public string PrivateAccessToTypeName { get { throw null; } }
public string? PrivateAccessToTypeName { get { throw null; } }
public static System.Xaml.Permissions.XamlAccessLevel AssemblyAccessTo(System.Reflection.Assembly assembly) { throw null; }
public static System.Xaml.Permissions.XamlAccessLevel AssemblyAccessTo(System.Reflection.AssemblyName assemblyName) { throw null; }
public static System.Xaml.Permissions.XamlAccessLevel PrivateAccessTo(string assemblyQualifiedTypeName) { throw null; }
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>$(NetCoreAppCurrent);netcoreapp3.1</TargetFrameworks>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<Compile Include="System.Windows.Extensions.cs" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
<PropertyGroup>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<TargetFrameworks>$(NetCoreAppCurrent)-windows;$(NetCoreAppCurrent);netcoreapp3.1-windows;netcoreapp3.1</TargetFrameworks>
<Nullable>enable</Nullable>
<IsPackable>true</IsPackable>
<PackageDescription>Provides miscellaneous Windows-specific types

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

using System.ComponentModel;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Net;
using System.Runtime.InteropServices;
Expand All @@ -18,7 +19,7 @@ public class SoundPlayer : Component, ISerializable
private const int BlockSize = 1024;
private const int DefaultLoadTimeout = 10000; // 10 secs

private Uri _uri;
private Uri? _uri;
private string _soundLocation = string.Empty;
private int _loadTimeout = DefaultLoadTimeout;

Expand All @@ -28,16 +29,16 @@ public class SoundPlayer : Component, ISerializable
// the worker copyTask
// we start the worker copyTask ONLY from entry points in the SoundPlayer API
// we also set the tread to null only from the entry points in the SoundPlayer API
private Task _copyTask;
private CancellationTokenSource _copyTaskCancellation;
private Task? _copyTask;
private CancellationTokenSource? _copyTaskCancellation;

// local buffer information
private int _currentPos;
private Stream _stream;
private Exception _lastLoadException;
private Stream? _stream;
private Exception? _lastLoadException;
private bool _doesLoadAppearSynchronous;
private byte[] _streamData;
private AsyncOperation _asyncOperation;
private byte[]? _streamData;
private AsyncOperation? _asyncOperation;
private readonly SendOrPostCallback _loadAsyncOperationCompleted;

// event
Expand All @@ -50,7 +51,7 @@ public SoundPlayer()
_loadAsyncOperationCompleted = new SendOrPostCallback(LoadAsyncOperationCompleted);
}

public SoundPlayer(string soundLocation) : this()
public SoundPlayer(string? soundLocation) : this()
huoyaoyuan marked this conversation as resolved.
Show resolved Hide resolved
{
SetupSoundLocation(soundLocation ?? string.Empty);
}
huoyaoyuan marked this conversation as resolved.
Show resolved Hide resolved
Expand Down Expand Up @@ -79,6 +80,7 @@ public int LoadTimeout
}
}

[AllowNull]
huoyaoyuan marked this conversation as resolved.
Show resolved Hide resolved
public string SoundLocation
{
get => _soundLocation;
Expand All @@ -99,7 +101,7 @@ public string SoundLocation
}
}

public Stream Stream
public Stream? Stream
{
get
{
Expand All @@ -126,7 +128,7 @@ public Stream Stream

public bool IsLoadCompleted { get; private set; }

public object Tag { get; set; }
public object? Tag { get; set; }

public void LoadAsync()
{
Expand Down Expand Up @@ -161,9 +163,9 @@ public void LoadAsync()
LoadStream(false);
}

private void LoadAsyncOperationCompleted(object arg)
private void LoadAsyncOperationCompleted(object? arg)
{
OnLoadCompleted((AsyncCompletedEventArgs)arg);
OnLoadCompleted((AsyncCompletedEventArgs)arg!);
}

// called for loading a stream synchronously
Expand Down Expand Up @@ -227,6 +229,7 @@ private void LoadAndPlay(int flags)
else
{
LoadSync();
Debug.Assert(_streamData != null);
ValidateSoundData(_streamData);
Interop.WinMM.PlaySound(_streamData, IntPtr.Zero, Interop.WinMM.SND_MEMORY | Interop.WinMM.SND_NODEFAULT | flags);
}
Expand Down Expand Up @@ -271,7 +274,9 @@ private void LoadSync()
_stream = webResponse.GetResponseStream();
}

if (_stream.CanSeek)
// DO NOT assert - NRE is expected for null stream
// See SoundPlayerTests.Load_NullStream_ThrowsNullReferenceException
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It'd be worth opening an issue for this to decide separately whether we should throw a better exception in that case.

if (_stream!.CanSeek)
{
// if we can get data synchronously, then get it
LoadStream(true);
Expand Down Expand Up @@ -304,6 +309,7 @@ private void LoadSync()

private void LoadStream(bool loadSync)
{
Debug.Assert(_stream != null);
if (loadSync && _stream.CanSeek)
{
int streamLen = (int)_stream.Length;
Expand Down Expand Up @@ -339,9 +345,9 @@ public void PlayLooping()
LoadAndPlay(Interop.WinMM.SND_LOOP | Interop.WinMM.SND_ASYNC);
}

private static Uri ResolveUri(string partialUri)
private static Uri? ResolveUri(string partialUri)
{
Uri result = null;
Uri? result = null;
try
{
result = new Uri(partialUri);
Expand Down Expand Up @@ -399,7 +405,7 @@ private void SetupSoundLocation(string soundLocation)
}
}

private void SetupStream(Stream stream)
private void SetupStream(Stream? stream)
{
if (_copyTask != null)
{
Expand All @@ -420,10 +426,10 @@ private void SetupStream(Stream stream)

public void Stop()
{
Interop.WinMM.PlaySound((byte[])null, IntPtr.Zero, Interop.WinMM.SND_PURGE);
Interop.WinMM.PlaySound((byte[]?)null, IntPtr.Zero, Interop.WinMM.SND_PURGE);
}

public event AsyncCompletedEventHandler LoadCompleted
public event AsyncCompletedEventHandler? LoadCompleted
{
add
{
Expand All @@ -435,7 +441,7 @@ public event AsyncCompletedEventHandler LoadCompleted
}
}

public event EventHandler SoundLocationChanged
public event EventHandler? SoundLocationChanged
{
add
{
Expand All @@ -447,7 +453,7 @@ public event EventHandler SoundLocationChanged
}
}

public event EventHandler StreamChanged
public event EventHandler? StreamChanged
{
add
{
Expand All @@ -461,17 +467,17 @@ public event EventHandler StreamChanged

protected virtual void OnLoadCompleted(AsyncCompletedEventArgs e)
{
((AsyncCompletedEventHandler)Events[s_eventLoadCompleted])?.Invoke(this, e);
((AsyncCompletedEventHandler?)Events[s_eventLoadCompleted])?.Invoke(this, e);
}

protected virtual void OnSoundLocationChanged(EventArgs e)
{
((EventHandler)Events[s_eventSoundLocationChanged])?.Invoke(this, e);
((EventHandler?)Events[s_eventSoundLocationChanged])?.Invoke(this, e);
}

protected virtual void OnStreamChanged(EventArgs e)
{
((EventHandler)Events[s_eventStreamChanged])?.Invoke(this, e);
((EventHandler?)Events[s_eventStreamChanged])?.Invoke(this, e);
}

private async Task CopyStreamAsync(CancellationToken cancellationToken)
Expand All @@ -484,7 +490,7 @@ private async Task CopyStreamAsync(CancellationToken cancellationToken)
#pragma warning disable SYSLIB0014 // WebRequest, HttpWebRequest, ServicePoint, and WebClient are obsolete. Use HttpClient instead.
WebRequest webRequest = WebRequest.Create(_uri);
#pragma warning restore SYSLIB0014
using (cancellationToken.Register(r => ((WebRequest)r).Abort(), webRequest))
using (cancellationToken.Register(r => ((WebRequest)r!).Abort(), webRequest))
{
WebResponse webResponse = await webRequest.GetResponseAsync().ConfigureAwait(false);
_stream = webResponse.GetResponseStream();
Expand All @@ -493,6 +499,7 @@ private async Task CopyStreamAsync(CancellationToken cancellationToken)

_streamData = new byte[BlockSize];

Debug.Assert(_stream != null);
int readBytes = await _stream.ReadAsync(_streamData.AsMemory(_currentPos, BlockSize), cancellationToken).ConfigureAwait(false);
int totalBytes = readBytes;

Expand Down Expand Up @@ -525,6 +532,7 @@ private async Task CopyStreamAsync(CancellationToken cancellationToken)
AsyncCompletedEventArgs ea = _lastLoadException is OperationCanceledException ?
new AsyncCompletedEventArgs(null, cancelled: true, null) :
new AsyncCompletedEventArgs(_lastLoadException, cancelled: false, null);
Debug.Assert(_asyncOperation != null);
_asyncOperation.PostOperationCompleted(_loadAsyncOperationCompleted, ea);
}
}
Expand All @@ -539,7 +547,7 @@ private unsafe void ValidateSoundFile(string fileName)

try
{
Interop.WinMM.WAVEFORMATEX waveFormat = null;
Interop.WinMM.WAVEFORMATEX? waveFormat = null;
var ckRIFF = new Interop.WinMM.MMCKINFO()
{
fccType = mmioFOURCC('W', 'A', 'V', 'E')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ namespace System.Media
{
public static class SystemSounds
{
private static volatile SystemSound s_asterisk;
private static volatile SystemSound s_beep;
private static volatile SystemSound s_exclamation;
private static volatile SystemSound s_hand;
private static volatile SystemSound s_question;
private static volatile SystemSound? s_asterisk;
private static volatile SystemSound? s_beep;
private static volatile SystemSound? s_exclamation;
private static volatile SystemSound? s_hand;
private static volatile SystemSound? s_question;

public static SystemSound Asterisk
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,15 @@ namespace System.Xaml.Permissions
{
public class XamlAccessLevel
{
private XamlAccessLevel(string assemblyName, string typeName)
private XamlAccessLevel(string assemblyName, string? typeName)
{
AssemblyNameString = assemblyName;
PrivateAccessToTypeName = typeName;
}

public static XamlAccessLevel AssemblyAccessTo(Assembly assembly)
{
return new XamlAccessLevel(assembly.FullName, null);
return new XamlAccessLevel(assembly.FullName!, null);
}

public static XamlAccessLevel AssemblyAccessTo(AssemblyName assemblyName)
Expand All @@ -26,7 +26,7 @@ public static XamlAccessLevel AssemblyAccessTo(AssemblyName assemblyName)

public static XamlAccessLevel PrivateAccessTo(Type type)
{
return new XamlAccessLevel(type.Assembly.FullName, type.FullName);
return new XamlAccessLevel(type.Assembly.FullName!, type.FullName);
}

public static XamlAccessLevel PrivateAccessTo(string assemblyQualifiedTypeName)
Expand All @@ -43,7 +43,7 @@ public AssemblyName AssemblyAccessToAssemblyName
get { return new AssemblyName(AssemblyNameString); }
}

public string PrivateAccessToTypeName { get; private set; }
public string? PrivateAccessToTypeName { get; private set; }

internal string AssemblyNameString { get; private set; }
}
Expand Down