Skip to content

Commit

Permalink
Merge branch 'main' into dev/mandel/stret-getvalue-type-size-roslyn
Browse files Browse the repository at this point in the history
  • Loading branch information
mandel-macaque committed Jan 24, 2025
2 parents caf8183 + fffd487 commit b2691b3
Show file tree
Hide file tree
Showing 61 changed files with 2,044 additions and 352 deletions.
5 changes: 3 additions & 2 deletions dotnet/Workloads/SignList.xml
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,13 @@
<Skip Include="Build\System.Text.Json.dll" />
<Skip Include="Build\System.Threading.Tasks.Dataflow.dll" />
<Skip Include="Build\System.Threading.Tasks.Extensions.dll" />
<!-- They are now signed by their origin build https://github.com/xamarin/XamarinVS/pull/14522 -->
<Skip Include="imobiledevice-*\*.dll" />
<Skip Include="imobiledevice-*\*.exe" />
</ItemGroup>

<ItemGroup>
<ThirdParty Include="BouncyCastle.Crypto.dll" />
<ThirdParty Include="imobiledevice-*\*.dll" />
<ThirdParty Include="imobiledevice-*\*.exe" />
<!-- Build.zip -->
<ThirdParty Include="Mono.Cecil*.dll" />

Expand Down
1 change: 1 addition & 0 deletions src/rgen/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Generated
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,9 @@
<Compile Include="../Microsoft.Macios.Generator/Extensions/TypeSymbolExtensions.Core.cs">
<Link>Generator/Extensions/TypeSymbolExtensions.Core.cs</Link>
</Compile>
<Compile Include="../Microsoft.Macios.Generator/Extensions/TypeSymbolExtensions.Generator.cs">
<Link>Generator/Extensions/TypeSymbolExtensions.Generator.cs</Link>
</Compile>
<Compile Include="../Microsoft.Macios.Generator/Extensions/TypedConstantExtensions.cs" >
<Link>Generator/Extensions/TypedConstantExtensions.cs</Link>
</Compile>
Expand Down
37 changes: 37 additions & 0 deletions src/rgen/Microsoft.Macios.Generator/Attributes/MarshalDirective.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

using System;

namespace Microsoft.Macios.Generator.Attributes;

record CustomMarshalDirective (string? NativePrefix, string? NativeSuffix, string? Library);

static class ExportDataExtensions {

public static bool ShouldMarshalNativeExceptions<T> (this ExportData<T> self) where T : Enum
=> self switch {
ExportData<ObjCBindings.Property> property => property.Flags.HasFlag (ObjCBindings.Property
.CustomMarshalDirective),
ExportData<ObjCBindings.Method> method => method.Flags.HasFlag (
ObjCBindings.Property.CustomMarshalDirective),
_ => false,
};

public static CustomMarshalDirective? ToCustomMarshalDirective<T> (this ExportData<T> self) where T : Enum
{
var present = self switch {
ExportData<ObjCBindings.Property> property => property.Flags.HasFlag (ObjCBindings.Property
.CustomMarshalDirective),
ExportData<ObjCBindings.Method> method => method.Flags.HasFlag (
ObjCBindings.Property.CustomMarshalDirective),
_ => false,
};
if (present) {
return new (self.NativePrefix, self.NativeSuffix, self.Library);
}

return null;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,12 @@ internal SupportedOSPlatformData (string platformName)
(Platform, Version) = platformName.GetPlatformAndVersion ();
}

internal SupportedOSPlatformData (ApplePlatform platform, Version version)
{
Platform = platform;
Version = version;
}

/// <summary>
/// Try to parse the attribute data to retrieve the information of an SupportedOSPlatformAttribute.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,12 @@ internal UnsupportedOSPlatformData (string platformName)
(Platform, Version) = platformName.GetPlatformAndVersion ();
}

internal UnsupportedOSPlatformData (ApplePlatform platform)
{
Platform = platform;
Version = new Version ();
}

internal UnsupportedOSPlatformData (string platformName, string? message = null) : this (platformName)
{
Message = message;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ public bool Equals (PlatformAvailability other)
var obsoleteComparer = new DictionaryComparer<Version, (string?, string?)> ();
var unsupportedComparer = new DictionaryComparer<Version, string?> ();

var x = Equals (SupportedVersion, other.SupportedVersion);
return Platform == other.Platform &&
Equals (SupportedVersion, other.SupportedVersion) &&
unsupportedComparer.Equals (unsupported, other.unsupported) &&
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,18 @@ public sealed class Builder {

internal Builder () { }

/// <summary>
/// Return the immutable version of the current data in the builder.
/// </summary>
public IEnumerable<PlatformAvailability> PlatformAvailabilities {
get {
// return the immutable version of the builder data
foreach (var availability in platforms.Values) {
yield return availability.ToImmutable ();
}
}
}

/// <summary>
/// Returns the PlatformAvailability for the given platform. If we did not have a builder for the
/// platform, a new one is created and added to the dictionary.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ namespace Microsoft.Macios.Generator;
/// </summary>
[Generator]
public class BindingSourceGeneratorGenerator : IIncrementalGenerator {
static readonly CodeChangesEqualityComparer equalityComparer = new ();
static readonly BindingEqualityComparer equalityComparer = new ();

/// <inheritdoc cref="IIncrementalGenerator"/>
public void Initialize (IncrementalGeneratorInitializationContext context)
Expand All @@ -45,16 +45,16 @@ public void Initialize (IncrementalGeneratorInitializationContext context)
static (ctx, _) => GetChangesForSourceGen (ctx))
.Where (tuple => tuple.BindingAttributeFound);

var codeChanges = provider
.Select (static (tuple, _) => tuple.Changes)
var bindings = provider
.Select (static (tuple, _) => tuple.Bindings)
.WithComparer (equalityComparer);

// ideally we could do a distinct, because each code change can return the same libs, this makes the library
// generation more common than what we would like, but it is the smallest code generation.
var libraryProvider = provider
.Select ((tuple, _) => (tuple.RootBindingContext, tuple.Changes.LibraryPaths));
.Select ((tuple, _) => (tuple.RootBindingContext, tuple.Bindings.LibraryPaths));

context.RegisterSourceOutput (context.CompilationProvider.Combine (codeChanges.Collect ()),
context.RegisterSourceOutput (context.CompilationProvider.Combine (bindings.Collect ()),
((ctx, t) => GenerateCode (ctx, t.Right)));

context.RegisterSourceOutput (context.CompilationProvider.Combine (libraryProvider.Collect ()),
Expand All @@ -71,7 +71,7 @@ public void Initialize (IncrementalGeneratorInitializationContext context)
_ => false,
};

static (RootBindingContext RootBindingContext, CodeChanges Changes, bool BindingAttributeFound) GetChangesForSourceGen (GeneratorSyntaxContext context)
static (RootBindingContext RootBindingContext, Binding Bindings, bool BindingAttributeFound) GetChangesForSourceGen (GeneratorSyntaxContext context)
{
var bindingContext = new RootBindingContext (context.SemanticModel);
// we do know that the context node has to be one of the base type declarations
Expand All @@ -85,14 +85,14 @@ public void Initialize (IncrementalGeneratorInitializationContext context)
return (bindingContext, default, false);
}

var codeChanges = CodeChanges.FromDeclaration (declarationSyntax, bindingContext);
var binding = Binding.FromDeclaration (declarationSyntax, bindingContext);
// if code changes are null, return the default value and a false to later ignore the change
return codeChanges is not null
? (bindingContext, codeChanges.Value, isBindingType)
return binding is not null
? (bindingContext, binding.Value, isBindingType)
: (bindingContext, default, false);
}

static void GenerateCode (SourceProductionContext context, in ImmutableArray<CodeChanges> changesList)
static void GenerateCode (SourceProductionContext context, in ImmutableArray<Binding> bindingsList)
{
// The process is as follows, get all the changes we have received from the incremental generator,
// loop over them, and based on the CodeChange.BindingType we are going to build the symbol context
Expand All @@ -101,20 +101,20 @@ static void GenerateCode (SourceProductionContext context, in ImmutableArray<Cod
// Once all the enums, classes and interfaces have been processed, we will use the data collected
// in the RootBindingContext to generate the library and trampoline code.
var sb = new TabbedStringBuilder (new ());
foreach (var change in changesList) {
foreach (var binding in bindingsList) {
// init sb and add the header
sb.Clear ();
sb.WriteHeader ();
if (EmitterFactory.TryCreate (change, out var emitter)) {
if (EmitterFactory.TryCreate (binding, out var emitter)) {
// write the using statements
CollectUsingStatements (change, sb, emitter);
CollectUsingStatements (binding, sb, emitter);

var bindingContext = new BindingContext (sb, change);
var bindingContext = new BindingContext (sb, binding);
if (emitter.TryEmit (bindingContext, out var diagnostics)) {
// only add a file when we do generate code
var code = sb.ToString ();
var namespacePath = Path.Combine (change.Namespace.ToArray ());
var fileName = emitter.GetSymbolName (change);
var namespacePath = Path.Combine (binding.Namespace.ToArray ());
var fileName = emitter.GetSymbolName (binding);
context.AddSource ($"{Path.Combine (namespacePath, fileName)}.g.cs",
SourceText.From (code, Encoding.UTF8));
} else {
Expand All @@ -128,7 +128,7 @@ static void GenerateCode (SourceProductionContext context, in ImmutableArray<Cod
Diagnostics
.RBI0000, // An unexpected error ocurred while processing '{0}'. Please fill a bug report at https://github.com/xamarin/xamarin-macios/issues/new.
null,
change.FullyQualifiedSymbol));
binding.FullyQualifiedSymbol));
}
}
}
Expand Down Expand Up @@ -175,14 +175,14 @@ static void GenerateLibraryCode (SourceProductionContext context,
/// that will be used to generate the code. This way we ensure that we have all the namespaces needed by the
/// generated code.
/// </summary>
/// <param name="codeChanges">The code changes for a given named type.</param>
/// <param name="binding">The code changes for a given named type.</param>
/// <param name="sb">String builder that will be used for the generated code.</param>
/// <param name="emitter">The emitter that will generate the code. Provides any extra needed namespace.</param>
static void CollectUsingStatements (in CodeChanges codeChanges, TabbedStringBuilder sb, ICodeEmitter emitter)
static void CollectUsingStatements (in Binding binding, TabbedStringBuilder sb, ICodeEmitter emitter)
{
// collect all using from the syntax tree, add them to a hash to make sure that we don't have duplicates
// and add those usings that we do know we need for bindings.
var usingDirectivesToKeep = new SortedSet<string> (codeChanges.UsingDirectives) {
var usingDirectivesToKeep = new SortedSet<string> (binding.UsingDirectives) {
// add the using statements that we know we need and print them to the sb
};

Expand Down
4 changes: 2 additions & 2 deletions src/rgen/Microsoft.Macios.Generator/Context/BindingContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ readonly struct BindingContext {
/// <summary>
/// Current code changes for the binding context.
/// </summary>
public CodeChanges Changes { get; }
public Binding Changes { get; }

public BindingContext (TabbedStringBuilder builder, CodeChanges changes)
public BindingContext (TabbedStringBuilder builder, Binding changes)
{
Builder = builder;
Changes = changes;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

namespace Microsoft.Macios.Generator.DataModel;

readonly partial struct CodeChanges {
readonly partial struct Binding {

/// <summary>
/// Represents the type of binding that the code changes are for.
Expand Down Expand Up @@ -146,7 +146,7 @@ static void GetMembers<T, TR> (TypeDeclarationSyntax baseDeclarationSyntax, Root
/// <param name="namespace">The namespace that contains the named type.</param>
/// <param name="fullyQualifiedSymbol">The fully qualified name of the symbol.</param>
/// <param name="symbolAvailability">The platform availability of the named symbol.</param>
internal CodeChanges (BindingInfo bindingInfo, string name, ImmutableArray<string> @namespace,
internal Binding (BindingInfo bindingInfo, string name, ImmutableArray<string> @namespace,
string fullyQualifiedSymbol, SymbolAvailability symbolAvailability)
{
this.bindingInfo = bindingInfo;
Expand All @@ -157,11 +157,11 @@ internal CodeChanges (BindingInfo bindingInfo, string name, ImmutableArray<strin
}

/// <summary>
/// Creates a new instance of the <see cref="CodeChanges"/> struct for a given enum declaration.
/// Creates a new instance of the <see cref="Binding"/> struct for a given enum declaration.
/// </summary>
/// <param name="enumDeclaration">The enum declaration that triggered the change.</param>
/// <param name="context">The root binding context of the current compilation.</param>
CodeChanges (EnumDeclarationSyntax enumDeclaration, RootBindingContext context)
Binding (EnumDeclarationSyntax enumDeclaration, RootBindingContext context)
{
context.SemanticModel.GetSymbolData (
declaration: enumDeclaration,
Expand Down Expand Up @@ -207,11 +207,11 @@ internal CodeChanges (BindingInfo bindingInfo, string name, ImmutableArray<strin
}

/// <summary>
/// Creates a new instance of the <see cref="CodeChanges"/> struct for a given class declaration.
/// Creates a new instance of the <see cref="Binding"/> struct for a given class declaration.
/// </summary>
/// <param name="classDeclaration">The class declaration that triggered the change.</param>
/// <param name="context">The root binding context of the current compilation.</param>
CodeChanges (ClassDeclarationSyntax classDeclaration, RootBindingContext context)
Binding (ClassDeclarationSyntax classDeclaration, RootBindingContext context)
{
context.SemanticModel.GetSymbolData (
declaration: classDeclaration,
Expand Down Expand Up @@ -239,11 +239,11 @@ internal CodeChanges (BindingInfo bindingInfo, string name, ImmutableArray<strin
}

/// <summary>
/// Creates a new instance of the <see cref="CodeChanges"/> struct for a given interface declaration.
/// Creates a new instance of the <see cref="Binding"/> struct for a given interface declaration.
/// </summary>
/// <param name="interfaceDeclaration">The interface declaration that triggered the change.</param>
/// <param name="context">The root binding context of the current compilation.</param>
CodeChanges (InterfaceDeclarationSyntax interfaceDeclaration, RootBindingContext context)
Binding (InterfaceDeclarationSyntax interfaceDeclaration, RootBindingContext context)
{
context.SemanticModel.GetSymbolData (
declaration: interfaceDeclaration,
Expand Down Expand Up @@ -275,13 +275,13 @@ internal CodeChanges (BindingInfo bindingInfo, string name, ImmutableArray<strin
/// <param name="baseTypeDeclarationSyntax">The declaration syntax whose change we want to calculate.</param>
/// <param name="context">The root binding context of the current compilation.</param>
/// <returns>A code change or null if it could not be calculated.</returns>
public static CodeChanges? FromDeclaration (BaseTypeDeclarationSyntax baseTypeDeclarationSyntax,
public static Binding? FromDeclaration (BaseTypeDeclarationSyntax baseTypeDeclarationSyntax,
RootBindingContext context)
=> baseTypeDeclarationSyntax switch {
EnumDeclarationSyntax enumDeclarationSyntax => new CodeChanges (enumDeclarationSyntax, context),
InterfaceDeclarationSyntax interfaceDeclarationSyntax => new CodeChanges (interfaceDeclarationSyntax,
EnumDeclarationSyntax enumDeclarationSyntax => new Binding (enumDeclarationSyntax, context),
InterfaceDeclarationSyntax interfaceDeclarationSyntax => new Binding (interfaceDeclarationSyntax,
context),
ClassDeclarationSyntax classDeclarationSyntax => new CodeChanges (classDeclarationSyntax, context),
ClassDeclarationSyntax classDeclarationSyntax => new Binding (classDeclarationSyntax, context),
_ => null
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ namespace Microsoft.Macios.Generator.DataModel;
/// generated code.
/// </summary>
[StructLayout (LayoutKind.Auto)]
readonly partial struct CodeChanges {
readonly partial struct Binding {

readonly string name = string.Empty;
/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ namespace Microsoft.Macios.Generator.DataModel;
/// <summary>
/// Custom code changes comparer used for the Roslyn code generation to invalidate caching.
/// </summary>
class CodeChangesEqualityComparer : EqualityComparer<CodeChanges> {
class BindingEqualityComparer : EqualityComparer<Binding> {
/// <inheritdoc />
public override bool Equals (CodeChanges x, CodeChanges y)
public override bool Equals (Binding x, Binding y)
{

// order does not matter in the using directives, use a comparer that sorts them
Expand Down Expand Up @@ -82,7 +82,7 @@ public override bool Equals (CodeChanges x, CodeChanges y)
}

/// <inheritdoc />
public override int GetHashCode (CodeChanges obj)
public override int GetHashCode (Binding obj)
{
return HashCode.Combine (obj.FullyQualifiedSymbol, obj.EnumMembers);
}
Expand Down
4 changes: 3 additions & 1 deletion src/rgen/Microsoft.Macios.Generator/DataModel/Parameter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System;
using System.Collections.Immutable;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.InteropServices;
using System.Text;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp.Syntax;
Expand All @@ -13,7 +14,8 @@ namespace Microsoft.Macios.Generator.DataModel;
/// <summary>
/// Readonly structure that represents a change in a parameter.
/// </summary>
readonly struct Parameter : IEquatable<Parameter> {
[StructLayout (LayoutKind.Auto)]
readonly partial struct Parameter : IEquatable<Parameter> {
/// <summary>
/// Parameter position in the method.
/// </summary>
Expand Down
12 changes: 11 additions & 1 deletion src/rgen/Microsoft.Macios.Generator/DataModel/Property.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,18 @@ namespace Microsoft.Macios.Generator.DataModel;

public string BackingField { get; private init; }

readonly TypeInfo returnType;

/// <summary>
/// Representation of the property type.
/// </summary>
public TypeInfo ReturnType { get; } = default;
public TypeInfo ReturnType {
get => returnType;
private init {
returnType = value;
ValueParameter = new Parameter (0, returnType, "value");
}
}

/// <summary>
/// Returns if the property type is bittable.
Expand Down Expand Up @@ -62,6 +70,8 @@ namespace Microsoft.Macios.Generator.DataModel;
/// </summary>
public ImmutableArray<Accessor> Accessors { get; } = [];

public Parameter ValueParameter { get; private init; }

public Accessor? GetAccessor (AccessorKind accessorKind)
{
// careful, do not use FirstOrDefault from LINQ because we are using structs!
Expand Down
Loading

0 comments on commit b2691b3

Please sign in to comment.