diff --git a/org.eclipse.tm4e.ui/src/main/java/org/eclipse/tm4e/ui/text/TMPresentationReconciler.java b/org.eclipse.tm4e.ui/src/main/java/org/eclipse/tm4e/ui/text/TMPresentationReconciler.java index 1cfc1f6b4..793a5fbb0 100644 --- a/org.eclipse.tm4e.ui/src/main/java/org/eclipse/tm4e/ui/text/TMPresentationReconciler.java +++ b/org.eclipse.tm4e.ui/src/main/java/org/eclipse/tm4e/ui/text/TMPresentationReconciler.java @@ -90,9 +90,6 @@ */ public class TMPresentationReconciler implements IPresentationReconciler { - /** The default text attribute if none is returned as data by the current token. */ - private final Token defaultToken; - /** The target viewer. */ @Nullable private ITextViewer viewer; @@ -125,7 +122,6 @@ public class TMPresentationReconciler implements IPresentationReconciler { private boolean throwError; public TMPresentationReconciler() { - this.defaultToken = new Token(null); this.internalListener = new InternalListener(); this.fDefaultTextAttribute = new TextAttribute(null); if (PreferenceUtils.isDebugGenerateTest()) { @@ -528,6 +524,9 @@ private void colorize(final IRegion damage, final TMDocumentModel model) throws TMUIPlugin.logTrace("Render from: " + fromLineIndex + " to: " + toLineIndex); final var presentation = new TextPresentation(damage, 1000); Exception error = null; + + final var tokenProvider = this.tokenProvider; + try { int lastStart = presentation.getExtent().getOffset(); int length = 0; @@ -561,7 +560,8 @@ private void colorize(final IRegion damage, final TMDocumentModel model) throws tokenStartIndex = damage.getOffset() - startLineOffset; } else { tokenStartIndex = damage.getOffset() - startLineOffset; - final IToken token = toToken(currentToken); + final IToken token = tokenProvider == null ? ITokenProvider.DEFAULT_TOKEN + : tokenProvider.getToken(currentToken.type); lastAttribute = getTokenTextAttribute(token); length += getTokenLengh(tokenStartIndex, nextToken, lineIndex, doc); firstToken = false; @@ -573,7 +573,7 @@ private void colorize(final IRegion damage, final TMDocumentModel model) throws break; } - final IToken token = toToken(currentToken); + final IToken token = tokenProvider == null ? ITokenProvider.DEFAULT_TOKEN : tokenProvider.getToken(currentToken.type); final TextAttribute attribute = getTokenTextAttribute(token); if (lastAttribute.equals(attribute)) { length += getTokenLengh(tokenStartIndex, nextToken, lineIndex, doc); @@ -616,17 +616,6 @@ private boolean isAfterRegion(final TMToken token, final int startLineOffset, fi return token.startIndex + startLineOffset >= damage.getOffset() + damage.getLength(); } - private IToken toToken(final TMToken token) { - final var tokenProvider = this.tokenProvider; - if (tokenProvider != null) { - final IToken result = tokenProvider.getToken(token.type); - if (result != null) { - return result; - } - } - return defaultToken; - } - private int getTokenLengh(final int tokenStartIndex, @Nullable final TMToken nextToken, final int line, final IDocument document) throws BadLocationException { if (nextToken != null) { diff --git a/org.eclipse.tm4e.ui/src/main/java/org/eclipse/tm4e/ui/themes/ITokenProvider.java b/org.eclipse.tm4e.ui/src/main/java/org/eclipse/tm4e/ui/themes/ITokenProvider.java index a68f5080c..0c84a62b0 100644 --- a/org.eclipse.tm4e.ui/src/main/java/org/eclipse/tm4e/ui/themes/ITokenProvider.java +++ b/org.eclipse.tm4e.ui/src/main/java/org/eclipse/tm4e/ui/themes/ITokenProvider.java @@ -13,6 +13,7 @@ import org.eclipse.jdt.annotation.Nullable; import org.eclipse.jface.text.rules.IToken; +import org.eclipse.jface.text.rules.Token; import org.eclipse.swt.graphics.Color; /** @@ -21,14 +22,15 @@ */ public interface ITokenProvider { + IToken DEFAULT_TOKEN = new Token(null); + /** - * Returns the Eclipse {@link IToken} from the given type and null otherwise. + * Returns the Eclipse {@link IToken} from the given type and {@link #DEFAULT_TOKEN} otherwise. * * @param type - * - * @return the Eclipse {@link IToken} from the given type and null otherwise. + * + * @return the Eclipse {@link IToken} from the given type and {@link #DEFAULT_TOKEN} otherwise. */ - @Nullable IToken getToken(String type); @Nullable diff --git a/org.eclipse.tm4e.ui/src/main/java/org/eclipse/tm4e/ui/themes/Theme.java b/org.eclipse.tm4e.ui/src/main/java/org/eclipse/tm4e/ui/themes/Theme.java index 65400957d..1ecb351eb 100644 --- a/org.eclipse.tm4e.ui/src/main/java/org/eclipse/tm4e/ui/themes/Theme.java +++ b/org.eclipse.tm4e.ui/src/main/java/org/eclipse/tm4e/ui/themes/Theme.java @@ -81,11 +81,10 @@ public String getName() { return name; } - @Nullable @Override public IToken getToken(final String type) { final ITokenProvider provider = getTokenProvider(); - return provider != null ? provider.getToken(type) : null; + return provider == null ? ITokenProvider.DEFAULT_TOKEN : provider.getToken(type); } @Nullable diff --git a/org.eclipse.tm4e.ui/src/main/java/org/eclipse/tm4e/ui/themes/css/CSSTokenProvider.java b/org.eclipse.tm4e.ui/src/main/java/org/eclipse/tm4e/ui/themes/css/CSSTokenProvider.java index c90d93661..5ce3aefe1 100644 --- a/org.eclipse.tm4e.ui/src/main/java/org/eclipse/tm4e/ui/themes/css/CSSTokenProvider.java +++ b/org.eclipse.tm4e.ui/src/main/java/org/eclipse/tm4e/ui/themes/css/CSSTokenProvider.java @@ -16,6 +16,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; import org.eclipse.jdt.annotation.Nullable; import org.eclipse.jface.text.TextAttribute; @@ -46,6 +47,7 @@ public List getStyles() { } private final Map tokenMaps = new HashMap<>(); + private final Map getTokenReturnValueCache = new ConcurrentHashMap<>(); private final CSSParser parser; @@ -80,17 +82,20 @@ public CSSTokenProvider(final InputStream in) { this.parser = parser == null ? new NoopCSSParser() : parser; } - @Nullable @Override public IToken getToken(@Nullable final String type) { - if (type == null) - return null; + if (type == null || type.isEmpty()) + return DEFAULT_TOKEN; + + return getTokenReturnValueCache.computeIfAbsent(type, this::getTokenInternal); + } + private IToken getTokenInternal(final String type) { final IStyle style = parser.getBestStyle(StringUtils.splitToArray(type, '.')); if (style == null) - return null; - - return tokenMaps.get(style); + return DEFAULT_TOKEN; + final IToken token = tokenMaps.get(style); + return token == null ? DEFAULT_TOKEN : token; } @Nullable