lsp: Add semantic token rules for Go (#50641)

Nianyu Shen created

gopls reports Go `const` declarations as `variable` with the `readonly`
modifier. Add a Go-specific semantic token rule to map this to the
`constant` theme style, matching VS Code's behavior.

<img width="465" height="32" alt="image"
src="https://github.com/user-attachments/assets/e0bc8a60-2275-4f81-9185-8b86c51d3d08"
/>

Closes #50642

Before you mark this PR as ready for review, make sure that you have:
- [x] Added a solid test coverage and/or screenshots from doing manual
testing
- [x] Done a self-review taking into account security and performance
aspects
- [x] Aligned any UI changes with the [UI
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)

Release Notes:

- N/A *or* Added/Fixed/Improved ...

Change summary

crates/languages/src/go.rs                        | 11 +++++++++++
crates/languages/src/go/semantic_token_rules.json |  7 +++++++
crates/languages/src/lib.rs                       |  1 +
3 files changed, 19 insertions(+)

Detailed changes

crates/languages/src/go.rs 🔗

@@ -11,6 +11,7 @@ use lsp::{LanguageServerBinary, LanguageServerName};
 use project::lsp_store::language_server_settings;
 use regex::Regex;
 use serde_json::{Value, json};
+use settings::SemanticTokenRules;
 use smol::fs;
 use std::{
     borrow::Cow,
@@ -27,6 +28,16 @@ use std::{
 use task::{TaskTemplate, TaskTemplates, TaskVariables, VariableName};
 use util::{ResultExt, fs::remove_matching, maybe, merge_json_value_into};
 
+use crate::LanguageDir;
+
+pub(crate) fn semantic_token_rules() -> SemanticTokenRules {
+    let content = LanguageDir::get("go/semantic_token_rules.json")
+        .expect("missing go/semantic_token_rules.json");
+    let json = std::str::from_utf8(&content.data).expect("invalid utf-8 in semantic_token_rules");
+    settings::parse_json_with_comments::<SemanticTokenRules>(json)
+        .expect("failed to parse go semantic_token_rules.json")
+}
+
 fn server_binary_arguments() -> Vec<OsString> {
     vec!["-mode=stdio".into()]
 }

crates/languages/src/lib.rs 🔗

@@ -141,6 +141,7 @@ pub fn init(languages: Arc<LanguageRegistry>, fs: Arc<dyn Fs>, node: NodeRuntime
             name: "go",
             adapters: vec![go_lsp_adapter.clone()],
             context: Some(go_context_provider.clone()),
+            semantic_token_rules: Some(go::semantic_token_rules()),
             ..Default::default()
         },
         LanguageInfo {