-
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.
Code calling dylib is replaced with one calling proc-macro-server. Also `aux_data` is removed as it is useless for LS. commit-id:381d1f35
- Loading branch information
Showing
7 changed files
with
742 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 | ||
/// [`ProcMacroGroup`](`crate::lang::proc_macros::db::ProcMacroGroup`). To do | ||
/// this, we first convert the `db` reference to its original concrete type that implements both | ||
/// traits [`AnalysisDatabase`]. After this, | ||
/// [`ProcMacroGroup`](`crate::lang::proc_macros::db::ProcMacroGroup`) 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::ProcMacroGroup; | ||
|
||
#[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
50 changes: 50 additions & 0 deletions
50
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,50 @@ | ||
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::ProcMacroGroup; | ||
|
||
// https://github.com/software-mansion/scarb/blob/4e81d1c4498137f80e211c6e2c6a5a6de01c66f2/scarb/src/compiler/plugin/proc_macro/host.rs#L1015-L1059 | ||
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); | ||
// region: Modified scarb code | ||
let result = db.get_inline_macros_expansion(ExpandInlineMacroParams { | ||
name: syntax.path(db).as_syntax_node().get_text(db), | ||
args: token_stream, | ||
}); | ||
// endregion | ||
// 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, | ||
} | ||
} | ||
} |
40 changes: 40 additions & 0 deletions
40
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,40 @@ | ||
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; | ||
|
||
// https://github.com/software-mansion/scarb/blob/4e81d1c4498137f80e211c6e2c6a5a6de01c66f2/scarb/src/compiler/plugin/proc_macro/ffi.rs#L30-L40 | ||
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) | ||
} | ||
} | ||
|
||
// https://github.com/software-mansion/scarb/blob/4e81d1c4498137f80e211c6e2c6a5a6de01c66f2/scarb/src/compiler/plugin/proc_macro/host.rs#L1068-L1083 | ||
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.