Context: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1311
Context: https://learn.microsoft.com/previous-versions/dotnet/articles/ms994325(v=msdn.10)#the-turkish-example
In 8a58e01f, I found & fixed some performance issues around
culture-aware strings. This takes this further by making `CA1311` a
build error.
As mentioned in "the turkish example", doing something like:
string text = something.ToUpper();
switch (text) { ... }
Can actually cause unexpected behavior in Turkish locales, because in
Turkish, the character I (Unicode 0049) is considered the upper case
version of a different character ý (Unicode 0131), and i (Unicode
0069) is considered the lower case version of yet another character Ý
(Unicode 0130).
`ToLowerInvariant()` and `ToUpperInvariant()` are also better for
startup performance as it avoids loading the current culture.
I only found one place that actually *would* want to use the current
culture, which is in `CaseConverter.cs`.
Added the following new checks:
```csharp
// dotnet_style_coalesce_expression = true
var v = x ?? y;
// dotnet_style_coalesce_expression = false
var v = x != null ? x : y; // or
var v = x == null ? y : x;
```
```csharp
// dotnet_style_null_propagation = true
var v = o?.ToString();
// dotnet_style_null_propagation = false
var v = o == null ? null : o.ToString(); // or
var v = o != null ? o.String() : null;
```
```csharp
// dotnet_style_prefer_is_null_check_over_reference_equality_method = true
if (value is null)
return;
// dotnet_style_prefer_is_null_check_over_reference_equality_method = false
if (object.ReferenceEquals(value, null))
return;
// dotnet_style_prefer_is_null_check_over_reference_equality_method = false
if ((object)o == null)
return;
```
Context: https://github.com/Vroomer/MAUI-master-detail-memory-leak
Context: https://github.com/dotnet/maui/issues/12039
Using the Visual Studio's `.NET Object Allocation Tracking` profiler
on the sample above I noticed after app launch:
Microsoft.Maui.WeakEventManager+Subscription
Allocations: 686,114
Bytes: 21,955,648
After spitting out my coffee, I drilled in a bit to see where these
are being created:
System.Collections.Generic.ObjectEqualityComparer<Microsoft.Maui.WeakEventManager+Subscription>.IndexOf
It turns out this `struct` doesn't implement `IEquatable<T>`:
https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1815
To solve this:
* `Subscription` is private, so we can make it a `readonly struct`.
* `dotnet_diagnostic.CA1815.severity = error` across the entire repo.
* Implement `IEquatable<T>` for all `struct` types.
After these changes, I can't find `Microsoft.Maui.WeakEventManager+Subscription`
in the memory report at all. Which assuming means, I saved ~21 MB of
allocations in this app.
Note that this doesn't actually solve #12039, as I'm still
investigating the leak. Maybe this partially closes the floodgate?
* Fix `struct`s in Controls.Core
Note that I did not update these, as they are some "internal" parts
from Xamarin.Forms:
* `Profile`
* `Datum`
We might actually just consider removing these in the future.
* Suppress warnings in Compatibility
I assume these structs aren't nearly as important, so ignoring a few.
They appear to be called once at startup in most cases.
* Disable `CA1815` in tests.
* Restore and fix tvOS checks and annotations
Some of them got lost in https://github.com/dotnet/maui/pull/6237
* Remove PlatformVersion and use OperatingSystem APIs directly
* Handling Platform compatability analyzer warnings
* Review updates
* dogfood 7.0 preview netanalyzer
* Suppress warnings caused by annotations
* Handle/suppress few more
* Apply some of the feedbacks, fix some typos
* Apply some feedback, handle more warnings found in Core
* Handle warnings in Core
* Revert windows handlings, handling warnings in Compatibility
* Handle warnings found in Compatibility
* Review updates, handle Blazor warnings
* Suppress some conditionals, update analyzer version to dogfood latest bug fix
* Fix CI build failures, disable analyzer on test projects
* Fix more few failures found in CI run
* Small updates
* Propogate the ios version support
* Re review updates
* Disable analyzers on test projects
* Propagate platform supports
* Revert "Disable analyzers on test projects"
* Disable tests in sample projects
* Suppress a warning in sample program
* Remove unneeded version caused by bad merging
* Annotate AndroidWebKitWebViewManager type, update template version for android
* Revert unneeded change
* Fix bad merging
* Change some asserts for unsupported vertion into attributes
* Suppress Paint.Color setter calls instead guarding
* Apply more feedback
* Unsaved change missing from previous commit
* More SpannableString.Length() found with latest code
Co-authored-by: Matthew Leibowitz <mattleibow@live.com>
* Annotate BindableProperty.DeclaringType for ILLink
Ensure the corresponding property or method that the BindableProperty represents is preserved. These are needed because we use Reflection to find the property/method and inspect whether it has a TypeConverter attribute on it or not.
This is option (1) of #4997.
* PR feedback
Fix whitespace.
Use Array.Empty instead of allocating a new array.
* Use the `$(IsTrimmable)` MSBuild property instead of the C# assembly-level attribute
Enables Trim Analyzer, but disable COMAnalyzer due to https://github.com/dotnet/linker/issues/2686
* Add RequiresUnreferencedCode to BootstrapHelper.
Context: https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1307
Context: https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1309
Context: https://github.com/dotnet/runtime/issues/43956
I was reviewing `dotnet trace` output of the .NET Podcast app:
6.32ms Microsoft.Maui.Controls!Microsoft.Maui.Controls.ShellNavigationManager.GetNavigationState
3.82ms Microsoft.Maui.Controls!Microsoft.Maui.Controls.ShellUriHandler.FormatUri
The bulk of this time is spent in `string.StartsWith()`, doing a
culture-aware string comparison?
3.82ms System.Private.CoreLib!System.String.StartsWith
2.57ms System.Private.CoreLib!System.Globalization.CultureInfo.get_CurrentCulture
This looks to be showing the cost of the 1st culture-aware comparision
plus any time making these slower string comparisons. It would be
ideal if project templates did not even hit
`CultureInfo.get_CurrentCulture`.
To solve this, let's add to the `.editorconfig` file:
dotnet_diagnostic.CA1307.severity = error
dotnet_diagnostic.CA1309.severity = error
And then fix all the places errors appear.
There are some complications in projects that use `netstandard2.0`:
1. For `Contains()` use `IndexOf()` instead.
2. Use `#if NETSTANDARD2_0` for `GetHashCode()` or `Replace()`. Use the `char` overload
of `string.Replace()` where possible.
3. Generally, `InvariantCulture` should not be used.
After these changes, the `FormatUri` method disappears completely from
the trace, and we instead get:
2.88ms Microsoft.Maui.Controls!Microsoft.Maui.Controls.ShellNavigationManager.GetNavigationState
I suspect this saves ~3.44ms for any MAUI app startup, and a small
amount more depending on the number of string comparisions happening.
* [build] Update to .NET 6 Preview 4
Brings in Preview 4 updates for the Android, MaciOS, and .NET SDks.
Initial build attempts were failing with hundreds of errors:
D:\a\1\s\src\Essentials\src\Connectivity\Connectivity.ios.tvos.macos.cs(12,70): error BI1234: 'CTCellularData' is obsolete: 'Starting with ios14.0 Use the 'CallKit' API instead.' [D:\a\1\s\src\Essentials\src\Essentials-net6.csproj]
D:\a\1\s\src\Essentials\src\Compass\Compass.ios.cs(31,6): error CA1416: This call site is reachable on: 'iOS' 13.6 and later. 'CLLocationManager.HeadingFilter' is only supported on: 'macos' 11.0 and later. [D:\a\1\s\src\Essentials\src\Essentials-net6.csproj]
D:\a\1\s\src\Core\src\Platform\MaciOS\ColorExtensions.cs(64,13): error CA1416: This call site is reachable on: 'MacCatalyst' 13.5 and later. 'UIColor.SystemBackgroundColor.get' is supported on: 'ios' 13.0 and later. [D:\a\1\s\src\Core\src\Core-net6.csproj]
CSC : error AD0001: Analyzer 'Microsoft.NetCore.Analyzers.InteropServices.PlatformCompatibilityAnalyzer' threw an exception of type 'System.NullReferenceException' with message 'Object reference not set to an instance of an object.'. [D:\a\1\s\src\BlazorWebView\src\core\Microsoft.AspNetCore.Components.WebView.Maui.csproj]
The [platform compatibility analyzer][0] has been disabled for now, and
it can be enabled locally to work through the few hundred errors in
future PRs.
Once these issues were sorted, there were a handful of other breaks
that I've attempted to fix:
D:\a\1\s\src\Essentials\src\AssemblyInfo\AssemblyInfo.ios.tvos.watchos.macos.cs(3,12): error CS0618: 'LinkerSafeAttribute' is obsolete: 'Replace with '[assembly: System.Reflection.AssemblyMetadata ("IsTrimmable", "True")]'.' [D:\a\1\s\src\Essentials\src\Essentials-net6.csproj]
D:\a\1\s\src\Compatibility\Core\src\iOS\Renderers\TabbedRenderer.cs(422,33): error CS1503: Argument 1: cannot convert from 'UIKit.UIStringAttributes' to 'UIKit.UITextAttributes' [D:\a\1\s\src\Compatibility\Core\src\Compatibility-net6.csproj]
D:\a\1\s\src\Compatibility\Core\src\iOS\CollectionView\CarouselViewController.cs(106,23): error CS0114: 'CarouselViewController.DraggingStarted(UIScrollView)' hides inherited member 'UICollectionViewController.DraggingStarted(UIScrollView)'. To make the current member override that implementation, add the override keyword. Otherwise add the new keyword. [ D:\a\1\s\src\Compatibility\Core\src\Compatibility-net6.csproj]
D:\a\1\s\src\Compatibility\Core\src\iOS\CollectionView\CarouselViewController.cs(117,23): error CS0114: 'CarouselViewController.DraggingEnded(UIScrollView, bool)' hides inherited member 'UICollectionViewController.DraggingEnded(UIScrollView, bool)'. To make the current member override that implementation, add the override keyword. Otherwise add the new keyword. [ D:\a\1\s\src\Compatibility\Core\src\Compatibility-net6.csproj]
Finally it seems JDK 14 was being preferred on macOS machines in CI, so
I've set `$(JI_JAVA_HOME)` to the [pre-installed JDK 11][1].
[0]: https://docs.microsoft.com/en-us/dotnet/fundamentals/code-analysis/quality-rules/ca1416
[1]: https://github.com/actions/virtual-environments/blob/macOS-10.15/20210419.2/images/macos/macos-10.15-Readme.md#java
* Apply feedback, bump p4 bits, provision xcode 12.5 rc
* Use Big Sur pool, clean up duplicate variable declaration
* Revert "Use Big Sur pool, clean up duplicate variable declaration"
This reverts commit b91482e10c.
* Disable linker for ios and catalyst
Co-authored-by: Rui Marinho <me@ruimarinho.net>