Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: ability to skip generation of obsolete properties #415

Merged
merged 3 commits into from
Jun 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
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
48 changes: 38 additions & 10 deletions src/Vetuviem.SourceGenerator/AbstractBaseSourceGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -120,26 +120,44 @@ public void Execute(GeneratorExecutionContext context)

var configOptions = context.AnalyzerConfigOptions;
var globalOptions = configOptions.GlobalOptions;
globalOptions.TryGetBuildPropertyValue("Vetuviem_Root_Namespace", out var rootNamespace);
globalOptions.TryGetBuildPropertyValue(
"Vetuviem_Root_Namespace",
out var rootNamespace);
var namespaceName = GetNamespace(rootNamespace);

globalOptions.TryGetBuildPropertyValue("Vetuviem_Make_Classes_Public", out var makeClassesPublicAsString);
globalOptions.TryGetBuildPropertyValue(
"Vetuviem_Make_Classes_Public",
out var makeClassesPublicAsString);
bool.TryParse(makeClassesPublicAsString, out var makeClassesPublic);

globalOptions.TryGetBuildPropertyValue("Vetuviem_Assemblies", out var assemblies);
globalOptions.TryGetBuildPropertyValue(
"Vetuviem_Assemblies",
out var assemblies);
var assembliesArray = assemblies?.Split(
[','],
StringSplitOptions.RemoveEmptyEntries)
.Where(s => !string.IsNullOrWhiteSpace(s))
.ToArray();

globalOptions.TryGetBuildPropertyValue("Vetuviem_Assembly_Mode", out var assemblyModeAsString);
globalOptions.TryGetBuildPropertyValue(
"Vetuviem_Assembly_Mode",
out var assemblyModeAsString);

var assemblyMode = GetAssemblyMode(assemblyModeAsString);

// base type name only used if passing a custom set of assemblies to search for.
// allows for 3rd parties to use the generator and produce a custom namespace that inherits off the root, or custom namespace.
globalOptions.TryGetBuildPropertyValue("Vetuviem_Base_Namespace", out var baseType);
globalOptions.TryGetBuildPropertyValue(
"Vetuviem_Base_Namespace",
out var baseType);

globalOptions.TryGetBuildPropertyValue(
"Vetuviem_Include_Obsolete_Items",
out var includeObsoleteItemsAsString);
bool.TryParse(
includeObsoleteItemsAsString,
out var includeObsoleteItems);
// includeObsoleteItems = true;

var namespaceDeclaration = SyntaxFactory.NamespaceDeclaration(SyntaxFactory.IdentifierName(namespaceName));

Expand All @@ -160,7 +178,10 @@ public void Execute(GeneratorExecutionContext context)
//}
#endif

var assembliesOfInterest = GetAssembliesOfInterest(platformResolver, assembliesArray, assemblyMode);
var assembliesOfInterest = GetAssembliesOfInterest(
platformResolver,
assembliesArray,
assemblyMode);
if (assembliesOfInterest.Length == 0)
{
return null;
Expand All @@ -177,12 +198,16 @@ public void Execute(GeneratorExecutionContext context)
if (referencesOfInterest.Length != assembliesOfInterest.Length)
{
// not got the expected count back, drop out.
context.ReportDiagnostic(ReportDiagnosticFactory.ReferencesOfInterestCountMismatch(assembliesOfInterest.Length, referencesOfInterest.Length));
context.ReportDiagnostic(ReportDiagnosticFactory.ReferencesOfInterestCountMismatch(
assembliesOfInterest.Length,
referencesOfInterest.Length));
return namespaceDeclaration;
}

var desiredBaseType = platformResolver.GetBaseUiElement();
var desiredNameWithoutGlobal = desiredBaseType.Replace("global::", string.Empty);
var desiredNameWithoutGlobal = desiredBaseType.Replace(
"global::",
string.Empty);
var desiredBaseTypeSymbolMatch = compilation.GetTypeByMetadataName(desiredNameWithoutGlobal);

if (desiredBaseTypeSymbolMatch == null)
Expand Down Expand Up @@ -221,7 +246,8 @@ public void Execute(GeneratorExecutionContext context)
desiredCommandInterface,
platformName,
namespaceName,
makeClassesPublic);
makeClassesPublic,
includeObsoleteItems);

return result;
}
Expand All @@ -233,7 +259,9 @@ private static AssemblyMode GetAssemblyMode(string? assemblyModeAsString)
return AssemblyMode.Replace;
}

if ( !Enum.TryParse<AssemblyMode>(assemblyModeAsString, out var assemblyMode))
if ( !Enum.TryParse<AssemblyMode>(
assemblyModeAsString,
out var assemblyMode))
{
return assemblyMode;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ public ClassDeclarationSyntax GenerateClass(
string? desiredCommandInterface,
string platformName,
string rootNamespace,
bool makeClassesPublic)
bool makeClassesPublic,
bool includeObsoleteItems)
{
var typeParameterList = GetTypeParameterListSyntax(namedTypeSymbol);

Expand All @@ -51,7 +52,15 @@ public ClassDeclarationSyntax GenerateClass(

var members = new SyntaxList<MemberDeclarationSyntax>(GetConstructorMethod(namedTypeSymbol, isDerivedType, makeClassesPublic, typeParameterList));

members = ApplyMembers(members, namedTypeSymbol, desiredCommandInterface, isDerivedType, controlClassFullName, platformName, makeClassesPublic);
members = ApplyMembers(
members,
namedTypeSymbol,
desiredCommandInterface,
isDerivedType,
controlClassFullName,
platformName,
makeClassesPublic,
includeObsoleteItems);

return classDeclaration
.WithModifiers(modifiers)
Expand Down Expand Up @@ -172,6 +181,7 @@ protected static IEnumerable<TypeSyntax> GetTypeArgumentsFromTypeParameters(INam
/// <param name="controlClassFullName">Full Name of the Control Class.</param>
/// <param name="platformName">Friendly Name for the platform.</param>
/// <param name="makeClassesPublic">A flag indicating whether to expose the generated binding classes as public rather than internal. Set this to true if you're created a reusable library file.</param>
/// <param name="includeObsoleteItems">Whether to include obsolete items in the generated code.</param>
/// <returns>Modified Syntax List of Member declarations.</returns>
protected abstract SyntaxList<MemberDeclarationSyntax> ApplyMembers(
SyntaxList<MemberDeclarationSyntax> members,
Expand All @@ -180,7 +190,8 @@ protected abstract SyntaxList<MemberDeclarationSyntax> ApplyMembers(
bool isDerivedType,
string controlClassFullName,
string platformName,
bool makeClassesPublic);
bool makeClassesPublic,
bool includeObsoleteItems);

/// <summary>
/// Gets the class name identifier from a named type symbol.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,13 @@ public static class ControlBindingModelPropertyGenerator
/// <param name="namedTypeSymbol">The type to check the properties on.</param>
/// <param name="desiredCommandInterface">The fully qualified typename for the Command interface used by the UI platform, if it uses one.</param>
/// <param name="makeClassesPublic">A flag indicating whether to expose the generated binding classes as public rather than internal. Set this to true if you're created a reusable library file.</param>
/// <param name="includeObsoleteItems">Whether to include obsolete items in the generated code.</param>
/// <returns>List of property declarations.</returns>
public static SyntaxList<MemberDeclarationSyntax> GetProperties(
INamedTypeSymbol namedTypeSymbol,
string? desiredCommandInterface,
bool makeClassesPublic)
bool makeClassesPublic,
bool includeObsoleteItems)
{
if (namedTypeSymbol == null)
{
Expand All @@ -55,6 +57,15 @@ public static SyntaxList<MemberDeclarationSyntax> GetProperties(
continue;
}

// check for obsolete attribute
var attributes = propertySymbol.GetAttributes();
if (!includeObsoleteItems && attributes.Any(a => a.AttributeClass?.GetFullName().Equals(
"global::System.ObsoleteAttribute",
StringComparison.Ordinal) == true))
{
continue;
}

// windows forms has an issue where some properties are provided as "new" instances instead of overridden
// we're getting build warnings for these.
if (ReplacesBaseProperty(propertySymbol, namedTypeSymbol))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ protected override SyntaxList<MemberDeclarationSyntax> ApplyMembers(
bool isDerivedType,
string controlClassFullName,
string platformName,
bool makeClassesPublic)
bool makeClassesPublic,
bool includeObsoleteItems)
{
return members;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,22 +33,26 @@ protected override SyntaxList<MemberDeclarationSyntax> ApplyMembers(
bool isDerivedType,
string controlClassFullName,
string platformName,
bool makeClassesPublic)
bool makeClassesPublic,
bool includeObsoleteItems)
{
members = members.AddRange(ControlBindingModelPropertyGenerator.GetProperties(
namedTypeSymbol,
desiredCommandInterface,
makeClassesPublic));
makeClassesPublic,
includeObsoleteItems));

members = members.Add(GetApplyBindingsWithDisposableActionMethod(
namedTypeSymbol,
isDerivedType,
desiredCommandInterface));
desiredCommandInterface,
includeObsoleteItems));

members = members.Add(GetApplyBindingsWithCompositeDisposableMethod(
namedTypeSymbol,
isDerivedType,
desiredCommandInterface));
desiredCommandInterface,
includeObsoleteItems));

return members;
}
Expand Down Expand Up @@ -269,15 +273,17 @@ private static SeparatedSyntaxList<TypeSyntax> GetTypeArgumentSeparatedSyntaxLis
private static MemberDeclarationSyntax GetApplyBindingsWithDisposableActionMethod(
INamedTypeSymbol namedTypeSymbol,
bool isDerivedType,
string? desiredCommandInterface)
string? desiredCommandInterface,
bool includeObsoleteItems)
{
const string methodName = "ApplyBindings";
var returnType = SyntaxFactory.ParseTypeName("void");

var methodBody = GetApplyBindingMethodBody(
namedTypeSymbol,
isDerivedType,
desiredCommandInterface);
desiredCommandInterface,
includeObsoleteItems);

var parameters = RoslynGenerationHelpers.GetParams(new[]
{
Expand All @@ -300,15 +306,17 @@ private static MemberDeclarationSyntax GetApplyBindingsWithDisposableActionMetho
private static MemberDeclarationSyntax GetApplyBindingsWithCompositeDisposableMethod(
INamedTypeSymbol namedTypeSymbol,
bool isDerivedType,
string? desiredCommandInterface)
string? desiredCommandInterface,
bool includeObsoleteItems)
{
const string methodName = "ApplyBindings";
var returnType = SyntaxFactory.ParseTypeName("void");

var methodBody = GetApplyBindingCompositeDisposableMethodBody(
namedTypeSymbol,
isDerivedType,
desiredCommandInterface);
desiredCommandInterface,
includeObsoleteItems);

var parameters = RoslynGenerationHelpers.GetParams(new[]
{
Expand All @@ -331,7 +339,8 @@ private static MemberDeclarationSyntax GetApplyBindingsWithCompositeDisposableMe
private static StatementSyntax[] GetApplyBindingMethodBody(
INamedTypeSymbol namedTypeSymbol,
bool isDerivedType,
string? desiredCommandInterface)
string? desiredCommandInterface,
bool includeObsoleteItems)
{
var body = new List<StatementSyntax>();

Expand Down Expand Up @@ -370,6 +379,15 @@ private static StatementSyntax[] GetApplyBindingMethodBody(
continue;
}

// check for obsolete attribute
var attributes = propertySymbol.GetAttributes();
if (!includeObsoleteItems && attributes.Any(a => a.AttributeClass?.GetFullName().Equals(
"global::System.ObsoleteAttribute",
StringComparison.Ordinal) == true))
{
continue;
}

var propType = propertySymbol.Type.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat);

var invokeArgs = new[]
Expand Down Expand Up @@ -402,10 +420,10 @@ private static StatementSyntax[] GetApplyBindingMethodBody(
return body.ToArray();
}

private static StatementSyntax[] GetApplyBindingCompositeDisposableMethodBody(
INamedTypeSymbol namedTypeSymbol,
private static StatementSyntax[] GetApplyBindingCompositeDisposableMethodBody(INamedTypeSymbol namedTypeSymbol,
bool isDerivedType,
string? desiredCommandInterface)
string? desiredCommandInterface,
bool includeObsoleteItems)
{
var body = new List<StatementSyntax>();

Expand Down Expand Up @@ -444,6 +462,15 @@ private static StatementSyntax[] GetApplyBindingCompositeDisposableMethodBody(
continue;
}

// check for obsolete attribute
var attributes = propertySymbol.GetAttributes();
if (!includeObsoleteItems && attributes.Any(a => a.AttributeClass?.GetFullName().Equals(
"global::System.ObsoleteAttribute",
StringComparison.Ordinal) == true))
{
continue;
}

var propType = propertySymbol.Type.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat);

var invokeArgs = new[]
Expand Down
Loading
Loading