mirror of
https://github.com/zhigang1992/esbuild.git
synced 2026-04-29 09:55:58 +08:00
enable hashes in entry file paths (#1001)
This commit is contained in:
@@ -3,6 +3,8 @@ package sourcemap
|
||||
import (
|
||||
"bytes"
|
||||
"unicode/utf8"
|
||||
|
||||
"github.com/evanw/esbuild/internal/helpers"
|
||||
)
|
||||
|
||||
type Mapping struct {
|
||||
@@ -184,6 +186,19 @@ type LineColumnOffset struct {
|
||||
Columns int
|
||||
}
|
||||
|
||||
func (a LineColumnOffset) ComesBefore(b LineColumnOffset) bool {
|
||||
return a.Lines < b.Lines || (a.Lines == b.Lines && a.Columns < b.Columns)
|
||||
}
|
||||
|
||||
func (a *LineColumnOffset) Add(b LineColumnOffset) {
|
||||
if b.Lines == 0 {
|
||||
a.Columns += b.Columns
|
||||
} else {
|
||||
a.Lines += b.Lines
|
||||
a.Columns = b.Columns
|
||||
}
|
||||
}
|
||||
|
||||
func (offset *LineColumnOffset) AdvanceBytes(bytes []byte) {
|
||||
columns := offset.Columns
|
||||
for len(bytes) > 0 {
|
||||
@@ -237,3 +252,109 @@ func (offset *LineColumnOffset) AdvanceString(text string) {
|
||||
}
|
||||
offset.Columns = columns
|
||||
}
|
||||
|
||||
type SourceMapPieces struct {
|
||||
Prefix []byte
|
||||
Mappings []byte
|
||||
Suffix []byte
|
||||
}
|
||||
|
||||
type SourceMapShift struct {
|
||||
Before LineColumnOffset
|
||||
After LineColumnOffset
|
||||
}
|
||||
|
||||
func (pieces SourceMapPieces) Finalize(shifts []SourceMapShift) []byte {
|
||||
// An optimized path for when there are no shifts
|
||||
if len(shifts) == 1 {
|
||||
bytes := pieces.Prefix
|
||||
minCap := len(bytes) + len(pieces.Mappings) + len(pieces.Suffix)
|
||||
if cap(bytes) < minCap {
|
||||
bytes = append(make([]byte, 0, minCap), bytes...)
|
||||
}
|
||||
bytes = append(bytes, pieces.Mappings...)
|
||||
bytes = append(bytes, pieces.Suffix...)
|
||||
return bytes
|
||||
}
|
||||
|
||||
startOfRun := 0
|
||||
current := 0
|
||||
generated := LineColumnOffset{}
|
||||
prevShiftColumnDelta := 0
|
||||
j := helpers.Joiner{}
|
||||
|
||||
// Start the source map
|
||||
j.AddBytes(pieces.Prefix)
|
||||
|
||||
// This assumes that a) all mappings are valid and b) all mappings are ordered
|
||||
// by increasing generated position. This should be the case for all mappings
|
||||
// generated by esbuild, which should be the only mappings we process here.
|
||||
for current < len(pieces.Mappings) {
|
||||
// Handle a line break
|
||||
if pieces.Mappings[current] == ';' {
|
||||
generated.Lines++
|
||||
generated.Columns = 0
|
||||
prevShiftColumnDelta = 0
|
||||
current++
|
||||
continue
|
||||
}
|
||||
|
||||
potentialEndOfRun := current
|
||||
|
||||
// Read the generated column
|
||||
generatedColumnDelta, next := DecodeVLQ(pieces.Mappings, current)
|
||||
generated.Columns += generatedColumnDelta
|
||||
current = next
|
||||
|
||||
potentialStartOfRun := current
|
||||
|
||||
// Skip over the original position information
|
||||
_, current = DecodeVLQ(pieces.Mappings, current) // The original source
|
||||
_, current = DecodeVLQ(pieces.Mappings, current) // The original line
|
||||
_, current = DecodeVLQ(pieces.Mappings, current) // The original column
|
||||
|
||||
// Skip a trailing comma
|
||||
if current < len(pieces.Mappings) && pieces.Mappings[current] == ',' {
|
||||
current++
|
||||
}
|
||||
|
||||
// Detect crossing shift boundaries
|
||||
didCrossBoundary := false
|
||||
for len(shifts) > 1 && shifts[1].Before.ComesBefore(generated) {
|
||||
shifts = shifts[1:]
|
||||
didCrossBoundary = true
|
||||
}
|
||||
if !didCrossBoundary {
|
||||
continue
|
||||
}
|
||||
|
||||
// This shift isn't relevant if the next mapping after this shift is on a
|
||||
// following line. In that case, don't split and keep scanning instead.
|
||||
shift := shifts[0]
|
||||
if shift.After.Lines != generated.Lines {
|
||||
continue
|
||||
}
|
||||
|
||||
// Add all previous mappings in a single run for efficiency. Since source
|
||||
// mappings are relative, no data needs to be modified inside this run.
|
||||
j.AddBytes(pieces.Mappings[startOfRun:potentialEndOfRun])
|
||||
|
||||
// Then modify the first mapping across the shift boundary with the updated
|
||||
// generated column value. It's simplest to only support column shifts. This
|
||||
// is reasonable because import paths should not contain newlines.
|
||||
if shift.Before.Lines != shift.After.Lines {
|
||||
panic("Unexpected line change when shifting source maps")
|
||||
}
|
||||
shiftColumnDelta := shift.After.Columns - shift.Before.Columns
|
||||
j.AddBytes(EncodeVLQ(generatedColumnDelta + shiftColumnDelta - prevShiftColumnDelta))
|
||||
prevShiftColumnDelta = shiftColumnDelta
|
||||
|
||||
// Finally, start the next run after the end of this generated column offset
|
||||
startOfRun = potentialStartOfRun
|
||||
}
|
||||
|
||||
// Finish the source map
|
||||
j.AddBytes(pieces.Mappings[startOfRun:])
|
||||
j.AddBytes(pieces.Suffix)
|
||||
return j.Done()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user