(path: string)
| 494 | }; |
| 495 | |
| 496 | const parse = function parse(path: string): ParsedPath { |
| 497 | assertPath(path); |
| 498 | |
| 499 | const ret = { |
| 500 | root: '', |
| 501 | dir: '', |
| 502 | base: '', |
| 503 | ext: '', |
| 504 | name: '', |
| 505 | }; |
| 506 | if (path.length === 0) { |
| 507 | return ret; |
| 508 | } |
| 509 | let code = path.charCodeAt(0); |
| 510 | let start; |
| 511 | const isAbsolute = code === 47; /*/*/ |
| 512 | if (isAbsolute) { |
| 513 | ret.root = '/'; |
| 514 | start = 1; |
| 515 | } else { |
| 516 | start = 0; |
| 517 | } |
| 518 | let startDot = -1; |
| 519 | let startPart = 0; |
| 520 | let end = -1; |
| 521 | let matchedSlash = true; |
| 522 | let i = path.length - 1; |
| 523 | |
| 524 | // Track the state of characters (if any) we see before our first dot and |
| 525 | // after any path separator we find |
| 526 | let preDotState = 0; |
| 527 | |
| 528 | // Get non-dir info |
| 529 | for (; i >= start; --i) { |
| 530 | code = path.charCodeAt(i); |
| 531 | if (code === 47 /*/*/) { |
| 532 | // If we reached a path separator that was not part of a set of path |
| 533 | // separators at the end of the string, stop now |
| 534 | if (!matchedSlash) { |
| 535 | startPart = i + 1; |
| 536 | break; |
| 537 | } |
| 538 | continue; |
| 539 | } |
| 540 | if (end === -1) { |
| 541 | // We saw the first non-path separator, mark this as the end of our |
| 542 | // extension |
| 543 | matchedSlash = false; |
| 544 | end = i + 1; |
| 545 | } |
| 546 | if (code === 46 /*.*/) { |
| 547 | // If this is our first dot, mark it as the start of our extension |
| 548 | if (startDot === -1) { |
| 549 | startDot = i; |
| 550 | } else if (preDotState !== 1) { |
| 551 | preDotState = 1; |
| 552 | } |
| 553 | } else if (startDot !== -1) { |
nothing calls this directly
no test coverage detected
searching dependent graphs…