Skip to main content

oak_objective_c/parser/
mod.rs

1use crate::{kind::ObjectiveCSyntaxKind, language::ObjectiveCLanguage, lexer::ObjectiveCLexer};
2use oak_core::{
3    parser::{ParseCache, ParseOutput, Parser, ParserState, parse_with_lexer},
4    source::{Source, TextEdit},
5};
6
7pub(crate) type State<'a, S> = ParserState<'a, ObjectiveCLanguage, S>;
8
9pub struct ObjectiveCParser<'config> {
10    pub language: &'config ObjectiveCLanguage,
11}
12
13impl<'config> ObjectiveCParser<'config> {
14    pub fn new(language: &'config ObjectiveCLanguage) -> Self {
15        Self { language }
16    }
17
18    fn parse_item<'b, S: Source + ?Sized>(&self, state: &mut State<'b, S>) {
19        if state.at(ObjectiveCSyntaxKind::At) {
20            state.bump();
21            if state.at(ObjectiveCSyntaxKind::InterfaceKeyword) {
22                self.parse_interface(state);
23            }
24            else if state.at(ObjectiveCSyntaxKind::ImplementationKeyword) {
25                self.parse_implementation(state);
26            }
27            else if state.at(ObjectiveCSyntaxKind::ProtocolKeyword) {
28                self.parse_protocol(state);
29            }
30            else {
31                let checkpoint = state.checkpoint();
32                state.bump();
33                state.finish_at(checkpoint, ObjectiveCSyntaxKind::Error.into());
34            }
35        }
36        else if state.at(ObjectiveCSyntaxKind::ImportKeyword) || state.at(ObjectiveCSyntaxKind::IncludeKeyword) {
37            self.parse_import(state);
38        }
39        else {
40            // Simplified: just consume tokens
41            state.bump();
42        }
43    }
44
45    fn parse_interface<'b, S: Source + ?Sized>(&self, state: &mut State<'b, S>) {
46        let checkpoint = state.checkpoint();
47        state.expect(ObjectiveCSyntaxKind::InterfaceKeyword).ok();
48        // Simplified: consume until @end
49        while state.not_at_end() && !state.at(ObjectiveCSyntaxKind::EndKeyword) {
50            state.bump();
51        }
52        if state.at(ObjectiveCSyntaxKind::EndKeyword) {
53            state.expect(ObjectiveCSyntaxKind::EndKeyword).ok();
54        }
55        state.finish_at(checkpoint, ObjectiveCSyntaxKind::InterfaceDeclaration.into());
56    }
57
58    fn parse_implementation<'b, S: Source + ?Sized>(&self, state: &mut State<'b, S>) {
59        let checkpoint = state.checkpoint();
60        state.expect(ObjectiveCSyntaxKind::ImplementationKeyword).ok();
61        // Simplified: consume until @end
62        while state.not_at_end() && !state.at(ObjectiveCSyntaxKind::EndKeyword) {
63            state.bump();
64        }
65        if state.at(ObjectiveCSyntaxKind::EndKeyword) {
66            state.expect(ObjectiveCSyntaxKind::EndKeyword).ok();
67        }
68        state.finish_at(checkpoint, ObjectiveCSyntaxKind::ImplementationDeclaration.into());
69    }
70
71    fn parse_protocol<'b, S: Source + ?Sized>(&self, state: &mut State<'b, S>) {
72        let checkpoint = state.checkpoint();
73        state.expect(ObjectiveCSyntaxKind::ProtocolKeyword).ok();
74        // Simplified: consume until @end
75        while state.not_at_end() && !state.at(ObjectiveCSyntaxKind::EndKeyword) {
76            state.bump();
77        }
78        if state.at(ObjectiveCSyntaxKind::EndKeyword) {
79            state.expect(ObjectiveCSyntaxKind::EndKeyword).ok();
80        }
81        state.finish_at(checkpoint, ObjectiveCSyntaxKind::ProtocolDeclaration.into());
82    }
83
84    fn parse_import<'b, S: Source + ?Sized>(&self, state: &mut State<'b, S>) {
85        // Simplified: consume until semicolon or newline
86        state.bump(); // #import or #include
87        while state.not_at_end() && !state.at(ObjectiveCSyntaxKind::Semicolon) && !state.at(ObjectiveCSyntaxKind::Newline) {
88            state.bump();
89        }
90        if state.at(ObjectiveCSyntaxKind::Semicolon) {
91            state.expect(ObjectiveCSyntaxKind::Semicolon).ok();
92        }
93    }
94}
95
96impl<'config> Parser<ObjectiveCLanguage> for ObjectiveCParser<'config> {
97    fn parse<'a, S: Source + ?Sized>(&self, text: &'a S, edits: &[TextEdit], cache: &'a mut impl ParseCache<ObjectiveCLanguage>) -> ParseOutput<'a, ObjectiveCLanguage> {
98        let lexer = ObjectiveCLexer::new(self.language);
99        parse_with_lexer(&lexer, text, edits, cache, |state| {
100            let checkpoint = state.checkpoint();
101
102            while state.not_at_end() {
103                self.parse_item(state);
104            }
105
106            Ok(state.finish_at(checkpoint, ObjectiveCSyntaxKind::Root.into()))
107        })
108    }
109}