diff --git a/Cargo.lock b/Cargo.lock index 9cc5a73c96..f1b559f405 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1833,9 +1833,9 @@ checksum = "0685c84d5d54d1c26f7d3eb96cd41550adb97baed141a761cf335d3d33bcd0ae" [[package]] name = "ungrammar" -version = "1.16.0" +version = "1.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a62374cbbda72c1459ce5e7bfcdf1bd284c812a4faf2324aa083e5d9ea87880f" +checksum = "a3e5df347f0bf3ec1d670aad6ca5c6a1859cd9ea61d2113125794654ccced68f" [[package]] name = "unicase" diff --git a/crates/hir/src/semantics.rs b/crates/hir/src/semantics.rs index 2e0dbf82b7..80205f7fbc 100644 --- a/crates/hir/src/semantics.rs +++ b/crates/hir/src/semantics.rs @@ -10,7 +10,10 @@ use hir_def::{ resolver::{self, HasResolver, Resolver, TypeNs}, AsMacroCall, FunctionId, TraitId, VariantId, }; -use hir_expand::{name::AsName, ExpansionInfo, MacroCallId}; +use hir_expand::{ + name::{known, AsName}, + ExpansionInfo, MacroCallId, +}; use hir_ty::Interner; use itertools::Itertools; use rustc_hash::{FxHashMap, FxHashSet}; @@ -910,13 +913,14 @@ impl<'db> SemanticsImpl<'db> { fn resolve_extern_crate(&self, extern_crate: &ast::ExternCrate) -> Option { let krate = self.scope(extern_crate.syntax()).krate()?; - krate.dependencies(self.db).into_iter().find_map(|dep| { - if dep.name == extern_crate.name_ref()?.as_name() { - Some(dep.krate) - } else { - None - } - }) + let name = extern_crate.name_ref()?.as_name(); + if name == known::SELF_PARAM { + return Some(krate); + } + krate + .dependencies(self.db) + .into_iter() + .find_map(|dep| (dep.name == name).then(|| dep.krate)) } fn resolve_variant(&self, record_lit: ast::RecordExpr) -> Option { diff --git a/crates/hir_def/src/macro_expansion_tests.rs b/crates/hir_def/src/macro_expansion_tests.rs index 1a7d9aa841..f86d87d5cc 100644 --- a/crates/hir_def/src/macro_expansion_tests.rs +++ b/crates/hir_def/src/macro_expansion_tests.rs @@ -302,6 +302,7 @@ fn pretty_print_macro_expansion(expn: SyntaxNode, map: Option<&TokenMap>) -> Str (T![fn], T!['(']) => "", (T![']'], _) if curr_kind.is_keyword() => " ", (T![']'], T![#]) => "\n", + (T![Self], T![::]) => "", _ if prev_kind.is_keyword() => " ", _ => "", }; diff --git a/crates/hir_def/src/path/lower.rs b/crates/hir_def/src/path/lower.rs index 49e55e03d1..550f12dabd 100644 --- a/crates/hir_def/src/path/lower.rs +++ b/crates/hir_def/src/path/lower.rs @@ -53,6 +53,10 @@ pub(super) fn lower_path(mut path: ast::Path, ctx: &LowerCtx) -> Option { } } } + ast::PathSegmentKind::SelfTypeKw => { + segments.push(name![Self]); + generic_args.push(None) + } ast::PathSegmentKind::Type { type_ref, trait_ref } => { assert!(path.qualifier().is_none()); // this can only occur at the first segment diff --git a/crates/hir_expand/src/mod_path.rs b/crates/hir_expand/src/mod_path.rs index 9c06a3f892..5e264d0398 100644 --- a/crates/hir_expand/src/mod_path.rs +++ b/crates/hir_expand/src/mod_path.rs @@ -5,7 +5,11 @@ use std::{ iter, }; -use crate::{db::AstDatabase, hygiene::Hygiene, name::Name}; +use crate::{ + db::AstDatabase, + hygiene::Hygiene, + name::{known, Name}, +}; use base_db::CrateId; use either::Either; use syntax::{ast, AstNode}; @@ -162,6 +166,12 @@ fn convert_path( } } } + ast::PathSegmentKind::SelfTypeKw => { + if prefix.is_some() { + return None; + } + ModPath::from_segments(PathKind::Plain, Some(known::SELF_TYPE)) + } ast::PathSegmentKind::CrateKw => { if prefix.is_some() { return None; diff --git a/crates/ide/src/extend_selection.rs b/crates/ide/src/extend_selection.rs index ae4dfd47bd..5520ee5528 100644 --- a/crates/ide/src/extend_selection.rs +++ b/crates/ide/src/extend_selection.rs @@ -246,7 +246,7 @@ fn pick_best(l: SyntaxToken, r: SyntaxToken) -> SyntaxToken { fn priority(n: &SyntaxToken) -> usize { match n.kind() { WHITESPACE => 0, - IDENT | T![self] | T![super] | T![crate] | LIFETIME_IDENT => 2, + IDENT | T![self] | T![super] | T![crate] | T![Self] | LIFETIME_IDENT => 2, _ => 1, } } diff --git a/crates/ide/src/goto_declaration.rs b/crates/ide/src/goto_declaration.rs index e62daf03f9..cb2cddc20d 100644 --- a/crates/ide/src/goto_declaration.rs +++ b/crates/ide/src/goto_declaration.rs @@ -18,7 +18,7 @@ pub(crate) fn goto_declaration( let file = sema.parse(position.file_id).syntax().clone(); let original_token = file .token_at_offset(position.offset) - .find(|it| matches!(it.kind(), IDENT | T![self] | T![super] | T![crate]))?; + .find(|it| matches!(it.kind(), IDENT | T![self] | T![super] | T![crate] | T![Self]))?; let range = original_token.text_range(); let info: Vec = sema .descend_into_macros(original_token) diff --git a/crates/ide/src/goto_definition.rs b/crates/ide/src/goto_definition.rs index e599efc5e2..d664e2ca65 100644 --- a/crates/ide/src/goto_definition.rs +++ b/crates/ide/src/goto_definition.rs @@ -30,7 +30,14 @@ pub(crate) fn goto_definition( let file = sema.parse(position.file_id).syntax().clone(); let original_token = pick_best_token(file.token_at_offset(position.offset), |kind| match kind { - IDENT | INT_NUMBER | LIFETIME_IDENT | T![self] | T![super] | T![crate] | COMMENT => 2, + IDENT + | INT_NUMBER + | LIFETIME_IDENT + | T![self] + | T![super] + | T![crate] + | T![Self] + | COMMENT => 2, kind if kind.is_trivia() => 0, _ => 1, })?; diff --git a/crates/ide/src/hover.rs b/crates/ide/src/hover.rs index 0eba0b09ba..30d0d34358 100644 --- a/crates/ide/src/hover.rs +++ b/crates/ide/src/hover.rs @@ -100,7 +100,7 @@ pub(crate) fn hover( let offset = range.start(); let original_token = pick_best_token(file.token_at_offset(offset), |kind| match kind { - IDENT | INT_NUMBER | LIFETIME_IDENT | T![self] | T![super] | T![crate] => 3, + IDENT | INT_NUMBER | LIFETIME_IDENT | T![self] | T![super] | T![crate] | T![Self] => 3, T!['('] | T![')'] => 2, kind if kind.is_trivia() => 0, _ => 1, diff --git a/crates/ide/src/hover/render.rs b/crates/ide/src/hover/render.rs index 40a647c90b..f8ac43bbdd 100644 --- a/crates/ide/src/hover/render.rs +++ b/crates/ide/src/hover/render.rs @@ -545,7 +545,6 @@ fn keyword_hints( }, } } - T![fn] => { let module = match ast::FnPtrType::cast(parent) { // treat fn keyword inside function pointer type as primitive @@ -554,7 +553,7 @@ fn keyword_hints( }; KeywordHint::new(token.text().to_string(), module) } - + T![Self] => KeywordHint::new(token.text().to_string(), "self_upper_keyword".into()), _ => KeywordHint::new(token.text().to_string(), format!("{}_keyword", token.text())), } } diff --git a/crates/ide/src/moniker.rs b/crates/ide/src/moniker.rs index 53f6d7ec7a..2e93d895f0 100644 --- a/crates/ide/src/moniker.rs +++ b/crates/ide/src/moniker.rs @@ -69,7 +69,14 @@ pub(crate) fn moniker( let file = sema.parse(file_id).syntax().clone(); let current_crate = crate_for_file(db, file_id)?; let original_token = pick_best_token(file.token_at_offset(offset), |kind| match kind { - IDENT | INT_NUMBER | LIFETIME_IDENT | T![self] | T![super] | T![crate] | COMMENT => 2, + IDENT + | INT_NUMBER + | LIFETIME_IDENT + | T![self] + | T![super] + | T![crate] + | T![Self] + | COMMENT => 2, kind if kind.is_trivia() => 0, _ => 1, })?; diff --git a/crates/ide/src/static_index.rs b/crates/ide/src/static_index.rs index d5bfbd1894..fb94342a78 100644 --- a/crates/ide/src/static_index.rs +++ b/crates/ide/src/static_index.rs @@ -126,7 +126,7 @@ impl StaticIndex<'_> { let tokens = tokens.filter(|token| { matches!( token.kind(), - IDENT | INT_NUMBER | LIFETIME_IDENT | T![self] | T![super] | T![crate] + IDENT | INT_NUMBER | LIFETIME_IDENT | T![self] | T![super] | T![crate] | T![Self] ) }); let mut result = StaticIndexedFile { file_id, inlay_hints, folds, tokens: vec![] }; diff --git a/crates/ide/src/syntax_highlighting.rs b/crates/ide/src/syntax_highlighting.rs index 776a0f8295..968aa33116 100644 --- a/crates/ide/src/syntax_highlighting.rs +++ b/crates/ide/src/syntax_highlighting.rs @@ -118,6 +118,7 @@ pub struct HlRange { // parameter:: Emitted for non-self function parameters. // property:: Emitted for struct and union fields. // selfKeyword:: Emitted for the self function parameter and self path-specifier. +// selfTypeKeyword:: Emitted for the Self type parameter. // toolModule:: Emitted for tool modules. // typeParameter:: Emitted for type parameters. // unresolvedReference:: Emitted for unresolved references, names that rust-analyzer can't find the definition of. @@ -327,7 +328,7 @@ fn traverse( // as otherwise we won't ever visit them match (token.kind(), parent.kind()) { (T![ident], NAME | NAME_REF) => parent.into(), - (T![self] | T![super] | T![crate], NAME_REF) => parent.into(), + (T![self] | T![super] | T![crate] | T![Self], NAME_REF) => parent.into(), (INT_NUMBER, NAME_REF) => parent.into(), (LIFETIME_IDENT, LIFETIME) => parent.into(), _ => token.into(), diff --git a/crates/ide/src/syntax_highlighting/highlight.rs b/crates/ide/src/syntax_highlighting/highlight.rs index 8ad27b1fdc..43a3fb2d71 100644 --- a/crates/ide/src/syntax_highlighting/highlight.rs +++ b/crates/ide/src/syntax_highlighting/highlight.rs @@ -192,9 +192,11 @@ fn keyword( T![true] | T![false] => HlTag::BoolLiteral.into(), // crate is handled just as a token if it's in an `extern crate` T![crate] if parent_matches::(&token) => h, - // self, crate and super are handled as either a Name or NameRef already, unless they + // self, crate, super and `Self` are handled as either a Name or NameRef already, unless they // are inside unmapped token trees - T![self] | T![crate] | T![super] if parent_matches::(&token) => return None, + T![self] | T![crate] | T![super] | T![Self] if parent_matches::(&token) => { + return None + } T![self] if parent_matches::(&token) => return None, T![ref] => match token.parent().and_then(ast::IdentPat::cast) { Some(ident) if sema.is_unsafe_ident_pat(&ident) => h | HlMod::Unsafe, @@ -269,12 +271,13 @@ fn highlight_name_ref( } NameRefClass::FieldShorthand { .. } => SymbolKind::Field.into(), }; - if name_ref.self_token().is_some() { - h.tag = HlTag::Symbol(SymbolKind::SelfParam); - } - if name_ref.crate_token().is_some() || name_ref.super_token().is_some() { - h.tag = HlTag::Keyword; - } + + h.tag = match name_ref.token_kind() { + T![Self] => HlTag::Symbol(SymbolKind::SelfType), + T![self] => HlTag::Symbol(SymbolKind::SelfParam), + T![super] | T![crate] => HlTag::Keyword, + _ => h.tag, + }; h } diff --git a/crates/ide/src/syntax_highlighting/tags.rs b/crates/ide/src/syntax_highlighting/tags.rs index bdf484e01f..cb9d36f830 100644 --- a/crates/ide/src/syntax_highlighting/tags.rs +++ b/crates/ide/src/syntax_highlighting/tags.rs @@ -141,6 +141,7 @@ impl HlTag { SymbolKind::Macro => "macro", SymbolKind::Module => "module", SymbolKind::SelfParam => "self_keyword", + SymbolKind::SelfType => "self_type_keyword", SymbolKind::Static => "static", SymbolKind::Struct => "struct", SymbolKind::ToolModule => "tool_module", diff --git a/crates/ide/src/syntax_highlighting/test_data/highlight_general.html b/crates/ide/src/syntax_highlighting/test_data/highlight_general.html index 22bdfffa3e..86ed8dbd77 100644 --- a/crates/ide/src/syntax_highlighting/test_data/highlight_general.html +++ b/crates/ide/src/syntax_highlighting/test_data/highlight_general.html @@ -59,11 +59,11 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd x: u32, } -trait Bar where Self: { +trait Bar { fn bar(&self) -> i32; } -impl Bar for Foo where Self: { +impl Bar for Foo { fn bar(&self) -> i32 { self.x } @@ -210,7 +210,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd impl Bool { pub const fn to_primitive(self) -> bool { - matches!(self, Self::True) + true } } const USAGE_OF_BOOL:bool = Bool::True.to_primitive(); diff --git a/crates/ide/src/syntax_highlighting/test_data/highlight_keywords.html b/crates/ide/src/syntax_highlighting/test_data/highlight_keywords.html new file mode 100644 index 0000000000..145bba2a06 --- /dev/null +++ b/crates/ide/src/syntax_highlighting/test_data/highlight_keywords.html @@ -0,0 +1,57 @@ + + +
extern crate self;
+
+use crate;
+use self;
+mod __ {
+    use super::*;
+}
+
+macro_rules! void {
+    ($($tt:tt)) => {}
+}
+void!(Self);
+struct __ where Self:;
+fn __(_: Self) {}
\ No newline at end of file diff --git a/crates/ide/src/syntax_highlighting/tests.rs b/crates/ide/src/syntax_highlighting/tests.rs index c14e3330e3..0af743431b 100644 --- a/crates/ide/src/syntax_highlighting/tests.rs +++ b/crates/ide/src/syntax_highlighting/tests.rs @@ -113,11 +113,11 @@ struct Foo { x: u32, } -trait Bar where Self: { +trait Bar { fn bar(&self) -> i32; } -impl Bar for Foo where Self: { +impl Bar for Foo { fn bar(&self) -> i32 { self.x } @@ -264,7 +264,7 @@ pub enum Bool { True, False } impl Bool { pub const fn to_primitive(self) -> bool { - matches!(self, Self::True) + true } } const USAGE_OF_BOOL:bool = Bool::True.to_primitive(); @@ -334,6 +334,30 @@ where ); } +#[test] +fn test_keyword_highlighting() { + check_highlighting( + r#" +extern crate self; + +use crate; +use self; +mod __ { + use super::*; +} + +macro_rules! void { + ($($tt:tt)) => {} +} +void!(Self); +struct __ where Self:; +fn __(_: Self) {} +"#, + expect_file!["./test_data/highlight_keywords.html"], + false, + ); +} + #[test] fn test_string_highlighting() { // The format string detection is based on macro-expansion, diff --git a/crates/ide_completion/src/item.rs b/crates/ide_completion/src/item.rs index acaf17c255..32b14764a1 100644 --- a/crates/ide_completion/src/item.rs +++ b/crates/ide_completion/src/item.rs @@ -260,6 +260,7 @@ impl CompletionItemKind { SymbolKind::Macro => "ma", SymbolKind::Module => "md", SymbolKind::SelfParam => "sp", + SymbolKind::SelfType => "sy", SymbolKind::Static => "sc", SymbolKind::Struct => "st", SymbolKind::ToolModule => "tm", diff --git a/crates/ide_db/src/helpers/insert_use.rs b/crates/ide_db/src/helpers/insert_use.rs index d6f8cd0f4b..efb704b253 100644 --- a/crates/ide_db/src/helpers/insert_use.rs +++ b/crates/ide_db/src/helpers/insert_use.rs @@ -238,7 +238,9 @@ impl ImportGroup { "core" => ImportGroup::Std, _ => ImportGroup::ExternCrate, }, - PathSegmentKind::Type { .. } => unreachable!(), + // these aren't valid use paths, so fall back to something random + PathSegmentKind::SelfTypeKw => ImportGroup::ExternCrate, + PathSegmentKind::Type { .. } => ImportGroup::ExternCrate, } } } diff --git a/crates/ide_db/src/lib.rs b/crates/ide_db/src/lib.rs index 602eaf0de5..3f64c0a124 100644 --- a/crates/ide_db/src/lib.rs +++ b/crates/ide_db/src/lib.rs @@ -163,6 +163,7 @@ pub enum SymbolKind { Macro, Module, SelfParam, + SelfType, Static, Struct, ToolModule, diff --git a/crates/parser/src/grammar/paths.rs b/crates/parser/src/grammar/paths.rs index 0cc0ed31aa..b4a60574e5 100644 --- a/crates/parser/src/grammar/paths.rs +++ b/crates/parser/src/grammar/paths.rs @@ -1,10 +1,10 @@ use super::*; pub(super) const PATH_FIRST: TokenSet = - TokenSet::new(&[IDENT, T![self], T![super], T![crate], T![:], T![<]]); + TokenSet::new(&[IDENT, T![self], T![super], T![crate], T![Self], T![:], T![<]]); pub(super) fn is_path_start(p: &Parser) -> bool { - is_use_path_start(p) || p.at(T![<]) + is_use_path_start(p) || p.at(T![<]) || p.at(T![Self]) } pub(super) fn is_use_path_start(p: &Parser) -> bool { @@ -88,7 +88,7 @@ fn path_segment(p: &mut Parser, mode: Mode, first: bool) { } // test crate_path // use crate::foo; - T![self] | T![super] | T![crate] => { + T![self] | T![super] | T![crate] | T![Self] => { let m = p.start(); p.bump_any(); m.complete(p, NAME_REF); diff --git a/crates/parser/src/grammar/types.rs b/crates/parser/src/grammar/types.rs index 05c1aea5c4..ff067f5293 100644 --- a/crates/parser/src/grammar/types.rs +++ b/crates/parser/src/grammar/types.rs @@ -14,6 +14,7 @@ pub(super) const TYPE_FIRST: TokenSet = paths::PATH_FIRST.union(TokenSet::new(&[ T![for], T![impl], T![dyn], + T![Self], ])); const TYPE_RECOVERY_SET: TokenSet = TokenSet::new(&[ @@ -46,7 +47,7 @@ fn type_with_bounds_cond(p: &mut Parser, allow_bounds: bool) { T![dyn] => dyn_trait_type(p), // Some path types are not allowed to have bounds (no plus) T![<] => path_type_(p, allow_bounds), - _ if paths::is_use_path_start(p) => path_or_macro_type_(p, allow_bounds), + _ if paths::is_path_start(p) => path_or_macro_type_(p, allow_bounds), _ => { p.err_recover("expected type", TYPE_RECOVERY_SET); } diff --git a/crates/parser/src/syntax_kind/generated.rs b/crates/parser/src/syntax_kind/generated.rs index 4e8a0cfe80..297809976e 100644 --- a/crates/parser/src/syntax_kind/generated.rs +++ b/crates/parser/src/syntax_kind/generated.rs @@ -90,6 +90,7 @@ pub enum SyntaxKind { REF_KW, RETURN_KW, SELF_KW, + SELF_TYPE_KW, STATIC_KW, STRUCT_KW, SUPER_KW, @@ -264,10 +265,10 @@ impl SyntaxKind { AS_KW | ASYNC_KW | AWAIT_KW | BOX_KW | BREAK_KW | CONST_KW | CONTINUE_KW | CRATE_KW | DYN_KW | ELSE_KW | ENUM_KW | EXTERN_KW | FALSE_KW | FN_KW | FOR_KW | IF_KW | IMPL_KW | IN_KW | LET_KW | LOOP_KW | MACRO_KW | MATCH_KW | MOD_KW | MOVE_KW - | MUT_KW | PUB_KW | REF_KW | RETURN_KW | SELF_KW | STATIC_KW | STRUCT_KW | SUPER_KW - | TRAIT_KW | TRUE_KW | TRY_KW | TYPE_KW | UNSAFE_KW | USE_KW | WHERE_KW | WHILE_KW - | YIELD_KW | AUTO_KW | DEFAULT_KW | EXISTENTIAL_KW | UNION_KW | RAW_KW - | MACRO_RULES_KW => true, + | MUT_KW | PUB_KW | REF_KW | RETURN_KW | SELF_KW | SELF_TYPE_KW | STATIC_KW + | STRUCT_KW | SUPER_KW | TRAIT_KW | TRUE_KW | TRY_KW | TYPE_KW | UNSAFE_KW | USE_KW + | WHERE_KW | WHILE_KW | YIELD_KW | AUTO_KW | DEFAULT_KW | EXISTENTIAL_KW | UNION_KW + | RAW_KW | MACRO_RULES_KW => true, _ => false, } } @@ -319,6 +320,7 @@ impl SyntaxKind { "ref" => REF_KW, "return" => RETURN_KW, "self" => SELF_KW, + "Self" => SELF_TYPE_KW, "static" => STATIC_KW, "struct" => STRUCT_KW, "super" => SUPER_KW, @@ -383,5 +385,5 @@ impl SyntaxKind { } } #[macro_export] -macro_rules ! T { [;] => { $ crate :: SyntaxKind :: SEMICOLON } ; [,] => { $ crate :: SyntaxKind :: COMMA } ; ['('] => { $ crate :: SyntaxKind :: L_PAREN } ; [')'] => { $ crate :: SyntaxKind :: R_PAREN } ; ['{'] => { $ crate :: SyntaxKind :: L_CURLY } ; ['}'] => { $ crate :: SyntaxKind :: R_CURLY } ; ['['] => { $ crate :: SyntaxKind :: L_BRACK } ; [']'] => { $ crate :: SyntaxKind :: R_BRACK } ; [<] => { $ crate :: SyntaxKind :: L_ANGLE } ; [>] => { $ crate :: SyntaxKind :: R_ANGLE } ; [@] => { $ crate :: SyntaxKind :: AT } ; [#] => { $ crate :: SyntaxKind :: POUND } ; [~] => { $ crate :: SyntaxKind :: TILDE } ; [?] => { $ crate :: SyntaxKind :: QUESTION } ; [$] => { $ crate :: SyntaxKind :: DOLLAR } ; [&] => { $ crate :: SyntaxKind :: AMP } ; [|] => { $ crate :: SyntaxKind :: PIPE } ; [+] => { $ crate :: SyntaxKind :: PLUS } ; [*] => { $ crate :: SyntaxKind :: STAR } ; [/] => { $ crate :: SyntaxKind :: SLASH } ; [^] => { $ crate :: SyntaxKind :: CARET } ; [%] => { $ crate :: SyntaxKind :: PERCENT } ; [_] => { $ crate :: SyntaxKind :: UNDERSCORE } ; [.] => { $ crate :: SyntaxKind :: DOT } ; [..] => { $ crate :: SyntaxKind :: DOT2 } ; [...] => { $ crate :: SyntaxKind :: DOT3 } ; [..=] => { $ crate :: SyntaxKind :: DOT2EQ } ; [:] => { $ crate :: SyntaxKind :: COLON } ; [::] => { $ crate :: SyntaxKind :: COLON2 } ; [=] => { $ crate :: SyntaxKind :: EQ } ; [==] => { $ crate :: SyntaxKind :: EQ2 } ; [=>] => { $ crate :: SyntaxKind :: FAT_ARROW } ; [!] => { $ crate :: SyntaxKind :: BANG } ; [!=] => { $ crate :: SyntaxKind :: NEQ } ; [-] => { $ crate :: SyntaxKind :: MINUS } ; [->] => { $ crate :: SyntaxKind :: THIN_ARROW } ; [<=] => { $ crate :: SyntaxKind :: LTEQ } ; [>=] => { $ crate :: SyntaxKind :: GTEQ } ; [+=] => { $ crate :: SyntaxKind :: PLUSEQ } ; [-=] => { $ crate :: SyntaxKind :: MINUSEQ } ; [|=] => { $ crate :: SyntaxKind :: PIPEEQ } ; [&=] => { $ crate :: SyntaxKind :: AMPEQ } ; [^=] => { $ crate :: SyntaxKind :: CARETEQ } ; [/=] => { $ crate :: SyntaxKind :: SLASHEQ } ; [*=] => { $ crate :: SyntaxKind :: STAREQ } ; [%=] => { $ crate :: SyntaxKind :: PERCENTEQ } ; [&&] => { $ crate :: SyntaxKind :: AMP2 } ; [||] => { $ crate :: SyntaxKind :: PIPE2 } ; [<<] => { $ crate :: SyntaxKind :: SHL } ; [>>] => { $ crate :: SyntaxKind :: SHR } ; [<<=] => { $ crate :: SyntaxKind :: SHLEQ } ; [>>=] => { $ crate :: SyntaxKind :: SHREQ } ; [as] => { $ crate :: SyntaxKind :: AS_KW } ; [async] => { $ crate :: SyntaxKind :: ASYNC_KW } ; [await] => { $ crate :: SyntaxKind :: AWAIT_KW } ; [box] => { $ crate :: SyntaxKind :: BOX_KW } ; [break] => { $ crate :: SyntaxKind :: BREAK_KW } ; [const] => { $ crate :: SyntaxKind :: CONST_KW } ; [continue] => { $ crate :: SyntaxKind :: CONTINUE_KW } ; [crate] => { $ crate :: SyntaxKind :: CRATE_KW } ; [dyn] => { $ crate :: SyntaxKind :: DYN_KW } ; [else] => { $ crate :: SyntaxKind :: ELSE_KW } ; [enum] => { $ crate :: SyntaxKind :: ENUM_KW } ; [extern] => { $ crate :: SyntaxKind :: EXTERN_KW } ; [false] => { $ crate :: SyntaxKind :: FALSE_KW } ; [fn] => { $ crate :: SyntaxKind :: FN_KW } ; [for] => { $ crate :: SyntaxKind :: FOR_KW } ; [if] => { $ crate :: SyntaxKind :: IF_KW } ; [impl] => { $ crate :: SyntaxKind :: IMPL_KW } ; [in] => { $ crate :: SyntaxKind :: IN_KW } ; [let] => { $ crate :: SyntaxKind :: LET_KW } ; [loop] => { $ crate :: SyntaxKind :: LOOP_KW } ; [macro] => { $ crate :: SyntaxKind :: MACRO_KW } ; [match] => { $ crate :: SyntaxKind :: MATCH_KW } ; [mod] => { $ crate :: SyntaxKind :: MOD_KW } ; [move] => { $ crate :: SyntaxKind :: MOVE_KW } ; [mut] => { $ crate :: SyntaxKind :: MUT_KW } ; [pub] => { $ crate :: SyntaxKind :: PUB_KW } ; [ref] => { $ crate :: SyntaxKind :: REF_KW } ; [return] => { $ crate :: SyntaxKind :: RETURN_KW } ; [self] => { $ crate :: SyntaxKind :: SELF_KW } ; [static] => { $ crate :: SyntaxKind :: STATIC_KW } ; [struct] => { $ crate :: SyntaxKind :: STRUCT_KW } ; [super] => { $ crate :: SyntaxKind :: SUPER_KW } ; [trait] => { $ crate :: SyntaxKind :: TRAIT_KW } ; [true] => { $ crate :: SyntaxKind :: TRUE_KW } ; [try] => { $ crate :: SyntaxKind :: TRY_KW } ; [type] => { $ crate :: SyntaxKind :: TYPE_KW } ; [unsafe] => { $ crate :: SyntaxKind :: UNSAFE_KW } ; [use] => { $ crate :: SyntaxKind :: USE_KW } ; [where] => { $ crate :: SyntaxKind :: WHERE_KW } ; [while] => { $ crate :: SyntaxKind :: WHILE_KW } ; [yield] => { $ crate :: SyntaxKind :: YIELD_KW } ; [auto] => { $ crate :: SyntaxKind :: AUTO_KW } ; [default] => { $ crate :: SyntaxKind :: DEFAULT_KW } ; [existential] => { $ crate :: SyntaxKind :: EXISTENTIAL_KW } ; [union] => { $ crate :: SyntaxKind :: UNION_KW } ; [raw] => { $ crate :: SyntaxKind :: RAW_KW } ; [macro_rules] => { $ crate :: SyntaxKind :: MACRO_RULES_KW } ; [lifetime_ident] => { $ crate :: SyntaxKind :: LIFETIME_IDENT } ; [ident] => { $ crate :: SyntaxKind :: IDENT } ; [shebang] => { $ crate :: SyntaxKind :: SHEBANG } ; } +macro_rules ! T { [;] => { $ crate :: SyntaxKind :: SEMICOLON } ; [,] => { $ crate :: SyntaxKind :: COMMA } ; ['('] => { $ crate :: SyntaxKind :: L_PAREN } ; [')'] => { $ crate :: SyntaxKind :: R_PAREN } ; ['{'] => { $ crate :: SyntaxKind :: L_CURLY } ; ['}'] => { $ crate :: SyntaxKind :: R_CURLY } ; ['['] => { $ crate :: SyntaxKind :: L_BRACK } ; [']'] => { $ crate :: SyntaxKind :: R_BRACK } ; [<] => { $ crate :: SyntaxKind :: L_ANGLE } ; [>] => { $ crate :: SyntaxKind :: R_ANGLE } ; [@] => { $ crate :: SyntaxKind :: AT } ; [#] => { $ crate :: SyntaxKind :: POUND } ; [~] => { $ crate :: SyntaxKind :: TILDE } ; [?] => { $ crate :: SyntaxKind :: QUESTION } ; [$] => { $ crate :: SyntaxKind :: DOLLAR } ; [&] => { $ crate :: SyntaxKind :: AMP } ; [|] => { $ crate :: SyntaxKind :: PIPE } ; [+] => { $ crate :: SyntaxKind :: PLUS } ; [*] => { $ crate :: SyntaxKind :: STAR } ; [/] => { $ crate :: SyntaxKind :: SLASH } ; [^] => { $ crate :: SyntaxKind :: CARET } ; [%] => { $ crate :: SyntaxKind :: PERCENT } ; [_] => { $ crate :: SyntaxKind :: UNDERSCORE } ; [.] => { $ crate :: SyntaxKind :: DOT } ; [..] => { $ crate :: SyntaxKind :: DOT2 } ; [...] => { $ crate :: SyntaxKind :: DOT3 } ; [..=] => { $ crate :: SyntaxKind :: DOT2EQ } ; [:] => { $ crate :: SyntaxKind :: COLON } ; [::] => { $ crate :: SyntaxKind :: COLON2 } ; [=] => { $ crate :: SyntaxKind :: EQ } ; [==] => { $ crate :: SyntaxKind :: EQ2 } ; [=>] => { $ crate :: SyntaxKind :: FAT_ARROW } ; [!] => { $ crate :: SyntaxKind :: BANG } ; [!=] => { $ crate :: SyntaxKind :: NEQ } ; [-] => { $ crate :: SyntaxKind :: MINUS } ; [->] => { $ crate :: SyntaxKind :: THIN_ARROW } ; [<=] => { $ crate :: SyntaxKind :: LTEQ } ; [>=] => { $ crate :: SyntaxKind :: GTEQ } ; [+=] => { $ crate :: SyntaxKind :: PLUSEQ } ; [-=] => { $ crate :: SyntaxKind :: MINUSEQ } ; [|=] => { $ crate :: SyntaxKind :: PIPEEQ } ; [&=] => { $ crate :: SyntaxKind :: AMPEQ } ; [^=] => { $ crate :: SyntaxKind :: CARETEQ } ; [/=] => { $ crate :: SyntaxKind :: SLASHEQ } ; [*=] => { $ crate :: SyntaxKind :: STAREQ } ; [%=] => { $ crate :: SyntaxKind :: PERCENTEQ } ; [&&] => { $ crate :: SyntaxKind :: AMP2 } ; [||] => { $ crate :: SyntaxKind :: PIPE2 } ; [<<] => { $ crate :: SyntaxKind :: SHL } ; [>>] => { $ crate :: SyntaxKind :: SHR } ; [<<=] => { $ crate :: SyntaxKind :: SHLEQ } ; [>>=] => { $ crate :: SyntaxKind :: SHREQ } ; [as] => { $ crate :: SyntaxKind :: AS_KW } ; [async] => { $ crate :: SyntaxKind :: ASYNC_KW } ; [await] => { $ crate :: SyntaxKind :: AWAIT_KW } ; [box] => { $ crate :: SyntaxKind :: BOX_KW } ; [break] => { $ crate :: SyntaxKind :: BREAK_KW } ; [const] => { $ crate :: SyntaxKind :: CONST_KW } ; [continue] => { $ crate :: SyntaxKind :: CONTINUE_KW } ; [crate] => { $ crate :: SyntaxKind :: CRATE_KW } ; [dyn] => { $ crate :: SyntaxKind :: DYN_KW } ; [else] => { $ crate :: SyntaxKind :: ELSE_KW } ; [enum] => { $ crate :: SyntaxKind :: ENUM_KW } ; [extern] => { $ crate :: SyntaxKind :: EXTERN_KW } ; [false] => { $ crate :: SyntaxKind :: FALSE_KW } ; [fn] => { $ crate :: SyntaxKind :: FN_KW } ; [for] => { $ crate :: SyntaxKind :: FOR_KW } ; [if] => { $ crate :: SyntaxKind :: IF_KW } ; [impl] => { $ crate :: SyntaxKind :: IMPL_KW } ; [in] => { $ crate :: SyntaxKind :: IN_KW } ; [let] => { $ crate :: SyntaxKind :: LET_KW } ; [loop] => { $ crate :: SyntaxKind :: LOOP_KW } ; [macro] => { $ crate :: SyntaxKind :: MACRO_KW } ; [match] => { $ crate :: SyntaxKind :: MATCH_KW } ; [mod] => { $ crate :: SyntaxKind :: MOD_KW } ; [move] => { $ crate :: SyntaxKind :: MOVE_KW } ; [mut] => { $ crate :: SyntaxKind :: MUT_KW } ; [pub] => { $ crate :: SyntaxKind :: PUB_KW } ; [ref] => { $ crate :: SyntaxKind :: REF_KW } ; [return] => { $ crate :: SyntaxKind :: RETURN_KW } ; [self] => { $ crate :: SyntaxKind :: SELF_KW } ; [Self] => { $ crate :: SyntaxKind :: SELF_TYPE_KW } ; [static] => { $ crate :: SyntaxKind :: STATIC_KW } ; [struct] => { $ crate :: SyntaxKind :: STRUCT_KW } ; [super] => { $ crate :: SyntaxKind :: SUPER_KW } ; [trait] => { $ crate :: SyntaxKind :: TRAIT_KW } ; [true] => { $ crate :: SyntaxKind :: TRUE_KW } ; [try] => { $ crate :: SyntaxKind :: TRY_KW } ; [type] => { $ crate :: SyntaxKind :: TYPE_KW } ; [unsafe] => { $ crate :: SyntaxKind :: UNSAFE_KW } ; [use] => { $ crate :: SyntaxKind :: USE_KW } ; [where] => { $ crate :: SyntaxKind :: WHERE_KW } ; [while] => { $ crate :: SyntaxKind :: WHILE_KW } ; [yield] => { $ crate :: SyntaxKind :: YIELD_KW } ; [auto] => { $ crate :: SyntaxKind :: AUTO_KW } ; [default] => { $ crate :: SyntaxKind :: DEFAULT_KW } ; [existential] => { $ crate :: SyntaxKind :: EXISTENTIAL_KW } ; [union] => { $ crate :: SyntaxKind :: UNION_KW } ; [raw] => { $ crate :: SyntaxKind :: RAW_KW } ; [macro_rules] => { $ crate :: SyntaxKind :: MACRO_RULES_KW } ; [lifetime_ident] => { $ crate :: SyntaxKind :: LIFETIME_IDENT } ; [ident] => { $ crate :: SyntaxKind :: IDENT } ; [shebang] => { $ crate :: SyntaxKind :: SHEBANG } ; } pub use T; diff --git a/crates/parser/test_data/parser/inline/ok/0018_arb_self_types.txt b/crates/parser/test_data/parser/inline/ok/0018_arb_self_types.txt index d542e0edc7..a0b5626296 100644 --- a/crates/parser/test_data/parser/inline/ok/0018_arb_self_types.txt +++ b/crates/parser/test_data/parser/inline/ok/0018_arb_self_types.txt @@ -29,7 +29,7 @@ SOURCE_FILE PATH PATH_SEGMENT NAME_REF - IDENT "Self" + SELF_TYPE_KW "Self" R_PAREN ")" WHITESPACE " " BLOCK_EXPR @@ -63,7 +63,7 @@ SOURCE_FILE PATH PATH_SEGMENT NAME_REF - IDENT "Self" + SELF_TYPE_KW "Self" R_ANGLE ">" R_PAREN ")" WHITESPACE " " diff --git a/crates/parser/test_data/parser/inline/ok/0041_trait_item.txt b/crates/parser/test_data/parser/inline/ok/0041_trait_item.txt index 86d92406d8..dd7f76eb93 100644 --- a/crates/parser/test_data/parser/inline/ok/0041_trait_item.txt +++ b/crates/parser/test_data/parser/inline/ok/0041_trait_item.txt @@ -24,7 +24,7 @@ SOURCE_FILE PATH PATH_SEGMENT NAME_REF - IDENT "Self" + SELF_TYPE_KW "Self" SEMICOLON ";" WHITESPACE " " R_CURLY "}" diff --git a/crates/parser/test_data/parser/inline/ok/0176_trait_item_where_clause.txt b/crates/parser/test_data/parser/inline/ok/0176_trait_item_where_clause.txt index ab42d81f9b..46cd8ee665 100644 --- a/crates/parser/test_data/parser/inline/ok/0176_trait_item_where_clause.txt +++ b/crates/parser/test_data/parser/inline/ok/0176_trait_item_where_clause.txt @@ -13,7 +13,7 @@ SOURCE_FILE PATH PATH_SEGMENT NAME_REF - IDENT "Self" + SELF_TYPE_KW "Self" COLON ":" WHITESPACE " " TYPE_BOUND_LIST diff --git a/crates/parser/test_data/parser/inline/ok/0177_trait_alias_where_clause.txt b/crates/parser/test_data/parser/inline/ok/0177_trait_alias_where_clause.txt index 88b1f8c29e..4443d9d142 100644 --- a/crates/parser/test_data/parser/inline/ok/0177_trait_alias_where_clause.txt +++ b/crates/parser/test_data/parser/inline/ok/0177_trait_alias_where_clause.txt @@ -73,7 +73,7 @@ SOURCE_FILE PATH PATH_SEGMENT NAME_REF - IDENT "Self" + SELF_TYPE_KW "Self" COLON ":" WHITESPACE " " TYPE_BOUND_LIST diff --git a/crates/parser/test_data/parser/ok/0045_block_attrs.txt b/crates/parser/test_data/parser/ok/0045_block_attrs.txt index 6b6f3bfe3e..9684bb11cd 100644 --- a/crates/parser/test_data/parser/ok/0045_block_attrs.txt +++ b/crates/parser/test_data/parser/ok/0045_block_attrs.txt @@ -199,7 +199,7 @@ SOURCE_FILE PATH PATH_SEGMENT NAME_REF - IDENT "Self" + SELF_TYPE_KW "Self" R_ANGLE ">" R_PAREN ")" WHITESPACE " " diff --git a/crates/parser/test_data/parser/ok/0051_parameter_attrs.txt b/crates/parser/test_data/parser/ok/0051_parameter_attrs.txt index e1ebf5a38c..f8b11e7782 100644 --- a/crates/parser/test_data/parser/ok/0051_parameter_attrs.txt +++ b/crates/parser/test_data/parser/ok/0051_parameter_attrs.txt @@ -494,7 +494,7 @@ SOURCE_FILE PATH PATH_SEGMENT NAME_REF - IDENT "Self" + SELF_TYPE_KW "Self" R_PAREN ")" WHITESPACE " " BLOCK_EXPR @@ -536,7 +536,7 @@ SOURCE_FILE PATH PATH_SEGMENT NAME_REF - IDENT "Self" + SELF_TYPE_KW "Self" R_ANGLE ">" R_PAREN ")" WHITESPACE " " diff --git a/crates/rust-analyzer/src/semantic_tokens.rs b/crates/rust-analyzer/src/semantic_tokens.rs index c6322327a5..5fb945ea98 100644 --- a/crates/rust-analyzer/src/semantic_tokens.rs +++ b/crates/rust-analyzer/src/semantic_tokens.rs @@ -66,6 +66,7 @@ define_semantic_token_types![ (PARENTHESIS, "parenthesis"), (PUNCTUATION, "punctuation"), (SELF_KEYWORD, "selfKeyword"), + (SELF_TYPE_KEYWORD, "selfTypeKeyword"), (SEMICOLON, "semicolon"), (TYPE_ALIAS, "typeAlias"), (TOOL_MODULE, "toolModule"), diff --git a/crates/rust-analyzer/src/to_proto.rs b/crates/rust-analyzer/src/to_proto.rs index f0de166d8b..4a2b3a1b47 100644 --- a/crates/rust-analyzer/src/to_proto.rs +++ b/crates/rust-analyzer/src/to_proto.rs @@ -55,7 +55,9 @@ pub(crate) fn symbol_kind(symbol_kind: SymbolKind) -> lsp_types::SymbolKind { | SymbolKind::Attribute | SymbolKind::Derive => lsp_types::SymbolKind::FUNCTION, SymbolKind::Module | SymbolKind::ToolModule => lsp_types::SymbolKind::MODULE, - SymbolKind::TypeAlias | SymbolKind::TypeParam => lsp_types::SymbolKind::TYPE_PARAMETER, + SymbolKind::TypeAlias | SymbolKind::TypeParam | SymbolKind::SelfType => { + lsp_types::SymbolKind::TYPE_PARAMETER + } SymbolKind::Field => lsp_types::SymbolKind::FIELD, SymbolKind::Static => lsp_types::SymbolKind::CONSTANT, SymbolKind::Const => lsp_types::SymbolKind::CONSTANT, @@ -124,6 +126,7 @@ pub(crate) fn completion_item_kind( SymbolKind::Macro => lsp_types::CompletionItemKind::FUNCTION, SymbolKind::Module => lsp_types::CompletionItemKind::MODULE, SymbolKind::SelfParam => lsp_types::CompletionItemKind::VALUE, + SymbolKind::SelfType => lsp_types::CompletionItemKind::TYPE_PARAMETER, SymbolKind::Static => lsp_types::CompletionItemKind::VALUE, SymbolKind::Struct => lsp_types::CompletionItemKind::STRUCT, SymbolKind::Trait => lsp_types::CompletionItemKind::INTERFACE, @@ -483,6 +486,7 @@ fn semantic_token_type_and_modifiers( SymbolKind::Label => semantic_tokens::LABEL, SymbolKind::ValueParam => lsp_types::SemanticTokenType::PARAMETER, SymbolKind::SelfParam => semantic_tokens::SELF_KEYWORD, + SymbolKind::SelfType => semantic_tokens::SELF_TYPE_KEYWORD, SymbolKind::Local => lsp_types::SemanticTokenType::VARIABLE, SymbolKind::Function => { if highlight.mods.contains(HlMod::Associated) { diff --git a/crates/syntax/Cargo.toml b/crates/syntax/Cargo.toml index 8baea77075..d8f8290745 100644 --- a/crates/syntax/Cargo.toml +++ b/crates/syntax/Cargo.toml @@ -30,7 +30,7 @@ rayon = "1" expect-test = "1.2.0-pre.1" proc-macro2 = "1.0.8" quote = "1.0.2" -ungrammar = "=1.16.0" +ungrammar = "=1.16.1" test_utils = { path = "../test_utils" } sourcegen = { path = "../sourcegen" } diff --git a/crates/syntax/src/ast/generated/nodes.rs b/crates/syntax/src/ast/generated/nodes.rs index fc1ee6f601..6f236c01ce 100644 --- a/crates/syntax/src/ast/generated/nodes.rs +++ b/crates/syntax/src/ast/generated/nodes.rs @@ -1,5 +1,6 @@ //! Generated by `sourcegen_ast`, do not edit by hand. +#![allow(non_snake_case)] use crate::{ ast::{self, support, AstChildren, AstNode}, SyntaxKind::{self, *}, @@ -24,6 +25,7 @@ impl NameRef { pub fn self_token(&self) -> Option { support::token(&self.syntax, T![self]) } pub fn super_token(&self) -> Option { support::token(&self.syntax, T![super]) } pub fn crate_token(&self) -> Option { support::token(&self.syntax, T![crate]) } + pub fn Self_token(&self) -> Option { support::token(&self.syntax, T![Self]) } } #[derive(Debug, Clone, PartialEq, Eq, Hash)] diff --git a/crates/syntax/src/ast/make.rs b/crates/syntax/src/ast/make.rs index 1a754ef460..19a007e072 100644 --- a/crates/syntax/src/ast/make.rs +++ b/crates/syntax/src/ast/make.rs @@ -185,7 +185,7 @@ pub(crate) fn generic_arg_list() -> ast::GenericArgList { } pub fn path_segment(name_ref: ast::NameRef) -> ast::PathSegment { - ast_from_text(&format!("use {};", name_ref)) + ast_from_text(&format!("type __ = {};", name_ref)) } pub fn path_segment_ty(type_ref: ast::Type, trait_ref: Option) -> ast::PathSegment { @@ -209,7 +209,7 @@ pub fn path_segment_crate() -> ast::PathSegment { } pub fn path_unqualified(segment: ast::PathSegment) -> ast::Path { - ast_from_text(&format!("use {}", segment)) + ast_from_text(&format!("type __ = {};", segment)) } pub fn path_qualified(qual: ast::Path, segment: ast::PathSegment) -> ast::Path { @@ -217,7 +217,7 @@ pub fn path_qualified(qual: ast::Path, segment: ast::PathSegment) -> ast::Path { } // FIXME: path concatenation operation doesn't make sense as AST op. pub fn path_concat(first: ast::Path, second: ast::Path) -> ast::Path { - ast_from_text(&format!("{}::{}", first, second)) + ast_from_text(&format!("type __ = {}::{};", first, second)) } pub fn path_from_segments( @@ -234,7 +234,7 @@ pub fn path_from_segments( pub fn join_paths(paths: impl IntoIterator) -> ast::Path { let paths = paths.into_iter().map(|it| it.syntax().clone()).join("::"); - ast_from_text(&format!("use {};", paths)) + ast_from_text(&format!("type __ = {};", paths)) } // FIXME: should not be pub @@ -782,6 +782,7 @@ pub fn struct_( )) } +#[track_caller] fn ast_from_text(text: &str) -> N { let parse = SourceFile::parse(text); let node = match parse.tree().syntax().descendants().find_map(N::cast) { diff --git a/crates/syntax/src/ast/node_ext.rs b/crates/syntax/src/ast/node_ext.rs index 229c71c76b..333ee35d63 100644 --- a/crates/syntax/src/ast/node_ext.rs +++ b/crates/syntax/src/ast/node_ext.rs @@ -34,6 +34,10 @@ impl ast::NameRef { pub fn as_tuple_field(&self) -> Option { self.text().parse().ok() } + + pub fn token_kind(&self) -> SyntaxKind { + self.syntax().first_token().map_or(SyntaxKind::ERROR, |it| it.kind()) + } } fn text_of_first_token(node: &SyntaxNode) -> TokenText<'_> { @@ -183,6 +187,7 @@ impl ast::Attr { pub enum PathSegmentKind { Name(ast::NameRef), Type { type_ref: Option, trait_ref: Option }, + SelfTypeKw, SelfKw, SuperKw, CrateKw, @@ -204,16 +209,21 @@ impl ast::PathSegment { self.name_ref().and_then(|it| it.self_token()) } + pub fn self_type_token(&self) -> Option { + self.name_ref().and_then(|it| it.Self_token()) + } + pub fn super_token(&self) -> Option { self.name_ref().and_then(|it| it.super_token()) } pub fn kind(&self) -> Option { let res = if let Some(name_ref) = self.name_ref() { - match name_ref.syntax().first_token().map(|it| it.kind()) { - Some(T![self]) => PathSegmentKind::SelfKw, - Some(T![super]) => PathSegmentKind::SuperKw, - Some(T![crate]) => PathSegmentKind::CrateKw, + match name_ref.token_kind() { + T![Self] => PathSegmentKind::SelfTypeKw, + T![self] => PathSegmentKind::SelfKw, + T![super] => PathSegmentKind::SuperKw, + T![crate] => PathSegmentKind::CrateKw, _ => PathSegmentKind::Name(name_ref), } } else { diff --git a/crates/syntax/src/tests/ast_src.rs b/crates/syntax/src/tests/ast_src.rs index 3152137fb8..e808cb4be4 100644 --- a/crates/syntax/src/tests/ast_src.rs +++ b/crates/syntax/src/tests/ast_src.rs @@ -67,8 +67,8 @@ pub(crate) const KINDS_SRC: KindsSrc = KindsSrc { keywords: &[ "as", "async", "await", "box", "break", "const", "continue", "crate", "dyn", "else", "enum", "extern", "false", "fn", "for", "if", "impl", "in", "let", "loop", "macro", - "match", "mod", "move", "mut", "pub", "ref", "return", "self", "static", "struct", "super", - "trait", "true", "try", "type", "unsafe", "use", "where", "while", "yield", + "match", "mod", "move", "mut", "pub", "ref", "return", "self", "Self", "static", "struct", + "super", "trait", "true", "try", "type", "unsafe", "use", "where", "while", "yield", ], contextual_keywords: &["auto", "default", "existential", "union", "raw", "macro_rules"], literals: &["INT_NUMBER", "FLOAT_NUMBER", "CHAR", "BYTE", "STRING", "BYTE_STRING"], diff --git a/crates/syntax/src/tests/sourcegen_ast.rs b/crates/syntax/src/tests/sourcegen_ast.rs index 5ed56a81c4..cb38abfe89 100644 --- a/crates/syntax/src/tests/sourcegen_ast.rs +++ b/crates/syntax/src/tests/sourcegen_ast.rs @@ -297,6 +297,7 @@ fn generate_nodes(kinds: KindsSrc<'_>, grammar: &AstSrc) -> String { } let ast = quote! { + #![allow(non_snake_case)] use crate::{ SyntaxNode, SyntaxToken, SyntaxKind::{self, *}, ast::{self, AstNode, AstChildren, support}, @@ -356,21 +357,24 @@ fn generate_syntax_kinds(grammar: KindsSrc<'_>) -> String { let punctuation = grammar.punct.iter().map(|(_token, name)| format_ident!("{}", name)).collect::>(); - let full_keywords_values = &grammar.keywords; - let full_keywords = - full_keywords_values.iter().map(|kw| format_ident!("{}_KW", to_upper_snake_case(kw))); + let x = |&name| match name { + "Self" => format_ident!("SELF_TYPE_KW"), + name => format_ident!("{}_KW", to_upper_snake_case(name)), + }; + let full_keywords_values = grammar.keywords; + let full_keywords = full_keywords_values.iter().map(x); let contextual_keywords_values = &grammar.contextual_keywords; - let contextual_keywords = - contextual_keywords_values.iter().map(|kw| format_ident!("{}_KW", to_upper_snake_case(kw))); + let contextual_keywords = contextual_keywords_values.iter().map(x); - let all_keywords_values = - grammar.keywords.iter().chain(grammar.contextual_keywords.iter()).collect::>(); - let all_keywords_idents = all_keywords_values.iter().map(|kw| format_ident!("{}", kw)); - let all_keywords = all_keywords_values + let all_keywords_values = grammar + .keywords .iter() - .map(|name| format_ident!("{}_KW", to_upper_snake_case(name))) + .chain(grammar.contextual_keywords.iter()) + .copied() .collect::>(); + let all_keywords_idents = all_keywords_values.iter().map(|kw| format_ident!("{}", kw)); + let all_keywords = all_keywords_values.iter().map(x).collect::>(); let literals = grammar.literals.iter().map(|name| format_ident!("{}", name)).collect::>(); diff --git a/editors/code/package.json b/editors/code/package.json index 1252752a9a..4843ea8421 100644 --- a/editors/code/package.json +++ b/editors/code/package.json @@ -1294,6 +1294,11 @@ "description": "Style for the self keyword", "superType": "keyword" }, + { + "id": "selfTypeKeyword", + "description": "Style for the self type keyword", + "superType": "keyword" + }, { "id": "semicolon", "description": "Style for ;",