Skip to content

Commit

Permalink
[RGen] Implement 'IsSmartEnum' for the transformer. (#22090)
Browse files Browse the repository at this point in the history
Co-authored-by: GitHub Actions Autoformatter <[email protected]>
  • Loading branch information
mandel-macaque and GitHub Actions Autoformatter authored Feb 1, 2025
1 parent 5c5febc commit abfc28e
Show file tree
Hide file tree
Showing 3 changed files with 115 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using Microsoft.Macios.Generator.Attributes;
using Microsoft.Macios.Generator.Availability;
using Microsoft.Macios.Transformer.Attributes;
using Microsoft.Macios.Transformer.Extensions;
using Xamarin.Utils;

namespace Microsoft.Macios.Generator.Extensions;
Expand Down Expand Up @@ -66,6 +67,21 @@ internal static SymbolAvailability GetAvailabilityForSymbol (this ISymbol symbol

public static bool IsSmartEnum (this ITypeSymbol symbol)
{
throw new NotImplementedException ();
// smart enums in the classic bindings are a little more complicated to detect since we need
// to find AT LEAST one enum field that contains the Field attribute.
if (symbol.TypeKind != TypeKind.Enum)
return false;

foreach (var member in symbol.GetMembers ()) {
if (member is not IFieldSymbol field || !field.IsConst)
continue;

// try to get the Field attribute from the current member, if we found it, then we have a smart enum
var attributeData = field.GetAttributeData ();
if (attributeData.HasFieldAttribute ())
return true;
}

return false;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@
// Licensed under the MIT License.

using System.Collections;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.Macios.Generator.Extensions;
using Microsoft.Macios.Transformer.Attributes;
using Xamarin.Tests;
using Xamarin.Utils;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

using System.Collections;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.Macios.Generator.Extensions;
using Xamarin.Tests;
using Xamarin.Utils;

namespace Microsoft.Macios.Transformer.Tests.Extensions;

public class TypeSymbolExtensionsTests : BaseTransformerTestClass {

class TestDataIsSmartEnum : IEnumerable<object []> {
public IEnumerator<object []> GetEnumerator ()
{
var path = "/some/random/path.cs";

const string normalEnum = @"
using System;
namespace Test;
public enum MyEnum {
First,
Second,
Last,
}
";
yield return [(Source: normalEnum, Path: path), false];

const string traditionalSmartEnum = @"
using System;
using Foundation;
using ObjCRuntime;
namespace Test;
public enum MyEnum {
[Field (""FirstEnum""]
First,
[Field (""Second""]
Second,
[Field (""Last""]
Last,
}
";

yield return [(Source: traditionalSmartEnum, Path: path), true];

const string partialSmartEnum = @"
using System;
using Foundation;
using ObjCRuntime;
namespace Test;
public enum MyEnum {
First,
Second,
[Field (""Last""]
Last,
}
";

// should not be very common, nevertheless test for it.
yield return [(Source: partialSmartEnum, Path: path), true];
}

IEnumerator IEnumerable.GetEnumerator () => GetEnumerator ();
}

[Theory]
[AllSupportedPlatformsClassData<TestDataIsSmartEnum>]
void IsSmartEnumTests (ApplePlatform platform, (string Source, string Path) source, bool expectedResult)
{
var compilation = CreateCompilation (platform, sources: source);
var syntaxTree = compilation.SyntaxTrees.ForSource (source);
var trees = compilation.SyntaxTrees.Where (s => s.FilePath == source.Path).ToArray ();
Assert.Single (trees);
Assert.NotNull (syntaxTree);

var semanticModel = compilation.GetSemanticModel (syntaxTree);
Assert.NotNull (semanticModel);

var declaration = syntaxTree.GetRoot ()
.DescendantNodes ().OfType<EnumDeclarationSyntax> ()
.LastOrDefault ();

Assert.NotNull (declaration);

var symbol = semanticModel.GetDeclaredSymbol (declaration);
Assert.NotNull (symbol);
var isSmartEnum = symbol.IsSmartEnum ();
Assert.Equal (expectedResult, symbol.IsSmartEnum ());
}
}

0 comments on commit abfc28e

Please sign in to comment.