diff options
author | nmio <[email protected]> | 2020-02-25 18:01:59 +0000 |
---|---|---|
committer | nmio <[email protected]> | 2020-02-25 18:01:59 +0000 |
commit | 39bd3b2bd719289a8dd03fb52d5060cdb10f9169 (patch) | |
tree | 4b627f15fcbb454aa09845ba8b456823cbc791b8 /crates | |
parent | 34e3ef61bd25c635721066c1f881d7f041366a0a (diff) | |
parent | d3040c0deba8266044029a6479a1c12c28e72750 (diff) |
Merge branch 'master' of https://github.com/rust-analyzer/rust-analyzer into find-cargo-toml-up-the-fs
Diffstat (limited to 'crates')
-rw-r--r-- | crates/ra_assists/src/ast_transform.rs | 25 | ||||
-rw-r--r-- | crates/ra_fmt/src/lib.rs | 36 | ||||
-rw-r--r-- | crates/ra_hir_ty/Cargo.toml | 6 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/traits.rs | 14 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/traits/chalk.rs | 107 | ||||
-rw-r--r-- | crates/ra_ide/src/call_hierarchy.rs | 20 | ||||
-rw-r--r-- | crates/ra_ide/src/display/navigation_target.rs | 2 | ||||
-rw-r--r-- | crates/ra_ide/src/extend_selection.rs | 24 | ||||
-rw-r--r-- | crates/ra_ide/src/join_lines.rs | 25 | ||||
-rw-r--r-- | crates/ra_ide/src/lib.rs | 2 | ||||
-rw-r--r-- | crates/ra_ide/src/syntax_highlighting.rs | 52 | ||||
-rw-r--r-- | crates/ra_syntax/Cargo.toml | 2 | ||||
-rw-r--r-- | crates/rust-analyzer/src/caps.rs | 24 | ||||
-rw-r--r-- | crates/rust-analyzer/src/conv.rs | 79 | ||||
-rw-r--r-- | crates/rust-analyzer/src/lib.rs | 1 | ||||
-rw-r--r-- | crates/rust-analyzer/src/main_loop.rs | 1 | ||||
-rw-r--r-- | crates/rust-analyzer/src/main_loop/handlers.rs | 28 | ||||
-rw-r--r-- | crates/rust-analyzer/src/req.rs | 6 | ||||
-rw-r--r-- | crates/rust-analyzer/src/semantic_tokens.rs | 94 |
19 files changed, 402 insertions, 146 deletions
diff --git a/crates/ra_assists/src/ast_transform.rs b/crates/ra_assists/src/ast_transform.rs index 56b7588ef..c6d15af5f 100644 --- a/crates/ra_assists/src/ast_transform.rs +++ b/crates/ra_assists/src/ast_transform.rs | |||
@@ -1,7 +1,8 @@ | |||
1 | //! `AstTransformer`s are functions that replace nodes in an AST and can be easily combined. | 1 | //! `AstTransformer`s are functions that replace nodes in an AST and can be easily combined. |
2 | use rustc_hash::FxHashMap; | 2 | use rustc_hash::FxHashMap; |
3 | 3 | ||
4 | use hir::{db::HirDatabase, InFile, PathResolution}; | 4 | use hir::{InFile, PathResolution}; |
5 | use ra_ide_db::RootDatabase; | ||
5 | use ra_syntax::ast::{self, AstNode}; | 6 | use ra_syntax::ast::{self, AstNode}; |
6 | 7 | ||
7 | pub trait AstTransform<'a> { | 8 | pub trait AstTransform<'a> { |
@@ -33,18 +34,18 @@ impl<'a> AstTransform<'a> for NullTransformer { | |||
33 | } | 34 | } |
34 | } | 35 | } |
35 | 36 | ||
36 | pub struct SubstituteTypeParams<'a, DB: HirDatabase> { | 37 | pub struct SubstituteTypeParams<'a> { |
37 | db: &'a DB, | 38 | db: &'a RootDatabase, |
38 | substs: FxHashMap<hir::TypeParam, ast::TypeRef>, | 39 | substs: FxHashMap<hir::TypeParam, ast::TypeRef>, |
39 | previous: Box<dyn AstTransform<'a> + 'a>, | 40 | previous: Box<dyn AstTransform<'a> + 'a>, |
40 | } | 41 | } |
41 | 42 | ||
42 | impl<'a, DB: HirDatabase> SubstituteTypeParams<'a, DB> { | 43 | impl<'a> SubstituteTypeParams<'a> { |
43 | pub fn for_trait_impl( | 44 | pub fn for_trait_impl( |
44 | db: &'a DB, | 45 | db: &'a RootDatabase, |
45 | trait_: hir::Trait, | 46 | trait_: hir::Trait, |
46 | impl_block: ast::ImplBlock, | 47 | impl_block: ast::ImplBlock, |
47 | ) -> SubstituteTypeParams<'a, DB> { | 48 | ) -> SubstituteTypeParams<'a> { |
48 | let substs = get_syntactic_substs(impl_block).unwrap_or_default(); | 49 | let substs = get_syntactic_substs(impl_block).unwrap_or_default(); |
49 | let generic_def: hir::GenericDef = trait_.into(); | 50 | let generic_def: hir::GenericDef = trait_.into(); |
50 | let substs_by_param: FxHashMap<_, _> = generic_def | 51 | let substs_by_param: FxHashMap<_, _> = generic_def |
@@ -95,7 +96,7 @@ impl<'a, DB: HirDatabase> SubstituteTypeParams<'a, DB> { | |||
95 | } | 96 | } |
96 | } | 97 | } |
97 | 98 | ||
98 | impl<'a, DB: HirDatabase> AstTransform<'a> for SubstituteTypeParams<'a, DB> { | 99 | impl<'a> AstTransform<'a> for SubstituteTypeParams<'a> { |
99 | fn get_substitution( | 100 | fn get_substitution( |
100 | &self, | 101 | &self, |
101 | node: InFile<&ra_syntax::SyntaxNode>, | 102 | node: InFile<&ra_syntax::SyntaxNode>, |
@@ -107,14 +108,14 @@ impl<'a, DB: HirDatabase> AstTransform<'a> for SubstituteTypeParams<'a, DB> { | |||
107 | } | 108 | } |
108 | } | 109 | } |
109 | 110 | ||
110 | pub struct QualifyPaths<'a, DB: HirDatabase> { | 111 | pub struct QualifyPaths<'a> { |
111 | db: &'a DB, | 112 | db: &'a RootDatabase, |
112 | from: Option<hir::Module>, | 113 | from: Option<hir::Module>, |
113 | previous: Box<dyn AstTransform<'a> + 'a>, | 114 | previous: Box<dyn AstTransform<'a> + 'a>, |
114 | } | 115 | } |
115 | 116 | ||
116 | impl<'a, DB: HirDatabase> QualifyPaths<'a, DB> { | 117 | impl<'a> QualifyPaths<'a> { |
117 | pub fn new(db: &'a DB, from: Option<hir::Module>) -> Self { | 118 | pub fn new(db: &'a RootDatabase, from: Option<hir::Module>) -> Self { |
118 | Self { db, from, previous: Box::new(NullTransformer) } | 119 | Self { db, from, previous: Box::new(NullTransformer) } |
119 | } | 120 | } |
120 | 121 | ||
@@ -168,7 +169,7 @@ pub fn apply<'a, N: AstNode>(transformer: &dyn AstTransform<'a>, node: InFile<N> | |||
168 | N::cast(result).unwrap() | 169 | N::cast(result).unwrap() |
169 | } | 170 | } |
170 | 171 | ||
171 | impl<'a, DB: HirDatabase> AstTransform<'a> for QualifyPaths<'a, DB> { | 172 | impl<'a> AstTransform<'a> for QualifyPaths<'a> { |
172 | fn get_substitution( | 173 | fn get_substitution( |
173 | &self, | 174 | &self, |
174 | node: InFile<&ra_syntax::SyntaxNode>, | 175 | node: InFile<&ra_syntax::SyntaxNode>, |
diff --git a/crates/ra_fmt/src/lib.rs b/crates/ra_fmt/src/lib.rs index 4bca27b5c..db27f9b83 100644 --- a/crates/ra_fmt/src/lib.rs +++ b/crates/ra_fmt/src/lib.rs | |||
@@ -43,15 +43,35 @@ pub fn unwrap_trivial_block(block: ast::BlockExpr) -> ast::Expr { | |||
43 | 43 | ||
44 | pub fn extract_trivial_expression(block: &ast::BlockExpr) -> Option<ast::Expr> { | 44 | pub fn extract_trivial_expression(block: &ast::BlockExpr) -> Option<ast::Expr> { |
45 | let block = block.block()?; | 45 | let block = block.block()?; |
46 | let expr = block.expr()?; | 46 | let has_anything_else = |thing: &SyntaxNode| -> bool { |
47 | let non_trivial_children = block.syntax().children().filter(|it| match it.kind() { | 47 | let mut non_trivial_children = |
48 | WHITESPACE | T!['{'] | T!['}'] => false, | 48 | block.syntax().children_with_tokens().filter(|it| match it.kind() { |
49 | _ => it != expr.syntax(), | 49 | WHITESPACE | T!['{'] | T!['}'] => false, |
50 | }); | 50 | _ => it.as_node() != Some(thing), |
51 | if non_trivial_children.count() > 0 { | 51 | }); |
52 | return None; | 52 | non_trivial_children.next().is_some() |
53 | }; | ||
54 | |||
55 | if let Some(expr) = block.expr() { | ||
56 | if has_anything_else(expr.syntax()) { | ||
57 | return None; | ||
58 | } | ||
59 | return Some(expr); | ||
60 | } else { | ||
61 | // Unwrap `{ continue; }` | ||
62 | let (stmt,) = block.statements().next_tuple()?; | ||
63 | if has_anything_else(stmt.syntax()) { | ||
64 | return None; | ||
65 | } | ||
66 | if let ast::Stmt::ExprStmt(expr_stmt) = stmt { | ||
67 | let expr = expr_stmt.expr()?; | ||
68 | match expr.syntax().kind() { | ||
69 | CONTINUE_EXPR | BREAK_EXPR | RETURN_EXPR => return Some(expr), | ||
70 | _ => (), | ||
71 | } | ||
72 | } | ||
53 | } | 73 | } |
54 | Some(expr) | 74 | None |
55 | } | 75 | } |
56 | 76 | ||
57 | pub fn compute_ws(left: SyntaxKind, right: SyntaxKind) -> &'static str { | 77 | pub fn compute_ws(left: SyntaxKind, right: SyntaxKind) -> &'static str { |
diff --git a/crates/ra_hir_ty/Cargo.toml b/crates/ra_hir_ty/Cargo.toml index 49cafc539..99e2fe1bf 100644 --- a/crates/ra_hir_ty/Cargo.toml +++ b/crates/ra_hir_ty/Cargo.toml | |||
@@ -21,9 +21,9 @@ ra_prof = { path = "../ra_prof" } | |||
21 | ra_syntax = { path = "../ra_syntax" } | 21 | ra_syntax = { path = "../ra_syntax" } |
22 | test_utils = { path = "../test_utils" } | 22 | test_utils = { path = "../test_utils" } |
23 | 23 | ||
24 | chalk-solve = { git = "https://github.com/rust-lang/chalk.git", rev = "af48f302a1f571b3ca418f7c5aa639a144a34f75" } | 24 | chalk-solve = { git = "https://github.com/rust-lang/chalk.git", rev = "2939913fb7bb94ac2a6721087dc086be11410702" } |
25 | chalk-rust-ir = { git = "https://github.com/rust-lang/chalk.git", rev = "af48f302a1f571b3ca418f7c5aa639a144a34f75" } | 25 | chalk-rust-ir = { git = "https://github.com/rust-lang/chalk.git", rev = "2939913fb7bb94ac2a6721087dc086be11410702" } |
26 | chalk-ir = { git = "https://github.com/rust-lang/chalk.git", rev = "af48f302a1f571b3ca418f7c5aa639a144a34f75" } | 26 | chalk-ir = { git = "https://github.com/rust-lang/chalk.git", rev = "2939913fb7bb94ac2a6721087dc086be11410702" } |
27 | 27 | ||
28 | lalrpop-intern = "0.15.1" | 28 | lalrpop-intern = "0.15.1" |
29 | 29 | ||
diff --git a/crates/ra_hir_ty/src/traits.rs b/crates/ra_hir_ty/src/traits.rs index 2317fcac3..17aef9490 100644 --- a/crates/ra_hir_ty/src/traits.rs +++ b/crates/ra_hir_ty/src/traits.rs | |||
@@ -14,7 +14,7 @@ use crate::db::HirDatabase; | |||
14 | 14 | ||
15 | use super::{Canonical, GenericPredicate, HirDisplay, ProjectionTy, TraitRef, Ty, TypeWalk}; | 15 | use super::{Canonical, GenericPredicate, HirDisplay, ProjectionTy, TraitRef, Ty, TypeWalk}; |
16 | 16 | ||
17 | use self::chalk::{from_chalk, ToChalk, TypeFamily}; | 17 | use self::chalk::{from_chalk, Interner, ToChalk}; |
18 | 18 | ||
19 | pub(crate) mod chalk; | 19 | pub(crate) mod chalk; |
20 | mod builtin; | 20 | mod builtin; |
@@ -22,7 +22,7 @@ mod builtin; | |||
22 | #[derive(Debug, Clone)] | 22 | #[derive(Debug, Clone)] |
23 | pub struct TraitSolver { | 23 | pub struct TraitSolver { |
24 | krate: CrateId, | 24 | krate: CrateId, |
25 | inner: Arc<Mutex<chalk_solve::Solver<TypeFamily>>>, | 25 | inner: Arc<Mutex<chalk_solve::Solver<Interner>>>, |
26 | } | 26 | } |
27 | 27 | ||
28 | /// We need eq for salsa | 28 | /// We need eq for salsa |
@@ -38,8 +38,8 @@ impl TraitSolver { | |||
38 | fn solve( | 38 | fn solve( |
39 | &self, | 39 | &self, |
40 | db: &impl HirDatabase, | 40 | db: &impl HirDatabase, |
41 | goal: &chalk_ir::UCanonical<chalk_ir::InEnvironment<chalk_ir::Goal<TypeFamily>>>, | 41 | goal: &chalk_ir::UCanonical<chalk_ir::InEnvironment<chalk_ir::Goal<Interner>>>, |
42 | ) -> Option<chalk_solve::Solution<TypeFamily>> { | 42 | ) -> Option<chalk_solve::Solution<Interner>> { |
43 | let context = ChalkContext { db, krate: self.krate }; | 43 | let context = ChalkContext { db, krate: self.krate }; |
44 | log::debug!("solve goal: {:?}", goal); | 44 | log::debug!("solve goal: {:?}", goal); |
45 | let mut solver = match self.inner.lock() { | 45 | let mut solver = match self.inner.lock() { |
@@ -110,7 +110,7 @@ pub(crate) fn trait_solver_query( | |||
110 | TraitSolver { krate, inner: Arc::new(Mutex::new(create_chalk_solver())) } | 110 | TraitSolver { krate, inner: Arc::new(Mutex::new(create_chalk_solver())) } |
111 | } | 111 | } |
112 | 112 | ||
113 | fn create_chalk_solver() -> chalk_solve::Solver<TypeFamily> { | 113 | fn create_chalk_solver() -> chalk_solve::Solver<Interner> { |
114 | let solver_choice = | 114 | let solver_choice = |
115 | chalk_solve::SolverChoice::SLG { max_size: CHALK_SOLVER_MAX_SIZE, expected_answers: None }; | 115 | chalk_solve::SolverChoice::SLG { max_size: CHALK_SOLVER_MAX_SIZE, expected_answers: None }; |
116 | solver_choice.into_solver() | 116 | solver_choice.into_solver() |
@@ -242,9 +242,9 @@ pub(crate) fn trait_solve_query( | |||
242 | 242 | ||
243 | fn solution_from_chalk( | 243 | fn solution_from_chalk( |
244 | db: &impl HirDatabase, | 244 | db: &impl HirDatabase, |
245 | solution: chalk_solve::Solution<TypeFamily>, | 245 | solution: chalk_solve::Solution<Interner>, |
246 | ) -> Solution { | 246 | ) -> Solution { |
247 | let convert_subst = |subst: chalk_ir::Canonical<chalk_ir::Substitution<TypeFamily>>| { | 247 | let convert_subst = |subst: chalk_ir::Canonical<chalk_ir::Substitution<Interner>>| { |
248 | let value = subst | 248 | let value = subst |
249 | .value | 249 | .value |
250 | .into_iter() | 250 | .into_iter() |
diff --git a/crates/ra_hir_ty/src/traits/chalk.rs b/crates/ra_hir_ty/src/traits/chalk.rs index e1e430aeb..5b6c1a62e 100644 --- a/crates/ra_hir_ty/src/traits/chalk.rs +++ b/crates/ra_hir_ty/src/traits/chalk.rs | |||
@@ -3,7 +3,7 @@ use std::{fmt, sync::Arc}; | |||
3 | 3 | ||
4 | use log::debug; | 4 | use log::debug; |
5 | 5 | ||
6 | use chalk_ir::{cast::Cast, GoalData, Parameter, PlaceholderIndex, TypeName, UniverseIndex}; | 6 | use chalk_ir::{cast::Cast, Goal, GoalData, Parameter, PlaceholderIndex, TypeName, UniverseIndex}; |
7 | 7 | ||
8 | use hir_def::{AssocContainerId, AssocItemId, GenericDefId, HasModule, Lookup, TypeAliasId}; | 8 | use hir_def::{AssocContainerId, AssocItemId, GenericDefId, HasModule, Lookup, TypeAliasId}; |
9 | use ra_db::{ | 9 | use ra_db::{ |
@@ -18,13 +18,14 @@ use crate::{ | |||
18 | }; | 18 | }; |
19 | 19 | ||
20 | #[derive(Debug, Copy, Clone, Hash, PartialOrd, Ord, PartialEq, Eq)] | 20 | #[derive(Debug, Copy, Clone, Hash, PartialOrd, Ord, PartialEq, Eq)] |
21 | pub struct TypeFamily {} | 21 | pub struct Interner {} |
22 | 22 | ||
23 | impl chalk_ir::family::TypeFamily for TypeFamily { | 23 | impl chalk_ir::interner::Interner for Interner { |
24 | type InternedType = Box<chalk_ir::TyData<Self>>; | 24 | type InternedType = Box<chalk_ir::TyData<Self>>; |
25 | type InternedLifetime = chalk_ir::LifetimeData<Self>; | 25 | type InternedLifetime = chalk_ir::LifetimeData<Self>; |
26 | type InternedParameter = chalk_ir::ParameterData<Self>; | 26 | type InternedParameter = chalk_ir::ParameterData<Self>; |
27 | type InternedGoal = Arc<GoalData<Self>>; | 27 | type InternedGoal = Arc<GoalData<Self>>; |
28 | type InternedGoals = Vec<Goal<Self>>; | ||
28 | type InternedSubstitution = Vec<Parameter<Self>>; | 29 | type InternedSubstitution = Vec<Parameter<Self>>; |
29 | type DefId = InternId; | 30 | type DefId = InternId; |
30 | 31 | ||
@@ -85,10 +86,18 @@ impl chalk_ir::family::TypeFamily for TypeFamily { | |||
85 | Arc::new(goal) | 86 | Arc::new(goal) |
86 | } | 87 | } |
87 | 88 | ||
89 | fn intern_goals(data: impl IntoIterator<Item = Goal<Self>>) -> Self::InternedGoals { | ||
90 | data.into_iter().collect() | ||
91 | } | ||
92 | |||
88 | fn goal_data(goal: &Arc<GoalData<Self>>) -> &GoalData<Self> { | 93 | fn goal_data(goal: &Arc<GoalData<Self>>) -> &GoalData<Self> { |
89 | goal | 94 | goal |
90 | } | 95 | } |
91 | 96 | ||
97 | fn goals_data(goals: &Vec<Goal<Interner>>) -> &[Goal<Interner>] { | ||
98 | goals | ||
99 | } | ||
100 | |||
92 | fn intern_substitution<E>( | 101 | fn intern_substitution<E>( |
93 | data: impl IntoIterator<Item = Result<Parameter<Self>, E>>, | 102 | data: impl IntoIterator<Item = Result<Parameter<Self>, E>>, |
94 | ) -> Result<Vec<Parameter<Self>>, E> { | 103 | ) -> Result<Vec<Parameter<Self>>, E> { |
@@ -100,20 +109,20 @@ impl chalk_ir::family::TypeFamily for TypeFamily { | |||
100 | } | 109 | } |
101 | } | 110 | } |
102 | 111 | ||
103 | impl chalk_ir::family::HasTypeFamily for TypeFamily { | 112 | impl chalk_ir::interner::HasInterner for Interner { |
104 | type TypeFamily = Self; | 113 | type Interner = Self; |
105 | } | 114 | } |
106 | 115 | ||
107 | pub type AssocTypeId = chalk_ir::AssocTypeId<TypeFamily>; | 116 | pub type AssocTypeId = chalk_ir::AssocTypeId<Interner>; |
108 | pub type AssociatedTyDatum = chalk_rust_ir::AssociatedTyDatum<TypeFamily>; | 117 | pub type AssociatedTyDatum = chalk_rust_ir::AssociatedTyDatum<Interner>; |
109 | pub type TraitId = chalk_ir::TraitId<TypeFamily>; | 118 | pub type TraitId = chalk_ir::TraitId<Interner>; |
110 | pub type TraitDatum = chalk_rust_ir::TraitDatum<TypeFamily>; | 119 | pub type TraitDatum = chalk_rust_ir::TraitDatum<Interner>; |
111 | pub type StructId = chalk_ir::StructId<TypeFamily>; | 120 | pub type StructId = chalk_ir::StructId<Interner>; |
112 | pub type StructDatum = chalk_rust_ir::StructDatum<TypeFamily>; | 121 | pub type StructDatum = chalk_rust_ir::StructDatum<Interner>; |
113 | pub type ImplId = chalk_ir::ImplId<TypeFamily>; | 122 | pub type ImplId = chalk_ir::ImplId<Interner>; |
114 | pub type ImplDatum = chalk_rust_ir::ImplDatum<TypeFamily>; | 123 | pub type ImplDatum = chalk_rust_ir::ImplDatum<Interner>; |
115 | pub type AssociatedTyValueId = chalk_rust_ir::AssociatedTyValueId; | 124 | pub type AssociatedTyValueId = chalk_rust_ir::AssociatedTyValueId; |
116 | pub type AssociatedTyValue = chalk_rust_ir::AssociatedTyValue<TypeFamily>; | 125 | pub type AssociatedTyValue = chalk_rust_ir::AssociatedTyValue<Interner>; |
117 | 126 | ||
118 | pub(super) trait ToChalk { | 127 | pub(super) trait ToChalk { |
119 | type Chalk; | 128 | type Chalk; |
@@ -129,8 +138,8 @@ where | |||
129 | } | 138 | } |
130 | 139 | ||
131 | impl ToChalk for Ty { | 140 | impl ToChalk for Ty { |
132 | type Chalk = chalk_ir::Ty<TypeFamily>; | 141 | type Chalk = chalk_ir::Ty<Interner>; |
133 | fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::Ty<TypeFamily> { | 142 | fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::Ty<Interner> { |
134 | match self { | 143 | match self { |
135 | Ty::Apply(apply_ty) => { | 144 | Ty::Apply(apply_ty) => { |
136 | let name = apply_ty.ctor.to_chalk(db); | 145 | let name = apply_ty.ctor.to_chalk(db); |
@@ -148,7 +157,7 @@ impl ToChalk for Ty { | |||
148 | ui: UniverseIndex::ROOT, | 157 | ui: UniverseIndex::ROOT, |
149 | idx: interned_id.as_intern_id().as_usize(), | 158 | idx: interned_id.as_intern_id().as_usize(), |
150 | } | 159 | } |
151 | .to_ty::<TypeFamily>() | 160 | .to_ty::<Interner>() |
152 | } | 161 | } |
153 | Ty::Bound(idx) => chalk_ir::TyData::BoundVar(idx as usize).intern(), | 162 | Ty::Bound(idx) => chalk_ir::TyData::BoundVar(idx as usize).intern(), |
154 | Ty::Infer(_infer_ty) => panic!("uncanonicalized infer ty"), | 163 | Ty::Infer(_infer_ty) => panic!("uncanonicalized infer ty"), |
@@ -169,7 +178,7 @@ impl ToChalk for Ty { | |||
169 | } | 178 | } |
170 | } | 179 | } |
171 | } | 180 | } |
172 | fn from_chalk(db: &impl HirDatabase, chalk: chalk_ir::Ty<TypeFamily>) -> Self { | 181 | fn from_chalk(db: &impl HirDatabase, chalk: chalk_ir::Ty<Interner>) -> Self { |
173 | match chalk.data().clone() { | 182 | match chalk.data().clone() { |
174 | chalk_ir::TyData::Apply(apply_ty) => match apply_ty.name { | 183 | chalk_ir::TyData::Apply(apply_ty) => match apply_ty.name { |
175 | TypeName::Error => Ty::Unknown, | 184 | TypeName::Error => Ty::Unknown, |
@@ -205,13 +214,13 @@ impl ToChalk for Ty { | |||
205 | } | 214 | } |
206 | 215 | ||
207 | impl ToChalk for Substs { | 216 | impl ToChalk for Substs { |
208 | type Chalk = chalk_ir::Substitution<TypeFamily>; | 217 | type Chalk = chalk_ir::Substitution<Interner>; |
209 | 218 | ||
210 | fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::Substitution<TypeFamily> { | 219 | fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::Substitution<Interner> { |
211 | chalk_ir::Substitution::from(self.iter().map(|ty| ty.clone().to_chalk(db))) | 220 | chalk_ir::Substitution::from(self.iter().map(|ty| ty.clone().to_chalk(db))) |
212 | } | 221 | } |
213 | 222 | ||
214 | fn from_chalk(db: &impl HirDatabase, parameters: chalk_ir::Substitution<TypeFamily>) -> Substs { | 223 | fn from_chalk(db: &impl HirDatabase, parameters: chalk_ir::Substitution<Interner>) -> Substs { |
215 | let tys = parameters | 224 | let tys = parameters |
216 | .into_iter() | 225 | .into_iter() |
217 | .map(|p| match p.ty() { | 226 | .map(|p| match p.ty() { |
@@ -224,15 +233,15 @@ impl ToChalk for Substs { | |||
224 | } | 233 | } |
225 | 234 | ||
226 | impl ToChalk for TraitRef { | 235 | impl ToChalk for TraitRef { |
227 | type Chalk = chalk_ir::TraitRef<TypeFamily>; | 236 | type Chalk = chalk_ir::TraitRef<Interner>; |
228 | 237 | ||
229 | fn to_chalk(self: TraitRef, db: &impl HirDatabase) -> chalk_ir::TraitRef<TypeFamily> { | 238 | fn to_chalk(self: TraitRef, db: &impl HirDatabase) -> chalk_ir::TraitRef<Interner> { |
230 | let trait_id = self.trait_.to_chalk(db); | 239 | let trait_id = self.trait_.to_chalk(db); |
231 | let substitution = self.substs.to_chalk(db); | 240 | let substitution = self.substs.to_chalk(db); |
232 | chalk_ir::TraitRef { trait_id, substitution } | 241 | chalk_ir::TraitRef { trait_id, substitution } |
233 | } | 242 | } |
234 | 243 | ||
235 | fn from_chalk(db: &impl HirDatabase, trait_ref: chalk_ir::TraitRef<TypeFamily>) -> Self { | 244 | fn from_chalk(db: &impl HirDatabase, trait_ref: chalk_ir::TraitRef<Interner>) -> Self { |
236 | let trait_ = from_chalk(db, trait_ref.trait_id); | 245 | let trait_ = from_chalk(db, trait_ref.trait_id); |
237 | let substs = from_chalk(db, trait_ref.substitution); | 246 | let substs = from_chalk(db, trait_ref.substitution); |
238 | TraitRef { trait_, substs } | 247 | TraitRef { trait_, substs } |
@@ -252,9 +261,9 @@ impl ToChalk for hir_def::TraitId { | |||
252 | } | 261 | } |
253 | 262 | ||
254 | impl ToChalk for TypeCtor { | 263 | impl ToChalk for TypeCtor { |
255 | type Chalk = TypeName<TypeFamily>; | 264 | type Chalk = TypeName<Interner>; |
256 | 265 | ||
257 | fn to_chalk(self, db: &impl HirDatabase) -> TypeName<TypeFamily> { | 266 | fn to_chalk(self, db: &impl HirDatabase) -> TypeName<Interner> { |
258 | match self { | 267 | match self { |
259 | TypeCtor::AssociatedType(type_alias) => { | 268 | TypeCtor::AssociatedType(type_alias) => { |
260 | let type_id = type_alias.to_chalk(db); | 269 | let type_id = type_alias.to_chalk(db); |
@@ -268,7 +277,7 @@ impl ToChalk for TypeCtor { | |||
268 | } | 277 | } |
269 | } | 278 | } |
270 | 279 | ||
271 | fn from_chalk(db: &impl HirDatabase, type_name: TypeName<TypeFamily>) -> TypeCtor { | 280 | fn from_chalk(db: &impl HirDatabase, type_name: TypeName<Interner>) -> TypeCtor { |
272 | match type_name { | 281 | match type_name { |
273 | TypeName::Struct(struct_id) => db.lookup_intern_type_ctor(struct_id.into()), | 282 | TypeName::Struct(struct_id) => db.lookup_intern_type_ctor(struct_id.into()), |
274 | TypeName::AssociatedType(type_id) => TypeCtor::AssociatedType(from_chalk(db, type_id)), | 283 | TypeName::AssociatedType(type_id) => TypeCtor::AssociatedType(from_chalk(db, type_id)), |
@@ -317,9 +326,9 @@ impl ToChalk for AssocTyValue { | |||
317 | } | 326 | } |
318 | 327 | ||
319 | impl ToChalk for GenericPredicate { | 328 | impl ToChalk for GenericPredicate { |
320 | type Chalk = chalk_ir::QuantifiedWhereClause<TypeFamily>; | 329 | type Chalk = chalk_ir::QuantifiedWhereClause<Interner>; |
321 | 330 | ||
322 | fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::QuantifiedWhereClause<TypeFamily> { | 331 | fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::QuantifiedWhereClause<Interner> { |
323 | match self { | 332 | match self { |
324 | GenericPredicate::Implemented(trait_ref) => { | 333 | GenericPredicate::Implemented(trait_ref) => { |
325 | make_binders(chalk_ir::WhereClause::Implemented(trait_ref.to_chalk(db)), 0) | 334 | make_binders(chalk_ir::WhereClause::Implemented(trait_ref.to_chalk(db)), 0) |
@@ -337,7 +346,7 @@ impl ToChalk for GenericPredicate { | |||
337 | 346 | ||
338 | fn from_chalk( | 347 | fn from_chalk( |
339 | db: &impl HirDatabase, | 348 | db: &impl HirDatabase, |
340 | where_clause: chalk_ir::QuantifiedWhereClause<TypeFamily>, | 349 | where_clause: chalk_ir::QuantifiedWhereClause<Interner>, |
341 | ) -> GenericPredicate { | 350 | ) -> GenericPredicate { |
342 | match where_clause.value { | 351 | match where_clause.value { |
343 | chalk_ir::WhereClause::Implemented(tr) => { | 352 | chalk_ir::WhereClause::Implemented(tr) => { |
@@ -353,9 +362,9 @@ impl ToChalk for GenericPredicate { | |||
353 | } | 362 | } |
354 | 363 | ||
355 | impl ToChalk for ProjectionTy { | 364 | impl ToChalk for ProjectionTy { |
356 | type Chalk = chalk_ir::AliasTy<TypeFamily>; | 365 | type Chalk = chalk_ir::AliasTy<Interner>; |
357 | 366 | ||
358 | fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::AliasTy<TypeFamily> { | 367 | fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::AliasTy<Interner> { |
359 | chalk_ir::AliasTy { | 368 | chalk_ir::AliasTy { |
360 | associated_ty_id: self.associated_ty.to_chalk(db), | 369 | associated_ty_id: self.associated_ty.to_chalk(db), |
361 | substitution: self.parameters.to_chalk(db), | 370 | substitution: self.parameters.to_chalk(db), |
@@ -364,7 +373,7 @@ impl ToChalk for ProjectionTy { | |||
364 | 373 | ||
365 | fn from_chalk( | 374 | fn from_chalk( |
366 | db: &impl HirDatabase, | 375 | db: &impl HirDatabase, |
367 | projection_ty: chalk_ir::AliasTy<TypeFamily>, | 376 | projection_ty: chalk_ir::AliasTy<Interner>, |
368 | ) -> ProjectionTy { | 377 | ) -> ProjectionTy { |
369 | ProjectionTy { | 378 | ProjectionTy { |
370 | associated_ty: from_chalk(db, projection_ty.associated_ty_id), | 379 | associated_ty: from_chalk(db, projection_ty.associated_ty_id), |
@@ -374,28 +383,28 @@ impl ToChalk for ProjectionTy { | |||
374 | } | 383 | } |
375 | 384 | ||
376 | impl ToChalk for super::ProjectionPredicate { | 385 | impl ToChalk for super::ProjectionPredicate { |
377 | type Chalk = chalk_ir::Normalize<TypeFamily>; | 386 | type Chalk = chalk_ir::Normalize<Interner>; |
378 | 387 | ||
379 | fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::Normalize<TypeFamily> { | 388 | fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::Normalize<Interner> { |
380 | chalk_ir::Normalize { alias: self.projection_ty.to_chalk(db), ty: self.ty.to_chalk(db) } | 389 | chalk_ir::Normalize { alias: self.projection_ty.to_chalk(db), ty: self.ty.to_chalk(db) } |
381 | } | 390 | } |
382 | 391 | ||
383 | fn from_chalk(_db: &impl HirDatabase, _normalize: chalk_ir::Normalize<TypeFamily>) -> Self { | 392 | fn from_chalk(_db: &impl HirDatabase, _normalize: chalk_ir::Normalize<Interner>) -> Self { |
384 | unimplemented!() | 393 | unimplemented!() |
385 | } | 394 | } |
386 | } | 395 | } |
387 | 396 | ||
388 | impl ToChalk for Obligation { | 397 | impl ToChalk for Obligation { |
389 | type Chalk = chalk_ir::DomainGoal<TypeFamily>; | 398 | type Chalk = chalk_ir::DomainGoal<Interner>; |
390 | 399 | ||
391 | fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::DomainGoal<TypeFamily> { | 400 | fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::DomainGoal<Interner> { |
392 | match self { | 401 | match self { |
393 | Obligation::Trait(tr) => tr.to_chalk(db).cast(), | 402 | Obligation::Trait(tr) => tr.to_chalk(db).cast(), |
394 | Obligation::Projection(pr) => pr.to_chalk(db).cast(), | 403 | Obligation::Projection(pr) => pr.to_chalk(db).cast(), |
395 | } | 404 | } |
396 | } | 405 | } |
397 | 406 | ||
398 | fn from_chalk(_db: &impl HirDatabase, _goal: chalk_ir::DomainGoal<TypeFamily>) -> Self { | 407 | fn from_chalk(_db: &impl HirDatabase, _goal: chalk_ir::DomainGoal<Interner>) -> Self { |
399 | unimplemented!() | 408 | unimplemented!() |
400 | } | 409 | } |
401 | } | 410 | } |
@@ -418,16 +427,16 @@ where | |||
418 | } | 427 | } |
419 | 428 | ||
420 | impl ToChalk for Arc<super::TraitEnvironment> { | 429 | impl ToChalk for Arc<super::TraitEnvironment> { |
421 | type Chalk = chalk_ir::Environment<TypeFamily>; | 430 | type Chalk = chalk_ir::Environment<Interner>; |
422 | 431 | ||
423 | fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::Environment<TypeFamily> { | 432 | fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::Environment<Interner> { |
424 | let mut clauses = Vec::new(); | 433 | let mut clauses = Vec::new(); |
425 | for pred in &self.predicates { | 434 | for pred in &self.predicates { |
426 | if pred.is_error() { | 435 | if pred.is_error() { |
427 | // for env, we just ignore errors | 436 | // for env, we just ignore errors |
428 | continue; | 437 | continue; |
429 | } | 438 | } |
430 | let program_clause: chalk_ir::ProgramClause<TypeFamily> = | 439 | let program_clause: chalk_ir::ProgramClause<Interner> = |
431 | pred.clone().to_chalk(db).cast(); | 440 | pred.clone().to_chalk(db).cast(); |
432 | clauses.push(program_clause.into_from_env_clause()); | 441 | clauses.push(program_clause.into_from_env_clause()); |
433 | } | 442 | } |
@@ -436,7 +445,7 @@ impl ToChalk for Arc<super::TraitEnvironment> { | |||
436 | 445 | ||
437 | fn from_chalk( | 446 | fn from_chalk( |
438 | _db: &impl HirDatabase, | 447 | _db: &impl HirDatabase, |
439 | _env: chalk_ir::Environment<TypeFamily>, | 448 | _env: chalk_ir::Environment<Interner>, |
440 | ) -> Arc<super::TraitEnvironment> { | 449 | ) -> Arc<super::TraitEnvironment> { |
441 | unimplemented!() | 450 | unimplemented!() |
442 | } | 451 | } |
@@ -444,7 +453,7 @@ impl ToChalk for Arc<super::TraitEnvironment> { | |||
444 | 453 | ||
445 | impl<T: ToChalk> ToChalk for super::InEnvironment<T> | 454 | impl<T: ToChalk> ToChalk for super::InEnvironment<T> |
446 | where | 455 | where |
447 | T::Chalk: chalk_ir::family::HasTypeFamily<TypeFamily = TypeFamily>, | 456 | T::Chalk: chalk_ir::interner::HasInterner<Interner = Interner>, |
448 | { | 457 | { |
449 | type Chalk = chalk_ir::InEnvironment<T::Chalk>; | 458 | type Chalk = chalk_ir::InEnvironment<T::Chalk>; |
450 | 459 | ||
@@ -522,7 +531,7 @@ fn convert_where_clauses( | |||
522 | db: &impl HirDatabase, | 531 | db: &impl HirDatabase, |
523 | def: GenericDefId, | 532 | def: GenericDefId, |
524 | substs: &Substs, | 533 | substs: &Substs, |
525 | ) -> Vec<chalk_ir::QuantifiedWhereClause<TypeFamily>> { | 534 | ) -> Vec<chalk_ir::QuantifiedWhereClause<Interner>> { |
526 | let generic_predicates = db.generic_predicates(def); | 535 | let generic_predicates = db.generic_predicates(def); |
527 | let mut result = Vec::with_capacity(generic_predicates.len()); | 536 | let mut result = Vec::with_capacity(generic_predicates.len()); |
528 | for pred in generic_predicates.iter() { | 537 | for pred in generic_predicates.iter() { |
@@ -535,7 +544,7 @@ fn convert_where_clauses( | |||
535 | result | 544 | result |
536 | } | 545 | } |
537 | 546 | ||
538 | impl<'a, DB> chalk_solve::RustIrDatabase<TypeFamily> for ChalkContext<'a, DB> | 547 | impl<'a, DB> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a, DB> |
539 | where | 548 | where |
540 | DB: HirDatabase, | 549 | DB: HirDatabase, |
541 | { | 550 | { |
@@ -554,7 +563,7 @@ where | |||
554 | fn impls_for_trait( | 563 | fn impls_for_trait( |
555 | &self, | 564 | &self, |
556 | trait_id: TraitId, | 565 | trait_id: TraitId, |
557 | parameters: &[Parameter<TypeFamily>], | 566 | parameters: &[Parameter<Interner>], |
558 | ) -> Vec<ImplId> { | 567 | ) -> Vec<ImplId> { |
559 | debug!("impls_for_trait {:?}", trait_id); | 568 | debug!("impls_for_trait {:?}", trait_id); |
560 | let trait_: hir_def::TraitId = from_chalk(self.db, trait_id); | 569 | let trait_: hir_def::TraitId = from_chalk(self.db, trait_id); |
@@ -589,14 +598,14 @@ where | |||
589 | fn associated_ty_value(&self, id: AssociatedTyValueId) -> Arc<AssociatedTyValue> { | 598 | fn associated_ty_value(&self, id: AssociatedTyValueId) -> Arc<AssociatedTyValue> { |
590 | self.db.associated_ty_value(self.krate, id) | 599 | self.db.associated_ty_value(self.krate, id) |
591 | } | 600 | } |
592 | fn custom_clauses(&self) -> Vec<chalk_ir::ProgramClause<TypeFamily>> { | 601 | fn custom_clauses(&self) -> Vec<chalk_ir::ProgramClause<Interner>> { |
593 | vec![] | 602 | vec![] |
594 | } | 603 | } |
595 | fn local_impls_to_coherence_check(&self, _trait_id: TraitId) -> Vec<ImplId> { | 604 | fn local_impls_to_coherence_check(&self, _trait_id: TraitId) -> Vec<ImplId> { |
596 | // We don't do coherence checking (yet) | 605 | // We don't do coherence checking (yet) |
597 | unimplemented!() | 606 | unimplemented!() |
598 | } | 607 | } |
599 | fn as_struct_id(&self, id: &TypeName<TypeFamily>) -> Option<StructId> { | 608 | fn as_struct_id(&self, id: &TypeName<Interner>) -> Option<StructId> { |
600 | match id { | 609 | match id { |
601 | TypeName::Struct(struct_id) => Some(*struct_id), | 610 | TypeName::Struct(struct_id) => Some(*struct_id), |
602 | _ => None, | 611 | _ => None, |
diff --git a/crates/ra_ide/src/call_hierarchy.rs b/crates/ra_ide/src/call_hierarchy.rs index f984f40ad..51ac59a71 100644 --- a/crates/ra_ide/src/call_hierarchy.rs +++ b/crates/ra_ide/src/call_hierarchy.rs | |||
@@ -4,16 +4,11 @@ use indexmap::IndexMap; | |||
4 | 4 | ||
5 | use hir::db::AstDatabase; | 5 | use hir::db::AstDatabase; |
6 | use ra_ide_db::RootDatabase; | 6 | use ra_ide_db::RootDatabase; |
7 | use ra_syntax::{ | 7 | use ra_syntax::{ast, match_ast, AstNode, TextRange}; |
8 | ast::{self, DocCommentsOwner}, | ||
9 | match_ast, AstNode, TextRange, | ||
10 | }; | ||
11 | 8 | ||
12 | use crate::{ | 9 | use crate::{ |
13 | call_info::FnCallNode, | 10 | call_info::FnCallNode, display::ToNav, expand::descend_into_macros, goto_definition, |
14 | display::{ShortLabel, ToNav}, | 11 | references, FilePosition, NavigationTarget, RangeInfo, |
15 | expand::descend_into_macros, | ||
16 | goto_definition, references, FilePosition, NavigationTarget, RangeInfo, | ||
17 | }; | 12 | }; |
18 | 13 | ||
19 | #[derive(Debug, Clone)] | 14 | #[derive(Debug, Clone)] |
@@ -49,6 +44,7 @@ pub(crate) fn incoming_calls(db: &RootDatabase, position: FilePosition) -> Optio | |||
49 | let refs = references::find_all_refs(db, position, None)?; | 44 | let refs = references::find_all_refs(db, position, None)?; |
50 | 45 | ||
51 | let mut calls = CallLocations::default(); | 46 | let mut calls = CallLocations::default(); |
47 | let mut sb = hir::SourceBinder::new(db); | ||
52 | 48 | ||
53 | for reference in refs.info.references() { | 49 | for reference in refs.info.references() { |
54 | let file_id = reference.file_range.file_id; | 50 | let file_id = reference.file_range.file_id; |
@@ -62,12 +58,8 @@ pub(crate) fn incoming_calls(db: &RootDatabase, position: FilePosition) -> Optio | |||
62 | match_ast! { | 58 | match_ast! { |
63 | match node { | 59 | match node { |
64 | ast::FnDef(it) => { | 60 | ast::FnDef(it) => { |
65 | Some(NavigationTarget::from_named( | 61 | let def = sb.to_def(token.with_value(it))?; |
66 | db, | 62 | Some(def.to_nav(sb.db)) |
67 | token.with_value(&it), | ||
68 | it.doc_comment_text(), | ||
69 | it.short_label(), | ||
70 | )) | ||
71 | }, | 63 | }, |
72 | _ => { None }, | 64 | _ => { None }, |
73 | } | 65 | } |
diff --git a/crates/ra_ide/src/display/navigation_target.rs b/crates/ra_ide/src/display/navigation_target.rs index b42cb477e..c9d0058a6 100644 --- a/crates/ra_ide/src/display/navigation_target.rs +++ b/crates/ra_ide/src/display/navigation_target.rs | |||
@@ -125,7 +125,7 @@ impl NavigationTarget { | |||
125 | } | 125 | } |
126 | 126 | ||
127 | /// Allows `NavigationTarget` to be created from a `NameOwner` | 127 | /// Allows `NavigationTarget` to be created from a `NameOwner` |
128 | pub(crate) fn from_named( | 128 | fn from_named( |
129 | db: &RootDatabase, | 129 | db: &RootDatabase, |
130 | node: InFile<&dyn ast::NameOwner>, | 130 | node: InFile<&dyn ast::NameOwner>, |
131 | docs: Option<String>, | 131 | docs: Option<String>, |
diff --git a/crates/ra_ide/src/extend_selection.rs b/crates/ra_ide/src/extend_selection.rs index 4757d8e22..1e7d0621a 100644 --- a/crates/ra_ide/src/extend_selection.rs +++ b/crates/ra_ide/src/extend_selection.rs | |||
@@ -145,25 +145,25 @@ fn extend_tokens_from_range( | |||
145 | let src = db.parse_or_expand(expanded.file_id)?; | 145 | let src = db.parse_or_expand(expanded.file_id)?; |
146 | let parent = shallowest_node(&find_covering_element(&src, expanded.value))?.parent()?; | 146 | let parent = shallowest_node(&find_covering_element(&src, expanded.value))?.parent()?; |
147 | 147 | ||
148 | let validate = |token: SyntaxToken| { | 148 | let validate = |token: &SyntaxToken| { |
149 | let node = descend_into_macros(db, file_id, token.clone()); | 149 | let node = descend_into_macros(db, file_id, token.clone()); |
150 | if node.file_id == expanded.file_id | 150 | node.file_id == expanded.file_id |
151 | && node.value.text_range().is_subrange(&parent.text_range()) | 151 | && node.value.text_range().is_subrange(&parent.text_range()) |
152 | { | ||
153 | Some(token) | ||
154 | } else { | ||
155 | None | ||
156 | } | ||
157 | }; | 152 | }; |
158 | 153 | ||
159 | // Find the first and last text range under expanded parent | 154 | // Find the first and last text range under expanded parent |
160 | let first = successors(Some(first_token), |token| { | 155 | let first = successors(Some(first_token), |token| { |
161 | validate(skip_whitespace(token.prev_token()?, Direction::Prev)?) | 156 | let token = token.prev_token()?; |
157 | skip_whitespace(token, Direction::Prev) | ||
162 | }) | 158 | }) |
159 | .take_while(validate) | ||
163 | .last()?; | 160 | .last()?; |
161 | |||
164 | let last = successors(Some(last_token), |token| { | 162 | let last = successors(Some(last_token), |token| { |
165 | validate(skip_whitespace(token.next_token()?, Direction::Next)?) | 163 | let token = token.next_token()?; |
164 | skip_whitespace(token, Direction::Next) | ||
166 | }) | 165 | }) |
166 | .take_while(validate) | ||
167 | .last()?; | 167 | .last()?; |
168 | 168 | ||
169 | let range = union_range(first.text_range(), last.text_range()); | 169 | let range = union_range(first.text_range(), last.text_range()); |
@@ -334,10 +334,12 @@ fn adj_comments(comment: &ast::Comment, dir: Direction) -> ast::Comment { | |||
334 | 334 | ||
335 | #[cfg(test)] | 335 | #[cfg(test)] |
336 | mod tests { | 336 | mod tests { |
337 | use super::*; | ||
338 | use crate::mock_analysis::single_file; | ||
339 | use test_utils::extract_offset; | 337 | use test_utils::extract_offset; |
340 | 338 | ||
339 | use crate::mock_analysis::single_file; | ||
340 | |||
341 | use super::*; | ||
342 | |||
341 | fn do_check(before: &str, afters: &[&str]) { | 343 | fn do_check(before: &str, afters: &[&str]) { |
342 | let (cursor, before) = extract_offset(before); | 344 | let (cursor, before) = extract_offset(before); |
343 | let (analysis, file_id) = single_file(&before); | 345 | let (analysis, file_id) = single_file(&before); |
diff --git a/crates/ra_ide/src/join_lines.rs b/crates/ra_ide/src/join_lines.rs index 01fb32b3d..7d70dab9c 100644 --- a/crates/ra_ide/src/join_lines.rs +++ b/crates/ra_ide/src/join_lines.rs | |||
@@ -228,6 +228,31 @@ fn foo() { | |||
228 | } | 228 | } |
229 | 229 | ||
230 | #[test] | 230 | #[test] |
231 | fn test_join_lines_diverging_block() { | ||
232 | let before = r" | ||
233 | fn foo() { | ||
234 | loop { | ||
235 | match x { | ||
236 | 92 => <|>{ | ||
237 | continue; | ||
238 | } | ||
239 | } | ||
240 | } | ||
241 | } | ||
242 | "; | ||
243 | let after = r" | ||
244 | fn foo() { | ||
245 | loop { | ||
246 | match x { | ||
247 | 92 => <|>continue, | ||
248 | } | ||
249 | } | ||
250 | } | ||
251 | "; | ||
252 | check_join_lines(before, after); | ||
253 | } | ||
254 | |||
255 | #[test] | ||
231 | fn join_lines_adds_comma_for_block_in_match_arm() { | 256 | fn join_lines_adds_comma_for_block_in_match_arm() { |
232 | check_join_lines( | 257 | check_join_lines( |
233 | r" | 258 | r" |
diff --git a/crates/ra_ide/src/lib.rs b/crates/ra_ide/src/lib.rs index f86f98be7..82e10bc7e 100644 --- a/crates/ra_ide/src/lib.rs +++ b/crates/ra_ide/src/lib.rs | |||
@@ -75,7 +75,7 @@ pub use crate::{ | |||
75 | runnables::{Runnable, RunnableKind, TestId}, | 75 | runnables::{Runnable, RunnableKind, TestId}, |
76 | source_change::{FileSystemEdit, SourceChange, SourceFileEdit}, | 76 | source_change::{FileSystemEdit, SourceChange, SourceFileEdit}, |
77 | ssr::SsrError, | 77 | ssr::SsrError, |
78 | syntax_highlighting::HighlightedRange, | 78 | syntax_highlighting::{tags, HighlightedRange}, |
79 | }; | 79 | }; |
80 | 80 | ||
81 | pub use hir::Documentation; | 81 | pub use hir::Documentation; |
diff --git a/crates/ra_ide/src/syntax_highlighting.rs b/crates/ra_ide/src/syntax_highlighting.rs index d873f153e..812229b4e 100644 --- a/crates/ra_ide/src/syntax_highlighting.rs +++ b/crates/ra_ide/src/syntax_highlighting.rs | |||
@@ -17,32 +17,32 @@ use crate::{ | |||
17 | }; | 17 | }; |
18 | 18 | ||
19 | pub mod tags { | 19 | pub mod tags { |
20 | pub(crate) const FIELD: &str = "field"; | 20 | pub const FIELD: &str = "field"; |
21 | pub(crate) const FUNCTION: &str = "function"; | 21 | pub const FUNCTION: &str = "function"; |
22 | pub(crate) const MODULE: &str = "module"; | 22 | pub const MODULE: &str = "module"; |
23 | pub(crate) const CONSTANT: &str = "constant"; | 23 | pub const CONSTANT: &str = "constant"; |
24 | pub(crate) const MACRO: &str = "macro"; | 24 | pub const MACRO: &str = "macro"; |
25 | 25 | ||
26 | pub(crate) const VARIABLE: &str = "variable"; | 26 | pub const VARIABLE: &str = "variable"; |
27 | pub(crate) const VARIABLE_MUT: &str = "variable.mut"; | 27 | pub const VARIABLE_MUT: &str = "variable.mut"; |
28 | 28 | ||
29 | pub(crate) const TYPE: &str = "type"; | 29 | pub const TYPE: &str = "type"; |
30 | pub(crate) const TYPE_BUILTIN: &str = "type.builtin"; | 30 | pub const TYPE_BUILTIN: &str = "type.builtin"; |
31 | pub(crate) const TYPE_SELF: &str = "type.self"; | 31 | pub const TYPE_SELF: &str = "type.self"; |
32 | pub(crate) const TYPE_PARAM: &str = "type.param"; | 32 | pub const TYPE_PARAM: &str = "type.param"; |
33 | pub(crate) const TYPE_LIFETIME: &str = "type.lifetime"; | 33 | pub const TYPE_LIFETIME: &str = "type.lifetime"; |
34 | 34 | ||
35 | pub(crate) const LITERAL_BYTE: &str = "literal.byte"; | 35 | pub const LITERAL_BYTE: &str = "literal.byte"; |
36 | pub(crate) const LITERAL_NUMERIC: &str = "literal.numeric"; | 36 | pub const LITERAL_NUMERIC: &str = "literal.numeric"; |
37 | pub(crate) const LITERAL_CHAR: &str = "literal.char"; | 37 | pub const LITERAL_CHAR: &str = "literal.char"; |
38 | 38 | ||
39 | pub(crate) const LITERAL_COMMENT: &str = "comment"; | 39 | pub const LITERAL_COMMENT: &str = "comment"; |
40 | pub(crate) const LITERAL_STRING: &str = "string"; | 40 | pub const LITERAL_STRING: &str = "string"; |
41 | pub(crate) const LITERAL_ATTRIBUTE: &str = "attribute"; | 41 | pub const LITERAL_ATTRIBUTE: &str = "attribute"; |
42 | 42 | ||
43 | pub(crate) const KEYWORD: &str = "keyword"; | 43 | pub const KEYWORD: &str = "keyword"; |
44 | pub(crate) const KEYWORD_UNSAFE: &str = "keyword.unsafe"; | 44 | pub const KEYWORD_UNSAFE: &str = "keyword.unsafe"; |
45 | pub(crate) const KEYWORD_CONTROL: &str = "keyword.control"; | 45 | pub const KEYWORD_CONTROL: &str = "keyword.control"; |
46 | } | 46 | } |
47 | 47 | ||
48 | #[derive(Debug)] | 48 | #[derive(Debug)] |
diff --git a/crates/ra_syntax/Cargo.toml b/crates/ra_syntax/Cargo.toml index 7891628dc..8efc6b368 100644 --- a/crates/ra_syntax/Cargo.toml +++ b/crates/ra_syntax/Cargo.toml | |||
@@ -12,7 +12,7 @@ doctest = false | |||
12 | 12 | ||
13 | [dependencies] | 13 | [dependencies] |
14 | itertools = "0.8.2" | 14 | itertools = "0.8.2" |
15 | rowan = "0.9.0" | 15 | rowan = "0.9.1" |
16 | rustc_lexer = "0.1.0" | 16 | rustc_lexer = "0.1.0" |
17 | rustc-hash = "1.1.0" | 17 | rustc-hash = "1.1.0" |
18 | arrayvec = "0.5.1" | 18 | arrayvec = "0.5.1" |
diff --git a/crates/rust-analyzer/src/caps.rs b/crates/rust-analyzer/src/caps.rs index c9fd645f1..638987ee8 100644 --- a/crates/rust-analyzer/src/caps.rs +++ b/crates/rust-analyzer/src/caps.rs | |||
@@ -1,12 +1,15 @@ | |||
1 | //! Advertizes the capabilities of the LSP Server. | 1 | //! Advertizes the capabilities of the LSP Server. |
2 | 2 | ||
3 | use crate::semantic_tokens; | ||
4 | |||
3 | use lsp_types::{ | 5 | use lsp_types::{ |
4 | CallHierarchyServerCapability, CodeActionProviderCapability, CodeLensOptions, | 6 | CallHierarchyServerCapability, CodeActionProviderCapability, CodeLensOptions, |
5 | CompletionOptions, DocumentOnTypeFormattingOptions, FoldingRangeProviderCapability, | 7 | CompletionOptions, DocumentOnTypeFormattingOptions, FoldingRangeProviderCapability, |
6 | ImplementationProviderCapability, RenameOptions, RenameProviderCapability, SaveOptions, | 8 | ImplementationProviderCapability, RenameOptions, RenameProviderCapability, SaveOptions, |
7 | SelectionRangeProviderCapability, ServerCapabilities, SignatureHelpOptions, | 9 | SelectionRangeProviderCapability, SemanticTokensDocumentProvider, SemanticTokensLegend, |
8 | TextDocumentSyncCapability, TextDocumentSyncKind, TextDocumentSyncOptions, | 10 | SemanticTokensOptions, SemanticTokensServerCapabilities, ServerCapabilities, |
9 | TypeDefinitionProviderCapability, WorkDoneProgressOptions, | 11 | SignatureHelpOptions, TextDocumentSyncCapability, TextDocumentSyncKind, |
12 | TextDocumentSyncOptions, TypeDefinitionProviderCapability, WorkDoneProgressOptions, | ||
10 | }; | 13 | }; |
11 | 14 | ||
12 | pub fn server_capabilities() -> ServerCapabilities { | 15 | pub fn server_capabilities() -> ServerCapabilities { |
@@ -57,7 +60,20 @@ pub fn server_capabilities() -> ServerCapabilities { | |||
57 | execute_command_provider: None, | 60 | execute_command_provider: None, |
58 | workspace: None, | 61 | workspace: None, |
59 | call_hierarchy_provider: Some(CallHierarchyServerCapability::Simple(true)), | 62 | call_hierarchy_provider: Some(CallHierarchyServerCapability::Simple(true)), |
60 | semantic_tokens_provider: None, | 63 | semantic_tokens_provider: Some(SemanticTokensServerCapabilities::SemanticTokensOptions( |
64 | SemanticTokensOptions { | ||
65 | legend: SemanticTokensLegend { | ||
66 | token_types: semantic_tokens::supported_token_types().iter().cloned().collect(), | ||
67 | token_modifiers: semantic_tokens::supported_token_modifiers() | ||
68 | .iter() | ||
69 | .cloned() | ||
70 | .collect(), | ||
71 | }, | ||
72 | |||
73 | document_provider: Some(SemanticTokensDocumentProvider::Bool(true)), | ||
74 | ..SemanticTokensOptions::default() | ||
75 | }, | ||
76 | )), | ||
61 | experimental: Default::default(), | 77 | experimental: Default::default(), |
62 | } | 78 | } |
63 | } | 79 | } |
diff --git a/crates/rust-analyzer/src/conv.rs b/crates/rust-analyzer/src/conv.rs index 90ef74056..5fcb46b61 100644 --- a/crates/rust-analyzer/src/conv.rs +++ b/crates/rust-analyzer/src/conv.rs | |||
@@ -4,11 +4,12 @@ | |||
4 | use lsp_types::{ | 4 | use lsp_types::{ |
5 | self, CreateFile, DiagnosticSeverity, DocumentChangeOperation, DocumentChanges, Documentation, | 5 | self, CreateFile, DiagnosticSeverity, DocumentChangeOperation, DocumentChanges, Documentation, |
6 | Location, LocationLink, MarkupContent, MarkupKind, Position, Range, RenameFile, ResourceOp, | 6 | Location, LocationLink, MarkupContent, MarkupKind, Position, Range, RenameFile, ResourceOp, |
7 | SymbolKind, TextDocumentEdit, TextDocumentIdentifier, TextDocumentItem, | 7 | SemanticTokenModifier, SemanticTokenType, SymbolKind, TextDocumentEdit, TextDocumentIdentifier, |
8 | TextDocumentPositionParams, Url, VersionedTextDocumentIdentifier, WorkspaceEdit, | 8 | TextDocumentItem, TextDocumentPositionParams, Url, VersionedTextDocumentIdentifier, |
9 | WorkspaceEdit, | ||
9 | }; | 10 | }; |
10 | use ra_ide::{ | 11 | use ra_ide::{ |
11 | translate_offset_with_edit, CompletionItem, CompletionItemKind, FileId, FilePosition, | 12 | tags, translate_offset_with_edit, CompletionItem, CompletionItemKind, FileId, FilePosition, |
12 | FileRange, FileSystemEdit, Fold, FoldKind, InsertTextFormat, LineCol, LineIndex, | 13 | FileRange, FileSystemEdit, Fold, FoldKind, InsertTextFormat, LineCol, LineIndex, |
13 | NavigationTarget, RangeInfo, ReferenceAccess, Severity, SourceChange, SourceFileEdit, | 14 | NavigationTarget, RangeInfo, ReferenceAccess, Severity, SourceChange, SourceFileEdit, |
14 | }; | 15 | }; |
@@ -16,7 +17,7 @@ use ra_syntax::{SyntaxKind, TextRange, TextUnit}; | |||
16 | use ra_text_edit::{AtomTextEdit, TextEdit}; | 17 | use ra_text_edit::{AtomTextEdit, TextEdit}; |
17 | use ra_vfs::LineEndings; | 18 | use ra_vfs::LineEndings; |
18 | 19 | ||
19 | use crate::{req, world::WorldSnapshot, Result}; | 20 | use crate::{req, semantic_tokens, world::WorldSnapshot, Result}; |
20 | 21 | ||
21 | pub trait Conv { | 22 | pub trait Conv { |
22 | type Output; | 23 | type Output; |
@@ -302,6 +303,76 @@ impl ConvWith<&FoldConvCtx<'_>> for Fold { | |||
302 | } | 303 | } |
303 | } | 304 | } |
304 | 305 | ||
306 | impl Conv for &'static str { | ||
307 | type Output = (SemanticTokenType, Vec<SemanticTokenModifier>); | ||
308 | |||
309 | fn conv(self) -> (SemanticTokenType, Vec<SemanticTokenModifier>) { | ||
310 | let token_type: SemanticTokenType = match self { | ||
311 | tags::FIELD => SemanticTokenType::MEMBER, | ||
312 | tags::FUNCTION => SemanticTokenType::FUNCTION, | ||
313 | tags::MODULE => SemanticTokenType::NAMESPACE, | ||
314 | tags::CONSTANT => { | ||
315 | return ( | ||
316 | SemanticTokenType::VARIABLE, | ||
317 | vec![SemanticTokenModifier::STATIC, SemanticTokenModifier::READONLY], | ||
318 | ) | ||
319 | } | ||
320 | tags::MACRO => SemanticTokenType::MACRO, | ||
321 | |||
322 | tags::VARIABLE => { | ||
323 | return (SemanticTokenType::VARIABLE, vec![SemanticTokenModifier::READONLY]) | ||
324 | } | ||
325 | tags::VARIABLE_MUT => SemanticTokenType::VARIABLE, | ||
326 | |||
327 | tags::TYPE => SemanticTokenType::TYPE, | ||
328 | tags::TYPE_BUILTIN => SemanticTokenType::TYPE, | ||
329 | tags::TYPE_SELF => { | ||
330 | return (SemanticTokenType::TYPE, vec![SemanticTokenModifier::REFERENCE]) | ||
331 | } | ||
332 | tags::TYPE_PARAM => SemanticTokenType::TYPE_PARAMETER, | ||
333 | tags::TYPE_LIFETIME => { | ||
334 | return (SemanticTokenType::LABEL, vec![SemanticTokenModifier::REFERENCE]) | ||
335 | } | ||
336 | |||
337 | tags::LITERAL_BYTE => SemanticTokenType::NUMBER, | ||
338 | tags::LITERAL_NUMERIC => SemanticTokenType::NUMBER, | ||
339 | tags::LITERAL_CHAR => SemanticTokenType::NUMBER, | ||
340 | |||
341 | tags::LITERAL_COMMENT => { | ||
342 | return (SemanticTokenType::COMMENT, vec![SemanticTokenModifier::DOCUMENTATION]) | ||
343 | } | ||
344 | |||
345 | tags::LITERAL_STRING => SemanticTokenType::STRING, | ||
346 | tags::LITERAL_ATTRIBUTE => SemanticTokenType::KEYWORD, | ||
347 | |||
348 | tags::KEYWORD => SemanticTokenType::KEYWORD, | ||
349 | tags::KEYWORD_UNSAFE => SemanticTokenType::KEYWORD, | ||
350 | tags::KEYWORD_CONTROL => SemanticTokenType::KEYWORD, | ||
351 | unknown => panic!("Unknown semantic token: {}", unknown), | ||
352 | }; | ||
353 | |||
354 | (token_type, vec![]) | ||
355 | } | ||
356 | } | ||
357 | |||
358 | impl Conv for (SemanticTokenType, Vec<SemanticTokenModifier>) { | ||
359 | type Output = (u32, u32); | ||
360 | |||
361 | fn conv(self) -> Self::Output { | ||
362 | let token_index = | ||
363 | semantic_tokens::supported_token_types().iter().position(|it| *it == self.0).unwrap(); | ||
364 | let mut token_modifier_bitset = 0; | ||
365 | for modifier in self.1.iter() { | ||
366 | token_modifier_bitset |= semantic_tokens::supported_token_modifiers() | ||
367 | .iter() | ||
368 | .position(|it| it == modifier) | ||
369 | .unwrap(); | ||
370 | } | ||
371 | |||
372 | (token_index as u32, token_modifier_bitset as u32) | ||
373 | } | ||
374 | } | ||
375 | |||
305 | impl<T: ConvWith<CTX>, CTX> ConvWith<CTX> for Option<T> { | 376 | impl<T: ConvWith<CTX>, CTX> ConvWith<CTX> for Option<T> { |
306 | type Output = Option<T::Output>; | 377 | type Output = Option<T::Output>; |
307 | 378 | ||
diff --git a/crates/rust-analyzer/src/lib.rs b/crates/rust-analyzer/src/lib.rs index 0dae30e46..a0f968823 100644 --- a/crates/rust-analyzer/src/lib.rs +++ b/crates/rust-analyzer/src/lib.rs | |||
@@ -36,6 +36,7 @@ pub mod req; | |||
36 | mod config; | 36 | mod config; |
37 | mod world; | 37 | mod world; |
38 | mod diagnostics; | 38 | mod diagnostics; |
39 | mod semantic_tokens; | ||
39 | 40 | ||
40 | use serde::de::DeserializeOwned; | 41 | use serde::de::DeserializeOwned; |
41 | 42 | ||
diff --git a/crates/rust-analyzer/src/main_loop.rs b/crates/rust-analyzer/src/main_loop.rs index 98306986b..6e9e604a6 100644 --- a/crates/rust-analyzer/src/main_loop.rs +++ b/crates/rust-analyzer/src/main_loop.rs | |||
@@ -528,6 +528,7 @@ fn on_request( | |||
528 | .on::<req::CallHierarchyIncomingCalls>(handlers::handle_call_hierarchy_incoming)? | 528 | .on::<req::CallHierarchyIncomingCalls>(handlers::handle_call_hierarchy_incoming)? |
529 | .on::<req::CallHierarchyOutgoingCalls>(handlers::handle_call_hierarchy_outgoing)? | 529 | .on::<req::CallHierarchyOutgoingCalls>(handlers::handle_call_hierarchy_outgoing)? |
530 | .on::<req::Ssr>(handlers::handle_ssr)? | 530 | .on::<req::Ssr>(handlers::handle_ssr)? |
531 | .on::<req::SemanticTokensRequest>(handlers::handle_semantic_tokens)? | ||
531 | .finish(); | 532 | .finish(); |
532 | Ok(()) | 533 | Ok(()) |
533 | } | 534 | } |
diff --git a/crates/rust-analyzer/src/main_loop/handlers.rs b/crates/rust-analyzer/src/main_loop/handlers.rs index bb7bab372..e13e7c95a 100644 --- a/crates/rust-analyzer/src/main_loop/handlers.rs +++ b/crates/rust-analyzer/src/main_loop/handlers.rs | |||
@@ -16,8 +16,9 @@ use lsp_types::{ | |||
16 | CodeAction, CodeActionOrCommand, CodeActionResponse, CodeLens, Command, CompletionItem, | 16 | CodeAction, CodeActionOrCommand, CodeActionResponse, CodeLens, Command, CompletionItem, |
17 | Diagnostic, DocumentFormattingParams, DocumentHighlight, DocumentSymbol, FoldingRange, | 17 | Diagnostic, DocumentFormattingParams, DocumentHighlight, DocumentSymbol, FoldingRange, |
18 | FoldingRangeParams, Hover, HoverContents, Location, MarkupContent, MarkupKind, Position, | 18 | FoldingRangeParams, Hover, HoverContents, Location, MarkupContent, MarkupKind, Position, |
19 | PrepareRenameResponse, Range, RenameParams, SymbolInformation, TextDocumentIdentifier, | 19 | PrepareRenameResponse, Range, RenameParams, SemanticTokenModifier, SemanticTokenType, |
20 | TextEdit, WorkspaceEdit, | 20 | SemanticTokens, SemanticTokensParams, SemanticTokensResult, SymbolInformation, |
21 | TextDocumentIdentifier, TextEdit, WorkspaceEdit, | ||
21 | }; | 22 | }; |
22 | use ra_ide::{ | 23 | use ra_ide::{ |
23 | AssistId, FileId, FilePosition, FileRange, Query, RangeInfo, Runnable, RunnableKind, | 24 | AssistId, FileId, FilePosition, FileRange, Query, RangeInfo, Runnable, RunnableKind, |
@@ -38,6 +39,7 @@ use crate::{ | |||
38 | diagnostics::DiagnosticTask, | 39 | diagnostics::DiagnosticTask, |
39 | from_json, | 40 | from_json, |
40 | req::{self, Decoration, InlayHint, InlayHintsParams, InlayKind}, | 41 | req::{self, Decoration, InlayHint, InlayHintsParams, InlayKind}, |
42 | semantic_tokens::SemanticTokensBuilder, | ||
41 | world::WorldSnapshot, | 43 | world::WorldSnapshot, |
42 | LspError, Result, | 44 | LspError, Result, |
43 | }; | 45 | }; |
@@ -1068,3 +1070,25 @@ pub fn handle_call_hierarchy_outgoing( | |||
1068 | 1070 | ||
1069 | Ok(Some(res)) | 1071 | Ok(Some(res)) |
1070 | } | 1072 | } |
1073 | |||
1074 | pub fn handle_semantic_tokens( | ||
1075 | world: WorldSnapshot, | ||
1076 | params: SemanticTokensParams, | ||
1077 | ) -> Result<Option<SemanticTokensResult>> { | ||
1078 | let _p = profile("handle_semantic_tokens"); | ||
1079 | |||
1080 | let file_id = params.text_document.try_conv_with(&world)?; | ||
1081 | let line_index = world.analysis().file_line_index(file_id)?; | ||
1082 | |||
1083 | let mut builder = SemanticTokensBuilder::default(); | ||
1084 | |||
1085 | for h in world.analysis().highlight(file_id)?.into_iter() { | ||
1086 | let type_and_modifiers: (SemanticTokenType, Vec<SemanticTokenModifier>) = h.tag.conv(); | ||
1087 | let (token_type, token_modifiers) = type_and_modifiers.conv(); | ||
1088 | builder.push(h.range.conv_with(&line_index), token_type, token_modifiers); | ||
1089 | } | ||
1090 | |||
1091 | let tokens = SemanticTokens { data: builder.build(), ..Default::default() }; | ||
1092 | |||
1093 | Ok(Some(tokens.into())) | ||
1094 | } | ||
diff --git a/crates/rust-analyzer/src/req.rs b/crates/rust-analyzer/src/req.rs index 7ff7f60b3..3734899bc 100644 --- a/crates/rust-analyzer/src/req.rs +++ b/crates/rust-analyzer/src/req.rs | |||
@@ -12,9 +12,9 @@ pub use lsp_types::{ | |||
12 | DocumentSymbolResponse, FileSystemWatcher, Hover, InitializeResult, MessageType, | 12 | DocumentSymbolResponse, FileSystemWatcher, Hover, InitializeResult, MessageType, |
13 | PartialResultParams, ProgressParams, ProgressParamsValue, ProgressToken, | 13 | PartialResultParams, ProgressParams, ProgressParamsValue, ProgressToken, |
14 | PublishDiagnosticsParams, ReferenceParams, Registration, RegistrationParams, SelectionRange, | 14 | PublishDiagnosticsParams, ReferenceParams, Registration, RegistrationParams, SelectionRange, |
15 | SelectionRangeParams, ServerCapabilities, ShowMessageParams, SignatureHelp, SymbolKind, | 15 | SelectionRangeParams, SemanticTokensParams, SemanticTokensResult, ServerCapabilities, |
16 | TextDocumentEdit, TextDocumentPositionParams, TextEdit, WorkDoneProgressParams, WorkspaceEdit, | 16 | ShowMessageParams, SignatureHelp, SymbolKind, TextDocumentEdit, TextDocumentPositionParams, |
17 | WorkspaceSymbolParams, | 17 | TextEdit, WorkDoneProgressParams, WorkspaceEdit, WorkspaceSymbolParams, |
18 | }; | 18 | }; |
19 | 19 | ||
20 | pub enum AnalyzerStatus {} | 20 | pub enum AnalyzerStatus {} |
diff --git a/crates/rust-analyzer/src/semantic_tokens.rs b/crates/rust-analyzer/src/semantic_tokens.rs new file mode 100644 index 000000000..e6a8eb146 --- /dev/null +++ b/crates/rust-analyzer/src/semantic_tokens.rs | |||
@@ -0,0 +1,94 @@ | |||
1 | //! Semantic Tokens helpers | ||
2 | |||
3 | use lsp_types::{Range, SemanticToken, SemanticTokenModifier, SemanticTokenType}; | ||
4 | |||
5 | const SUPPORTED_TYPES: &[SemanticTokenType] = &[ | ||
6 | SemanticTokenType::COMMENT, | ||
7 | SemanticTokenType::KEYWORD, | ||
8 | SemanticTokenType::STRING, | ||
9 | SemanticTokenType::NUMBER, | ||
10 | SemanticTokenType::REGEXP, | ||
11 | SemanticTokenType::OPERATOR, | ||
12 | SemanticTokenType::NAMESPACE, | ||
13 | SemanticTokenType::TYPE, | ||
14 | SemanticTokenType::STRUCT, | ||
15 | SemanticTokenType::CLASS, | ||
16 | SemanticTokenType::INTERFACE, | ||
17 | SemanticTokenType::ENUM, | ||
18 | SemanticTokenType::TYPE_PARAMETER, | ||
19 | SemanticTokenType::FUNCTION, | ||
20 | SemanticTokenType::MEMBER, | ||
21 | SemanticTokenType::PROPERTY, | ||
22 | SemanticTokenType::MACRO, | ||
23 | SemanticTokenType::VARIABLE, | ||
24 | SemanticTokenType::PARAMETER, | ||
25 | SemanticTokenType::LABEL, | ||
26 | ]; | ||
27 | |||
28 | const SUPPORTED_MODIFIERS: &[SemanticTokenModifier] = &[ | ||
29 | SemanticTokenModifier::DOCUMENTATION, | ||
30 | SemanticTokenModifier::DECLARATION, | ||
31 | SemanticTokenModifier::DEFINITION, | ||
32 | SemanticTokenModifier::REFERENCE, | ||
33 | SemanticTokenModifier::STATIC, | ||
34 | SemanticTokenModifier::ABSTRACT, | ||
35 | SemanticTokenModifier::DEPRECATED, | ||
36 | SemanticTokenModifier::ASYNC, | ||
37 | SemanticTokenModifier::VOLATILE, | ||
38 | SemanticTokenModifier::READONLY, | ||
39 | ]; | ||
40 | |||
41 | /// Token types that the server supports | ||
42 | pub(crate) fn supported_token_types() -> &'static [SemanticTokenType] { | ||
43 | SUPPORTED_TYPES | ||
44 | } | ||
45 | |||
46 | /// Token modifiers that the server supports | ||
47 | pub(crate) fn supported_token_modifiers() -> &'static [SemanticTokenModifier] { | ||
48 | SUPPORTED_MODIFIERS | ||
49 | } | ||
50 | |||
51 | /// Tokens are encoded relative to each other. | ||
52 | /// | ||
53 | /// This is a direct port of https://github.com/microsoft/vscode-languageserver-node/blob/f425af9de46a0187adb78ec8a46b9b2ce80c5412/server/src/sematicTokens.proposed.ts#L45 | ||
54 | #[derive(Default)] | ||
55 | pub(crate) struct SemanticTokensBuilder { | ||
56 | prev_line: u32, | ||
57 | prev_char: u32, | ||
58 | data: Vec<SemanticToken>, | ||
59 | } | ||
60 | |||
61 | impl SemanticTokensBuilder { | ||
62 | /// Push a new token onto the builder | ||
63 | pub fn push(&mut self, range: Range, token_index: u32, modifier_bitset: u32) { | ||
64 | let mut push_line = range.start.line as u32; | ||
65 | let mut push_char = range.start.character as u32; | ||
66 | |||
67 | if !self.data.is_empty() { | ||
68 | push_line -= self.prev_line; | ||
69 | if push_line == 0 { | ||
70 | push_char -= self.prev_char; | ||
71 | } | ||
72 | } | ||
73 | |||
74 | // A token cannot be multiline | ||
75 | let token_len = range.end.character - range.start.character; | ||
76 | |||
77 | let token = SemanticToken { | ||
78 | delta_line: push_line, | ||
79 | delta_start: push_char, | ||
80 | length: token_len as u32, | ||
81 | token_type: token_index, | ||
82 | token_modifiers_bitset: modifier_bitset, | ||
83 | }; | ||
84 | |||
85 | self.data.push(token); | ||
86 | |||
87 | self.prev_line = range.start.line as u32; | ||
88 | self.prev_char = range.start.character as u32; | ||
89 | } | ||
90 | |||
91 | pub fn build(self) -> Vec<SemanticToken> { | ||
92 | self.data | ||
93 | } | ||
94 | } | ||