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 57539ae07de0..a8316f8dc0ee 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,15 +18,8 @@ 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.Document; -import com.intellij.openapi.editor.highlighter.EditorHighlighter; -import com.intellij.openapi.editor.highlighter.EditorHighlighterFactory; -import com.intellij.openapi.editor.impl.EditorHighlighterCache; -import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.JspPsiUtil; -import com.intellij.psi.PsiDocumentManager; import com.intellij.psi.PsiFile; -import com.intellij.psi.impl.cache.impl.id.PlatformIdTableBuilding; import com.intellij.psi.impl.source.tree.StdTokenSets; import com.intellij.psi.jsp.JspFile; import com.intellij.psi.jsp.JspTokenType; @@ -41,27 +34,7 @@ public class JspIndexPatternBuilder implements IndexPatternBuilder { @Override public Lexer getIndexingLexer(@NotNull final PsiFile file) { if (JspPsiUtil.isInJspFile(file)) { - EditorHighlighter highlighter = null; - - final Document document = PsiDocumentManager.getInstance(file.getProject()).getDocument(file); - final EditorHighlighter cachedEditorHighlighter; - boolean alreadyInitializedHighlighter = false; - - if ((cachedEditorHighlighter = EditorHighlighterCache.getEditorHighlighterForCachesBuilding(document)) != null && - PlatformIdTableBuilding.checkCanUseCachedEditorHighlighter(file.getText(), cachedEditorHighlighter)) { - highlighter = cachedEditorHighlighter; - alreadyInitializedHighlighter = true; - } - else { - final VirtualFile virtualFile = file.getVirtualFile(); - if (virtualFile != null) { - highlighter = EditorHighlighterFactory.getInstance().createEditorHighlighter(file.getProject(), virtualFile); - } - } - - if (highlighter != null) { - return new LexerEditorHighlighterLexer(highlighter, alreadyInitializedHighlighter); - } + return LexerEditorHighlighterLexer.getLexerBasedOnLexerHighlighter(file.getText(), file.getVirtualFile(), file.getProject()); } return null; diff --git a/java/java-tests/testSrc/com/intellij/find/FindManagerTest.java b/java/java-tests/testSrc/com/intellij/find/FindManagerTest.java index 3a38c8ca9340..5a77577466f7 100644 --- a/java/java-tests/testSrc/com/intellij/find/FindManagerTest.java +++ b/java/java-tests/testSrc/com/intellij/find/FindManagerTest.java @@ -595,6 +595,23 @@ public class FindManagerTest extends DaemonAnalyzerTestCase { runFindInCommentsAndLiterals(findManager, findModel, text, "cs"); } + public void testFindInJsp() throws Exception{ + FindManager findManager = FindManager.getInstance(myProject); + + FindModel findModel = new FindModel(); + findModel.setStringToFind("done"); + findModel.setWholeWordsOnly(false); + findModel.setFromCursor(false); + findModel.setGlobal(true); + findModel.setMultipleFiles(false); + findModel.setProjectScope(true); + + String text = "\n<%--done-->\n<% /*done*/ %>"; + + findModel.setInCommentsOnly(true); + runFindForwardAndBackward(findManager, findModel, text, "jsp"); + } + public void testFindInLiteralToSkipQuotes() throws Exception{ FindManager findManager = FindManager.getInstance(myProject); 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 c1d35d14b54e..273d928da2f4 100644 --- a/platform/lang-impl/src/com/intellij/find/impl/FindManagerImpl.java +++ b/platform/lang-impl/src/com/intellij/find/impl/FindManagerImpl.java @@ -41,6 +41,9 @@ 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.LayeredLexerEditorHighlighter; +import com.intellij.openapi.editor.highlighter.EditorHighlighter; +import com.intellij.openapi.editor.highlighter.EditorHighlighterFactory; import com.intellij.openapi.editor.markup.RangeHighlighter; import com.intellij.openapi.fileEditor.FileEditor; import com.intellij.openapi.fileEditor.TextEditor; @@ -53,6 +56,7 @@ 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.tree.IElementType; import com.intellij.psi.tree.TokenSet; import com.intellij.ui.LightweightHint; @@ -360,7 +364,7 @@ public class FindManagerImpl extends FindManager implements PersistentStateCompo } @NotNull - private static FindResult doFindString(@NotNull CharSequence text, + private FindResult doFindString(@NotNull CharSequence text, @Nullable char[] textArray, int offset, @NotNull FindModel findmodel, @@ -411,9 +415,10 @@ public class FindManagerImpl extends FindManager implements PersistentStateCompo final StringSearcher searcher; final Matcher matcher; final Set relevantLanguages; - final FindModel myModel; + final FindModel model; - public CommentsLiteralsSearchData(VirtualFile lastFile, Set relevantLanguages, SyntaxHighlighter highlighter, TokenSet tokensOfInterest, + public CommentsLiteralsSearchData(VirtualFile lastFile, Set relevantLanguages, SyntaxHighlighter highlighter, + Lexer lexer, TokenSet tokensOfInterest, StringSearcher searcher, Matcher matcher, FindModel model) { this.lastFile = lastFile; this.highlighter = highlighter; @@ -421,15 +426,15 @@ public class FindManagerImpl extends FindManager implements PersistentStateCompo this.searcher = searcher; this.matcher = matcher; this.relevantLanguages = relevantLanguages; - highlightingLexer = highlighter.getHighlightingLexer(); - myModel = model; + highlightingLexer = lexer; + this.model = model; } } public static final Key ourCommentsLiteralsSearchDataKey = Key.create("comments.literals.search.data"); @NotNull - private static FindResult findInCommentsAndLiterals(@NotNull CharSequence text, + private FindResult findInCommentsAndLiterals(@NotNull CharSequence text, char[] textArray, int offset, @NotNull FindModel model, @@ -441,7 +446,7 @@ public class FindManagerImpl extends FindManager implements PersistentStateCompo } CommentsLiteralsSearchData data = model.getUserData(ourCommentsLiteralsSearchDataKey); - if (data == null || !Comparing.equal(data.lastFile, file) || !data.myModel.equals(model)) { + if (data == null || !Comparing.equal(data.lastFile, file) || !data.model.equals(model)) { SyntaxHighlighter highlighter = getHighlighter(file, lang); if (highlighter == null) { @@ -450,7 +455,7 @@ public class FindManagerImpl extends FindManager implements PersistentStateCompo } TokenSet tokensOfInterest = TokenSet.EMPTY; - Set relevantLanguages = null; + Set relevantLanguages; if (lang != null) { final Language finalLang = lang; relevantLanguages = ApplicationManager.getApplication().runReadAction(new Computable>() { @@ -507,12 +512,25 @@ 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); - data = new CommentsLiteralsSearchData(file, relevantLanguages, highlighter, tokensOfInterest, searcher, matcher, (FindModel)model.clone()); + EditorHighlighter editorHighlighter = EditorHighlighterFactory.getInstance().createEditorHighlighter(myProject, file); + Lexer lexer; + if (editorHighlighter instanceof LayeredLexerEditorHighlighter) { + lexer = LexerEditorHighlighterLexer.getLexerBasedOnLexerHighlighter(text, file, myProject); + } else { + lexer = highlighter.getHighlightingLexer(); + } + data = new CommentsLiteralsSearchData(file, relevantLanguages, highlighter, lexer, tokensOfInterest, searcher, matcher, (FindModel)model.clone()); + lexer.start(text, 0, text.length(), 0); model.putUserData(ourCommentsLiteralsSearchDataKey, data); } + int initialStartOffset = model.isForward() && data.startOffset < offset ? data.startOffset : 0; final Lexer lexer = data.highlightingLexer; - lexer.start(text, model.isForward() && data.startOffset < offset ? data.startOffset : 0, text.length(), 0); + if (lexer instanceof LexerEditorHighlighterLexer) { + ((LexerEditorHighlighterLexer)lexer).resetPosition(initialStartOffset); + } else { + lexer.start(text, initialStartOffset, text.length(), 0); + } IElementType tokenType; TokenSet tokens = data.tokensOfInterest; diff --git a/java/java-impl/src/com/intellij/psi/impl/search/LexerEditorHighlighterLexer.java b/platform/lang-impl/src/com/intellij/psi/impl/search/LexerEditorHighlighterLexer.java similarity index 58% rename from java/java-impl/src/com/intellij/psi/impl/search/LexerEditorHighlighterLexer.java rename to platform/lang-impl/src/com/intellij/psi/impl/search/LexerEditorHighlighterLexer.java index 894b88b5d11e..e6b88f8132d9 100644 --- a/java/java-impl/src/com/intellij/psi/impl/search/LexerEditorHighlighterLexer.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/search/LexerEditorHighlighterLexer.java @@ -15,12 +15,23 @@ */ 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 @@ -38,6 +49,30 @@ public class LexerEditorHighlighterLexer extends LexerBase { myAlreadyInitializedHighlighter = alreadyInitializedHighlighter; } + public static @Nullable Lexer getLexerBasedOnLexerHighlighter(CharSequence text, VirtualFile virtualFile, Project project) { + EditorHighlighter highlighter = null; + + PsiFile psiFile = PsiManager.getInstance(project).findFile(virtualFile); + 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) { @@ -50,6 +85,10 @@ public class LexerEditorHighlighterLexer extends LexerBase { iterator = myHighlighter.createIterator(0); } + public void resetPosition(int offset) { + iterator = myHighlighter.createIterator(offset); + } + @Override public int getState() { return 0;