133 lines
3.6 KiB
Go
133 lines
3.6 KiB
Go
|
package bundler
|
||
|
|
||
|
import (
|
||
|
"fmt"
|
||
|
"strings"
|
||
|
|
||
|
"github.com/evanw/esbuild/internal/ast"
|
||
|
"github.com/evanw/esbuild/internal/graph"
|
||
|
"github.com/evanw/esbuild/internal/js_ast"
|
||
|
"github.com/evanw/esbuild/internal/js_printer"
|
||
|
)
|
||
|
|
||
|
// 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{}
|
||
|
|
||
|
quoteSym := func(ref js_ast.Ref) string {
|
||
|
name := fmt.Sprintf("%d:%d [%s]", ref.SourceIndex, ref.InnerIndex, c.graph.Symbols.Get(ref).OriginalName)
|
||
|
return string(js_printer.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 {
|
||
|
start := part.Stmts[0].Loc.Start
|
||
|
end := len(file.InputFile.Source.Contents)
|
||
|
if partIndex+1 < len(repr.AST.Parts) {
|
||
|
if nextStmts := repr.AST.Parts[partIndex+1].Stmts; len(nextStmts) > 0 {
|
||
|
if nextStart := nextStmts[0].Loc.Start; nextStart >= start {
|
||
|
end = int(nextStart)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
code = file.InputFile.Source.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.PrettyPath
|
||
|
sb.WriteString(fmt.Sprintf(`{"source":%s}`, js_printer.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}`,
|
||
|
js_printer.QuoteForJSON(c.graph.Files[dep.SourceIndex].InputFile.Source.PrettyPath, c.options.ASCIIOnly),
|
||
|
dep.PartIndex,
|
||
|
))
|
||
|
}
|
||
|
sb.WriteByte(']')
|
||
|
|
||
|
// code
|
||
|
sb.WriteString(`,"code":`)
|
||
|
sb.Write(js_printer.QuoteForJSON(strings.TrimRight(code, "\n"), c.options.ASCIIOnly))
|
||
|
|
||
|
sb.WriteByte('}')
|
||
|
}
|
||
|
sb.WriteString(`]`)
|
||
|
|
||
|
return sb.String()
|
||
|
}
|