diff --git a/.editorconfig b/.editorconfig
index 092893b6..52af9e73 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -234,25 +234,32 @@ dotnet_diagnostic.IDE1006.severity = none # These words must begin with up
# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/quality-rules/?view=vs-2022
[*.{cs,vb}]
-dotnet_diagnostic.CA1507.severity = error # Use nameof in place of string
-dotnet_diagnostic.CS1573.severity = silent # Parameter has no matching param tag in the XML comment (but other parameters do). Justification: Don't require unneccessary comments. Only add comments for parameters that need clairification.
-dotnet_diagnostic.CA1508.severity = warning # Avoid dead conditional code
-dotnet_diagnostic.CA1700.severity = error # Do not name enum values 'Reserved'
-dotnet_diagnostic.CA1707.severity = warning # Identifiers should not contain underscores
-dotnet_diagnostic.CA1708.severity = error # Identifiers should differ by more than case
-dotnet_diagnostic.CA1710.severity = error # Identifiers should have correct suffix
-dotnet_diagnostic.CA1712.severity = error # Do not prefix enum values with type name
-dotnet_diagnostic.CA1720.severity = error # Identifiers should not contain type names
-dotnet_diagnostic.CA1802.severity = error # Use Literals Where Appropriate
-dotnet_diagnostic.CA1805.severity = warning # Do not initialize unnecessarily
-dotnet_diagnostic.CA1810.severity = error # Initialize reference type static fields inline
-dotnet_diagnostic.CA1821.severity = error # Remove empty finalizers
-dotnet_diagnostic.CA1822.severity = warning # Mark members as static
-dotnet_diagnostic.CA1823.severity = warning # Avoid unused private fields
-dotnet_diagnostic.CA1826.severity = warning # Use property instead of Linq Enumerable method
-dotnet_diagnostic.CA1827.severity = warning # Do not use Count()/LongCount() when Any() can be used
-dotnet_diagnostic.CA1849.severity = warning # Call async methods when in an async method
-dotnet_diagnostic.CA2000.severity = warning # Dispose objects before losing scope
+dotnet_diagnostic.CA1031.severity = error # Do not catch general exception types
+dotnet_diagnostic.CA1063.severity = error # Implement IDisposable correctly
+dotnet_diagnostic.CA1001.severity = error # Types that own disposable fields should be disposable
+dotnet_diagnostic.CA1507.severity = error # Use nameof in place of string
+dotnet_diagnostic.CS1573.severity = silent # Parameter has no matching param tag in the XML comment (but other parameters do). Justification: Don't require unneccessary comments. Only add comments for parameters that need clairification.
+dotnet_diagnostic.CA1508.severity = warning # Avoid dead conditional code
+dotnet_diagnostic.CA1700.severity = error # Do not name enum values 'Reserved'
+dotnet_diagnostic.CA1707.severity = warning # Identifiers should not contain underscores
+dotnet_diagnostic.CA1708.severity = error # Identifiers should differ by more than case
+dotnet_diagnostic.CA1710.severity = error # Identifiers should have correct suffix
+dotnet_diagnostic.CA1712.severity = error # Do not prefix enum values with type name
+dotnet_diagnostic.CA1720.severity = error # Identifiers should not contain type names
+dotnet_diagnostic.CA1802.severity = error # Use Literals Where Appropriate
+dotnet_diagnostic.CA1805.severity = warning # Do not initialize unnecessarily
+dotnet_diagnostic.CA1810.severity = error # Initialize reference type static fields inline
+dotnet_diagnostic.CA1816.severity = error # Call GC.SuppressFinalize correctly
+dotnet_diagnostic.CA1821.severity = error # Remove empty finalizers
+dotnet_diagnostic.CA1822.severity = warning # Mark members as static
+dotnet_diagnostic.CA1823.severity = warning # Avoid unused private fields
+dotnet_diagnostic.CA1826.severity = warning # Use property instead of Linq Enumerable method
+dotnet_diagnostic.CA1827.severity = warning # Do not use Count()/LongCount() when Any() can be used
+dotnet_diagnostic.CA1849.severity = warning # Call async methods when in an async method
+dotnet_diagnostic.CA2000.severity = error # Dispose objects before losing scope
+dotnet_diagnostic.CA2213.severity = error # Disposable fields should be disposed
+dotnet_diagnostic.CA2215.severity = error # Dispose methods should call base class dispose
+dotnet_diagnostic.CA2216.severity = warning # Disposable types should declare finalizer
# *****************************************
diff --git a/samples/MauiMsApp/CreatePage.xaml.cs b/samples/MauiMsApp/CreatePage.xaml.cs
index 77a572ed..acef00f4 100644
--- a/samples/MauiMsApp/CreatePage.xaml.cs
+++ b/samples/MauiMsApp/CreatePage.xaml.cs
@@ -1,7 +1,6 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
-using Microsoft.PowerPlatform.PowerApps.Persistence.MsApp;
using MSAppGenerator;
namespace MauiMsApp;
@@ -13,9 +12,8 @@ public CreatePage()
InitializeComponent();
}
-#pragma warning disable CA1822 // Mark members as static
+ [System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1031:Do not catch general exception types", Justification = "REVIEW")]
private async void OnCreateClicked(object sender, EventArgs e)
-#pragma warning restore CA1822 // Mark members as static
{
try
{
diff --git a/samples/MauiMsApp/MainPage.xaml.cs b/samples/MauiMsApp/MainPage.xaml.cs
index 3106995b..aa8d5427 100644
--- a/samples/MauiMsApp/MainPage.xaml.cs
+++ b/samples/MauiMsApp/MainPage.xaml.cs
@@ -12,9 +12,8 @@ public MainPage()
InitializeComponent();
}
-#pragma warning disable CA1822 // Mark members as static
+ [System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1031:Do not catch general exception types", Justification = "REVIEW")]
private async void OnOpenClicked(object sender, EventArgs e)
-#pragma warning restore CA1822 // Mark members as static
{
try
{
diff --git a/samples/Test.AppWriter/InputProcessor.cs b/samples/Test.AppWriter/InputProcessor.cs
index 01089709..9dcdfc0e 100644
--- a/samples/Test.AppWriter/InputProcessor.cs
+++ b/samples/Test.AppWriter/InputProcessor.cs
@@ -43,6 +43,7 @@ private static bool ValidateFilePath(string filePath, out string error)
///
/// Function to bind to the Create command and call App Creation code
///
+ [System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1031:Do not catch general exception types", Justification = "REVIEW")]
private static void CreateFunction(bool interactive, string fullPathToMsApp, int numScreens, IList? controlsinfo)
{
var creator = new AppCreator();
diff --git a/src/PAModel/ControlTemplates/ControlTemplateParser.cs b/src/PAModel/ControlTemplates/ControlTemplateParser.cs
index 744d850c..bc3d4ffa 100644
--- a/src/PAModel/ControlTemplates/ControlTemplateParser.cs
+++ b/src/PAModel/ControlTemplates/ControlTemplateParser.cs
@@ -12,6 +12,7 @@ internal class ControlTemplateParser
{
internal static Regex _reservedIdentifierRegex = new(@"%([a-zA-Z]*)\.RESERVED%");
+ [System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1031:Do not catch general exception types", Justification = "")]
internal static bool TryParseTemplate(TemplateStore templateStore, string templateString, AppType type, Dictionary loadedTemplates, out ControlTemplate template, out string name)
{
template = null;
diff --git a/src/PAModel/MsAppTest.cs b/src/PAModel/MsAppTest.cs
index 81d13e15..1d5a0181 100644
--- a/src/PAModel/MsAppTest.cs
+++ b/src/PAModel/MsAppTest.cs
@@ -25,6 +25,7 @@ public static bool Compare(CanvasDocument doc1, CanvasDocument doc2, TextWriter
}
}
+ [System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1031:Do not catch general exception types", Justification = "")]
public static bool MergeStressTest(string pathToMsApp1, string pathToMsApp2)
{
try
@@ -142,6 +143,7 @@ public static CanvasDocument RemoveEntropy(string pathToMsApp)
}
// Given an msapp (original source of truth), stress test the conversions
+ [System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1031:Do not catch general exception types", Justification = "")]
public static bool StressTest(string pathToMsApp)
{
try
@@ -283,7 +285,7 @@ public static void CompareChecksums(string pathToZip, TextWriter log, Dictionary
JsonDocument.Parse(originalContents);
JsonDocument.Parse(newContents);
}
- catch
+ catch (JsonException)
{
isJson = false;
}
diff --git a/src/PAModel/PAConvert/Parser/Parser.cs b/src/PAModel/PAConvert/Parser/Parser.cs
index 9a9e64b9..0978f55b 100644
--- a/src/PAModel/PAConvert/Parser/Parser.cs
+++ b/src/PAModel/PAConvert/Parser/Parser.cs
@@ -9,11 +9,12 @@
namespace Microsoft.PowerPlatform.Formulas.Tools.Parser;
-internal class Parser
+internal class Parser : IDisposable
{
public readonly ErrorContainer _errorContainer;
private readonly YamlLexer _yaml;
+ private bool _isDisposed;
public Parser(string fileName, string contents, ErrorContainer errors)
{
@@ -345,4 +346,24 @@ private static bool IsControlStart(string line)
line = line.Substring(length).TrimStart();
return line.StartsWith("As");
}
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (!_isDisposed)
+ {
+ if (disposing)
+ {
+ _yaml.Dispose();
+ }
+
+ _isDisposed = true;
+ }
+ }
+
+ public void Dispose()
+ {
+ // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
+ Dispose(disposing: true);
+ GC.SuppressFinalize(this);
+ }
}
diff --git a/src/PAModel/PAConvert/Yaml/YamlLexer.cs b/src/PAModel/PAConvert/Yaml/YamlLexer.cs
index 0434fda0..d0056a04 100644
--- a/src/PAModel/PAConvert/Yaml/YamlLexer.cs
+++ b/src/PAModel/PAConvert/Yaml/YamlLexer.cs
@@ -651,7 +651,7 @@ protected virtual void Dispose(bool disposing)
{
if (disposing)
{
- _reader?.Dispose();
+ _reader.Dispose();
}
_isDisposed = true;
diff --git a/src/PAModel/Serializers/MsAppSerializer.cs b/src/PAModel/Serializers/MsAppSerializer.cs
index 4daa10b0..59140215 100644
--- a/src/PAModel/Serializers/MsAppSerializer.cs
+++ b/src/PAModel/Serializers/MsAppSerializer.cs
@@ -80,6 +80,7 @@ public static CanvasDocument Load(Stream streamToMsapp, ErrorContainer errors)
var screenOrder = new Dictionary();
ZipArchive zipOpen;
+#pragma warning disable CA1031 // Do not catch general exception types
try
{
#pragma warning disable CA2000 // Dispose objects before losing scope
@@ -92,6 +93,7 @@ public static CanvasDocument Load(Stream streamToMsapp, ErrorContainer errors)
errors.MsAppFormatError(e.Message);
return null;
}
+#pragma warning restore CA1031 // Do not catch general exception types
using (var z = zipOpen)
{
diff --git a/src/PAModel/Serializers/SourceSerializer.cs b/src/PAModel/Serializers/SourceSerializer.cs
index ac24c671..a92bf0de 100644
--- a/src/PAModel/Serializers/SourceSerializer.cs
+++ b/src/PAModel/Serializers/SourceSerializer.cs
@@ -479,7 +479,7 @@ private static void AddControl(CanvasDocument app, string filePath, bool isCompo
_ = Path.GetFileName(filePath);
try
{
- var parser = new Parser.Parser(filePath, fileContents, errors);
+ using var parser = new Parser.Parser(filePath, fileContents, errors);
var controlIR = parser.ParseControl(isComponent);
if (controlIR == null)
{
@@ -1061,6 +1061,7 @@ private static void AddDefaultTheme(CanvasDocument app)
private static BuildVerJson GetBuildDetails()
{
+#pragma warning disable CA1031 // Do not catch general exception types
try
{
var assembly = Assembly.GetExecutingAssembly();
@@ -1078,6 +1079,7 @@ private static BuildVerJson GetBuildDetails()
{
return null;
}
+#pragma warning restore CA1031 // Do not catch general exception types
}
///
diff --git a/src/PAModelTests/RoundtripTests.cs b/src/PAModelTests/RoundtripTests.cs
index 301a4102..297f0df7 100644
--- a/src/PAModelTests/RoundtripTests.cs
+++ b/src/PAModelTests/RoundtripTests.cs
@@ -2,7 +2,7 @@
// Licensed under the MIT License.
using System.IO;
-using System.Threading.Tasks;
+using System.Linq;
using Microsoft.PowerPlatform.Formulas.Tools;
namespace PAModelTests;
@@ -11,27 +11,16 @@ namespace PAModelTests;
[TestClass]
public class RoundtripTests
{
+ private static IEnumerable