* Find the matching `}` for the `{` at `openIdx`, skipping string literals and * comments so a brace inside `"{"` / `// }` doesn't throw off the count. * Returns the index of the closing brace, or -1 if unbalanced.
(src: string, openIdx: number)
| 190 | * Returns the index of the closing brace, or -1 if unbalanced. |
| 191 | */ |
| 192 | private matchBrace(src: string, openIdx: number): number { |
| 193 | let depth = 0; |
| 194 | for (let i = openIdx; i < src.length; i++) { |
| 195 | const ch = src[i]; |
| 196 | if (ch === '"' || ch === "'") { |
| 197 | const quote = ch; |
| 198 | i++; |
| 199 | while (i < src.length && src[i] !== quote) { |
| 200 | if (src[i] === '\\') i++; |
| 201 | i++; |
| 202 | } |
| 203 | continue; |
| 204 | } |
| 205 | if (ch === '/' && src[i + 1] === '/') { |
| 206 | while (i < src.length && src[i] !== '\n') i++; |
| 207 | continue; |
| 208 | } |
| 209 | if (ch === '/' && src[i + 1] === '*') { |
| 210 | i += 2; |
| 211 | while (i < src.length && !(src[i] === '*' && src[i + 1] === '/')) i++; |
| 212 | i++; |
| 213 | continue; |
| 214 | } |
| 215 | if (ch === '{') depth++; |
| 216 | else if (ch === '}') { |
| 217 | depth--; |
| 218 | if (depth === 0) return i; |
| 219 | } |
| 220 | } |
| 221 | return -1; |
| 222 | } |
| 223 | |
| 224 | /** `@code { … }` / `@functions { … }` (Blazor) and `@{ … }` (Razor) C# blocks. */ |
| 225 | private extractCodeBlocks(): Array<{ content: string; lineOffset: number }> { |