also looking at this
fix(scanner): leave line comments out when collapsing multi-line generics
#3119
2 files
+67
-9
| @@ -1389,28 +1389,41 @@ function scanDeclarationsInternal(_source: string, _filename: string, _keepComme | ||
| 1389 | 1389 | return rebased.join('\n') |
| 1390 | 1390 | } |
| 1391 | 1391 | |
| 1392 | /** Extract type parameters <...> (normalized to single line) */ | |
| 1392 | /** Extract type parameters <...>, whitespace outside literals and comments collapsed */ | |
| 1393 | 1393 | function extractGenerics(): string { |
| 1394 | 1394 | if (pos >= len || source.charCodeAt(pos) !== CH_LANGLE) |
| 1395 | 1395 | return '' |
| 1396 | 1396 | const start = pos |
| 1397 | 1397 | findMatchingClose(CH_LANGLE, CH_RANGLE) |
| 1398 | const raw = source.slice(start, pos) | |
| 1399 | // Normalize multi-line generics to single line (avoid regex) | |
| 1398 | const end = pos | |
| 1399 | const raw = source.slice(start, end) | |
| 1400 | // Normalize multi-line generics (avoid regex) | |
| 1400 | 1401 | if (raw.includes('\n')) { |
| 1401 | // Collapse whitespace/newlines to single spaces | |
| 1402 | // Collapse whitespace/newlines to single spaces. A `//` comment is left | |
| 1403 | // out: on one line it would comment out everything after it, the closing | |
| 1404 | // `>` included. Strings and block comments are copied as they are. | |
| 1402 | 1405 | let result = '' |
| 1403 | 1406 | let prevSpace = false |
| 1404 | for (let i = 0; i < raw.length; i++) { | |
| 1405 | const c = raw.charCodeAt(i) | |
| 1407 | pos = start | |
| 1408 | while (pos < end) { | |
| 1409 | const c = source.charCodeAt(pos) | |
| 1406 | 1410 | if (c === 32 || c === 9 || c === 10 || c === 13) { |
| 1407 | 1411 | if (!prevSpace && result.length > 0) { result += ' '; prevSpace = true } |
| 1412 | pos++ | |
| 1413 | continue | |
| 1408 | 1414 | } |
| 1409 | else { | |
| 1410 | result += raw[i] | |
| 1411 | prevSpace = false | |
| 1415 | if (c === CH_SLASH && source.charCodeAt(pos + 1) === CH_SLASH) { | |
| 1416 | const nl = source.indexOf('\n', pos + 2) | |
| 1417 | pos = nl === -1 || nl > end ? end : nl | |
| 1418 | continue | |
| 1412 | 1419 | } |
| 1420 | const from = pos | |
| 1421 | if (!skipNonCode()) | |
| 1422 | pos++ | |
| 1423 | result += source.slice(from, Math.min(pos, end)) | |
| 1424 | prevSpace = false | |
| 1413 | 1425 | } |
| 1426 | pos = end | |
| 1414 | 1427 | // Trim spaces around < and > |
| 1415 | 1428 | if (result.charCodeAt(1) === 32) result = `<${result.slice(2)}` |
| 1416 | 1429 | if (result.charCodeAt(result.length - 2) === 32) result = `${result.slice(0, -2)}>` |