cairo_lang_parser/
utils.rs1use std::path::PathBuf;
2
3use cairo_lang_diagnostics::{Diagnostics, DiagnosticsBuilder};
4use cairo_lang_filesystem::db::{ExternalFiles, FilesDatabase, FilesGroup, init_files_group};
5use cairo_lang_filesystem::ids::{FileId, FileKind, FileLongId, VirtualFile};
6use cairo_lang_syntax::node::ast::SyntaxFile;
7use cairo_lang_syntax::node::db::{SyntaxDatabase, SyntaxGroup};
8use cairo_lang_syntax::node::{SyntaxNode, TypedSyntaxNode};
9use cairo_lang_utils::{Intern, Upcast};
10
11use crate::ParserDiagnostic;
12use crate::db::ParserDatabase;
13use crate::parser::Parser;
14use crate::types::TokenStream;
15
16#[salsa::database(ParserDatabase, SyntaxDatabase, FilesDatabase)]
18pub struct SimpleParserDatabase {
19 storage: salsa::Storage<SimpleParserDatabase>,
20}
21impl salsa::Database for SimpleParserDatabase {}
22impl ExternalFiles for SimpleParserDatabase {}
23impl Default for SimpleParserDatabase {
24 fn default() -> Self {
25 let mut res = Self { storage: Default::default() };
26 init_files_group(&mut res);
27 res
28 }
29}
30
31impl Upcast<dyn SyntaxGroup> for SimpleParserDatabase {
32 fn upcast(&self) -> &(dyn SyntaxGroup + 'static) {
33 self
34 }
35}
36impl Upcast<dyn FilesGroup> for SimpleParserDatabase {
37 fn upcast(&self) -> &(dyn FilesGroup + 'static) {
38 self
39 }
40}
41
42impl SimpleParserDatabase {
43 pub fn parse_virtual(
50 &self,
51 content: impl ToString,
52 ) -> Result<SyntaxNode, Diagnostics<ParserDiagnostic>> {
53 let (node, diagnostics) = self.parse_virtual_with_diagnostics(content);
54 if diagnostics.check_error_free().is_ok() { Ok(node) } else { Err(diagnostics) }
55 }
56
57 pub fn parse_virtual_with_diagnostics(
62 &self,
63 content: impl ToString,
64 ) -> (SyntaxNode, Diagnostics<ParserDiagnostic>) {
65 let file = FileLongId::Virtual(VirtualFile {
66 parent: None,
67 name: "parser_input".into(),
68 content: content.to_string().into(),
69 code_mappings: [].into(),
70 kind: FileKind::Module,
71 })
72 .intern(self);
73 get_syntax_root_and_diagnostics(self, file, content.to_string().as_str())
74 }
75
76 pub fn parse_token_stream(
80 &self,
81 token_stream: &dyn TokenStream,
82 ) -> (SyntaxNode, Diagnostics<ParserDiagnostic>) {
83 let file_id = FileLongId::Virtual(VirtualFile {
84 parent: Default::default(),
85 name: "token_stream_file_parser_input".into(),
86 content: token_stream.as_str().into(),
87 code_mappings: Default::default(),
88 kind: FileKind::Module,
89 })
90 .intern(self);
91 let mut diagnostics = DiagnosticsBuilder::default();
92
93 (
94 Parser::parse_token_stream(self, &mut diagnostics, file_id, token_stream)
95 .as_syntax_node(),
96 diagnostics.build(),
97 )
98 }
99
100 pub fn parse_token_stream_expr(
103 &self,
104 token_stream: &dyn TokenStream,
105 ) -> (SyntaxNode, Diagnostics<ParserDiagnostic>) {
106 let file_id = FileLongId::Virtual(VirtualFile {
107 parent: Default::default(),
108 name: "token_stream_expr_parser_input".into(),
109 content: Default::default(),
110 code_mappings: Default::default(),
111 kind: FileKind::Module,
112 })
113 .intern(self);
114 let mut diagnostics = DiagnosticsBuilder::default();
115
116 (
117 Parser::parse_token_stream_expr(self, &mut diagnostics, file_id, token_stream)
118 .as_syntax_node(),
119 diagnostics.build(),
120 )
121 }
122}
123
124pub fn get_syntax_root_and_diagnostics_from_file(
126 db: &SimpleParserDatabase,
127 cairo_filepath: PathBuf,
128) -> (SyntaxNode, Diagnostics<ParserDiagnostic>) {
129 let file_id = FileId::new(db, cairo_filepath);
130 let contents = db.file_content(file_id).unwrap();
131 get_syntax_root_and_diagnostics(db, file_id, &contents)
132}
133
134pub fn get_syntax_root_and_diagnostics(
136 db: &SimpleParserDatabase,
137 file_id: FileId,
138 contents: &str,
139) -> (SyntaxNode, Diagnostics<ParserDiagnostic>) {
140 let (syntax_file, diagnostics) = get_syntax_file_and_diagnostics(db, file_id, contents);
141 (syntax_file.as_syntax_node(), diagnostics)
142}
143
144pub fn get_syntax_file_and_diagnostics(
146 db: &SimpleParserDatabase,
147 file_id: FileId,
148 contents: &str,
149) -> (SyntaxFile, Diagnostics<ParserDiagnostic>) {
150 let mut diagnostics = DiagnosticsBuilder::default();
151 let syntax_file = Parser::parse_file(db, &mut diagnostics, file_id, contents);
152 (syntax_file, diagnostics.build())
153}