mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-22 06:02:11 +02:00
[LSP4E] Support separate semantic highlightings for declarations of functions, methods, and local variables
Change-Id: Iee7252b55810b8691a1b2344593a804a47ab6cbe
This commit is contained in:
parent
f5322a32d3
commit
8c78a241d5
4 changed files with 60 additions and 12 deletions
|
@ -23,6 +23,7 @@ import org.eclipse.cdt.lsp.core.cquery.ExtendedSymbolKindType;
|
||||||
import org.eclipse.cdt.lsp.core.cquery.HighlightSymbol;
|
import org.eclipse.cdt.lsp.core.cquery.HighlightSymbol;
|
||||||
import org.eclipse.cdt.lsp.core.cquery.IndexingProgressStats;
|
import org.eclipse.cdt.lsp.core.cquery.IndexingProgressStats;
|
||||||
import org.eclipse.cdt.lsp.core.cquery.StorageClass;
|
import org.eclipse.cdt.lsp.core.cquery.StorageClass;
|
||||||
|
import org.eclipse.cdt.lsp.core.cquery.SymbolRole;
|
||||||
import org.eclipse.lsp4j.Position;
|
import org.eclipse.lsp4j.Position;
|
||||||
import org.eclipse.lsp4j.Range;
|
import org.eclipse.lsp4j.Range;
|
||||||
import org.eclipse.lsp4j.jsonrpc.json.JsonRpcMethod;
|
import org.eclipse.lsp4j.jsonrpc.json.JsonRpcMethod;
|
||||||
|
@ -84,9 +85,9 @@ public class CqueryJsonParseTest {
|
||||||
public void testPublishSemanticHighlighting() {
|
public void testPublishSemanticHighlighting() {
|
||||||
String json = "{\"jsonrpc\": \"2.0\",\"method\": \"$cquery/publishSemanticHighlighting\"," //$NON-NLS-1$
|
String json = "{\"jsonrpc\": \"2.0\",\"method\": \"$cquery/publishSemanticHighlighting\"," //$NON-NLS-1$
|
||||||
+ "\"params\": {\"uri\": \"file:///home/foobar.cpp\",\"symbols\": [{\"stableId\": 21," //$NON-NLS-1$
|
+ "\"params\": {\"uri\": \"file:///home/foobar.cpp\",\"symbols\": [{\"stableId\": 21," //$NON-NLS-1$
|
||||||
+ "\"parentKind\": 8,\"kind\": 0,\"storage\": 3,\"ranges\": [{\"start\": {\"line\": 41," //$NON-NLS-1$
|
+ "\"parentKind\": 8,\"kind\": 0,\"storage\": 3,\"role\": 1,\"ranges\": [{\"start\": {\"line\": 41," //$NON-NLS-1$
|
||||||
+ "\"character\": 1},\"end\": {\"line\": 41,\"character\": 5}}]},{\"stableId\": 19," //$NON-NLS-1$
|
+ "\"character\": 1},\"end\": {\"line\": 41,\"character\": 5}}]},{\"stableId\": 19," //$NON-NLS-1$
|
||||||
+ "\"parentKind\": 12,\"kind\": 253,\"storage\": 5,\"ranges\": [{\"start\": {\"line\": 39," //$NON-NLS-1$
|
+ "\"parentKind\": 12,\"kind\": 253,\"storage\": 5,\"role\": 4,\"ranges\": [{\"start\": {\"line\": 39," //$NON-NLS-1$
|
||||||
+ "\"character\": 9},\"end\": {\"line\": 39,\"character\": 10}}]}]}}"; //$NON-NLS-1$
|
+ "\"character\": 9},\"end\": {\"line\": 39,\"character\": 10}}]}]}}"; //$NON-NLS-1$
|
||||||
|
|
||||||
URI uri = URI.create("file:///home/foobar.cpp"); //$NON-NLS-1$
|
URI uri = URI.create("file:///home/foobar.cpp"); //$NON-NLS-1$
|
||||||
|
@ -106,8 +107,10 @@ public class CqueryJsonParseTest {
|
||||||
ExtendedSymbolKindType kind2 = new ExtendedSymbolKindType(253);
|
ExtendedSymbolKindType kind2 = new ExtendedSymbolKindType(253);
|
||||||
StorageClass storage1 = StorageClass.Static;
|
StorageClass storage1 = StorageClass.Static;
|
||||||
StorageClass storage2 = StorageClass.Auto;
|
StorageClass storage2 = StorageClass.Auto;
|
||||||
HighlightSymbol symbol1 = new HighlightSymbol(21, parentKind1, kind1, storage1, ranges1);
|
int role1 = SymbolRole.Declaration;
|
||||||
HighlightSymbol symbol2 = new HighlightSymbol(19, parentKind2, kind2, storage2, ranges2);
|
int role2 = SymbolRole.Reference;
|
||||||
|
HighlightSymbol symbol1 = new HighlightSymbol(21, parentKind1, kind1, storage1, role1, ranges1);
|
||||||
|
HighlightSymbol symbol2 = new HighlightSymbol(19, parentKind2, kind2, storage2, role2, ranges2);
|
||||||
List<HighlightSymbol> symbols = new ArrayList<>();
|
List<HighlightSymbol> symbols = new ArrayList<>();
|
||||||
symbols.add(symbol1);
|
symbols.add(symbol1);
|
||||||
symbols.add(symbol2);
|
symbols.add(symbol2);
|
||||||
|
|
|
@ -168,7 +168,7 @@ public class Server2ClientProtocolExtension extends LanguageClientImpl {
|
||||||
for (HighlightSymbol highlight : highlights.getSymbols()) {
|
for (HighlightSymbol highlight : highlights.getSymbols()) {
|
||||||
|
|
||||||
String highlightingName = HighlightSymbol.getHighlightingName(highlight.getKind(),
|
String highlightingName = HighlightSymbol.getHighlightingName(highlight.getKind(),
|
||||||
highlight.getParentKind(), highlight.getStorage());
|
highlight.getParentKind(), highlight.getStorage(), highlight.getRole());
|
||||||
String colorKey = PreferenceConstants.EDITOR_SEMANTIC_HIGHLIGHTING_PREFIX + highlightingName
|
String colorKey = PreferenceConstants.EDITOR_SEMANTIC_HIGHLIGHTING_PREFIX + highlightingName
|
||||||
+ PreferenceConstants.EDITOR_SEMANTIC_HIGHLIGHTING_COLOR_SUFFIX;
|
+ PreferenceConstants.EDITOR_SEMANTIC_HIGHLIGHTING_COLOR_SUFFIX;
|
||||||
|
|
||||||
|
|
|
@ -25,15 +25,13 @@ public class HighlightSymbol {
|
||||||
private ExtendedSymbolKindType kind;
|
private ExtendedSymbolKindType kind;
|
||||||
private StorageClass storage;
|
private StorageClass storage;
|
||||||
private List<Range> ranges;
|
private List<Range> ranges;
|
||||||
|
private Integer role;
|
||||||
public static Map<Integer, String> semanticHighlightSymbolsMap = new HashMap<>();
|
public static Map<Integer, String> semanticHighlightSymbolsMap = new HashMap<>();
|
||||||
|
|
||||||
static {
|
static {
|
||||||
semanticHighlightSymbolsMap.put(SymbolKind.Namespace.getValue(), SemanticHighlightings.NAMESPACE);
|
semanticHighlightSymbolsMap.put(SymbolKind.Namespace.getValue(), SemanticHighlightings.NAMESPACE);
|
||||||
semanticHighlightSymbolsMap.put(SymbolKind.Class.getValue(), SemanticHighlightings.CLASS);
|
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.Enum.getValue(), SemanticHighlightings.ENUM);
|
||||||
semanticHighlightSymbolsMap.put(SymbolKind.Function.getValue(), SemanticHighlightings.FUNCTION);
|
|
||||||
semanticHighlightSymbolsMap.put(SymbolKind.EnumMember.getValue(), SemanticHighlightings.ENUMERATOR);
|
semanticHighlightSymbolsMap.put(SymbolKind.EnumMember.getValue(), SemanticHighlightings.ENUMERATOR);
|
||||||
semanticHighlightSymbolsMap.put(SymbolKind.Struct.getValue(), SemanticHighlightings.CLASS);
|
semanticHighlightSymbolsMap.put(SymbolKind.Struct.getValue(), SemanticHighlightings.CLASS);
|
||||||
semanticHighlightSymbolsMap.put(SymbolKind.TypeParameter.getValue(), SemanticHighlightings.TEMPLATE_PARAMETER);
|
semanticHighlightSymbolsMap.put(SymbolKind.TypeParameter.getValue(), SemanticHighlightings.TEMPLATE_PARAMETER);
|
||||||
|
@ -45,16 +43,24 @@ public class HighlightSymbol {
|
||||||
semanticHighlightSymbolsMap.put(CquerySymbolKind.Macro.getValue(), SemanticHighlightings.MACRO_DEFINITION);
|
semanticHighlightSymbolsMap.put(CquerySymbolKind.Macro.getValue(), SemanticHighlightings.MACRO_DEFINITION);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean isDeclaration(int role) {
|
||||||
|
return (role & SymbolRole.Declaration) != 0 || (role & SymbolRole.Definition) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
public static String getHighlightingName(ExtendedSymbolKindType kind, ExtendedSymbolKindType parentKind,
|
public static String getHighlightingName(ExtendedSymbolKindType kind, ExtendedSymbolKindType parentKind,
|
||||||
StorageClass storage) {
|
StorageClass storage, int role) {
|
||||||
|
// semanticHighlightSymbolsMap contains mappings where the color is determined entirely
|
||||||
|
// by the symbol kind.
|
||||||
|
// The additional checks below handle cases where the color also depends on the parent kind,
|
||||||
|
// storage class, or role.
|
||||||
String highlightingName = semanticHighlightSymbolsMap.get(kind.getValue());
|
String highlightingName = semanticHighlightSymbolsMap.get(kind.getValue());
|
||||||
if (highlightingName == null) {
|
if (highlightingName == null) {
|
||||||
if (kind.getValue() == SymbolKind.Variable.getValue()) {
|
if (kind.getValue() == SymbolKind.Variable.getValue()) {
|
||||||
if (parentKind.getValue() == SymbolKind.Function.getValue()
|
if (parentKind.getValue() == SymbolKind.Function.getValue()
|
||||||
|| parentKind.getValue() == SymbolKind.Method.getValue()
|
|| parentKind.getValue() == SymbolKind.Method.getValue()
|
||||||
|| parentKind.getValue() == SymbolKind.Constructor.getValue()) {
|
|| parentKind.getValue() == SymbolKind.Constructor.getValue()) {
|
||||||
|
highlightingName = isDeclaration(role) ? SemanticHighlightings.LOCAL_VARIABLE_DECLARATION
|
||||||
highlightingName = SemanticHighlightings.LOCAL_VARIABLE;
|
: SemanticHighlightings.LOCAL_VARIABLE;
|
||||||
} else {
|
} else {
|
||||||
highlightingName = SemanticHighlightings.GLOBAL_VARIABLE;
|
highlightingName = SemanticHighlightings.GLOBAL_VARIABLE;
|
||||||
}
|
}
|
||||||
|
@ -64,17 +70,25 @@ public class HighlightSymbol {
|
||||||
} else {
|
} else {
|
||||||
highlightingName = SemanticHighlightings.FIELD;
|
highlightingName = SemanticHighlightings.FIELD;
|
||||||
}
|
}
|
||||||
|
} else if (kind.getValue() == SymbolKind.Function.getValue()) {
|
||||||
|
highlightingName = isDeclaration(role) ? SemanticHighlightings.FUNCTION_DECLARATION
|
||||||
|
: SemanticHighlightings.FUNCTION;
|
||||||
|
} else if (kind.getValue() == SymbolKind.Method.getValue()
|
||||||
|
|| kind.getValue() == SymbolKind.Constructor.getValue()) {
|
||||||
|
highlightingName = isDeclaration(role) ? SemanticHighlightings.METHOD_DECLARATION
|
||||||
|
: SemanticHighlightings.METHOD;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return highlightingName;
|
return highlightingName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public HighlightSymbol(int stableId, ExtendedSymbolKindType parentKind, ExtendedSymbolKindType kind,
|
public HighlightSymbol(int stableId, ExtendedSymbolKindType parentKind, ExtendedSymbolKindType kind,
|
||||||
StorageClass storage, List<Range> ranges) {
|
StorageClass storage, Integer role, List<Range> ranges) {
|
||||||
this.stableId = stableId;
|
this.stableId = stableId;
|
||||||
this.parentKind = parentKind;
|
this.parentKind = parentKind;
|
||||||
this.kind = kind;
|
this.kind = kind;
|
||||||
this.storage = storage;
|
this.storage = storage;
|
||||||
|
this.role = role;
|
||||||
this.ranges = ranges;
|
this.ranges = ranges;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -94,6 +108,10 @@ public class HighlightSymbol {
|
||||||
return storage;
|
return storage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Integer getRole() {
|
||||||
|
return role;
|
||||||
|
}
|
||||||
|
|
||||||
public List<Range> getRanges() {
|
public List<Range> getRanges() {
|
||||||
return ranges;
|
return ranges;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2018 Nathan Ridge and others.
|
||||||
|
* All rights reserved. This program and the accompanying materials
|
||||||
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
|
*******************************************************************************/
|
||||||
|
|
||||||
|
package org.eclipse.cdt.lsp.core.cquery;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A class to contain constants that represent different roles
|
||||||
|
* a symbol can have.
|
||||||
|
* The constants are used as bit-flags to compose the value of
|
||||||
|
* HighlightSymbol.role.
|
||||||
|
*/
|
||||||
|
public final class SymbolRole {
|
||||||
|
public static final int Declaration = 1 << 0;
|
||||||
|
public static final int Definition = 1 << 1;
|
||||||
|
public static final int Reference = 1 << 2;
|
||||||
|
public static final int Read = 1 << 3;
|
||||||
|
public static final int Write = 1 << 4;
|
||||||
|
public static final int Call = 1 << 5;
|
||||||
|
public static final int Dynamic = 1 << 6;
|
||||||
|
public static final int Address = 1 << 7;
|
||||||
|
public static final int Implicit = 1 << 8;
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue