From a9eca33e31a8b0d5688e0a03f41954b7e6b84cf4 Mon Sep 17 00:00:00 2001 From: Rekkonnect Date: Tue, 27 Feb 2024 03:07:00 +0200 Subject: [PATCH 1/3] Implement ThrowIfDisposed() --- src/IDisposableGenerator/ClassItems.cs | 2 + .../DisposableCodeWriter.cs | 85 +++++++-- .../Properties/Resources.resx | 165 +++++++++++++++--- .../WorkItemCollection.cs | 48 +++-- tests/IDisposableGeneratorTests.CSharp10.cs | 58 ++++++ tests/IDisposableGeneratorTests.CSharp9.cs | 61 +++++++ .../IDisposableGeneratorTests.VisualBasic.cs | 58 ++++++ 7 files changed, 421 insertions(+), 56 deletions(-) diff --git a/src/IDisposableGenerator/ClassItems.cs b/src/IDisposableGenerator/ClassItems.cs index 4d19549..777bc95 100644 --- a/src/IDisposableGenerator/ClassItems.cs +++ b/src/IDisposableGenerator/ClassItems.cs @@ -5,6 +5,7 @@ internal class ClassItems public string? Name { get; set; } public Accessibility Accessibility { get; set; } public bool Stream { get; set; } + public bool ThrowIfDisposed { get; set; } public List Owns { get; } = []; public List Fields { get; } = []; public List SetNull { get; } = []; @@ -46,6 +47,7 @@ public override string ToString() _ = result.Append($"Class: Name {this.Name}") .Append($", Accessibility: {this.Accessibility}") .Append($", Stream: {this.Stream}") + .Append($", ThrowIfDisposed: {this.ThrowIfDisposed}") .Append($", Owns Count: {this.Owns.Count}") .Append($", Fields Count: {this.Fields.Count}") .Append($", SetNull Count: {this.SetNull.Count}") diff --git a/src/IDisposableGenerator/DisposableCodeWriter.cs b/src/IDisposableGenerator/DisposableCodeWriter.cs index 0f2a723..4bacadf 100644 --- a/src/IDisposableGenerator/DisposableCodeWriter.cs +++ b/src/IDisposableGenerator/DisposableCodeWriter.cs @@ -101,9 +101,28 @@ End If "); } - _ = sourceBuilder.Append(@" End Sub - End Class -"); + _ = sourceBuilder.Append(""" + End Sub + + """); + + if (classItem.ThrowIfDisposed) + { + _ = sourceBuilder.Append($$""" + + Friend Sub ThrowIfDisposed() + If Me.isDisposed Then + Throw New ObjectDisposedException(NameOf({{classItem.Name}})) + End If + End Sub + + """); + } + + _ = sourceBuilder.Append(""" + End Class + + """); } _ = sourceBuilder.Append(@"End Namespace @@ -209,9 +228,30 @@ namespace {workItem.Namespace}; "); } - _ = sourceBuilder.Append(@" } -} -"); + _ = sourceBuilder.Append(""" + } + + """); + + if (classItem.ThrowIfDisposed) + { + _ = sourceBuilder.Append($$""" + + internal void ThrowIfDisposed() + { + if (this.isDisposed) + { + throw new ObjectDisposedException(nameof({{classItem.Name}})); + } + } + + """); + } + + _ = sourceBuilder.Append(""" + } + + """); } // inject the created sources into the users compilation. @@ -319,13 +359,36 @@ namespace {workItem.Namespace} "); } - _ = sourceBuilder.Append(@" } - } -"); + _ = sourceBuilder.Append(""" + } + + """); + + if (classItem.ThrowIfDisposed) + { + _ = sourceBuilder.Append($$""" + + internal void ThrowIfDisposed() + { + if (this.isDisposed) + { + throw new ObjectDisposedException(nameof({{classItem.Name}})); + } + } + + """); + } + + _ = sourceBuilder.Append(""" + } + + """); } - _ = sourceBuilder.Append(@"} -"); + _ = sourceBuilder.Append(""" + } + + """); } // inject the created source into the users compilation. diff --git a/src/IDisposableGenerator/Properties/Resources.resx b/src/IDisposableGenerator/Properties/Resources.resx index ef047f3..284c1f7 100644 --- a/src/IDisposableGenerator/Properties/Resources.resx +++ b/src/IDisposableGenerator/Properties/Resources.resx @@ -1,25 +1,124 @@ - - - - - - - - text/microsoft-resx - - - 1.3 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - // <autogenerated/> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + // <autogenerated/> #pragma warning disable SA1636, 8618 namespace IDisposableGenerator { @@ -60,12 +159,17 @@ namespace IDisposableGenerator { } } + + // used only by a source generator to generate Dispose() and Dispose(bool). + [AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)] + internal class GenerateThrowIfDisposedAttribute : Attribute + { + } } -#pragma warning restore SA1636, 8618 - - - - ' <autogenerated/> +#pragma warning restore SA1636, 8618 + + + ' <autogenerated/> #Disable Warning SA1636 Imports System @@ -101,8 +205,13 @@ Namespace IDisposableGenerator Inherits Attribute End Class + ' used only by a source generator to generate Dispose() and Dispose(bool). + <AttributeUsage(AttributeTargets.Class, Inherited:=False, AllowMultiple:=False)> + Friend Class GenerateThrowIfDisposedAttribute + Inherits Attribute + End Class + End Namespace -#Enable Warning SA1636 - - +#Enable Warning SA1636 + \ No newline at end of file diff --git a/src/IDisposableGenerator/WorkItemCollection.cs b/src/IDisposableGenerator/WorkItemCollection.cs index 9530cb6..4402a81 100644 --- a/src/IDisposableGenerator/WorkItemCollection.cs +++ b/src/IDisposableGenerator/WorkItemCollection.cs @@ -22,19 +22,19 @@ public void Process(INamedTypeSymbol testClass, CancellationToken ct) } ct.ThrowIfCancellationRequested(); - var classItemsQuery = - from att in testClass.GetAttributes() - where att.AttributeClass!.Name.Equals( - "GenerateDisposeAttribute", StringComparison.Ordinal) - select GetClassItem(att, testClass); + var classItem = GetClassItem(testClass); + + if (classItem is null) + { + return; + } + + ct.ThrowIfCancellationRequested(); + workItem!.Classes.Add(classItem); + var memberQuery = from member in testClass.GetMembers() select member; - foreach (var classItem in classItemsQuery) - { - ct.ThrowIfCancellationRequested(); - workItem!.Classes.Add(classItem); - } foreach (var member in memberQuery) { @@ -49,16 +49,30 @@ public List GetWorkItems() public int IndexOf(WorkItem item) => this.WorkItems.IndexOf(item); - private static ClassItems GetClassItem(AttributeData attr, INamedTypeSymbol testClass) + private static ClassItems? GetClassItem(INamedTypeSymbol testClass) { - var result = new ClassItems + var result = new ClassItems(); + var hasDisposalGeneration = false; + + foreach (var attr in testClass.GetAttributes()) { - Name = testClass.Name, - Accessibility = testClass.DeclaredAccessibility, - Stream = (bool)attr.ConstructorArguments[0].Value!, - }; + switch (attr.AttributeClass!.Name) + { + case "GenerateDisposeAttribute": + hasDisposalGeneration = true; + result.Name = testClass.Name; + result.Accessibility = testClass.DeclaredAccessibility; + result.Stream = (bool)attr.ConstructorArguments[0].Value!; + break; + case "GenerateThrowIfDisposedAttribute": + result.ThrowIfDisposed = true; + break; + default: + break; + } + } - return result; + return !hasDisposalGeneration ? null : result; } private static void CheckAttributesOnMember(ISymbol member, diff --git a/tests/IDisposableGeneratorTests.CSharp10.cs b/tests/IDisposableGeneratorTests.CSharp10.cs index e329199..5ab6039 100644 --- a/tests/IDisposableGeneratorTests.CSharp10.cs +++ b/tests/IDisposableGeneratorTests.CSharp10.cs @@ -385,6 +385,7 @@ private void Dispose(bool disposing) } "} }; + await RunTest(@"// namespace MyApp; @@ -420,4 +421,61 @@ internal partial class TestDisposable } ", LanguageVersion.CSharp10, testSources, generatedSources); } + + + [Fact] + public async Task TestGenerateThrowIfDisposedCSharp10() + { + const string generatedSource = """ + // + namespace MyApp; + + internal partial class TestDisposable : IDisposable + { + private bool isDisposed; + + /// + /// Cleans up the resources used by . + /// + public void Dispose() => this.Dispose(true); + + private void Dispose(bool disposing) + { + if (!this.isDisposed && disposing) + { + this.test = null; + this.isDisposed = true; + } + } + + internal void ThrowIfDisposed() + { + if (this.isDisposed) + { + throw new ObjectDisposedException(nameof(TestDisposable)); + } + } + } + + """; + + const string testSource = """ + global using System; + global using System.ComponentModel.DataAnnotations; + global using IDisposableGenerator; + + namespace MyApp; + + [GenerateDispose(false)] + [GenerateThrowIfDisposed] + internal partial class TestDisposable + { + [NullOnDispose] + public string? test { get; set; } = "stuff here."; + } + + """; + + await RunTest(generatedSource, testSource, LanguageVersion.CSharp10); + } } diff --git a/tests/IDisposableGeneratorTests.CSharp9.cs b/tests/IDisposableGeneratorTests.CSharp9.cs index 8b8e59b..2e633b7 100644 --- a/tests/IDisposableGeneratorTests.CSharp9.cs +++ b/tests/IDisposableGeneratorTests.CSharp9.cs @@ -353,4 +353,65 @@ internal partial class TestDisposable } } "); + + [Fact] + public async Task TestGenerateThrowIfDisposedCSharp9() + { + const string generatedSource = """ + // + namespace MyApp + { + using global::System; + + internal partial class TestDisposable : IDisposable + { + private bool isDisposed; + + /// + /// Cleans up the resources used by . + /// + public void Dispose() => this.Dispose(true); + + private void Dispose(bool disposing) + { + if (!this.isDisposed && disposing) + { + this.test = null; + this.isDisposed = true; + } + } + + internal void ThrowIfDisposed() + { + if (this.isDisposed) + { + throw new ObjectDisposedException(nameof(TestDisposable)); + } + } + } + } + + """; + + const string testSource = """ + namespace MyApp + { + using System; + using System.ComponentModel.DataAnnotations; + using IDisposableGenerator; + + [GenerateDispose(false)] + [GenerateThrowIfDisposed] + internal partial class TestDisposable + { + [NullOnDispose] + [StringLength(50)] + public string? test { get; set; } = "stuff here."; + } + } + + """; + + await RunTest(generatedSource, testSource, LanguageVersion.CSharp9); + } } diff --git a/tests/IDisposableGeneratorTests.VisualBasic.cs b/tests/IDisposableGeneratorTests.VisualBasic.cs index f44036c..2cc67ca 100644 --- a/tests/IDisposableGeneratorTests.VisualBasic.cs +++ b/tests/IDisposableGeneratorTests.VisualBasic.cs @@ -411,4 +411,62 @@ Friend Partial Class TestDisposable End Class End Namespace ", null); + + [Fact] + public async Task TestGenerateThrowIfDisposedVisualBasic() + { + const string generatedSource = """ + ' + Imports System + + Namespace MyApp + + Friend Partial Class TestDisposable + Implements IDisposable + + Private isDisposed As Boolean + + ''' + ''' Cleans up the resources used by . + ''' + Public Sub Dispose() Implements IDisposable.Dispose + Me.Dispose(True) + End Sub + + Private Sub Dispose(ByVal disposing As Boolean) + If Not Me.isDisposed AndAlso disposing Then + Me.test = Nothing + Me.isDisposed = True + End If + End Sub + + Friend Sub ThrowIfDisposed() + If Me.isDisposed Then + Throw New ObjectDisposedException(NameOf(TestDisposable)) + End If + End Sub + End Class + End Namespace + + """; + + const string testSource = """ + Imports System + Imports System.ComponentModel.DataAnnotations + Imports IDisposableGenerator + + Namespace MyApp + + + Friend Partial Class TestDisposable + + + Public Property test As String = "stuff here." + End Class + End Namespace + + """; + + await RunTest(generatedSource, testSource, null); + } } From 661f05048ccc73143dba450b55cdb02278be6f85 Mon Sep 17 00:00:00 2001 From: Rekkonnect Date: Tue, 27 Feb 2024 03:23:57 +0200 Subject: [PATCH 2/3] Warning ignorance Signed-off-by: Rekkonnect --- src/IDisposableGenerator/WorkItemCollection.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/IDisposableGenerator/WorkItemCollection.cs b/src/IDisposableGenerator/WorkItemCollection.cs index 4402a81..bb94ee9 100644 --- a/src/IDisposableGenerator/WorkItemCollection.cs +++ b/src/IDisposableGenerator/WorkItemCollection.cs @@ -56,6 +56,7 @@ public int IndexOf(WorkItem item) foreach (var attr in testClass.GetAttributes()) { +#pragma warning disable IDE0010 // Add missing cases switch (attr.AttributeClass!.Name) { case "GenerateDisposeAttribute": @@ -67,12 +68,11 @@ public int IndexOf(WorkItem item) case "GenerateThrowIfDisposedAttribute": result.ThrowIfDisposed = true; break; - default: - break; } +#pragma warning restore IDE0010 // Add missing cases } - return !hasDisposalGeneration ? null : result; + return hasDisposalGeneration ? result : null; } private static void CheckAttributesOnMember(ISymbol member, From 7b8b81951abcd1e0ff2686bbb9f1c2754274aa1c Mon Sep 17 00:00:00 2001 From: Rekkonnect Date: Tue, 27 Feb 2024 18:48:46 +0200 Subject: [PATCH 3/3] Invert ThrowIfDisposed attribute role Signed-off-by: Rekkonnect --- src/IDisposableGenerator/ClassItems.cs | 4 +- .../DisposableCodeWriter.cs | 6 +- .../Properties/Resources.resx | 10 +- .../WorkItemCollection.cs | 4 +- tests/IDisposableGeneratorTests.CSharp10.cs | 93 ++++++++++++++++--- tests/IDisposableGeneratorTests.CSharp9.cs | 68 ++++++++++++-- .../IDisposableGeneratorTests.VisualBasic.cs | 52 +++++++++-- 7 files changed, 197 insertions(+), 40 deletions(-) diff --git a/src/IDisposableGenerator/ClassItems.cs b/src/IDisposableGenerator/ClassItems.cs index 777bc95..a21c35f 100644 --- a/src/IDisposableGenerator/ClassItems.cs +++ b/src/IDisposableGenerator/ClassItems.cs @@ -5,7 +5,7 @@ internal class ClassItems public string? Name { get; set; } public Accessibility Accessibility { get; set; } public bool Stream { get; set; } - public bool ThrowIfDisposed { get; set; } + public bool WithoutThrowIfDisposed { get; set; } public List Owns { get; } = []; public List Fields { get; } = []; public List SetNull { get; } = []; @@ -47,7 +47,7 @@ public override string ToString() _ = result.Append($"Class: Name {this.Name}") .Append($", Accessibility: {this.Accessibility}") .Append($", Stream: {this.Stream}") - .Append($", ThrowIfDisposed: {this.ThrowIfDisposed}") + .Append($", Without ThrowIfDisposed: {this.WithoutThrowIfDisposed}") .Append($", Owns Count: {this.Owns.Count}") .Append($", Fields Count: {this.Fields.Count}") .Append($", SetNull Count: {this.SetNull.Count}") diff --git a/src/IDisposableGenerator/DisposableCodeWriter.cs b/src/IDisposableGenerator/DisposableCodeWriter.cs index 4bacadf..1615f1c 100644 --- a/src/IDisposableGenerator/DisposableCodeWriter.cs +++ b/src/IDisposableGenerator/DisposableCodeWriter.cs @@ -106,7 +106,7 @@ End Sub """); - if (classItem.ThrowIfDisposed) + if (!classItem.WithoutThrowIfDisposed) { _ = sourceBuilder.Append($$""" @@ -233,7 +233,7 @@ namespace {workItem.Namespace}; """); - if (classItem.ThrowIfDisposed) + if (!classItem.WithoutThrowIfDisposed) { _ = sourceBuilder.Append($$""" @@ -364,7 +364,7 @@ namespace {workItem.Namespace} """); - if (classItem.ThrowIfDisposed) + if (!classItem.WithoutThrowIfDisposed) { _ = sourceBuilder.Append($$""" diff --git a/src/IDisposableGenerator/Properties/Resources.resx b/src/IDisposableGenerator/Properties/Resources.resx index 284c1f7..7c16a63 100644 --- a/src/IDisposableGenerator/Properties/Resources.resx +++ b/src/IDisposableGenerator/Properties/Resources.resx @@ -162,11 +162,12 @@ namespace IDisposableGenerator // used only by a source generator to generate Dispose() and Dispose(bool). [AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)] - internal class GenerateThrowIfDisposedAttribute : Attribute + internal class WithoutThrowIfDisposedAttribute : Attribute { } } -#pragma warning restore SA1636, 8618 +#pragma warning restore SA1636, 8618 + ' <autogenerated/> @@ -207,11 +208,12 @@ Namespace IDisposableGenerator ' used only by a source generator to generate Dispose() and Dispose(bool). <AttributeUsage(AttributeTargets.Class, Inherited:=False, AllowMultiple:=False)> - Friend Class GenerateThrowIfDisposedAttribute + Friend Class WithoutThrowIfDisposedAttribute Inherits Attribute End Class End Namespace -#Enable Warning SA1636 +#Enable Warning SA1636 + \ No newline at end of file diff --git a/src/IDisposableGenerator/WorkItemCollection.cs b/src/IDisposableGenerator/WorkItemCollection.cs index bb94ee9..bcf0d52 100644 --- a/src/IDisposableGenerator/WorkItemCollection.cs +++ b/src/IDisposableGenerator/WorkItemCollection.cs @@ -65,8 +65,8 @@ public int IndexOf(WorkItem item) result.Accessibility = testClass.DeclaredAccessibility; result.Stream = (bool)attr.ConstructorArguments[0].Value!; break; - case "GenerateThrowIfDisposedAttribute": - result.ThrowIfDisposed = true; + case "WithoutThrowIfDisposedAttribute": + result.WithoutThrowIfDisposed = true; break; } #pragma warning restore IDE0010 // Add missing cases diff --git a/tests/IDisposableGeneratorTests.CSharp10.cs b/tests/IDisposableGeneratorTests.CSharp10.cs index 5ab6039..3145737 100644 --- a/tests/IDisposableGeneratorTests.CSharp10.cs +++ b/tests/IDisposableGeneratorTests.CSharp10.cs @@ -26,6 +26,14 @@ private void Dispose(bool disposing) this.isDisposed = true; } } + + internal void ThrowIfDisposed() + { + if (this.isDisposed) + { + throw new ObjectDisposedException(nameof(TestDisposable)); + } + } } ", @"global using System; global using IDisposableGenerator; @@ -67,6 +75,14 @@ private void Dispose(bool disposing) this.isDisposed = true; } } + + internal void ThrowIfDisposed() + { + if (this.isDisposed) + { + throw new ObjectDisposedException(nameof(TestDisposable)); + } + } } ", @"global using System; global using IDisposableGenerator; @@ -113,6 +129,14 @@ private void Dispose(bool disposing) this.isDisposed = true; } } + + internal void ThrowIfDisposed() + { + if (this.isDisposed) + { + throw new ObjectDisposedException(nameof(TestDisposable)); + } + } } ", @"global using System; global using IDisposableGenerator; @@ -153,6 +177,14 @@ protected override void Dispose(bool disposing) // On Streams call base.Dispose(disposing)!!! base.Dispose(disposing); } + + internal void ThrowIfDisposed() + { + if (this.isDisposed) + { + throw new ObjectDisposedException(nameof(TestDisposable)); + } + } } ", @"global using System; global using System.IO; @@ -210,6 +242,14 @@ protected override void Dispose(bool disposing) // On Streams call base.Dispose(disposing)!!! base.Dispose(disposing); } + + internal void ThrowIfDisposed() + { + if (this.isDisposed) + { + throw new ObjectDisposedException(nameof(TestDisposable)); + } + } } ", @"global using System; global using System.IO; @@ -264,6 +304,14 @@ private void Dispose(bool disposing) this.isDisposed = true; } } + + internal void ThrowIfDisposed() + { + if (this.isDisposed) + { + throw new ObjectDisposedException(nameof(TestDisposable)); + } + } } ", @"global using System; global using IDisposableGenerator; @@ -310,6 +358,14 @@ private void Dispose(bool disposing) this.isDisposed = true; } } + + internal void ThrowIfDisposed() + { + if (this.isDisposed) + { + throw new ObjectDisposedException(nameof(TestDisposable)); + } + } } ", @"global using System; global using System.ComponentModel.DataAnnotations; @@ -361,6 +417,14 @@ private void Dispose(bool disposing) this.isDisposed = true; } } + + internal void ThrowIfDisposed() + { + if (this.isDisposed) + { + throw new ObjectDisposedException(nameof(TestDisposable)); + } + } } "}, {"Disposables.1.g.cs", @"// @@ -382,6 +446,14 @@ private void Dispose(bool disposing) this.isDisposed = true; } } + + internal void ThrowIfDisposed() + { + if (this.isDisposed) + { + throw new ObjectDisposedException(nameof(AnotherDisposable)); + } + } } "} }; @@ -406,6 +478,14 @@ private void Dispose(bool disposing) this.isDisposed = true; } } + + internal void ThrowIfDisposed() + { + if (this.isDisposed) + { + throw new ObjectDisposedException(nameof(TestDisposable)); + } + } } ", @"global using System; global using System.ComponentModel.DataAnnotations; @@ -422,9 +502,8 @@ internal partial class TestDisposable ", LanguageVersion.CSharp10, testSources, generatedSources); } - [Fact] - public async Task TestGenerateThrowIfDisposedCSharp10() + public async Task TestWithoutThrowIfDisposedCSharp10() { const string generatedSource = """ // @@ -447,14 +526,6 @@ private void Dispose(bool disposing) this.isDisposed = true; } } - - internal void ThrowIfDisposed() - { - if (this.isDisposed) - { - throw new ObjectDisposedException(nameof(TestDisposable)); - } - } } """; @@ -467,7 +538,7 @@ internal void ThrowIfDisposed() namespace MyApp; [GenerateDispose(false)] - [GenerateThrowIfDisposed] + [WithoutThrowIfDisposed] internal partial class TestDisposable { [NullOnDispose] diff --git a/tests/IDisposableGeneratorTests.CSharp9.cs b/tests/IDisposableGeneratorTests.CSharp9.cs index 2e633b7..5633342 100644 --- a/tests/IDisposableGeneratorTests.CSharp9.cs +++ b/tests/IDisposableGeneratorTests.CSharp9.cs @@ -28,6 +28,14 @@ private void Dispose(bool disposing) this.isDisposed = true; } } + + internal void ThrowIfDisposed() + { + if (this.isDisposed) + { + throw new ObjectDisposedException(nameof(TestDisposable)); + } + } } } ", @"namespace MyApp @@ -73,6 +81,14 @@ private void Dispose(bool disposing) this.isDisposed = true; } } + + internal void ThrowIfDisposed() + { + if (this.isDisposed) + { + throw new ObjectDisposedException(nameof(TestDisposable)); + } + } } } ", @"namespace MyApp @@ -123,6 +139,14 @@ private void Dispose(bool disposing) this.isDisposed = true; } } + + internal void ThrowIfDisposed() + { + if (this.isDisposed) + { + throw new ObjectDisposedException(nameof(TestDisposable)); + } + } } } ", @"namespace MyApp @@ -167,6 +191,14 @@ protected override void Dispose(bool disposing) // On Streams call base.Dispose(disposing)!!! base.Dispose(disposing); } + + internal void ThrowIfDisposed() + { + if (this.isDisposed) + { + throw new ObjectDisposedException(nameof(TestDisposable)); + } + } } } ", @"namespace MyApp @@ -228,6 +260,14 @@ protected override void Dispose(bool disposing) // On Streams call base.Dispose(disposing)!!! base.Dispose(disposing); } + + internal void ThrowIfDisposed() + { + if (this.isDisposed) + { + throw new ObjectDisposedException(nameof(TestDisposable)); + } + } } } ", @"namespace MyApp @@ -286,6 +326,14 @@ private void Dispose(bool disposing) this.isDisposed = true; } } + + internal void ThrowIfDisposed() + { + if (this.isDisposed) + { + throw new ObjectDisposedException(nameof(TestDisposable)); + } + } } } ", @"namespace MyApp @@ -336,6 +384,14 @@ private void Dispose(bool disposing) this.isDisposed = true; } } + + internal void ThrowIfDisposed() + { + if (this.isDisposed) + { + throw new ObjectDisposedException(nameof(TestDisposable)); + } + } } } ", @"namespace MyApp @@ -355,7 +411,7 @@ internal partial class TestDisposable "); [Fact] - public async Task TestGenerateThrowIfDisposedCSharp9() + public async Task TestWithoutThrowIfDisposedCSharp9() { const string generatedSource = """ // @@ -380,14 +436,6 @@ private void Dispose(bool disposing) this.isDisposed = true; } } - - internal void ThrowIfDisposed() - { - if (this.isDisposed) - { - throw new ObjectDisposedException(nameof(TestDisposable)); - } - } } } @@ -401,7 +449,7 @@ namespace MyApp using IDisposableGenerator; [GenerateDispose(false)] - [GenerateThrowIfDisposed] + [WithoutThrowIfDisposed] internal partial class TestDisposable { [NullOnDispose] diff --git a/tests/IDisposableGeneratorTests.VisualBasic.cs b/tests/IDisposableGeneratorTests.VisualBasic.cs index 2cc67ca..c9b9a4a 100644 --- a/tests/IDisposableGeneratorTests.VisualBasic.cs +++ b/tests/IDisposableGeneratorTests.VisualBasic.cs @@ -29,6 +29,12 @@ If Not Me.isDisposed AndAlso disposing Then Me.isDisposed = True End If End Sub + + Friend Sub ThrowIfDisposed() + If Me.isDisposed Then + Throw New ObjectDisposedException(NameOf(TestDisposable)) + End If + End Sub End Class End Namespace ", @"Imports System @@ -74,6 +80,12 @@ If Not Me.isDisposed AndAlso disposing Then Me.isDisposed = True End If End Sub + + Friend Sub ThrowIfDisposed() + If Me.isDisposed Then + Throw New ObjectDisposedException(NameOf(TestDisposable)) + End If + End Sub End Class End Namespace ", @"Imports System @@ -123,6 +135,12 @@ End If Me.isDisposed = True End If End Sub + + Friend Sub ThrowIfDisposed() + If Me.isDisposed Then + Throw New ObjectDisposedException(NameOf(TestDisposable)) + End If + End Sub End Class End Namespace ", @"Imports System @@ -163,6 +181,12 @@ End If ' On Streams call MyBase.Dispose(disposing)!!! MyBase.Dispose(disposing) End Sub + + Friend Sub ThrowIfDisposed() + If Me.isDisposed Then + Throw New ObjectDisposedException(NameOf(TestDisposable)) + End If + End Sub End Class End Namespace ", @"Imports System @@ -254,6 +278,12 @@ End If ' On Streams call MyBase.Dispose(disposing)!!! MyBase.Dispose(disposing) End Sub + + Friend Sub ThrowIfDisposed() + If Me.isDisposed Then + Throw New ObjectDisposedException(NameOf(TestDisposable)) + End If + End Sub End Class End Namespace ", @"Imports System @@ -347,6 +377,12 @@ If Not Me.isDisposed AndAlso disposing Then Me.isDisposed = True End If End Sub + + Friend Sub ThrowIfDisposed() + If Me.isDisposed Then + Throw New ObjectDisposedException(NameOf(TestDisposable)) + End If + End Sub End Class End Namespace ", @"Imports System @@ -395,6 +431,12 @@ If Not Me.isDisposed AndAlso disposing Then Me.isDisposed = True End If End Sub + + Friend Sub ThrowIfDisposed() + If Me.isDisposed Then + Throw New ObjectDisposedException(NameOf(TestDisposable)) + End If + End Sub End Class End Namespace ", @"Imports System @@ -413,7 +455,7 @@ End Namespace ", null); [Fact] - public async Task TestGenerateThrowIfDisposedVisualBasic() + public async Task TestWithoutThrowIfDisposedVisualBasic() { const string generatedSource = """ ' @@ -439,12 +481,6 @@ If Not Me.isDisposed AndAlso disposing Then Me.isDisposed = True End If End Sub - - Friend Sub ThrowIfDisposed() - If Me.isDisposed Then - Throw New ObjectDisposedException(NameOf(TestDisposable)) - End If - End Sub End Class End Namespace @@ -457,7 +493,7 @@ Imports IDisposableGenerator Namespace MyApp - + Friend Partial Class TestDisposable