[net9.0] Merge main into net9.0.

This commit is contained in:
Rolf Bjarne Kvinge 2024-04-16 18:01:21 +02:00
Родитель cf7a33ed2f 53d21b14db
Коммит 950304a898
44 изменённых файлов: 1279 добавлений и 16637 удалений

Просмотреть файл

@ -11,6 +11,11 @@ jobs:
updateSinglePlatformBranches:
name: Merge main into single-platform release test branches
runs-on: ubuntu-latest
# GITHUB_TOKEN change from read-write to read-only on 2024-02-01 requires permissions block
# https://docs.opensource.microsoft.com/github/apps/permission-changes/
# https://docs.github.com/en/actions/using-jobs/assigning-permissions-to-jobs
permissions:
contents: write
steps:
- name: Checkout repo

Просмотреть файл

@ -248,11 +248,10 @@ MONO_HASH := $(NEEDED_MONO_VERSION)
# Minimum Mono version for building XI/XM
MIN_MONO_VERSION=6.12.0.179
MAX_MONO_VERSION=6.12.99
MIN_MONO_URL=https://xamjenkinsartifact.blob.core.windows.net/build-package-osx-mono/2020-02/185/dffa5ab92245f2419238a35b7c2052e9a24036b4/MonoFramework-MDK-6.12.0.179.macos10.xamarin.universal.pkg
MIN_MONO_URL=https://download.mono-project.com/archive/6.12.0/macos-10-universal/MonoFramework-MDK-6.12.0.179.macos10.xamarin.universal.pkg
# Minimum Mono version for Xamarin.Mac apps using the system mono
MIN_XM_MONO_VERSION=6.4.0.94
MIN_XM_MONO_URL=https://xamjenkinsartifact.blob.core.windows.net/build-package-osx-mono/2019-06/77/c608cf3eafaea310e11af13cc9380d770112bb83/MonoFramework-MDK-6.4.0.94.macos10.xamarin.universal.pkg
# Minimum CMake version
MIN_CMAKE_URL=https://cmake.org/files/v3.6/cmake-3.6.2-Darwin-x86_64.dmg

Просмотреть файл

@ -137,6 +137,42 @@
</PropertyGroup>
<!-- Now that we know the runtime identifier, we can determine if we're building for a simulator -->
<PropertyGroup>
<_SdkIsSimulator Condition="$(RuntimeIdentifier.Contains('simulator')) Or $(RuntimeIdentifiers.Contains('simulator'))">true</_SdkIsSimulator>
<_SdkIsSimulator Condition="'$(_SdkIsSimulator)' == ''">false</_SdkIsSimulator>
</PropertyGroup>
<!-- Since we know if we're building for a simulator or not, we can determine the default trimming behavior -->
<PropertyGroup Condition="'$(TrimMode)' != ''">
<!-- If TrimMode is set, then that's the default link mode -->
<_DefaultLinkMode>TrimMode</_DefaultLinkMode>
</PropertyGroup>
<PropertyGroup Condition="'$(TrimMode)' == ''">
<!-- Linking is always on for all assemblies when using NativeAOT - this is because we need to modify all assemblies in the linker for them to be compatible with NativeAOT -->
<_DefaultLinkMode Condition="'$(_UseNativeAot)' == 'true'">Full</_DefaultLinkMode>
<_DefaultLinkMode Condition="'$(_UseNativeAot)' != 'true' And '$(_PlatformName)' == 'macOS'">None</_DefaultLinkMode> <!-- Linking is off by default for macOS apps -->
<_DefaultLinkMode Condition="'$(_UseNativeAot)' != 'true' And '$(_PlatformName)' == 'MacCatalyst' And '$(Configuration)' == 'Release'">SdkOnly</_DefaultLinkMode> <!-- Default linking is on for release builds for Mac Catalyst apps -->
<_DefaultLinkMode Condition="'$(_UseNativeAot)' != 'true' And '$(_PlatformName)' == 'MacCatalyst' And '$(Configuration)' != 'Release'">None</_DefaultLinkMode> <!-- Default linking is off for non-release builds for Mac Catalyst apps -->
<_DefaultLinkMode Condition="'$(_UseNativeAot)' != 'true' And '$(_PlatformName)' != 'macOS' And '$(_PlatformName)' != 'MacCatalyst' And '$(_SdkIsSimulator)' == 'true'">None</_DefaultLinkMode> <!-- Linking is off by default in the simulator -->
<_DefaultLinkMode Condition="'$(_UseNativeAot)' != 'true' And '$(_PlatformName)' != 'macOS' And '$(_PlatformName)' != 'MacCatalyst' And '$(_SdkIsSimulator)' != 'true'">SdkOnly</_DefaultLinkMode> <!-- Linking is SdkOnly for iOS/tvOS/watchOS apps on device -->
</PropertyGroup>
<PropertyGroup>
<_LinkMode Condition="'$(_LinkMode)' == '' And '$(_PlatformName)' == 'macOS'">$(LinkMode)</_LinkMode>
<_LinkMode Condition="'$(_LinkMode)' == '' And '$(_PlatformName)' != 'macOS'">$(MtouchLink)</_LinkMode>
<_LinkMode Condition="'$(_LinkMode)' == ''">$(_DefaultLinkMode)</_LinkMode>
<_LinkMode Condition="'$(_LinkMode)' == '' And '$(_PlatformName)' == 'macOS'">None</_LinkMode> <!-- Linking is off by default for macOS apps -->
<_LinkMode Condition="'$(_LinkMode)' == '' And '$(_PlatformName)' != 'macOS'">SdkOnly</_LinkMode> <!-- Default linking is SdkOnly for iOS/tvOS/watchOS apps -->
<!-- TrimMode specifies what the linker will do with framework assemblies -->
<TrimMode Condition="'$(_LinkMode)' == 'TrimMode'">$(TrimMode)</TrimMode>
<TrimMode Condition="'$(_LinkMode)' == 'None'">copy</TrimMode>
<TrimMode Condition="'$(_LinkMode)' == 'SdkOnly'">partial</TrimMode>
<TrimMode Condition="'$(_LinkMode)' == 'Full'">full</TrimMode>
<!-- For None link mode we also need to set TrimMode for all assemblies. This is done later -->
</PropertyGroup>
<!-- We're never using any app hosts -->
<PropertyGroup>
<_RuntimeIdentifierUsesAppHost>false</_RuntimeIdentifierUsesAppHost>

Просмотреть файл

@ -1643,29 +1643,6 @@
</ReadItemsFromFile>
</Target>
<Target Name="_ComputeDefaultLinkMode" DependsOnTargets="_DetectSdkLocations">
<PropertyGroup Condition="'$(TrimMode)' != ''">
<!-- If TrimMode is set, then that's the default link mode -->
<_DefaultLinkMode>TrimMode</_DefaultLinkMode>
</PropertyGroup>
<PropertyGroup Condition="'$(TrimMode)' == ''">
<!-- Linking is always on for all assemblies when using NativeAOT - this is because we need to modify all assemblies in the linker for them to be compatible with NativeAOT -->
<_DefaultLinkMode Condition="'$(_UseNativeAot)' == 'true'">Full</_DefaultLinkMode>
<_DefaultLinkMode Condition="'$(_UseNativeAot)' != 'true' And '$(_PlatformName)' == 'macOS'">None</_DefaultLinkMode> <!-- Linking is off by default for macOS apps -->
<_DefaultLinkMode Condition="'$(_UseNativeAot)' != 'true' And '$(_PlatformName)' == 'MacCatalyst' And '$(Configuration)' == 'Release'">SdkOnly</_DefaultLinkMode> <!-- Default linking is on for release builds for Mac Catalyst apps -->
<_DefaultLinkMode Condition="'$(_UseNativeAot)' != 'true' And '$(_PlatformName)' == 'MacCatalyst' And '$(Configuration)' != 'Release'">None</_DefaultLinkMode> <!-- Default linking is off for non-release builds for Mac Catalyst apps -->
<_DefaultLinkMode Condition="'$(_UseNativeAot)' != 'true' And '$(_PlatformName)' != 'macOS' And '$(_PlatformName)' != 'MacCatalyst' And '$(_SdkIsSimulator)' == 'true'">None</_DefaultLinkMode> <!-- Linking is off by default in the simulator -->
<_DefaultLinkMode Condition="'$(_UseNativeAot)' != 'true' And '$(_PlatformName)' != 'macOS' And '$(_PlatformName)' != 'MacCatalyst' And '$(_SdkIsSimulator)' != 'true'">SdkOnly</_DefaultLinkMode> <!-- Linking is SdkOnly for iOS/tvOS/watchOS apps on device -->
</PropertyGroup>
</Target>
<PropertyGroup>
<_ComputeLinkModeDependsOn>
$(_ComputeLinkModeDependsOn);
_ComputeDefaultLinkMode;
</_ComputeLinkModeDependsOn>
</PropertyGroup>
<PropertyGroup>
<_CodesignAppBundleDependsOn Condition="'$(RuntimeIdentifiers)' != ''">
_CollectRidSpecificCodesignItems;

Просмотреть файл

@ -11,7 +11,7 @@
<MicrosoftNETRuntimeMonoTargetsSdkPackageVersion>9.0.0-alpha.1.23556.4</MicrosoftNETRuntimeMonoTargetsSdkPackageVersion>
<MicrosoftTemplateEngineTasksVersion>7.0.100-alpha.1.21601.1</MicrosoftTemplateEngineTasksVersion>
<MicrosoftDotNetCecilPackageVersion>0.11.4-alpha.24168.1</MicrosoftDotNetCecilPackageVersion>
<MicrosoftDotNetXHarnessiOSSharedPackageVersion>9.0.0-prerelease.24203.1</MicrosoftDotNetXHarnessiOSSharedPackageVersion>
<MicrosoftDotNetXHarnessiOSSharedPackageVersion>9.0.0-prerelease.24208.1</MicrosoftDotNetXHarnessiOSSharedPackageVersion>
<!-- Manually updated versions -->
<Emscriptennet7WorkloadVersion>$(MicrosoftNETWorkloadEmscriptenCurrentManifest80100Version)</Emscriptennet7WorkloadVersion>
<EmscriptenWorkloadVersion>$(MicrosoftNETWorkloadEmscriptenCurrentManifest80100Version)</EmscriptenWorkloadVersion>

Просмотреть файл

@ -2278,7 +2278,7 @@ Copyright (C) 2018 Microsoft. All rights reserved.
</_ComputeLinkModeDependsOn>
</PropertyGroup>
<Target Name="_ComputeLinkMode" DependsOnTargets="$(_ComputeLinkModeDependsOn)">
<PropertyGroup>
<PropertyGroup Condition="'$(UsingAppleNETSdk)' != 'true'"> <!-- this is already done outside of a target for .NET -->
<_LinkMode Condition="'$(_LinkMode)' == '' And '$(_PlatformName)' == 'macOS'">$(LinkMode)</_LinkMode>
<_LinkMode Condition="'$(_LinkMode)' == '' And '$(_PlatformName)' != 'macOS'">$(MtouchLink)</_LinkMode>
<_LinkMode Condition="'$(_LinkMode)' == ''">$(_DefaultLinkMode)</_LinkMode> <!-- Let the .NET targets chime in -->

Просмотреть файл

@ -1,10 +1,17 @@
#nullable enable
using System;
using System.Globalization;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
#if !NO_SYSTEM_DRAWING
using System.Drawing;
#endif
using CoreFoundation;
using Foundation;
using ObjCRuntime;
namespace CoreGraphics {
@ -16,15 +23,167 @@ namespace CoreGraphics {
[SupportedOSPlatform ("macos")]
[SupportedOSPlatform ("tvos")]
#endif
// the remaining of the struct is defined inside src/NativeTypes/Drawing.tt
public partial struct CGPoint {
[Serializable]
public struct CGPoint : IEquatable<CGPoint> {
nfloat x;
nfloat y;
#if NET
public override int GetHashCode ()
public static readonly CGPoint Empty;
#if !COREBUILD
public static bool operator == (CGPoint l, CGPoint r)
{
return HashCode.Combine (x, y);
// the following version of Equals cannot be removed by the linker, while == can be
return l.Equals (r);
}
public static bool operator != (CGPoint l, CGPoint r)
{
return l.x != r.x || l.y != r.y;
}
public static CGPoint operator + (CGPoint l, CGSize r)
{
return new CGPoint (l.x + r.Width, l.y + r.Height);
}
public static CGPoint operator - (CGPoint l, CGSize r)
{
return new CGPoint (l.x - r.Width, l.y - r.Height);
}
#if !NO_SYSTEM_DRAWING
public static implicit operator CGPoint (PointF point)
{
return new CGPoint (point.X, point.Y);
}
public static implicit operator CGPoint (Point point)
{
return new CGPoint (point.X, point.Y);
}
public static explicit operator PointF (CGPoint point)
{
return new PointF ((float) point.X, (float) point.Y);
}
public static explicit operator Point (CGPoint point)
{
return new Point ((int) point.X, (int) point.Y);
}
#endif
public static CGPoint Add (CGPoint point, CGSize size)
{
return point + size;
}
public static CGPoint Subtract (CGPoint point, CGSize size)
{
return point - size;
}
public nfloat X {
get { return x; }
set { x = value; }
}
public nfloat Y {
get { return y; }
set { y = value; }
}
public bool IsEmpty {
get { return x == 0.0 && y == 0.0; }
}
#endif // !COREBUILD
public CGPoint (nfloat x, nfloat y)
{
this.x = x;
this.y = y;
}
#if !COREBUILD
public CGPoint (double x, double y)
{
this.x = (nfloat) x;
this.y = (nfloat) y;
}
public CGPoint (float x, float y)
{
this.x = x;
this.y = y;
}
public CGPoint (CGPoint point)
{
this.x = point.x;
this.y = point.y;
}
public static bool TryParse (NSDictionary? dictionaryRepresentation, out CGPoint point)
{
if (dictionaryRepresentation is null) {
point = Empty;
return false;
}
unsafe {
point = default;
return NativeDrawingMethods.CGPointMakeWithDictionaryRepresentation (dictionaryRepresentation.Handle, (CGPoint*) Unsafe.AsPointer<CGPoint> (ref point)) != 0;
}
}
public NSDictionary ToDictionary ()
{
return new NSDictionary (NativeDrawingMethods.CGPointCreateDictionaryRepresentation (this));
}
#endif // !COREBUILD
public override bool Equals (object? obj)
{
return (obj is CGPoint t) && Equals (t);
}
public bool Equals (CGPoint point)
{
return point.x == x && point.y == y;
}
public override int GetHashCode ()
{
#if NET
return HashCode.Combine (x, y);
#else
var hash = 23;
hash = hash * 31 + x.GetHashCode ();
hash = hash * 31 + y.GetHashCode ();
return hash;
#endif
}
#if !COREBUILD
public void Deconstruct (out nfloat x, out nfloat y)
{
x = X;
y = Y;
}
public override string? ToString ()
{
#if NET
return CFString.FromHandle (NSStringFromCGPoint (this));
#else
return String.Format ("{{X={0}, Y={1}}}",
x.ToString (CultureInfo.CurrentCulture),
y.ToString (CultureInfo.CurrentCulture)
);
#endif
}
#if NET
#if MONOMAC
// <quote>When building for 64 bit systems, or building 32 bit like 64 bit, NSPoint is typedefd to CGPoint.</quote>
// https://developer.apple.com/documentation/foundation/nspoint?language=objc
@ -34,14 +193,7 @@ namespace CoreGraphics {
[DllImport (Constants.UIKitLibrary)]
extern static /* NSString* */ IntPtr NSStringFromCGPoint (CGPoint point);
#endif // MONOMAC
#if !COREBUILD
public override string? ToString ()
{
return CFString.FromHandle (NSStringFromCGPoint (this));
}
#endif
#endif // !NET
#endif // !COREBUILD
}
}

Просмотреть файл

@ -1,22 +1,384 @@
#nullable enable
using System;
using System.Globalization;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
#if !NO_SYSTEM_DRAWING
using System.Drawing;
#endif
using CoreFoundation;
using Foundation;
using ObjCRuntime;
namespace CoreGraphics {
// the remaining of the struct is defined inside src/NativeTypes/Drawing.tt
public partial struct CGRect {
[Serializable]
public struct CGRect : IEquatable<CGRect> {
nfloat x;
nfloat y;
nfloat width;
nfloat height;
#if NET
public override int GetHashCode ()
{
return HashCode.Combine (x, y, width, height);
#if !COREBUILD
[Field ("CGRectZero", "CoreGraphics")] // unused but helps xtro
#endif
public static readonly CGRect Empty;
#if !COREBUILD
[Field ("CGRectNull", "CoreGraphics")] // unused but helps xtro
public static CGRect Null {
get { return Dlfcn.GetCGRect (Libraries.CoreGraphics.Handle, "CGRectNull"); }
}
[Field ("CGRectInfinite", "CoreGraphics")] // unused but helps xtro
public static CGRect Infinite {
get { return Dlfcn.GetCGRect (Libraries.CoreGraphics.Handle, "CGRectInfinite"); }
}
public static bool operator == (CGRect left, CGRect right)
{
// the following version of Equals cannot be removed by the linker, while == can be
return left.Equals (right);
}
public static bool operator != (CGRect left, CGRect right)
{
return
left.X != right.X ||
left.Y != right.Y ||
left.Width != right.Width ||
left.Height != right.Height;
}
#if !NO_SYSTEM_DRAWING
public static implicit operator CGRect (RectangleF rect)
{
return new CGRect (rect.X, rect.Y, rect.Width, rect.Height);
}
public static implicit operator CGRect (Rectangle rect)
{
return new CGRect (rect.X, rect.Y, rect.Width, rect.Height);
}
public static explicit operator RectangleF (CGRect rect)
{
return new RectangleF ((float) rect.X, (float) rect.Y, (float) rect.Width, (float) rect.Height);
}
public static explicit operator Rectangle (CGRect rect)
{
return new Rectangle ((int) rect.X, (int) rect.Y, (int) rect.Width, (int) rect.Height);
}
#endif
public static CGRect Intersect (CGRect a, CGRect b)
{
// MS.NET returns a non-empty rectangle if the two rectangles
// touch each other
if (!a.IntersectsWithInclusive (b)) {
return Empty;
}
return FromLTRB (
(nfloat) Math.Max (a.Left, b.Left),
(nfloat) Math.Max (a.Top, b.Top),
(nfloat) Math.Min (a.Right, b.Right),
(nfloat) Math.Min (a.Bottom, b.Bottom)
);
}
public void Intersect (CGRect rect)
{
this = CGRect.Intersect (this, rect);
}
public static CGRect Union (CGRect a, CGRect b)
{
return FromLTRB (
(nfloat) Math.Min (a.Left, b.Left),
(nfloat) Math.Min (a.Top, b.Top),
(nfloat) Math.Max (a.Right, b.Right),
(nfloat) Math.Max (a.Bottom, b.Bottom)
);
}
public static CGRect FromLTRB (nfloat left, nfloat top, nfloat right, nfloat bottom)
{
return new CGRect (left, top, right - left, bottom - top);
}
public static CGRect Inflate (CGRect rect, nfloat x, nfloat y)
{
var inflated = new CGRect (rect.X, rect.Y, rect.Width, rect.Height);
inflated.Inflate (x, y);
return inflated;
}
public bool IsEmpty {
get { return width == 0.0 || height == 0.0; }
}
public nfloat X {
get { return x; }
set { x = value; }
}
public nfloat Y {
get { return y; }
set { y = value; }
}
public nfloat Width {
get { return width; }
set { width = value; }
}
public nfloat Height {
get { return height; }
set { height = value; }
}
public nfloat Top {
get { return Y; }
}
public nfloat Bottom {
get { return Y + Height; }
}
public nfloat Left {
get { return X; }
}
public nfloat Right {
get { return X + Width; }
}
public CGPoint Location {
get { return new CGPoint (x, y); }
set {
x = value.X;
y = value.Y;
}
}
public CGSize Size {
get { return new CGSize (width, height); }
set {
width = value.Width;
height = value.Height;
}
}
public CGRect (CGPoint location, CGSize size)
{
x = location.X;
y = location.Y;
width = size.Width;
height = size.Height;
}
#endif // !COREBUILD
public CGRect (nfloat x, nfloat y, nfloat width, nfloat height)
{
this.x = x;
this.y = y;
this.width = width;
this.height = height;
}
#if !COREBUILD
public CGRect (double x, double y, double width, double height)
{
this.x = (nfloat) x;
this.y = (nfloat) y;
this.width = (nfloat) width;
this.height = (nfloat) height;
}
public CGRect (float x, float y, float width, float height)
{
this.x = x;
this.y = y;
this.width = width;
this.height = height;
}
public bool Contains (nfloat x, nfloat y)
{
return
x >= Left &&
x < Right &&
y >= Top &&
y < Bottom;
}
public bool Contains (float x, float y)
{
return Contains ((nfloat) x, (nfloat) y);
}
public bool Contains (double x, double y)
{
return Contains ((nfloat) x, (nfloat) y);
}
public bool Contains (CGPoint point)
{
return Contains (point.X, point.Y);
}
public bool Contains (CGRect rect)
{
return
X <= rect.X &&
Right >= rect.Right &&
Y <= rect.Y &&
Bottom >= rect.Bottom;
}
public void Inflate (nfloat x, nfloat y)
{
this.x -= x;
this.y -= y;
width += x * 2;
height += y * 2;
}
public void Inflate (float x, float y)
{
Inflate ((nfloat) x, (nfloat) y);
}
public void Inflate (double x, double y)
{
Inflate ((nfloat) x, (nfloat) y);
}
public void Inflate (CGSize size)
{
Inflate (size.Width, size.Height);
}
public void Offset (nfloat x, nfloat y)
{
X += x;
Y += y;
}
public void Offset (float x, float y)
{
Offset ((nfloat) x, (nfloat) y);
}
public void Offset (double x, double y)
{
Offset ((nfloat) x, (nfloat) y);
}
public void Offset (CGPoint pos)
{
Offset (pos.X, pos.Y);
}
public bool IntersectsWith (CGRect rect)
{
return !(
Left >= rect.Right ||
Right <= rect.Left ||
Top >= rect.Bottom ||
Bottom <= rect.Top
);
}
private bool IntersectsWithInclusive (CGRect r)
{
return !(
Left > r.Right ||
Right < r.Left ||
Top > r.Bottom ||
Bottom < r.Top
);
}
#endif // !COREBUILD
public override bool Equals (object? obj)
{
return (obj is CGRect rect) && Equals (rect);
}
public bool Equals (CGRect rect)
{
return
x == rect.x &&
y == rect.y &&
width == rect.width &&
height == rect.height;
}
public override int GetHashCode ()
{
#if NET
return HashCode.Combine (x, y, width, height);
#else
var hash = 23;
hash = hash * 31 + x.GetHashCode ();
hash = hash * 31 + y.GetHashCode ();
hash = hash * 31 + width.GetHashCode ();
hash = hash * 31 + height.GetHashCode ();
return hash;
#endif
}
#if !COREBUILD
public override string? ToString ()
{
#if NET
return CFString.FromHandle (NSStringFromCGRect (this));
#else
return String.Format ("{{X={0},Y={1},Width={2},Height={3}}}",
x, y, width, height);
#endif
}
public void Deconstruct (out nfloat x, out nfloat y, out nfloat width, out nfloat height)
{
x = X;
y = Y;
width = Width;
height = Height;
}
public void Deconstruct (out CGPoint location, out CGSize size)
{
location = Location;
size = Size;
}
public static bool TryParse (NSDictionary? dictionaryRepresentation, out CGRect rect)
{
if (dictionaryRepresentation is null) {
rect = Empty;
return false;
}
rect = default;
unsafe {
return NativeDrawingMethods.CGRectMakeWithDictionaryRepresentation (dictionaryRepresentation.Handle, (CGRect*) Unsafe.AsPointer<CGRect> (ref rect)) != 0;
}
}
public NSDictionary ToDictionary ()
{
return new NSDictionary (NativeDrawingMethods.CGRectCreateDictionaryRepresentation (this));
}
#if NET
#if MONOMAC
// <quote>When building for 64 bit systems, or building 32 bit like 64 bit, NSRect is typedefd to CGRect.</quote>
// https://developer.apple.com/documentation/foundation/nsrect?language=objc
@ -26,14 +388,7 @@ namespace CoreGraphics {
[DllImport (Constants.UIKitLibrary)]
extern static /* NSString* */ IntPtr NSStringFromCGRect (CGRect rect);
#endif // MONOMAC
#if !COREBUILD
public override string? ToString ()
{
return CFString.FromHandle (NSStringFromCGRect (this));
}
#endif
#endif // !NET
#endif // !COREBUILD
}
}

Просмотреть файл

@ -1,22 +1,217 @@
#nullable enable
using System;
using System.Globalization;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
#if !NO_SYSTEM_DRAWING
using System.Drawing;
#endif
using CoreFoundation;
using Foundation;
using ObjCRuntime;
namespace CoreGraphics {
// the remaining of the struct is defined inside src/NativeTypes/Drawing.tt
public partial struct CGSize {
[Serializable]
public struct CGSize : IEquatable<CGSize> {
nfloat width;
nfloat height;
#if NET
public override int GetHashCode ()
public static readonly CGSize Empty;
#if !COREBUILD
public static bool operator == (CGSize l, CGSize r)
{
return HashCode.Combine (width, height);
// the following version of Equals cannot be removed by the linker, while == can be
return l.Equals (r);
}
public static bool operator != (CGSize l, CGSize r)
{
return l.width != r.width || l.height != r.height;
}
public static CGSize operator + (CGSize l, CGSize r)
{
return new CGSize (l.width + r.Width, l.height + r.Height);
}
public static CGSize operator - (CGSize l, CGSize r)
{
return new CGSize (l.width - r.Width, l.height - r.Height);
}
#if !NO_SYSTEM_DRAWING
public static implicit operator CGSize (SizeF size)
{
return new CGSize (size.Width, size.Height);
}
public static implicit operator CGSize (Size size)
{
return new CGSize (size.Width, size.Height);
}
public static explicit operator SizeF (CGSize size)
{
return new SizeF ((float) size.Width, (float) size.Height);
}
public static explicit operator Size (CGSize size)
{
return new Size ((int) size.Width, (int) size.Height);
}
#endif
public static explicit operator CGPoint (CGSize size)
{
return new CGPoint (size.Width, size.Height);
}
public static CGSize Add (CGSize size1, CGSize size2)
{
return size1 + size2;
}
public static CGSize Subtract (CGSize size1, CGSize size2)
{
return size1 - size2;
}
public nfloat Width {
get { return width; }
set { width = value; }
}
public nfloat Height {
get { return height; }
set { height = value; }
}
public bool IsEmpty {
get { return width == 0.0 && height == 0.0; }
}
#endif // !COREBUILD
public CGSize (nfloat width, nfloat height)
{
this.width = width;
this.height = height;
}
#if !COREBUILD
public CGSize (double width, double height)
{
this.width = (nfloat) width;
this.height = (nfloat) height;
}
public CGSize (float width, float height)
{
this.width = width;
this.height = height;
}
public CGSize (CGSize size)
{
this.width = size.width;
this.height = size.height;
}
public static bool TryParse (NSDictionary? dictionaryRepresentation, out CGSize size)
{
if (dictionaryRepresentation is null) {
size = Empty;
return false;
}
unsafe {
size = default;
return NativeDrawingMethods.CGSizeMakeWithDictionaryRepresentation (dictionaryRepresentation.Handle, (CGSize*) Unsafe.AsPointer<CGSize> (ref size)) != 0;
}
}
public NSDictionary ToDictionary ()
{
return new NSDictionary (NativeDrawingMethods.CGSizeCreateDictionaryRepresentation (this));
}
public CGSize (CGPoint point)
{
this.width = point.X;
this.height = point.Y;
}
#endif // !COREBUILD
public override bool Equals (object? obj)
{
return (obj is CGSize t) && Equals (t);
}
public bool Equals (CGSize size)
{
return size.width == width && size.height == height;
}
public override int GetHashCode ()
{
#if NET
return HashCode.Combine (width, height);
#else
var hash = 23;
hash = hash * 31 + width.GetHashCode ();
hash = hash * 31 + height.GetHashCode ();
return hash;
#endif
}
#if !COREBUILD
public void Deconstruct (out nfloat width, out nfloat height)
{
width = Width;
height = Height;
}
public CGSize ToRoundedCGSize ()
{
return new CGSize ((nfloat) Math.Round (width), (nfloat) Math.Round (height));
}
#if !XAMCORE_3_0
[Obsolete ("Use 'ToRoundedCGSize' instead.")]
public CGSize ToSize ()
{
return ToRoundedCGSize ();
}
[Obsolete ("Use 'ToCGPoint' instead.")]
public CGPoint ToPointF ()
{
return (CGPoint) this;
}
#endif
public CGPoint ToCGPoint ()
{
return (CGPoint) this;
}
public override string? ToString ()
{
#if NET
return CFString.FromHandle (NSStringFromCGSize (this));
#else
return String.Format ("{{Width={0}, Height={1}}}",
width.ToString (CultureInfo.CurrentCulture),
height.ToString (CultureInfo.CurrentCulture)
);
#endif
}
#if NET
#if MONOMAC
// <quote>When building for 64 bit systems, or building 32 bit like 64 bit, NSSize is typedefd to CGSize.</quote>
// https://developer.apple.com/documentation/foundation/nssize?language=objc
@ -26,14 +221,7 @@ namespace CoreGraphics {
[DllImport (Constants.UIKitLibrary)]
extern static /* NSString* */ IntPtr NSStringFromCGSize (CGSize size);
#endif // MONOMAC
#if !COREBUILD
public override string? ToString ()
{
return CFString.FromHandle (NSStringFromCGSize (this));
}
#endif
#endif // !NET
#endif // !COREBUILD
}
}

Просмотреть файл

@ -0,0 +1,30 @@
using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using ObjCRuntime;
#nullable enable
namespace CoreGraphics {
static class NativeDrawingMethods {
#if MONOMAC
internal const string CG = Constants.ApplicationServicesCoreGraphicsLibrary;
#else
internal const string CG = Constants.CoreGraphicsLibrary;
#endif
[DllImport (CG)]
internal unsafe extern static byte CGRectMakeWithDictionaryRepresentation (IntPtr dict, CGRect* rect);
[DllImport (CG)]
internal unsafe extern static byte CGPointMakeWithDictionaryRepresentation (IntPtr dict, CGPoint* point);
[DllImport (CG)]
internal unsafe extern static byte CGSizeMakeWithDictionaryRepresentation (IntPtr dict, CGSize* point);
[DllImport (CG)]
internal extern static IntPtr CGRectCreateDictionaryRepresentation (CGRect rect);
[DllImport (CG)]
internal extern static IntPtr CGSizeCreateDictionaryRepresentation (CGSize size);
[DllImport (CG)]
internal extern static IntPtr CGPointCreateDictionaryRepresentation (CGPoint point);
}
}

Просмотреть файл

@ -1,646 +0,0 @@
// !!! WARNING - GENERATED CODE - DO NOT EDIT !!!
//
// Generated by Drawing.tt, a T4 template.
//
// Drawing.cs: basic types with 32 or 64 bit member sizes:
//
// - CGSize { nfloat, nfloat }
// - CGPoint { nfloat, nfloat }
// - CGRect { nfloat, nfloat, nfloat, nfloat }
//
// If ARCH_32 is defined, the underlying types for n* types will be
// 32 bit (int, uint, float). If not defined, the underlying types
// will be 64 bit (long, ulong, double).
//
// Authors:
// Aaron Bockover <abock@xamarin.com>
// Miguel de Icaza <miguel@xamarin.com>
//
// Copyright 2020 Microsoft Corp. All Rights Reserved.
// Copyright 2013 Xamarin, Inc. All rights reserved.
//
<#@ template language="C#v3.5" #>
<#@ import namespace="System" #>
<#@ import namespace="System.Collections.Generic" #>
using System;
#if !NO_SYSTEM_DRAWING
using System.Drawing;
#endif
using System.Globalization;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using Foundation;
using ObjCRuntime;
// Disable until we get around to enable + fix any issues.
#nullable disable
namespace CoreGraphics
{
<#
Func<string, string> ucfirst = s => Char.ToUpper (s [0]) + s.Substring (1);
foreach (var type in new [] {
new { Name = "CGPoint", SDFloatName = "PointF", SDIntName = "Point", ArgName = "point", X_Width = "x", Y_Height = "y" },
new { Name = "CGSize", SDFloatName = "SizeF", SDIntName = "Size", ArgName = "size", X_Width = "width", Y_Height = "height" }
}) {
#>
[Serializable]
public partial struct <#= type.Name #> : IEquatable<<#= type.Name #>>
{
public static readonly <#= type.Name #> Empty;
public static bool operator == (<#= type.Name #> l, <#= type.Name #> r)
{
// the following version of Equals cannot be removed by the linker, while == can be
return l.Equals (r);
}
public static bool operator != (<#= type.Name #> l, <#= type.Name #> r)
{
return l.<#= type.X_Width #> != r.<#= type.X_Width #> || l.<#= type.Y_Height #> != r.<#= type.Y_Height #>;
}
public static <#= type.Name #> operator + (<#= type.Name #> l, CGSize r)
{
return new <#= type.Name #> (l.<#= type.X_Width #> + r.Width, l.<#= type.Y_Height #> + r.Height);
}
public static <#= type.Name #> operator - (<#= type.Name #> l, CGSize r)
{
return new <#= type.Name #> (l.<#= type.X_Width #> - r.Width, l.<#= type.Y_Height #> - r.Height);
}
#if !NO_SYSTEM_DRAWING
public static implicit operator <#= type.Name #> (<#= type.SDFloatName #> <#= type.ArgName #>)
{
return new <#= type.Name #> (<#= String.Format ("{0}.{1}, {0}.{2}", type.ArgName,
ucfirst (type.X_Width), ucfirst (type.Y_Height)) #>);
}
public static implicit operator <#= type.Name #> (<#= type.SDIntName #> <#= type.ArgName #>)
{
return new <#= type.Name #> (<#= String.Format ("{0}.{1}, {0}.{2}", type.ArgName,
ucfirst (type.X_Width), ucfirst (type.Y_Height)) #>);
}
public static explicit operator <#= type.SDFloatName #> (<#= type.Name #> <#= type.ArgName #>)
{
return new <#= type.SDFloatName #> (<#= String.Format ("(float){0}.{1}, (float){0}.{2}", type.ArgName,
ucfirst (type.X_Width), ucfirst (type.Y_Height)) #>);
}
public static explicit operator <#= type.SDIntName #> (<#= type.Name #> <#= type.ArgName #>)
{
return new <#= type.SDIntName #> (<#= String.Format ("(int){0}.{1}, (int){0}.{2}", type.ArgName,
ucfirst (type.X_Width), ucfirst (type.Y_Height)) #>);
}
#endif
<# if (type.Name == "CGPoint") { #>
public static CGPoint Add (CGPoint point, CGSize size)
{
return point + size;
}
public static CGPoint Subtract (CGPoint point, CGSize size)
{
return point - size;
}
<# } else { #>
public static explicit operator CGPoint (CGSize size)
{
return new CGPoint (size.Width, size.Height);
}
public static CGSize Add (CGSize size1, CGSize size2)
{
return size1 + size2;
}
public static CGSize Subtract (CGSize size1, CGSize size2)
{
return size1 - size2;
}
<# } #>
nfloat <#= type.X_Width #>;
nfloat <#= type.Y_Height #>;
public nfloat <#= ucfirst (type.X_Width) #> {
get { return <#= type.X_Width #>; }
set { <#= type.X_Width #> = value; }
}
public nfloat <#= ucfirst (type.Y_Height) #> {
get { return <#= type.Y_Height #>; }
set { <#= type.Y_Height #> = value; }
}
public bool IsEmpty {
get { return <#= type.X_Width #> == 0.0 && <#= type.Y_Height #> == 0.0; }
}
public <#= type.Name #> (nfloat <#= type.X_Width #>, nfloat <#= type.Y_Height #>)
{
this.<#= type.X_Width #> = <#= type.X_Width #>;
this.<#= type.Y_Height #> = <#= type.Y_Height #>;
}
public <#= type.Name #> (double <#= type.X_Width #>, double <#= type.Y_Height #>)
{
this.<#= type.X_Width #> = (nfloat)<#= type.X_Width #>;
this.<#= type.Y_Height #> = (nfloat)<#= type.Y_Height #>;
}
public <#= type.Name #> (float <#= type.X_Width #>, float <#= type.Y_Height #>)
{
this.<#= type.X_Width #> = <#= type.X_Width #>;
this.<#= type.Y_Height #> = <#= type.Y_Height #>;
}
public <#= type.Name #> (<#= type.Name #> <#= type.ArgName #>)
{
this.<#= type.X_Width #> = <#= type.ArgName #>.<#= type.X_Width #>;
this.<#= type.Y_Height #> = <#= type.ArgName #>.<#= type.Y_Height #>;
}
#if !COREBUILD
public static bool TryParse (NSDictionary dictionaryRepresentation, out <#= type.Name #> <#= type.ArgName #>)
{
if (dictionaryRepresentation is null) {
<#= type.ArgName #> = Empty;
return false;
}
unsafe {
<#=type.ArgName#> = default;
return NativeDrawingMethods.<#= type.Name #>MakeWithDictionaryRepresentation (dictionaryRepresentation.Handle, (<#= type.Name #> *) Unsafe.AsPointer<<#= type.Name #>> (ref <#=type.ArgName#>)) != 0;
}
}
public NSDictionary ToDictionary ()
{
return new NSDictionary (NativeDrawingMethods.<#=type.Name#>CreateDictionaryRepresentation (this));
}
#endif
<# if (type.Name == "CGSize") { #>
public CGSize (CGPoint point)
{
this.width = point.X;
this.height = point.Y;
}
<# } #>
public override bool Equals (object obj)
{
return (obj is <#= type.Name #> t) && Equals (t);
}
<# if (type.Name == "CGPoint") { #>
public bool Equals (CGPoint point)
{
return point.<#= type.X_Width #> == <#= type.X_Width #> && point.<#= type.Y_Height #> == <#= type.Y_Height #>;
}
<# } else { #>
public bool Equals (CGSize size)
{
return size.<#= type.X_Width #> == <#= type.X_Width #> && size.<#= type.Y_Height #> == <#= type.Y_Height #>;
}
<# } #>
#if !NET
public override int GetHashCode ()
{
var hash = 23;
hash = hash * 31 + <#= type.X_Width #>.GetHashCode ();
hash = hash * 31 + <#= type.Y_Height #>.GetHashCode ();
return hash;
}
#endif
public void Deconstruct (out nfloat <#= type.X_Width #>, out nfloat <#= type.Y_Height #>)
{
<#= type.X_Width #> = <#= ucfirst (type.X_Width) #>;
<#= type.Y_Height #> = <#= ucfirst (type.Y_Height) #>;
}
<# if (type.Name == "CGSize") { #>
public CGSize ToRoundedCGSize ()
{
return new CGSize ((nfloat)Math.Round (width), (nfloat)Math.Round (height));
}
#if !XAMCORE_3_0
[Obsolete ("Use 'ToRoundedCGSize' instead.")]
public CGSize ToSize ()
{
return ToRoundedCGSize ();
}
[Obsolete ("Use 'ToCGPoint' instead.")]
public CGPoint ToPointF ()
{
return (CGPoint)this;
}
#endif
public CGPoint ToCGPoint ()
{
return (CGPoint)this;
}
<# } #>
#if !NET
public override string ToString ()
{
return String.Format ("{{<#= ucfirst (type.X_Width) #>={0}, <#= ucfirst (type.Y_Height) #>={1}}}",
<#= type.X_Width #>.ToString (CultureInfo.CurrentCulture),
<#= type.Y_Height #>.ToString (CultureInfo.CurrentCulture)
);
}
#endif
}
<# } #>
[Serializable]
public partial struct CGRect : IEquatable<CGRect>
{
[Field ("CGRectZero", "CoreGraphics")] // unused but helps xtro
public static readonly CGRect Empty;
#if !COREBUILD
[Field ("CGRectNull", "CoreGraphics")] // unused but helps xtro
public static CGRect Null {
get { return Dlfcn.GetCGRect (Libraries.CoreGraphics.Handle, "CGRectNull"); }
}
[Field ("CGRectInfinite", "CoreGraphics")] // unused but helps xtro
public static CGRect Infinite {
get { return Dlfcn.GetCGRect (Libraries.CoreGraphics.Handle, "CGRectInfinite"); }
}
#endif
public static bool operator == (CGRect left, CGRect right)
{
// the following version of Equals cannot be removed by the linker, while == can be
return left.Equals (right);
}
public static bool operator != (CGRect left, CGRect right)
{
return
left.X != right.X ||
left.Y != right.Y ||
left.Width != right.Width ||
left.Height != right.Height;
}
#if !NO_SYSTEM_DRAWING
public static implicit operator CGRect (RectangleF rect)
{
return new CGRect (rect.X, rect.Y, rect.Width, rect.Height);
}
public static implicit operator CGRect (Rectangle rect)
{
return new CGRect (rect.X, rect.Y, rect.Width, rect.Height);
}
public static explicit operator RectangleF (CGRect rect)
{
return new RectangleF ((float)rect.X, (float)rect.Y, (float)rect.Width, (float)rect.Height);
}
public static explicit operator Rectangle (CGRect rect)
{
return new Rectangle ((int)rect.X, (int)rect.Y, (int)rect.Width, (int)rect.Height);
}
#endif
public static CGRect Intersect (CGRect a, CGRect b)
{
// MS.NET returns a non-empty rectangle if the two rectangles
// touch each other
if (!a.IntersectsWithInclusive (b)) {
return Empty;
}
return FromLTRB (
(nfloat)Math.Max (a.Left, b.Left),
(nfloat)Math.Max (a.Top, b.Top),
(nfloat)Math.Min (a.Right, b.Right),
(nfloat)Math.Min (a.Bottom, b.Bottom)
);
}
public void Intersect (CGRect rect)
{
this = CGRect.Intersect (this, rect);
}
public static CGRect Union (CGRect a, CGRect b)
{
return FromLTRB (
(nfloat)Math.Min (a.Left, b.Left),
(nfloat)Math.Min (a.Top, b.Top),
(nfloat)Math.Max (a.Right, b.Right),
(nfloat)Math.Max (a.Bottom, b.Bottom)
);
}
public static CGRect FromLTRB (nfloat left, nfloat top, nfloat right, nfloat bottom)
{
return new CGRect (left, top, right - left, bottom - top);
}
public static CGRect Inflate (CGRect rect, nfloat x, nfloat y)
{
var inflated = new CGRect (rect.X, rect.Y, rect.Width, rect.Height);
inflated.Inflate (x, y);
return inflated;
}
nfloat x;
nfloat y;
nfloat width;
nfloat height;
public bool IsEmpty {
get { return width == 0.0 || height == 0.0; }
}
public nfloat X {
get { return x; }
set { x = value; }
}
public nfloat Y {
get { return y; }
set { y = value; }
}
public nfloat Width {
get { return width; }
set { width = value; }
}
public nfloat Height {
get { return height; }
set { height = value; }
}
public nfloat Top {
get { return Y; }
}
public nfloat Bottom {
get { return Y + Height; }
}
public nfloat Left {
get { return X; }
}
public nfloat Right {
get { return X + Width; }
}
public CGPoint Location {
get { return new CGPoint (x, y); }
set {
x = value.X;
y = value.Y;
}
}
public CGSize Size {
get { return new CGSize (width, height); }
set {
width = value.Width;
height = value.Height;
}
}
public CGRect (CGPoint location, CGSize size)
{
x = location.X;
y = location.Y;
width = size.Width;
height = size.Height;
}
public CGRect (nfloat x, nfloat y, nfloat width, nfloat height)
{
this.x = x;
this.y = y;
this.width = width;
this.height = height;
}
public CGRect (double x, double y, double width, double height)
{
this.x = (nfloat)x;
this.y = (nfloat)y;
this.width = (nfloat)width;
this.height = (nfloat)height;
}
public CGRect (float x, float y, float width, float height)
{
this.x = x;
this.y = y;
this.width = width;
this.height = height;
}
public bool Contains (nfloat x, nfloat y)
{
return
x >= Left &&
x < Right &&
y >= Top &&
y < Bottom;
}
public bool Contains (float x, float y)
{
return Contains ((nfloat) x, (nfloat) y);
}
public bool Contains (double x, double y)
{
return Contains ((nfloat) x, (nfloat) y);
}
public bool Contains (CGPoint point)
{
return Contains (point.X, point.Y);
}
public bool Contains (CGRect rect)
{
return
X <= rect.X &&
Right >= rect.Right &&
Y <= rect.Y &&
Bottom >= rect.Bottom;
}
public void Inflate (nfloat x, nfloat y)
{
this.x -= x;
this.y -= y;
width += x * 2;
height += y * 2;
}
public void Inflate (float x, float y)
{
Inflate ((nfloat) x, (nfloat) y);
}
public void Inflate (double x, double y)
{
Inflate ((nfloat) x, (nfloat) y);
}
public void Inflate (CGSize size)
{
Inflate (size.Width, size.Height);
}
public void Offset (nfloat x, nfloat y)
{
X += x;
Y += y;
}
public void Offset (float x, float y)
{
Offset ((nfloat) x, (nfloat) y);
}
public void Offset (double x, double y)
{
Offset ((nfloat) x, (nfloat) y);
}
public void Offset (CGPoint pos)
{
Offset (pos.X, pos.Y);
}
public bool IntersectsWith (CGRect rect)
{
return !(
Left >= rect.Right ||
Right <= rect.Left ||
Top >= rect.Bottom ||
Bottom <= rect.Top
);
}
private bool IntersectsWithInclusive (CGRect r)
{
return !(
Left > r.Right ||
Right < r.Left ||
Top > r.Bottom ||
Bottom < r.Top
);
}
public override bool Equals (object obj)
{
return (obj is CGRect rect) && Equals (rect);
}
public bool Equals (CGRect rect)
{
return
x == rect.x &&
y == rect.y &&
width == rect.width &&
height == rect.height;
}
#if !NET
public override int GetHashCode ()
{
var hash = 23;
hash = hash * 31 + x.GetHashCode ();
hash = hash * 31 + y.GetHashCode ();
hash = hash * 31 + width.GetHashCode ();
hash = hash * 31 + height.GetHashCode ();
return hash;
}
public override string ToString ()
{
return String.Format ("{{X={0},Y={1},Width={2},Height={3}}}",
x, y, width, height);
}
#endif
public void Deconstruct (out nfloat x, out nfloat y, out nfloat width, out nfloat height)
{
x = X;
y = Y;
width = Width;
height = Height;
}
public void Deconstruct (out CGPoint location, out CGSize size)
{
location = Location;
size = Size;
}
#if !COREBUILD
public static bool TryParse (NSDictionary dictionaryRepresentation, out CGRect rect)
{
if (dictionaryRepresentation is null) {
rect = Empty;
return false;
}
rect = default;
unsafe {
return NativeDrawingMethods.CGRectMakeWithDictionaryRepresentation (dictionaryRepresentation.Handle, (CGRect *) Unsafe.AsPointer<CGRect> (ref rect)) != 0;
}
}
public NSDictionary ToDictionary ()
{
return new NSDictionary (NativeDrawingMethods.CGRectCreateDictionaryRepresentation (this));
}
#endif
}
#if !COREBUILD
internal static class NativeDrawingMethods {
#if MONOMAC
internal const string CG = Constants.ApplicationServicesCoreGraphicsLibrary;
#else
internal const string CG = Constants.CoreGraphicsLibrary;
#endif
[DllImport (CG)]
internal unsafe extern static byte CGRectMakeWithDictionaryRepresentation (IntPtr dict, CGRect* rect);
[DllImport (CG)]
internal unsafe extern static byte CGPointMakeWithDictionaryRepresentation (IntPtr dict, CGPoint* point);
[DllImport (CG)]
internal unsafe extern static byte CGSizeMakeWithDictionaryRepresentation (IntPtr dict, CGSize* point);
[DllImport (CG)]
internal extern static IntPtr CGRectCreateDictionaryRepresentation (CGRect rect);
[DllImport (CG)]
internal extern static IntPtr CGSizeCreateDictionaryRepresentation (CGSize size);
[DllImport (CG)]
internal extern static IntPtr CGPointCreateDictionaryRepresentation (CGPoint point);
}
#endif
}

Просмотреть файл

@ -24,8 +24,12 @@ namespace UIKit {
public void SetTitleTextAttributes (TextAttributes attributes, UIControlState state)
{
using (var dict = attributes is null ? null : attributes.Dictionary)
_SetTitleTextAttributes (dict, state);
#if XAMCORE_3_0
var dict = attributes?.Dictionary;
#else
using var dict = attributes?.ToDictionary ();
#endif
_SetTitleTextAttributes (dict, state);
}
public TextAttributes GetTitleTextAttributes (UIControlState state)
@ -40,9 +44,12 @@ namespace UIKit {
{
if (attributes is null)
throw new ArgumentNullException ("attributes");
using (var dict = attributes.Dictionary) {
_SetTitleTextAttributes (dict, state);
}
#if XAMCORE_3_0
var dict = attributes.Dictionary;
#else
using var dict = attributes.ToDictionary ();
#endif
_SetTitleTextAttributes (dict, state);
}
public virtual TextAttributes GetTitleTextAttributes (UIControlState state)

Просмотреть файл

@ -24,9 +24,12 @@ namespace UIKit {
if (attributes is null)
throw new ArgumentNullException ("attributes");
using (var dict = attributes.Dictionary) {
_SetScopeBarButtonTitle (dict, state);
}
#if XAMCORE_3_0
var dict = attributes.Dictionary;
#else
using var dict = attributes.ToDictionary ();
#endif
_SetScopeBarButtonTitle (dict, state);
}
public TextAttributes GetScopeBarButtonTitleTextAttributes (UIControlState state)
@ -42,9 +45,12 @@ namespace UIKit {
if (attributes is null)
throw new ArgumentNullException ("attributes");
using (var dict = attributes.Dictionary) {
_SetScopeBarButtonTitle (dict, state);
}
#if XAMCORE_3_0
var dict = attributes.Dictionary;
#else
using var dict = attributes.ToDictionary ();
#endif
_SetScopeBarButtonTitle (dict, state);
}
public TextAttributes GetScopeBarButtonTitleTextAttributes (UIControlState state)

Просмотреть файл

@ -98,9 +98,12 @@ namespace UIKit {
if (attributes is null)
throw new ArgumentNullException ("attributes");
using (var dict = attributes.Dictionary) {
_SetTitleTextAttributes (dict, state);
}
#if XAMCORE_3_0
var dict = attributes.Dictionary;
#else
using var dict = attributes.ToDictionary ();
#endif
_SetTitleTextAttributes (dict, state);
}
public TextAttributes GetTitleTextAttributes (UIControlState state)
@ -116,9 +119,12 @@ namespace UIKit {
if (attributes is null)
throw new ArgumentNullException ("attributes");
using (var dict = attributes.Dictionary) {
_SetTitleTextAttributes (dict, state);
}
#if XAMCORE_3_0
var dict = attributes.Dictionary;
#else
using var dict = attributes.ToDictionary ();
#endif
_SetTitleTextAttributes (dict, state);
}
public TextAttributes GetTitleTextAttributes (UIControlState state)

Просмотреть файл

@ -22,13 +22,6 @@ namespace UIKit {
public UIColor TextShadowColor;
public UIOffset TextShadowOffset;
// This property is intended for compatibility with UIStringAttributes
internal NSDictionary Dictionary {
get {
return ToDictionary ();
}
}
public UITextAttributes ()
{
}

Просмотреть файл

@ -7937,6 +7937,12 @@ namespace AppKit {
[Export ("CGEvent")]
IntPtr CGEvent { get; }
/// <summary>The CGEvent object corresponding to this event.</summary>
/// <appledoc>https://developer.apple.com/documentation/appkit/nsevent/1530429-cgevent?language=objc</appledoc>
[return: NullAllowed]
[Wrap ("Runtime.GetINativeObject<CGEvent> (CGEvent, false)")]
CGEvent GetCGEventObject ();
[Static]
[Export ("eventWithCGEvent:")]
[Obsolete ("Use 'Create (CGEvent)' instead.")]

Просмотреть файл

@ -68,6 +68,8 @@ public class BindingTouch : IDisposable {
bool supportsXmlDocumentation = true;
List<string> references = new List<string> ();
public bool SupportsXmlDocumentation { get => supportsXmlDocumentation; }
public MetadataLoadContext? universe;
public Frameworks? Frameworks;

Просмотреть файл

@ -5594,6 +5594,15 @@ public partial class Generator : IMemberGatherer {
if (!is_static_class && !is_partial) {
if (!is_model && !external) {
if (BindingTouch.SupportsXmlDocumentation) {
print ("/// <summary>The Objective-C class handle for this class.</summary>");
print ("/// <value>The pointer to the Objective-C class.</value>");
print ("/// <remarks>");
print ("/// Each managed class mirrors an unmanaged Objective-C class.");
print ("/// This value contains the pointer to the Objective-C class.");
print ("/// It is similar to calling the managed <see cref=\"ObjCRuntime.Class.GetHandle(string)\" /> or the native <see href=\"https://developer.apple.com/documentation/objectivec/1418952-objc_getclass\">objc_getClass</see> method with the type name.");
print ("/// </remarks>");
}
print ("public {1} {2} ClassHandle {{ get {{ return class_ptr; }} }}\n", objc_type_name, TypeName == "NSObject" ? "virtual" : "override", NativeHandleType);
}
@ -5682,6 +5691,15 @@ public partial class Generator : IMemberGatherer {
}
var nscoding = ConformToNSCoding (type);
if (nscoding) {
if (BindingTouch.SupportsXmlDocumentation) {
sw.WriteLine ($"\t\t/// <summary>A constructor that initializes the object from the data stored in the unarchiver object.</summary>");
sw.WriteLine ($"\t\t/// <param name=\"coder\">The unarchiver object.</param>");
sw.WriteLine ($"\t\t/// <remarks>");
sw.WriteLine ($"\t\t/// <para>This constructor is provided to allow the class to be initialized from an unarchiver (for example, during NIB deserialization). This is part of the <see cref=\"Foundation.NSCoding\" /> protocol.</para>");
sw.WriteLine ($"\t\t/// <para>If developers want to create a subclass of this object and continue to support deserialization from an archive, they should implement a constructor with an identical signature: taking a single parameter of type <see cref=\"Foundation.NSCoder\" /> and decorate it with the <c>[Export(\"initWithCoder:\"]</c> attribute.</para>");
sw.WriteLine ($"\t\t/// <para>The state of this object can also be serialized by using the <see cref=\"Foundation.INSCoding.EncodeTo\" /> companion method.</para>");
sw.WriteLine ($"\t\t/// </remarks>");
}
GeneratedCode (sw, 2);
sw.WriteLine ("\t\t[DesignatedInitializer]");
sw.WriteLine ("\t\t[EditorBrowsable (EditorBrowsableState.Advanced)]");
@ -5715,6 +5733,53 @@ public partial class Generator : IMemberGatherer {
}
}
if (!is_sealed) {
if (BindingTouch.SupportsXmlDocumentation) {
sw.WriteLine ("\t\t/// <summary>Constructor to call on derived classes to skip initialization and merely allocate the object.</summary>");
sw.WriteLine ("\t\t/// <param name=\"t\">Unused sentinel value, pass NSObjectFlag.Empty.</param>");
sw.WriteLine ("\t\t/// <remarks>");
sw.WriteLine ("\t\t/// <para>");
sw.WriteLine ("\t\t/// This constructor should be called by derived classes when they completely construct the object in managed code and merely want the runtime to allocate and initialize the <see cref=\"Foundation.NSObject\" />.");
sw.WriteLine ("\t\t/// This is required to implement the two-step initialization process that Objective-C uses, the first step is to perform the object allocation, the second step is to initialize the object.");
sw.WriteLine ("\t\t/// When developers invoke this constructor, they take advantage of a direct path that goes all the way up to <see cref=\"Foundation.NSObject\" /> to merely allocate the object's memory and bind the Objective-C and C# objects together.");
sw.WriteLine ("\t\t/// The actual initialization of the object is up to the developer.");
sw.WriteLine ("\t\t/// </para>");
sw.WriteLine ("\t\t/// <para>");
sw.WriteLine ("\t\t/// This constructor is typically used by the binding generator to allocate the object, but prevent the actual initialization to take place.");
sw.WriteLine ("\t\t/// Once the allocation has taken place, the constructor has to initialize the object.");
sw.WriteLine ("\t\t/// With constructors generated by the binding generator this means that it manually invokes one of the \"init\" methods to initialize the object.");
sw.WriteLine ("\t\t/// </para>");
sw.WriteLine ("\t\t/// <para>It is the developer's responsibility to completely initialize the object if they chain up using this constructor chain.</para>");
sw.WriteLine ("\t\t/// <para>");
sw.WriteLine ("\t\t/// In general, if the developer's constructor invokes the corresponding base implementation, then it should also call an Objective-C init method.");
sw.WriteLine ("\t\t/// If this is not the case, developers should instead chain to the proper constructor in their class.");
sw.WriteLine ("\t\t/// </para>");
sw.WriteLine ("\t\t/// <para>");
sw.WriteLine ("\t\t/// The argument value is ignored and merely ensures that the only code that is executed is the construction phase is the basic <see cref=\"Foundation.NSObject\" /> allocation and runtime type registration.");
sw.WriteLine ("\t\t/// Typically the chaining would look like this:");
sw.WriteLine ("\t\t/// </para>");
sw.WriteLine ("\t\t/// <example>");
sw.WriteLine ("\t\t/// <code lang=\"csharp lang-csharp\"><![CDATA[");
sw.WriteLine ("\t\t/// //");
sw.WriteLine ("\t\t/// // The NSObjectFlag constructor merely allocates the object and registers the C# class with the Objective-C runtime if necessary.");
sw.WriteLine ("\t\t/// // No actual initXxx method is invoked, that is done later in the constructor");
sw.WriteLine ("\t\t/// //");
sw.WriteLine ("\t\t/// // This is taken from the iOS SDK's source code for the UIView class:");
sw.WriteLine ("\t\t/// //");
sw.WriteLine ("\t\t/// [Export (\"initWithFrame:\")]");
sw.WriteLine ("\t\t/// public UIView (System.Drawing.RectangleF frame) : base (NSObjectFlag.Empty)");
sw.WriteLine ("\t\t/// {");
sw.WriteLine ("\t\t/// // Invoke the init method now.");
sw.WriteLine ("\t\t/// var initWithFrame = new Selector (\"initWithFrame:\").Handle;");
sw.WriteLine ("\t\t/// if (IsDirectBinding) {");
sw.WriteLine ("\t\t/// Handle = ObjCRuntime.Messaging.IntPtr_objc_msgSend_CGRect (this.Handle, initWithFrame, frame);");
sw.WriteLine ("\t\t/// } else {");
sw.WriteLine ("\t\t/// Handle = ObjCRuntime.Messaging.IntPtr_objc_msgSendSuper_CGRect (this.SuperHandle, initWithFrame, frame);");
sw.WriteLine ("\t\t/// }");
sw.WriteLine ("\t\t/// }");
sw.WriteLine ("\t\t/// ]]></code>");
sw.WriteLine ("\t\t/// </example>");
sw.WriteLine ("\t\t/// </remarks>");
}
GeneratedCode (sw, 2);
sw.WriteLine ("\t\t[EditorBrowsable (EditorBrowsableState.Advanced)]");
sw.WriteLine ("\t\tprotected {0} (NSObjectFlag t) : base (t)", TypeName);
@ -5725,6 +5790,17 @@ public partial class Generator : IMemberGatherer {
sw.WriteLine ("\t\t}");
sw.WriteLine ();
}
if (!is_sealed && BindingTouch.SupportsXmlDocumentation) {
sw.WriteLine ("\t\t/// <summary>A constructor used when creating managed representations of unmanaged objects. Called by the runtime.</summary>");
sw.WriteLine ("\t\t/// <param name=\"handle\">Pointer (handle) to the unmanaged object.</param>");
sw.WriteLine ("\t\t/// <remarks>");
sw.WriteLine ("\t\t/// <para>");
sw.WriteLine ("\t\t/// This constructor is invoked by the runtime infrastructure (<see cref=\"ObjCRuntime.Runtime.GetNSObject(System.IntPtr)\" />) to create a new managed representation for a pointer to an unmanaged Objective-C object.");
sw.WriteLine ("\t\t/// Developers should not invoke this method directly, instead they should call <see cref=\"ObjCRuntime.Runtime.GetNSObject(System.IntPtr)\" /> as it will prevent two instances of a managed object pointing to the same native object.");
sw.WriteLine ("\t\t/// </para>");
sw.WriteLine ("\t\t/// </remarks>");
}
GeneratedCode (sw, 2);
sw.WriteLine ("\t\t[EditorBrowsable (EditorBrowsableState.Advanced)]");
sw.Write ($"\t\t");

Просмотреть файл

@ -549,6 +549,7 @@ COREGRAPHICS_SOURCES = \
CoreGraphics/CGPDFString.cs \
CoreGraphics/CGPdfTagType.cs \
CoreGraphics/CGShading.cs \
CoreGraphics/NativeDrawingMethods.cs \
# CoreHaptics
@ -1943,7 +1944,6 @@ SHARED_CORE_SOURCES = \
DotNetGlobals.cs \
MinimumVersions.cs \
MonoPInvokeCallbackAttribute.cs \
$(BUILD_DIR)/common/NativeTypes/Drawing.cs \
$(BUILD_DIR)/common/NativeTypes/Primitives.cs \
ObjCRuntime/ArgumentSemantic.cs \
ObjCRuntime/BindAsAttribute.cs \

Просмотреть файл

@ -12,7 +12,7 @@ endif
MTOUCH=$(IOS_DESTDIR)/$(MONOTOUCH_PREFIX)/bin/mtouch
XHARNESS_EXECUTABLE=xharness/bin/Debug/$(DOTNET_TFM)/xharness.dll
XHARNESS_EXECUTABLE=xharness/bin/Debug/xharness.dll
export MD_MTOUCH_SDK_ROOT=$(IOS_DESTDIR)/$(MONOTOUCH_PREFIX)
export MSBUILD_EXE_PATH=$(MONO_PREFIX)/lib/mono/msbuild/15.0/bin/MSBuild.dll

Просмотреть файл

@ -8,6 +8,7 @@
//
using System;
using System.Diagnostics.CodeAnalysis;
using System.Reflection;
using System.Runtime.InteropServices;
@ -41,6 +42,9 @@ namespace XamarinTests.ObjCRuntime {
}
}
#if NET
[UnconditionalSuppressMessage ("Trimming", "IL2026", Justification = "This test accesses internals, and this code seems to work fine with the trimmer enabled.")]
#endif
public static Registrars CurrentRegistrar {
get {
var __registrar__ = typeof (Class).Assembly.GetType ("ObjCRuntime.__Registrar__");

Просмотреть файл

@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.InteropServices;
using System.Linq;
@ -29,6 +30,9 @@ namespace Xamarin.BindingTests {
}
[Test]
#if NET
[UnconditionalSuppressMessage ("Trimming", "IL2026", Justification = "This test verifies trimmer behavior, and as such must do trimmer-unsafe stuff.")]
#endif
public void OnlyProtocol ()
{
// a binding with only [Protocol]
@ -60,6 +64,9 @@ namespace Xamarin.BindingTests {
}
[Test]
#if NET
[UnconditionalSuppressMessage ("Trimming", "IL2026", Justification = "This test verifies trimmer behavior, and as such must do trimmer-unsafe stuff.")]
#endif
public void ProtocolWithBaseType ()
{
// a binding with [Protocol] and [BaseType]
@ -96,6 +103,9 @@ namespace Xamarin.BindingTests {
}
[Test]
#if NET
[UnconditionalSuppressMessage ("Trimming", "IL2026", Justification = "This test verifies trimmer behavior, and as such must do trimmer-unsafe stuff.")]
#endif
public void ProtocolWithBaseTypeAndModel ()
{
// a binding with [Protocol] and [BaseType]

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -8,6 +8,7 @@
// Copyright 2015 Xamarin Inc. All rights reserved.
using System;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Reflection;
using System.Collections.Generic;
@ -137,6 +138,9 @@ namespace Xamarin.Tests {
return attributeProvider.IsAvailable (PlatformInfo.Host);
}
#if NET
[UnconditionalSuppressMessage ("Trimming", "IL2045", Justification = "Some of the attributes this method uses may have been linked away, so things might not work. It actually works though, so unless something changes, we're going to assume it's trimmer-compatible.")]
#endif
public static bool IsAvailable (this ICustomAttributeProvider attributeProvider, PlatformInfo targetPlatform)
{
var customAttributes = attributeProvider.GetCustomAttributes (true);
@ -201,6 +205,9 @@ namespace Xamarin.Tests {
// return attributes.Count () == 0;
}
#if NET
[UnconditionalSuppressMessage ("Trimming", "IL2045", Justification = "Some of the attributes this method uses may have been linked away, so things might not work. It actually works though, so unless something changes, we're going to assume it's trimmer-compatible.")]
#endif
public static bool? IsAvailable (IEnumerable<(OSPlatformAttribute Attribute, ApplePlatform Platform, Version Version)> attributes, PlatformInfo targetPlatform, ApplePlatform attributePlatform)
{
// First we check for any unsupported attributes, and only once we know that there aren't any unsupported

Просмотреть файл

@ -4,6 +4,7 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Linq;
using System.Net;
@ -1454,6 +1455,9 @@ partial class TestRuntime {
// Determine if linkall was enabled by checking if an unused class in this assembly is still here.
static bool? link_all;
#if NET
[UnconditionalSuppressMessage ("Trimming", "IL2026", Justification = "This property checks whether the trimmer is enabled by checking if a type survived trimming; it's thus trimmer safe in that the any behavioral difference when the trimmer is enabled is exactly what it's looking for.")]
#endif
public static bool IsLinkAll {
get {
if (!link_all.HasValue)

Просмотреть файл

@ -66,6 +66,28 @@
<DefineConstants>$(DefineConstants);NATIVEAOT</DefineConstants>
</PropertyGroup>
<!-- Trimmer options -->
<!-- We want to ignore any trimmer warnings from NUnit. We do this by:
* Enable all warnings
* Turn off all warnings (enabling single-warning mode) for NUnit
* Ignore the warning produced when single-warning logic is triggered.
-->
<PropertyGroup>
<!-- We want all the trimmer warnings -->
<TrimmerSingleWarn Condition="'$(TrimmerSingleWarn)' == ''">false</TrimmerSingleWarn>
<!-- IL2104: Assembly '...' produced trim warnings -->
<NoWarn>$(NoWarn);IL2104</NoWarn>
</PropertyGroup>
<Target Name="IgnoreTrimmerWarningsInNUnit" BeforeTargets="PrepareForILLink">
<ItemGroup>
<ManagedAssemblyToLink Condition="'%(Filename)' == 'nunit.framework'">
<TrimmerSingleWarn>true</TrimmerSingleWarn>
</ManagedAssemblyToLink>
<!-- The above ItemGroup doesn't work for NativeAOT, so pass the argument manually to ILC: https://github.com/dotnet/runtime/issues/94255 -->
<IlcArg Include="--singlewarnassembly:nunit.framework" />
</ItemGroup>
</Target>
<ItemGroup>
<PackageReference Include="NUnitLite" Version="3.12.0" Condition="'$(ExcludeNUnitLiteReference)' != 'true'" />
<ProjectReference Include="$(MSBuildThisFileDirectory)\..\..\external\Touch.Unit\Touch.Client\dotnet\$(_PlatformName)\Touch.Client-$(_PlatformName).dotnet.csproj" Condition="'$(ExcludeTouchUnitReference)' != 'true'" />

Просмотреть файл

@ -25,3 +25,12 @@ if ls ~/Library/Logs/Xamarin.Messaging* >& /dev/null ; then
else
echo "No logs in ~/Library/Logs/Xamarin.Messaging"
fi
# Zip up all the logs in /tmp/com.xamarin.*
if ls /tmp/com.xamarin.* >& /dev/null ; then
zip -9r ~/remote_build_testing/windows-remote-logs.zip /tmp/com.xamarin.*
else
echo "No logs in /tmp/com.xamarin.*"
fi
ps auxww > ~/remote_build_testing/processes.txt || true

Просмотреть файл

@ -1440,8 +1440,13 @@ namespace GeneratorTests {
var bgen = BuildFile (Profile.iOS, false, true, "tests/xmldocs.cs");
Assert.That (bgen.XmlDocumentation, Does.Exist);
var contents = File.ReadAllText (bgen.XmlDocumentation);
#if NET
const string NativeHandleType = "ObjCRuntime.NativeHandle";
#else
const string NativeHandleType = "System.IntPtr";
#endif
var expectedContents =
@"<?xml version=""1.0""?>
@$"<?xml version=""1.0""?>
<doc>
<assembly>
<name>api0</name>
@ -1502,6 +1507,72 @@ namespace GeneratorTests {
Summary for T1
</summary>
</member>
<member name=""P:XmlDocumentation.T1.ClassHandle"">
<summary>The Objective-C class handle for this class.</summary>
<value>The pointer to the Objective-C class.</value>
<remarks>
Each managed class mirrors an unmanaged Objective-C class.
This value contains the pointer to the Objective-C class.
It is similar to calling the managed <see cref=""M:ObjCRuntime.Class.GetHandle(System.String)"" /> or the native <see href=""https://developer.apple.com/documentation/objectivec/1418952-objc_getclass"">objc_getClass</see> method with the type name.
</remarks>
</member>
<member name=""M:XmlDocumentation.T1.#ctor(Foundation.NSObjectFlag)"">
<summary>Constructor to call on derived classes to skip initialization and merely allocate the object.</summary>
<param name=""t"">Unused sentinel value, pass NSObjectFlag.Empty.</param>
<remarks>
<para>
This constructor should be called by derived classes when they completely construct the object in managed code and merely want the runtime to allocate and initialize the <see cref=""T:Foundation.NSObject"" />.
This is required to implement the two-step initialization process that Objective-C uses, the first step is to perform the object allocation, the second step is to initialize the object.
When developers invoke this constructor, they take advantage of a direct path that goes all the way up to <see cref=""T:Foundation.NSObject"" /> to merely allocate the object's memory and bind the Objective-C and C# objects together.
The actual initialization of the object is up to the developer.
</para>
<para>
This constructor is typically used by the binding generator to allocate the object, but prevent the actual initialization to take place.
Once the allocation has taken place, the constructor has to initialize the object.
With constructors generated by the binding generator this means that it manually invokes one of the ""init"" methods to initialize the object.
</para>
<para>It is the developer's responsibility to completely initialize the object if they chain up using this constructor chain.</para>
<para>
In general, if the developer's constructor invokes the corresponding base implementation, then it should also call an Objective-C init method.
If this is not the case, developers should instead chain to the proper constructor in their class.
</para>
<para>
The argument value is ignored and merely ensures that the only code that is executed is the construction phase is the basic <see cref=""T:Foundation.NSObject"" /> allocation and runtime type registration.
Typically the chaining would look like this:
</para>
<example>
<code lang=""csharp lang-csharp""><![CDATA[
//
// The NSObjectFlag constructor merely allocates the object and registers the C# class with the Objective-C runtime if necessary.
// No actual initXxx method is invoked, that is done later in the constructor
//
// This is taken from the iOS SDK's source code for the UIView class:
//
[Export (""initWithFrame:"")]
public UIView (System.Drawing.RectangleF frame) : base (NSObjectFlag.Empty)
{{
// Invoke the init method now.
var initWithFrame = new Selector (""initWithFrame:"").Handle;
if (IsDirectBinding) {{
Handle = ObjCRuntime.Messaging.IntPtr_objc_msgSend_CGRect (this.Handle, initWithFrame, frame);
}} else {{
Handle = ObjCRuntime.Messaging.IntPtr_objc_msgSendSuper_CGRect (this.SuperHandle, initWithFrame, frame);
}}
}}
]]></code>
</example>
</remarks>
</member>
<member name=""M:XmlDocumentation.T1.#ctor({NativeHandleType})"">
<summary>A constructor used when creating managed representations of unmanaged objects. Called by the runtime.</summary>
<param name=""handle"">Pointer (handle) to the unmanaged object.</param>
<remarks>
<para>
This constructor is invoked by the runtime infrastructure (<see cref=""M:ObjCRuntime.Runtime.GetNSObject(System.IntPtr)"" />) to create a new managed representation for a pointer to an unmanaged Objective-C object.
Developers should not invoke this method directly, instead they should call <see cref=""M:ObjCRuntime.Runtime.GetNSObject(System.IntPtr)"" /> as it will prevent two instances of a managed object pointing to the same native object.
</para>
</remarks>
</member>
<member name=""M:XmlDocumentation.T1.Method"">
<summary>
Summary for T1.Method
@ -1532,6 +1603,72 @@ namespace GeneratorTests {
Summary for TG1
</summary>
</member>
<member name=""P:XmlDocumentation.TG1`2.ClassHandle"">
<summary>The Objective-C class handle for this class.</summary>
<value>The pointer to the Objective-C class.</value>
<remarks>
Each managed class mirrors an unmanaged Objective-C class.
This value contains the pointer to the Objective-C class.
It is similar to calling the managed <see cref=""M:ObjCRuntime.Class.GetHandle(System.String)"" /> or the native <see href=""https://developer.apple.com/documentation/objectivec/1418952-objc_getclass"">objc_getClass</see> method with the type name.
</remarks>
</member>
<member name=""M:XmlDocumentation.TG1`2.#ctor(Foundation.NSObjectFlag)"">
<summary>Constructor to call on derived classes to skip initialization and merely allocate the object.</summary>
<param name=""t"">Unused sentinel value, pass NSObjectFlag.Empty.</param>
<remarks>
<para>
This constructor should be called by derived classes when they completely construct the object in managed code and merely want the runtime to allocate and initialize the <see cref=""T:Foundation.NSObject"" />.
This is required to implement the two-step initialization process that Objective-C uses, the first step is to perform the object allocation, the second step is to initialize the object.
When developers invoke this constructor, they take advantage of a direct path that goes all the way up to <see cref=""T:Foundation.NSObject"" /> to merely allocate the object's memory and bind the Objective-C and C# objects together.
The actual initialization of the object is up to the developer.
</para>
<para>
This constructor is typically used by the binding generator to allocate the object, but prevent the actual initialization to take place.
Once the allocation has taken place, the constructor has to initialize the object.
With constructors generated by the binding generator this means that it manually invokes one of the ""init"" methods to initialize the object.
</para>
<para>It is the developer's responsibility to completely initialize the object if they chain up using this constructor chain.</para>
<para>
In general, if the developer's constructor invokes the corresponding base implementation, then it should also call an Objective-C init method.
If this is not the case, developers should instead chain to the proper constructor in their class.
</para>
<para>
The argument value is ignored and merely ensures that the only code that is executed is the construction phase is the basic <see cref=""T:Foundation.NSObject"" /> allocation and runtime type registration.
Typically the chaining would look like this:
</para>
<example>
<code lang=""csharp lang-csharp""><![CDATA[
//
// The NSObjectFlag constructor merely allocates the object and registers the C# class with the Objective-C runtime if necessary.
// No actual initXxx method is invoked, that is done later in the constructor
//
// This is taken from the iOS SDK's source code for the UIView class:
//
[Export (""initWithFrame:"")]
public UIView (System.Drawing.RectangleF frame) : base (NSObjectFlag.Empty)
{{
// Invoke the init method now.
var initWithFrame = new Selector (""initWithFrame:"").Handle;
if (IsDirectBinding) {{
Handle = ObjCRuntime.Messaging.IntPtr_objc_msgSend_CGRect (this.Handle, initWithFrame, frame);
}} else {{
Handle = ObjCRuntime.Messaging.IntPtr_objc_msgSendSuper_CGRect (this.SuperHandle, initWithFrame, frame);
}}
}}
]]></code>
</example>
</remarks>
</member>
<member name=""M:XmlDocumentation.TG1`2.#ctor({NativeHandleType})"">
<summary>A constructor used when creating managed representations of unmanaged objects. Called by the runtime.</summary>
<param name=""handle"">Pointer (handle) to the unmanaged object.</param>
<remarks>
<para>
This constructor is invoked by the runtime infrastructure (<see cref=""M:ObjCRuntime.Runtime.GetNSObject(System.IntPtr)"" />) to create a new managed representation for a pointer to an unmanaged Objective-C object.
Developers should not invoke this method directly, instead they should call <see cref=""M:ObjCRuntime.Runtime.GetNSObject(System.IntPtr)"" /> as it will prevent two instances of a managed object pointing to the same native object.
</para>
</remarks>
</member>
<member name=""M:XmlDocumentation.TG1`2.TGMethod"">
<summary>
Summary for TG1.TGMethod

Просмотреть файл

@ -1,6 +1,7 @@
#if __MACOS__
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Reflection;
using NUnit.Framework;
@ -59,6 +60,9 @@ namespace Xamarin.Mac.Tests {
}
[Test]
#if NET
[UnconditionalSuppressMessage ("Trimming", "IL2075", Justification = "This test handles APIs that have been linked away, so it's trimmer-safe.")]
#endif
public void AllItemsWithNSMenuShouldAllowNull ()
{
// Can't test NSResponder since it is abstract

Просмотреть файл

@ -9,6 +9,7 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Threading;
@ -153,6 +154,9 @@ namespace MonoTouchFixtures.ObjCRuntime {
#endif
[Test]
#if NET
[UnconditionalSuppressMessage ("Trimming", "IL2026", Justification = "This test searches for types to tests; if a type has been trimmed away that's OK, just less to test.")]
#endif
public void Bug33981 ()
{
var types = new List<Type> ();

Просмотреть файл

@ -1,6 +1,7 @@
#if __MACOS__
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Reflection;
using NUnit.Framework;
@ -12,6 +13,9 @@ using ObjCRuntime;
namespace Xamarin.Mac.Tests {
static class TypeExtension {
#if NET
[UnconditionalSuppressMessage ("Trimming", "IL2070", Justification = "There will always be a most derived property (if the property exists), so this is trimmer-safe.")]
#endif
public static PropertyInfo GetMostDerivedProperty (this Type t, string name)
{
while (t is not null && t != t.BaseType) {
@ -27,6 +31,10 @@ namespace Xamarin.Mac.Tests {
[TestFixture]
[Preserve (AllMembers = true)]
public class DelegateAndDataSourceTest {
#if NET
[UnconditionalSuppressMessage ("Trimming", "IL2026", Justification = "This test searches for types to tests; if a type has been trimmed away that's OK, just less to test.")]
[UnconditionalSuppressMessage ("Trimming", "IL2075", Justification = "This test searches for types to tests; if a type has been trimmed away that's OK, just less to test.")]
#endif
[Test]
public void DelegateAndDataSourceAllowsNull ()
{
@ -151,6 +159,9 @@ namespace Xamarin.Mac.Tests {
// An ArgumentSemantic (Strong, Retain, etc) is required to keep the reference around so the app doesn't crash after a GC.
// This test scans all bindings looking for instances where bindings don't have the correct ArgumentSemantic
[Test]
#if NET
[UnconditionalSuppressMessage ("Trimming", "IL2026", Justification = "This test searches for types to tests; if a type has been trimmed away that's OK, just less to test.")]
#endif
public void DelegateAndDataSourceHaveArgumentSemanticAttribute ()
{
var failingTypes = new Dictionary<Type, string> ();
@ -232,6 +243,9 @@ namespace Xamarin.Mac.Tests {
}
[Test]
#if NET
[UnconditionalSuppressMessage ("Trimming", "IL2026", Justification = "This test searches for types to tests; if a type has been trimmed away that's OK, just less to test.")]
#endif
public void TargetArgumentSemanticAttribute ()
{
var failingTypes = new Dictionary<Type, string> ();

Просмотреть файл

@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
@ -105,6 +106,9 @@ namespace MonoTouchFixtures.ObjCRuntime {
}
[Test]
#if NET
[UnconditionalSuppressMessage ("Trimming", "IL2026", Justification = "This test verifies linker behavior, and as such any behavioral difference when the trimmer is enabled is exactly what it's looking for.")]
#endif
public void RegistrarRemoval ()
{
// define set by xharness when creating test variations.
@ -2249,6 +2253,10 @@ namespace MonoTouchFixtures.ObjCRuntime {
// This test uses Assembly.LoadFrom, which isn't supported with NativeAOT
#if __MACOS__ && !NATIVEAOT
[Test]
#if NET
[UnconditionalSuppressMessage ("Trimming", "IL2026", Justification = "This test loads an assembly dynamically, so it's expected to not be trimmer safe. It works though, so unless something changes, we're going to assume it's trimmer-compatible.")]
[UnconditionalSuppressMessage ("Trimming", "IL2072", Justification = "This test loads an assembly dynamically, so it's expected to not be trimmer safe. It works though, so unless something changes, we're going to assume it's trimmer-compatible.")]
#endif
public void CustomUserTypeWithDynamicallyLoadedAssembly ()
{
if (!global::Xamarin.Tests.Configuration.TryGetRootPath (out var rootPath))

Просмотреть файл

@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Reflection;
using Foundation;
@ -21,6 +22,10 @@ namespace MonoTouchFixtures {
TestAssembly (typeof (TestRuntime).Assembly);
}
#if NET
[UnconditionalSuppressMessage ("Trimming", "IL2026", Justification = "This test verifies that all tests have been correctly preserved, and fails if that's not the case. It'll thus fail if the trimmer removed anything it didn't expect - and is then technically trimmer safe in that it's aware and react accordingly if there's any behavioral change when the trimmer is enabled.")]
[UnconditionalSuppressMessage ("Trimming", "IL2045", Justification = "This test verifies that all tests have been correctly preserved, and fails if that's not the case. It'll thus fail if the trimmer removed anything it didn't expect - and is then technically trimmer safe in that it's aware and react accordingly if there's any behavioral change when the trimmer is enabled.")]
#endif
void TestAssembly (Assembly asm)
{
var failedTypes = new List<string> ();
@ -56,6 +61,9 @@ namespace MonoTouchFixtures {
return false;
}
#if NET
[UnconditionalSuppressMessage ("Trimming", "IL2070", Justification = "This test verifies that all tests have been correctly preserved, and fails if that's not the case. It'll thus fail if the trimmer removed anything it didn't expect - and is then technically trimmer safe in that it's aware and react accordingly if there's any behavioral change when the trimmer is enabled.")]
#endif
bool IsTestFixture (Type type)
{
// what's a test fixture: https://docs.nunit.org/articles/nunit/writing-tests/attributes/testfixture.html

Просмотреть файл

@ -1,6 +1,7 @@
#if !__TVOS__ && !__WATCHOS__
using System;
using System.Diagnostics.CodeAnalysis;
using System.Reflection;
using System.Runtime.InteropServices;
using CoreGraphics;
@ -56,6 +57,10 @@ namespace MonoTouchFixtures.Photos {
}
}
#if NET
[UnconditionalSuppressMessage ("Trimming", "IL2026", Justification = "This test pokes at internals, so it's expected to not be trimmer safe. It works though, so unless something changes, we're going to assume it's trimmer-compatible.")]
[UnconditionalSuppressMessage ("Trimming", "IL2075", Justification = "This test pokes at internals, so it's expected to not be trimmer safe. It works though, so unless something changes, we're going to assume it's trimmer-compatible.")]
#endif
[Test]
public unsafe void FrameProcessingBlock2 ()
{

Просмотреть файл

@ -10,9 +10,16 @@
#if !MONOMAC
using System;
using Foundation;
using CoreGraphics;
using UIKit;
using NUnit.Framework;
#if XAMCORE_3_0
using TextAttributes = UIKit.UIStringAttributes;
#else
using TextAttributes = UIKit.UITextAttributes;
#endif
namespace MonoTouchFixtures.UIKit {
[TestFixture]
@ -141,6 +148,40 @@ namespace MonoTouchFixtures.UIKit {
Assert.AreSame (UIColor.Red, nb.TitleTextAttributes.ForegroundColor, "TitleTextAttributes.ForegroundColor should match");
}
}
#endif // !__WATCHOS__
#if !__WATCHOS__
[Test]
public void PrematureDisposal_SegmentedControl ()
{
// https://github.com/xamarin/xamarin-macios/issues/20409
using var control = new UISegmentedControl ();
var attrs = new TextAttributes ();
control.SetTitleTextAttributes (attrs, UIControlState.Normal);
control.SetTitleTextAttributes (attrs, UIControlState.Selected);
}
[Test]
public void PrematureDisposal_BarItem ()
{
// https://github.com/xamarin/xamarin-macios/issues/20409
using var control = new UIBarButtonItem (); // UIBarItem is abstract, so use a derived class.
var attrs = new TextAttributes ();
control.SetTitleTextAttributes (attrs, UIControlState.Normal);
control.SetTitleTextAttributes (attrs, UIControlState.Selected);
}
#if !__TVOS__
[Test]
public void PrematureDisposal_SearchBar ()
{
// https://github.com/xamarin/xamarin-macios/issues/20409
using var control = new UISearchBar (new CGRect (0, 0, 42, 42));
var attrs = new TextAttributes ();
control.SetScopeBarButtonTitle (attrs, UIControlState.Normal);
control.SetScopeBarButtonTitle (attrs, UIControlState.Selected);
}
#endif // !__TVOS__
#endif // !__WATCHOS__
}
}

Просмотреть файл

@ -1,4 +1,5 @@
using System;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Runtime.InteropServices;
using System.Threading;
@ -65,6 +66,9 @@ namespace Xamarin {
}
}
#if NET
[UnconditionalSuppressMessage ("Trimming", "IL2026", Justification = "StackFrame.GetMethod might not work, but there's a fallback, so this is trimmer-safe.")]
#endif
public static string CreateTemporaryDirectory (string? name = null)
{
if (string.IsNullOrEmpty (name)) {

Просмотреть файл

@ -4509,7 +4509,7 @@ public class Dummy {
environment_variables ["SKIP_SIMULATOR_SETUP"] = "1";
environment_variables ["USE_TCP_TUNNEL"] = null;
var executable = Path.Combine (Configuration.RootPath, "tests", "xharness", "bin", "Debug", Configuration.DotNetTfm, "xharness");
var executable = Path.Combine (Configuration.RootPath, "tests", "xharness", "bin", "Debug", "xharness");
var args = new List<string> ();
args.Add ("--run");
args.Add (csprojpath);

23
tests/xharness/.vscode/launch.json поставляемый Normal file
Просмотреть файл

@ -0,0 +1,23 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "C#: xharness Debug Site",
"preLaunchTask": "dotnet: build",
"type": "coreclr",
"request": "launch",
"program": "${workspaceFolder}/bin/Debug/xharness.dll",
"args": [
"--verbose",
"--jenkins:server",
"--autoconf",
"--rootdir",
"..",
],
"cwd": "${workspaceFolder}",
}
]
}

12
tests/xharness/.vscode/tasks.json поставляемый Normal file
Просмотреть файл

@ -0,0 +1,12 @@
{
"version": "2.0.0",
"tasks": [
{
"type": "dotnet",
"task": "build",
"group": "build",
"problemMatcher": [],
"label": "dotnet: build"
}
]
}

Просмотреть файл

@ -195,6 +195,24 @@ namespace Xharness {
}
}
public static void AddTopLevelInclude (this XmlDocument csproj, string type, string link, string include, bool prepend = false)
{
var type_node = csproj.SelectSingleNode ($"//*[local-name() = '{type}']");
var item_group = type_node?.ParentNode ?? csproj.SelectSingleNode ($"/Project/*[local-name() = 'ItemGroup'][last()]")!;
var node = csproj.CreateElement (type, csproj.GetNamespace ());
var include_attribute = csproj.CreateAttribute ("Include");
include_attribute.Value = include;
node.Attributes.Append (include_attribute);
var linkElement = csproj.CreateElement ("Link", csproj.GetNamespace ());
linkElement.InnerText = link;
node.AppendChild (linkElement);
if (prepend) {
item_group.PrependChild (node);
} else {
item_group.AppendChild (node);
}
}
// This is an evolved version of https://github.com/dotnet/xharness/blob/b2297d610df1ae15fc7ba8bd8c9bc0a7192aaefa/src/Microsoft.DotNet.XHarness.iOS.Shared/Utilities/ProjectFileExtensions.cs#L1168
public static void ResolveAllPaths (this XmlDocument csproj, string project_path, Dictionary<string, string>? variableSubstitution = null)
{

Просмотреть файл

@ -147,19 +147,19 @@ namespace Xharness {
var windows_file = full_path.Replace ('/', '\\');
if (file.Contains (".xcasset")) {
doc.AddInclude ("ImageAsset", file, windows_file, true);
doc.AddTopLevelInclude ("ImageAsset", file, windows_file, true);
continue;
}
switch (ext.ToLowerInvariant ()) {
case ".cs":
doc.AddInclude ("Compile", file, windows_file, true);
doc.AddTopLevelInclude ("Compile", file, windows_file, true);
break;
case ".plist":
doc.AddInclude ("None", file, windows_file, true);
doc.AddTopLevelInclude ("None", file, windows_file, true);
break;
case ".storyboard":
doc.AddInclude ("InterfaceDefinition", file, windows_file, true);
doc.AddTopLevelInclude ("InterfaceDefinition", file, windows_file, true);
break;
case ".gitignore":
case ".csproj":

Просмотреть файл

@ -9,6 +9,7 @@
<EnableDefaultItems>false</EnableDefaultItems>
<WarningsAsErrors>Nullable</WarningsAsErrors>
<!--<Nullable>enable</Nullable>-->
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
</PropertyGroup>
<PropertyGroup Condition=" '$(RunConfiguration)' == 'Default' ">

Просмотреть файл

@ -12,3 +12,9 @@ fi
# Make sure we don't have stuff from earlier builds.
rm -rf ~/remote_build_testing
# Kill any existing brokers and builders
ps auxww || true
pkill -f Broker.exe || true
pkill -f Build.exe || true
ps auxww || true

Просмотреть файл

@ -26,6 +26,7 @@ steps:
name: fix_commit
displayName: "Undo Github merge"
workingDirectory: $(System.DefaultWorkingDirectory)/xamarin-macios/tools/devops/automation/scripts
timeoutInMinutes: 15
- checkout: maccore
clean: true