Skip to content

Commit

Permalink
Feature: ability to skip generation of obsolete properties (#415)
Browse files Browse the repository at this point in the history
* skip obsolete classes

* skip property generation

* add msbuild property
  • Loading branch information
dpvreony authored Jun 5, 2024
1 parent 8687542 commit 9447fbb
Show file tree
Hide file tree
Showing 10 changed files with 152 additions and 45 deletions.
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

0 comments on commit 9447fbb

Please sign in to comment.