js_ast

package
v0.13.8 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 17, 2021 License: MIT Imports: 5 Imported by: 0

Documentation

Index

Constants

View Source
const NSExportPartIndex = uint32(0)

This is the index to the automatically-generated part containing code that calls "__export(exports, { ... getters ... })". This is used to generate getters on an exports object for ES6 export statements, and is both for ES6 star imports and CommonJS-style modules. All files have one of these, although it may contain no statements if there is nothing to export.

Variables

View Source
var BMissingShared = &BMissing{}

These help reduce unnecessary memory allocations

View Source
var DefaultNameMinifier = NameMinifier{
	// contains filtered or unexported fields
}
View Source
var EImportMetaShared = &EImportMeta{}
View Source
var EMissingShared = &EMissing{}
View Source
var ENullShared = &ENull{}
View Source
var ESuperShared = &ESuper{}
View Source
var EThisShared = &EThis{}
View Source
var EUndefinedShared = &EUndefined{}
View Source
var OpTable = []opTableEntry{

	{"+", LPrefix, false},
	{"-", LPrefix, false},
	{"~", LPrefix, false},
	{"!", LPrefix, false},
	{"void", LPrefix, true},
	{"typeof", LPrefix, true},
	{"delete", LPrefix, true},

	{"--", LPrefix, false},
	{"++", LPrefix, false},

	{"--", LPostfix, false},
	{"++", LPostfix, false},

	{"+", LAdd, false},
	{"-", LAdd, false},
	{"*", LMultiply, false},
	{"/", LMultiply, false},
	{"%", LMultiply, false},
	{"**", LExponentiation, false},
	{"<", LCompare, false},
	{"<=", LCompare, false},
	{">", LCompare, false},
	{">=", LCompare, false},
	{"in", LCompare, true},
	{"instanceof", LCompare, true},
	{"<<", LShift, false},
	{">>", LShift, false},
	{">>>", LShift, false},
	{"==", LEquals, false},
	{"!=", LEquals, false},
	{"===", LEquals, false},
	{"!==", LEquals, false},
	{"??", LNullishCoalescing, false},
	{"||", LLogicalOr, false},
	{"&&", LLogicalAnd, false},
	{"|", LBitwiseOr, false},
	{"&", LBitwiseAnd, false},
	{"^", LBitwiseXor, false},

	{",", LComma, false},

	{"=", LAssign, false},
	{"+=", LAssign, false},
	{"-=", LAssign, false},
	{"*=", LAssign, false},
	{"/=", LAssign, false},
	{"%=", LAssign, false},
	{"**=", LAssign, false},
	{"<<=", LAssign, false},
	{">>=", LAssign, false},
	{">>>=", LAssign, false},
	{"|=", LAssign, false},
	{"&=", LAssign, false},
	{"^=", LAssign, false},
	{"??=", LAssign, false},
	{"||=", LAssign, false},
	{"&&=", LAssign, false},
}

Functions

func EnsureValidIdentifier added in v0.8.27

func EnsureValidIdentifier(base string) string

func FollowAllSymbols

func FollowAllSymbols(symbols SymbolMap)

Use this before calling "FollowSymbols" from separate threads to avoid concurrent map update hazards. In Go, mutating a map is not threadsafe but reading from a map is. Calling "FollowAllSymbols" first ensures that all mutation is done up front.

func GenerateNonUniqueNameFromPath

func GenerateNonUniqueNameFromPath(path string) string

For readability, the names of certain automatically-generated symbols are derived from the file name. For example, instead of the CommonJS wrapper for a file being called something like "require273" it can be called something like "require_react" instead. This function generates the part of these identifiers that's specific to the file path. It can take both an absolute path (OS-specific) and a path in the source code (OS-independent).

Note that these generated names do not at all relate to the correctness of the code as far as avoiding symbol name collisions. These names still go through the renaming logic that all other symbols go through to avoid name collisions.

func IsBooleanValue

func IsBooleanValue(a Expr) bool

func IsNumericValue added in v0.8.30

func IsNumericValue(a Expr) bool

func IsOptionalChain added in v0.8.48

func IsOptionalChain(value Expr) bool

func IsStringValue added in v0.8.30

func IsStringValue(a Expr) bool

func IsSuperCall

func IsSuperCall(stmt Stmt) bool

Types

type AST

type AST struct {
	ApproximateLineCount  int32
	NestedScopeSlotCounts SlotCounts
	HasLazyExport         bool

	// This is a list of CommonJS features. When a file uses CommonJS features,
	// it's not a candidate for "flat bundling" and must be wrapped in its own
	// closure. Note that this also includes top-level "return" but these aren't
	// here because only the parser checks those.
	UsesExportsRef bool
	UsesModuleRef  bool
	ExportsKind    ExportsKind

	// This is a list of ES6 features. They are ranges instead of booleans so
	// that they can be used in log messages. Check to see if "Len > 0".
	ImportKeyword        logger.Range // Does not include TypeScript-specific syntax or "import()"
	ExportKeyword        logger.Range // Does not include TypeScript-specific syntax
	TopLevelAwaitKeyword logger.Range

	Hashbang    string
	Directive   string
	URLForCSS   string
	Parts       []Part
	Symbols     []Symbol
	ModuleScope *Scope
	CharFreq    *CharFreq
	ExportsRef  Ref
	ModuleRef   Ref
	WrapperRef  Ref

	// These are stored at the AST level instead of on individual AST nodes so
	// they can be manipulated efficiently without a full AST traversal
	ImportRecords []ast.ImportRecord

	// These are used when bundling. They are filled in during the parser pass
	// since we already have to traverse the AST then anyway and the parser pass
	// is conveniently fully parallelized.
	NamedImports            map[Ref]NamedImport
	NamedExports            map[string]NamedExport
	ExportStarImportRecords []uint32

	// Note: If you're in the linker, do not use this map directly. This map is
	// filled in by the parser and is considered immutable. For performance reasons,
	// the linker doesn't mutate this map (cloning a map is slow in Go). Instead the
	// linker super-imposes relevant information on top in a method call. You should
	// call "TopLevelSymbolToParts" instead.
	TopLevelSymbolToPartsFromParser map[Ref][]uint32

	SourceMapComment logger.Span
}

type Arg

type Arg struct {
	TSDecorators []Expr
	Binding      Binding
	DefaultOrNil Expr

	// "constructor(public x: boolean) {}"
	IsTypeScriptCtorField bool
}

type ArrayBinding

type ArrayBinding struct {
	Binding           Binding
	DefaultValueOrNil Expr
}

type AssignTarget

type AssignTarget uint8
const (
	AssignTargetNone    AssignTarget = iota
	AssignTargetReplace              // "a = b"
	AssignTargetUpdate               // "a += b"
)

type B

type B interface {
	// contains filtered or unexported methods
}

This interface is never called. Its purpose is to encode a variant type in Go's type system.

type BArray

type BArray struct {
	Items        []ArrayBinding
	HasSpread    bool
	IsSingleLine bool
}

type BIdentifier

type BIdentifier struct{ Ref Ref }

type BMissing

type BMissing struct{}

type BObject

type BObject struct {
	Properties   []PropertyBinding
	IsSingleLine bool
}

type Binding

type Binding struct {
	Loc  logger.Loc
	Data B
}

type Case

type Case struct {
	ValueOrNil Expr // If this is nil, this is "default" instead of "case"
	Body       []Stmt
}

type Catch

type Catch struct {
	Loc          logger.Loc
	BindingOrNil Binding
	Body         []Stmt
}

type CharFreq

type CharFreq [64]int32

This is a histogram of character frequencies for minification

func (*CharFreq) Compile

func (freq *CharFreq) Compile() NameMinifier

func (*CharFreq) Include

func (freq *CharFreq) Include(other *CharFreq)

func (*CharFreq) Scan

func (freq *CharFreq) Scan(text string, delta int32)

type Class

type Class struct {
	ClassKeyword logger.Range
	TSDecorators []Expr
	Name         *LocRef
	ExtendsOrNil Expr
	BodyLoc      logger.Loc
	Properties   []Property
}

type ClauseItem

type ClauseItem struct {
	Alias    string
	AliasLoc logger.Loc
	Name     LocRef

	// This is the original name of the symbol stored in "Name". It's needed for
	// "SExportClause" statements such as this:
	//
	//   export {foo as bar} from 'path'
	//
	// In this case both "foo" and "bar" are aliases because it's a re-export.
	// We need to preserve both aliases in case the symbol is renamed. In this
	// example, "foo" is "OriginalName" and "bar" is "Alias".
	OriginalName string
}

type Comment

type Comment struct {
	Loc  logger.Loc
	Text string
}

type Decl

type Decl struct {
	Binding    Binding
	ValueOrNil Expr
}

type DeclaredSymbol

type DeclaredSymbol struct {
	Ref        Ref
	IsTopLevel bool
}

type Dependency added in v0.11.3

type Dependency struct {
	SourceIndex uint32
	PartIndex   uint32
}

type E

type E interface {
	// contains filtered or unexported methods
}

This interface is never called. Its purpose is to encode a variant type in Go's type system.

type EArray

type EArray struct {
	Items            []Expr
	CommaAfterSpread logger.Loc
	IsSingleLine     bool
	IsParenthesized  bool
}

type EArrow

type EArrow struct {
	Args []Arg
	Body FnBody

	IsAsync    bool
	HasRestArg bool
	PreferExpr bool // Use shorthand if true and "Body" is a single return statement
}

type EAwait

type EAwait struct {
	Value Expr
}

type EBigInt

type EBigInt struct{ Value string }

type EBinary

type EBinary struct {
	Left  Expr
	Right Expr
	Op    OpCode
}

type EBoolean

type EBoolean struct{ Value bool }

type ECall

type ECall struct {
	Target        Expr
	Args          []Expr
	OptionalChain OptionalChain
	IsDirectEval  bool

	// True if there is a comment containing "@__PURE__" or "#__PURE__" preceding
	// this call expression. This is an annotation used for tree shaking, and
	// means that the call can be removed if it's unused. It does not mean the
	// call is pure (e.g. it may still return something different if called twice).
	//
	// Note that the arguments are not considered to be part of the call. If the
	// call itself is removed due to this annotation, the arguments must remain
	// if they have side effects.
	CanBeUnwrappedIfUnused bool
}

func (*ECall) HasSameFlagsAs

func (a *ECall) HasSameFlagsAs(b *ECall) bool

type EClass

type EClass struct{ Class Class }

type EDot

type EDot struct {
	Target        Expr
	Name          string
	NameLoc       logger.Loc
	OptionalChain OptionalChain

	// If true, this property access is known to be free of side-effects. That
	// means it can be removed if the resulting value isn't used.
	CanBeRemovedIfUnused bool

	// If true, this property access is a function that, when called, can be
	// unwrapped if the resulting value is unused. Unwrapping means discarding
	// the call target but keeping any arguments with side effects.
	CallCanBeUnwrappedIfUnused bool
}

func (*EDot) HasSameFlagsAs

func (a *EDot) HasSameFlagsAs(b *EDot) bool

type EFunction

type EFunction struct{ Fn Fn }

type EIdentifier

type EIdentifier struct {
	Ref Ref

	// If we're inside a "with" statement, this identifier may be a property
	// access. In that case it would be incorrect to remove this identifier since
	// the property access may be a getter or setter with side effects.
	MustKeepDueToWithStmt bool

	// If true, this identifier is known to not have a side effect (i.e. to not
	// throw an exception) when referenced. If false, this identifier may or may
	// not have side effects when referenced. This is used to allow the removal
	// of known globals such as "Object" if they aren't used.
	CanBeRemovedIfUnused bool

	// If true, this identifier represents a function that, when called, can be
	// unwrapped if the resulting value is unused. Unwrapping means discarding
	// the call target but keeping any arguments with side effects.
	CallCanBeUnwrappedIfUnused bool
}

type EIf

type EIf struct {
	Test Expr
	Yes  Expr
	No   Expr
}

type EImportCall added in v0.11.22

type EImportCall struct {
	Expr         Expr
	OptionsOrNil Expr

	// See the comment for this same field on "EImportCall" for more information
	LeadingInteriorComments []Comment
}

type EImportIdentifier

type EImportIdentifier struct {
	Ref             Ref
	PreferQuotedKey bool

	// If true, this was originally an identifier expression such as "foo". If
	// false, this could potentially have been a member access expression such
	// as "ns.foo" off of an imported namespace object.
	WasOriginallyIdentifier bool
}

This is similar to an EIdentifier but it represents a reference to an ES6 import item.

Depending on how the code is linked, the file containing this EImportIdentifier may or may not be in the same module group as the file it was imported from.

If it's the same module group than we can just merge the import item symbol with the corresponding symbol that was imported, effectively renaming them to be the same thing and statically binding them together.

But if it's a different module group, then the import must be dynamically evaluated using a property access off the corresponding namespace symbol, which represents the result of a require() call.

It's stored as a separate type so it's not easy to confuse with a plain identifier. For example, it'd be bad if code trying to convert "{x: x}" into "{x}" shorthand syntax wasn't aware that the "x" in this case is actually "{x: importedNamespace.x}". This separate type forces code to opt-in to doing this instead of opt-out.

type EImportMeta

type EImportMeta struct{}

type EImportString added in v0.11.22

type EImportString struct {
	ImportRecordIndex uint32

	// Comments inside "import()" expressions have special meaning for Webpack.
	// Preserving comments inside these expressions makes it possible to use
	// esbuild as a TypeScript-to-JavaScript frontend for Webpack to improve
	// performance. We intentionally do not interpret these comments in esbuild
	// because esbuild is not Webpack. But we do preserve them since doing so is
	// harmless, easy to maintain, and useful to people. See the Webpack docs for
	// more info: https://webpack.js.org/api/module-methods/#magic-comments.
	LeadingInteriorComments []Comment
}

type EIndex

type EIndex struct {
	Target        Expr
	Index         Expr
	OptionalChain OptionalChain
}

func (*EIndex) HasSameFlagsAs

func (a *EIndex) HasSameFlagsAs(b *EIndex) bool

type EJSXElement

type EJSXElement struct {
	TagOrNil   Expr
	Properties []Property
	Children   []Expr
	CloseLoc   logger.Loc
}

type EMissing

type EMissing struct{}

type ENew

type ENew struct {
	Target Expr
	Args   []Expr

	// True if there is a comment containing "@__PURE__" or "#__PURE__" preceding
	// this call expression. See the comment inside ECall for more details.
	CanBeUnwrappedIfUnused bool
}

type ENewTarget

type ENewTarget struct {
	Range logger.Range
}

type ENull

type ENull struct{}

type ENumber

type ENumber struct{ Value float64 }

type EObject

type EObject struct {
	Properties       []Property
	CommaAfterSpread logger.Loc
	IsSingleLine     bool
	IsParenthesized  bool
}

type EPrivateIdentifier

type EPrivateIdentifier struct {
	Ref Ref
}

This is similar to EIdentifier but it represents class-private fields and methods. It can be used where computed properties can be used, such as EIndex and Property.

type ERegExp

type ERegExp struct{ Value string }

type ERequireResolveString added in v0.11.22

type ERequireResolveString struct {
	ImportRecordIndex uint32
}

type ERequireString added in v0.11.22

type ERequireString struct {
	ImportRecordIndex uint32
}

type ESpread

type ESpread struct{ Value Expr }

type EString

type EString struct {
	Value          []uint16
	LegacyOctalLoc logger.Loc
	PreferTemplate bool
}

This is used for both strings and no-substitution template literals to reduce the number of cases that need to be checked for string optimization code

type ESuper

type ESuper struct{}

type ETemplate

type ETemplate struct {
	TagOrNil       Expr
	HeadLoc        logger.Loc
	HeadCooked     []uint16 // Only use when "TagOrNil" is nil
	HeadRaw        string   // Only use when "TagOrNil" is not nil
	Parts          []TemplatePart
	LegacyOctalLoc logger.Loc
}

type EThis

type EThis struct{}

type EUnary

type EUnary struct {
	Op    OpCode
	Value Expr
}

type EUndefined

type EUndefined struct{}

type EYield

type EYield struct {
	ValueOrNil Expr
	IsStar     bool
}

type EnumValue

type EnumValue struct {
	Name       []uint16
	ValueOrNil Expr
	Ref        Ref
	Loc        logger.Loc
}

type ExportStarAlias

type ExportStarAlias struct {
	Loc logger.Loc

	// Although this alias name starts off as being the same as the statement's
	// namespace symbol, it may diverge if the namespace symbol name is minified.
	// The original alias name is preserved here to avoid this scenario.
	OriginalName string
}

type ExportsKind added in v0.10.0

type ExportsKind uint8
const (
	// This file doesn't have any kind of export, so it's impossible to say what
	// kind of file this is. An empty file is in this category, for example.
	ExportsNone ExportsKind = iota

	// The exports are stored on "module" and/or "exports". Calling "require()"
	// on this module returns "module.exports". All imports to this module are
	// allowed but may return undefined.
	ExportsCommonJS

	// All export names are known explicitly. Calling "require()" on this module
	// generates an exports object (stored in "exports") with getters for the
	// export names. Named imports to this module are only allowed if they are
	// in the set of export names.
	ExportsESM

	// Some export names are known explicitly, but others fall back to a dynamic
	// run-time object. This is necessary when using the "export * from" syntax
	// with either a CommonJS module or an external module (i.e. a module whose
	// export names are not known at compile-time).
	//
	// Calling "require()" on this module generates an exports object (stored in
	// "exports") with getters for the export names. All named imports to this
	// module are allowed. Direct named imports reference the corresponding export
	// directly. Other imports go through property accesses on "exports".
	ExportsESMWithDynamicFallback
)

func (ExportsKind) IsDynamic added in v0.10.0

func (kind ExportsKind) IsDynamic() bool

type Expr

type Expr struct {
	Loc  logger.Loc
	Data E
}

func Assign

func Assign(a Expr, b Expr) Expr

func ConvertBindingToExpr added in v0.11.0

func ConvertBindingToExpr(binding Binding, wrapIdentifier func(logger.Loc, Ref) Expr) Expr

func JoinAllWithComma

func JoinAllWithComma(all []Expr) (result Expr)

func JoinWithComma

func JoinWithComma(a Expr, b Expr) Expr

func JoinWithLeftAssociativeOp added in v0.8.30

func JoinWithLeftAssociativeOp(op OpCode, a Expr, b Expr) Expr

The goal of this function is to "rotate" the AST if it's possible to use the left-associative property of the operator to avoid unnecessary parentheses.

When using this, make absolutely sure that the operator is actually associative. For example, the "-" operator is not associative for floating-point numbers.

func MaybeSimplifyNot added in v0.8.29

func MaybeSimplifyNot(expr Expr) (Expr, bool)

The given "expr" argument should be the operand of a "!" prefix operator (i.e. the "x" in "!x"). This returns a simplified expression for the whole operator (i.e. the "!x") if it can be simplified, or false if not. It's separate from "Not()" above to avoid allocation on failure in case that is undesired.

func Not

func Not(expr Expr) Expr

Wraps the provided expression in the "!" prefix operator. The expression will potentially be simplified to avoid generating unnecessary extra "!" operators. For example, calling this with "!!x" will return "!x" instead of returning "!!!x".

type Finally

type Finally struct {
	Loc   logger.Loc
	Stmts []Stmt
}

type Fn

type Fn struct {
	Name         *LocRef
	OpenParenLoc logger.Loc
	Args         []Arg
	Body         FnBody
	ArgumentsRef Ref

	IsAsync     bool
	IsGenerator bool
	HasRestArg  bool
	HasIfScope  bool

	// This is true if the function is a method
	IsUniqueFormalParameters bool
}

type FnBody

type FnBody struct {
	Loc   logger.Loc
	Stmts []Stmt
}

type ImportItemStatus

type ImportItemStatus uint8
const (
	ImportItemNone ImportItemStatus = iota

	// The linker doesn't report import/export mismatch errors
	ImportItemGenerated

	// The printer will replace this import with "undefined"
	ImportItemMissing
)

type L

type L int
const (
	LLowest L = iota
	LComma
	LSpread
	LYield
	LAssign
	LConditional
	LNullishCoalescing
	LLogicalOr
	LLogicalAnd
	LBitwiseOr
	LBitwiseXor
	LBitwiseAnd
	LEquals
	LCompare
	LShift
	LAdd
	LMultiply
	LExponentiation
	LPrefix
	LPostfix
	LNew
	LCall
	LMember
)

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence

type LocRef

type LocRef struct {
	Loc logger.Loc
	Ref Ref
}

type LocalKind

type LocalKind uint8
const (
	LocalVar LocalKind = iota
	LocalLet
	LocalConst
)

type NameMinifier

type NameMinifier struct {
	// contains filtered or unexported fields
}

func (*NameMinifier) NumberToMinifiedName

func (minifier *NameMinifier) NumberToMinifiedName(i int) string

type NamedExport added in v0.8.8

type NamedExport struct {
	Ref      Ref
	AliasLoc logger.Loc
}

type NamedImport

type NamedImport struct {
	// Parts within this file that use this import
	LocalPartsWithUses []uint32

	Alias             string
	AliasLoc          logger.Loc
	NamespaceRef      Ref
	ImportRecordIndex uint32

	// If true, the alias refers to the entire export namespace object of a
	// module. This is no longer represented as an alias called "*" because of
	// the upcoming "Arbitrary module namespace identifier names" feature:
	// https://github.com/tc39/ecma262/pull/2154
	AliasIsStar bool

	// It's useful to flag exported imports because if they are in a TypeScript
	// file, we can't tell if they are a type or a value.
	IsExported bool
}

type NamespaceAlias

type NamespaceAlias struct {
	NamespaceRef Ref
	Alias        string
}

type OpCode

type OpCode int
const (
	// Prefix
	UnOpPos OpCode = iota
	UnOpNeg
	UnOpCpl
	UnOpNot
	UnOpVoid
	UnOpTypeof
	UnOpDelete

	// Prefix update
	UnOpPreDec
	UnOpPreInc

	// Postfix update
	UnOpPostDec
	UnOpPostInc

	// Left-associative
	BinOpAdd
	BinOpSub
	BinOpMul
	BinOpDiv
	BinOpRem
	BinOpPow
	BinOpLt
	BinOpLe
	BinOpGt
	BinOpGe
	BinOpIn
	BinOpInstanceof
	BinOpShl
	BinOpShr
	BinOpUShr
	BinOpLooseEq
	BinOpLooseNe
	BinOpStrictEq
	BinOpStrictNe
	BinOpNullishCoalescing
	BinOpLogicalOr
	BinOpLogicalAnd
	BinOpBitwiseOr
	BinOpBitwiseAnd
	BinOpBitwiseXor

	// Non-associative
	BinOpComma

	// Right-associative
	BinOpAssign
	BinOpAddAssign
	BinOpSubAssign
	BinOpMulAssign
	BinOpDivAssign
	BinOpRemAssign
	BinOpPowAssign
	BinOpShlAssign
	BinOpShrAssign
	BinOpUShrAssign
	BinOpBitwiseOrAssign
	BinOpBitwiseAndAssign
	BinOpBitwiseXorAssign
	BinOpNullishCoalescingAssign
	BinOpLogicalOrAssign
	BinOpLogicalAndAssign
)

If you add a new token, remember to add it to "OpTable" too

func (OpCode) BinaryAssignTarget

func (op OpCode) BinaryAssignTarget() AssignTarget

func (OpCode) IsLeftAssociative

func (op OpCode) IsLeftAssociative() bool

func (OpCode) IsPrefix

func (op OpCode) IsPrefix() bool

func (OpCode) IsRightAssociative

func (op OpCode) IsRightAssociative() bool

func (OpCode) IsShortCircuit added in v0.8.29

func (op OpCode) IsShortCircuit() bool

func (OpCode) UnaryAssignTarget

func (op OpCode) UnaryAssignTarget() AssignTarget

type OptionalChain

type OptionalChain uint8
const (
	// "a.b"
	OptionalChainNone OptionalChain = iota

	// "a?.b"
	OptionalChainStart

	// "a?.b.c" => ".c" is OptionalChainContinue
	// "(a?.b).c" => ".c" is OptionalChainNone
	OptionalChainContinue
)

type Part

type Part struct {
	Stmts  []Stmt
	Scopes []*Scope

	// Each is an index into the file-level import record list
	ImportRecordIndices []uint32

	// All symbols that are declared in this part. Note that a given symbol may
	// have multiple declarations, and so may end up being declared in multiple
	// parts (e.g. multiple "var" declarations with the same name). Also note
	// that this list isn't deduplicated and may contain duplicates.
	DeclaredSymbols []DeclaredSymbol

	// An estimate of the number of uses of all symbols used within this part.
	SymbolUses map[Ref]SymbolUse

	// The indices of the other parts in this file that are needed if this part
	// is needed.
	Dependencies []Dependency

	// If true, this part can be removed if none of the declared symbols are
	// used. If the file containing this part is imported, then all parts that
	// don't have this flag enabled must be included.
	CanBeRemovedIfUnused bool

	// This is used for generated parts that we don't want to be present if they
	// aren't needed. This enables tree shaking for these parts even if global
	// tree shaking isn't enabled.
	ForceTreeShaking bool

	// This is true if this file has been marked as live by the tree shaking
	// algorithm.
	IsLive bool
}

Each file is made up of multiple parts, and each part consists of one or more top-level statements. Parts are used for tree shaking and code splitting analysis. Individual parts of a file can be discarded by tree shaking and can be assigned to separate chunks (i.e. output files) by code splitting.

type Property

type Property struct {
	TSDecorators []Expr
	Key          Expr

	// This is omitted for class fields
	ValueOrNil Expr

	// This is used when parsing a pattern that uses default values:
	//
	//   [a = 1] = [];
	//   ({a = 1} = {});
	//
	// It's also used for class fields:
	//
	//   class Foo { a = 1 }
	//
	InitializerOrNil Expr

	Kind            PropertyKind
	IsComputed      bool
	IsMethod        bool
	IsStatic        bool
	WasShorthand    bool
	PreferQuotedKey bool
}

type PropertyBinding

type PropertyBinding struct {
	Key               Expr
	Value             Binding
	DefaultValueOrNil Expr
	IsComputed        bool
	IsSpread          bool
	PreferQuotedKey   bool
}

type PropertyKind

type PropertyKind int
const (
	PropertyNormal PropertyKind = iota
	PropertyGet
	PropertySet
	PropertySpread
	PropertyDeclare
)

type Ref

type Ref struct {
	SourceIndex uint32
	InnerIndex  uint32
}

Files are parsed in parallel for speed. We want to allow each parser to generate symbol IDs that won't conflict with each other. We also want to be able to quickly merge symbol tables from all files into one giant symbol table.

We can accomplish both goals by giving each symbol ID two parts: a source index that is unique to the parser goroutine, and an inner index that increments as the parser generates new symbol IDs. Then a symbol map can be an array of arrays indexed first by source index, then by inner index. The maps can be merged quickly by creating a single outer array containing all inner arrays from all parsed files.

var InvalidRef Ref = Ref{^uint32(0), ^uint32(0)}

func FollowSymbols

func FollowSymbols(symbols SymbolMap, ref Ref) Ref

Returns the canonical ref that represents the ref for the provided symbol. This may not be the provided ref if the symbol has been merged with another symbol.

func MergeSymbols

func MergeSymbols(symbols SymbolMap, old Ref, new Ref) Ref

Makes "old" point to "new" by joining the linked lists for the two symbols together. That way "FollowSymbols" on both "old" and "new" will result in the same ref.

type S

type S interface {
	// contains filtered or unexported methods
}

This interface is never called. Its purpose is to encode a variant type in Go's type system.

type SBlock

type SBlock struct {
	Stmts []Stmt
}

type SBreak

type SBreak struct {
	Label *LocRef
}

type SClass

type SClass struct {
	Class    Class
	IsExport bool
}

type SComment

type SComment struct {
	Text           string
	IsLegalComment bool
}

type SContinue

type SContinue struct {
	Label *LocRef
}

type SDebugger

type SDebugger struct{}

type SDirective

type SDirective struct {
	Value          []uint16
	LegacyOctalLoc logger.Loc
}

type SDoWhile

type SDoWhile struct {
	Body Stmt
	Test Expr
}

type SEmpty

type SEmpty struct{}

type SEnum

type SEnum struct {
	Name     LocRef
	Arg      Ref
	Values   []EnumValue
	IsExport bool
}

type SExportClause

type SExportClause struct {
	Items        []ClauseItem
	IsSingleLine bool
}

type SExportDefault

type SExportDefault struct {
	DefaultName LocRef
	Value       Stmt // May be a SExpr or SFunction or SClass
}

type SExportEquals

type SExportEquals struct {
	Value Expr
}

This is an "export = value;" statement in TypeScript

type SExportFrom

type SExportFrom struct {
	Items             []ClauseItem
	NamespaceRef      Ref
	ImportRecordIndex uint32
	IsSingleLine      bool
}

type SExportStar

type SExportStar struct {
	NamespaceRef      Ref
	Alias             *ExportStarAlias
	ImportRecordIndex uint32
}

type SExpr

type SExpr struct {
	Value Expr

	// This is set to true for automatically-generated expressions that should
	// not affect tree shaking. For example, calling a function from the runtime
	// that doesn't have externally-visible side effects.
	DoesNotAffectTreeShaking bool
}

type SFor

type SFor struct {
	InitOrNil   Stmt // May be a SConst, SLet, SVar, or SExpr
	TestOrNil   Expr
	UpdateOrNil Expr
	Body        Stmt
}

type SForIn

type SForIn struct {
	Init  Stmt // May be a SConst, SLet, SVar, or SExpr
	Value Expr
	Body  Stmt
}

type SForOf

type SForOf struct {
	IsAwait bool
	Init    Stmt // May be a SConst, SLet, SVar, or SExpr
	Value   Expr
	Body    Stmt
}

type SFunction

type SFunction struct {
	Fn       Fn
	IsExport bool
}

type SIf

type SIf struct {
	Test    Expr
	Yes     Stmt
	NoOrNil Stmt
}

type SImport

type SImport struct {
	// If this is a star import: This is a Ref for the namespace symbol. The Loc
	// for the symbol is StarLoc.
	//
	// Otherwise: This is an auto-generated Ref for the namespace representing
	// the imported file. In this case StarLoc is nil. The NamespaceRef is used
	// when converting this module to a CommonJS module.
	NamespaceRef Ref

	DefaultName       *LocRef
	Items             *[]ClauseItem
	StarNameLoc       *logger.Loc
	ImportRecordIndex uint32
	IsSingleLine      bool
}

This object represents all of these types of import statements:

import 'path'
import {item1, item2} from 'path'
import * as ns from 'path'
import defaultItem, {item1, item2} from 'path'
import defaultItem, * as ns from 'path'

Many parts are optional and can be combined in different ways. The only restriction is that you cannot have both a clause and a star namespace.

type SLabel

type SLabel struct {
	Name LocRef
	Stmt Stmt
}

type SLazyExport

type SLazyExport struct {
	Value Expr
}

The decision of whether to export an expression using "module.exports" or "export default" is deferred until linking using this statement kind

type SLocal

type SLocal struct {
	Decls    []Decl
	Kind     LocalKind
	IsExport bool

	// The TypeScript compiler doesn't generate code for "import foo = bar"
	// statements where the import is never used.
	WasTSImportEquals bool
}

type SNamespace

type SNamespace struct {
	Name     LocRef
	Arg      Ref
	Stmts    []Stmt
	IsExport bool
}

type SReturn

type SReturn struct {
	ValueOrNil Expr
}

type SSwitch

type SSwitch struct {
	Test    Expr
	BodyLoc logger.Loc
	Cases   []Case
}

type SThrow

type SThrow struct {
	Value Expr
}

type STry

type STry struct {
	BodyLoc logger.Loc
	Body    []Stmt
	Catch   *Catch
	Finally *Finally
}

type STypeScript

type STypeScript struct{}

This is a stand-in for a TypeScript type declaration

type SWhile

type SWhile struct {
	Test Expr
	Body Stmt
}

type SWith

type SWith struct {
	Value   Expr
	BodyLoc logger.Loc
	Body    Stmt
}

type Scope

type Scope struct {
	Kind      ScopeKind
	Parent    *Scope
	Children  []*Scope
	Members   map[string]ScopeMember
	Generated []Ref

	// The location of the "use strict" directive for ExplicitStrictMode
	UseStrictLoc logger.Loc

	// This is used to store the ref of the label symbol for ScopeLabel scopes.
	Label           LocRef
	LabelStmtIsLoop bool

	// If a scope contains a direct eval() expression, then none of the symbols
	// inside that scope can be renamed. We conservatively assume that the
	// evaluated code might reference anything that it has access to.
	ContainsDirectEval bool

	// This is to help forbid "arguments" inside class body scopes
	ForbidArguments bool

	StrictMode StrictModeKind
}

func (*Scope) RecursiveSetStrictMode added in v0.8.41

func (s *Scope) RecursiveSetStrictMode(kind StrictModeKind)

type ScopeKind

type ScopeKind int
const (
	ScopeBlock ScopeKind = iota
	ScopeWith
	ScopeLabel
	ScopeClassName
	ScopeClassBody

	// The scopes below stop hoisted variables from extending into parent scopes
	ScopeEntry // This is a module, TypeScript enum, or TypeScript namespace
	ScopeFunctionArgs
	ScopeFunctionBody
	ScopeClassStaticInit
)

func (ScopeKind) StopsHoisting

func (kind ScopeKind) StopsHoisting() bool

type ScopeMember

type ScopeMember struct {
	Ref Ref
	Loc logger.Loc
}

type SlotCounts

type SlotCounts [3]uint32

func (*SlotCounts) UnionMax

func (a *SlotCounts) UnionMax(b SlotCounts)

type SlotNamespace

type SlotNamespace uint8
const (
	SlotDefault SlotNamespace = iota
	SlotLabel
	SlotPrivateName
	SlotMustNotBeRenamed
)

type Stmt

type Stmt struct {
	Loc  logger.Loc
	Data S
}

func AssignStmt

func AssignStmt(a Expr, b Expr) Stmt

type StrictModeKind added in v0.8.41

type StrictModeKind uint8
const (
	SloppyMode StrictModeKind = iota
	ExplicitStrictMode
	ImplicitStrictModeImport
	ImplicitStrictModeExport
	ImplicitStrictModeTopLevelAwait
	ImplicitStrictModeClass
)

type Symbol

type Symbol struct {
	// This is the name that came from the parser. Printed names may be renamed
	// during minification or to avoid name collisions. Do not use the original
	// name during printing.
	OriginalName string

	// This is used for symbols that represent items in the import clause of an
	// ES6 import statement. These should always be referenced by EImportIdentifier
	// instead of an EIdentifier. When this is present, the expression should
	// be printed as a property access off the namespace instead of as a bare
	// identifier.
	//
	// For correctness, this must be stored on the symbol instead of indirectly
	// associated with the Ref for the symbol somehow. In ES6 "flat bundling"
	// mode, re-exported symbols are collapsed using MergeSymbols() and renamed
	// symbols from other files that end up at this symbol must be able to tell
	// if it has a namespace alias.
	NamespaceAlias *NamespaceAlias

	// Used by the parser for single pass parsing. Symbols that have been merged
	// form a linked-list where the last link is the symbol to use. This link is
	// an invalid ref if it's the last link. If this isn't invalid, you need to
	// FollowSymbols to get the real one.
	Link Ref

	// An estimate of the number of uses of this symbol. This is used to detect
	// whether a symbol is used or not. For example, TypeScript imports that are
	// unused must be removed because they are probably type-only imports. This
	// is an estimate and may not be completely accurate due to oversights in the
	// code. But it should always be non-zero when the symbol is used.
	UseCountEstimate uint32

	// This is for generating cross-chunk imports and exports for code splitting.
	ChunkIndex ast.Index32

	// This is used for minification. Symbols that are declared in sibling scopes
	// can share a name. A good heuristic (from Google Closure Compiler) is to
	// assign names to symbols from sibling scopes in declaration order. That way
	// local variable names are reused in each global function like this, which
	// improves gzip compression:
	//
	//   function x(a, b) { ... }
	//   function y(a, b, c) { ... }
	//
	// The parser fills this in for symbols inside nested scopes. There are three
	// slot namespaces: regular symbols, label symbols, and private symbols.
	NestedScopeSlot ast.Index32

	Kind SymbolKind

	// Certain symbols must not be renamed or minified. For example, the
	// "arguments" variable is declared by the runtime for every function.
	// Renaming can also break any identifier used inside a "with" statement.
	MustNotBeRenamed bool

	// In React's version of JSX, lower-case names are strings while upper-case
	// names are identifiers. If we are preserving JSX syntax (i.e. not
	// transforming it), then we need to be careful to name the identifiers
	// something with a capital letter so further JSX processing doesn't treat
	// them as strings instead.
	MustStartWithCapitalLetterForJSX bool

	// If true, this symbol is the target of a "__name" helper function call.
	// This call is special because it deliberately doesn't count as a use
	// of the symbol (otherwise keeping names would disable tree shaking)
	// so "UseCountEstimate" is not incremented. This flag helps us know to
	// avoid optimizing this symbol when "UseCountEstimate" is 1 in this case.
	DidKeepName bool

	// We automatically generate import items for property accesses off of
	// namespace imports. This lets us remove the expensive namespace imports
	// while bundling in many cases, replacing them with a cheap import item
	// instead:
	//
	//   import * as ns from 'path'
	//   ns.foo()
	//
	// That can often be replaced by this, which avoids needing the namespace:
	//
	//   import {foo} from 'path'
	//   foo()
	//
	// However, if the import is actually missing then we don't want to report a
	// compile-time error like we do for real import items. This status lets us
	// avoid this. We also need to be able to replace such import items with
	// undefined, which this status is also used for.
	ImportItemStatus ImportItemStatus

	// Sometimes we lower private symbols even if they are supported. For example,
	// consider the following TypeScript code:
	//
	//   class Foo {
	//     #foo = 123
	//     bar = this.#foo
	//   }
	//
	// If "useDefineForClassFields: false" is set in "tsconfig.json", then "bar"
	// must use assignment semantics instead of define semantics. We can compile
	// that to this code:
	//
	//   class Foo {
	//     constructor() {
	//       this.#foo = 123;
	//       this.bar = this.#foo;
	//     }
	//     #foo;
	//   }
	//
	// However, we can't do the same for static fields:
	//
	//   class Foo {
	//     static #foo = 123
	//     static bar = this.#foo
	//   }
	//
	// Compiling these static fields to something like this would be invalid:
	//
	//   class Foo {
	//     static #foo;
	//   }
	//   Foo.#foo = 123;
	//   Foo.bar = Foo.#foo;
	//
	// Thus "#foo" must be lowered even though it's supported. Another case is
	// when we're converting top-level class declarations to class expressions
	// to avoid the TDZ and the class shadowing symbol is referenced within the
	// class body:
	//
	//   class Foo {
	//     static #foo = Foo
	//   }
	//
	// This cannot be converted into something like this:
	//
	//   var Foo = class {
	//     static #foo;
	//   };
	//   Foo.#foo = Foo;
	//
	PrivateSymbolMustBeLowered bool
}

Note: the order of values in this struct matters to reduce struct size.

func (*Symbol) SlotNamespace

func (s *Symbol) SlotNamespace() SlotNamespace

type SymbolKind

type SymbolKind uint8
const (
	// An unbound symbol is one that isn't declared in the file it's referenced
	// in. For example, using "window" without declaring it will be unbound.
	SymbolUnbound SymbolKind = iota

	// This has special merging behavior. You're allowed to re-declare these
	// symbols more than once in the same scope. These symbols are also hoisted
	// out of the scope they are declared in to the closest containing function
	// or module scope. These are the symbols with this kind:
	//
	// - Function arguments
	// - Function statements
	// - Variables declared using "var"
	//
	SymbolHoisted
	SymbolHoistedFunction

	// There's a weird special case where catch variables declared using a simple
	// identifier (i.e. not a binding pattern) block hoisted variables instead of
	// becoming an error:
	//
	//   var e = 0;
	//   try { throw 1 } catch (e) {
	//     print(e) // 1
	//     var e = 2
	//     print(e) // 2
	//   }
	//   print(e) // 0 (since the hoisting stops at the catch block boundary)
	//
	// However, other forms are still a syntax error:
	//
	//   try {} catch (e) { let e }
	//   try {} catch ({e}) { var e }
	//
	// This symbol is for handling this weird special case.
	SymbolCatchIdentifier

	// Generator and async functions are not hoisted, but still have special
	// properties such as being able to overwrite previous functions with the
	// same name
	SymbolGeneratorOrAsyncFunction

	// This is the special "arguments" variable inside functions
	SymbolArguments

	// Classes can merge with TypeScript namespaces.
	SymbolClass

	// A class-private identifier (i.e. "#foo").
	SymbolPrivateField
	SymbolPrivateMethod
	SymbolPrivateGet
	SymbolPrivateSet
	SymbolPrivateGetSetPair
	SymbolPrivateStaticField
	SymbolPrivateStaticMethod
	SymbolPrivateStaticGet
	SymbolPrivateStaticSet
	SymbolPrivateStaticGetSetPair

	// Labels are in their own namespace
	SymbolLabel

	// TypeScript enums can merge with TypeScript namespaces and other TypeScript
	// enums.
	SymbolTSEnum

	// TypeScript namespaces can merge with classes, functions, TypeScript enums,
	// and other TypeScript namespaces.
	SymbolTSNamespace

	// In TypeScript, imports are allowed to silently collide with symbols within
	// the module. Presumably this is because the imports may be type-only.
	SymbolImport

	// Assigning to a "const" symbol will throw a TypeError at runtime
	SymbolConst

	// Injected symbols can be overridden by provided defines
	SymbolInjected

	// This annotates all other symbols that don't have special behavior.
	SymbolOther
)

func (SymbolKind) Feature

func (kind SymbolKind) Feature() compat.JSFeature

func (SymbolKind) IsFunction added in v0.8.50

func (kind SymbolKind) IsFunction() bool

func (SymbolKind) IsHoisted

func (kind SymbolKind) IsHoisted() bool

func (SymbolKind) IsHoistedOrFunction

func (kind SymbolKind) IsHoistedOrFunction() bool

func (SymbolKind) IsPrivate

func (kind SymbolKind) IsPrivate() bool

func (SymbolKind) IsUnboundOrInjected added in v0.12.0

func (kind SymbolKind) IsUnboundOrInjected() bool

type SymbolMap

type SymbolMap struct {
	// This could be represented as a "map[Ref]Symbol" but a two-level array was
	// more efficient in profiles. This appears to be because it doesn't involve
	// a hash. This representation also makes it trivial to quickly merge symbol
	// maps from multiple files together. Each file only generates symbols in a
	// single inner array, so you can join the maps together by just make a
	// single outer array containing all of the inner arrays. See the comment on
	// "Ref" for more detail.
	SymbolsForSource [][]Symbol
}

func NewSymbolMap

func NewSymbolMap(sourceCount int) SymbolMap

func (SymbolMap) Get

func (sm SymbolMap) Get(ref Ref) *Symbol

type SymbolUse

type SymbolUse struct {
	CountEstimate uint32
}

type TemplatePart

type TemplatePart struct {
	Value      Expr
	TailLoc    logger.Loc
	TailCooked []uint16 // Only use when "TagOrNil" is nil
	TailRaw    string   // Only use when "TagOrNil" is not nil
}

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL