diff options
Diffstat (limited to 'platform/usageView/src/com/intellij/usages/ChunkExtractor.java')
-rw-r--r-- | platform/usageView/src/com/intellij/usages/ChunkExtractor.java | 84 |
1 files changed, 62 insertions, 22 deletions
diff --git a/platform/usageView/src/com/intellij/usages/ChunkExtractor.java b/platform/usageView/src/com/intellij/usages/ChunkExtractor.java index 930321fc61d5..dbbaeb48b72f 100644 --- a/platform/usageView/src/com/intellij/usages/ChunkExtractor.java +++ b/platform/usageView/src/com/intellij/usages/ChunkExtractor.java @@ -19,9 +19,7 @@ import com.intellij.injected.editor.DocumentWindow; import com.intellij.lang.injection.InjectedLanguageManager; import com.intellij.lexer.Lexer; import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.editor.Document; -import com.intellij.openapi.editor.HighlighterColors; -import com.intellij.openapi.editor.RangeMarker; +import com.intellij.openapi.editor.*; import com.intellij.openapi.editor.colors.EditorColorsScheme; import com.intellij.openapi.editor.colors.TextAttributesKey; import com.intellij.openapi.editor.markup.TextAttributes; @@ -39,11 +37,14 @@ 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; import com.intellij.util.text.CharArrayUtil; import com.intellij.util.text.StringFactory; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.awt.*; import java.lang.ref.WeakReference; @@ -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<T> { private WeakReference<T> 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<RangeMarker> rangeMarkers) { @@ -194,18 +192,21 @@ public class ChunkExtractor { int end, boolean selectUsageWithBold, @NotNull List<TextChunk> 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); // todo restart from nearest position with initial state } + 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); @@ -234,7 +237,7 @@ public class ChunkExtractor { @NotNull final CharSequence chars, int hiStart, final int hiEnd, - @NotNull TextAttributesKey[] tokenHighlights, + @NotNull final TextAttributesKey[] tokenHighlights, final boolean selectUsageWithBold, @NotNull final List<TextChunk> result) { final TextAttributes originalAttrs = convertAttributes(tokenHighlights); @@ -249,8 +252,12 @@ public class ChunkExtractor { int usageStart = segment.getStartOffset(); int usageEnd = segment.getEndOffset(); if (rangeIntersect(lastOffset[0], hiEnd, usageStart, usageEnd)) { - addChunk(chars, lastOffset[0], Math.max(lastOffset[0], usageStart), originalAttrs, false, result); - addChunk(chars, Math.max(lastOffset[0], usageStart), Math.min(hiEnd, usageEnd), originalAttrs, selectUsageWithBold, result); + addChunk(chars, lastOffset[0], Math.max(lastOffset[0], usageStart), originalAttrs, false, null, result); + + UsageType usageType = isHighlightedAsString(tokenHighlights) + ? UsageType.LITERAL_USAGE + : isHighlightedAsComment(tokenHighlights) ? UsageType.COMMENT_USAGE : null; + addChunk(chars, Math.max(lastOffset[0], usageStart), Math.min(hiEnd, usageEnd), originalAttrs, selectUsageWithBold, usageType, result); lastOffset[0] = usageEnd; if (usageEnd > hiEnd) { return false; @@ -260,8 +267,40 @@ public class ChunkExtractor { } }); if (lastOffset[0] < hiEnd) { - addChunk(chars, lastOffset[0], hiEnd, originalAttrs, false, result); + addChunk(chars, lastOffset[0], hiEnd, originalAttrs, false, null, result); + } + } + + public static boolean isHighlightedAsComment(TextAttributesKey... keys) { + for (TextAttributesKey key : keys) { + if (key == DefaultLanguageHighlighterColors.DOC_COMMENT || + key == SyntaxHighlighterColors.DOC_COMMENT || + key == DefaultLanguageHighlighterColors.LINE_COMMENT || + key == SyntaxHighlighterColors.LINE_COMMENT || + key == DefaultLanguageHighlighterColors.BLOCK_COMMENT || + key == SyntaxHighlighterColors.JAVA_BLOCK_COMMENT + ) { + return true; + } + final TextAttributesKey fallbackAttributeKey = key.getFallbackAttributeKey(); + if (fallbackAttributeKey != null && isHighlightedAsComment(fallbackAttributeKey)) { + return true; + } + } + return false; + } + + public static boolean isHighlightedAsString(TextAttributesKey... keys) { + for (TextAttributesKey key : keys) { + if (key == DefaultLanguageHighlighterColors.STRING || key == SyntaxHighlighterColors.STRING) { + return true; + } + final TextAttributesKey fallbackAttributeKey = key.getFallbackAttributeKey(); + if (fallbackAttributeKey != null && isHighlightedAsString(fallbackAttributeKey)) { + return true; + } } + return false; } private static void addChunk(@NotNull CharSequence chars, @@ -269,13 +308,14 @@ public class ChunkExtractor { int end, @NotNull TextAttributes originalAttrs, boolean bold, + @Nullable UsageType usageType, @NotNull List<TextChunk> result) { if (start >= end) return; TextAttributes attrs = bold ? TextAttributes.merge(originalAttrs, new TextAttributes(null, null, null, null, Font.BOLD)) : originalAttrs; - result.add(new TextChunk(attrs, StringFactory.createShared(CharArrayUtil.fromSequence(chars, start, end)))); + result.add(new TextChunk(attrs, StringFactory.createShared(CharArrayUtil.fromSequence(chars, start, end)), usageType)); } private static boolean rangeIntersect(int s1, int e1, int s2, int e2) { |