Skip to content

Commit

Permalink
Update TransitiveMembersGenerator for new embedded resources
Browse files Browse the repository at this point in the history
  • Loading branch information
Sergio0694 committed Dec 2, 2021
1 parent 680be41 commit b86238c
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 37 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -130,21 +130,6 @@ private void OnExecute(
SyntaxTree sourceSyntaxTree)
{
ClassDeclarationSyntax sourceDeclaration = sourceSyntaxTree.GetRoot().DescendantNodes().OfType<ClassDeclarationSyntax>().First();
UsingDirectiveSyntax[] usingDirectives = sourceSyntaxTree.GetRoot().DescendantNodes().OfType<UsingDirectiveSyntax>().ToArray();
BaseListSyntax? baseListSyntax = BaseList(SeparatedList(
sourceDeclaration.BaseList?.Types
.OfType<SimpleBaseTypeSyntax>()
.Select(static t => t.Type)
.OfType<IdentifierNameSyntax>()
.Where(static t => t.Identifier.ValueText.StartsWith("I"))
.Select(static t => SimpleBaseType(t))
.ToArray()
?? Array.Empty<BaseTypeSyntax>()));

if (baseListSyntax.Types.Count == 0)
{
baseListSyntax = null;
}

// Create the class declaration for the user type. This will produce a tree as follows:
//
Expand All @@ -155,7 +140,7 @@ private void OnExecute(
ClassDeclarationSyntax? classDeclarationSyntax =
ClassDeclaration(classDeclaration.Identifier.Text)
.WithModifiers(classDeclaration.Modifiers)
.WithBaseList(baseListSyntax)
.WithBaseList(sourceDeclaration.BaseList)
.AddMembers(OnLoadDeclaredMembers(context, attributeData, classDeclaration, classDeclarationSymbol, sourceDeclaration).ToArray());

TypeDeclarationSyntax typeDeclarationSyntax = classDeclarationSyntax;
Expand All @@ -175,15 +160,14 @@ private void OnExecute(
// From this, we can finally generate the source code to output.
string? namespaceName = classDeclarationSymbol.ContainingNamespace.ToDisplayString(new(typeQualificationStyle: NameAndContainingTypesAndNamespaces));

// Create the final compilation unit to generate (with using directives and the full type declaration)
// Create the final compilation unit to generate (with the full type declaration)
string? source =
CompilationUnit()
.AddMembers(NamespaceDeclaration(IdentifierName(namespaceName))
.AddMembers(typeDeclarationSyntax))
.AddUsings(usingDirectives.First().WithLeadingTrivia(TriviaList(
.WithLeadingTrivia(TriviaList(
Comment("// <auto-generated/>"),
Trivia(PragmaWarningDirectiveTrivia(Token(SyntaxKind.DisableKeyword), true)))))
.AddUsings(usingDirectives.Skip(1).ToArray())
Trivia(PragmaWarningDirectiveTrivia(Token(SyntaxKind.DisableKeyword), true))))
.AddMembers(typeDeclarationSyntax))
.NormalizeWhitespace()
.ToFullString();

Expand Down Expand Up @@ -212,30 +196,30 @@ private IEnumerable<MemberDeclarationSyntax> OnLoadDeclaredMembers(
// Add the attributes on each member
return generatedMembers.Select(member =>
{
// [GeneratedCode] is always present
member = member
.WithoutLeadingTrivia()
.AddAttributeLists(AttributeList(SingletonSeparatedList(
Attribute(IdentifierName($"global::System.CodeDom.Compiler.GeneratedCode"))
.AddArgumentListArguments(
AttributeArgument(LiteralExpression(SyntaxKind.StringLiteralExpression, Literal(GetType().FullName))),
AttributeArgument(LiteralExpression(SyntaxKind.StringLiteralExpression, Literal(GetType().Assembly.GetName().Version.ToString())))))))
.WithLeadingTrivia(member.GetLeadingTrivia());
// [DebuggerNonUserCode] is not supported over interfaces, events or fields
if (member.Kind() is not SyntaxKind.InterfaceDeclaration and not SyntaxKind.EventFieldDeclaration and not SyntaxKind.FieldDeclaration)
// [GeneratedCode] is always present
member = member
.WithoutLeadingTrivia()
.AddAttributeLists(AttributeList(SingletonSeparatedList(
Attribute(IdentifierName($"global::System.CodeDom.Compiler.GeneratedCode"))
.AddArgumentListArguments(
AttributeArgument(LiteralExpression(SyntaxKind.StringLiteralExpression, Literal(GetType().FullName))),
AttributeArgument(LiteralExpression(SyntaxKind.StringLiteralExpression, Literal(GetType().Assembly.GetName().Version.ToString())))))))
.WithLeadingTrivia(member.GetLeadingTrivia());
// [DebuggerNonUserCode] is not supported over interfaces, events or fields
if (member.Kind() is not SyntaxKind.InterfaceDeclaration and not SyntaxKind.EventFieldDeclaration and not SyntaxKind.FieldDeclaration)
{
member = member.AddAttributeLists(AttributeList(SingletonSeparatedList(Attribute(IdentifierName("global::System.Diagnostics.DebuggerNonUserCode")))));
}
// [ExcludeFromCodeCoverage] is not supported on interfaces and fields
if (member.Kind() is not SyntaxKind.InterfaceDeclaration and not SyntaxKind.FieldDeclaration)
// [ExcludeFromCodeCoverage] is not supported on interfaces and fields
if (member.Kind() is not SyntaxKind.InterfaceDeclaration and not SyntaxKind.FieldDeclaration)
{
member = member.AddAttributeLists(AttributeList(SingletonSeparatedList(Attribute(IdentifierName("global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage")))));
}
// If the target class is sealed, make protected members private and remove the virtual modifier
if (classDeclarationSymbol.IsSealed)
// If the target class is sealed, make protected members private and remove the virtual modifier
if (classDeclarationSymbol.IsSealed)
{
return member
.ReplaceModifier(SyntaxKind.ProtectedKeyword, SyntaxKind.PrivateKeyword)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ public partial class Test_ObservableObjectAttribute
[TestMethod]
public void Test_ObservableObjectAttribute_Events()
{
Assert.IsTrue(typeof(INotifyPropertyChanged).IsAssignableFrom(typeof(SampleModel)));
Assert.IsTrue(typeof(INotifyPropertyChanging).IsAssignableFrom(typeof(SampleModel)));

SampleModel? model = new();

(PropertyChangingEventArgs, int) changing = default;
Expand Down Expand Up @@ -52,6 +55,9 @@ public void Test_ObservableObjectAttribute_Events()
[TestMethod]
public void Test_ObservableObjectAttribute_OnSealedClass_Events()
{
Assert.IsTrue(typeof(INotifyPropertyChanged).IsAssignableFrom(typeof(SampleModelSealed)));
Assert.IsTrue(typeof(INotifyPropertyChanging).IsAssignableFrom(typeof(SampleModelSealed)));

SampleModelSealed? model = new();

(PropertyChangingEventArgs, int) changing = default;
Expand Down

0 comments on commit b86238c

Please sign in to comment.