Rust: macro expansion

This commit is contained in:
Arthur Baars
2024-09-27 16:20:34 +02:00
parent cad2b74137
commit 0b3b95ab54
17 changed files with 427 additions and 31 deletions

View File

@@ -1,2 +1,2 @@
mod.rs 4bcb9def847469aae9d8649461546b7c21ec97cf6e63d3cf394e339915ce65d7 4bcb9def847469aae9d8649461546b7c21ec97cf6e63d3cf394e339915ce65d7
top.rs 00321b829ffca674c66daa86c003b9d5f8c64fef42873d03fa677cfa479039a2 00321b829ffca674c66daa86c003b9d5f8c64fef42873d03fa677cfa479039a2
top.rs bbb8453f35cce3f2afa86b32c01296f78a24c19f504f9416aa049d256d11d23a bbb8453f35cce3f2afa86b32c01296f78a24c19f504f9416aa049d256d11d23a

View File

@@ -8631,6 +8631,12 @@ impl trap::TrapEntry for MacroCall {
}
}
impl MacroCall {
pub fn emit_expanded(id: trap::Label<Self>, value: trap::Label<AstNode>, out: &mut trap::Writer) {
out.add_tuple("macro_call_expandeds", vec![id.into(), value.into()]);
}
}
impl trap::TrapClass for MacroCall {
fn class_name() -> &'static str { "MacroCall" }
}

View File

@@ -1,5 +1,5 @@
use anyhow::Context;
use ra_ap_ide_db::line_index::LineIndex;
use ra_ap_ide_db::line_index::{LineCol, LineIndex};
mod archive;
mod config;
pub mod generated;
@@ -17,10 +17,21 @@ fn extract(
let display_path = file.to_string_lossy();
let mut trap = traps.create("source", &file);
let label = trap.emit_file(&file);
let mut translator = translate::Translator::new(trap, label, line_index, semi);
let mut translator =
translate::Translator::new(trap, display_path.as_ref(), label, line_index, semi);
for err in parse_errors {
translator.emit_parse_error(display_path.as_ref(), err);
translator.emit_parse_error(&err);
}
let no_location = (LineCol { line: 0, col: 0 }, LineCol { line: 0, col: 0 });
if translator.semi.is_none() {
translator.emit_diagnostic(
trap::DiagnosticSeverity::Warning,
"semantics".to_owned(),
"semantic analyzer unavailable".to_owned(),
"semantic analyzer unavailable: macro expansion, call graph, and type inference will be skipped.".to_owned(),
no_location,
);
}
translator.emit_source_file(ast);
translator.trap.commit()?;

View File

@@ -85,11 +85,21 @@ impl RustAnalyzer {
}
}
}
let input = std::fs::read(&path).unwrap();
let mut errors = Vec::new();
let input = match std::fs::read(path) {
Ok(data) => data,
Err(e) => {
errors.push(SyntaxError::new(
format!("Could not read {}: {}", path.to_string_lossy(), e),
TextRange::empty(TextSize::default()),
));
vec![]
}
};
let (input, err) = from_utf8_lossy(&input);
let parse = ra_ap_syntax::ast::SourceFile::parse(&input, Edition::CURRENT);
let mut errors = parse.errors();
errors.extend(err.into_iter());
errors.extend(parse.errors());
errors.extend(err);
(parse.tree(), input.as_ref().into(), errors, None)
}
}

View File

@@ -1,13 +1,18 @@
use crate::generated::{self, AstNode};
use crate::generated::MacroCall;
use crate::generated::{self};
use crate::trap::{DiagnosticSeverity, TrapFile, TrapId};
use crate::trap::{Label, TrapClass};
use codeql_extractor::trap::{self};
use log::Level;
use ra_ap_hir::db::ExpandDatabase;
use ra_ap_hir::Semantics;
use ra_ap_ide_db::line_index::{LineCol, LineIndex};
use ra_ap_ide_db::RootDatabase;
use ra_ap_parser::SyntaxKind;
use ra_ap_syntax::ast::RangeItem;
use ra_ap_syntax::{ast, NodeOrToken, SyntaxElementChildren, SyntaxError, SyntaxToken, TextRange};
use ra_ap_syntax::{
ast, AstNode, NodeOrToken, SyntaxElementChildren, SyntaxError, SyntaxToken, TextRange,
};
pub trait TextValue {
fn try_get_text(&self) -> Option<String>;
}
@@ -60,32 +65,35 @@ impl TextValue for ast::RangePat {
}
pub struct Translator<'a> {
pub trap: TrapFile,
path: &'a str,
label: trap::Label,
line_index: LineIndex,
semi: Option<Semantics<'a, RootDatabase>>,
pub semi: Option<Semantics<'a, RootDatabase>>,
}
impl Translator<'_> {
impl<'a> Translator<'a> {
pub fn new(
trap: TrapFile,
path: &'a str,
label: trap::Label,
line_index: LineIndex,
semi: Option<Semantics<'_, RootDatabase>>,
) -> Translator {
semi: Option<Semantics<'a, RootDatabase>>,
) -> Translator<'a> {
Translator {
trap,
path,
label,
line_index,
semi,
}
}
pub fn location(&self, range: TextRange) -> (LineCol, LineCol) {
fn location(&self, range: TextRange) -> (LineCol, LineCol) {
let start = self.line_index.line_col(range.start());
let range_end = range.end();
// QL end positions are inclusive, while TextRange offsets are exclusive and point at the position
// right after the last character of the range. We need to shift the end offset one character to the left to
// get the right inclusive QL position. Unfortunately, simply subtracting `1` from the end-offset may cause
// the offset to point in the middle of a mult-byte character, resulting in a `panic`. Therefore we use `try_line_col`
// the offset to point in the middle of a multi-byte character, resulting in a `panic`. Therefore we use `try_line_col`
// with decreasing offsets to find the start of the last character included in the range.
for i in 1..4 {
if let Some(end) = range_end
@@ -98,20 +106,60 @@ impl Translator<'_> {
let end = self.line_index.line_col(range_end);
(start, end)
}
pub fn text_range_for_node(&mut self, node: &impl ast::AstNode) -> TextRange {
if let Some(semi) = self.semi.as_ref() {
let file_range = semi.original_range(node.syntax());
file_range.range
} else {
node.syntax().text_range()
}
}
pub fn emit_location<T: TrapClass>(&mut self, label: Label<T>, node: &impl ast::AstNode) {
let (start, end) = self.location(node.syntax().text_range());
let range = self.text_range_for_node(node);
let (start, end) = self.location(range);
self.trap.emit_location(self.label, label, start, end)
}
pub fn emit_location_token(&mut self, label: Label<generated::Token>, token: &SyntaxToken) {
let (start, end) = self.location(token.text_range());
self.trap.emit_location(self.label, label, start, end)
}
pub fn emit_parse_error(&mut self, path: &str, err: SyntaxError) {
let (start, end) = self.location(err.range());
log::warn!("{}:{}:{}: {}", path, start.line + 1, start.col + 1, err);
let message = err.to_string();
pub fn emit_diagnostic(
&mut self,
severity: DiagnosticSeverity,
error_tag: String,
error_message: String,
full_error_message: String,
location: (LineCol, LineCol),
) {
let (start, end) = location;
let level = match severity {
DiagnosticSeverity::Debug => Level::Debug,
DiagnosticSeverity::Info => Level::Info,
DiagnosticSeverity::Warning => Level::Warn,
DiagnosticSeverity::Error => Level::Error,
};
log::log!(
level,
"{}:{}:{}: {}",
self.path,
start.line + 1,
start.col + 1,
&error_message
);
let location = self.trap.emit_location_label(self.label, start, end);
self.trap.emit_diagnostic(
severity,
error_tag,
error_message,
full_error_message,
location,
);
}
pub fn emit_parse_error(&mut self, err: &SyntaxError) {
let location = self.location(err.range());
let message = err.to_string();
self.emit_diagnostic(
DiagnosticSeverity::Warning,
"parse_error".to_owned(),
message.clone(),
@@ -119,7 +167,11 @@ impl Translator<'_> {
location,
);
}
pub fn emit_tokens(&mut self, parent: Label<AstNode>, children: SyntaxElementChildren) {
pub fn emit_tokens(
&mut self,
parent: Label<generated::AstNode>,
children: SyntaxElementChildren,
) {
for child in children {
if let NodeOrToken::Token(token) = child {
if token.kind() == SyntaxKind::COMMENT {
@@ -133,4 +185,83 @@ impl Translator<'_> {
}
}
}
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(&SyntaxError::new(message, location));
};
}
for err in value.value.iter() {
self.emit_parse_error(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(&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,
));
}
} else {
let range = self.text_range_for_node(mcall);
self.emit_parse_error(&SyntaxError::new(
format!(
"macro expansion failed: could not resolve macro '{}'",
mcall.path().map(|p| p.to_string()).unwrap_or_default()
),
range,
));
}
}
}
}

View File

@@ -970,6 +970,7 @@ impl Translator<'_> {
token_tree,
});
self.emit_location(label, &node);
self.extract_macro_call_expanded(&node, label);
self.emit_tokens(label.into(), node.syntax().children_with_tokens());
label
}

View File

@@ -124,7 +124,7 @@ impl<T: TrapClass> From<Label<T>> for trap::Arg {
pub struct TrapFile {
path: PathBuf,
writer: Writer,
pub writer: Writer,
compression: Compression,
}

View File

@@ -64,7 +64,7 @@ lib/codeql/rust/elements/LiteralExpr.qll 40b67404b7c2b81e5afabc53a2a93e0a503f687
lib/codeql/rust/elements/LiteralPat.qll daffb5f380a47543669c8cc92628b0e0de478c3ac82685802c63e8d75a206bed adfe9796598cf6ca4a9170c89ffd871e117f1cea6dd7dd80ecbbb947327a1a5d
lib/codeql/rust/elements/Locatable.qll 2855efa4a469b54e0ca85daa89309a8b991cded6f3f10db361010831ba1e11d3 00c3406d14603f90abea11bf074eaf2c0b623a30e29cf6afc3a247cb58b92f0f
lib/codeql/rust/elements/LoopExpr.qll 58ade0bc4a01a1cc361363682fde3ea56f4c5fbb4b28f5723ceff52ebaf897d7 fa299162c742bcf3b2211dc20821b312e3c133350c288a050eb26e6f8b5a5c78
lib/codeql/rust/elements/MacroCall.qll 16933db15c6c0dbb717ef442f751ad8f63c444f36a12f8d56b8a05a3e5f71d1b ac05cbf50e4b06f39f58817cddbeac6f804c2d1e4f60956a960d63d495e7183d
lib/codeql/rust/elements/MacroCall.qll a39a11d387355f59af3007dcbab3282e2b9e3289c1f8f4c6b96154ddb802f8c3 88d4575e462af2aa780219ba1338a790547fdfc1d267c4b84f1b929f4bc08d05
lib/codeql/rust/elements/MacroDef.qll acb39275a1a3257084314a46ad4d8477946130f57e401c70c5949ad6aafc5c5f 6a8a8db12a3ec345fede51ca36e8c6acbdce58c5144388bb94f0706416fa152a
lib/codeql/rust/elements/MacroExpr.qll ea9fed13f610bab1a2c4541c994510e0cb806530b60beef0d0c36b23e3b620f0 ad11a6bbd3a229ad97a16049cc6b0f3c8740f9f75ea61bbf4eebb072db9b12d2
lib/codeql/rust/elements/MacroItems.qll 4acf8e5ab8f84dc8fae442d52a29266be2f1e7160120bb1dd52238b3d62b4cab 0d6e25bbf1f3082b739bb846d7c3ef21a58c79e6a65b72272a00cffc3d32aa47
@@ -515,7 +515,7 @@ lib/codeql/rust/elements/internal/generated/LiteralExpr.qll f3a564d0a3ed0d915f5a
lib/codeql/rust/elements/internal/generated/LiteralPat.qll ecc2bfe559abfce1be873fbf7b61b5728897c9afc3bb3f69551d8320d273da71 42196fb6a4a0ff9b570fd0bdbc920f24744b3f46772efbb46648af7fbfe1fbda
lib/codeql/rust/elements/internal/generated/Locatable.qll c897dc1bdd4dfcb6ded83a4a93332ca3d8f421bae02493ea2a0555023071775e b32d242f8c9480dc9b53c1e13a5cb8dcfce575b0373991c082c1db460a3e37b8
lib/codeql/rust/elements/internal/generated/LoopExpr.qll 22b755dfaf238ecea722c0c94c399992014e23481ec6fdd61f803bbec012b6f9 08731630c2dc05aa1e0ada222a6057752d9ce737329c62076708828247a358be
lib/codeql/rust/elements/internal/generated/MacroCall.qll 8b49d44e6aeac26dc2fc4b9ba03c482c65ebf0cba089d16f9d65e784e48ccbb0 9ecf6e278007adcbdc42ed1c10e7b1c0652b6c64738b780d256c9326afa3b393
lib/codeql/rust/elements/internal/generated/MacroCall.qll fc8988696493992cc4fdce8c0e5610c54ee92ea52ebb05262338f8b612353f50 188a2d7a484bd402a521787371e64f6e00e928306c8d437e6b19bf890a7aa14e
lib/codeql/rust/elements/internal/generated/MacroDef.qll e9b3f07ba41aa12a8e0bd6ec1437b26a6c363065ce134b6d059478e96c2273a6 87470dea99da1a6afb3a19565291f9382e851ba864b50a995ac6f29589efbd70
lib/codeql/rust/elements/internal/generated/MacroExpr.qll 03a1daa41866f51e479ac20f51f8406d04e9946b24f3875e3cf75a6b172c3d35 1ae8ca0ee96bd2be32575d87c07cc999a6ff7770151b66c0e3406f9454153786
lib/codeql/rust/elements/internal/generated/MacroItems.qll ec02912230762f2759c3ed97ff52fded62ed14fb68d0807c8085a85152a5d4b1 c9cc4f8f0a1d63787995dde173f1bc8ac25351faa66b1d323e2ac1c894c9be85
@@ -541,7 +541,7 @@ lib/codeql/rust/elements/internal/generated/ParamList.qll c808c9d84dd7800573832b
lib/codeql/rust/elements/internal/generated/ParenExpr.qll bc0731505bfe88516205ec360582a4222d2681d11342c93e15258590ddee82f2 d4bd6e0c80cf1d63746c88d4bcb3a01d4c75732e5da09e3ebd9437ced227fb60
lib/codeql/rust/elements/internal/generated/ParenPat.qll ce24b8f8ecbf0f204af200317405724063887257460c80cf250c39b2fdf37185 e7c87d37e1a0ca7ea03840017e1aa9ddb7f927f1f3b6396c0305b46aeee33db6
lib/codeql/rust/elements/internal/generated/ParenType.qll 9cc954d73f8330dcac7b475f97748b63af5c8766dee9d2f2872c0a7e4c903537 c07534c8a9c683c4a9b11d490095647e420de0a0bfc23273eaf6f31b00244273
lib/codeql/rust/elements/internal/generated/ParentChild.qll 3a14261d30beea704042dea144ef1972a93b8384eb258c6f8ff6c8254264c0e2 9fbf1176a5822728097e4c33dfefc057e381c662058b339007bea7273b6b27c6
lib/codeql/rust/elements/internal/generated/ParentChild.qll 8df70abc5ebf6bd1439976404a002b457a006ca677645c970f7e8a23c31b2884 887cf53d918c0825f60b7e7824eefb61f3b7d48a15d73116c42bb67b362cd376
lib/codeql/rust/elements/internal/generated/Pat.qll 3605ac062be2f294ee73336e9669027b8b655f4ad55660e1eab35266275154ee 7f9400db2884d336dd1d21df2a8093759c2a110be9bf6482ce8e80ae0fd74ed4
lib/codeql/rust/elements/internal/generated/Path.qll 299abce24762a5ab023f3cf1ab9718b83047e171aed42a8092e7a155914b1657 db1a23d18640c548f08c9f94823838b5e019ac85877c7b15df2d1493d1846572
lib/codeql/rust/elements/internal/generated/PathExpr.qll 17cdb0a7393258a207450f08e37178fc9d35d167f064ba6015be94246f3dc933 a75fdd280aff6d87e083a92030e041c2eb52b57cf7151d4a6989fcd31d6a64bf
@@ -553,7 +553,7 @@ lib/codeql/rust/elements/internal/generated/PtrType.qll 5f12b6ad29b4e5ce51c205e2
lib/codeql/rust/elements/internal/generated/PureSynthConstructors.qll dc03515d678ba052c2ff2dd9f0883e0bce54cac740ba9a15e5173f292c1b6971 dc03515d678ba052c2ff2dd9f0883e0bce54cac740ba9a15e5173f292c1b6971
lib/codeql/rust/elements/internal/generated/RangeExpr.qll 23cca03bf43535f33b22a38894f70d669787be4e4f5b8fe5c8f7b964d30e9027 18624cef6c6b679eeace2a98737e472432e0ead354cca02192b4d45330f047c9
lib/codeql/rust/elements/internal/generated/RangePat.qll efd93730de217cf50dcba5875595263a5eadf9f7e4e1272401342a094d158614 229b251b3d118932e31e78ac4dfb75f48b766f240f20d436062785606d44467b
lib/codeql/rust/elements/internal/generated/Raw.qll 32faaa3ad1bd2e1bc0d588caed9ef629f1bd3f2cef3d43a2edea7b3c7d14467d a64b8cf08ef39876a7b3e33555c3305cba320d80acc8dead5ec8be6dd1fe225f
lib/codeql/rust/elements/internal/generated/Raw.qll 37d705750dbbcddc20f86d03e98c0b9d381dfe7c050dd48587591ee5e94c7043 5db207a0a9a3b6d537f7ae2829913a5bc7c0fdb5fcc34bd3b3d1b80b748e8c67
lib/codeql/rust/elements/internal/generated/RecordExpr.qll eb6cb662e463f9260efae1a6ce874fa781172063b916ef1963f861e9942d308d 1a21cbccc8f3799ff13281e822818ebfb21d81591720a427cac3625512cb9d40
lib/codeql/rust/elements/internal/generated/RecordExprField.qll 7e9f8663d3b74ebbc9603b10c9912f082febba6bd73d344b100bbd3edf837802 fbe6b578e7fd5d5a6f21bbb8c388957ab7210a6a249ec71510a50fb35b319ea1
lib/codeql/rust/elements/internal/generated/RecordExprFieldList.qll 179a97211fe7aa6265085d4d54115cdbc0e1cd7c9b2135591e8f36d6432f13d3 dd44bbbc1e83a1ed3a587afb729d7debf7aeb7b63245de181726af13090e50c0
@@ -816,8 +816,9 @@ test/extractor-tests/generated/LoopExpr/LoopExpr.ql 636c28bff5f8c1ca0fb834f614b3
test/extractor-tests/generated/LoopExpr/LoopExpr_getAttr.ql d557c1a34ae8762b32702d6b50e79c25bc506275c33a896b6b94bbbe73d04c49 34846c9eefa0219f4a16e28b518b2afa23f372d0aa03b08d042c5a35375e0cd6
test/extractor-tests/generated/LoopExpr/LoopExpr_getLabel.ql 0b77b9d9fb5903d37bce5a2c0d6b276e6269da56fcb37b83cd931872fb88490f c7f09c526e59dcadec13ec9719980d68b8619d630caab2c26b8368b06c1f2cc0
test/extractor-tests/generated/LoopExpr/LoopExpr_getLoopBody.ql 0267f54077640f3dfeb38524577e4a1229115eeb1c839398d0c5f460c1d65129 96ec876635b8c561f7add19e57574444f630eae3df9ab9bc33ac180e61f3a7b8
test/extractor-tests/generated/MacroCall/MacroCall.ql d8b71880ffbfa0f9efa56c598a9bdd3f91e85129e0f8f2b30be6862556f87fcd 682736663ad11f9fdde165904324a8b2f3cdc59f91196a1accb1cd4cf5fb70d4
test/extractor-tests/generated/MacroCall/MacroCall.ql 9eca338d7bc42dcfc3cfcd7953484d724d4f06b1182c01a426925d9963820e37 25fe9e90c38d3bd0c92c70bf2af01b034e3c375f3dbd1c1b8aab1fc1aae09547
test/extractor-tests/generated/MacroCall/MacroCall_getAttr.ql c22a2a29d705e85b03a6586d1eda1a2f4f99f95f7dfeb4e6908ec3188b5ad0ad 9b8d9dcc2116a123c15c520a880efab73ade20e08197c64bc3ed0c50902c4672
test/extractor-tests/generated/MacroCall/MacroCall_getExpanded.ql 757c4a4c32888e4604044c798a3180aa6d4f73381eec9bc28ba9dc71ffcbd03a 27d5edaa2c1096a24c86744aaad0f006da20d5caa28ccfd8528e7c98aa1bead1
test/extractor-tests/generated/MacroCall/MacroCall_getPath.ql 160edc6a001a2d946da6049ffb21a84b9a3756e85f9a2fb0a4d85058124b399a 1e25dd600f19ef89a99f328f86603bce12190220168387c5a88bfb9926da56d9
test/extractor-tests/generated/MacroCall/MacroCall_getTokenTree.ql 1cbf6b1ac7fa0910ff299b939743153fc00ad7e28a9a70c69a8297c6841e8238 570380c0dc4b20fe25c0499378569720a6da14bdb058e73d757e174bdd62d0c0
test/extractor-tests/generated/MacroDef/MacroDef.ql dde2df9196800d9af9645fe21786e30245bff6cfa58117900582ce1f5c0b859d 6b87bec4e4df8e9b6ed09f18e7b7c20204c39c8d249494cc66d3a06ae39791e4

1
rust/ql/.gitattributes generated vendored
View File

@@ -820,6 +820,7 @@
/test/extractor-tests/generated/LoopExpr/LoopExpr_getLoopBody.ql linguist-generated
/test/extractor-tests/generated/MacroCall/MacroCall.ql linguist-generated
/test/extractor-tests/generated/MacroCall/MacroCall_getAttr.ql linguist-generated
/test/extractor-tests/generated/MacroCall/MacroCall_getExpanded.ql linguist-generated
/test/extractor-tests/generated/MacroCall/MacroCall_getPath.ql linguist-generated
/test/extractor-tests/generated/MacroCall/MacroCall_getTokenTree.ql linguist-generated
/test/extractor-tests/generated/MacroDef/MacroDef.ql linguist-generated

View File

@@ -5,6 +5,7 @@
private import internal.MacroCallImpl
import codeql.rust.elements.AssocItem
import codeql.rust.elements.AstNode
import codeql.rust.elements.Attr
import codeql.rust.elements.ExternItem
import codeql.rust.elements.Item

View File

@@ -7,6 +7,7 @@
private import codeql.rust.elements.internal.generated.Synth
private import codeql.rust.elements.internal.generated.Raw
import codeql.rust.elements.internal.AssocItemImpl::Impl as AssocItemImpl
import codeql.rust.elements.AstNode
import codeql.rust.elements.Attr
import codeql.rust.elements.internal.ExternItemImpl::Impl as ExternItemImpl
import codeql.rust.elements.internal.ItemImpl::Impl as ItemImpl
@@ -76,5 +77,20 @@ module Generated {
* Holds if `getTokenTree()` exists.
*/
final predicate hasTokenTree() { exists(this.getTokenTree()) }
/**
* Gets the expanded of this macro call, if it exists.
*/
AstNode getExpanded() {
result =
Synth::convertAstNodeFromRaw(Synth::convertMacroCallToRaw(this)
.(Raw::MacroCall)
.getExpanded())
}
/**
* Holds if `getExpanded()` exists.
*/
final predicate hasExpanded() { exists(this.getExpanded()) }
}
}

View File

@@ -3048,7 +3048,8 @@ private module Impl {
private Element getImmediateChildOfMacroCall(MacroCall e, int index, string partialPredicateCall) {
exists(
int b, int bAssocItem, int bExternItem, int bItem, int n, int nAttr, int nPath, int nTokenTree
int b, int bAssocItem, int bExternItem, int bItem, int n, int nAttr, int nPath,
int nTokenTree, int nExpanded
|
b = 0 and
bAssocItem = b + 1 + max(int i | i = -1 or exists(getImmediateChildOfAssocItem(e, i, _)) | i) and
@@ -3059,6 +3060,7 @@ private module Impl {
nAttr = n + 1 + max(int i | i = -1 or exists(e.getAttr(i)) | i) and
nPath = nAttr + 1 and
nTokenTree = nPath + 1 and
nExpanded = nTokenTree + 1 and
(
none()
or
@@ -3074,6 +3076,8 @@ private module Impl {
index = nAttr and result = e.getPath() and partialPredicateCall = "Path()"
or
index = nPath and result = e.getTokenTree() and partialPredicateCall = "TokenTree()"
or
index = nTokenTree and result = e.getExpanded() and partialPredicateCall = "Expanded()"
)
)
}

View File

@@ -3294,6 +3294,11 @@ module Raw {
* Gets the token tree of this macro call, if it exists.
*/
TokenTree getTokenTree() { macro_call_token_trees(this, result) }
/**
* Gets the expanded of this macro call, if it exists.
*/
AstNode getExpanded() { macro_call_expandeds(this, result) }
}
/**

View File

@@ -2753,6 +2753,12 @@ macro_call_token_trees(
int token_tree: @token_tree ref
);
#keyset[id]
macro_call_expandeds(
int id: @macro_call ref,
int expanded: @ast_node ref
);
macro_defs(
unique int id: @macro_def
);

View File

@@ -2,11 +2,13 @@
import codeql.rust.elements
import TestUtils
from MacroCall x, int getNumberOfAttrs, string hasPath, string hasTokenTree
from MacroCall x, int getNumberOfAttrs, string hasPath, string hasTokenTree, string hasExpanded
where
toBeTested(x) and
not x.isUnknown() and
getNumberOfAttrs = x.getNumberOfAttrs() and
(if x.hasPath() then hasPath = "yes" else hasPath = "no") and
if x.hasTokenTree() then hasTokenTree = "yes" else hasTokenTree = "no"
select x, "getNumberOfAttrs:", getNumberOfAttrs, "hasPath:", hasPath, "hasTokenTree:", hasTokenTree
(if x.hasTokenTree() then hasTokenTree = "yes" else hasTokenTree = "no") and
if x.hasExpanded() then hasExpanded = "yes" else hasExpanded = "no"
select x, "getNumberOfAttrs:", getNumberOfAttrs, "hasPath:", hasPath, "hasTokenTree:", hasTokenTree,
"hasExpanded:", hasExpanded

View File

@@ -0,0 +1,7 @@
// generated by codegen, do not edit
import codeql.rust.elements
import TestUtils
from MacroCall x
where toBeTested(x) and not x.isUnknown()
select x, x.getExpanded()

View File

@@ -24,12 +24,14 @@ class _:
The base class for expressions.
"""
@annotate(Pat)
class _:
"""
The base class for patterns.
"""
@annotate(Label)
class _:
"""
@@ -49,6 +51,7 @@ class _:
The base class for statements.
"""
@annotate(TypeRef)
class _:
"""
@@ -60,6 +63,7 @@ class _:
```
"""
@annotate(Path)
class _:
"""
@@ -69,6 +73,7 @@ class _:
```
"""
@annotate(GenericArgList)
class _:
"""
@@ -78,6 +83,7 @@ class _:
```
"""
@annotate(Function)
@rust.doc_test_signature(None)
class _:
@@ -535,6 +541,7 @@ class _:
```
"""
@annotate(UnderscoreExpr)
class _:
"""
@@ -544,6 +551,7 @@ class _:
```
"""
@annotate(OffsetOfExpr)
class _:
"""
@@ -604,6 +612,7 @@ class _:
```
"""
@annotate(TuplePat)
class _:
"""
@@ -774,6 +783,8 @@ class _:
};
```
"""
@annotate(Abi)
class _:
"""
@@ -782,6 +793,8 @@ class _:
todo!()
```
"""
@annotate(ArgList)
class _:
"""
@@ -790,6 +803,8 @@ class _:
todo!()
```
"""
@annotate(ArrayType)
class _:
"""
@@ -798,6 +813,8 @@ class _:
todo!()
```
"""
@annotate(AssocItem)
class _:
"""
@@ -806,6 +823,8 @@ class _:
todo!()
```
"""
@annotate(AssocItemList)
class _:
"""
@@ -814,6 +833,8 @@ class _:
todo!()
```
"""
@annotate(AssocTypeArg)
class _:
"""
@@ -822,6 +843,8 @@ class _:
todo!()
```
"""
@annotate(Attr)
class _:
"""
@@ -830,6 +853,8 @@ class _:
todo!()
```
"""
@annotate(ClosureBinder)
class _:
"""
@@ -838,6 +863,8 @@ class _:
todo!()
```
"""
@annotate(Const)
class _:
"""
@@ -846,6 +873,8 @@ class _:
todo!()
```
"""
@annotate(ConstArg)
class _:
"""
@@ -854,6 +883,8 @@ class _:
todo!()
```
"""
@annotate(ConstParam)
class _:
"""
@@ -862,6 +893,8 @@ class _:
todo!()
```
"""
@annotate(DynTraitType)
class _:
"""
@@ -870,6 +903,8 @@ class _:
todo!()
```
"""
@annotate(Enum)
class _:
"""
@@ -878,6 +913,8 @@ class _:
todo!()
```
"""
@annotate(ExternBlock)
class _:
"""
@@ -886,6 +923,8 @@ class _:
todo!()
```
"""
@annotate(ExternCrate)
class _:
"""
@@ -894,6 +933,8 @@ class _:
todo!()
```
"""
@annotate(ExternItem)
class _:
"""
@@ -902,6 +943,8 @@ class _:
todo!()
```
"""
@annotate(ExternItemList)
class _:
"""
@@ -910,6 +953,8 @@ class _:
todo!()
```
"""
@annotate(FieldList)
class _:
"""
@@ -918,6 +963,8 @@ class _:
todo!()
```
"""
@annotate(FnPtrType)
class _:
"""
@@ -926,6 +973,8 @@ class _:
todo!()
```
"""
@annotate(ForExpr)
class _:
"""
@@ -934,6 +983,8 @@ class _:
todo!()
```
"""
@annotate(ForType)
class _:
"""
@@ -942,6 +993,8 @@ class _:
todo!()
```
"""
@annotate(FormatArgsArg)
class _:
"""
@@ -950,6 +1003,8 @@ class _:
todo!()
```
"""
@annotate(FormatArgsExpr)
class _:
"""
@@ -958,6 +1013,8 @@ class _:
todo!()
```
"""
@annotate(GenericArg)
class _:
"""
@@ -966,6 +1023,8 @@ class _:
todo!()
```
"""
@annotate(GenericParam)
class _:
"""
@@ -974,6 +1033,8 @@ class _:
todo!()
```
"""
@annotate(GenericParamList)
class _:
"""
@@ -982,6 +1043,8 @@ class _:
todo!()
```
"""
@annotate(Impl)
class _:
"""
@@ -990,6 +1053,8 @@ class _:
todo!()
```
"""
@annotate(ImplTraitType)
class _:
"""
@@ -998,6 +1063,8 @@ class _:
todo!()
```
"""
@annotate(InferType)
class _:
"""
@@ -1006,6 +1073,8 @@ class _:
todo!()
```
"""
@annotate(Item)
class _:
"""
@@ -1014,6 +1083,8 @@ class _:
todo!()
```
"""
@annotate(ItemList)
class _:
"""
@@ -1022,6 +1093,8 @@ class _:
todo!()
```
"""
@annotate(LetElse)
class _:
"""
@@ -1030,6 +1103,8 @@ class _:
todo!()
```
"""
@annotate(Lifetime)
class _:
"""
@@ -1038,6 +1113,8 @@ class _:
todo!()
```
"""
@annotate(LifetimeArg)
class _:
"""
@@ -1046,6 +1123,8 @@ class _:
todo!()
```
"""
@annotate(LifetimeParam)
class _:
"""
@@ -1054,6 +1133,8 @@ class _:
todo!()
```
"""
@annotate(MacroCall)
class _:
"""
@@ -1062,6 +1143,9 @@ class _:
todo!()
```
"""
expanded: optional[AstNode] | child | rust.detach
@annotate(MacroDef)
class _:
"""
@@ -1070,6 +1154,8 @@ class _:
todo!()
```
"""
@annotate(MacroExpr)
class _:
"""
@@ -1078,6 +1164,8 @@ class _:
todo!()
```
"""
@annotate(MacroPat)
class _:
"""
@@ -1086,6 +1174,8 @@ class _:
todo!()
```
"""
@annotate(MacroRules)
class _:
"""
@@ -1094,6 +1184,8 @@ class _:
todo!()
```
"""
@annotate(MacroType)
class _:
"""
@@ -1102,6 +1194,8 @@ class _:
todo!()
```
"""
@annotate(MatchArmList)
class _:
"""
@@ -1110,6 +1204,8 @@ class _:
todo!()
```
"""
@annotate(MatchGuard)
class _:
"""
@@ -1118,6 +1214,8 @@ class _:
todo!()
```
"""
@annotate(Meta)
class _:
"""
@@ -1126,6 +1224,8 @@ class _:
todo!()
```
"""
@annotate(Name)
class _:
"""
@@ -1134,6 +1234,8 @@ class _:
todo!()
```
"""
@annotate(NameRef)
class _:
"""
@@ -1142,6 +1244,8 @@ class _:
todo!()
```
"""
@annotate(NeverType)
class _:
"""
@@ -1150,6 +1254,8 @@ class _:
todo!()
```
"""
@annotate(Param)
class _:
"""
@@ -1158,6 +1264,8 @@ class _:
todo!()
```
"""
@annotate(ParamList)
class _:
"""
@@ -1166,6 +1274,8 @@ class _:
todo!()
```
"""
@annotate(ParenExpr)
class _:
"""
@@ -1174,6 +1284,8 @@ class _:
todo!()
```
"""
@annotate(ParenPat)
class _:
"""
@@ -1182,6 +1294,8 @@ class _:
todo!()
```
"""
@annotate(ParenType)
class _:
"""
@@ -1190,6 +1304,8 @@ class _:
todo!()
```
"""
@annotate(PathSegment)
class _:
"""
@@ -1198,6 +1314,8 @@ class _:
todo!()
```
"""
@annotate(PathType)
class _:
"""
@@ -1206,6 +1324,8 @@ class _:
todo!()
```
"""
@annotate(PtrType)
class _:
"""
@@ -1214,6 +1334,8 @@ class _:
todo!()
```
"""
@annotate(RecordExprFieldList)
class _:
"""
@@ -1222,6 +1344,8 @@ class _:
todo!()
```
"""
@annotate(RecordField)
class _:
"""
@@ -1230,6 +1354,8 @@ class _:
todo!()
```
"""
@annotate(RecordFieldList)
class _:
"""
@@ -1238,6 +1364,8 @@ class _:
todo!()
```
"""
@annotate(RecordPatFieldList)
class _:
"""
@@ -1246,6 +1374,8 @@ class _:
todo!()
```
"""
@annotate(RefType)
class _:
"""
@@ -1254,6 +1384,8 @@ class _:
todo!()
```
"""
@annotate(Rename)
class _:
"""
@@ -1262,6 +1394,8 @@ class _:
todo!()
```
"""
@annotate(RestPat)
class _:
"""
@@ -1270,6 +1404,8 @@ class _:
todo!()
```
"""
@annotate(RetType)
class _:
"""
@@ -1278,6 +1414,8 @@ class _:
todo!()
```
"""
@annotate(ReturnTypeSyntax)
class _:
"""
@@ -1286,6 +1424,8 @@ class _:
todo!()
```
"""
@annotate(SelfParam)
class _:
"""
@@ -1294,6 +1434,8 @@ class _:
todo!()
```
"""
@annotate(SliceType)
class _:
"""
@@ -1302,6 +1444,8 @@ class _:
todo!()
```
"""
@annotate(SourceFile)
class _:
"""
@@ -1310,6 +1454,8 @@ class _:
todo!()
```
"""
@annotate(Static)
class _:
"""
@@ -1318,6 +1464,8 @@ class _:
todo!()
```
"""
@annotate(StmtList)
class _:
"""
@@ -1326,6 +1474,8 @@ class _:
todo!()
```
"""
@annotate(Struct)
class _:
"""
@@ -1334,6 +1484,8 @@ class _:
todo!()
```
"""
@annotate(TokenTree)
class _:
"""
@@ -1342,6 +1494,8 @@ class _:
todo!()
```
"""
@annotate(Trait)
class _:
"""
@@ -1350,6 +1504,8 @@ class _:
todo!()
```
"""
@annotate(TraitAlias)
class _:
"""
@@ -1358,6 +1514,8 @@ class _:
todo!()
```
"""
@annotate(TryExpr)
class _:
"""
@@ -1366,6 +1524,8 @@ class _:
todo!()
```
"""
@annotate(TupleField)
class _:
"""
@@ -1374,6 +1534,8 @@ class _:
todo!()
```
"""
@annotate(TupleFieldList)
class _:
"""
@@ -1382,6 +1544,8 @@ class _:
todo!()
```
"""
@annotate(TupleType)
class _:
"""
@@ -1390,6 +1554,8 @@ class _:
todo!()
```
"""
@annotate(TypeAlias)
class _:
"""
@@ -1398,6 +1564,8 @@ class _:
todo!()
```
"""
@annotate(TypeArg)
class _:
"""
@@ -1406,6 +1574,8 @@ class _:
todo!()
```
"""
@annotate(TypeBound)
class _:
"""
@@ -1414,6 +1584,8 @@ class _:
todo!()
```
"""
@annotate(TypeBoundList)
class _:
"""
@@ -1422,6 +1594,8 @@ class _:
todo!()
```
"""
@annotate(TypeParam)
class _:
"""
@@ -1430,6 +1604,8 @@ class _:
todo!()
```
"""
@annotate(Union)
class _:
"""
@@ -1438,6 +1614,8 @@ class _:
todo!()
```
"""
@annotate(Use)
class _:
"""
@@ -1446,6 +1624,8 @@ class _:
todo!()
```
"""
@annotate(UseTree)
class _:
"""
@@ -1454,6 +1634,8 @@ class _:
todo!()
```
"""
@annotate(UseTreeList)
class _:
"""
@@ -1462,6 +1644,8 @@ class _:
todo!()
```
"""
@annotate(Variant)
class _:
"""
@@ -1470,6 +1654,8 @@ class _:
todo!()
```
"""
@annotate(VariantList)
class _:
"""
@@ -1478,6 +1664,8 @@ class _:
todo!()
```
"""
@annotate(Visibility)
class _:
"""
@@ -1486,6 +1674,8 @@ class _:
todo!()
```
"""
@annotate(WhereClause)
class _:
"""
@@ -1494,6 +1684,8 @@ class _:
todo!()
```
"""
@annotate(WherePred)
class _:
"""
@@ -1502,6 +1694,8 @@ class _:
todo!()
```
"""
@annotate(WhileExpr)
class _:
"""