(P: ParseState)
| 1883 | } |
| 1884 | |
| 1885 | function scanHeredocBodies(P: ParseState): void { |
| 1886 | // Skip to newline if not already there |
| 1887 | while (P.L.i < P.L.len && P.L.src[P.L.i] !== '\n') advance(P.L) |
| 1888 | if (P.L.i < P.L.len) advance(P.L) |
| 1889 | for (const hd of P.L.heredocs) { |
| 1890 | hd.bodyStart = P.L.b |
| 1891 | const delimLen = hd.delim.length |
| 1892 | while (P.L.i < P.L.len) { |
| 1893 | const lineStart = P.L.i |
| 1894 | const lineStartB = P.L.b |
| 1895 | // Skip leading tabs if <<- |
| 1896 | let checkI = lineStart |
| 1897 | if (hd.stripTabs) { |
| 1898 | while (checkI < P.L.len && P.L.src[checkI] === '\t') checkI++ |
| 1899 | } |
| 1900 | // Check if this line is the delimiter |
| 1901 | if ( |
| 1902 | P.L.src.startsWith(hd.delim, checkI) && |
| 1903 | (checkI + delimLen >= P.L.len || |
| 1904 | P.L.src[checkI + delimLen] === '\n' || |
| 1905 | P.L.src[checkI + delimLen] === '\r') |
| 1906 | ) { |
| 1907 | hd.bodyEnd = lineStartB |
| 1908 | // Advance past tabs |
| 1909 | while (P.L.i < checkI) advance(P.L) |
| 1910 | hd.endStart = P.L.b |
| 1911 | // Advance past delimiter |
| 1912 | for (let k = 0; k < delimLen; k++) advance(P.L) |
| 1913 | hd.endEnd = P.L.b |
| 1914 | // Skip trailing newline |
| 1915 | if (P.L.i < P.L.len && P.L.src[P.L.i] === '\n') advance(P.L) |
| 1916 | return |
| 1917 | } |
| 1918 | // Consume line |
| 1919 | while (P.L.i < P.L.len && P.L.src[P.L.i] !== '\n') advance(P.L) |
| 1920 | if (P.L.i < P.L.len) advance(P.L) |
| 1921 | } |
| 1922 | // Unterminated |
| 1923 | hd.bodyEnd = P.L.b |
| 1924 | hd.endStart = P.L.b |
| 1925 | hd.endEnd = P.L.b |
| 1926 | } |
| 1927 | } |
| 1928 | |
| 1929 | function parseHeredocBodyContent( |
| 1930 | P: ParseState, |
no test coverage detected