<!doctype html><html><head><meta name='viewport' content='width=device-width,initial-scale=1'><meta charset='UTF-8'><link rel='stylesheet' type='text/css' href='../../../../css/llvm-cov.css'><script src='../../../control.js'></script><script>
// Sync theme with main site and setup theme toggle
(function() {
const THEME_KEY = 'vb6parse-theme';
function getSystemPreference() {
return (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) ? 'dark' : 'light';
}
function getTheme() {
return localStorage.getItem(THEME_KEY) || getSystemPreference();
}
function applyTheme(theme) {
document.documentElement.setAttribute('data-theme', theme);
const themeIcon = document.querySelector('.theme-icon');
if (themeIcon) {
themeIcon.textContent = theme === 'dark' ? '☀️' : '🌙';
}
}
function toggleTheme() {
const currentTheme = getTheme();
const newTheme = currentTheme === 'dark' ? 'light' : 'dark';
localStorage.setItem(THEME_KEY, newTheme);
applyTheme(newTheme);
}
// Apply theme immediately
const theme = getTheme();
applyTheme(theme);
// Setup toggle button when DOM is ready
document.addEventListener('DOMContentLoaded', function() {
const toggle = document.querySelector('.theme-toggle');
if (toggle) {
toggle.addEventListener('click', toggleTheme);
}
});
})();
</script></head><body><header>
<div class="container">
<h1>VB6Parse Coverage Report</h1>
<p class="tagline">Generated from llvm-cov</p>
</div>
</header>
<nav>
<div class="container">
<a href='../../../../../coverage.html'>Coverage Report</a>
<a href='../../../../../index.html'>Overview</a>
<button id="theme-toggle" class="theme-toggle" aria-label="Toggle theme">
<span class="theme-icon">🌙</span>
</button>
</div>
</nav><span class='control'><a href='javascript:next_line()'>next uncovered line (L)</a>, <a href='javascript:next_region()'>next uncovered region (R)</a>, <a href='javascript:next_branch()'>next uncovered branch (B)</a></span><div class='centered'><table><div class='source-name-title'><a href='https://github.com/scriptandcompile/vb6parse/blob/master/src/parsers/cst/mod.rs'>src/parsers/cst/mod.rs</a></div><tr><td><pre>Line</pre></td><td><pre>Count</pre></td><td><pre>Source</pre></td></tr><tr><td class='line-number'><a name='L1' href='#L1'><pre>1</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//! Concrete Syntax Tree (CST) implementation for VB6.</pre></td></tr><tr><td class='line-number'><a name='L2' href='#L2'><pre>2</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//!</pre></td></tr><tr><td class='line-number'><a name='L3' href='#L3'><pre>3</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//! This module provides a CST that wraps the rowan library internally while</pre></td></tr><tr><td class='line-number'><a name='L4' href='#L4'><pre>4</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//! providing a public API that doesn't expose rowan types directly.</pre></td></tr><tr><td class='line-number'><a name='L5' href='#L5'><pre>5</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//!</pre></td></tr><tr><td class='line-number'><a name='L6' href='#L6'><pre>6</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//! # Overview</pre></td></tr><tr><td class='line-number'><a name='L7' href='#L7'><pre>7</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//!</pre></td></tr><tr><td class='line-number'><a name='L8' href='#L8'><pre>8</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//! The CST (Concrete Syntax Tree) represents the complete structure of VB6 source code,</pre></td></tr><tr><td class='line-number'><a name='L9' href='#L9'><pre>9</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//! including all tokens such as whitespace, comments, and keywords. Unlike an AST</pre></td></tr><tr><td class='line-number'><a name='L10' href='#L10'><pre>10</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//! (Abstract Syntax Tree), a CST preserves all the original formatting and structure</pre></td></tr><tr><td class='line-number'><a name='L11' href='#L11'><pre>11</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//! of the source code, making it ideal for tools like formatters, linters, and</pre></td></tr><tr><td class='line-number'><a name='L12' href='#L12'><pre>12</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//! source-to-source transformations.</pre></td></tr><tr><td class='line-number'><a name='L13' href='#L13'><pre>13</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//!</pre></td></tr><tr><td class='line-number'><a name='L14' href='#L14'><pre>14</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//! # Architecture</pre></td></tr><tr><td class='line-number'><a name='L15' href='#L15'><pre>15</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//!</pre></td></tr><tr><td class='line-number'><a name='L16' href='#L16'><pre>16</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//! This implementation uses the [`rowan`](https://docs.rs/rowan/) library internally</pre></td></tr><tr><td class='line-number'><a name='L17' href='#L17'><pre>17</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//! for efficient CST representation, but all rowan types are kept private to the module.</pre></td></tr><tr><td class='line-number'><a name='L18' href='#L18'><pre>18</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//! The public API only exposes:</pre></td></tr><tr><td class='line-number'><a name='L19' href='#L19'><pre>19</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//!</pre></td></tr><tr><td class='line-number'><a name='L20' href='#L20'><pre>20</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//! - [`ConcreteSyntaxTree`] - The main CST struct</pre></td></tr><tr><td class='line-number'><a name='L21' href='#L21'><pre>21</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//! - [`SyntaxKind`] - An enum representing all possible node and token types</pre></td></tr><tr><td class='line-number'><a name='L22' href='#L22'><pre>22</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//! - [`parse`] - A function to parse a [`TokenStream`] into a CST</pre></td></tr><tr><td class='line-number'><a name='L23' href='#L23'><pre>23</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//! - [`CstNode`] - A structure for navigating and querying the CST</pre></td></tr><tr><td class='line-number'><a name='L24' href='#L24'><pre>24</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//!</pre></td></tr><tr><td class='line-number'><a name='L25' href='#L25'><pre>25</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//! # Example Usage</pre></td></tr><tr><td class='line-number'><a name='L26' href='#L26'><pre>26</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//!</pre></td></tr><tr><td class='line-number'><a name='L27' href='#L27'><pre>27</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//! ```rust</pre></td></tr><tr><td class='line-number'><a name='L28' href='#L28'><pre>28</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//! use vb6parse::language::Token;</pre></td></tr><tr><td class='line-number'><a name='L29' href='#L29'><pre>29</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//! use vb6parse::parsers::cst::parse;</pre></td></tr><tr><td class='line-number'><a name='L30' href='#L30'><pre>30</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//! use vb6parse::lexer::TokenStream;</pre></td></tr><tr><td class='line-number'><a name='L31' href='#L31'><pre>31</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//!</pre></td></tr><tr><td class='line-number'><a name='L32' href='#L32'><pre>32</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//! // Create a token stream</pre></td></tr><tr><td class='line-number'><a name='L33' href='#L33'><pre>33</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//! let tokens = vec![</pre></td></tr><tr><td class='line-number'><a name='L34' href='#L34'><pre>34</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//! ("Sub", Token::SubKeyword),</pre></td></tr><tr><td class='line-number'><a name='L35' href='#L35'><pre>35</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//! (" ", Token::Whitespace),</pre></td></tr><tr><td class='line-number'><a name='L36' href='#L36'><pre>36</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//! ("Main", Token::Identifier),</pre></td></tr><tr><td class='line-number'><a name='L37' href='#L37'><pre>37</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//! ("(", Token::LeftParenthesis),</pre></td></tr><tr><td class='line-number'><a name='L38' href='#L38'><pre>38</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//! (")", Token::RightParenthesis),</pre></td></tr><tr><td class='line-number'><a name='L39' href='#L39'><pre>39</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//! ("\n", Token::Newline),</pre></td></tr><tr><td class='line-number'><a name='L40' href='#L40'><pre>40</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//! ];</pre></td></tr><tr><td class='line-number'><a name='L41' href='#L41'><pre>41</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//!</pre></td></tr><tr><td class='line-number'><a name='L42' href='#L42'><pre>42</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//! let token_stream = TokenStream::new("test.bas".to_string(), tokens);</pre></td></tr><tr><td class='line-number'><a name='L43' href='#L43'><pre>43</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//!</pre></td></tr><tr><td class='line-number'><a name='L44' href='#L44'><pre>44</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//! // Parse into a CST</pre></td></tr><tr><td class='line-number'><a name='L45' href='#L45'><pre>45</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//! let cst = parse(token_stream);</pre></td></tr><tr><td class='line-number'><a name='L46' href='#L46'><pre>46</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//!</pre></td></tr><tr><td class='line-number'><a name='L47' href='#L47'><pre>47</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//! // Use the CST</pre></td></tr><tr><td class='line-number'><a name='L48' href='#L48'><pre>48</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//! println!("Text: {}", cst.text());</pre></td></tr><tr><td class='line-number'><a name='L49' href='#L49'><pre>49</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//! println!("Children: {}", cst.child_count());</pre></td></tr><tr><td class='line-number'><a name='L50' href='#L50'><pre>50</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//! ```</pre></td></tr><tr><td class='line-number'><a name='L51' href='#L51'><pre>51</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//!</pre></td></tr><tr><td class='line-number'><a name='L52' href='#L52'><pre>52</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//! # Navigating the CST</pre></td></tr><tr><td class='line-number'><a name='L53' href='#L53'><pre>53</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//!</pre></td></tr><tr><td class='line-number'><a name='L54' href='#L54'><pre>54</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//! The CST provides rich navigation capabilities for traversing and querying the tree.</pre></td></tr><tr><td class='line-number'><a name='L55' href='#L55'><pre>55</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//! Both [`ConcreteSyntaxTree`] and [`CstNode`] provide parallel navigation APIs:</pre></td></tr><tr><td class='line-number'><a name='L56' href='#L56'><pre>56</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//!</pre></td></tr><tr><td class='line-number'><a name='L57' href='#L57'><pre>57</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//! ## Root-Level Navigation</pre></td></tr><tr><td class='line-number'><a name='L58' href='#L58'><pre>58</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//!</pre></td></tr><tr><td class='line-number'><a name='L59' href='#L59'><pre>59</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//! ```rust</pre></td></tr><tr><td class='line-number'><a name='L60' href='#L60'><pre>60</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//! use vb6parse::ConcreteSyntaxTree;</pre></td></tr><tr><td class='line-number'><a name='L61' href='#L61'><pre>61</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//! use vb6parse::parsers::SyntaxKind;</pre></td></tr><tr><td class='line-number'><a name='L62' href='#L62'><pre>62</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//!</pre></td></tr><tr><td class='line-number'><a name='L63' href='#L63'><pre>63</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//! let source = "Sub Test()\nEnd Sub\n";</pre></td></tr><tr><td class='line-number'><a name='L64' href='#L64'><pre>64</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//! let cst = ConcreteSyntaxTree::from_text("test.bas", source).unwrap();</pre></td></tr><tr><td class='line-number'><a name='L65' href='#L65'><pre>65</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//!</pre></td></tr><tr><td class='line-number'><a name='L66' href='#L66'><pre>66</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//! // Access root-level children</pre></td></tr><tr><td class='line-number'><a name='L67' href='#L67'><pre>67</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//! println!("Child count: {}", cst.child_count());</pre></td></tr><tr><td class='line-number'><a name='L68' href='#L68'><pre>68</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//! let first = cst.first_child();</pre></td></tr><tr><td class='line-number'><a name='L69' href='#L69'><pre>69</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//!</pre></td></tr><tr><td class='line-number'><a name='L70' href='#L70'><pre>70</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//! // Search root-level children</pre></td></tr><tr><td class='line-number'><a name='L71' href='#L71'><pre>71</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//! let subs: Vec<_> = cst.children_by_kind(SyntaxKind::SubStatement).collect();</pre></td></tr><tr><td class='line-number'><a name='L72' href='#L72'><pre>72</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//! ```</pre></td></tr><tr><td class='line-number'><a name='L73' href='#L73'><pre>73</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//!</pre></td></tr><tr><td class='line-number'><a name='L74' href='#L74'><pre>74</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//! ## Node-Level Navigation</pre></td></tr><tr><td class='line-number'><a name='L75' href='#L75'><pre>75</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//!</pre></td></tr><tr><td class='line-number'><a name='L76' href='#L76'><pre>76</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//! Once you have a [`CstNode`], you can navigate its structure:</pre></td></tr><tr><td class='line-number'><a name='L77' href='#L77'><pre>77</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//!</pre></td></tr><tr><td class='line-number'><a name='L78' href='#L78'><pre>78</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//! ```rust</pre></td></tr><tr><td class='line-number'><a name='L79' href='#L79'><pre>79</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//! # use vb6parse::ConcreteSyntaxTree;</pre></td></tr><tr><td class='line-number'><a name='L80' href='#L80'><pre>80</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//! # use vb6parse::parsers::SyntaxKind;</pre></td></tr><tr><td class='line-number'><a name='L81' href='#L81'><pre>81</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//! # let source = "Sub Test()\nDim x\nEnd Sub\n";</pre></td></tr><tr><td class='line-number'><a name='L82' href='#L82'><pre>82</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//! # let cst = ConcreteSyntaxTree::from_text("test.bas", source).unwrap();</pre></td></tr><tr><td class='line-number'><a name='L83' href='#L83'><pre>83</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//! let root = cst.to_serializable().root;</pre></td></tr><tr><td class='line-number'><a name='L84' href='#L84'><pre>84</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//!</pre></td></tr><tr><td class='line-number'><a name='L85' href='#L85'><pre>85</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//! // Direct children</pre></td></tr><tr><td class='line-number'><a name='L86' href='#L86'><pre>86</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//! println!("Child count: {}", root.child_count());</pre></td></tr><tr><td class='line-number'><a name='L87' href='#L87'><pre>87</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//! let first = root.first_child();</pre></td></tr><tr><td class='line-number'><a name='L88' href='#L88'><pre>88</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//!</pre></td></tr><tr><td class='line-number'><a name='L89' href='#L89'><pre>89</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//! // Filter by kind</pre></td></tr><tr><td class='line-number'><a name='L90' href='#L90'><pre>90</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//! let statements: Vec<_> = root.children_by_kind(SyntaxKind::DimStatement).collect();</pre></td></tr><tr><td class='line-number'><a name='L91' href='#L91'><pre>91</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//!</pre></td></tr><tr><td class='line-number'><a name='L92' href='#L92'><pre>92</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//! // Recursive search</pre></td></tr><tr><td class='line-number'><a name='L93' href='#L93'><pre>93</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//! let dim_stmt = root.find(SyntaxKind::DimStatement);</pre></td></tr><tr><td class='line-number'><a name='L94' href='#L94'><pre>94</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//! let all_identifiers = root.find_all(SyntaxKind::Identifier);</pre></td></tr><tr><td class='line-number'><a name='L95' href='#L95'><pre>95</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//!</pre></td></tr><tr><td class='line-number'><a name='L96' href='#L96'><pre>96</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//! // Filter tokens</pre></td></tr><tr><td class='line-number'><a name='L97' href='#L97'><pre>97</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//! let non_tokens: Vec<_> = root.non_token_children().collect();</pre></td></tr><tr><td class='line-number'><a name='L98' href='#L98'><pre>98</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//! let significant: Vec<_> = root.significant_children().collect();</pre></td></tr><tr><td class='line-number'><a name='L99' href='#L99'><pre>99</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//!</pre></td></tr><tr><td class='line-number'><a name='L100' href='#L100'><pre>100</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//! // Custom predicates</pre></td></tr><tr><td class='line-number'><a name='L101' href='#L101'><pre>101</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//! let keywords = root.find_all_if(|n| {</pre></td></tr><tr><td class='line-number'><a name='L102' href='#L102'><pre>102</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//! matches!(n.kind(), SyntaxKind::SubKeyword | SyntaxKind::DimKeyword)</pre></td></tr><tr><td class='line-number'><a name='L103' href='#L103'><pre>103</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//! });</pre></td></tr><tr><td class='line-number'><a name='L104' href='#L104'><pre>104</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//!</pre></td></tr><tr><td class='line-number'><a name='L105' href='#L105'><pre>105</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//! // Iterate all nodes</pre></td></tr><tr><td class='line-number'><a name='L106' href='#L106'><pre>106</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//! for node in root.descendants() {</pre></td></tr><tr><td class='line-number'><a name='L107' href='#L107'><pre>107</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//! if node.is_significant() {</pre></td></tr><tr><td class='line-number'><a name='L108' href='#L108'><pre>108</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//! println!("{:?}: {}", node.kind(), node.text());</pre></td></tr><tr><td class='line-number'><a name='L109' href='#L109'><pre>109</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//! }</pre></td></tr><tr><td class='line-number'><a name='L110' href='#L110'><pre>110</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//! }</pre></td></tr><tr><td class='line-number'><a name='L111' href='#L111'><pre>111</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//! ```</pre></td></tr><tr><td class='line-number'><a name='L112' href='#L112'><pre>112</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//!</pre></td></tr><tr><td class='line-number'><a name='L113' href='#L113'><pre>113</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//! ## Navigation Methods</pre></td></tr><tr><td class='line-number'><a name='L114' href='#L114'><pre>114</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//!</pre></td></tr><tr><td class='line-number'><a name='L115' href='#L115'><pre>115</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//! Available on both [`ConcreteSyntaxTree`] and [`CstNode`]:</pre></td></tr><tr><td class='line-number'><a name='L116' href='#L116'><pre>116</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//!</pre></td></tr><tr><td class='line-number'><a name='L117' href='#L117'><pre>117</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//! **Basic Access:**</pre></td></tr><tr><td class='line-number'><a name='L118' href='#L118'><pre>118</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//! - `child_count()` - Number of direct children</pre></td></tr><tr><td class='line-number'><a name='L119' href='#L119'><pre>119</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//! - `first_child()`, `last_child()`, `child_at(index)` - Access specific children</pre></td></tr><tr><td class='line-number'><a name='L120' href='#L120'><pre>120</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//!</pre></td></tr><tr><td class='line-number'><a name='L121' href='#L121'><pre>121</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//! **By Kind:**</pre></td></tr><tr><td class='line-number'><a name='L122' href='#L122'><pre>122</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//! - `children_by_kind(kind)` - Iterator over children of a specific kind</pre></td></tr><tr><td class='line-number'><a name='L123' href='#L123'><pre>123</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//! - `first_child_by_kind(kind)` - First child of a specific kind</pre></td></tr><tr><td class='line-number'><a name='L124' href='#L124'><pre>124</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//! - `contains_kind(kind)` - Check if a kind exists in children</pre></td></tr><tr><td class='line-number'><a name='L125' href='#L125'><pre>125</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//!</pre></td></tr><tr><td class='line-number'><a name='L126' href='#L126'><pre>126</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//! **Recursive Search:**</pre></td></tr><tr><td class='line-number'><a name='L127' href='#L127'><pre>127</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//! - `find(kind)` - Find first descendant of a specific kind</pre></td></tr><tr><td class='line-number'><a name='L128' href='#L128'><pre>128</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//! - `find_all(kind)` - Find all descendants of a specific kind</pre></td></tr><tr><td class='line-number'><a name='L129' href='#L129'><pre>129</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//!</pre></td></tr><tr><td class='line-number'><a name='L130' href='#L130'><pre>130</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//! **Token Filtering:**</pre></td></tr><tr><td class='line-number'><a name='L131' href='#L131'><pre>131</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//! - `non_token_children()` - Structural nodes only</pre></td></tr><tr><td class='line-number'><a name='L132' href='#L132'><pre>132</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//! - `token_children()` - Tokens only</pre></td></tr><tr><td class='line-number'><a name='L133' href='#L133'><pre>133</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//! - `first_non_whitespace_child()` - Skip leading whitespace</pre></td></tr><tr><td class='line-number'><a name='L134' href='#L134'><pre>134</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//! - `significant_children()` - Exclude whitespace and newlines</pre></td></tr><tr><td class='line-number'><a name='L135' href='#L135'><pre>135</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//!</pre></td></tr><tr><td class='line-number'><a name='L136' href='#L136'><pre>136</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//! **Predicate-Based:**</pre></td></tr><tr><td class='line-number'><a name='L137' href='#L137'><pre>137</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//! - `find_if(predicate)` - Find first node matching a custom condition</pre></td></tr><tr><td class='line-number'><a name='L138' href='#L138'><pre>138</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//! - `find_all_if(predicate)` - Find all nodes matching a custom condition</pre></td></tr><tr><td class='line-number'><a name='L139' href='#L139'><pre>139</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//!</pre></td></tr><tr><td class='line-number'><a name='L140' href='#L140'><pre>140</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//! **Tree Traversal:**</pre></td></tr><tr><td class='line-number'><a name='L141' href='#L141'><pre>141</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//! - `descendants()` - Depth-first iterator over all nodes</pre></td></tr><tr><td class='line-number'><a name='L142' href='#L142'><pre>142</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//! - `depth_first_iter()` - Alias for `descendants()`</pre></td></tr><tr><td class='line-number'><a name='L143' href='#L143'><pre>143</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//!</pre></td></tr><tr><td class='line-number'><a name='L144' href='#L144'><pre>144</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//! **Convenience Checkers** (`CstNode` only):</pre></td></tr><tr><td class='line-number'><a name='L145' href='#L145'><pre>145</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//! - `is_whitespace()` - Check if node is whitespace.</pre></td></tr><tr><td class='line-number'><a name='L146' href='#L146'><pre>146</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//! - `is_newline()` - Check if node is newline.</pre></td></tr><tr><td class='line-number'><a name='L147' href='#L147'><pre>147</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//! - `is_comment()` - Check if node is an end-of-Line or REM comment.</pre></td></tr><tr><td class='line-number'><a name='L148' href='#L148'><pre>148</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//! - `is_trivia()` - Whitespace, newline, end-of-Line comment, or REM comment.</pre></td></tr><tr><td class='line-number'><a name='L149' href='#L149'><pre>149</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//! - `is_significant()` - Not trivia.</pre></td></tr><tr><td class='line-number'><a name='L150' href='#L150'><pre>150</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//!</pre></td></tr><tr><td class='line-number'><a name='L151' href='#L151'><pre>151</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//! For more details, see the documentation for [`ConcreteSyntaxTree`] and [`CstNode`].</pre></td></tr><tr><td class='line-number'><a name='L152' href='#L152'><pre>152</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//!</pre></td></tr><tr><td class='line-number'><a name='L153' href='#L153'><pre>153</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//! # Design Principles</pre></td></tr><tr><td class='line-number'><a name='L154' href='#L154'><pre>154</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//!</pre></td></tr><tr><td class='line-number'><a name='L155' href='#L155'><pre>155</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//! 1. **No rowan types exposed**: All public APIs use custom types that don't expose rowan.</pre></td></tr><tr><td class='line-number'><a name='L156' href='#L156'><pre>156</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//! 2. **Complete representation**: The CST includes all tokens, including whitespace and comments.</pre></td></tr><tr><td class='line-number'><a name='L157' href='#L157'><pre>157</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//! 3. **Efficient**: Uses rowan's red-green tree architecture for memory efficiency.</pre></td></tr><tr><td class='line-number'><a name='L158' href='#L158'><pre>158</pre></a></td><td class='skipped-line'></td><td class='code'><pre>//! 4. **Type-safe**: All syntax kinds are represented as a Rust enum for compile-time safety.</pre></td></tr><tr><td class='line-number'><a name='L159' href='#L159'><pre>159</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L160' href='#L160'><pre>160</pre></a></td><td class='skipped-line'></td><td class='code'><pre>use std::num::NonZeroUsize;</pre></td></tr><tr><td class='line-number'><a name='L161' href='#L161'><pre>161</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L162' href='#L162'><pre>162</pre></a></td><td class='skipped-line'></td><td class='code'><pre>use crate::io::{SourceFile, SourceStream};</pre></td></tr><tr><td class='line-number'><a name='L163' href='#L163'><pre>163</pre></a></td><td class='skipped-line'></td><td class='code'><pre>use crate::language::Token;</pre></td></tr><tr><td class='line-number'><a name='L164' href='#L164'><pre>164</pre></a></td><td class='skipped-line'></td><td class='code'><pre>use crate::lexer::{tokenize, TokenStream};</pre></td></tr><tr><td class='line-number'><a name='L165' href='#L165'><pre>165</pre></a></td><td class='skipped-line'></td><td class='code'><pre>use crate::parsers::SyntaxKind;</pre></td></tr><tr><td class='line-number'><a name='L166' href='#L166'><pre>166</pre></a></td><td class='skipped-line'></td><td class='code'><pre>use crate::CodeErrorKind;</pre></td></tr><tr><td class='line-number'><a name='L167' href='#L167'><pre>167</pre></a></td><td class='skipped-line'></td><td class='code'><pre>use crate::ParseResult;</pre></td></tr><tr><td class='line-number'><a name='L168' href='#L168'><pre>168</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L169' href='#L169'><pre>169</pre></a></td><td class='skipped-line'></td><td class='code'><pre>use rowan::{GreenNode, GreenNodeBuilder, Language};</pre></td></tr><tr><td class='line-number'><a name='L170' href='#L170'><pre>170</pre></a></td><td class='skipped-line'></td><td class='code'><pre>use serde::Serialize;</pre></td></tr><tr><td class='line-number'><a name='L171' href='#L171'><pre>171</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L172' href='#L172'><pre>172</pre></a></td><td class='skipped-line'></td><td class='code'><pre>// Submodules for organized CST parsing</pre></td></tr><tr><td class='line-number'><a name='L173' href='#L173'><pre>173</pre></a></td><td class='skipped-line'></td><td class='code'><pre>mod assignment;</pre></td></tr><tr><td class='line-number'><a name='L174' href='#L174'><pre>174</pre></a></td><td class='skipped-line'></td><td class='code'><pre>mod attribute_statements;</pre></td></tr><tr><td class='line-number'><a name='L175' href='#L175'><pre>175</pre></a></td><td class='skipped-line'></td><td class='code'><pre>mod declarations;</pre></td></tr><tr><td class='line-number'><a name='L176' href='#L176'><pre>176</pre></a></td><td class='skipped-line'></td><td class='code'><pre>mod deftype_statements;</pre></td></tr><tr><td class='line-number'><a name='L177' href='#L177'><pre>177</pre></a></td><td class='skipped-line'></td><td class='code'><pre>mod enum_statements;</pre></td></tr><tr><td class='line-number'><a name='L178' href='#L178'><pre>178</pre></a></td><td class='skipped-line'></td><td class='code'><pre>mod for_statements;</pre></td></tr><tr><td class='line-number'><a name='L179' href='#L179'><pre>179</pre></a></td><td class='skipped-line'></td><td class='code'><pre>mod function_statements;</pre></td></tr><tr><td class='line-number'><a name='L180' href='#L180'><pre>180</pre></a></td><td class='skipped-line'></td><td class='code'><pre>mod helpers;</pre></td></tr><tr><td class='line-number'><a name='L181' href='#L181'><pre>181</pre></a></td><td class='skipped-line'></td><td class='code'><pre>mod if_statements;</pre></td></tr><tr><td class='line-number'><a name='L182' href='#L182'><pre>182</pre></a></td><td class='skipped-line'></td><td class='code'><pre>mod loop_statements;</pre></td></tr><tr><td class='line-number'><a name='L183' href='#L183'><pre>183</pre></a></td><td class='skipped-line'></td><td class='code'><pre>mod navigation;</pre></td></tr><tr><td class='line-number'><a name='L184' href='#L184'><pre>184</pre></a></td><td class='skipped-line'></td><td class='code'><pre>mod option_statements;</pre></td></tr><tr><td class='line-number'><a name='L185' href='#L185'><pre>185</pre></a></td><td class='skipped-line'></td><td class='code'><pre>mod parameters;</pre></td></tr><tr><td class='line-number'><a name='L186' href='#L186'><pre>186</pre></a></td><td class='skipped-line'></td><td class='code'><pre>mod properties;</pre></td></tr><tr><td class='line-number'><a name='L187' href='#L187'><pre>187</pre></a></td><td class='skipped-line'></td><td class='code'><pre>mod property_statements;</pre></td></tr><tr><td class='line-number'><a name='L188' href='#L188'><pre>188</pre></a></td><td class='skipped-line'></td><td class='code'><pre>mod select_statements;</pre></td></tr><tr><td class='line-number'><a name='L189' href='#L189'><pre>189</pre></a></td><td class='skipped-line'></td><td class='code'><pre>mod sub_statements;</pre></td></tr><tr><td class='line-number'><a name='L190' href='#L190'><pre>190</pre></a></td><td class='skipped-line'></td><td class='code'><pre>mod type_statements;</pre></td></tr><tr><td class='line-number'><a name='L191' href='#L191'><pre>191</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L192' href='#L192'><pre>192</pre></a></td><td class='skipped-line'></td><td class='code'><pre>// Re-export navigation types</pre></td></tr><tr><td class='line-number'><a name='L193' href='#L193'><pre>193</pre></a></td><td class='skipped-line'></td><td class='code'><pre>pub use navigation::CstNode;</pre></td></tr><tr><td class='line-number'><a name='L194' href='#L194'><pre>194</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L195' href='#L195'><pre>195</pre></a></td><td class='skipped-line'></td><td class='code'><pre>/// A serializable representation of the CST for snapshot testing.</pre></td></tr><tr><td class='line-number'><a name='L196' href='#L196'><pre>196</pre></a></td><td class='skipped-line'></td><td class='code'><pre>///</pre></td></tr><tr><td class='line-number'><a name='L197' href='#L197'><pre>197</pre></a></td><td class='skipped-line'></td><td class='code'><pre>/// This struct wraps the tree structure in a way that can be serialized</pre></td></tr><tr><td class='line-number'><a name='L198' href='#L198'><pre>198</pre></a></td><td class='skipped-line'></td><td class='code'><pre>/// with serde, making it suitable for use with snapshot testing tools like insta.</pre></td></tr><tr><td class='line-number'><a name='L199' href='#L199'><pre>199</pre></a></td><td class='skipped-line'></td><td class='code'><pre>#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, Hash)]</pre></td></tr><tr><td class='line-number'><a name='L200' href='#L200'><pre>200</pre></a></td><td class='skipped-line'></td><td class='code'><pre>pub struct SerializableTree {</pre></td></tr><tr><td class='line-number'><a name='L201' href='#L201'><pre>201</pre></a></td><td class='skipped-line'></td><td class='code'><pre> /// The root node of the tree</pre></td></tr><tr><td class='line-number'><a name='L202' href='#L202'><pre>202</pre></a></td><td class='skipped-line'></td><td class='code'><pre> pub root: CstNode,</pre></td></tr><tr><td class='line-number'><a name='L203' href='#L203'><pre>203</pre></a></td><td class='skipped-line'></td><td class='code'><pre>}</pre></td></tr><tr><td class='line-number'><a name='L204' href='#L204'><pre>204</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L205' href='#L205'><pre>205</pre></a></td><td class='skipped-line'></td><td class='code'><pre>/// Helper function to serialize `ConcreteSyntaxTree` as `SerializableTree`</pre></td></tr><tr><td class='line-number'><a name='L206' href='#L206'><pre>206</pre></a></td><td class='covered-line'><pre>12</pre></td><td class='code'><pre>pub(crate) fn serialize_cst<S>(cst: &ConcreteSyntaxTree, serializer: S) -> Result<S::Ok, S::Error></pre></td></tr><tr><td class='line-number'><a name='L207' href='#L207'><pre>207</pre></a></td><td class='covered-line'><pre>12</pre></td><td class='code'><pre>where</pre></td></tr><tr><td class='line-number'><a name='L208' href='#L208'><pre>208</pre></a></td><td class='covered-line'><pre>12</pre></td><td class='code'><pre> S: serde::Serializer,</pre></td></tr><tr><td class='line-number'><a name='L209' href='#L209'><pre>209</pre></a></td><td class='skipped-line'></td><td class='code'><pre>{</pre></td></tr><tr><td class='line-number'><a name='L210' href='#L210'><pre>210</pre></a></td><td class='covered-line'><pre>12</pre></td><td class='code'><pre> cst.to_serializable().serialize(serializer)</pre></td></tr><tr><td class='line-number'><a name='L211' href='#L211'><pre>211</pre></a></td><td class='covered-line'><pre>12</pre></td><td class='code'><pre>}</pre></td></tr><tr><td class='line-number'><a name='L212' href='#L212'><pre>212</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L213' href='#L213'><pre>213</pre></a></td><td class='skipped-line'></td><td class='code'><pre>/// The language type for VB6 syntax trees.</pre></td></tr><tr><td class='line-number'><a name='L214' href='#L214'><pre>214</pre></a></td><td class='skipped-line'></td><td class='code'><pre>#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]</pre></td></tr><tr><td class='line-number'><a name='L215' href='#L215'><pre>215</pre></a></td><td class='skipped-line'></td><td class='code'><pre>pub enum VB6Language {}</pre></td></tr><tr><td class='line-number'><a name='L216' href='#L216'><pre>216</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L217' href='#L217'><pre>217</pre></a></td><td class='skipped-line'></td><td class='code'><pre>impl Language for VB6Language {</pre></td></tr><tr><td class='line-number'><a name='L218' href='#L218'><pre>218</pre></a></td><td class='skipped-line'></td><td class='code'><pre> type Kind = SyntaxKind;</pre></td></tr><tr><td class='line-number'><a name='L219' href='#L219'><pre>219</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L220' href='#L220'><pre>220</pre></a></td><td class='covered-line'><pre>420k</pre></td><td class='code'><pre> fn kind_from_raw(raw: rowan::SyntaxKind) -> Self::Kind {</pre></td></tr><tr><td class='line-number'><a name='L221' href='#L221'><pre>221</pre></a></td><td class='covered-line'><pre>420k</pre></td><td class='code'><pre> SyntaxKind::from_raw(raw)</pre></td></tr><tr><td class='line-number'><a name='L222' href='#L222'><pre>222</pre></a></td><td class='covered-line'><pre>420k</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L223' href='#L223'><pre>223</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L224' href='#L224'><pre>224</pre></a></td><td class='uncovered-line'><pre>0</pre></td><td class='code'><pre> <span class='region red'>fn kind_to_raw(kind: Self::Kind) -> rowan::SyntaxKind</span> {</pre></td></tr><tr><td class='line-number'><a name='L225' href='#L225'><pre>225</pre></a></td><td class='uncovered-line'><pre>0</pre></td><td class='code'><pre> <span class='region red'>kind</span>.<span class='region red'>to_raw</span>()</pre></td></tr><tr><td class='line-number'><a name='L226' href='#L226'><pre>226</pre></a></td><td class='uncovered-line'><pre>0</pre></td><td class='code'><pre> <span class='region red'>}</span></pre></td></tr><tr><td class='line-number'><a name='L227' href='#L227'><pre>227</pre></a></td><td class='skipped-line'></td><td class='code'><pre>}</pre></td></tr><tr><td class='line-number'><a name='L228' href='#L228'><pre>228</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L229' href='#L229'><pre>229</pre></a></td><td class='skipped-line'></td><td class='code'><pre>/// A Concrete Syntax Tree for VB6 code.</pre></td></tr><tr><td class='line-number'><a name='L230' href='#L230'><pre>230</pre></a></td><td class='skipped-line'></td><td class='code'><pre>///</pre></td></tr><tr><td class='line-number'><a name='L231' href='#L231'><pre>231</pre></a></td><td class='skipped-line'></td><td class='code'><pre>/// This structure wraps the rowan library's `GreenNode` internally but provides</pre></td></tr><tr><td class='line-number'><a name='L232' href='#L232'><pre>232</pre></a></td><td class='skipped-line'></td><td class='code'><pre>/// a public API that doesn't expose rowan types.</pre></td></tr><tr><td class='line-number'><a name='L233' href='#L233'><pre>233</pre></a></td><td class='skipped-line'></td><td class='code'><pre>#[derive(Debug, Clone, PartialEq, Eq, Hash)]</pre></td></tr><tr><td class='line-number'><a name='L234' href='#L234'><pre>234</pre></a></td><td class='skipped-line'></td><td class='code'><pre>pub struct ConcreteSyntaxTree {</pre></td></tr><tr><td class='line-number'><a name='L235' href='#L235'><pre>235</pre></a></td><td class='skipped-line'></td><td class='code'><pre> /// The root green node (internal implementation detail)</pre></td></tr><tr><td class='line-number'><a name='L236' href='#L236'><pre>236</pre></a></td><td class='skipped-line'></td><td class='code'><pre> root: GreenNode,</pre></td></tr><tr><td class='line-number'><a name='L237' href='#L237'><pre>237</pre></a></td><td class='skipped-line'></td><td class='code'><pre>}</pre></td></tr><tr><td class='line-number'><a name='L238' href='#L238'><pre>238</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L239' href='#L239'><pre>239</pre></a></td><td class='skipped-line'></td><td class='code'><pre>impl ConcreteSyntaxTree {</pre></td></tr><tr><td class='line-number'><a name='L240' href='#L240'><pre>240</pre></a></td><td class='skipped-line'></td><td class='code'><pre> /// Create a new CST from a `GreenNode` (internal use only)</pre></td></tr><tr><td class='line-number'><a name='L241' href='#L241'><pre>241</pre></a></td><td class='covered-line'><pre>5.44k</pre></td><td class='code'><pre> fn new(root: GreenNode) -> Self {</pre></td></tr><tr><td class='line-number'><a name='L242' href='#L242'><pre>242</pre></a></td><td class='covered-line'><pre>5.44k</pre></td><td class='code'><pre> Self { root }</pre></td></tr><tr><td class='line-number'><a name='L243' href='#L243'><pre>243</pre></a></td><td class='covered-line'><pre>5.44k</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L244' href='#L244'><pre>244</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L245' href='#L245'><pre>245</pre></a></td><td class='skipped-line'></td><td class='code'><pre> /// Parse a CST from a `SourceFile`.</pre></td></tr><tr><td class='line-number'><a name='L246' href='#L246'><pre>246</pre></a></td><td class='skipped-line'></td><td class='code'><pre> ///</pre></td></tr><tr><td class='line-number'><a name='L247' href='#L247'><pre>247</pre></a></td><td class='skipped-line'></td><td class='code'><pre> /// # Arguments</pre></td></tr><tr><td class='line-number'><a name='L248' href='#L248'><pre>248</pre></a></td><td class='skipped-line'></td><td class='code'><pre> ///</pre></td></tr><tr><td class='line-number'><a name='L249' href='#L249'><pre>249</pre></a></td><td class='skipped-line'></td><td class='code'><pre> /// * `source_file` - The source file to parse.</pre></td></tr><tr><td class='line-number'><a name='L250' href='#L250'><pre>250</pre></a></td><td class='skipped-line'></td><td class='code'><pre> ///</pre></td></tr><tr><td class='line-number'><a name='L251' href='#L251'><pre>251</pre></a></td><td class='skipped-line'></td><td class='code'><pre> /// # Returns</pre></td></tr><tr><td class='line-number'><a name='L252' href='#L252'><pre>252</pre></a></td><td class='skipped-line'></td><td class='code'><pre> ///</pre></td></tr><tr><td class='line-number'><a name='L253' href='#L253'><pre>253</pre></a></td><td class='skipped-line'></td><td class='code'><pre> /// A result containing the parsed CST or an error.</pre></td></tr><tr><td class='line-number'><a name='L254' href='#L254'><pre>254</pre></a></td><td class='skipped-line'></td><td class='code'><pre> #[must_use]</pre></td></tr><tr><td class='line-number'><a name='L255' href='#L255'><pre>255</pre></a></td><td class='uncovered-line'><pre>0</pre></td><td class='code'><pre> <span class='region red'>pub fn from_source(source_file: &SourceFile) -> ParseResult<'_, Self, CodeErrorKind></span> {</pre></td></tr><tr><td class='line-number'><a name='L256' href='#L256'><pre>256</pre></a></td><td class='uncovered-line'><pre>0</pre></td><td class='code'><pre> <span class='region red'>Self::from_text</span>(</pre></td></tr><tr><td class='line-number'><a name='L257' href='#L257'><pre>257</pre></a></td><td class='uncovered-line'><pre>0</pre></td><td class='code'><pre> <span class='region red'>source_file.file_name()</span>.<span class='region red'>to_string</span>(),</pre></td></tr><tr><td class='line-number'><a name='L258' href='#L258'><pre>258</pre></a></td><td class='uncovered-line'><pre>0</pre></td><td class='code'><pre> <span class='region red'>source_file.source_stream().contents</span>,</pre></td></tr><tr><td class='line-number'><a name='L259' href='#L259'><pre>259</pre></a></td><td class='skipped-line'></td><td class='code'><pre> )</pre></td></tr><tr><td class='line-number'><a name='L260' href='#L260'><pre>260</pre></a></td><td class='uncovered-line'><pre>0</pre></td><td class='code'><pre> <span class='region red'>}</span></pre></td></tr><tr><td class='line-number'><a name='L261' href='#L261'><pre>261</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L262' href='#L262'><pre>262</pre></a></td><td class='skipped-line'></td><td class='code'><pre> /// Parse a CST from source code.</pre></td></tr><tr><td class='line-number'><a name='L263' href='#L263'><pre>263</pre></a></td><td class='skipped-line'></td><td class='code'><pre> ///</pre></td></tr><tr><td class='line-number'><a name='L264' href='#L264'><pre>264</pre></a></td><td class='skipped-line'></td><td class='code'><pre> /// # Arguments</pre></td></tr><tr><td class='line-number'><a name='L265' href='#L265'><pre>265</pre></a></td><td class='skipped-line'></td><td class='code'><pre> ///</pre></td></tr><tr><td class='line-number'><a name='L266' href='#L266'><pre>266</pre></a></td><td class='skipped-line'></td><td class='code'><pre> /// * `file_name` - The name of the source file.</pre></td></tr><tr><td class='line-number'><a name='L267' href='#L267'><pre>267</pre></a></td><td class='skipped-line'></td><td class='code'><pre> /// * `contents` - The contents of the source file.</pre></td></tr><tr><td class='line-number'><a name='L268' href='#L268'><pre>268</pre></a></td><td class='skipped-line'></td><td class='code'><pre> ///</pre></td></tr><tr><td class='line-number'><a name='L269' href='#L269'><pre>269</pre></a></td><td class='skipped-line'></td><td class='code'><pre> /// # Returns</pre></td></tr><tr><td class='line-number'><a name='L270' href='#L270'><pre>270</pre></a></td><td class='skipped-line'></td><td class='code'><pre> ///</pre></td></tr><tr><td class='line-number'><a name='L271' href='#L271'><pre>271</pre></a></td><td class='skipped-line'></td><td class='code'><pre> /// A result containing the parsed CST or an error.</pre></td></tr><tr><td class='line-number'><a name='L272' href='#L272'><pre>272</pre></a></td><td class='covered-line'><pre>5.37k</pre></td><td class='code'><pre> pub fn from_text<S>(file_name: S, contents: &str) -> ParseResult<'_, Self, CodeErrorKind></pre></td></tr><tr><td class='line-number'><a name='L273' href='#L273'><pre>273</pre></a></td><td class='covered-line'><pre>5.37k</pre></td><td class='code'><pre> where</pre></td></tr><tr><td class='line-number'><a name='L274' href='#L274'><pre>274</pre></a></td><td class='covered-line'><pre>5.37k</pre></td><td class='code'><pre> S: Into<String>,</pre></td></tr><tr><td class='line-number'><a name='L275' href='#L275'><pre>275</pre></a></td><td class='skipped-line'></td><td class='code'><pre> {</pre></td></tr><tr><td class='line-number'><a name='L276' href='#L276'><pre>276</pre></a></td><td class='covered-line'><pre>5.37k</pre></td><td class='code'><pre> let mut source_stream = SourceStream::new(file_name.into(), contents);</pre></td></tr><tr><td class='line-number'><a name='L277' href='#L277'><pre>277</pre></a></td><td class='covered-line'><pre>5.37k</pre></td><td class='code'><pre> let token_stream_result = tokenize(&mut source_stream);</pre></td></tr><tr><td class='line-number'><a name='L278' href='#L278'><pre>278</pre></a></td><td class='covered-line'><pre>5.37k</pre></td><td class='code'><pre> let (token_stream_opt, failures) = token_stream_result.unpack();</pre></td></tr><tr><td class='line-number'><a name='L279' href='#L279'><pre>279</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L280' href='#L280'><pre>280</pre></a></td><td class='covered-line'><pre>5.37k</pre></td><td class='code'><pre> let Some(token_stream) = token_stream_opt else {</pre></td></tr><tr><td class='line-number'><a name='L281' href='#L281'><pre>281</pre></a></td><td class='uncovered-line'><pre>0</pre></td><td class='code'><pre> return <span class='region red'>ParseResult::new</span>(<span class='region red'>None</span>, <span class='region red'>failures</span>);</pre></td></tr><tr><td class='line-number'><a name='L282' href='#L282'><pre>282</pre></a></td><td class='skipped-line'></td><td class='code'><pre> };</pre></td></tr><tr><td class='line-number'><a name='L283' href='#L283'><pre>283</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L284' href='#L284'><pre>284</pre></a></td><td class='covered-line'><pre>5.37k</pre></td><td class='code'><pre> let cst = parse(token_stream);</pre></td></tr><tr><td class='line-number'><a name='L285' href='#L285'><pre>285</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L286' href='#L286'><pre>286</pre></a></td><td class='covered-line'><pre>5.37k</pre></td><td class='code'><pre> ParseResult::new(Some(cst), failures)</pre></td></tr><tr><td class='line-number'><a name='L287' href='#L287'><pre>287</pre></a></td><td class='covered-line'><pre>5.37k</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L288' href='#L288'><pre>288</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L289' href='#L289'><pre>289</pre></a></td><td class='skipped-line'></td><td class='code'><pre> /// Get the kind of the root node</pre></td></tr><tr><td class='line-number'><a name='L290' href='#L290'><pre>290</pre></a></td><td class='skipped-line'></td><td class='code'><pre> #[must_use]</pre></td></tr><tr><td class='line-number'><a name='L291' href='#L291'><pre>291</pre></a></td><td class='covered-line'><pre>4</pre></td><td class='code'><pre> pub fn root_kind(&self) -> SyntaxKind {</pre></td></tr><tr><td class='line-number'><a name='L292' href='#L292'><pre>292</pre></a></td><td class='covered-line'><pre>4</pre></td><td class='code'><pre> SyntaxKind::from_raw(self.root.kind())</pre></td></tr><tr><td class='line-number'><a name='L293' href='#L293'><pre>293</pre></a></td><td class='covered-line'><pre>4</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L294' href='#L294'><pre>294</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L295' href='#L295'><pre>295</pre></a></td><td class='skipped-line'></td><td class='code'><pre> /// Convert the CST to a serializable representation.</pre></td></tr><tr><td class='line-number'><a name='L296' href='#L296'><pre>296</pre></a></td><td class='skipped-line'></td><td class='code'><pre> ///</pre></td></tr><tr><td class='line-number'><a name='L297' href='#L297'><pre>297</pre></a></td><td class='skipped-line'></td><td class='code'><pre> /// This method creates a `SerializableTree` that can be used with</pre></td></tr><tr><td class='line-number'><a name='L298' href='#L298'><pre>298</pre></a></td><td class='skipped-line'></td><td class='code'><pre> /// snapshot testing tools like `insta`. The serializable tree contains</pre></td></tr><tr><td class='line-number'><a name='L299' href='#L299'><pre>299</pre></a></td><td class='skipped-line'></td><td class='code'><pre> /// the complete tree structure as a hierarchy of `CstNode` instances.</pre></td></tr><tr><td class='line-number'><a name='L300' href='#L300'><pre>300</pre></a></td><td class='skipped-line'></td><td class='code'><pre> ///</pre></td></tr><tr><td class='line-number'><a name='L301' href='#L301'><pre>301</pre></a></td><td class='skipped-line'></td><td class='code'><pre> /// # Example</pre></td></tr><tr><td class='line-number'><a name='L302' href='#L302'><pre>302</pre></a></td><td class='skipped-line'></td><td class='code'><pre> ///</pre></td></tr><tr><td class='line-number'><a name='L303' href='#L303'><pre>303</pre></a></td><td class='skipped-line'></td><td class='code'><pre> /// ```rust</pre></td></tr><tr><td class='line-number'><a name='L304' href='#L304'><pre>304</pre></a></td><td class='skipped-line'></td><td class='code'><pre> /// use vb6parse::ConcreteSyntaxTree;</pre></td></tr><tr><td class='line-number'><a name='L305' href='#L305'><pre>305</pre></a></td><td class='skipped-line'></td><td class='code'><pre> ///</pre></td></tr><tr><td class='line-number'><a name='L306' href='#L306'><pre>306</pre></a></td><td class='skipped-line'></td><td class='code'><pre> /// let source = "Sub Test()\nEnd Sub\n";</pre></td></tr><tr><td class='line-number'><a name='L307' href='#L307'><pre>307</pre></a></td><td class='skipped-line'></td><td class='code'><pre> /// let result = ConcreteSyntaxTree::from_text("test.bas", source);</pre></td></tr><tr><td class='line-number'><a name='L308' href='#L308'><pre>308</pre></a></td><td class='skipped-line'></td><td class='code'><pre> ///</pre></td></tr><tr><td class='line-number'><a name='L309' href='#L309'><pre>309</pre></a></td><td class='skipped-line'></td><td class='code'><pre> /// let (cst_opt, failures) = result.unpack();</pre></td></tr><tr><td class='line-number'><a name='L310' href='#L310'><pre>310</pre></a></td><td class='skipped-line'></td><td class='code'><pre> ///</pre></td></tr><tr><td class='line-number'><a name='L311' href='#L311'><pre>311</pre></a></td><td class='skipped-line'></td><td class='code'><pre> /// let cst = cst_opt.expect("Failed to parse source");</pre></td></tr><tr><td class='line-number'><a name='L312' href='#L312'><pre>312</pre></a></td><td class='skipped-line'></td><td class='code'><pre> ///</pre></td></tr><tr><td class='line-number'><a name='L313' href='#L313'><pre>313</pre></a></td><td class='skipped-line'></td><td class='code'><pre> /// if !failures.is_empty() {</pre></td></tr><tr><td class='line-number'><a name='L314' href='#L314'><pre>314</pre></a></td><td class='skipped-line'></td><td class='code'><pre> /// for failure in failures.iter() {</pre></td></tr><tr><td class='line-number'><a name='L315' href='#L315'><pre>315</pre></a></td><td class='skipped-line'></td><td class='code'><pre> /// failure.print();</pre></td></tr><tr><td class='line-number'><a name='L316' href='#L316'><pre>316</pre></a></td><td class='skipped-line'></td><td class='code'><pre> /// }</pre></td></tr><tr><td class='line-number'><a name='L317' href='#L317'><pre>317</pre></a></td><td class='skipped-line'></td><td class='code'><pre> /// panic!("Failed to parse source with {} errors.", failures.len());</pre></td></tr><tr><td class='line-number'><a name='L318' href='#L318'><pre>318</pre></a></td><td class='skipped-line'></td><td class='code'><pre> /// };</pre></td></tr><tr><td class='line-number'><a name='L319' href='#L319'><pre>319</pre></a></td><td class='skipped-line'></td><td class='code'><pre> ///</pre></td></tr><tr><td class='line-number'><a name='L320' href='#L320'><pre>320</pre></a></td><td class='skipped-line'></td><td class='code'><pre> /// let serializable = cst.to_serializable();</pre></td></tr><tr><td class='line-number'><a name='L321' href='#L321'><pre>321</pre></a></td><td class='skipped-line'></td><td class='code'><pre> ///</pre></td></tr><tr><td class='line-number'><a name='L322' href='#L322'><pre>322</pre></a></td><td class='skipped-line'></td><td class='code'><pre> /// // Can now be used with insta::assert_yaml_snapshot!</pre></td></tr><tr><td class='line-number'><a name='L323' href='#L323'><pre>323</pre></a></td><td class='skipped-line'></td><td class='code'><pre> /// ```</pre></td></tr><tr><td class='line-number'><a name='L324' href='#L324'><pre>324</pre></a></td><td class='skipped-line'></td><td class='code'><pre> #[must_use]</pre></td></tr><tr><td class='line-number'><a name='L325' href='#L325'><pre>325</pre></a></td><td class='covered-line'><pre>5.40k</pre></td><td class='code'><pre> pub fn to_serializable(&self) -> SerializableTree {</pre></td></tr><tr><td class='line-number'><a name='L326' href='#L326'><pre>326</pre></a></td><td class='covered-line'><pre>5.40k</pre></td><td class='code'><pre> SerializableTree {</pre></td></tr><tr><td class='line-number'><a name='L327' href='#L327'><pre>327</pre></a></td><td class='covered-line'><pre>5.40k</pre></td><td class='code'><pre> root: self.to_root_node(),</pre></td></tr><tr><td class='line-number'><a name='L328' href='#L328'><pre>328</pre></a></td><td class='covered-line'><pre>5.40k</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L329' href='#L329'><pre>329</pre></a></td><td class='covered-line'><pre>5.40k</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L330' href='#L330'><pre>330</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L331' href='#L331'><pre>331</pre></a></td><td class='skipped-line'></td><td class='code'><pre> /// Convert the internal rowan tree to a root `CstNode`.</pre></td></tr><tr><td class='line-number'><a name='L332' href='#L332'><pre>332</pre></a></td><td class='skipped-line'></td><td class='code'><pre> ///</pre></td></tr><tr><td class='line-number'><a name='L333' href='#L333'><pre>333</pre></a></td><td class='skipped-line'></td><td class='code'><pre> /// # Returns</pre></td></tr><tr><td class='line-number'><a name='L334' href='#L334'><pre>334</pre></a></td><td class='skipped-line'></td><td class='code'><pre> ///</pre></td></tr><tr><td class='line-number'><a name='L335' href='#L335'><pre>335</pre></a></td><td class='skipped-line'></td><td class='code'><pre> /// The root `CstNode` representing the entire CST.</pre></td></tr><tr><td class='line-number'><a name='L336' href='#L336'><pre>336</pre></a></td><td class='skipped-line'></td><td class='code'><pre> #[must_use]</pre></td></tr><tr><td class='line-number'><a name='L337' href='#L337'><pre>337</pre></a></td><td class='covered-line'><pre>5.41k</pre></td><td class='code'><pre> pub fn to_root_node(&self) -> CstNode {</pre></td></tr><tr><td class='line-number'><a name='L338' href='#L338'><pre>338</pre></a></td><td class='covered-line'><pre>5.41k</pre></td><td class='code'><pre> CstNode::new(SyntaxKind::Root, self.text(), false, self.children())</pre></td></tr><tr><td class='line-number'><a name='L339' href='#L339'><pre>339</pre></a></td><td class='covered-line'><pre>5.41k</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L340' href='#L340'><pre>340</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L341' href='#L341'><pre>341</pre></a></td><td class='skipped-line'></td><td class='code'><pre> /// Create a new CST with specified node kinds removed from the root level.</pre></td></tr><tr><td class='line-number'><a name='L342' href='#L342'><pre>342</pre></a></td><td class='skipped-line'></td><td class='code'><pre> ///</pre></td></tr><tr><td class='line-number'><a name='L343' href='#L343'><pre>343</pre></a></td><td class='skipped-line'></td><td class='code'><pre> /// This method filters out direct children of the root node that match any of the</pre></td></tr><tr><td class='line-number'><a name='L344' href='#L344'><pre>344</pre></a></td><td class='skipped-line'></td><td class='code'><pre> /// specified kinds. This is useful for removing nodes that have already been parsed</pre></td></tr><tr><td class='line-number'><a name='L345' href='#L345'><pre>345</pre></a></td><td class='skipped-line'></td><td class='code'><pre> /// into structured data (like version statements, attributes, etc.) to avoid duplication.</pre></td></tr><tr><td class='line-number'><a name='L346' href='#L346'><pre>346</pre></a></td><td class='skipped-line'></td><td class='code'><pre> ///</pre></td></tr><tr><td class='line-number'><a name='L347' href='#L347'><pre>347</pre></a></td><td class='skipped-line'></td><td class='code'><pre> /// # Arguments</pre></td></tr><tr><td class='line-number'><a name='L348' href='#L348'><pre>348</pre></a></td><td class='skipped-line'></td><td class='code'><pre> ///</pre></td></tr><tr><td class='line-number'><a name='L349' href='#L349'><pre>349</pre></a></td><td class='skipped-line'></td><td class='code'><pre> /// * `kinds_to_remove` - A slice of `SyntaxKind` values to filter out</pre></td></tr><tr><td class='line-number'><a name='L350' href='#L350'><pre>350</pre></a></td><td class='skipped-line'></td><td class='code'><pre> ///</pre></td></tr><tr><td class='line-number'><a name='L351' href='#L351'><pre>351</pre></a></td><td class='skipped-line'></td><td class='code'><pre> /// # Returns</pre></td></tr><tr><td class='line-number'><a name='L352' href='#L352'><pre>352</pre></a></td><td class='skipped-line'></td><td class='code'><pre> ///</pre></td></tr><tr><td class='line-number'><a name='L353' href='#L353'><pre>353</pre></a></td><td class='skipped-line'></td><td class='code'><pre> /// A new `ConcreteSyntaxTree` with the specified kinds removed from the root level.</pre></td></tr><tr><td class='line-number'><a name='L354' href='#L354'><pre>354</pre></a></td><td class='skipped-line'></td><td class='code'><pre> ///</pre></td></tr><tr><td class='line-number'><a name='L355' href='#L355'><pre>355</pre></a></td><td class='skipped-line'></td><td class='code'><pre> /// # Example</pre></td></tr><tr><td class='line-number'><a name='L356' href='#L356'><pre>356</pre></a></td><td class='skipped-line'></td><td class='code'><pre> ///</pre></td></tr><tr><td class='line-number'><a name='L357' href='#L357'><pre>357</pre></a></td><td class='skipped-line'></td><td class='code'><pre> /// ```rust</pre></td></tr><tr><td class='line-number'><a name='L358' href='#L358'><pre>358</pre></a></td><td class='skipped-line'></td><td class='code'><pre> /// use vb6parse::ConcreteSyntaxTree;</pre></td></tr><tr><td class='line-number'><a name='L359' href='#L359'><pre>359</pre></a></td><td class='skipped-line'></td><td class='code'><pre> /// use vb6parse::parsers::SyntaxKind;</pre></td></tr><tr><td class='line-number'><a name='L360' href='#L360'><pre>360</pre></a></td><td class='skipped-line'></td><td class='code'><pre> ///</pre></td></tr><tr><td class='line-number'><a name='L361' href='#L361'><pre>361</pre></a></td><td class='skipped-line'></td><td class='code'><pre> /// let source = "VERSION 5.00\nSub Test()\nEnd Sub\n";</pre></td></tr><tr><td class='line-number'><a name='L362' href='#L362'><pre>362</pre></a></td><td class='skipped-line'></td><td class='code'><pre> /// let result = ConcreteSyntaxTree::from_text("test.bas", source);</pre></td></tr><tr><td class='line-number'><a name='L363' href='#L363'><pre>363</pre></a></td><td class='skipped-line'></td><td class='code'><pre> /// let (cst_opt, failures) = result.unpack();</pre></td></tr><tr><td class='line-number'><a name='L364' href='#L364'><pre>364</pre></a></td><td class='skipped-line'></td><td class='code'><pre> /// let cst = cst_opt.expect("Failed to parse source");</pre></td></tr><tr><td class='line-number'><a name='L365' href='#L365'><pre>365</pre></a></td><td class='skipped-line'></td><td class='code'><pre> ///</pre></td></tr><tr><td class='line-number'><a name='L366' href='#L366'><pre>366</pre></a></td><td class='skipped-line'></td><td class='code'><pre> /// // Remove version statement since it's already parsed</pre></td></tr><tr><td class='line-number'><a name='L367' href='#L367'><pre>367</pre></a></td><td class='skipped-line'></td><td class='code'><pre> /// let filtered = cst.without_kinds(&[SyntaxKind::VersionStatement]);</pre></td></tr><tr><td class='line-number'><a name='L368' href='#L368'><pre>368</pre></a></td><td class='skipped-line'></td><td class='code'><pre> ///</pre></td></tr><tr><td class='line-number'><a name='L369' href='#L369'><pre>369</pre></a></td><td class='skipped-line'></td><td class='code'><pre> /// assert!(!filtered.contains_kind(SyntaxKind::VersionStatement));</pre></td></tr><tr><td class='line-number'><a name='L370' href='#L370'><pre>370</pre></a></td><td class='skipped-line'></td><td class='code'><pre> /// ```</pre></td></tr><tr><td class='line-number'><a name='L371' href='#L371'><pre>371</pre></a></td><td class='skipped-line'></td><td class='code'><pre> #[must_use]</pre></td></tr><tr><td class='line-number'><a name='L372' href='#L372'><pre>372</pre></a></td><td class='covered-line'><pre>15</pre></td><td class='code'><pre> pub fn without_kinds(&self, kinds_to_remove: &[SyntaxKind]) -> Self {</pre></td></tr><tr><td class='line-number'><a name='L373' href='#L373'><pre>373</pre></a></td><td class='covered-line'><pre>15</pre></td><td class='code'><pre> let syntax_node = rowan::SyntaxNode::<VB6Language>::new_root(self.root.clone());</pre></td></tr><tr><td class='line-number'><a name='L374' href='#L374'><pre>374</pre></a></td><td class='covered-line'><pre>15</pre></td><td class='code'><pre> let mut builder = GreenNodeBuilder::new();</pre></td></tr><tr><td class='line-number'><a name='L375' href='#L375'><pre>375</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L376' href='#L376'><pre>376</pre></a></td><td class='covered-line'><pre>15</pre></td><td class='code'><pre> builder.start_node(SyntaxKind::Root.to_raw());</pre></td></tr><tr><td class='line-number'><a name='L377' href='#L377'><pre>377</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L378' href='#L378'><pre>378</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Iterate through children and only add those not in the filter list</pre></td></tr><tr><td class='line-number'><a name='L379' href='#L379'><pre>379</pre></a></td><td class='covered-line'><pre>912</pre></td><td class='code'><pre> for child in <div class='tooltip'>syntax_node<span class='tooltip-content'>15</span></div>.<div class='tooltip'>children_with_tokens<span class='tooltip-content'>15</span></div>() {</pre></td></tr><tr><td class='line-number'><a name='L380' href='#L380'><pre>380</pre></a></td><td class='covered-line'><pre>912</pre></td><td class='code'><pre> let child_kind = match &child {</pre></td></tr><tr><td class='line-number'><a name='L381' href='#L381'><pre>381</pre></a></td><td class='covered-line'><pre>275</pre></td><td class='code'><pre> rowan::NodeOrToken::Node(node) => node.kind(),</pre></td></tr><tr><td class='line-number'><a name='L382' href='#L382'><pre>382</pre></a></td><td class='covered-line'><pre>637</pre></td><td class='code'><pre> rowan::NodeOrToken::Token(token) => token.kind(),</pre></td></tr><tr><td class='line-number'><a name='L383' href='#L383'><pre>383</pre></a></td><td class='skipped-line'></td><td class='code'><pre> };</pre></td></tr><tr><td class='line-number'><a name='L384' href='#L384'><pre>384</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L385' href='#L385'><pre>385</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Skip if this kind should be removed</pre></td></tr><tr><td class='line-number'><a name='L386' href='#L386'><pre>386</pre></a></td><td class='covered-line'><pre>912</pre></td><td class='code'><pre> if kinds_to_remove.contains(&child_kind) {</pre></td></tr><tr><td class='line-number'><a name='L387' href='#L387'><pre>387</pre></a></td><td class='covered-line'><pre>66</pre></td><td class='code'><pre> continue;</pre></td></tr><tr><td class='line-number'><a name='L388' href='#L388'><pre>388</pre></a></td><td class='covered-line'><pre>846</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L389' href='#L389'><pre>389</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L390' href='#L390'><pre>390</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Add the child to the new tree</pre></td></tr><tr><td class='line-number'><a name='L391' href='#L391'><pre>391</pre></a></td><td class='covered-line'><pre>846</pre></td><td class='code'><pre> Self::clone_node_or_token(&mut builder, child);</pre></td></tr><tr><td class='line-number'><a name='L392' href='#L392'><pre>392</pre></a></td><td class='skipped-line'></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L393' href='#L393'><pre>393</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L394' href='#L394'><pre>394</pre></a></td><td class='covered-line'><pre>15</pre></td><td class='code'><pre> builder.finish_node();</pre></td></tr><tr><td class='line-number'><a name='L395' href='#L395'><pre>395</pre></a></td><td class='covered-line'><pre>15</pre></td><td class='code'><pre> let new_root = builder.finish();</pre></td></tr><tr><td class='line-number'><a name='L396' href='#L396'><pre>396</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L397' href='#L397'><pre>397</pre></a></td><td class='covered-line'><pre>15</pre></td><td class='code'><pre> Self::new(new_root)</pre></td></tr><tr><td class='line-number'><a name='L398' href='#L398'><pre>398</pre></a></td><td class='covered-line'><pre>15</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L399' href='#L399'><pre>399</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L400' href='#L400'><pre>400</pre></a></td><td class='skipped-line'></td><td class='code'><pre> /// Recursively clone a node or token into a builder</pre></td></tr><tr><td class='line-number'><a name='L401' href='#L401'><pre>401</pre></a></td><td class='covered-line'><pre>23.1k</pre></td><td class='code'><pre> fn clone_node_or_token(</pre></td></tr><tr><td class='line-number'><a name='L402' href='#L402'><pre>402</pre></a></td><td class='covered-line'><pre>23.1k</pre></td><td class='code'><pre> builder: &mut GreenNodeBuilder<'static>,</pre></td></tr><tr><td class='line-number'><a name='L403' href='#L403'><pre>403</pre></a></td><td class='covered-line'><pre>23.1k</pre></td><td class='code'><pre> node_or_token: rowan::NodeOrToken<</pre></td></tr><tr><td class='line-number'><a name='L404' href='#L404'><pre>404</pre></a></td><td class='covered-line'><pre>23.1k</pre></td><td class='code'><pre> rowan::SyntaxNode<VB6Language>,</pre></td></tr><tr><td class='line-number'><a name='L405' href='#L405'><pre>405</pre></a></td><td class='covered-line'><pre>23.1k</pre></td><td class='code'><pre> rowan::SyntaxToken<VB6Language>,</pre></td></tr><tr><td class='line-number'><a name='L406' href='#L406'><pre>406</pre></a></td><td class='covered-line'><pre>23.1k</pre></td><td class='code'><pre> >,</pre></td></tr><tr><td class='line-number'><a name='L407' href='#L407'><pre>407</pre></a></td><td class='covered-line'><pre>23.1k</pre></td><td class='code'><pre> ) {</pre></td></tr><tr><td class='line-number'><a name='L408' href='#L408'><pre>408</pre></a></td><td class='covered-line'><pre>23.1k</pre></td><td class='code'><pre> match node_or_token {</pre></td></tr><tr><td class='line-number'><a name='L409' href='#L409'><pre>409</pre></a></td><td class='covered-line'><pre>3.65k</pre></td><td class='code'><pre> rowan::NodeOrToken::Node(node) => {</pre></td></tr><tr><td class='line-number'><a name='L410' href='#L410'><pre>410</pre></a></td><td class='covered-line'><pre>3.65k</pre></td><td class='code'><pre> builder.start_node(node.kind().to_raw());</pre></td></tr><tr><td class='line-number'><a name='L411' href='#L411'><pre>411</pre></a></td><td class='covered-line'><pre>22.3k</pre></td><td class='code'><pre> for child in <div class='tooltip'>node<span class='tooltip-content'>3.65k</span></div>.<div class='tooltip'>children_with_tokens<span class='tooltip-content'>3.65k</span></div>() {</pre></td></tr><tr><td class='line-number'><a name='L412' href='#L412'><pre>412</pre></a></td><td class='covered-line'><pre>22.3k</pre></td><td class='code'><pre> Self::clone_node_or_token(builder, child);</pre></td></tr><tr><td class='line-number'><a name='L413' href='#L413'><pre>413</pre></a></td><td class='covered-line'><pre>22.3k</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L414' href='#L414'><pre>414</pre></a></td><td class='covered-line'><pre>3.65k</pre></td><td class='code'><pre> builder.finish_node();</pre></td></tr><tr><td class='line-number'><a name='L415' href='#L415'><pre>415</pre></a></td><td class='skipped-line'></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L416' href='#L416'><pre>416</pre></a></td><td class='covered-line'><pre>19.5k</pre></td><td class='code'><pre> rowan::NodeOrToken::Token(token) => {</pre></td></tr><tr><td class='line-number'><a name='L417' href='#L417'><pre>417</pre></a></td><td class='covered-line'><pre>19.5k</pre></td><td class='code'><pre> builder.token(token.kind().to_raw(), token.text());</pre></td></tr><tr><td class='line-number'><a name='L418' href='#L418'><pre>418</pre></a></td><td class='covered-line'><pre>19.5k</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L419' href='#L419'><pre>419</pre></a></td><td class='skipped-line'></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L420' href='#L420'><pre>420</pre></a></td><td class='covered-line'><pre>23.1k</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L421' href='#L421'><pre>421</pre></a></td><td class='skipped-line'></td><td class='code'><pre>}</pre></td></tr><tr><td class='line-number'><a name='L422' href='#L422'><pre>422</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L423' href='#L423'><pre>423</pre></a></td><td class='skipped-line'></td><td class='code'><pre>/// Parse a `TokenStream` into a Concrete Syntax Tree.</pre></td></tr><tr><td class='line-number'><a name='L424' href='#L424'><pre>424</pre></a></td><td class='skipped-line'></td><td class='code'><pre>///</pre></td></tr><tr><td class='line-number'><a name='L425' href='#L425'><pre>425</pre></a></td><td class='skipped-line'></td><td class='code'><pre>/// This function takes a `TokenStream` and constructs a CST that represents</pre></td></tr><tr><td class='line-number'><a name='L426' href='#L426'><pre>426</pre></a></td><td class='skipped-line'></td><td class='code'><pre>/// the structure of the VB6 code.</pre></td></tr><tr><td class='line-number'><a name='L427' href='#L427'><pre>427</pre></a></td><td class='skipped-line'></td><td class='code'><pre>///</pre></td></tr><tr><td class='line-number'><a name='L428' href='#L428'><pre>428</pre></a></td><td class='skipped-line'></td><td class='code'><pre>/// # Arguments</pre></td></tr><tr><td class='line-number'><a name='L429' href='#L429'><pre>429</pre></a></td><td class='skipped-line'></td><td class='code'><pre>///</pre></td></tr><tr><td class='line-number'><a name='L430' href='#L430'><pre>430</pre></a></td><td class='skipped-line'></td><td class='code'><pre>/// * `tokens` - The token stream to parse</pre></td></tr><tr><td class='line-number'><a name='L431' href='#L431'><pre>431</pre></a></td><td class='skipped-line'></td><td class='code'><pre>///</pre></td></tr><tr><td class='line-number'><a name='L432' href='#L432'><pre>432</pre></a></td><td class='skipped-line'></td><td class='code'><pre>/// # Returns</pre></td></tr><tr><td class='line-number'><a name='L433' href='#L433'><pre>433</pre></a></td><td class='skipped-line'></td><td class='code'><pre>///</pre></td></tr><tr><td class='line-number'><a name='L434' href='#L434'><pre>434</pre></a></td><td class='skipped-line'></td><td class='code'><pre>/// A `ConcreteSyntaxTree` representing the parsed code.</pre></td></tr><tr><td class='line-number'><a name='L435' href='#L435'><pre>435</pre></a></td><td class='skipped-line'></td><td class='code'><pre>///</pre></td></tr><tr><td class='line-number'><a name='L436' href='#L436'><pre>436</pre></a></td><td class='skipped-line'></td><td class='code'><pre>/// # Example</pre></td></tr><tr><td class='line-number'><a name='L437' href='#L437'><pre>437</pre></a></td><td class='skipped-line'></td><td class='code'><pre>///</pre></td></tr><tr><td class='line-number'><a name='L438' href='#L438'><pre>438</pre></a></td><td class='skipped-line'></td><td class='code'><pre>/// ```rust</pre></td></tr><tr><td class='line-number'><a name='L439' href='#L439'><pre>439</pre></a></td><td class='skipped-line'></td><td class='code'><pre>/// use vb6parse::lexer::TokenStream;</pre></td></tr><tr><td class='line-number'><a name='L440' href='#L440'><pre>440</pre></a></td><td class='skipped-line'></td><td class='code'><pre>/// use vb6parse::parsers::cst::parse;</pre></td></tr><tr><td class='line-number'><a name='L441' href='#L441'><pre>441</pre></a></td><td class='skipped-line'></td><td class='code'><pre>///</pre></td></tr><tr><td class='line-number'><a name='L442' href='#L442'><pre>442</pre></a></td><td class='skipped-line'></td><td class='code'><pre>/// let tokens = TokenStream::new("example.bas".to_string(), vec![]);</pre></td></tr><tr><td class='line-number'><a name='L443' href='#L443'><pre>443</pre></a></td><td class='skipped-line'></td><td class='code'><pre>/// let cst = parse(tokens);</pre></td></tr><tr><td class='line-number'><a name='L444' href='#L444'><pre>444</pre></a></td><td class='skipped-line'></td><td class='code'><pre>/// ```</pre></td></tr><tr><td class='line-number'><a name='L445' href='#L445'><pre>445</pre></a></td><td class='skipped-line'></td><td class='code'><pre>#[must_use]</pre></td></tr><tr><td class='line-number'><a name='L446' href='#L446'><pre>446</pre></a></td><td class='covered-line'><pre>5.43k</pre></td><td class='code'><pre>pub fn parse(tokens: TokenStream) -> ConcreteSyntaxTree {</pre></td></tr><tr><td class='line-number'><a name='L447' href='#L447'><pre>447</pre></a></td><td class='covered-line'><pre>5.43k</pre></td><td class='code'><pre> let parser = Parser::new(tokens);</pre></td></tr><tr><td class='line-number'><a name='L448' href='#L448'><pre>448</pre></a></td><td class='covered-line'><pre>5.43k</pre></td><td class='code'><pre> parser.parse_root()</pre></td></tr><tr><td class='line-number'><a name='L449' href='#L449'><pre>449</pre></a></td><td class='covered-line'><pre>5.43k</pre></td><td class='code'><pre>}</pre></td></tr><tr><td class='line-number'><a name='L450' href='#L450'><pre>450</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L451' href='#L451'><pre>451</pre></a></td><td class='skipped-line'></td><td class='code'><pre>/// Internal parser state for building the CST</pre></td></tr><tr><td class='line-number'><a name='L452' href='#L452'><pre>452</pre></a></td><td class='skipped-line'></td><td class='code'><pre>pub(crate) struct Parser<'a> {</pre></td></tr><tr><td class='line-number'><a name='L453' href='#L453'><pre>453</pre></a></td><td class='skipped-line'></td><td class='code'><pre> pub(crate) tokens: Vec<(&'a str, Token)>,</pre></td></tr><tr><td class='line-number'><a name='L454' href='#L454'><pre>454</pre></a></td><td class='skipped-line'></td><td class='code'><pre> pub(crate) pos: usize,</pre></td></tr><tr><td class='line-number'><a name='L455' href='#L455'><pre>455</pre></a></td><td class='skipped-line'></td><td class='code'><pre> pub(crate) builder: GreenNodeBuilder<'static>,</pre></td></tr><tr><td class='line-number'><a name='L456' href='#L456'><pre>456</pre></a></td><td class='skipped-line'></td><td class='code'><pre> pub(crate) parsing_header: bool,</pre></td></tr><tr><td class='line-number'><a name='L457' href='#L457'><pre>457</pre></a></td><td class='skipped-line'></td><td class='code'><pre>}</pre></td></tr><tr><td class='line-number'><a name='L458' href='#L458'><pre>458</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L459' href='#L459'><pre>459</pre></a></td><td class='skipped-line'></td><td class='code'><pre>impl<'a> Parser<'a> {</pre></td></tr><tr><td class='line-number'><a name='L460' href='#L460'><pre>460</pre></a></td><td class='covered-line'><pre>5.43k</pre></td><td class='code'><pre> fn new(token_stream: TokenStream<'a>) -> Self {</pre></td></tr><tr><td class='line-number'><a name='L461' href='#L461'><pre>461</pre></a></td><td class='covered-line'><pre>5.43k</pre></td><td class='code'><pre> Parser {</pre></td></tr><tr><td class='line-number'><a name='L462' href='#L462'><pre>462</pre></a></td><td class='covered-line'><pre>5.43k</pre></td><td class='code'><pre> tokens: token_stream.into_tokens(),</pre></td></tr><tr><td class='line-number'><a name='L463' href='#L463'><pre>463</pre></a></td><td class='covered-line'><pre>5.43k</pre></td><td class='code'><pre> pos: 0,</pre></td></tr><tr><td class='line-number'><a name='L464' href='#L464'><pre>464</pre></a></td><td class='covered-line'><pre>5.43k</pre></td><td class='code'><pre> builder: GreenNodeBuilder::new(),</pre></td></tr><tr><td class='line-number'><a name='L465' href='#L465'><pre>465</pre></a></td><td class='covered-line'><pre>5.43k</pre></td><td class='code'><pre> parsing_header: true,</pre></td></tr><tr><td class='line-number'><a name='L466' href='#L466'><pre>466</pre></a></td><td class='covered-line'><pre>5.43k</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L467' href='#L467'><pre>467</pre></a></td><td class='covered-line'><pre>5.43k</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L468' href='#L468'><pre>468</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L469' href='#L469'><pre>469</pre></a></td><td class='skipped-line'></td><td class='code'><pre> /// Create parser for direct extraction mode (control-only parsing)</pre></td></tr><tr><td class='line-number'><a name='L470' href='#L470'><pre>470</pre></a></td><td class='covered-line'><pre>72</pre></td><td class='code'><pre> pub(crate) fn new_direct_extraction(tokens: Vec<(&'a str, Token)>, pos: usize) -> Self {</pre></td></tr><tr><td class='line-number'><a name='L471' href='#L471'><pre>471</pre></a></td><td class='covered-line'><pre>72</pre></td><td class='code'><pre> Parser {</pre></td></tr><tr><td class='line-number'><a name='L472' href='#L472'><pre>472</pre></a></td><td class='covered-line'><pre>72</pre></td><td class='code'><pre> tokens,</pre></td></tr><tr><td class='line-number'><a name='L473' href='#L473'><pre>473</pre></a></td><td class='covered-line'><pre>72</pre></td><td class='code'><pre> pos,</pre></td></tr><tr><td class='line-number'><a name='L474' href='#L474'><pre>474</pre></a></td><td class='covered-line'><pre>72</pre></td><td class='code'><pre> builder: GreenNodeBuilder::new(),</pre></td></tr><tr><td class='line-number'><a name='L475' href='#L475'><pre>475</pre></a></td><td class='covered-line'><pre>72</pre></td><td class='code'><pre> parsing_header: true,</pre></td></tr><tr><td class='line-number'><a name='L476' href='#L476'><pre>476</pre></a></td><td class='covered-line'><pre>72</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L477' href='#L477'><pre>477</pre></a></td><td class='covered-line'><pre>72</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L478' href='#L478'><pre>478</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L479' href='#L479'><pre>479</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Create parser for hybrid mode (`FormFile` optimization)</pre></td></tr><tr><td class='line-number'><a name='L480' href='#L480'><pre>480</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // ==================== Direct Extraction Helpers ====================</pre></td></tr><tr><td class='line-number'><a name='L481' href='#L481'><pre>481</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // These methods support direct extraction without CST building</pre></td></tr><tr><td class='line-number'><a name='L482' href='#L482'><pre>482</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L483' href='#L483'><pre>483</pre></a></td><td class='skipped-line'></td><td class='code'><pre> /// Consume the parser and return the remaining tokens</pre></td></tr><tr><td class='line-number'><a name='L484' href='#L484'><pre>484</pre></a></td><td class='skipped-line'></td><td class='code'><pre> /// Used to get tokens after direct extraction for CST building</pre></td></tr><tr><td class='line-number'><a name='L485' href='#L485'><pre>485</pre></a></td><td class='covered-line'><pre>35</pre></td><td class='code'><pre> pub(crate) fn into_tokens(self) -> Vec<(&'a str, Token)> {</pre></td></tr><tr><td class='line-number'><a name='L486' href='#L486'><pre>486</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Return tokens from current position onwards</pre></td></tr><tr><td class='line-number'><a name='L487' href='#L487'><pre>487</pre></a></td><td class='covered-line'><pre>35</pre></td><td class='code'><pre> self.tokens[self.pos..].to_vec()</pre></td></tr><tr><td class='line-number'><a name='L488' href='#L488'><pre>488</pre></a></td><td class='covered-line'><pre>35</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L489' href='#L489'><pre>489</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L490' href='#L490'><pre>490</pre></a></td><td class='skipped-line'></td><td class='code'><pre> /// Skip whitespace tokens without consuming them into the CST</pre></td></tr><tr><td class='line-number'><a name='L491' href='#L491'><pre>491</pre></a></td><td class='covered-line'><pre>19.4k</pre></td><td class='code'><pre> pub(crate) fn skip_whitespace(&mut self) {</pre></td></tr><tr><td class='line-number'><a name='L492' href='#L492'><pre>492</pre></a></td><td class='covered-line'><pre>32.1k</pre></td><td class='code'><pre> while self.at_token(Token::Whitespace) {</pre></td></tr><tr><td class='line-number'><a name='L493' href='#L493'><pre>493</pre></a></td><td class='covered-line'><pre>12.7k</pre></td><td class='code'><pre> self.pos += 1;</pre></td></tr><tr><td class='line-number'><a name='L494' href='#L494'><pre>494</pre></a></td><td class='covered-line'><pre>12.7k</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L495' href='#L495'><pre>495</pre></a></td><td class='covered-line'><pre>19.4k</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L496' href='#L496'><pre>496</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L497' href='#L497'><pre>497</pre></a></td><td class='skipped-line'></td><td class='code'><pre> /// Skip whitespace and newline tokens without consuming them into the CST</pre></td></tr><tr><td class='line-number'><a name='L498' href='#L498'><pre>498</pre></a></td><td class='covered-line'><pre>7.18k</pre></td><td class='code'><pre> pub(crate) fn skip_whitespace_and_newlines(&mut self) {</pre></td></tr><tr><td class='line-number'><a name='L499' href='#L499'><pre>499</pre></a></td><td class='covered-line'><pre>21.5k</pre></td><td class='code'><pre> while self.at_token(Token::Whitespace) || <div class='tooltip'>self<span class='tooltip-content'>14.2k</span></div>.<div class='tooltip'>at_token<span class='tooltip-content'>14.2k</span></div>(<div class='tooltip'>Token::Newline<span class='tooltip-content'>14.2k</span></div>) {</pre></td></tr><tr><td class='line-number'><a name='L500' href='#L500'><pre>500</pre></a></td><td class='covered-line'><pre>14.3k</pre></td><td class='code'><pre> self.pos += 1;</pre></td></tr><tr><td class='line-number'><a name='L501' href='#L501'><pre>501</pre></a></td><td class='covered-line'><pre>14.3k</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L502' href='#L502'><pre>502</pre></a></td><td class='covered-line'><pre>7.18k</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L503' href='#L503'><pre>503</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L504' href='#L504'><pre>504</pre></a></td><td class='skipped-line'></td><td class='code'><pre> /// Consume and advance past the current token without adding to CST</pre></td></tr><tr><td class='line-number'><a name='L505' href='#L505'><pre>505</pre></a></td><td class='skipped-line'></td><td class='code'><pre> /// Returns the consumed token for inspection</pre></td></tr><tr><td class='line-number'><a name='L506' href='#L506'><pre>506</pre></a></td><td class='covered-line'><pre>25.1k</pre></td><td class='code'><pre> pub(crate) fn consume_advance(&mut self) -> Option<(&'a str, Token)> {</pre></td></tr><tr><td class='line-number'><a name='L507' href='#L507'><pre>507</pre></a></td><td class='covered-line'><pre>25.1k</pre></td><td class='code'><pre> if self.pos < self.tokens.len() {</pre></td></tr><tr><td class='line-number'><a name='L508' href='#L508'><pre>508</pre></a></td><td class='covered-line'><pre>25.1k</pre></td><td class='code'><pre> let token = self.tokens[self.pos];</pre></td></tr><tr><td class='line-number'><a name='L509' href='#L509'><pre>509</pre></a></td><td class='covered-line'><pre>25.1k</pre></td><td class='code'><pre> self.pos += 1;</pre></td></tr><tr><td class='line-number'><a name='L510' href='#L510'><pre>510</pre></a></td><td class='covered-line'><pre>25.1k</pre></td><td class='code'><pre> Some(token)</pre></td></tr><tr><td class='line-number'><a name='L511' href='#L511'><pre>511</pre></a></td><td class='skipped-line'></td><td class='code'><pre> } else {</pre></td></tr><tr><td class='line-number'><a name='L512' href='#L512'><pre>512</pre></a></td><td class='uncovered-line'><pre>0</pre></td><td class='code'><pre> <span class='region red'>None</span></pre></td></tr><tr><td class='line-number'><a name='L513' href='#L513'><pre>513</pre></a></td><td class='skipped-line'></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L514' href='#L514'><pre>514</pre></a></td><td class='covered-line'><pre>25.1k</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L515' href='#L515'><pre>515</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L516' href='#L516'><pre>516</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // ==================== Direct Extraction Methods ====================</pre></td></tr><tr><td class='line-number'><a name='L517' href='#L517'><pre>517</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L518' href='#L518'><pre>518</pre></a></td><td class='skipped-line'></td><td class='code'><pre> /// Parse VERSION statement directly without building CST</pre></td></tr><tr><td class='line-number'><a name='L519' href='#L519'><pre>519</pre></a></td><td class='skipped-line'></td><td class='code'><pre> ///</pre></td></tr><tr><td class='line-number'><a name='L520' href='#L520'><pre>520</pre></a></td><td class='skipped-line'></td><td class='code'><pre> /// Extracts the file format version (e.g., \"VERSION 5.00\") by directly</pre></td></tr><tr><td class='line-number'><a name='L521' href='#L521'><pre>521</pre></a></td><td class='skipped-line'></td><td class='code'><pre> /// parsing tokens without CST construction overhead.</pre></td></tr><tr><td class='line-number'><a name='L522' href='#L522'><pre>522</pre></a></td><td class='skipped-line'></td><td class='code'><pre> ///</pre></td></tr><tr><td class='line-number'><a name='L523' href='#L523'><pre>523</pre></a></td><td class='skipped-line'></td><td class='code'><pre> /// # Returns</pre></td></tr><tr><td class='line-number'><a name='L524' href='#L524'><pre>524</pre></a></td><td class='skipped-line'></td><td class='code'><pre> ///</pre></td></tr><tr><td class='line-number'><a name='L525' href='#L525'><pre>525</pre></a></td><td class='skipped-line'></td><td class='code'><pre> /// A `ParseResult` containing:</pre></td></tr><tr><td class='line-number'><a name='L526' href='#L526'><pre>526</pre></a></td><td class='skipped-line'></td><td class='code'><pre> /// - `result`: `Some(FileFormatVersion)` if found and valid, `None` if not present or invalid</pre></td></tr><tr><td class='line-number'><a name='L527' href='#L527'><pre>527</pre></a></td><td class='skipped-line'></td><td class='code'><pre> /// - `failures`: Empty vec (no errors generated for missing VERSION)</pre></td></tr><tr><td class='line-number'><a name='L528' href='#L528'><pre>528</pre></a></td><td class='covered-line'><pre>46</pre></td><td class='code'><pre> pub(crate) fn parse_version_direct(</pre></td></tr><tr><td class='line-number'><a name='L529' href='#L529'><pre>529</pre></a></td><td class='covered-line'><pre>46</pre></td><td class='code'><pre> &mut self,</pre></td></tr><tr><td class='line-number'><a name='L530' href='#L530'><pre>530</pre></a></td><td class='covered-line'><pre>46</pre></td><td class='code'><pre> ) -> crate::ParseResult<'a, crate::files::common::FileFormatVersion, crate::errors::FormErrorKind></pre></td></tr><tr><td class='line-number'><a name='L531' href='#L531'><pre>531</pre></a></td><td class='skipped-line'></td><td class='code'><pre> {</pre></td></tr><tr><td class='line-number'><a name='L532' href='#L532'><pre>532</pre></a></td><td class='skipped-line'></td><td class='code'><pre> use crate::files::common::FileFormatVersion;</pre></td></tr><tr><td class='line-number'><a name='L533' href='#L533'><pre>533</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L534' href='#L534'><pre>534</pre></a></td><td class='covered-line'><pre>46</pre></td><td class='code'><pre> self.skip_whitespace();</pre></td></tr><tr><td class='line-number'><a name='L535' href='#L535'><pre>535</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L536' href='#L536'><pre>536</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Check if VERSION keyword is present</pre></td></tr><tr><td class='line-number'><a name='L537' href='#L537'><pre>537</pre></a></td><td class='covered-line'><pre>46</pre></td><td class='code'><pre> if !self.at_token(Token::VersionKeyword) {</pre></td></tr><tr><td class='line-number'><a name='L538' href='#L538'><pre>538</pre></a></td><td class='covered-line'><pre>2</pre></td><td class='code'><pre> return crate::ParseResult::new(None, Vec::new());</pre></td></tr><tr><td class='line-number'><a name='L539' href='#L539'><pre>539</pre></a></td><td class='covered-line'><pre>44</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L540' href='#L540'><pre>540</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L541' href='#L541'><pre>541</pre></a></td><td class='covered-line'><pre>44</pre></td><td class='code'><pre> self.consume_advance(); // VERSION keyword</pre></td></tr><tr><td class='line-number'><a name='L542' href='#L542'><pre>542</pre></a></td><td class='covered-line'><pre>44</pre></td><td class='code'><pre> self.skip_whitespace();</pre></td></tr><tr><td class='line-number'><a name='L543' href='#L543'><pre>543</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L544' href='#L544'><pre>544</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Parse version number (e.g., \"5.00\" or \"1.0\")</pre></td></tr><tr><td class='line-number'><a name='L545' href='#L545'><pre>545</pre></a></td><td class='covered-line'><pre>44</pre></td><td class='code'><pre> let version_result = if let Some((text, token)) = self.tokens.get(self.pos) {</pre></td></tr><tr><td class='line-number'><a name='L546' href='#L546'><pre>546</pre></a></td><td class='covered-line'><pre>44</pre></td><td class='code'><pre> match token {</pre></td></tr><tr><td class='line-number'><a name='L547' href='#L547'><pre>547</pre></a></td><td class='skipped-line'></td><td class='code'><pre> Token::SingleLiteral | Token::DoubleLiteral | Token::IntegerLiteral => {</pre></td></tr><tr><td class='line-number'><a name='L548' href='#L548'><pre>548</pre></a></td><td class='covered-line'><pre>44</pre></td><td class='code'><pre> let version_str = text.trim();</pre></td></tr><tr><td class='line-number'><a name='L549' href='#L549'><pre>549</pre></a></td><td class='covered-line'><pre>44</pre></td><td class='code'><pre> self.consume_advance();</pre></td></tr><tr><td class='line-number'><a name='L550' href='#L550'><pre>550</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L551' href='#L551'><pre>551</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Parse \"major.minor\" format</pre></td></tr><tr><td class='line-number'><a name='L552' href='#L552'><pre>552</pre></a></td><td class='covered-line'><pre>44</pre></td><td class='code'><pre> let parts: Vec<&str> = version_str.split('.').collect();</pre></td></tr><tr><td class='line-number'><a name='L553' href='#L553'><pre>553</pre></a></td><td class='covered-line'><pre>44</pre></td><td class='code'><pre> if parts.len() == 2 {</pre></td></tr><tr><td class='line-number'><a name='L554' href='#L554'><pre>554</pre></a></td><td class='covered-line'><pre>44</pre></td><td class='code'><pre> if let (Ok(major), Ok(minor)) =</pre></td></tr><tr><td class='line-number'><a name='L555' href='#L555'><pre>555</pre></a></td><td class='covered-line'><pre>44</pre></td><td class='code'><pre> (parts[0].parse::<u8>(), parts[1].parse::<u8>())</pre></td></tr><tr><td class='line-number'><a name='L556' href='#L556'><pre>556</pre></a></td><td class='skipped-line'></td><td class='code'><pre> {</pre></td></tr><tr><td class='line-number'><a name='L557' href='#L557'><pre>557</pre></a></td><td class='covered-line'><pre>44</pre></td><td class='code'><pre> Some(FileFormatVersion { major, minor })</pre></td></tr><tr><td class='line-number'><a name='L558' href='#L558'><pre>558</pre></a></td><td class='skipped-line'></td><td class='code'><pre> } else {</pre></td></tr><tr><td class='line-number'><a name='L559' href='#L559'><pre>559</pre></a></td><td class='uncovered-line'><pre>0</pre></td><td class='code'><pre> <span class='region red'>None</span></pre></td></tr><tr><td class='line-number'><a name='L560' href='#L560'><pre>560</pre></a></td><td class='skipped-line'></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L561' href='#L561'><pre>561</pre></a></td><td class='skipped-line'></td><td class='code'><pre> } else {</pre></td></tr><tr><td class='line-number'><a name='L562' href='#L562'><pre>562</pre></a></td><td class='uncovered-line'><pre>0</pre></td><td class='code'><pre> <span class='region red'>None</span></pre></td></tr><tr><td class='line-number'><a name='L563' href='#L563'><pre>563</pre></a></td><td class='skipped-line'></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L564' href='#L564'><pre>564</pre></a></td><td class='skipped-line'></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L565' href='#L565'><pre>565</pre></a></td><td class='uncovered-line'><pre>0</pre></td><td class='code'><pre> _ => <span class='region red'>None</span>,</pre></td></tr><tr><td class='line-number'><a name='L566' href='#L566'><pre>566</pre></a></td><td class='skipped-line'></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L567' href='#L567'><pre>567</pre></a></td><td class='skipped-line'></td><td class='code'><pre> } else {</pre></td></tr><tr><td class='line-number'><a name='L568' href='#L568'><pre>568</pre></a></td><td class='uncovered-line'><pre>0</pre></td><td class='code'><pre> <span class='region red'>None</span></pre></td></tr><tr><td class='line-number'><a name='L569' href='#L569'><pre>569</pre></a></td><td class='skipped-line'></td><td class='code'><pre> };</pre></td></tr><tr><td class='line-number'><a name='L570' href='#L570'><pre>570</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L571' href='#L571'><pre>571</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Skip optional CLASS keyword and trailing whitespace</pre></td></tr><tr><td class='line-number'><a name='L572' href='#L572'><pre>572</pre></a></td><td class='covered-line'><pre>44</pre></td><td class='code'><pre> self.skip_whitespace();</pre></td></tr><tr><td class='line-number'><a name='L573' href='#L573'><pre>573</pre></a></td><td class='covered-line'><pre>44</pre></td><td class='code'><pre> if self.at_token(Token::ClassKeyword) {</pre></td></tr><tr><td class='line-number'><a name='L574' href='#L574'><pre>574</pre></a></td><td class='covered-line'><pre>2</pre></td><td class='code'><pre> self.consume_advance();</pre></td></tr><tr><td class='line-number'><a name='L575' href='#L575'><pre>575</pre></a></td><td class='covered-line'><pre>42</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L576' href='#L576'><pre>576</pre></a></td><td class='covered-line'><pre>44</pre></td><td class='code'><pre> self.skip_whitespace_and_newlines();</pre></td></tr><tr><td class='line-number'><a name='L577' href='#L577'><pre>577</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L578' href='#L578'><pre>578</pre></a></td><td class='covered-line'><pre>44</pre></td><td class='code'><pre> crate::ParseResult::new(version_result, Vec::new())</pre></td></tr><tr><td class='line-number'><a name='L579' href='#L579'><pre>579</pre></a></td><td class='covered-line'><pre>46</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L580' href='#L580'><pre>580</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L581' href='#L581'><pre>581</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // ==================== Core Control Extraction Methods ====================</pre></td></tr><tr><td class='line-number'><a name='L582' href='#L582'><pre>582</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L583' href='#L583'><pre>583</pre></a></td><td class='skipped-line'></td><td class='code'><pre> /// Check if current token is `BeginProperty` identifier</pre></td></tr><tr><td class='line-number'><a name='L584' href='#L584'><pre>584</pre></a></td><td class='covered-line'><pre>4.15k</pre></td><td class='code'><pre> fn is_begin_property(&self) -> bool {</pre></td></tr><tr><td class='line-number'><a name='L585' href='#L585'><pre>585</pre></a></td><td class='covered-line'><pre>4.15k</pre></td><td class='code'><pre> if let Some((text, token)) = self.tokens.get(self.pos) {</pre></td></tr><tr><td class='line-number'><a name='L586' href='#L586'><pre>586</pre></a></td><td class='covered-line'><pre>4.15k</pre></td><td class='code'><pre> *token == Token::Identifier && <div class='tooltip'>text<span class='tooltip-content'>3.71k</span></div>.<div class='tooltip'>eq_ignore_ascii_case<span class='tooltip-content'>3.71k</span></div>(<div class='tooltip'>"BeginProperty"<span class='tooltip-content'>3.71k</span></div>)</pre></td></tr><tr><td class='line-number'><a name='L587' href='#L587'><pre>587</pre></a></td><td class='skipped-line'></td><td class='code'><pre> } else {</pre></td></tr><tr><td class='line-number'><a name='L588' href='#L588'><pre>588</pre></a></td><td class='uncovered-line'><pre>0</pre></td><td class='code'><pre> <span class='region red'>false</span></pre></td></tr><tr><td class='line-number'><a name='L589' href='#L589'><pre>589</pre></a></td><td class='skipped-line'></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L590' href='#L590'><pre>590</pre></a></td><td class='covered-line'><pre>4.15k</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L591' href='#L591'><pre>591</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L592' href='#L592'><pre>592</pre></a></td><td class='skipped-line'></td><td class='code'><pre> /// Check if current token is an identifier matching the target text (case-insensitive)</pre></td></tr><tr><td class='line-number'><a name='L593' href='#L593'><pre>593</pre></a></td><td class='covered-line'><pre>5.44k</pre></td><td class='code'><pre> fn is_identifier_text(&self, target: &str) -> bool {</pre></td></tr><tr><td class='line-number'><a name='L594' href='#L594'><pre>594</pre></a></td><td class='covered-line'><pre>5.44k</pre></td><td class='code'><pre> if let Some((text, token)) = self.tokens.get(self.pos) {</pre></td></tr><tr><td class='line-number'><a name='L595' href='#L595'><pre>595</pre></a></td><td class='covered-line'><pre>5.44k</pre></td><td class='code'><pre> *token == Token::Identifier && <div class='tooltip'>text<span class='tooltip-content'>4.74k</span></div>.<div class='tooltip'>eq_ignore_ascii_case<span class='tooltip-content'>4.74k</span></div>(<div class='tooltip'>target<span class='tooltip-content'>4.74k</span></div>)</pre></td></tr><tr><td class='line-number'><a name='L596' href='#L596'><pre>596</pre></a></td><td class='skipped-line'></td><td class='code'><pre> } else {</pre></td></tr><tr><td class='line-number'><a name='L597' href='#L597'><pre>597</pre></a></td><td class='uncovered-line'><pre>0</pre></td><td class='code'><pre> <span class='region red'>false</span></pre></td></tr><tr><td class='line-number'><a name='L598' href='#L598'><pre>598</pre></a></td><td class='skipped-line'></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L599' href='#L599'><pre>599</pre></a></td><td class='covered-line'><pre>5.44k</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L600' href='#L600'><pre>600</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L601' href='#L601'><pre>601</pre></a></td><td class='skipped-line'></td><td class='code'><pre> /// Convert a Menu-typed Control into `MenuControl`</pre></td></tr><tr><td class='line-number'><a name='L602' href='#L602'><pre>602</pre></a></td><td class='covered-line'><pre>44</pre></td><td class='code'><pre> fn control_to_menu(control: crate::language::Control) -> crate::language::MenuControl {</pre></td></tr><tr><td class='line-number'><a name='L603' href='#L603'><pre>603</pre></a></td><td class='skipped-line'></td><td class='code'><pre> use crate::language::MenuProperties;</pre></td></tr><tr><td class='line-number'><a name='L604' href='#L604'><pre>604</pre></a></td><td class='skipped-line'></td><td class='code'><pre> use crate::language::{ControlKind, MenuControl};</pre></td></tr><tr><td class='line-number'><a name='L605' href='#L605'><pre>605</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L606' href='#L606'><pre>606</pre></a></td><td class='covered-line'><pre>44</pre></td><td class='code'><pre> let (name, tag, index, kind) = control.into_parts();</pre></td></tr><tr><td class='line-number'><a name='L607' href='#L607'><pre>607</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L608' href='#L608'><pre>608</pre></a></td><td class='skipped-line'></td><td class='code'><pre> if let ControlKind::Menu {</pre></td></tr><tr><td class='line-number'><a name='L609' href='#L609'><pre>609</pre></a></td><td class='covered-line'><pre>44</pre></td><td class='code'><pre> properties,</pre></td></tr><tr><td class='line-number'><a name='L610' href='#L610'><pre>610</pre></a></td><td class='covered-line'><pre>44</pre></td><td class='code'><pre> sub_menus,</pre></td></tr><tr><td class='line-number'><a name='L611' href='#L611'><pre>611</pre></a></td><td class='covered-line'><pre>44</pre></td><td class='code'><pre> } = kind</pre></td></tr><tr><td class='line-number'><a name='L612' href='#L612'><pre>612</pre></a></td><td class='skipped-line'></td><td class='code'><pre> {</pre></td></tr><tr><td class='line-number'><a name='L613' href='#L613'><pre>613</pre></a></td><td class='covered-line'><pre>44</pre></td><td class='code'><pre> MenuControl::new(name, tag, index, properties, sub_menus)</pre></td></tr><tr><td class='line-number'><a name='L614' href='#L614'><pre>614</pre></a></td><td class='skipped-line'></td><td class='code'><pre> } else {</pre></td></tr><tr><td class='line-number'><a name='L615' href='#L615'><pre>615</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Fallback: create empty menu control</pre></td></tr><tr><td class='line-number'><a name='L616' href='#L616'><pre>616</pre></a></td><td class='uncovered-line'><pre>0</pre></td><td class='code'><pre> <span class='region red'>MenuControl::new</span>(<span class='region red'>name</span>, <span class='region red'>tag</span>, <span class='region red'>index</span>, <span class='region red'>MenuProperties::default</span>(), <span class='region red'>Vec::new</span>())</pre></td></tr><tr><td class='line-number'><a name='L617' href='#L617'><pre>617</pre></a></td><td class='skipped-line'></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L618' href='#L618'><pre>618</pre></a></td><td class='covered-line'><pre>44</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L619' href='#L619'><pre>619</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L620' href='#L620'><pre>620</pre></a></td><td class='skipped-line'></td><td class='code'><pre> /// Parse control type directly from tokens (e.g., "VB.Form", "VB.CommandButton")</pre></td></tr><tr><td class='line-number'><a name='L621' href='#L621'><pre>621</pre></a></td><td class='covered-line'><pre>464</pre></td><td class='code'><pre> fn parse_control_type_direct(&mut self) -> String {</pre></td></tr><tr><td class='line-number'><a name='L622' href='#L622'><pre>622</pre></a></td><td class='covered-line'><pre>464</pre></td><td class='code'><pre> let mut parts = Vec::new();</pre></td></tr><tr><td class='line-number'><a name='L623' href='#L623'><pre>623</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L624' href='#L624'><pre>624</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Parse identifier or keyword</pre></td></tr><tr><td class='line-number'><a name='L625' href='#L625'><pre>625</pre></a></td><td class='covered-line'><pre>464</pre></td><td class='code'><pre> if self.is_identifier() || <div class='tooltip'><span class='region red'>self</span><span class='tooltip-content'>0</span></div>.<div class='tooltip'><span class='region red'>at_keyword</span><span class='tooltip-content'>0</span></div>() {</pre></td></tr><tr><td class='line-number'><a name='L626' href='#L626'><pre>626</pre></a></td><td class='covered-line'><pre>464</pre></td><td class='code'><pre> if let Some((text, _)) = self.tokens.get(self.pos) {</pre></td></tr><tr><td class='line-number'><a name='L627' href='#L627'><pre>627</pre></a></td><td class='covered-line'><pre>464</pre></td><td class='code'><pre> parts.push(text.to_string());</pre></td></tr><tr><td class='line-number'><a name='L628' href='#L628'><pre>628</pre></a></td><td class='covered-line'><pre>464</pre></td><td class='code'><pre> self.consume_advance();</pre></td></tr><tr><td class='line-number'><a name='L629' href='#L629'><pre>629</pre></a></td><td class='covered-line'><pre>464</pre></td><td class='code'><pre> <div class='tooltip'><span class='region red'>}</span><span class='tooltip-content'>0</span></div></pre></td></tr><tr><td class='line-number'><a name='L630' href='#L630'><pre>630</pre></a></td><td class='uncovered-line'><pre>0</pre></td><td class='code'><pre> <span class='region red'>}</span></pre></td></tr><tr><td class='line-number'><a name='L631' href='#L631'><pre>631</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L632' href='#L632'><pre>632</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Parse dot-separated parts (e.g., "VB.Form")</pre></td></tr><tr><td class='line-number'><a name='L633' href='#L633'><pre>633</pre></a></td><td class='covered-line'><pre>928</pre></td><td class='code'><pre> while self.at_token(Token::PeriodOperator) {</pre></td></tr><tr><td class='line-number'><a name='L634' href='#L634'><pre>634</pre></a></td><td class='covered-line'><pre>464</pre></td><td class='code'><pre> self.consume_advance(); // dot</pre></td></tr><tr><td class='line-number'><a name='L635' href='#L635'><pre>635</pre></a></td><td class='covered-line'><pre>464</pre></td><td class='code'><pre> if self.is_identifier() || <div class='tooltip'>self<span class='tooltip-content'>4</span></div>.<div class='tooltip'>at_keyword<span class='tooltip-content'>4</span></div>() {</pre></td></tr><tr><td class='line-number'><a name='L636' href='#L636'><pre>636</pre></a></td><td class='covered-line'><pre>464</pre></td><td class='code'><pre> if let Some((text, _)) = self.tokens.get(self.pos) {</pre></td></tr><tr><td class='line-number'><a name='L637' href='#L637'><pre>637</pre></a></td><td class='covered-line'><pre>464</pre></td><td class='code'><pre> parts.push(".".to_string());</pre></td></tr><tr><td class='line-number'><a name='L638' href='#L638'><pre>638</pre></a></td><td class='covered-line'><pre>464</pre></td><td class='code'><pre> parts.push(text.to_string());</pre></td></tr><tr><td class='line-number'><a name='L639' href='#L639'><pre>639</pre></a></td><td class='covered-line'><pre>464</pre></td><td class='code'><pre> self.consume_advance();</pre></td></tr><tr><td class='line-number'><a name='L640' href='#L640'><pre>640</pre></a></td><td class='covered-line'><pre>464</pre></td><td class='code'><pre> <div class='tooltip'><span class='region red'>}</span><span class='tooltip-content'>0</span></div></pre></td></tr><tr><td class='line-number'><a name='L641' href='#L641'><pre>641</pre></a></td><td class='uncovered-line'><pre>0</pre></td><td class='code'><pre> <span class='region red'>}</span></pre></td></tr><tr><td class='line-number'><a name='L642' href='#L642'><pre>642</pre></a></td><td class='skipped-line'></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L643' href='#L643'><pre>643</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L644' href='#L644'><pre>644</pre></a></td><td class='covered-line'><pre>464</pre></td><td class='code'><pre> parts.join("")</pre></td></tr><tr><td class='line-number'><a name='L645' href='#L645'><pre>645</pre></a></td><td class='covered-line'><pre>464</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L646' href='#L646'><pre>646</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L647' href='#L647'><pre>647</pre></a></td><td class='skipped-line'></td><td class='code'><pre> /// Parse control name directly from tokens</pre></td></tr><tr><td class='line-number'><a name='L648' href='#L648'><pre>648</pre></a></td><td class='covered-line'><pre>464</pre></td><td class='code'><pre> fn parse_control_name_direct(&mut self) -> String {</pre></td></tr><tr><td class='line-number'><a name='L649' href='#L649'><pre>649</pre></a></td><td class='covered-line'><pre>464</pre></td><td class='code'><pre> if self.is_identifier() || <div class='tooltip'><span class='region red'>self</span><span class='tooltip-content'>0</span></div>.<div class='tooltip'><span class='region red'>at_keyword</span><span class='tooltip-content'>0</span></div>() {</pre></td></tr><tr><td class='line-number'><a name='L650' href='#L650'><pre>650</pre></a></td><td class='covered-line'><pre>464</pre></td><td class='code'><pre> if let Some((text, _)) = self.tokens.get(self.pos) {</pre></td></tr><tr><td class='line-number'><a name='L651' href='#L651'><pre>651</pre></a></td><td class='covered-line'><pre>464</pre></td><td class='code'><pre> let name = text.to_string();</pre></td></tr><tr><td class='line-number'><a name='L652' href='#L652'><pre>652</pre></a></td><td class='covered-line'><pre>464</pre></td><td class='code'><pre> self.consume_advance();</pre></td></tr><tr><td class='line-number'><a name='L653' href='#L653'><pre>653</pre></a></td><td class='covered-line'><pre>464</pre></td><td class='code'><pre> return name;</pre></td></tr><tr><td class='line-number'><a name='L654' href='#L654'><pre>654</pre></a></td><td class='uncovered-line'><pre>0</pre></td><td class='code'><pre> <span class='region red'>}</span></pre></td></tr><tr><td class='line-number'><a name='L655' href='#L655'><pre>655</pre></a></td><td class='uncovered-line'><pre>0</pre></td><td class='code'><pre> <span class='region red'>}</span></pre></td></tr><tr><td class='line-number'><a name='L656' href='#L656'><pre>656</pre></a></td><td class='uncovered-line'><pre>0</pre></td><td class='code'><pre> <span class='region red'>String::new</span>()</pre></td></tr><tr><td class='line-number'><a name='L657' href='#L657'><pre>657</pre></a></td><td class='covered-line'><pre>464</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L658' href='#L658'><pre>658</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L659' href='#L659'><pre>659</pre></a></td><td class='skipped-line'></td><td class='code'><pre> /// Parse a property assignment (Key = Value) directly from tokens</pre></td></tr><tr><td class='line-number'><a name='L660' href='#L660'><pre>660</pre></a></td><td class='skipped-line'></td><td class='code'><pre> /// Returns (key, value) tuple</pre></td></tr><tr><td class='line-number'><a name='L661' href='#L661'><pre>661</pre></a></td><td class='covered-line'><pre>5.49k</pre></td><td class='code'><pre> fn parse_property_direct(&mut self) -> Option<(String, String)> {</pre></td></tr><tr><td class='line-number'><a name='L662' href='#L662'><pre>662</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Parse property key</pre></td></tr><tr><td class='line-number'><a name='L663' href='#L663'><pre>663</pre></a></td><td class='covered-line'><pre>5.49k</pre></td><td class='code'><pre> let key = if self.is_identifier() || <div class='tooltip'>self<span class='tooltip-content'>662</span></div>.<div class='tooltip'>at_keyword<span class='tooltip-content'>662</span></div>() {</pre></td></tr><tr><td class='line-number'><a name='L664' href='#L664'><pre>664</pre></a></td><td class='covered-line'><pre>5.49k</pre></td><td class='code'><pre> if let Some((text, _)) = self.tokens.get(self.pos) {</pre></td></tr><tr><td class='line-number'><a name='L665' href='#L665'><pre>665</pre></a></td><td class='covered-line'><pre>5.49k</pre></td><td class='code'><pre> let k = text.to_string();</pre></td></tr><tr><td class='line-number'><a name='L666' href='#L666'><pre>666</pre></a></td><td class='covered-line'><pre>5.49k</pre></td><td class='code'><pre> self.consume_advance();</pre></td></tr><tr><td class='line-number'><a name='L667' href='#L667'><pre>667</pre></a></td><td class='covered-line'><pre>5.49k</pre></td><td class='code'><pre> k</pre></td></tr><tr><td class='line-number'><a name='L668' href='#L668'><pre>668</pre></a></td><td class='skipped-line'></td><td class='code'><pre> } else {</pre></td></tr><tr><td class='line-number'><a name='L669' href='#L669'><pre>669</pre></a></td><td class='uncovered-line'><pre>0</pre></td><td class='code'><pre> return <span class='region red'>None</span>;</pre></td></tr><tr><td class='line-number'><a name='L670' href='#L670'><pre>670</pre></a></td><td class='skipped-line'></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L671' href='#L671'><pre>671</pre></a></td><td class='skipped-line'></td><td class='code'><pre> } else {</pre></td></tr><tr><td class='line-number'><a name='L672' href='#L672'><pre>672</pre></a></td><td class='uncovered-line'><pre>0</pre></td><td class='code'><pre> return <span class='region red'>None</span>;</pre></td></tr><tr><td class='line-number'><a name='L673' href='#L673'><pre>673</pre></a></td><td class='skipped-line'></td><td class='code'><pre> };</pre></td></tr><tr><td class='line-number'><a name='L674' href='#L674'><pre>674</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L675' href='#L675'><pre>675</pre></a></td><td class='covered-line'><pre>5.49k</pre></td><td class='code'><pre> self.skip_whitespace();</pre></td></tr><tr><td class='line-number'><a name='L676' href='#L676'><pre>676</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L677' href='#L677'><pre>677</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Parse = sign</pre></td></tr><tr><td class='line-number'><a name='L678' href='#L678'><pre>678</pre></a></td><td class='covered-line'><pre>5.49k</pre></td><td class='code'><pre> if !self.at_token(Token::EqualityOperator) {</pre></td></tr><tr><td class='line-number'><a name='L679' href='#L679'><pre>679</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> return None;</pre></td></tr><tr><td class='line-number'><a name='L680' href='#L680'><pre>680</pre></a></td><td class='covered-line'><pre>5.49k</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L681' href='#L681'><pre>681</pre></a></td><td class='covered-line'><pre>5.49k</pre></td><td class='code'><pre> self.consume_advance();</pre></td></tr><tr><td class='line-number'><a name='L682' href='#L682'><pre>682</pre></a></td><td class='covered-line'><pre>5.49k</pre></td><td class='code'><pre> self.skip_whitespace();</pre></td></tr><tr><td class='line-number'><a name='L683' href='#L683'><pre>683</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L684' href='#L684'><pre>684</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Parse value (everything until newline/colon)</pre></td></tr><tr><td class='line-number'><a name='L685' href='#L685'><pre>685</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Special case: Resource references like "file.frx":0000 or $"file.frx":0000</pre></td></tr><tr><td class='line-number'><a name='L686' href='#L686'><pre>686</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // should include the colon and offset. The quotes should be preserved.</pre></td></tr><tr><td class='line-number'><a name='L687' href='#L687'><pre>687</pre></a></td><td class='covered-line'><pre>5.49k</pre></td><td class='code'><pre> let mut value_parts = Vec::new();</pre></td></tr><tr><td class='line-number'><a name='L688' href='#L688'><pre>688</pre></a></td><td class='covered-line'><pre>5.49k</pre></td><td class='code'><pre> let mut in_resource_reference = false;</pre></td></tr><tr><td class='line-number'><a name='L689' href='#L689'><pre>689</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L690' href='#L690'><pre>690</pre></a></td><td class='covered-line'><pre>14.9k</pre></td><td class='code'><pre> while !self.is_at_end() && !self.at_token(Token::Newline) {</pre></td></tr><tr><td class='line-number'><a name='L691' href='#L691'><pre>691</pre></a></td><td class='covered-line'><pre>9.51k</pre></td><td class='code'><pre> if let Some((text, token)) = self.tokens.get(self.pos) {</pre></td></tr><tr><td class='line-number'><a name='L692' href='#L692'><pre>692</pre></a></td><td class='covered-line'><pre>9.51k</pre></td><td class='code'><pre> let text_copy = *text;</pre></td></tr><tr><td class='line-number'><a name='L693' href='#L693'><pre>693</pre></a></td><td class='covered-line'><pre>9.51k</pre></td><td class='code'><pre> let token_copy = *token;</pre></td></tr><tr><td class='line-number'><a name='L694' href='#L694'><pre>694</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L695' href='#L695'><pre>695</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Check if we see a dollar sign</pre></td></tr><tr><td class='line-number'><a name='L696' href='#L696'><pre>696</pre></a></td><td class='covered-line'><pre>9.51k</pre></td><td class='code'><pre> if token_copy == Token::DollarSign {</pre></td></tr><tr><td class='line-number'><a name='L697' href='#L697'><pre>697</pre></a></td><td class='covered-line'><pre>2</pre></td><td class='code'><pre> value_parts.push(text_copy);</pre></td></tr><tr><td class='line-number'><a name='L698' href='#L698'><pre>698</pre></a></td><td class='covered-line'><pre>2</pre></td><td class='code'><pre> self.consume_advance();</pre></td></tr><tr><td class='line-number'><a name='L699' href='#L699'><pre>699</pre></a></td><td class='covered-line'><pre>2</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L700' href='#L700'><pre>700</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // If we see a string literal (with or without $), check if resource reference follows</pre></td></tr><tr><td class='line-number'><a name='L701' href='#L701'><pre>701</pre></a></td><td class='covered-line'><pre>9.50k</pre></td><td class='code'><pre> else if token_copy == Token::StringLiteral {</pre></td></tr><tr><td class='line-number'><a name='L702' href='#L702'><pre>702</pre></a></td><td class='covered-line'><pre>625</pre></td><td class='code'><pre> value_parts.push(text_copy);</pre></td></tr><tr><td class='line-number'><a name='L703' href='#L703'><pre>703</pre></a></td><td class='covered-line'><pre>625</pre></td><td class='code'><pre> self.consume_advance();</pre></td></tr><tr><td class='line-number'><a name='L704' href='#L704'><pre>704</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L705' href='#L705'><pre>705</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Peek ahead - if next token is colon, this is a resource reference</pre></td></tr><tr><td class='line-number'><a name='L706' href='#L706'><pre>706</pre></a></td><td class='covered-line'><pre>625</pre></td><td class='code'><pre> if let Some((_, next_token)) = self.tokens.get(self.pos) {</pre></td></tr><tr><td class='line-number'><a name='L707' href='#L707'><pre>707</pre></a></td><td class='covered-line'><pre>625</pre></td><td class='code'><pre> if *next_token == Token::ColonOperator {</pre></td></tr><tr><td class='line-number'><a name='L708' href='#L708'><pre>708</pre></a></td><td class='covered-line'><pre>22</pre></td><td class='code'><pre> in_resource_reference = true;</pre></td></tr><tr><td class='line-number'><a name='L709' href='#L709'><pre>709</pre></a></td><td class='covered-line'><pre>603</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L710' href='#L710'><pre>710</pre></a></td><td class='uncovered-line'><pre>0</pre></td><td class='code'><pre> <span class='region red'>}</span></pre></td></tr><tr><td class='line-number'><a name='L711' href='#L711'><pre>711</pre></a></td><td class='skipped-line'></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L712' href='#L712'><pre>712</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // If in resource reference, capture colon</pre></td></tr><tr><td class='line-number'><a name='L713' href='#L713'><pre>713</pre></a></td><td class='covered-line'><pre>8.88k</pre></td><td class='code'><pre> else if in_resource_reference && <div class='tooltip'>token_copy == Token::ColonOperator<span class='tooltip-content'>45</span></div> {</pre></td></tr><tr><td class='line-number'><a name='L714' href='#L714'><pre>714</pre></a></td><td class='covered-line'><pre>22</pre></td><td class='code'><pre> value_parts.push(text_copy);</pre></td></tr><tr><td class='line-number'><a name='L715' href='#L715'><pre>715</pre></a></td><td class='covered-line'><pre>22</pre></td><td class='code'><pre> self.consume_advance();</pre></td></tr><tr><td class='line-number'><a name='L716' href='#L716'><pre>716</pre></a></td><td class='covered-line'><pre>22</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L717' href='#L717'><pre>717</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // If in resource reference and we see the offset number, capture it and stop</pre></td></tr><tr><td class='line-number'><a name='L718' href='#L718'><pre>718</pre></a></td><td class='covered-line'><pre>8.86k</pre></td><td class='code'><pre> else if in_resource_reference</pre></td></tr><tr><td class='line-number'><a name='L719' href='#L719'><pre>719</pre></a></td><td class='covered-line'><pre>23</pre></td><td class='code'><pre> && (token_copy == Token::IntegerLiteral || <div class='tooltip'>token_copy == Token::LongLiteral<span class='tooltip-content'>9</span></div>)</pre></td></tr><tr><td class='line-number'><a name='L720' href='#L720'><pre>720</pre></a></td><td class='skipped-line'></td><td class='code'><pre> {</pre></td></tr><tr><td class='line-number'><a name='L721' href='#L721'><pre>721</pre></a></td><td class='covered-line'><pre>14</pre></td><td class='code'><pre> value_parts.push(text_copy);</pre></td></tr><tr><td class='line-number'><a name='L722' href='#L722'><pre>722</pre></a></td><td class='covered-line'><pre>14</pre></td><td class='code'><pre> self.consume_advance();</pre></td></tr><tr><td class='line-number'><a name='L723' href='#L723'><pre>723</pre></a></td><td class='covered-line'><pre>14</pre></td><td class='code'><pre> break; // Done with resource reference</pre></td></tr><tr><td class='line-number'><a name='L724' href='#L724'><pre>724</pre></a></td><td class='skipped-line'></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L725' href='#L725'><pre>725</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // If we hit a colon and not in resource reference, stop</pre></td></tr><tr><td class='line-number'><a name='L726' href='#L726'><pre>726</pre></a></td><td class='covered-line'><pre>8.84k</pre></td><td class='code'><pre> else if token_copy == Token::ColonOperator {</pre></td></tr><tr><td class='line-number'><a name='L727' href='#L727'><pre>727</pre></a></td><td class='uncovered-line'><pre>0</pre></td><td class='code'><pre> <span class='region red'>break</span>;</pre></td></tr><tr><td class='line-number'><a name='L728' href='#L728'><pre>728</pre></a></td><td class='skipped-line'></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L729' href='#L729'><pre>729</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Otherwise, capture the token</pre></td></tr><tr><td class='line-number'><a name='L730' href='#L730'><pre>730</pre></a></td><td class='covered-line'><pre>8.84k</pre></td><td class='code'><pre> else {</pre></td></tr><tr><td class='line-number'><a name='L731' href='#L731'><pre>731</pre></a></td><td class='covered-line'><pre>8.84k</pre></td><td class='code'><pre> value_parts.push(text_copy);</pre></td></tr><tr><td class='line-number'><a name='L732' href='#L732'><pre>732</pre></a></td><td class='covered-line'><pre>8.84k</pre></td><td class='code'><pre> self.consume_advance();</pre></td></tr><tr><td class='line-number'><a name='L733' href='#L733'><pre>733</pre></a></td><td class='covered-line'><pre>8.84k</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L734' href='#L734'><pre>734</pre></a></td><td class='skipped-line'></td><td class='code'><pre> } else {</pre></td></tr><tr><td class='line-number'><a name='L735' href='#L735'><pre>735</pre></a></td><td class='uncovered-line'><pre>0</pre></td><td class='code'><pre> <span class='region red'>break</span>;</pre></td></tr><tr><td class='line-number'><a name='L736' href='#L736'><pre>736</pre></a></td><td class='skipped-line'></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L737' href='#L737'><pre>737</pre></a></td><td class='skipped-line'></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L738' href='#L738'><pre>738</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L739' href='#L739'><pre>739</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Skip newline</pre></td></tr><tr><td class='line-number'><a name='L740' href='#L740'><pre>740</pre></a></td><td class='covered-line'><pre>5.49k</pre></td><td class='code'><pre> self.skip_whitespace_and_newlines();</pre></td></tr><tr><td class='line-number'><a name='L741' href='#L741'><pre>741</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L742' href='#L742'><pre>742</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Join tokens directly without intermediate conversion</pre></td></tr><tr><td class='line-number'><a name='L743' href='#L743'><pre>743</pre></a></td><td class='covered-line'><pre>5.49k</pre></td><td class='code'><pre> let value = value_parts.concat().trim().to_string();</pre></td></tr><tr><td class='line-number'><a name='L744' href='#L744'><pre>744</pre></a></td><td class='covered-line'><pre>5.49k</pre></td><td class='code'><pre> Some((key, value))</pre></td></tr><tr><td class='line-number'><a name='L745' href='#L745'><pre>745</pre></a></td><td class='covered-line'><pre>5.49k</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L746' href='#L746'><pre>746</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L747' href='#L747'><pre>747</pre></a></td><td class='skipped-line'></td><td class='code'><pre> /// Parse property group directly (BeginProperty...EndProperty)</pre></td></tr><tr><td class='line-number'><a name='L748' href='#L748'><pre>748</pre></a></td><td class='covered-line'><pre>232</pre></td><td class='code'><pre> fn parse_property_group_direct(&mut self) -> Option<crate::language::PropertyGroup> {</pre></td></tr><tr><td class='line-number'><a name='L749' href='#L749'><pre>749</pre></a></td><td class='skipped-line'></td><td class='code'><pre> use either::Either;</pre></td></tr><tr><td class='line-number'><a name='L750' href='#L750'><pre>750</pre></a></td><td class='skipped-line'></td><td class='code'><pre> use std::collections::HashMap;</pre></td></tr><tr><td class='line-number'><a name='L751' href='#L751'><pre>751</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L752' href='#L752'><pre>752</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Expect BeginProperty identifier</pre></td></tr><tr><td class='line-number'><a name='L753' href='#L753'><pre>753</pre></a></td><td class='covered-line'><pre>232</pre></td><td class='code'><pre> if !self.is_identifier_text("BeginProperty") {</pre></td></tr><tr><td class='line-number'><a name='L754' href='#L754'><pre>754</pre></a></td><td class='uncovered-line'><pre>0</pre></td><td class='code'><pre> return <span class='region red'>None</span>;</pre></td></tr><tr><td class='line-number'><a name='L755' href='#L755'><pre>755</pre></a></td><td class='covered-line'><pre>232</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L756' href='#L756'><pre>756</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L757' href='#L757'><pre>757</pre></a></td><td class='covered-line'><pre>232</pre></td><td class='code'><pre> self.consume_advance(); // BeginProperty</pre></td></tr><tr><td class='line-number'><a name='L758' href='#L758'><pre>758</pre></a></td><td class='covered-line'><pre>232</pre></td><td class='code'><pre> self.skip_whitespace();</pre></td></tr><tr><td class='line-number'><a name='L759' href='#L759'><pre>759</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L760' href='#L760'><pre>760</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Parse property group name and optional GUID</pre></td></tr><tr><td class='line-number'><a name='L761' href='#L761'><pre>761</pre></a></td><td class='covered-line'><pre>232</pre></td><td class='code'><pre> let (name, guid) = self.parse_property_group_name_direct();</pre></td></tr><tr><td class='line-number'><a name='L762' href='#L762'><pre>762</pre></a></td><td class='covered-line'><pre>232</pre></td><td class='code'><pre> self.skip_whitespace_and_newlines();</pre></td></tr><tr><td class='line-number'><a name='L763' href='#L763'><pre>763</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L764' href='#L764'><pre>764</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Parse nested properties and property groups</pre></td></tr><tr><td class='line-number'><a name='L765' href='#L765'><pre>765</pre></a></td><td class='covered-line'><pre>232</pre></td><td class='code'><pre> let mut properties = HashMap::new();</pre></td></tr><tr><td class='line-number'><a name='L766' href='#L766'><pre>766</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L767' href='#L767'><pre>767</pre></a></td><td class='covered-line'><pre>1.81k</pre></td><td class='code'><pre> while !self.is_at_end() && !self.is_identifier_text("EndProperty") {</pre></td></tr><tr><td class='line-number'><a name='L768' href='#L768'><pre>768</pre></a></td><td class='covered-line'><pre>1.58k</pre></td><td class='code'><pre> self.skip_whitespace();</pre></td></tr><tr><td class='line-number'><a name='L769' href='#L769'><pre>769</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L770' href='#L770'><pre>770</pre></a></td><td class='covered-line'><pre>1.58k</pre></td><td class='code'><pre> if self.is_identifier_text("EndProperty") {</pre></td></tr><tr><td class='line-number'><a name='L771' href='#L771'><pre>771</pre></a></td><td class='uncovered-line'><pre>0</pre></td><td class='code'><pre> <span class='region red'>break</span>;</pre></td></tr><tr><td class='line-number'><a name='L772' href='#L772'><pre>772</pre></a></td><td class='covered-line'><pre>1.58k</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L773' href='#L773'><pre>773</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L774' href='#L774'><pre>774</pre></a></td><td class='covered-line'><pre>1.58k</pre></td><td class='code'><pre> if self.is_identifier_text("BeginProperty") {</pre></td></tr><tr><td class='line-number'><a name='L775' href='#L775'><pre>775</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Nested property group</pre></td></tr><tr><td class='line-number'><a name='L776' href='#L776'><pre>776</pre></a></td><td class='covered-line'><pre>6</pre></td><td class='code'><pre> if let Some(nested_group) = self.parse_property_group_direct() {</pre></td></tr><tr><td class='line-number'><a name='L777' href='#L777'><pre>777</pre></a></td><td class='covered-line'><pre>6</pre></td><td class='code'><pre> properties.insert(nested_group.name.clone(), Either::Right(nested_group));</pre></td></tr><tr><td class='line-number'><a name='L778' href='#L778'><pre>778</pre></a></td><td class='covered-line'><pre>6</pre></td><td class='code'><pre> <div class='tooltip'><span class='region red'>}</span><span class='tooltip-content'>0</span></div></pre></td></tr><tr><td class='line-number'><a name='L779' href='#L779'><pre>779</pre></a></td><td class='covered-line'><pre>1.57k</pre></td><td class='code'><pre> } else if self.is_identifier() || <div class='tooltip'>self<span class='tooltip-content'>234</span></div>.<div class='tooltip'>at_keyword<span class='tooltip-content'>234</span></div>() {</pre></td></tr><tr><td class='line-number'><a name='L780' href='#L780'><pre>780</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Regular property</pre></td></tr><tr><td class='line-number'><a name='L781' href='#L781'><pre>781</pre></a></td><td class='covered-line'><pre>1.57k</pre></td><td class='code'><pre> if let Some((key, value)) = self.parse_property_direct() {</pre></td></tr><tr><td class='line-number'><a name='L782' href='#L782'><pre>782</pre></a></td><td class='covered-line'><pre>1.57k</pre></td><td class='code'><pre> properties.insert(key, Either::Left(value));</pre></td></tr><tr><td class='line-number'><a name='L783' href='#L783'><pre>783</pre></a></td><td class='covered-line'><pre>1.57k</pre></td><td class='code'><pre> <div class='tooltip'><span class='region red'>}</span><span class='tooltip-content'>0</span></div></pre></td></tr><tr><td class='line-number'><a name='L784' href='#L784'><pre>784</pre></a></td><td class='covered-line'><pre>5</pre></td><td class='code'><pre> } else {</pre></td></tr><tr><td class='line-number'><a name='L785' href='#L785'><pre>785</pre></a></td><td class='covered-line'><pre>5</pre></td><td class='code'><pre> self.consume_advance();</pre></td></tr><tr><td class='line-number'><a name='L786' href='#L786'><pre>786</pre></a></td><td class='covered-line'><pre>5</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L787' href='#L787'><pre>787</pre></a></td><td class='skipped-line'></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L788' href='#L788'><pre>788</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L789' href='#L789'><pre>789</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Parse EndProperty</pre></td></tr><tr><td class='line-number'><a name='L790' href='#L790'><pre>790</pre></a></td><td class='covered-line'><pre>232</pre></td><td class='code'><pre> if self.is_identifier_text("EndProperty") {</pre></td></tr><tr><td class='line-number'><a name='L791' href='#L791'><pre>791</pre></a></td><td class='covered-line'><pre>232</pre></td><td class='code'><pre> self.consume_advance();</pre></td></tr><tr><td class='line-number'><a name='L792' href='#L792'><pre>792</pre></a></td><td class='covered-line'><pre>232</pre></td><td class='code'><pre> self.skip_whitespace_and_newlines();</pre></td></tr><tr><td class='line-number'><a name='L793' href='#L793'><pre>793</pre></a></td><td class='covered-line'><pre>232</pre></td><td class='code'><pre> <div class='tooltip'><span class='region red'>}</span><span class='tooltip-content'>0</span></div></pre></td></tr><tr><td class='line-number'><a name='L794' href='#L794'><pre>794</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L795' href='#L795'><pre>795</pre></a></td><td class='covered-line'><pre>232</pre></td><td class='code'><pre> Some(crate::language::PropertyGroup {</pre></td></tr><tr><td class='line-number'><a name='L796' href='#L796'><pre>796</pre></a></td><td class='covered-line'><pre>232</pre></td><td class='code'><pre> name,</pre></td></tr><tr><td class='line-number'><a name='L797' href='#L797'><pre>797</pre></a></td><td class='covered-line'><pre>232</pre></td><td class='code'><pre> guid,</pre></td></tr><tr><td class='line-number'><a name='L798' href='#L798'><pre>798</pre></a></td><td class='covered-line'><pre>232</pre></td><td class='code'><pre> properties,</pre></td></tr><tr><td class='line-number'><a name='L799' href='#L799'><pre>799</pre></a></td><td class='covered-line'><pre>232</pre></td><td class='code'><pre> })</pre></td></tr><tr><td class='line-number'><a name='L800' href='#L800'><pre>800</pre></a></td><td class='covered-line'><pre>232</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L801' href='#L801'><pre>801</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L802' href='#L802'><pre>802</pre></a></td><td class='skipped-line'></td><td class='code'><pre> /// Parse property group name and extract optional GUID</pre></td></tr><tr><td class='line-number'><a name='L803' href='#L803'><pre>803</pre></a></td><td class='skipped-line'></td><td class='code'><pre> /// Format: "Name {GUID}" or just "Name"</pre></td></tr><tr><td class='line-number'><a name='L804' href='#L804'><pre>804</pre></a></td><td class='covered-line'><pre>232</pre></td><td class='code'><pre> fn parse_property_group_name_direct(&mut self) -> (String, Option<uuid::Uuid>) {</pre></td></tr><tr><td class='line-number'><a name='L805' href='#L805'><pre>805</pre></a></td><td class='covered-line'><pre>232</pre></td><td class='code'><pre> let mut name_parts: Vec<&str> = Vec::new();</pre></td></tr><tr><td class='line-number'><a name='L806' href='#L806'><pre>806</pre></a></td><td class='covered-line'><pre>232</pre></td><td class='code'><pre> let mut guid_parts: Vec<&str> = Vec::new();</pre></td></tr><tr><td class='line-number'><a name='L807' href='#L807'><pre>807</pre></a></td><td class='covered-line'><pre>232</pre></td><td class='code'><pre> let mut in_guid = false;</pre></td></tr><tr><td class='line-number'><a name='L808' href='#L808'><pre>808</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L809' href='#L809'><pre>809</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Collect tokens until newline</pre></td></tr><tr><td class='line-number'><a name='L810' href='#L810'><pre>810</pre></a></td><td class='covered-line'><pre>792</pre></td><td class='code'><pre> while !self.is_at_end() && !self.at_token(Token::Newline) {</pre></td></tr><tr><td class='line-number'><a name='L811' href='#L811'><pre>811</pre></a></td><td class='covered-line'><pre>560</pre></td><td class='code'><pre> if let Some((text, token)) = self.tokens.get(self.pos) {</pre></td></tr><tr><td class='line-number'><a name='L812' href='#L812'><pre>812</pre></a></td><td class='covered-line'><pre>560</pre></td><td class='code'><pre> if *token == Token::LeftCurlyBrace {</pre></td></tr><tr><td class='line-number'><a name='L813' href='#L813'><pre>813</pre></a></td><td class='covered-line'><pre>7</pre></td><td class='code'><pre> // Start of GUID</pre></td></tr><tr><td class='line-number'><a name='L814' href='#L814'><pre>814</pre></a></td><td class='covered-line'><pre>7</pre></td><td class='code'><pre> in_guid = true;</pre></td></tr><tr><td class='line-number'><a name='L815' href='#L815'><pre>815</pre></a></td><td class='covered-line'><pre>553</pre></td><td class='code'><pre> } else if *token == Token::RightCurlyBrace {</pre></td></tr><tr><td class='line-number'><a name='L816' href='#L816'><pre>816</pre></a></td><td class='covered-line'><pre>7</pre></td><td class='code'><pre> // End of GUID</pre></td></tr><tr><td class='line-number'><a name='L817' href='#L817'><pre>817</pre></a></td><td class='covered-line'><pre>7</pre></td><td class='code'><pre> in_guid = false;</pre></td></tr><tr><td class='line-number'><a name='L818' href='#L818'><pre>818</pre></a></td><td class='covered-line'><pre>546</pre></td><td class='code'><pre> } else if *token != Token::Whitespace && <div class='tooltip'>*token != Token::EndOfLineComment<span class='tooltip-content'>312</span></div> {</pre></td></tr><tr><td class='line-number'><a name='L819' href='#L819'><pre>819</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Collect non-whitespace tokens</pre></td></tr><tr><td class='line-number'><a name='L820' href='#L820'><pre>820</pre></a></td><td class='covered-line'><pre>312</pre></td><td class='code'><pre> if in_guid {</pre></td></tr><tr><td class='line-number'><a name='L821' href='#L821'><pre>821</pre></a></td><td class='covered-line'><pre>80</pre></td><td class='code'><pre> guid_parts.push(*text);</pre></td></tr><tr><td class='line-number'><a name='L822' href='#L822'><pre>822</pre></a></td><td class='covered-line'><pre>232</pre></td><td class='code'><pre> } else {</pre></td></tr><tr><td class='line-number'><a name='L823' href='#L823'><pre>823</pre></a></td><td class='covered-line'><pre>232</pre></td><td class='code'><pre> name_parts.push(*text);</pre></td></tr><tr><td class='line-number'><a name='L824' href='#L824'><pre>824</pre></a></td><td class='covered-line'><pre>232</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L825' href='#L825'><pre>825</pre></a></td><td class='covered-line'><pre>234</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L826' href='#L826'><pre>826</pre></a></td><td class='uncovered-line'><pre>0</pre></td><td class='code'><pre> <span class='region red'>}</span></pre></td></tr><tr><td class='line-number'><a name='L827' href='#L827'><pre>827</pre></a></td><td class='covered-line'><pre>560</pre></td><td class='code'><pre> self.consume_advance();</pre></td></tr><tr><td class='line-number'><a name='L828' href='#L828'><pre>828</pre></a></td><td class='skipped-line'></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L829' href='#L829'><pre>829</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L830' href='#L830'><pre>830</pre></a></td><td class='covered-line'><pre>232</pre></td><td class='code'><pre> let name = name_parts.concat();</pre></td></tr><tr><td class='line-number'><a name='L831' href='#L831'><pre>831</pre></a></td><td class='covered-line'><pre>232</pre></td><td class='code'><pre> let guid = if guid_parts.is_empty() {</pre></td></tr><tr><td class='line-number'><a name='L832' href='#L832'><pre>832</pre></a></td><td class='covered-line'><pre>225</pre></td><td class='code'><pre> None</pre></td></tr><tr><td class='line-number'><a name='L833' href='#L833'><pre>833</pre></a></td><td class='skipped-line'></td><td class='code'><pre> } else {</pre></td></tr><tr><td class='line-number'><a name='L834' href='#L834'><pre>834</pre></a></td><td class='covered-line'><pre>7</pre></td><td class='code'><pre> let guid_str = guid_parts.concat();</pre></td></tr><tr><td class='line-number'><a name='L835' href='#L835'><pre>835</pre></a></td><td class='covered-line'><pre>7</pre></td><td class='code'><pre> uuid::Uuid::parse_str(&guid_str).ok()</pre></td></tr><tr><td class='line-number'><a name='L836' href='#L836'><pre>836</pre></a></td><td class='skipped-line'></td><td class='code'><pre> };</pre></td></tr><tr><td class='line-number'><a name='L837' href='#L837'><pre>837</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L838' href='#L838'><pre>838</pre></a></td><td class='covered-line'><pre>232</pre></td><td class='code'><pre> (name, guid)</pre></td></tr><tr><td class='line-number'><a name='L839' href='#L839'><pre>839</pre></a></td><td class='covered-line'><pre>232</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L840' href='#L840'><pre>840</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L841' href='#L841'><pre>841</pre></a></td><td class='skipped-line'></td><td class='code'><pre> /// Parse Object statements directly (without CST)</pre></td></tr><tr><td class='line-number'><a name='L842' href='#L842'><pre>842</pre></a></td><td class='skipped-line'></td><td class='code'><pre> /// Phase 5: Direct extraction of Object references</pre></td></tr><tr><td class='line-number'><a name='L843' href='#L843'><pre>843</pre></a></td><td class='covered-line'><pre>38</pre></td><td class='code'><pre> pub(crate) fn parse_objects_direct(&mut self) -> Vec<crate::files::common::ObjectReference> {</pre></td></tr><tr><td class='line-number'><a name='L844' href='#L844'><pre>844</pre></a></td><td class='covered-line'><pre>38</pre></td><td class='code'><pre> let mut objects = Vec::new();</pre></td></tr><tr><td class='line-number'><a name='L845' href='#L845'><pre>845</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L846' href='#L846'><pre>846</pre></a></td><td class='covered-line'><pre>38</pre></td><td class='code'><pre> self.skip_whitespace_and_newlines();</pre></td></tr><tr><td class='line-number'><a name='L847' href='#L847'><pre>847</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L848' href='#L848'><pre>848</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Continue parsing Object statements until we hit something else</pre></td></tr><tr><td class='line-number'><a name='L849' href='#L849'><pre>849</pre></a></td><td class='covered-line'><pre>43</pre></td><td class='code'><pre> while self.at_token(Token::ObjectKeyword) {</pre></td></tr><tr><td class='line-number'><a name='L850' href='#L850'><pre>850</pre></a></td><td class='covered-line'><pre>5</pre></td><td class='code'><pre> if let Some(obj_ref) = self.parse_single_object_direct() {</pre></td></tr><tr><td class='line-number'><a name='L851' href='#L851'><pre>851</pre></a></td><td class='covered-line'><pre>5</pre></td><td class='code'><pre> objects.push(obj_ref);</pre></td></tr><tr><td class='line-number'><a name='L852' href='#L852'><pre>852</pre></a></td><td class='covered-line'><pre>5</pre></td><td class='code'><pre> <div class='tooltip'><span class='region red'>}</span><span class='tooltip-content'>0</span></div></pre></td></tr><tr><td class='line-number'><a name='L853' href='#L853'><pre>853</pre></a></td><td class='covered-line'><pre>5</pre></td><td class='code'><pre> self.skip_whitespace_and_newlines();</pre></td></tr><tr><td class='line-number'><a name='L854' href='#L854'><pre>854</pre></a></td><td class='skipped-line'></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L855' href='#L855'><pre>855</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L856' href='#L856'><pre>856</pre></a></td><td class='covered-line'><pre>38</pre></td><td class='code'><pre> objects</pre></td></tr><tr><td class='line-number'><a name='L857' href='#L857'><pre>857</pre></a></td><td class='covered-line'><pre>38</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L858' href='#L858'><pre>858</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L859' href='#L859'><pre>859</pre></a></td><td class='skipped-line'></td><td class='code'><pre> /// Parse a single Object statement line</pre></td></tr><tr><td class='line-number'><a name='L860' href='#L860'><pre>860</pre></a></td><td class='skipped-line'></td><td class='code'><pre> /// Format: Object = "{UUID}#version#flags"; "filename"</pre></td></tr><tr><td class='line-number'><a name='L861' href='#L861'><pre>861</pre></a></td><td class='skipped-line'></td><td class='code'><pre> /// Or: Object = *\G{UUID}#version#flags; "filename"</pre></td></tr><tr><td class='line-number'><a name='L862' href='#L862'><pre>862</pre></a></td><td class='covered-line'><pre>5</pre></td><td class='code'><pre> fn parse_single_object_direct(&mut self) -> Option<crate::files::common::ObjectReference> {</pre></td></tr><tr><td class='line-number'><a name='L863' href='#L863'><pre>863</pre></a></td><td class='skipped-line'></td><td class='code'><pre> use crate::files::common::ObjectReference;</pre></td></tr><tr><td class='line-number'><a name='L864' href='#L864'><pre>864</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L865' href='#L865'><pre>865</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Expect "Object" keyword</pre></td></tr><tr><td class='line-number'><a name='L866' href='#L866'><pre>866</pre></a></td><td class='covered-line'><pre>5</pre></td><td class='code'><pre> if !self.at_token(Token::ObjectKeyword) {</pre></td></tr><tr><td class='line-number'><a name='L867' href='#L867'><pre>867</pre></a></td><td class='uncovered-line'><pre>0</pre></td><td class='code'><pre> return <span class='region red'>None</span>;</pre></td></tr><tr><td class='line-number'><a name='L868' href='#L868'><pre>868</pre></a></td><td class='covered-line'><pre>5</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L869' href='#L869'><pre>869</pre></a></td><td class='covered-line'><pre>5</pre></td><td class='code'><pre> self.consume_advance(); // Object</pre></td></tr><tr><td class='line-number'><a name='L870' href='#L870'><pre>870</pre></a></td><td class='covered-line'><pre>5</pre></td><td class='code'><pre> self.skip_whitespace();</pre></td></tr><tr><td class='line-number'><a name='L871' href='#L871'><pre>871</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L872' href='#L872'><pre>872</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Expect "="</pre></td></tr><tr><td class='line-number'><a name='L873' href='#L873'><pre>873</pre></a></td><td class='covered-line'><pre>5</pre></td><td class='code'><pre> if !self.at_token(Token::EqualityOperator) {</pre></td></tr><tr><td class='line-number'><a name='L874' href='#L874'><pre>874</pre></a></td><td class='uncovered-line'><pre>0</pre></td><td class='code'><pre> return <span class='region red'>None</span>;</pre></td></tr><tr><td class='line-number'><a name='L875' href='#L875'><pre>875</pre></a></td><td class='covered-line'><pre>5</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L876' href='#L876'><pre>876</pre></a></td><td class='covered-line'><pre>5</pre></td><td class='code'><pre> self.consume_advance(); // =</pre></td></tr><tr><td class='line-number'><a name='L877' href='#L877'><pre>877</pre></a></td><td class='covered-line'><pre>5</pre></td><td class='code'><pre> self.skip_whitespace();</pre></td></tr><tr><td class='line-number'><a name='L878' href='#L878'><pre>878</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L879' href='#L879'><pre>879</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Check for optional "*\G" prefix (embedded object)</pre></td></tr><tr><td class='line-number'><a name='L880' href='#L880'><pre>880</pre></a></td><td class='covered-line'><pre>5</pre></td><td class='code'><pre> let mut _is_embedded = false;</pre></td></tr><tr><td class='line-number'><a name='L881' href='#L881'><pre>881</pre></a></td><td class='covered-line'><pre>5</pre></td><td class='code'><pre> if self.at_token(Token::MultiplicationOperator) {</pre></td></tr><tr><td class='line-number'><a name='L882' href='#L882'><pre>882</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> self.consume_advance(); // *</pre></td></tr><tr><td class='line-number'><a name='L883' href='#L883'><pre>883</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Expect \G (backslash followed by identifier "G")</pre></td></tr><tr><td class='line-number'><a name='L884' href='#L884'><pre>884</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> if let Some((_text, token)) = self.tokens.get(self.pos) {</pre></td></tr><tr><td class='line-number'><a name='L885' href='#L885'><pre>885</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> if *token == Token::BackwardSlashOperator {</pre></td></tr><tr><td class='line-number'><a name='L886' href='#L886'><pre>886</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> self.consume_advance(); // \</pre></td></tr><tr><td class='line-number'><a name='L887' href='#L887'><pre>887</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> if let Some((text2, token2)) = self.tokens.get(self.pos) {</pre></td></tr><tr><td class='line-number'><a name='L888' href='#L888'><pre>888</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> if *token2 == Token::Identifier && text2.eq_ignore_ascii_case("G") {</pre></td></tr><tr><td class='line-number'><a name='L889' href='#L889'><pre>889</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> self.consume_advance(); // G</pre></td></tr><tr><td class='line-number'><a name='L890' href='#L890'><pre>890</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> _is_embedded = true;</pre></td></tr><tr><td class='line-number'><a name='L891' href='#L891'><pre>891</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> <div class='tooltip'><span class='region red'>}</span><span class='tooltip-content'>0</span></div></pre></td></tr><tr><td class='line-number'><a name='L892' href='#L892'><pre>892</pre></a></td><td class='uncovered-line'><pre>0</pre></td><td class='code'><pre> <span class='region red'>}</span></pre></td></tr><tr><td class='line-number'><a name='L893' href='#L893'><pre>893</pre></a></td><td class='uncovered-line'><pre>0</pre></td><td class='code'><pre> <span class='region red'>}</span></pre></td></tr><tr><td class='line-number'><a name='L894' href='#L894'><pre>894</pre></a></td><td class='uncovered-line'><pre>0</pre></td><td class='code'><pre> <span class='region red'>}</span></pre></td></tr><tr><td class='line-number'><a name='L895' href='#L895'><pre>895</pre></a></td><td class='covered-line'><pre>4</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L896' href='#L896'><pre>896</pre></a></td><td class='covered-line'><pre>5</pre></td><td class='code'><pre> self.skip_whitespace();</pre></td></tr><tr><td class='line-number'><a name='L897' href='#L897'><pre>897</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L898' href='#L898'><pre>898</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Parse first string literal or GUID tokens: "{UUID}#version#flags"</pre></td></tr><tr><td class='line-number'><a name='L899' href='#L899'><pre>899</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // The GUID may be tokenized as:</pre></td></tr><tr><td class='line-number'><a name='L900' href='#L900'><pre>900</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // - A StringLiteral: "{UUID}#version#flags"</pre></td></tr><tr><td class='line-number'><a name='L901' href='#L901'><pre>901</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // - Individual tokens: { UUID-parts } # version # flags</pre></td></tr><tr><td class='line-number'><a name='L902' href='#L902'><pre>902</pre></a></td><td class='covered-line'><pre>5</pre></td><td class='code'><pre> let uuid_part = if let Some((text, token)) = self.tokens.get(self.pos) {</pre></td></tr><tr><td class='line-number'><a name='L903' href='#L903'><pre>903</pre></a></td><td class='covered-line'><pre>5</pre></td><td class='code'><pre> if *token == Token::StringLiteral {</pre></td></tr><tr><td class='line-number'><a name='L904' href='#L904'><pre>904</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // String literal format</pre></td></tr><tr><td class='line-number'><a name='L905' href='#L905'><pre>905</pre></a></td><td class='covered-line'><pre>4</pre></td><td class='code'><pre> let s = text.trim_matches('"').to_string();</pre></td></tr><tr><td class='line-number'><a name='L906' href='#L906'><pre>906</pre></a></td><td class='covered-line'><pre>4</pre></td><td class='code'><pre> self.consume_advance();</pre></td></tr><tr><td class='line-number'><a name='L907' href='#L907'><pre>907</pre></a></td><td class='covered-line'><pre>4</pre></td><td class='code'><pre> s</pre></td></tr><tr><td class='line-number'><a name='L908' href='#L908'><pre>908</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> } else if *token == Token::LeftCurlyBrace {</pre></td></tr><tr><td class='line-number'><a name='L909' href='#L909'><pre>909</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Token format: { guid-parts } #version# flags</pre></td></tr><tr><td class='line-number'><a name='L910' href='#L910'><pre>910</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Collect all tokens until semicolon</pre></td></tr><tr><td class='line-number'><a name='L911' href='#L911'><pre>911</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let mut parts: Vec<&str> = Vec::new();</pre></td></tr><tr><td class='line-number'><a name='L912' href='#L912'><pre>912</pre></a></td><td class='covered-line'><pre>15</pre></td><td class='code'><pre> while !self.is_at_end() && !self.at_token(Token::Semicolon) {</pre></td></tr><tr><td class='line-number'><a name='L913' href='#L913'><pre>913</pre></a></td><td class='covered-line'><pre>14</pre></td><td class='code'><pre> if let Some((text, token)) = self.tokens.get(self.pos) {</pre></td></tr><tr><td class='line-number'><a name='L914' href='#L914'><pre>914</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Skip whitespace but collect everything else</pre></td></tr><tr><td class='line-number'><a name='L915' href='#L915'><pre>915</pre></a></td><td class='covered-line'><pre>14</pre></td><td class='code'><pre> if *token != Token::Whitespace {</pre></td></tr><tr><td class='line-number'><a name='L916' href='#L916'><pre>916</pre></a></td><td class='covered-line'><pre>14</pre></td><td class='code'><pre> parts.push(text);</pre></td></tr><tr><td class='line-number'><a name='L917' href='#L917'><pre>917</pre></a></td><td class='covered-line'><pre>14</pre></td><td class='code'><pre> <div class='tooltip'><span class='region red'>}</span><span class='tooltip-content'>0</span></div></pre></td></tr><tr><td class='line-number'><a name='L918' href='#L918'><pre>918</pre></a></td><td class='covered-line'><pre>14</pre></td><td class='code'><pre> self.consume_advance();</pre></td></tr><tr><td class='line-number'><a name='L919' href='#L919'><pre>919</pre></a></td><td class='skipped-line'></td><td class='code'><pre> } else {</pre></td></tr><tr><td class='line-number'><a name='L920' href='#L920'><pre>920</pre></a></td><td class='uncovered-line'><pre>0</pre></td><td class='code'><pre> <span class='region red'>break</span>;</pre></td></tr><tr><td class='line-number'><a name='L921' href='#L921'><pre>921</pre></a></td><td class='skipped-line'></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L922' href='#L922'><pre>922</pre></a></td><td class='skipped-line'></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L923' href='#L923'><pre>923</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Reconstruct the UUID part string</pre></td></tr><tr><td class='line-number'><a name='L924' href='#L924'><pre>924</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Need to convert: { ... } #version# flags -> {UUID}#version#flags</pre></td></tr><tr><td class='line-number'><a name='L925' href='#L925'><pre>925</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> parts.concat()</pre></td></tr><tr><td class='line-number'><a name='L926' href='#L926'><pre>926</pre></a></td><td class='skipped-line'></td><td class='code'><pre> } else {</pre></td></tr><tr><td class='line-number'><a name='L927' href='#L927'><pre>927</pre></a></td><td class='uncovered-line'><pre>0</pre></td><td class='code'><pre> return <span class='region red'>None</span>;</pre></td></tr><tr><td class='line-number'><a name='L928' href='#L928'><pre>928</pre></a></td><td class='skipped-line'></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L929' href='#L929'><pre>929</pre></a></td><td class='skipped-line'></td><td class='code'><pre> } else {</pre></td></tr><tr><td class='line-number'><a name='L930' href='#L930'><pre>930</pre></a></td><td class='uncovered-line'><pre>0</pre></td><td class='code'><pre> return <span class='region red'>None</span>;</pre></td></tr><tr><td class='line-number'><a name='L931' href='#L931'><pre>931</pre></a></td><td class='skipped-line'></td><td class='code'><pre> };</pre></td></tr><tr><td class='line-number'><a name='L932' href='#L932'><pre>932</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L933' href='#L933'><pre>933</pre></a></td><td class='covered-line'><pre>5</pre></td><td class='code'><pre> self.skip_whitespace();</pre></td></tr><tr><td class='line-number'><a name='L934' href='#L934'><pre>934</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L935' href='#L935'><pre>935</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Expect semicolon</pre></td></tr><tr><td class='line-number'><a name='L936' href='#L936'><pre>936</pre></a></td><td class='covered-line'><pre>5</pre></td><td class='code'><pre> if !self.at_token(Token::Semicolon) {</pre></td></tr><tr><td class='line-number'><a name='L937' href='#L937'><pre>937</pre></a></td><td class='uncovered-line'><pre>0</pre></td><td class='code'><pre> return <span class='region red'>None</span>;</pre></td></tr><tr><td class='line-number'><a name='L938' href='#L938'><pre>938</pre></a></td><td class='covered-line'><pre>5</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L939' href='#L939'><pre>939</pre></a></td><td class='covered-line'><pre>5</pre></td><td class='code'><pre> self.consume_advance(); // ;</pre></td></tr><tr><td class='line-number'><a name='L940' href='#L940'><pre>940</pre></a></td><td class='covered-line'><pre>5</pre></td><td class='code'><pre> self.skip_whitespace();</pre></td></tr><tr><td class='line-number'><a name='L941' href='#L941'><pre>941</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L942' href='#L942'><pre>942</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Parse second string literal: filename</pre></td></tr><tr><td class='line-number'><a name='L943' href='#L943'><pre>943</pre></a></td><td class='covered-line'><pre>5</pre></td><td class='code'><pre> let file_name = if let Some((text, token)) = self.tokens.get(self.pos) {</pre></td></tr><tr><td class='line-number'><a name='L944' href='#L944'><pre>944</pre></a></td><td class='covered-line'><pre>5</pre></td><td class='code'><pre> if *token == Token::StringLiteral {</pre></td></tr><tr><td class='line-number'><a name='L945' href='#L945'><pre>945</pre></a></td><td class='covered-line'><pre>5</pre></td><td class='code'><pre> let s = text.trim_matches('"').to_string();</pre></td></tr><tr><td class='line-number'><a name='L946' href='#L946'><pre>946</pre></a></td><td class='covered-line'><pre>5</pre></td><td class='code'><pre> self.consume_advance();</pre></td></tr><tr><td class='line-number'><a name='L947' href='#L947'><pre>947</pre></a></td><td class='covered-line'><pre>5</pre></td><td class='code'><pre> s</pre></td></tr><tr><td class='line-number'><a name='L948' href='#L948'><pre>948</pre></a></td><td class='skipped-line'></td><td class='code'><pre> } else {</pre></td></tr><tr><td class='line-number'><a name='L949' href='#L949'><pre>949</pre></a></td><td class='uncovered-line'><pre>0</pre></td><td class='code'><pre> return <span class='region red'>None</span>;</pre></td></tr><tr><td class='line-number'><a name='L950' href='#L950'><pre>950</pre></a></td><td class='skipped-line'></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L951' href='#L951'><pre>951</pre></a></td><td class='skipped-line'></td><td class='code'><pre> } else {</pre></td></tr><tr><td class='line-number'><a name='L952' href='#L952'><pre>952</pre></a></td><td class='uncovered-line'><pre>0</pre></td><td class='code'><pre> return <span class='region red'>None</span>;</pre></td></tr><tr><td class='line-number'><a name='L953' href='#L953'><pre>953</pre></a></td><td class='skipped-line'></td><td class='code'><pre> };</pre></td></tr><tr><td class='line-number'><a name='L954' href='#L954'><pre>954</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L955' href='#L955'><pre>955</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Parse UUID part: {UUID}#version#flags or UUID#version#flags</pre></td></tr><tr><td class='line-number'><a name='L956' href='#L956'><pre>956</pre></a></td><td class='covered-line'><pre>5</pre></td><td class='code'><pre> let parts: Vec<&str> = uuid_part.split('#').collect();</pre></td></tr><tr><td class='line-number'><a name='L957' href='#L957'><pre>957</pre></a></td><td class='covered-line'><pre>5</pre></td><td class='code'><pre> if parts.len() >= 3 {</pre></td></tr><tr><td class='line-number'><a name='L958' href='#L958'><pre>958</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Extract UUID (remove braces if present)</pre></td></tr><tr><td class='line-number'><a name='L959' href='#L959'><pre>959</pre></a></td><td class='covered-line'><pre>20</pre></td><td class='code'><pre> let <div class='tooltip'>uuid_str<span class='tooltip-content'>5</span></div> = <div class='tooltip'>parts[0]<span class='tooltip-content'>5</span></div>.<div class='tooltip'>trim_matches<span class='tooltip-content'>5</span></div>(|c| c == '{' || <div class='tooltip'>c == '}'<span class='tooltip-content'>15</span></div>);</pre></td></tr><tr><td class='line-number'><a name='L960' href='#L960'><pre>960</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L961' href='#L961'><pre>961</pre></a></td><td class='covered-line'><pre>5</pre></td><td class='code'><pre> if let Ok(uuid) = uuid::Uuid::parse_str(uuid_str) {</pre></td></tr><tr><td class='line-number'><a name='L962' href='#L962'><pre>962</pre></a></td><td class='covered-line'><pre>5</pre></td><td class='code'><pre> let version = parts[1].to_string();</pre></td></tr><tr><td class='line-number'><a name='L963' href='#L963'><pre>963</pre></a></td><td class='covered-line'><pre>5</pre></td><td class='code'><pre> let unknown1 = parts[2].to_string();</pre></td></tr><tr><td class='line-number'><a name='L964' href='#L964'><pre>964</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L965' href='#L965'><pre>965</pre></a></td><td class='covered-line'><pre>5</pre></td><td class='code'><pre> return Some(ObjectReference::Compiled {</pre></td></tr><tr><td class='line-number'><a name='L966' href='#L966'><pre>966</pre></a></td><td class='covered-line'><pre>5</pre></td><td class='code'><pre> uuid,</pre></td></tr><tr><td class='line-number'><a name='L967' href='#L967'><pre>967</pre></a></td><td class='covered-line'><pre>5</pre></td><td class='code'><pre> version,</pre></td></tr><tr><td class='line-number'><a name='L968' href='#L968'><pre>968</pre></a></td><td class='covered-line'><pre>5</pre></td><td class='code'><pre> unknown1,</pre></td></tr><tr><td class='line-number'><a name='L969' href='#L969'><pre>969</pre></a></td><td class='covered-line'><pre>5</pre></td><td class='code'><pre> file_name,</pre></td></tr><tr><td class='line-number'><a name='L970' href='#L970'><pre>970</pre></a></td><td class='covered-line'><pre>5</pre></td><td class='code'><pre> });</pre></td></tr><tr><td class='line-number'><a name='L971' href='#L971'><pre>971</pre></a></td><td class='uncovered-line'><pre>0</pre></td><td class='code'><pre> <span class='region red'>}</span></pre></td></tr><tr><td class='line-number'><a name='L972' href='#L972'><pre>972</pre></a></td><td class='uncovered-line'><pre>0</pre></td><td class='code'><pre> <span class='region red'>}</span></pre></td></tr><tr><td class='line-number'><a name='L973' href='#L973'><pre>973</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L974' href='#L974'><pre>974</pre></a></td><td class='uncovered-line'><pre>0</pre></td><td class='code'><pre> <span class='region red'>None</span></pre></td></tr><tr><td class='line-number'><a name='L975' href='#L975'><pre>975</pre></a></td><td class='covered-line'><pre>5</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L976' href='#L976'><pre>976</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L977' href='#L977'><pre>977</pre></a></td><td class='skipped-line'></td><td class='code'><pre> /// Parse Attribute statements directly (without CST)</pre></td></tr><tr><td class='line-number'><a name='L978' href='#L978'><pre>978</pre></a></td><td class='skipped-line'></td><td class='code'><pre> /// Phase 6: Direct extraction of file attributes</pre></td></tr><tr><td class='line-number'><a name='L979' href='#L979'><pre>979</pre></a></td><td class='covered-line'><pre>41</pre></td><td class='code'><pre> pub(crate) fn parse_attributes_direct(&mut self) -> crate::files::common::FileAttributes {</pre></td></tr><tr><td class='line-number'><a name='L980' href='#L980'><pre>980</pre></a></td><td class='skipped-line'></td><td class='code'><pre> use crate::files::common::{Creatable, Exposed, FileAttributes, NameSpace, PreDeclaredID};</pre></td></tr><tr><td class='line-number'><a name='L981' href='#L981'><pre>981</pre></a></td><td class='skipped-line'></td><td class='code'><pre> use std::collections::HashMap;</pre></td></tr><tr><td class='line-number'><a name='L982' href='#L982'><pre>982</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L983' href='#L983'><pre>983</pre></a></td><td class='covered-line'><pre>41</pre></td><td class='code'><pre> let mut name = String::new();</pre></td></tr><tr><td class='line-number'><a name='L984' href='#L984'><pre>984</pre></a></td><td class='covered-line'><pre>41</pre></td><td class='code'><pre> let mut global_name_space = NameSpace::Local;</pre></td></tr><tr><td class='line-number'><a name='L985' href='#L985'><pre>985</pre></a></td><td class='covered-line'><pre>41</pre></td><td class='code'><pre> let mut creatable = Creatable::True;</pre></td></tr><tr><td class='line-number'><a name='L986' href='#L986'><pre>986</pre></a></td><td class='covered-line'><pre>41</pre></td><td class='code'><pre> let mut predeclared_id = PreDeclaredID::False;</pre></td></tr><tr><td class='line-number'><a name='L987' href='#L987'><pre>987</pre></a></td><td class='covered-line'><pre>41</pre></td><td class='code'><pre> let mut exposed = Exposed::False;</pre></td></tr><tr><td class='line-number'><a name='L988' href='#L988'><pre>988</pre></a></td><td class='covered-line'><pre>41</pre></td><td class='code'><pre> let mut description: Option<String> = None;</pre></td></tr><tr><td class='line-number'><a name='L989' href='#L989'><pre>989</pre></a></td><td class='covered-line'><pre>41</pre></td><td class='code'><pre> let mut ext_key: HashMap<String, String> = HashMap::new();</pre></td></tr><tr><td class='line-number'><a name='L990' href='#L990'><pre>990</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L991' href='#L991'><pre>991</pre></a></td><td class='covered-line'><pre>41</pre></td><td class='code'><pre> self.skip_whitespace_and_newlines();</pre></td></tr><tr><td class='line-number'><a name='L992' href='#L992'><pre>992</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L993' href='#L993'><pre>993</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Continue parsing Attribute statements until we hit something else</pre></td></tr><tr><td class='line-number'><a name='L994' href='#L994'><pre>994</pre></a></td><td class='covered-line'><pre>218</pre></td><td class='code'><pre> while self.at_token(Token::AttributeKeyword) {</pre></td></tr><tr><td class='line-number'><a name='L995' href='#L995'><pre>995</pre></a></td><td class='covered-line'><pre>177</pre></td><td class='code'><pre> if let Some((key, value)) = self.parse_single_attribute_direct() {</pre></td></tr><tr><td class='line-number'><a name='L996' href='#L996'><pre>996</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Process the extracted key-value pair</pre></td></tr><tr><td class='line-number'><a name='L997' href='#L997'><pre>997</pre></a></td><td class='covered-line'><pre>177</pre></td><td class='code'><pre> match key.as_str() {</pre></td></tr><tr><td class='line-number'><a name='L998' href='#L998'><pre>998</pre></a></td><td class='covered-line'><pre>177</pre></td><td class='code'><pre> "VB_Name" => {</pre></td></tr><tr><td class='line-number'><a name='L999' href='#L999'><pre>999</pre></a></td><td class='covered-line'><pre>37</pre></td><td class='code'><pre> name = value;</pre></td></tr><tr><td class='line-number'><a name='L1000' href='#L1000'><pre>1000</pre></a></td><td class='covered-line'><pre>37</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L1001' href='#L1001'><pre>1001</pre></a></td><td class='covered-line'><pre>140</pre></td><td class='code'><pre> "VB_GlobalNameSpace" => {</pre></td></tr><tr><td class='line-number'><a name='L1002' href='#L1002'><pre>1002</pre></a></td><td class='covered-line'><pre>34</pre></td><td class='code'><pre> global_name_space = if value == "True" || value == "-1" {</pre></td></tr><tr><td class='line-number'><a name='L1003' href='#L1003'><pre>1003</pre></a></td><td class='uncovered-line'><pre>0</pre></td><td class='code'><pre> <span class='region red'>NameSpace::Global</span></pre></td></tr><tr><td class='line-number'><a name='L1004' href='#L1004'><pre>1004</pre></a></td><td class='skipped-line'></td><td class='code'><pre> } else {</pre></td></tr><tr><td class='line-number'><a name='L1005' href='#L1005'><pre>1005</pre></a></td><td class='covered-line'><pre>34</pre></td><td class='code'><pre> NameSpace::Local</pre></td></tr><tr><td class='line-number'><a name='L1006' href='#L1006'><pre>1006</pre></a></td><td class='skipped-line'></td><td class='code'><pre> };</pre></td></tr><tr><td class='line-number'><a name='L1007' href='#L1007'><pre>1007</pre></a></td><td class='skipped-line'></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L1008' href='#L1008'><pre>1008</pre></a></td><td class='covered-line'><pre>106</pre></td><td class='code'><pre> "VB_Creatable" => {</pre></td></tr><tr><td class='line-number'><a name='L1009' href='#L1009'><pre>1009</pre></a></td><td class='covered-line'><pre>34</pre></td><td class='code'><pre> creatable = if value == "True" || <div class='tooltip'>value == "-1"<span class='tooltip-content'>33</span></div> {</pre></td></tr><tr><td class='line-number'><a name='L1010' href='#L1010'><pre>1010</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> Creatable::True</pre></td></tr><tr><td class='line-number'><a name='L1011' href='#L1011'><pre>1011</pre></a></td><td class='skipped-line'></td><td class='code'><pre> } else {</pre></td></tr><tr><td class='line-number'><a name='L1012' href='#L1012'><pre>1012</pre></a></td><td class='covered-line'><pre>33</pre></td><td class='code'><pre> Creatable::False</pre></td></tr><tr><td class='line-number'><a name='L1013' href='#L1013'><pre>1013</pre></a></td><td class='skipped-line'></td><td class='code'><pre> };</pre></td></tr><tr><td class='line-number'><a name='L1014' href='#L1014'><pre>1014</pre></a></td><td class='skipped-line'></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L1015' href='#L1015'><pre>1015</pre></a></td><td class='covered-line'><pre>72</pre></td><td class='code'><pre> "VB_PredeclaredId" => {</pre></td></tr><tr><td class='line-number'><a name='L1016' href='#L1016'><pre>1016</pre></a></td><td class='covered-line'><pre>35</pre></td><td class='code'><pre> predeclared_id = if value == "True" || <div class='tooltip'>value == "-1"<span class='tooltip-content'>1</span></div> {</pre></td></tr><tr><td class='line-number'><a name='L1017' href='#L1017'><pre>1017</pre></a></td><td class='covered-line'><pre>35</pre></td><td class='code'><pre> PreDeclaredID::True</pre></td></tr><tr><td class='line-number'><a name='L1018' href='#L1018'><pre>1018</pre></a></td><td class='skipped-line'></td><td class='code'><pre> } else {</pre></td></tr><tr><td class='line-number'><a name='L1019' href='#L1019'><pre>1019</pre></a></td><td class='uncovered-line'><pre>0</pre></td><td class='code'><pre> <span class='region red'>PreDeclaredID::False</span></pre></td></tr><tr><td class='line-number'><a name='L1020' href='#L1020'><pre>1020</pre></a></td><td class='skipped-line'></td><td class='code'><pre> };</pre></td></tr><tr><td class='line-number'><a name='L1021' href='#L1021'><pre>1021</pre></a></td><td class='skipped-line'></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L1022' href='#L1022'><pre>1022</pre></a></td><td class='covered-line'><pre>37</pre></td><td class='code'><pre> "VB_Exposed" => {</pre></td></tr><tr><td class='line-number'><a name='L1023' href='#L1023'><pre>1023</pre></a></td><td class='covered-line'><pre>34</pre></td><td class='code'><pre> exposed = if value == "True" || value == "-1" {</pre></td></tr><tr><td class='line-number'><a name='L1024' href='#L1024'><pre>1024</pre></a></td><td class='uncovered-line'><pre>0</pre></td><td class='code'><pre> <span class='region red'>Exposed::True</span></pre></td></tr><tr><td class='line-number'><a name='L1025' href='#L1025'><pre>1025</pre></a></td><td class='skipped-line'></td><td class='code'><pre> } else {</pre></td></tr><tr><td class='line-number'><a name='L1026' href='#L1026'><pre>1026</pre></a></td><td class='covered-line'><pre>34</pre></td><td class='code'><pre> Exposed::False</pre></td></tr><tr><td class='line-number'><a name='L1027' href='#L1027'><pre>1027</pre></a></td><td class='skipped-line'></td><td class='code'><pre> };</pre></td></tr><tr><td class='line-number'><a name='L1028' href='#L1028'><pre>1028</pre></a></td><td class='skipped-line'></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L1029' href='#L1029'><pre>1029</pre></a></td><td class='covered-line'><pre>3</pre></td><td class='code'><pre> "VB_Description" => {</pre></td></tr><tr><td class='line-number'><a name='L1030' href='#L1030'><pre>1030</pre></a></td><td class='covered-line'><pre>2</pre></td><td class='code'><pre> description = Some(value);</pre></td></tr><tr><td class='line-number'><a name='L1031' href='#L1031'><pre>1031</pre></a></td><td class='covered-line'><pre>2</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L1032' href='#L1032'><pre>1032</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> _ => {</pre></td></tr><tr><td class='line-number'><a name='L1033' href='#L1033'><pre>1033</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> // Store any other attributes in ext_key</pre></td></tr><tr><td class='line-number'><a name='L1034' href='#L1034'><pre>1034</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> ext_key.insert(key, value);</pre></td></tr><tr><td class='line-number'><a name='L1035' href='#L1035'><pre>1035</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L1036' href='#L1036'><pre>1036</pre></a></td><td class='skipped-line'></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L1037' href='#L1037'><pre>1037</pre></a></td><td class='uncovered-line'><pre>0</pre></td><td class='code'><pre> <span class='region red'>}</span></pre></td></tr><tr><td class='line-number'><a name='L1038' href='#L1038'><pre>1038</pre></a></td><td class='covered-line'><pre>177</pre></td><td class='code'><pre> self.skip_whitespace_and_newlines();</pre></td></tr><tr><td class='line-number'><a name='L1039' href='#L1039'><pre>1039</pre></a></td><td class='skipped-line'></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L1040' href='#L1040'><pre>1040</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L1041' href='#L1041'><pre>1041</pre></a></td><td class='covered-line'><pre>41</pre></td><td class='code'><pre> FileAttributes {</pre></td></tr><tr><td class='line-number'><a name='L1042' href='#L1042'><pre>1042</pre></a></td><td class='covered-line'><pre>41</pre></td><td class='code'><pre> name,</pre></td></tr><tr><td class='line-number'><a name='L1043' href='#L1043'><pre>1043</pre></a></td><td class='covered-line'><pre>41</pre></td><td class='code'><pre> global_name_space,</pre></td></tr><tr><td class='line-number'><a name='L1044' href='#L1044'><pre>1044</pre></a></td><td class='covered-line'><pre>41</pre></td><td class='code'><pre> creatable,</pre></td></tr><tr><td class='line-number'><a name='L1045' href='#L1045'><pre>1045</pre></a></td><td class='covered-line'><pre>41</pre></td><td class='code'><pre> predeclared_id,</pre></td></tr><tr><td class='line-number'><a name='L1046' href='#L1046'><pre>1046</pre></a></td><td class='covered-line'><pre>41</pre></td><td class='code'><pre> exposed,</pre></td></tr><tr><td class='line-number'><a name='L1047' href='#L1047'><pre>1047</pre></a></td><td class='covered-line'><pre>41</pre></td><td class='code'><pre> description,</pre></td></tr><tr><td class='line-number'><a name='L1048' href='#L1048'><pre>1048</pre></a></td><td class='covered-line'><pre>41</pre></td><td class='code'><pre> ext_key,</pre></td></tr><tr><td class='line-number'><a name='L1049' href='#L1049'><pre>1049</pre></a></td><td class='covered-line'><pre>41</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L1050' href='#L1050'><pre>1050</pre></a></td><td class='covered-line'><pre>41</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L1051' href='#L1051'><pre>1051</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L1052' href='#L1052'><pre>1052</pre></a></td><td class='skipped-line'></td><td class='code'><pre> /// Parse a single Attribute statement line</pre></td></tr><tr><td class='line-number'><a name='L1053' href='#L1053'><pre>1053</pre></a></td><td class='skipped-line'></td><td class='code'><pre> /// ```Attribute VB_Name = "Value"```</pre></td></tr><tr><td class='line-number'><a name='L1054' href='#L1054'><pre>1054</pre></a></td><td class='skipped-line'></td><td class='code'><pre> /// Or</pre></td></tr><tr><td class='line-number'><a name='L1055' href='#L1055'><pre>1055</pre></a></td><td class='skipped-line'></td><td class='code'><pre> /// ```Attribute VB_GlobalNameSpace = True```</pre></td></tr><tr><td class='line-number'><a name='L1056' href='#L1056'><pre>1056</pre></a></td><td class='covered-line'><pre>177</pre></td><td class='code'><pre> fn parse_single_attribute_direct(&mut self) -> Option<(String, String)> {</pre></td></tr><tr><td class='line-number'><a name='L1057' href='#L1057'><pre>1057</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Expect "Attribute" keyword</pre></td></tr><tr><td class='line-number'><a name='L1058' href='#L1058'><pre>1058</pre></a></td><td class='covered-line'><pre>177</pre></td><td class='code'><pre> if !self.at_token(Token::AttributeKeyword) {</pre></td></tr><tr><td class='line-number'><a name='L1059' href='#L1059'><pre>1059</pre></a></td><td class='uncovered-line'><pre>0</pre></td><td class='code'><pre> return <span class='region red'>None</span>;</pre></td></tr><tr><td class='line-number'><a name='L1060' href='#L1060'><pre>1060</pre></a></td><td class='covered-line'><pre>177</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L1061' href='#L1061'><pre>1061</pre></a></td><td class='covered-line'><pre>177</pre></td><td class='code'><pre> self.consume_advance(); // Attribute</pre></td></tr><tr><td class='line-number'><a name='L1062' href='#L1062'><pre>1062</pre></a></td><td class='covered-line'><pre>177</pre></td><td class='code'><pre> self.skip_whitespace();</pre></td></tr><tr><td class='line-number'><a name='L1063' href='#L1063'><pre>1063</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L1064' href='#L1064'><pre>1064</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Parse attribute key (e.g., "VB_Name")</pre></td></tr><tr><td class='line-number'><a name='L1065' href='#L1065'><pre>1065</pre></a></td><td class='covered-line'><pre>177</pre></td><td class='code'><pre> let key = if let Some((text, token)) = self.tokens.get(self.pos) {</pre></td></tr><tr><td class='line-number'><a name='L1066' href='#L1066'><pre>1066</pre></a></td><td class='covered-line'><pre>177</pre></td><td class='code'><pre> if *token == Token::Identifier {</pre></td></tr><tr><td class='line-number'><a name='L1067' href='#L1067'><pre>1067</pre></a></td><td class='covered-line'><pre>177</pre></td><td class='code'><pre> let k = text.to_string();</pre></td></tr><tr><td class='line-number'><a name='L1068' href='#L1068'><pre>1068</pre></a></td><td class='covered-line'><pre>177</pre></td><td class='code'><pre> self.consume_advance();</pre></td></tr><tr><td class='line-number'><a name='L1069' href='#L1069'><pre>1069</pre></a></td><td class='covered-line'><pre>177</pre></td><td class='code'><pre> k</pre></td></tr><tr><td class='line-number'><a name='L1070' href='#L1070'><pre>1070</pre></a></td><td class='skipped-line'></td><td class='code'><pre> } else {</pre></td></tr><tr><td class='line-number'><a name='L1071' href='#L1071'><pre>1071</pre></a></td><td class='uncovered-line'><pre>0</pre></td><td class='code'><pre> return <span class='region red'>None</span>;</pre></td></tr><tr><td class='line-number'><a name='L1072' href='#L1072'><pre>1072</pre></a></td><td class='skipped-line'></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L1073' href='#L1073'><pre>1073</pre></a></td><td class='skipped-line'></td><td class='code'><pre> } else {</pre></td></tr><tr><td class='line-number'><a name='L1074' href='#L1074'><pre>1074</pre></a></td><td class='uncovered-line'><pre>0</pre></td><td class='code'><pre> return <span class='region red'>None</span>;</pre></td></tr><tr><td class='line-number'><a name='L1075' href='#L1075'><pre>1075</pre></a></td><td class='skipped-line'></td><td class='code'><pre> };</pre></td></tr><tr><td class='line-number'><a name='L1076' href='#L1076'><pre>1076</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L1077' href='#L1077'><pre>1077</pre></a></td><td class='covered-line'><pre>177</pre></td><td class='code'><pre> self.skip_whitespace();</pre></td></tr><tr><td class='line-number'><a name='L1078' href='#L1078'><pre>1078</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L1079' href='#L1079'><pre>1079</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Expect "="</pre></td></tr><tr><td class='line-number'><a name='L1080' href='#L1080'><pre>1080</pre></a></td><td class='covered-line'><pre>177</pre></td><td class='code'><pre> if !self.at_token(Token::EqualityOperator) {</pre></td></tr><tr><td class='line-number'><a name='L1081' href='#L1081'><pre>1081</pre></a></td><td class='uncovered-line'><pre>0</pre></td><td class='code'><pre> return <span class='region red'>None</span>;</pre></td></tr><tr><td class='line-number'><a name='L1082' href='#L1082'><pre>1082</pre></a></td><td class='covered-line'><pre>177</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L1083' href='#L1083'><pre>1083</pre></a></td><td class='covered-line'><pre>177</pre></td><td class='code'><pre> self.consume_advance(); // =</pre></td></tr><tr><td class='line-number'><a name='L1084' href='#L1084'><pre>1084</pre></a></td><td class='covered-line'><pre>177</pre></td><td class='code'><pre> self.skip_whitespace();</pre></td></tr><tr><td class='line-number'><a name='L1085' href='#L1085'><pre>1085</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L1086' href='#L1086'><pre>1086</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Parse value (can be string, True/False, or number)</pre></td></tr><tr><td class='line-number'><a name='L1087' href='#L1087'><pre>1087</pre></a></td><td class='covered-line'><pre>177</pre></td><td class='code'><pre> let mut value = String::new();</pre></td></tr><tr><td class='line-number'><a name='L1088' href='#L1088'><pre>1088</pre></a></td><td class='covered-line'><pre>177</pre></td><td class='code'><pre> let mut found_value = false;</pre></td></tr><tr><td class='line-number'><a name='L1089' href='#L1089'><pre>1089</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L1090' href='#L1090'><pre>1090</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Check for negative sign first (for values like "-1")</pre></td></tr><tr><td class='line-number'><a name='L1091' href='#L1091'><pre>1091</pre></a></td><td class='covered-line'><pre>177</pre></td><td class='code'><pre> if self.at_token(Token::SubtractionOperator) {</pre></td></tr><tr><td class='line-number'><a name='L1092' href='#L1092'><pre>1092</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> value.push('-');</pre></td></tr><tr><td class='line-number'><a name='L1093' href='#L1093'><pre>1093</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> self.consume_advance();</pre></td></tr><tr><td class='line-number'><a name='L1094' href='#L1094'><pre>1094</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> self.skip_whitespace();</pre></td></tr><tr><td class='line-number'><a name='L1095' href='#L1095'><pre>1095</pre></a></td><td class='covered-line'><pre>176</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L1096' href='#L1096'><pre>1096</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L1097' href='#L1097'><pre>1097</pre></a></td><td class='covered-line'><pre>177</pre></td><td class='code'><pre> if let Some((text, token)) = self.tokens.get(self.pos) {</pre></td></tr><tr><td class='line-number'><a name='L1098' href='#L1098'><pre>1098</pre></a></td><td class='covered-line'><pre>177</pre></td><td class='code'><pre> match token {</pre></td></tr><tr><td class='line-number'><a name='L1099' href='#L1099'><pre>1099</pre></a></td><td class='covered-line'><pre>40</pre></td><td class='code'><pre> Token::StringLiteral => {</pre></td></tr><tr><td class='line-number'><a name='L1100' href='#L1100'><pre>1100</pre></a></td><td class='covered-line'><pre>40</pre></td><td class='code'><pre> // Remove surrounding quotes</pre></td></tr><tr><td class='line-number'><a name='L1101' href='#L1101'><pre>1101</pre></a></td><td class='covered-line'><pre>40</pre></td><td class='code'><pre> value.push_str(text.trim().trim_matches('"'));</pre></td></tr><tr><td class='line-number'><a name='L1102' href='#L1102'><pre>1102</pre></a></td><td class='covered-line'><pre>40</pre></td><td class='code'><pre> self.consume_advance();</pre></td></tr><tr><td class='line-number'><a name='L1103' href='#L1103'><pre>1103</pre></a></td><td class='covered-line'><pre>40</pre></td><td class='code'><pre> found_value = true;</pre></td></tr><tr><td class='line-number'><a name='L1104' href='#L1104'><pre>1104</pre></a></td><td class='covered-line'><pre>40</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L1105' href='#L1105'><pre>1105</pre></a></td><td class='covered-line'><pre>35</pre></td><td class='code'><pre> Token::TrueKeyword => {</pre></td></tr><tr><td class='line-number'><a name='L1106' href='#L1106'><pre>1106</pre></a></td><td class='covered-line'><pre>35</pre></td><td class='code'><pre> value.push_str("True");</pre></td></tr><tr><td class='line-number'><a name='L1107' href='#L1107'><pre>1107</pre></a></td><td class='covered-line'><pre>35</pre></td><td class='code'><pre> self.consume_advance();</pre></td></tr><tr><td class='line-number'><a name='L1108' href='#L1108'><pre>1108</pre></a></td><td class='covered-line'><pre>35</pre></td><td class='code'><pre> found_value = true;</pre></td></tr><tr><td class='line-number'><a name='L1109' href='#L1109'><pre>1109</pre></a></td><td class='covered-line'><pre>35</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L1110' href='#L1110'><pre>1110</pre></a></td><td class='covered-line'><pre>101</pre></td><td class='code'><pre> Token::FalseKeyword => {</pre></td></tr><tr><td class='line-number'><a name='L1111' href='#L1111'><pre>1111</pre></a></td><td class='covered-line'><pre>101</pre></td><td class='code'><pre> value.push_str("False");</pre></td></tr><tr><td class='line-number'><a name='L1112' href='#L1112'><pre>1112</pre></a></td><td class='covered-line'><pre>101</pre></td><td class='code'><pre> self.consume_advance();</pre></td></tr><tr><td class='line-number'><a name='L1113' href='#L1113'><pre>1113</pre></a></td><td class='covered-line'><pre>101</pre></td><td class='code'><pre> found_value = true;</pre></td></tr><tr><td class='line-number'><a name='L1114' href='#L1114'><pre>1114</pre></a></td><td class='covered-line'><pre>101</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L1115' href='#L1115'><pre>1115</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> Token::IntegerLiteral | Token::LongLiteral => {</pre></td></tr><tr><td class='line-number'><a name='L1116' href='#L1116'><pre>1116</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> value.push_str(text.trim());</pre></td></tr><tr><td class='line-number'><a name='L1117' href='#L1117'><pre>1117</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> self.consume_advance();</pre></td></tr><tr><td class='line-number'><a name='L1118' href='#L1118'><pre>1118</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> found_value = true;</pre></td></tr><tr><td class='line-number'><a name='L1119' href='#L1119'><pre>1119</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L1120' href='#L1120'><pre>1120</pre></a></td><td class='uncovered-line'><pre>0</pre></td><td class='code'><pre> _ => <span class='region red'>{}</span></pre></td></tr><tr><td class='line-number'><a name='L1121' href='#L1121'><pre>1121</pre></a></td><td class='skipped-line'></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L1122' href='#L1122'><pre>1122</pre></a></td><td class='uncovered-line'><pre>0</pre></td><td class='code'><pre> <span class='region red'>}</span></pre></td></tr><tr><td class='line-number'><a name='L1123' href='#L1123'><pre>1123</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L1124' href='#L1124'><pre>1124</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Consume the rest of the line (for complex attributes like VB_Ext_KEY)</pre></td></tr><tr><td class='line-number'><a name='L1125' href='#L1125'><pre>1125</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Skip until we hit a newline or end of tokens</pre></td></tr><tr><td class='line-number'><a name='L1126' href='#L1126'><pre>1126</pre></a></td><td class='covered-line'><pre>180</pre></td><td class='code'><pre> while self.pos < self.tokens.len() {</pre></td></tr><tr><td class='line-number'><a name='L1127' href='#L1127'><pre>1127</pre></a></td><td class='covered-line'><pre>180</pre></td><td class='code'><pre> if let Some((_, token)) = self.tokens.get(self.pos) {</pre></td></tr><tr><td class='line-number'><a name='L1128' href='#L1128'><pre>1128</pre></a></td><td class='covered-line'><pre>180</pre></td><td class='code'><pre> if *token == Token::Newline {</pre></td></tr><tr><td class='line-number'><a name='L1129' href='#L1129'><pre>1129</pre></a></td><td class='covered-line'><pre>177</pre></td><td class='code'><pre> break;</pre></td></tr><tr><td class='line-number'><a name='L1130' href='#L1130'><pre>1130</pre></a></td><td class='covered-line'><pre>3</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L1131' href='#L1131'><pre>1131</pre></a></td><td class='covered-line'><pre>3</pre></td><td class='code'><pre> self.consume_advance();</pre></td></tr><tr><td class='line-number'><a name='L1132' href='#L1132'><pre>1132</pre></a></td><td class='skipped-line'></td><td class='code'><pre> } else {</pre></td></tr><tr><td class='line-number'><a name='L1133' href='#L1133'><pre>1133</pre></a></td><td class='uncovered-line'><pre>0</pre></td><td class='code'><pre> <span class='region red'>break</span>;</pre></td></tr><tr><td class='line-number'><a name='L1134' href='#L1134'><pre>1134</pre></a></td><td class='skipped-line'></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L1135' href='#L1135'><pre>1135</pre></a></td><td class='skipped-line'></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L1136' href='#L1136'><pre>1136</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L1137' href='#L1137'><pre>1137</pre></a></td><td class='covered-line'><pre>177</pre></td><td class='code'><pre> if found_value {</pre></td></tr><tr><td class='line-number'><a name='L1138' href='#L1138'><pre>1138</pre></a></td><td class='covered-line'><pre>177</pre></td><td class='code'><pre> Some((key, value))</pre></td></tr><tr><td class='line-number'><a name='L1139' href='#L1139'><pre>1139</pre></a></td><td class='skipped-line'></td><td class='code'><pre> } else {</pre></td></tr><tr><td class='line-number'><a name='L1140' href='#L1140'><pre>1140</pre></a></td><td class='uncovered-line'><pre>0</pre></td><td class='code'><pre> <span class='region red'>None</span></pre></td></tr><tr><td class='line-number'><a name='L1141' href='#L1141'><pre>1141</pre></a></td><td class='skipped-line'></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L1142' href='#L1142'><pre>1142</pre></a></td><td class='covered-line'><pre>177</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L1143' href='#L1143'><pre>1143</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L1144' href='#L1144'><pre>1144</pre></a></td><td class='skipped-line'></td><td class='code'><pre> /// Build `ControlKind` from control type string and properties</pre></td></tr><tr><td class='line-number'><a name='L1145' href='#L1145'><pre>1145</pre></a></td><td class='covered-line'><pre>463</pre></td><td class='code'><pre> fn build_control_kind(</pre></td></tr><tr><td class='line-number'><a name='L1146' href='#L1146'><pre>1146</pre></a></td><td class='covered-line'><pre>463</pre></td><td class='code'><pre> control_type: &str,</pre></td></tr><tr><td class='line-number'><a name='L1147' href='#L1147'><pre>1147</pre></a></td><td class='covered-line'><pre>463</pre></td><td class='code'><pre> properties: crate::files::common::Properties,</pre></td></tr><tr><td class='line-number'><a name='L1148' href='#L1148'><pre>1148</pre></a></td><td class='covered-line'><pre>463</pre></td><td class='code'><pre> child_controls: Vec<crate::language::Control>,</pre></td></tr><tr><td class='line-number'><a name='L1149' href='#L1149'><pre>1149</pre></a></td><td class='covered-line'><pre>463</pre></td><td class='code'><pre> menus: Vec<crate::language::MenuControl>,</pre></td></tr><tr><td class='line-number'><a name='L1150' href='#L1150'><pre>1150</pre></a></td><td class='covered-line'><pre>463</pre></td><td class='code'><pre> property_groups: Vec<crate::language::PropertyGroup>,</pre></td></tr><tr><td class='line-number'><a name='L1151' href='#L1151'><pre>1151</pre></a></td><td class='covered-line'><pre>463</pre></td><td class='code'><pre> ) -> crate::language::ControlKind {</pre></td></tr><tr><td class='line-number'><a name='L1152' href='#L1152'><pre>1152</pre></a></td><td class='skipped-line'></td><td class='code'><pre> use crate::language::ControlKind;</pre></td></tr><tr><td class='line-number'><a name='L1153' href='#L1153'><pre>1153</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L1154' href='#L1154'><pre>1154</pre></a></td><td class='covered-line'><pre>463</pre></td><td class='code'><pre> match control_type {</pre></td></tr><tr><td class='line-number'><a name='L1155' href='#L1155'><pre>1155</pre></a></td><td class='covered-line'><pre>463</pre></td><td class='code'><pre> "VB.Form" => ControlKind::Form {</pre></td></tr><tr><td class='line-number'><a name='L1156' href='#L1156'><pre>1156</pre></a></td><td class='covered-line'><pre>38</pre></td><td class='code'><pre> properties: properties.into(),</pre></td></tr><tr><td class='line-number'><a name='L1157' href='#L1157'><pre>1157</pre></a></td><td class='covered-line'><pre>38</pre></td><td class='code'><pre> controls: child_controls,</pre></td></tr><tr><td class='line-number'><a name='L1158' href='#L1158'><pre>1158</pre></a></td><td class='covered-line'><pre>38</pre></td><td class='code'><pre> menus,</pre></td></tr><tr><td class='line-number'><a name='L1159' href='#L1159'><pre>1159</pre></a></td><td class='covered-line'><pre>38</pre></td><td class='code'><pre> },</pre></td></tr><tr><td class='line-number'><a name='L1160' href='#L1160'><pre>1160</pre></a></td><td class='covered-line'><pre>425</pre></td><td class='code'><pre> "VB.MDIForm" => <span class='region red'>ControlKind::MDIForm {</span></pre></td></tr><tr><td class='line-number'><a name='L1161' href='#L1161'><pre>1161</pre></a></td><td class='uncovered-line'><pre>0</pre></td><td class='code'><pre><span class='region red'> properties: </span><span class='region red'>properties</span><span class='region red'>.</span><span class='region red'>into</span><span class='region red'>(),</span></pre></td></tr><tr><td class='line-number'><a name='L1162' href='#L1162'><pre>1162</pre></a></td><td class='uncovered-line'><pre>0</pre></td><td class='code'><pre><span class='region red'> controls: child_controls,</span></pre></td></tr><tr><td class='line-number'><a name='L1163' href='#L1163'><pre>1163</pre></a></td><td class='uncovered-line'><pre>0</pre></td><td class='code'><pre><span class='region red'> menus,</span></pre></td></tr><tr><td class='line-number'><a name='L1164' href='#L1164'><pre>1164</pre></a></td><td class='uncovered-line'><pre>0</pre></td><td class='code'><pre><span class='region red'> }</span>,</pre></td></tr><tr><td class='line-number'><a name='L1165' href='#L1165'><pre>1165</pre></a></td><td class='covered-line'><pre>425</pre></td><td class='code'><pre> "VB.CommandButton" => ControlKind::CommandButton {</pre></td></tr><tr><td class='line-number'><a name='L1166' href='#L1166'><pre>1166</pre></a></td><td class='covered-line'><pre>41</pre></td><td class='code'><pre> properties: properties.into(),</pre></td></tr><tr><td class='line-number'><a name='L1167' href='#L1167'><pre>1167</pre></a></td><td class='covered-line'><pre>41</pre></td><td class='code'><pre> },</pre></td></tr><tr><td class='line-number'><a name='L1168' href='#L1168'><pre>1168</pre></a></td><td class='covered-line'><pre>384</pre></td><td class='code'><pre> "VB.Data" => <span class='region red'>ControlKind::Data {</span></pre></td></tr><tr><td class='line-number'><a name='L1169' href='#L1169'><pre>1169</pre></a></td><td class='uncovered-line'><pre>0</pre></td><td class='code'><pre><span class='region red'> properties: properties.into(),</span></pre></td></tr><tr><td class='line-number'><a name='L1170' href='#L1170'><pre>1170</pre></a></td><td class='uncovered-line'><pre>0</pre></td><td class='code'><pre><span class='region red'> }</span>,</pre></td></tr><tr><td class='line-number'><a name='L1171' href='#L1171'><pre>1171</pre></a></td><td class='covered-line'><pre>384</pre></td><td class='code'><pre> "VB.TextBox" => ControlKind::TextBox {</pre></td></tr><tr><td class='line-number'><a name='L1172' href='#L1172'><pre>1172</pre></a></td><td class='covered-line'><pre>66</pre></td><td class='code'><pre> properties: properties.into(),</pre></td></tr><tr><td class='line-number'><a name='L1173' href='#L1173'><pre>1173</pre></a></td><td class='covered-line'><pre>66</pre></td><td class='code'><pre> },</pre></td></tr><tr><td class='line-number'><a name='L1174' href='#L1174'><pre>1174</pre></a></td><td class='covered-line'><pre>318</pre></td><td class='code'><pre> "VB.Label" => ControlKind::Label {</pre></td></tr><tr><td class='line-number'><a name='L1175' href='#L1175'><pre>1175</pre></a></td><td class='covered-line'><pre>114</pre></td><td class='code'><pre> properties: properties.into(),</pre></td></tr><tr><td class='line-number'><a name='L1176' href='#L1176'><pre>1176</pre></a></td><td class='covered-line'><pre>114</pre></td><td class='code'><pre> },</pre></td></tr><tr><td class='line-number'><a name='L1177' href='#L1177'><pre>1177</pre></a></td><td class='covered-line'><pre>204</pre></td><td class='code'><pre> "VB.CheckBox" => ControlKind::CheckBox {</pre></td></tr><tr><td class='line-number'><a name='L1178' href='#L1178'><pre>1178</pre></a></td><td class='covered-line'><pre>13</pre></td><td class='code'><pre> properties: properties.into(),</pre></td></tr><tr><td class='line-number'><a name='L1179' href='#L1179'><pre>1179</pre></a></td><td class='covered-line'><pre>13</pre></td><td class='code'><pre> },</pre></td></tr><tr><td class='line-number'><a name='L1180' href='#L1180'><pre>1180</pre></a></td><td class='covered-line'><pre>191</pre></td><td class='code'><pre> "VB.Line" => ControlKind::Line {</pre></td></tr><tr><td class='line-number'><a name='L1181' href='#L1181'><pre>1181</pre></a></td><td class='covered-line'><pre>4</pre></td><td class='code'><pre> properties: properties.into(),</pre></td></tr><tr><td class='line-number'><a name='L1182' href='#L1182'><pre>1182</pre></a></td><td class='covered-line'><pre>4</pre></td><td class='code'><pre> },</pre></td></tr><tr><td class='line-number'><a name='L1183' href='#L1183'><pre>1183</pre></a></td><td class='covered-line'><pre>187</pre></td><td class='code'><pre> "VB.Shape" => <span class='region red'>ControlKind::Shape {</span></pre></td></tr><tr><td class='line-number'><a name='L1184' href='#L1184'><pre>1184</pre></a></td><td class='uncovered-line'><pre>0</pre></td><td class='code'><pre><span class='region red'> properties: properties.into(),</span></pre></td></tr><tr><td class='line-number'><a name='L1185' href='#L1185'><pre>1185</pre></a></td><td class='uncovered-line'><pre>0</pre></td><td class='code'><pre><span class='region red'> }</span>,</pre></td></tr><tr><td class='line-number'><a name='L1186' href='#L1186'><pre>1186</pre></a></td><td class='covered-line'><pre>187</pre></td><td class='code'><pre> "VB.ListBox" => ControlKind::ListBox {</pre></td></tr><tr><td class='line-number'><a name='L1187' href='#L1187'><pre>1187</pre></a></td><td class='covered-line'><pre>3</pre></td><td class='code'><pre> properties: properties.into(),</pre></td></tr><tr><td class='line-number'><a name='L1188' href='#L1188'><pre>1188</pre></a></td><td class='covered-line'><pre>3</pre></td><td class='code'><pre> },</pre></td></tr><tr><td class='line-number'><a name='L1189' href='#L1189'><pre>1189</pre></a></td><td class='covered-line'><pre>184</pre></td><td class='code'><pre> "VB.ComboBox" => ControlKind::ComboBox {</pre></td></tr><tr><td class='line-number'><a name='L1190' href='#L1190'><pre>1190</pre></a></td><td class='covered-line'><pre>8</pre></td><td class='code'><pre> properties: properties.into(),</pre></td></tr><tr><td class='line-number'><a name='L1191' href='#L1191'><pre>1191</pre></a></td><td class='covered-line'><pre>8</pre></td><td class='code'><pre> },</pre></td></tr><tr><td class='line-number'><a name='L1192' href='#L1192'><pre>1192</pre></a></td><td class='covered-line'><pre>176</pre></td><td class='code'><pre> "VB.Timer" => <span class='region red'>ControlKind::Timer {</span></pre></td></tr><tr><td class='line-number'><a name='L1193' href='#L1193'><pre>1193</pre></a></td><td class='uncovered-line'><pre>0</pre></td><td class='code'><pre><span class='region red'> properties: properties.into(),</span></pre></td></tr><tr><td class='line-number'><a name='L1194' href='#L1194'><pre>1194</pre></a></td><td class='uncovered-line'><pre>0</pre></td><td class='code'><pre><span class='region red'> }</span>,</pre></td></tr><tr><td class='line-number'><a name='L1195' href='#L1195'><pre>1195</pre></a></td><td class='covered-line'><pre>176</pre></td><td class='code'><pre> "VB.HScrollBar" => ControlKind::HScrollBar {</pre></td></tr><tr><td class='line-number'><a name='L1196' href='#L1196'><pre>1196</pre></a></td><td class='covered-line'><pre>22</pre></td><td class='code'><pre> properties: properties.into(),</pre></td></tr><tr><td class='line-number'><a name='L1197' href='#L1197'><pre>1197</pre></a></td><td class='covered-line'><pre>22</pre></td><td class='code'><pre> },</pre></td></tr><tr><td class='line-number'><a name='L1198' href='#L1198'><pre>1198</pre></a></td><td class='covered-line'><pre>154</pre></td><td class='code'><pre> "VB.VScrollBar" => ControlKind::VScrollBar {</pre></td></tr><tr><td class='line-number'><a name='L1199' href='#L1199'><pre>1199</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> properties: properties.into(),</pre></td></tr><tr><td class='line-number'><a name='L1200' href='#L1200'><pre>1200</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> },</pre></td></tr><tr><td class='line-number'><a name='L1201' href='#L1201'><pre>1201</pre></a></td><td class='covered-line'><pre>153</pre></td><td class='code'><pre> "VB.Frame" => ControlKind::Frame {</pre></td></tr><tr><td class='line-number'><a name='L1202' href='#L1202'><pre>1202</pre></a></td><td class='covered-line'><pre>19</pre></td><td class='code'><pre> properties: properties.into(),</pre></td></tr><tr><td class='line-number'><a name='L1203' href='#L1203'><pre>1203</pre></a></td><td class='covered-line'><pre>19</pre></td><td class='code'><pre> controls: child_controls,</pre></td></tr><tr><td class='line-number'><a name='L1204' href='#L1204'><pre>1204</pre></a></td><td class='covered-line'><pre>19</pre></td><td class='code'><pre> },</pre></td></tr><tr><td class='line-number'><a name='L1205' href='#L1205'><pre>1205</pre></a></td><td class='covered-line'><pre>134</pre></td><td class='code'><pre> "VB.PictureBox" => ControlKind::PictureBox {</pre></td></tr><tr><td class='line-number'><a name='L1206' href='#L1206'><pre>1206</pre></a></td><td class='covered-line'><pre>75</pre></td><td class='code'><pre> properties: properties.into(),</pre></td></tr><tr><td class='line-number'><a name='L1207' href='#L1207'><pre>1207</pre></a></td><td class='covered-line'><pre>75</pre></td><td class='code'><pre> controls: child_controls,</pre></td></tr><tr><td class='line-number'><a name='L1208' href='#L1208'><pre>1208</pre></a></td><td class='covered-line'><pre>75</pre></td><td class='code'><pre> },</pre></td></tr><tr><td class='line-number'><a name='L1209' href='#L1209'><pre>1209</pre></a></td><td class='covered-line'><pre>59</pre></td><td class='code'><pre> "VB.FileListBox" => <span class='region red'>ControlKind::FileListBox {</span></pre></td></tr><tr><td class='line-number'><a name='L1210' href='#L1210'><pre>1210</pre></a></td><td class='uncovered-line'><pre>0</pre></td><td class='code'><pre><span class='region red'> properties: properties.into(),</span></pre></td></tr><tr><td class='line-number'><a name='L1211' href='#L1211'><pre>1211</pre></a></td><td class='uncovered-line'><pre>0</pre></td><td class='code'><pre><span class='region red'> }</span>,</pre></td></tr><tr><td class='line-number'><a name='L1212' href='#L1212'><pre>1212</pre></a></td><td class='covered-line'><pre>59</pre></td><td class='code'><pre> "VB.DirListBox" => <span class='region red'>ControlKind::DirListBox {</span></pre></td></tr><tr><td class='line-number'><a name='L1213' href='#L1213'><pre>1213</pre></a></td><td class='uncovered-line'><pre>0</pre></td><td class='code'><pre><span class='region red'> properties: properties.into(),</span></pre></td></tr><tr><td class='line-number'><a name='L1214' href='#L1214'><pre>1214</pre></a></td><td class='uncovered-line'><pre>0</pre></td><td class='code'><pre><span class='region red'> }</span>,</pre></td></tr><tr><td class='line-number'><a name='L1215' href='#L1215'><pre>1215</pre></a></td><td class='covered-line'><pre>59</pre></td><td class='code'><pre> "VB.DriveListBox" => <span class='region red'>ControlKind::DriveListBox {</span></pre></td></tr><tr><td class='line-number'><a name='L1216' href='#L1216'><pre>1216</pre></a></td><td class='uncovered-line'><pre>0</pre></td><td class='code'><pre><span class='region red'> properties: properties.into(),</span></pre></td></tr><tr><td class='line-number'><a name='L1217' href='#L1217'><pre>1217</pre></a></td><td class='uncovered-line'><pre>0</pre></td><td class='code'><pre><span class='region red'> }</span>,</pre></td></tr><tr><td class='line-number'><a name='L1218' href='#L1218'><pre>1218</pre></a></td><td class='covered-line'><pre>59</pre></td><td class='code'><pre> "VB.Image" => <span class='region red'>ControlKind::Image {</span></pre></td></tr><tr><td class='line-number'><a name='L1219' href='#L1219'><pre>1219</pre></a></td><td class='uncovered-line'><pre>0</pre></td><td class='code'><pre><span class='region red'> properties: properties.into(),</span></pre></td></tr><tr><td class='line-number'><a name='L1220' href='#L1220'><pre>1220</pre></a></td><td class='uncovered-line'><pre>0</pre></td><td class='code'><pre><span class='region red'> }</span>,</pre></td></tr><tr><td class='line-number'><a name='L1221' href='#L1221'><pre>1221</pre></a></td><td class='covered-line'><pre>59</pre></td><td class='code'><pre> "VB.OptionButton" => ControlKind::OptionButton {</pre></td></tr><tr><td class='line-number'><a name='L1222' href='#L1222'><pre>1222</pre></a></td><td class='covered-line'><pre>12</pre></td><td class='code'><pre> properties: properties.into(),</pre></td></tr><tr><td class='line-number'><a name='L1223' href='#L1223'><pre>1223</pre></a></td><td class='covered-line'><pre>12</pre></td><td class='code'><pre> },</pre></td></tr><tr><td class='line-number'><a name='L1224' href='#L1224'><pre>1224</pre></a></td><td class='covered-line'><pre>47</pre></td><td class='code'><pre> "VB.OLE" => <span class='region red'>ControlKind::Ole {</span></pre></td></tr><tr><td class='line-number'><a name='L1225' href='#L1225'><pre>1225</pre></a></td><td class='uncovered-line'><pre>0</pre></td><td class='code'><pre><span class='region red'> properties: properties.into(),</span></pre></td></tr><tr><td class='line-number'><a name='L1226' href='#L1226'><pre>1226</pre></a></td><td class='uncovered-line'><pre>0</pre></td><td class='code'><pre><span class='region red'> }</span>,</pre></td></tr><tr><td class='line-number'><a name='L1227' href='#L1227'><pre>1227</pre></a></td><td class='covered-line'><pre>47</pre></td><td class='code'><pre> "VB.Menu" => ControlKind::Menu {</pre></td></tr><tr><td class='line-number'><a name='L1228' href='#L1228'><pre>1228</pre></a></td><td class='covered-line'><pre>44</pre></td><td class='code'><pre> properties: properties.into(),</pre></td></tr><tr><td class='line-number'><a name='L1229' href='#L1229'><pre>1229</pre></a></td><td class='covered-line'><pre>44</pre></td><td class='code'><pre> sub_menus: menus,</pre></td></tr><tr><td class='line-number'><a name='L1230' href='#L1230'><pre>1230</pre></a></td><td class='covered-line'><pre>44</pre></td><td class='code'><pre> },</pre></td></tr><tr><td class='line-number'><a name='L1231' href='#L1231'><pre>1231</pre></a></td><td class='covered-line'><pre>3</pre></td><td class='code'><pre> _ => ControlKind::Custom {</pre></td></tr><tr><td class='line-number'><a name='L1232' href='#L1232'><pre>1232</pre></a></td><td class='covered-line'><pre>3</pre></td><td class='code'><pre> properties: properties.into(),</pre></td></tr><tr><td class='line-number'><a name='L1233' href='#L1233'><pre>1233</pre></a></td><td class='covered-line'><pre>3</pre></td><td class='code'><pre> property_groups,</pre></td></tr><tr><td class='line-number'><a name='L1234' href='#L1234'><pre>1234</pre></a></td><td class='covered-line'><pre>3</pre></td><td class='code'><pre> },</pre></td></tr><tr><td class='line-number'><a name='L1235' href='#L1235'><pre>1235</pre></a></td><td class='skipped-line'></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L1236' href='#L1236'><pre>1236</pre></a></td><td class='covered-line'><pre>463</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L1237' href='#L1237'><pre>1237</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L1238' href='#L1238'><pre>1238</pre></a></td><td class='skipped-line'></td><td class='code'><pre> /// Parse properties block directly to Control without building CST</pre></td></tr><tr><td class='line-number'><a name='L1239' href='#L1239'><pre>1239</pre></a></td><td class='skipped-line'></td><td class='code'><pre> /// Phase 4: Full implementation with nested controls and property groups</pre></td></tr><tr><td class='line-number'><a name='L1240' href='#L1240'><pre>1240</pre></a></td><td class='covered-line'><pre>464</pre></td><td class='code'><pre> pub(crate) fn parse_properties_block_to_control(</pre></td></tr><tr><td class='line-number'><a name='L1241' href='#L1241'><pre>1241</pre></a></td><td class='covered-line'><pre>464</pre></td><td class='code'><pre> &mut self,</pre></td></tr><tr><td class='line-number'><a name='L1242' href='#L1242'><pre>1242</pre></a></td><td class='covered-line'><pre>464</pre></td><td class='code'><pre> ) -> crate::ParseResult<'a, crate::language::Control, crate::errors::FormErrorKind> {</pre></td></tr><tr><td class='line-number'><a name='L1243' href='#L1243'><pre>1243</pre></a></td><td class='skipped-line'></td><td class='code'><pre> use crate::files::common::Properties;</pre></td></tr><tr><td class='line-number'><a name='L1244' href='#L1244'><pre>1244</pre></a></td><td class='skipped-line'></td><td class='code'><pre> use crate::language::Control;</pre></td></tr><tr><td class='line-number'><a name='L1245' href='#L1245'><pre>1245</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L1246' href='#L1246'><pre>1246</pre></a></td><td class='covered-line'><pre>464</pre></td><td class='code'><pre> self.skip_whitespace();</pre></td></tr><tr><td class='line-number'><a name='L1247' href='#L1247'><pre>1247</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L1248' href='#L1248'><pre>1248</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Expect BEGIN keyword</pre></td></tr><tr><td class='line-number'><a name='L1249' href='#L1249'><pre>1249</pre></a></td><td class='covered-line'><pre>464</pre></td><td class='code'><pre> if !self.at_token(Token::BeginKeyword) {</pre></td></tr><tr><td class='line-number'><a name='L1250' href='#L1250'><pre>1250</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> return crate::ParseResult::new(None, Vec::new());</pre></td></tr><tr><td class='line-number'><a name='L1251' href='#L1251'><pre>1251</pre></a></td><td class='covered-line'><pre>463</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L1252' href='#L1252'><pre>1252</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L1253' href='#L1253'><pre>1253</pre></a></td><td class='covered-line'><pre>463</pre></td><td class='code'><pre> self.consume_advance(); // BEGIN</pre></td></tr><tr><td class='line-number'><a name='L1254' href='#L1254'><pre>1254</pre></a></td><td class='covered-line'><pre>463</pre></td><td class='code'><pre> self.skip_whitespace();</pre></td></tr><tr><td class='line-number'><a name='L1255' href='#L1255'><pre>1255</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L1256' href='#L1256'><pre>1256</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Parse control type (e.g., "VB.Form")</pre></td></tr><tr><td class='line-number'><a name='L1257' href='#L1257'><pre>1257</pre></a></td><td class='covered-line'><pre>463</pre></td><td class='code'><pre> let control_type = self.parse_control_type_direct();</pre></td></tr><tr><td class='line-number'><a name='L1258' href='#L1258'><pre>1258</pre></a></td><td class='covered-line'><pre>463</pre></td><td class='code'><pre> self.skip_whitespace();</pre></td></tr><tr><td class='line-number'><a name='L1259' href='#L1259'><pre>1259</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L1260' href='#L1260'><pre>1260</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Parse control name</pre></td></tr><tr><td class='line-number'><a name='L1261' href='#L1261'><pre>1261</pre></a></td><td class='covered-line'><pre>463</pre></td><td class='code'><pre> let control_name = self.parse_control_name_direct();</pre></td></tr><tr><td class='line-number'><a name='L1262' href='#L1262'><pre>1262</pre></a></td><td class='covered-line'><pre>463</pre></td><td class='code'><pre> self.skip_whitespace_and_newlines();</pre></td></tr><tr><td class='line-number'><a name='L1263' href='#L1263'><pre>1263</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L1264' href='#L1264'><pre>1264</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Parse properties, child controls, and property groups</pre></td></tr><tr><td class='line-number'><a name='L1265' href='#L1265'><pre>1265</pre></a></td><td class='covered-line'><pre>463</pre></td><td class='code'><pre> let mut properties = Properties::new();</pre></td></tr><tr><td class='line-number'><a name='L1266' href='#L1266'><pre>1266</pre></a></td><td class='covered-line'><pre>463</pre></td><td class='code'><pre> let mut child_controls = Vec::new();</pre></td></tr><tr><td class='line-number'><a name='L1267' href='#L1267'><pre>1267</pre></a></td><td class='covered-line'><pre>463</pre></td><td class='code'><pre> let mut menus = Vec::new();</pre></td></tr><tr><td class='line-number'><a name='L1268' href='#L1268'><pre>1268</pre></a></td><td class='covered-line'><pre>463</pre></td><td class='code'><pre> let mut property_groups = Vec::new();</pre></td></tr><tr><td class='line-number'><a name='L1269' href='#L1269'><pre>1269</pre></a></td><td class='covered-line'><pre>463</pre></td><td class='code'><pre> let mut failures = Vec::new();</pre></td></tr><tr><td class='line-number'><a name='L1270' href='#L1270'><pre>1270</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L1271' href='#L1271'><pre>1271</pre></a></td><td class='covered-line'><pre>5.03k</pre></td><td class='code'><pre> while !self.is_at_end() && !self.at_token(Token::EndKeyword) {</pre></td></tr><tr><td class='line-number'><a name='L1272' href='#L1272'><pre>1272</pre></a></td><td class='covered-line'><pre>4.57k</pre></td><td class='code'><pre> self.skip_whitespace();</pre></td></tr><tr><td class='line-number'><a name='L1273' href='#L1273'><pre>1273</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L1274' href='#L1274'><pre>1274</pre></a></td><td class='covered-line'><pre>4.57k</pre></td><td class='code'><pre> if self.at_token(Token::EndKeyword) {</pre></td></tr><tr><td class='line-number'><a name='L1275' href='#L1275'><pre>1275</pre></a></td><td class='uncovered-line'><pre>0</pre></td><td class='code'><pre> <span class='region red'>break</span>;</pre></td></tr><tr><td class='line-number'><a name='L1276' href='#L1276'><pre>1276</pre></a></td><td class='covered-line'><pre>4.57k</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L1277' href='#L1277'><pre>1277</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L1278' href='#L1278'><pre>1278</pre></a></td><td class='covered-line'><pre>4.57k</pre></td><td class='code'><pre> if self.at_token(Token::BeginKeyword) {</pre></td></tr><tr><td class='line-number'><a name='L1279' href='#L1279'><pre>1279</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Nested control (Begin VB.xxx)</pre></td></tr><tr><td class='line-number'><a name='L1280' href='#L1280'><pre>1280</pre></a></td><td class='covered-line'><pre>419</pre></td><td class='code'><pre> let child_result = self.parse_properties_block_to_control();</pre></td></tr><tr><td class='line-number'><a name='L1281' href='#L1281'><pre>1281</pre></a></td><td class='covered-line'><pre>419</pre></td><td class='code'><pre> let (child_opt, child_failures) = child_result.unpack();</pre></td></tr><tr><td class='line-number'><a name='L1282' href='#L1282'><pre>1282</pre></a></td><td class='covered-line'><pre>419</pre></td><td class='code'><pre> failures.extend(child_failures);</pre></td></tr><tr><td class='line-number'><a name='L1283' href='#L1283'><pre>1283</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L1284' href='#L1284'><pre>1284</pre></a></td><td class='covered-line'><pre>419</pre></td><td class='code'><pre> if let Some(child) = child_opt {</pre></td></tr><tr><td class='line-number'><a name='L1285' href='#L1285'><pre>1285</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Check if it's a menu control</pre></td></tr><tr><td class='line-number'><a name='L1286' href='#L1286'><pre>1286</pre></a></td><td class='covered-line'><pre>419</pre></td><td class='code'><pre> if <div class='tooltip'>matches!<span class='tooltip-content'>375</span></div>(child.kind(), crate::language::ControlKind::Menu { .. }) {</pre></td></tr><tr><td class='line-number'><a name='L1287' href='#L1287'><pre>1287</pre></a></td><td class='covered-line'><pre>44</pre></td><td class='code'><pre> menus.push(Self::control_to_menu(child));</pre></td></tr><tr><td class='line-number'><a name='L1288' href='#L1288'><pre>1288</pre></a></td><td class='covered-line'><pre>375</pre></td><td class='code'><pre> } else {</pre></td></tr><tr><td class='line-number'><a name='L1289' href='#L1289'><pre>1289</pre></a></td><td class='covered-line'><pre>375</pre></td><td class='code'><pre> child_controls.push(child);</pre></td></tr><tr><td class='line-number'><a name='L1290' href='#L1290'><pre>1290</pre></a></td><td class='covered-line'><pre>375</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L1291' href='#L1291'><pre>1291</pre></a></td><td class='uncovered-line'><pre>0</pre></td><td class='code'><pre> <span class='region red'>}</span></pre></td></tr><tr><td class='line-number'><a name='L1292' href='#L1292'><pre>1292</pre></a></td><td class='covered-line'><pre>4.15k</pre></td><td class='code'><pre> } else if self.is_begin_property() {</pre></td></tr><tr><td class='line-number'><a name='L1293' href='#L1293'><pre>1293</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Parse property group (BeginProperty)</pre></td></tr><tr><td class='line-number'><a name='L1294' href='#L1294'><pre>1294</pre></a></td><td class='covered-line'><pre>226</pre></td><td class='code'><pre> if let Some(group) = self.parse_property_group_direct() {</pre></td></tr><tr><td class='line-number'><a name='L1295' href='#L1295'><pre>1295</pre></a></td><td class='covered-line'><pre>226</pre></td><td class='code'><pre> property_groups.push(group);</pre></td></tr><tr><td class='line-number'><a name='L1296' href='#L1296'><pre>1296</pre></a></td><td class='covered-line'><pre>226</pre></td><td class='code'><pre> <div class='tooltip'><span class='region red'>}</span><span class='tooltip-content'>0</span></div></pre></td></tr><tr><td class='line-number'><a name='L1297' href='#L1297'><pre>1297</pre></a></td><td class='covered-line'><pre>3.92k</pre></td><td class='code'><pre> } else if self.is_identifier() || <div class='tooltip'>self<span class='tooltip-content'>437</span></div>.<div class='tooltip'>at_keyword<span class='tooltip-content'>437</span></div>() {</pre></td></tr><tr><td class='line-number'><a name='L1298' href='#L1298'><pre>1298</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Parse property (Key = Value)</pre></td></tr><tr><td class='line-number'><a name='L1299' href='#L1299'><pre>1299</pre></a></td><td class='covered-line'><pre>3.92k</pre></td><td class='code'><pre> if let Some((<div class='tooltip'>key<span class='tooltip-content'>3.92k</span></div>, <div class='tooltip'>value<span class='tooltip-content'>3.92k</span></div>)) = self.parse_property_direct() {</pre></td></tr><tr><td class='line-number'><a name='L1300' href='#L1300'><pre>1300</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Remove surrounding quotes if this is a simple string literal</pre></td></tr><tr><td class='line-number'><a name='L1301' href='#L1301'><pre>1301</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // BUT NOT if it's a resource reference (contains ":digit" pattern)</pre></td></tr><tr><td class='line-number'><a name='L1302' href='#L1302'><pre>1302</pre></a></td><td class='covered-line'><pre>3.92k</pre></td><td class='code'><pre> let is_resource_reference = value.contains(':')</pre></td></tr><tr><td class='line-number'><a name='L1303' href='#L1303'><pre>1303</pre></a></td><td class='covered-line'><pre>110</pre></td><td class='code'><pre> && value</pre></td></tr><tr><td class='line-number'><a name='L1304' href='#L1304'><pre>1304</pre></a></td><td class='covered-line'><pre>110</pre></td><td class='code'><pre> .split(':')</pre></td></tr><tr><td class='line-number'><a name='L1305' href='#L1305'><pre>1305</pre></a></td><td class='covered-line'><pre>110</pre></td><td class='code'><pre> .next_back()</pre></td></tr><tr><td class='line-number'><a name='L1306' href='#L1306'><pre>1306</pre></a></td><td class='covered-line'><pre>156</pre></td><td class='code'><pre> .<div class='tooltip'>is_some_and<span class='tooltip-content'>110</span></div>(|part| <div class='tooltip'>part.chars()<span class='tooltip-content'>110</span></div>.<div class='tooltip'>all<span class='tooltip-content'>110</span></div>(|c| c.is_ascii_digit()));</pre></td></tr><tr><td class='line-number'><a name='L1307' href='#L1307'><pre>1307</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L1308' href='#L1308'><pre>1308</pre></a></td><td class='covered-line'><pre>3.92k</pre></td><td class='code'><pre> let cleaned_value = if !is_resource_reference</pre></td></tr><tr><td class='line-number'><a name='L1309' href='#L1309'><pre>1309</pre></a></td><td class='covered-line'><pre>3.90k</pre></td><td class='code'><pre> && value.starts_with('"')</pre></td></tr><tr><td class='line-number'><a name='L1310' href='#L1310'><pre>1310</pre></a></td><td class='covered-line'><pre>379</pre></td><td class='code'><pre> && value.ends_with('"')</pre></td></tr><tr><td class='line-number'><a name='L1311' href='#L1311'><pre>1311</pre></a></td><td class='covered-line'><pre>371</pre></td><td class='code'><pre> && value.len() >= 2</pre></td></tr><tr><td class='line-number'><a name='L1312' href='#L1312'><pre>1312</pre></a></td><td class='skipped-line'></td><td class='code'><pre> {</pre></td></tr><tr><td class='line-number'><a name='L1313' href='#L1313'><pre>1313</pre></a></td><td class='covered-line'><pre>371</pre></td><td class='code'><pre> &value[1..value.len() - 1]</pre></td></tr><tr><td class='line-number'><a name='L1314' href='#L1314'><pre>1314</pre></a></td><td class='skipped-line'></td><td class='code'><pre> } else {</pre></td></tr><tr><td class='line-number'><a name='L1315' href='#L1315'><pre>1315</pre></a></td><td class='covered-line'><pre>3.54k</pre></td><td class='code'><pre> &value</pre></td></tr><tr><td class='line-number'><a name='L1316' href='#L1316'><pre>1316</pre></a></td><td class='skipped-line'></td><td class='code'><pre> };</pre></td></tr><tr><td class='line-number'><a name='L1317' href='#L1317'><pre>1317</pre></a></td><td class='covered-line'><pre>3.92k</pre></td><td class='code'><pre> properties.insert(&key, cleaned_value);</pre></td></tr><tr><td class='line-number'><a name='L1318' href='#L1318'><pre>1318</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L1319' href='#L1319'><pre>1319</pre></a></td><td class='covered-line'><pre>4</pre></td><td class='code'><pre> } else {</pre></td></tr><tr><td class='line-number'><a name='L1320' href='#L1320'><pre>1320</pre></a></td><td class='covered-line'><pre>4</pre></td><td class='code'><pre> // Skip unknown token</pre></td></tr><tr><td class='line-number'><a name='L1321' href='#L1321'><pre>1321</pre></a></td><td class='covered-line'><pre>4</pre></td><td class='code'><pre> self.consume_advance();</pre></td></tr><tr><td class='line-number'><a name='L1322' href='#L1322'><pre>1322</pre></a></td><td class='covered-line'><pre>4</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L1323' href='#L1323'><pre>1323</pre></a></td><td class='skipped-line'></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L1324' href='#L1324'><pre>1324</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L1325' href='#L1325'><pre>1325</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Parse END keyword</pre></td></tr><tr><td class='line-number'><a name='L1326' href='#L1326'><pre>1326</pre></a></td><td class='covered-line'><pre>463</pre></td><td class='code'><pre> if self.at_token(Token::EndKeyword) {</pre></td></tr><tr><td class='line-number'><a name='L1327' href='#L1327'><pre>1327</pre></a></td><td class='covered-line'><pre>463</pre></td><td class='code'><pre> self.consume_advance();</pre></td></tr><tr><td class='line-number'><a name='L1328' href='#L1328'><pre>1328</pre></a></td><td class='covered-line'><pre>463</pre></td><td class='code'><pre> self.skip_whitespace_and_newlines();</pre></td></tr><tr><td class='line-number'><a name='L1329' href='#L1329'><pre>1329</pre></a></td><td class='covered-line'><pre>463</pre></td><td class='code'><pre> <div class='tooltip'><span class='region red'>}</span><span class='tooltip-content'>0</span></div></pre></td></tr><tr><td class='line-number'><a name='L1330' href='#L1330'><pre>1330</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L1331' href='#L1331'><pre>1331</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Extract tag and index from properties</pre></td></tr><tr><td class='line-number'><a name='L1332' href='#L1332'><pre>1332</pre></a></td><td class='covered-line'><pre>463</pre></td><td class='code'><pre> let tag = properties.get("Tag").cloned().unwrap_or_default();</pre></td></tr><tr><td class='line-number'><a name='L1333' href='#L1333'><pre>1333</pre></a></td><td class='covered-line'><pre>463</pre></td><td class='code'><pre> let index = properties</pre></td></tr><tr><td class='line-number'><a name='L1334' href='#L1334'><pre>1334</pre></a></td><td class='covered-line'><pre>463</pre></td><td class='code'><pre> .get("Index")</pre></td></tr><tr><td class='line-number'><a name='L1335' href='#L1335'><pre>1335</pre></a></td><td class='covered-line'><pre>463</pre></td><td class='code'><pre> .and_then(|s| <div class='tooltip'>s.parse()<span class='tooltip-content'>47</span></div>.<div class='tooltip'>ok<span class='tooltip-content'>47</span></div>())</pre></td></tr><tr><td class='line-number'><a name='L1336' href='#L1336'><pre>1336</pre></a></td><td class='covered-line'><pre>463</pre></td><td class='code'><pre> .unwrap_or(0);</pre></td></tr><tr><td class='line-number'><a name='L1337' href='#L1337'><pre>1337</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L1338' href='#L1338'><pre>1338</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Build control kind with all components</pre></td></tr><tr><td class='line-number'><a name='L1339' href='#L1339'><pre>1339</pre></a></td><td class='covered-line'><pre>463</pre></td><td class='code'><pre> let kind = Self::build_control_kind(</pre></td></tr><tr><td class='line-number'><a name='L1340' href='#L1340'><pre>1340</pre></a></td><td class='covered-line'><pre>463</pre></td><td class='code'><pre> &control_type,</pre></td></tr><tr><td class='line-number'><a name='L1341' href='#L1341'><pre>1341</pre></a></td><td class='covered-line'><pre>463</pre></td><td class='code'><pre> properties,</pre></td></tr><tr><td class='line-number'><a name='L1342' href='#L1342'><pre>1342</pre></a></td><td class='covered-line'><pre>463</pre></td><td class='code'><pre> child_controls,</pre></td></tr><tr><td class='line-number'><a name='L1343' href='#L1343'><pre>1343</pre></a></td><td class='covered-line'><pre>463</pre></td><td class='code'><pre> menus,</pre></td></tr><tr><td class='line-number'><a name='L1344' href='#L1344'><pre>1344</pre></a></td><td class='covered-line'><pre>463</pre></td><td class='code'><pre> property_groups,</pre></td></tr><tr><td class='line-number'><a name='L1345' href='#L1345'><pre>1345</pre></a></td><td class='skipped-line'></td><td class='code'><pre> );</pre></td></tr><tr><td class='line-number'><a name='L1346' href='#L1346'><pre>1346</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L1347' href='#L1347'><pre>1347</pre></a></td><td class='covered-line'><pre>463</pre></td><td class='code'><pre> let control = Control::new(control_name, tag, index, kind);</pre></td></tr><tr><td class='line-number'><a name='L1348' href='#L1348'><pre>1348</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L1349' href='#L1349'><pre>1349</pre></a></td><td class='covered-line'><pre>463</pre></td><td class='code'><pre> crate::ParseResult::new(Some(control), failures)</pre></td></tr><tr><td class='line-number'><a name='L1350' href='#L1350'><pre>1350</pre></a></td><td class='covered-line'><pre>464</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L1351' href='#L1351'><pre>1351</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L1352' href='#L1352'><pre>1352</pre></a></td><td class='skipped-line'></td><td class='code'><pre> /// Parse a complete module/class/form (the top-level structure)</pre></td></tr><tr><td class='line-number'><a name='L1353' href='#L1353'><pre>1353</pre></a></td><td class='skipped-line'></td><td class='code'><pre> ///</pre></td></tr><tr><td class='line-number'><a name='L1354' href='#L1354'><pre>1354</pre></a></td><td class='skipped-line'></td><td class='code'><pre> /// This function loops through all tokens and identifies what kind of</pre></td></tr><tr><td class='line-number'><a name='L1355' href='#L1355'><pre>1355</pre></a></td><td class='skipped-line'></td><td class='code'><pre> /// VB6 construct to parse based on the current token. As more VB6 syntax</pre></td></tr><tr><td class='line-number'><a name='L1356' href='#L1356'><pre>1356</pre></a></td><td class='skipped-line'></td><td class='code'><pre> /// is supported, additional branches can be added to this loop.</pre></td></tr><tr><td class='line-number'><a name='L1357' href='#L1357'><pre>1357</pre></a></td><td class='covered-line'><pre>5.43k</pre></td><td class='code'><pre> fn parse_root(mut self) -> ConcreteSyntaxTree {</pre></td></tr><tr><td class='line-number'><a name='L1358' href='#L1358'><pre>1358</pre></a></td><td class='covered-line'><pre>5.43k</pre></td><td class='code'><pre> self.builder.start_node(SyntaxKind::Root.to_raw());</pre></td></tr><tr><td class='line-number'><a name='L1359' href='#L1359'><pre>1359</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L1360' href='#L1360'><pre>1360</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Parse VERSION statement (if present)</pre></td></tr><tr><td class='line-number'><a name='L1361' href='#L1361'><pre>1361</pre></a></td><td class='covered-line'><pre>5.43k</pre></td><td class='code'><pre> if self.at_token(Token::VersionKeyword) {</pre></td></tr><tr><td class='line-number'><a name='L1362' href='#L1362'><pre>1362</pre></a></td><td class='covered-line'><pre>18</pre></td><td class='code'><pre> self.parse_version_statement();</pre></td></tr><tr><td class='line-number'><a name='L1363' href='#L1363'><pre>1363</pre></a></td><td class='covered-line'><pre>5.41k</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L1364' href='#L1364'><pre>1364</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L1365' href='#L1365'><pre>1365</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Parse BEGIN ... END block (if present)</pre></td></tr><tr><td class='line-number'><a name='L1366' href='#L1366'><pre>1366</pre></a></td><td class='covered-line'><pre>5.43k</pre></td><td class='code'><pre> if self.at_token(Token::BeginKeyword) {</pre></td></tr><tr><td class='line-number'><a name='L1367' href='#L1367'><pre>1367</pre></a></td><td class='covered-line'><pre>13</pre></td><td class='code'><pre> self.parse_properties_block();</pre></td></tr><tr><td class='line-number'><a name='L1368' href='#L1368'><pre>1368</pre></a></td><td class='covered-line'><pre>5.41k</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L1369' href='#L1369'><pre>1369</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L1370' href='#L1370'><pre>1370</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Parse Attribute statements (if present)</pre></td></tr><tr><td class='line-number'><a name='L1371' href='#L1371'><pre>1371</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // These come after the PropertiesBlock in forms/classes</pre></td></tr><tr><td class='line-number'><a name='L1372' href='#L1372'><pre>1372</pre></a></td><td class='covered-line'><pre>5.48k</pre></td><td class='code'><pre> while self.at_token(Token::AttributeKeyword) {</pre></td></tr><tr><td class='line-number'><a name='L1373' href='#L1373'><pre>1373</pre></a></td><td class='covered-line'><pre>56</pre></td><td class='code'><pre> self.parse_attribute_statement();</pre></td></tr><tr><td class='line-number'><a name='L1374' href='#L1374'><pre>1374</pre></a></td><td class='covered-line'><pre>56</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L1375' href='#L1375'><pre>1375</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L1376' href='#L1376'><pre>1376</pre></a></td><td class='covered-line'><pre>5.43k</pre></td><td class='code'><pre> self.parse_module_body();</pre></td></tr><tr><td class='line-number'><a name='L1377' href='#L1377'><pre>1377</pre></a></td><td class='covered-line'><pre>5.43k</pre></td><td class='code'><pre> self.builder.finish_node(); // Root</pre></td></tr><tr><td class='line-number'><a name='L1378' href='#L1378'><pre>1378</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L1379' href='#L1379'><pre>1379</pre></a></td><td class='covered-line'><pre>5.43k</pre></td><td class='code'><pre> let root = self.builder.finish();</pre></td></tr><tr><td class='line-number'><a name='L1380' href='#L1380'><pre>1380</pre></a></td><td class='covered-line'><pre>5.43k</pre></td><td class='code'><pre> ConcreteSyntaxTree::new(root)</pre></td></tr><tr><td class='line-number'><a name='L1381' href='#L1381'><pre>1381</pre></a></td><td class='covered-line'><pre>5.43k</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L1382' href='#L1382'><pre>1382</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L1383' href='#L1383'><pre>1383</pre></a></td><td class='covered-line'><pre>5.43k</pre></td><td class='code'><pre> fn parse_module_body(&mut self) {</pre></td></tr><tr><td class='line-number'><a name='L1384' href='#L1384'><pre>1384</pre></a></td><td class='covered-line'><pre>20.2k</pre></td><td class='code'><pre> while !self.is_at_end() {</pre></td></tr><tr><td class='line-number'><a name='L1385' href='#L1385'><pre>1385</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // For a CST, we need to consume ALL tokens, including whitespace and comments</pre></td></tr><tr><td class='line-number'><a name='L1386' href='#L1386'><pre>1386</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // We look ahead to determine structure, but still consume everything</pre></td></tr><tr><td class='line-number'><a name='L1387' href='#L1387'><pre>1387</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L1388' href='#L1388'><pre>1388</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Check what kind of statement or declaration we're looking at</pre></td></tr><tr><td class='line-number'><a name='L1389' href='#L1389'><pre>1389</pre></a></td><td class='covered-line'><pre>14.8k</pre></td><td class='code'><pre> match self.current_token() {</pre></td></tr><tr><td class='line-number'><a name='L1390' href='#L1390'><pre>1390</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // BEGIN ... END block (for forms/classes with properties)</pre></td></tr><tr><td class='line-number'><a name='L1391' href='#L1391'><pre>1391</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // This can appear after Object statements in form files</pre></td></tr><tr><td class='line-number'><a name='L1392' href='#L1392'><pre>1392</pre></a></td><td class='covered-line'><pre>3</pre></td><td class='code'><pre> Some(Token::BeginKeyword) => {</pre></td></tr><tr><td class='line-number'><a name='L1393' href='#L1393'><pre>1393</pre></a></td><td class='covered-line'><pre>3</pre></td><td class='code'><pre> self.parse_properties_block();</pre></td></tr><tr><td class='line-number'><a name='L1394' href='#L1394'><pre>1394</pre></a></td><td class='covered-line'><pre>3</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L1395' href='#L1395'><pre>1395</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Object statement: Object = "{UUID}#version#flags"; "filename"</pre></td></tr><tr><td class='line-number'><a name='L1396' href='#L1396'><pre>1396</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Only parse as ObjectStatement if it matches the proper format</pre></td></tr><tr><td class='line-number'><a name='L1397' href='#L1397'><pre>1397</pre></a></td><td class='covered-line'><pre>7</pre></td><td class='code'><pre> Some(Token::ObjectKeyword) if self.is_object_statement(<div class='tooltip'>)<span class='tooltip-content'>6</span></div> => {</pre></td></tr><tr><td class='line-number'><a name='L1398' href='#L1398'><pre>1398</pre></a></td><td class='covered-line'><pre>6</pre></td><td class='code'><pre> self.parse_object_statement();</pre></td></tr><tr><td class='line-number'><a name='L1399' href='#L1399'><pre>1399</pre></a></td><td class='covered-line'><pre>6</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L1400' href='#L1400'><pre>1400</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Attribute statement: Attribute VB_Name = "..."</pre></td></tr><tr><td class='line-number'><a name='L1401' href='#L1401'><pre>1401</pre></a></td><td class='covered-line'><pre>11</pre></td><td class='code'><pre> Some(Token::AttributeKeyword) => {</pre></td></tr><tr><td class='line-number'><a name='L1402' href='#L1402'><pre>1402</pre></a></td><td class='covered-line'><pre>11</pre></td><td class='code'><pre> self.parse_attribute_statement();</pre></td></tr><tr><td class='line-number'><a name='L1403' href='#L1403'><pre>1403</pre></a></td><td class='covered-line'><pre>11</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L1404' href='#L1404'><pre>1404</pre></a></td><td class='skipped-line'></td><td class='code'><pre> Some(Token::OptionKeyword) => {</pre></td></tr><tr><td class='line-number'><a name='L1405' href='#L1405'><pre>1405</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Peek ahead to check if this is Option Base, Option Compare, or Option Private</pre></td></tr><tr><td class='line-number'><a name='L1406' href='#L1406'><pre>1406</pre></a></td><td class='covered-line'><pre>84</pre></td><td class='code'><pre> if let Some(Token::BaseKeyword) = self.peek_next_keyword() {</pre></td></tr><tr><td class='line-number'><a name='L1407' href='#L1407'><pre>1407</pre></a></td><td class='covered-line'><pre>14</pre></td><td class='code'><pre> self.parse_option_base_statement();</pre></td></tr><tr><td class='line-number'><a name='L1408' href='#L1408'><pre>1408</pre></a></td><td class='covered-line'><pre>70</pre></td><td class='code'><pre> } else if let Some(Token::CompareKeyword) = self.peek_next_keyword() {</pre></td></tr><tr><td class='line-number'><a name='L1409' href='#L1409'><pre>1409</pre></a></td><td class='covered-line'><pre>16</pre></td><td class='code'><pre> self.parse_option_compare_statement();</pre></td></tr><tr><td class='line-number'><a name='L1410' href='#L1410'><pre>1410</pre></a></td><td class='covered-line'><pre>54</pre></td><td class='code'><pre> } else if let Some(Token::PrivateKeyword) = self.peek_next_keyword() {</pre></td></tr><tr><td class='line-number'><a name='L1411' href='#L1411'><pre>1411</pre></a></td><td class='covered-line'><pre>12</pre></td><td class='code'><pre> self.parse_option_private_statement();</pre></td></tr><tr><td class='line-number'><a name='L1412' href='#L1412'><pre>1412</pre></a></td><td class='covered-line'><pre>42</pre></td><td class='code'><pre> } else {</pre></td></tr><tr><td class='line-number'><a name='L1413' href='#L1413'><pre>1413</pre></a></td><td class='covered-line'><pre>42</pre></td><td class='code'><pre> self.parse_option_statement();</pre></td></tr><tr><td class='line-number'><a name='L1414' href='#L1414'><pre>1414</pre></a></td><td class='covered-line'><pre>42</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L1415' href='#L1415'><pre>1415</pre></a></td><td class='skipped-line'></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L1416' href='#L1416'><pre>1416</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // DefType statements: DefInt, DefLng, DefStr, etc.</pre></td></tr><tr><td class='line-number'><a name='L1417' href='#L1417'><pre>1417</pre></a></td><td class='skipped-line'></td><td class='code'><pre> Some(</pre></td></tr><tr><td class='line-number'><a name='L1418' href='#L1418'><pre>1418</pre></a></td><td class='skipped-line'></td><td class='code'><pre> Token::DefBoolKeyword</pre></td></tr><tr><td class='line-number'><a name='L1419' href='#L1419'><pre>1419</pre></a></td><td class='skipped-line'></td><td class='code'><pre> | Token::DefByteKeyword</pre></td></tr><tr><td class='line-number'><a name='L1420' href='#L1420'><pre>1420</pre></a></td><td class='skipped-line'></td><td class='code'><pre> | Token::DefIntKeyword</pre></td></tr><tr><td class='line-number'><a name='L1421' href='#L1421'><pre>1421</pre></a></td><td class='skipped-line'></td><td class='code'><pre> | Token::DefLngKeyword</pre></td></tr><tr><td class='line-number'><a name='L1422' href='#L1422'><pre>1422</pre></a></td><td class='skipped-line'></td><td class='code'><pre> | Token::DefCurKeyword</pre></td></tr><tr><td class='line-number'><a name='L1423' href='#L1423'><pre>1423</pre></a></td><td class='skipped-line'></td><td class='code'><pre> | Token::DefSngKeyword</pre></td></tr><tr><td class='line-number'><a name='L1424' href='#L1424'><pre>1424</pre></a></td><td class='skipped-line'></td><td class='code'><pre> | Token::DefDblKeyword</pre></td></tr><tr><td class='line-number'><a name='L1425' href='#L1425'><pre>1425</pre></a></td><td class='skipped-line'></td><td class='code'><pre> | Token::DefDecKeyword</pre></td></tr><tr><td class='line-number'><a name='L1426' href='#L1426'><pre>1426</pre></a></td><td class='skipped-line'></td><td class='code'><pre> | Token::DefDateKeyword</pre></td></tr><tr><td class='line-number'><a name='L1427' href='#L1427'><pre>1427</pre></a></td><td class='skipped-line'></td><td class='code'><pre> | Token::DefStrKeyword</pre></td></tr><tr><td class='line-number'><a name='L1428' href='#L1428'><pre>1428</pre></a></td><td class='skipped-line'></td><td class='code'><pre> | Token::DefObjKeyword</pre></td></tr><tr><td class='line-number'><a name='L1429' href='#L1429'><pre>1429</pre></a></td><td class='skipped-line'></td><td class='code'><pre> | Token::DefVarKeyword,</pre></td></tr><tr><td class='line-number'><a name='L1430' href='#L1430'><pre>1430</pre></a></td><td class='covered-line'><pre>22</pre></td><td class='code'><pre> ) => {</pre></td></tr><tr><td class='line-number'><a name='L1431' href='#L1431'><pre>1431</pre></a></td><td class='covered-line'><pre>22</pre></td><td class='code'><pre> self.parse_deftype_statement();</pre></td></tr><tr><td class='line-number'><a name='L1432' href='#L1432'><pre>1432</pre></a></td><td class='covered-line'><pre>22</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L1433' href='#L1433'><pre>1433</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Declare statement: Declare Sub/Function Name Lib "..."</pre></td></tr><tr><td class='line-number'><a name='L1434' href='#L1434'><pre>1434</pre></a></td><td class='covered-line'><pre>2</pre></td><td class='code'><pre> Some(Token::DeclareKeyword) => {</pre></td></tr><tr><td class='line-number'><a name='L1435' href='#L1435'><pre>1435</pre></a></td><td class='covered-line'><pre>2</pre></td><td class='code'><pre> self.parse_declare_statement();</pre></td></tr><tr><td class='line-number'><a name='L1436' href='#L1436'><pre>1436</pre></a></td><td class='covered-line'><pre>2</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L1437' href='#L1437'><pre>1437</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Event statement: Event Name(...)</pre></td></tr><tr><td class='line-number'><a name='L1438' href='#L1438'><pre>1438</pre></a></td><td class='covered-line'><pre>11</pre></td><td class='code'><pre> Some(Token::EventKeyword) => {</pre></td></tr><tr><td class='line-number'><a name='L1439' href='#L1439'><pre>1439</pre></a></td><td class='covered-line'><pre>11</pre></td><td class='code'><pre> self.parse_event_statement();</pre></td></tr><tr><td class='line-number'><a name='L1440' href='#L1440'><pre>1440</pre></a></td><td class='covered-line'><pre>11</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L1441' href='#L1441'><pre>1441</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Implements statement: Implements InterfaceName</pre></td></tr><tr><td class='line-number'><a name='L1442' href='#L1442'><pre>1442</pre></a></td><td class='uncovered-line'><pre>0</pre></td><td class='code'><pre> Some(Token::ImplementsKeyword) => <span class='region red'>{</span></pre></td></tr><tr><td class='line-number'><a name='L1443' href='#L1443'><pre>1443</pre></a></td><td class='uncovered-line'><pre>0</pre></td><td class='code'><pre><span class='region red'> self.parse_implements_statement();</span></pre></td></tr><tr><td class='line-number'><a name='L1444' href='#L1444'><pre>1444</pre></a></td><td class='uncovered-line'><pre>0</pre></td><td class='code'><pre><span class='region red'> }</span></pre></td></tr><tr><td class='line-number'><a name='L1445' href='#L1445'><pre>1445</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Enum statement: Enum Name ... End Enum</pre></td></tr><tr><td class='line-number'><a name='L1446' href='#L1446'><pre>1446</pre></a></td><td class='covered-line'><pre>11</pre></td><td class='code'><pre> Some(Token::EnumKeyword) => {</pre></td></tr><tr><td class='line-number'><a name='L1447' href='#L1447'><pre>1447</pre></a></td><td class='covered-line'><pre>11</pre></td><td class='code'><pre> self.parse_enum_statement();</pre></td></tr><tr><td class='line-number'><a name='L1448' href='#L1448'><pre>1448</pre></a></td><td class='covered-line'><pre>11</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L1449' href='#L1449'><pre>1449</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Type statement: Type Name ... End Type</pre></td></tr><tr><td class='line-number'><a name='L1450' href='#L1450'><pre>1450</pre></a></td><td class='covered-line'><pre>34</pre></td><td class='code'><pre> Some(Token::TypeKeyword) => {</pre></td></tr><tr><td class='line-number'><a name='L1451' href='#L1451'><pre>1451</pre></a></td><td class='covered-line'><pre>34</pre></td><td class='code'><pre> self.parse_type_statement();</pre></td></tr><tr><td class='line-number'><a name='L1452' href='#L1452'><pre>1452</pre></a></td><td class='covered-line'><pre>34</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L1453' href='#L1453'><pre>1453</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Sub procedure: Sub Name(...)</pre></td></tr><tr><td class='line-number'><a name='L1454' href='#L1454'><pre>1454</pre></a></td><td class='covered-line'><pre>2.79k</pre></td><td class='code'><pre> Some(Token::SubKeyword) => {</pre></td></tr><tr><td class='line-number'><a name='L1455' href='#L1455'><pre>1455</pre></a></td><td class='covered-line'><pre>2.79k</pre></td><td class='code'><pre> self.parse_sub_statement();</pre></td></tr><tr><td class='line-number'><a name='L1456' href='#L1456'><pre>1456</pre></a></td><td class='covered-line'><pre>2.79k</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L1457' href='#L1457'><pre>1457</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Function Procedure Syntax:</pre></td></tr><tr><td class='line-number'><a name='L1458' href='#L1458'><pre>1458</pre></a></td><td class='skipped-line'></td><td class='code'><pre> //</pre></td></tr><tr><td class='line-number'><a name='L1459' href='#L1459'><pre>1459</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // [Public | Private | Friend] [ Static ] Function name [ ( arglist ) ] [ As type ]</pre></td></tr><tr><td class='line-number'><a name='L1460' href='#L1460'><pre>1460</pre></a></td><td class='skipped-line'></td><td class='code'><pre> //</pre></td></tr><tr><td class='line-number'><a name='L1461' href='#L1461'><pre>1461</pre></a></td><td class='covered-line'><pre>385</pre></td><td class='code'><pre> Some(Token::FunctionKeyword) => {</pre></td></tr><tr><td class='line-number'><a name='L1462' href='#L1462'><pre>1462</pre></a></td><td class='covered-line'><pre>385</pre></td><td class='code'><pre> self.parse_function_statement();</pre></td></tr><tr><td class='line-number'><a name='L1463' href='#L1463'><pre>1463</pre></a></td><td class='covered-line'><pre>385</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L1464' href='#L1464'><pre>1464</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Property Procedure Syntax:</pre></td></tr><tr><td class='line-number'><a name='L1465' href='#L1465'><pre>1465</pre></a></td><td class='skipped-line'></td><td class='code'><pre> //</pre></td></tr><tr><td class='line-number'><a name='L1466' href='#L1466'><pre>1466</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // [Public | Private | Friend] [ Static ] Property Get|Let|Set name [ ( arglist ) ] [ As type ]</pre></td></tr><tr><td class='line-number'><a name='L1467' href='#L1467'><pre>1467</pre></a></td><td class='skipped-line'></td><td class='code'><pre> //</pre></td></tr><tr><td class='line-number'><a name='L1468' href='#L1468'><pre>1468</pre></a></td><td class='covered-line'><pre>18</pre></td><td class='code'><pre> Some(Token::PropertyKeyword) => {</pre></td></tr><tr><td class='line-number'><a name='L1469' href='#L1469'><pre>1469</pre></a></td><td class='covered-line'><pre>18</pre></td><td class='code'><pre> self.parse_property_statement();</pre></td></tr><tr><td class='line-number'><a name='L1470' href='#L1470'><pre>1470</pre></a></td><td class='covered-line'><pre>18</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L1471' href='#L1471'><pre>1471</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Variable declarations: Dim/Const</pre></td></tr><tr><td class='line-number'><a name='L1472' href='#L1472'><pre>1472</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // For Public/Private/Friend/Static, we need to look ahead to see if it's a</pre></td></tr><tr><td class='line-number'><a name='L1473' href='#L1473'><pre>1473</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // function/sub declaration or a variable declaration</pre></td></tr><tr><td class='line-number'><a name='L1474' href='#L1474'><pre>1474</pre></a></td><td class='covered-line'><pre>321</pre></td><td class='code'><pre> Some(Token::DimKeyword | Token::ConstKeyword) => {</pre></td></tr><tr><td class='line-number'><a name='L1475' href='#L1475'><pre>1475</pre></a></td><td class='covered-line'><pre>321</pre></td><td class='code'><pre> self.parse_dim();</pre></td></tr><tr><td class='line-number'><a name='L1476' href='#L1476'><pre>1476</pre></a></td><td class='covered-line'><pre>321</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L1477' href='#L1477'><pre>1477</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Public/Private/Friend/Static - could be function/sub/property or declaration</pre></td></tr><tr><td class='line-number'><a name='L1478' href='#L1478'><pre>1478</pre></a></td><td class='skipped-line'></td><td class='code'><pre> Some(</pre></td></tr><tr><td class='line-number'><a name='L1479' href='#L1479'><pre>1479</pre></a></td><td class='skipped-line'></td><td class='code'><pre> Token::PrivateKeyword</pre></td></tr><tr><td class='line-number'><a name='L1480' href='#L1480'><pre>1480</pre></a></td><td class='skipped-line'></td><td class='code'><pre> | Token::PublicKeyword</pre></td></tr><tr><td class='line-number'><a name='L1481' href='#L1481'><pre>1481</pre></a></td><td class='skipped-line'></td><td class='code'><pre> | Token::FriendKeyword</pre></td></tr><tr><td class='line-number'><a name='L1482' href='#L1482'><pre>1482</pre></a></td><td class='skipped-line'></td><td class='code'><pre> | Token::StaticKeyword,</pre></td></tr><tr><td class='line-number'><a name='L1483' href='#L1483'><pre>1483</pre></a></td><td class='skipped-line'></td><td class='code'><pre> ) => {</pre></td></tr><tr><td class='line-number'><a name='L1484' href='#L1484'><pre>1484</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Look ahead to see if this is a function/sub/property/enum declaration</pre></td></tr><tr><td class='line-number'><a name='L1485' href='#L1485'><pre>1485</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Peek at the next 2 keywords to handle cases like "Public Static Function"</pre></td></tr><tr><td class='line-number'><a name='L1486' href='#L1486'><pre>1486</pre></a></td><td class='covered-line'><pre>678</pre></td><td class='code'><pre> let next_keywords: Vec<_> = self</pre></td></tr><tr><td class='line-number'><a name='L1487' href='#L1487'><pre>1487</pre></a></td><td class='covered-line'><pre>678</pre></td><td class='code'><pre> .peek_next_count_keywords(NonZeroUsize::new(2).unwrap())</pre></td></tr><tr><td class='line-number'><a name='L1488' href='#L1488'><pre>1488</pre></a></td><td class='covered-line'><pre>678</pre></td><td class='code'><pre> .collect();</pre></td></tr><tr><td class='line-number'><a name='L1489' href='#L1489'><pre>1489</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L1490' href='#L1490'><pre>1490</pre></a></td><td class='covered-line'><pre>678</pre></td><td class='code'><pre> match next_keywords.as_slice() {</pre></td></tr><tr><td class='line-number'><a name='L1491' href='#L1491'><pre>1491</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Direct: Public/Private/Friend Function, Sub, Property, Enum, Type, Declare, or Event</pre></td></tr><tr><td class='line-number'><a name='L1492' href='#L1492'><pre>1492</pre></a></td><td class='covered-line'><pre>678</pre></td><td class='code'><pre> [Token::FunctionKeyword, ..] => <div class='tooltip'>self<span class='tooltip-content'>39</span></div>.<div class='tooltip'>parse_function_statement<span class='tooltip-content'>39</span></div>(), // Function</pre></td></tr><tr><td class='line-number'><a name='L1493' href='#L1493'><pre>1493</pre></a></td><td class='covered-line'><pre>283</pre></td><td class='code'><pre> [Token::SubKeyword, ..] => self.parse_sub_statement(), // Sub</pre></td></tr><tr><td class='line-number'><a name='L1494' href='#L1494'><pre>1494</pre></a></td><td class='covered-line'><pre>16</pre></td><td class='code'><pre> [Token::PropertyKeyword, ..] => self.parse_property_statement(), // Property</pre></td></tr><tr><td class='line-number'><a name='L1495' href='#L1495'><pre>1495</pre></a></td><td class='covered-line'><pre>75</pre></td><td class='code'><pre> [Token::DeclareKeyword, ..] => self.parse_declare_statement(), // Declare</pre></td></tr><tr><td class='line-number'><a name='L1496' href='#L1496'><pre>1496</pre></a></td><td class='covered-line'><pre>19</pre></td><td class='code'><pre> [Token::EnumKeyword, ..] => self.parse_enum_statement(), // Enum</pre></td></tr><tr><td class='line-number'><a name='L1497' href='#L1497'><pre>1497</pre></a></td><td class='covered-line'><pre>26</pre></td><td class='code'><pre> [Token::TypeKeyword, ..] => self.parse_type_statement(), // Type</pre></td></tr><tr><td class='line-number'><a name='L1498' href='#L1498'><pre>1498</pre></a></td><td class='covered-line'><pre>3</pre></td><td class='code'><pre> [Token::EventKeyword, ..] => self.parse_event_statement(), // Event</pre></td></tr><tr><td class='line-number'><a name='L1499' href='#L1499'><pre>1499</pre></a></td><td class='uncovered-line'><pre>0</pre></td><td class='code'><pre> [Token::ImplementsKeyword, ..] => <span class='region red'>self</span>.<span class='region red'>parse_implements_statement</span>(), // Implements</pre></td></tr><tr><td class='line-number'><a name='L1500' href='#L1500'><pre>1500</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // With Static: Public/Private/Friend Static Function, Sub, or Property</pre></td></tr><tr><td class='line-number'><a name='L1501' href='#L1501'><pre>1501</pre></a></td><td class='covered-line'><pre>217</pre></td><td class='code'><pre> [Token::StaticKeyword, Token::FunctionKeyword] => {</pre></td></tr><tr><td class='line-number'><a name='L1502' href='#L1502'><pre>1502</pre></a></td><td class='covered-line'><pre>4</pre></td><td class='code'><pre> self.parse_function_statement();</pre></td></tr><tr><td class='line-number'><a name='L1503' href='#L1503'><pre>1503</pre></a></td><td class='covered-line'><pre>4</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L1504' href='#L1504'><pre>1504</pre></a></td><td class='covered-line'><pre>3</pre></td><td class='code'><pre> [Token::StaticKeyword, Token::SubKeyword] => {</pre></td></tr><tr><td class='line-number'><a name='L1505' href='#L1505'><pre>1505</pre></a></td><td class='covered-line'><pre>3</pre></td><td class='code'><pre> self.parse_sub_statement();</pre></td></tr><tr><td class='line-number'><a name='L1506' href='#L1506'><pre>1506</pre></a></td><td class='covered-line'><pre>3</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L1507' href='#L1507'><pre>1507</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> [Token::StaticKeyword, Token::PropertyKeyword] => {</pre></td></tr><tr><td class='line-number'><a name='L1508' href='#L1508'><pre>1508</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> self.parse_property_statement();</pre></td></tr><tr><td class='line-number'><a name='L1509' href='#L1509'><pre>1509</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L1510' href='#L1510'><pre>1510</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Anything else is a declaration</pre></td></tr><tr><td class='line-number'><a name='L1511' href='#L1511'><pre>1511</pre></a></td><td class='covered-line'><pre>209</pre></td><td class='code'><pre> _ => self.parse_dim(),</pre></td></tr><tr><td class='line-number'><a name='L1512' href='#L1512'><pre>1512</pre></a></td><td class='skipped-line'></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L1513' href='#L1513'><pre>1513</pre></a></td><td class='skipped-line'></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L1514' href='#L1514'><pre>1514</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Anything else - check if it's a statement, label, assignment, or unknown</pre></td></tr><tr><td class='line-number'><a name='L1515' href='#L1515'><pre>1515</pre></a></td><td class='skipped-line'></td><td class='code'><pre> _ => {</pre></td></tr><tr><td class='line-number'><a name='L1516' href='#L1516'><pre>1516</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Whitespace, newlines, and comments - consume directly FIRST</pre></td></tr><tr><td class='line-number'><a name='L1517' href='#L1517'><pre>1517</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // This must be checked before is_at_procedure_call to avoid</pre></td></tr><tr><td class='line-number'><a name='L1518' href='#L1518'><pre>1518</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // treating REM comments as procedure calls</pre></td></tr><tr><td class='line-number'><a name='L1519' href='#L1519'><pre>1519</pre></a></td><td class='covered-line'><pre>2.47k</pre></td><td class='code'><pre> if matches!(</pre></td></tr><tr><td class='line-number'><a name='L1520' href='#L1520'><pre>1520</pre></a></td><td class='covered-line'><pre>10.4k</pre></td><td class='code'><pre> self.current_token(),</pre></td></tr><tr><td class='line-number'><a name='L1521' href='#L1521'><pre>1521</pre></a></td><td class='skipped-line'></td><td class='code'><pre> Some(</pre></td></tr><tr><td class='line-number'><a name='L1522' href='#L1522'><pre>1522</pre></a></td><td class='skipped-line'></td><td class='code'><pre> Token::Whitespace</pre></td></tr><tr><td class='line-number'><a name='L1523' href='#L1523'><pre>1523</pre></a></td><td class='skipped-line'></td><td class='code'><pre> | Token::Newline</pre></td></tr><tr><td class='line-number'><a name='L1524' href='#L1524'><pre>1524</pre></a></td><td class='skipped-line'></td><td class='code'><pre> | Token::EndOfLineComment</pre></td></tr><tr><td class='line-number'><a name='L1525' href='#L1525'><pre>1525</pre></a></td><td class='skipped-line'></td><td class='code'><pre> | Token::RemComment</pre></td></tr><tr><td class='line-number'><a name='L1526' href='#L1526'><pre>1526</pre></a></td><td class='skipped-line'></td><td class='code'><pre> )</pre></td></tr><tr><td class='line-number'><a name='L1527' href='#L1527'><pre>1527</pre></a></td><td class='covered-line'><pre>8.00k</pre></td><td class='code'><pre> ) {</pre></td></tr><tr><td class='line-number'><a name='L1528' href='#L1528'><pre>1528</pre></a></td><td class='covered-line'><pre>8.00k</pre></td><td class='code'><pre> self.consume_token();</pre></td></tr><tr><td class='line-number'><a name='L1529' href='#L1529'><pre>1529</pre></a></td><td class='covered-line'><pre>8.00k</pre></td><td class='code'><pre> // Try control flow statements</pre></td></tr><tr><td class='line-number'><a name='L1530' href='#L1530'><pre>1530</pre></a></td><td class='covered-line'><pre>8.00k</pre></td><td class='code'><pre> } else if <div class='tooltip'>self<span class='tooltip-content'>2.47k</span></div>.<div class='tooltip'>is_control_flow_keyword<span class='tooltip-content'>2.47k</span></div>() {</pre></td></tr><tr><td class='line-number'><a name='L1531' href='#L1531'><pre>1531</pre></a></td><td class='covered-line'><pre>659</pre></td><td class='code'><pre> self.parse_control_flow_statement();</pre></td></tr><tr><td class='line-number'><a name='L1532' href='#L1532'><pre>1532</pre></a></td><td class='covered-line'><pre>659</pre></td><td class='code'><pre> // Try built-in statements</pre></td></tr><tr><td class='line-number'><a name='L1533' href='#L1533'><pre>1533</pre></a></td><td class='covered-line'><pre>1.82k</pre></td><td class='code'><pre> } else if self.is_library_statement_keyword() {</pre></td></tr><tr><td class='line-number'><a name='L1534' href='#L1534'><pre>1534</pre></a></td><td class='covered-line'><pre>123</pre></td><td class='code'><pre> self.parse_library_statement();</pre></td></tr><tr><td class='line-number'><a name='L1535' href='#L1535'><pre>1535</pre></a></td><td class='covered-line'><pre>123</pre></td><td class='code'><pre> // Try array statements</pre></td></tr><tr><td class='line-number'><a name='L1536' href='#L1536'><pre>1536</pre></a></td><td class='covered-line'><pre>1.69k</pre></td><td class='code'><pre> } else if self.is_variable_declaration_keyword() {</pre></td></tr><tr><td class='line-number'><a name='L1537' href='#L1537'><pre>1537</pre></a></td><td class='covered-line'><pre>7</pre></td><td class='code'><pre> self.parse_array_statement();</pre></td></tr><tr><td class='line-number'><a name='L1538' href='#L1538'><pre>1538</pre></a></td><td class='covered-line'><pre>7</pre></td><td class='code'><pre> // Try to parse common statements using centralized dispatcher</pre></td></tr><tr><td class='line-number'><a name='L1539' href='#L1539'><pre>1539</pre></a></td><td class='covered-line'><pre>1.69k</pre></td><td class='code'><pre> } else if self.is_statement_keyword() {</pre></td></tr><tr><td class='line-number'><a name='L1540' href='#L1540'><pre>1540</pre></a></td><td class='covered-line'><pre>157</pre></td><td class='code'><pre> self.parse_statement();</pre></td></tr><tr><td class='line-number'><a name='L1541' href='#L1541'><pre>1541</pre></a></td><td class='covered-line'><pre>157</pre></td><td class='code'><pre> // Check if this is a label (identifier followed by colon)</pre></td></tr><tr><td class='line-number'><a name='L1542' href='#L1542'><pre>1542</pre></a></td><td class='covered-line'><pre>1.53k</pre></td><td class='code'><pre> } else if self.is_at_label() {</pre></td></tr><tr><td class='line-number'><a name='L1543' href='#L1543'><pre>1543</pre></a></td><td class='covered-line'><pre>8</pre></td><td class='code'><pre> self.parse_label_statement();</pre></td></tr><tr><td class='line-number'><a name='L1544' href='#L1544'><pre>1544</pre></a></td><td class='covered-line'><pre>8</pre></td><td class='code'><pre> // Check for Let statement (optional assignment keyword)</pre></td></tr><tr><td class='line-number'><a name='L1545' href='#L1545'><pre>1545</pre></a></td><td class='covered-line'><pre>1.52k</pre></td><td class='code'><pre> } else if self.at_token(Token::LetKeyword) {</pre></td></tr><tr><td class='line-number'><a name='L1546' href='#L1546'><pre>1546</pre></a></td><td class='covered-line'><pre>2</pre></td><td class='code'><pre> self.parse_let_statement();</pre></td></tr><tr><td class='line-number'><a name='L1547' href='#L1547'><pre>1547</pre></a></td><td class='covered-line'><pre>2</pre></td><td class='code'><pre> // Check if this looks like an assignment statement (identifier = expression)</pre></td></tr><tr><td class='line-number'><a name='L1548' href='#L1548'><pre>1548</pre></a></td><td class='covered-line'><pre>2</pre></td><td class='code'><pre> // This must come BEFORE at_keyword() check to handle keywords used as variables</pre></td></tr><tr><td class='line-number'><a name='L1549' href='#L1549'><pre>1549</pre></a></td><td class='covered-line'><pre>1.52k</pre></td><td class='code'><pre> } else if self.is_at_assignment() {</pre></td></tr><tr><td class='line-number'><a name='L1550' href='#L1550'><pre>1550</pre></a></td><td class='covered-line'><pre>1.07k</pre></td><td class='code'><pre> self.parse_assignment_statement();</pre></td></tr><tr><td class='line-number'><a name='L1551' href='#L1551'><pre>1551</pre></a></td><td class='covered-line'><pre>1.07k</pre></td><td class='code'><pre> // Check if this looks like a procedure call (identifier without assignment)</pre></td></tr><tr><td class='line-number'><a name='L1552' href='#L1552'><pre>1552</pre></a></td><td class='covered-line'><pre>1.07k</pre></td><td class='code'><pre> } else if <div class='tooltip'>self<span class='tooltip-content'>445</span></div>.<div class='tooltip'>is_at_procedure_call<span class='tooltip-content'>445</span></div>() {</pre></td></tr><tr><td class='line-number'><a name='L1553' href='#L1553'><pre>1553</pre></a></td><td class='covered-line'><pre>174</pre></td><td class='code'><pre> self.parse_procedure_call();</pre></td></tr><tr><td class='line-number'><a name='L1554' href='#L1554'><pre>1554</pre></a></td><td class='covered-line'><pre>271</pre></td><td class='code'><pre> } else if self.is_identifier() || <div class='tooltip'>self<span class='tooltip-content'>175</span></div>.<div class='tooltip'>at_keyword<span class='tooltip-content'>175</span></div>() {</pre></td></tr><tr><td class='line-number'><a name='L1555' href='#L1555'><pre>1555</pre></a></td><td class='covered-line'><pre>115</pre></td><td class='code'><pre> self.consume_token();</pre></td></tr><tr><td class='line-number'><a name='L1556' href='#L1556'><pre>1556</pre></a></td><td class='covered-line'><pre>156</pre></td><td class='code'><pre> } else {</pre></td></tr><tr><td class='line-number'><a name='L1557' href='#L1557'><pre>1557</pre></a></td><td class='covered-line'><pre>156</pre></td><td class='code'><pre> // This is purely being done this way to make it easier during development.</pre></td></tr><tr><td class='line-number'><a name='L1558' href='#L1558'><pre>1558</pre></a></td><td class='covered-line'><pre>156</pre></td><td class='code'><pre> // In a full implementation, we would have specific parsing functions</pre></td></tr><tr><td class='line-number'><a name='L1559' href='#L1559'><pre>1559</pre></a></td><td class='covered-line'><pre>156</pre></td><td class='code'><pre> // for all VB6 constructs with anything unrecognized being treated as an error node.</pre></td></tr><tr><td class='line-number'><a name='L1560' href='#L1560'><pre>1560</pre></a></td><td class='covered-line'><pre>156</pre></td><td class='code'><pre> self.consume_token_as_unknown();</pre></td></tr><tr><td class='line-number'><a name='L1561' href='#L1561'><pre>1561</pre></a></td><td class='covered-line'><pre>156</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L1562' href='#L1562'><pre>1562</pre></a></td><td class='skipped-line'></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L1563' href='#L1563'><pre>1563</pre></a></td><td class='skipped-line'></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L1564' href='#L1564'><pre>1564</pre></a></td><td class='skipped-line'></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L1565' href='#L1565'><pre>1565</pre></a></td><td class='covered-line'><pre>5.43k</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L1566' href='#L1566'><pre>1566</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L1567' href='#L1567'><pre>1567</pre></a></td><td class='skipped-line'></td><td class='code'><pre> /// Check if the current token is a control flow keyword.</pre></td></tr><tr><td class='line-number'><a name='L1568' href='#L1568'><pre>1568</pre></a></td><td class='skipped-line'></td><td class='code'><pre> /// Checks both current position and next non-whitespace token.</pre></td></tr><tr><td class='line-number'><a name='L1569' href='#L1569'><pre>1569</pre></a></td><td class='covered-line'><pre>35.2k</pre></td><td class='code'><pre> fn is_control_flow_keyword(&self) -> bool {</pre></td></tr><tr><td class='line-number'><a name='L1570' href='#L1570'><pre>1570</pre></a></td><td class='covered-line'><pre>35.2k</pre></td><td class='code'><pre> let token = if self.at_token(Token::Whitespace) {</pre></td></tr><tr><td class='line-number'><a name='L1571' href='#L1571'><pre>1571</pre></a></td><td class='covered-line'><pre>17.0k</pre></td><td class='code'><pre> self.peek_next_keyword()</pre></td></tr><tr><td class='line-number'><a name='L1572' href='#L1572'><pre>1572</pre></a></td><td class='skipped-line'></td><td class='code'><pre> } else {</pre></td></tr><tr><td class='line-number'><a name='L1573' href='#L1573'><pre>1573</pre></a></td><td class='covered-line'><pre>18.1k</pre></td><td class='code'><pre> self.current_token().copied()</pre></td></tr><tr><td class='line-number'><a name='L1574' href='#L1574'><pre>1574</pre></a></td><td class='skipped-line'></td><td class='code'><pre> };</pre></td></tr><tr><td class='line-number'><a name='L1575' href='#L1575'><pre>1575</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L1576' href='#L1576'><pre>1576</pre></a></td><td class='covered-line'><pre>32.3k</pre></td><td class='code'><pre> matches!(</pre></td></tr><tr><td class='line-number'><a name='L1577' href='#L1577'><pre>1577</pre></a></td><td class='covered-line'><pre>35.2k</pre></td><td class='code'><pre> token,</pre></td></tr><tr><td class='line-number'><a name='L1578' href='#L1578'><pre>1578</pre></a></td><td class='skipped-line'></td><td class='code'><pre> Some(</pre></td></tr><tr><td class='line-number'><a name='L1579' href='#L1579'><pre>1579</pre></a></td><td class='skipped-line'></td><td class='code'><pre> Token::IfKeyword</pre></td></tr><tr><td class='line-number'><a name='L1580' href='#L1580'><pre>1580</pre></a></td><td class='skipped-line'></td><td class='code'><pre> | Token::SelectKeyword</pre></td></tr><tr><td class='line-number'><a name='L1581' href='#L1581'><pre>1581</pre></a></td><td class='skipped-line'></td><td class='code'><pre> | Token::ForKeyword</pre></td></tr><tr><td class='line-number'><a name='L1582' href='#L1582'><pre>1582</pre></a></td><td class='skipped-line'></td><td class='code'><pre> | Token::DoKeyword</pre></td></tr><tr><td class='line-number'><a name='L1583' href='#L1583'><pre>1583</pre></a></td><td class='skipped-line'></td><td class='code'><pre> | Token::WhileKeyword</pre></td></tr><tr><td class='line-number'><a name='L1584' href='#L1584'><pre>1584</pre></a></td><td class='skipped-line'></td><td class='code'><pre> | Token::GotoKeyword</pre></td></tr><tr><td class='line-number'><a name='L1585' href='#L1585'><pre>1585</pre></a></td><td class='skipped-line'></td><td class='code'><pre> | Token::GoSubKeyword</pre></td></tr><tr><td class='line-number'><a name='L1586' href='#L1586'><pre>1586</pre></a></td><td class='skipped-line'></td><td class='code'><pre> | Token::ReturnKeyword</pre></td></tr><tr><td class='line-number'><a name='L1587' href='#L1587'><pre>1587</pre></a></td><td class='skipped-line'></td><td class='code'><pre> | Token::ResumeKeyword</pre></td></tr><tr><td class='line-number'><a name='L1588' href='#L1588'><pre>1588</pre></a></td><td class='skipped-line'></td><td class='code'><pre> | Token::ExitKeyword</pre></td></tr><tr><td class='line-number'><a name='L1589' href='#L1589'><pre>1589</pre></a></td><td class='skipped-line'></td><td class='code'><pre> | Token::OnKeyword</pre></td></tr><tr><td class='line-number'><a name='L1590' href='#L1590'><pre>1590</pre></a></td><td class='skipped-line'></td><td class='code'><pre> )</pre></td></tr><tr><td class='line-number'><a name='L1591' href='#L1591'><pre>1591</pre></a></td><td class='skipped-line'></td><td class='code'><pre> )</pre></td></tr><tr><td class='line-number'><a name='L1592' href='#L1592'><pre>1592</pre></a></td><td class='covered-line'><pre>35.2k</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L1593' href='#L1593'><pre>1593</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L1594' href='#L1594'><pre>1594</pre></a></td><td class='skipped-line'></td><td class='code'><pre> /// Dispatch control flow statement parsing to the appropriate parser.</pre></td></tr><tr><td class='line-number'><a name='L1595' href='#L1595'><pre>1595</pre></a></td><td class='covered-line'><pre>2.92k</pre></td><td class='code'><pre> fn parse_control_flow_statement(&mut self) {</pre></td></tr><tr><td class='line-number'><a name='L1596' href='#L1596'><pre>1596</pre></a></td><td class='covered-line'><pre>2.92k</pre></td><td class='code'><pre> let token = if self.at_token(Token::Whitespace) {</pre></td></tr><tr><td class='line-number'><a name='L1597' href='#L1597'><pre>1597</pre></a></td><td class='covered-line'><pre>2.19k</pre></td><td class='code'><pre> self.peek_next_keyword()</pre></td></tr><tr><td class='line-number'><a name='L1598' href='#L1598'><pre>1598</pre></a></td><td class='skipped-line'></td><td class='code'><pre> } else {</pre></td></tr><tr><td class='line-number'><a name='L1599' href='#L1599'><pre>1599</pre></a></td><td class='covered-line'><pre>734</pre></td><td class='code'><pre> self.current_token().copied()</pre></td></tr><tr><td class='line-number'><a name='L1600' href='#L1600'><pre>1600</pre></a></td><td class='skipped-line'></td><td class='code'><pre> };</pre></td></tr><tr><td class='line-number'><a name='L1601' href='#L1601'><pre>1601</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L1602' href='#L1602'><pre>1602</pre></a></td><td class='covered-line'><pre>2.92k</pre></td><td class='code'><pre> match token {</pre></td></tr><tr><td class='line-number'><a name='L1603' href='#L1603'><pre>1603</pre></a></td><td class='covered-line'><pre>1.36k</pre></td><td class='code'><pre> Some(Token::IfKeyword) => {</pre></td></tr><tr><td class='line-number'><a name='L1604' href='#L1604'><pre>1604</pre></a></td><td class='covered-line'><pre>1.36k</pre></td><td class='code'><pre> self.parse_if_statement();</pre></td></tr><tr><td class='line-number'><a name='L1605' href='#L1605'><pre>1605</pre></a></td><td class='covered-line'><pre>1.36k</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L1606' href='#L1606'><pre>1606</pre></a></td><td class='covered-line'><pre>200</pre></td><td class='code'><pre> Some(Token::SelectKeyword) => {</pre></td></tr><tr><td class='line-number'><a name='L1607' href='#L1607'><pre>1607</pre></a></td><td class='covered-line'><pre>200</pre></td><td class='code'><pre> self.parse_select_case_statement();</pre></td></tr><tr><td class='line-number'><a name='L1608' href='#L1608'><pre>1608</pre></a></td><td class='covered-line'><pre>200</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L1609' href='#L1609'><pre>1609</pre></a></td><td class='skipped-line'></td><td class='code'><pre> Some(Token::ForKeyword) => {</pre></td></tr><tr><td class='line-number'><a name='L1610' href='#L1610'><pre>1610</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Peek ahead to see if next keyword is "Each"</pre></td></tr><tr><td class='line-number'><a name='L1611' href='#L1611'><pre>1611</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Need to peek TWO keywords ahead if we're currently at whitespace</pre></td></tr><tr><td class='line-number'><a name='L1612' href='#L1612'><pre>1612</pre></a></td><td class='covered-line'><pre>467</pre></td><td class='code'><pre> let next_kw = if self.at_token(Token::Whitespace) {</pre></td></tr><tr><td class='line-number'><a name='L1613' href='#L1613'><pre>1613</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // We peeked to find "For", now peek one more for "Each"</pre></td></tr><tr><td class='line-number'><a name='L1614' href='#L1614'><pre>1614</pre></a></td><td class='covered-line'><pre>377</pre></td><td class='code'><pre> self.peek_next_count_keywords(NonZeroUsize::new(2).unwrap())</pre></td></tr><tr><td class='line-number'><a name='L1615' href='#L1615'><pre>1615</pre></a></td><td class='covered-line'><pre>377</pre></td><td class='code'><pre> .nth(1)</pre></td></tr><tr><td class='line-number'><a name='L1616' href='#L1616'><pre>1616</pre></a></td><td class='skipped-line'></td><td class='code'><pre> } else {</pre></td></tr><tr><td class='line-number'><a name='L1617' href='#L1617'><pre>1617</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // We're directly at "For", peek once for "Each"</pre></td></tr><tr><td class='line-number'><a name='L1618' href='#L1618'><pre>1618</pre></a></td><td class='covered-line'><pre>90</pre></td><td class='code'><pre> self.peek_next_keyword()</pre></td></tr><tr><td class='line-number'><a name='L1619' href='#L1619'><pre>1619</pre></a></td><td class='skipped-line'></td><td class='code'><pre> };</pre></td></tr><tr><td class='line-number'><a name='L1620' href='#L1620'><pre>1620</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L1621' href='#L1621'><pre>1621</pre></a></td><td class='covered-line'><pre>467</pre></td><td class='code'><pre> if let Some(Token::EachKeyword) = next_kw {</pre></td></tr><tr><td class='line-number'><a name='L1622' href='#L1622'><pre>1622</pre></a></td><td class='covered-line'><pre>15</pre></td><td class='code'><pre> self.parse_for_each_statement();</pre></td></tr><tr><td class='line-number'><a name='L1623' href='#L1623'><pre>1623</pre></a></td><td class='covered-line'><pre>452</pre></td><td class='code'><pre> } else {</pre></td></tr><tr><td class='line-number'><a name='L1624' href='#L1624'><pre>1624</pre></a></td><td class='covered-line'><pre>452</pre></td><td class='code'><pre> self.parse_for_statement();</pre></td></tr><tr><td class='line-number'><a name='L1625' href='#L1625'><pre>1625</pre></a></td><td class='covered-line'><pre>452</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L1626' href='#L1626'><pre>1626</pre></a></td><td class='skipped-line'></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L1627' href='#L1627'><pre>1627</pre></a></td><td class='covered-line'><pre>242</pre></td><td class='code'><pre> Some(Token::DoKeyword) => {</pre></td></tr><tr><td class='line-number'><a name='L1628' href='#L1628'><pre>1628</pre></a></td><td class='covered-line'><pre>242</pre></td><td class='code'><pre> self.parse_do_statement();</pre></td></tr><tr><td class='line-number'><a name='L1629' href='#L1629'><pre>1629</pre></a></td><td class='covered-line'><pre>242</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L1630' href='#L1630'><pre>1630</pre></a></td><td class='covered-line'><pre>107</pre></td><td class='code'><pre> Some(Token::WhileKeyword) => {</pre></td></tr><tr><td class='line-number'><a name='L1631' href='#L1631'><pre>1631</pre></a></td><td class='covered-line'><pre>107</pre></td><td class='code'><pre> self.parse_while_statement();</pre></td></tr><tr><td class='line-number'><a name='L1632' href='#L1632'><pre>1632</pre></a></td><td class='covered-line'><pre>107</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L1633' href='#L1633'><pre>1633</pre></a></td><td class='covered-line'><pre>31</pre></td><td class='code'><pre> Some(Token::GotoKeyword) => {</pre></td></tr><tr><td class='line-number'><a name='L1634' href='#L1634'><pre>1634</pre></a></td><td class='covered-line'><pre>31</pre></td><td class='code'><pre> self.parse_goto_statement();</pre></td></tr><tr><td class='line-number'><a name='L1635' href='#L1635'><pre>1635</pre></a></td><td class='covered-line'><pre>31</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L1636' href='#L1636'><pre>1636</pre></a></td><td class='covered-line'><pre>28</pre></td><td class='code'><pre> Some(Token::GoSubKeyword) => {</pre></td></tr><tr><td class='line-number'><a name='L1637' href='#L1637'><pre>1637</pre></a></td><td class='covered-line'><pre>28</pre></td><td class='code'><pre> self.parse_gosub_statement();</pre></td></tr><tr><td class='line-number'><a name='L1638' href='#L1638'><pre>1638</pre></a></td><td class='covered-line'><pre>28</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L1639' href='#L1639'><pre>1639</pre></a></td><td class='covered-line'><pre>40</pre></td><td class='code'><pre> Some(Token::ReturnKeyword) => {</pre></td></tr><tr><td class='line-number'><a name='L1640' href='#L1640'><pre>1640</pre></a></td><td class='covered-line'><pre>40</pre></td><td class='code'><pre> self.parse_return_statement();</pre></td></tr><tr><td class='line-number'><a name='L1641' href='#L1641'><pre>1641</pre></a></td><td class='covered-line'><pre>40</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L1642' href='#L1642'><pre>1642</pre></a></td><td class='covered-line'><pre>38</pre></td><td class='code'><pre> Some(Token::ResumeKeyword) => {</pre></td></tr><tr><td class='line-number'><a name='L1643' href='#L1643'><pre>1643</pre></a></td><td class='covered-line'><pre>38</pre></td><td class='code'><pre> self.parse_resume_statement();</pre></td></tr><tr><td class='line-number'><a name='L1644' href='#L1644'><pre>1644</pre></a></td><td class='covered-line'><pre>38</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L1645' href='#L1645'><pre>1645</pre></a></td><td class='covered-line'><pre>176</pre></td><td class='code'><pre> Some(Token::ExitKeyword) => {</pre></td></tr><tr><td class='line-number'><a name='L1646' href='#L1646'><pre>1646</pre></a></td><td class='covered-line'><pre>176</pre></td><td class='code'><pre> self.parse_exit_statement();</pre></td></tr><tr><td class='line-number'><a name='L1647' href='#L1647'><pre>1647</pre></a></td><td class='covered-line'><pre>176</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L1648' href='#L1648'><pre>1648</pre></a></td><td class='skipped-line'></td><td class='code'><pre> Some(Token::OnKeyword) => {</pre></td></tr><tr><td class='line-number'><a name='L1649' href='#L1649'><pre>1649</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Look ahead to distinguish between On Error, On GoTo, and On GoSub</pre></td></tr><tr><td class='line-number'><a name='L1650' href='#L1650'><pre>1650</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Need to peek different amounts depending on whether we're at whitespace</pre></td></tr><tr><td class='line-number'><a name='L1651' href='#L1651'><pre>1651</pre></a></td><td class='covered-line'><pre>231</pre></td><td class='code'><pre> let next_kw = if self.at_token(Token::Whitespace) {</pre></td></tr><tr><td class='line-number'><a name='L1652' href='#L1652'><pre>1652</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // We peeked to find "On", now peek one more for "Error/GoTo/GoSub"</pre></td></tr><tr><td class='line-number'><a name='L1653' href='#L1653'><pre>1653</pre></a></td><td class='covered-line'><pre>157</pre></td><td class='code'><pre> self.peek_next_count_keywords(NonZeroUsize::new(2).unwrap())</pre></td></tr><tr><td class='line-number'><a name='L1654' href='#L1654'><pre>1654</pre></a></td><td class='covered-line'><pre>157</pre></td><td class='code'><pre> .nth(1)</pre></td></tr><tr><td class='line-number'><a name='L1655' href='#L1655'><pre>1655</pre></a></td><td class='skipped-line'></td><td class='code'><pre> } else {</pre></td></tr><tr><td class='line-number'><a name='L1656' href='#L1656'><pre>1656</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // We're directly at "On", peek once for next keyword</pre></td></tr><tr><td class='line-number'><a name='L1657' href='#L1657'><pre>1657</pre></a></td><td class='covered-line'><pre>74</pre></td><td class='code'><pre> self.peek_next_keyword()</pre></td></tr><tr><td class='line-number'><a name='L1658' href='#L1658'><pre>1658</pre></a></td><td class='skipped-line'></td><td class='code'><pre> };</pre></td></tr><tr><td class='line-number'><a name='L1659' href='#L1659'><pre>1659</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L1660' href='#L1660'><pre>1660</pre></a></td><td class='covered-line'><pre>231</pre></td><td class='code'><pre> if let Some(Token::ErrorKeyword) = next_kw {</pre></td></tr><tr><td class='line-number'><a name='L1661' href='#L1661'><pre>1661</pre></a></td><td class='covered-line'><pre>221</pre></td><td class='code'><pre> self.parse_on_error_statement();</pre></td></tr><tr><td class='line-number'><a name='L1662' href='#L1662'><pre>1662</pre></a></td><td class='covered-line'><pre>221</pre></td><td class='code'><pre> } else {</pre></td></tr><tr><td class='line-number'><a name='L1663' href='#L1663'><pre>1663</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Need to scan ahead to find GoTo or GoSub keyword</pre></td></tr><tr><td class='line-number'><a name='L1664' href='#L1664'><pre>1664</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // to distinguish between On GoTo and On GoSub</pre></td></tr><tr><td class='line-number'><a name='L1665' href='#L1665'><pre>1665</pre></a></td><td class='covered-line'><pre>10</pre></td><td class='code'><pre> let peek_start = if self.at_token(Token::Whitespace) {</pre></td></tr><tr><td class='line-number'><a name='L1666' href='#L1666'><pre>1666</pre></a></td><td class='covered-line'><pre>10</pre></td><td class='code'><pre> 2</pre></td></tr><tr><td class='line-number'><a name='L1667' href='#L1667'><pre>1667</pre></a></td><td class='skipped-line'></td><td class='code'><pre> } else {</pre></td></tr><tr><td class='line-number'><a name='L1668' href='#L1668'><pre>1668</pre></a></td><td class='uncovered-line'><pre>0</pre></td><td class='code'><pre> <span class='region red'>1</span></pre></td></tr><tr><td class='line-number'><a name='L1669' href='#L1669'><pre>1669</pre></a></td><td class='skipped-line'></td><td class='code'><pre> };</pre></td></tr><tr><td class='line-number'><a name='L1670' href='#L1670'><pre>1670</pre></a></td><td class='covered-line'><pre>10</pre></td><td class='code'><pre> let keywords: Vec<Token> = self</pre></td></tr><tr><td class='line-number'><a name='L1671' href='#L1671'><pre>1671</pre></a></td><td class='covered-line'><pre>10</pre></td><td class='code'><pre> .peek_next_count_keywords(NonZeroUsize::new(20).unwrap())</pre></td></tr><tr><td class='line-number'><a name='L1672' href='#L1672'><pre>1672</pre></a></td><td class='covered-line'><pre>10</pre></td><td class='code'><pre> .skip(peek_start)</pre></td></tr><tr><td class='line-number'><a name='L1673' href='#L1673'><pre>1673</pre></a></td><td class='covered-line'><pre>10</pre></td><td class='code'><pre> .collect();</pre></td></tr><tr><td class='line-number'><a name='L1674' href='#L1674'><pre>1674</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L1675' href='#L1675'><pre>1675</pre></a></td><td class='covered-line'><pre>10</pre></td><td class='code'><pre> let has_goto = keywords.contains(&Token::GotoKeyword);</pre></td></tr><tr><td class='line-number'><a name='L1676' href='#L1676'><pre>1676</pre></a></td><td class='covered-line'><pre>10</pre></td><td class='code'><pre> let has_gosub = keywords.contains(&Token::GoSubKeyword);</pre></td></tr><tr><td class='line-number'><a name='L1677' href='#L1677'><pre>1677</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L1678' href='#L1678'><pre>1678</pre></a></td><td class='covered-line'><pre>10</pre></td><td class='code'><pre> if has_goto {</pre></td></tr><tr><td class='line-number'><a name='L1679' href='#L1679'><pre>1679</pre></a></td><td class='covered-line'><pre>5</pre></td><td class='code'><pre> self.parse_on_goto_statement();</pre></td></tr><tr><td class='line-number'><a name='L1680' href='#L1680'><pre>1680</pre></a></td><td class='covered-line'><pre>5</pre></td><td class='code'><pre> } else if has_gosub {</pre></td></tr><tr><td class='line-number'><a name='L1681' href='#L1681'><pre>1681</pre></a></td><td class='covered-line'><pre>5</pre></td><td class='code'><pre> self.parse_on_gosub_statement();</pre></td></tr><tr><td class='line-number'><a name='L1682' href='#L1682'><pre>1682</pre></a></td><td class='covered-line'><pre>5</pre></td><td class='code'><pre> } else <span class='region red'>{</span></pre></td></tr><tr><td class='line-number'><a name='L1683' href='#L1683'><pre>1683</pre></a></td><td class='uncovered-line'><pre>0</pre></td><td class='code'><pre><span class='region red'> // Fallback - treat as On Error if we can't determine</span></pre></td></tr><tr><td class='line-number'><a name='L1684' href='#L1684'><pre>1684</pre></a></td><td class='uncovered-line'><pre>0</pre></td><td class='code'><pre><span class='region red'> self.parse_on_error_statement();</span></pre></td></tr><tr><td class='line-number'><a name='L1685' href='#L1685'><pre>1685</pre></a></td><td class='uncovered-line'><pre>0</pre></td><td class='code'><pre><span class='region red'> }</span></pre></td></tr><tr><td class='line-number'><a name='L1686' href='#L1686'><pre>1686</pre></a></td><td class='skipped-line'></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L1687' href='#L1687'><pre>1687</pre></a></td><td class='skipped-line'></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L1688' href='#L1688'><pre>1688</pre></a></td><td class='uncovered-line'><pre>0</pre></td><td class='code'><pre> _ => <span class='region red'>{}</span></pre></td></tr><tr><td class='line-number'><a name='L1689' href='#L1689'><pre>1689</pre></a></td><td class='skipped-line'></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L1690' href='#L1690'><pre>1690</pre></a></td><td class='covered-line'><pre>2.92k</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L1691' href='#L1691'><pre>1691</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L1692' href='#L1692'><pre>1692</pre></a></td><td class='skipped-line'></td><td class='code'><pre> /// Check if the current token is an array statement keyword.</pre></td></tr><tr><td class='line-number'><a name='L1693' href='#L1693'><pre>1693</pre></a></td><td class='skipped-line'></td><td class='code'><pre> /// Checks both current position and next non-whitespace token.</pre></td></tr><tr><td class='line-number'><a name='L1694' href='#L1694'><pre>1694</pre></a></td><td class='covered-line'><pre>31.2k</pre></td><td class='code'><pre> fn is_variable_declaration_keyword(&self) -> bool {</pre></td></tr><tr><td class='line-number'><a name='L1695' href='#L1695'><pre>1695</pre></a></td><td class='covered-line'><pre>31.2k</pre></td><td class='code'><pre> let token = if self.at_token(Token::Whitespace) {</pre></td></tr><tr><td class='line-number'><a name='L1696' href='#L1696'><pre>1696</pre></a></td><td class='covered-line'><pre>13.9k</pre></td><td class='code'><pre> self.peek_next_keyword()</pre></td></tr><tr><td class='line-number'><a name='L1697' href='#L1697'><pre>1697</pre></a></td><td class='skipped-line'></td><td class='code'><pre> } else {</pre></td></tr><tr><td class='line-number'><a name='L1698' href='#L1698'><pre>1698</pre></a></td><td class='covered-line'><pre>17.2k</pre></td><td class='code'><pre> self.current_token().copied()</pre></td></tr><tr><td class='line-number'><a name='L1699' href='#L1699'><pre>1699</pre></a></td><td class='skipped-line'></td><td class='code'><pre> };</pre></td></tr><tr><td class='line-number'><a name='L1700' href='#L1700'><pre>1700</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L1701' href='#L1701'><pre>1701</pre></a></td><td class='covered-line'><pre>31.2k</pre></td><td class='code'><pre> <div class='tooltip'>matches!<span class='tooltip-content'>31.1k</span></div>(token, Some(Token::ReDimKeyword | Token::EraseKeyword))</pre></td></tr><tr><td class='line-number'><a name='L1702' href='#L1702'><pre>1702</pre></a></td><td class='covered-line'><pre>31.2k</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L1703' href='#L1703'><pre>1703</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L1704' href='#L1704'><pre>1704</pre></a></td><td class='skipped-line'></td><td class='code'><pre> /// Check if we're at an Object statement with proper format.</pre></td></tr><tr><td class='line-number'><a name='L1705' href='#L1705'><pre>1705</pre></a></td><td class='skipped-line'></td><td class='code'><pre> ///</pre></td></tr><tr><td class='line-number'><a name='L1706' href='#L1706'><pre>1706</pre></a></td><td class='skipped-line'></td><td class='code'><pre> /// Object statements in VB6 forms have the format:</pre></td></tr><tr><td class='line-number'><a name='L1707' href='#L1707'><pre>1707</pre></a></td><td class='skipped-line'></td><td class='code'><pre> /// `Object = "{GUID}#version#flags"; "filename"`</pre></td></tr><tr><td class='line-number'><a name='L1708' href='#L1708'><pre>1708</pre></a></td><td class='skipped-line'></td><td class='code'><pre> /// or</pre></td></tr><tr><td class='line-number'><a name='L1709' href='#L1709'><pre>1709</pre></a></td><td class='skipped-line'></td><td class='code'><pre> /// `Object = *\G{GUID}#version#flags; "filename"`</pre></td></tr><tr><td class='line-number'><a name='L1710' href='#L1710'><pre>1710</pre></a></td><td class='skipped-line'></td><td class='code'><pre> ///</pre></td></tr><tr><td class='line-number'><a name='L1711' href='#L1711'><pre>1711</pre></a></td><td class='skipped-line'></td><td class='code'><pre> /// This checks if the pattern matches before committing to parse as `ObjectStatement`.</pre></td></tr><tr><td class='line-number'><a name='L1712' href='#L1712'><pre>1712</pre></a></td><td class='skipped-line'></td><td class='code'><pre> #[allow(clippy::needless_continue)] // continue on whitespace is needed but clippy is incorrectly catching here.</pre></td></tr><tr><td class='line-number'><a name='L1713' href='#L1713'><pre>1713</pre></a></td><td class='covered-line'><pre>7</pre></td><td class='code'><pre> fn is_object_statement(&self) -> bool {</pre></td></tr><tr><td class='line-number'><a name='L1714' href='#L1714'><pre>1714</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Must start with Object keyword</pre></td></tr><tr><td class='line-number'><a name='L1715' href='#L1715'><pre>1715</pre></a></td><td class='covered-line'><pre>7</pre></td><td class='code'><pre> if !self.at_token(Token::ObjectKeyword) {</pre></td></tr><tr><td class='line-number'><a name='L1716' href='#L1716'><pre>1716</pre></a></td><td class='uncovered-line'><pre>0</pre></td><td class='code'><pre> return <span class='region red'>false</span>;</pre></td></tr><tr><td class='line-number'><a name='L1717' href='#L1717'><pre>1717</pre></a></td><td class='covered-line'><pre>7</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L1718' href='#L1718'><pre>1718</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L1719' href='#L1719'><pre>1719</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Look ahead to verify it matches Object statement pattern</pre></td></tr><tr><td class='line-number'><a name='L1720' href='#L1720'><pre>1720</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Skip whitespace, should find =, then whitespace, then string or *\G pattern</pre></td></tr><tr><td class='line-number'><a name='L1721' href='#L1721'><pre>1721</pre></a></td><td class='covered-line'><pre>7</pre></td><td class='code'><pre> let mut found_equals = false;</pre></td></tr><tr><td class='line-number'><a name='L1722' href='#L1722'><pre>1722</pre></a></td><td class='covered-line'><pre>28</pre></td><td class='code'><pre> for (_text, token) in <div class='tooltip'>self.tokens.iter()<span class='tooltip-content'>7</span></div>.<div class='tooltip'>skip<span class='tooltip-content'>7</span></div>(<div class='tooltip'>self.pos + 1<span class='tooltip-content'>7</span></div>) {</pre></td></tr><tr><td class='line-number'><a name='L1723' href='#L1723'><pre>1723</pre></a></td><td class='uncovered-line'><pre>0</pre></td><td class='code'><pre> match <span class='region red'>token</span> {</pre></td></tr><tr><td class='line-number'><a name='L1724' href='#L1724'><pre>1724</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // TODO: Change this parsing to better handle leading whitespace on object statements.</pre></td></tr><tr><td class='line-number'><a name='L1725' href='#L1725'><pre>1725</pre></a></td><td class='covered-line'><pre>14</pre></td><td class='code'><pre> Token::Whitespace => continue,</pre></td></tr><tr><td class='line-number'><a name='L1726' href='#L1726'><pre>1726</pre></a></td><td class='covered-line'><pre>7</pre></td><td class='code'><pre> Token::EqualityOperator if !found_equals => {</pre></td></tr><tr><td class='line-number'><a name='L1727' href='#L1727'><pre>1727</pre></a></td><td class='covered-line'><pre>7</pre></td><td class='code'><pre> found_equals = true;</pre></td></tr><tr><td class='line-number'><a name='L1728' href='#L1728'><pre>1728</pre></a></td><td class='covered-line'><pre>7</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L1729' href='#L1729'><pre>1729</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // After =, we expect either a quoted string starting with { or * for type library refs</pre></td></tr><tr><td class='line-number'><a name='L1730' href='#L1730'><pre>1730</pre></a></td><td class='covered-line'><pre>5</pre></td><td class='code'><pre> Token::StringLiteral | Token::MultiplicationOperator if found_equals => {</pre></td></tr><tr><td class='line-number'><a name='L1731' href='#L1731'><pre>1731</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Valid Object statement - string literal after =</pre></td></tr><tr><td class='line-number'><a name='L1732' href='#L1732'><pre>1732</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // or</pre></td></tr><tr><td class='line-number'><a name='L1733' href='#L1733'><pre>1733</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Could be *\G{ pattern for type libraries</pre></td></tr><tr><td class='line-number'><a name='L1734' href='#L1734'><pre>1734</pre></a></td><td class='covered-line'><pre>6</pre></td><td class='code'><pre> return true;</pre></td></tr><tr><td class='line-number'><a name='L1735' href='#L1735'><pre>1735</pre></a></td><td class='skipped-line'></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L1736' href='#L1736'><pre>1736</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // If we hit anything else after =, not an Object statement</pre></td></tr><tr><td class='line-number'><a name='L1737' href='#L1737'><pre>1737</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> _ if found_equals => return false,</pre></td></tr><tr><td class='line-number'><a name='L1738' href='#L1738'><pre>1738</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // If we hit a newline before =, not an Object statement</pre></td></tr><tr><td class='line-number'><a name='L1739' href='#L1739'><pre>1739</pre></a></td><td class='skipped-line'></td><td class='code'><pre> Token::Newline | Token::EndOfLineComment | Token::RemComment => {</pre></td></tr><tr><td class='line-number'><a name='L1740' href='#L1740'><pre>1740</pre></a></td><td class='uncovered-line'><pre>0</pre></td><td class='code'><pre> return <span class='region red'>false</span>;</pre></td></tr><tr><td class='line-number'><a name='L1741' href='#L1741'><pre>1741</pre></a></td><td class='skipped-line'></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L1742' href='#L1742'><pre>1742</pre></a></td><td class='uncovered-line'><pre>0</pre></td><td class='code'><pre> _ => return <span class='region red'>false</span>,</pre></td></tr><tr><td class='line-number'><a name='L1743' href='#L1743'><pre>1743</pre></a></td><td class='skipped-line'></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L1744' href='#L1744'><pre>1744</pre></a></td><td class='skipped-line'></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L1745' href='#L1745'><pre>1745</pre></a></td><td class='uncovered-line'><pre>0</pre></td><td class='code'><pre> <span class='region red'>false</span></pre></td></tr><tr><td class='line-number'><a name='L1746' href='#L1746'><pre>1746</pre></a></td><td class='covered-line'><pre>7</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L1747' href='#L1747'><pre>1747</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L1748' href='#L1748'><pre>1748</pre></a></td><td class='skipped-line'></td><td class='code'><pre> /// Dispatch array statement parsing to the appropriate parser.</pre></td></tr><tr><td class='line-number'><a name='L1749' href='#L1749'><pre>1749</pre></a></td><td class='covered-line'><pre>87</pre></td><td class='code'><pre> fn parse_array_statement(&mut self) {</pre></td></tr><tr><td class='line-number'><a name='L1750' href='#L1750'><pre>1750</pre></a></td><td class='covered-line'><pre>87</pre></td><td class='code'><pre> let token = if self.at_token(Token::Whitespace) {</pre></td></tr><tr><td class='line-number'><a name='L1751' href='#L1751'><pre>1751</pre></a></td><td class='covered-line'><pre>78</pre></td><td class='code'><pre> self.peek_next_keyword()</pre></td></tr><tr><td class='line-number'><a name='L1752' href='#L1752'><pre>1752</pre></a></td><td class='skipped-line'></td><td class='code'><pre> } else {</pre></td></tr><tr><td class='line-number'><a name='L1753' href='#L1753'><pre>1753</pre></a></td><td class='covered-line'><pre>9</pre></td><td class='code'><pre> self.current_token().copied()</pre></td></tr><tr><td class='line-number'><a name='L1754' href='#L1754'><pre>1754</pre></a></td><td class='skipped-line'></td><td class='code'><pre> };</pre></td></tr><tr><td class='line-number'><a name='L1755' href='#L1755'><pre>1755</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L1756' href='#L1756'><pre>1756</pre></a></td><td class='covered-line'><pre>87</pre></td><td class='code'><pre> match token {</pre></td></tr><tr><td class='line-number'><a name='L1757' href='#L1757'><pre>1757</pre></a></td><td class='covered-line'><pre>71</pre></td><td class='code'><pre> Some(Token::ReDimKeyword) => {</pre></td></tr><tr><td class='line-number'><a name='L1758' href='#L1758'><pre>1758</pre></a></td><td class='covered-line'><pre>71</pre></td><td class='code'><pre> self.parse_redim_statement();</pre></td></tr><tr><td class='line-number'><a name='L1759' href='#L1759'><pre>1759</pre></a></td><td class='covered-line'><pre>71</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L1760' href='#L1760'><pre>1760</pre></a></td><td class='covered-line'><pre>16</pre></td><td class='code'><pre> Some(Token::EraseKeyword) => {</pre></td></tr><tr><td class='line-number'><a name='L1761' href='#L1761'><pre>1761</pre></a></td><td class='covered-line'><pre>16</pre></td><td class='code'><pre> self.parse_erase_statement();</pre></td></tr><tr><td class='line-number'><a name='L1762' href='#L1762'><pre>1762</pre></a></td><td class='covered-line'><pre>16</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L1763' href='#L1763'><pre>1763</pre></a></td><td class='uncovered-line'><pre>0</pre></td><td class='code'><pre> _ => <span class='region red'>{}</span></pre></td></tr><tr><td class='line-number'><a name='L1764' href='#L1764'><pre>1764</pre></a></td><td class='skipped-line'></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L1765' href='#L1765'><pre>1765</pre></a></td><td class='covered-line'><pre>87</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L1766' href='#L1766'><pre>1766</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L1767' href='#L1767'><pre>1767</pre></a></td><td class='skipped-line'></td><td class='code'><pre> /// Parse a statement list, consuming tokens until a termination condition is met.</pre></td></tr><tr><td class='line-number'><a name='L1768' href='#L1768'><pre>1768</pre></a></td><td class='skipped-line'></td><td class='code'><pre> ///</pre></td></tr><tr><td class='line-number'><a name='L1769' href='#L1769'><pre>1769</pre></a></td><td class='skipped-line'></td><td class='code'><pre> /// This is a generic statement list parser that can handle different termination conditions:</pre></td></tr><tr><td class='line-number'><a name='L1770' href='#L1770'><pre>1770</pre></a></td><td class='skipped-line'></td><td class='code'><pre> /// - End Sub, End Function, End If, etc.</pre></td></tr><tr><td class='line-number'><a name='L1771' href='#L1771'><pre>1771</pre></a></td><td class='skipped-line'></td><td class='code'><pre> /// - `ElseIf` or Else (for If statements)</pre></td></tr><tr><td class='line-number'><a name='L1772' href='#L1772'><pre>1772</pre></a></td><td class='skipped-line'></td><td class='code'><pre> ///</pre></td></tr><tr><td class='line-number'><a name='L1773' href='#L1773'><pre>1773</pre></a></td><td class='skipped-line'></td><td class='code'><pre> /// # Arguments</pre></td></tr><tr><td class='line-number'><a name='L1774' href='#L1774'><pre>1774</pre></a></td><td class='skipped-line'></td><td class='code'><pre> /// * `stop_conditions` - A closure that returns true when the block should stop parsing</pre></td></tr><tr><td class='line-number'><a name='L1775' href='#L1775'><pre>1775</pre></a></td><td class='covered-line'><pre>6.13k</pre></td><td class='code'><pre> pub(crate) fn parse_statement_list<F>(&mut self, stop_conditions: F)</pre></td></tr><tr><td class='line-number'><a name='L1776' href='#L1776'><pre>1776</pre></a></td><td class='covered-line'><pre>6.13k</pre></td><td class='code'><pre> where</pre></td></tr><tr><td class='line-number'><a name='L1777' href='#L1777'><pre>1777</pre></a></td><td class='covered-line'><pre>6.13k</pre></td><td class='code'><pre> F: Fn(&Parser) -> bool,</pre></td></tr><tr><td class='line-number'><a name='L1778' href='#L1778'><pre>1778</pre></a></td><td class='skipped-line'></td><td class='code'><pre> {</pre></td></tr><tr><td class='line-number'><a name='L1779' href='#L1779'><pre>1779</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Statement lists can appear in both header and body, so we do not modify parsing_header here.</pre></td></tr><tr><td class='line-number'><a name='L1780' href='#L1780'><pre>1780</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L1781' href='#L1781'><pre>1781</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Start a StatementList node</pre></td></tr><tr><td class='line-number'><a name='L1782' href='#L1782'><pre>1782</pre></a></td><td class='covered-line'><pre>6.13k</pre></td><td class='code'><pre> self.builder.start_node(SyntaxKind::StatementList.to_raw());</pre></td></tr><tr><td class='line-number'><a name='L1783' href='#L1783'><pre>1783</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L1784' href='#L1784'><pre>1784</pre></a></td><td class='covered-line'><pre>36.4k</pre></td><td class='code'><pre> while !self.is_at_end() {</pre></td></tr><tr><td class='line-number'><a name='L1785' href='#L1785'><pre>1785</pre></a></td><td class='covered-line'><pre>36.2k</pre></td><td class='code'><pre> if stop_conditions(self) {</pre></td></tr><tr><td class='line-number'><a name='L1786' href='#L1786'><pre>1786</pre></a></td><td class='covered-line'><pre>5.92k</pre></td><td class='code'><pre> break;</pre></td></tr><tr><td class='line-number'><a name='L1787' href='#L1787'><pre>1787</pre></a></td><td class='covered-line'><pre>30.3k</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L1788' href='#L1788'><pre>1788</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L1789' href='#L1789'><pre>1789</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Try control flow statements first</pre></td></tr><tr><td class='line-number'><a name='L1790' href='#L1790'><pre>1790</pre></a></td><td class='covered-line'><pre>30.3k</pre></td><td class='code'><pre> if self.is_control_flow_keyword() {</pre></td></tr><tr><td class='line-number'><a name='L1791' href='#L1791'><pre>1791</pre></a></td><td class='covered-line'><pre>2.07k</pre></td><td class='code'><pre> self.parse_control_flow_statement();</pre></td></tr><tr><td class='line-number'><a name='L1792' href='#L1792'><pre>1792</pre></a></td><td class='covered-line'><pre>2.07k</pre></td><td class='code'><pre> continue;</pre></td></tr><tr><td class='line-number'><a name='L1793' href='#L1793'><pre>1793</pre></a></td><td class='covered-line'><pre>28.2k</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L1794' href='#L1794'><pre>1794</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L1795' href='#L1795'><pre>1795</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Try built-in library statements</pre></td></tr><tr><td class='line-number'><a name='L1796' href='#L1796'><pre>1796</pre></a></td><td class='covered-line'><pre>28.2k</pre></td><td class='code'><pre> if self.is_library_statement_keyword() {</pre></td></tr><tr><td class='line-number'><a name='L1797' href='#L1797'><pre>1797</pre></a></td><td class='covered-line'><pre>961</pre></td><td class='code'><pre> self.parse_library_statement();</pre></td></tr><tr><td class='line-number'><a name='L1798' href='#L1798'><pre>1798</pre></a></td><td class='covered-line'><pre>961</pre></td><td class='code'><pre> continue;</pre></td></tr><tr><td class='line-number'><a name='L1799' href='#L1799'><pre>1799</pre></a></td><td class='covered-line'><pre>27.2k</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L1800' href='#L1800'><pre>1800</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L1801' href='#L1801'><pre>1801</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Try array statements</pre></td></tr><tr><td class='line-number'><a name='L1802' href='#L1802'><pre>1802</pre></a></td><td class='covered-line'><pre>27.2k</pre></td><td class='code'><pre> if self.is_variable_declaration_keyword() {</pre></td></tr><tr><td class='line-number'><a name='L1803' href='#L1803'><pre>1803</pre></a></td><td class='covered-line'><pre>78</pre></td><td class='code'><pre> self.parse_array_statement();</pre></td></tr><tr><td class='line-number'><a name='L1804' href='#L1804'><pre>1804</pre></a></td><td class='covered-line'><pre>78</pre></td><td class='code'><pre> continue;</pre></td></tr><tr><td class='line-number'><a name='L1805' href='#L1805'><pre>1805</pre></a></td><td class='covered-line'><pre>27.2k</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L1806' href='#L1806'><pre>1806</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L1807' href='#L1807'><pre>1807</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Try to parse a statement using the centralized dispatcher</pre></td></tr><tr><td class='line-number'><a name='L1808' href='#L1808'><pre>1808</pre></a></td><td class='covered-line'><pre>27.2k</pre></td><td class='code'><pre> if self.is_statement_keyword() {</pre></td></tr><tr><td class='line-number'><a name='L1809' href='#L1809'><pre>1809</pre></a></td><td class='covered-line'><pre>258</pre></td><td class='code'><pre> self.parse_statement();</pre></td></tr><tr><td class='line-number'><a name='L1810' href='#L1810'><pre>1810</pre></a></td><td class='covered-line'><pre>258</pre></td><td class='code'><pre> continue;</pre></td></tr><tr><td class='line-number'><a name='L1811' href='#L1811'><pre>1811</pre></a></td><td class='covered-line'><pre>26.9k</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L1812' href='#L1812'><pre>1812</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L1813' href='#L1813'><pre>1813</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Handle other constructs that aren't in parse_statement</pre></td></tr><tr><td class='line-number'><a name='L1814' href='#L1814'><pre>1814</pre></a></td><td class='covered-line'><pre>26.9k</pre></td><td class='code'><pre> match self.current_token() {</pre></td></tr><tr><td class='line-number'><a name='L1815' href='#L1815'><pre>1815</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Whitespace, newlines, and comments - consume directly FIRST</pre></td></tr><tr><td class='line-number'><a name='L1816' href='#L1816'><pre>1816</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // This must be checked before is_at_procedure_call to avoid</pre></td></tr><tr><td class='line-number'><a name='L1817' href='#L1817'><pre>1817</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // treating REM comments as procedure calls</pre></td></tr><tr><td class='line-number'><a name='L1818' href='#L1818'><pre>1818</pre></a></td><td class='skipped-line'></td><td class='code'><pre> Some(</pre></td></tr><tr><td class='line-number'><a name='L1819' href='#L1819'><pre>1819</pre></a></td><td class='skipped-line'></td><td class='code'><pre> Token::Whitespace</pre></td></tr><tr><td class='line-number'><a name='L1820' href='#L1820'><pre>1820</pre></a></td><td class='skipped-line'></td><td class='code'><pre> | Token::Newline</pre></td></tr><tr><td class='line-number'><a name='L1821' href='#L1821'><pre>1821</pre></a></td><td class='skipped-line'></td><td class='code'><pre> | Token::EndOfLineComment</pre></td></tr><tr><td class='line-number'><a name='L1822' href='#L1822'><pre>1822</pre></a></td><td class='skipped-line'></td><td class='code'><pre> | Token::RemComment,</pre></td></tr><tr><td class='line-number'><a name='L1823' href='#L1823'><pre>1823</pre></a></td><td class='covered-line'><pre>17.8k</pre></td><td class='code'><pre> ) => {</pre></td></tr><tr><td class='line-number'><a name='L1824' href='#L1824'><pre>1824</pre></a></td><td class='covered-line'><pre>17.8k</pre></td><td class='code'><pre> self.consume_token();</pre></td></tr><tr><td class='line-number'><a name='L1825' href='#L1825'><pre>1825</pre></a></td><td class='covered-line'><pre>17.8k</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L1826' href='#L1826'><pre>1826</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Variable declarations: Dim/Private/Public/Const/Static</pre></td></tr><tr><td class='line-number'><a name='L1827' href='#L1827'><pre>1827</pre></a></td><td class='skipped-line'></td><td class='code'><pre> Some(</pre></td></tr><tr><td class='line-number'><a name='L1828' href='#L1828'><pre>1828</pre></a></td><td class='skipped-line'></td><td class='code'><pre> Token::DimKeyword</pre></td></tr><tr><td class='line-number'><a name='L1829' href='#L1829'><pre>1829</pre></a></td><td class='skipped-line'></td><td class='code'><pre> | Token::PrivateKeyword</pre></td></tr><tr><td class='line-number'><a name='L1830' href='#L1830'><pre>1830</pre></a></td><td class='skipped-line'></td><td class='code'><pre> | Token::PublicKeyword</pre></td></tr><tr><td class='line-number'><a name='L1831' href='#L1831'><pre>1831</pre></a></td><td class='skipped-line'></td><td class='code'><pre> | Token::ConstKeyword</pre></td></tr><tr><td class='line-number'><a name='L1832' href='#L1832'><pre>1832</pre></a></td><td class='skipped-line'></td><td class='code'><pre> | Token::StaticKeyword,</pre></td></tr><tr><td class='line-number'><a name='L1833' href='#L1833'><pre>1833</pre></a></td><td class='covered-line'><pre>1.45k</pre></td><td class='code'><pre> ) => {</pre></td></tr><tr><td class='line-number'><a name='L1834' href='#L1834'><pre>1834</pre></a></td><td class='covered-line'><pre>1.45k</pre></td><td class='code'><pre> self.parse_dim();</pre></td></tr><tr><td class='line-number'><a name='L1835' href='#L1835'><pre>1835</pre></a></td><td class='covered-line'><pre>1.45k</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L1836' href='#L1836'><pre>1836</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Anything else - check if it's a label, assignment, procedure call, or unknown</pre></td></tr><tr><td class='line-number'><a name='L1837' href='#L1837'><pre>1837</pre></a></td><td class='skipped-line'></td><td class='code'><pre> _ => {</pre></td></tr><tr><td class='line-number'><a name='L1838' href='#L1838'><pre>1838</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Check if this is a label (identifier followed by colon)</pre></td></tr><tr><td class='line-number'><a name='L1839' href='#L1839'><pre>1839</pre></a></td><td class='covered-line'><pre>7.61k</pre></td><td class='code'><pre> if self.is_at_label() {</pre></td></tr><tr><td class='line-number'><a name='L1840' href='#L1840'><pre>1840</pre></a></td><td class='covered-line'><pre>144</pre></td><td class='code'><pre> self.parse_label_statement();</pre></td></tr><tr><td class='line-number'><a name='L1841' href='#L1841'><pre>1841</pre></a></td><td class='covered-line'><pre>144</pre></td><td class='code'><pre> // Check for Let statement (optional assignment keyword)</pre></td></tr><tr><td class='line-number'><a name='L1842' href='#L1842'><pre>1842</pre></a></td><td class='covered-line'><pre>7.46k</pre></td><td class='code'><pre> } else if self.at_token(Token::LetKeyword)</pre></td></tr><tr><td class='line-number'><a name='L1843' href='#L1843'><pre>1843</pre></a></td><td class='covered-line'><pre>7.45k</pre></td><td class='code'><pre> || (self.at_token(Token::Whitespace)</pre></td></tr><tr><td class='line-number'><a name='L1844' href='#L1844'><pre>1844</pre></a></td><td class='uncovered-line'><pre>0</pre></td><td class='code'><pre> && <span class='region red'>self.peek_next_keyword() == Some(Token::LetKeyword)</span>)</pre></td></tr><tr><td class='line-number'><a name='L1845' href='#L1845'><pre>1845</pre></a></td><td class='covered-line'><pre>12</pre></td><td class='code'><pre> {</pre></td></tr><tr><td class='line-number'><a name='L1846' href='#L1846'><pre>1846</pre></a></td><td class='covered-line'><pre>12</pre></td><td class='code'><pre> self.parse_let_statement();</pre></td></tr><tr><td class='line-number'><a name='L1847' href='#L1847'><pre>1847</pre></a></td><td class='covered-line'><pre>12</pre></td><td class='code'><pre> // Check if this looks like an assignment statement (identifier = expression)</pre></td></tr><tr><td class='line-number'><a name='L1848' href='#L1848'><pre>1848</pre></a></td><td class='covered-line'><pre>7.45k</pre></td><td class='code'><pre> } else if self.is_at_assignment() {</pre></td></tr><tr><td class='line-number'><a name='L1849' href='#L1849'><pre>1849</pre></a></td><td class='covered-line'><pre>4.75k</pre></td><td class='code'><pre> self.parse_assignment_statement();</pre></td></tr><tr><td class='line-number'><a name='L1850' href='#L1850'><pre>1850</pre></a></td><td class='covered-line'><pre>4.75k</pre></td><td class='code'><pre> // Check if this looks like a procedure call (identifier without assignment)</pre></td></tr><tr><td class='line-number'><a name='L1851' href='#L1851'><pre>1851</pre></a></td><td class='covered-line'><pre>4.75k</pre></td><td class='code'><pre> } else if <div class='tooltip'>self<span class='tooltip-content'>2.70k</span></div>.<div class='tooltip'>is_at_procedure_call<span class='tooltip-content'>2.70k</span></div>() {</pre></td></tr><tr><td class='line-number'><a name='L1852' href='#L1852'><pre>1852</pre></a></td><td class='covered-line'><pre>1.79k</pre></td><td class='code'><pre> self.parse_procedure_call();</pre></td></tr><tr><td class='line-number'><a name='L1853' href='#L1853'><pre>1853</pre></a></td><td class='covered-line'><pre>1.79k</pre></td><td class='code'><pre> } else {</pre></td></tr><tr><td class='line-number'><a name='L1854' href='#L1854'><pre>1854</pre></a></td><td class='covered-line'><pre>915</pre></td><td class='code'><pre> self.consume_token_as_unknown();</pre></td></tr><tr><td class='line-number'><a name='L1855' href='#L1855'><pre>1855</pre></a></td><td class='covered-line'><pre>915</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L1856' href='#L1856'><pre>1856</pre></a></td><td class='skipped-line'></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L1857' href='#L1857'><pre>1857</pre></a></td><td class='skipped-line'></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L1858' href='#L1858'><pre>1858</pre></a></td><td class='skipped-line'></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L1859' href='#L1859'><pre>1859</pre></a></td><td class='covered-line'><pre>6.13k</pre></td><td class='code'><pre> self.builder.finish_node(); // StatementList</pre></td></tr><tr><td class='line-number'><a name='L1860' href='#L1860'><pre>1860</pre></a></td><td class='covered-line'><pre>6.13k</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L1861' href='#L1861'><pre>1861</pre></a></td><td class='skipped-line'></td><td class='code'><pre>}</pre></td></tr><tr><td class='line-number'><a name='L1862' href='#L1862'><pre>1862</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L1863' href='#L1863'><pre>1863</pre></a></td><td class='skipped-line'></td><td class='code'><pre>#[cfg(test)]</pre></td></tr><tr><td class='line-number'><a name='L1864' href='#L1864'><pre>1864</pre></a></td><td class='skipped-line'></td><td class='code'><pre>mod tests {</pre></td></tr><tr><td class='line-number'><a name='L1865' href='#L1865'><pre>1865</pre></a></td><td class='skipped-line'></td><td class='code'><pre> use super::Parser;</pre></td></tr><tr><td class='line-number'><a name='L1866' href='#L1866'><pre>1866</pre></a></td><td class='skipped-line'></td><td class='code'><pre> use crate::*;</pre></td></tr><tr><td class='line-number'><a name='L1867' href='#L1867'><pre>1867</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L1868' href='#L1868'><pre>1868</pre></a></td><td class='skipped-line'></td><td class='code'><pre> #[test]</pre></td></tr><tr><td class='line-number'><a name='L1869' href='#L1869'><pre>1869</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> fn parse_single_quote_comment() {</pre></td></tr><tr><td class='line-number'><a name='L1870' href='#L1870'><pre>1870</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let code = "' This is a comment\nSub Main()\n";</pre></td></tr><tr><td class='line-number'><a name='L1871' href='#L1871'><pre>1871</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L1872' href='#L1872'><pre>1872</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let mut source_stream = SourceStream::new("test.bas", code);</pre></td></tr><tr><td class='line-number'><a name='L1873' href='#L1873'><pre>1873</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let result = tokenize(&mut source_stream);</pre></td></tr><tr><td class='line-number'><a name='L1874' href='#L1874'><pre>1874</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let (token_stream_opt, _failures) = result.unpack();</pre></td></tr><tr><td class='line-number'><a name='L1875' href='#L1875'><pre>1875</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L1876' href='#L1876'><pre>1876</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let token_stream = token_stream_opt.expect("Tokenization failed");</pre></td></tr><tr><td class='line-number'><a name='L1877' href='#L1877'><pre>1877</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let cst = parse(token_stream);</pre></td></tr><tr><td class='line-number'><a name='L1878' href='#L1878'><pre>1878</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L1879' href='#L1879'><pre>1879</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert_eq!(cst.root_kind(), SyntaxKind::Root);</pre></td></tr><tr><td class='line-number'><a name='L1880' href='#L1880'><pre>1880</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Should have 2 children: the comment and the SubStatement</pre></td></tr><tr><td class='line-number'><a name='L1881' href='#L1881'><pre>1881</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert_eq!(cst.child_count(), 3); // 2 statements + EOF</pre></td></tr><tr><td class='line-number'><a name='L1882' href='#L1882'><pre>1882</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert!(cst.text().contains("' This is a comment"));</pre></td></tr><tr><td class='line-number'><a name='L1883' href='#L1883'><pre>1883</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert!(cst.text().contains("Sub Main()"));</pre></td></tr><tr><td class='line-number'><a name='L1884' href='#L1884'><pre>1884</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L1885' href='#L1885'><pre>1885</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Use navigation methods</pre></td></tr><tr><td class='line-number'><a name='L1886' href='#L1886'><pre>1886</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert!(cst.contains_kind(SyntaxKind::EndOfLineComment));</pre></td></tr><tr><td class='line-number'><a name='L1887' href='#L1887'><pre>1887</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert!(cst.contains_kind(SyntaxKind::SubStatement));</pre></td></tr><tr><td class='line-number'><a name='L1888' href='#L1888'><pre>1888</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L1889' href='#L1889'><pre>1889</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let first = cst.first_child().unwrap();</pre></td></tr><tr><td class='line-number'><a name='L1890' href='#L1890'><pre>1890</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert_eq!(first.kind(), SyntaxKind::EndOfLineComment);</pre></td></tr><tr><td class='line-number'><a name='L1891' href='#L1891'><pre>1891</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert!(first.is_token());</pre></td></tr><tr><td class='line-number'><a name='L1892' href='#L1892'><pre>1892</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L1893' href='#L1893'><pre>1893</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L1894' href='#L1894'><pre>1894</pre></a></td><td class='skipped-line'></td><td class='code'><pre> #[test]</pre></td></tr><tr><td class='line-number'><a name='L1895' href='#L1895'><pre>1895</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> fn syntax_kind_conversions() {</pre></td></tr><tr><td class='line-number'><a name='L1896' href='#L1896'><pre>1896</pre></a></td><td class='skipped-line'></td><td class='code'><pre> use crate::language::Token;</pre></td></tr><tr><td class='line-number'><a name='L1897' href='#L1897'><pre>1897</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L1898' href='#L1898'><pre>1898</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Test keyword conversions</pre></td></tr><tr><td class='line-number'><a name='L1899' href='#L1899'><pre>1899</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert_eq!(</pre></td></tr><tr><td class='line-number'><a name='L1900' href='#L1900'><pre>1900</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> SyntaxKind::from(Token::FunctionKeyword),</pre></td></tr><tr><td class='line-number'><a name='L1901' href='#L1901'><pre>1901</pre></a></td><td class='skipped-line'></td><td class='code'><pre> SyntaxKind::FunctionKeyword</pre></td></tr><tr><td class='line-number'><a name='L1902' href='#L1902'><pre>1902</pre></a></td><td class='skipped-line'></td><td class='code'><pre> );</pre></td></tr><tr><td class='line-number'><a name='L1903' href='#L1903'><pre>1903</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert_eq!(SyntaxKind::from(Token::IfKeyword), SyntaxKind::IfKeyword);</pre></td></tr><tr><td class='line-number'><a name='L1904' href='#L1904'><pre>1904</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert_eq!(SyntaxKind::from(Token::ForKeyword), SyntaxKind::ForKeyword);</pre></td></tr><tr><td class='line-number'><a name='L1905' href='#L1905'><pre>1905</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L1906' href='#L1906'><pre>1906</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Test operators</pre></td></tr><tr><td class='line-number'><a name='L1907' href='#L1907'><pre>1907</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert_eq!(</pre></td></tr><tr><td class='line-number'><a name='L1908' href='#L1908'><pre>1908</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> SyntaxKind::from(Token::AdditionOperator),</pre></td></tr><tr><td class='line-number'><a name='L1909' href='#L1909'><pre>1909</pre></a></td><td class='skipped-line'></td><td class='code'><pre> SyntaxKind::AdditionOperator</pre></td></tr><tr><td class='line-number'><a name='L1910' href='#L1910'><pre>1910</pre></a></td><td class='skipped-line'></td><td class='code'><pre> );</pre></td></tr><tr><td class='line-number'><a name='L1911' href='#L1911'><pre>1911</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert_eq!(</pre></td></tr><tr><td class='line-number'><a name='L1912' href='#L1912'><pre>1912</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> SyntaxKind::from(Token::EqualityOperator),</pre></td></tr><tr><td class='line-number'><a name='L1913' href='#L1913'><pre>1913</pre></a></td><td class='skipped-line'></td><td class='code'><pre> SyntaxKind::EqualityOperator</pre></td></tr><tr><td class='line-number'><a name='L1914' href='#L1914'><pre>1914</pre></a></td><td class='skipped-line'></td><td class='code'><pre> );</pre></td></tr><tr><td class='line-number'><a name='L1915' href='#L1915'><pre>1915</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L1916' href='#L1916'><pre>1916</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Test literals</pre></td></tr><tr><td class='line-number'><a name='L1917' href='#L1917'><pre>1917</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert_eq!(</pre></td></tr><tr><td class='line-number'><a name='L1918' href='#L1918'><pre>1918</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> SyntaxKind::from(Token::StringLiteral),</pre></td></tr><tr><td class='line-number'><a name='L1919' href='#L1919'><pre>1919</pre></a></td><td class='skipped-line'></td><td class='code'><pre> SyntaxKind::StringLiteral</pre></td></tr><tr><td class='line-number'><a name='L1920' href='#L1920'><pre>1920</pre></a></td><td class='skipped-line'></td><td class='code'><pre> );</pre></td></tr><tr><td class='line-number'><a name='L1921' href='#L1921'><pre>1921</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert_eq!(</pre></td></tr><tr><td class='line-number'><a name='L1922' href='#L1922'><pre>1922</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> SyntaxKind::from(Token::IntegerLiteral),</pre></td></tr><tr><td class='line-number'><a name='L1923' href='#L1923'><pre>1923</pre></a></td><td class='skipped-line'></td><td class='code'><pre> SyntaxKind::IntegerLiteral</pre></td></tr><tr><td class='line-number'><a name='L1924' href='#L1924'><pre>1924</pre></a></td><td class='skipped-line'></td><td class='code'><pre> );</pre></td></tr><tr><td class='line-number'><a name='L1925' href='#L1925'><pre>1925</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert_eq!(</pre></td></tr><tr><td class='line-number'><a name='L1926' href='#L1926'><pre>1926</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> SyntaxKind::from(Token::LongLiteral),</pre></td></tr><tr><td class='line-number'><a name='L1927' href='#L1927'><pre>1927</pre></a></td><td class='skipped-line'></td><td class='code'><pre> SyntaxKind::LongLiteral</pre></td></tr><tr><td class='line-number'><a name='L1928' href='#L1928'><pre>1928</pre></a></td><td class='skipped-line'></td><td class='code'><pre> );</pre></td></tr><tr><td class='line-number'><a name='L1929' href='#L1929'><pre>1929</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert_eq!(</pre></td></tr><tr><td class='line-number'><a name='L1930' href='#L1930'><pre>1930</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> SyntaxKind::from(Token::SingleLiteral),</pre></td></tr><tr><td class='line-number'><a name='L1931' href='#L1931'><pre>1931</pre></a></td><td class='skipped-line'></td><td class='code'><pre> SyntaxKind::SingleLiteral</pre></td></tr><tr><td class='line-number'><a name='L1932' href='#L1932'><pre>1932</pre></a></td><td class='skipped-line'></td><td class='code'><pre> );</pre></td></tr><tr><td class='line-number'><a name='L1933' href='#L1933'><pre>1933</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert_eq!(</pre></td></tr><tr><td class='line-number'><a name='L1934' href='#L1934'><pre>1934</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> SyntaxKind::from(Token::DoubleLiteral),</pre></td></tr><tr><td class='line-number'><a name='L1935' href='#L1935'><pre>1935</pre></a></td><td class='skipped-line'></td><td class='code'><pre> SyntaxKind::DoubleLiteral</pre></td></tr><tr><td class='line-number'><a name='L1936' href='#L1936'><pre>1936</pre></a></td><td class='skipped-line'></td><td class='code'><pre> );</pre></td></tr><tr><td class='line-number'><a name='L1937' href='#L1937'><pre>1937</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert_eq!(</pre></td></tr><tr><td class='line-number'><a name='L1938' href='#L1938'><pre>1938</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> SyntaxKind::from(Token::DateTimeLiteral),</pre></td></tr><tr><td class='line-number'><a name='L1939' href='#L1939'><pre>1939</pre></a></td><td class='skipped-line'></td><td class='code'><pre> SyntaxKind::DateLiteral</pre></td></tr><tr><td class='line-number'><a name='L1940' href='#L1940'><pre>1940</pre></a></td><td class='skipped-line'></td><td class='code'><pre> );</pre></td></tr><tr><td class='line-number'><a name='L1941' href='#L1941'><pre>1941</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L1942' href='#L1942'><pre>1942</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L1943' href='#L1943'><pre>1943</pre></a></td><td class='skipped-line'></td><td class='code'><pre> #[test]</pre></td></tr><tr><td class='line-number'><a name='L1944' href='#L1944'><pre>1944</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> fn parse_empty_stream() {</pre></td></tr><tr><td class='line-number'><a name='L1945' href='#L1945'><pre>1945</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let source = "";</pre></td></tr><tr><td class='line-number'><a name='L1946' href='#L1946'><pre>1946</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let cst = ConcreteSyntaxTree::from_text("test.bas", source).unwrap();</pre></td></tr><tr><td class='line-number'><a name='L1947' href='#L1947'><pre>1947</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L1948' href='#L1948'><pre>1948</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert_eq!(cst.root_kind(), SyntaxKind::Root);</pre></td></tr><tr><td class='line-number'><a name='L1949' href='#L1949'><pre>1949</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert_eq!(cst.child_count(), 0);</pre></td></tr><tr><td class='line-number'><a name='L1950' href='#L1950'><pre>1950</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L1951' href='#L1951'><pre>1951</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L1952' href='#L1952'><pre>1952</pre></a></td><td class='skipped-line'></td><td class='code'><pre> #[test]</pre></td></tr><tr><td class='line-number'><a name='L1953' href='#L1953'><pre>1953</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> fn parse_rem_comment() {</pre></td></tr><tr><td class='line-number'><a name='L1954' href='#L1954'><pre>1954</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let source = "REM This is a REM comment\nSub Test()\nEnd Sub\n";</pre></td></tr><tr><td class='line-number'><a name='L1955' href='#L1955'><pre>1955</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let cst = ConcreteSyntaxTree::from_text("test.bas", source).unwrap();</pre></td></tr><tr><td class='line-number'><a name='L1956' href='#L1956'><pre>1956</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L1957' href='#L1957'><pre>1957</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert_eq!(cst.root_kind(), SyntaxKind::Root);</pre></td></tr><tr><td class='line-number'><a name='L1958' href='#L1958'><pre>1958</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Should have 2 children: the REM comment and the SubStatement</pre></td></tr><tr><td class='line-number'><a name='L1959' href='#L1959'><pre>1959</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert_eq!(cst.child_count(), 3); // 2 statements + EOF</pre></td></tr><tr><td class='line-number'><a name='L1960' href='#L1960'><pre>1960</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert!(cst.text().contains("REM This is a REM comment"));</pre></td></tr><tr><td class='line-number'><a name='L1961' href='#L1961'><pre>1961</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert!(cst.text().contains("Sub Test()"));</pre></td></tr><tr><td class='line-number'><a name='L1962' href='#L1962'><pre>1962</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L1963' href='#L1963'><pre>1963</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Verify REM comment is preserved</pre></td></tr><tr><td class='line-number'><a name='L1964' href='#L1964'><pre>1964</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let debug = cst.debug_tree();</pre></td></tr><tr><td class='line-number'><a name='L1965' href='#L1965'><pre>1965</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert!(debug.contains("RemComment"));</pre></td></tr><tr><td class='line-number'><a name='L1966' href='#L1966'><pre>1966</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L1967' href='#L1967'><pre>1967</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L1968' href='#L1968'><pre>1968</pre></a></td><td class='skipped-line'></td><td class='code'><pre> #[test]</pre></td></tr><tr><td class='line-number'><a name='L1969' href='#L1969'><pre>1969</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> fn parse_mixed_comments() {</pre></td></tr><tr><td class='line-number'><a name='L1970' href='#L1970'><pre>1970</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let source = "' Single quote comment\nREM REM comment\nSub Test()\nEnd Sub\n";</pre></td></tr><tr><td class='line-number'><a name='L1971' href='#L1971'><pre>1971</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let cst = ConcreteSyntaxTree::from_text("test.bas", source).unwrap();</pre></td></tr><tr><td class='line-number'><a name='L1972' href='#L1972'><pre>1972</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L1973' href='#L1973'><pre>1973</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert_eq!(cst.root_kind(), SyntaxKind::Root);</pre></td></tr><tr><td class='line-number'><a name='L1974' href='#L1974'><pre>1974</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Should have 5 children: EndOfLineComment, Newline, RemComment, Newline, SubStatement</pre></td></tr><tr><td class='line-number'><a name='L1975' href='#L1975'><pre>1975</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert_eq!(cst.child_count(), 5);</pre></td></tr><tr><td class='line-number'><a name='L1976' href='#L1976'><pre>1976</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert!(cst.text().contains("' Single quote comment"));</pre></td></tr><tr><td class='line-number'><a name='L1977' href='#L1977'><pre>1977</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert!(cst.text().contains("REM REM comment"));</pre></td></tr><tr><td class='line-number'><a name='L1978' href='#L1978'><pre>1978</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L1979' href='#L1979'><pre>1979</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Use navigation methods</pre></td></tr><tr><td class='line-number'><a name='L1980' href='#L1980'><pre>1980</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let children = cst.children();</pre></td></tr><tr><td class='line-number'><a name='L1981' href='#L1981'><pre>1981</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert_eq!(children[0].kind(), SyntaxKind::EndOfLineComment);</pre></td></tr><tr><td class='line-number'><a name='L1982' href='#L1982'><pre>1982</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert_eq!(children[1].kind(), SyntaxKind::Newline);</pre></td></tr><tr><td class='line-number'><a name='L1983' href='#L1983'><pre>1983</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert_eq!(children[2].kind(), SyntaxKind::RemComment);</pre></td></tr><tr><td class='line-number'><a name='L1984' href='#L1984'><pre>1984</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert_eq!(children[3].kind(), SyntaxKind::Newline);</pre></td></tr><tr><td class='line-number'><a name='L1985' href='#L1985'><pre>1985</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert_eq!(children[4].kind(), SyntaxKind::SubStatement);</pre></td></tr><tr><td class='line-number'><a name='L1986' href='#L1986'><pre>1986</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L1987' href='#L1987'><pre>1987</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert!(cst.contains_kind(SyntaxKind::EndOfLineComment));</pre></td></tr><tr><td class='line-number'><a name='L1988' href='#L1988'><pre>1988</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert!(cst.contains_kind(SyntaxKind::RemComment));</pre></td></tr><tr><td class='line-number'><a name='L1989' href='#L1989'><pre>1989</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L1990' href='#L1990'><pre>1990</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L1991' href='#L1991'><pre>1991</pre></a></td><td class='skipped-line'></td><td class='code'><pre> #[test]</pre></td></tr><tr><td class='line-number'><a name='L1992' href='#L1992'><pre>1992</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> fn cst_with_comments() {</pre></td></tr><tr><td class='line-number'><a name='L1993' href='#L1993'><pre>1993</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let source = "' This is a comment\nSub Main()\n";</pre></td></tr><tr><td class='line-number'><a name='L1994' href='#L1994'><pre>1994</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let cst = ConcreteSyntaxTree::from_text("test.bas", source).unwrap();</pre></td></tr><tr><td class='line-number'><a name='L1995' href='#L1995'><pre>1995</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L1996' href='#L1996'><pre>1996</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Now has 3 children: comment token, newline token, SubStatement</pre></td></tr><tr><td class='line-number'><a name='L1997' href='#L1997'><pre>1997</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert_eq!(cst.child_count(), 3);</pre></td></tr><tr><td class='line-number'><a name='L1998' href='#L1998'><pre>1998</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert!(cst.text().contains("' This is a comment"));</pre></td></tr><tr><td class='line-number'><a name='L1999' href='#L1999'><pre>1999</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert!(cst.text().contains("Sub Main()"));</pre></td></tr><tr><td class='line-number'><a name='L2000' href='#L2000'><pre>2000</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L2001' href='#L2001'><pre>2001</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2002' href='#L2002'><pre>2002</pre></a></td><td class='skipped-line'></td><td class='code'><pre> #[test]</pre></td></tr><tr><td class='line-number'><a name='L2003' href='#L2003'><pre>2003</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> fn cst_serializable_tree() {</pre></td></tr><tr><td class='line-number'><a name='L2004' href='#L2004'><pre>2004</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let source = "Sub Test()\nEnd Sub\n";</pre></td></tr><tr><td class='line-number'><a name='L2005' href='#L2005'><pre>2005</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let cst = ConcreteSyntaxTree::from_text("test.bas", source).unwrap();</pre></td></tr><tr><td class='line-number'><a name='L2006' href='#L2006'><pre>2006</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2007' href='#L2007'><pre>2007</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Convert to serializable format</pre></td></tr><tr><td class='line-number'><a name='L2008' href='#L2008'><pre>2008</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let serializable = cst.to_serializable();</pre></td></tr><tr><td class='line-number'><a name='L2009' href='#L2009'><pre>2009</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2010' href='#L2010'><pre>2010</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Verify structure</pre></td></tr><tr><td class='line-number'><a name='L2011' href='#L2011'><pre>2011</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert_eq!(serializable.root.kind(), SyntaxKind::Root);</pre></td></tr><tr><td class='line-number'><a name='L2012' href='#L2012'><pre>2012</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert!(!serializable.root.is_token());</pre></td></tr><tr><td class='line-number'><a name='L2013' href='#L2013'><pre>2013</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert_eq!(serializable.root.children().len(), 1);</pre></td></tr><tr><td class='line-number'><a name='L2014' href='#L2014'><pre>2014</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert_eq!(</pre></td></tr><tr><td class='line-number'><a name='L2015' href='#L2015'><pre>2015</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> serializable.root.children()[0].kind(),</pre></td></tr><tr><td class='line-number'><a name='L2016' href='#L2016'><pre>2016</pre></a></td><td class='skipped-line'></td><td class='code'><pre> SyntaxKind::SubStatement</pre></td></tr><tr><td class='line-number'><a name='L2017' href='#L2017'><pre>2017</pre></a></td><td class='skipped-line'></td><td class='code'><pre> );</pre></td></tr><tr><td class='line-number'><a name='L2018' href='#L2018'><pre>2018</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2019' href='#L2019'><pre>2019</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Can be used with insta for snapshot testing:</pre></td></tr><tr><td class='line-number'><a name='L2020' href='#L2020'><pre>2020</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // insta::assert_yaml_snapshot!(serializable);</pre></td></tr><tr><td class='line-number'><a name='L2021' href='#L2021'><pre>2021</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L2022' href='#L2022'><pre>2022</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2023' href='#L2023'><pre>2023</pre></a></td><td class='skipped-line'></td><td class='code'><pre> #[test]</pre></td></tr><tr><td class='line-number'><a name='L2024' href='#L2024'><pre>2024</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> fn cst_serializable_with_insta() {</pre></td></tr><tr><td class='line-number'><a name='L2025' href='#L2025'><pre>2025</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let source = "Dim x As Integer\n";</pre></td></tr><tr><td class='line-number'><a name='L2026' href='#L2026'><pre>2026</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let cst = ConcreteSyntaxTree::from_text("test.bas", source).unwrap();</pre></td></tr><tr><td class='line-number'><a name='L2027' href='#L2027'><pre>2027</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let serializable = cst.to_serializable();</pre></td></tr><tr><td class='line-number'><a name='L2028' href='#L2028'><pre>2028</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2029' href='#L2029'><pre>2029</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Example of using with insta (commented out to not create snapshot files in normal test runs)</pre></td></tr><tr><td class='line-number'><a name='L2030' href='#L2030'><pre>2030</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // insta::assert_yaml_snapshot!(serializable);</pre></td></tr><tr><td class='line-number'><a name='L2031' href='#L2031'><pre>2031</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2032' href='#L2032'><pre>2032</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Verify it's serializable by checking structure</pre></td></tr><tr><td class='line-number'><a name='L2033' href='#L2033'><pre>2033</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert!(!serializable.root.children().is_empty());</pre></td></tr><tr><td class='line-number'><a name='L2034' href='#L2034'><pre>2034</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L2035' href='#L2035'><pre>2035</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2036' href='#L2036'><pre>2036</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Phase 1 Tests: Parser Modes and Constructors</pre></td></tr><tr><td class='line-number'><a name='L2037' href='#L2037'><pre>2037</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2038' href='#L2038'><pre>2038</pre></a></td><td class='skipped-line'></td><td class='code'><pre> #[test]</pre></td></tr><tr><td class='line-number'><a name='L2039' href='#L2039'><pre>2039</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> fn parser_mode_full_cst_default() {</pre></td></tr><tr><td class='line-number'><a name='L2040' href='#L2040'><pre>2040</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let source = "Sub Test()\nEnd Sub\n";</pre></td></tr><tr><td class='line-number'><a name='L2041' href='#L2041'><pre>2041</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let mut stream = SourceStream::new("test.bas".to_string(), source);</pre></td></tr><tr><td class='line-number'><a name='L2042' href='#L2042'><pre>2042</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let (token_stream_opt, _) = tokenize(&mut stream).unpack();</pre></td></tr><tr><td class='line-number'><a name='L2043' href='#L2043'><pre>2043</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let token_stream = token_stream_opt.expect("Tokenization failed");</pre></td></tr><tr><td class='line-number'><a name='L2044' href='#L2044'><pre>2044</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2045' href='#L2045'><pre>2045</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let parser = Parser::new(token_stream);</pre></td></tr><tr><td class='line-number'><a name='L2046' href='#L2046'><pre>2046</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Verify parser was created successfully</pre></td></tr><tr><td class='line-number'><a name='L2047' href='#L2047'><pre>2047</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert_eq!(parser.pos, 0);</pre></td></tr><tr><td class='line-number'><a name='L2048' href='#L2048'><pre>2048</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L2049' href='#L2049'><pre>2049</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2050' href='#L2050'><pre>2050</pre></a></td><td class='skipped-line'></td><td class='code'><pre> #[test]</pre></td></tr><tr><td class='line-number'><a name='L2051' href='#L2051'><pre>2051</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> fn parser_mode_direct_extraction() {</pre></td></tr><tr><td class='line-number'><a name='L2052' href='#L2052'><pre>2052</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let source = "Sub Test()\nEnd Sub\n";</pre></td></tr><tr><td class='line-number'><a name='L2053' href='#L2053'><pre>2053</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let mut stream = SourceStream::new("test.bas".to_string(), source);</pre></td></tr><tr><td class='line-number'><a name='L2054' href='#L2054'><pre>2054</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let (token_stream_opt, _) = tokenize(&mut stream).unpack();</pre></td></tr><tr><td class='line-number'><a name='L2055' href='#L2055'><pre>2055</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let token_stream = token_stream_opt.expect("Tokenization failed");</pre></td></tr><tr><td class='line-number'><a name='L2056' href='#L2056'><pre>2056</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let tokens = token_stream.into_tokens();</pre></td></tr><tr><td class='line-number'><a name='L2057' href='#L2057'><pre>2057</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2058' href='#L2058'><pre>2058</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let parser = Parser::new_direct_extraction(tokens, 0);</pre></td></tr><tr><td class='line-number'><a name='L2059' href='#L2059'><pre>2059</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert_eq!(parser.pos, 0);</pre></td></tr><tr><td class='line-number'><a name='L2060' href='#L2060'><pre>2060</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L2061' href='#L2061'><pre>2061</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2062' href='#L2062'><pre>2062</pre></a></td><td class='skipped-line'></td><td class='code'><pre> #[test]</pre></td></tr><tr><td class='line-number'><a name='L2063' href='#L2063'><pre>2063</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> fn parser_constructors_preserve_tokens() {</pre></td></tr><tr><td class='line-number'><a name='L2064' href='#L2064'><pre>2064</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let source = "VERSION 5.00\n";</pre></td></tr><tr><td class='line-number'><a name='L2065' href='#L2065'><pre>2065</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let mut stream = SourceStream::new("test.frm".to_string(), source);</pre></td></tr><tr><td class='line-number'><a name='L2066' href='#L2066'><pre>2066</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let (token_stream_opt, _) = tokenize(&mut stream).unpack();</pre></td></tr><tr><td class='line-number'><a name='L2067' href='#L2067'><pre>2067</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let token_stream = token_stream_opt.expect("Tokenization failed");</pre></td></tr><tr><td class='line-number'><a name='L2068' href='#L2068'><pre>2068</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2069' href='#L2069'><pre>2069</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let tokens_vec = token_stream.into_tokens();</pre></td></tr><tr><td class='line-number'><a name='L2070' href='#L2070'><pre>2070</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let token_count = tokens_vec.len();</pre></td></tr><tr><td class='line-number'><a name='L2071' href='#L2071'><pre>2071</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2072' href='#L2072'><pre>2072</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let parser = Parser::new_direct_extraction(tokens_vec, 0);</pre></td></tr><tr><td class='line-number'><a name='L2073' href='#L2073'><pre>2073</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert_eq!(parser.tokens.len(), token_count);</pre></td></tr><tr><td class='line-number'><a name='L2074' href='#L2074'><pre>2074</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert!(parser.tokens[0].1 == Token::VersionKeyword);</pre></td></tr><tr><td class='line-number'><a name='L2075' href='#L2075'><pre>2075</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L2076' href='#L2076'><pre>2076</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2077' href='#L2077'><pre>2077</pre></a></td><td class='skipped-line'></td><td class='code'><pre> #[test]</pre></td></tr><tr><td class='line-number'><a name='L2078' href='#L2078'><pre>2078</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> fn parser_new_with_position() {</pre></td></tr><tr><td class='line-number'><a name='L2079' href='#L2079'><pre>2079</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let source = "VERSION 5.00\nSub Test()\nEnd Sub\n";</pre></td></tr><tr><td class='line-number'><a name='L2080' href='#L2080'><pre>2080</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let mut stream = SourceStream::new("test.bas".to_string(), source);</pre></td></tr><tr><td class='line-number'><a name='L2081' href='#L2081'><pre>2081</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let (token_stream_opt, _) = tokenize(&mut stream).unpack();</pre></td></tr><tr><td class='line-number'><a name='L2082' href='#L2082'><pre>2082</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let token_stream = token_stream_opt.expect("Tokenization failed");</pre></td></tr><tr><td class='line-number'><a name='L2083' href='#L2083'><pre>2083</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let tokens = token_stream.into_tokens();</pre></td></tr><tr><td class='line-number'><a name='L2084' href='#L2084'><pre>2084</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2085' href='#L2085'><pre>2085</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Create parser starting at position 3 (after VERSION keyword, whitespace, and version number)</pre></td></tr><tr><td class='line-number'><a name='L2086' href='#L2086'><pre>2086</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let parser = Parser::new_direct_extraction(tokens, 3);</pre></td></tr><tr><td class='line-number'><a name='L2087' href='#L2087'><pre>2087</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert_eq!(parser.pos, 3);</pre></td></tr><tr><td class='line-number'><a name='L2088' href='#L2088'><pre>2088</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L2089' href='#L2089'><pre>2089</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2090' href='#L2090'><pre>2090</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Phase 2 Tests: VERSION Parsing</pre></td></tr><tr><td class='line-number'><a name='L2091' href='#L2091'><pre>2091</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2092' href='#L2092'><pre>2092</pre></a></td><td class='skipped-line'></td><td class='code'><pre> #[test]</pre></td></tr><tr><td class='line-number'><a name='L2093' href='#L2093'><pre>2093</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> fn parse_version_direct_with_version() {</pre></td></tr><tr><td class='line-number'><a name='L2094' href='#L2094'><pre>2094</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let source = "VERSION 5.00\nSub Test()\nEnd Sub\n";</pre></td></tr><tr><td class='line-number'><a name='L2095' href='#L2095'><pre>2095</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let mut stream = SourceStream::new("test.frm".to_string(), source);</pre></td></tr><tr><td class='line-number'><a name='L2096' href='#L2096'><pre>2096</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let (token_stream_opt, _) = tokenize(&mut stream).unpack();</pre></td></tr><tr><td class='line-number'><a name='L2097' href='#L2097'><pre>2097</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let token_stream = token_stream_opt.expect("Tokenization failed");</pre></td></tr><tr><td class='line-number'><a name='L2098' href='#L2098'><pre>2098</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let tokens = token_stream.into_tokens();</pre></td></tr><tr><td class='line-number'><a name='L2099' href='#L2099'><pre>2099</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2100' href='#L2100'><pre>2100</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let mut parser = Parser::new_direct_extraction(tokens, 0);</pre></td></tr><tr><td class='line-number'><a name='L2101' href='#L2101'><pre>2101</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let (version_opt, failures) = parser.parse_version_direct().unpack();</pre></td></tr><tr><td class='line-number'><a name='L2102' href='#L2102'><pre>2102</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2103' href='#L2103'><pre>2103</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert!(version_opt.is_some());</pre></td></tr><tr><td class='line-number'><a name='L2104' href='#L2104'><pre>2104</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let version = version_opt.unwrap();</pre></td></tr><tr><td class='line-number'><a name='L2105' href='#L2105'><pre>2105</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert_eq!(version.major, 5);</pre></td></tr><tr><td class='line-number'><a name='L2106' href='#L2106'><pre>2106</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert_eq!(version.minor, 0);</pre></td></tr><tr><td class='line-number'><a name='L2107' href='#L2107'><pre>2107</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert!(failures.is_empty());</pre></td></tr><tr><td class='line-number'><a name='L2108' href='#L2108'><pre>2108</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L2109' href='#L2109'><pre>2109</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2110' href='#L2110'><pre>2110</pre></a></td><td class='skipped-line'></td><td class='code'><pre> #[test]</pre></td></tr><tr><td class='line-number'><a name='L2111' href='#L2111'><pre>2111</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> fn parse_version_direct_without_version() {</pre></td></tr><tr><td class='line-number'><a name='L2112' href='#L2112'><pre>2112</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let source = "Sub Test()\nEnd Sub\n";</pre></td></tr><tr><td class='line-number'><a name='L2113' href='#L2113'><pre>2113</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let mut stream = SourceStream::new("test.bas".to_string(), source);</pre></td></tr><tr><td class='line-number'><a name='L2114' href='#L2114'><pre>2114</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let (token_stream_opt, _) = tokenize(&mut stream).unpack();</pre></td></tr><tr><td class='line-number'><a name='L2115' href='#L2115'><pre>2115</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let token_stream = token_stream_opt.expect("Tokenization failed");</pre></td></tr><tr><td class='line-number'><a name='L2116' href='#L2116'><pre>2116</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let tokens = token_stream.into_tokens();</pre></td></tr><tr><td class='line-number'><a name='L2117' href='#L2117'><pre>2117</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2118' href='#L2118'><pre>2118</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let mut parser = Parser::new_direct_extraction(tokens, 0);</pre></td></tr><tr><td class='line-number'><a name='L2119' href='#L2119'><pre>2119</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let (version_opt, failures) = parser.parse_version_direct().unpack();</pre></td></tr><tr><td class='line-number'><a name='L2120' href='#L2120'><pre>2120</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2121' href='#L2121'><pre>2121</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert!(version_opt.is_none());</pre></td></tr><tr><td class='line-number'><a name='L2122' href='#L2122'><pre>2122</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert!(failures.is_empty());</pre></td></tr><tr><td class='line-number'><a name='L2123' href='#L2123'><pre>2123</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L2124' href='#L2124'><pre>2124</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2125' href='#L2125'><pre>2125</pre></a></td><td class='skipped-line'></td><td class='code'><pre> #[test]</pre></td></tr><tr><td class='line-number'><a name='L2126' href='#L2126'><pre>2126</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> fn parse_version_direct_with_class_keyword() {</pre></td></tr><tr><td class='line-number'><a name='L2127' href='#L2127'><pre>2127</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let source = "VERSION 1.0 CLASS\nSub Test()\nEnd Sub\n";</pre></td></tr><tr><td class='line-number'><a name='L2128' href='#L2128'><pre>2128</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let mut stream = SourceStream::new("test.cls".to_string(), source);</pre></td></tr><tr><td class='line-number'><a name='L2129' href='#L2129'><pre>2129</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let (token_stream_opt, _) = tokenize(&mut stream).unpack();</pre></td></tr><tr><td class='line-number'><a name='L2130' href='#L2130'><pre>2130</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let token_stream = token_stream_opt.expect("Tokenization failed");</pre></td></tr><tr><td class='line-number'><a name='L2131' href='#L2131'><pre>2131</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let tokens = token_stream.into_tokens();</pre></td></tr><tr><td class='line-number'><a name='L2132' href='#L2132'><pre>2132</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2133' href='#L2133'><pre>2133</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let mut parser = Parser::new_direct_extraction(tokens, 0);</pre></td></tr><tr><td class='line-number'><a name='L2134' href='#L2134'><pre>2134</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let (version_opt, failures) = parser.parse_version_direct().unpack();</pre></td></tr><tr><td class='line-number'><a name='L2135' href='#L2135'><pre>2135</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2136' href='#L2136'><pre>2136</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert!(version_opt.is_some());</pre></td></tr><tr><td class='line-number'><a name='L2137' href='#L2137'><pre>2137</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let version = version_opt.unwrap();</pre></td></tr><tr><td class='line-number'><a name='L2138' href='#L2138'><pre>2138</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert_eq!(version.major, 1);</pre></td></tr><tr><td class='line-number'><a name='L2139' href='#L2139'><pre>2139</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert_eq!(version.minor, 0);</pre></td></tr><tr><td class='line-number'><a name='L2140' href='#L2140'><pre>2140</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert!(failures.is_empty());</pre></td></tr><tr><td class='line-number'><a name='L2141' href='#L2141'><pre>2141</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L2142' href='#L2142'><pre>2142</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2143' href='#L2143'><pre>2143</pre></a></td><td class='skipped-line'></td><td class='code'><pre> #[test]</pre></td></tr><tr><td class='line-number'><a name='L2144' href='#L2144'><pre>2144</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> fn parse_version_direct_version_100() {</pre></td></tr><tr><td class='line-number'><a name='L2145' href='#L2145'><pre>2145</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let source = "VERSION 1.00\n";</pre></td></tr><tr><td class='line-number'><a name='L2146' href='#L2146'><pre>2146</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let mut stream = SourceStream::new("test.cls".to_string(), source);</pre></td></tr><tr><td class='line-number'><a name='L2147' href='#L2147'><pre>2147</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let (token_stream_opt, _) = tokenize(&mut stream).unpack();</pre></td></tr><tr><td class='line-number'><a name='L2148' href='#L2148'><pre>2148</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let token_stream = token_stream_opt.expect("Tokenization failed");</pre></td></tr><tr><td class='line-number'><a name='L2149' href='#L2149'><pre>2149</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let tokens = token_stream.into_tokens();</pre></td></tr><tr><td class='line-number'><a name='L2150' href='#L2150'><pre>2150</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2151' href='#L2151'><pre>2151</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let mut parser = Parser::new_direct_extraction(tokens, 0);</pre></td></tr><tr><td class='line-number'><a name='L2152' href='#L2152'><pre>2152</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let (version_opt, _failures) = parser.parse_version_direct().unpack();</pre></td></tr><tr><td class='line-number'><a name='L2153' href='#L2153'><pre>2153</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2154' href='#L2154'><pre>2154</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert!(version_opt.is_some());</pre></td></tr><tr><td class='line-number'><a name='L2155' href='#L2155'><pre>2155</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let version = version_opt.unwrap();</pre></td></tr><tr><td class='line-number'><a name='L2156' href='#L2156'><pre>2156</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert_eq!(version.major, 1);</pre></td></tr><tr><td class='line-number'><a name='L2157' href='#L2157'><pre>2157</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert_eq!(version.minor, 0);</pre></td></tr><tr><td class='line-number'><a name='L2158' href='#L2158'><pre>2158</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L2159' href='#L2159'><pre>2159</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2160' href='#L2160'><pre>2160</pre></a></td><td class='skipped-line'></td><td class='code'><pre> #[test]</pre></td></tr><tr><td class='line-number'><a name='L2161' href='#L2161'><pre>2161</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> fn parse_version_direct_with_whitespace() {</pre></td></tr><tr><td class='line-number'><a name='L2162' href='#L2162'><pre>2162</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let source = " VERSION 5.00 \nSub Test()\n";</pre></td></tr><tr><td class='line-number'><a name='L2163' href='#L2163'><pre>2163</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let mut stream = SourceStream::new("test.frm".to_string(), source);</pre></td></tr><tr><td class='line-number'><a name='L2164' href='#L2164'><pre>2164</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let (token_stream_opt, _) = tokenize(&mut stream).unpack();</pre></td></tr><tr><td class='line-number'><a name='L2165' href='#L2165'><pre>2165</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let token_stream = token_stream_opt.expect("Tokenization failed");</pre></td></tr><tr><td class='line-number'><a name='L2166' href='#L2166'><pre>2166</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let tokens = token_stream.into_tokens();</pre></td></tr><tr><td class='line-number'><a name='L2167' href='#L2167'><pre>2167</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2168' href='#L2168'><pre>2168</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let mut parser = Parser::new_direct_extraction(tokens, 0);</pre></td></tr><tr><td class='line-number'><a name='L2169' href='#L2169'><pre>2169</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let (version_opt, _failures) = parser.parse_version_direct().unpack();</pre></td></tr><tr><td class='line-number'><a name='L2170' href='#L2170'><pre>2170</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2171' href='#L2171'><pre>2171</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert!(version_opt.is_some());</pre></td></tr><tr><td class='line-number'><a name='L2172' href='#L2172'><pre>2172</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let version = version_opt.unwrap();</pre></td></tr><tr><td class='line-number'><a name='L2173' href='#L2173'><pre>2173</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert_eq!(version.major, 5);</pre></td></tr><tr><td class='line-number'><a name='L2174' href='#L2174'><pre>2174</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert_eq!(version.minor, 0);</pre></td></tr><tr><td class='line-number'><a name='L2175' href='#L2175'><pre>2175</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L2176' href='#L2176'><pre>2176</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2177' href='#L2177'><pre>2177</pre></a></td><td class='skipped-line'></td><td class='code'><pre> #[test]</pre></td></tr><tr><td class='line-number'><a name='L2178' href='#L2178'><pre>2178</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> fn parse_version_direct_position_advances() {</pre></td></tr><tr><td class='line-number'><a name='L2179' href='#L2179'><pre>2179</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let source = "VERSION 5.00\nBegin VB.Form Form1\nEnd\n";</pre></td></tr><tr><td class='line-number'><a name='L2180' href='#L2180'><pre>2180</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let mut stream = SourceStream::new("test.frm".to_string(), source);</pre></td></tr><tr><td class='line-number'><a name='L2181' href='#L2181'><pre>2181</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let (token_stream_opt, _) = tokenize(&mut stream).unpack();</pre></td></tr><tr><td class='line-number'><a name='L2182' href='#L2182'><pre>2182</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let token_stream = token_stream_opt.expect("Tokenization failed");</pre></td></tr><tr><td class='line-number'><a name='L2183' href='#L2183'><pre>2183</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let tokens = token_stream.into_tokens();</pre></td></tr><tr><td class='line-number'><a name='L2184' href='#L2184'><pre>2184</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2185' href='#L2185'><pre>2185</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let mut parser = Parser::new_direct_extraction(tokens, 0);</pre></td></tr><tr><td class='line-number'><a name='L2186' href='#L2186'><pre>2186</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let initial_pos = parser.pos;</pre></td></tr><tr><td class='line-number'><a name='L2187' href='#L2187'><pre>2187</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let _result = parser.parse_version_direct();</pre></td></tr><tr><td class='line-number'><a name='L2188' href='#L2188'><pre>2188</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2189' href='#L2189'><pre>2189</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Position should have advanced past VERSION statement</pre></td></tr><tr><td class='line-number'><a name='L2190' href='#L2190'><pre>2190</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert!(parser.pos > initial_pos);</pre></td></tr><tr><td class='line-number'><a name='L2191' href='#L2191'><pre>2191</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2192' href='#L2192'><pre>2192</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Should now be positioned at Begin keyword</pre></td></tr><tr><td class='line-number'><a name='L2193' href='#L2193'><pre>2193</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert_eq!(parser.current_token(), Some(&Token::BeginKeyword));</pre></td></tr><tr><td class='line-number'><a name='L2194' href='#L2194'><pre>2194</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L2195' href='#L2195'><pre>2195</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2196' href='#L2196'><pre>2196</pre></a></td><td class='skipped-line'></td><td class='code'><pre> #[test]</pre></td></tr><tr><td class='line-number'><a name='L2197' href='#L2197'><pre>2197</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> fn parse_version_direct_accuracy() {</pre></td></tr><tr><td class='line-number'><a name='L2198' href='#L2198'><pre>2198</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let test_cases = vec![</pre></td></tr><tr><td class='line-number'><a name='L2199' href='#L2199'><pre>2199</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> ("VERSION 5.00\n", Some((5, 0))),</pre></td></tr><tr><td class='line-number'><a name='L2200' href='#L2200'><pre>2200</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> ("VERSION 1.0\n", Some((1, 0))),</pre></td></tr><tr><td class='line-number'><a name='L2201' href='#L2201'><pre>2201</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> ("VERSION 6.00 CLASS\n", Some((6, 0))),</pre></td></tr><tr><td class='line-number'><a name='L2202' href='#L2202'><pre>2202</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> ("VERSION 4.00\n", Some((4, 0))),</pre></td></tr><tr><td class='line-number'><a name='L2203' href='#L2203'><pre>2203</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> ("Sub Test()\n", None), // No VERSION</pre></td></tr><tr><td class='line-number'><a name='L2204' href='#L2204'><pre>2204</pre></a></td><td class='skipped-line'></td><td class='code'><pre> ];</pre></td></tr><tr><td class='line-number'><a name='L2205' href='#L2205'><pre>2205</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2206' href='#L2206'><pre>2206</pre></a></td><td class='covered-line'><pre>5</pre></td><td class='code'><pre> for (source, expected) in <div class='tooltip'>test_cases<span class='tooltip-content'>1</span></div> {</pre></td></tr><tr><td class='line-number'><a name='L2207' href='#L2207'><pre>2207</pre></a></td><td class='covered-line'><pre>5</pre></td><td class='code'><pre> let mut stream = SourceStream::new("test.vb".to_string(), source);</pre></td></tr><tr><td class='line-number'><a name='L2208' href='#L2208'><pre>2208</pre></a></td><td class='covered-line'><pre>5</pre></td><td class='code'><pre> let (token_stream_opt, _) = tokenize(&mut stream).unpack();</pre></td></tr><tr><td class='line-number'><a name='L2209' href='#L2209'><pre>2209</pre></a></td><td class='covered-line'><pre>5</pre></td><td class='code'><pre> let token_stream = token_stream_opt.expect("Tokenization failed");</pre></td></tr><tr><td class='line-number'><a name='L2210' href='#L2210'><pre>2210</pre></a></td><td class='covered-line'><pre>5</pre></td><td class='code'><pre> let tokens = token_stream.into_tokens();</pre></td></tr><tr><td class='line-number'><a name='L2211' href='#L2211'><pre>2211</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2212' href='#L2212'><pre>2212</pre></a></td><td class='covered-line'><pre>5</pre></td><td class='code'><pre> let mut parser = Parser::new_direct_extraction(tokens, 0);</pre></td></tr><tr><td class='line-number'><a name='L2213' href='#L2213'><pre>2213</pre></a></td><td class='covered-line'><pre>5</pre></td><td class='code'><pre> let (version_opt, _failures) = parser.parse_version_direct().unpack();</pre></td></tr><tr><td class='line-number'><a name='L2214' href='#L2214'><pre>2214</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2215' href='#L2215'><pre>2215</pre></a></td><td class='covered-line'><pre>5</pre></td><td class='code'><pre> match expected {</pre></td></tr><tr><td class='line-number'><a name='L2216' href='#L2216'><pre>2216</pre></a></td><td class='covered-line'><pre>4</pre></td><td class='code'><pre> Some((major, minor)) => {</pre></td></tr><tr><td class='line-number'><a name='L2217' href='#L2217'><pre>2217</pre></a></td><td class='covered-line'><pre>4</pre></td><td class='code'><pre> assert!(version_opt.is_some(), "Expected version for: {source}");</pre></td></tr><tr><td class='line-number'><a name='L2218' href='#L2218'><pre>2218</pre></a></td><td class='covered-line'><pre>4</pre></td><td class='code'><pre> let version = version_opt.unwrap();</pre></td></tr><tr><td class='line-number'><a name='L2219' href='#L2219'><pre>2219</pre></a></td><td class='covered-line'><pre>4</pre></td><td class='code'><pre> assert_eq!(version.major, major, "Major mismatch for: {source}");</pre></td></tr><tr><td class='line-number'><a name='L2220' href='#L2220'><pre>2220</pre></a></td><td class='covered-line'><pre>4</pre></td><td class='code'><pre> assert_eq!(version.minor, minor, "Minor mismatch for: {source}");</pre></td></tr><tr><td class='line-number'><a name='L2221' href='#L2221'><pre>2221</pre></a></td><td class='skipped-line'></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L2222' href='#L2222'><pre>2222</pre></a></td><td class='skipped-line'></td><td class='code'><pre> None => {</pre></td></tr><tr><td class='line-number'><a name='L2223' href='#L2223'><pre>2223</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert!(version_opt.is_none(), "Expected no version for: {source}");</pre></td></tr><tr><td class='line-number'><a name='L2224' href='#L2224'><pre>2224</pre></a></td><td class='skipped-line'></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L2225' href='#L2225'><pre>2225</pre></a></td><td class='skipped-line'></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L2226' href='#L2226'><pre>2226</pre></a></td><td class='skipped-line'></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L2227' href='#L2227'><pre>2227</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L2228' href='#L2228'><pre>2228</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2229' href='#L2229'><pre>2229</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Phase 3 Tests: Core Control Extraction</pre></td></tr><tr><td class='line-number'><a name='L2230' href='#L2230'><pre>2230</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2231' href='#L2231'><pre>2231</pre></a></td><td class='skipped-line'></td><td class='code'><pre> #[test]</pre></td></tr><tr><td class='line-number'><a name='L2232' href='#L2232'><pre>2232</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> fn parse_control_type_direct_simple() {</pre></td></tr><tr><td class='line-number'><a name='L2233' href='#L2233'><pre>2233</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let source = "VB.Form Form1\n";</pre></td></tr><tr><td class='line-number'><a name='L2234' href='#L2234'><pre>2234</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let mut stream = SourceStream::new("test.frm".to_string(), source);</pre></td></tr><tr><td class='line-number'><a name='L2235' href='#L2235'><pre>2235</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let (token_stream_opt, _) = tokenize(&mut stream).unpack();</pre></td></tr><tr><td class='line-number'><a name='L2236' href='#L2236'><pre>2236</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let token_stream = token_stream_opt.expect("Tokenization failed");</pre></td></tr><tr><td class='line-number'><a name='L2237' href='#L2237'><pre>2237</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let tokens = token_stream.into_tokens();</pre></td></tr><tr><td class='line-number'><a name='L2238' href='#L2238'><pre>2238</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2239' href='#L2239'><pre>2239</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let mut parser = Parser::new_direct_extraction(tokens, 0);</pre></td></tr><tr><td class='line-number'><a name='L2240' href='#L2240'><pre>2240</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let control_type = parser.parse_control_type_direct();</pre></td></tr><tr><td class='line-number'><a name='L2241' href='#L2241'><pre>2241</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2242' href='#L2242'><pre>2242</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert_eq!(control_type, "VB.Form");</pre></td></tr><tr><td class='line-number'><a name='L2243' href='#L2243'><pre>2243</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L2244' href='#L2244'><pre>2244</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2245' href='#L2245'><pre>2245</pre></a></td><td class='skipped-line'></td><td class='code'><pre> #[test]</pre></td></tr><tr><td class='line-number'><a name='L2246' href='#L2246'><pre>2246</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> fn parse_control_name_direct_simple() {</pre></td></tr><tr><td class='line-number'><a name='L2247' href='#L2247'><pre>2247</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let source = "Form1 \n";</pre></td></tr><tr><td class='line-number'><a name='L2248' href='#L2248'><pre>2248</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let mut stream = SourceStream::new("test.frm".to_string(), source);</pre></td></tr><tr><td class='line-number'><a name='L2249' href='#L2249'><pre>2249</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let (token_stream_opt, _) = tokenize(&mut stream).unpack();</pre></td></tr><tr><td class='line-number'><a name='L2250' href='#L2250'><pre>2250</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let token_stream = token_stream_opt.expect("Tokenization failed");</pre></td></tr><tr><td class='line-number'><a name='L2251' href='#L2251'><pre>2251</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let tokens = token_stream.into_tokens();</pre></td></tr><tr><td class='line-number'><a name='L2252' href='#L2252'><pre>2252</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2253' href='#L2253'><pre>2253</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let mut parser = Parser::new_direct_extraction(tokens, 0);</pre></td></tr><tr><td class='line-number'><a name='L2254' href='#L2254'><pre>2254</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let control_name = parser.parse_control_name_direct();</pre></td></tr><tr><td class='line-number'><a name='L2255' href='#L2255'><pre>2255</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2256' href='#L2256'><pre>2256</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert_eq!(control_name, "Form1");</pre></td></tr><tr><td class='line-number'><a name='L2257' href='#L2257'><pre>2257</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L2258' href='#L2258'><pre>2258</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2259' href='#L2259'><pre>2259</pre></a></td><td class='skipped-line'></td><td class='code'><pre> #[test]</pre></td></tr><tr><td class='line-number'><a name='L2260' href='#L2260'><pre>2260</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> fn parse_property_direct_simple() {</pre></td></tr><tr><td class='line-number'><a name='L2261' href='#L2261'><pre>2261</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let source = "Caption = \"Hello World\"\n";</pre></td></tr><tr><td class='line-number'><a name='L2262' href='#L2262'><pre>2262</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let mut stream = SourceStream::new("test.frm".to_string(), source);</pre></td></tr><tr><td class='line-number'><a name='L2263' href='#L2263'><pre>2263</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let (token_stream_opt, _) = tokenize(&mut stream).unpack();</pre></td></tr><tr><td class='line-number'><a name='L2264' href='#L2264'><pre>2264</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let token_stream = token_stream_opt.expect("Tokenization failed");</pre></td></tr><tr><td class='line-number'><a name='L2265' href='#L2265'><pre>2265</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let tokens = token_stream.into_tokens();</pre></td></tr><tr><td class='line-number'><a name='L2266' href='#L2266'><pre>2266</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2267' href='#L2267'><pre>2267</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let mut parser = Parser::new_direct_extraction(tokens, 0);</pre></td></tr><tr><td class='line-number'><a name='L2268' href='#L2268'><pre>2268</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let property = parser.parse_property_direct();</pre></td></tr><tr><td class='line-number'><a name='L2269' href='#L2269'><pre>2269</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2270' href='#L2270'><pre>2270</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert!(property.is_some());</pre></td></tr><tr><td class='line-number'><a name='L2271' href='#L2271'><pre>2271</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let (key, value) = property.unwrap();</pre></td></tr><tr><td class='line-number'><a name='L2272' href='#L2272'><pre>2272</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert_eq!(key, "Caption");</pre></td></tr><tr><td class='line-number'><a name='L2273' href='#L2273'><pre>2273</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert_eq!(value, "\"Hello World\"");</pre></td></tr><tr><td class='line-number'><a name='L2274' href='#L2274'><pre>2274</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L2275' href='#L2275'><pre>2275</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2276' href='#L2276'><pre>2276</pre></a></td><td class='skipped-line'></td><td class='code'><pre> #[test]</pre></td></tr><tr><td class='line-number'><a name='L2277' href='#L2277'><pre>2277</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> fn parse_properties_block_to_control_simple_form() {</pre></td></tr><tr><td class='line-number'><a name='L2278' href='#L2278'><pre>2278</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let source = r#"Begin VB.Form Form1</pre></td></tr><tr><td class='line-number'><a name='L2279' href='#L2279'><pre>2279</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> Caption = "Test Form"</pre></td></tr><tr><td class='line-number'><a name='L2280' href='#L2280'><pre>2280</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> ClientHeight = 3000</pre></td></tr><tr><td class='line-number'><a name='L2281' href='#L2281'><pre>2281</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> ClientWidth = 4000</pre></td></tr><tr><td class='line-number'><a name='L2282' href='#L2282'><pre>2282</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre>End</pre></td></tr><tr><td class='line-number'><a name='L2283' href='#L2283'><pre>2283</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre>"#;</pre></td></tr><tr><td class='line-number'><a name='L2284' href='#L2284'><pre>2284</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let mut stream = SourceStream::new("test.frm".to_string(), source);</pre></td></tr><tr><td class='line-number'><a name='L2285' href='#L2285'><pre>2285</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let (token_stream_opt, _) = tokenize(&mut stream).unpack();</pre></td></tr><tr><td class='line-number'><a name='L2286' href='#L2286'><pre>2286</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let token_stream = token_stream_opt.expect("Tokenization failed");</pre></td></tr><tr><td class='line-number'><a name='L2287' href='#L2287'><pre>2287</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let tokens = token_stream.into_tokens();</pre></td></tr><tr><td class='line-number'><a name='L2288' href='#L2288'><pre>2288</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2289' href='#L2289'><pre>2289</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let mut parser = Parser::new_direct_extraction(tokens, 0);</pre></td></tr><tr><td class='line-number'><a name='L2290' href='#L2290'><pre>2290</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let (control_opt, failures) = parser.parse_properties_block_to_control().unpack();</pre></td></tr><tr><td class='line-number'><a name='L2291' href='#L2291'><pre>2291</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2292' href='#L2292'><pre>2292</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert!(failures.is_empty(), "Expected no failures");</pre></td></tr><tr><td class='line-number'><a name='L2293' href='#L2293'><pre>2293</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert!(control_opt.is_some(), "Expected control to be parsed");</pre></td></tr><tr><td class='line-number'><a name='L2294' href='#L2294'><pre>2294</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2295' href='#L2295'><pre>2295</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let control = control_opt.unwrap();</pre></td></tr><tr><td class='line-number'><a name='L2296' href='#L2296'><pre>2296</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert_eq!(control.name(), "Form1");</pre></td></tr><tr><td class='line-number'><a name='L2297' href='#L2297'><pre>2297</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2298' href='#L2298'><pre>2298</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Verify it's a Form</pre></td></tr><tr><td class='line-number'><a name='L2299' href='#L2299'><pre>2299</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert!(<div class='tooltip'><span class='region red'>matches!</span><span class='tooltip-content'>0</span></div>(</pre></td></tr><tr><td class='line-number'><a name='L2300' href='#L2300'><pre>2300</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> control.kind(),</pre></td></tr><tr><td class='line-number'><a name='L2301' href='#L2301'><pre>2301</pre></a></td><td class='skipped-line'></td><td class='code'><pre> crate::language::ControlKind::Form { .. }</pre></td></tr><tr><td class='line-number'><a name='L2302' href='#L2302'><pre>2302</pre></a></td><td class='skipped-line'></td><td class='code'><pre> ));</pre></td></tr><tr><td class='line-number'><a name='L2303' href='#L2303'><pre>2303</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L2304' href='#L2304'><pre>2304</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2305' href='#L2305'><pre>2305</pre></a></td><td class='skipped-line'></td><td class='code'><pre> #[test]</pre></td></tr><tr><td class='line-number'><a name='L2306' href='#L2306'><pre>2306</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> fn parse_properties_block_to_control_command_button() {</pre></td></tr><tr><td class='line-number'><a name='L2307' href='#L2307'><pre>2307</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let source = r#"Begin VB.CommandButton Command1</pre></td></tr><tr><td class='line-number'><a name='L2308' href='#L2308'><pre>2308</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> Caption = "Click Me"</pre></td></tr><tr><td class='line-number'><a name='L2309' href='#L2309'><pre>2309</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> Height = 495</pre></td></tr><tr><td class='line-number'><a name='L2310' href='#L2310'><pre>2310</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> Width = 1215</pre></td></tr><tr><td class='line-number'><a name='L2311' href='#L2311'><pre>2311</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre>End</pre></td></tr><tr><td class='line-number'><a name='L2312' href='#L2312'><pre>2312</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre>"#;</pre></td></tr><tr><td class='line-number'><a name='L2313' href='#L2313'><pre>2313</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let mut stream = SourceStream::new("test.frm".to_string(), source);</pre></td></tr><tr><td class='line-number'><a name='L2314' href='#L2314'><pre>2314</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let (token_stream_opt, _) = tokenize(&mut stream).unpack();</pre></td></tr><tr><td class='line-number'><a name='L2315' href='#L2315'><pre>2315</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let token_stream = token_stream_opt.expect("Tokenization failed");</pre></td></tr><tr><td class='line-number'><a name='L2316' href='#L2316'><pre>2316</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let tokens = token_stream.into_tokens();</pre></td></tr><tr><td class='line-number'><a name='L2317' href='#L2317'><pre>2317</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2318' href='#L2318'><pre>2318</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let mut parser = Parser::new_direct_extraction(tokens, 0);</pre></td></tr><tr><td class='line-number'><a name='L2319' href='#L2319'><pre>2319</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let (control_opt, failures) = parser.parse_properties_block_to_control().unpack();</pre></td></tr><tr><td class='line-number'><a name='L2320' href='#L2320'><pre>2320</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2321' href='#L2321'><pre>2321</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert!(failures.is_empty());</pre></td></tr><tr><td class='line-number'><a name='L2322' href='#L2322'><pre>2322</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert!(control_opt.is_some());</pre></td></tr><tr><td class='line-number'><a name='L2323' href='#L2323'><pre>2323</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2324' href='#L2324'><pre>2324</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let control = control_opt.unwrap();</pre></td></tr><tr><td class='line-number'><a name='L2325' href='#L2325'><pre>2325</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert_eq!(control.name(), "Command1");</pre></td></tr><tr><td class='line-number'><a name='L2326' href='#L2326'><pre>2326</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert!(<div class='tooltip'><span class='region red'>matches!</span><span class='tooltip-content'>0</span></div>(</pre></td></tr><tr><td class='line-number'><a name='L2327' href='#L2327'><pre>2327</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> control.kind(),</pre></td></tr><tr><td class='line-number'><a name='L2328' href='#L2328'><pre>2328</pre></a></td><td class='skipped-line'></td><td class='code'><pre> crate::language::ControlKind::CommandButton { .. }</pre></td></tr><tr><td class='line-number'><a name='L2329' href='#L2329'><pre>2329</pre></a></td><td class='skipped-line'></td><td class='code'><pre> ));</pre></td></tr><tr><td class='line-number'><a name='L2330' href='#L2330'><pre>2330</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L2331' href='#L2331'><pre>2331</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2332' href='#L2332'><pre>2332</pre></a></td><td class='skipped-line'></td><td class='code'><pre> #[test]</pre></td></tr><tr><td class='line-number'><a name='L2333' href='#L2333'><pre>2333</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> fn parse_properties_block_to_control_textbox() {</pre></td></tr><tr><td class='line-number'><a name='L2334' href='#L2334'><pre>2334</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let source = r#"Begin VB.TextBox Text1</pre></td></tr><tr><td class='line-number'><a name='L2335' href='#L2335'><pre>2335</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> Text = "Initial Text"</pre></td></tr><tr><td class='line-number'><a name='L2336' href='#L2336'><pre>2336</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> Height = 300</pre></td></tr><tr><td class='line-number'><a name='L2337' href='#L2337'><pre>2337</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> Width = 2000</pre></td></tr><tr><td class='line-number'><a name='L2338' href='#L2338'><pre>2338</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre>End</pre></td></tr><tr><td class='line-number'><a name='L2339' href='#L2339'><pre>2339</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre>"#;</pre></td></tr><tr><td class='line-number'><a name='L2340' href='#L2340'><pre>2340</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let mut stream = SourceStream::new("test.frm".to_string(), source);</pre></td></tr><tr><td class='line-number'><a name='L2341' href='#L2341'><pre>2341</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let (token_stream_opt, _) = tokenize(&mut stream).unpack();</pre></td></tr><tr><td class='line-number'><a name='L2342' href='#L2342'><pre>2342</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let token_stream = token_stream_opt.expect("Tokenization failed");</pre></td></tr><tr><td class='line-number'><a name='L2343' href='#L2343'><pre>2343</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let tokens = token_stream.into_tokens();</pre></td></tr><tr><td class='line-number'><a name='L2344' href='#L2344'><pre>2344</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2345' href='#L2345'><pre>2345</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let mut parser = Parser::new_direct_extraction(tokens, 0);</pre></td></tr><tr><td class='line-number'><a name='L2346' href='#L2346'><pre>2346</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let (control_opt, _failures) = parser.parse_properties_block_to_control().unpack();</pre></td></tr><tr><td class='line-number'><a name='L2347' href='#L2347'><pre>2347</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2348' href='#L2348'><pre>2348</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert!(control_opt.is_some());</pre></td></tr><tr><td class='line-number'><a name='L2349' href='#L2349'><pre>2349</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let control = control_opt.unwrap();</pre></td></tr><tr><td class='line-number'><a name='L2350' href='#L2350'><pre>2350</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert_eq!(control.name(), "Text1");</pre></td></tr><tr><td class='line-number'><a name='L2351' href='#L2351'><pre>2351</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert!(<div class='tooltip'><span class='region red'>matches!</span><span class='tooltip-content'>0</span></div>(</pre></td></tr><tr><td class='line-number'><a name='L2352' href='#L2352'><pre>2352</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> control.kind(),</pre></td></tr><tr><td class='line-number'><a name='L2353' href='#L2353'><pre>2353</pre></a></td><td class='skipped-line'></td><td class='code'><pre> crate::language::ControlKind::TextBox { .. }</pre></td></tr><tr><td class='line-number'><a name='L2354' href='#L2354'><pre>2354</pre></a></td><td class='skipped-line'></td><td class='code'><pre> ));</pre></td></tr><tr><td class='line-number'><a name='L2355' href='#L2355'><pre>2355</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L2356' href='#L2356'><pre>2356</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2357' href='#L2357'><pre>2357</pre></a></td><td class='skipped-line'></td><td class='code'><pre> #[test]</pre></td></tr><tr><td class='line-number'><a name='L2358' href='#L2358'><pre>2358</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> fn parse_properties_block_without_begin() {</pre></td></tr><tr><td class='line-number'><a name='L2359' href='#L2359'><pre>2359</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let source = "Caption = \"Test\"\nEnd\n";</pre></td></tr><tr><td class='line-number'><a name='L2360' href='#L2360'><pre>2360</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let mut stream = SourceStream::new("test.frm".to_string(), source);</pre></td></tr><tr><td class='line-number'><a name='L2361' href='#L2361'><pre>2361</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let (token_stream_opt, _) = tokenize(&mut stream).unpack();</pre></td></tr><tr><td class='line-number'><a name='L2362' href='#L2362'><pre>2362</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let token_stream = token_stream_opt.expect("Tokenization failed");</pre></td></tr><tr><td class='line-number'><a name='L2363' href='#L2363'><pre>2363</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let tokens = token_stream.into_tokens();</pre></td></tr><tr><td class='line-number'><a name='L2364' href='#L2364'><pre>2364</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2365' href='#L2365'><pre>2365</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let mut parser = Parser::new_direct_extraction(tokens, 0);</pre></td></tr><tr><td class='line-number'><a name='L2366' href='#L2366'><pre>2366</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let (control_opt, _failures) = parser.parse_properties_block_to_control().unpack();</pre></td></tr><tr><td class='line-number'><a name='L2367' href='#L2367'><pre>2367</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2368' href='#L2368'><pre>2368</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Should return None when BEGIN is missing</pre></td></tr><tr><td class='line-number'><a name='L2369' href='#L2369'><pre>2369</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert!(control_opt.is_none());</pre></td></tr><tr><td class='line-number'><a name='L2370' href='#L2370'><pre>2370</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L2371' href='#L2371'><pre>2371</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2372' href='#L2372'><pre>2372</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Phase 4 Tests: Nested Controls and Property Groups</pre></td></tr><tr><td class='line-number'><a name='L2373' href='#L2373'><pre>2373</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2374' href='#L2374'><pre>2374</pre></a></td><td class='skipped-line'></td><td class='code'><pre> #[test]</pre></td></tr><tr><td class='line-number'><a name='L2375' href='#L2375'><pre>2375</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> fn parse_form_with_nested_control() {</pre></td></tr><tr><td class='line-number'><a name='L2376' href='#L2376'><pre>2376</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let source = r#"Begin VB.Form Form1</pre></td></tr><tr><td class='line-number'><a name='L2377' href='#L2377'><pre>2377</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> Caption = "Main Form"</pre></td></tr><tr><td class='line-number'><a name='L2378' href='#L2378'><pre>2378</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> Begin VB.CommandButton Command1</pre></td></tr><tr><td class='line-number'><a name='L2379' href='#L2379'><pre>2379</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> Caption = "Click Me"</pre></td></tr><tr><td class='line-number'><a name='L2380' href='#L2380'><pre>2380</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> Height = 400</pre></td></tr><tr><td class='line-number'><a name='L2381' href='#L2381'><pre>2381</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> End</pre></td></tr><tr><td class='line-number'><a name='L2382' href='#L2382'><pre>2382</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre>End</pre></td></tr><tr><td class='line-number'><a name='L2383' href='#L2383'><pre>2383</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre>"#;</pre></td></tr><tr><td class='line-number'><a name='L2384' href='#L2384'><pre>2384</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let mut stream = SourceStream::new("test.frm".to_string(), source);</pre></td></tr><tr><td class='line-number'><a name='L2385' href='#L2385'><pre>2385</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let (token_stream_opt, _) = tokenize(&mut stream).unpack();</pre></td></tr><tr><td class='line-number'><a name='L2386' href='#L2386'><pre>2386</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let token_stream = token_stream_opt.expect("Tokenization failed");</pre></td></tr><tr><td class='line-number'><a name='L2387' href='#L2387'><pre>2387</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let tokens = token_stream.into_tokens();</pre></td></tr><tr><td class='line-number'><a name='L2388' href='#L2388'><pre>2388</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2389' href='#L2389'><pre>2389</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let mut parser = Parser::new_direct_extraction(tokens, 0);</pre></td></tr><tr><td class='line-number'><a name='L2390' href='#L2390'><pre>2390</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let (control_opt, failures) = parser.parse_properties_block_to_control().unpack();</pre></td></tr><tr><td class='line-number'><a name='L2391' href='#L2391'><pre>2391</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2392' href='#L2392'><pre>2392</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert!(failures.is_empty(), "Should have no failures");</pre></td></tr><tr><td class='line-number'><a name='L2393' href='#L2393'><pre>2393</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert!(control_opt.is_some());</pre></td></tr><tr><td class='line-number'><a name='L2394' href='#L2394'><pre>2394</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let control = control_opt.unwrap();</pre></td></tr><tr><td class='line-number'><a name='L2395' href='#L2395'><pre>2395</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert_eq!(control.name(), "Form1");</pre></td></tr><tr><td class='line-number'><a name='L2396' href='#L2396'><pre>2396</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2397' href='#L2397'><pre>2397</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Check form has child controls</pre></td></tr><tr><td class='line-number'><a name='L2398' href='#L2398'><pre>2398</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> if let crate::language::ControlKind::Form { controls, .. } = control.kind() {</pre></td></tr><tr><td class='line-number'><a name='L2399' href='#L2399'><pre>2399</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert_eq!(controls.len(), 1);</pre></td></tr><tr><td class='line-number'><a name='L2400' href='#L2400'><pre>2400</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert_eq!(controls[0].name(), "Command1");</pre></td></tr><tr><td class='line-number'><a name='L2401' href='#L2401'><pre>2401</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert!(<div class='tooltip'><span class='region red'>matches!</span><span class='tooltip-content'>0</span></div>(</pre></td></tr><tr><td class='line-number'><a name='L2402' href='#L2402'><pre>2402</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> controls[0].kind(),</pre></td></tr><tr><td class='line-number'><a name='L2403' href='#L2403'><pre>2403</pre></a></td><td class='skipped-line'></td><td class='code'><pre> crate::language::ControlKind::CommandButton { .. }</pre></td></tr><tr><td class='line-number'><a name='L2404' href='#L2404'><pre>2404</pre></a></td><td class='skipped-line'></td><td class='code'><pre> ));</pre></td></tr><tr><td class='line-number'><a name='L2405' href='#L2405'><pre>2405</pre></a></td><td class='skipped-line'></td><td class='code'><pre> } else {</pre></td></tr><tr><td class='line-number'><a name='L2406' href='#L2406'><pre>2406</pre></a></td><td class='uncovered-line'><pre>0</pre></td><td class='code'><pre> <span class='region red'>panic!</span>("Expected Form control kind");</pre></td></tr><tr><td class='line-number'><a name='L2407' href='#L2407'><pre>2407</pre></a></td><td class='skipped-line'></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L2408' href='#L2408'><pre>2408</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L2409' href='#L2409'><pre>2409</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2410' href='#L2410'><pre>2410</pre></a></td><td class='skipped-line'></td><td class='code'><pre> #[test]</pre></td></tr><tr><td class='line-number'><a name='L2411' href='#L2411'><pre>2411</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> fn parse_frame_with_multiple_nested_controls() {</pre></td></tr><tr><td class='line-number'><a name='L2412' href='#L2412'><pre>2412</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let source = r#"Begin VB.Frame Frame1</pre></td></tr><tr><td class='line-number'><a name='L2413' href='#L2413'><pre>2413</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> Caption = "Options"</pre></td></tr><tr><td class='line-number'><a name='L2414' href='#L2414'><pre>2414</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> Begin VB.CheckBox Check1</pre></td></tr><tr><td class='line-number'><a name='L2415' href='#L2415'><pre>2415</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> Caption = "Option 1"</pre></td></tr><tr><td class='line-number'><a name='L2416' href='#L2416'><pre>2416</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> End</pre></td></tr><tr><td class='line-number'><a name='L2417' href='#L2417'><pre>2417</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> Begin VB.CheckBox Check2</pre></td></tr><tr><td class='line-number'><a name='L2418' href='#L2418'><pre>2418</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> Caption = "Option 2"</pre></td></tr><tr><td class='line-number'><a name='L2419' href='#L2419'><pre>2419</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> End</pre></td></tr><tr><td class='line-number'><a name='L2420' href='#L2420'><pre>2420</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre>End</pre></td></tr><tr><td class='line-number'><a name='L2421' href='#L2421'><pre>2421</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre>"#;</pre></td></tr><tr><td class='line-number'><a name='L2422' href='#L2422'><pre>2422</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let mut stream = SourceStream::new("test.frm".to_string(), source);</pre></td></tr><tr><td class='line-number'><a name='L2423' href='#L2423'><pre>2423</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let (token_stream_opt, _) = tokenize(&mut stream).unpack();</pre></td></tr><tr><td class='line-number'><a name='L2424' href='#L2424'><pre>2424</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let token_stream = token_stream_opt.expect("Tokenization failed");</pre></td></tr><tr><td class='line-number'><a name='L2425' href='#L2425'><pre>2425</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let tokens = token_stream.into_tokens();</pre></td></tr><tr><td class='line-number'><a name='L2426' href='#L2426'><pre>2426</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2427' href='#L2427'><pre>2427</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let mut parser = Parser::new_direct_extraction(tokens, 0);</pre></td></tr><tr><td class='line-number'><a name='L2428' href='#L2428'><pre>2428</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let (control_opt, failures) = parser.parse_properties_block_to_control().unpack();</pre></td></tr><tr><td class='line-number'><a name='L2429' href='#L2429'><pre>2429</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2430' href='#L2430'><pre>2430</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert!(failures.is_empty());</pre></td></tr><tr><td class='line-number'><a name='L2431' href='#L2431'><pre>2431</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert!(control_opt.is_some());</pre></td></tr><tr><td class='line-number'><a name='L2432' href='#L2432'><pre>2432</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let control = control_opt.unwrap();</pre></td></tr><tr><td class='line-number'><a name='L2433' href='#L2433'><pre>2433</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert_eq!(control.name(), "Frame1");</pre></td></tr><tr><td class='line-number'><a name='L2434' href='#L2434'><pre>2434</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2435' href='#L2435'><pre>2435</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Check frame has 2 child checkboxes</pre></td></tr><tr><td class='line-number'><a name='L2436' href='#L2436'><pre>2436</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> if let crate::language::ControlKind::Frame { controls, .. } = control.kind() {</pre></td></tr><tr><td class='line-number'><a name='L2437' href='#L2437'><pre>2437</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert_eq!(controls.len(), 2);</pre></td></tr><tr><td class='line-number'><a name='L2438' href='#L2438'><pre>2438</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert_eq!(controls[0].name(), "Check1");</pre></td></tr><tr><td class='line-number'><a name='L2439' href='#L2439'><pre>2439</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert_eq!(controls[1].name(), "Check2");</pre></td></tr><tr><td class='line-number'><a name='L2440' href='#L2440'><pre>2440</pre></a></td><td class='skipped-line'></td><td class='code'><pre> } else {</pre></td></tr><tr><td class='line-number'><a name='L2441' href='#L2441'><pre>2441</pre></a></td><td class='uncovered-line'><pre>0</pre></td><td class='code'><pre> <span class='region red'>panic!</span>("Expected Frame control kind");</pre></td></tr><tr><td class='line-number'><a name='L2442' href='#L2442'><pre>2442</pre></a></td><td class='skipped-line'></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L2443' href='#L2443'><pre>2443</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L2444' href='#L2444'><pre>2444</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2445' href='#L2445'><pre>2445</pre></a></td><td class='skipped-line'></td><td class='code'><pre> #[test]</pre></td></tr><tr><td class='line-number'><a name='L2446' href='#L2446'><pre>2446</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> fn parse_control_with_property_group() {</pre></td></tr><tr><td class='line-number'><a name='L2447' href='#L2447'><pre>2447</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let source = r#"Begin VB.CommandButton Command1</pre></td></tr><tr><td class='line-number'><a name='L2448' href='#L2448'><pre>2448</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> Caption = "Button"</pre></td></tr><tr><td class='line-number'><a name='L2449' href='#L2449'><pre>2449</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> BeginProperty Font</pre></td></tr><tr><td class='line-number'><a name='L2450' href='#L2450'><pre>2450</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> Name = "Arial"</pre></td></tr><tr><td class='line-number'><a name='L2451' href='#L2451'><pre>2451</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> Size = 12</pre></td></tr><tr><td class='line-number'><a name='L2452' href='#L2452'><pre>2452</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> EndProperty</pre></td></tr><tr><td class='line-number'><a name='L2453' href='#L2453'><pre>2453</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre>End</pre></td></tr><tr><td class='line-number'><a name='L2454' href='#L2454'><pre>2454</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre>"#;</pre></td></tr><tr><td class='line-number'><a name='L2455' href='#L2455'><pre>2455</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let mut stream = SourceStream::new("test.frm".to_string(), source);</pre></td></tr><tr><td class='line-number'><a name='L2456' href='#L2456'><pre>2456</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let (token_stream_opt, _) = tokenize(&mut stream).unpack();</pre></td></tr><tr><td class='line-number'><a name='L2457' href='#L2457'><pre>2457</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let token_stream = token_stream_opt.expect("Tokenization failed");</pre></td></tr><tr><td class='line-number'><a name='L2458' href='#L2458'><pre>2458</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let tokens = token_stream.into_tokens();</pre></td></tr><tr><td class='line-number'><a name='L2459' href='#L2459'><pre>2459</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2460' href='#L2460'><pre>2460</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let mut parser = Parser::new_direct_extraction(tokens, 0);</pre></td></tr><tr><td class='line-number'><a name='L2461' href='#L2461'><pre>2461</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let (control_opt, failures) = parser.parse_properties_block_to_control().unpack();</pre></td></tr><tr><td class='line-number'><a name='L2462' href='#L2462'><pre>2462</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2463' href='#L2463'><pre>2463</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert!(failures.is_empty());</pre></td></tr><tr><td class='line-number'><a name='L2464' href='#L2464'><pre>2464</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert!(control_opt.is_some());</pre></td></tr><tr><td class='line-number'><a name='L2465' href='#L2465'><pre>2465</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let control = control_opt.unwrap();</pre></td></tr><tr><td class='line-number'><a name='L2466' href='#L2466'><pre>2466</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert_eq!(control.name(), "Command1");</pre></td></tr><tr><td class='line-number'><a name='L2467' href='#L2467'><pre>2467</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2468' href='#L2468'><pre>2468</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Check for property - CommandButton should have parsed successfully</pre></td></tr><tr><td class='line-number'><a name='L2469' href='#L2469'><pre>2469</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Property groups are stored in Custom control kind, not specific control types</pre></td></tr><tr><td class='line-number'><a name='L2470' href='#L2470'><pre>2470</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert!(<div class='tooltip'><span class='region red'>matches!</span><span class='tooltip-content'>0</span></div>(</pre></td></tr><tr><td class='line-number'><a name='L2471' href='#L2471'><pre>2471</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> control.kind(),</pre></td></tr><tr><td class='line-number'><a name='L2472' href='#L2472'><pre>2472</pre></a></td><td class='skipped-line'></td><td class='code'><pre> crate::language::ControlKind::CommandButton { .. }</pre></td></tr><tr><td class='line-number'><a name='L2473' href='#L2473'><pre>2473</pre></a></td><td class='skipped-line'></td><td class='code'><pre> ));</pre></td></tr><tr><td class='line-number'><a name='L2474' href='#L2474'><pre>2474</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L2475' href='#L2475'><pre>2475</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2476' href='#L2476'><pre>2476</pre></a></td><td class='skipped-line'></td><td class='code'><pre> #[test]</pre></td></tr><tr><td class='line-number'><a name='L2477' href='#L2477'><pre>2477</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> fn parse_custom_control_with_property_group() {</pre></td></tr><tr><td class='line-number'><a name='L2478' href='#L2478'><pre>2478</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let source = r#"Begin MSComctlLib.TreeView TreeView1</pre></td></tr><tr><td class='line-number'><a name='L2479' href='#L2479'><pre>2479</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> BeginProperty Font {0BE35203-8F91-11CE-9DE3-00AA004BB851}</pre></td></tr><tr><td class='line-number'><a name='L2480' href='#L2480'><pre>2480</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> Name = "MS Sans Serif"</pre></td></tr><tr><td class='line-number'><a name='L2481' href='#L2481'><pre>2481</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> Size = 8.25</pre></td></tr><tr><td class='line-number'><a name='L2482' href='#L2482'><pre>2482</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> Charset = 0</pre></td></tr><tr><td class='line-number'><a name='L2483' href='#L2483'><pre>2483</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> EndProperty</pre></td></tr><tr><td class='line-number'><a name='L2484' href='#L2484'><pre>2484</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> Caption = "Tree"</pre></td></tr><tr><td class='line-number'><a name='L2485' href='#L2485'><pre>2485</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre>End</pre></td></tr><tr><td class='line-number'><a name='L2486' href='#L2486'><pre>2486</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre>"#;</pre></td></tr><tr><td class='line-number'><a name='L2487' href='#L2487'><pre>2487</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let mut stream = SourceStream::new("test.frm".to_string(), source);</pre></td></tr><tr><td class='line-number'><a name='L2488' href='#L2488'><pre>2488</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let (token_stream_opt, _) = tokenize(&mut stream).unpack();</pre></td></tr><tr><td class='line-number'><a name='L2489' href='#L2489'><pre>2489</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let token_stream = token_stream_opt.expect("Tokenization failed");</pre></td></tr><tr><td class='line-number'><a name='L2490' href='#L2490'><pre>2490</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let tokens = token_stream.into_tokens();</pre></td></tr><tr><td class='line-number'><a name='L2491' href='#L2491'><pre>2491</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2492' href='#L2492'><pre>2492</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let mut parser = Parser::new_direct_extraction(tokens, 0);</pre></td></tr><tr><td class='line-number'><a name='L2493' href='#L2493'><pre>2493</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let (control_opt, failures) = parser.parse_properties_block_to_control().unpack();</pre></td></tr><tr><td class='line-number'><a name='L2494' href='#L2494'><pre>2494</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2495' href='#L2495'><pre>2495</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert!(failures.is_empty());</pre></td></tr><tr><td class='line-number'><a name='L2496' href='#L2496'><pre>2496</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert!(control_opt.is_some());</pre></td></tr><tr><td class='line-number'><a name='L2497' href='#L2497'><pre>2497</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let control = control_opt.unwrap();</pre></td></tr><tr><td class='line-number'><a name='L2498' href='#L2498'><pre>2498</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert_eq!(control.name(), "TreeView1");</pre></td></tr><tr><td class='line-number'><a name='L2499' href='#L2499'><pre>2499</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2500' href='#L2500'><pre>2500</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Check for Custom control with property groups</pre></td></tr><tr><td class='line-number'><a name='L2501' href='#L2501'><pre>2501</pre></a></td><td class='skipped-line'></td><td class='code'><pre> if let crate::language::ControlKind::Custom {</pre></td></tr><tr><td class='line-number'><a name='L2502' href='#L2502'><pre>2502</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> property_groups, ..</pre></td></tr><tr><td class='line-number'><a name='L2503' href='#L2503'><pre>2503</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> } = control.kind()</pre></td></tr><tr><td class='line-number'><a name='L2504' href='#L2504'><pre>2504</pre></a></td><td class='skipped-line'></td><td class='code'><pre> {</pre></td></tr><tr><td class='line-number'><a name='L2505' href='#L2505'><pre>2505</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert_eq!(property_groups.len(), 1);</pre></td></tr><tr><td class='line-number'><a name='L2506' href='#L2506'><pre>2506</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert_eq!(property_groups[0].name, "Font");</pre></td></tr><tr><td class='line-number'><a name='L2507' href='#L2507'><pre>2507</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert!(property_groups[0].guid.is_some());</pre></td></tr><tr><td class='line-number'><a name='L2508' href='#L2508'><pre>2508</pre></a></td><td class='skipped-line'></td><td class='code'><pre> } else {</pre></td></tr><tr><td class='line-number'><a name='L2509' href='#L2509'><pre>2509</pre></a></td><td class='uncovered-line'><pre>0</pre></td><td class='code'><pre> <span class='region red'>panic!</span>("Expected Custom control kind");</pre></td></tr><tr><td class='line-number'><a name='L2510' href='#L2510'><pre>2510</pre></a></td><td class='skipped-line'></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L2511' href='#L2511'><pre>2511</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L2512' href='#L2512'><pre>2512</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2513' href='#L2513'><pre>2513</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Phase 5 Tests: Direct Object Parsing</pre></td></tr><tr><td class='line-number'><a name='L2514' href='#L2514'><pre>2514</pre></a></td><td class='skipped-line'></td><td class='code'><pre> #[test]</pre></td></tr><tr><td class='line-number'><a name='L2515' href='#L2515'><pre>2515</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> fn parse_simple_object_statement() {</pre></td></tr><tr><td class='line-number'><a name='L2516' href='#L2516'><pre>2516</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let source = r#"Object = "{12345678-1234-1234-1234-123456789ABC}#1.0#0"; "MyLib.dll""#;</pre></td></tr><tr><td class='line-number'><a name='L2517' href='#L2517'><pre>2517</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let mut stream = SourceStream::new("test.frm".to_string(), source);</pre></td></tr><tr><td class='line-number'><a name='L2518' href='#L2518'><pre>2518</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let (token_stream_opt, _) = tokenize(&mut stream).unpack();</pre></td></tr><tr><td class='line-number'><a name='L2519' href='#L2519'><pre>2519</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let token_stream = token_stream_opt.expect("Tokenization failed");</pre></td></tr><tr><td class='line-number'><a name='L2520' href='#L2520'><pre>2520</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let tokens = token_stream.into_tokens();</pre></td></tr><tr><td class='line-number'><a name='L2521' href='#L2521'><pre>2521</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2522' href='#L2522'><pre>2522</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let mut parser = Parser::new_direct_extraction(tokens, 0);</pre></td></tr><tr><td class='line-number'><a name='L2523' href='#L2523'><pre>2523</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let objects = parser.parse_objects_direct();</pre></td></tr><tr><td class='line-number'><a name='L2524' href='#L2524'><pre>2524</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2525' href='#L2525'><pre>2525</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert_eq!(objects.len(), 1);</pre></td></tr><tr><td class='line-number'><a name='L2526' href='#L2526'><pre>2526</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> match &objects[0] {</pre></td></tr><tr><td class='line-number'><a name='L2527' href='#L2527'><pre>2527</pre></a></td><td class='skipped-line'></td><td class='code'><pre> crate::files::common::ObjectReference::Compiled {</pre></td></tr><tr><td class='line-number'><a name='L2528' href='#L2528'><pre>2528</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> uuid,</pre></td></tr><tr><td class='line-number'><a name='L2529' href='#L2529'><pre>2529</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> version,</pre></td></tr><tr><td class='line-number'><a name='L2530' href='#L2530'><pre>2530</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> unknown1,</pre></td></tr><tr><td class='line-number'><a name='L2531' href='#L2531'><pre>2531</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> file_name,</pre></td></tr><tr><td class='line-number'><a name='L2532' href='#L2532'><pre>2532</pre></a></td><td class='skipped-line'></td><td class='code'><pre> } => {</pre></td></tr><tr><td class='line-number'><a name='L2533' href='#L2533'><pre>2533</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert_eq!(</pre></td></tr><tr><td class='line-number'><a name='L2534' href='#L2534'><pre>2534</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> uuid.to_string().to_uppercase(),</pre></td></tr><tr><td class='line-number'><a name='L2535' href='#L2535'><pre>2535</pre></a></td><td class='skipped-line'></td><td class='code'><pre> "12345678-1234-1234-1234-123456789ABC"</pre></td></tr><tr><td class='line-number'><a name='L2536' href='#L2536'><pre>2536</pre></a></td><td class='skipped-line'></td><td class='code'><pre> );</pre></td></tr><tr><td class='line-number'><a name='L2537' href='#L2537'><pre>2537</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert_eq!(version, "1.0");</pre></td></tr><tr><td class='line-number'><a name='L2538' href='#L2538'><pre>2538</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert_eq!(unknown1, "0");</pre></td></tr><tr><td class='line-number'><a name='L2539' href='#L2539'><pre>2539</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert_eq!(file_name, "MyLib.dll");</pre></td></tr><tr><td class='line-number'><a name='L2540' href='#L2540'><pre>2540</pre></a></td><td class='skipped-line'></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L2541' href='#L2541'><pre>2541</pre></a></td><td class='skipped-line'></td><td class='code'><pre> crate::files::common::ObjectReference::Project { .. } => {</pre></td></tr><tr><td class='line-number'><a name='L2542' href='#L2542'><pre>2542</pre></a></td><td class='uncovered-line'><pre>0</pre></td><td class='code'><pre> <span class='region red'>panic!</span>("Expected Compiled object reference")</pre></td></tr><tr><td class='line-number'><a name='L2543' href='#L2543'><pre>2543</pre></a></td><td class='skipped-line'></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L2544' href='#L2544'><pre>2544</pre></a></td><td class='skipped-line'></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L2545' href='#L2545'><pre>2545</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L2546' href='#L2546'><pre>2546</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2547' href='#L2547'><pre>2547</pre></a></td><td class='skipped-line'></td><td class='code'><pre> #[test]</pre></td></tr><tr><td class='line-number'><a name='L2548' href='#L2548'><pre>2548</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> fn parse_multiple_object_statements() {</pre></td></tr><tr><td class='line-number'><a name='L2549' href='#L2549'><pre>2549</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let source = r#"Object = "{AAAAAAAA-AAAA-AAAA-AAAA-AAAAAAAAAAAA}#1.0#0"; "Lib1.dll"</pre></td></tr><tr><td class='line-number'><a name='L2550' href='#L2550'><pre>2550</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre>Object = "{BBBBBBBB-BBBB-BBBB-BBBB-BBBBBBBBBBBB}#2.0#1"; "Lib2.ocx"</pre></td></tr><tr><td class='line-number'><a name='L2551' href='#L2551'><pre>2551</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre>"#;</pre></td></tr><tr><td class='line-number'><a name='L2552' href='#L2552'><pre>2552</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let mut stream = SourceStream::new("test.frm".to_string(), source);</pre></td></tr><tr><td class='line-number'><a name='L2553' href='#L2553'><pre>2553</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let (token_stream_opt, _) = tokenize(&mut stream).unpack();</pre></td></tr><tr><td class='line-number'><a name='L2554' href='#L2554'><pre>2554</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let token_stream = token_stream_opt.expect("Tokenization failed");</pre></td></tr><tr><td class='line-number'><a name='L2555' href='#L2555'><pre>2555</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let tokens = token_stream.into_tokens();</pre></td></tr><tr><td class='line-number'><a name='L2556' href='#L2556'><pre>2556</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2557' href='#L2557'><pre>2557</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let mut parser = Parser::new_direct_extraction(tokens, 0);</pre></td></tr><tr><td class='line-number'><a name='L2558' href='#L2558'><pre>2558</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let objects = parser.parse_objects_direct();</pre></td></tr><tr><td class='line-number'><a name='L2559' href='#L2559'><pre>2559</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2560' href='#L2560'><pre>2560</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert_eq!(objects.len(), 2);</pre></td></tr><tr><td class='line-number'><a name='L2561' href='#L2561'><pre>2561</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2562' href='#L2562'><pre>2562</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> match &objects[0] {</pre></td></tr><tr><td class='line-number'><a name='L2563' href='#L2563'><pre>2563</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> crate::files::common::ObjectReference::Compiled { file_name, .. } => {</pre></td></tr><tr><td class='line-number'><a name='L2564' href='#L2564'><pre>2564</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert_eq!(file_name, "Lib1.dll");</pre></td></tr><tr><td class='line-number'><a name='L2565' href='#L2565'><pre>2565</pre></a></td><td class='skipped-line'></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L2566' href='#L2566'><pre>2566</pre></a></td><td class='skipped-line'></td><td class='code'><pre> crate::files::common::ObjectReference::Project { .. } => {</pre></td></tr><tr><td class='line-number'><a name='L2567' href='#L2567'><pre>2567</pre></a></td><td class='uncovered-line'><pre>0</pre></td><td class='code'><pre> <span class='region red'>panic!</span>("Expected Compiled object reference")</pre></td></tr><tr><td class='line-number'><a name='L2568' href='#L2568'><pre>2568</pre></a></td><td class='skipped-line'></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L2569' href='#L2569'><pre>2569</pre></a></td><td class='skipped-line'></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L2570' href='#L2570'><pre>2570</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2571' href='#L2571'><pre>2571</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> match &objects[1] {</pre></td></tr><tr><td class='line-number'><a name='L2572' href='#L2572'><pre>2572</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> crate::files::common::ObjectReference::Compiled { file_name, .. } => {</pre></td></tr><tr><td class='line-number'><a name='L2573' href='#L2573'><pre>2573</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert_eq!(file_name, "Lib2.ocx");</pre></td></tr><tr><td class='line-number'><a name='L2574' href='#L2574'><pre>2574</pre></a></td><td class='skipped-line'></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L2575' href='#L2575'><pre>2575</pre></a></td><td class='skipped-line'></td><td class='code'><pre> crate::files::common::ObjectReference::Project { .. } => {</pre></td></tr><tr><td class='line-number'><a name='L2576' href='#L2576'><pre>2576</pre></a></td><td class='uncovered-line'><pre>0</pre></td><td class='code'><pre> <span class='region red'>panic!</span>("Expected Compiled object reference")</pre></td></tr><tr><td class='line-number'><a name='L2577' href='#L2577'><pre>2577</pre></a></td><td class='skipped-line'></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L2578' href='#L2578'><pre>2578</pre></a></td><td class='skipped-line'></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L2579' href='#L2579'><pre>2579</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L2580' href='#L2580'><pre>2580</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2581' href='#L2581'><pre>2581</pre></a></td><td class='skipped-line'></td><td class='code'><pre> #[test]</pre></td></tr><tr><td class='line-number'><a name='L2582' href='#L2582'><pre>2582</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> fn parse_embedded_object_statement() {</pre></td></tr><tr><td class='line-number'><a name='L2583' href='#L2583'><pre>2583</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let source = r#"Object = *\G{87654321-4321-4321-4321-CBA987654321}#3.0#5; "Embedded.ocx""#;</pre></td></tr><tr><td class='line-number'><a name='L2584' href='#L2584'><pre>2584</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let mut stream = SourceStream::new("test.frm".to_string(), source);</pre></td></tr><tr><td class='line-number'><a name='L2585' href='#L2585'><pre>2585</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let (token_stream_opt, _) = tokenize(&mut stream).unpack();</pre></td></tr><tr><td class='line-number'><a name='L2586' href='#L2586'><pre>2586</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let token_stream = token_stream_opt.expect("Tokenization failed");</pre></td></tr><tr><td class='line-number'><a name='L2587' href='#L2587'><pre>2587</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let tokens = token_stream.into_tokens();</pre></td></tr><tr><td class='line-number'><a name='L2588' href='#L2588'><pre>2588</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2589' href='#L2589'><pre>2589</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let mut parser = Parser::new_direct_extraction(tokens, 0);</pre></td></tr><tr><td class='line-number'><a name='L2590' href='#L2590'><pre>2590</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let objects = parser.parse_objects_direct();</pre></td></tr><tr><td class='line-number'><a name='L2591' href='#L2591'><pre>2591</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2592' href='#L2592'><pre>2592</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert_eq!(objects.len(), 1);</pre></td></tr><tr><td class='line-number'><a name='L2593' href='#L2593'><pre>2593</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> match &objects[0] {</pre></td></tr><tr><td class='line-number'><a name='L2594' href='#L2594'><pre>2594</pre></a></td><td class='skipped-line'></td><td class='code'><pre> crate::files::common::ObjectReference::Compiled {</pre></td></tr><tr><td class='line-number'><a name='L2595' href='#L2595'><pre>2595</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> uuid,</pre></td></tr><tr><td class='line-number'><a name='L2596' href='#L2596'><pre>2596</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> version,</pre></td></tr><tr><td class='line-number'><a name='L2597' href='#L2597'><pre>2597</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> file_name,</pre></td></tr><tr><td class='line-number'><a name='L2598' href='#L2598'><pre>2598</pre></a></td><td class='skipped-line'></td><td class='code'><pre> ..</pre></td></tr><tr><td class='line-number'><a name='L2599' href='#L2599'><pre>2599</pre></a></td><td class='skipped-line'></td><td class='code'><pre> } => {</pre></td></tr><tr><td class='line-number'><a name='L2600' href='#L2600'><pre>2600</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert_eq!(</pre></td></tr><tr><td class='line-number'><a name='L2601' href='#L2601'><pre>2601</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> uuid.to_string().to_uppercase(),</pre></td></tr><tr><td class='line-number'><a name='L2602' href='#L2602'><pre>2602</pre></a></td><td class='skipped-line'></td><td class='code'><pre> "87654321-4321-4321-4321-CBA987654321"</pre></td></tr><tr><td class='line-number'><a name='L2603' href='#L2603'><pre>2603</pre></a></td><td class='skipped-line'></td><td class='code'><pre> );</pre></td></tr><tr><td class='line-number'><a name='L2604' href='#L2604'><pre>2604</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert_eq!(version, "3.0");</pre></td></tr><tr><td class='line-number'><a name='L2605' href='#L2605'><pre>2605</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert_eq!(file_name, "Embedded.ocx");</pre></td></tr><tr><td class='line-number'><a name='L2606' href='#L2606'><pre>2606</pre></a></td><td class='skipped-line'></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L2607' href='#L2607'><pre>2607</pre></a></td><td class='skipped-line'></td><td class='code'><pre> crate::files::common::ObjectReference::Project { .. } => {</pre></td></tr><tr><td class='line-number'><a name='L2608' href='#L2608'><pre>2608</pre></a></td><td class='uncovered-line'><pre>0</pre></td><td class='code'><pre> <span class='region red'>panic!</span>("Expected Compiled object reference")</pre></td></tr><tr><td class='line-number'><a name='L2609' href='#L2609'><pre>2609</pre></a></td><td class='skipped-line'></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L2610' href='#L2610'><pre>2610</pre></a></td><td class='skipped-line'></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L2611' href='#L2611'><pre>2611</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L2612' href='#L2612'><pre>2612</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2613' href='#L2613'><pre>2613</pre></a></td><td class='skipped-line'></td><td class='code'><pre> #[test]</pre></td></tr><tr><td class='line-number'><a name='L2614' href='#L2614'><pre>2614</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> fn parse_nested_property_groups() {</pre></td></tr><tr><td class='line-number'><a name='L2615' href='#L2615'><pre>2615</pre></a></td><td class='skipped-line'></td><td class='code'><pre> use either::Either;</pre></td></tr><tr><td class='line-number'><a name='L2616' href='#L2616'><pre>2616</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2617' href='#L2617'><pre>2617</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let source = r#"Begin Custom.Control Ctrl1</pre></td></tr><tr><td class='line-number'><a name='L2618' href='#L2618'><pre>2618</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> BeginProperty Outer</pre></td></tr><tr><td class='line-number'><a name='L2619' href='#L2619'><pre>2619</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> Value1 = "Test"</pre></td></tr><tr><td class='line-number'><a name='L2620' href='#L2620'><pre>2620</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> BeginProperty Inner</pre></td></tr><tr><td class='line-number'><a name='L2621' href='#L2621'><pre>2621</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> Value2 = "Nested"</pre></td></tr><tr><td class='line-number'><a name='L2622' href='#L2622'><pre>2622</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> EndProperty</pre></td></tr><tr><td class='line-number'><a name='L2623' href='#L2623'><pre>2623</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> EndProperty</pre></td></tr><tr><td class='line-number'><a name='L2624' href='#L2624'><pre>2624</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre>End</pre></td></tr><tr><td class='line-number'><a name='L2625' href='#L2625'><pre>2625</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre>"#;</pre></td></tr><tr><td class='line-number'><a name='L2626' href='#L2626'><pre>2626</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let mut stream = SourceStream::new("test.frm".to_string(), source);</pre></td></tr><tr><td class='line-number'><a name='L2627' href='#L2627'><pre>2627</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let (token_stream_opt, _) = tokenize(&mut stream).unpack();</pre></td></tr><tr><td class='line-number'><a name='L2628' href='#L2628'><pre>2628</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let token_stream = token_stream_opt.expect("Tokenization failed");</pre></td></tr><tr><td class='line-number'><a name='L2629' href='#L2629'><pre>2629</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let tokens = token_stream.into_tokens();</pre></td></tr><tr><td class='line-number'><a name='L2630' href='#L2630'><pre>2630</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2631' href='#L2631'><pre>2631</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let mut parser = Parser::new_direct_extraction(tokens, 0);</pre></td></tr><tr><td class='line-number'><a name='L2632' href='#L2632'><pre>2632</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let (control_opt, failures) = parser.parse_properties_block_to_control().unpack();</pre></td></tr><tr><td class='line-number'><a name='L2633' href='#L2633'><pre>2633</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2634' href='#L2634'><pre>2634</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert!(failures.is_empty());</pre></td></tr><tr><td class='line-number'><a name='L2635' href='#L2635'><pre>2635</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert!(control_opt.is_some());</pre></td></tr><tr><td class='line-number'><a name='L2636' href='#L2636'><pre>2636</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let control = control_opt.unwrap();</pre></td></tr><tr><td class='line-number'><a name='L2637' href='#L2637'><pre>2637</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2638' href='#L2638'><pre>2638</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Check for nested property groups</pre></td></tr><tr><td class='line-number'><a name='L2639' href='#L2639'><pre>2639</pre></a></td><td class='skipped-line'></td><td class='code'><pre> if let crate::language::ControlKind::Custom {</pre></td></tr><tr><td class='line-number'><a name='L2640' href='#L2640'><pre>2640</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> property_groups, ..</pre></td></tr><tr><td class='line-number'><a name='L2641' href='#L2641'><pre>2641</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> } = control.kind()</pre></td></tr><tr><td class='line-number'><a name='L2642' href='#L2642'><pre>2642</pre></a></td><td class='skipped-line'></td><td class='code'><pre> {</pre></td></tr><tr><td class='line-number'><a name='L2643' href='#L2643'><pre>2643</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert_eq!(property_groups.len(), 1);</pre></td></tr><tr><td class='line-number'><a name='L2644' href='#L2644'><pre>2644</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert_eq!(property_groups[0].name, "Outer");</pre></td></tr><tr><td class='line-number'><a name='L2645' href='#L2645'><pre>2645</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2646' href='#L2646'><pre>2646</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Check for nested group</pre></td></tr><tr><td class='line-number'><a name='L2647' href='#L2647'><pre>2647</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2648' href='#L2648'><pre>2648</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> if let Some(Either::Right(inner)) = property_groups[0].properties.get("Inner") {</pre></td></tr><tr><td class='line-number'><a name='L2649' href='#L2649'><pre>2649</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert_eq!(inner.name, "Inner");</pre></td></tr><tr><td class='line-number'><a name='L2650' href='#L2650'><pre>2650</pre></a></td><td class='skipped-line'></td><td class='code'><pre> } else {</pre></td></tr><tr><td class='line-number'><a name='L2651' href='#L2651'><pre>2651</pre></a></td><td class='uncovered-line'><pre>0</pre></td><td class='code'><pre> <span class='region red'>panic!</span>("Expected nested Inner property group");</pre></td></tr><tr><td class='line-number'><a name='L2652' href='#L2652'><pre>2652</pre></a></td><td class='skipped-line'></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L2653' href='#L2653'><pre>2653</pre></a></td><td class='skipped-line'></td><td class='code'><pre> } else {</pre></td></tr><tr><td class='line-number'><a name='L2654' href='#L2654'><pre>2654</pre></a></td><td class='uncovered-line'><pre>0</pre></td><td class='code'><pre> <span class='region red'>panic!</span>("Expected Custom control kind");</pre></td></tr><tr><td class='line-number'><a name='L2655' href='#L2655'><pre>2655</pre></a></td><td class='skipped-line'></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L2656' href='#L2656'><pre>2656</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L2657' href='#L2657'><pre>2657</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2658' href='#L2658'><pre>2658</pre></a></td><td class='skipped-line'></td><td class='code'><pre> #[test]</pre></td></tr><tr><td class='line-number'><a name='L2659' href='#L2659'><pre>2659</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> fn parse_deeply_nested_controls() {</pre></td></tr><tr><td class='line-number'><a name='L2660' href='#L2660'><pre>2660</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let source = r#"Begin VB.Form Form1</pre></td></tr><tr><td class='line-number'><a name='L2661' href='#L2661'><pre>2661</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> Caption = "Outer"</pre></td></tr><tr><td class='line-number'><a name='L2662' href='#L2662'><pre>2662</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> Begin VB.PictureBox Picture1</pre></td></tr><tr><td class='line-number'><a name='L2663' href='#L2663'><pre>2663</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> Begin VB.Frame Frame1</pre></td></tr><tr><td class='line-number'><a name='L2664' href='#L2664'><pre>2664</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> Begin VB.Label Label1</pre></td></tr><tr><td class='line-number'><a name='L2665' href='#L2665'><pre>2665</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> Caption = "Deep"</pre></td></tr><tr><td class='line-number'><a name='L2666' href='#L2666'><pre>2666</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> End</pre></td></tr><tr><td class='line-number'><a name='L2667' href='#L2667'><pre>2667</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> End</pre></td></tr><tr><td class='line-number'><a name='L2668' href='#L2668'><pre>2668</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> End</pre></td></tr><tr><td class='line-number'><a name='L2669' href='#L2669'><pre>2669</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre>End</pre></td></tr><tr><td class='line-number'><a name='L2670' href='#L2670'><pre>2670</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre>"#;</pre></td></tr><tr><td class='line-number'><a name='L2671' href='#L2671'><pre>2671</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let mut stream = SourceStream::new("test.frm".to_string(), source);</pre></td></tr><tr><td class='line-number'><a name='L2672' href='#L2672'><pre>2672</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let (token_stream_opt, _) = tokenize(&mut stream).unpack();</pre></td></tr><tr><td class='line-number'><a name='L2673' href='#L2673'><pre>2673</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let token_stream = token_stream_opt.expect("Tokenization failed");</pre></td></tr><tr><td class='line-number'><a name='L2674' href='#L2674'><pre>2674</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let tokens = token_stream.into_tokens();</pre></td></tr><tr><td class='line-number'><a name='L2675' href='#L2675'><pre>2675</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2676' href='#L2676'><pre>2676</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let mut parser = Parser::new_direct_extraction(tokens, 0);</pre></td></tr><tr><td class='line-number'><a name='L2677' href='#L2677'><pre>2677</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let (control_opt, failures) = parser.parse_properties_block_to_control().unpack();</pre></td></tr><tr><td class='line-number'><a name='L2678' href='#L2678'><pre>2678</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2679' href='#L2679'><pre>2679</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert!(failures.is_empty());</pre></td></tr><tr><td class='line-number'><a name='L2680' href='#L2680'><pre>2680</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert!(control_opt.is_some());</pre></td></tr><tr><td class='line-number'><a name='L2681' href='#L2681'><pre>2681</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let control = control_opt.unwrap();</pre></td></tr><tr><td class='line-number'><a name='L2682' href='#L2682'><pre>2682</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2683' href='#L2683'><pre>2683</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Verify deep nesting: Form > PictureBox > Frame > Label</pre></td></tr><tr><td class='line-number'><a name='L2684' href='#L2684'><pre>2684</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> if let crate::language::ControlKind::Form { controls, .. } = control.kind() {</pre></td></tr><tr><td class='line-number'><a name='L2685' href='#L2685'><pre>2685</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert_eq!(controls.len(), 1);</pre></td></tr><tr><td class='line-number'><a name='L2686' href='#L2686'><pre>2686</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> if let crate::language::ControlKind::PictureBox { controls, .. } = controls[0].kind() {</pre></td></tr><tr><td class='line-number'><a name='L2687' href='#L2687'><pre>2687</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert_eq!(controls.len(), 1);</pre></td></tr><tr><td class='line-number'><a name='L2688' href='#L2688'><pre>2688</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> if let crate::language::ControlKind::Frame { controls, .. } = controls[0].kind() {</pre></td></tr><tr><td class='line-number'><a name='L2689' href='#L2689'><pre>2689</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert_eq!(controls.len(), 1);</pre></td></tr><tr><td class='line-number'><a name='L2690' href='#L2690'><pre>2690</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert_eq!(controls[0].name(), "Label1");</pre></td></tr><tr><td class='line-number'><a name='L2691' href='#L2691'><pre>2691</pre></a></td><td class='skipped-line'></td><td class='code'><pre> } else {</pre></td></tr><tr><td class='line-number'><a name='L2692' href='#L2692'><pre>2692</pre></a></td><td class='uncovered-line'><pre>0</pre></td><td class='code'><pre> <span class='region red'>panic!</span>("Expected Frame");</pre></td></tr><tr><td class='line-number'><a name='L2693' href='#L2693'><pre>2693</pre></a></td><td class='skipped-line'></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L2694' href='#L2694'><pre>2694</pre></a></td><td class='skipped-line'></td><td class='code'><pre> } else {</pre></td></tr><tr><td class='line-number'><a name='L2695' href='#L2695'><pre>2695</pre></a></td><td class='uncovered-line'><pre>0</pre></td><td class='code'><pre> <span class='region red'>panic!</span>("Expected PictureBox");</pre></td></tr><tr><td class='line-number'><a name='L2696' href='#L2696'><pre>2696</pre></a></td><td class='skipped-line'></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L2697' href='#L2697'><pre>2697</pre></a></td><td class='skipped-line'></td><td class='code'><pre> } else {</pre></td></tr><tr><td class='line-number'><a name='L2698' href='#L2698'><pre>2698</pre></a></td><td class='uncovered-line'><pre>0</pre></td><td class='code'><pre> <span class='region red'>panic!</span>("Expected Form");</pre></td></tr><tr><td class='line-number'><a name='L2699' href='#L2699'><pre>2699</pre></a></td><td class='skipped-line'></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L2700' href='#L2700'><pre>2700</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L2701' href='#L2701'><pre>2701</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2702' href='#L2702'><pre>2702</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // Phase 6 Tests: Direct Attribute Parsing</pre></td></tr><tr><td class='line-number'><a name='L2703' href='#L2703'><pre>2703</pre></a></td><td class='skipped-line'></td><td class='code'><pre> #[test]</pre></td></tr><tr><td class='line-number'><a name='L2704' href='#L2704'><pre>2704</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> fn parse_simple_string_attribute() {</pre></td></tr><tr><td class='line-number'><a name='L2705' href='#L2705'><pre>2705</pre></a></td><td class='skipped-line'></td><td class='code'><pre> use crate::files::common::{Creatable, Exposed, NameSpace, PreDeclaredID};</pre></td></tr><tr><td class='line-number'><a name='L2706' href='#L2706'><pre>2706</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2707' href='#L2707'><pre>2707</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let source = r#"Attribute VB_Name = "Form1"</pre></td></tr><tr><td class='line-number'><a name='L2708' href='#L2708'><pre>2708</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre>"#;</pre></td></tr><tr><td class='line-number'><a name='L2709' href='#L2709'><pre>2709</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let mut stream = SourceStream::new("test.frm".to_string(), source);</pre></td></tr><tr><td class='line-number'><a name='L2710' href='#L2710'><pre>2710</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let (token_stream_opt, _) = tokenize(&mut stream).unpack();</pre></td></tr><tr><td class='line-number'><a name='L2711' href='#L2711'><pre>2711</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let token_stream = token_stream_opt.expect("Tokenization failed");</pre></td></tr><tr><td class='line-number'><a name='L2712' href='#L2712'><pre>2712</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let tokens = token_stream.into_tokens();</pre></td></tr><tr><td class='line-number'><a name='L2713' href='#L2713'><pre>2713</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2714' href='#L2714'><pre>2714</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let mut parser = Parser::new_direct_extraction(tokens, 0);</pre></td></tr><tr><td class='line-number'><a name='L2715' href='#L2715'><pre>2715</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let attrs = parser.parse_attributes_direct();</pre></td></tr><tr><td class='line-number'><a name='L2716' href='#L2716'><pre>2716</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2717' href='#L2717'><pre>2717</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert_eq!(attrs.name, "Form1");</pre></td></tr><tr><td class='line-number'><a name='L2718' href='#L2718'><pre>2718</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert_eq!(attrs.global_name_space, NameSpace::Local);</pre></td></tr><tr><td class='line-number'><a name='L2719' href='#L2719'><pre>2719</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert_eq!(attrs.creatable, Creatable::True);</pre></td></tr><tr><td class='line-number'><a name='L2720' href='#L2720'><pre>2720</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert_eq!(attrs.predeclared_id, PreDeclaredID::False);</pre></td></tr><tr><td class='line-number'><a name='L2721' href='#L2721'><pre>2721</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert_eq!(attrs.exposed, Exposed::False);</pre></td></tr><tr><td class='line-number'><a name='L2722' href='#L2722'><pre>2722</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert_eq!(attrs.description, None);</pre></td></tr><tr><td class='line-number'><a name='L2723' href='#L2723'><pre>2723</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L2724' href='#L2724'><pre>2724</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2725' href='#L2725'><pre>2725</pre></a></td><td class='skipped-line'></td><td class='code'><pre> #[test]</pre></td></tr><tr><td class='line-number'><a name='L2726' href='#L2726'><pre>2726</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> fn parse_boolean_attributes() {</pre></td></tr><tr><td class='line-number'><a name='L2727' href='#L2727'><pre>2727</pre></a></td><td class='skipped-line'></td><td class='code'><pre> use crate::files::common::{Creatable, Exposed, NameSpace, PreDeclaredID};</pre></td></tr><tr><td class='line-number'><a name='L2728' href='#L2728'><pre>2728</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2729' href='#L2729'><pre>2729</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let source = r"Attribute VB_GlobalNameSpace = False</pre></td></tr><tr><td class='line-number'><a name='L2730' href='#L2730'><pre>2730</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre>Attribute VB_Creatable = True</pre></td></tr><tr><td class='line-number'><a name='L2731' href='#L2731'><pre>2731</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre>Attribute VB_PredeclaredId = True</pre></td></tr><tr><td class='line-number'><a name='L2732' href='#L2732'><pre>2732</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre>Attribute VB_Exposed = False</pre></td></tr><tr><td class='line-number'><a name='L2733' href='#L2733'><pre>2733</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre>";</pre></td></tr><tr><td class='line-number'><a name='L2734' href='#L2734'><pre>2734</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let mut stream = SourceStream::new("test.frm".to_string(), source);</pre></td></tr><tr><td class='line-number'><a name='L2735' href='#L2735'><pre>2735</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let (token_stream_opt, _) = tokenize(&mut stream).unpack();</pre></td></tr><tr><td class='line-number'><a name='L2736' href='#L2736'><pre>2736</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let token_stream = token_stream_opt.expect("Tokenization failed");</pre></td></tr><tr><td class='line-number'><a name='L2737' href='#L2737'><pre>2737</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let tokens = token_stream.into_tokens();</pre></td></tr><tr><td class='line-number'><a name='L2738' href='#L2738'><pre>2738</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2739' href='#L2739'><pre>2739</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let mut parser = Parser::new_direct_extraction(tokens, 0);</pre></td></tr><tr><td class='line-number'><a name='L2740' href='#L2740'><pre>2740</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let attrs = parser.parse_attributes_direct();</pre></td></tr><tr><td class='line-number'><a name='L2741' href='#L2741'><pre>2741</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2742' href='#L2742'><pre>2742</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert_eq!(attrs.global_name_space, NameSpace::Local);</pre></td></tr><tr><td class='line-number'><a name='L2743' href='#L2743'><pre>2743</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert_eq!(attrs.creatable, Creatable::True);</pre></td></tr><tr><td class='line-number'><a name='L2744' href='#L2744'><pre>2744</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert_eq!(attrs.predeclared_id, PreDeclaredID::True);</pre></td></tr><tr><td class='line-number'><a name='L2745' href='#L2745'><pre>2745</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert_eq!(attrs.exposed, Exposed::False);</pre></td></tr><tr><td class='line-number'><a name='L2746' href='#L2746'><pre>2746</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L2747' href='#L2747'><pre>2747</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2748' href='#L2748'><pre>2748</pre></a></td><td class='skipped-line'></td><td class='code'><pre> #[test]</pre></td></tr><tr><td class='line-number'><a name='L2749' href='#L2749'><pre>2749</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> fn parse_numeric_attribute() {</pre></td></tr><tr><td class='line-number'><a name='L2750' href='#L2750'><pre>2750</pre></a></td><td class='skipped-line'></td><td class='code'><pre> use crate::files::common::PreDeclaredID;</pre></td></tr><tr><td class='line-number'><a name='L2751' href='#L2751'><pre>2751</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2752' href='#L2752'><pre>2752</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let source = r"Attribute VB_PredeclaredId = -1</pre></td></tr><tr><td class='line-number'><a name='L2753' href='#L2753'><pre>2753</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre>";</pre></td></tr><tr><td class='line-number'><a name='L2754' href='#L2754'><pre>2754</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let mut stream = SourceStream::new("test.frm".to_string(), source);</pre></td></tr><tr><td class='line-number'><a name='L2755' href='#L2755'><pre>2755</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let (token_stream_opt, _) = tokenize(&mut stream).unpack();</pre></td></tr><tr><td class='line-number'><a name='L2756' href='#L2756'><pre>2756</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let token_stream = token_stream_opt.expect("Tokenization failed");</pre></td></tr><tr><td class='line-number'><a name='L2757' href='#L2757'><pre>2757</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let tokens = token_stream.into_tokens();</pre></td></tr><tr><td class='line-number'><a name='L2758' href='#L2758'><pre>2758</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2759' href='#L2759'><pre>2759</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let mut parser = Parser::new_direct_extraction(tokens, 0);</pre></td></tr><tr><td class='line-number'><a name='L2760' href='#L2760'><pre>2760</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let attrs = parser.parse_attributes_direct();</pre></td></tr><tr><td class='line-number'><a name='L2761' href='#L2761'><pre>2761</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2762' href='#L2762'><pre>2762</pre></a></td><td class='skipped-line'></td><td class='code'><pre> // -1 is truthy in VB6, so should be parsed as true</pre></td></tr><tr><td class='line-number'><a name='L2763' href='#L2763'><pre>2763</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert_eq!(attrs.predeclared_id, PreDeclaredID::True);</pre></td></tr><tr><td class='line-number'><a name='L2764' href='#L2764'><pre>2764</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L2765' href='#L2765'><pre>2765</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2766' href='#L2766'><pre>2766</pre></a></td><td class='skipped-line'></td><td class='code'><pre> #[test]</pre></td></tr><tr><td class='line-number'><a name='L2767' href='#L2767'><pre>2767</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> fn parse_multiple_attributes() {</pre></td></tr><tr><td class='line-number'><a name='L2768' href='#L2768'><pre>2768</pre></a></td><td class='skipped-line'></td><td class='code'><pre> use crate::files::common::{Creatable, Exposed, NameSpace, PreDeclaredID};</pre></td></tr><tr><td class='line-number'><a name='L2769' href='#L2769'><pre>2769</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2770' href='#L2770'><pre>2770</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let source = r#"Attribute VB_Name = "MyForm"</pre></td></tr><tr><td class='line-number'><a name='L2771' href='#L2771'><pre>2771</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre>Attribute VB_GlobalNameSpace = False</pre></td></tr><tr><td class='line-number'><a name='L2772' href='#L2772'><pre>2772</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre>Attribute VB_Creatable = False</pre></td></tr><tr><td class='line-number'><a name='L2773' href='#L2773'><pre>2773</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre>Attribute VB_PredeclaredId = True</pre></td></tr><tr><td class='line-number'><a name='L2774' href='#L2774'><pre>2774</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre>Attribute VB_Exposed = False</pre></td></tr><tr><td class='line-number'><a name='L2775' href='#L2775'><pre>2775</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre>Attribute VB_Description = "This is a test form"</pre></td></tr><tr><td class='line-number'><a name='L2776' href='#L2776'><pre>2776</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre>"#;</pre></td></tr><tr><td class='line-number'><a name='L2777' href='#L2777'><pre>2777</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let mut stream = SourceStream::new("test.frm".to_string(), source);</pre></td></tr><tr><td class='line-number'><a name='L2778' href='#L2778'><pre>2778</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let (token_stream_opt, _) = tokenize(&mut stream).unpack();</pre></td></tr><tr><td class='line-number'><a name='L2779' href='#L2779'><pre>2779</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let token_stream = token_stream_opt.expect("Tokenization failed");</pre></td></tr><tr><td class='line-number'><a name='L2780' href='#L2780'><pre>2780</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let tokens = token_stream.into_tokens();</pre></td></tr><tr><td class='line-number'><a name='L2781' href='#L2781'><pre>2781</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2782' href='#L2782'><pre>2782</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let mut parser = Parser::new_direct_extraction(tokens, 0);</pre></td></tr><tr><td class='line-number'><a name='L2783' href='#L2783'><pre>2783</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let attrs = parser.parse_attributes_direct();</pre></td></tr><tr><td class='line-number'><a name='L2784' href='#L2784'><pre>2784</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2785' href='#L2785'><pre>2785</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert_eq!(attrs.name, "MyForm");</pre></td></tr><tr><td class='line-number'><a name='L2786' href='#L2786'><pre>2786</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert_eq!(attrs.global_name_space, NameSpace::Local);</pre></td></tr><tr><td class='line-number'><a name='L2787' href='#L2787'><pre>2787</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert_eq!(attrs.creatable, Creatable::False);</pre></td></tr><tr><td class='line-number'><a name='L2788' href='#L2788'><pre>2788</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert_eq!(attrs.predeclared_id, PreDeclaredID::True);</pre></td></tr><tr><td class='line-number'><a name='L2789' href='#L2789'><pre>2789</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert_eq!(attrs.exposed, Exposed::False);</pre></td></tr><tr><td class='line-number'><a name='L2790' href='#L2790'><pre>2790</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert_eq!(attrs.description, Some("This is a test form".to_string()));</pre></td></tr><tr><td class='line-number'><a name='L2791' href='#L2791'><pre>2791</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L2792' href='#L2792'><pre>2792</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2793' href='#L2793'><pre>2793</pre></a></td><td class='skipped-line'></td><td class='code'><pre> #[test]</pre></td></tr><tr><td class='line-number'><a name='L2794' href='#L2794'><pre>2794</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> fn parse_ext_key_attributes() {</pre></td></tr><tr><td class='line-number'><a name='L2795' href='#L2795'><pre>2795</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let source = r#"Attribute VB_Name = "Form1"</pre></td></tr><tr><td class='line-number'><a name='L2796' href='#L2796'><pre>2796</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre>Attribute VB_Ext_KEY = "CustomKey" ,"CustomValue"</pre></td></tr><tr><td class='line-number'><a name='L2797' href='#L2797'><pre>2797</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre>Attribute VB_Description = "Test"</pre></td></tr><tr><td class='line-number'><a name='L2798' href='#L2798'><pre>2798</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre>"#;</pre></td></tr><tr><td class='line-number'><a name='L2799' href='#L2799'><pre>2799</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let mut stream = SourceStream::new("test.frm".to_string(), source);</pre></td></tr><tr><td class='line-number'><a name='L2800' href='#L2800'><pre>2800</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let (token_stream_opt, _) = tokenize(&mut stream).unpack();</pre></td></tr><tr><td class='line-number'><a name='L2801' href='#L2801'><pre>2801</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let token_stream = token_stream_opt.expect("Tokenization failed");</pre></td></tr><tr><td class='line-number'><a name='L2802' href='#L2802'><pre>2802</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let tokens = token_stream.into_tokens();</pre></td></tr><tr><td class='line-number'><a name='L2803' href='#L2803'><pre>2803</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2804' href='#L2804'><pre>2804</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let mut parser = Parser::new_direct_extraction(tokens, 0);</pre></td></tr><tr><td class='line-number'><a name='L2805' href='#L2805'><pre>2805</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let attrs = parser.parse_attributes_direct();</pre></td></tr><tr><td class='line-number'><a name='L2806' href='#L2806'><pre>2806</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2807' href='#L2807'><pre>2807</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert_eq!(attrs.name, "Form1");</pre></td></tr><tr><td class='line-number'><a name='L2808' href='#L2808'><pre>2808</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert_eq!(attrs.description, Some("Test".to_string()));</pre></td></tr><tr><td class='line-number'><a name='L2809' href='#L2809'><pre>2809</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert_eq!(attrs.ext_key.len(), 1);</pre></td></tr><tr><td class='line-number'><a name='L2810' href='#L2810'><pre>2810</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert!(attrs.ext_key.contains_key("VB_Ext_KEY"));</pre></td></tr><tr><td class='line-number'><a name='L2811' href='#L2811'><pre>2811</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L2812' href='#L2812'><pre>2812</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2813' href='#L2813'><pre>2813</pre></a></td><td class='skipped-line'></td><td class='code'><pre> #[test]</pre></td></tr><tr><td class='line-number'><a name='L2814' href='#L2814'><pre>2814</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> fn parse_empty_attributes() {</pre></td></tr><tr><td class='line-number'><a name='L2815' href='#L2815'><pre>2815</pre></a></td><td class='skipped-line'></td><td class='code'><pre> use crate::files::common::{Creatable, Exposed, NameSpace, PreDeclaredID};</pre></td></tr><tr><td class='line-number'><a name='L2816' href='#L2816'><pre>2816</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2817' href='#L2817'><pre>2817</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let source = r"";</pre></td></tr><tr><td class='line-number'><a name='L2818' href='#L2818'><pre>2818</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let mut stream = SourceStream::new("test.frm".to_string(), source);</pre></td></tr><tr><td class='line-number'><a name='L2819' href='#L2819'><pre>2819</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let (token_stream_opt, _) = tokenize(&mut stream).unpack();</pre></td></tr><tr><td class='line-number'><a name='L2820' href='#L2820'><pre>2820</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let token_stream = token_stream_opt.expect("Tokenization failed");</pre></td></tr><tr><td class='line-number'><a name='L2821' href='#L2821'><pre>2821</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let tokens = token_stream.into_tokens();</pre></td></tr><tr><td class='line-number'><a name='L2822' href='#L2822'><pre>2822</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2823' href='#L2823'><pre>2823</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let mut parser = Parser::new_direct_extraction(tokens, 0);</pre></td></tr><tr><td class='line-number'><a name='L2824' href='#L2824'><pre>2824</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let attrs = parser.parse_attributes_direct();</pre></td></tr><tr><td class='line-number'><a name='L2825' href='#L2825'><pre>2825</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2826' href='#L2826'><pre>2826</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert_eq!(attrs.name, "");</pre></td></tr><tr><td class='line-number'><a name='L2827' href='#L2827'><pre>2827</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert_eq!(attrs.global_name_space, NameSpace::Local);</pre></td></tr><tr><td class='line-number'><a name='L2828' href='#L2828'><pre>2828</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert_eq!(attrs.creatable, Creatable::True);</pre></td></tr><tr><td class='line-number'><a name='L2829' href='#L2829'><pre>2829</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert_eq!(attrs.predeclared_id, PreDeclaredID::False);</pre></td></tr><tr><td class='line-number'><a name='L2830' href='#L2830'><pre>2830</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert_eq!(attrs.exposed, Exposed::False);</pre></td></tr><tr><td class='line-number'><a name='L2831' href='#L2831'><pre>2831</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert_eq!(attrs.description, None);</pre></td></tr><tr><td class='line-number'><a name='L2832' href='#L2832'><pre>2832</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert!(attrs.ext_key.is_empty());</pre></td></tr><tr><td class='line-number'><a name='L2833' href='#L2833'><pre>2833</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L2834' href='#L2834'><pre>2834</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2835' href='#L2835'><pre>2835</pre></a></td><td class='skipped-line'></td><td class='code'><pre> #[test]</pre></td></tr><tr><td class='line-number'><a name='L2836' href='#L2836'><pre>2836</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> fn parse_resource_reference_property() {</pre></td></tr><tr><td class='line-number'><a name='L2837' href='#L2837'><pre>2837</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let source = r#"Caption = $"Gradient.frx":0000</pre></td></tr><tr><td class='line-number'><a name='L2838' href='#L2838'><pre>2838</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre>"#;</pre></td></tr><tr><td class='line-number'><a name='L2839' href='#L2839'><pre>2839</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let mut stream = SourceStream::new("test.frm".to_string(), source);</pre></td></tr><tr><td class='line-number'><a name='L2840' href='#L2840'><pre>2840</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let (token_stream_opt, _) = tokenize(&mut stream).unpack();</pre></td></tr><tr><td class='line-number'><a name='L2841' href='#L2841'><pre>2841</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let token_stream = token_stream_opt.expect("Tokenization failed");</pre></td></tr><tr><td class='line-number'><a name='L2842' href='#L2842'><pre>2842</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let tokens = token_stream.into_tokens();</pre></td></tr><tr><td class='line-number'><a name='L2843' href='#L2843'><pre>2843</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2844' href='#L2844'><pre>2844</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let mut parser = Parser::new_direct_extraction(tokens, 0);</pre></td></tr><tr><td class='line-number'><a name='L2845' href='#L2845'><pre>2845</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let property = parser.parse_property_direct();</pre></td></tr><tr><td class='line-number'><a name='L2846' href='#L2846'><pre>2846</pre></a></td><td class='skipped-line'></td><td class='code'><pre></pre></td></tr><tr><td class='line-number'><a name='L2847' href='#L2847'><pre>2847</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert!(property.is_some());</pre></td></tr><tr><td class='line-number'><a name='L2848' href='#L2848'><pre>2848</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> let (key, value) = property.unwrap();</pre></td></tr><tr><td class='line-number'><a name='L2849' href='#L2849'><pre>2849</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert_eq!(key, "Caption");</pre></td></tr><tr><td class='line-number'><a name='L2850' href='#L2850'><pre>2850</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> assert_eq!(value, r#"$"Gradient.frx":0000"#);</pre></td></tr><tr><td class='line-number'><a name='L2851' href='#L2851'><pre>2851</pre></a></td><td class='covered-line'><pre>1</pre></td><td class='code'><pre> }</pre></td></tr><tr><td class='line-number'><a name='L2852' href='#L2852'><pre>2852</pre></a></td><td class='skipped-line'></td><td class='code'><pre>}</pre></td></tr></table></div></body></html>