Skip to main content

oak_objective_c/parser/
mod.rs

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