From ea45219c340c4d8e01abf993f2e438ed8990d51f Mon Sep 17 00:00:00 2001
From: Dave Black <656118+udlose@users.noreply.github.com>
Date: Sat, 7 Mar 2026 16:04:37 -0600
Subject: [PATCH 1/8] Refactor TMModel to proper Dispose pattern
Refactored TMModel.cs to implement the recommended Dispose pattern:
- Replaced original Dispose with public Dispose and protected virtual Dispose(bool).
- Added detailed XML documentation for disposal methods.
- Ensured managed resources are disposed only once via Interlocked.CompareExchange inside the isDisposing branch.
- Moved resource cleanup logic to managed disposal section.
- Suppressed finalization and enabled safe extension for derived classes.
- Structure allows for future unmanaged resource handling.
---
src/TextMateSharp/Model/TMModel.cs | 64 +++++++++++++++++++++++++-----
1 file changed, 53 insertions(+), 11 deletions(-)
diff --git a/src/TextMateSharp/Model/TMModel.cs b/src/TextMateSharp/Model/TMModel.cs
index 341d469..92d6ba7 100644
--- a/src/TextMateSharp/Model/TMModel.cs
+++ b/src/TextMateSharp/Model/TMModel.cs
@@ -838,22 +838,64 @@ public void RemoveModelTokensChangedListener(IModelTokensChangedListener listene
}
}
+ ///
+ /// Releases all resources used by the current instance of the class.
+ ///
+ /// This method should be called when the object is no longer needed to free up
+ /// resources. It is safe to call this method multiple times. After calling this method,
+ /// the object should not be used.
public void Dispose()
{
- if (Interlocked.CompareExchange(ref _isDisposedFlag, 1, 0) != 0)
- return;
-
- // Stop first (acquires _lock internally) without holding listeners. This preserves the global
- // lock ordering _lock -> listeners used elsewhere (e.g. in AddModelTokensChangedListener) and
- // avoids any lock inversion between _lock and listeners.
- Stop();
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
- lock (listeners)
+ ///
+ /// Releases the resources used by the object, enforcing a one-time dispose guard and optionally
+ /// disposing managed resources based on the flag.
+ ///
+ ///
+ /// This method ensures that the dispose logic runs only once, regardless of the value of
+ /// , preventing potential issues with multiple calls. When
+ /// is , it disposes of managed resources in
+ /// addition to any unmanaged resources. When , only unmanaged cleanup would be
+ /// performed (although this implementation currently has no unmanaged resources to release). It is intended
+ /// to be overridden in derived classes to provide custom disposal logic following the same pattern.
+ ///
+ ///
+ /// Indicates whether the method was invoked via an explicit call to or from a
+ /// finalizer/indirect path. If , the method may dispose of both managed and unmanaged
+ /// resources; if , it should only dispose of unmanaged resources.
+ ///
+ protected virtual void Dispose(bool isDisposing)
+ {
+ if (isDisposing)
{
- listeners.Clear();
- }
+ // Dispose managed resources
+ // DESIGN NOTE: The Interlocked.CompareExchange guard is intentionally placed inside the
+ // isDisposing branch, not at the top of this method. Because TMModel is abstract, a derived
+ // class may introduce a finalizer that calls Dispose(false). If the guard were at the top,
+ // a finalizer-first invocation would set the flag and block a subsequent Dispose(true) call,
+ // preventing managed resource cleanup. Placing the guard here ensures that managed disposal
+ // runs exactly once while leaving the unmanaged branch (currently empty) unaffected by the
+ // managed-disposal flag. If unmanaged resources are ever added, a separate guard should be
+ // introduced for that branch.
+ if (Interlocked.CompareExchange(ref _isDisposedFlag, 1, 0) != 0)
+ return;
+
+ // Stop first (acquires _lock internally) without holding listeners. This preserves the global
+ // lock ordering _lock -> listeners used elsewhere (e.g. in AddModelTokensChangedListener) and
+ // avoids any lock inversion between _lock and listeners.
+ Stop();
- GetLines().Dispose();
+ lock (listeners)
+ {
+ listeners.Clear();
+ }
+
+ GetLines().Dispose();
+ }
+ // Free unmanaged resources (none currently)
}
private void Stop()
From d92e9069162d248e9ed17abd5d798bf49c41a179 Mon Sep 17 00:00:00 2001
From: Dave Black <656118+udlose@users.noreply.github.com>
Date: Sat, 7 Mar 2026 17:27:01 -0600
Subject: [PATCH 2/8] Fixes #124 by bringing parity with upstream tm4e
implementation
Strengthen encapsulation and immutability
Several classes changed from public to internal and sealed, with fields and methods updated to internal and readonly where appropriate. GrammarNames made static; SupportedGrammars is now readonly. These changes improve code safety and clarify usage boundaries.
---
src/TextMateSharp.Grammars/GrammarNames.cs | 4 ++--
.../Internal/Grammars/AttributedScopeStack.cs | 11 +++++------
.../Grammars/BalancedBracketSelectors.cs | 12 ++++++------
.../Internal/Grammars/BasicScopeAttributes.cs | 10 +++++-----
.../Grammars/BasicScopeAttributesProvider.cs | 18 +++++++++---------
.../Internal/Matcher/IMatchesName.cs | 2 +-
6 files changed, 28 insertions(+), 29 deletions(-)
diff --git a/src/TextMateSharp.Grammars/GrammarNames.cs b/src/TextMateSharp.Grammars/GrammarNames.cs
index b6ba7db..664cd2b 100644
--- a/src/TextMateSharp.Grammars/GrammarNames.cs
+++ b/src/TextMateSharp.Grammars/GrammarNames.cs
@@ -1,8 +1,8 @@
namespace TextMateSharp.Grammars
{
- internal class GrammarNames
+ internal static class GrammarNames
{
- internal static string[] SupportedGrammars = new string[] {
+ internal static readonly string[] SupportedGrammars = new string[] {
"Asciidoc",
"Bat",
"Clojure",
diff --git a/src/TextMateSharp/Internal/Grammars/AttributedScopeStack.cs b/src/TextMateSharp/Internal/Grammars/AttributedScopeStack.cs
index 9b1f598..11d11b2 100644
--- a/src/TextMateSharp/Internal/Grammars/AttributedScopeStack.cs
+++ b/src/TextMateSharp/Internal/Grammars/AttributedScopeStack.cs
@@ -1,21 +1,20 @@
using System;
using System.Collections.Generic;
-
using TextMateSharp.Themes;
namespace TextMateSharp.Internal.Grammars
{
- public class AttributedScopeStack : IEquatable
+ internal sealed class AttributedScopeStack : IEquatable
{
- public AttributedScopeStack Parent { get; private set; }
- public string ScopePath { get; private set; }
- public int TokenAttributes { get; private set; }
+ internal AttributedScopeStack Parent { get; private set; }
+ internal string ScopePath { get; private set; }
+ internal int TokenAttributes { get; private set; }
private List _cachedScopeNames;
// Precomputed, per-node hash code (persistent structure => safe as long as instances are immutable)
private readonly int _hashCode;
- public AttributedScopeStack(AttributedScopeStack parent, string scopePath, int tokenAttributes)
+ internal AttributedScopeStack(AttributedScopeStack parent, string scopePath, int tokenAttributes)
{
Parent = parent;
ScopePath = scopePath;
diff --git a/src/TextMateSharp/Internal/Grammars/BalancedBracketSelectors.cs b/src/TextMateSharp/Internal/Grammars/BalancedBracketSelectors.cs
index ecc1fb2..0061975 100644
--- a/src/TextMateSharp/Internal/Grammars/BalancedBracketSelectors.cs
+++ b/src/TextMateSharp/Internal/Grammars/BalancedBracketSelectors.cs
@@ -3,10 +3,10 @@
namespace TextMateSharp.Internal.Grammars
{
- public class BalancedBracketSelectors
+ public sealed class BalancedBracketSelectors
{
- private Predicate>[] _balancedBracketScopes;
- private Predicate>[] _unbalancedBracketScopes;
+ private readonly Predicate>[] _balancedBracketScopes;
+ private readonly Predicate>[] _unbalancedBracketScopes;
private bool _allowAny = false;
@@ -18,17 +18,17 @@ public BalancedBracketSelectors(
_unbalancedBracketScopes = CreateUnbalancedBracketScopes(unbalancedBracketScopes);
}
- public bool MatchesAlways()
+ internal bool MatchesAlways()
{
return _allowAny && _unbalancedBracketScopes.Length == 0;
}
- public bool MatchesNever()
+ internal bool MatchesNever()
{
return !_allowAny && _balancedBracketScopes.Length == 0;
}
- public bool Match(List scopes)
+ internal bool Match(List scopes)
{
foreach (var excluder in _unbalancedBracketScopes)
{
diff --git a/src/TextMateSharp/Internal/Grammars/BasicScopeAttributes.cs b/src/TextMateSharp/Internal/Grammars/BasicScopeAttributes.cs
index 05939b3..25a7e17 100644
--- a/src/TextMateSharp/Internal/Grammars/BasicScopeAttributes.cs
+++ b/src/TextMateSharp/Internal/Grammars/BasicScopeAttributes.cs
@@ -4,13 +4,13 @@
namespace TextMateSharp.Internal.Grammars
{
- public class BasicScopeAttributes
+ internal sealed class BasicScopeAttributes
{
- public int LanguageId { get; private set; }
- public int TokenType { get; private set; } /* OptionalStandardTokenType */
- public List ThemeData { get; private set; }
+ internal int LanguageId { get; private set; }
+ internal int TokenType { get; private set; } /* OptionalStandardTokenType */
+ internal List ThemeData { get; private set; }
- public BasicScopeAttributes(
+ internal BasicScopeAttributes(
int languageId,
int tokenType,
List themeData)
diff --git a/src/TextMateSharp/Internal/Grammars/BasicScopeAttributesProvider.cs b/src/TextMateSharp/Internal/Grammars/BasicScopeAttributesProvider.cs
index e6bed5b..597d91a 100644
--- a/src/TextMateSharp/Internal/Grammars/BasicScopeAttributesProvider.cs
+++ b/src/TextMateSharp/Internal/Grammars/BasicScopeAttributesProvider.cs
@@ -7,21 +7,21 @@
namespace TextMateSharp.Internal.Grammars
{
- public class BasicScopeAttributesProvider
+ internal sealed class BasicScopeAttributesProvider
{
private static BasicScopeAttributes _NULL_SCOPE_METADATA = new BasicScopeAttributes(0, 0, null);
private static Regex STANDARD_TOKEN_TYPE_REGEXP = new Regex("\\b(comment|string|regex|meta\\.embedded)\\b");
- private int _initialLanguage;
- private IThemeProvider _themeProvider;
- private Dictionary _cache = new Dictionary();
+ private readonly int _initialLanguage;
+ private readonly IThemeProvider _themeProvider;
+ private readonly Dictionary _cache = new Dictionary();
private BasicScopeAttributes _defaultAttributes;
- private Dictionary _embeddedLanguages;
- private Regex _embeddedLanguagesRegex;
+ private readonly Dictionary _embeddedLanguages;
+ private readonly Regex _embeddedLanguagesRegex;
- public BasicScopeAttributesProvider(int initialLanguage, IThemeProvider themeProvider,
+ internal BasicScopeAttributesProvider(int initialLanguage, IThemeProvider themeProvider,
Dictionary embeddedLanguages)
{
this._initialLanguage = initialLanguage;
@@ -72,12 +72,12 @@ public void OnDidChangeTheme()
new List() { this._themeProvider.GetDefaults() });
}
- public BasicScopeAttributes GetDefaultAttributes()
+ internal BasicScopeAttributes GetDefaultAttributes()
{
return this._defaultAttributes;
}
- public BasicScopeAttributes GetBasicScopeAttributes(string scopeName)
+ internal BasicScopeAttributes GetBasicScopeAttributes(string scopeName)
{
if (scopeName == null)
{
diff --git a/src/TextMateSharp/Internal/Matcher/IMatchesName.cs b/src/TextMateSharp/Internal/Matcher/IMatchesName.cs
index 3c36bfb..a7fd4ff 100644
--- a/src/TextMateSharp/Internal/Matcher/IMatchesName.cs
+++ b/src/TextMateSharp/Internal/Matcher/IMatchesName.cs
@@ -9,7 +9,7 @@ public interface IMatchesName
bool Match(ICollection names, T scopes);
}
- public class NameMatcher : IMatchesName>
+ public sealed class NameMatcher : IMatchesName>
{
public static IMatchesName> Default = new NameMatcher();
From 96e2c5838b1464921ca4b892572b9b9efbd4f933 Mon Sep 17 00:00:00 2001
From: Dave Black <656118+udlose@users.noreply.github.com>
Date: Sat, 7 Mar 2026 17:43:51 -0600
Subject: [PATCH 3/8] Add custom benchmark config for KB memory reporting
Introduced CustomBenchmarksConfig to display memory usage in kilobytes for more precise measurement in benchmark summaries. Applied this config to BigFileTokenizationBenchmark via attribute. Cleaned up using statements and improved formatting.
---
.../BigFileTokenizationBenchmark.cs | 22 ++++++++++++++-----
1 file changed, 16 insertions(+), 6 deletions(-)
diff --git a/src/TextMateSharp.Benchmarks/BigFileTokenizationBenchmark.cs b/src/TextMateSharp.Benchmarks/BigFileTokenizationBenchmark.cs
index 6a0748d..6593b92 100644
--- a/src/TextMateSharp.Benchmarks/BigFileTokenizationBenchmark.cs
+++ b/src/TextMateSharp.Benchmarks/BigFileTokenizationBenchmark.cs
@@ -1,13 +1,14 @@
+using BenchmarkDotNet.Attributes;
+using BenchmarkDotNet.Configs;
+using Perfolizer.Metrology;
using System;
using System.Collections.Generic;
using System.IO;
-
-using BenchmarkDotNet.Attributes;
-
using TextMateSharp.Grammars;
namespace TextMateSharp.Benchmarks
{
+ [Config(typeof(CustomBenchmarksConfig))]
[MemoryDiagnoser]
public class BigFileTokenizationBenchmark
{
@@ -20,10 +21,10 @@ public void Setup()
// Walk up directories to find the solution root
string? dir = AppDomain.CurrentDomain.BaseDirectory;
string bigFilePath = "";
-
+
while (dir != null)
{
- string candidate = Path.Combine(dir, "src", "TextMateSharp.Demo",
+ string candidate = Path.Combine(dir, "src", "TextMateSharp.Demo",
"testdata", "samplefiles", "bigfile.cs");
if (File.Exists(candidate))
{
@@ -48,7 +49,7 @@ public void Setup()
RegistryOptions options = new RegistryOptions(ThemeName.DarkPlus);
Registry.Registry registry = new Registry.Registry(options);
_grammar = registry.LoadGrammar("source.cs");
-
+
if (_grammar == null)
{
throw new InvalidOperationException("Failed to load C# grammar");
@@ -94,5 +95,14 @@ public int TokenizeAllLines()
yield return (lineStart, content.Length - lineStart);
}
}
+
+ public class CustomBenchmarksConfig : ManualConfig
+ {
+ public CustomBenchmarksConfig()
+ {
+ // Use the default summary style but with size unit in kilobytes so we can measure even small differences in memory usage
+ SummaryStyle = BenchmarkDotNet.Reports.SummaryStyle.Default.WithSizeUnit(SizeUnit.KB);
+ }
+ }
}
}
From da0638f2acf1cd7a0723418091fa58ac173b1e49 Mon Sep 17 00:00:00 2001
From: Dave Black <656118+udlose@users.noreply.github.com>
Date: Sat, 7 Mar 2026 18:18:17 -0600
Subject: [PATCH 4/8] Add AllocatedBytesColumn to benchmark config
Introduced AllocatedBytesColumn for detailed memory usage reporting in benchmark results. Updated CustomBenchmarksConfig to include this column and set summary style to kilobytes and current culture. Minor formatting and console message improvements.
---
.../BigFileTokenizationBenchmark.cs | 61 +++++++++++++++++--
1 file changed, 57 insertions(+), 4 deletions(-)
diff --git a/src/TextMateSharp.Benchmarks/BigFileTokenizationBenchmark.cs b/src/TextMateSharp.Benchmarks/BigFileTokenizationBenchmark.cs
index 6593b92..83be144 100644
--- a/src/TextMateSharp.Benchmarks/BigFileTokenizationBenchmark.cs
+++ b/src/TextMateSharp.Benchmarks/BigFileTokenizationBenchmark.cs
@@ -1,8 +1,12 @@
using BenchmarkDotNet.Attributes;
+using BenchmarkDotNet.Columns;
using BenchmarkDotNet.Configs;
+using BenchmarkDotNet.Reports;
+using BenchmarkDotNet.Running;
using Perfolizer.Metrology;
using System;
using System.Collections.Generic;
+using System.Globalization;
using System.IO;
using TextMateSharp.Grammars;
@@ -43,7 +47,7 @@ public void Setup()
// Load the file into memory
_content = File.ReadAllText(bigFilePath);
- Console.WriteLine($"Loaded bigfile.cs");
+ Console.WriteLine("Loaded bigfile.cs");
// Load the C# grammar
RegistryOptions options = new RegistryOptions(ThemeName.DarkPlus);
@@ -96,13 +100,62 @@ public int TokenizeAllLines()
}
}
- public class CustomBenchmarksConfig : ManualConfig
+ #region helper classes for benchmarks
+
+ public sealed class CustomBenchmarksConfig : ManualConfig
{
public CustomBenchmarksConfig()
{
- // Use the default summary style but with size unit in kilobytes so we can measure even small differences in memory usage
- SummaryStyle = BenchmarkDotNet.Reports.SummaryStyle.Default.WithSizeUnit(SizeUnit.KB);
+ // Use the default summary style with size unit in kilobytes.
+ // We have a separate column to measure in bytes so we can measure even small differences in memory usage.
+ SummaryStyle = SummaryStyle.Default
+ .WithSizeUnit(SizeUnit.KB)
+ .WithCultureInfo(CultureInfo.CurrentCulture);
+
+ AddColumn(new AllocatedBytesColumn());
}
}
+
+ public sealed class AllocatedBytesColumn : IColumn
+ {
+ public string Id => nameof(AllocatedBytesColumn);
+
+ public string ColumnName => "Allocated B";
+
+ public bool AlwaysShow => true;
+
+ public ColumnCategory Category => ColumnCategory.Custom;
+
+ public int PriorityInCategory => 0;
+
+ public bool IsNumeric => true;
+
+ public UnitType UnitType => UnitType.Dimensionless;
+
+ public string Legend => "Bytes allocated per operation";
+
+ public bool IsAvailable(Summary summary) => true;
+
+ public bool IsDefault(Summary summary, BenchmarkCase benchmarkCase) => false;
+
+ public string GetValue(Summary summary, BenchmarkCase benchmarkCase, SummaryStyle style)
+ {
+ BenchmarkReport? report = summary[benchmarkCase];
+ long? bytesAllocatedPerOperation = report?.GcStats.GetBytesAllocatedPerOperation(benchmarkCase);
+ if (!bytesAllocatedPerOperation.HasValue)
+ {
+ return "NA";
+ }
+
+ return bytesAllocatedPerOperation.Value.ToString("N0", style.CultureInfo);
+ }
+
+ public string GetValue(Summary summary, BenchmarkCase benchmarkCase)
+ => GetValue(summary, benchmarkCase, summary.Style);
+
+ public override string ToString() => ColumnName;
+ }
+
+ #endregion helper classes for benchmarks
}
}
From 22ee172483f0d22edc8302320423e84b874121c6 Mon Sep 17 00:00:00 2001
From: Dave Black <656118+udlose@users.noreply.github.com>
Date: Sun, 8 Mar 2026 14:09:10 -0500
Subject: [PATCH 5/8] Improve parsing and error handling in EndElement method
Refactored variable naming for clarity. Replaced exception-based parsing with TryParse for integers and floats, providing more accurate error messages. Corrected grammar in integer error message.
---
src/TextMateSharp/Internal/Parser/PList.cs | 25 ++++++++--------------
1 file changed, 9 insertions(+), 16 deletions(-)
diff --git a/src/TextMateSharp/Internal/Parser/PList.cs b/src/TextMateSharp/Internal/Parser/PList.cs
index 606954f..62b39b9 100644
--- a/src/TextMateSharp/Internal/Parser/PList.cs
+++ b/src/TextMateSharp/Internal/Parser/PList.cs
@@ -1,4 +1,3 @@
-using System;
using System.Collections.Generic;
using System.Text;
@@ -55,7 +54,7 @@ private PListObject Create(PListObject parent, bool valueAsArray)
public void EndElement(string tagName)
{
object value = null;
- string text = this.text.ToString();
+ string t = this.text.ToString();
if ("key".Equals(tagName))
{
if (currObject == null || currObject.IsValueAsArray())
@@ -63,7 +62,7 @@ public void EndElement(string tagName)
errors.Add("key can only be used inside an open dict element");
return;
}
- currObject.SetLastKey(text);
+ currObject.SetLastKey(t);
return;
}
else if ("dict".Equals(tagName) || "array".Equals(tagName))
@@ -78,7 +77,7 @@ public void EndElement(string tagName)
}
else if ("string".Equals(tagName) || "data".Equals(tagName))
{
- value = text;
+ value = t;
}
else if ("date".Equals(tagName))
{
@@ -86,27 +85,21 @@ public void EndElement(string tagName)
}
else if ("integer".Equals(tagName))
{
- try
+ if (!int.TryParse(t, out int i))
{
- value = int.Parse(text);
- }
- catch (Exception)
- {
- errors.Add(text + " is not a integer");
+ errors.Add(t + " is not an integer");
return;
}
+ value = i;
}
else if ("real".Equals(tagName))
{
- try
- {
- value = float.Parse(text);
- }
- catch (Exception)
+ if (!float.TryParse(t, out float f))
{
- errors.Add(text + " is not a float");
+ errors.Add(t + " is not a float");
return;
}
+ value = f;
}
else if ("true".Equals(tagName))
{
From 0bfff1d8d4e3af650486d85f6fb83eb7e98f86f0 Mon Sep 17 00:00:00 2001
From: Dave Black <656118+udlose@users.noreply.github.com>
Date: Sun, 8 Mar 2026 14:53:13 -0500
Subject: [PATCH 6/8] Fix bug in BasicScopeAttributesProvider per @danipen:
https://github.com/danipen/TextMateSharp/issues/120#issuecomment-4016645793
---
.../Internal/Grammars/BasicScopeAttributesProvider.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/TextMateSharp/Internal/Grammars/BasicScopeAttributesProvider.cs b/src/TextMateSharp/Internal/Grammars/BasicScopeAttributesProvider.cs
index 597d91a..a3e91de 100644
--- a/src/TextMateSharp/Internal/Grammars/BasicScopeAttributesProvider.cs
+++ b/src/TextMateSharp/Internal/Grammars/BasicScopeAttributesProvider.cs
@@ -58,7 +58,7 @@ internal BasicScopeAttributesProvider(int initialLanguage, IThemeProvider themeP
reversedScopes.Reverse();
this._embeddedLanguagesRegex = new Regex(
"^((" +
- string.Join(")|(", escapedScopes) +
+ string.Join(")|(", reversedScopes) +
"))($|\\.)");
}
}
From d84dd5069ca28d1a273089f6a4a3c4f874ee0a80 Mon Sep 17 00:00:00 2001
From: Dave Black <656118+udlose@users.noreply.github.com>
Date: Sun, 8 Mar 2026 14:56:43 -0500
Subject: [PATCH 7/8] Enable internals access for DynamicProxyGenAssembly2
Added InternalsVisibleTo for DynamicProxyGenAssembly2 in AssemblyInfo.cs, allowing internal members to be accessed by mocking frameworks such as Moq during unit testing. Existing access for TextMateSharp.Tests remains unchanged.
---
src/TextMateSharp.Grammars/Properties/AssemblyInfo.cs | 3 ++-
src/TextMateSharp/Properties/AssemblyInfo.cs | 3 ++-
2 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/src/TextMateSharp.Grammars/Properties/AssemblyInfo.cs b/src/TextMateSharp.Grammars/Properties/AssemblyInfo.cs
index c4511fe..278d7d3 100644
--- a/src/TextMateSharp.Grammars/Properties/AssemblyInfo.cs
+++ b/src/TextMateSharp.Grammars/Properties/AssemblyInfo.cs
@@ -1,3 +1,4 @@
using System.Runtime.CompilerServices;
-[assembly: InternalsVisibleTo("TextMateSharp.Tests, PublicKey=00240000048000009400000006020000002400005253413100040000010001000db16f8de24159e7ee94e32addce2a9b60f3ea5be200ae7b5abbf8676705064a1b5a5a44d570a884bd86bd2d3e83411fb88914e00028bc7d4b5be1ba8fd8db4335e3ad911d0ef7e694cf433f3314e991100c72c7473641a9e3437deeab402c8f4a03fdf9c174cbae00142a28ce43475ca61f0016ede73dc778b5ed5a0344cfc2")]
\ No newline at end of file
+[assembly: InternalsVisibleTo("TextMateSharp.Tests, PublicKey=00240000048000009400000006020000002400005253413100040000010001000db16f8de24159e7ee94e32addce2a9b60f3ea5be200ae7b5abbf8676705064a1b5a5a44d570a884bd86bd2d3e83411fb88914e00028bc7d4b5be1ba8fd8db4335e3ad911d0ef7e694cf433f3314e991100c72c7473641a9e3437deeab402c8f4a03fdf9c174cbae00142a28ce43475ca61f0016ede73dc778b5ed5a0344cfc2")]
+[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7")]
\ No newline at end of file
diff --git a/src/TextMateSharp/Properties/AssemblyInfo.cs b/src/TextMateSharp/Properties/AssemblyInfo.cs
index c4511fe..278d7d3 100644
--- a/src/TextMateSharp/Properties/AssemblyInfo.cs
+++ b/src/TextMateSharp/Properties/AssemblyInfo.cs
@@ -1,3 +1,4 @@
using System.Runtime.CompilerServices;
-[assembly: InternalsVisibleTo("TextMateSharp.Tests, PublicKey=00240000048000009400000006020000002400005253413100040000010001000db16f8de24159e7ee94e32addce2a9b60f3ea5be200ae7b5abbf8676705064a1b5a5a44d570a884bd86bd2d3e83411fb88914e00028bc7d4b5be1ba8fd8db4335e3ad911d0ef7e694cf433f3314e991100c72c7473641a9e3437deeab402c8f4a03fdf9c174cbae00142a28ce43475ca61f0016ede73dc778b5ed5a0344cfc2")]
\ No newline at end of file
+[assembly: InternalsVisibleTo("TextMateSharp.Tests, PublicKey=00240000048000009400000006020000002400005253413100040000010001000db16f8de24159e7ee94e32addce2a9b60f3ea5be200ae7b5abbf8676705064a1b5a5a44d570a884bd86bd2d3e83411fb88914e00028bc7d4b5be1ba8fd8db4335e3ad911d0ef7e694cf433f3314e991100c72c7473641a9e3437deeab402c8f4a03fdf9c174cbae00142a28ce43475ca61f0016ede73dc778b5ed5a0344cfc2")]
+[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7")]
\ No newline at end of file
From eefd2691e410c831b5457b59b541771f2dd61060 Mon Sep 17 00:00:00 2001
From: Dave Black <656118+udlose@users.noreply.github.com>
Date: Sun, 8 Mar 2026 18:04:35 -0500
Subject: [PATCH 8/8] Completes #123 Apply signature parity with tm4e upstream
per
https://github.com/eclipse-tm4e/tm4e/tree/main/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/rule
Restrict visibility and improve encapsulation
Refactored multiple classes to be internal and/or sealed, limiting access to within the assembly. Updated constructors, properties, and methods for better encapsulation and immutability. Renamed methods to follow C# conventions. Made static fields in RuleId readonly. Converted ThemeReader to a static class. Removed ICompilePatternsResult.cs and merged its contents. These changes clarify API boundaries and enhance maintainability.
---
.../Internal/Grammars/LineTokenizer.cs | 2 +-
.../Internal/Rules/BeginEndRule.cs | 16 ++++-----
.../Internal/Rules/BeginWhileRule.cs | 16 ++++-----
.../Internal/Rules/CaptureRule.cs | 8 ++---
.../Internal/Rules/CompilePatternsResult.cs | 16 +++++++++
.../{ICompiledRule.cs => CompiledRule.cs} | 6 ++--
.../Internal/Rules/ICompilePatternsResult.cs | 16 ---------
.../Internal/Rules/IncludeOnlyRule.cs | 8 ++---
src/TextMateSharp/Internal/Rules/MatchRule.cs | 6 ++--
.../Internal/Rules/RegExpSource.cs | 32 ++++++++---------
.../Internal/Rules/RegExpSourceList.cs | 34 +++++++------------
src/TextMateSharp/Internal/Rules/Rule.cs | 14 ++++----
.../Internal/Rules/RuleFactory.cs | 2 +-
src/TextMateSharp/Internal/Rules/RuleId.cs | 8 ++---
.../Internal/Themes/reader/ThemeReader.cs | 4 +--
15 files changed, 88 insertions(+), 100 deletions(-)
create mode 100644 src/TextMateSharp/Internal/Rules/CompilePatternsResult.cs
rename src/TextMateSharp/Internal/Rules/{ICompiledRule.cs => CompiledRule.cs} (73%)
delete mode 100644 src/TextMateSharp/Internal/Rules/ICompilePatternsResult.cs
diff --git a/src/TextMateSharp/Internal/Grammars/LineTokenizer.cs b/src/TextMateSharp/Internal/Grammars/LineTokenizer.cs
index 21d575c..16e2dde 100644
--- a/src/TextMateSharp/Internal/Grammars/LineTokenizer.cs
+++ b/src/TextMateSharp/Internal/Grammars/LineTokenizer.cs
@@ -203,7 +203,7 @@ private void ScanNext()
if (beginWhileRule.WhileHasBackReferences)
{
_stack = _stack.WithEndRule(
- beginWhileRule.getWhileWithResolvedBackReferences(_lineText, captureIndices));
+ beginWhileRule.GetWhileWithResolvedBackReferences(_lineText, captureIndices));
}
if (!hasAdvanced && beforePush.HasSameRuleAs(_stack))
diff --git a/src/TextMateSharp/Internal/Rules/BeginEndRule.cs b/src/TextMateSharp/Internal/Rules/BeginEndRule.cs
index 38d0259..b790171 100644
--- a/src/TextMateSharp/Internal/Rules/BeginEndRule.cs
+++ b/src/TextMateSharp/Internal/Rules/BeginEndRule.cs
@@ -1,23 +1,23 @@
+using Onigwrap;
using System;
using System.Collections.Generic;
-using Onigwrap;
namespace TextMateSharp.Internal.Rules
{
- public class BeginEndRule : Rule
+ public sealed class BeginEndRule : Rule
{
public List BeginCaptures { get; private set; }
public bool EndHasBackReferences { get; private set; }
public List EndCaptures { get; private set; }
- public bool ApplyEndPatternLast { get; private set; }
- public bool HasMissingPatterns { get; private set; }
- public IList Patterns { get; private set; }
+ private bool ApplyEndPatternLast { get; }
+ internal bool HasMissingPatterns { get; private set; }
+ internal IList Patterns { get; private set; }
- private RegExpSource _begin;
- private RegExpSource _end;
+ private readonly RegExpSource _begin;
+ private readonly RegExpSource _end;
private RegExpSourceList _cachedCompiledPatterns;
- public BeginEndRule(RuleId id, string name, string contentName, string begin, List beginCaptures,
+ internal BeginEndRule(RuleId id, string name, string contentName, string begin, List beginCaptures,
string end, List endCaptures, bool applyEndPatternLast, CompilePatternsResult patterns)
: base(id, name, contentName)
{
diff --git a/src/TextMateSharp/Internal/Rules/BeginWhileRule.cs b/src/TextMateSharp/Internal/Rules/BeginWhileRule.cs
index 99290e2..1ab18cb 100644
--- a/src/TextMateSharp/Internal/Rules/BeginWhileRule.cs
+++ b/src/TextMateSharp/Internal/Rules/BeginWhileRule.cs
@@ -1,23 +1,23 @@
+using Onigwrap;
using System;
using System.Collections.Generic;
-using Onigwrap;
namespace TextMateSharp.Internal.Rules
{
- public class BeginWhileRule : Rule
+ public sealed class BeginWhileRule : Rule
{
public List BeginCaptures { get; private set; }
public List WhileCaptures { get; private set; }
public bool WhileHasBackReferences { get; private set; }
- public bool HasMissingPatterns { get; private set; }
- public IListPatterns { get; private set; }
+ internal bool HasMissingPatterns { get; private set; }
+ internal IList Patterns { get; private set; }
- private RegExpSource _begin;
- private RegExpSource _while;
+ private readonly RegExpSource _begin;
+ private readonly RegExpSource _while;
private RegExpSourceList _cachedCompiledPatterns;
private RegExpSourceList _cachedCompiledWhilePatterns;
- public BeginWhileRule(RuleId id, string name, string contentName, string begin,
+ internal BeginWhileRule(RuleId id, string name, string contentName, string begin,
List beginCaptures, string whileStr, List whileCaptures,
CompilePatternsResult patterns) : base(id, name, contentName)
{
@@ -34,7 +34,7 @@ public BeginWhileRule(RuleId id, string name, string contentName, string begin,
_cachedCompiledWhilePatterns = null;
}
- public string getWhileWithResolvedBackReferences(ReadOnlyMemory lineText, IOnigCaptureIndex[] captureIndices)
+ public string GetWhileWithResolvedBackReferences(ReadOnlyMemory lineText, IOnigCaptureIndex[] captureIndices)
{
return this._while.ResolveBackReferences(lineText, captureIndices);
}
diff --git a/src/TextMateSharp/Internal/Rules/CaptureRule.cs b/src/TextMateSharp/Internal/Rules/CaptureRule.cs
index 7377a8e..7cd8281 100644
--- a/src/TextMateSharp/Internal/Rules/CaptureRule.cs
+++ b/src/TextMateSharp/Internal/Rules/CaptureRule.cs
@@ -1,19 +1,17 @@
-using System;
-
namespace TextMateSharp.Internal.Rules
{
- public class CaptureRule : Rule
+ public sealed class CaptureRule : Rule
{
public RuleId RetokenizeCapturedWithRuleId { get; private set; }
- public CaptureRule(RuleId id, string name, string contentName, RuleId retokenizeCapturedWithRuleId) : base(id, name, contentName)
+ internal CaptureRule(RuleId id, string name, string contentName, RuleId retokenizeCapturedWithRuleId) : base(id, name, contentName)
{
RetokenizeCapturedWithRuleId = retokenizeCapturedWithRuleId;
}
public override void CollectPatternsRecursive(IRuleRegistry grammar, RegExpSourceList sourceList, bool isFirst)
{
-
+
}
public override CompiledRule Compile(IRuleRegistry grammar, string endRegexSource, bool allowA, bool allowG)
diff --git a/src/TextMateSharp/Internal/Rules/CompilePatternsResult.cs b/src/TextMateSharp/Internal/Rules/CompilePatternsResult.cs
new file mode 100644
index 0000000..836693c
--- /dev/null
+++ b/src/TextMateSharp/Internal/Rules/CompilePatternsResult.cs
@@ -0,0 +1,16 @@
+using System.Collections.Generic;
+
+namespace TextMateSharp.Internal.Rules
+{
+ internal sealed class CompilePatternsResult
+ {
+ internal IList Patterns { get; private set; }
+ internal bool HasMissingPatterns { get; private set; }
+
+ internal CompilePatternsResult(IList patterns, bool hasMissingPatterns)
+ {
+ HasMissingPatterns = hasMissingPatterns;
+ Patterns = patterns;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/TextMateSharp/Internal/Rules/ICompiledRule.cs b/src/TextMateSharp/Internal/Rules/CompiledRule.cs
similarity index 73%
rename from src/TextMateSharp/Internal/Rules/ICompiledRule.cs
rename to src/TextMateSharp/Internal/Rules/CompiledRule.cs
index 2152310..510d152 100644
--- a/src/TextMateSharp/Internal/Rules/ICompiledRule.cs
+++ b/src/TextMateSharp/Internal/Rules/CompiledRule.cs
@@ -1,14 +1,14 @@
-using System.Collections.Generic;
using Onigwrap;
+using System.Collections.Generic;
namespace TextMateSharp.Internal.Rules
{
- public class CompiledRule
+ public sealed class CompiledRule
{
public OnigScanner Scanner { get; private set; }
public IList Rules { get; private set; }
- public CompiledRule(OnigScanner scanner, IList rules)
+ internal CompiledRule(OnigScanner scanner, IList rules)
{
Scanner = scanner;
Rules = rules;
diff --git a/src/TextMateSharp/Internal/Rules/ICompilePatternsResult.cs b/src/TextMateSharp/Internal/Rules/ICompilePatternsResult.cs
deleted file mode 100644
index bd75726..0000000
--- a/src/TextMateSharp/Internal/Rules/ICompilePatternsResult.cs
+++ /dev/null
@@ -1,16 +0,0 @@
-using System.Collections.Generic;
-
-namespace TextMateSharp.Internal.Rules
-{
- public class CompilePatternsResult
- {
- public IList Patterns { get; private set; }
- public bool HasMissingPatterns { get; private set; }
-
- public CompilePatternsResult(IList patterns, bool hasMissingPatterns)
- {
- HasMissingPatterns = hasMissingPatterns;
- Patterns = patterns;
- }
- }
-}
\ No newline at end of file
diff --git a/src/TextMateSharp/Internal/Rules/IncludeOnlyRule.cs b/src/TextMateSharp/Internal/Rules/IncludeOnlyRule.cs
index ddd74df..66d13fc 100644
--- a/src/TextMateSharp/Internal/Rules/IncludeOnlyRule.cs
+++ b/src/TextMateSharp/Internal/Rules/IncludeOnlyRule.cs
@@ -2,14 +2,14 @@
namespace TextMateSharp.Internal.Rules
{
- public class IncludeOnlyRule : Rule
+ internal sealed class IncludeOnlyRule : Rule
{
- public bool HasMissingPatterns { get; private set; }
- public IList Patterns { get; private set; }
+ internal bool HasMissingPatterns { get; private set; }
+ internal IList Patterns { get; private set; }
private RegExpSourceList _cachedCompiledPatterns;
- public IncludeOnlyRule(RuleId id, string name, string contentName, CompilePatternsResult patterns) : base(id, name, contentName)
+ internal IncludeOnlyRule(RuleId id, string name, string contentName, CompilePatternsResult patterns) : base(id, name, contentName)
{
Patterns = patterns.Patterns;
HasMissingPatterns = patterns.HasMissingPatterns;
diff --git a/src/TextMateSharp/Internal/Rules/MatchRule.cs b/src/TextMateSharp/Internal/Rules/MatchRule.cs
index baad820..a3aa6ca 100644
--- a/src/TextMateSharp/Internal/Rules/MatchRule.cs
+++ b/src/TextMateSharp/Internal/Rules/MatchRule.cs
@@ -2,14 +2,14 @@
namespace TextMateSharp.Internal.Rules
{
- public class MatchRule : Rule
+ public sealed class MatchRule : Rule
{
public List Captures { get; private set; }
- private RegExpSource _match;
+ private readonly RegExpSource _match;
private RegExpSourceList _cachedCompiledPatterns;
- public MatchRule(RuleId id, string name, string match, List captures) : base(id, name, null)
+ internal MatchRule(RuleId id, string name, string match, List captures) : base(id, name, null)
{
this._match = new RegExpSource(match, this.Id);
this.Captures = captures;
diff --git a/src/TextMateSharp/Internal/Rules/RegExpSource.cs b/src/TextMateSharp/Internal/Rules/RegExpSource.cs
index 6d63240..abbd3d1 100644
--- a/src/TextMateSharp/Internal/Rules/RegExpSource.cs
+++ b/src/TextMateSharp/Internal/Rules/RegExpSource.cs
@@ -7,24 +7,24 @@
namespace TextMateSharp.Internal.Rules
{
- public class RegExpSource
+ internal sealed class RegExpSource
{
- private static Regex HAS_BACK_REFERENCES = new Regex("\\\\(\\d+)");
- private static Regex BACK_REFERENCING_END = new Regex("\\\\(\\d+)");
+ private static readonly Regex HAS_BACK_REFERENCES = new Regex("\\\\(\\d+)");
+ private static readonly Regex BACK_REFERENCING_END = new Regex("\\\\(\\d+)");
- private RuleId _ruleId;
+ private readonly RuleId _ruleId;
private bool _hasAnchor;
- private bool _hasBackReferences;
+ private readonly bool _hasBackReferences;
private RegExpSourceAnchorCache _anchorCache;
private string _source;
- public RegExpSource(string regExpSource, RuleId ruleId) :
+ internal RegExpSource(string regExpSource, RuleId ruleId) :
this(regExpSource, ruleId, true)
{
}
- public RegExpSource(string regExpSource, RuleId ruleId, bool handleAnchors)
+ internal RegExpSource(string regExpSource, RuleId ruleId, bool handleAnchors)
{
if (handleAnchors)
{
@@ -45,12 +45,12 @@ public RegExpSource(string regExpSource, RuleId ruleId, bool handleAnchors)
this._hasBackReferences = HAS_BACK_REFERENCES.Match(this._source).Success;
}
- public RegExpSource Clone()
+ internal RegExpSource Clone()
{
return new RegExpSource(this._source, this._ruleId, true);
}
- public void SetSource(string newSource)
+ internal void SetSource(string newSource)
{
if (this._source.Equals(newSource))
{
@@ -118,7 +118,7 @@ private void HandleAnchors(string regExpSource)
}
}
- public string ResolveBackReferences(ReadOnlyMemory lineText, IOnigCaptureIndex[] captureIndices)
+ internal string ResolveBackReferences(ReadOnlyMemory lineText, IOnigCaptureIndex[] captureIndices)
{
List capturedValues = new List(captureIndices.Length);
@@ -154,7 +154,7 @@ public string ResolveBackReferences(ReadOnlyMemory lineText, IOnigCaptureI
return lineText.Span.ToString();
}
- private string EscapeRegExpCharacters(string value)
+ private static string EscapeRegExpCharacters(string value)
{
int valueLen = value.Length;
var sb = new StringBuilder(valueLen);
@@ -257,7 +257,7 @@ private RegExpSourceAnchorCache BuildAnchorCache()
A1_G1_result.ToString());
}
- public string ResolveAnchors(bool allowA, bool allowG)
+ internal string ResolveAnchors(bool allowA, bool allowG)
{
if (!this._hasAnchor)
return this._source;
@@ -276,22 +276,22 @@ public string ResolveAnchors(bool allowA, bool allowG)
return this._anchorCache.A0_G0;
}
- public bool HasAnchor()
+ internal bool HasAnchor()
{
return this._hasAnchor;
}
- public string GetSource()
+ internal string GetSource()
{
return this._source;
}
- public RuleId GetRuleId()
+ internal RuleId GetRuleId()
{
return this._ruleId;
}
- public bool HasBackReferences()
+ internal bool HasBackReferences()
{
return this._hasBackReferences;
}
diff --git a/src/TextMateSharp/Internal/Rules/RegExpSourceList.cs b/src/TextMateSharp/Internal/Rules/RegExpSourceList.cs
index 3fc4b0d..47e4030 100644
--- a/src/TextMateSharp/Internal/Rules/RegExpSourceList.cs
+++ b/src/TextMateSharp/Internal/Rules/RegExpSourceList.cs
@@ -3,49 +3,41 @@
namespace TextMateSharp.Internal.Rules
{
- public class RegExpSourceList
+ public sealed class RegExpSourceList
{
- private class RegExpSourceListAnchorCache
+ private sealed class RegExpSourceListAnchorCache
{
- public CompiledRule A0_G0;
- public CompiledRule A0_G1;
- public CompiledRule A1_G0;
- public CompiledRule A1_G1;
+ internal CompiledRule A0_G0;
+ internal CompiledRule A0_G1;
+ internal CompiledRule A1_G0;
+ internal CompiledRule A1_G1;
}
- private List _items;
+ private readonly List _items = new List();
private bool _hasAnchors;
private CompiledRule _cached;
- private RegExpSourceListAnchorCache _anchorCache;
+ private readonly RegExpSourceListAnchorCache _anchorCache = new RegExpSourceListAnchorCache();
- public RegExpSourceList()
- {
- this._items = new List();
- this._hasAnchors = false;
- this._cached = null;
- this._anchorCache = new RegExpSourceListAnchorCache();
- }
-
- public void Push(RegExpSource item)
+ internal void Push(RegExpSource item)
{
this._items.Add(item);
this._hasAnchors = this._hasAnchors ? this._hasAnchors : item.HasAnchor();
}
- public void UnShift(RegExpSource item)
+ internal void UnShift(RegExpSource item)
{
this._items.Insert(0, item);
this._hasAnchors = this._hasAnchors ? this._hasAnchors : item.HasAnchor();
}
- public int Length()
+ internal int Length()
{
return this._items.Count;
}
- public void SetSource(int index, string newSource)
+ internal void SetSource(int index, string newSource)
{
RegExpSource r = this._items[index];
if (!r.GetSource().Equals(newSource))
@@ -61,7 +53,7 @@ public void SetSource(int index, string newSource)
}
}
- public CompiledRule Compile(bool allowA, bool allowG)
+ internal CompiledRule Compile(bool allowA, bool allowG)
{
if (!this._hasAnchors)
{
diff --git a/src/TextMateSharp/Internal/Rules/Rule.cs b/src/TextMateSharp/Internal/Rules/Rule.cs
index a238361..3946aa7 100644
--- a/src/TextMateSharp/Internal/Rules/Rule.cs
+++ b/src/TextMateSharp/Internal/Rules/Rule.cs
@@ -1,5 +1,5 @@
-using System;
using Onigwrap;
+using System;
using TextMateSharp.Internal.Utils;
@@ -7,15 +7,15 @@ namespace TextMateSharp.Internal.Rules
{
public abstract class Rule
{
- public RuleId Id { get; private set; }
+ internal RuleId Id { get; private set; }
- private bool _nameIsCapturing;
- private string _name;
+ private readonly bool _nameIsCapturing;
+ private readonly string _name;
- private bool _contentNameIsCapturing;
- private string _contentName;
+ private readonly bool _contentNameIsCapturing;
+ private readonly string _contentName;
- public Rule(RuleId id, string name, string contentName)
+ protected Rule(RuleId id, string name, string contentName)
{
Id = id;
diff --git a/src/TextMateSharp/Internal/Rules/RuleFactory.cs b/src/TextMateSharp/Internal/Rules/RuleFactory.cs
index e946214..ea21f9a 100644
--- a/src/TextMateSharp/Internal/Rules/RuleFactory.cs
+++ b/src/TextMateSharp/Internal/Rules/RuleFactory.cs
@@ -7,7 +7,7 @@ namespace TextMateSharp.Internal.Rules
{
public static class RuleFactory
{
- public static CaptureRule CreateCaptureRule(IRuleFactoryHelper helper, string name, string contentName,
+ private static CaptureRule CreateCaptureRule(IRuleFactoryHelper helper, string name, string contentName,
RuleId retokenizeCapturedWithRuleId)
{
return (CaptureRule)helper.RegisterRule(id => new CaptureRule(id, name, contentName, retokenizeCapturedWithRuleId));
diff --git a/src/TextMateSharp/Internal/Rules/RuleId.cs b/src/TextMateSharp/Internal/Rules/RuleId.cs
index f78b132..78764db 100644
--- a/src/TextMateSharp/Internal/Rules/RuleId.cs
+++ b/src/TextMateSharp/Internal/Rules/RuleId.cs
@@ -4,17 +4,17 @@ namespace TextMateSharp.Internal.Rules
{
public sealed class RuleId
{
- public static RuleId NO_RULE = new RuleId(0);
+ public static readonly RuleId NO_RULE = new RuleId(0);
/**
* This is a special constant to indicate that the end regexp matched.
*/
- public static RuleId END_RULE = new RuleId(-1);
+ public static readonly RuleId END_RULE = new RuleId(-1);
/**
* This is a special constant to indicate that the while regexp matched.
*/
- public static RuleId WHILE_RULE = new RuleId(-2);
+ public static readonly RuleId WHILE_RULE = new RuleId(-2);
public static RuleId Of(int id)
{
@@ -23,7 +23,7 @@ public static RuleId Of(int id)
return new RuleId(id);
}
- public int Id;
+ public int Id { get; }
private RuleId(int id)
{
diff --git a/src/TextMateSharp/Internal/Themes/reader/ThemeReader.cs b/src/TextMateSharp/Internal/Themes/reader/ThemeReader.cs
index 5e2f3a7..e0cc916 100644
--- a/src/TextMateSharp/Internal/Themes/reader/ThemeReader.cs
+++ b/src/TextMateSharp/Internal/Themes/reader/ThemeReader.cs
@@ -1,13 +1,11 @@
-using System.Collections.Generic;
using System.IO;
using TextMateSharp.Internal.Parser.Json;
-using TextMateSharp.Registry;
using TextMateSharp.Themes;
namespace TextMateSharp.Internal.Themes.Reader
{
- public class ThemeReader
+ public static class ThemeReader
{
public static IRawTheme ReadThemeSync(StreamReader reader)
{