diff --git a/java/java-impl/src/com/intellij/psi/impl/search/JspIndexPatternBuilder.java b/java/java-impl/src/com/intellij/psi/impl/search/JspIndexPatternBuilder.java index a8316f8dc0ee..eaa93875ba15 100644 --- a/java/java-impl/src/com/intellij/psi/impl/search/JspIndexPatternBuilder.java +++ b/java/java-impl/src/com/intellij/psi/impl/search/JspIndexPatternBuilder.java @@ -18,6 +18,7 @@ package com.intellij.psi.impl.search; import com.intellij.lang.LanguageParserDefinitions; import com.intellij.lang.ParserDefinition; import com.intellij.lexer.Lexer; +import com.intellij.openapi.editor.impl.EditorHighlighterCache; import com.intellij.psi.JspPsiUtil; import com.intellij.psi.PsiFile; import com.intellij.psi.impl.source.tree.StdTokenSets; @@ -34,7 +35,7 @@ public class JspIndexPatternBuilder implements IndexPatternBuilder { @Override public Lexer getIndexingLexer(@NotNull final PsiFile file) { if (JspPsiUtil.isInJspFile(file)) { - return LexerEditorHighlighterLexer.getLexerBasedOnLexerHighlighter(file.getText(), file.getVirtualFile(), file.getProject()); + return EditorHighlighterCache.getLexerBasedOnLexerHighlighter(file.getText(), file.getVirtualFile(), file.getProject()); } return null; diff --git a/platform/lang-impl/src/com/intellij/psi/impl/search/LexerEditorHighlighterLexer.java b/platform/editor-ui-ex/src/com/intellij/psi/impl/search/LexerEditorHighlighterLexer.java similarity index 61% rename from platform/lang-impl/src/com/intellij/psi/impl/search/LexerEditorHighlighterLexer.java rename to platform/editor-ui-ex/src/com/intellij/psi/impl/search/LexerEditorHighlighterLexer.java index 2add3ed1b3c5..a966d831b71a 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/search/LexerEditorHighlighterLexer.java +++ b/platform/editor-ui-ex/src/com/intellij/psi/impl/search/LexerEditorHighlighterLexer.java @@ -15,23 +15,12 @@ */ package com.intellij.psi.impl.search; -import com.intellij.lexer.Lexer; import com.intellij.lexer.LexerBase; -import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.highlighter.EditorHighlighter; -import com.intellij.openapi.editor.highlighter.EditorHighlighterFactory; import com.intellij.openapi.editor.highlighter.HighlighterIterator; -import com.intellij.openapi.editor.impl.EditorHighlighterCache; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.psi.PsiDocumentManager; -import com.intellij.psi.PsiFile; -import com.intellij.psi.PsiManager; -import com.intellij.psi.impl.cache.impl.id.PlatformIdTableBuilding; import com.intellij.psi.tree.IElementType; import com.intellij.util.text.CharSequenceSubSequence; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; /** * @author Sergey Evdokimov @@ -49,31 +38,6 @@ public class LexerEditorHighlighterLexer extends LexerBase { myAlreadyInitializedHighlighter = alreadyInitializedHighlighter; } - @Nullable - public static Lexer getLexerBasedOnLexerHighlighter(CharSequence text, VirtualFile virtualFile, Project project) { - EditorHighlighter highlighter = null; - - PsiFile psiFile = virtualFile != null ? PsiManager.getInstance(project).findFile(virtualFile) : null; - final Document document = psiFile != null ? PsiDocumentManager.getInstance(project).getDocument(psiFile) : null; - final EditorHighlighter cachedEditorHighlighter; - boolean alreadyInitializedHighlighter = false; - - if (document != null && - (cachedEditorHighlighter = EditorHighlighterCache.getEditorHighlighterForCachesBuilding(document)) != null && - PlatformIdTableBuilding.checkCanUseCachedEditorHighlighter(text, cachedEditorHighlighter)) { - highlighter = cachedEditorHighlighter; - alreadyInitializedHighlighter = true; - } - else if (virtualFile != null) { - highlighter = EditorHighlighterFactory.getInstance().createEditorHighlighter(project, virtualFile); - } - - if (highlighter != null) { - return new LexerEditorHighlighterLexer(highlighter, alreadyInitializedHighlighter); - } - return null; - } - @Override public void start(@NotNull CharSequence buffer, int startOffset, int endOffset, int state) { if (myAlreadyInitializedHighlighter) { diff --git a/platform/lang-impl/src/com/intellij/find/impl/FindManagerImpl.java b/platform/lang-impl/src/com/intellij/find/impl/FindManagerImpl.java index bc99477ac08f..05a40ab19ec5 100644 --- a/platform/lang-impl/src/com/intellij/find/impl/FindManagerImpl.java +++ b/platform/lang-impl/src/com/intellij/find/impl/FindManagerImpl.java @@ -27,7 +27,6 @@ import com.intellij.find.impl.livePreview.SearchResults; import com.intellij.lang.Language; import com.intellij.lang.LanguageParserDefinitions; import com.intellij.lang.ParserDefinition; -import com.intellij.lexer.LayeredLexer; import com.intellij.lexer.Lexer; import com.intellij.navigation.NavigationItem; import com.intellij.openapi.actionSystem.ActionManager; @@ -42,11 +41,6 @@ import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.*; import com.intellij.openapi.editor.colors.TextAttributesKey; import com.intellij.openapi.editor.ex.FoldingModelEx; -import com.intellij.openapi.editor.ex.util.LayeredHighlighterIterator; -import com.intellij.openapi.editor.ex.util.LayeredLexerEditorHighlighter; -import com.intellij.openapi.editor.highlighter.EditorHighlighter; -import com.intellij.openapi.editor.highlighter.EditorHighlighterFactory; -import com.intellij.openapi.editor.highlighter.HighlighterIterator; import com.intellij.openapi.editor.markup.RangeHighlighter; import com.intellij.openapi.fileEditor.FileEditor; import com.intellij.openapi.fileEditor.TextEditor; @@ -58,7 +52,6 @@ import com.intellij.openapi.util.*; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.*; -import com.intellij.psi.impl.search.LexerEditorHighlighterLexer; import com.intellij.psi.search.SearchScope; import com.intellij.psi.tree.IElementType; import com.intellij.psi.tree.TokenSet; @@ -66,6 +59,7 @@ import com.intellij.ui.LightweightHint; import com.intellij.ui.ReplacePromptDialog; import com.intellij.usages.ChunkExtractor; import com.intellij.usages.UsageViewManager; +import com.intellij.usages.impl.SyntaxHighlighterOverEditorHighlighter; import com.intellij.util.Consumer; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.messages.MessageBus; @@ -424,8 +418,7 @@ public class FindManagerImpl extends FindManager implements PersistentStateCompo private static class CommentsLiteralsSearchData { final VirtualFile lastFile; int startOffset = 0; - final SyntaxHighlighter highlighter; - final Lexer highlightingLexer; + final SyntaxHighlighterOverEditorHighlighter highlighter; TokenSet tokensOfInterest; final StringSearcher searcher; @@ -433,8 +426,8 @@ public class FindManagerImpl extends FindManager implements PersistentStateCompo final Set relevantLanguages; final FindModel model; - public CommentsLiteralsSearchData(VirtualFile lastFile, Set relevantLanguages, SyntaxHighlighter highlighter, - Lexer lexer, TokenSet tokensOfInterest, + public CommentsLiteralsSearchData(VirtualFile lastFile, Set relevantLanguages, + SyntaxHighlighterOverEditorHighlighter highlighter, TokenSet tokensOfInterest, StringSearcher searcher, Matcher matcher, FindModel model) { this.lastFile = lastFile; this.highlighter = highlighter; @@ -442,7 +435,6 @@ public class FindManagerImpl extends FindManager implements PersistentStateCompo this.searcher = searcher; this.matcher = matcher; this.relevantLanguages = relevantLanguages; - highlightingLexer = lexer; this.model = model; } } @@ -525,38 +517,15 @@ public class FindManagerImpl extends FindManager implements PersistentStateCompo Matcher matcher = model.isRegularExpressions() ? compileRegExp(model, ""):null; StringSearcher searcher = matcher != null ? null: new StringSearcher(model.getStringToFind(), model.isCaseSensitive(), true); - LayeredLexer.ourDisableLayersFlag.set(Boolean.TRUE); - EditorHighlighter editorHighlighter = EditorHighlighterFactory.getInstance().createEditorHighlighter(myProject, file); - Lexer lexer; - - try { - if (editorHighlighter instanceof LayeredLexerEditorHighlighter) { - lexer = new LexerEditorHighlighterLexer(editorHighlighter, false); - } else { - lexer = highlighter.getHighlightingLexer(); - } - } - finally { - LayeredLexer.ourDisableLayersFlag.set(null); - } - - data = new CommentsLiteralsSearchData(file, relevantLanguages, highlighter, lexer, tokensOfInterest, searcher, matcher, (FindModel)model.clone()); - lexer.start(text, 0, text.length(), 0); + SyntaxHighlighterOverEditorHighlighter highlighterAdapter = new SyntaxHighlighterOverEditorHighlighter(highlighter, file, myProject); + data = new CommentsLiteralsSearchData(file, relevantLanguages, highlighterAdapter, tokensOfInterest, searcher, matcher, model.clone()); + data.highlighter.restart(text); model.putUserData(ourCommentsLiteralsSearchDataKey, data); } int initialStartOffset = model.isForward() && data.startOffset < offset ? data.startOffset : 0; - final Lexer lexer = data.highlightingLexer; - LayeredHighlighterIterator layeredHighlighterIterator = null; - if (lexer instanceof LexerEditorHighlighterLexer) { - ((LexerEditorHighlighterLexer)lexer).resetPosition(initialStartOffset); - HighlighterIterator iterator = ((LexerEditorHighlighterLexer)lexer).getHighlighterIterator(); - if (iterator instanceof LayeredHighlighterIterator) { - layeredHighlighterIterator = (LayeredHighlighterIterator)iterator; - } - } else { - lexer.start(text, initialStartOffset, text.length(), 0); - } + data.highlighter.resetPosition(initialStartOffset); + final Lexer lexer = data.highlighter.getHighlightingLexer(); IElementType tokenType; TokenSet tokens = data.tokensOfInterest; @@ -568,9 +537,7 @@ public class FindManagerImpl extends FindManager implements PersistentStateCompo while((tokenType = lexer.getTokenType()) != null) { if (lexer.getState() == 0) lastGoodOffset = lexer.getTokenStart(); - final SyntaxHighlighter activeSyntaxHighlighter = - layeredHighlighterIterator != null ? layeredHighlighterIterator.getActiveSyntaxHighlighter() : data.highlighter; - final TextAttributesKey[] keys = activeSyntaxHighlighter.getTokenHighlights(tokenType); + final TextAttributesKey[] keys = data.highlighter.getTokenHighlights(tokenType); if (tokens.contains(tokenType) || (model.isInStringLiteralsOnly() && ChunkExtractor.isHighlightedAsString(keys)) || diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorHighlighterCache.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorHighlighterCache.java index c1499a71a71b..8be2284e8360 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorHighlighterCache.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorHighlighterCache.java @@ -15,10 +15,19 @@ */ package com.intellij.openapi.editor.impl; +import com.intellij.lexer.Lexer; import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.ex.util.LexerEditorHighlighter; import com.intellij.openapi.editor.highlighter.EditorHighlighter; +import com.intellij.openapi.editor.highlighter.EditorHighlighterFactory; +import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Key; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiDocumentManager; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiManager; +import com.intellij.psi.impl.cache.impl.id.PlatformIdTableBuilding; +import com.intellij.psi.impl.search.LexerEditorHighlighterLexer; import com.intellij.reference.SoftReference; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -55,4 +64,28 @@ public class EditorHighlighterCache { return null; } + @Nullable + public static Lexer getLexerBasedOnLexerHighlighter(CharSequence text, VirtualFile virtualFile, Project project) { + EditorHighlighter highlighter = null; + + PsiFile psiFile = virtualFile != null ? PsiManager.getInstance(project).findFile(virtualFile) : null; + final Document document = psiFile != null ? PsiDocumentManager.getInstance(project).getDocument(psiFile) : null; + final EditorHighlighter cachedEditorHighlighter; + boolean alreadyInitializedHighlighter = false; + + if (document != null && + (cachedEditorHighlighter = getEditorHighlighterForCachesBuilding(document)) != null && + PlatformIdTableBuilding.checkCanUseCachedEditorHighlighter(text, cachedEditorHighlighter)) { + highlighter = cachedEditorHighlighter; + alreadyInitializedHighlighter = true; + } + else if (virtualFile != null) { + highlighter = EditorHighlighterFactory.getInstance().createEditorHighlighter(project, virtualFile); + } + + if (highlighter != null) { + return new LexerEditorHighlighterLexer(highlighter, alreadyInitializedHighlighter); + } + return null; + } } diff --git a/platform/usageView/src/com/intellij/usages/ChunkExtractor.java b/platform/usageView/src/com/intellij/usages/ChunkExtractor.java index 71a1f50f1cd5..eea15c93605d 100644 --- a/platform/usageView/src/com/intellij/usages/ChunkExtractor.java +++ b/platform/usageView/src/com/intellij/usages/ChunkExtractor.java @@ -37,6 +37,7 @@ import com.intellij.psi.tree.IElementType; import com.intellij.reference.SoftReference; import com.intellij.usageView.UsageTreeColors; import com.intellij.usageView.UsageTreeColorsScheme; +import com.intellij.usages.impl.SyntaxHighlighterOverEditorHighlighter; import com.intellij.usages.impl.rules.UsageType; import com.intellij.util.Processor; import com.intellij.util.containers.FactoryMap; @@ -64,9 +65,7 @@ public class ChunkExtractor { private final Document myDocument; private long myDocumentStamp; - private final SyntaxHighlighter myHighlighter; - - private final Lexer myLexer; + private final SyntaxHighlighterOverEditorHighlighter myHighlighter; private abstract static class WeakFactory { private WeakReference myRef; @@ -119,11 +118,10 @@ public class ChunkExtractor { myDocument = PsiDocumentManager.getInstance(project).getDocument(file); LOG.assertTrue(myDocument != null); final FileType fileType = file.getFileType(); - final SyntaxHighlighter highlighter = SyntaxHighlighterFactory.getSyntaxHighlighter(fileType, project, file.getVirtualFile()); - myHighlighter = highlighter == null ? new PlainSyntaxHighlighter() : highlighter; - myLexer = myHighlighter.getHighlightingLexer(); - myLexer.start(myDocument.getCharsSequence()); - myDocumentStamp = myDocument.getModificationStamp(); + SyntaxHighlighter highlighter = SyntaxHighlighterFactory.getSyntaxHighlighter(fileType, project, file.getVirtualFile()); + highlighter = highlighter == null ? new PlainSyntaxHighlighter() : highlighter; + myHighlighter = new SyntaxHighlighterOverEditorHighlighter(highlighter, file.getVirtualFile(), project); + myDocumentStamp = -1; } public static int getStartOffset(final List rangeMarkers) { @@ -194,18 +192,21 @@ public class ChunkExtractor { int end, boolean selectUsageWithBold, @NotNull List result) { - final Lexer lexer = myLexer; - final SyntaxHighlighter highlighter = myHighlighter; + final Lexer lexer = myHighlighter.getHighlightingLexer(); + final SyntaxHighlighterOverEditorHighlighter highlighter = myHighlighter; LOG.assertTrue(start <= end); int i = StringUtil.indexOf(chars, '\n', start, end); if (i != -1) end = i; - if (lexer.getTokenStart() > start || myDocumentStamp != myDocument.getModificationStamp()) { - lexer.start(chars); + if (myDocumentStamp != myDocument.getModificationStamp()) { + highlighter.restart(chars); myDocumentStamp = myDocument.getModificationStamp(); + } else if(lexer.getTokenStart() > start) { + highlighter.resetPosition(0); } + boolean isBeginning = true; for(;lexer.getTokenType() != null; lexer.advance()) { @@ -218,8 +219,10 @@ public class ChunkExtractor { hiEnd = Math.min(hiEnd, end); if (hiStart >= hiEnd) { continue; } - String text = chars.subSequence(hiStart, hiEnd).toString(); - if (isBeginning && text.trim().isEmpty()) continue; + if (isBeginning) { + String text = chars.subSequence(hiStart, hiEnd).toString(); + if(text.trim().isEmpty()) continue; + } isBeginning = false; IElementType tokenType = lexer.getTokenType(); TextAttributesKey[] tokenHighlights = highlighter.getTokenHighlights(tokenType); diff --git a/platform/usageView/src/com/intellij/usages/impl/SyntaxHighlighterOverEditorHighlighter.java b/platform/usageView/src/com/intellij/usages/impl/SyntaxHighlighterOverEditorHighlighter.java new file mode 100644 index 000000000000..94162fcb0715 --- /dev/null +++ b/platform/usageView/src/com/intellij/usages/impl/SyntaxHighlighterOverEditorHighlighter.java @@ -0,0 +1,101 @@ +/* + * Copyright 2000-2014 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.usages.impl; + +import com.intellij.lexer.LayeredLexer; +import com.intellij.lexer.Lexer; +import com.intellij.openapi.editor.colors.TextAttributesKey; +import com.intellij.openapi.editor.ex.util.LayeredHighlighterIterator; +import com.intellij.openapi.editor.ex.util.LayeredLexerEditorHighlighter; +import com.intellij.openapi.editor.highlighter.EditorHighlighter; +import com.intellij.openapi.editor.highlighter.EditorHighlighterFactory; +import com.intellij.openapi.editor.highlighter.HighlighterIterator; +import com.intellij.openapi.fileTypes.SyntaxHighlighter; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.impl.search.LexerEditorHighlighterLexer; +import com.intellij.psi.tree.IElementType; +import org.jetbrains.annotations.NotNull; + +/** +* Created by Maxim.Mossienko on 7/31/2014. +*/ +public class SyntaxHighlighterOverEditorHighlighter implements SyntaxHighlighter { + private final Lexer lexer; + private LayeredHighlighterIterator layeredHighlighterIterator = null; + private boolean lexerEditorHighlighterInitialized; + private final SyntaxHighlighter highlighter; + + public SyntaxHighlighterOverEditorHighlighter(SyntaxHighlighter _highlighter, VirtualFile file, Project project) { + highlighter = _highlighter; + LayeredLexer.ourDisableLayersFlag.set(Boolean.TRUE); + EditorHighlighter editorHighlighter = EditorHighlighterFactory.getInstance().createEditorHighlighter(project, file); + + try { + if (editorHighlighter instanceof LayeredLexerEditorHighlighter) { + lexer = new LexerEditorHighlighterLexer(editorHighlighter, false); + } else { + lexer = highlighter.getHighlightingLexer(); + } + } + finally { + LayeredLexer.ourDisableLayersFlag.set(null); + } + } + + @NotNull + @Override + public Lexer getHighlightingLexer() { + return lexer; + } + + @NotNull + @Override + public TextAttributesKey[] getTokenHighlights(IElementType tokenType) { + final SyntaxHighlighter activeSyntaxHighlighter = + layeredHighlighterIterator != null ? layeredHighlighterIterator.getActiveSyntaxHighlighter() : highlighter; + return activeSyntaxHighlighter.getTokenHighlights(tokenType); + } + + public void restart(@NotNull CharSequence text) { + lexer.start(text); + + if (lexer instanceof LexerEditorHighlighterLexer) { + HighlighterIterator iterator = ((LexerEditorHighlighterLexer)lexer).getHighlighterIterator(); + if (iterator instanceof LayeredHighlighterIterator) { + layeredHighlighterIterator = (LayeredHighlighterIterator)iterator; + } else { + layeredHighlighterIterator = null; + } + } + } + + public void resetPosition(int startOffset) { + if (lexer instanceof LexerEditorHighlighterLexer) { + ((LexerEditorHighlighterLexer)lexer).resetPosition(startOffset); + + HighlighterIterator iterator = ((LexerEditorHighlighterLexer)lexer).getHighlighterIterator(); + if (iterator instanceof LayeredHighlighterIterator) { + layeredHighlighterIterator = (LayeredHighlighterIterator)iterator; + } else { + layeredHighlighterIterator = null; + } + } else { + CharSequence text = lexer.getBufferSequence(); + lexer.start(text, startOffset, text.length()); + } + } +} diff --git a/platform/usageView/usageView.iml b/platform/usageView/usageView.iml index e3943e442779..d69cf73e8a0c 100644 --- a/platform/usageView/usageView.iml +++ b/platform/usageView/usageView.iml @@ -9,6 +9,7 @@ +