Skip to content

Commit

Permalink
Rust: address comments
Browse files Browse the repository at this point in the history
  • Loading branch information
aibaars committed Oct 11, 2024
1 parent 9fad541 commit 6ade2a8
Show file tree
Hide file tree
Showing 3 changed files with 119 additions and 99 deletions.
18 changes: 12 additions & 6 deletions rust/extractor/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use anyhow::Context;
use archive::Archiver;
use ra_ap_ide_db::line_index::{LineCol, LineIndex};
use ra_ap_project_model::ProjectManifest;
use rust_analyzer::RustAnalyzer;
use rust_analyzer::{ParseResult, RustAnalyzer};
mod archive;
mod config;
pub mod generated;
Expand All @@ -23,8 +23,14 @@ fn extract(
) {
archiver.archive(file);

let (ast, input, parse_errors, file_id, semi) = rust_analyzer.parse(file);
let line_index = LineIndex::new(input.as_ref());
let ParseResult {
ast,
text,
errors,
file_id,
semantics,
} = rust_analyzer.parse(file);
let line_index = LineIndex::new(text.as_ref());
let display_path = file.to_string_lossy();
let mut trap = traps.create("source", file);
let label = trap.emit_file(file);
Expand All @@ -34,14 +40,14 @@ fn extract(
label,
line_index,
file_id,
semi,
semantics,
);

for err in parse_errors {
for err in errors {
translator.emit_parse_error(&ast, &err);
}
let no_location = (LineCol { line: 0, col: 0 }, LineCol { line: 0, col: 0 });
if translator.semi.is_none() {
if translator.semantics.is_none() {
translator.emit_diagnostic(
trap::DiagnosticSeverity::Warning,
"semantics".to_owned(),
Expand Down
43 changes: 23 additions & 20 deletions rust/extractor/src/rust_analyzer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,13 @@ pub enum RustAnalyzer {
WithDatabase { db: RootDatabase, vfs: Vfs },
WithoutDatabase(),
}

pub struct ParseResult<'a> {
pub ast: SourceFile,
pub text: Arc<str>,
pub errors: Vec<SyntaxError>,
pub file_id: Option<EditionedFileId>,
pub semantics: Option<Semantics<'a, RootDatabase>>,
}
impl RustAnalyzer {
pub fn new(project: &ProjectManifest, scratch_dir: &Path) -> Self {
let config = CargoConfig {
Expand All @@ -51,16 +57,7 @@ impl RustAnalyzer {
}
}
}
pub fn parse(
&mut self,
path: &Path,
) -> (
SourceFile,
Arc<str>,
Vec<SyntaxError>,
Option<EditionedFileId>,
Option<Semantics<'_, RootDatabase>>,
) {
pub fn parse(&mut self, path: &Path) -> ParseResult<'_> {
let mut errors = Vec::new();
let input = match std::fs::read(path) {
Ok(data) => data,
Expand All @@ -82,28 +79,34 @@ impl RustAnalyzer {
.and_then(|x| vfs.file_id(&x))
{
db.set_file_text(file_id, &input);
let semi = Semantics::new(db);
let semantics = Semantics::new(db);

let file_id = EditionedFileId::current_edition(file_id);
let source_file = semi.parse(file_id);
let source_file = semantics.parse(file_id);
errors.extend(
db.parse_errors(file_id)
.into_iter()
.flat_map(|x| x.to_vec()),
);
return (
source_file,
input.as_ref().into(),
return ParseResult {
ast: source_file,
text: input.as_ref().into(),
errors,
Some(file_id),
Some(semi),
);
file_id: Some(file_id),
semantics: Some(semantics),
};
}
}
let parse = ra_ap_syntax::ast::SourceFile::parse(&input, Edition::CURRENT);
errors.extend(parse.errors());
errors.extend(err);
(parse.tree(), input.as_ref().into(), errors, None, None)
ParseResult {
ast: parse.tree(),
text: input.as_ref().into(),
errors,
file_id: None,
semantics: None,
}
}
}

Expand Down
157 changes: 84 additions & 73 deletions rust/extractor/src/translate/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,15 @@ use codeql_extractor::trap::{self};
use log::Level;
use ra_ap_hir::db::ExpandDatabase;
use ra_ap_hir::Semantics;
use ra_ap_hir_expand::ExpandTo;
use ra_ap_ide_db::line_index::{LineCol, LineIndex};
use ra_ap_ide_db::RootDatabase;
use ra_ap_parser::SyntaxKind;
use ra_ap_span::{EditionedFileId, TextSize};
use ra_ap_syntax::ast::RangeItem;
use ra_ap_syntax::{
ast, AstNode, NodeOrToken, SyntaxElementChildren, SyntaxError, SyntaxToken, TextRange,
ast, AstNode, NodeOrToken, SyntaxElementChildren, SyntaxError, SyntaxNode, SyntaxToken,
TextRange,
};

#[macro_export]
Expand Down Expand Up @@ -80,7 +82,7 @@ pub struct Translator<'a> {
label: trap::Label,
line_index: LineIndex,
file_id: Option<EditionedFileId>,
pub semi: Option<Semantics<'a, RootDatabase>>,
pub semantics: Option<Semantics<'a, RootDatabase>>,
}

impl<'a> Translator<'a> {
Expand All @@ -90,15 +92,15 @@ impl<'a> Translator<'a> {
label: trap::Label,
line_index: LineIndex,
file_id: Option<EditionedFileId>,
semi: Option<Semantics<'a, RootDatabase>>,
semantics: Option<Semantics<'a, RootDatabase>>,
) -> Translator<'a> {
Translator {
trap,
path,
label,
line_index,
file_id,
semi,
semantics,
}
}
fn location(&self, range: TextRange) -> (LineCol, LineCol) {
Expand All @@ -122,8 +124,8 @@ impl<'a> Translator<'a> {
}

pub fn text_range_for_node(&mut self, node: &impl ast::AstNode) -> Option<TextRange> {
if let Some(semi) = self.semi.as_ref() {
let file_range = semi.original_range(node.syntax());
if let Some(semantics) = self.semantics.as_ref() {
let file_range = semantics.original_range(node.syntax());
let file_id = self.file_id?;
if file_id == file_range.file_id {
Some(file_range.range)
Expand Down Expand Up @@ -235,86 +237,95 @@ impl<'a> Translator<'a> {
}
}
}
fn emit_macro_expansion_parse_errors(&mut self, mcall: &ast::MacroCall, expanded: &SyntaxNode) {
let semantics = self.semantics.as_ref().unwrap();
if let Some(value) = semantics
.hir_file_for(expanded)
.macro_file()
.and_then(|macro_file| {
semantics
.db
.parse_macro_expansion_error(macro_file.macro_call_id)
})
{
if let Some(err) = &value.err {
let (message, _error) = err.render_to_string(semantics.db);

if err.span().anchor.file_id == semantics.hir_file_for(mcall.syntax()) {
let location = err.span().range
+ semantics
.db
.ast_id_map(err.span().anchor.file_id.into())
.get_erased(err.span().anchor.ast_id)
.text_range()
.start();
self.emit_parse_error(mcall, &SyntaxError::new(message, location));
};
}
for err in value.value.iter() {
self.emit_parse_error(mcall, err);
}
}
}

fn emit_expanded_as(
&mut self,
expand_to: ExpandTo,
expanded: SyntaxNode,
) -> Option<Label<generated::AstNode>> {
match expand_to {
ra_ap_hir_expand::ExpandTo::Statements => {
ast::MacroStmts::cast(expanded).map(|x| self.emit_macro_stmts(x).into())
}
ra_ap_hir_expand::ExpandTo::Items => {
ast::MacroItems::cast(expanded).map(|x| self.emit_macro_items(x).into())
}

ra_ap_hir_expand::ExpandTo::Pattern => {
ast::Pat::cast(expanded).map(|x| self.emit_pat(x).into())
}
ra_ap_hir_expand::ExpandTo::Type => {
ast::Type::cast(expanded).map(|x| self.emit_type(x).into())
}
ra_ap_hir_expand::ExpandTo::Expr => {
ast::Expr::cast(expanded).map(|x| self.emit_expr(x).into())
}
}
}
pub(crate) fn extract_macro_call_expanded(
&mut self,
mcall: &ast::MacroCall,
label: Label<generated::MacroCall>,
) {
if let Some(semi) = &self.semi {
if let Some(expanded) = semi.expand(mcall) {
if let Some(value) =
semi.hir_file_for(&expanded)
.macro_file()
.and_then(|macro_file| {
semi.db
.parse_macro_expansion_error(macro_file.macro_call_id)
})
{
if let Some(err) = &value.err {
let (message, _error) = err.render_to_string(semi.db);

if err.span().anchor.file_id == semi.hir_file_for(mcall.syntax()) {
let location = err.span().range
+ semi
.db
.ast_id_map(err.span().anchor.file_id.into())
.get_erased(err.span().anchor.ast_id)
.text_range()
.start();
self.emit_parse_error(mcall, &SyntaxError::new(message, location));
};
}
for err in value.value.iter() {
self.emit_parse_error(mcall, err);
}
}
let expand_to = ra_ap_hir_expand::ExpandTo::from_call_site(mcall);
let kind = expanded.kind();
let value: Option<Label<crate::generated::AstNode>> = match expand_to {
ra_ap_hir_expand::ExpandTo::Statements => {
ast::MacroStmts::cast(expanded).map(|x| self.emit_macro_stmts(x).into())
}
ra_ap_hir_expand::ExpandTo::Items => {
ast::MacroItems::cast(expanded).map(|x| self.emit_macro_items(x).into())
}

ra_ap_hir_expand::ExpandTo::Pattern => {
ast::Pat::cast(expanded).map(|x| self.emit_pat(x).into())
}
ra_ap_hir_expand::ExpandTo::Type => {
ast::Type::cast(expanded).map(|x| self.emit_type(x).into())
}
ra_ap_hir_expand::ExpandTo::Expr => {
ast::Expr::cast(expanded).map(|x| self.emit_expr(x).into())
}
};
if let Some(value) = value {
MacroCall::emit_expanded(label, value, &mut self.trap.writer);
} else {
let range = self.text_range_for_node(mcall);
self.emit_parse_error(mcall, &SyntaxError::new(
if let Some(expanded) = self.semantics.as_ref().and_then(|s| s.expand(mcall)) {
self.emit_macro_expansion_parse_errors(mcall, &expanded);
let expand_to = ra_ap_hir_expand::ExpandTo::from_call_site(mcall);
let kind = expanded.kind();
if let Some(value) = self.emit_expanded_as(expand_to, expanded) {
MacroCall::emit_expanded(label, value, &mut self.trap.writer);
} else {
let range = self.text_range_for_node(mcall);
self.emit_parse_error(mcall, &SyntaxError::new(
format!(
"macro expansion failed: the macro '{}' expands to {:?} but a {:?} was expected",
mcall.path().map(|p| p.to_string()).unwrap_or_default(),
kind, expand_to
),
range.unwrap_or_else(|| TextRange::empty(TextSize::from(0))),
));
}
} else {
let range = self.text_range_for_node(mcall);

self.emit_parse_error(
mcall,
&SyntaxError::new(
format!(
"macro expansion failed: could not resolve macro '{}'",
mcall.path().map(|p| p.to_string()).unwrap_or_default()
),
range.unwrap_or_else(|| TextRange::empty(TextSize::from(0))),
),
);
}
} else {
let range = self.text_range_for_node(mcall);
self.emit_parse_error(
mcall,
&SyntaxError::new(
format!(
"macro expansion failed: could not resolve macro '{}'",
mcall.path().map(|p| p.to_string()).unwrap_or_default()
),
range.unwrap_or_else(|| TextRange::empty(TextSize::from(0))),
),
);
}
}
}

0 comments on commit 6ade2a8

Please sign in to comment.