Documentation ¶
Index ¶
- Variables
- func FollowAllSymbols(symbols *SymbolMap)
- func GenerateNonUniqueNameFromPath(text string) string
- func IsSuperCall(stmt Stmt) bool
- type AST
- type Arg
- type ArrayBinding
- type B
- type BArray
- type BIdentifier
- type BMissing
- type BObject
- type Binding
- type Case
- type Catch
- type Class
- type ClauseItem
- type Decl
- 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 EImport
- type EImportIdentifier
- type EImportMeta
- type EIndex
- type EJSXElement
- type EMissing
- type ENew
- type ENewTarget
- type ENull
- type ENumber
- type EObject
- type ERegExp
- type ERequire
- type ERuntimeCall
- type ESpread
- type EString
- type ESuper
- type ETemplate
- type EThis
- type EUnary
- type EUndefined
- type EYield
- type EnumValue
- type Expr
- type ExprOrStmt
- type Finally
- type Fn
- type FnBody
- type ImportKind
- type ImportPath
- type L
- type Loc
- type LocRef
- type LocalKind
- type NamespaceAlias
- type OpCode
- type Path
- type Property
- type PropertyBinding
- type PropertyKind
- type Range
- type Ref
- type S
- type SBlock
- type SBreak
- type SClass
- 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 SLocal
- type SNamespace
- type SReturn
- type SSwitch
- type SThrow
- type STry
- type STypeScript
- type SWhile
- type SWith
- type Scope
- type ScopeKind
- type Stmt
- type Symbol
- type SymbolKind
- type SymbolMap
- type TemplatePart
Constants ¶
This section is empty.
Variables ¶
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}, }
Functions ¶
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 IsSuperCall ¶
Types ¶
type AST ¶
type AST struct { ImportPaths []ImportPath WasTypeScript bool // This is true if something used the "exports" or "module" variables, which // means they could have exported something. It's also true if the file // contains a top-level return statement. When a file uses CommonJS features, // it's not a candidate for "flat bundling" and must be wrapped in its own // closure. UsesCommonJSFeatures bool Hashbang string Stmts []Stmt Symbols *SymbolMap ModuleScope *Scope ExportsRef Ref ModuleRef Ref // This is a bitwise-or of all runtime symbols used by this AST. Runtime // symbols are used by ERuntimeCall expressions. UsedRuntimeSyms runtime.Sym }
type ArrayBinding ¶
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 }
type BIdentifier ¶
type BIdentifier struct{ Ref Ref }
type BObject ¶
type BObject struct{ Properties []PropertyBinding }
type ClauseItem ¶
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 EIdentifier ¶
type EIdentifier struct{ Ref Ref }
type EImportIdentifier ¶
type EImportIdentifier struct {
Ref Ref
}
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 EJSXElement ¶
type ENewTarget ¶
type ENewTarget struct{}
type ERuntimeCall ¶
type ETemplate ¶
type ETemplate struct { Tag *Expr Head []uint16 HeadRaw string // This is only filled out for tagged template literals Parts []TemplatePart }
type EUndefined ¶
type EUndefined struct{}
type ExprOrStmt ¶
type ImportKind ¶
type ImportKind uint8
const ( ImportStmt ImportKind = iota ImportRequire ImportDynamic )
type ImportPath ¶
type ImportPath struct { Path Path Kind ImportKind }
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 )
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence
type Loc ¶
type Loc struct { // This is the 0-based index of this location from the start of the file Start int32 }
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 )
If you add a new token, remember to add it to "OpTable" too
func (OpCode) IsBinaryAssign ¶
func (OpCode) IsLeftAssociative ¶
func (OpCode) IsRightAssociative ¶
func (OpCode) IsUnaryUpdate ¶
type Property ¶
type Property struct { Kind PropertyKind IsComputed bool IsMethod bool IsStatic bool Key Expr // This is omitted for class fields Value *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 } // Initializer *Expr }
type PropertyBinding ¶
type PropertyKind ¶
type PropertyKind int
const ( PropertyNormal PropertyKind = iota PropertyGet PropertySet PropertySpread )
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: an outer 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 outer 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 SDirective struct {
Value []uint16
}
type SExportClause ¶
type SExportClause struct {
Items []ClauseItem
}
type SExportDefault ¶
type SExportDefault struct { DefaultName LocRef Value ExprOrStmt // May be a 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 Path Path }
type SExportStar ¶
type SExportStar struct { Item *ClauseItem Path Path }
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 StarLoc *Loc Path Path }
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 Scope ¶
type Scope struct { Kind ScopeKind Parent *Scope Children []*Scope Members map[string]Ref Generated []Ref // This is used to store the ref of the label symbol for ScopeLabel scopes. LabelRef Ref // 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 }
type Symbol ¶
type Symbol struct { 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 // An estimate of the number of uses of this symbol. This is used for // minification (to prefer shorter names for more frequently used symbols). // The reason why this is an estimate instead of an accurate count is that // it's not updated during dead code elimination for speed. I figure that // even without updating after parsing it's still a pretty good heuristic. UseCountEstimate uint32 Name string // 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 // 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 }
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 // Classes can merge with TypeScript namespaces. SymbolClass // 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. SymbolTSImport // This annotates all other symbols that don't have special behavior. SymbolOther )
func (SymbolKind) IsHoisted ¶
func (kind SymbolKind) IsHoisted() 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. Outer [][]Symbol }
func NewSymbolMap ¶
func (*SymbolMap) IncrementUseCountEstimate ¶
func (*SymbolMap) SetKind ¶
func (sm *SymbolMap) SetKind(ref Ref, kind SymbolKind)
func (*SymbolMap) SetNamespaceAlias ¶
func (sm *SymbolMap) SetNamespaceAlias(ref Ref, alias NamespaceAlias)