summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorManish Khurana2018-08-01 05:49:57 -0400
committermkhurana2018-08-01 05:49:57 -0400
commit02344726c8ea4d1c88dce63c808d5abb19d1600e (patch)
tree9d7d059698dc52df59c9b61641dc99152d7cff9d
parent09d4a1121c9af18ff0cb42c5398c29e979a45aa4 (diff)
downloadorg.eclipse.cdt-02344726c8ea4d1c88dce63c808d5abb19d1600e.tar.gz
org.eclipse.cdt-02344726c8ea4d1c88dce63c808d5abb19d1600e.tar.xz
org.eclipse.cdt-02344726c8ea4d1c88dce63c808d5abb19d1600e.zip
Bug 537306 - Add implementation for "$cquery/publishSemanticHighlights"
Change-Id: I598cda18678f7b268a72e4aa5dfe9563d33727bd Signed-off-by: Manish Khurana <mkmanishkhurana98@gmail.com>
-rw-r--r--lsp4e-cpp/org.eclipse.lsp4e.cpp.language/src/org/eclipse/lsp4e/cpp/language/PresentationReconcilerCPP.java106
-rw-r--r--lsp4e-cpp/org.eclipse.lsp4e.cpp.language/src/org/eclipse/lsp4e/cpp/language/Server2ClientProtocolExtension.java47
-rw-r--r--lsp4e-cpp/org.eclipse.lsp4e.cpp.language/src/org/eclipse/lsp4e/cpp/language/cquery/CquerySemanticHighlights.java3
-rw-r--r--lsp4e-cpp/org.eclipse.lsp4e.cpp.language/src/org/eclipse/lsp4e/cpp/language/cquery/HighlightSymbol.java45
4 files changed, 195 insertions, 6 deletions
diff --git a/lsp4e-cpp/org.eclipse.lsp4e.cpp.language/src/org/eclipse/lsp4e/cpp/language/PresentationReconcilerCPP.java b/lsp4e-cpp/org.eclipse.lsp4e.cpp.language/src/org/eclipse/lsp4e/cpp/language/PresentationReconcilerCPP.java
index 520e531d35..1b16aeb935 100644
--- a/lsp4e-cpp/org.eclipse.lsp4e.cpp.language/src/org/eclipse/lsp4e/cpp/language/PresentationReconcilerCPP.java
+++ b/lsp4e-cpp/org.eclipse.lsp4e.cpp.language/src/org/eclipse/lsp4e/cpp/language/PresentationReconcilerCPP.java
@@ -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);
}
}
diff --git a/lsp4e-cpp/org.eclipse.lsp4e.cpp.language/src/org/eclipse/lsp4e/cpp/language/Server2ClientProtocolExtension.java b/lsp4e-cpp/org.eclipse.lsp4e.cpp.language/src/org/eclipse/lsp4e/cpp/language/Server2ClientProtocolExtension.java
index 41dc5d5b80..c2e913c25f 100644
--- a/lsp4e-cpp/org.eclipse.lsp4e.cpp.language/src/org/eclipse/lsp4e/cpp/language/Server2ClientProtocolExtension.java
+++ b/lsp4e-cpp/org.eclipse.lsp4e.cpp.language/src/org/eclipse/lsp4e/cpp/language/Server2ClientProtocolExtension.java
@@ -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);
+ }
+ }
+ });
}
}
diff --git a/lsp4e-cpp/org.eclipse.lsp4e.cpp.language/src/org/eclipse/lsp4e/cpp/language/cquery/CquerySemanticHighlights.java b/lsp4e-cpp/org.eclipse.lsp4e.cpp.language/src/org/eclipse/lsp4e/cpp/language/cquery/CquerySemanticHighlights.java
index 2917e9551c..5b504a4a7c 100644
--- a/lsp4e-cpp/org.eclipse.lsp4e.cpp.language/src/org/eclipse/lsp4e/cpp/language/cquery/CquerySemanticHighlights.java
+++ b/lsp4e-cpp/org.eclipse.lsp4e.cpp.language/src/org/eclipse/lsp4e/cpp/language/cquery/CquerySemanticHighlights.java
@@ -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;
diff --git a/lsp4e-cpp/org.eclipse.lsp4e.cpp.language/src/org/eclipse/lsp4e/cpp/language/cquery/HighlightSymbol.java b/lsp4e-cpp/org.eclipse.lsp4e.cpp.language/src/org/eclipse/lsp4e/cpp/language/cquery/HighlightSymbol.java
index b17b6a5346..2eaeabcb60 100644
--- a/lsp4e-cpp/org.eclipse.lsp4e.cpp.language/src/org/eclipse/lsp4e/cpp/language/cquery/HighlightSymbol.java
+++ b/lsp4e-cpp/org.eclipse.lsp4e.cpp.language/src/org/eclipse/lsp4e/cpp/language/cquery/HighlightSymbol.java
@@ -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) {