diff --git a/org.eclipse.tm4e.core.tests/src/main/java/org/eclipse/tm4e/core/grammar/internal/RawTestImpl.java b/org.eclipse.tm4e.core.tests/src/main/java/org/eclipse/tm4e/core/grammar/internal/RawTestImpl.java index e0ee69be5..ed0a7d6e1 100644 --- a/org.eclipse.tm4e.core.tests/src/main/java/org/eclipse/tm4e/core/grammar/internal/RawTestImpl.java +++ b/org.eclipse.tm4e.core.tests/src/main/java/org/eclipse/tm4e/core/grammar/internal/RawTestImpl.java @@ -30,7 +30,7 @@ import org.eclipse.tm4e.core.registry.Registry; /** - * @see + * @see * github.com/microsoft/vscode-textmate/blob/main/src/tests/tokenization.test.ts */ public class RawTestImpl { diff --git a/org.eclipse.tm4e.core.tests/src/main/java/org/eclipse/tm4e/core/internal/matcher/MatcherTest.java b/org.eclipse.tm4e.core.tests/src/main/java/org/eclipse/tm4e/core/internal/matcher/MatcherTest.java index b7904051d..8b03d6472 100644 --- a/org.eclipse.tm4e.core.tests/src/main/java/org/eclipse/tm4e/core/internal/matcher/MatcherTest.java +++ b/org.eclipse.tm4e.core.tests/src/main/java/org/eclipse/tm4e/core/internal/matcher/MatcherTest.java @@ -27,7 +27,7 @@ /** * VSCode TextMate matcher tests * - * @see + * @see * github.com/microsoft/vscode-textmate/blob/main/src/tests/matcher.test.ts */ public class MatcherTest { diff --git a/org.eclipse.tm4e.core.tests/src/main/java/org/eclipse/tm4e/core/internal/theme/ThemeMatchingTest.java b/org.eclipse.tm4e.core.tests/src/main/java/org/eclipse/tm4e/core/internal/theme/ThemeMatchingTest.java index d3c88c3c0..627ea29dd 100644 --- a/org.eclipse.tm4e.core.tests/src/main/java/org/eclipse/tm4e/core/internal/theme/ThemeMatchingTest.java +++ b/org.eclipse.tm4e.core.tests/src/main/java/org/eclipse/tm4e/core/internal/theme/ThemeMatchingTest.java @@ -23,7 +23,7 @@ /** * @see + * "https://github.com/microsoft/vscode-textmate/blob/167bbbd509356cc4617f250c0d754aef670ab14a/src/tests/themes.test.ts#L126"> * github.com/microsoft/vscode-textmate/blob/main/src/tests/themes.test.ts */ @TestMethodOrder(MethodOrderer.OrderAnnotation.class) diff --git a/org.eclipse.tm4e.core.tests/src/main/java/org/eclipse/tm4e/core/internal/theme/ThemeParsingTest.java b/org.eclipse.tm4e.core.tests/src/main/java/org/eclipse/tm4e/core/internal/theme/ThemeParsingTest.java index ae074c036..f1da88524 100644 --- a/org.eclipse.tm4e.core.tests/src/main/java/org/eclipse/tm4e/core/internal/theme/ThemeParsingTest.java +++ b/org.eclipse.tm4e.core.tests/src/main/java/org/eclipse/tm4e/core/internal/theme/ThemeParsingTest.java @@ -26,7 +26,7 @@ /** * @see + * "https://github.com/microsoft/vscode-textmate/blob/167bbbd509356cc4617f250c0d754aef670ab14a/src/tests/themes.test.ts#L286"> * github.com/microsoft/vscode-textmate/blob/main/src/tests/themes.test.ts */ @TestMethodOrder(MethodOrderer.OrderAnnotation.class) diff --git a/org.eclipse.tm4e.core.tests/src/main/java/org/eclipse/tm4e/core/internal/theme/ThemeResolvingTest.java b/org.eclipse.tm4e.core.tests/src/main/java/org/eclipse/tm4e/core/internal/theme/ThemeResolvingTest.java index f1864da7a..71627bc7b 100644 --- a/org.eclipse.tm4e.core.tests/src/main/java/org/eclipse/tm4e/core/internal/theme/ThemeResolvingTest.java +++ b/org.eclipse.tm4e.core.tests/src/main/java/org/eclipse/tm4e/core/internal/theme/ThemeResolvingTest.java @@ -20,6 +20,7 @@ import java.util.List; +import org.eclipse.tm4e.core.internal.grammar.ScopeStack; import org.eclipse.tm4e.core.internal.utils.StringUtils; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.MethodOrderer; @@ -34,7 +35,7 @@ /** * @see + * "https://github.com/microsoft/vscode-textmate/blob/167bbbd509356cc4617f250c0d754aef670ab14a/src/tests/themes.test.ts#L323"> * github.com/microsoft/vscode-textmate/blob/main/src/tests/themes.test.ts */ @TestMethodOrder(MethodOrderer.OrderAnnotation.class) @@ -347,6 +348,72 @@ public void testRulesWithParentScopes() { @Test @Order(15) + @DisplayName("Theme resolving a rule with child combinator") + public void testRuleWithChildCombinator() throws Exception { + final var theme = createTheme(""" + {"settings": [ + { "settings": { "foreground": "#100000" } }, + { "scope": "b a", "settings": { "foreground": "#200000" } }, + { "scope": "b > a", "settings": { "foreground": "#300000" } }, + { "scope": "c > b > a", "settings": { "foreground": "#400000" } }, + { "scope": "a", "settings": { "foreground": "#500000" } }, + ]}"""); + + final var colorMap = theme.getColorMap(); + + interface Matcher { + String match(String... path); + } + + final Matcher matcher = (String[] path) -> { + final var result = theme.match(ScopeStack.from(path)); + if (result == null || result.foregroundId == 0) + return null; + return colorMap.get(result.foregroundId); + }; + + assertEquals(matcher.match("b", "a"), "#300000", "b a"); + assertEquals(matcher.match("b", "c", "a"), "#200000", "b c a"); + assertEquals(matcher.match("c", "b", "a"), "#400000", "c b a"); + assertEquals(matcher.match("c", "b", "d", "a"), "#200000", "c b d a"); + } + + @Test + @Order(16) + @DisplayName("Theme resolving should give deeper scopes higher specificity (#233)") + public void testGiveDeeperScopesHigherSpecificity() throws Exception { + final var theme = createTheme(""" + {"settings": [ + { "settings": { "foreground": "#100000" } }, + { "scope": "y.z a.b", "settings": { "foreground": "#200000" } }, + { "scope": "x y a.b", "settings": { "foreground": "#300000" } }, + ]}"""); + + final var colorMap = theme.getColorMap(); + + interface Matcher { + String match(String... path); + } + + final Matcher matcher = (String[] path) -> { + final var result = theme.match(ScopeStack.from(path)); + if (result == null || result.foregroundId == 0) + return null; + return colorMap.get(result.foregroundId); + }; + + assertEquals(matcher.match("x", "a.b"), null, "x a.b"); + assertEquals(matcher.match("y", "a.b"), null, "y a.b"); + assertEquals(matcher.match("y.z", "a"), null, "y.z a"); + assertEquals(matcher.match("x", "y", "a.b"), "#300000", "x y a.b"); + + // Even though the "x y a.b" rule has more scopes in its path, the "y.z a.b" rule has + // a deeper match, so it should take precedence. + assertEquals(matcher.match("x", "y.z", "a.b"), "#200000", "y.z a.b"); + } + + @Test + @Order(17) @DisplayName("Theme resolving issue #38: ignores rules with invalid colors") public void testIssue_38_ignores_rules_with_invalid_colors() throws Exception { final var actual = parseTheme(""" @@ -404,7 +471,7 @@ public void testIssue_38_ignores_rules_with_invalid_colors() throws Exception { } @Test - @Order(16) + @Order(18) @DisplayName("Theme resolving issue #35: Trailing comma in a tmTheme scope selector") public void testIssue_35_Trailing_comma_in_a_tmTheme_scope_selector() throws Exception { final var actual = parseTheme(""" diff --git a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/grammar/IGrammar.java b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/grammar/IGrammar.java index 8476d7d69..43eb9bd85 100644 --- a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/grammar/IGrammar.java +++ b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/grammar/IGrammar.java @@ -24,7 +24,7 @@ /** * TextMate grammar API. * - * @see + * @see * github.com/microsoft/vscode-textmate/blob/main/src/main.ts */ public interface IGrammar { diff --git a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/grammar/IStateStack.java b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/grammar/IStateStack.java index 0d5a5b565..04df566fb 100644 --- a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/grammar/IStateStack.java +++ b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/grammar/IStateStack.java @@ -19,7 +19,7 @@ /** * Represents a "pushed" state on the stack (as a linked list element). * - * @see + * @see * github.com/microsoft/vscode-textmate/blob/main/src/main.ts */ public interface IStateStack { diff --git a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/grammar/IToken.java b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/grammar/IToken.java index 96d14cee4..e413b88e8 100644 --- a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/grammar/IToken.java +++ b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/grammar/IToken.java @@ -19,7 +19,7 @@ import java.util.List; /** - * @see + * @see * github.com/microsoft/vscode-textmate/blob/main/src/main.ts */ public interface IToken { diff --git a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/grammar/ITokenizeLineResult.java b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/grammar/ITokenizeLineResult.java index d8ee2b6db..64565a4a6 100644 --- a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/grammar/ITokenizeLineResult.java +++ b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/grammar/ITokenizeLineResult.java @@ -19,7 +19,7 @@ /** * Result of the line tokenization API. * - * @see + * @see * github.com/microsoft/vscode-textmate/blob/main/src/main.ts */ public interface ITokenizeLineResult { diff --git a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/grammar/AttributedScopeStack.java b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/grammar/AttributedScopeStack.java index 0b947e031..fcc108930 100644 --- a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/grammar/AttributedScopeStack.java +++ b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/grammar/AttributedScopeStack.java @@ -26,7 +26,7 @@ /** * @see + * "https://github.com/microsoft/vscode-textmate/blob/167bbbd509356cc4617f250c0d754aef670ab14a/src/grammar/grammar.ts#L418"> * github.com/microsoft/vscode-textmate/blob/main/src/grammar/grammar.ts */ final class AttributedScopeStack { diff --git a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/grammar/BalancedBracketSelectors.java b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/grammar/BalancedBracketSelectors.java index d0e3315da..3b9e7b1c4 100644 --- a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/grammar/BalancedBracketSelectors.java +++ b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/grammar/BalancedBracketSelectors.java @@ -24,7 +24,7 @@ /** * @see + * "https://github.com/microsoft/vscode-textmate/blob/167bbbd509356cc4617f250c0d754aef670ab14a/src/grammar/grammar.ts#L898"> * github.com/microsoft/vscode-textmate/blob/main/src/grammar/grammar.ts */ public final class BalancedBracketSelectors { diff --git a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/grammar/BasicScopeAttributes.java b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/grammar/BasicScopeAttributes.java index afc867d40..55f7601ba 100644 --- a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/grammar/BasicScopeAttributes.java +++ b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/grammar/BasicScopeAttributes.java @@ -17,7 +17,7 @@ /** * @see + * "https://github.com/microsoft/vscode-textmate/blob/167bbbd509356cc4617f250c0d754aef670ab14a/src/grammar/basicScopesAttributeProvider.ts#L10"> * github.com/microsoft/vscode-textmate/blob/main/src/basicScopesAttributeProvider.ts */ final class BasicScopeAttributes { diff --git a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/grammar/BasicScopeAttributesProvider.java b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/grammar/BasicScopeAttributesProvider.java index 0e17aee9b..d952bb4d4 100644 --- a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/grammar/BasicScopeAttributesProvider.java +++ b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/grammar/BasicScopeAttributesProvider.java @@ -31,7 +31,7 @@ /** * @see + * "https://github.com/microsoft/vscode-textmate/blob/167bbbd509356cc4617f250c0d754aef670ab14a/src/grammar/basicScopesAttributeProvider.ts#L18"> * github.com/microsoft/vscode-textmate/blob/main/src/basicScopesAttributeProvider.ts */ final class BasicScopeAttributesProvider { diff --git a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/grammar/Grammar.java b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/grammar/Grammar.java index 509fbdde4..90de1738d 100644 --- a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/grammar/Grammar.java +++ b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/grammar/Grammar.java @@ -54,7 +54,7 @@ * TextMate grammar implementation. * * @see + * "https://github.com/microsoft/vscode-textmate/blob/167bbbd509356cc4617f250c0d754aef670ab14a/src/grammar/grammar.ts#L98"> * github.com/microsoft/vscode-textmate/blob/main/src/grammar/grammar.ts */ public final class Grammar implements IGrammar, IRuleFactoryHelper { diff --git a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/grammar/Injection.java b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/grammar/Injection.java index 73877718a..bec409c50 100644 --- a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/grammar/Injection.java +++ b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/grammar/Injection.java @@ -24,7 +24,7 @@ /** * @see + * "https://github.com/microsoft/vscode-textmate/blob/167bbbd509356cc4617f250c0d754aef670ab14a/src/grammar/grammar.ts#L49"> * github.com/microsoft/vscode-textmate/blob/main/src/grammar/grammar.ts */ final class Injection { diff --git a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/grammar/LineTokenizer.java b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/grammar/LineTokenizer.java index 847b59c8c..f1d7c9b66 100644 --- a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/grammar/LineTokenizer.java +++ b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/grammar/LineTokenizer.java @@ -41,7 +41,7 @@ /** * @see + * "https://github.com/microsoft/vscode-textmate/blob/167bbbd509356cc4617f250c0d754aef670ab14a/src/grammar/tokenizeString.ts#L31"> * github.com/microsoft/vscode-textmate/blob/main/src/grammar/tokenizeString.ts */ final class LineTokenizer { diff --git a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/grammar/LineTokens.java b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/grammar/LineTokens.java index cb8b6ea35..cce335422 100644 --- a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/grammar/LineTokens.java +++ b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/grammar/LineTokens.java @@ -34,7 +34,7 @@ /** * @see + * "https://github.com/microsoft/vscode-textmate/blob/167bbbd509356cc4617f250c0d754aef670ab14a/src/grammar/grammar.ts#L945"> * github.com/microsoft/vscode-textmate/blob/main/src/grammar/grammar.ts */ final class LineTokens { diff --git a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/grammar/ScopeStack.java b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/grammar/ScopeStack.java index e47e624c0..2c3131fdb 100644 --- a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/grammar/ScopeStack.java +++ b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/grammar/ScopeStack.java @@ -24,7 +24,7 @@ /** * @see + * "https://github.com/microsoft/vscode-textmate/blob/167bbbd509356cc4617f250c0d754aef670ab14a/src/theme.ts#L101"> * github.com/microsoft/vscode-textmate/blob/main/src/theme.ts */ public final class ScopeStack { diff --git a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/grammar/StateStack.java b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/grammar/StateStack.java index 499a84826..ca60083c4 100644 --- a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/grammar/StateStack.java +++ b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/grammar/StateStack.java @@ -33,7 +33,7 @@ * Represents a "pushed" state on the stack (as a linked list element). * * @see + * "https://github.com/microsoft/vscode-textmate/blob/167bbbd509356cc4617f250c0d754aef670ab14a/src/grammar/grammar.ts#L592"> * github.com/microsoft/vscode-textmate/blob/main/src/grammar/grammar.ts */ public final class StateStack implements IStateStack { diff --git a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/grammar/TokenTypeMatcher.java b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/grammar/TokenTypeMatcher.java index 6a4ee7a58..bfafaa3cf 100644 --- a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/grammar/TokenTypeMatcher.java +++ b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/grammar/TokenTypeMatcher.java @@ -23,7 +23,7 @@ /** * @see + * "https://github.com/microsoft/vscode-textmate/blob/167bbbd509356cc4617f250c0d754aef670ab14a/src/grammar/grammar.ts#L893"> * github.com/microsoft/vscode-textmate/blob/main/src/grammar/grammar.ts */ final class TokenTypeMatcher { diff --git a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/grammar/TokenizeLineResult.java b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/grammar/TokenizeLineResult.java index a154c8c18..fdbdc0fe0 100644 --- a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/grammar/TokenizeLineResult.java +++ b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/grammar/TokenizeLineResult.java @@ -21,7 +21,7 @@ /** * Result of the line tokenization implementation. * - * @see + * @see * github.com/microsoft/vscode-textmate/blob/main/src/main.ts */ final class TokenizeLineResult implements ITokenizeLineResult { diff --git a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/grammar/dependencies/AbsoluteRuleReference.java b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/grammar/dependencies/AbsoluteRuleReference.java index b6cce0139..3923c5b8e 100644 --- a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/grammar/dependencies/AbsoluteRuleReference.java +++ b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/grammar/dependencies/AbsoluteRuleReference.java @@ -19,7 +19,7 @@ /** * @see + * "https://github.com/microsoft/vscode-textmate/blob/167bbbd509356cc4617f250c0d754aef670ab14a/src/grammar/grammarDependencies.ts#L10"> * github.com/microsoft/vscode-textmate/blob/main/src/grammar/grammarDependencies.ts */ public abstract class AbsoluteRuleReference { diff --git a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/grammar/dependencies/IncludeReference.java b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/grammar/dependencies/IncludeReference.java index e988968d5..f7fc55297 100644 --- a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/grammar/dependencies/IncludeReference.java +++ b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/grammar/dependencies/IncludeReference.java @@ -21,7 +21,7 @@ /** * @see + * "https://github.com/microsoft/vscode-textmate/blob/167bbbd509356cc4617f250c0d754aef670ab14a/src/grammar/grammarDependencies.ts#L240"> * github.com/microsoft/vscode-textmate/blob/main/src/grammar/grammarDependencies.ts */ public final class IncludeReference { diff --git a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/grammar/dependencies/ScopeDependencyProcessor.java b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/grammar/dependencies/ScopeDependencyProcessor.java index fceffd4d0..0c20bd1f7 100644 --- a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/grammar/dependencies/ScopeDependencyProcessor.java +++ b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/grammar/dependencies/ScopeDependencyProcessor.java @@ -37,7 +37,7 @@ /** * @see + * "https://github.com/microsoft/vscode-textmate/blob/167bbbd509356cc4617f250c0d754aef670ab14a/src/grammar/grammarDependencies.ts#L59"> * github.com/microsoft/vscode-textmate/blob/main/src/grammar/grammarDependencies.ts */ public final class ScopeDependencyProcessor { diff --git a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/grammar/raw/IRawCaptures.java b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/grammar/raw/IRawCaptures.java index 682612a55..18eb873a3 100644 --- a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/grammar/raw/IRawCaptures.java +++ b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/grammar/raw/IRawCaptures.java @@ -22,7 +22,7 @@ /** * @see + * "https://github.com/microsoft/vscode-textmate/blob/167bbbd509356cc4617f250c0d754aef670ab14a/src/rawGrammar.ts#L62"> * github.com/microsoft/vscode-textmate/blob/main/src/rawGrammar.ts */ public interface IRawCaptures { diff --git a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/grammar/raw/IRawGrammar.java b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/grammar/raw/IRawGrammar.java index a0abc52b9..c86b67561 100644 --- a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/grammar/raw/IRawGrammar.java +++ b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/grammar/raw/IRawGrammar.java @@ -23,7 +23,7 @@ /** * @see + * "https://github.com/microsoft/vscode-textmate/blob/167bbbd509356cc4617f250c0d754aef670ab14a/src/rawGrammar.ts#L8"> * github.com/microsoft/vscode-textmate/blob/main/src/rawGrammar.ts */ public interface IRawGrammar { diff --git a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/grammar/raw/IRawRepository.java b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/grammar/raw/IRawRepository.java index 0a846fbe5..2599ef939 100644 --- a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/grammar/raw/IRawRepository.java +++ b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/grammar/raw/IRawRepository.java @@ -21,7 +21,7 @@ /** * @see + * "https://github.com/microsoft/vscode-textmate/blob/167bbbd509356cc4617f250c0d754aef670ab14a/src/rawGrammar.ts#L37"> * github.com/microsoft/vscode-textmate/blob/main/src/rawGrammar.ts */ public interface IRawRepository { diff --git a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/grammar/raw/IRawRule.java b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/grammar/raw/IRawRule.java index 58e6d967e..c96b5b111 100644 --- a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/grammar/raw/IRawRule.java +++ b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/grammar/raw/IRawRule.java @@ -23,7 +23,7 @@ /** * @see + * "https://github.com/microsoft/vscode-textmate/blob/167bbbd509356cc4617f250c0d754aef670ab14a/src/rawGrammar.ts#L39"> * github.com/microsoft/vscode-textmate/blob/main/src/rawGrammar.ts */ public interface IRawRule { diff --git a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/grammar/tokenattrs/EncodedTokenAttributes.java b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/grammar/tokenattrs/EncodedTokenAttributes.java index 6037cda6a..2498da49c 100644 --- a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/grammar/tokenattrs/EncodedTokenAttributes.java +++ b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/grammar/tokenattrs/EncodedTokenAttributes.java @@ -16,7 +16,7 @@ /** * @see + * "https://github.com/microsoft/vscode-textmate/blob/167bbbd509356cc4617f250c0d754aef670ab14a/src/encodedTokenAttributes.ts#L9"> * github.com/microsoft/vscode-textmate/blob/main/src/encodedTokenAttributes.ts */ public final class EncodedTokenAttributes { diff --git a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/grammar/tokenattrs/EncodedTokenDataConsts.java b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/grammar/tokenattrs/EncodedTokenDataConsts.java index e7a51e87c..987e523b7 100644 --- a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/grammar/tokenattrs/EncodedTokenDataConsts.java +++ b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/grammar/tokenattrs/EncodedTokenDataConsts.java @@ -33,7 +33,7 @@ * - b = background color (9 bits) * * @see + * "https://github.com/microsoft/vscode-textmate/blob/167bbbd509356cc4617f250c0d754aef670ab14a/src/encodedTokenAttributes.ts#L143"> * github.com/microsoft/vscode-textmate/blob/main/src/encodedTokenAttributes.ts */ final class EncodedTokenDataConsts { diff --git a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/grammar/tokenattrs/OptionalStandardTokenType.java b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/grammar/tokenattrs/OptionalStandardTokenType.java index 6b277dfda..6b325e828 100644 --- a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/grammar/tokenattrs/OptionalStandardTokenType.java +++ b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/grammar/tokenattrs/OptionalStandardTokenType.java @@ -19,7 +19,7 @@ /** * @see + * "https://github.com/microsoft/vscode-textmate/blob/167bbbd509356cc4617f250c0d754aef670ab14a/src/encodedTokenAttributes.ts#L181"> * github.com/microsoft/vscode-textmate/blob/main/src/encodedTokenAttributes.ts */ public final class OptionalStandardTokenType { diff --git a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/grammar/tokenattrs/StandardTokenType.java b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/grammar/tokenattrs/StandardTokenType.java index b5720485c..27d1736cb 100644 --- a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/grammar/tokenattrs/StandardTokenType.java +++ b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/grammar/tokenattrs/StandardTokenType.java @@ -15,7 +15,7 @@ * Standard TextMate token type. * * @see + * "https://github.com/microsoft/vscode-textmate/blob/167bbbd509356cc4617f250c0d754aef670ab14a/src/encodedTokenAttributes.ts#L159"> * github.com/microsoft/vscode-textmate/blob/main/src/encodedTokenAttributes.ts */ final class StandardTokenType { diff --git a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/matcher/Matcher.java b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/matcher/Matcher.java index 1f95d78ba..c53dcbcec 100644 --- a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/matcher/Matcher.java +++ b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/matcher/Matcher.java @@ -20,7 +20,7 @@ /** * @see + * "https://github.com/microsoft/vscode-textmate/blob/167bbbd509356cc4617f250c0d754aef670ab14a/src/matcher.ts#L10"> * github.com/microsoft/vscode-textmate/blob/main/src/matcher.ts */ @FunctionalInterface diff --git a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/matcher/MatcherBuilder.java b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/matcher/MatcherBuilder.java index 1efefd83a..4a9864394 100644 --- a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/matcher/MatcherBuilder.java +++ b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/matcher/MatcherBuilder.java @@ -27,7 +27,7 @@ /** * @see + * "https://github.com/microsoft/vscode-textmate/blob/167bbbd509356cc4617f250c0d754aef670ab14a/src/matcher.ts#L14"> * github.com/microsoft/vscode-textmate/blob/main/src/matcher.ts */ final class MatcherBuilder { @@ -150,7 +150,7 @@ private Matcher parseInnerExpression() { /** * @see + * "https://github.com/microsoft/vscode-textmate/blob/167bbbd509356cc4617f250c0d754aef670ab14a/src/matcher.ts#L89"> * github.com/microsoft/vscode-textmate/blob/main/src/matcher.ts */ private boolean isIdentifier(final String token) { @@ -178,7 +178,7 @@ private boolean isIdentifier(final String token) { /** * @see + * "https://github.com/microsoft/vscode-textmate/blob/167bbbd509356cc4617f250c0d754aef670ab14a/src/matcher.ts#L93"> * github.com/microsoft/vscode-textmate/blob/main/src/matcher.ts */ private static final class Tokenizer { diff --git a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/matcher/MatcherWithPriority.java b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/matcher/MatcherWithPriority.java index 310bc3d65..8f7547f50 100644 --- a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/matcher/MatcherWithPriority.java +++ b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/matcher/MatcherWithPriority.java @@ -18,7 +18,7 @@ /** * @see + * "https://github.com/microsoft/vscode-textmate/blob/167bbbd509356cc4617f250c0d754aef670ab14a/src/matcher.ts#L5"> * github.com/microsoft/vscode-textmate/blob/main/src/matcher.ts */ public final class MatcherWithPriority { diff --git a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/matcher/NameMatcher.java b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/matcher/NameMatcher.java index b6a573cb8..d4d446440 100644 --- a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/matcher/NameMatcher.java +++ b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/matcher/NameMatcher.java @@ -23,7 +23,7 @@ /** * @see + * "https://github.com/microsoft/vscode-textmate/blob/167bbbd509356cc4617f250c0d754aef670ab14a/src/grammar/grammar.ts#L71"> * github.com/microsoft/vscode-textmate/blob/main/src/grammar/grammar.ts */ public interface NameMatcher { diff --git a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/parser/TMParserJSON.java b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/parser/TMParserJSON.java index 72789c440..4f2c7d8d6 100644 --- a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/parser/TMParserJSON.java +++ b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/parser/TMParserJSON.java @@ -14,9 +14,11 @@ import static org.eclipse.tm4e.core.internal.utils.NullSafetyHelper.assertNonNull; +import java.io.BufferedReader; import java.io.Reader; import java.util.List; import java.util.Map; +import java.util.stream.Collectors; import org.eclipse.jdt.annotation.NonNull; @@ -26,13 +28,32 @@ public class TMParserJSON implements TMParser { public static final TMParserJSON INSTANCE = new TMParserJSON(); + private static String removeTrailingCommas(final String jsonString) { + /* matches: + * -------------- + * }, + * } + * -------------- + * as well as: + * -------------- + * }, + * // foo + * // bar + * } + * -------------- + */ + return jsonString.replaceAll("(,)(\\s*\\n(\\s*\\/\\/.*\\n)*\\s*[\\]}])", "$2"); + } + private static final Gson LOADER = new Gson(); protected TMParserJSON() { } protected Map loadRaw(final Reader source) { - return assertNonNull(LOADER.fromJson(source, Map.class)); + // GSON does not support trailing commas so we have to manually remove them -> maybe better switch to jackson json parser? + final var jsonString = removeTrailingCommas(new BufferedReader(source).lines().collect(Collectors.joining("\n"))); + return assertNonNull(LOADER.fromJson(jsonString, Map.class)); } @Override diff --git a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/registry/IGrammarRepository.java b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/registry/IGrammarRepository.java index 76855799d..32ba94d61 100644 --- a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/registry/IGrammarRepository.java +++ b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/registry/IGrammarRepository.java @@ -25,7 +25,7 @@ * TextMate grammar repository API. * * @see + * "https://github.com/microsoft/vscode-textmate/blob/167bbbd509356cc4617f250c0d754aef670ab14a/src/grammar/grammar.ts#L44"> * github.com/microsoft/vscode-textmate/blob/main/src/grammar/grammar.ts */ public interface IGrammarRepository { diff --git a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/registry/IThemeProvider.java b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/registry/IThemeProvider.java index eb7c08e9d..947923d10 100644 --- a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/registry/IThemeProvider.java +++ b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/registry/IThemeProvider.java @@ -17,7 +17,7 @@ /** * @see + * "https://github.com/microsoft/vscode-textmate/blob/167bbbd509356cc4617f250c0d754aef670ab14a/src/grammar/grammar.ts#L39"> * github.com/microsoft/vscode-textmate/blob/main/src/grammar/grammar.ts */ public interface IThemeProvider { diff --git a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/registry/SyncRegistry.java b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/registry/SyncRegistry.java index 30b36acb3..c46ed9784 100644 --- a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/registry/SyncRegistry.java +++ b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/registry/SyncRegistry.java @@ -33,7 +33,7 @@ /** * @see + * "https://github.com/microsoft/vscode-textmate/blob/167bbbd509356cc4617f250c0d754aef670ab14a/src/registry.ts#L11"> * github.com/microsoft/vscode-textmate/blob/main/src/registry.ts */ public class SyncRegistry implements IGrammarRepository, IThemeProvider { diff --git a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/rule/BeginEndRule.java b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/rule/BeginEndRule.java index 26c83d4fb..7e344967a 100644 --- a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/rule/BeginEndRule.java +++ b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/rule/BeginEndRule.java @@ -25,7 +25,7 @@ /** * @see + * "https://github.com/microsoft/vscode-textmate/blob/167bbbd509356cc4617f250c0d754aef670ab14a/src/rule.ts#L209"> * github.com/microsoft/vscode-textmate/blob/main/src/rule.ts */ public final class BeginEndRule extends Rule { diff --git a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/rule/BeginWhileRule.java b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/rule/BeginWhileRule.java index 1457a4cb3..5c37c77d9 100644 --- a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/rule/BeginWhileRule.java +++ b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/rule/BeginWhileRule.java @@ -25,7 +25,7 @@ /** * @see + * "https://github.com/microsoft/vscode-textmate/blob/167bbbd509356cc4617f250c0d754aef670ab14a/src/rule.ts#L290"> * github.com/microsoft/vscode-textmate/blob/main/src/rule.ts */ public final class BeginWhileRule extends Rule { diff --git a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/rule/CaptureRule.java b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/rule/CaptureRule.java index 05b10c965..882462b5f 100644 --- a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/rule/CaptureRule.java +++ b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/rule/CaptureRule.java @@ -20,7 +20,7 @@ /** * @see + * "https://github.com/microsoft/vscode-textmate/blob/167bbbd509356cc4617f250c0d754aef670ab14a/src/rule.ts#L96"> * github.com/microsoft/vscode-textmate/blob/main/src/rule.ts */ public final class CaptureRule extends Rule { diff --git a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/rule/CompilePatternsResult.java b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/rule/CompilePatternsResult.java index 072557b00..ddecd1ba7 100644 --- a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/rule/CompilePatternsResult.java +++ b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/rule/CompilePatternsResult.java @@ -18,7 +18,7 @@ /** * @see + * "https://github.com/microsoft/vscode-textmate/blob/167bbbd509356cc4617f250c0d754aef670ab14a/src/rule.ts#L91"> * github.com/microsoft/vscode-textmate/blob/main/src/rule.ts */ final class CompilePatternsResult { diff --git a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/rule/CompiledRule.java b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/rule/CompiledRule.java index 3448e8aa1..c2f36c5f4 100644 --- a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/rule/CompiledRule.java +++ b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/rule/CompiledRule.java @@ -22,7 +22,7 @@ /** * @see + * "https://github.com/microsoft/vscode-textmate/blob/167bbbd509356cc4617f250c0d754aef670ab14a/src/rule.ts#L858"> * github.com/microsoft/vscode-textmate/blob/main/src/rule.ts */ public final class CompiledRule { diff --git a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/rule/IGrammarRegistry.java b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/rule/IGrammarRegistry.java index b7c737095..3323f4d96 100644 --- a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/rule/IGrammarRegistry.java +++ b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/rule/IGrammarRegistry.java @@ -22,7 +22,7 @@ /** * @see + * "https://github.com/microsoft/vscode-textmate/blob/167bbbd509356cc4617f250c0d754aef670ab14a/src/rule.ts#L17"> * github.com/microsoft/vscode-textmate/blob/main/src/rule.ts */ interface IGrammarRegistry { diff --git a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/rule/IRuleFactoryHelper.java b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/rule/IRuleFactoryHelper.java index 48f2ea25f..dc624e942 100644 --- a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/rule/IRuleFactoryHelper.java +++ b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/rule/IRuleFactoryHelper.java @@ -18,7 +18,7 @@ /** * @see + * "https://github.com/microsoft/vscode-textmate/blob/167bbbd509356cc4617f250c0d754aef670ab14a/src/rule.ts#L40"> * github.com/microsoft/vscode-textmate/blob/main/src/rule.ts */ public interface IRuleFactoryHelper extends IRuleRegistry, IGrammarRegistry { diff --git a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/rule/IRuleRegistry.java b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/rule/IRuleRegistry.java index 63b032fff..aa94299c8 100644 --- a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/rule/IRuleRegistry.java +++ b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/rule/IRuleRegistry.java @@ -20,7 +20,7 @@ /** * @see + * "https://github.com/microsoft/vscode-textmate/blob/167bbbd509356cc4617f250c0d754aef670ab14a/src/rule.ts#L31"> * github.com/microsoft/vscode-textmate/blob/main/src/rule.ts */ public interface IRuleRegistry { diff --git a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/rule/IncludeOnlyRule.java b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/rule/IncludeOnlyRule.java index efb63a6e1..dbe808928 100644 --- a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/rule/IncludeOnlyRule.java +++ b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/rule/IncludeOnlyRule.java @@ -20,7 +20,7 @@ /** * @see + * "https://github.com/microsoft/vscode-textmate/blob/167bbbd509356cc4617f250c0d754aef670ab14a/src/rule.ts#L166"> * github.com/microsoft/vscode-textmate/blob/main/src/rule.ts */ final class IncludeOnlyRule extends Rule { diff --git a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/rule/MatchRule.java b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/rule/MatchRule.java index 529ff685f..81ab7bfb3 100644 --- a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/rule/MatchRule.java +++ b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/rule/MatchRule.java @@ -22,7 +22,7 @@ /** * @see + * "https://github.com/microsoft/vscode-textmate/blob/167bbbd509356cc4617f250c0d754aef670ab14a/src/rule.ts#L122"> * github.com/microsoft/vscode-textmate/blob/main/src/rule.ts */ public final class MatchRule extends Rule { diff --git a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/rule/RegExpSource.java b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/rule/RegExpSource.java index 9ebe5afcd..aaba9f903 100644 --- a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/rule/RegExpSource.java +++ b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/rule/RegExpSource.java @@ -27,7 +27,7 @@ /** * @see + * "https://github.com/microsoft/vscode-textmate/blob/167bbbd509356cc4617f250c0d754aef670ab14a/src/rule.ts#L582"> * github.com/microsoft/vscode-textmate/blob/main/src/rule.ts */ final class RegExpSource { diff --git a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/rule/RegExpSourceList.java b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/rule/RegExpSourceList.java index cf0fcfe08..16ea2e5d4 100644 --- a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/rule/RegExpSourceList.java +++ b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/rule/RegExpSourceList.java @@ -24,7 +24,7 @@ /** * @see + * "https://github.com/microsoft/vscode-textmate/blob/167bbbd509356cc4617f250c0d754aef670ab14a/src/rule.ts#L744"> * github.com/microsoft/vscode-textmate/blob/main/src/rule.ts */ final class RegExpSourceList { diff --git a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/rule/Rule.java b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/rule/Rule.java index 76ac497cd..c6fb33181 100644 --- a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/rule/Rule.java +++ b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/rule/Rule.java @@ -23,7 +23,7 @@ /** * @see + * "https://github.com/microsoft/vscode-textmate/blob/167bbbd509356cc4617f250c0d754aef670ab14a/src/rule.ts#L43"> * github.com/microsoft/vscode-textmate/blob/main/src/rule.ts */ public abstract class Rule { diff --git a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/rule/RuleFactory.java b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/rule/RuleFactory.java index f32ed06bf..f9ac514d0 100644 --- a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/rule/RuleFactory.java +++ b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/rule/RuleFactory.java @@ -34,7 +34,7 @@ /** * @see + * "https://github.com/microsoft/vscode-textmate/blob/167bbbd509356cc4617f250c0d754aef670ab14a/src/rule.ts#L381"> * github.com/microsoft/vscode-textmate/blob/main/src/rule.ts */ public final class RuleFactory { diff --git a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/rule/RuleId.java b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/rule/RuleId.java index 7cc948489..2332c5838 100644 --- a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/rule/RuleId.java +++ b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/rule/RuleId.java @@ -21,7 +21,7 @@ /** * @see + * "https://github.com/microsoft/vscode-textmate/blob/167bbbd509356cc4617f250c0d754aef670ab14a/src/rule.ts#L14"> * github.com/microsoft/vscode-textmate/blob/main/src/rule.ts */ public final class RuleId { diff --git a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/theme/ColorMap.java b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/theme/ColorMap.java index c55735158..489b38466 100644 --- a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/theme/ColorMap.java +++ b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/theme/ColorMap.java @@ -21,7 +21,7 @@ import org.eclipse.tm4e.core.TMException; /** - * Based on + * Based on * github.com/microsoft/vscode-textmate/blob/main/src/theme.ts#ColorMap. *

* See also + * "https://github.com/microsoft/vscode-textmate/blob/167bbbd509356cc4617f250c0d754aef670ab14a/src/theme.ts#L306"> * https://github.com/microsoft/vscode-textmate/blob/main/src/theme.ts */ public final class FontStyle { diff --git a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/theme/ParsedThemeRule.java b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/theme/ParsedThemeRule.java index b424f115d..b768a9144 100644 --- a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/theme/ParsedThemeRule.java +++ b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/theme/ParsedThemeRule.java @@ -18,7 +18,7 @@ /** * @see + * "https://github.com/microsoft/vscode-textmate/blob/167bbbd509356cc4617f250c0d754aef670ab14a/src/theme.ts#L294"> * github.com/microsoft/vscode-textmate/blob/main/src/theme.ts */ public class ParsedThemeRule { diff --git a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/theme/StyleAttributes.java b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/theme/StyleAttributes.java index cf601b391..1759a5cdc 100644 --- a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/theme/StyleAttributes.java +++ b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/theme/StyleAttributes.java @@ -20,7 +20,7 @@ /** * @see + * "https://github.com/microsoft/vscode-textmate/blob/167bbbd509356cc4617f250c0d754aef670ab14a/src/theme.ts#L190"> * github.com/microsoft/vscode-textmate/blob/main/src/theme.ts */ public class StyleAttributes { diff --git a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/theme/Theme.java b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/theme/Theme.java index efadec9c7..6f1e9b001 100644 --- a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/theme/Theme.java +++ b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/theme/Theme.java @@ -30,7 +30,7 @@ /** * TextMate theme. * - * Based on + * Based on * github.com/microsoft/vscode-textmate/blob/main/src/theme.ts#Theme. *

* See also getEditorColors() { // custom tm4e code, not from ups effectiveRule.background); } - private boolean _scopePathMatchesParentScopes(@Nullable ScopeStack scopePath, @Nullable final List parentScopeNames) { - if (parentScopeNames == null) { + private boolean _scopePathMatchesParentScopes(@Nullable ScopeStack scopePath, final List parentScopeNames) { + if (parentScopeNames.isEmpty()) { return true; } - var index = 0; - var scopePattern = parentScopeNames.get(index); + // Starting with the deepest parent scope, look for a match in the scope path. + final var parentScopeNamesLen = parentScopeNames.size(); + for (int index = 0; index < parentScopeNamesLen; index++) { + var scopePattern = parentScopeNames.get(index); + boolean scopeMustMatch = false; + + // Check for a child combinator (a parent-child relationship) + if (">".equals(scopePattern)) { + if (index == parentScopeNamesLen - 1) { + // Invalid use of child combinator + return false; + } + scopePattern = parentScopeNames.get(++index); + scopeMustMatch = true; + } - while (scopePath != null) { - if (_matchesScope(scopePath.scopeName, scopePattern)) { - index++; - if (index == parentScopeNames.size()) { - return true; + while (scopePath != null) { + if (_matchesScope(scopePath.scopeName, scopePattern)) { + break; + } + if (scopeMustMatch) { + // If a child combinator was used, the parent scope must match. + return false; } - scopePattern = parentScopeNames.get(index); + scopePath = scopePath.parent; + } + + if (scopePath == null) { + // No more potential matches + return false; } scopePath = scopePath.parent; } - return false; + // All parent scopes were matched. + return true; } private boolean _matchesScope(final String scopeName, final String scopeNamePattern) { diff --git a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/theme/ThemeTrieElement.java b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/theme/ThemeTrieElement.java index 8a230aeec..235371157 100644 --- a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/theme/ThemeTrieElement.java +++ b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/theme/ThemeTrieElement.java @@ -11,7 +11,6 @@ */ package org.eclipse.tm4e.core.internal.theme; -import static org.eclipse.tm4e.core.internal.utils.MoreCollections.asArrayList; import static org.eclipse.tm4e.core.internal.utils.StringUtils.strArrCmp; import java.util.ArrayList; @@ -22,7 +21,7 @@ import org.eclipse.jdt.annotation.Nullable; /** - * Based on + * Based on * github.com/microsoft/vscode-textmate/blob/main/src/theme.ts#ThemeTrieElement. *

* See also _sortBySpecificity(final List arr) { - if (arr.size() == 1) { - return arr; + private static int _cmpBySpecificity(final ThemeTrieElementRule a, final ThemeTrieElementRule b) { + // First, compare the scope depths of both rules. The “scope depth” of a rule is + // the number of segments (delimited by dots) in the rule's deepest scope name + // (i.e. the final scope name in the scope path delimited by spaces). + if (a.scopeDepth != b.scopeDepth) { + return b.scopeDepth - a.scopeDepth; } - arr.sort(ThemeTrieElement::_cmpBySpecificity); - return arr; - } - private static int _cmpBySpecificity(final ThemeTrieElementRule a, final ThemeTrieElementRule b) { - if (a.scopeDepth == b.scopeDepth) { - final var aParentScopes = a.parentScopes; - final var bParentScopes = b.parentScopes; - final int aParentScopesLen = aParentScopes == null ? 0 : aParentScopes.size(); - final int bParentScopesLen = bParentScopes == null ? 0 : bParentScopes.size(); - if (aParentScopesLen == bParentScopesLen) { - for (int i = 0; i < aParentScopesLen; i++) { - @SuppressWarnings("null") - final String aScope = aParentScopes.get(i); - @SuppressWarnings("null") - final String bScope = bParentScopes.get(i); - final int aLen = aScope.length(); - final int bLen = bScope.length(); - if (aLen != bLen) { - return bLen - aLen; - } - } + // Traverse the parent scopes depth-first, comparing the specificity of both + // rules' parent scopes, which matches the behavior described by ”Ranking Matches” + // in TextMate 1.5's manual: https://macromates.com/manual/en/scope_selectors + // Start at index 0 for both rules, since the parent scopes were reversed + // beforehand (i.e. index 0 is the deepest parent scope). + int aParentIndex = 0; + int bParentIndex = 0; + + final int aParentScopesSize = a.parentScopes.size(); + final int bParentScopesSize = b.parentScopes.size(); + + while (true) { + // Child combinators don't affect specificity. + if (aParentScopesSize > aParentIndex && ">".equals(a.parentScopes.get(aParentIndex))) { + aParentIndex++; + } + if (bParentScopesSize > bParentIndex && ">".equals(b.parentScopes.get(bParentIndex))) { + bParentIndex++; } - return bParentScopesLen - aParentScopesLen; + + // This is a scope-by-scope comparison, so we need to stop once a rule runs + // out of parent scopes. + if (aParentIndex >= aParentScopesSize || bParentIndex >= bParentScopesSize) { + break; + } + + // When sorting by scope name specificity, it's safe to treat a longer parent + // scope as more specific. If both rules' parent scopes match a given scope + // path, the longer parent scope will always be more specific. + final int parentScopeLengthDiff = b.parentScopes.get(bParentIndex).length() - a.parentScopes.get(aParentIndex).length(); + + if (parentScopeLengthDiff != 0) { + return parentScopeLengthDiff; + } + + aParentIndex++; + bParentIndex++; } - return b.scopeDepth - a.scopeDepth; + + // If a depth-first, scope-by-scope comparison resulted in a tie, the rule with + // more parent scopes is considered more specific. + return bParentScopesSize - aParentScopesSize; } public List match(final String scope) { - if ("".equals(scope)) { - return ThemeTrieElement._sortBySpecificity(asArrayList(this._mainRule, this._rulesWithParentScopes)); - } - - final int dotIndex = scope.indexOf('.'); - final String head; - final String tail; - if (dotIndex == -1) { - head = scope; - tail = ""; - } else { - head = scope.substring(0, dotIndex); - tail = scope.substring(dotIndex + 1); - } + if (!scope.isEmpty()) { + final int dotIndex = scope.indexOf('.'); + String head; + String tail; + if (dotIndex == -1) { + head = scope; + tail = ""; + } else { + head = scope.substring(0, dotIndex); + tail = scope.substring(dotIndex + 1); + } - final ThemeTrieElement child = this._children.get(head); - if (child != null) { - return child.match(tail); + final ThemeTrieElement child = this._children.get(head); + if (child != null) { + return child.match(tail); + } } - return ThemeTrieElement._sortBySpecificity(asArrayList(this._mainRule, this._rulesWithParentScopes)); + final var rules = new ArrayList<>(this._rulesWithParentScopes); + rules.add(this._mainRule); + rules.sort(ThemeTrieElement::_cmpBySpecificity); + return rules; } public void insert(final int scopeDepth, final String scope, @Nullable final List parentScopes, final int fontStyle, diff --git a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/theme/ThemeTrieElementRule.java b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/theme/ThemeTrieElementRule.java index d157a47fc..8f166ab78 100644 --- a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/theme/ThemeTrieElementRule.java +++ b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/theme/ThemeTrieElementRule.java @@ -12,13 +12,14 @@ package org.eclipse.tm4e.core.internal.theme; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.Objects; import org.eclipse.jdt.annotation.Nullable; /** - * Based on + * Based on * github.com/microsoft/vscode-textmate/blob/main/src/theme.ts#ThemeTrieElementRule. *

* See also parentScopes; + public final List parentScopes; public int fontStyle; public int foreground; public int background; @@ -36,7 +37,7 @@ public class ThemeTrieElementRule { public ThemeTrieElementRule(final int scopeDepth, final @Nullable List parentScopes, final int fontStyle, final int foreground, final int background) { this.scopeDepth = scopeDepth; - this.parentScopes = parentScopes; + this.parentScopes = parentScopes == null ? Collections.emptyList() : parentScopes; this.fontStyle = fontStyle; this.foreground = foreground; this.background = background; diff --git a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/theme/raw/IRawTheme.java b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/theme/raw/IRawTheme.java index 6188caa86..c60586993 100644 --- a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/theme/raw/IRawTheme.java +++ b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/theme/raw/IRawTheme.java @@ -17,7 +17,7 @@ import org.eclipse.jdt.annotation.Nullable; /** - * @see + * @see * github.com/microsoft/vscode-textmate/blob/main/src/theme.ts */ public interface IRawTheme { diff --git a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/theme/raw/IRawThemeSetting.java b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/theme/raw/IRawThemeSetting.java index fa8bca99b..e5d1e10f2 100644 --- a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/theme/raw/IRawThemeSetting.java +++ b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/theme/raw/IRawThemeSetting.java @@ -16,7 +16,7 @@ /** * A single theme setting. * - * @see + * @see * github.com/microsoft/vscode-textmate/blob/main/src/theme.ts */ public interface IRawThemeSetting { diff --git a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/utils/RegexSource.java b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/utils/RegexSource.java index 2e4011e79..01eb11741 100644 --- a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/utils/RegexSource.java +++ b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/utils/RegexSource.java @@ -24,7 +24,7 @@ /** * @see + * "https://github.com/microsoft/vscode-textmate/blob/167bbbd509356cc4617f250c0d754aef670ab14a/src/utils.ts#L59"> * github.com/microsoft/vscode-textmate/blob/main/src/utils.ts */ public final class RegexSource { @@ -35,7 +35,7 @@ public final class RegexSource { * Escapes/prefixes RegEx meta characters with a backslash in the given string. * * It is a non-regex based faster alternative to the TypeScript + * "https://github.com/microsoft/vscode-textmate/blob/167bbbd509356cc4617f250c0d754aef670ab14a/src/utils.ts#L159">TypeScript * implementation: * *

diff --git a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/utils/StringUtils.java b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/utils/StringUtils.java
index b29d3311e..fbdbd39f6 100644
--- a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/utils/StringUtils.java
+++ b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/internal/utils/StringUtils.java
@@ -26,7 +26,7 @@
 
 /**
  * @see 
+ *      "https://github.com/microsoft/vscode-textmate/blob/167bbbd509356cc4617f250c0d754aef670ab14a/src/utils.ts">
  *      github.com/microsoft/vscode-textmate/blob/main/src/utils.ts
  */
 public final class StringUtils {
diff --git a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/registry/IGrammarConfiguration.java b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/registry/IGrammarConfiguration.java
index 863ad613b..652bad49e 100644
--- a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/registry/IGrammarConfiguration.java
+++ b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/registry/IGrammarConfiguration.java
@@ -24,7 +24,7 @@
 
 /**
  * @see 
+ *      "https://github.com/microsoft/vscode-textmate/blob/167bbbd509356cc4617f250c0d754aef670ab14a/src/main.ts#L44">
  *      github.com/microsoft/vscode-textmate/blob/main/src/main.ts
  */
 public interface IGrammarConfiguration {
diff --git a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/registry/IRegistryOptions.java b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/registry/IRegistryOptions.java
index 962a06df9..eb5d0eb36 100644
--- a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/registry/IRegistryOptions.java
+++ b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/registry/IRegistryOptions.java
@@ -24,7 +24,7 @@
 
 /**
  * @see 
+ *      "https://github.com/microsoft/vscode-textmate/blob/167bbbd509356cc4617f250c0d754aef670ab14a/src/main.ts#L22">
  *      github.com/microsoft/vscode-textmate/blob/main/src/main.ts
  */
 public interface IRegistryOptions {
diff --git a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/registry/Registry.java b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/registry/Registry.java
index eb56b1f1e..5d27f91c0 100644
--- a/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/registry/Registry.java
+++ b/org.eclipse.tm4e.core/src/main/java/org/eclipse/tm4e/core/registry/Registry.java
@@ -41,7 +41,7 @@
  * The registry that will hold all grammars.
  *
  * @see 
+ *      "https://github.com/microsoft/vscode-textmate/blob/167bbbd509356cc4617f250c0d754aef670ab14a/src/main.ts#L54">
  *      github.com/microsoft/vscode-textmate/blob/main/src/main.ts
  *
  */
diff --git a/org.eclipse.tm4e.core/src/test/java/org/eclipse/tm4e/core/internal/grammar/tokenattrs/EncodedTokenAttributesTest.java b/org.eclipse.tm4e.core/src/test/java/org/eclipse/tm4e/core/internal/grammar/tokenattrs/EncodedTokenAttributesTest.java
index 4f75268f6..2cd4ddec8 100644
--- a/org.eclipse.tm4e.core/src/test/java/org/eclipse/tm4e/core/internal/grammar/tokenattrs/EncodedTokenAttributesTest.java
+++ b/org.eclipse.tm4e.core/src/test/java/org/eclipse/tm4e/core/internal/grammar/tokenattrs/EncodedTokenAttributesTest.java
@@ -27,7 +27,7 @@
 /**
  * {@link EncodedTokenAttributes} tests same than vscode-textmate.
  *
- * @see 
+ * @see 
  *      github.com/Microsoft/vscode-textmate/blob/master/src/tests/grammar.test.ts
  */
 @TestMethodOrder(MethodOrderer.OrderAnnotation.class)