diff --git a/lsp/org.eclipse.cdt.lsp.core.tests/src/org/eclipse/cdt/lsp/core/tests/cquery/CqueryJsonParseTest.java b/lsp/org.eclipse.cdt.lsp.core.tests/src/org/eclipse/cdt/lsp/core/tests/cquery/CqueryJsonParseTest.java index 2d9b0ef08fd..e891b9c8acf 100644 --- a/lsp/org.eclipse.cdt.lsp.core.tests/src/org/eclipse/cdt/lsp/core/tests/cquery/CqueryJsonParseTest.java +++ b/lsp/org.eclipse.cdt.lsp.core.tests/src/org/eclipse/cdt/lsp/core/tests/cquery/CqueryJsonParseTest.java @@ -23,6 +23,7 @@ import org.eclipse.cdt.lsp.core.cquery.HighlightSymbol; import org.eclipse.cdt.lsp.core.cquery.IndexingProgressStats; 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.Range; import org.eclipse.lsp4j.jsonrpc.json.JsonRpcMethod; @@ -84,9 +85,9 @@ public void testSetInactiveRegions() { public void testPublishSemanticHighlighting() { String json = "{\"jsonrpc\": \"2.0\",\"method\": \"$cquery/publishSemanticHighlighting\"," //$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$ - + "\"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$ URI uri = URI.create("file:///home/foobar.cpp"); //$NON-NLS-1$ @@ -106,8 +107,10 @@ public void testPublishSemanticHighlighting() { ExtendedSymbolKindType kind2 = new ExtendedSymbolKindType(253); StorageClass storage1 = StorageClass.Static; StorageClass storage2 = StorageClass.Auto; - HighlightSymbol symbol1 = new HighlightSymbol(21, parentKind1, kind1, storage1, ranges1); - HighlightSymbol symbol2 = new HighlightSymbol(19, parentKind2, kind2, storage2, ranges2); + int role1 = SymbolRole.Declaration; + 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 symbols = new ArrayList<>(); symbols.add(symbol1); symbols.add(symbol2); diff --git a/lsp/org.eclipse.cdt.lsp.core/src/org/eclipse/cdt/lsp/core/Server2ClientProtocolExtension.java b/lsp/org.eclipse.cdt.lsp.core/src/org/eclipse/cdt/lsp/core/Server2ClientProtocolExtension.java index eaed3ea0d30..08b55705d79 100644 --- a/lsp/org.eclipse.cdt.lsp.core/src/org/eclipse/cdt/lsp/core/Server2ClientProtocolExtension.java +++ b/lsp/org.eclipse.cdt.lsp.core/src/org/eclipse/cdt/lsp/core/Server2ClientProtocolExtension.java @@ -168,7 +168,7 @@ public final void semanticHighlights(CquerySemanticHighlights highlights) { for (HighlightSymbol highlight : highlights.getSymbols()) { String highlightingName = HighlightSymbol.getHighlightingName(highlight.getKind(), - highlight.getParentKind(), highlight.getStorage()); + highlight.getParentKind(), highlight.getStorage(), highlight.getRole()); String colorKey = PreferenceConstants.EDITOR_SEMANTIC_HIGHLIGHTING_PREFIX + highlightingName + PreferenceConstants.EDITOR_SEMANTIC_HIGHLIGHTING_COLOR_SUFFIX; diff --git a/lsp/org.eclipse.cdt.lsp.core/src/org/eclipse/cdt/lsp/core/cquery/HighlightSymbol.java b/lsp/org.eclipse.cdt.lsp.core/src/org/eclipse/cdt/lsp/core/cquery/HighlightSymbol.java index 46313a281fc..b5b4820a33e 100644 --- a/lsp/org.eclipse.cdt.lsp.core/src/org/eclipse/cdt/lsp/core/cquery/HighlightSymbol.java +++ b/lsp/org.eclipse.cdt.lsp.core/src/org/eclipse/cdt/lsp/core/cquery/HighlightSymbol.java @@ -25,15 +25,13 @@ public class HighlightSymbol { private ExtendedSymbolKindType kind; private StorageClass storage; private List ranges; + private Integer role; public static Map 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); @@ -45,16 +43,24 @@ public class HighlightSymbol { 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, - 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()); 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; + highlightingName = isDeclaration(role) ? SemanticHighlightings.LOCAL_VARIABLE_DECLARATION + : SemanticHighlightings.LOCAL_VARIABLE; } else { highlightingName = SemanticHighlightings.GLOBAL_VARIABLE; } @@ -64,17 +70,25 @@ public static String getHighlightingName(ExtendedSymbolKindType kind, ExtendedSy } else { 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; } public HighlightSymbol(int stableId, ExtendedSymbolKindType parentKind, ExtendedSymbolKindType kind, - StorageClass storage, List ranges) { + StorageClass storage, Integer role, List ranges) { this.stableId = stableId; this.parentKind = parentKind; this.kind = kind; this.storage = storage; + this.role = role; this.ranges = ranges; } @@ -94,6 +108,10 @@ public StorageClass getStorage() { return storage; } + public Integer getRole() { + return role; + } + public List getRanges() { return ranges; } diff --git a/lsp/org.eclipse.cdt.lsp.core/src/org/eclipse/cdt/lsp/core/cquery/SymbolRole.java b/lsp/org.eclipse.cdt.lsp.core/src/org/eclipse/cdt/lsp/core/cquery/SymbolRole.java new file mode 100644 index 00000000000..a163d711b90 --- /dev/null +++ b/lsp/org.eclipse.cdt.lsp.core/src/org/eclipse/cdt/lsp/core/cquery/SymbolRole.java @@ -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; +} \ No newline at end of file