1pub mod rules;
2pub mod structs;
3
4use flams_math_archives::backend::AnyBackend;
5use flams_utils::{
6 prelude::{TreeChild, TreeLike},
7 sourcerefs::{LSPLineCol, StringRange},
8 vecmap::VecSet,
9};
10use ftml_ontology::narrative::elements::{paragraphs::ParagraphKind, problems::CognitiveDimension};
11use ftml_solver::results::DocumentCheckResult;
12use ftml_uris::{
13 ArchiveId, DocumentElementUri, DocumentUri, Language, ModuleUri, SymbolUri, UriName,
14 UriWithArchive,
15};
16use rules::{
17 MathStructureArg, MathStructureArgIter, NotationArg, NotationArgIter, ParagraphArg,
18 ParagraphArgIter, ProblemArg, ProblemArgIter, SModuleArg, SModuleArgIter, SymdeclArg,
19 SymdeclArgIter, SymdefArg, SymdefArgIter, TextSymdeclArg, TextSymdeclArgIter, VardefArg,
20 VardefArgIter,
21};
22use smallvec::SmallVec;
23use std::path::Path;
24use structs::{
25 InlineMorphAssIter, InlineMorphAssign, ModuleOrStruct, ModuleReference, ModuleRules,
26 MorphismKind, STeXModuleStore, STeXParseState, STeXToken, SymbolReference, SymnameMode,
27};
28
29use crate::quickparse::stex::rules::{
30 IncludeProblemArg, MHGraphicsArg, SRefOptsA, SRefOptsAIter, SRefOptsB, SRefOptsBIter,
31};
32
33use super::latex::LaTeXParser;
34
35#[derive(Default, Debug)]
36pub struct STeXParseDataI {
37 pub annotations: Vec<STeXAnnot>,
38 pub diagnostics: VecSet<STeXDiagnostic>,
39 pub check: Option<DocumentCheckResult>,
40 pub modules: SmallVec<(ModuleUri, ModuleRules<LSPLineCol>), 1>,
41 pub dependencies: Vec<std::sync::Arc<Path>>,
42}
43impl STeXParseDataI {
44 #[inline]
45 #[must_use]
46 pub fn lock(self) -> STeXParseData {
47 flams_utils::triomphe::Arc::new(parking_lot::Mutex::new(self))
48 }
49 #[inline]
50 pub fn replace(self, old: &STeXParseData) {
51 *old.lock() = self;
52 }
53 #[inline]
54 #[must_use]
55 pub const fn is_empty(&self) -> bool {
56 self.annotations.is_empty() && self.diagnostics.is_empty()
57 }
58}
59
60pub type STeXParseData = flams_utils::triomphe::Arc<parking_lot::Mutex<STeXParseDataI>>;
61
62#[allow(clippy::large_enum_variant)]
63#[derive(Debug, Clone, serde::Serialize)]
64pub enum STeXAnnot {
65 Module {
66 uri: ModuleUri,
67 name_range: StringRange<LSPLineCol>,
68 opts: Vec<SModuleArg<LSPLineCol, Self>>,
69 sig: Option<Language>,
70 meta_theory: Option<ModuleReference>,
71 full_range: StringRange<LSPLineCol>,
72 smodule_range: StringRange<LSPLineCol>,
73 children: Vec<Self>,
74 },
75 MathStructure {
76 uri: SymbolReference<LSPLineCol>,
77 extends: Vec<(SymbolReference<LSPLineCol>, StringRange<LSPLineCol>)>,
78 name_range: StringRange<LSPLineCol>,
79 opts: Vec<MathStructureArg<LSPLineCol, Self>>,
80 full_range: StringRange<LSPLineCol>,
81 children: Vec<Self>,
82 mathstructure_range: StringRange<LSPLineCol>,
83 },
84 ConservativeExt {
85 uri: SymbolReference<LSPLineCol>,
86 ext_range: StringRange<LSPLineCol>,
87 full_range: StringRange<LSPLineCol>,
88 extstructure_range: StringRange<LSPLineCol>,
89 children: Vec<Self>,
90 },
91 MorphismEnv {
92 full_range: StringRange<LSPLineCol>,
93 name_range: StringRange<LSPLineCol>,
94 env_range: StringRange<LSPLineCol>,
95 uri: SymbolUri,
96 star: bool,
97 domain: ModuleOrStruct<LSPLineCol>,
98 domain_range: StringRange<LSPLineCol>,
99 kind: MorphismKind,
100 children: Vec<Self>,
101 },
102 InlineMorphism {
103 full_range: StringRange<LSPLineCol>,
104 token_range: StringRange<LSPLineCol>,
105 name_range: StringRange<LSPLineCol>,
106 uri: SymbolUri,
107 domain: ModuleOrStruct<LSPLineCol>,
108 domain_range: StringRange<LSPLineCol>,
109 kind: MorphismKind,
110 assignments: Vec<InlineMorphAssign<LSPLineCol, Self>>,
111 },
112 SemanticMacro {
113 uri: SymbolReference<LSPLineCol>,
114 argnum: u8,
115 token_range: StringRange<LSPLineCol>,
116 full_range: StringRange<LSPLineCol>,
117 },
118 VariableMacro {
119 name: UriName,
120 argnum: u8,
121 orig: StringRange<LSPLineCol>,
122 sequence: bool,
123 token_range: StringRange<LSPLineCol>,
124 full_range: StringRange<LSPLineCol>,
125 },
126 Svar {
127 name: UriName,
128 token_range: StringRange<LSPLineCol>,
129 full_range: StringRange<LSPLineCol>,
130 arg_range: StringRange<LSPLineCol>,
131 name_range: Option<StringRange<LSPLineCol>>,
132 },
133 ImportModule {
134 archive_range: Option<StringRange<LSPLineCol>>,
135 path_range: StringRange<LSPLineCol>,
136 module: ModuleReference,
137 token_range: StringRange<LSPLineCol>,
138 full_range: StringRange<LSPLineCol>,
139 },
140 UseModule {
141 archive_range: Option<StringRange<LSPLineCol>>,
142 path_range: StringRange<LSPLineCol>,
143 module: ModuleReference,
144 token_range: StringRange<LSPLineCol>,
145 full_range: StringRange<LSPLineCol>,
146 },
147 UseStructure {
148 structure: SymbolReference<LSPLineCol>,
149 structure_range: StringRange<LSPLineCol>,
150 token_range: StringRange<LSPLineCol>,
151 full_range: StringRange<LSPLineCol>,
152 },
153 SetMetatheory {
154 archive_range: Option<StringRange<LSPLineCol>>,
155 path_range: StringRange<LSPLineCol>,
156 module: ModuleReference,
157 token_range: StringRange<LSPLineCol>,
158 full_range: StringRange<LSPLineCol>,
159 },
160 Inputref {
161 archive: Option<(ArchiveId, StringRange<LSPLineCol>)>,
162 filepath: (std::sync::Arc<str>, StringRange<LSPLineCol>),
163 token_range: StringRange<LSPLineCol>,
164 full_range: StringRange<LSPLineCol>,
165 },
166 MHInput {
167 archive: Option<(ArchiveId, StringRange<LSPLineCol>)>,
168 filepath: (std::sync::Arc<str>, StringRange<LSPLineCol>),
169 token_range: StringRange<LSPLineCol>,
170 full_range: StringRange<LSPLineCol>,
171 },
172 #[allow(clippy::type_complexity)]
173 Symdecl {
174 uri: SymbolReference<LSPLineCol>,
175 main_name_range: StringRange<LSPLineCol>,
176 parsed_args: Vec<SymdeclArg<LSPLineCol, Self>>,
177 token_range: StringRange<LSPLineCol>,
178 full_range: StringRange<LSPLineCol>,
179 starred: bool,
180 },
181 #[allow(clippy::type_complexity)]
182 TextSymdecl {
183 uri: SymbolReference<LSPLineCol>,
184 main_name_range: StringRange<LSPLineCol>,
185 parsed_args: Vec<TextSymdeclArg<LSPLineCol, Self>>,
186 token_range: StringRange<LSPLineCol>,
187 full_range: StringRange<LSPLineCol>,
188 },
189 Notation {
190 uri: SmallVec<SymbolReference<LSPLineCol>, 1>,
191 token_range: StringRange<LSPLineCol>,
192 name_range: StringRange<LSPLineCol>,
193 notation_args: Vec<NotationArg<LSPLineCol, Self>>,
194 full_range: StringRange<LSPLineCol>,
195 },
196 RenameDecl {
197 uri: SymbolReference<LSPLineCol>,
198 token_range: StringRange<LSPLineCol>,
199 orig_range: StringRange<LSPLineCol>,
200 name_range: Option<StringRange<LSPLineCol>>,
201 macroname_range: StringRange<LSPLineCol>,
202 full_range: StringRange<LSPLineCol>,
203 },
204 Assign {
205 uri: SymbolReference<LSPLineCol>,
206 token_range: StringRange<LSPLineCol>,
207 orig_range: StringRange<LSPLineCol>,
208 full_range: StringRange<LSPLineCol>,
209 },
210 #[allow(clippy::type_complexity)]
211 Symdef {
212 uri: SymbolReference<LSPLineCol>,
213 main_name_range: StringRange<LSPLineCol>,
214 parsed_args: Vec<SymdefArg<LSPLineCol, Self>>,
215 token_range: StringRange<LSPLineCol>,
216 full_range: StringRange<LSPLineCol>,
217 },
218 #[allow(clippy::type_complexity)]
219 Vardef {
220 name: UriName,
221 main_name_range: StringRange<LSPLineCol>,
222 parsed_args: Vec<VardefArg<LSPLineCol, Self>>,
223 token_range: StringRange<LSPLineCol>,
224 full_range: StringRange<LSPLineCol>,
225 },
226 #[allow(clippy::type_complexity)]
227 Varseq {
228 name: UriName,
229 main_name_range: StringRange<LSPLineCol>,
230 parsed_args: Vec<VardefArg<LSPLineCol, Self>>,
231 token_range: StringRange<LSPLineCol>,
232 full_range: StringRange<LSPLineCol>,
233 },
234 SymName {
235 is_def: bool,
236 uri: SmallVec<SymbolReference<LSPLineCol>, 1>,
237 full_range: StringRange<LSPLineCol>,
238 token_range: StringRange<LSPLineCol>,
239 name_range: StringRange<LSPLineCol>,
240 mode: SymnameMode<LSPLineCol>,
241 },
242 IncludeProblem {
243 filepath: (std::sync::Arc<str>, StringRange<LSPLineCol>),
244 archive: Option<(ArchiveId, StringRange<LSPLineCol>)>,
245 full_range: StringRange<LSPLineCol>,
246 token_range: StringRange<LSPLineCol>,
247 args: Vec<IncludeProblemArg<LSPLineCol>>,
248 },
249 Symuse {
250 uri: SmallVec<SymbolReference<LSPLineCol>, 1>,
251 full_range: StringRange<LSPLineCol>,
252 token_range: StringRange<LSPLineCol>,
253 name_range: StringRange<LSPLineCol>,
254 },
255 Symref {
256 is_def: bool,
257 uri: SmallVec<SymbolReference<LSPLineCol>, 1>,
258 full_range: StringRange<LSPLineCol>,
259 token_range: StringRange<LSPLineCol>,
260 name_range: StringRange<LSPLineCol>,
261 text: (StringRange<LSPLineCol>, Vec<Self>),
262 },
263 Definiens {
264 uri: SmallVec<SymbolReference<LSPLineCol>, 1>,
265 full_range: StringRange<LSPLineCol>,
266 token_range: StringRange<LSPLineCol>,
267 name_range: Option<StringRange<LSPLineCol>>,
268 },
269 Defnotation {
270 full_range: StringRange<LSPLineCol>,
271 },
272 Paragraph {
273 kind: ParagraphKind,
274 full_range: StringRange<LSPLineCol>,
275 name_range: StringRange<LSPLineCol>,
276 symbol: Option<SymbolReference<LSPLineCol>>,
277 parsed_args: Vec<ParagraphArg<LSPLineCol, Self>>,
278 children: Vec<Self>,
279 },
280 Problem {
281 sub: bool,
282 full_range: StringRange<LSPLineCol>,
283 name_range: StringRange<LSPLineCol>,
284 parsed_args: Vec<ProblemArg<LSPLineCol, Self>>,
285 children: Vec<Self>,
286 },
287 Precondition {
288 uri: SmallVec<SymbolReference<LSPLineCol>, 1>,
289 full_range: StringRange<LSPLineCol>,
290 token_range: StringRange<LSPLineCol>,
291 dim_range: StringRange<LSPLineCol>,
292 symbol_range: StringRange<LSPLineCol>,
293 dim: CognitiveDimension,
294 },
295 Objective {
296 uri: SmallVec<SymbolReference<LSPLineCol>, 1>,
297 full_range: StringRange<LSPLineCol>,
298 token_range: StringRange<LSPLineCol>,
299 dim_range: StringRange<LSPLineCol>,
300 symbol_range: StringRange<LSPLineCol>,
301 dim: CognitiveDimension,
302 },
303 InlineParagraph {
304 kind: ParagraphKind,
305 full_range: StringRange<LSPLineCol>,
306 token_range: StringRange<LSPLineCol>,
307 symbol: Option<SymbolReference<LSPLineCol>>,
308 parsed_args: Vec<ParagraphArg<LSPLineCol, Self>>,
309 children: Vec<Self>,
310 children_range: StringRange<LSPLineCol>,
311 },
312 MHGraphics {
313 filepath: (std::sync::Arc<str>, StringRange<LSPLineCol>),
314 archive: Option<(ArchiveId, StringRange<LSPLineCol>)>,
315 full_range: StringRange<LSPLineCol>,
316 token_range: StringRange<LSPLineCol>,
317 args: Vec<MHGraphicsArg<LSPLineCol>>,
318 },
319 SRef {
320 full_range: StringRange<LSPLineCol>,
321 token_range: StringRange<LSPLineCol>,
322 opt_args: Vec<SRefOptsA<LSPLineCol, Self>>,
323 label_range: StringRange<LSPLineCol>,
324 in_opt_args: Vec<SRefOptsB<LSPLineCol, Self>>,
325 target: DocumentElementUri,
326 target_path: std::sync::Arc<Path>,
327 in_doc: Option<(DocumentUri, std::sync::Arc<Path>)>,
328 },
329 SnifySuggestion {
330 range: StringRange<LSPLineCol>,
331 symbols: SmallVec<(SymbolUri, bool), 1>,
332 },
333}
334impl STeXAnnot {
335 #[allow(clippy::too_many_lines)]
336 fn from_tokens<I: IntoIterator<Item = STeXToken<LSPLineCol>>>(
337 iter: I,
338 mut modules: Option<&mut SmallVec<(ModuleUri, ModuleRules<LSPLineCol>), 1>>,
339 ) -> Vec<Self> {
340 let mut v = Vec::new();
341 macro_rules! cont {
342 ($e:ident) => { $e.into_iter().map(|o| o.into_other(cont!(+))).collect() };
343 (+) => { |v| Self::from_tokens(v,if let Some(m) = modules.as_mut() { Some(*m) } else { None }) };
344 }
345 for t in iter {
346 match t {
347 STeXToken::SnifySuggestion { range, symbols } => {
348 v.push(Self::SnifySuggestion { range, symbols })
349 }
350 STeXToken::Module {
351 uri,
352 name_range,
353 sig,
354 meta_theory,
355 full_range,
356 smodule_range,
357 children,
358 rules,
359 opts,
360 } => {
361 if let Some(ref mut m) = modules {
362 m.push((uri.clone(), rules));
363 }
364 v.push(Self::Module {
365 uri,
366 name_range,
367 sig,
368 meta_theory,
369 full_range,
370 smodule_range,
371 opts: cont!(opts),
372 children: Self::from_tokens(children, None),
373 });
374 }
375 STeXToken::SRef {
376 full_range,
377 token_range,
378 opt_args,
379 label_range,
380 in_opt_args,
381 target,
382 target_path,
383 in_doc,
384 } => v.push(Self::SRef {
385 full_range,
386 token_range,
387 opt_args: cont!(opt_args),
388 label_range,
389 in_opt_args: cont!(in_opt_args),
390 target,
391 target_path,
392 in_doc,
393 }),
394 STeXToken::MHGraphics {
395 filepath,
396 archive,
397 full_range,
398 token_range,
399 args,
400 } => v.push(Self::MHGraphics {
401 filepath,
402 archive,
403 full_range,
404 token_range,
405 args,
406 }),
407 STeXToken::UseStructure {
408 structure,
409 structure_range,
410 full_range,
411 token_range,
412 } => v.push(Self::UseStructure {
413 structure,
414 structure_range,
415 full_range,
416 token_range,
417 }),
418 STeXToken::ConservativeExt {
419 uri,
420 ext_range,
421 full_range,
422 children,
423 extstructure_range,
424 } => v.push(Self::ConservativeExt {
425 uri,
426 ext_range,
427 full_range,
428 children: Self::from_tokens(children, None),
429 extstructure_range,
430 }),
431 STeXToken::MathStructure {
432 uri,
433 extends,
434 name_range,
435 opts,
436 full_range,
437 children,
438 mathstructure_range,
439 ..
440 } => {
441 v.push(Self::MathStructure {
442 uri,
443 extends,
444 name_range,
445 opts: cont!(opts),
446 full_range,
447 children: Self::from_tokens(children, None),
448 mathstructure_range,
449 });
450 }
451 STeXToken::MorphismEnv {
452 uri,
453 star,
454 env_range,
455 full_range,
456 children,
457 name_range,
458 domain,
459 domain_range,
460 kind,
461 ..
462 } => v.push(Self::MorphismEnv {
463 uri,
464 env_range,
465 star,
466 full_range,
467 children: Self::from_tokens(children, None),
468 name_range,
469 domain,
470 domain_range,
471 kind,
472 }),
473 STeXToken::InlineMorphism {
474 full_range,
475 token_range,
476 name_range,
477 uri,
478 domain,
479 domain_range,
480 kind,
481 assignments,
482 ..
483 } => v.push(Self::InlineMorphism {
484 full_range,
485 token_range,
486 name_range,
487 uri,
488 domain,
489 domain_range,
490 kind,
491 assignments: cont!(assignments),
492 }),
493 STeXToken::SemanticMacro {
494 uri,
495 argnum,
496 token_range,
497 full_range,
498 } => v.push(Self::SemanticMacro {
499 uri,
500 argnum,
501 token_range,
502 full_range,
503 }),
504 STeXToken::VariableMacro {
505 name,
506 sequence,
507 argnum,
508 orig,
509 token_range,
510 full_range,
511 } => v.push(Self::VariableMacro {
512 name,
513 argnum,
514 sequence,
515 orig,
516 token_range,
517 full_range,
518 }),
519 STeXToken::Svar {
520 name,
521 full_range,
522 token_range,
523 name_range,
524 arg_range,
525 } => v.push(Self::Svar {
526 name,
527 full_range,
528 token_range,
529 name_range,
530 arg_range,
531 }),
532 STeXToken::ImportModule {
533 archive_range,
534 path_range,
535 module,
536 token_range,
537 full_range,
538 } => v.push(Self::ImportModule {
539 archive_range,
540 path_range,
541 module,
542 token_range,
543 full_range,
544 }),
545 STeXToken::UseModule {
546 archive_range,
547 path_range,
548 module,
549 token_range,
550 full_range,
551 } => v.push(Self::UseModule {
552 archive_range,
553 path_range,
554 module,
555 token_range,
556 full_range,
557 }),
558 STeXToken::IncludeProblem {
559 filepath,
560 full_range,
561 token_range,
562 archive,
563 args,
564 } => v.push(Self::IncludeProblem {
565 filepath,
566 archive,
567 full_range,
568 token_range,
569 args,
570 }),
571 STeXToken::SetMetatheory {
572 archive_range,
573 path_range,
574 module,
575 token_range,
576 full_range,
577 } => v.push(Self::SetMetatheory {
578 archive_range,
579 path_range,
580 module,
581 token_range,
582 full_range,
583 }),
584 STeXToken::Inputref {
585 archive,
586 filepath,
587 token_range,
588 full_range,
589 } => v.push(Self::Inputref {
590 archive,
591 filepath,
592 token_range,
593 full_range,
594 }),
595 STeXToken::MHInput {
596 archive,
597 filepath,
598 token_range,
599 full_range,
600 } => v.push(Self::MHInput {
601 archive,
602 filepath,
603 token_range,
604 full_range,
605 }),
606 STeXToken::Symdecl {
607 uri,
608 main_name_range,
609 token_range,
610 full_range,
611 parsed_args,
612 starred,
613 } => v.push(Self::Symdecl {
614 uri,
615 main_name_range,
616 token_range,
617 full_range,
618 starred,
619 parsed_args: cont!(parsed_args),
620 }),
621 STeXToken::TextSymdecl {
622 uri,
623 main_name_range,
624 full_range,
625 parsed_args,
626 token_range,
627 } => v.push(Self::TextSymdecl {
628 uri,
629 main_name_range,
630 full_range,
631 token_range,
632 parsed_args: cont!(parsed_args),
633 }),
634 STeXToken::Definiens {
635 uri,
636 full_range,
637 token_range,
638 name_range,
639 } => v.push(Self::Definiens {
640 uri,
641 full_range,
642 token_range,
643 name_range,
644 }),
645 STeXToken::Defnotation { full_range } => {
646 v.push(Self::Defnotation { full_range });
647 }
648 STeXToken::Notation {
649 uri,
650 token_range,
651 name_range,
652 notation_args,
653 full_range,
654 } => v.push(Self::Notation {
655 uri,
656 token_range,
657 name_range,
658 full_range,
659 notation_args: cont!(notation_args),
660 }),
661 STeXToken::Symdef {
662 uri,
663 main_name_range,
664 token_range,
665 full_range,
666 parsed_args,
667 } => v.push(Self::Symdef {
668 uri,
669 main_name_range,
670 token_range,
671 full_range,
672 parsed_args: cont!(parsed_args),
673 }),
674 STeXToken::Vardef {
675 name,
676 main_name_range,
677 token_range,
678 full_range,
679 parsed_args,
680 } => v.push(Self::Vardef {
681 name,
682 main_name_range,
683 token_range,
684 full_range,
685 parsed_args: cont!(parsed_args),
686 }),
687 STeXToken::Varseq {
688 name,
689 main_name_range,
690 token_range,
691 full_range,
692 parsed_args,
693 } => v.push(Self::Varseq {
694 name,
695 main_name_range,
696 token_range,
697 full_range,
698 parsed_args: cont!(parsed_args),
699 }),
700 STeXToken::Symref {
701 uri,
702 is_def,
703 full_range,
704 token_range,
705 name_range,
706 text,
707 } => v.push(Self::Symref {
708 uri,
709 is_def,
710 full_range,
711 token_range,
712 name_range,
713 text: (text.0, Self::from_tokens(text.1, None)),
714 }),
715 STeXToken::Precondition {
716 uri,
717 full_range,
718 token_range,
719 dim_range,
720 symbol_range,
721 dim,
722 } => v.push(Self::Precondition {
723 uri,
724 full_range,
725 token_range,
726 dim_range,
727 symbol_range,
728 dim,
729 }),
730 STeXToken::Objective {
731 uri,
732 full_range,
733 token_range,
734 dim_range,
735 symbol_range,
736 dim,
737 } => v.push(Self::Objective {
738 uri,
739 full_range,
740 token_range,
741 dim_range,
742 symbol_range,
743 dim,
744 }),
745 STeXToken::SymName {
746 uri,
747 is_def,
748 full_range,
749 token_range,
750 name_range,
751 mode: mod_,
752 } => v.push(Self::SymName {
753 uri,
754 is_def,
755 full_range,
756 token_range,
757 name_range,
758 mode: mod_,
759 }),
760 STeXToken::Symuse {
761 uri,
762 full_range,
763 token_range,
764 name_range,
765 } => v.push(Self::Symuse {
766 uri,
767 full_range,
768 token_range,
769 name_range,
770 }),
771 STeXToken::Paragraph {
772 kind,
773 full_range,
774 name_range,
775 symbol,
776 parsed_args,
777 children,
778 } => v.push(Self::Paragraph {
779 symbol,
780 kind,
781 full_range,
782 name_range,
783 parsed_args: cont!(parsed_args),
784 children: Self::from_tokens(children, None),
785 }),
786 STeXToken::Problem {
787 sub,
788 full_range,
789 name_range,
790 parsed_args,
791 children,
792 } => v.push(Self::Problem {
793 sub,
794 full_range,
795 name_range,
796 parsed_args: cont!(parsed_args),
797 children: Self::from_tokens(children, None),
798 }),
799 STeXToken::InlineParagraph {
800 kind,
801 full_range,
802 token_range,
803 children_range,
804 symbol,
805 parsed_args,
806 children,
807 } => v.push(Self::InlineParagraph {
808 symbol,
809 kind,
810 full_range,
811 token_range,
812 children_range,
813 parsed_args: cont!(parsed_args),
814 children: Self::from_tokens(children, None),
815 }),
816 STeXToken::RenameDecl {
817 uri,
818 token_range,
819 orig_range,
820 name_range,
821 macroname_range,
822 full_range,
823 } => v.push(Self::RenameDecl {
824 uri,
825 token_range,
826 orig_range,
827 name_range,
828 macroname_range,
829 full_range,
830 }),
831 STeXToken::Assign {
832 uri,
833 token_range,
834 orig_range,
835 full_range,
836 } => v.push(Self::Assign {
837 uri,
838 token_range,
839 orig_range,
840 full_range,
841 }),
842 STeXToken::Vec(vi) => v.extend(Self::from_tokens(
843 vi,
844 modules.as_mut().map_or(None, |m| Some(*m)),
845 )),
846 }
847 }
848 v
849 }
850
851 #[must_use]
852 #[inline]
853 pub const fn range(&self) -> StringRange<LSPLineCol> {
854 match self {
855 Self::Module { full_range, .. }
856 | Self::MathStructure { full_range, .. }
857 | Self::SemanticMacro { full_range, .. }
858 | Self::ImportModule { full_range, .. }
859 | Self::UseModule { full_range, .. }
860 | Self::SetMetatheory { full_range, .. }
861 | Self::Symdecl { full_range, .. }
862 | Self::Symdef { full_range, .. }
863 | Self::IncludeProblem { full_range, .. }
864 | Self::SymName { full_range, .. }
865 | Self::Symuse { full_range, .. }
866 | Self::Symref { full_range, .. }
867 | Self::Vardef { full_range, .. }
868 | Self::VariableMacro { full_range, .. }
869 | Self::Varseq { full_range, .. }
870 | Self::Notation { full_range, .. }
871 | Self::Svar { full_range, .. }
872 | Self::Definiens { full_range, .. }
873 | Self::Defnotation { full_range }
874 | Self::ConservativeExt { full_range, .. }
875 | Self::Paragraph { full_range, .. }
876 | Self::Problem { full_range, .. }
877 | Self::UseStructure { full_range, .. }
878 | Self::InlineParagraph { full_range, .. }
879 | Self::MorphismEnv { full_range, .. }
880 | Self::RenameDecl { full_range, .. }
881 | Self::Assign { full_range, .. }
882 | Self::Inputref { full_range, .. }
883 | Self::MHInput { full_range, .. }
884 | Self::InlineMorphism { full_range, .. }
885 | Self::Precondition { full_range, .. }
886 | Self::Objective { full_range, .. }
887 | Self::MHGraphics { full_range, .. }
888 | Self::SRef { full_range, .. }
889 | Self::SnifySuggestion {
890 range: full_range, ..
891 }
892 | Self::TextSymdecl { full_range, .. } => *full_range,
893 }
894 }
895}
896
897pub enum AnnotIter<'a> {
898 Module(
899 std::iter::Chain<
900 SModuleArgIter<'a, LSPLineCol, STeXAnnot>,
901 std::slice::Iter<'a, STeXAnnot>,
902 >,
903 ),
904 InlineAss(InlineMorphAssIter<'a, LSPLineCol, STeXAnnot>),
905 Slice(std::slice::Iter<'a, STeXAnnot>),
906 Paragraph(std::iter::Chain<ParagraphArgIter<'a, STeXAnnot>, std::slice::Iter<'a, STeXAnnot>>),
907 Problem(std::iter::Chain<ProblemArgIter<'a, STeXAnnot>, std::slice::Iter<'a, STeXAnnot>>),
908 Structure(
909 std::iter::Chain<
910 MathStructureArgIter<'a, LSPLineCol, STeXAnnot>,
911 std::slice::Iter<'a, STeXAnnot>,
912 >,
913 ),
914 SRef(
915 std::iter::Chain<
916 SRefOptsAIter<'a, LSPLineCol, STeXAnnot>,
917 SRefOptsBIter<'a, LSPLineCol, STeXAnnot>,
918 >,
919 ),
920 Symdecl(SymdeclArgIter<'a, LSPLineCol, STeXAnnot>),
921 TextSymdecl(TextSymdeclArgIter<'a, LSPLineCol, STeXAnnot>),
922 Notation(NotationArgIter<'a, LSPLineCol, STeXAnnot>),
923 Symdef(SymdefArgIter<'a, LSPLineCol, STeXAnnot>),
924 Vardef(VardefArgIter<'a, LSPLineCol, STeXAnnot>),
925}
926impl<'a> From<std::slice::Iter<'a, STeXAnnot>> for AnnotIter<'a> {
927 #[inline]
928 fn from(v: std::slice::Iter<'a, STeXAnnot>) -> Self {
929 Self::Slice(v)
930 }
931}
932impl<'a> Iterator for AnnotIter<'a> {
933 type Item = &'a STeXAnnot;
934 #[inline]
935 fn next(&mut self) -> Option<Self::Item> {
936 match self {
937 Self::SRef(i) => i.next(),
938 Self::Module(i) => i.next(),
939 Self::Structure(i) => i.next(),
940 Self::InlineAss(i) => i.next(),
941 Self::Paragraph(i) => i.next(),
942 Self::Problem(i) => i.next(),
943 Self::Symdecl(i) => i.next(),
944 Self::TextSymdecl(i) => i.next(),
945 Self::Notation(i) => i.next(),
946 Self::Symdef(i) => i.next(),
947 Self::Vardef(i) => i.next(),
948 Self::Slice(i) => i.next(),
949 }
950 }
951}
952
953impl TreeLike for STeXAnnot {
954 type Child<'a> = &'a Self;
955 type RefIter<'a> = AnnotIter<'a>;
956 fn children(&self) -> Option<Self::RefIter<'_>> {
957 match self {
958 Self::Module { opts, children, .. } => Some(AnnotIter::Module(
959 SModuleArgIter::new(opts).chain(children.iter()),
960 )),
961 Self::InlineMorphism { assignments, .. } => {
962 Some(AnnotIter::InlineAss(InlineMorphAssIter::new(assignments)))
963 }
964 Self::SRef {
965 opt_args,
966 in_opt_args,
967 ..
968 } => Some(AnnotIter::SRef(
969 SRefOptsAIter::new(opt_args).chain(SRefOptsBIter::new(in_opt_args)),
970 )),
971 Self::Paragraph {
972 parsed_args,
973 children,
974 ..
975 }
976 | Self::InlineParagraph {
977 parsed_args,
978 children,
979 ..
980 } => Some(AnnotIter::Paragraph(
981 ParagraphArgIter::new(parsed_args).chain(children.iter()),
982 )),
983 Self::Problem {
984 parsed_args,
985 children,
986 ..
987 } => Some(AnnotIter::Problem(
988 ProblemArgIter::new(parsed_args).chain(children.iter()),
989 )),
990 Self::Symdecl { parsed_args, .. } => {
991 Some(AnnotIter::Symdecl(SymdeclArgIter::new(parsed_args)))
992 }
993 Self::TextSymdecl { parsed_args, .. } => {
994 Some(AnnotIter::TextSymdecl(TextSymdeclArgIter::new(parsed_args)))
995 }
996 Self::Notation { notation_args, .. } => {
997 Some(AnnotIter::Notation(NotationArgIter::new(notation_args)))
998 }
999 Self::Symdef { parsed_args, .. } => {
1000 Some(AnnotIter::Symdef(SymdefArgIter::new(parsed_args)))
1001 }
1002 Self::Vardef { parsed_args, .. } | Self::Varseq { parsed_args, .. } => {
1003 Some(AnnotIter::Vardef(VardefArgIter::new(parsed_args)))
1004 }
1005 Self::MathStructure { children, opts, .. } => Some(AnnotIter::Structure(
1006 MathStructureArgIter::new(opts).chain(children.iter()),
1007 )),
1008 Self::ConservativeExt { children, .. } | Self::MorphismEnv { children, .. } => {
1009 Some(AnnotIter::Slice(children.iter()))
1010 }
1011 Self::SemanticMacro { .. }
1012 | Self::VariableMacro { .. }
1013 | Self::ImportModule { .. }
1014 | Self::UseModule { .. }
1015 | Self::SetMetatheory { .. }
1016 | Self::Inputref { .. }
1017 | Self::MHInput { .. }
1018 | Self::SymName { .. }
1019 | Self::Symref { .. }
1020 | Self::Symuse { .. }
1021 | Self::Svar { .. }
1022 | Self::Definiens { .. }
1023 | Self::Defnotation { .. }
1024 | Self::UseStructure { .. }
1025 | Self::Precondition { .. }
1026 | Self::Objective { .. }
1027 | Self::RenameDecl { .. }
1028 | Self::IncludeProblem { .. }
1029 | Self::MHGraphics { .. }
1030 | Self::Assign { .. }
1031 | Self::SnifySuggestion { .. } => None,
1032 }
1033 }
1034}
1035
1036impl TreeChild<STeXAnnot> for &STeXAnnot {
1037 fn children<'a>(&self) -> Option<AnnotIter<'a>>
1038 where
1039 Self: 'a,
1040 {
1041 <STeXAnnot as TreeLike>::children(self)
1042 }
1043}
1044
1045#[derive(Copy, Clone, Debug, PartialEq, Eq)]
1046pub enum DiagnosticLevel {
1047 Error,
1048 Warning,
1049 Info,
1050 Hint,
1051}
1052
1053#[derive(PartialEq, Eq, Debug)]
1054pub struct STeXDiagnostic {
1055 pub level: DiagnosticLevel,
1056 pub message: String,
1057 pub range: StringRange<LSPLineCol>,
1058}
1059
1060#[must_use]
1061pub fn quickparse<'a, S: STeXModuleStore>(
1062 uri: &'a DocumentUri,
1063 source: &'a str,
1064 path: &'a Path,
1065 backend: &'a AnyBackend,
1066 store: S,
1067) -> STeXParseDataI {
1068 let mut diagnostics = VecSet::new();
1069 let mut modules = SmallVec::new();
1070 let mut err = |message, range, level| {
1071 diagnostics.insert(STeXDiagnostic {
1072 level,
1073 message,
1074 range,
1075 });
1076 };
1077 let mut parser = if S::FULL {
1078 LaTeXParser::with_rules(
1079 source,
1080 STeXParseState::new(Some(uri.archive_uri()), Some(path), uri, backend, store),
1081 &mut err,
1082 LaTeXParser::default_rules()
1083 .into_iter()
1084 .chain(rules::all_rules()),
1085 LaTeXParser::default_env_rules()
1086 .into_iter()
1087 .chain(rules::all_env_rules()),
1088 )
1089 } else {
1090 LaTeXParser::with_rules(
1091 source,
1092 STeXParseState::new(Some(uri.archive_uri()), Some(path), uri, backend, store),
1093 &mut err,
1094 LaTeXParser::default_rules()
1095 .into_iter()
1096 .chain(rules::declarative_rules()),
1097 LaTeXParser::default_env_rules()
1098 .into_iter()
1099 .chain(rules::declarative_env_rules()),
1100 )
1101 };
1102
1103 let annotations = STeXAnnot::from_tokens(&mut parser, Some(&mut modules));
1104
1105 let dependents = parser.state.dependencies;
1106 STeXParseDataI {
1107 annotations,
1108 diagnostics,
1109 check: None,
1110 modules,
1111 dependencies: dependents,
1112 }
1113}