1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-23 17:05:26 +02:00

Bug 537306 - Add implementation for "$cquery/publishSemanticHighlights"

Change-Id: I598cda18678f7b268a72e4aa5dfe9563d33727bd
Signed-off-by: Manish Khurana <mkmanishkhurana98@gmail.com>
This commit is contained in:
Manish Khurana 2018-08-01 15:19:57 +05:30 committed by mkhurana
parent 09d4a1121c
commit 02344726c8
4 changed files with 195 additions and 6 deletions

View file

@ -17,6 +17,12 @@
package org.eclipse.lsp4e.cpp.language;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import org.eclipse.cdt.core.dom.ast.gnu.cpp.GPPLanguage;
import org.eclipse.cdt.core.model.ICLanguageKeywords;
import org.eclipse.cdt.core.model.ILanguage;
@ -24,12 +30,12 @@ import org.eclipse.cdt.internal.ui.text.CCodeScanner;
import org.eclipse.cdt.internal.ui.text.CCommentScanner;
import org.eclipse.cdt.internal.ui.text.CPreprocessorScanner;
import org.eclipse.cdt.internal.ui.text.CPresentationReconciler;
import org.eclipse.cdt.internal.ui.text.FastCPartitioner;
import org.eclipse.cdt.internal.ui.text.PartitionDamager;
import org.eclipse.cdt.internal.ui.text.SingleTokenCScanner;
import org.eclipse.cdt.internal.ui.text.TokenStore;
import org.eclipse.cdt.ui.CUIPlugin;
import org.eclipse.cdt.ui.ILanguageUI;
import org.eclipse.cdt.ui.PreferenceConstants;
import org.eclipse.cdt.ui.text.AbstractCScanner;
import org.eclipse.cdt.ui.text.ICColorConstants;
import org.eclipse.cdt.ui.text.ICPartitions;
@ -38,6 +44,9 @@ import org.eclipse.cdt.ui.text.ITokenStore;
import org.eclipse.cdt.ui.text.ITokenStoreFactory;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.preference.PreferenceConverter;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.ITextInputListener;
@ -45,7 +54,14 @@ import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.TextPresentation;
import org.eclipse.jface.text.rules.DefaultDamagerRepairer;
import org.eclipse.jface.text.rules.RuleBasedScanner;
import org.eclipse.lsp4e.cpp.language.cquery.CquerySemanticHighlights;
import org.eclipse.lsp4e.cpp.language.cquery.HighlightSymbol;
import org.eclipse.lsp4j.Range;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StyleRange;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.widgets.Display;
/**
* Hack-ish reconciler to get some colors in the generic editor using the C/C++
@ -61,6 +77,9 @@ public class PresentationReconcilerCPP extends CPresentationReconciler {
private CqueryLineBackgroundListener fLineBackgroundListener = new CqueryLineBackgroundListener();
private ITextViewer textViewer;
private TextInputListenerCPP textInputListener;
public static Set<PresentationReconcilerCPP> presentationReconcilers = ConcurrentHashMap.newKeySet();
protected ITokenStoreFactory getTokenStoreFactory() {
return new ITokenStoreFactory() {
@Override
@ -154,8 +173,81 @@ public class PresentationReconcilerCPP extends CPresentationReconciler {
@Override
protected TextPresentation createPresentation(IRegion damage, IDocument document) {
TextPresentation createPresentation = super.createPresentation(damage, document);
return createPresentation;
TextPresentation presentation = super.createPresentation(damage, document);
IDocument doc = textViewer.getDocument();
URI uri = Server2ClientProtocolExtension.getUri(doc);
if (uri == null) {
return presentation;
}
List<HighlightSymbol> semanticHighlights = CquerySemanticHighlights.uriToSemanticHighlightsMapping.get(uri);
if(semanticHighlights == null) {
return presentation;
}
IPreferenceStore store = CUIPlugin.getDefault().getPreferenceStore();
List<StyleRange> styleRanges = new ArrayList<>();
for (HighlightSymbol highlight : semanticHighlights) {
String highlightingName = HighlightSymbol.getHighlightingName(highlight.getKind(), highlight.getParentKind(), highlight.getStorage());
String colorKey = PreferenceConstants.EDITOR_SEMANTIC_HIGHLIGHTING_PREFIX
+ highlightingName + PreferenceConstants.EDITOR_SEMANTIC_HIGHLIGHTING_COLOR_SUFFIX;
boolean isBold = store.getBoolean(PreferenceConstants.EDITOR_SEMANTIC_HIGHLIGHTING_PREFIX
+ highlightingName + PreferenceConstants.EDITOR_SEMANTIC_HIGHLIGHTING_BOLD_SUFFIX);
boolean isItalic = store.getBoolean(PreferenceConstants.EDITOR_SEMANTIC_HIGHLIGHTING_PREFIX
+ highlightingName + PreferenceConstants.EDITOR_SEMANTIC_HIGHLIGHTING_ITALIC_SUFFIX);
boolean isUnderline = store.getBoolean(PreferenceConstants.EDITOR_SEMANTIC_HIGHLIGHTING_PREFIX
+ highlightingName + PreferenceConstants.EDITOR_SEMANTIC_HIGHLIGHTING_UNDERLINE_SUFFIX);
boolean isStrikethrough = store.getBoolean(PreferenceConstants.EDITOR_SEMANTIC_HIGHLIGHTING_PREFIX
+ highlightingName + PreferenceConstants.EDITOR_SEMANTIC_HIGHLIGHTING_STRIKETHROUGH_SUFFIX);
Color color = new Color(Display.getCurrent(),
PreferenceConverter.getColor(CUIPlugin.getDefault().getPreferenceStore(), colorKey));
int damageStartOffset = damage.getOffset();
int damageEndOffset = damageStartOffset + damage.getLength();
List<Range> ranges = highlight.getRanges();
for (Range range : ranges) {
int offset = 0, length = 0;
try {
offset = doc.getLineOffset(range.getStart().getLine()) + range.getStart().getCharacter();
length = doc.getLineOffset(range.getEnd().getLine()) + range.getEnd().getCharacter() - offset;
} catch (BadLocationException e) {
Activator.log(e);
}
if ((offset + length) >= damageStartOffset && offset < damageEndOffset) {
StyleRange styleRange = new StyleRange(offset, length, color, null);
if (isBold) {
styleRange.fontStyle = SWT.BOLD;
}
if (isItalic) {
styleRange.fontStyle |= SWT.ITALIC;
}
if (isUnderline) {
styleRange.underline = true;
}
if (isStrikethrough) {
styleRange.strikeout = true;
}
styleRanges.add(styleRange);
}
}
}
StyleRange[] styleRangesArray = new StyleRange[styleRanges.size()];
styleRangesArray = styleRanges.toArray(styleRangesArray);
presentation.replaceStyleRanges(styleRangesArray);
return presentation;
}
/**
@ -218,7 +310,7 @@ public class PresentationReconcilerCPP extends CPresentationReconciler {
return fPreprocessorScanner;
}
class TextInputListenerCPP implements ITextInputListener {
public class TextInputListenerCPP implements ITextInputListener {
@Override
public void inputDocumentChanged(IDocument oldInput, IDocument newInput) {
@ -236,6 +328,10 @@ public class PresentationReconcilerCPP extends CPresentationReconciler {
}
}
public ITextViewer getTextViewer() {
return textViewer;
}
@Override
public void install(ITextViewer viewer) {
super.install(viewer);
@ -248,6 +344,7 @@ public class PresentationReconcilerCPP extends CPresentationReconciler {
}
StyledText textWidget = textViewer.getTextWidget();
textWidget.addLineBackgroundListener(fLineBackgroundListener);
presentationReconcilers.add(this);
}
@Override
@ -255,5 +352,6 @@ public class PresentationReconcilerCPP extends CPresentationReconciler {
super.uninstall();
textViewer.getTextWidget().removeLineBackgroundListener(fLineBackgroundListener);
textViewer.removeTextInputListener(textInputListener);
presentationReconcilers.remove(this);
}
}

View file

@ -9,10 +9,16 @@
package org.eclipse.lsp4e.cpp.language;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.core.resources.IFile;
import org.eclipse.jface.action.StatusLineContributionItem;
import org.eclipse.jface.action.StatusLineManager;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.Region;
import org.eclipse.jface.text.TextPresentation;
import org.eclipse.lsp4e.LSPEclipseUtils;
import org.eclipse.lsp4e.LanguageClientImpl;
import org.eclipse.lsp4e.cpp.language.cquery.CqueryInactiveRegions;
import org.eclipse.lsp4e.cpp.language.cquery.CquerySemanticHighlights;
@ -25,7 +31,6 @@ import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.internal.WorkbenchWindow;
@SuppressWarnings("restriction")
public class Server2ClientProtocolExtension extends LanguageClientImpl {
@ -60,8 +65,46 @@ public class Server2ClientProtocolExtension extends LanguageClientImpl {
CqueryLineBackgroundListener.fileInactiveRegionsMap.put(uri, inactiveRegions);
}
public static URI getUri(IDocument document) {
URI uri = null;
IFile file = LSPEclipseUtils.getFile(document);
if (file != null) {
uri = LSPEclipseUtils.toUri(file);
}
return uri;
}
@JsonNotification("$cquery/publishSemanticHighlighting")
public final void semanticHighlights(CquerySemanticHighlights highlights) {
// TODO: Implement
URI uriReceived = highlights.getUri();
CquerySemanticHighlights.uriToSemanticHighlightsMapping.put(uriReceived, highlights.getSymbols());
List<PresentationReconcilerCPP> matchingReconcilers = new ArrayList<>();
for (PresentationReconcilerCPP eachReconciler: PresentationReconcilerCPP.presentationReconcilers) {
IDocument currentReconcilerDoc = eachReconciler.getTextViewer().getDocument();
URI currentReconcilerUri = getUri(currentReconcilerDoc);
if(currentReconcilerUri == null) {
continue;
}
if (uriReceived.equals(currentReconcilerUri)) {
matchingReconcilers.add(eachReconciler);
}
}
Display.getDefault().asyncExec(new Runnable() {
@Override
public void run() {
for (PresentationReconcilerCPP p: matchingReconcilers) {
IDocument currentReconcilerDoc = p.getTextViewer().getDocument();
if (currentReconcilerDoc == null) {
continue;
}
TextPresentation textPresentation = p.createPresentation(new Region(0, currentReconcilerDoc.getLength()), currentReconcilerDoc);
p.getTextViewer().changeTextPresentation(textPresentation, false);
}
}
});
}
}

View file

@ -10,10 +10,13 @@ package org.eclipse.lsp4e.cpp.language.cquery;
import java.net.URI;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
public class CquerySemanticHighlights {
private URI uri;
private List<HighlightSymbol> symbols;
public static ConcurrentMap<URI, List<HighlightSymbol>> uriToSemanticHighlightsMapping = new ConcurrentHashMap<>(16, 0.75f, 1);
public URI getUri() {
return uri;

View file

@ -8,16 +8,61 @@
package org.eclipse.lsp4e.cpp.language.cquery;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.cdt.internal.ui.editor.SemanticHighlightings;
import org.eclipse.lsp4j.Range;
import org.eclipse.lsp4j.SymbolKind;
@SuppressWarnings("restriction")
public class HighlightSymbol {
private int stableId;
private ExtendedSymbolKindType parentKind;
private ExtendedSymbolKindType kind;
private StorageClass storage;
private List<Range> ranges;
public static Map<Integer, String> semanticHighlightSymbolsMap = new HashMap<>();
static {
semanticHighlightSymbolsMap.put(SymbolKind.Namespace.getValue(), SemanticHighlightings.NAMESPACE);
semanticHighlightSymbolsMap.put(SymbolKind.Class.getValue(), SemanticHighlightings.CLASS);
semanticHighlightSymbolsMap.put(SymbolKind.Method.getValue(), SemanticHighlightings.METHOD);
semanticHighlightSymbolsMap.put(SymbolKind.Constructor.getValue(), SemanticHighlightings.METHOD);
semanticHighlightSymbolsMap.put(SymbolKind.Enum.getValue(), SemanticHighlightings.ENUM);
semanticHighlightSymbolsMap.put(SymbolKind.Function.getValue(), SemanticHighlightings.FUNCTION);
semanticHighlightSymbolsMap.put(SymbolKind.EnumMember.getValue(), SemanticHighlightings.ENUMERATOR);
semanticHighlightSymbolsMap.put(SymbolKind.Struct.getValue(), SemanticHighlightings.CLASS);
semanticHighlightSymbolsMap.put(SymbolKind.TypeParameter.getValue(), SemanticHighlightings.TEMPLATE_PARAMETER);
semanticHighlightSymbolsMap.put(CquerySymbolKind.TypeAlias.getValue(), SemanticHighlightings.TYPEDEF);
semanticHighlightSymbolsMap.put(CquerySymbolKind.Parameter.getValue(), SemanticHighlightings.PARAMETER_VARIABLE);
semanticHighlightSymbolsMap.put(CquerySymbolKind.StaticMethod.getValue(), SemanticHighlightings.STATIC_METHOD_INVOCATION);
semanticHighlightSymbolsMap.put(CquerySymbolKind.Macro.getValue(), SemanticHighlightings.MACRO_DEFINITION);
}
public static String getHighlightingName(ExtendedSymbolKindType kind, ExtendedSymbolKindType parentKind, StorageClass storage) {
String highlightingName = semanticHighlightSymbolsMap.get(kind.getValue());
if (highlightingName == null) {
if (kind.getValue() == SymbolKind.Variable.getValue()) {
if (parentKind.getValue() == SymbolKind.Function.getValue()
|| parentKind.getValue() == SymbolKind.Method.getValue()
|| parentKind.getValue() == SymbolKind.Constructor.getValue()) {
highlightingName = SemanticHighlightings.LOCAL_VARIABLE;
} else {
highlightingName = SemanticHighlightings.GLOBAL_VARIABLE;
}
} else if (kind.getValue() == SymbolKind.Field.getValue()) {
if (storage == StorageClass.Static) {
highlightingName = SemanticHighlightings.STATIC_FIELD;
} else {
highlightingName = SemanticHighlightings.FIELD;
}
}
}
return highlightingName;
}
public HighlightSymbol(int stableId, ExtendedSymbolKindType parentKind, ExtendedSymbolKindType kind,
StorageClass storage, List<Range> ranges) {