Skip to content

Commit 7624997

Browse files
Support all fixture features in fixture highlight injection
That is, multiple crates and `minicore`.
1 parent c09b440 commit 7624997

File tree

15 files changed

+346
-93
lines changed

15 files changed

+346
-93
lines changed

crates/ide-diagnostics/src/tests.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -311,7 +311,7 @@ fn minicore_smoke_test() {
311311
}
312312

313313
fn check(minicore: MiniCore) {
314-
let source = minicore.source_code();
314+
let source = minicore.source_code(MiniCore::RAW_SOURCE);
315315
let mut config = DiagnosticsConfig::test_sample();
316316
// This should be ignored since we conditionally remove code which creates single item use with braces
317317
config.disabled.insert("unused_braces".to_owned());
@@ -321,7 +321,7 @@ fn minicore_smoke_test() {
321321
}
322322

323323
// Checks that there is no diagnostic in minicore for each flag.
324-
for flag in MiniCore::available_flags() {
324+
for flag in MiniCore::available_flags(MiniCore::RAW_SOURCE) {
325325
if flag == "clone" {
326326
// Clone without copy has `moved-out-of-ref`, so ignoring.
327327
// FIXME: Maybe we should merge copy and clone in a single flag?
@@ -332,5 +332,5 @@ fn minicore_smoke_test() {
332332
}
333333
// And one time for all flags, to check codes which are behind multiple flags + prevent name collisions
334334
eprintln!("Checking all minicore flags");
335-
check(MiniCore::from_flags(MiniCore::available_flags()))
335+
check(MiniCore::from_flags(MiniCore::available_flags(MiniCore::RAW_SOURCE)))
336336
}

crates/ide/Cargo.toml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,16 +43,16 @@ span.workspace = true
4343
# something from some `hir-xxx` subpackage, reexport the API via `hir`.
4444
hir.workspace = true
4545

46+
test-utils.workspace = true
47+
# local deps
48+
test-fixture.workspace = true
49+
4650
[target.'cfg(not(any(target_arch = "wasm32", target_os = "emscripten")))'.dependencies]
4751
toolchain.workspace = true
4852

4953
[dev-dependencies]
5054
expect-test = "1.5.1"
5155

52-
# local deps
53-
test-utils.workspace = true
54-
test-fixture.workspace = true
55-
5656
[features]
5757
in-rust-tree = []
5858

crates/ide/src/lib.rs

Lines changed: 39 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,41 @@ impl Analysis {
274274
(host.analysis(), file_id)
275275
}
276276

277+
pub fn from_ra_fixture(text: &str, minicore: &str) -> (Analysis, Vec<(FileId, usize)>) {
278+
// We don't want a mistake in the fixture to crash r-a, so we wrap this in `catch_unwind()`.
279+
std::panic::catch_unwind(|| {
280+
let mut host = AnalysisHost::default();
281+
let fixture = test_fixture::ChangeFixture::parse_with_proc_macros(
282+
&host.db,
283+
text,
284+
minicore,
285+
Vec::new(),
286+
);
287+
host.apply_change(fixture.change);
288+
let files = fixture
289+
.files
290+
.into_iter()
291+
.zip(fixture.file_lines)
292+
.map(|(file_id, range)| (file_id.file_id(&host.db), range))
293+
.collect();
294+
(host.analysis(), files)
295+
})
296+
.unwrap_or_else(|error| {
297+
tracing::error!(
298+
"cannot crate the crate graph: {}\nCrate graph:\n{}\n",
299+
if let Some(&s) = error.downcast_ref::<&'static str>() {
300+
s
301+
} else if let Some(s) = error.downcast_ref::<String>() {
302+
s.as_str()
303+
} else {
304+
"Box<dyn Any>"
305+
},
306+
text,
307+
);
308+
(AnalysisHost::default().analysis(), Vec::new())
309+
})
310+
}
311+
277312
/// Debug info about the current state of the analysis.
278313
pub fn status(&self, file_id: Option<FileId>) -> Cancellable<String> {
279314
self.with_db(|db| status::status(db, file_id))
@@ -675,28 +710,28 @@ impl Analysis {
675710
/// Computes syntax highlighting for the given file
676711
pub fn highlight(
677712
&self,
678-
highlight_config: HighlightConfig,
713+
highlight_config: HighlightConfig<'_>,
679714
file_id: FileId,
680715
) -> Cancellable<Vec<HlRange>> {
681716
// highlighting may construct a new database for "speculative" execution, so we can't currently attach the database
682717
// highlighting instead sets up the attach hook where neceesary for the trait solver
683718
Cancelled::catch(|| {
684-
syntax_highlighting::highlight(&self.db, highlight_config, file_id, None)
719+
syntax_highlighting::highlight(&self.db, &highlight_config, file_id, None)
685720
})
686721
}
687722

688723
/// Computes syntax highlighting for the given file range.
689724
pub fn highlight_range(
690725
&self,
691-
highlight_config: HighlightConfig,
726+
highlight_config: HighlightConfig<'_>,
692727
frange: FileRange,
693728
) -> Cancellable<Vec<HlRange>> {
694729
// highlighting may construct a new database for "speculative" execution, so we can't currently attach the database
695730
// highlighting instead sets up the attach hook where neceesary for the trait solver
696731
Cancelled::catch(|| {
697732
syntax_highlighting::highlight(
698733
&self.db,
699-
highlight_config,
734+
&highlight_config,
700735
frange.file_id,
701736
Some(frange.range),
702737
)

crates/ide/src/syntax_highlighting.rs

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ pub struct HlRange {
4444
}
4545

4646
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
47-
pub struct HighlightConfig {
47+
pub struct HighlightConfig<'a> {
4848
/// Whether to highlight strings
4949
pub strings: bool,
5050
/// Whether to highlight punctuation
@@ -61,6 +61,12 @@ pub struct HighlightConfig {
6161
pub macro_bang: bool,
6262
/// Whether to highlight unresolved things be their syntax
6363
pub syntactic_name_ref_highlighting: bool,
64+
/// This is a bit of a special field, it's not really a config, rather it's a way to pass information to highlight.
65+
///
66+
/// Fixture highlighting requires the presence of a `minicore.rs` file. If such file is believed to be found in
67+
/// the workspace (based on the path), this field stores its contents. Otherwise, highlighting will use the `minicore`
68+
/// that was baked into the rust-analyzer binary.
69+
pub minicore: Option<&'a str>,
6470
}
6571

6672
// Feature: Semantic Syntax Highlighting
@@ -188,7 +194,7 @@ pub struct HighlightConfig {
188194
// ![Semantic Syntax Highlighting](https://user-images.githubusercontent.com/48062697/113187625-f7f50100-9250-11eb-825e-91c58f236071.png)
189195
pub(crate) fn highlight(
190196
db: &RootDatabase,
191-
config: HighlightConfig,
197+
config: &HighlightConfig<'_>,
192198
file_id: FileId,
193199
range_to_highlight: Option<TextRange>,
194200
) -> Vec<HlRange> {
@@ -223,7 +229,7 @@ pub(crate) fn highlight(
223229
fn traverse(
224230
hl: &mut Highlights,
225231
sema: &Semantics<'_, RootDatabase>,
226-
config: HighlightConfig,
232+
config: &HighlightConfig<'_>,
227233
InRealFile { file_id, value: root }: InRealFile<&SyntaxNode>,
228234
krate: Option<hir::Crate>,
229235
range_to_highlight: TextRange,
@@ -488,7 +494,7 @@ fn traverse(
488494
fn string_injections(
489495
hl: &mut Highlights,
490496
sema: &Semantics<'_, RootDatabase>,
491-
config: HighlightConfig,
497+
config: &HighlightConfig<'_>,
492498
file_id: EditionedFileId,
493499
krate: Option<hir::Crate>,
494500
token: SyntaxToken,
@@ -585,7 +591,7 @@ fn descend_token(
585591
})
586592
}
587593

588-
fn filter_by_config(highlight: &mut Highlight, config: HighlightConfig) -> bool {
594+
fn filter_by_config(highlight: &mut Highlight, config: &HighlightConfig<'_>) -> bool {
589595
match &mut highlight.tag {
590596
HlTag::StringLiteral if !config.strings => return false,
591597
// If punctuation is disabled, make the macro bang part of the macro call again.

crates/ide/src/syntax_highlighting/html.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ pub(crate) fn highlight_as_html(db: &RootDatabase, file_id: FileId, rainbow: boo
2929

3030
let hl_ranges = highlight(
3131
db,
32-
HighlightConfig {
32+
&HighlightConfig {
3333
strings: true,
3434
punctuation: true,
3535
specialize_punctuation: true,
@@ -38,6 +38,7 @@ pub(crate) fn highlight_as_html(db: &RootDatabase, file_id: FileId, rainbow: boo
3838
inject_doc_comment: true,
3939
macro_bang: true,
4040
syntactic_name_ref_highlighting: false,
41+
minicore: None,
4142
},
4243
file_id.file_id(db),
4344
None,

0 commit comments

Comments
 (0)