Skip to content

Commit c78d269

Browse files
bors[bot]matklad
andauthored
Merge #2837
2837: Accidentally quadratic r=matklad a=matklad Our syntax highlighting is accdentally quadratic. Current state of the PR fixes it in a pretty crude way, looks like for the proper fix we need to redo how source-analyzer works. **NB:** don't be scared by diff stats, that's mostly a test-data file Co-authored-by: Aleksey Kladov <[email protected]>
2 parents aa2e13b + aaef88d commit c78d269

File tree

12 files changed

+4309
-177
lines changed

12 files changed

+4309
-177
lines changed

Cargo.lock

Lines changed: 6 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/ra_hir/src/lib.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
#![recursion_limit = "512"]
99

1010
macro_rules! impl_froms {
11-
($e:ident: $($v:ident $(($($sv:ident),*))?),*) => {
11+
($e:ident: $($v:ident $(($($sv:ident),*))?),*$(,)?) => {
1212
$(
1313
impl From<$v> for $e {
1414
fn from(it: $v) -> $e {
@@ -28,6 +28,7 @@ macro_rules! impl_froms {
2828

2929
pub mod db;
3030
pub mod source_analyzer;
31+
pub mod source_binder;
3132

3233
pub mod diagnostics;
3334

@@ -47,6 +48,7 @@ pub use crate::{
4748
from_source::FromSource,
4849
has_source::HasSource,
4950
source_analyzer::{PathResolution, ScopeEntryWithSyntax, SourceAnalyzer},
51+
source_binder::SourceBinder,
5052
};
5153

5254
pub use hir_def::{

crates/ra_hir/src/source_analyzer.rs

Lines changed: 41 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -14,26 +14,22 @@ use hir_def::{
1414
BodySourceMap,
1515
},
1616
expr::{ExprId, PatId},
17-
nameres::ModuleSource,
18-
resolver::{self, resolver_for_scope, HasResolver, Resolver, TypeNs, ValueNs},
17+
resolver::{self, resolver_for_scope, Resolver, TypeNs, ValueNs},
1918
DefWithBodyId, TraitId,
2019
};
2120
use hir_expand::{
2221
hygiene::Hygiene, name::AsName, AstId, HirFileId, InFile, MacroCallId, MacroCallKind,
2322
};
2423
use hir_ty::{InEnvironment, InferenceResult, TraitEnvironment};
25-
use ra_prof::profile;
2624
use ra_syntax::{
2725
ast::{self, AstNode},
28-
match_ast, AstPtr,
29-
SyntaxKind::*,
30-
SyntaxNode, SyntaxNodePtr, SyntaxToken, TextRange, TextUnit,
26+
AstPtr, SyntaxNode, SyntaxNodePtr, SyntaxToken, TextRange, TextUnit,
3127
};
3228
use rustc_hash::FxHashSet;
3329

3430
use crate::{
35-
db::HirDatabase, Adt, Const, DefWithBody, Enum, EnumVariant, FromSource, Function, ImplBlock,
36-
Local, MacroDef, Name, Path, ScopeDef, Static, Struct, Trait, Type, TypeAlias, TypeParam,
31+
db::HirDatabase, Adt, Const, DefWithBody, EnumVariant, Function, Local, MacroDef, Name, Path,
32+
ScopeDef, Static, Struct, Trait, Type, TypeAlias, TypeParam,
3733
};
3834

3935
/// `SourceAnalyzer` is a convenience wrapper which exposes HIR API in terms of
@@ -109,37 +105,43 @@ impl SourceAnalyzer {
109105
node: InFile<&SyntaxNode>,
110106
offset: Option<TextUnit>,
111107
) -> SourceAnalyzer {
112-
let _p = profile("SourceAnalyzer::new");
113-
let def_with_body = def_with_body_from_child_node(db, node);
114-
if let Some(def) = def_with_body {
115-
let (_body, source_map) = db.body_with_source_map(def.into());
116-
let scopes = db.expr_scopes(def.into());
117-
let scope = match offset {
118-
None => scope_for(&scopes, &source_map, node),
119-
Some(offset) => scope_for_offset(&scopes, &source_map, node.with_value(offset)),
120-
};
121-
let resolver = resolver_for_scope(db, def.into(), scope);
122-
SourceAnalyzer {
123-
resolver,
124-
body_owner: Some(def),
125-
body_source_map: Some(source_map),
126-
infer: Some(db.infer(def.into())),
127-
scopes: Some(scopes),
128-
file_id: node.file_id,
129-
}
130-
} else {
131-
SourceAnalyzer {
132-
resolver: node
133-
.value
134-
.ancestors()
135-
.find_map(|it| try_get_resolver_for_node(db, node.with_value(&it)))
136-
.unwrap_or_default(),
137-
body_owner: None,
138-
body_source_map: None,
139-
infer: None,
140-
scopes: None,
141-
file_id: node.file_id,
142-
}
108+
crate::source_binder::SourceBinder::new(db).analyze(node, offset)
109+
}
110+
111+
pub(crate) fn new_for_body(
112+
db: &impl HirDatabase,
113+
def: DefWithBodyId,
114+
node: InFile<&SyntaxNode>,
115+
offset: Option<TextUnit>,
116+
) -> SourceAnalyzer {
117+
let (_body, source_map) = db.body_with_source_map(def);
118+
let scopes = db.expr_scopes(def);
119+
let scope = match offset {
120+
None => scope_for(&scopes, &source_map, node),
121+
Some(offset) => scope_for_offset(&scopes, &source_map, node.with_value(offset)),
122+
};
123+
let resolver = resolver_for_scope(db, def, scope);
124+
SourceAnalyzer {
125+
resolver,
126+
body_owner: Some(def.into()),
127+
body_source_map: Some(source_map),
128+
infer: Some(db.infer(def)),
129+
scopes: Some(scopes),
130+
file_id: node.file_id,
131+
}
132+
}
133+
134+
pub(crate) fn new_for_resolver(
135+
resolver: Resolver,
136+
node: InFile<&SyntaxNode>,
137+
) -> SourceAnalyzer {
138+
SourceAnalyzer {
139+
resolver,
140+
body_owner: None,
141+
body_source_map: None,
142+
infer: None,
143+
scopes: None,
144+
file_id: node.file_id,
143145
}
144146
}
145147

@@ -366,64 +368,6 @@ impl SourceAnalyzer {
366368
}
367369
}
368370

369-
fn try_get_resolver_for_node(db: &impl HirDatabase, node: InFile<&SyntaxNode>) -> Option<Resolver> {
370-
match_ast! {
371-
match (node.value) {
372-
ast::Module(it) => {
373-
let src = node.with_value(it);
374-
Some(crate::Module::from_declaration(db, src)?.id.resolver(db))
375-
},
376-
ast::SourceFile(it) => {
377-
let src = node.with_value(ModuleSource::SourceFile(it));
378-
Some(crate::Module::from_definition(db, src)?.id.resolver(db))
379-
},
380-
ast::StructDef(it) => {
381-
let src = node.with_value(it);
382-
Some(Struct::from_source(db, src)?.id.resolver(db))
383-
},
384-
ast::EnumDef(it) => {
385-
let src = node.with_value(it);
386-
Some(Enum::from_source(db, src)?.id.resolver(db))
387-
},
388-
ast::ImplBlock(it) => {
389-
let src = node.with_value(it);
390-
Some(ImplBlock::from_source(db, src)?.id.resolver(db))
391-
},
392-
ast::TraitDef(it) => {
393-
let src = node.with_value(it);
394-
Some(Trait::from_source(db, src)?.id.resolver(db))
395-
},
396-
_ => match node.value.kind() {
397-
FN_DEF | CONST_DEF | STATIC_DEF => {
398-
let def = def_with_body_from_child_node(db, node)?;
399-
let def = DefWithBodyId::from(def);
400-
Some(def.resolver(db))
401-
}
402-
// FIXME add missing cases
403-
_ => None
404-
}
405-
}
406-
}
407-
}
408-
409-
fn def_with_body_from_child_node(
410-
db: &impl HirDatabase,
411-
child: InFile<&SyntaxNode>,
412-
) -> Option<DefWithBody> {
413-
let _p = profile("def_with_body_from_child_node");
414-
child.cloned().ancestors_with_macros(db).find_map(|node| {
415-
let n = &node.value;
416-
match_ast! {
417-
match n {
418-
ast::FnDef(def) => { return Function::from_source(db, node.with_value(def)).map(DefWithBody::from); },
419-
ast::ConstDef(def) => { return Const::from_source(db, node.with_value(def)).map(DefWithBody::from); },
420-
ast::StaticDef(def) => { return Static::from_source(db, node.with_value(def)).map(DefWithBody::from); },
421-
_ => { None },
422-
}
423-
}
424-
})
425-
}
426-
427371
fn scope_for(
428372
scopes: &ExprScopes,
429373
source_map: &BodySourceMap,

0 commit comments

Comments
 (0)