-
Notifications
You must be signed in to change notification settings - Fork 495
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
commit-id:381d1f35
- Loading branch information
Showing
7 changed files
with
524 additions
and
6 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
57 changes: 57 additions & 0 deletions
57
crates/cairo-lang-language-server/src/lang/proc_macros/plugins/downcast.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
use cairo_lang_syntax::node::db::SyntaxGroup; | ||
|
||
use crate::lang::db::AnalysisDatabase; | ||
|
||
/// This function is necessary due to trait bounds that cannot be bypassed in any other way. | ||
/// `generate_code()` takes db: [`&dyn SyntaxGroup`](`SyntaxGroup`), | ||
/// but we need to use | ||
/// [`ProcMacroCacheGroup`](`crate::lang::proc_macros::cache_group::ProcMacroCacheGroup`). To do | ||
/// this, we first convert the `db` reference to its original concrete type that implements both | ||
/// traits [`AnalysisDatabase`]. After this, | ||
/// [`ProcMacroCacheGroup`](`crate::lang::proc_macros::cache_group::ProcMacroCacheGroup`) can be | ||
/// accessed. | ||
/// | ||
/// Safety: This function MUST only be invoked with an object that is of type | ||
/// [AnalysisDatabase]. Using it with any other type leads to undefined behavior. | ||
pub(super) unsafe fn unsafe_downcast_ref(db: &dyn SyntaxGroup) -> &AnalysisDatabase { | ||
// Replicated logic from `impl dyn Any downcast_ref_unchecked()`. | ||
// This approach works as long as `impl dyn Any downcast_ref_unchecked()` implementation is | ||
// unchanged and the caller can ensure that `db` is truly an instance of AnalysisDatabase. | ||
&*(db as *const dyn SyntaxGroup as *const AnalysisDatabase) | ||
} | ||
|
||
#[cfg(test)] | ||
mod unsafe_downcast_ref_tests { | ||
use cairo_lang_macro::TokenStream; | ||
use cairo_lang_syntax::node::db::SyntaxGroup; | ||
use rustc_hash::FxHashMap; | ||
use scarb_proc_macro_server_types::methods::ProcMacroResult; | ||
use scarb_proc_macro_server_types::methods::expand::ExpandAttributeParams; | ||
|
||
use super::unsafe_downcast_ref; | ||
use crate::lang::db::AnalysisDatabase; | ||
use crate::lang::proc_macros::db::ProcMacroCacheGroup; | ||
|
||
#[test] | ||
fn cast_succeed() { | ||
let mut db = AnalysisDatabase::new(&Default::default()); | ||
|
||
let input = ExpandAttributeParams { | ||
attr: "asd".to_string(), | ||
args: TokenStream::new("asd".to_string()), | ||
item: TokenStream::new("asd".to_string()), | ||
}; | ||
let output = ProcMacroResult { | ||
token_stream: TokenStream::new("asd".to_string()), | ||
diagnostics: Default::default(), | ||
}; | ||
let macro_resolution: FxHashMap<_, _> = [(input, output)].into_iter().collect(); | ||
|
||
db.set_attribute_macro_resolution(macro_resolution.clone()); | ||
|
||
let syntax: &dyn SyntaxGroup = &db; | ||
let analysis_db = unsafe { unsafe_downcast_ref(syntax) }; | ||
|
||
assert_eq!(analysis_db.attribute_macro_resolution(), macro_resolution); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
51 changes: 51 additions & 0 deletions
51
crates/cairo-lang-language-server/src/lang/proc_macros/plugins/scarb/inline.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
use cairo_lang_defs::plugin::{InlinePluginResult, PluginGeneratedFile}; | ||
use cairo_lang_filesystem::ids::{CodeMapping, CodeOrigin}; | ||
use cairo_lang_filesystem::span::{TextOffset, TextSpan, TextWidth}; | ||
use cairo_lang_macro::TokenStream; | ||
use cairo_lang_syntax::node::{TypedStablePtr, TypedSyntaxNode, ast}; | ||
use scarb_proc_macro_server_types::methods::expand::ExpandInlineMacroParams; | ||
|
||
use super::{FromSyntaxNode, into_cairo_diagnostics}; | ||
use crate::lang::db::AnalysisDatabase; | ||
use crate::lang::proc_macros::db::ProcMacroCacheGroup; | ||
|
||
// scarb code | ||
|
||
pub fn inline_macro_generate_code( | ||
db: &AnalysisDatabase, | ||
syntax: &ast::ExprInlineMacro, | ||
) -> InlinePluginResult { | ||
let origin = CodeOrigin::Span(syntax.as_syntax_node().span(db)); | ||
let stable_ptr = syntax.clone().stable_ptr().untyped(); | ||
let token_stream = TokenStream::from_syntax_node(db, syntax); | ||
// modified | ||
let result = db.get_inline_macros_expansion(ExpandInlineMacroParams { | ||
name: syntax.path(db).as_syntax_node().get_text(db), | ||
args: token_stream, | ||
}); | ||
// end modified | ||
// Handle diagnostics. | ||
let diagnostics = into_cairo_diagnostics(result.diagnostics, stable_ptr); | ||
let token_stream = result.token_stream.clone(); | ||
if token_stream.is_empty() { | ||
// Remove original code | ||
InlinePluginResult { code: None, diagnostics } | ||
} else { | ||
let content = token_stream.to_string(); | ||
InlinePluginResult { | ||
code: Some(PluginGeneratedFile { | ||
name: "inline_proc_macro".into(), | ||
code_mappings: vec![CodeMapping { | ||
origin, | ||
span: TextSpan { | ||
start: TextOffset::default(), | ||
end: TextOffset::default().add_width(TextWidth::from_str(&content)), | ||
}, | ||
}], | ||
content, | ||
aux_data: None, | ||
}), | ||
diagnostics, | ||
} | ||
} | ||
} |
39 changes: 39 additions & 0 deletions
39
crates/cairo-lang-language-server/src/lang/proc_macros/plugins/scarb/mod.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
use cairo_lang_defs::patcher::PatchBuilder; | ||
use cairo_lang_defs::plugin::PluginDiagnostic; | ||
use cairo_lang_macro::{Severity, TokenStream}; | ||
use cairo_lang_syntax::node::TypedSyntaxNode; | ||
use cairo_lang_syntax::node::db::SyntaxGroup; | ||
use cairo_lang_syntax::node::ids::SyntaxStablePtrId; | ||
|
||
pub mod inline; | ||
pub mod regular; | ||
|
||
// Code from scarb. | ||
trait FromSyntaxNode { | ||
fn from_syntax_node(db: &dyn SyntaxGroup, node: &impl TypedSyntaxNode) -> Self; | ||
} | ||
|
||
impl FromSyntaxNode for TokenStream { | ||
fn from_syntax_node(db: &dyn SyntaxGroup, node: &impl TypedSyntaxNode) -> Self { | ||
let mut builder = PatchBuilder::new(db, node); | ||
builder.add_node(node.as_syntax_node()); | ||
Self::new(builder.build().0) | ||
} | ||
} | ||
|
||
fn into_cairo_diagnostics( | ||
diagnostics: Vec<cairo_lang_macro::Diagnostic>, | ||
stable_ptr: SyntaxStablePtrId, | ||
) -> Vec<PluginDiagnostic> { | ||
diagnostics | ||
.into_iter() | ||
.map(|diag| PluginDiagnostic { | ||
stable_ptr, | ||
message: diag.message, | ||
severity: match diag.severity { | ||
Severity::Error => cairo_lang_diagnostics::Severity::Error, | ||
Severity::Warning => cairo_lang_diagnostics::Severity::Warning, | ||
}, | ||
}) | ||
.collect() | ||
} |
Oops, something went wrong.