Skip to content

Commit

Permalink
Add BuildFields to NamedTypeSymbolProvider (#4140)
Browse files Browse the repository at this point in the history
Resolves: #3806
  • Loading branch information
nisha-bhatia authored Aug 13, 2024
1 parent deca55d commit ee03132
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using System.Linq;
using System.Xml.Linq;
using Microsoft.CodeAnalysis;
using Microsoft.Generator.CSharp.Expressions;
using Microsoft.Generator.CSharp.Primitives;
using Microsoft.Generator.CSharp.Statements;

Expand All @@ -26,19 +27,28 @@ public NamedTypeSymbolProvider(INamedTypeSymbol namedTypeSymbol)

protected override string GetNamespace() => GetFullyQualifiedNameFromDisplayString(_namedTypeSymbol.ContainingNamespace);

protected override ConstructorProvider[] BuildConstructors()
protected override FieldProvider[] BuildFields()
{
List<ConstructorProvider> constructors = new List<ConstructorProvider>();
foreach (var constructorSymbol in _namedTypeSymbol.Constructors)
List<FieldProvider> fields = new List<FieldProvider>();
foreach (var fieldSymbol in _namedTypeSymbol.GetMembers().OfType<IFieldSymbol>())
{
var signature = new ConstructorSignature(
Type,
GetSymbolXmlDoc(constructorSymbol, "summary"),
GetAccessModifier(constructorSymbol.DeclaredAccessibility),
[.. constructorSymbol.Parameters.Select(p => ConvertToParameterProvider(constructorSymbol, p))]);
constructors.Add(new ConstructorProvider(signature, MethodBodyStatement.Empty, this));
if (!fieldSymbol.Name.EndsWith("k__BackingField"))
{
var modifiers = GetFieldsAccessModifier(fieldSymbol.DeclaredAccessibility);
if (fieldSymbol.IsStatic)
{
modifiers |= FieldModifiers.Static;
}

var fieldProvider = new FieldProvider(
modifiers,
GetCSharpType(fieldSymbol.Type),
fieldSymbol.Name,
GetSymbolXmlDoc(fieldSymbol, "summary"));
fields.Add(fieldProvider);
}
}
return [.. constructors];
return [.. fields];
}

protected override PropertyProvider[] BuildProperties()
Expand All @@ -57,6 +67,21 @@ protected override PropertyProvider[] BuildProperties()
return [.. properties];
}

protected override ConstructorProvider[] BuildConstructors()
{
List<ConstructorProvider> constructors = new List<ConstructorProvider>();
foreach (var constructorSymbol in _namedTypeSymbol.Constructors)
{
var signature = new ConstructorSignature(
Type,
GetSymbolXmlDoc(constructorSymbol, "summary"),
GetAccessModifier(constructorSymbol.DeclaredAccessibility),
[.. constructorSymbol.Parameters.Select(p => ConvertToParameterProvider(constructorSymbol, p))]);
constructors.Add(new ConstructorProvider(signature, MethodBodyStatement.Empty, this));
}
return [.. constructors];
}

protected override MethodProvider[] BuildMethods()
{
List<MethodProvider> methods = new List<MethodProvider>();
Expand Down Expand Up @@ -142,6 +167,15 @@ private void AddAdditionalModifiers(IMethodSymbol methodSymbol, ref MethodSignat
_ => MethodSignatureModifiers.None
};

private static FieldModifiers GetFieldsAccessModifier(Accessibility accessibility) => accessibility switch
{
Accessibility.Private => FieldModifiers.Private,
Accessibility.Protected => FieldModifiers.Protected,
Accessibility.Internal => FieldModifiers.Internal,
Accessibility.Public => FieldModifiers.Public,
_ => FieldModifiers.Public
};

private static CSharpType GetCSharpType(ITypeSymbol typeSymbol)
{
var fullyQualifiedName = GetFullyQualifiedName(typeSymbol);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,24 @@ public void ValidateConstructors()
}
}

[Test]
public void ValidateFields()
{
Dictionary<string, FieldProvider> fields = _namedTypeSymbolProvider.Fields.ToDictionary(p => p.Name);
Assert.AreEqual(_namedSymbol.Fields.Count, fields.Count);
foreach (var expected in _namedSymbol.Fields)
{
var actual = fields[expected.Name];

Assert.IsTrue(fields.ContainsKey(expected.Name));
Assert.AreEqual(expected.Modifiers, actual.Modifiers);
Assert.AreEqual(expected.Type, actual.Type);
Assert.AreEqual(expected.Name, actual.Name);
Assert.AreEqual($"{expected.Description}.", actual.Description!.ToString()); // the writer adds a period
Assert.AreEqual(expected.InitializationValue, actual.InitializationValue);
}
}

private class NamedSymbol : TypeProvider
{
protected override string BuildRelativeFilePath() => ".";
Expand All @@ -127,6 +145,17 @@ private class NamedSymbol : TypeProvider

protected override string GetNamespace() => CodeModelPlugin.Instance.Configuration.ModelNamespace;

protected override FieldProvider[] BuildFields()
{
return
[
new FieldProvider(FieldModifiers.Public, typeof(int), "IntProperty", $"PublicIntProperty property"),
new FieldProvider(FieldModifiers.Private, typeof(string), "StringProperty", $"PrivateStringProperty property no setter"),
new FieldProvider(FieldModifiers.Internal, typeof(double), "DoubleProperty", $"InternalDoubleProperty property"),
new FieldProvider(FieldModifiers.Public | FieldModifiers.Static, typeof(float), "FloatProperty", $"PublicStaticFloatProperty property"),
];
}

protected override PropertyProvider[] BuildProperties()
{
return
Expand All @@ -138,27 +167,27 @@ protected override PropertyProvider[] BuildProperties()
];
}

protected override MethodProvider[] BuildMethods()
protected override ConstructorProvider[] BuildConstructors()
{
var intParam = new ParameterProvider("intParam", $"intParam", new CSharpType(typeof(int)));

return
[
new MethodProvider(
new MethodSignature("Method1", $"Description of method1", MethodSignatureModifiers.Public | MethodSignatureModifiers.Virtual, typeof(Task<int>), null, [intParam]),
new ConstructorProvider(
new ConstructorSignature(Type, $"Initializes a new instance of {Type}", MethodSignatureModifiers.Public, [intParam]),
Throw(New.Instance(typeof(NotImplementedException))),
this)
];
}

protected override ConstructorProvider[] BuildConstructors()
protected override MethodProvider[] BuildMethods()
{
var intParam = new ParameterProvider("intParam", $"intParam", new CSharpType(typeof(int)));

return
[
new ConstructorProvider(
new ConstructorSignature(Type, $"Initializes a new instance of {Type}", MethodSignatureModifiers.Public, [intParam]),
new MethodProvider(
new MethodSignature("Method1", $"Description of method1", MethodSignatureModifiers.Public | MethodSignatureModifiers.Virtual, typeof(Task<int>), null, [intParam]),
Throw(New.Instance(typeof(NotImplementedException))),
this)
];
Expand Down

0 comments on commit ee03132

Please sign in to comment.