Documentation ¶
Index ¶
- Constants
- Variables
- func EnsureValidIdentifier(base string) string
- func FollowAllSymbols(symbols SymbolMap)
- func GenerateNonUniqueNameFromPath(path string) string
- func IsOptionalChain(value Expr) bool
- func IsSuperCall(stmt Stmt) bool
- type AST
- type Arg
- type ArrayBinding
- type AssignTarget
- type B
- type BArray
- type BIdentifier
- type BMissing
- type BObject
- type Binding
- type Case
- type Catch
- type CharFreq
- type Class
- type ClassStaticBlock
- type ClauseItem
- type Comment
- type Decl
- type DeclaredSymbol
- type Dependency
- type E
- type EArray
- type EArrow
- type EAwait
- type EBigInt
- type EBinary
- type EBoolean
- type ECall
- type EClass
- type EDot
- type EFunction
- type EIdentifier
- type EIf
- type EImportCall
- type EImportIdentifier
- type EImportMeta
- type EImportString
- type EIndex
- type EInlinedEnum
- type EJSXElement
- type EMissing
- type ENew
- type ENewTarget
- type ENull
- type ENumber
- type EObject
- type EPrivateIdentifier
- type ERegExp
- type ERequireResolveString
- type ERequireString
- type ESpread
- type EString
- type ESuper
- type ETemplate
- type EThis
- type EUnary
- type EUndefined
- type EYield
- type EnumValue
- type ExportStarAlias
- type ExportsKind
- type Expr
- func Assign(a Expr, b Expr) Expr
- func ConvertBindingToExpr(binding Binding, wrapIdentifier func(logger.Loc, Ref) Expr) Expr
- func JoinAllWithComma(all []Expr) (result Expr)
- func JoinWithComma(a Expr, b Expr) Expr
- func JoinWithLeftAssociativeOp(op OpCode, a Expr, b Expr) Expr
- func MaybeSimplifyNot(expr Expr) (Expr, bool)
- func Not(expr Expr) Expr
- type Finally
- type Fn
- type FnBody
- type ImportItemStatus
- type L
- type LocRef
- type LocalKind
- type ModuleType
- type ModuleTypeData
- type NameMinifier
- type NamedExport
- type NamedImport
- type NamespaceAlias
- type OpCode
- type OptionalChain
- type Part
- type PrimitiveType
- type Property
- type PropertyBinding
- type PropertyKind
- type Ref
- type S
- type SBlock
- type SBreak
- type SClass
- type SComment
- type SContinue
- type SDebugger
- type SDirective
- type SDoWhile
- type SEmpty
- type SEnum
- type SExportClause
- type SExportDefault
- type SExportEquals
- type SExportFrom
- type SExportStar
- type SExpr
- type SFor
- type SForIn
- type SForOf
- type SFunction
- type SIf
- type SImport
- type SLabel
- type SLazyExport
- type SLocal
- type SNamespace
- type SReturn
- type SSwitch
- type SThrow
- type STry
- type STypeScript
- type SWhile
- type SWith
- type Scope
- type ScopeKind
- type ScopeMember
- type SlotCounts
- type SlotNamespace
- type Stmt
- type StrictModeKind
- type Symbol
- type SymbolFlags
- type SymbolKind
- type SymbolMap
- type SymbolUse
- type TSEnumValue
- type TSNamespaceMember
- type TSNamespaceMemberData
- type TSNamespaceMemberEnumNumber
- type TSNamespaceMemberEnumString
- type TSNamespaceMemberNamespace
- type TSNamespaceMemberProperty
- type TSNamespaceMembers
- type TSNamespaceScope
- type TemplatePart
Constants ¶
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 ¶
These help reduce unnecessary memory allocations
var DefaultNameMinifier = NameMinifier{ // contains filtered or unexported fields }
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 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 ¶
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 IsOptionalChain ¶ added in v0.8.48
func IsSuperCall ¶
Types ¶
type AST ¶
type AST struct { ApproximateLineCount int32 NestedScopeSlotCounts SlotCounts HasLazyExport bool ModuleTypeData ModuleTypeData // 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". 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 // This contains all top-level exported TypeScript enum constants. It exists // to enable cross-module inlining of constant enums. TSEnums map[Ref]map[string]TSEnumValue // 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 ArrayBinding ¶
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 BObject ¶
type BObject struct { Properties []PropertyBinding IsSingleLine bool }
type CharFreq ¶
type CharFreq [64]int32
This is a histogram of character frequencies for minification
func (*CharFreq) Compile ¶
func (freq *CharFreq) Compile() NameMinifier
type ClassStaticBlock ¶ added in v0.13.11
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 DeclaredSymbol ¶
type Dependency ¶ added in v0.11.3
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 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 ¶
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 ¶
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 EImportCall ¶ added in v0.11.22
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 {
RangeLen int32
}
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 ¶
type EInlinedEnum ¶ added in v0.14.1
type EJSXElement ¶
type ENewTarget ¶
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 ERequireResolveString ¶ added in v0.11.22
type ERequireResolveString struct {
ImportRecordIndex uint32
}
type ERequireString ¶ added in v0.11.22
type ERequireString struct {
ImportRecordIndex uint32
}
type EString ¶
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 EUndefined ¶
type EUndefined struct{}
type ExportStarAlias ¶
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 ¶
func ConvertBindingToExpr ¶ added in v0.11.0
func JoinAllWithComma ¶
func JoinWithComma ¶
func JoinWithLeftAssociativeOp ¶ added in v0.8.30
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
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.
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 ModuleType ¶ added in v0.14.4
type ModuleType uint8
const ( ModuleUnknown ModuleType = iota // ".cjs" or ".cts" or "type: commonjs" in package.json ModuleCommonJS_CJS ModuleCommonJS_CTS ModuleCommonJS_PackageJSON // ".mjs" or ".mts" or "type: module" in package.json ModuleESM_MJS ModuleESM_MTS ModuleESM_PackageJSON )
func (ModuleType) IsCommonJS ¶ added in v0.14.9
func (mt ModuleType) IsCommonJS() bool
func (ModuleType) IsESM ¶ added in v0.14.9
func (mt ModuleType) IsESM() bool
type ModuleTypeData ¶ added in v0.14.9
type ModuleTypeData struct { Source *logger.Source Range logger.Range Type ModuleType }
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 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 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 (OpCode) IsRightAssociative ¶
func (OpCode) IsShortCircuit ¶ added in v0.8.29
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 // This tracks property accesses off of imported symbols. We don't know // during parsing if an imported symbol is going to be an inlined enum // value or not. This is only known during linking. So we defer adding // a dependency on these imported symbols until we know whether the // property access is an inlined enum value or not. ImportSymbolPropertyUses map[Ref]map[string]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 PrimitiveType ¶ added in v0.14.6
type PrimitiveType uint8
const ( PrimitiveUnknown PrimitiveType = iota PrimitiveMixed PrimitiveNull PrimitiveUndefined PrimitiveBoolean PrimitiveNumber PrimitiveString PrimitiveBigInt )
func KnownPrimitiveType ¶ added in v0.14.6
func KnownPrimitiveType(a Expr) PrimitiveType
func MergedKnownPrimitiveTypes ¶ added in v0.14.6
func MergedKnownPrimitiveTypes(a Expr, b Expr) PrimitiveType
This can be used when the returned type is either one or the other
type Property ¶
type Property struct { TSDecorators []Expr ClassStaticBlock *ClassStaticBlock 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 PropertyKind ¶
type PropertyKind int
const ( PropertyNormal PropertyKind = iota PropertyGet PropertySet PropertySpread PropertyDeclare PropertyClassStaticBlock )
type Ref ¶
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.
func FollowSymbols ¶
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.
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 SDirective ¶
type SExportClause ¶
type SExportClause struct { Items []ClauseItem IsSingleLine bool }
type SExportDefault ¶
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 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 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 Scope ¶
type Scope struct { Kind ScopeKind Parent *Scope Children []*Scope Members map[string]ScopeMember Generated []Ref // This will be non-nil if this is a TypeScript "namespace" or "enum" TSNamespace *TSNamespaceScope // 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 ScopeCatchBinding // 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 ¶
type ScopeMember ¶
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 ¶
func AssignStmt ¶
type StrictModeKind ¶ added in v0.8.41
type StrictModeKind uint8
const ( SloppyMode StrictModeKind = iota ExplicitStrictMode ImplicitStrictModeClass ImplicitStrictModeESM )
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 // 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 // Boolean values should all be flags instead to save space Flags SymbolFlags }
Note: the order of values in this struct matters to reduce struct size.
func (*Symbol) MergeContentsWith ¶ added in v0.14.8
You should call "MergeSymbols" instead of calling this directly
func (*Symbol) SlotNamespace ¶
func (s *Symbol) SlotNamespace() SlotNamespace
type SymbolFlags ¶ added in v0.14.8
type SymbolFlags uint8
const ( // 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 SymbolFlags = 1 << iota // 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 // 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 // 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 // This is used to remove the all but the last function re-declaration if a // function is re-declared multiple times like this: // // function foo() { console.log(1) } // function foo() { console.log(2) } // RemoveOverwrittenFunctionDeclaration // This flag is to avoid warning about this symbol more than once. It only // applies to the "module" and "exports" unbound symbols. DidWarnAboutCommonJSInESM )
func (SymbolFlags) Has ¶ added in v0.14.8
func (flags SymbolFlags) Has(flag SymbolFlags) bool
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 ¶
type TSEnumValue ¶ added in v0.14.7
type TSNamespaceMember ¶ added in v0.14.0
type TSNamespaceMember struct { Data TSNamespaceMemberData Loc logger.Loc IsEnumValue bool }
type TSNamespaceMemberData ¶ added in v0.14.0
type TSNamespaceMemberData interface {
// contains filtered or unexported methods
}
type TSNamespaceMemberEnumNumber ¶ added in v0.14.0
type TSNamespaceMemberEnumNumber struct {
Value float64
}
"enum ns { it }"
type TSNamespaceMemberEnumString ¶ added in v0.14.0
type TSNamespaceMemberEnumString struct {
Value []uint16
}
"enum ns { it = 'it' }"
type TSNamespaceMemberNamespace ¶ added in v0.14.0
type TSNamespaceMemberNamespace struct {
ExportedMembers TSNamespaceMembers
}
"namespace ns { export namespace it {} }"
type TSNamespaceMemberProperty ¶ added in v0.14.0
type TSNamespaceMemberProperty struct{}
"namespace ns { export let it }"
type TSNamespaceMembers ¶ added in v0.14.0
type TSNamespaceMembers map[string]TSNamespaceMember
type TSNamespaceScope ¶ added in v0.14.0
type TSNamespaceScope struct { // This is shared between all sibling namespace blocks ExportedMembers TSNamespaceMembers // This is specific to this namespace block. It's the argument of the // immediately-invoked function expression that the namespace block is // compiled into: // // var ns; // (function (ns2) { // ns2.x = 123; // })(ns || (ns = {})); // // This variable is "ns2" in the above example. It's the symbol to use when // generating property accesses off of this namespace when it's in scope. ArgRef Ref // This is a lazily-generated map of identifiers that actually represent // property accesses to this namespace's properties. For example: // // namespace x { // export let y = 123 // } // namespace x { // export let z = y // } // // This should be compiled into the following code: // // var x; // (function(x2) { // x2.y = 123; // })(x || (x = {})); // (function(x3) { // x3.z = x3.y; // })(x || (x = {})); // // When we try to find the symbol "y", we instead return one of these lazily // generated proxy symbols that represent the property access "x3.y". This // map is unique per namespace block because "x3" is the argument symbol that // is specific to that particular namespace block. LazilyGeneratedProperyAccesses map[string]Ref // Even though enums are like namespaces and both enums and namespaces allow // implicit references to properties of sibling scopes, they behave like // separate, er, namespaces. Implicit references only work namespace-to- // namespace and enum-to-enum. They do not work enum-to-namespace. And I'm // not sure what's supposed to happen for the namespace-to-enum case because // the compiler crashes: https://github.com/microsoft/TypeScript/issues/46891. // So basically these both work: // // enum a { b = 1 } // enum a { c = b } // // namespace x { export let y = 1 } // namespace x { export let z = y } // // This doesn't work: // // enum a { b = 1 } // namespace a { export let c = b } // // And this crashes the TypeScript compiler: // // namespace a { export let b = 1 } // enum a { c = b } // // Therefore we only allow enum/enum and namespace/namespace interactions. IsEnumScope bool }
This is for TypeScript "enum" and "namespace" blocks. Each block can potentially be instantiated multiple times. The exported members of each block are merged into a single namespace while the non-exported code is still scoped to just within that block:
let x = 1; namespace Foo { let x = 2; export let y = 3; } namespace Foo { console.log(x); // 1 console.log(y); // 3 }
Doing this also works inside an enum:
enum Foo { A = 3, B = A + 1, } enum Foo { C = A + 2, } console.log(Foo.B) // 4 console.log(Foo.C) // 5
This is a form of identifier lookup that works differently than the hierarchical scope-based identifier lookup in JavaScript. Lookup now needs to search sibling scopes in addition to parent scopes. This is accomplished by sharing the map of exported members between all matching sibling scopes.