KEMBAR78
[Nomenclator] Deal correctly with nested classed. by mandel-macaque · Pull Request #22943 · dotnet/macios · GitHub
Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
[Nomenclator] Deal correctly with nested classed.
Nested classes names will contain a '.' to indicate they are nested but
leaving the '.' will result in an invalid name.
  • Loading branch information
mandel-macaque committed May 29, 2025
commit 58fcce6c7d9f48c4b97f5100f29356e6b8b44496
10 changes: 6 additions & 4 deletions src/rgen/Microsoft.Macios.Generator/Nomenclator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -62,11 +62,13 @@ public string GetTrampolineName (TypeInfo typeInfo)
// }
// return trampolineName;

// trampoline name will the the name of the type + the arity + the length of the generic types
// else it will be the trampoline name
// trampoline name will the name of the type + the arity + the length of the generic types
// else it will be the trampoline name. We will replace any . with _ to ensure that the name is valid
// when working with nested classes.
var typeName = typeInfo.Name.Replace ('.', '_');
var trampolineName = typeInfo.IsGenericType
? $"{typeInfo.Name}Arity{typeInfo.TypeArguments.Length}"
: typeInfo.Name;
? $"{typeName}Arity{typeInfo.TypeArguments.Length}"
: typeName;

if (!typeInfo.IsGenericType)
return trampolineName;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ static partial class Trampolines
unsafe internal delegate global::ObjCRuntime.NativeHandle DTrampolinePropertyTests.CreateObject (global::System.IntPtr block_ptr, global::ObjCRuntime.NativeHandle obj);

/// <summary>This class bridges native block invocations that call into C#</summary>
static internal class SDTrampolinePropertyTests.CreateObject
static internal class SDTrampolinePropertyTests_CreateObject
{
[Preserve (Conditional = true)]
[UnmanagedCallersOnly]
Expand All @@ -45,7 +45,7 @@ static internal class SDTrampolinePropertyTests.CreateObject
internal static unsafe global::ObjCRuntime.BlockLiteral CreateBlock (global::Microsoft.Macios.Generator.Tests.Classes.Data.TestNamespace.TrampolinePropertyTests.CreateObject callback)
{
delegate* unmanaged<global::System.IntPtr, global::ObjCRuntime.NativeHandle, global::ObjCRuntime.NativeHandle> trampoline = &Invoke;
return new global::ObjCRuntime.BlockLiteral (trampoline, callback, typeof (SDTrampolinePropertyTests.CreateObject), nameof (Invoke));
return new global::ObjCRuntime.BlockLiteral (trampoline, callback, typeof (SDTrampolinePropertyTests_CreateObject), nameof (Invoke));
}
}
// TODO: generate trampoline for Microsoft.Macios.Generator.Tests.Classes.Data.TestNamespace.TrampolinePropertyTests.CreateObject
Expand Down
45 changes: 45 additions & 0 deletions tests/rgen/Microsoft.Macios.Generator.Tests/NomenclatorTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,51 @@ public class Example {
Assert.Equal ("GenericTrampolineArity1V1", name2);
Assert.NotEqual (name1, name2);
}

[Theory]
[AllSupportedPlatforms]
public void GetTrampolineNestedClass (ApplePlatform platform)
{
var nomenclator = new Nomenclator ();

// write a sample code to retrieve the roslyn symbol and type info so that
// we can test the nomenclator.
var code = @"
using System;
using System.Collections.Generic;

namespace Test;

public class Example {
public class GenericTrampoline<T> where T : class {
void DidAccelerateSeveral (object accelerometer, object second, object last);
}

public GenericTrampoline<string> Trampoline { get; set; }
}
";

var (compilation, syntaxTrees) = CreateCompilation (platform, sources: code);

Assert.Single (syntaxTrees);
var declaration = syntaxTrees [0].GetRoot ()
.DescendantNodes ()
.OfType<PropertyDeclarationSyntax> ()
.FirstOrDefault ();
Assert.NotNull (declaration);
var semanticModel = compilation.GetSemanticModel (syntaxTrees [0]);
Assert.NotNull (semanticModel);
Assert.True (Property.TryCreate (declaration, semanticModel, out var property));
Assert.NotNull (property);
var type = property.Value.ReturnType;

var name1 = nomenclator.GetTrampolineName (type);
var name2 = nomenclator.GetTrampolineName (type);
// compare names and ensure that the correct number is used
Assert.Equal ("Example_GenericTrampolineArity1V0", name1);
Assert.Equal ("Example_GenericTrampolineArity1V1", name2);
Assert.NotEqual (name1, name2);
}

[Theory]
[AllSupportedPlatforms]
Expand Down
Loading