mirror of
https://github.com/hanzoai/esbuild.git
synced 2026-09-24 16:58:50 +00:00
149 lines
4.0 KiB
Go
149 lines
4.0 KiB
Go
package linker
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
|
|
"github.com/evanw/esbuild/internal/ast"
|
|
"github.com/evanw/esbuild/internal/graph"
|
|
"github.com/evanw/esbuild/internal/helpers"
|
|
"github.com/evanw/esbuild/internal/js_ast"
|
|
)
|
|
|
|
// Set this to true and then load the resulting metafile in "graph-debugger.html"
|
|
// to debug graph information.
|
|
//
|
|
// This is deliberately not exposed in the final binary. It is *very* internal
|
|
// and only exists to help debug esbuild itself. Make sure this is always set
|
|
// back to false before committing.
|
|
const debugVerboseMetafile = false
|
|
|
|
func (c *linkerContext) generateExtraDataForFileJS(sourceIndex uint32) string {
|
|
if !debugVerboseMetafile {
|
|
return ""
|
|
}
|
|
|
|
file := &c.graph.Files[sourceIndex]
|
|
repr := file.InputFile.Repr.(*graph.JSRepr)
|
|
sb := strings.Builder{}
|
|
isFirstPartWithStmts := true
|
|
|
|
quoteSym := func(ref ast.Ref) string {
|
|
name := fmt.Sprintf("%d:%d [%s]", ref.SourceIndex, ref.InnerIndex, c.graph.Symbols.Get(ref).OriginalName)
|
|
return string(helpers.QuoteForJSON(name, c.options.ASCIIOnly))
|
|
}
|
|
|
|
sb.WriteString(`,"parts":[`)
|
|
for partIndex, part := range repr.AST.Parts {
|
|
if partIndex > 0 {
|
|
sb.WriteByte(',')
|
|
}
|
|
var isFirst bool
|
|
code := ""
|
|
|
|
sb.WriteString(fmt.Sprintf(`{"isLive":%v`, part.IsLive))
|
|
sb.WriteString(fmt.Sprintf(`,"canBeRemovedIfUnused":%v`, part.CanBeRemovedIfUnused))
|
|
|
|
if partIndex == int(js_ast.NSExportPartIndex) {
|
|
sb.WriteString(`,"nsExportPartIndex":true`)
|
|
} else if ast.MakeIndex32(uint32(partIndex)) == repr.Meta.WrapperPartIndex {
|
|
sb.WriteString(`,"wrapperPartIndex":true`)
|
|
} else if len(part.Stmts) > 0 {
|
|
contents := file.InputFile.Source.Contents
|
|
start := int(part.Stmts[0].Loc.Start)
|
|
if isFirstPartWithStmts {
|
|
start = 0
|
|
isFirstPartWithStmts = false
|
|
}
|
|
end := len(contents)
|
|
if partIndex+1 < len(repr.AST.Parts) {
|
|
if nextStmts := repr.AST.Parts[partIndex+1].Stmts; len(nextStmts) > 0 {
|
|
if nextStart := int(nextStmts[0].Loc.Start); nextStart >= start {
|
|
end = int(nextStart)
|
|
}
|
|
}
|
|
}
|
|
start = moveBeforeExport(contents, start)
|
|
end = moveBeforeExport(contents, end)
|
|
code = contents[start:end]
|
|
}
|
|
|
|
// importRecords
|
|
sb.WriteString(`,"importRecords":[`)
|
|
isFirst = true
|
|
for _, importRecordIndex := range part.ImportRecordIndices {
|
|
record := repr.AST.ImportRecords[importRecordIndex]
|
|
if !record.SourceIndex.IsValid() {
|
|
continue
|
|
}
|
|
if isFirst {
|
|
isFirst = false
|
|
} else {
|
|
sb.WriteByte(',')
|
|
}
|
|
path := c.graph.Files[record.SourceIndex.GetIndex()].InputFile.Source.PrettyPaths.Rel
|
|
sb.WriteString(fmt.Sprintf(`{"source":%s}`, helpers.QuoteForJSON(path, c.options.ASCIIOnly)))
|
|
}
|
|
sb.WriteByte(']')
|
|
|
|
// declaredSymbols
|
|
sb.WriteString(`,"declaredSymbols":[`)
|
|
isFirst = true
|
|
for _, declSym := range part.DeclaredSymbols {
|
|
if !declSym.IsTopLevel {
|
|
continue
|
|
}
|
|
if isFirst {
|
|
isFirst = false
|
|
} else {
|
|
sb.WriteByte(',')
|
|
}
|
|
sb.WriteString(fmt.Sprintf(`{"name":%s}`, quoteSym(declSym.Ref)))
|
|
}
|
|
sb.WriteByte(']')
|
|
|
|
// symbolUses
|
|
sb.WriteString(`,"symbolUses":[`)
|
|
isFirst = true
|
|
for ref, uses := range part.SymbolUses {
|
|
if isFirst {
|
|
isFirst = false
|
|
} else {
|
|
sb.WriteByte(',')
|
|
}
|
|
sb.WriteString(fmt.Sprintf(`{"name":%s,"countEstimate":%d}`, quoteSym(ref), uses.CountEstimate))
|
|
}
|
|
sb.WriteByte(']')
|
|
|
|
// dependencies
|
|
sb.WriteString(`,"dependencies":[`)
|
|
for i, dep := range part.Dependencies {
|
|
if i > 0 {
|
|
sb.WriteByte(',')
|
|
}
|
|
sb.WriteString(fmt.Sprintf(`{"source":%s,"partIndex":%d}`,
|
|
helpers.QuoteForJSON(c.graph.Files[dep.SourceIndex].InputFile.Source.PrettyPaths.Rel, c.options.ASCIIOnly),
|
|
dep.PartIndex,
|
|
))
|
|
}
|
|
sb.WriteByte(']')
|
|
|
|
// code
|
|
sb.WriteString(`,"code":`)
|
|
sb.Write(helpers.QuoteForJSON(code, c.options.ASCIIOnly))
|
|
|
|
sb.WriteByte('}')
|
|
}
|
|
sb.WriteString(`]`)
|
|
|
|
return sb.String()
|
|
}
|
|
|
|
func moveBeforeExport(contents string, i int) int {
|
|
contents = strings.TrimRight(contents[:i], " \t\r\n")
|
|
if strings.HasSuffix(contents, "export") {
|
|
return len(contents) - 6
|
|
}
|
|
return i
|
|
}
|