diff --git a/src/.idea/.idea.PASopa/.idea/.gitignore b/src/.idea/.idea.PASopa/.idea/.gitignore
new file mode 100644
index 00000000..c3770630
--- /dev/null
+++ b/src/.idea/.idea.PASopa/.idea/.gitignore
@@ -0,0 +1,13 @@
+# Default ignored files
+/shelf/
+/workspace.xml
+# Rider ignored files
+/modules.xml
+/projectSettingsUpdater.xml
+/contentModel.xml
+/.idea.PASopa.iml
+# Editor-based HTTP Client requests
+/httpRequests/
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml
diff --git a/src/.idea/.idea.PASopa/.idea/.name b/src/.idea/.idea.PASopa/.idea/.name
new file mode 100644
index 00000000..8772a5ab
--- /dev/null
+++ b/src/.idea/.idea.PASopa/.idea/.name
@@ -0,0 +1 @@
+PASopa
\ No newline at end of file
diff --git a/src/.idea/.idea.PASopa/.idea/indexLayout.xml b/src/.idea/.idea.PASopa/.idea/indexLayout.xml
new file mode 100644
index 00000000..7b08163c
--- /dev/null
+++ b/src/.idea/.idea.PASopa/.idea/indexLayout.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/.idea/.idea.PASopa/.idea/vcs.xml b/src/.idea/.idea.PASopa/.idea/vcs.xml
new file mode 100644
index 00000000..6c0b8635
--- /dev/null
+++ b/src/.idea/.idea.PASopa/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/PAModel/CanvasDocument.cs b/src/PAModel/CanvasDocument.cs
index d2d4fcd5..43454947 100644
--- a/src/PAModel/CanvasDocument.cs
+++ b/src/PAModel/CanvasDocument.cs
@@ -16,22 +16,22 @@
namespace Microsoft.PowerPlatform.Formulas.Tools;
///
-/// Represents a PowerApps document. This can be save/loaded from a MsApp or Source representation.
-/// This is a full in-memory representation of the msapp file.
+/// Represents a PowerApps document. This can be save/loaded from a MsApp or Source representation.
+/// This is a full in-memory representation of the msapp file.
///
public class CanvasDocument
{
///
- /// Current source format version.
+ /// Current source format version.
///
public static Version CurrentSourceVersion => SourceSerializer.CurrentSourceVersion;
// Rules for CanvasDocument
- // - Save/Load must faithfully roundtrip an msapp exactly.
- // - this is an in-memory representation - so it must parse/shard everything on load.
- // - Save should not mutate any state.
+ // - Save/Load must faithfully roundtrip an msapp exactly.
+ // - this is an in-memory representation - so it must parse/shard everything on load.
+ // - Save should not mutate any state.
- // Track all unknown "files". Ensures round-tripping isn't lossy.
+ // Track all unknown "files". Ensures round-tripping isn't lossy.
// Only contains files of FileKind.Unknown
internal Dictionary _unknownFiles = new();
@@ -42,7 +42,7 @@ public class CanvasDocument
internal EditorStateStore _editorStateStore;
internal TemplateStore _templateStore;
- // Various data sources
+ // Various data sources
// This is references\dataSources.json
// Also includes entries for DataSources made from a DataComponent
// Key is parent entity name (datasource name for non cds data sources)
@@ -76,7 +76,7 @@ public class CanvasDocument
internal IDictionary _dataSourceReferences;
// Extracted from _properties.LibraryDependencies
- // Must preserve server ordering.
+ // Must preserve server ordering.
internal ComponentDependencyInfo[] _libraryReferences;
internal FileEntry _logoFile;
@@ -84,7 +84,7 @@ public class CanvasDocument
// Save for roundtripping.
internal Entropy _entropy = new();
- // Checksum from existing msapp.
+ // Checksum from existing msapp.
internal ChecksumJson _checksum;
// Track all asset files, key is file name
@@ -102,7 +102,7 @@ public class CanvasDocument
#region Save/Load
///
- /// Load an .msapp file for a Canvas Document.
+ /// Load an .msapp file for a Canvas Document.
///
/// path to an .msapp file
/// A tuple of the document and errors and warnings. If there are errors, the document is null.
@@ -218,7 +218,7 @@ public static (CanvasDocument, ErrorContainer) MakeFromSources(string appName, s
#endregion
- // Wrapper to ensure consistent invariants between loading a document, exception handling, and returning errors.
+ // Wrapper to ensure consistent invariants between loading a document, exception handling, and returning errors.
private static CanvasDocument Wrapper(Func worker, ErrorContainer errors)
{
try
@@ -320,7 +320,7 @@ internal CanvasDocument(CanvasDocument other)
_localAssetInfoJson = other._localAssetInfoJson.JsonClone();
}
- // iOrder is used to preserve ordering value for round-tripping.
+ // iOrder is used to preserve ordering value for round-tripping.
internal void AddDataSourceForLoad(DataSourceEntry ds, int? order = null)
{
// Key is parent entity name
@@ -376,7 +376,7 @@ internal void ApplyAfterMsAppLoadTransforms(ErrorContainer errors)
var componentInstanceTransform = new ComponentInstanceTransform(errors);
var componentDefTransform = new ComponentDefinitionTransform(errors, _templateStore, componentInstanceTransform);
- // Transform component definitions and populate template set of component instances that need updates
+ // Transform component definitions and populate template set of component instances that need updates
foreach (var ctrl in _components)
{
AddComponentDefaults(ctrl.Value, templateDefaults);
@@ -433,7 +433,7 @@ internal void ApplyBeforeMsAppWriteTransforms(ErrorContainer errors)
var componentInstanceTransform = new ComponentInstanceTransform(errors);
var componentDefTransform = new ComponentDefinitionTransform(errors, _templateStore, componentInstanceTransform);
- // Transform component definitions and populate template set of component instances that need updates
+ // Transform component definitions and populate template set of component instances that need updates
foreach (var ctrl in _components)
{
componentDefTransform.BeforeWrite(ctrl.Value);
@@ -466,10 +466,10 @@ private void AddComponentDefaults(BlockNode topParent, Dictionary GetImportedComponents()
{
var set = new HashSet();
@@ -679,21 +679,15 @@ private void RestoreAssetFilePaths(ErrorContainer errors)
}
}
- // Helper for traversing and ensuring unique control names.
- internal class UniqueControlNameVisitor
+ // Helper for traversing and ensuring unique control names.
+ internal class UniqueControlNameVisitor(ErrorContainer errors)
{
- // Control names are case sensitive.
+ // Control names are case sensitive.
private readonly Dictionary _names = new(StringComparer.Ordinal);
- private readonly ErrorContainer _errors;
-
- public UniqueControlNameVisitor(ErrorContainer errors)
- {
- _errors = errors;
- }
public void Visit(BlockNode node)
{
- // Ignore test templates here.
+ // Ignore test templates here.
// Test templates have control-like syntax, but allowed to repeat names:
// Step4 As TestStep:
if (AppTestTransform.IsTestSuite(node.Name.Kind.TypeName))
@@ -712,7 +706,7 @@ public void Visit(TypedNameNode node)
{
if (_names.TryGetValue(node.Identifier, out var existing))
{
- _errors.DuplicateSymbolError(node.SourceSpan.GetValueOrDefault(), node.Identifier, existing.GetValueOrDefault());
+ errors.DuplicateSymbolError(node.SourceSpan.GetValueOrDefault(), node.Identifier, existing.GetValueOrDefault());
}
else
{
diff --git a/src/PAModel/Checksum/IHashMaker.cs b/src/PAModel/Checksum/IHashMaker.cs
index 6d4c4d78..2b9285cb 100644
--- a/src/PAModel/Checksum/IHashMaker.cs
+++ b/src/PAModel/Checksum/IHashMaker.cs
@@ -10,7 +10,7 @@
namespace Microsoft.PowerPlatform.Formulas.Tools;
-// Helpers for creating checksums.
+// Helpers for creating checksums.
internal interface IHashMaker : IDisposable
{
void AppendStartObj();
@@ -24,11 +24,11 @@ internal interface IHashMaker : IDisposable
void AppendData(bool value);
void AppendNull();
- // Called after all Appends().
+ // Called after all Appends().
byte[] GetFinalValue();
}
-// Create a checksum using an incremental hash.
+// Create a checksum using an incremental hash.
internal class Sha256HashMaker : IHashMaker, IDisposable
{
private readonly IncrementalHash _hash;
@@ -37,11 +37,11 @@ internal class Sha256HashMaker : IHashMaker, IDisposable
private static readonly byte[] _endObj = "}"u8.ToArray();
private static readonly byte[] _startArray = "["u8.ToArray();
private static readonly byte[] _endArray = "]"u8.ToArray();
- private static readonly byte[] _null = new byte[] { 254 };
- private static readonly byte[] _true = new byte[] { 1 };
- private static readonly byte[] _false = new byte[] { 0 };
+ private static readonly byte[] _null = [254];
+ private static readonly byte[] _true = [1];
+ private static readonly byte[] _false = [0];
- private static readonly byte[] _marker = new byte[] { 255 };
+ private static readonly byte[] _marker = [255];
public Sha256HashMaker()
{
@@ -120,7 +120,7 @@ public byte[] GetFinalValue()
// A debug version of the checksum maker that captures the full raw normalized input.
-// If a checksum doesn't match, re-run it with this algorithm and you can see and diff the raw inputs.
+// If a checksum doesn't match, re-run it with this algorithm and you can see and diff the raw inputs.
internal class DebugTextHashMaker : IHashMaker
{
private readonly Utf8JsonWriter _writer;
diff --git a/src/PAModel/Collections/LazyList.cs b/src/PAModel/Collections/LazyList.cs
index bf656b50..668c6994 100644
--- a/src/PAModel/Collections/LazyList.cs
+++ b/src/PAModel/Collections/LazyList.cs
@@ -16,7 +16,7 @@ internal class LazyList : IEnumerable
{
private readonly IEnumerable values;
- public static readonly LazyList Empty = new(Enumerable.Empty());
+ public static readonly LazyList Empty = new([]);
public LazyList(IEnumerable values)
{
diff --git a/src/PAModel/ControlTemplates/ControlProperty.cs b/src/PAModel/ControlTemplates/ControlProperty.cs
index 492ea49d..f71e2167 100644
--- a/src/PAModel/ControlTemplates/ControlProperty.cs
+++ b/src/PAModel/ControlTemplates/ControlProperty.cs
@@ -5,20 +5,12 @@
namespace Microsoft.PowerPlatform.Formulas.Tools.ControlTemplates;
-internal sealed class ControlProperty
+internal sealed class ControlProperty(string name, string defaultVal, string phoneDefault, string webDefault)
{
- public string Name { get; }
- public string DefaultValue { get; }
- public string PhoneDefaultValue { get; }
- public string WebDefaultValue { get; }
-
- public ControlProperty(string name, string defaultVal, string phoneDefault, string webDefault)
- {
- Name = name;
- DefaultValue = defaultVal;
- PhoneDefaultValue = phoneDefault;
- WebDefaultValue = webDefault;
- }
+ public string Name { get; } = name;
+ public string DefaultValue { get; } = defaultVal;
+ public string PhoneDefaultValue { get; } = phoneDefault;
+ public string WebDefaultValue { get; } = webDefault;
public string GetDefaultValue(AppType type)
{
diff --git a/src/PAModel/ControlTemplates/ControlTemplate.cs b/src/PAModel/ControlTemplates/ControlTemplate.cs
index 6802b05b..29b6b114 100644
--- a/src/PAModel/ControlTemplates/ControlTemplate.cs
+++ b/src/PAModel/ControlTemplates/ControlTemplate.cs
@@ -3,24 +3,15 @@
namespace Microsoft.PowerPlatform.Formulas.Tools.ControlTemplates;
-internal sealed class ControlTemplate
+internal sealed class ControlTemplate(string name, string version, string id)
{
- public string Name { get; }
- public string Version { get; }
- public string Id { get; }
+ public string Name { get; } = name;
+ public string Version { get; } = version;
+ public string Id { get; } = id;
// Property Name -> Default Expression
- public Dictionary InputDefaults { get; }
+ public Dictionary InputDefaults { get; } = new();
// Variant name => property name => default expresion
- public Dictionary> VariantDefaultValues { get; }
-
- public ControlTemplate(string name, string version, string id)
- {
- Name = name;
- Version = version;
- Id = id;
- InputDefaults = new Dictionary();
- VariantDefaultValues = new Dictionary>();
- }
+ public Dictionary> VariantDefaultValues { get; } = new();
}
diff --git a/src/PAModel/Entropy.cs b/src/PAModel/Entropy.cs
index 09a7dff7..e12d2b05 100644
--- a/src/PAModel/Entropy.cs
+++ b/src/PAModel/Entropy.cs
@@ -192,7 +192,7 @@ public static string GetResourcesJsonIndicesKey(ResourceJson resource)
// Removing the 'ContentKind-' gives the resource name
public static string GetResourceNameFromKey(string key)
{
- var prefix = key.Split(new char[] { '-' }).First();
+ var prefix = key.Split(['-']).First();
return key.Substring(prefix.Length + 1);
}
diff --git a/src/PAModel/Extensions/CollectionsExtensions.cs b/src/PAModel/Extensions/CollectionsExtensions.cs
index 4b8d34d6..a6a580d7 100644
--- a/src/PAModel/Extensions/CollectionsExtensions.cs
+++ b/src/PAModel/Extensions/CollectionsExtensions.cs
@@ -16,7 +16,7 @@ public static void Add(this Stack stack, T item)
public static IEnumerable NullOk(this IEnumerable list)
{
- if (list == null) return Enumerable.Empty();
+ if (list == null) return [];
return list;
}
diff --git a/src/PAModel/IO/ControlPath.cs b/src/PAModel/IO/ControlPath.cs
index 0975588a..ffb39796 100644
--- a/src/PAModel/IO/ControlPath.cs
+++ b/src/PAModel/IO/ControlPath.cs
@@ -10,10 +10,10 @@ namespace Microsoft.PowerPlatform.Formulas.Tools.IO;
/// Each segment is a control name
///
[DebuggerDisplay("{string.Join('.', _segments)}")]
-internal class ControlPath
+internal class ControlPath(List segments)
{
// switch this to be a queue?
- private readonly List _segments;
+ private readonly List _segments = segments;
public string Current => _segments.Any() ? _segments[0] : null;
public static ControlPath Empty => new(new List());
@@ -36,11 +36,6 @@ public ControlPath Append(string controlName)
return new ControlPath(newPath);
}
- public ControlPath(List segments)
- {
- _segments = segments;
- }
-
public static bool operator ==(ControlPath left, ControlPath right)
{
return left?.Equals(right) ?? right is null;
diff --git a/src/PAModel/IO/DirectoryReader.cs b/src/PAModel/IO/DirectoryReader.cs
index b73947d7..cdb21200 100644
--- a/src/PAModel/IO/DirectoryReader.cs
+++ b/src/PAModel/IO/DirectoryReader.cs
@@ -11,51 +11,38 @@
namespace Microsoft.PowerPlatform.Formulas.Tools.IO;
///
-/// Abstraction over file system.
+/// Abstraction over file system.
/// Helps organize full path, relative paths
///
-internal class DirectoryReader
+internal class DirectoryReader(string directory)
{
- private readonly string _directory;
-
- public DirectoryReader(string directory)
- {
- _directory = directory;
- }
-
- // A file that can be read.
- public class Entry
+ // A file that can be read.
+ public class Entry(string fullPath)
{
- private readonly string _fullpath;
public FileKind Kind;
internal string _relativeName;
- public Entry(string fullPath)
- {
- _fullpath = fullPath;
- }
-
- public SourceLocation SourceSpan => SourceLocation.FromFile(_fullpath);
+ public SourceLocation SourceSpan => SourceLocation.FromFile(fullPath);
- // FileEntry is the same structure we get back from a Zip file.
+ // FileEntry is the same structure we get back from a Zip file.
public FileEntry ToFileEntry()
{
// Some paths mistakenly start with DirectorySepChar in the msapp,
- // We replaced it with `_/` when writing, remove that now.
+ // We replaced it with `_/` when writing, remove that now.
if (_relativeName.StartsWith(FileEntry.FilenameLeadingUnderscore.ToString()))
_relativeName = _relativeName.TrimStart(FileEntry.FilenameLeadingUnderscore);
return new FileEntry
{
Name = FilePath.FromPlatformPath(_relativeName),
- RawBytes = File.ReadAllBytes(_fullpath)
+ RawBytes = File.ReadAllBytes(fullPath)
};
}
public T ToObject()
{
- if (FilePath.IsYamlFile(_fullpath))
+ if (FilePath.IsYamlFile(fullPath))
{
- using (var textReader = new StreamReader(_fullpath))
+ using (var textReader = new StreamReader(fullPath))
{
var obj = YamlPocoSerializer.Read(textReader);
return obj;
@@ -63,25 +50,25 @@ public T ToObject()
}
else
{
- var str = File.ReadAllText(_fullpath);
+ var str = File.ReadAllText(fullPath);
return JsonSerializer.Deserialize(str, JsonExtensions._jsonOpts);
}
}
public string GetContents()
{
- return File.ReadAllText(_fullpath);
+ return File.ReadAllText(fullPath);
}
}
- // Returns file entries.
+ // Returns file entries.
public Entry[] EnumerateFiles(string subdir, string pattern = "*", bool searchSubdirectories = true)
{
- var root = Path.Combine(_directory, subdir);
+ var root = Path.Combine(directory, subdir);
if (!Directory.Exists(root))
{
- return new Entry[0];
+ return [];
}
var fullPaths = Directory.EnumerateFiles(root, pattern, searchSubdirectories ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly);
@@ -94,17 +81,17 @@ public Entry[] EnumerateFiles(string subdir, string pattern = "*", bool searchSu
Kind = FileEntry.TriageKind(FilePath.FromPlatformPath(relativePath))
};
- return entries.ToArray();
+ return [.. entries];
}
- // Returns subdirectories.
+ // Returns subdirectories.
public DirectoryReader[] EnumerateDirectories(string subdir, string pattern = "*", bool searchSubdirectories = false)
{
- var root = Path.Combine(_directory, subdir);
+ var root = Path.Combine(directory, subdir);
if (!Directory.Exists(root))
{
- return new DirectoryReader[0];
+ return [];
}
var fullPaths = Directory.EnumerateDirectories(root, pattern, searchSubdirectories ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly);
@@ -113,6 +100,6 @@ public DirectoryReader[] EnumerateDirectories(string subdir, string pattern = "*
let relativePath = FilePath.GetRelativePath(root, fullPath)
select new DirectoryReader(fullPath);
- return entries.ToArray();
+ return [.. entries];
}
}
diff --git a/src/PAModel/IO/DirectoryWriter.cs b/src/PAModel/IO/DirectoryWriter.cs
index 2fe0388e..af63b21d 100644
--- a/src/PAModel/IO/DirectoryWriter.cs
+++ b/src/PAModel/IO/DirectoryWriter.cs
@@ -12,35 +12,28 @@
namespace Microsoft.PowerPlatform.Formulas.Tools.IO;
///
-/// Abstraction over file system.
+/// Abstraction over file system.
/// Helps organize full path, relative paths
///
-public class DirectoryWriter
+public class DirectoryWriter(string directory)
{
- private readonly string _directory;
-
- public DirectoryWriter(string directory)
- {
- _directory = directory;
- }
-
// Remove all subdirectories. This is important to avoid have previous
// artifacts in the directories that we then pull back when round-tripping.
public void DeleteAllSubdirs(ErrorContainer errors)
{
- if (!Directory.Exists(_directory))
+ if (!Directory.Exists(directory))
{
- Directory.CreateDirectory(_directory);
+ Directory.CreateDirectory(directory);
}
if (ValidateSafeToDelete(errors))
{
- foreach (var dir in Directory.EnumerateDirectories(_directory))
+ foreach (var dir in Directory.EnumerateDirectories(directory))
{
if (dir.EndsWith(".git"))
continue;
Directory.Delete(dir, recursive: true);
}
- foreach (var file in Directory.EnumerateFiles(_directory))
+ foreach (var file in Directory.EnumerateFiles(directory))
{
if (file.StartsWith(".git"))
continue;
@@ -100,7 +93,7 @@ public void WriteAllXML(string subdir, FilePath filename, string xmlText)
public void WriteAllText(string subdir, FilePath filename, string text)
{
- var path = Path.Combine(_directory, subdir, filename.ToPlatformPath());
+ var path = Path.Combine(directory, subdir, filename.ToPlatformPath());
EnsureFileDirExists(path);
File.WriteAllText(path, text);
}
@@ -108,7 +101,7 @@ public void WriteAllText(string subdir, FilePath filename, string text)
// Use this if the filename is already escaped.
public void WriteAllText(string subdir, string filename, string text)
{
- var path = Path.Combine(_directory, subdir, filename);
+ var path = Path.Combine(directory, subdir, filename);
// Check for collision so that we don't overwrite an existing file.
if (File.Exists(path))
@@ -122,13 +115,13 @@ public void WriteAllText(string subdir, string filename, string text)
public void WriteAllBytes(string subdir, FilePath filename, byte[] bytes)
{
- var path = Path.Combine(_directory, subdir, filename.ToPlatformPath());
+ var path = Path.Combine(directory, subdir, filename.ToPlatformPath());
EnsureFileDirExists(path);
File.WriteAllBytes(path, bytes);
}
- // System.IO.File's built in functions fail if the directory doesn't already exist.
- // Must pre-create it before writing.
+ // System.IO.File's built in functions fail if the directory doesn't already exist.
+ // Must pre-create it before writing.
public static void EnsureFileDirExists(string path)
{
var errors = new ErrorContainer();
@@ -151,7 +144,7 @@ public static void EnsureFileDirExists(string path)
/// True if the file exists.
public bool FileExists(string subdir, string filename)
{
- var path = Path.Combine(_directory, subdir, filename);
+ var path = Path.Combine(directory, subdir, filename);
return File.Exists(path);
}
@@ -161,7 +154,7 @@ public bool FileExists(string subdir, string filename)
///
private bool ValidateSafeToDelete(ErrorContainer errors)
{
- if (Directory.EnumerateFiles(_directory).Any() && !File.Exists(Path.Combine(_directory, "CanvasManifest.json")))
+ if (Directory.EnumerateFiles(directory).Any() && !File.Exists(Path.Combine(directory, "CanvasManifest.json")))
{
errors.BadParameter("Must provide path to either empty directory or a directory where the app was previously unpacked.");
throw new DocumentException();
diff --git a/src/PAModel/IO/FilePath.cs b/src/PAModel/IO/FilePath.cs
index 5554286a..26289b9b 100644
--- a/src/PAModel/IO/FilePath.cs
+++ b/src/PAModel/IO/FilePath.cs
@@ -9,18 +9,13 @@
namespace Microsoft.PowerPlatform.Formulas.Tools.IO;
[DebuggerDisplay("{ToPlatformPath()}")]
-public class FilePath
+public class FilePath(params string[] segments)
{
public const int MaxFileNameLength = 60;
public const int MaxNameLength = 50;
private const string yamlExtension = ".fx.yaml";
private const string editorStateExtension = ".editorstate.json";
- private readonly string[] _pathSegments;
-
- public FilePath(params string[] segments)
- {
- _pathSegments = segments ?? (new string[] { });
- }
+ private readonly string[] _pathSegments = segments ?? ([]);
public static bool IsYamlFile(FilePath path)
{
@@ -52,7 +47,7 @@ public string ToMsAppPath()
var path = string.Join("\\", _pathSegments);
// Some paths mistakenly start with DirectorySepChar in the msapp,
- // We replaced it with `_/` when writing, remove that now.
+ // We replaced it with `_/` when writing, remove that now.
if (path.StartsWith(FileEntry.FilenameLeadingUnderscore.ToString()))
{
path = path.TrimStart(FileEntry.FilenameLeadingUnderscore);
@@ -103,7 +98,7 @@ public static string GetResourceRelativePath(ContentKind contentType)
/// Thrown if or path is null or an empty string.
///
/// Want to use Path.GetRelativePath() from Net 2.1. But since we target netstandard 2.0, we need to shim it.
- /// Convert to URIs and make the relative path.
+ /// Convert to URIs and make the relative path.
/// see https://stackoverflow.com/questions/275689/how-to-get-relative-path-from-absolute-path
/// For reference, see Core's impl at: https://github.com/dotnet/runtime/blob/main/src/libraries/System.Private.CoreLib/src/System/IO/Path.cs#L861
///
@@ -330,14 +325,13 @@ public static FilePath RootedAt(string root, FilePath remainder)
{
var segments = new List() { root };
segments.AddRange(remainder._pathSegments);
- return new FilePath(segments.ToArray());
+ return new FilePath([.. segments]);
}
public FilePath Append(string segment)
{
- var newSegments = new List(_pathSegments);
- newSegments.Add(segment);
- return new FilePath(newSegments.ToArray());
+ var newSegments = new List(_pathSegments) { segment };
+ return new FilePath([.. newSegments]);
}
public bool StartsWith(string root, StringComparison stringComparison)
diff --git a/src/PAModel/IR/IRStateHelpers.cs b/src/PAModel/IR/IRStateHelpers.cs
index 3aefef65..e05b5300 100644
--- a/src/PAModel/IR/IRStateHelpers.cs
+++ b/src/PAModel/IR/IRStateHelpers.cs
@@ -61,7 +61,7 @@ private static void SplitIRAndState(Item control, string topParentName, int inde
if (invariantScript != null && invariantScript != arg.ScopeVariableInfo.DefaultRule)
{
var argKey = $"{control.Name}.{arg.Name}";
- entropy.FunctionParamsInvariantScriptsOnInstances.Add(argKey, new string[] { arg.ScopeVariableInfo.DefaultRule, invariantScript });
+ entropy.FunctionParamsInvariantScriptsOnInstances.Add(argKey, [arg.ScopeVariableInfo.DefaultRule, invariantScript]);
}
}
}
@@ -111,7 +111,7 @@ private static void SplitIRAndState(Item control, string topParentName, int inde
if (invariantScript != null && invariantScript != arg.ScopeVariableInfo.DefaultRule)
{
var argKey = $"{control.Name}.{arg.Name}";
- entropy.FunctionParamsInvariantScripts.Add(argKey, new string[] { arg.ScopeVariableInfo.DefaultRule, invariantScript });
+ entropy.FunctionParamsInvariantScripts.Add(argKey, [arg.ScopeVariableInfo.DefaultRule, invariantScript]);
}
arg.ScopeVariableInfo.DefaultRule = null;
@@ -225,7 +225,7 @@ private static void SplitIRAndState(Item control, string topParentName, int inde
};
var templateName = templateState.TemplateDisplayName ?? templateState.Name;
// Template values could be different for each host control instances.
- // Considering that, we need to store each of these template values separately in templatestore, rather than once for hostcontrol.
+ // Considering that, we need to store each of these template values separately in templatestore, rather than once for hostcontrol.
// This enables Storing Template HostType and HostService details for each host control instances.
// Example Scenarios:
// Host Control Instance 1 -> template1 -> HostType1
@@ -378,7 +378,7 @@ private static (Item item, int index) CombineIRAndState(BlockNode blockNode, Err
}
// Reorder to preserve roundtripping
- dynamicProperties = dynamicProperties.OrderBy(prop => state.DynamicProperties.Select(propState => propState.PropertyName).ToList().IndexOf(prop.PropertyName)).ToList();
+ dynamicProperties = [.. dynamicProperties.OrderBy(prop => state.DynamicProperties.Select(propState => propState.PropertyName).ToList().IndexOf(prop.PropertyName))];
}
if (blockNode.Functions.Any())
@@ -423,15 +423,15 @@ private static (Item item, int index) CombineIRAndState(BlockNode blockNode, Err
// Preserve ordering from serialized IR
// Required for roundtrip checks
- properties = properties.OrderBy(prop => state.Properties?.Select(propState => propState.PropertyName).ToList().IndexOf(prop.Property) ?? -1).ToList();
+ properties = [.. properties.OrderBy(prop => state.Properties?.Select(propState => propState.PropertyName).ToList().IndexOf(prop.Property) ?? -1)];
resultControlInfo = new Item()
{
Parent = parent,
Name = controlName,
ControlUniqueId = uniqueId.ToString(),
VariantName = variantName ?? string.Empty,
- Rules = properties.ToArray(),
- DynamicProperties = (isInResponsiveLayout && dynamicProperties.Any()) ? dynamicProperties.ToArray() : null,
+ Rules = [.. properties],
+ DynamicProperties = (isInResponsiveLayout && dynamicProperties.Any()) ? [.. dynamicProperties] : null,
HasDynamicProperties = state.HasDynamicProperties,
StyleName = state.StyleName,
ExtensionData = state.ExtensionData,
@@ -480,9 +480,9 @@ private static (Item item, int index) CombineIRAndState(BlockNode blockNode, Err
properties.Add(CombinePropertyIRAndState(propIR, errors));
}
}
- resultControlInfo.Rules = properties.ToArray();
+ resultControlInfo.Rules = [.. properties];
var hasDynamicProperties = isInResponsiveLayout && dynamicProperties.Any();
- resultControlInfo.DynamicProperties = hasDynamicProperties ? dynamicProperties.ToArray() : null;
+ resultControlInfo.DynamicProperties = hasDynamicProperties ? [.. dynamicProperties] : null;
resultControlInfo.HasDynamicProperties = hasDynamicProperties;
resultControlInfo.AllowAccessToGlobals = templateState?.ComponentManifest?.AllowAccessToGlobals;
}
diff --git a/src/PAModel/MergeTool/ControlDiffVisitor.cs b/src/PAModel/MergeTool/ControlDiffVisitor.cs
index 0f33de0c..cb0ddfaf 100644
--- a/src/PAModel/MergeTool/ControlDiffVisitor.cs
+++ b/src/PAModel/MergeTool/ControlDiffVisitor.cs
@@ -39,7 +39,7 @@ private Dictionary GetSubtreeStates(BlockNode node)
private IEnumerable GetSubtreeStatesImpl(BlockNode node)
{
- var childstates = node.Children?.SelectMany(GetSubtreeStatesImpl) ?? Enumerable.Empty();
+ var childstates = node.Children?.SelectMany(GetSubtreeStatesImpl) ?? [];
if (!_childStateStore.TryGetControlState(node.Name.Identifier, out var state))
return childstates;
@@ -200,16 +200,9 @@ private bool TryGetUpdatedCustomPropertyMetadata(string currentControlKind, stri
}
}
-internal class ControlDiffContext
+internal class ControlDiffContext(ControlPath path, IRNode theirs, bool isInComponent)
{
- public IRNode Theirs { get; }
- public ControlPath Path { get; }
- public bool IsInComponent { get; }
-
- public ControlDiffContext(ControlPath path, IRNode theirs, bool isInComponent)
- {
- Theirs = theirs;
- Path = path;
- IsInComponent = isInComponent;
- }
+ public IRNode Theirs { get; } = theirs;
+ public ControlPath Path { get; } = path;
+ public bool IsInComponent { get; } = isInComponent;
}
diff --git a/src/PAModel/MergeTool/Deltas/AddControl.cs b/src/PAModel/MergeTool/Deltas/AddControl.cs
index ed90169a..e8ad9615 100644
--- a/src/PAModel/MergeTool/Deltas/AddControl.cs
+++ b/src/PAModel/MergeTool/Deltas/AddControl.cs
@@ -7,58 +7,50 @@
namespace Microsoft.PowerPlatform.Formulas.Tools.MergeTool.Deltas;
-internal class AddControl : IDelta
+internal class AddControl(
+ ControlPath parentControlPath,
+ BlockNode control,
+ Dictionary controlStates,
+ bool isInComponent)
+ : IDelta
{
- private readonly bool _isInComponent;
- private readonly ControlPath _parentControlPath;
- private readonly BlockNode _control;
- private readonly Dictionary _controlStates;
-
- public string ControlName => _control.Name.Identifier;
-
- public AddControl(ControlPath parentControlPath, BlockNode control, Dictionary controlStates, bool isInComponent)
- {
- _isInComponent = isInComponent;
- _parentControlPath = parentControlPath;
- _control = control;
- _controlStates = controlStates;
- }
+ public string ControlName => control.Name.Identifier;
public void Apply(CanvasDocument document)
{
- var controlSet = _isInComponent ? document._components : document._screens;
+ var controlSet = isInComponent ? document._components : document._screens;
// Top level addition
- if (_parentControlPath == ControlPath.Empty)
+ if (parentControlPath == ControlPath.Empty)
{
- var repairedTopParent = MakeControlTreeCollisionFree(_control, _controlStates, document._editorStateStore);
+ var repairedTopParent = MakeControlTreeCollisionFree(control, controlStates, document._editorStateStore);
if (repairedTopParent == null)
return;
AddControlStates(repairedTopParent, document._editorStateStore);
- controlSet.Add(_control.Name.Identifier, repairedTopParent);
+ controlSet.Add(control.Name.Identifier, repairedTopParent);
// Add screen to order set to avoid confusing diffs
- if (!_isInComponent && !document._screenOrder.Contains(ControlName))
+ if (!isInComponent && !document._screenOrder.Contains(ControlName))
document._screenOrder.Add(ControlName);
return;
}
// Top Parent was removed
- if (!controlSet.TryGetValue(_parentControlPath.Current, out var control))
+ if (!controlSet.TryGetValue(parentControlPath.Current, out var value))
return;
- var path = _parentControlPath.Next();
+ var path = parentControlPath.Next();
while (path.Current != null)
{
var found = false;
- foreach (var child in control.Children)
+ foreach (var child in value.Children)
{
if (child.Name.Identifier == path.Current)
{
- control = child;
+ value = child;
path = path.Next();
found = true;
break;
@@ -71,12 +63,12 @@ public void Apply(CanvasDocument document)
}
}
- var repairedControl = MakeControlTreeCollisionFree(_control, _controlStates, document._editorStateStore);
+ var repairedControl = MakeControlTreeCollisionFree(control, controlStates, document._editorStateStore);
if (repairedControl == null)
return;
AddControlStates(repairedControl, document._editorStateStore);
- control.Children.Add(repairedControl);
+ value.Children.Add(repairedControl);
}
private static BlockNode MakeControlTreeCollisionFree(BlockNode root, Dictionary states, EditorStateStore stateStore)
@@ -121,7 +113,7 @@ private void AddControlStates(BlockNode root, EditorStateStore stateStore)
var name = root.Name.Identifier;
// If the state exists, add to merged document
- if (_controlStates.TryGetValue(name, out var state))
+ if (controlStates.TryGetValue(name, out var state))
{
stateStore.TryAddControl(state);
}
diff --git a/src/PAModel/MergeTool/Deltas/AddTemplate.cs b/src/PAModel/MergeTool/Deltas/AddTemplate.cs
index 208c2aaf..64c54f0f 100644
--- a/src/PAModel/MergeTool/Deltas/AddTemplate.cs
+++ b/src/PAModel/MergeTool/Deltas/AddTemplate.cs
@@ -43,7 +43,7 @@ public void Apply(CanvasDocument document)
}
else if (_jsonTemplate != null)
{
- document._templates.UsedTemplates = document._templates.UsedTemplates.Concat(new[] { _jsonTemplate }).ToArray();
+ document._templates.UsedTemplates = [.. document._templates.UsedTemplates.Concat(new[] { _jsonTemplate })];
}
}
}
diff --git a/src/PAModel/MergeTool/Deltas/ChangeComponentFunction.cs b/src/PAModel/MergeTool/Deltas/ChangeComponentFunction.cs
index 78bda698..aedc98e0 100644
--- a/src/PAModel/MergeTool/Deltas/ChangeComponentFunction.cs
+++ b/src/PAModel/MergeTool/Deltas/ChangeComponentFunction.cs
@@ -63,7 +63,7 @@ public void Apply(CanvasDocument document)
customProps[PropertyName] = _customProperty;
else
return;
- updatableTemplate.CustomProperties = customProps.Values.ToArray();
+ updatableTemplate.CustomProperties = [.. customProps.Values];
}
}
}
diff --git a/src/PAModel/MergeTool/Deltas/ChangeProperty.cs b/src/PAModel/MergeTool/Deltas/ChangeProperty.cs
index fe9be781..7e9043a3 100644
--- a/src/PAModel/MergeTool/Deltas/ChangeProperty.cs
+++ b/src/PAModel/MergeTool/Deltas/ChangeProperty.cs
@@ -63,7 +63,7 @@ public void Apply(CanvasDocument document)
customProps[PropertyName] = _customProperty;
else
return;
- updatableTemplate.CustomProperties = customProps.Values.ToArray();
+ updatableTemplate.CustomProperties = [.. customProps.Values];
}
}
}
diff --git a/src/PAModel/MergeTool/Deltas/RemoveControl.cs b/src/PAModel/MergeTool/Deltas/RemoveControl.cs
index b6ce944d..1cf64564 100644
--- a/src/PAModel/MergeTool/Deltas/RemoveControl.cs
+++ b/src/PAModel/MergeTool/Deltas/RemoveControl.cs
@@ -6,35 +6,25 @@
namespace Microsoft.PowerPlatform.Formulas.Tools.MergeTool.Deltas;
-internal class RemoveControl : IDelta
+internal class RemoveControl(ControlPath parentControlPath, string controlName, bool isInComponent)
+ : IDelta
{
- private readonly ControlPath _parentControlPath;
- private readonly string _controlName;
- private readonly bool _isInComponent;
-
- public RemoveControl(ControlPath parentControlPath, string controlName, bool isInComponent)
- {
- _parentControlPath = parentControlPath;
- _controlName = controlName;
- _isInComponent = isInComponent;
- }
-
public void Apply(CanvasDocument document)
{
- var controlSet = _isInComponent ? document._components : document._screens;
+ var controlSet = isInComponent ? document._components : document._screens;
// Screen removal
- if (_parentControlPath == ControlPath.Empty)
+ if (parentControlPath == ControlPath.Empty)
{
- controlSet.Remove(_controlName);
+ controlSet.Remove(controlName);
return;
}
// error case?
- if (!controlSet.TryGetValue(_parentControlPath.Current, out var control))
+ if (!controlSet.TryGetValue(parentControlPath.Current, out var control))
return;
- var path = _parentControlPath.Next();
+ var path = parentControlPath.Next();
while (path.Current != null)
{
var found = false;
@@ -54,7 +44,7 @@ public void Apply(CanvasDocument document)
// Remove the control
// maybe add error checks here too?
- control.Children = control.Children.Where(child => child.Name.Identifier != _controlName).ToList();
- document._editorStateStore.Remove(_controlName);
+ control.Children = control.Children.Where(child => child.Name.Identifier != controlName).ToList();
+ document._editorStateStore.Remove(controlName);
}
}
diff --git a/src/PAModel/MergeTool/Deltas/Resources.cs b/src/PAModel/MergeTool/Deltas/Resources.cs
index c1ea761b..f041a02d 100644
--- a/src/PAModel/MergeTool/Deltas/Resources.cs
+++ b/src/PAModel/MergeTool/Deltas/Resources.cs
@@ -40,7 +40,7 @@ public void Apply(CanvasDocument document)
document.AddAssetFile(_file);
}
- document._resourcesJson.Resources = resources.Values.ToArray();
+ document._resourcesJson.Resources = [.. resources.Values];
}
}
@@ -65,7 +65,7 @@ public void Apply(CanvasDocument document)
{
var resources = document._resourcesJson.Resources.ToDictionary(res => res.Name);
resources.Remove(_name);
- document._resourcesJson.Resources = resources.Values.ToArray();
+ document._resourcesJson.Resources = [.. resources.Values];
if (_assetKey != null)
document._assetFiles.Remove(_assetKey);
@@ -75,7 +75,7 @@ public void Apply(CanvasDocument document)
internal class UpdateResource : IDelta
{
private readonly string _name;
- private readonly FileEntry _file; // null if no contents.
+ private readonly FileEntry _file; // null if no contents.
private readonly ResourceJson _resource;
private readonly FilePath _assetKey; // needed for deletion (in case file is missing)
@@ -94,7 +94,7 @@ public void Apply(CanvasDocument document)
{
var resources = document._resourcesJson.Resources.ToDictionary(res => res.Name);
resources[_name] = _resource;
- document._resourcesJson.Resources = resources.Values.ToArray();
+ document._resourcesJson.Resources = [.. resources.Values];
document._assetFiles.Remove(_assetKey);
diff --git a/src/PAModel/MergeTool/Deltas/ScreenOrderChange.cs b/src/PAModel/MergeTool/Deltas/ScreenOrderChange.cs
index b0e0a1b9..97e0dea4 100644
--- a/src/PAModel/MergeTool/Deltas/ScreenOrderChange.cs
+++ b/src/PAModel/MergeTool/Deltas/ScreenOrderChange.cs
@@ -5,18 +5,11 @@
namespace Microsoft.PowerPlatform.Formulas.Tools.MergeTool.Deltas;
-internal class ScreenOrderChange : IDelta
+internal class ScreenOrderChange(List screenOrder) : IDelta
{
- private readonly List _screenOrder;
-
- public ScreenOrderChange(List screenOrder)
- {
- _screenOrder = screenOrder;
- }
-
public void Apply(CanvasDocument document)
{
// Clone this, we don't want to potentially modify the order from one of the loaded CanvasDocuments
- document._screenOrder = _screenOrder.JsonClone();
+ document._screenOrder = screenOrder.JsonClone();
}
}
diff --git a/src/PAModel/MergeTool/Deltas/ThemeChange.cs b/src/PAModel/MergeTool/Deltas/ThemeChange.cs
index 6be2e2cf..72a1c574 100644
--- a/src/PAModel/MergeTool/Deltas/ThemeChange.cs
+++ b/src/PAModel/MergeTool/Deltas/ThemeChange.cs
@@ -5,18 +5,11 @@
namespace Microsoft.PowerPlatform.Formulas.Tools.MergeTool.Deltas;
-internal class ThemeChange : IDelta
+internal class ThemeChange(ThemesJson theme) : IDelta
{
- private readonly ThemesJson _theme;
-
- public ThemeChange(ThemesJson theme)
- {
- _theme = theme;
- }
-
// As a starting point, overwrite the theme as a whole.
public void Apply(CanvasDocument document)
{
- document._themes = _theme;
+ document._themes = theme;
}
}
diff --git a/src/PAModel/PAConvert/Parser/Parser.cs b/src/PAModel/PAConvert/Parser/Parser.cs
index 0978f55b..39daf5ac 100644
--- a/src/PAModel/PAConvert/Parser/Parser.cs
+++ b/src/PAModel/PAConvert/Parser/Parser.cs
@@ -9,20 +9,13 @@
namespace Microsoft.PowerPlatform.Formulas.Tools.Parser;
-internal class Parser : IDisposable
+internal class Parser(string fileName, string contents, ErrorContainer errors) : IDisposable
{
- public readonly ErrorContainer _errorContainer;
+ public readonly ErrorContainer _errorContainer = errors;
- private readonly YamlLexer _yaml;
+ private readonly YamlLexer _yaml = new(new StringReader(contents), fileName);
private bool _isDisposed;
- public Parser(string fileName, string contents, ErrorContainer errors)
- {
- _errorContainer = errors;
-
- _yaml = new YamlLexer(new StringReader(contents), fileName);
- }
-
// Parse the control definition line. Something like:
// Screen1 as Screen
// Label1 As Label.Variant
@@ -192,7 +185,7 @@ private BlockNode ParseNestedControl(YamlToken p)
return block;
case YamlTokenKind.Property:
- // Yaml parser only gives back a single span for property name and value.
+ // Yaml parser only gives back a single span for property name and value.
block.Properties.Add(new PropertyNode
{
SourceSpan = p.Span,
@@ -293,7 +286,7 @@ private FunctionNode ParseFunctionDef(YamlToken p)
case YamlTokenKind.EndObj:
return functionNode;
- // Expecting N+1 child objs where one is ThisProperty and the others N are the args
+ // Expecting N+1 child objs where one is ThisProperty and the others N are the args
case YamlTokenKind.StartObj:
functionNode.Metadata.Add(ParseArgMetadataBlock(p));
break;
diff --git a/src/PAModel/PAConvert/Parser/SourceLocation.cs b/src/PAModel/PAConvert/Parser/SourceLocation.cs
index cb96aabb..696cccba 100644
--- a/src/PAModel/PAConvert/Parser/SourceLocation.cs
+++ b/src/PAModel/PAConvert/Parser/SourceLocation.cs
@@ -5,23 +5,15 @@
namespace Microsoft.PowerPlatform.Formulas.Tools.IR;
-internal readonly struct SourceLocation
+internal readonly struct SourceLocation(int startLine, int startChar, int endLine, int endChar, string fileName)
{
- public readonly int StartLine;
- public readonly int StartChar;
- public readonly int EndLine;
- public readonly int EndChar;
- public readonly string FileName;
+ public readonly int StartLine = startLine;
+ public readonly int StartChar = startChar;
+ public readonly int EndLine = endLine;
+ public readonly int EndChar = endChar;
+ public readonly string FileName = fileName;
// Indices into file are 1-based.
- public SourceLocation(int startLine, int startChar, int endLine, int endChar, string fileName)
- {
- StartLine = startLine;
- StartChar = startChar;
- EndLine = endLine;
- EndChar = endChar;
- FileName = fileName;
- }
public static SourceLocation FromFile(string filename)
{
diff --git a/src/PAModel/PAConvert/Yaml/YamlLexer.cs b/src/PAModel/PAConvert/Yaml/YamlLexer.cs
index d0056a04..67cac226 100644
--- a/src/PAModel/PAConvert/Yaml/YamlLexer.cs
+++ b/src/PAModel/PAConvert/Yaml/YamlLexer.cs
@@ -12,16 +12,16 @@ namespace Microsoft.PowerPlatform.Formulas.Tools.Yaml;
/// Helper to read our strict subset of Yaml.
/// Give useful errors on things outside of the subset.
/// See https://yaml.org/
-/// This will strip '=' signs at the start of single property values.
+/// This will strip '=' signs at the start of single property values.
///
internal class YamlLexer : IDisposable
{
private const string NewLine = "\n";
- // The actual contents to read.
+ // The actual contents to read.
private readonly TextReader _reader;
- // Stack of indentations.
+ // Stack of indentations.
private readonly Stack _currentIndent;
private YamlToken _lastPair;
@@ -34,7 +34,7 @@ internal class YamlLexer : IDisposable
private string _currentLineContents;
// Per https://github.com/microsoft/PowerApps-Language-Tooling/issues/115,
- // We allow comments, but don't round-trip them. Issue a warning.
+ // We allow comments, but don't round-trip them. Issue a warning.
public SourceLocation? _commentStrippedWarning;
private bool _isDisposed;
public const string MissingSingleQuoteFunctionNode = "Missing closing \' in Function Node";
@@ -85,7 +85,7 @@ private void MoveNextLine()
}
///
- /// Get the next token in the stream. Returns an EOF at the end of document.
+ /// Get the next token in the stream. Returns an EOF at the end of document.
///
///
public YamlToken ReadNext()
@@ -105,12 +105,12 @@ private YamlToken ReadNextWorker()
// different indent size
// duplicate keys
// empty properties (should have an indent)
- // no tabs.
- // don't allow --- documents
+ // no tabs.
+ // don't allow --- documents
// Start of line.
// [Indent] [PropertyName] [Colon]
- // [Indent] [PropertyName] [Colon] [space] [equals] [VALUE]
+ // [Indent] [PropertyName] [Colon] [space] [equals] [VALUE]
// [Indent] [PropertyName] [Colon] [space] [MultilineEscape]
LineParser line;
@@ -134,7 +134,7 @@ private YamlToken ReadNextWorker()
// get starting indent.
indentLen = line.EatIndent();
- // Comment indent level doesn't matter - may not match object indent.
+ // Comment indent level doesn't matter - may not match object indent.
if (line.Current == '#')
{
// https://github.com/microsoft/PowerApps-Language-Tooling/issues/115
@@ -153,7 +153,7 @@ private YamlToken ReadNextWorker()
break;
}
- // Eat the newline and go to the next line.
+ // Eat the newline and go to the next line.
MoveNextLine();
}
@@ -183,11 +183,11 @@ private YamlToken ReadNextWorker()
}
else if (indentLen < lastIndent)
{
- // Close current objects one at a time.
+ // Close current objects one at a time.
_currentIndent.Pop();
var prevIndent = _currentIndent.Peek()._oldIndentLevel;
- // Indent must exactly match a previous one up the stack.
+ // Indent must exactly match a previous one up the stack.
if (indentLen > prevIndent)
{
return Error(line, "Property indent must align exactly with a previous indent level.");
@@ -210,7 +210,7 @@ private YamlToken ReadNextWorker()
if (indentLen == expectedIndent)
{
// Good. Common case.
- // Continue processing below to actually parse this property.
+ // Continue processing below to actually parse this property.
}
else if (indentLen > expectedIndent)
{
@@ -219,13 +219,13 @@ private YamlToken ReadNextWorker()
else
{
// Closing an object.
- // Indent must exactly match a previous one up the stack.
+ // Indent must exactly match a previous one up the stack.
if (indentLen > _currentIndent.Peek()._oldIndentLevel)
{
return Error(line, "Property indent must align exactly with a previous indent level.");
}
- // Close current objects one at a time.
+ // Close current objects one at a time.
_currentIndent.Pop();
return YamlToken.EndObj;
}
@@ -261,9 +261,9 @@ private YamlToken ReadNextWorker()
}
line._idx++;
}
- line.MaybeEat(':'); // skip colon.
+ line.MaybeEat(':'); // skip colon.
- // Prop name could have spaces, but no colons.
+ // Prop name could have spaces, but no colons.
var propName = line._line.Substring(indentLen, line._idx - indentLen - 1).Trim();
if (requiresClosingDoubleQuote)
@@ -272,7 +272,7 @@ private YamlToken ReadNextWorker()
}
// If it's a property, must have at least 1 space.
- // If it's start object, then ignore all spaces.
+ // If it's start object, then ignore all spaces.
var iSpaces = 0;
while (line.MaybeEat(' '))
@@ -333,7 +333,7 @@ private YamlToken ReadNextWorker()
{
// These are common YAml sequences, but extremely problematic and could be user error.
// Disallow them and force the user to explicit.
- // Is "hello" a string or identifier?
+ // Is "hello" a string or identifier?
// Foo: "Hello"
//
// Instead, have the user write:
@@ -358,11 +358,11 @@ private YamlToken ReadNextWorker()
}
else if (line.MaybeEat('+'))
{
- multilineMode = 2; // 1+ newlines.
+ multilineMode = 2; // 1+ newlines.
}
else
{
- multilineMode = 1; // exactly 1 newline at end.
+ multilineMode = 1; // exactly 1 newline at end.
}
iSpaces = 0;
@@ -375,7 +375,7 @@ private YamlToken ReadNextWorker()
{
return UnsupportedComment(line);
}
- else if (line.Current != 0) // EOL, catch all error.
+ else if (line.Current != 0) // EOL, catch all error.
{
return Error(line, "Content for | escape must start on next line.");
}
@@ -397,7 +397,7 @@ private YamlToken ReadNextWorker()
}
else if (Options.HasFlag(YamlLexerOptions.EnforceLeadingEquals))
{
- // Warn on legal yaml escapes (>) that we don't support in our subset here.
+ // Warn on legal yaml escapes (>) that we don't support in our subset here.
return Error(line, "Expected either '=' for a single line expression or '|' to begin a multiline expression");
}
else
@@ -419,7 +419,7 @@ private YamlToken ReadNextWorker()
}
- // Errors that are valid yaml, but not in our supported subset.
+ // Errors that are valid yaml, but not in our supported subset.
private YamlToken Unsupported(LineParser line, string message)
{
return Error(line, message);
@@ -451,7 +451,7 @@ private YamlToken Error(LineParser line, string message)
}
- // For an error at a specific character.
+ // For an error at a specific character.
private SourceLocation Loc(LineParser line)
{
var columnIdx1 = line._idx + 1;
@@ -461,11 +461,11 @@ private SourceLocation Loc(LineParser line)
// For a success case referring to a range.
private SourceLocation Loc(int startIndex1, LineParser endChar)
{
- var endIndex1 = endChar._idx + 1; // convert 0-based to 1-base
+ var endIndex1 = endChar._idx + 1; // convert 0-based to 1-base
return LocWorker(startIndex1, endIndex1);
}
- // 1-based indexes.
+ // 1-based indexes.
private SourceLocation LocWorker(int startIndex1, int endIndex1)
{
return new SourceLocation(CurrentLine, startIndex1, CurrentLine, endIndex1, _currentFileName);
@@ -478,7 +478,7 @@ private string ReadMultiline(int multilineMode)
var sb = new StringBuilder();
// First line establishes indent level.
- // Yaml allows empty Multilines, we require it must have at least 1 line in it. (no empty values)
+ // Yaml allows empty Multilines, we require it must have at least 1 line in it. (no empty values)
var parentIndent = _currentIndent.Peek()._newIndentLevel;
var thisIndent = -1;
@@ -488,12 +488,12 @@ private string ReadMultiline(int multilineMode)
var line = PeekLine();
if (line == null)
{
- break; // end of file.
+ break; // end of file.
}
var indentLen = line.EatIndent();
if (thisIndent == -1)
{
- // First line, sets the indent
+ // First line, sets the indent
thisIndent = indentLen;
}
@@ -536,11 +536,11 @@ private string ReadMultiline(int multilineMode)
}
else if (multilineMode == 1)
{
- // Just one. This is already the case.
+ // Just one. This is already the case.
}
else if (multilineMode > 1)
{
- // Allows multiple.
+ // Allows multiple.
}
// End of multiline escape.
@@ -550,19 +550,14 @@ private string ReadMultiline(int multilineMode)
// Helper for reading through a single line.
// This treats EOL as (char) 0.
[DebuggerDisplay("{DebuggerToString()}")]
- private class LineParser
+ private class LineParser(string line)
{
- // 0-based character index into line
+ // 0-based character index into line
public int _idx;
- public readonly string _line;
+ public readonly string _line = line;
- public LineParser(string line)
- {
- _line = line;
- }
-
- // Helper to handle eol.
+ // Helper to handle eol.
public char Current
{
get
@@ -602,7 +597,7 @@ public bool MaybeEat(char ch)
}
// Eat the left indent and return # of spaces in it.
- // We require spaces and don't allow tabs.
+ // We require spaces and don't allow tabs.
public int EatIndent()
{
while (MaybeEat(' ')) ;
@@ -623,12 +618,12 @@ private string DebuggerToString()
private class Indent
{
public int _oldIndentLevel;
- public int _newIndentLevel; // for children of this object.
+ public int _newIndentLevel; // for children of this object.
public int _lineStart; // what line did this indenting start at?
// For detecting collisions in previous properties.
// Collisions must be *case-sensitive*
- // Map property name to line that it was declared on.
+ // Map property name to line that it was declared on.
public Dictionary _previousProperties = new(StringComparer.Ordinal);
internal YamlToken CheckDuplicate(string propName, int currentLine)
diff --git a/src/PAModel/PAConvert/Yaml/YamlParseException.cs b/src/PAModel/PAConvert/Yaml/YamlParseException.cs
index d65e8e3b..b7ab2e36 100644
--- a/src/PAModel/PAConvert/Yaml/YamlParseException.cs
+++ b/src/PAModel/PAConvert/Yaml/YamlParseException.cs
@@ -3,13 +3,8 @@
namespace Microsoft.PowerPlatform.Formulas.Tools.Yaml;
-public class YamlParseException : Exception
+public class YamlParseException(string message, int line = 0, Exception innerException = null)
+ : Exception(message, innerException)
{
- public YamlParseException(string message, int line = 0, Exception innerException = null)
- : base(message, innerException)
- {
- Line = line;
- }
-
- public int Line { get; init; }
+ public int Line { get; init; } = line;
}
diff --git a/src/PAModel/PAConvert/Yaml/YamlWriter.cs b/src/PAModel/PAConvert/Yaml/YamlWriter.cs
index a7509873..3dfb8e58 100644
--- a/src/PAModel/PAConvert/Yaml/YamlWriter.cs
+++ b/src/PAModel/PAConvert/Yaml/YamlWriter.cs
@@ -32,7 +32,7 @@ public void WriteStartObject(string propertyName)
{
WriteIndent();
- var needsEscape = propertyName.IndexOfAny(new char[] { '\"', '\'' }) != -1;
+ var needsEscape = propertyName.IndexOfAny(['\"', '\'']) != -1;
if (needsEscape)
propertyName = $"\"{propertyName.Replace("\"", "\\\"")}\"";
@@ -89,7 +89,7 @@ public void WriteProperty(string propertyName, double value, bool includeEquals
///
/// Safely write a property. Based on the value, will chose whether single-line (and prefix with an '=')
- /// or multi-line and pick the right the escape.
+ /// or multi-line and pick the right the escape.
///
///
///
@@ -106,7 +106,7 @@ public void WriteProperty(string propertyName, string value, bool includeEquals
value = NormalizeNewlines(value);
- var isSingleLine = value.IndexOfAny(new char[] { '#', '\n', ':' }) == -1;
+ var isSingleLine = value.IndexOfAny(['#', '\n', ':']) == -1;
// For consistency, both single and multiline PA properties prefix with '='.
// Only single-line actually needs this - to avoid yaml's regular expression escaping.
@@ -177,7 +177,7 @@ public void WriteProperty(string propertyName, string value, bool includeEquals
}
// Write a newline, for aesthics. since this is inbetween properties,
- // it should get ignored on parse.
+ // it should get ignored on parse.
public void WriteNewline()
{
_textWriter.WriteLine();
diff --git a/src/PAModel/Schemas/DocumentPropertiesJson.cs b/src/PAModel/Schemas/DocumentPropertiesJson.cs
index 4603a8c4..52fa5e82 100644
--- a/src/PAModel/Schemas/DocumentPropertiesJson.cs
+++ b/src/PAModel/Schemas/DocumentPropertiesJson.cs
@@ -27,8 +27,8 @@ internal class DocumentPropertiesJson
public string Id { get; set; }
public string FileID { get; set; }
- // Stores the connections
- // Dictionary-->Connection object
+ // Stores the connections
+ // Dictionary-->Connection object
public string LocalConnectionReferences { get; set; }
public string LocalDatabaseReferences { get; set; }
@@ -96,8 +96,7 @@ public static DocumentPropertiesJson CreateDefault(string name)
private static string[] GetAppPreviewFlagDefault()
{
- return new string[]
- {
+ return [
"delayloadscreens",
"blockmovingcontrol",
"projectionmapping",
@@ -116,7 +115,7 @@ private static string[] GetAppPreviewFlagDefault()
"aibuilderserviceenrollment",
"enablesummerlandgeospatialfeatures",
"enablesummerlandmixedrealityfeatures"
- };
+ ];
}
}
diff --git a/src/PAModel/Schemas/adhoc/Control.cs b/src/PAModel/Schemas/adhoc/Control.cs
index 2b467a93..1c6e6ba9 100644
--- a/src/PAModel/Schemas/adhoc/Control.cs
+++ b/src/PAModel/Schemas/adhoc/Control.cs
@@ -158,7 +158,7 @@ public static Item CreateDefaultControl(ControlTemplate templateDefault = null)
{
var defaultCtrl = new Item();
var rules = new List();
- defaultCtrl.Rules = rules.ToArray();
+ defaultCtrl.Rules = [.. rules];
defaultCtrl.PublishOrderIndex = 0;
defaultCtrl.ExtensionData = CreateDefaultExtensionData();
diff --git a/src/PAModel/Serializers/DefaultRuleHelper.cs b/src/PAModel/Serializers/DefaultRuleHelper.cs
index 8d960d40..9acfa7c8 100644
--- a/src/PAModel/Serializers/DefaultRuleHelper.cs
+++ b/src/PAModel/Serializers/DefaultRuleHelper.cs
@@ -10,39 +10,22 @@ namespace Microsoft.PowerPlatform.Formulas.Tools.Serializers;
// Provides collection of all default rules.
// Used by reader/writer to add/remove default rules - avoid redundancy.
// The exact defaulting rules don't actually matter, as long as it's the same for
-// read and write so that we roundtrip.
-internal class DefaultRuleHelper
+// read and write so that we roundtrip.
+internal class DefaultRuleHelper(
+ string styleName,
+ ControlTemplate template,
+ string templateName,
+ string variantName,
+ Theme theme,
+ bool inResponsiveContext)
{
- private readonly ControlTemplate _template;
- private readonly string _templateName;
- private readonly string _variantName;
- private readonly Theme _theme;
- private readonly string _styleName;
- private readonly bool _inResponsiveContext;
-
- public DefaultRuleHelper(
- string styleName,
- ControlTemplate template,
- string templateName,
- string variantName,
- Theme theme,
- bool inResponsiveContext)
- {
- _template = template;
- _templateName = templateName;
- _variantName = variantName;
- _styleName = styleName;
- _theme = theme;
- _inResponsiveContext = inResponsiveContext;
- }
-
- // Used on writing to source to omit default rules.
+ // Used on writing to source to omit default rules.
public bool TryGetDefaultRule(string propertyName, out string defaultScript)
{
- // Themes (styles) are higher precedence then Template XML.
- var template = _template;
+ // Themes (styles) are higher precedence then Template XML.
+ var template1 = template;
- if (_theme.TryLookup(_styleName, propertyName, out defaultScript))
+ if (theme.TryLookup(styleName, propertyName, out defaultScript))
{
if (ControlTemplateParser.IsLocalizationKey(defaultScript))
return false;
@@ -50,11 +33,11 @@ public bool TryGetDefaultRule(string propertyName, out string defaultScript)
}
// Check template variant first, then template base
- if (template != null &&
- ((_variantName != null &&
- template.VariantDefaultValues.TryGetValue(_variantName, out var defaults) &&
+ if (template1 != null &&
+ ((variantName != null &&
+ template1.VariantDefaultValues.TryGetValue(variantName, out var defaults) &&
defaults.TryGetValue(propertyName, out defaultScript)) ||
- template.InputDefaults.TryGetValue(propertyName, out defaultScript)))
+ template1.InputDefaults.TryGetValue(propertyName, out defaultScript)))
{
if (ControlTemplateParser.IsLocalizationKey(defaultScript))
return false;
@@ -63,7 +46,7 @@ public bool TryGetDefaultRule(string propertyName, out string defaultScript)
return true;
}
- if (_inResponsiveContext && DynamicProperties.TryGetDefaultValue(propertyName, _templateName, this, out defaultScript))
+ if (inResponsiveContext && DynamicProperties.TryGetDefaultValue(propertyName, templateName, this, out defaultScript))
{
return true;
}
@@ -72,28 +55,28 @@ public bool TryGetDefaultRule(string propertyName, out string defaultScript)
return false;
}
- // Used on reading from source. Get full list of rules for this control.
+ // Used on reading from source. Get full list of rules for this control.
public Dictionary GetDefaultRules()
{
// Add themes first.
var defaults = new Dictionary();
var variantDefaults = new Dictionary();
- if (_template != null)
+ if (template != null)
{
// Default values from the variants take precedence over the base template
- var hasVariantDefaults = _variantName != null && _template.VariantDefaultValues.TryGetValue(_variantName, out variantDefaults);
+ var hasVariantDefaults = variantName != null && template.VariantDefaultValues.TryGetValue(variantName, out variantDefaults);
if (hasVariantDefaults)
defaults.AddRange(variantDefaults);
- defaults.AddRange(_template.InputDefaults.Where(kvp => !ControlTemplateParser.IsLocalizationKey(kvp.Value) && !(hasVariantDefaults && variantDefaults.ContainsKey(kvp.Key))));
+ defaults.AddRange(template.InputDefaults.Where(kvp => !ControlTemplateParser.IsLocalizationKey(kvp.Value) && !(hasVariantDefaults && variantDefaults.ContainsKey(kvp.Key))));
}
- defaults.AddRange(_theme.GetStyle(_styleName).Where(kvp => !ControlTemplateParser.IsLocalizationKey(kvp.Value)));
+ defaults.AddRange(theme.GetStyle(styleName).Where(kvp => !ControlTemplateParser.IsLocalizationKey(kvp.Value)));
- if (_inResponsiveContext)
+ if (inResponsiveContext)
{
- defaults.AddRange(DynamicProperties.GetDefaultValues(_templateName, this));
+ defaults.AddRange(DynamicProperties.GetDefaultValues(templateName, this));
}
return defaults;
diff --git a/src/PAModel/Serializers/FileEntry.cs b/src/PAModel/Serializers/FileEntry.cs
index 0f521871..dd5a5b19 100644
--- a/src/PAModel/Serializers/FileEntry.cs
+++ b/src/PAModel/Serializers/FileEntry.cs
@@ -10,7 +10,7 @@
namespace Microsoft.PowerPlatform.Formulas.Tools;
-// Raw kinds of files we recognize in the .msapp
+// Raw kinds of files we recognize in the .msapp
public enum FileKind
{
Unknown,
@@ -26,25 +26,25 @@ public enum FileKind
DataComponentTemplates,
- // If this file is present, it's an older format.
+ // If this file is present, it's an older format.
OldEntityJSon,
- // Resources
+ // Resources
PublishInfo,
- // References
+ // References
DataSources,
Themes,
Templates,
Resources,
Asset,
- // Category so
+ // Category so
ControlSrc,
ComponentSrc,
TestSrc,
- // Unique to source format.
+ // Unique to source format.
Entropy,
CanvasManifest,
Connections,
@@ -56,14 +56,14 @@ public enum FileKind
// AppTest parent control source file
AppTestParentControl,
- // Schema.yaml describing app's parameters at top level.
+ // Schema.yaml describing app's parameters at top level.
Defines,
// Custom page inputs for outbound custom page navigate calls.
CustomPageInputs,
}
-// Represent a file from disk or a Zip archive.
+// Represent a file from disk or a Zip archive.
[DebuggerDisplay("{Name}")]
internal class FileEntry
{
@@ -77,7 +77,7 @@ public FileEntry() { }
public FileEntry(FileEntry other)
{
Name = other.Name;
- RawBytes = other.RawBytes.ToArray(); // ToArray clones byte arrays
+ RawBytes = [.. other.RawBytes]; // ToArray clones byte arrays
}
public const string CustomPagesMetadataFileName = "CustomPagesMetadata.json";
@@ -100,7 +100,7 @@ public static FileEntry FromZip(ZipArchiveEntry z, string name = null)
{
name = z.FullName;
// Some paths mistakenly start with DirectorySepChar in the msapp,
- // We add _ to it when writing so that windows can handle it correctly.
+ // We add _ to it when writing so that windows can handle it correctly.
if (z.FullName.StartsWith(Path.DirectorySeparatorChar.ToString()))
name = FilenameLeadingUnderscore + z.FullName;
}
@@ -113,7 +113,7 @@ public static FileEntry FromZip(ZipArchiveEntry z, string name = null)
public const char FilenameLeadingUnderscore = '_';
- // Map from path in .msapp to type.
+ // Map from path in .msapp to type.
internal static Dictionary _fileKinds = new(StringComparer.OrdinalIgnoreCase)
{
{"Entities.json", FileKind.OldEntityJSon },
@@ -160,7 +160,7 @@ internal static FileKind TriageKind(FilePath fullname)
return kind;
}
- // Source?
+ // Source?
if (fullname.StartsWith(@"Controls", StringComparison.OrdinalIgnoreCase))
{
return FileKind.ControlSrc;
@@ -175,7 +175,7 @@ internal static FileKind TriageKind(FilePath fullname)
return FileKind.TestSrc;
}
- // Resource
+ // Resource
if (fullname.StartsWith(@"Assets", StringComparison.OrdinalIgnoreCase))
{
return FileKind.Asset;
diff --git a/src/PAModel/Serializers/MsAppSerializer.cs b/src/PAModel/Serializers/MsAppSerializer.cs
index 59140215..5e894137 100644
--- a/src/PAModel/Serializers/MsAppSerializer.cs
+++ b/src/PAModel/Serializers/MsAppSerializer.cs
@@ -16,7 +16,7 @@
namespace Microsoft.PowerPlatform.Formulas.Tools;
-// Read/Write to an .msapp file.
+// Read/Write to an .msapp file.
internal static class MsAppSerializer
{
public const string ConnectionInstanceIDPropertyName = "connectionInstanceId";
@@ -57,13 +57,10 @@ private static string AsString(ZipArchiveEntry entry)
public static CanvasDocument Load(Stream streamToMsapp, ErrorContainer errors)
{
- if (streamToMsapp == null)
- {
- throw new ArgumentNullException(nameof(streamToMsapp));
- }
+ ArgumentNullException.ThrowIfNull(streamToMsapp);
- // Read raw files.
- // Apply transforms.
+ // Read raw files.
+ // Apply transforms.
var app = new CanvasDocument
{
_checksum = new ChecksumJson(), // default empty. Will get overwritten if the file is present.
@@ -288,7 +285,7 @@ public static CanvasDocument Load(Stream streamToMsapp, ErrorContainer errors)
var isNullOrOlderChecksum = app._checksum.ServerStampedChecksum == null || ChecksumMaker.GetChecksumVersion(app._checksum.ServerStampedChecksum) < ChecksumMaker.Version;
if (!isNullOrOlderChecksum && app._checksum.ServerStampedChecksum != currentChecksum.wholeChecksum)
{
- // The server checksum doesn't match the actual contents.
+ // The server checksum doesn't match the actual contents.
// likely has been tampered.
errors.ChecksumMismatch("Checksum doesn't match on extract.");
if (app._checksum.ServerPerFileChecksums != null)
@@ -316,7 +313,7 @@ public static CanvasDocument Load(Stream streamToMsapp, ErrorContainer errors)
app._checksum.ClientStampedChecksum = currentChecksum.wholeChecksum;
app._checksum.ClientPerFileChecksums = currentChecksum.perFileChecksum;
- // Normalize logo filename.
+ // Normalize logo filename.
app.TransformLogoOnLoad();
if (!string.IsNullOrEmpty(app._properties.LibraryDependencies))
@@ -339,7 +336,7 @@ public static CanvasDocument Load(Stream streamToMsapp, ErrorContainer errors)
{
var serializedID = JsonSerializer.Serialize(connectionInstanceID);
- // Mapping the connection key to the serializedID and adding it to _entropy
+ // Mapping the connection key to the serializedID and adding it to _entropy
app._entropy.LocalConnectionIDReferences.Add(connectionJson.Key, serializedID);
// Basically making sure conn instance id is not added to app._connections
@@ -422,8 +419,8 @@ public static CanvasDocument Load(Stream streamToMsapp, ErrorContainer errors)
if (dcSources?.DataSources != null)
{
- // Component Data sources only appear if the data component is actually
- // used as a data source in this app.
+ // Component Data sources only appear if the data component is actually
+ // used as a data source in this app.
foreach (var x in dcSources.DataSources)
{
if (x.Type != DataComponentSourcesJson.NativeCDSDataSourceInfo)
@@ -461,7 +458,7 @@ internal static void AddAssetFile(this CanvasDocument app, FileEntry entry)
app._assetFiles.Add(entry.Name, entry);
}
- // Write back out to a msapp file.
+ // Write back out to a msapp file.
public static void SaveAsMsApp(CanvasDocument app, string fullPathToMsApp, ErrorContainer errors, bool isValidation = false)
{
try
@@ -665,11 +662,10 @@ private static IEnumerable GetMsAppFiles(this CanvasDocument app, Err
// "DataComponent" data sources are not part of DataSource.json, and instead in their own file
var dataSources = new DataSourcesJson
{
- DataSources = app.GetDataSources()
+ DataSources = [.. app.GetDataSources()
.SelectMany(x => x.Value)
.Where(x => !x.IsDataComponent)
- .OrderBy(app._entropy.GetOrder)
- .ToArray()
+ .OrderBy(app._entropy.GetOrder)]
};
yield return ToFile(FileKind.DataSources, dataSources);
@@ -746,12 +742,12 @@ private static IEnumerable GetMsAppFiles(this CanvasDocument app, Err
}
}
- var pcfTemplates = app._templates.PcfTemplates ?? Array.Empty();
- app._templates = new TemplatesJson()
+ var pcfTemplates = app._templates.PcfTemplates ?? [];
+ app._templates = new TemplatesJson
{
- ComponentTemplates = componentTemplates.Any() ? componentTemplates.OrderBy(app._entropy.GetComponentOrder).ToArray() : null,
- UsedTemplates = app._templates.UsedTemplates.OrderBy(app._entropy.GetOrder).ToArray(),
- PcfTemplates = pcfTemplates.Any() ? pcfTemplates.OrderBy(app._entropy.GetPcfVersioning).ToArray() : null
+ ComponentTemplates = componentTemplates.Any() ? [.. componentTemplates.OrderBy(app._entropy.GetComponentOrder)] : null,
+ UsedTemplates = [.. app._templates.UsedTemplates.OrderBy(app._entropy.GetOrder)],
+ PcfTemplates = pcfTemplates.Any() ? [.. pcfTemplates.OrderBy(app._entropy.GetPcfVersioning)] : null
};
yield return ToFile(FileKind.Templates, app._templates);
@@ -787,7 +783,7 @@ private static IEnumerable GetMsAppFiles(this CanvasDocument app, Err
DataComponentDefinitionKey = manifest.DataComponentDefinitionKey
};
- // Rehydrate fields.
+ // Rehydrate fields.
template.DataComponentDefinitionKey.ControlUniqueId = controlId;
dcTemplate.Add(template);
@@ -796,12 +792,10 @@ private static IEnumerable GetMsAppFiles(this CanvasDocument app, Err
if (componentsMetadata.Count > 0)
{
- // If the components file is present, then write out all files.
+ // If the components file is present, then write out all files.
yield return ToFile(FileKind.ComponentsMetadata, new ComponentsMetadataJson
{
- Components = componentsMetadata
- .OrderBy(app._entropy.GetOrder)
- .ToArray()
+ Components = [.. componentsMetadata.OrderBy(app._entropy.GetOrder)]
});
}
@@ -809,14 +803,12 @@ private static IEnumerable GetMsAppFiles(this CanvasDocument app, Err
{
yield return ToFile(FileKind.DataComponentTemplates, new DataComponentTemplatesJson
{
- ComponentTemplates = dcTemplate
- .OrderBy(app._entropy.GetOrder)
- .ToArray()
+ ComponentTemplates = [.. dcTemplate.OrderBy(app._entropy.GetOrder)]
});
}
- // Rehydrate the DataComponent DataSource file.
+ // Rehydrate the DataComponent DataSource file.
{
var ds =
from item in app.GetDataSources().SelectMany(x => x.Value).Where(x => x.IsDataComponent)
diff --git a/src/PAModel/Serializers/SourceSerializer.cs b/src/PAModel/Serializers/SourceSerializer.cs
index a92bf0de..1bb13b8f 100644
--- a/src/PAModel/Serializers/SourceSerializer.cs
+++ b/src/PAModel/Serializers/SourceSerializer.cs
@@ -18,7 +18,7 @@
namespace Microsoft.PowerPlatform.Formulas.Tools;
-// Read/Write to a source format.
+// Read/Write to a source format.
internal static partial class SourceSerializer
{
// 1 - .pa1 format
@@ -37,9 +37,9 @@ internal static partial class SourceSerializer
// 14 - Yaml DoubleQuote escape
// 15 - Use dictionary for templates
// 16 - Group Control transform
- // 17 - Moved PublishOrderIndex entirely to Entropy
- // 18 - AppChecker result is not part of entropy (See change 0.5 in this list)
- // 19 - Switch extension to .fx.yaml
+ // 17 - Moved PublishOrderIndex entirely to Entropy
+ // 18 - AppChecker result is not part of entropy (See change 0.5 in this list)
+ // 19 - Switch extension to .fx.yaml
// 20 - Only load themes that match the specified theme name
// 21 - Resources.json is sharded into individual json files for non-local resources.
// 22 - AppTest is sharded into individual TestSuite.fx.yaml files in Src/Tests directory.
@@ -50,7 +50,7 @@ internal static partial class SourceSerializer
// Layout is:
// src\
// DataSources\
- // Other\ (all unrecognized files)
+ // Other\ (all unrecognized files)
public const string CodeDir = "Src";
public const string AssetsDir = "Assets";
public static readonly string TestDir = Path.Combine("Src", "Tests");
@@ -98,8 +98,8 @@ public static CanvasDocument LoadFromSource(string directory2, ErrorContainer er
var app = new CanvasDocument();
string appInsightsInstrumentationKey = null;
- // Do the manifest check (and version check) first.
- // MAnifest lives in top-level directory.
+ // Do the manifest check (and version check) first.
+ // MAnifest lives in top-level directory.
foreach (var file in dir.EnumerateFiles("", "*.json"))
{
switch (file.Kind)
@@ -191,7 +191,7 @@ public static CanvasDocument LoadFromSource(string directory2, ErrorContainer er
// The resource entries for sample data is sharded into individual json files.
// Add each of these entries back into Resources.json
var resources = new List();
- app._resourcesJson = new ResourcesJson() { Resources = Array.Empty() };
+ app._resourcesJson = new ResourcesJson { Resources = [] };
foreach (var file in dir.EnumerateFiles(AssetsDir, "*", false))
{
var fileEntry = file.ToFileEntry();
@@ -205,7 +205,7 @@ public static CanvasDocument LoadFromSource(string directory2, ErrorContainer er
// Add the resources from sharded files to _resourcesJson.Resources
if (resources.Count > 0)
{
- app._resourcesJson.Resources = resources.ToArray();
+ app._resourcesJson.Resources = [.. resources];
}
// We have processed all the json files in Assets directory, now iterate through all the files to add the asset files.
@@ -237,7 +237,7 @@ public static CanvasDocument LoadFromSource(string directory2, ErrorContainer er
foreach (var file in dir.EnumerateFiles(OtherDir))
{
- // Special files like Header / Properties
+ // Special files like Header / Properties
switch (file.Kind)
{
case FileKind.Unknown:
@@ -251,14 +251,14 @@ public static CanvasDocument LoadFromSource(string directory2, ErrorContainer er
break;
}
- } // each loose file in '\other'
+ } // each loose file in '\other'
LoadDataSources(app, dir, errors);
LoadSourceFiles(app, dir, templateDefaults, errors);
foreach (var file in dir.EnumerateFiles(ConnectionDir))
{
- // Special files like Header / Properties
+ // Special files like Header / Properties
switch (file.Kind)
{
case FileKind.Connections:
@@ -272,7 +272,7 @@ public static CanvasDocument LoadFromSource(string directory2, ErrorContainer er
}
- // Defaults.
+ // Defaults.
// - DynamicTypes.Json, Resources.Json , Templates.Json - could all be empty
// - Themes.json- default to
@@ -335,7 +335,7 @@ private static void LoadTemplateFiles(ErrorContainer errors, CanvasDocument app,
// Also add Screen and App templates (not xml, constructed in code on the server)
GlobalTemplates.AddCodeOnlyTemplates(new TemplateStore(), loadedTemplates, app._properties.DocumentAppType);
- app._templates = new TemplatesJson() { UsedTemplates = templateList.ToArray(), PcfTemplates = pcfTemplateConversions.ToArray() };
+ app._templates = new TemplatesJson() { UsedTemplates = [.. templateList], PcfTemplates = [.. pcfTemplateConversions] };
}
private static void LoadPcfControlTemplateFiles(ErrorContainer errors, CanvasDocument app, string paControlTemplatesPath)
@@ -356,10 +356,10 @@ private static void LoadCustomPagesSchemaMetadata(CanvasDocument app, string cus
}
}
- // The publish info points to the logo file. Grab it from the unknowns.
+ // The publish info points to the logo file. Grab it from the unknowns.
private static void GetLogoFile(this CanvasDocument app)
{
- // Logo file.
+ // Logo file.
if (!string.IsNullOrEmpty(app._publishInfo?.LogoFileName))
{
var key = FilePath.FromMsAppPath(app._publishInfo.LogoFileName);
@@ -502,7 +502,7 @@ private static void AddControl(CanvasDocument app, string filePath, bool isCompo
}
catch (DocumentException)
{
- // On DocumentException, continue looking for errors in other files.
+ // On DocumentException, continue looking for errors in other files.
}
}
@@ -511,7 +511,7 @@ public static Dictionary ReadTemplates(TemplatesJson te
throw new NotImplementedException();
}
- // Write out to a directory (this shards it)
+ // Write out to a directory (this shards it)
public static void SaveAsSource(CanvasDocument app, string directory2, ErrorContainer errors)
{
var dir = new DirectoryWriter(directory2);
@@ -621,7 +621,7 @@ public static void SaveAsSource(CanvasDocument app, string directory2, ErrorCont
WriteDataSources(dir, app, errors);
- // Loose files.
+ // Loose files.
foreach (var file in app._unknownFiles.Values)
{
// Standardize the .json files so they're deterministic and comparable
@@ -674,14 +674,14 @@ private static void WriteDataSources(DirectoryWriter dir, CanvasDocument app, Er
{
var untrackedLdr = app._dataSourceReferences?.Select(x => x.Key)?.ToList() ?? new List();
- // Data Sources - write out each individual source.
+ // Data Sources - write out each individual source.
var filenames = new HashSet();
var dataSourceDefinitions = new Dictionary>();
foreach (var kvp in app.GetDataSources())
{
- // Filename doesn't actually matter, but careful to avoid collisions and overwriting.
- // Also be deterministic.
+ // Filename doesn't actually matter, but careful to avoid collisions and overwriting.
+ // Also be deterministic.
var filename = kvp.Key + ".json";
if (!filenames.Add(filename.ToLower()))
@@ -865,7 +865,7 @@ private static void LoadDataSources(CanvasDocument app, DirectoryReader director
}
else
{
- // create a new one in case UnusedDataSources is not of type Dictionary
+ // create a new one in case UnusedDataSources is not of type Dictionary
localDatabaseReferenceJson.dataSources = tableDef.UnusedDataSources.ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
}
@@ -961,7 +961,7 @@ private static void LoadDataSources(CanvasDocument app, DirectoryReader director
// CDS View entities have Names that start with the environment guid (datasetname)
// This trims that from the start of the name so that all the environment-specific info
- // can be moved to the /pkg directory
+ // can be moved to the /pkg directory
private static void TrimViewNames(IEnumerable dataSourceEntries, string dataSetName)
{
foreach (var ds in dataSourceEntries.Where(ds => ds.Type == "ViewInfo"))
@@ -1009,7 +1009,7 @@ private static void WriteTopParent(
{
foreach (var child in ir.Children)
{
- WriteTopParent(dir, app, child.Properties.FirstOrDefault(x => x.Identifier == "DisplayName").Expression.Expression.Trim(new char[] { '"' }), child, subDir, controlName);
+ WriteTopParent(dir, app, child.Properties.FirstOrDefault(x => x.Identifier == "DisplayName").Expression.Expression.Trim(['"']), child, subDir, controlName);
}
// Clear the children since they have already been sharded into their individual files.
diff --git a/src/PAModel/Serializers/TransformResourceJson.cs b/src/PAModel/Serializers/TransformResourceJson.cs
index 5156f85a..c88859ba 100644
--- a/src/PAModel/Serializers/TransformResourceJson.cs
+++ b/src/PAModel/Serializers/TransformResourceJson.cs
@@ -54,7 +54,8 @@ public static void AddLocalAssetEntriesToResourceJson(this CanvasDocument app)
localFileResourceJsonEntries.Add(GenerateResourceJsonEntryFromAssetFile(file.Key));
}
}
- app._resourcesJson.Resources = app._resourcesJson.Resources.Concat(localFileResourceJsonEntries).ToArray();
+
+ app._resourcesJson.Resources = [.. app._resourcesJson.Resources.Concat(localFileResourceJsonEntries)];
// Bring the order of resourceJson back to avoid checksum violation.
if (app._entropy?.ResourcesJsonIndices != null && app._entropy.ResourcesJsonIndices.Count > 0)
@@ -70,7 +71,7 @@ public static void AddLocalAssetEntriesToResourceJson(this CanvasDocument app)
// Handle the cases when some new files were added to the asset folder offline. The entries for the new assets would go at the end, after all the ordered resources have been added.
orderedResourcesList.AddRange(app._resourcesJson.Resources.Where(x => !app._entropy.ResourcesJsonIndices.ContainsKey(Entropy.GetResourcesJsonIndicesKey(x))));
- app._resourcesJson.Resources = orderedResourcesList.ToArray();
+ app._resourcesJson.Resources = [.. orderedResourcesList];
}
}
diff --git a/src/PAModel/SourceFile.cs b/src/PAModel/SourceFile.cs
index d8b80e9b..8e73f1cf 100644
--- a/src/PAModel/SourceFile.cs
+++ b/src/PAModel/SourceFile.cs
@@ -48,7 +48,7 @@ internal string GetMsAppFilename()
private IEnumerable Flatten(ControlInfoJson.Item control)
{
- return control.Children?.Concat(control.Children.SelectMany(Flatten)) ?? Enumerable.Empty();
+ return control.Children?.Concat(control.Children.SelectMany(Flatten)) ?? [];
}
public IEnumerable Flatten()
diff --git a/src/PAModel/SourceTransforms/ComponentDefinitionTransform.cs b/src/PAModel/SourceTransforms/ComponentDefinitionTransform.cs
index 9789eeb7..84d739be 100644
--- a/src/PAModel/SourceTransforms/ComponentDefinitionTransform.cs
+++ b/src/PAModel/SourceTransforms/ComponentDefinitionTransform.cs
@@ -15,23 +15,15 @@ namespace Microsoft.PowerPlatform.Formulas.Tools.SourceTransforms;
/// The reverse is true for writing to msapp
/// This must always be run before the ComponentInstanceTransform in both directions
///
-internal class ComponentDefinitionTransform
+internal class ComponentDefinitionTransform(
+ ErrorContainer errors,
+ TemplateStore templateStore,
+ ComponentInstanceTransform componentInstanceTransform)
{
- private readonly TemplateStore _templateStore;
- private readonly ComponentInstanceTransform _componentInstanceTransform;
- private readonly ErrorContainer _errors;
-
- public ComponentDefinitionTransform(ErrorContainer errors, TemplateStore templateStore, ComponentInstanceTransform componentInstanceTransform)
- {
- _templateStore = templateStore;
- _componentInstanceTransform = componentInstanceTransform;
- _errors = errors;
- }
-
public void AfterRead(BlockNode control)
{
var templateName = control.Name?.Kind?.TypeName ?? string.Empty;
- if (!_templateStore.TryGetTemplate(templateName, out var componentTemplate) ||
+ if (!templateStore.TryGetTemplate(templateName, out var componentTemplate) ||
!(componentTemplate.IsComponentTemplate ?? false))
{
return;
@@ -52,10 +44,10 @@ public void AfterRead(BlockNode control)
}
var controlName = control.Name.Identifier;
- if (!_templateStore.TryRenameTemplate(templateName, controlName))
+ if (!templateStore.TryRenameTemplate(templateName, controlName))
return;
- _componentInstanceTransform.ComponentRenames.Add(templateName, controlName);
+ componentInstanceTransform.ComponentRenames.Add(templateName, controlName);
control.Name.Kind.TypeName = kindName;
}
@@ -70,21 +62,21 @@ public void BeforeWrite(BlockNode control)
return;
}
- if (!_templateStore.TryGetTemplate(controlName, out var componentTemplate) ||
+ if (!templateStore.TryGetTemplate(controlName, out var componentTemplate) ||
!(componentTemplate.IsComponentTemplate ?? false))
{
- _errors.ValidationError($"Unable to find template for component {controlName}");
+ errors.ValidationError($"Unable to find template for component {controlName}");
throw new DocumentException();
}
var originalTemplateName = componentTemplate.Name;
- if (!_templateStore.TryRenameTemplate(controlName, originalTemplateName))
+ if (!templateStore.TryRenameTemplate(controlName, originalTemplateName))
{
- _errors.ValidationError($"Unable to update template for component {controlName}, id {originalTemplateName}");
+ errors.ValidationError($"Unable to update template for component {controlName}, id {originalTemplateName}");
throw new DocumentException();
}
- _componentInstanceTransform.ComponentRenames.Add(controlName, originalTemplateName);
+ componentInstanceTransform.ComponentRenames.Add(controlName, originalTemplateName);
control.Name.Kind.TypeName = originalTemplateName;
}
}
diff --git a/src/PAModel/SourceTransforms/ComponentInstanceTransform.cs b/src/PAModel/SourceTransforms/ComponentInstanceTransform.cs
index a6213cc2..6ca05183 100644
--- a/src/PAModel/SourceTransforms/ComponentInstanceTransform.cs
+++ b/src/PAModel/SourceTransforms/ComponentInstanceTransform.cs
@@ -5,18 +5,12 @@
namespace Microsoft.PowerPlatform.Formulas.Tools.SourceTransforms;
-internal class ComponentInstanceTransform : IControlTemplateTransform
+internal class ComponentInstanceTransform(ErrorContainer errors) : IControlTemplateTransform
{
// Key is name in source, value is name in target
// For AfterRead, that's ComponentID => ComponentName
// For BeforeWrite, that's ComponentName => ComponentID
internal Dictionary ComponentRenames = new();
- private readonly ErrorContainer _errors;
-
- public ComponentInstanceTransform(ErrorContainer errors)
- {
- _errors = errors;
- }
public IEnumerable TargetTemplates => ComponentRenames.Keys;
@@ -39,7 +33,7 @@ private void DoRename(BlockNode control)
}
else
{
- _errors.ValidationWarning("Renaming component instance but unable to find target name");
+ errors.ValidationWarning("Renaming component instance but unable to find target name");
}
}
}
diff --git a/src/PAModel/SourceTransforms/DefaultValuesTransform.cs b/src/PAModel/SourceTransforms/DefaultValuesTransform.cs
index 82ed9158..8aed5a5f 100644
--- a/src/PAModel/SourceTransforms/DefaultValuesTransform.cs
+++ b/src/PAModel/SourceTransforms/DefaultValuesTransform.cs
@@ -10,19 +10,11 @@
namespace Microsoft.PowerPlatform.Formulas.Tools.SourceTransforms;
-internal class DefaultValuesTransform
+internal class DefaultValuesTransform(
+ Dictionary templateStore,
+ Theme theme,
+ EditorStateStore stateStore)
{
- private readonly EditorStateStore _controlStore;
- private readonly Theme _theme;
- private readonly Dictionary _templateStore;
-
- public DefaultValuesTransform(Dictionary templateStore, Theme theme, EditorStateStore stateStore)
- {
- _controlStore = stateStore;
- _templateStore = templateStore;
- _theme = theme;
- }
-
public void AfterRead(BlockNode node, bool inResponsiveContext)
{
var controlName = node.Name.Identifier;
@@ -31,13 +23,13 @@ public void AfterRead(BlockNode node, bool inResponsiveContext)
var styleName = $"default{templateName.FirstCharToUpper()}Style";
- if (_controlStore.TryGetControlState(controlName, out var controlState))
+ if (stateStore.TryGetControlState(controlName, out var controlState))
styleName = controlState.StyleName;
- if (!_templateStore.TryGetValue(templateName, out var template))
+ if (!templateStore.TryGetValue(templateName, out var template))
template = null;
- var defaultHelper = new DefaultRuleHelper(styleName, template, templateName, variantName, _theme, inResponsiveContext);
+ var defaultHelper = new DefaultRuleHelper(styleName, template, templateName, variantName, theme, inResponsiveContext);
foreach (var property in node.Properties.ToList())
{
var propName = property.Identifier;
@@ -55,17 +47,17 @@ public void BeforeWrite(BlockNode node, bool inResponsiveContext)
var styleName = $"default{templateName.FirstCharToUpper()}Style";
HashSet propNames = null;
- if (_controlStore.TryGetControlState(controlName, out var controlState) && controlState.Properties != null)
+ if (stateStore.TryGetControlState(controlName, out var controlState) && controlState.Properties != null)
{
styleName = controlState.StyleName;
propNames = new HashSet(controlState.Properties.Select(state => state.PropertyName)
- .Concat(controlState.DynamicProperties?.Where(state => state.Property != null).Select(state => state.PropertyName) ?? Enumerable.Empty()));
+ .Concat(controlState.DynamicProperties?.Where(state => state.Property != null).Select(state => state.PropertyName) ?? []));
}
- if (!_templateStore.TryGetValue(templateName, out var template))
+ if (!templateStore.TryGetValue(templateName, out var template))
template = null;
- var defaults = new DefaultRuleHelper(styleName, template, templateName, variantName, _theme, inResponsiveContext).GetDefaultRules();
+ var defaults = new DefaultRuleHelper(styleName, template, templateName, variantName, theme, inResponsiveContext).GetDefaultRules();
foreach (var property in node.Properties)
{
defaults.Remove(property.Identifier);
diff --git a/src/PAModel/SourceTransforms/GroupControlTransform.cs b/src/PAModel/SourceTransforms/GroupControlTransform.cs
index 3796ee97..13fb3d8e 100644
--- a/src/PAModel/SourceTransforms/GroupControlTransform.cs
+++ b/src/PAModel/SourceTransforms/GroupControlTransform.cs
@@ -16,21 +16,10 @@ namespace Microsoft.PowerPlatform.Formulas.Tools.SourceTransforms;
/// since the transform deals with controls that are peers within the IR.
/// As such, it needs to be run on the Parent of the group control, not on the group control itself.
///
-internal class GroupControlTransform
+internal class GroupControlTransform(ErrorContainer errors, EditorStateStore editorStateStore, Entropy entropy)
{
private const string GroupControlTemplateName = "group";
- private readonly EditorStateStore _editorStateStore;
- private readonly ErrorContainer _errors;
- private readonly Entropy _entropy;
-
- public GroupControlTransform(ErrorContainer errors, EditorStateStore editorStateStore, Entropy entropy)
- {
- _editorStateStore = editorStateStore;
- _errors = errors;
- _entropy = entropy;
- }
-
public void AfterRead(BlockNode control)
{
var groupControls = GetGroupControlChildren(control);
@@ -41,18 +30,18 @@ public void AfterRead(BlockNode control)
foreach (var groupControl in groupControls)
{
var groupControlName = groupControl.Name.Identifier;
- if (!_editorStateStore.TryGetControlState(groupControlName, out var groupControlState))
+ if (!editorStateStore.TryGetControlState(groupControlName, out var groupControlState))
{
- _errors.ValidationError($"Group control state is missing for {groupControlName}");
+ errors.ValidationError($"Group control state is missing for {groupControlName}");
throw new DocumentException();
}
if (groupControlState.GroupedControlsKey.Count == 0)
{
- _errors.ValidationWarning($"Group control state is empty for {groupControlName}");
+ errors.ValidationWarning($"Group control state is empty for {groupControlName}");
}
- _entropy.AddGroupControl(groupControlState);
+ entropy.AddGroupControl(groupControlState);
foreach (var childKey in groupControlState.GroupedControlsKey)
{
@@ -63,7 +52,7 @@ public void AfterRead(BlockNode control)
}
else
{
- _errors.ValidationWarning($"Group control {groupControlName}'s state refers to non-existent child {childKey}");
+ errors.ValidationWarning($"Group control {groupControlName}'s state refers to non-existent child {childKey}");
}
}
groupControlState.GroupedControlsKey = null;
@@ -80,7 +69,7 @@ public void BeforeWrite(BlockNode control)
foreach (var groupControl in groupControls)
{
var groupControlName = groupControl.Name.Identifier;
- if (!_editorStateStore.TryGetControlState(groupControlName, out var groupControlState))
+ if (!editorStateStore.TryGetControlState(groupControlName, out var groupControlState))
{
// There may not be editorstate present for this. Create a fake state to use
groupControlState = new ControlState()
@@ -91,19 +80,19 @@ public void BeforeWrite(BlockNode control)
IsGroupControl = true,
ExtensionData = ControlInfoJson.Item.CreateDefaultExtensionData()
};
- _editorStateStore.TryAddControl(groupControlState);
+ editorStateStore.TryAddControl(groupControlState);
}
var groupedControlNames = groupControl.Children
.Select(child => child.Name.Identifier)
- .OrderBy(childName => _entropy.GetGroupControlOrder(groupControlName, childName));
+ .OrderBy(childName => entropy.GetGroupControlOrder(groupControlName, childName));
// Add the group controls to the parent's children instead
foreach (var child in groupControl.Children)
{
control.Children.Add(child);
}
groupControl.Children = new List();
- groupControlState.GroupedControlsKey = groupedControlNames.ToList();
+ groupControlState.GroupedControlsKey = [.. groupedControlNames];
}
}
diff --git a/src/PAModel/packages.lock.json b/src/PAModel/packages.lock.json
index 56aee619..f16e14db 100644
--- a/src/PAModel/packages.lock.json
+++ b/src/PAModel/packages.lock.json
@@ -1,12 +1,12 @@
{
"version": 1,
"dependencies": {
- "net7.0": {
+ "net8.0": {
"Newtonsoft.Json": {
"type": "Direct",
"requested": "[13.0.1, )",
- "resolved": "13.0.3",
- "contentHash": "HrC5BXdl00IP9zeV+0Z848QWPAoCr9P3bDEZguI+gkLcBKAOxix/tLEAAHC+UvDNPv4a2d18lOReHMOagPa+zQ=="
+ "resolved": "13.0.1",
+ "contentHash": "ppPFpBcvxdsfUonNcvITKqLl3bqxWbDCZIzDWHzjpdAHRFfZe0Dw9HmA0+za13IdyrgJwpkDTDA9fHaxOrt20A=="
},
"System.Text.Encodings.Web": {
"type": "Direct",
@@ -20,8 +20,8 @@
"System.Text.Json": {
"type": "Direct",
"requested": "[6.0.0, )",
- "resolved": "6.0.9",
- "contentHash": "2j16oUgtIzl7Xtk7demG0i/v5aU/ZvULcAnJvPb63U3ZhXJ494UYcxuEj5Fs49i3XDrk5kU/8I+6l9zRCw3cJw==",
+ "resolved": "6.0.0",
+ "contentHash": "zaJsHfESQvJ11vbXnNlkrR46IaMULk/gHxYsJphzSF+07kTjPHv+Oc14w6QEOfo3Q4hqLJgStUaYB9DBl0TmWg==",
"dependencies": {
"System.Runtime.CompilerServices.Unsafe": "6.0.0",
"System.Text.Encodings.Web": "6.0.0"
@@ -119,4 +119,4 @@
}
}
}
-}
+}
\ No newline at end of file
diff --git a/src/PAModelTests/DefaultValuesTransformTests.cs b/src/PAModelTests/DefaultValuesTransformTests.cs
index 05eb263d..91d36572 100644
--- a/src/PAModelTests/DefaultValuesTransformTests.cs
+++ b/src/PAModelTests/DefaultValuesTransformTests.cs
@@ -79,7 +79,7 @@ private static EditorStateStore getEditorStateStore()
private static Theme getTheme()
{
var CustomTheme = new CustomThemeJson() { name = "SomeCustomTheme" };
- var themeJson = new ThemesJson() { CurrentTheme = "SomeTheme", CustomThemes = new[] { CustomTheme } };
+ var themeJson = new ThemesJson() { CurrentTheme = "SomeTheme", CustomThemes = [CustomTheme] };
return new Theme(themeJson);
}
diff --git a/src/PAModelTests/EntropyTests.cs b/src/PAModelTests/EntropyTests.cs
index e9097ef0..32532cf0 100644
--- a/src/PAModelTests/EntropyTests.cs
+++ b/src/PAModelTests/EntropyTests.cs
@@ -93,7 +93,7 @@ public void TestGetResourcesJSONIndicesKeyNullException(string filename)
errors.ThrowOnErrors();
// passing null resource in resourcesJson
- msapp._resourcesJson = new ResourcesJson() { Resources = new ResourceJson[] { null } };
+ msapp._resourcesJson = new ResourcesJson() { Resources = [null] };
TransformResourceJson.PersistOrderingOfResourcesJsonEntries(msapp);
}
diff --git a/src/PAModelTests/NameCollisionTests.cs b/src/PAModelTests/NameCollisionTests.cs
index e6246eb8..8d88c749 100644
--- a/src/PAModelTests/NameCollisionTests.cs
+++ b/src/PAModelTests/NameCollisionTests.cs
@@ -51,7 +51,7 @@ public void TestAssetFileRename()
doc._assetFiles.Add(new FilePath("Images", "image_1.png"), new FileEntry());
- doc._resourcesJson = new ResourcesJson() { Resources = new ResourceJson[] { resource1, resource2, resource3 } };
+ doc._resourcesJson = new ResourcesJson() { Resources = [resource1, resource2, resource3] };
var errorContainer = new ErrorContainer();
doc.StabilizeAssetFilePaths(errorContainer);
@@ -197,7 +197,7 @@ public void TestAssetPathCollision()
};
doc._assetFiles.Add(new FilePath("Images", "Image2.png"), new FileEntry());
- doc._resourcesJson = new ResourcesJson() { Resources = new ResourceJson[] { resource1, resource2 } };
+ doc._resourcesJson = new ResourcesJson() { Resources = [resource1, resource2] };
var errorContainer = new ErrorContainer();
doc.StabilizeAssetFilePaths(errorContainer);
@@ -262,7 +262,7 @@ public void TestAssetFileCollision()
// Second Asset file
doc._assetFiles.Add(new FilePath("Images", "0012.png"), f2);
- doc._resourcesJson = new ResourcesJson() { Resources = new ResourceJson[] { resource1, resource2 } };
+ doc._resourcesJson = new ResourcesJson() { Resources = [resource1, resource2] };
var errorContainer = new ErrorContainer();
doc.StabilizeAssetFilePaths(errorContainer);
diff --git a/src/PAModelTests/ReadTransformTests.cs b/src/PAModelTests/ReadTransformTests.cs
index ceff8c14..be449428 100644
--- a/src/PAModelTests/ReadTransformTests.cs
+++ b/src/PAModelTests/ReadTransformTests.cs
@@ -45,7 +45,7 @@ public void TestNullResource()
doc._assetFiles.Add(new FilePath("Images", "Image.png"), new FileEntry());
// passing null resource in resourcesJson
- doc._resourcesJson = new ResourcesJson() { Resources = new ResourceJson[] { resource1, null } };
+ doc._resourcesJson = new ResourcesJson() { Resources = [resource1, null] };
var errorContainer = new ErrorContainer();
doc.StabilizeAssetFilePaths(errorContainer);
diff --git a/src/PAModelTests/SmartMergeTests.cs b/src/PAModelTests/SmartMergeTests.cs
index 019e315e..da017d34 100644
--- a/src/PAModelTests/SmartMergeTests.cs
+++ b/src/PAModelTests/SmartMergeTests.cs
@@ -489,7 +489,7 @@ public void PropertiesTest()
(branchBDoc) =>
{
branchBDoc._properties.DocumentLayoutWidth = 2222;
- branchBDoc._properties.AppPreviewFlagsKey = branchBDoc._properties.AppPreviewFlagsKey.Concat(new List() { "NewFlag" }).ToArray();
+ branchBDoc._properties.AppPreviewFlagsKey = [.. branchBDoc._properties.AppPreviewFlagsKey.Concat(new List() { "NewFlag" })];
},
(resultDoc) =>
{
diff --git a/src/Persistence.Tests/Extensions/IYamlDeserializerExtensions.cs b/src/Persistence.Tests/Extensions/IYamlDeserializerExtensions.cs
index ada764e9..776321fc 100644
--- a/src/Persistence.Tests/Extensions/IYamlDeserializerExtensions.cs
+++ b/src/Persistence.Tests/Extensions/IYamlDeserializerExtensions.cs
@@ -9,7 +9,7 @@ internal static class YamlDeserializerExtensions
{
internal static object? DeserializeControl(this IYamlDeserializer deserializer, TextReader yamlReader, Type controlType)
{
- var deserializeMethod = typeof(IYamlDeserializer).GetMethod(nameof(IYamlDeserializer.Deserialize), types: new[] { typeof(TextReader) })!.MakeGenericMethod(controlType);
- return deserializeMethod.Invoke(deserializer, new object[] { yamlReader });
+ var deserializeMethod = typeof(IYamlDeserializer).GetMethod(nameof(IYamlDeserializer.Deserialize), types: [typeof(TextReader)])!.MakeGenericMethod(controlType);
+ return deserializeMethod.Invoke(deserializer, [yamlReader]);
}
}
diff --git a/src/Persistence.Tests/Extensions/NamedObjectAssertionExtensions.cs b/src/Persistence.Tests/Extensions/NamedObjectAssertionExtensions.cs
index d0e92efe..e7670fd1 100644
--- a/src/Persistence.Tests/Extensions/NamedObjectAssertionExtensions.cs
+++ b/src/Persistence.Tests/Extensions/NamedObjectAssertionExtensions.cs
@@ -21,32 +21,21 @@ public static NamedObjectAssertions Should(this NamedObject is in the expected state.
///
[DebuggerNonUserCode]
-public class NamedObjectAssertions
- : NamedObjectAssertions?, string, TValue, NamedObjectAssertions>
- where TValue : notnull
-{
- public NamedObjectAssertions(NamedObject? actualValue)
- : base(actualValue)
- {
- }
-}
+public class NamedObjectAssertions(NamedObject? actualValue)
+ : NamedObjectAssertions?, string, TValue, NamedObjectAssertions>(actualValue)
+ where TValue : notnull;
///
/// Contains a number of methods to assert that a is in the expected state.
///
[DebuggerNonUserCode]
-public class NamedObjectAssertions
- : ReferenceTypeAssertions
+public class NamedObjectAssertions(TNamedObject actualValue)
+ : ReferenceTypeAssertions(actualValue)
where TNamedObject : INamedObject?
where TName : notnull
where TValue : notnull
where TAssertions : NamedObjectAssertions
{
- public NamedObjectAssertions(TNamedObject actualValue)
- : base(actualValue)
- {
- }
-
protected override string Identifier => "NamedObject";
public AndConstraint HaveValueEqual(TValue expected, string because = "", params object[] becauseArgs)
diff --git a/src/Persistence.Tests/Extensions/NamedObjectCollectionAssertionExtensions.cs b/src/Persistence.Tests/Extensions/NamedObjectCollectionAssertionExtensions.cs
index 1265522f..314ee678 100644
--- a/src/Persistence.Tests/Extensions/NamedObjectCollectionAssertionExtensions.cs
+++ b/src/Persistence.Tests/Extensions/NamedObjectCollectionAssertionExtensions.cs
@@ -21,31 +21,21 @@ public static NamedObjectCollectionAssertions Should(this IReadO
/// Contains a number of methods to assert that a is in the expected state.
///
[DebuggerNonUserCode]
-public class NamedObjectCollectionAssertions
- : NamedObjectCollectionAssertions?, TValue, NamedObjectCollectionAssertions>
- where TValue : notnull
-{
- public NamedObjectCollectionAssertions(IReadOnlyNamedObjectCollection? actualValue)
- : base(actualValue)
- {
- }
-}
+public class NamedObjectCollectionAssertions(IReadOnlyNamedObjectCollection? actualValue)
+ : NamedObjectCollectionAssertions?, TValue,
+ NamedObjectCollectionAssertions>(actualValue)
+ where TValue : notnull;
///
/// Contains a number of methods to assert that a is in the expected state.
///
[DebuggerNonUserCode]
-public class NamedObjectCollectionAssertions
- : GenericCollectionAssertions, TAssertions>
+public class NamedObjectCollectionAssertions(TCollection actualValue)
+ : GenericCollectionAssertions, TAssertions>(actualValue)
where TCollection : IReadOnlyNamedObjectCollection?
where TValue : notnull
where TAssertions : NamedObjectCollectionAssertions
{
- public NamedObjectCollectionAssertions(TCollection actualValue)
- : base(actualValue)
- {
- }
-
public AndConstraint ContainNames(params string[] expected)
{
return ContainNames(expected, string.Empty);
@@ -98,16 +88,14 @@ public WhoseNamedObjectConstraint ContainName(
}
[DebuggerNonUserCode]
-public class WhoseNamedObjectConstraint : AndConstraint
+public class WhoseNamedObjectConstraint(
+ TAssertions parentConstraint,
+ NamedObject namedObject)
+ : AndConstraint(parentConstraint)
where TCollection : IReadOnlyNamedObjectCollection?
where TValue : notnull
where TAssertions : NamedObjectCollectionAssertions
{
- public WhoseNamedObjectConstraint(TAssertions parentConstraint, NamedObject namedObject) : base(parentConstraint)
- {
- WhoseNamedObject = namedObject;
- }
-
- public NamedObject WhoseNamedObject { get; }
+ public NamedObject WhoseNamedObject { get; } = namedObject;
public TValue WhoseValue => WhoseNamedObject.Value;
}
diff --git a/src/Persistence.Tests/MsApp/MsappArchiveTests.cs b/src/Persistence.Tests/MsApp/MsappArchiveTests.cs
index 4bc1e76f..982827a1 100644
--- a/src/Persistence.Tests/MsApp/MsappArchiveTests.cs
+++ b/src/Persistence.Tests/MsApp/MsappArchiveTests.cs
@@ -8,9 +8,10 @@
namespace Persistence.Tests.MsApp;
[TestClass]
+[System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1861: Prefer 'static readonly' fields over constant array arguments if the called method is called repeatedly and is not mutating the passed array", Justification = "Obfuscates tests")]
public class MsappArchiveTests : TestBase
{
- [DataRow(new string[] { "abc.txt" }, MsappArchive.Directories.Resources, null, 0, 0)]
+ [DataRow(new[] { "abc.txt" }, MsappArchive.Directories.Resources, null, 0, 0)]
[DataRow(new string[] { "abc.txt", @$"{MsappArchive.Directories.Resources}\", @$"{MsappArchive.Directories.Resources}\abc.txt" }, null, null, 1, 2)]
[DataRow(new string[] { "abc.txt", @$"{MsappArchive.Directories.Resources}\", @$"{MsappArchive.Directories.Resources}\abc.txt" }, null, ".txt", 1, 2)]
[DataRow(new string[] { "abc.txt", "def.txt", @$"{MsappArchive.Directories.Resources}\", @$"{MsappArchive.Directories.Resources}\abc.txt" }, null, ".txt", 2, 3)]
@@ -78,26 +79,27 @@ public void AddEntryTests(string[] entries, string[] expectedEntries)
msappArchive.TryGetEntry("not-exist", out var _).Should().BeFalse();
}
- private static IEnumerable