aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/ra_ide/src/syntax_highlighting.rs30
-rw-r--r--crates/ra_ide/src/syntax_highlighting/tags.rs92
-rw-r--r--crates/rust-analyzer/src/conv.rs46
-rw-r--r--crates/rust-analyzer/src/semantic_tokens.rs16
-rw-r--r--editors/code/package.json87
5 files changed, 169 insertions, 102 deletions
diff --git a/crates/ra_ide/src/syntax_highlighting.rs b/crates/ra_ide/src/syntax_highlighting.rs
index ae2163f9f..30ca9d8b0 100644
--- a/crates/ra_ide/src/syntax_highlighting.rs
+++ b/crates/ra_ide/src/syntax_highlighting.rs
@@ -177,10 +177,11 @@ fn highlight_element(
177 } 177 }
178 }; 178 };
179 179
180 match name_kind { 180 let h = match name_kind {
181 Some(name_kind) => highlight_name(db, name_kind), 181 Some(name_kind) => highlight_name(db, name_kind),
182 None => highlight_name_by_syntax(name), 182 None => highlight_name_by_syntax(name),
183 } 183 };
184 h | HighlightModifier::Definition
184 } 185 }
185 186
186 // Highlight references like the definitions they resolve to 187 // Highlight references like the definitions they resolve to
@@ -206,12 +207,13 @@ fn highlight_element(
206 207
207 // Simple token-based highlighting 208 // Simple token-based highlighting
208 COMMENT => HighlightTag::Comment.into(), 209 COMMENT => HighlightTag::Comment.into(),
209 STRING | RAW_STRING | RAW_BYTE_STRING | BYTE_STRING => HighlightTag::LiteralString.into(), 210 STRING | RAW_STRING | RAW_BYTE_STRING | BYTE_STRING => HighlightTag::StringLiteral.into(),
210 ATTR => HighlightTag::Attribute.into(), 211 ATTR => HighlightTag::Attribute.into(),
211 INT_NUMBER | FLOAT_NUMBER => HighlightTag::LiteralNumeric.into(), 212 INT_NUMBER | FLOAT_NUMBER => HighlightTag::NumericLiteral.into(),
212 BYTE => HighlightTag::LiteralByte.into(), 213 BYTE => HighlightTag::ByteLiteral.into(),
213 CHAR => HighlightTag::LiteralChar.into(), 214 CHAR => HighlightTag::CharLiteral.into(),
214 LIFETIME => HighlightTag::TypeLifetime.into(), 215 // FIXME: set Declaration for decls
216 LIFETIME => HighlightTag::Lifetime.into(),
215 217
216 k if k.is_keyword() => { 218 k if k.is_keyword() => {
217 let h = Highlight::new(HighlightTag::Keyword); 219 let h = Highlight::new(HighlightTag::Keyword);
@@ -258,17 +260,18 @@ fn highlight_name(db: &RootDatabase, def: NameDefinition) -> Highlight {
258 hir::ModuleDef::Adt(hir::Adt::Struct(_)) => HighlightTag::Struct, 260 hir::ModuleDef::Adt(hir::Adt::Struct(_)) => HighlightTag::Struct,
259 hir::ModuleDef::Adt(hir::Adt::Enum(_)) => HighlightTag::Enum, 261 hir::ModuleDef::Adt(hir::Adt::Enum(_)) => HighlightTag::Enum,
260 hir::ModuleDef::Adt(hir::Adt::Union(_)) => HighlightTag::Union, 262 hir::ModuleDef::Adt(hir::Adt::Union(_)) => HighlightTag::Union,
261 hir::ModuleDef::EnumVariant(_) => HighlightTag::Constant, 263 hir::ModuleDef::EnumVariant(_) => HighlightTag::EnumVariant,
262 hir::ModuleDef::Const(_) => HighlightTag::Constant, 264 hir::ModuleDef::Const(_) => HighlightTag::Constant,
263 hir::ModuleDef::Static(_) => HighlightTag::Constant, 265 hir::ModuleDef::Static(_) => HighlightTag::Static,
264 hir::ModuleDef::Trait(_) => HighlightTag::Trait, 266 hir::ModuleDef::Trait(_) => HighlightTag::Trait,
265 hir::ModuleDef::TypeAlias(_) => HighlightTag::TypeAlias, 267 hir::ModuleDef::TypeAlias(_) => HighlightTag::TypeAlias,
266 hir::ModuleDef::BuiltinType(_) => HighlightTag::BuiltinType, 268 hir::ModuleDef::BuiltinType(_) => HighlightTag::BuiltinType,
267 }, 269 },
268 NameDefinition::SelfType(_) => HighlightTag::TypeSelf, 270 NameDefinition::SelfType(_) => HighlightTag::SelfType,
269 NameDefinition::TypeParam(_) => HighlightTag::TypeParam, 271 NameDefinition::TypeParam(_) => HighlightTag::TypeParam,
272 // FIXME: distinguish between locals and parameters
270 NameDefinition::Local(local) => { 273 NameDefinition::Local(local) => {
271 let mut h = Highlight::new(HighlightTag::Variable); 274 let mut h = Highlight::new(HighlightTag::Local);
272 if local.is_mut(db) || local.ty(db).is_mutable_reference() { 275 if local.is_mut(db) || local.ty(db).is_mutable_reference() {
273 h |= HighlightModifier::Mutable; 276 h |= HighlightModifier::Mutable;
274 } 277 }
@@ -289,6 +292,7 @@ fn highlight_name_by_syntax(name: ast::Name) -> Highlight {
289 match parent.kind() { 292 match parent.kind() {
290 STRUCT_DEF => HighlightTag::Struct.into(), 293 STRUCT_DEF => HighlightTag::Struct.into(),
291 ENUM_DEF => HighlightTag::Enum.into(), 294 ENUM_DEF => HighlightTag::Enum.into(),
295 UNION_KW => HighlightTag::Union.into(),
292 TRAIT_DEF => HighlightTag::Trait.into(), 296 TRAIT_DEF => HighlightTag::Trait.into(),
293 TYPE_ALIAS_DEF => HighlightTag::TypeAlias.into(), 297 TYPE_ALIAS_DEF => HighlightTag::TypeAlias.into(),
294 TYPE_PARAM => HighlightTag::TypeParam.into(), 298 TYPE_PARAM => HighlightTag::TypeParam.into(),
@@ -315,7 +319,7 @@ fn highlight_injection(
315 if let Some(range) = literal.open_quote_text_range() { 319 if let Some(range) = literal.open_quote_text_range() {
316 acc.push(HighlightedRange { 320 acc.push(HighlightedRange {
317 range, 321 range,
318 highlight: HighlightTag::LiteralString.into(), 322 highlight: HighlightTag::StringLiteral.into(),
319 binding_hash: None, 323 binding_hash: None,
320 }) 324 })
321 } 325 }
@@ -330,7 +334,7 @@ fn highlight_injection(
330 if let Some(range) = literal.close_quote_text_range() { 334 if let Some(range) = literal.close_quote_text_range() {
331 acc.push(HighlightedRange { 335 acc.push(HighlightedRange {
332 range, 336 range,
333 highlight: HighlightTag::LiteralString.into(), 337 highlight: HighlightTag::StringLiteral.into(),
334 binding_hash: None, 338 binding_hash: None,
335 }) 339 })
336 } 340 }
diff --git a/crates/ra_ide/src/syntax_highlighting/tags.rs b/crates/ra_ide/src/syntax_highlighting/tags.rs
index df2fc3c48..0b12bdef5 100644
--- a/crates/ra_ide/src/syntax_highlighting/tags.rs
+++ b/crates/ra_ide/src/syntax_highlighting/tags.rs
@@ -14,70 +14,71 @@ pub struct HighlightModifiers(u32);
14 14
15#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] 15#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
16pub enum HighlightTag { 16pub enum HighlightTag {
17 Struct, 17 Attribute,
18 Enum,
19 Union,
20 Trait,
21 TypeAlias,
22 BuiltinType, 18 BuiltinType,
23 19 ByteLiteral,
20 CharLiteral,
21 Comment,
22 Constant,
23 Enum,
24 EnumVariant,
24 Field, 25 Field,
25 Function, 26 Function,
26 Module, 27 Keyword,
27 Constant, 28 Lifetime,
28 Macro, 29 Macro,
29 Variable, 30 Module,
30 31 NumericLiteral,
31 TypeSelf, 32 SelfType,
33 Static,
34 StringLiteral,
35 Struct,
36 Trait,
37 TypeAlias,
32 TypeParam, 38 TypeParam,
33 TypeLifetime, 39 Union,
34 40 Local,
35 LiteralByte,
36 LiteralNumeric,
37 LiteralChar,
38
39 Comment,
40 LiteralString,
41 Attribute,
42
43 Keyword,
44} 41}
45 42
46#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] 43#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
47#[repr(u8)] 44#[repr(u8)]
48pub enum HighlightModifier { 45pub enum HighlightModifier {
49 Mutable = 0,
50 Unsafe,
51 /// Used with keywords like `if` and `break`. 46 /// Used with keywords like `if` and `break`.
52 Control, 47 Control = 0,
48 /// `foo` in `fn foo(x: i32)` is a definition, `foo` in `foo(90 + 2)` is
49 /// not.
50 Definition,
51 Mutable,
52 Unsafe,
53} 53}
54 54
55impl HighlightTag { 55impl HighlightTag {
56 fn as_str(self) -> &'static str { 56 fn as_str(self) -> &'static str {
57 match self { 57 match self {
58 HighlightTag::Struct => "struct", 58 HighlightTag::Attribute => "attribute",
59 HighlightTag::Enum => "enum",
60 HighlightTag::Union => "union",
61 HighlightTag::Trait => "trait",
62 HighlightTag::TypeAlias => "type_alias",
63 HighlightTag::BuiltinType => "builtin_type", 59 HighlightTag::BuiltinType => "builtin_type",
64 60 HighlightTag::ByteLiteral => "byte_literal",
61 HighlightTag::CharLiteral => "char_literal",
62 HighlightTag::Comment => "comment",
63 HighlightTag::Constant => "constant",
64 HighlightTag::Enum => "enum",
65 HighlightTag::EnumVariant => "enum_variant",
65 HighlightTag::Field => "field", 66 HighlightTag::Field => "field",
66 HighlightTag::Function => "function", 67 HighlightTag::Function => "function",
67 HighlightTag::Module => "module",
68 HighlightTag::Constant => "constant",
69 HighlightTag::Macro => "macro",
70 HighlightTag::Variable => "variable",
71 HighlightTag::TypeSelf => "type.self",
72 HighlightTag::TypeParam => "type.param",
73 HighlightTag::TypeLifetime => "type.lifetime",
74 HighlightTag::LiteralByte => "literal.byte",
75 HighlightTag::LiteralNumeric => "literal.numeric",
76 HighlightTag::LiteralChar => "literal.char",
77 HighlightTag::Comment => "comment",
78 HighlightTag::LiteralString => "string",
79 HighlightTag::Attribute => "attribute",
80 HighlightTag::Keyword => "keyword", 68 HighlightTag::Keyword => "keyword",
69 HighlightTag::Lifetime => "lifetime",
70 HighlightTag::Macro => "macro",
71 HighlightTag::Module => "module",
72 HighlightTag::NumericLiteral => "numeric_literal",
73 HighlightTag::SelfType => "self_type",
74 HighlightTag::Static => "static",
75 HighlightTag::StringLiteral => "string",
76 HighlightTag::Struct => "struct",
77 HighlightTag::Trait => "trait",
78 HighlightTag::TypeAlias => "type_alias",
79 HighlightTag::TypeParam => "type_param",
80 HighlightTag::Union => "union",
81 HighlightTag::Local => "variable",
81 } 82 }
82 } 83 }
83} 84}
@@ -94,9 +95,10 @@ impl HighlightModifier {
94 95
95 fn as_str(self) -> &'static str { 96 fn as_str(self) -> &'static str {
96 match self { 97 match self {
98 HighlightModifier::Control => "control",
99 HighlightModifier::Definition => "declaration",
97 HighlightModifier::Mutable => "mutable", 100 HighlightModifier::Mutable => "mutable",
98 HighlightModifier::Unsafe => "unsafe", 101 HighlightModifier::Unsafe => "unsafe",
99 HighlightModifier::Control => "control",
100 } 102 }
101 } 103 }
102 104
diff --git a/crates/rust-analyzer/src/conv.rs b/crates/rust-analyzer/src/conv.rs
index e4255e24a..ff156307a 100644
--- a/crates/rust-analyzer/src/conv.rs
+++ b/crates/rust-analyzer/src/conv.rs
@@ -20,11 +20,11 @@ use ra_vfs::LineEndings;
20 20
21use crate::{ 21use crate::{
22 req, 22 req,
23 semantic_tokens::{self, ModifierSet, BUILTIN, CONSTANT, CONTROL, MUTABLE, UNSAFE}, 23 semantic_tokens::{self, ModifierSet, CONSTANT, CONTROL, MUTABLE, UNSAFE},
24 world::WorldSnapshot, 24 world::WorldSnapshot,
25 Result, 25 Result,
26}; 26};
27use semantic_tokens::ATTRIBUTE; 27use semantic_tokens::{ATTRIBUTE, BUILTIN_TYPE, ENUM_MEMBER, LIFETIME, TYPE_ALIAS, UNION};
28 28
29pub trait Conv { 29pub trait Conv {
30 type Output; 30 type Output;
@@ -316,45 +316,43 @@ impl Conv for Highlight {
316 fn conv(self) -> Self::Output { 316 fn conv(self) -> Self::Output {
317 let mut mods = ModifierSet::default(); 317 let mut mods = ModifierSet::default();
318 let type_ = match self.tag { 318 let type_ = match self.tag {
319 HighlightTag::Struct 319 HighlightTag::Struct => SemanticTokenType::STRUCT,
320 | HighlightTag::Enum 320 HighlightTag::Enum => SemanticTokenType::ENUM,
321 | HighlightTag::Union 321 HighlightTag::Union => UNION,
322 | HighlightTag::TypeAlias 322 HighlightTag::TypeAlias => TYPE_ALIAS,
323 | HighlightTag::Trait 323 HighlightTag::Trait => SemanticTokenType::INTERFACE,
324 | HighlightTag::BuiltinType => SemanticTokenType::TYPE, 324 HighlightTag::BuiltinType => BUILTIN_TYPE,
325 HighlightTag::SelfType => SemanticTokenType::TYPE,
325 HighlightTag::Field => SemanticTokenType::MEMBER, 326 HighlightTag::Field => SemanticTokenType::MEMBER,
326 HighlightTag::Function => SemanticTokenType::FUNCTION, 327 HighlightTag::Function => SemanticTokenType::FUNCTION,
327 HighlightTag::Module => SemanticTokenType::NAMESPACE, 328 HighlightTag::Module => SemanticTokenType::NAMESPACE,
328 HighlightTag::Constant => { 329 HighlightTag::Constant => {
330 mods |= CONSTANT;
329 mods |= SemanticTokenModifier::STATIC; 331 mods |= SemanticTokenModifier::STATIC;
330 mods |= SemanticTokenModifier::READONLY; 332 SemanticTokenType::VARIABLE
331 CONSTANT
332 } 333 }
333 HighlightTag::Macro => SemanticTokenType::MACRO, 334 HighlightTag::Static => {
334 HighlightTag::Variable => SemanticTokenType::VARIABLE, 335 mods |= SemanticTokenModifier::STATIC;
335 HighlightTag::TypeSelf => { 336 SemanticTokenType::VARIABLE
336 mods |= SemanticTokenModifier::REFERENCE;
337 SemanticTokenType::TYPE
338 } 337 }
338 HighlightTag::EnumVariant => ENUM_MEMBER,
339 HighlightTag::Macro => SemanticTokenType::MACRO,
340 HighlightTag::Local => SemanticTokenType::VARIABLE,
339 HighlightTag::TypeParam => SemanticTokenType::TYPE_PARAMETER, 341 HighlightTag::TypeParam => SemanticTokenType::TYPE_PARAMETER,
340 HighlightTag::TypeLifetime => { 342 HighlightTag::Lifetime => LIFETIME,
341 mods |= SemanticTokenModifier::REFERENCE; 343 HighlightTag::ByteLiteral | HighlightTag::NumericLiteral => SemanticTokenType::NUMBER,
342 SemanticTokenType::LABEL 344 HighlightTag::CharLiteral | HighlightTag::StringLiteral => SemanticTokenType::STRING,
343 }
344 HighlightTag::LiteralByte => SemanticTokenType::NUMBER,
345 HighlightTag::LiteralNumeric => SemanticTokenType::NUMBER,
346 HighlightTag::LiteralChar => SemanticTokenType::NUMBER,
347 HighlightTag::Comment => SemanticTokenType::COMMENT, 345 HighlightTag::Comment => SemanticTokenType::COMMENT,
348 HighlightTag::LiteralString => SemanticTokenType::STRING,
349 HighlightTag::Attribute => ATTRIBUTE, 346 HighlightTag::Attribute => ATTRIBUTE,
350 HighlightTag::Keyword => SemanticTokenType::KEYWORD, 347 HighlightTag::Keyword => SemanticTokenType::KEYWORD,
351 }; 348 };
352 349
353 for modifier in self.modifiers.iter() { 350 for modifier in self.modifiers.iter() {
354 let modifier = match modifier { 351 let modifier = match modifier {
352 HighlightModifier::Definition => SemanticTokenModifier::DECLARATION,
353 HighlightModifier::Control => CONTROL,
355 HighlightModifier::Mutable => MUTABLE, 354 HighlightModifier::Mutable => MUTABLE,
356 HighlightModifier::Unsafe => UNSAFE, 355 HighlightModifier::Unsafe => UNSAFE,
357 HighlightModifier::Control => CONTROL,
358 }; 356 };
359 mods |= modifier; 357 mods |= modifier;
360 } 358 }
diff --git a/crates/rust-analyzer/src/semantic_tokens.rs b/crates/rust-analyzer/src/semantic_tokens.rs
index 3069f3054..1b146e4d8 100644
--- a/crates/rust-analyzer/src/semantic_tokens.rs
+++ b/crates/rust-analyzer/src/semantic_tokens.rs
@@ -5,11 +5,16 @@ use std::ops;
5use lsp_types::{Range, SemanticToken, SemanticTokenModifier, SemanticTokenType}; 5use lsp_types::{Range, SemanticToken, SemanticTokenModifier, SemanticTokenType};
6 6
7pub(crate) const ATTRIBUTE: SemanticTokenType = SemanticTokenType::new("attribute"); 7pub(crate) const ATTRIBUTE: SemanticTokenType = SemanticTokenType::new("attribute");
8pub(crate) const CONSTANT: SemanticTokenType = SemanticTokenType::new("constant"); 8pub(crate) const BUILTIN_TYPE: SemanticTokenType = SemanticTokenType::new("builtinType");
9pub(crate) const ENUM_MEMBER: SemanticTokenType = SemanticTokenType::new("enumMember");
10pub(crate) const LIFETIME: SemanticTokenType = SemanticTokenType::new("lifetime");
11pub(crate) const TYPE_ALIAS: SemanticTokenType = SemanticTokenType::new("typeAlias");
12pub(crate) const UNION: SemanticTokenType = SemanticTokenType::new("union");
9 13
14pub(crate) const CONSTANT: SemanticTokenModifier = SemanticTokenModifier::new("constant");
15pub(crate) const CONTROL: SemanticTokenModifier = SemanticTokenModifier::new("control");
10pub(crate) const MUTABLE: SemanticTokenModifier = SemanticTokenModifier::new("mutable"); 16pub(crate) const MUTABLE: SemanticTokenModifier = SemanticTokenModifier::new("mutable");
11pub(crate) const UNSAFE: SemanticTokenModifier = SemanticTokenModifier::new("unsafe"); 17pub(crate) const UNSAFE: SemanticTokenModifier = SemanticTokenModifier::new("unsafe");
12pub(crate) const CONTROL: SemanticTokenModifier = SemanticTokenModifier::new("control");
13 18
14pub(crate) const SUPPORTED_TYPES: &[SemanticTokenType] = &[ 19pub(crate) const SUPPORTED_TYPES: &[SemanticTokenType] = &[
15 SemanticTokenType::COMMENT, 20 SemanticTokenType::COMMENT,
@@ -33,7 +38,11 @@ pub(crate) const SUPPORTED_TYPES: &[SemanticTokenType] = &[
33 SemanticTokenType::PARAMETER, 38 SemanticTokenType::PARAMETER,
34 SemanticTokenType::LABEL, 39 SemanticTokenType::LABEL,
35 ATTRIBUTE, 40 ATTRIBUTE,
36 CONSTANT, 41 BUILTIN_TYPE,
42 ENUM_MEMBER,
43 LIFETIME,
44 TYPE_ALIAS,
45 UNION,
37]; 46];
38 47
39pub(crate) const SUPPORTED_MODIFIERS: &[SemanticTokenModifier] = &[ 48pub(crate) const SUPPORTED_MODIFIERS: &[SemanticTokenModifier] = &[
@@ -47,6 +56,7 @@ pub(crate) const SUPPORTED_MODIFIERS: &[SemanticTokenModifier] = &[
47 SemanticTokenModifier::ASYNC, 56 SemanticTokenModifier::ASYNC,
48 SemanticTokenModifier::VOLATILE, 57 SemanticTokenModifier::VOLATILE,
49 SemanticTokenModifier::READONLY, 58 SemanticTokenModifier::READONLY,
59 CONSTANT,
50 MUTABLE, 60 MUTABLE,
51 UNSAFE, 61 UNSAFE,
52 CONTROL, 62 CONTROL,
diff --git a/editors/code/package.json b/editors/code/package.json
index fd29710ba..df8265be1 100644
--- a/editors/code/package.json
+++ b/editors/code/package.json
@@ -383,21 +383,42 @@
383 ], 383 ],
384 "semanticTokenTypes": [ 384 "semanticTokenTypes": [
385 { 385 {
386 "id": "attribute" 386 "id": "attribute",
387 "description": "Style for attributes"
387 }, 388 },
388 { 389 {
389 "id": "constant" 390 "id": "builtinType",
391 "description": "Style for builtin types"
392 },
393 {
394 "id": "lifetime",
395 "description": "Style for lifetimes"
396 },
397 {
398 "id": "typeAlias",
399 "description": "Style for type aliases"
400 },
401 {
402 "id": "union",
403 "description": "Style for C-style untagged unions"
390 } 404 }
391 ], 405 ],
392 "semanticTokenModifiers": [ 406 "semanticTokenModifiers": [
393 { 407 {
394 "id": "mutable" 408 "id": "constant",
409 "description": "Style for compile-time constants"
395 }, 410 },
396 { 411 {
397 "id": "unsafe" 412 "id": "control",
413 "description": "Style for control flow keywords"
398 }, 414 },
399 { 415 {
400 "id": "control" 416 "id": "mutable",
417 "description": "Style for mutable bindings"
418 },
419 {
420 "id": "unsafe",
421 "description": "Style for unsafe operations"
401 } 422 }
402 ], 423 ],
403 "semanticTokenStyleDefaults": [ 424 "semanticTokenStyleDefaults": [
@@ -408,21 +429,29 @@
408 ] 429 ]
409 }, 430 },
410 { 431 {
411 "selector": "*.mutable", 432 "selector": "builtinType",
412 "light": { 433 "scope": [
413 "fontStyle": "underline" 434 "support.type.primitive"
414 }, 435 ]
415 "dark": {
416 "fontStyle": "underline"
417 },
418 "highContrast": {
419 "fontStyle": "underline"
420 }
421 }, 436 },
422 { 437 {
423 "selector": "constant", 438 "selector": "lifetime",
424 "scope": [ 439 "scope": [
425 "entity.name.constant" 440 "entity.name.lifetime.rust"
441 ]
442 },
443 {
444 "selector": "typeAlias",
445 "scope": [
446 "entity.name.type",
447 "entity.name.typeAlias"
448 ]
449 },
450 {
451 "selector": "union",
452 "scope": [
453 "entity.name.type",
454 "entity.name.union"
426 ] 455 ]
427 }, 456 },
428 { 457 {
@@ -430,6 +459,30 @@
430 "scope": [ 459 "scope": [
431 "keyword.other.unsafe" 460 "keyword.other.unsafe"
432 ] 461 ]
462 },
463 {
464 "selector": "keyword.control",
465 "scope": [
466 "keyword.control"
467 ]
468 },
469 {
470 "selector": "variable.constant",
471 "scope": [
472 "entity.name.constant"
473 ]
474 },
475 {
476 "selector": "*.mutable",
477 "light": {
478 "fontStyle": "underline"
479 },
480 "dark": {
481 "fontStyle": "underline"
482 },
483 "highContrast": {
484 "fontStyle": "underline"
485 }
433 } 486 }
434 ] 487 ]
435 } 488 }