Skip to content

Commit 6ade2a8

Browse files
committed
Rust: address comments
1 parent 9fad541 commit 6ade2a8

File tree

3 files changed

+119
-99
lines changed

3 files changed

+119
-99
lines changed

rust/extractor/src/main.rs

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use anyhow::Context;
77
use archive::Archiver;
88
use ra_ap_ide_db::line_index::{LineCol, LineIndex};
99
use ra_ap_project_model::ProjectManifest;
10-
use rust_analyzer::RustAnalyzer;
10+
use rust_analyzer::{ParseResult, RustAnalyzer};
1111
mod archive;
1212
mod config;
1313
pub mod generated;
@@ -23,8 +23,14 @@ fn extract(
2323
) {
2424
archiver.archive(file);
2525

26-
let (ast, input, parse_errors, file_id, semi) = rust_analyzer.parse(file);
27-
let line_index = LineIndex::new(input.as_ref());
26+
let ParseResult {
27+
ast,
28+
text,
29+
errors,
30+
file_id,
31+
semantics,
32+
} = rust_analyzer.parse(file);
33+
let line_index = LineIndex::new(text.as_ref());
2834
let display_path = file.to_string_lossy();
2935
let mut trap = traps.create("source", file);
3036
let label = trap.emit_file(file);
@@ -34,14 +40,14 @@ fn extract(
3440
label,
3541
line_index,
3642
file_id,
37-
semi,
43+
semantics,
3844
);
3945

40-
for err in parse_errors {
46+
for err in errors {
4147
translator.emit_parse_error(&ast, &err);
4248
}
4349
let no_location = (LineCol { line: 0, col: 0 }, LineCol { line: 0, col: 0 });
44-
if translator.semi.is_none() {
50+
if translator.semantics.is_none() {
4551
translator.emit_diagnostic(
4652
trap::DiagnosticSeverity::Warning,
4753
"semantics".to_owned(),

rust/extractor/src/rust_analyzer.rs

Lines changed: 23 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,13 @@ pub enum RustAnalyzer {
2525
WithDatabase { db: RootDatabase, vfs: Vfs },
2626
WithoutDatabase(),
2727
}
28-
28+
pub struct ParseResult<'a> {
29+
pub ast: SourceFile,
30+
pub text: Arc<str>,
31+
pub errors: Vec<SyntaxError>,
32+
pub file_id: Option<EditionedFileId>,
33+
pub semantics: Option<Semantics<'a, RootDatabase>>,
34+
}
2935
impl RustAnalyzer {
3036
pub fn new(project: &ProjectManifest, scratch_dir: &Path) -> Self {
3137
let config = CargoConfig {
@@ -51,16 +57,7 @@ impl RustAnalyzer {
5157
}
5258
}
5359
}
54-
pub fn parse(
55-
&mut self,
56-
path: &Path,
57-
) -> (
58-
SourceFile,
59-
Arc<str>,
60-
Vec<SyntaxError>,
61-
Option<EditionedFileId>,
62-
Option<Semantics<'_, RootDatabase>>,
63-
) {
60+
pub fn parse(&mut self, path: &Path) -> ParseResult<'_> {
6461
let mut errors = Vec::new();
6562
let input = match std::fs::read(path) {
6663
Ok(data) => data,
@@ -82,28 +79,34 @@ impl RustAnalyzer {
8279
.and_then(|x| vfs.file_id(&x))
8380
{
8481
db.set_file_text(file_id, &input);
85-
let semi = Semantics::new(db);
82+
let semantics = Semantics::new(db);
8683

8784
let file_id = EditionedFileId::current_edition(file_id);
88-
let source_file = semi.parse(file_id);
85+
let source_file = semantics.parse(file_id);
8986
errors.extend(
9087
db.parse_errors(file_id)
9188
.into_iter()
9289
.flat_map(|x| x.to_vec()),
9390
);
94-
return (
95-
source_file,
96-
input.as_ref().into(),
91+
return ParseResult {
92+
ast: source_file,
93+
text: input.as_ref().into(),
9794
errors,
98-
Some(file_id),
99-
Some(semi),
100-
);
95+
file_id: Some(file_id),
96+
semantics: Some(semantics),
97+
};
10198
}
10299
}
103100
let parse = ra_ap_syntax::ast::SourceFile::parse(&input, Edition::CURRENT);
104101
errors.extend(parse.errors());
105102
errors.extend(err);
106-
(parse.tree(), input.as_ref().into(), errors, None, None)
103+
ParseResult {
104+
ast: parse.tree(),
105+
text: input.as_ref().into(),
106+
errors,
107+
file_id: None,
108+
semantics: None,
109+
}
107110
}
108111
}
109112

rust/extractor/src/translate/base.rs

Lines changed: 84 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,15 @@ use codeql_extractor::trap::{self};
66
use log::Level;
77
use ra_ap_hir::db::ExpandDatabase;
88
use ra_ap_hir::Semantics;
9+
use ra_ap_hir_expand::ExpandTo;
910
use ra_ap_ide_db::line_index::{LineCol, LineIndex};
1011
use ra_ap_ide_db::RootDatabase;
1112
use ra_ap_parser::SyntaxKind;
1213
use ra_ap_span::{EditionedFileId, TextSize};
1314
use ra_ap_syntax::ast::RangeItem;
1415
use ra_ap_syntax::{
15-
ast, AstNode, NodeOrToken, SyntaxElementChildren, SyntaxError, SyntaxToken, TextRange,
16+
ast, AstNode, NodeOrToken, SyntaxElementChildren, SyntaxError, SyntaxNode, SyntaxToken,
17+
TextRange,
1618
};
1719

1820
#[macro_export]
@@ -80,7 +82,7 @@ pub struct Translator<'a> {
8082
label: trap::Label,
8183
line_index: LineIndex,
8284
file_id: Option<EditionedFileId>,
83-
pub semi: Option<Semantics<'a, RootDatabase>>,
85+
pub semantics: Option<Semantics<'a, RootDatabase>>,
8486
}
8587

8688
impl<'a> Translator<'a> {
@@ -90,15 +92,15 @@ impl<'a> Translator<'a> {
9092
label: trap::Label,
9193
line_index: LineIndex,
9294
file_id: Option<EditionedFileId>,
93-
semi: Option<Semantics<'a, RootDatabase>>,
95+
semantics: Option<Semantics<'a, RootDatabase>>,
9496
) -> Translator<'a> {
9597
Translator {
9698
trap,
9799
path,
98100
label,
99101
line_index,
100102
file_id,
101-
semi,
103+
semantics,
102104
}
103105
}
104106
fn location(&self, range: TextRange) -> (LineCol, LineCol) {
@@ -122,8 +124,8 @@ impl<'a> Translator<'a> {
122124
}
123125

124126
pub fn text_range_for_node(&mut self, node: &impl ast::AstNode) -> Option<TextRange> {
125-
if let Some(semi) = self.semi.as_ref() {
126-
let file_range = semi.original_range(node.syntax());
127+
if let Some(semantics) = self.semantics.as_ref() {
128+
let file_range = semantics.original_range(node.syntax());
127129
let file_id = self.file_id?;
128130
if file_id == file_range.file_id {
129131
Some(file_range.range)
@@ -235,86 +237,95 @@ impl<'a> Translator<'a> {
235237
}
236238
}
237239
}
240+
fn emit_macro_expansion_parse_errors(&mut self, mcall: &ast::MacroCall, expanded: &SyntaxNode) {
241+
let semantics = self.semantics.as_ref().unwrap();
242+
if let Some(value) = semantics
243+
.hir_file_for(expanded)
244+
.macro_file()
245+
.and_then(|macro_file| {
246+
semantics
247+
.db
248+
.parse_macro_expansion_error(macro_file.macro_call_id)
249+
})
250+
{
251+
if let Some(err) = &value.err {
252+
let (message, _error) = err.render_to_string(semantics.db);
253+
254+
if err.span().anchor.file_id == semantics.hir_file_for(mcall.syntax()) {
255+
let location = err.span().range
256+
+ semantics
257+
.db
258+
.ast_id_map(err.span().anchor.file_id.into())
259+
.get_erased(err.span().anchor.ast_id)
260+
.text_range()
261+
.start();
262+
self.emit_parse_error(mcall, &SyntaxError::new(message, location));
263+
};
264+
}
265+
for err in value.value.iter() {
266+
self.emit_parse_error(mcall, err);
267+
}
268+
}
269+
}
270+
271+
fn emit_expanded_as(
272+
&mut self,
273+
expand_to: ExpandTo,
274+
expanded: SyntaxNode,
275+
) -> Option<Label<generated::AstNode>> {
276+
match expand_to {
277+
ra_ap_hir_expand::ExpandTo::Statements => {
278+
ast::MacroStmts::cast(expanded).map(|x| self.emit_macro_stmts(x).into())
279+
}
280+
ra_ap_hir_expand::ExpandTo::Items => {
281+
ast::MacroItems::cast(expanded).map(|x| self.emit_macro_items(x).into())
282+
}
283+
284+
ra_ap_hir_expand::ExpandTo::Pattern => {
285+
ast::Pat::cast(expanded).map(|x| self.emit_pat(x).into())
286+
}
287+
ra_ap_hir_expand::ExpandTo::Type => {
288+
ast::Type::cast(expanded).map(|x| self.emit_type(x).into())
289+
}
290+
ra_ap_hir_expand::ExpandTo::Expr => {
291+
ast::Expr::cast(expanded).map(|x| self.emit_expr(x).into())
292+
}
293+
}
294+
}
238295
pub(crate) fn extract_macro_call_expanded(
239296
&mut self,
240297
mcall: &ast::MacroCall,
241298
label: Label<generated::MacroCall>,
242299
) {
243-
if let Some(semi) = &self.semi {
244-
if let Some(expanded) = semi.expand(mcall) {
245-
if let Some(value) =
246-
semi.hir_file_for(&expanded)
247-
.macro_file()
248-
.and_then(|macro_file| {
249-
semi.db
250-
.parse_macro_expansion_error(macro_file.macro_call_id)
251-
})
252-
{
253-
if let Some(err) = &value.err {
254-
let (message, _error) = err.render_to_string(semi.db);
255-
256-
if err.span().anchor.file_id == semi.hir_file_for(mcall.syntax()) {
257-
let location = err.span().range
258-
+ semi
259-
.db
260-
.ast_id_map(err.span().anchor.file_id.into())
261-
.get_erased(err.span().anchor.ast_id)
262-
.text_range()
263-
.start();
264-
self.emit_parse_error(mcall, &SyntaxError::new(message, location));
265-
};
266-
}
267-
for err in value.value.iter() {
268-
self.emit_parse_error(mcall, err);
269-
}
270-
}
271-
let expand_to = ra_ap_hir_expand::ExpandTo::from_call_site(mcall);
272-
let kind = expanded.kind();
273-
let value: Option<Label<crate::generated::AstNode>> = match expand_to {
274-
ra_ap_hir_expand::ExpandTo::Statements => {
275-
ast::MacroStmts::cast(expanded).map(|x| self.emit_macro_stmts(x).into())
276-
}
277-
ra_ap_hir_expand::ExpandTo::Items => {
278-
ast::MacroItems::cast(expanded).map(|x| self.emit_macro_items(x).into())
279-
}
280-
281-
ra_ap_hir_expand::ExpandTo::Pattern => {
282-
ast::Pat::cast(expanded).map(|x| self.emit_pat(x).into())
283-
}
284-
ra_ap_hir_expand::ExpandTo::Type => {
285-
ast::Type::cast(expanded).map(|x| self.emit_type(x).into())
286-
}
287-
ra_ap_hir_expand::ExpandTo::Expr => {
288-
ast::Expr::cast(expanded).map(|x| self.emit_expr(x).into())
289-
}
290-
};
291-
if let Some(value) = value {
292-
MacroCall::emit_expanded(label, value, &mut self.trap.writer);
293-
} else {
294-
let range = self.text_range_for_node(mcall);
295-
self.emit_parse_error(mcall, &SyntaxError::new(
300+
if let Some(expanded) = self.semantics.as_ref().and_then(|s| s.expand(mcall)) {
301+
self.emit_macro_expansion_parse_errors(mcall, &expanded);
302+
let expand_to = ra_ap_hir_expand::ExpandTo::from_call_site(mcall);
303+
let kind = expanded.kind();
304+
if let Some(value) = self.emit_expanded_as(expand_to, expanded) {
305+
MacroCall::emit_expanded(label, value, &mut self.trap.writer);
306+
} else {
307+
let range = self.text_range_for_node(mcall);
308+
self.emit_parse_error(mcall, &SyntaxError::new(
296309
format!(
297310
"macro expansion failed: the macro '{}' expands to {:?} but a {:?} was expected",
298311
mcall.path().map(|p| p.to_string()).unwrap_or_default(),
299312
kind, expand_to
300313
),
301314
range.unwrap_or_else(|| TextRange::empty(TextSize::from(0))),
302315
));
303-
}
304-
} else {
305-
let range = self.text_range_for_node(mcall);
306-
307-
self.emit_parse_error(
308-
mcall,
309-
&SyntaxError::new(
310-
format!(
311-
"macro expansion failed: could not resolve macro '{}'",
312-
mcall.path().map(|p| p.to_string()).unwrap_or_default()
313-
),
314-
range.unwrap_or_else(|| TextRange::empty(TextSize::from(0))),
315-
),
316-
);
317316
}
317+
} else {
318+
let range = self.text_range_for_node(mcall);
319+
self.emit_parse_error(
320+
mcall,
321+
&SyntaxError::new(
322+
format!(
323+
"macro expansion failed: could not resolve macro '{}'",
324+
mcall.path().map(|p| p.to_string()).unwrap_or_default()
325+
),
326+
range.unwrap_or_else(|| TextRange::empty(TextSize::from(0))),
327+
),
328+
);
318329
}
319330
}
320331
}

0 commit comments

Comments
 (0)