Add support for copying files and folders.
This commit is contained in:
583
vendor/github.com/evanw/esbuild/internal/config/config.go
generated
vendored
Normal file
583
vendor/github.com/evanw/esbuild/internal/config/config.go
generated
vendored
Normal file
@ -0,0 +1,583 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/evanw/esbuild/internal/ast"
|
||||
"github.com/evanw/esbuild/internal/compat"
|
||||
"github.com/evanw/esbuild/internal/js_ast"
|
||||
"github.com/evanw/esbuild/internal/logger"
|
||||
)
|
||||
|
||||
type JSXOptions struct {
|
||||
Factory JSXExpr
|
||||
Fragment JSXExpr
|
||||
Parse bool
|
||||
Preserve bool
|
||||
}
|
||||
|
||||
type JSXExpr struct {
|
||||
Parts []string
|
||||
Constant js_ast.E
|
||||
}
|
||||
|
||||
type TSOptions struct {
|
||||
Parse bool
|
||||
NoAmbiguousLessThan bool
|
||||
}
|
||||
|
||||
type Platform uint8
|
||||
|
||||
const (
|
||||
PlatformBrowser Platform = iota
|
||||
PlatformNode
|
||||
PlatformNeutral
|
||||
)
|
||||
|
||||
type StrictOptions struct {
|
||||
// Loose: "class Foo { foo = 1 }" => "class Foo { constructor() { this.foo = 1; } }"
|
||||
// Strict: "class Foo { foo = 1 }" => "class Foo { constructor() { __publicField(this, 'foo', 1); } }"
|
||||
//
|
||||
// The disadvantage of strictness here is code bloat and performance. The
|
||||
// advantage is following the class field specification accurately. For
|
||||
// example, loose mode will incorrectly trigger setter methods while strict
|
||||
// mode won't.
|
||||
ClassFields bool
|
||||
}
|
||||
|
||||
type SourceMap uint8
|
||||
|
||||
const (
|
||||
SourceMapNone SourceMap = iota
|
||||
SourceMapInline
|
||||
SourceMapLinkedWithComment
|
||||
SourceMapExternalWithoutComment
|
||||
SourceMapInlineAndExternal
|
||||
)
|
||||
|
||||
type LegalComments uint8
|
||||
|
||||
const (
|
||||
LegalCommentsInline LegalComments = iota
|
||||
LegalCommentsNone
|
||||
LegalCommentsEndOfFile
|
||||
LegalCommentsLinkedWithComment
|
||||
LegalCommentsExternalWithoutComment
|
||||
)
|
||||
|
||||
func (lc LegalComments) HasExternalFile() bool {
|
||||
return lc == LegalCommentsLinkedWithComment || lc == LegalCommentsExternalWithoutComment
|
||||
}
|
||||
|
||||
type Loader int
|
||||
|
||||
const (
|
||||
LoaderNone Loader = iota
|
||||
LoaderJS
|
||||
LoaderJSX
|
||||
LoaderTS
|
||||
LoaderTSNoAmbiguousLessThan // Used with ".mts" and ".cts"
|
||||
LoaderTSX
|
||||
LoaderJSON
|
||||
LoaderText
|
||||
LoaderBase64
|
||||
LoaderDataURL
|
||||
LoaderFile
|
||||
LoaderBinary
|
||||
LoaderCSS
|
||||
LoaderDefault
|
||||
)
|
||||
|
||||
func (loader Loader) IsTypeScript() bool {
|
||||
switch loader {
|
||||
case LoaderTS, LoaderTSNoAmbiguousLessThan, LoaderTSX:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func (loader Loader) CanHaveSourceMap() bool {
|
||||
switch loader {
|
||||
case LoaderJS, LoaderJSX, LoaderTS, LoaderTSNoAmbiguousLessThan, LoaderTSX, LoaderCSS:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
type Format uint8
|
||||
|
||||
const (
|
||||
// This is used when not bundling. It means to preserve whatever form the
|
||||
// import or export was originally in. ES6 syntax stays ES6 syntax and
|
||||
// CommonJS syntax stays CommonJS syntax.
|
||||
FormatPreserve Format = iota
|
||||
|
||||
// IIFE stands for immediately-invoked function expression. That looks like
|
||||
// this:
|
||||
//
|
||||
// (() => {
|
||||
// ... bundled code ...
|
||||
// })();
|
||||
//
|
||||
// If the optional GlobalName is configured, then we'll write out this:
|
||||
//
|
||||
// let globalName = (() => {
|
||||
// ... bundled code ...
|
||||
// return exports;
|
||||
// })();
|
||||
//
|
||||
FormatIIFE
|
||||
|
||||
// The CommonJS format looks like this:
|
||||
//
|
||||
// ... bundled code ...
|
||||
// module.exports = exports;
|
||||
//
|
||||
FormatCommonJS
|
||||
|
||||
// The ES module format looks like this:
|
||||
//
|
||||
// ... bundled code ...
|
||||
// export {...};
|
||||
//
|
||||
FormatESModule
|
||||
)
|
||||
|
||||
func (f Format) KeepES6ImportExportSyntax() bool {
|
||||
return f == FormatPreserve || f == FormatESModule
|
||||
}
|
||||
|
||||
func (f Format) String() string {
|
||||
switch f {
|
||||
case FormatIIFE:
|
||||
return "iife"
|
||||
case FormatCommonJS:
|
||||
return "cjs"
|
||||
case FormatESModule:
|
||||
return "esm"
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type StdinInfo struct {
|
||||
Loader Loader
|
||||
Contents string
|
||||
SourceFile string
|
||||
AbsResolveDir string
|
||||
}
|
||||
|
||||
type WildcardPattern struct {
|
||||
Prefix string
|
||||
Suffix string
|
||||
}
|
||||
|
||||
type ExternalModules struct {
|
||||
NodeModules map[string]bool
|
||||
AbsPaths map[string]bool
|
||||
Patterns []WildcardPattern
|
||||
}
|
||||
|
||||
type Mode uint8
|
||||
|
||||
const (
|
||||
ModePassThrough Mode = iota
|
||||
ModeConvertFormat
|
||||
ModeBundle
|
||||
)
|
||||
|
||||
type MaybeBool uint8
|
||||
|
||||
const (
|
||||
Unspecified MaybeBool = iota
|
||||
True
|
||||
False
|
||||
)
|
||||
|
||||
type Options struct {
|
||||
Mode Mode
|
||||
ModuleType js_ast.ModuleType
|
||||
PreserveSymlinks bool
|
||||
RemoveWhitespace bool
|
||||
MinifyIdentifiers bool
|
||||
MangleSyntax bool
|
||||
ProfilerNames bool
|
||||
CodeSplitting bool
|
||||
WatchMode bool
|
||||
AllowOverwrite bool
|
||||
LegalComments LegalComments
|
||||
|
||||
// If true, make sure to generate a single file that can be written to stdout
|
||||
WriteToStdout bool
|
||||
|
||||
OmitRuntimeForTests bool
|
||||
UnusedImportsTS UnusedImportsTS
|
||||
UseDefineForClassFields MaybeBool
|
||||
ASCIIOnly bool
|
||||
KeepNames bool
|
||||
IgnoreDCEAnnotations bool
|
||||
TreeShaking bool
|
||||
|
||||
Defines *ProcessedDefines
|
||||
TS TSOptions
|
||||
JSX JSXOptions
|
||||
Platform Platform
|
||||
|
||||
TargetFromAPI TargetFromAPI
|
||||
UnsupportedJSFeatures compat.JSFeature
|
||||
UnsupportedCSSFeatures compat.CSSFeature
|
||||
TSTarget *TSTarget
|
||||
|
||||
// This is the original information that was used to generate the
|
||||
// unsupported feature sets above. It's used for error messages.
|
||||
OriginalTargetEnv string
|
||||
|
||||
ExtensionOrder []string
|
||||
MainFields []string
|
||||
Conditions []string
|
||||
AbsNodePaths []string // The "NODE_PATH" variable from Node.js
|
||||
ExternalModules ExternalModules
|
||||
|
||||
AbsOutputFile string
|
||||
AbsOutputDir string
|
||||
AbsOutputBase string
|
||||
OutputExtensionJS string
|
||||
OutputExtensionCSS string
|
||||
GlobalName []string
|
||||
TsConfigOverride string
|
||||
ExtensionToLoader map[string]Loader
|
||||
OutputFormat Format
|
||||
PublicPath string
|
||||
InjectAbsPaths []string
|
||||
InjectedDefines []InjectedDefine
|
||||
InjectedFiles []InjectedFile
|
||||
|
||||
JSBanner string
|
||||
JSFooter string
|
||||
CSSBanner string
|
||||
CSSFooter string
|
||||
|
||||
EntryPathTemplate []PathTemplate
|
||||
ChunkPathTemplate []PathTemplate
|
||||
AssetPathTemplate []PathTemplate
|
||||
|
||||
Plugins []Plugin
|
||||
|
||||
NeedsMetafile bool
|
||||
|
||||
SourceMap SourceMap
|
||||
SourceRoot string
|
||||
ExcludeSourcesContent bool
|
||||
|
||||
Stdin *StdinInfo
|
||||
}
|
||||
|
||||
type TargetFromAPI uint8
|
||||
|
||||
const (
|
||||
// In this state, the "target" field in "tsconfig.json" is respected
|
||||
TargetWasUnconfigured TargetFromAPI = iota
|
||||
|
||||
// In this state, the "target" field in "tsconfig.json" is overridden
|
||||
TargetWasConfigured
|
||||
|
||||
// In this state, "useDefineForClassFields" is true unless overridden
|
||||
TargetWasConfiguredIncludingESNext
|
||||
)
|
||||
|
||||
type UnusedImportsTS uint8
|
||||
|
||||
const (
|
||||
// "import { unused } from 'foo'" => "" (TypeScript's default behavior)
|
||||
UnusedImportsRemoveStmt UnusedImportsTS = iota
|
||||
|
||||
// "import { unused } from 'foo'" => "import 'foo'" ("importsNotUsedAsValues" != "remove")
|
||||
UnusedImportsKeepStmtRemoveValues
|
||||
|
||||
// "import { unused } from 'foo'" => "import { unused } from 'foo'" ("preserveValueImports" == true)
|
||||
UnusedImportsKeepValues
|
||||
)
|
||||
|
||||
func UnusedImportsFromTsconfigValues(preserveImportsNotUsedAsValues bool, preserveValueImports bool) UnusedImportsTS {
|
||||
if preserveValueImports {
|
||||
return UnusedImportsKeepValues
|
||||
}
|
||||
if preserveImportsNotUsedAsValues {
|
||||
return UnusedImportsKeepStmtRemoveValues
|
||||
}
|
||||
return UnusedImportsRemoveStmt
|
||||
}
|
||||
|
||||
type TSTarget struct {
|
||||
Source logger.Source
|
||||
Range logger.Range
|
||||
Target string
|
||||
UnsupportedJSFeatures compat.JSFeature
|
||||
}
|
||||
|
||||
type PathPlaceholder uint8
|
||||
|
||||
const (
|
||||
NoPlaceholder PathPlaceholder = iota
|
||||
|
||||
// The relative path from the original parent directory to the configured
|
||||
// "outbase" directory, or to the lowest common ancestor directory
|
||||
DirPlaceholder
|
||||
|
||||
// The original name of the file, or the manual chunk name, or the name of
|
||||
// the type of output file ("entry" or "chunk" or "asset")
|
||||
NamePlaceholder
|
||||
|
||||
// A hash of the contents of this file, and the contents and output paths of
|
||||
// all dependencies (except for their hash placeholders)
|
||||
HashPlaceholder
|
||||
|
||||
// The original extension of the file, or the name of the output file
|
||||
// (e.g. "css", "svg", "png")
|
||||
ExtPlaceholder
|
||||
)
|
||||
|
||||
type PathTemplate struct {
|
||||
Data string
|
||||
Placeholder PathPlaceholder
|
||||
}
|
||||
|
||||
type PathPlaceholders struct {
|
||||
Dir *string
|
||||
Name *string
|
||||
Hash *string
|
||||
Ext *string
|
||||
}
|
||||
|
||||
func (placeholders PathPlaceholders) Get(placeholder PathPlaceholder) *string {
|
||||
switch placeholder {
|
||||
case DirPlaceholder:
|
||||
return placeholders.Dir
|
||||
case NamePlaceholder:
|
||||
return placeholders.Name
|
||||
case HashPlaceholder:
|
||||
return placeholders.Hash
|
||||
case ExtPlaceholder:
|
||||
return placeholders.Ext
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func TemplateToString(template []PathTemplate) string {
|
||||
if len(template) == 1 && template[0].Placeholder == NoPlaceholder {
|
||||
// Avoid allocations in this case
|
||||
return template[0].Data
|
||||
}
|
||||
sb := strings.Builder{}
|
||||
for _, part := range template {
|
||||
sb.WriteString(part.Data)
|
||||
switch part.Placeholder {
|
||||
case DirPlaceholder:
|
||||
sb.WriteString("[dir]")
|
||||
case NamePlaceholder:
|
||||
sb.WriteString("[name]")
|
||||
case HashPlaceholder:
|
||||
sb.WriteString("[hash]")
|
||||
case ExtPlaceholder:
|
||||
sb.WriteString("[ext]")
|
||||
}
|
||||
}
|
||||
return sb.String()
|
||||
}
|
||||
|
||||
func HasPlaceholder(template []PathTemplate, placeholder PathPlaceholder) bool {
|
||||
for _, part := range template {
|
||||
if part.Placeholder == placeholder {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func SubstituteTemplate(template []PathTemplate, placeholders PathPlaceholders) []PathTemplate {
|
||||
// Don't allocate if no substitution is possible and the template is already minimal
|
||||
shouldSubstitute := false
|
||||
for i, part := range template {
|
||||
if placeholders.Get(part.Placeholder) != nil || (part.Placeholder == NoPlaceholder && i+1 < len(template)) {
|
||||
shouldSubstitute = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !shouldSubstitute {
|
||||
return template
|
||||
}
|
||||
|
||||
// Otherwise, substitute and merge as appropriate
|
||||
result := make([]PathTemplate, 0, len(template))
|
||||
for _, part := range template {
|
||||
if sub := placeholders.Get(part.Placeholder); sub != nil {
|
||||
part.Data += *sub
|
||||
part.Placeholder = NoPlaceholder
|
||||
}
|
||||
if last := len(result) - 1; last >= 0 && result[last].Placeholder == NoPlaceholder {
|
||||
last := &result[last]
|
||||
last.Data += part.Data
|
||||
last.Placeholder = part.Placeholder
|
||||
} else {
|
||||
result = append(result, part)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func ShouldCallRuntimeRequire(mode Mode, outputFormat Format) bool {
|
||||
return mode == ModeBundle && outputFormat != FormatCommonJS
|
||||
}
|
||||
|
||||
type InjectedDefine struct {
|
||||
Source logger.Source
|
||||
Data js_ast.E
|
||||
Name string
|
||||
}
|
||||
|
||||
type InjectedFile struct {
|
||||
Source logger.Source
|
||||
Exports []InjectableExport
|
||||
DefineName string
|
||||
}
|
||||
|
||||
type InjectableExport struct {
|
||||
Alias string
|
||||
Loc logger.Loc
|
||||
}
|
||||
|
||||
var filterMutex sync.Mutex
|
||||
var filterCache map[string]*regexp.Regexp
|
||||
|
||||
func compileFilter(filter string) (result *regexp.Regexp) {
|
||||
if filter == "" {
|
||||
// Must provide a filter
|
||||
return nil
|
||||
}
|
||||
ok := false
|
||||
|
||||
// Cache hit?
|
||||
(func() {
|
||||
filterMutex.Lock()
|
||||
defer filterMutex.Unlock()
|
||||
if filterCache != nil {
|
||||
result, ok = filterCache[filter]
|
||||
}
|
||||
})()
|
||||
if ok {
|
||||
return
|
||||
}
|
||||
|
||||
// Cache miss
|
||||
result, err := regexp.Compile(filter)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Cache for next time
|
||||
filterMutex.Lock()
|
||||
defer filterMutex.Unlock()
|
||||
if filterCache == nil {
|
||||
filterCache = make(map[string]*regexp.Regexp)
|
||||
}
|
||||
filterCache[filter] = result
|
||||
return
|
||||
}
|
||||
|
||||
func CompileFilterForPlugin(pluginName string, kind string, filter string) (*regexp.Regexp, error) {
|
||||
if filter == "" {
|
||||
return nil, fmt.Errorf("[%s] %q is missing a filter", pluginName, kind)
|
||||
}
|
||||
|
||||
result := compileFilter(filter)
|
||||
if result == nil {
|
||||
return nil, fmt.Errorf("[%s] %q filter is not a valid Go regular expression: %q", pluginName, kind, filter)
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func PluginAppliesToPath(path logger.Path, filter *regexp.Regexp, namespace string) bool {
|
||||
return (namespace == "" || path.Namespace == namespace) && filter.MatchString(path.Text)
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Plugin API
|
||||
|
||||
type Plugin struct {
|
||||
Name string
|
||||
OnStart []OnStart
|
||||
OnResolve []OnResolve
|
||||
OnLoad []OnLoad
|
||||
}
|
||||
|
||||
type OnStart struct {
|
||||
Name string
|
||||
Callback func() OnStartResult
|
||||
}
|
||||
|
||||
type OnStartResult struct {
|
||||
Msgs []logger.Msg
|
||||
ThrownError error
|
||||
}
|
||||
|
||||
type OnResolve struct {
|
||||
Name string
|
||||
Filter *regexp.Regexp
|
||||
Namespace string
|
||||
Callback func(OnResolveArgs) OnResolveResult
|
||||
}
|
||||
|
||||
type OnResolveArgs struct {
|
||||
Path string
|
||||
Importer logger.Path
|
||||
ResolveDir string
|
||||
Kind ast.ImportKind
|
||||
PluginData interface{}
|
||||
}
|
||||
|
||||
type OnResolveResult struct {
|
||||
PluginName string
|
||||
|
||||
Path logger.Path
|
||||
External bool
|
||||
IsSideEffectFree bool
|
||||
PluginData interface{}
|
||||
|
||||
Msgs []logger.Msg
|
||||
ThrownError error
|
||||
|
||||
AbsWatchFiles []string
|
||||
AbsWatchDirs []string
|
||||
}
|
||||
|
||||
type OnLoad struct {
|
||||
Name string
|
||||
Filter *regexp.Regexp
|
||||
Namespace string
|
||||
Callback func(OnLoadArgs) OnLoadResult
|
||||
}
|
||||
|
||||
type OnLoadArgs struct {
|
||||
Path logger.Path
|
||||
PluginData interface{}
|
||||
}
|
||||
|
||||
type OnLoadResult struct {
|
||||
PluginName string
|
||||
|
||||
Contents *string
|
||||
AbsResolveDir string
|
||||
Loader Loader
|
||||
PluginData interface{}
|
||||
|
||||
Msgs []logger.Msg
|
||||
ThrownError error
|
||||
|
||||
AbsWatchFiles []string
|
||||
AbsWatchDirs []string
|
||||
}
|
969
vendor/github.com/evanw/esbuild/internal/config/globals.go
generated
vendored
Normal file
969
vendor/github.com/evanw/esbuild/internal/config/globals.go
generated
vendored
Normal file
@ -0,0 +1,969 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"math"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/evanw/esbuild/internal/js_ast"
|
||||
"github.com/evanw/esbuild/internal/logger"
|
||||
)
|
||||
|
||||
var processedGlobalsMutex sync.Mutex
|
||||
var processedGlobals *ProcessedDefines
|
||||
|
||||
// If something is in this list, then a direct identifier expression or property
|
||||
// access chain matching this will be assumed to have no side effects and will
|
||||
// be removed.
|
||||
//
|
||||
// This also means code is allowed to be reordered past things in this list. For
|
||||
// example, if "console.log" is in this list, permitting reordering allows for
|
||||
// "if (a) console.log(b); else console.log(c)" to be reordered and transformed
|
||||
// into "console.log(a ? b : c)". Notice that "a" and "console.log" are in a
|
||||
// different order, which can only happen if evaluating the "console.log"
|
||||
// property access can be assumed to not change the value of "a".
|
||||
//
|
||||
// Note that membership in this list says nothing about whether calling any of
|
||||
// these functions has any side effects. It only says something about
|
||||
// referencing these function without calling them.
|
||||
var knownGlobals = [][]string{
|
||||
// These global identifiers should exist in all JavaScript environments. This
|
||||
// deliberately omits "NaN", "Infinity", and "undefined" because these are
|
||||
// treated as automatically-inlined constants instead of identifiers.
|
||||
{"Array"},
|
||||
{"Boolean"},
|
||||
{"Function"},
|
||||
{"Math"},
|
||||
{"Number"},
|
||||
{"Object"},
|
||||
{"RegExp"},
|
||||
{"String"},
|
||||
|
||||
// Object: Static methods
|
||||
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object#Static_methods
|
||||
{"Object", "assign"},
|
||||
{"Object", "create"},
|
||||
{"Object", "defineProperties"},
|
||||
{"Object", "defineProperty"},
|
||||
{"Object", "entries"},
|
||||
{"Object", "freeze"},
|
||||
{"Object", "fromEntries"},
|
||||
{"Object", "getOwnPropertyDescriptor"},
|
||||
{"Object", "getOwnPropertyDescriptors"},
|
||||
{"Object", "getOwnPropertyNames"},
|
||||
{"Object", "getOwnPropertySymbols"},
|
||||
{"Object", "getPrototypeOf"},
|
||||
{"Object", "is"},
|
||||
{"Object", "isExtensible"},
|
||||
{"Object", "isFrozen"},
|
||||
{"Object", "isSealed"},
|
||||
{"Object", "keys"},
|
||||
{"Object", "preventExtensions"},
|
||||
{"Object", "seal"},
|
||||
{"Object", "setPrototypeOf"},
|
||||
{"Object", "values"},
|
||||
|
||||
// Object: Instance methods
|
||||
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object#Instance_methods
|
||||
{"Object", "prototype", "__defineGetter__"},
|
||||
{"Object", "prototype", "__defineSetter__"},
|
||||
{"Object", "prototype", "__lookupGetter__"},
|
||||
{"Object", "prototype", "__lookupSetter__"},
|
||||
{"Object", "prototype", "hasOwnProperty"},
|
||||
{"Object", "prototype", "isPrototypeOf"},
|
||||
{"Object", "prototype", "propertyIsEnumerable"},
|
||||
{"Object", "prototype", "toLocaleString"},
|
||||
{"Object", "prototype", "toString"},
|
||||
{"Object", "prototype", "unwatch"},
|
||||
{"Object", "prototype", "valueOf"},
|
||||
{"Object", "prototype", "watch"},
|
||||
|
||||
// Math: Static properties
|
||||
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math#Static_properties
|
||||
{"Math", "E"},
|
||||
{"Math", "LN10"},
|
||||
{"Math", "LN2"},
|
||||
{"Math", "LOG10E"},
|
||||
{"Math", "LOG2E"},
|
||||
{"Math", "PI"},
|
||||
{"Math", "SQRT1_2"},
|
||||
{"Math", "SQRT2"},
|
||||
|
||||
// Math: Static methods
|
||||
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math#Static_methods
|
||||
{"Math", "abs"},
|
||||
{"Math", "acos"},
|
||||
{"Math", "acosh"},
|
||||
{"Math", "asin"},
|
||||
{"Math", "asinh"},
|
||||
{"Math", "atan"},
|
||||
{"Math", "atan2"},
|
||||
{"Math", "atanh"},
|
||||
{"Math", "cbrt"},
|
||||
{"Math", "ceil"},
|
||||
{"Math", "clz32"},
|
||||
{"Math", "cos"},
|
||||
{"Math", "cosh"},
|
||||
{"Math", "exp"},
|
||||
{"Math", "expm1"},
|
||||
{"Math", "floor"},
|
||||
{"Math", "fround"},
|
||||
{"Math", "hypot"},
|
||||
{"Math", "imul"},
|
||||
{"Math", "log"},
|
||||
{"Math", "log10"},
|
||||
{"Math", "log1p"},
|
||||
{"Math", "log2"},
|
||||
{"Math", "max"},
|
||||
{"Math", "min"},
|
||||
{"Math", "pow"},
|
||||
{"Math", "random"},
|
||||
{"Math", "round"},
|
||||
{"Math", "sign"},
|
||||
{"Math", "sin"},
|
||||
{"Math", "sinh"},
|
||||
{"Math", "sqrt"},
|
||||
{"Math", "tan"},
|
||||
{"Math", "tanh"},
|
||||
{"Math", "trunc"},
|
||||
|
||||
// Reflect: Static methods
|
||||
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect#static_methods
|
||||
{"Reflect", "apply"},
|
||||
{"Reflect", "construct"},
|
||||
{"Reflect", "defineProperty"},
|
||||
{"Reflect", "deleteProperty"},
|
||||
{"Reflect", "get"},
|
||||
{"Reflect", "getOwnPropertyDescriptor"},
|
||||
{"Reflect", "getPrototypeOf"},
|
||||
{"Reflect", "has"},
|
||||
{"Reflect", "isExtensible"},
|
||||
{"Reflect", "ownKeys"},
|
||||
{"Reflect", "preventExtensions"},
|
||||
{"Reflect", "set"},
|
||||
{"Reflect", "setPrototypeOf"},
|
||||
|
||||
// Other globals present in both the browser and node (except "eval" because
|
||||
// it has special behavior)
|
||||
{"AbortController"},
|
||||
{"AbortSignal"},
|
||||
{"AggregateError"},
|
||||
{"ArrayBuffer"},
|
||||
{"BigInt"},
|
||||
{"DataView"},
|
||||
{"Date"},
|
||||
{"Error"},
|
||||
{"EvalError"},
|
||||
{"Event"},
|
||||
{"EventTarget"},
|
||||
{"Float32Array"},
|
||||
{"Float64Array"},
|
||||
{"Int16Array"},
|
||||
{"Int32Array"},
|
||||
{"Int8Array"},
|
||||
{"Intl"},
|
||||
{"JSON"},
|
||||
{"Map"},
|
||||
{"MessageChannel"},
|
||||
{"MessageEvent"},
|
||||
{"MessagePort"},
|
||||
{"Promise"},
|
||||
{"Proxy"},
|
||||
{"RangeError"},
|
||||
{"ReferenceError"},
|
||||
{"Reflect"},
|
||||
{"Set"},
|
||||
{"Symbol"},
|
||||
{"SyntaxError"},
|
||||
{"TextDecoder"},
|
||||
{"TextEncoder"},
|
||||
{"TypeError"},
|
||||
{"URIError"},
|
||||
{"URL"},
|
||||
{"URLSearchParams"},
|
||||
{"Uint16Array"},
|
||||
{"Uint32Array"},
|
||||
{"Uint8Array"},
|
||||
{"Uint8ClampedArray"},
|
||||
{"WeakMap"},
|
||||
{"WeakSet"},
|
||||
{"WebAssembly"},
|
||||
{"clearInterval"},
|
||||
{"clearTimeout"},
|
||||
{"console"},
|
||||
{"decodeURI"},
|
||||
{"decodeURIComponent"},
|
||||
{"encodeURI"},
|
||||
{"encodeURIComponent"},
|
||||
{"escape"},
|
||||
{"globalThis"},
|
||||
{"isFinite"},
|
||||
{"isNaN"},
|
||||
{"parseFloat"},
|
||||
{"parseInt"},
|
||||
{"queueMicrotask"},
|
||||
{"setInterval"},
|
||||
{"setTimeout"},
|
||||
{"unescape"},
|
||||
|
||||
// Console method references are assumed to have no side effects
|
||||
// https://developer.mozilla.org/en-US/docs/Web/API/console
|
||||
{"console", "assert"},
|
||||
{"console", "clear"},
|
||||
{"console", "count"},
|
||||
{"console", "countReset"},
|
||||
{"console", "debug"},
|
||||
{"console", "dir"},
|
||||
{"console", "dirxml"},
|
||||
{"console", "error"},
|
||||
{"console", "group"},
|
||||
{"console", "groupCollapsed"},
|
||||
{"console", "groupEnd"},
|
||||
{"console", "info"},
|
||||
{"console", "log"},
|
||||
{"console", "table"},
|
||||
{"console", "time"},
|
||||
{"console", "timeEnd"},
|
||||
{"console", "timeLog"},
|
||||
{"console", "trace"},
|
||||
{"console", "warn"},
|
||||
|
||||
// CSSOM APIs
|
||||
{"CSSAnimation"},
|
||||
{"CSSFontFaceRule"},
|
||||
{"CSSImportRule"},
|
||||
{"CSSKeyframeRule"},
|
||||
{"CSSKeyframesRule"},
|
||||
{"CSSMediaRule"},
|
||||
{"CSSNamespaceRule"},
|
||||
{"CSSPageRule"},
|
||||
{"CSSRule"},
|
||||
{"CSSRuleList"},
|
||||
{"CSSStyleDeclaration"},
|
||||
{"CSSStyleRule"},
|
||||
{"CSSStyleSheet"},
|
||||
{"CSSSupportsRule"},
|
||||
{"CSSTransition"},
|
||||
|
||||
// SVG DOM
|
||||
{"SVGAElement"},
|
||||
{"SVGAngle"},
|
||||
{"SVGAnimateElement"},
|
||||
{"SVGAnimateMotionElement"},
|
||||
{"SVGAnimateTransformElement"},
|
||||
{"SVGAnimatedAngle"},
|
||||
{"SVGAnimatedBoolean"},
|
||||
{"SVGAnimatedEnumeration"},
|
||||
{"SVGAnimatedInteger"},
|
||||
{"SVGAnimatedLength"},
|
||||
{"SVGAnimatedLengthList"},
|
||||
{"SVGAnimatedNumber"},
|
||||
{"SVGAnimatedNumberList"},
|
||||
{"SVGAnimatedPreserveAspectRatio"},
|
||||
{"SVGAnimatedRect"},
|
||||
{"SVGAnimatedString"},
|
||||
{"SVGAnimatedTransformList"},
|
||||
{"SVGAnimationElement"},
|
||||
{"SVGCircleElement"},
|
||||
{"SVGClipPathElement"},
|
||||
{"SVGComponentTransferFunctionElement"},
|
||||
{"SVGDefsElement"},
|
||||
{"SVGDescElement"},
|
||||
{"SVGElement"},
|
||||
{"SVGEllipseElement"},
|
||||
{"SVGFEBlendElement"},
|
||||
{"SVGFEColorMatrixElement"},
|
||||
{"SVGFEComponentTransferElement"},
|
||||
{"SVGFECompositeElement"},
|
||||
{"SVGFEConvolveMatrixElement"},
|
||||
{"SVGFEDiffuseLightingElement"},
|
||||
{"SVGFEDisplacementMapElement"},
|
||||
{"SVGFEDistantLightElement"},
|
||||
{"SVGFEDropShadowElement"},
|
||||
{"SVGFEFloodElement"},
|
||||
{"SVGFEFuncAElement"},
|
||||
{"SVGFEFuncBElement"},
|
||||
{"SVGFEFuncGElement"},
|
||||
{"SVGFEFuncRElement"},
|
||||
{"SVGFEGaussianBlurElement"},
|
||||
{"SVGFEImageElement"},
|
||||
{"SVGFEMergeElement"},
|
||||
{"SVGFEMergeNodeElement"},
|
||||
{"SVGFEMorphologyElement"},
|
||||
{"SVGFEOffsetElement"},
|
||||
{"SVGFEPointLightElement"},
|
||||
{"SVGFESpecularLightingElement"},
|
||||
{"SVGFESpotLightElement"},
|
||||
{"SVGFETileElement"},
|
||||
{"SVGFETurbulenceElement"},
|
||||
{"SVGFilterElement"},
|
||||
{"SVGForeignObjectElement"},
|
||||
{"SVGGElement"},
|
||||
{"SVGGeometryElement"},
|
||||
{"SVGGradientElement"},
|
||||
{"SVGGraphicsElement"},
|
||||
{"SVGImageElement"},
|
||||
{"SVGLength"},
|
||||
{"SVGLengthList"},
|
||||
{"SVGLineElement"},
|
||||
{"SVGLinearGradientElement"},
|
||||
{"SVGMPathElement"},
|
||||
{"SVGMarkerElement"},
|
||||
{"SVGMaskElement"},
|
||||
{"SVGMatrix"},
|
||||
{"SVGMetadataElement"},
|
||||
{"SVGNumber"},
|
||||
{"SVGNumberList"},
|
||||
{"SVGPathElement"},
|
||||
{"SVGPatternElement"},
|
||||
{"SVGPoint"},
|
||||
{"SVGPointList"},
|
||||
{"SVGPolygonElement"},
|
||||
{"SVGPolylineElement"},
|
||||
{"SVGPreserveAspectRatio"},
|
||||
{"SVGRadialGradientElement"},
|
||||
{"SVGRect"},
|
||||
{"SVGRectElement"},
|
||||
{"SVGSVGElement"},
|
||||
{"SVGScriptElement"},
|
||||
{"SVGSetElement"},
|
||||
{"SVGStopElement"},
|
||||
{"SVGStringList"},
|
||||
{"SVGStyleElement"},
|
||||
{"SVGSwitchElement"},
|
||||
{"SVGSymbolElement"},
|
||||
{"SVGTSpanElement"},
|
||||
{"SVGTextContentElement"},
|
||||
{"SVGTextElement"},
|
||||
{"SVGTextPathElement"},
|
||||
{"SVGTextPositioningElement"},
|
||||
{"SVGTitleElement"},
|
||||
{"SVGTransform"},
|
||||
{"SVGTransformList"},
|
||||
{"SVGUnitTypes"},
|
||||
{"SVGUseElement"},
|
||||
{"SVGViewElement"},
|
||||
|
||||
// Other browser APIs
|
||||
//
|
||||
// This list contains all globals present in modern versions of Chrome, Safari,
|
||||
// and Firefox except for the following properties, since they have a side effect
|
||||
// of triggering layout (https://gist.github.com/paulirish/5d52fb081b3570c81e3a):
|
||||
//
|
||||
// - scrollX
|
||||
// - scrollY
|
||||
// - innerWidth
|
||||
// - innerHeight
|
||||
// - pageXOffset
|
||||
// - pageYOffset
|
||||
//
|
||||
// The following globals have also been removed since they sometimes throw an
|
||||
// exception when accessed, which is a side effect (for more information see
|
||||
// https://stackoverflow.com/a/33047477):
|
||||
//
|
||||
// - localStorage
|
||||
// - sessionStorage
|
||||
//
|
||||
{"AnalyserNode"},
|
||||
{"Animation"},
|
||||
{"AnimationEffect"},
|
||||
{"AnimationEvent"},
|
||||
{"AnimationPlaybackEvent"},
|
||||
{"AnimationTimeline"},
|
||||
{"Attr"},
|
||||
{"Audio"},
|
||||
{"AudioBuffer"},
|
||||
{"AudioBufferSourceNode"},
|
||||
{"AudioDestinationNode"},
|
||||
{"AudioListener"},
|
||||
{"AudioNode"},
|
||||
{"AudioParam"},
|
||||
{"AudioProcessingEvent"},
|
||||
{"AudioScheduledSourceNode"},
|
||||
{"BarProp"},
|
||||
{"BeforeUnloadEvent"},
|
||||
{"BiquadFilterNode"},
|
||||
{"Blob"},
|
||||
{"BlobEvent"},
|
||||
{"ByteLengthQueuingStrategy"},
|
||||
{"CDATASection"},
|
||||
{"CSS"},
|
||||
{"CanvasGradient"},
|
||||
{"CanvasPattern"},
|
||||
{"CanvasRenderingContext2D"},
|
||||
{"ChannelMergerNode"},
|
||||
{"ChannelSplitterNode"},
|
||||
{"CharacterData"},
|
||||
{"ClipboardEvent"},
|
||||
{"CloseEvent"},
|
||||
{"Comment"},
|
||||
{"CompositionEvent"},
|
||||
{"ConvolverNode"},
|
||||
{"CountQueuingStrategy"},
|
||||
{"Crypto"},
|
||||
{"CustomElementRegistry"},
|
||||
{"CustomEvent"},
|
||||
{"DOMException"},
|
||||
{"DOMImplementation"},
|
||||
{"DOMMatrix"},
|
||||
{"DOMMatrixReadOnly"},
|
||||
{"DOMParser"},
|
||||
{"DOMPoint"},
|
||||
{"DOMPointReadOnly"},
|
||||
{"DOMQuad"},
|
||||
{"DOMRect"},
|
||||
{"DOMRectList"},
|
||||
{"DOMRectReadOnly"},
|
||||
{"DOMStringList"},
|
||||
{"DOMStringMap"},
|
||||
{"DOMTokenList"},
|
||||
{"DataTransfer"},
|
||||
{"DataTransferItem"},
|
||||
{"DataTransferItemList"},
|
||||
{"DelayNode"},
|
||||
{"Document"},
|
||||
{"DocumentFragment"},
|
||||
{"DocumentTimeline"},
|
||||
{"DocumentType"},
|
||||
{"DragEvent"},
|
||||
{"DynamicsCompressorNode"},
|
||||
{"Element"},
|
||||
{"ErrorEvent"},
|
||||
{"EventSource"},
|
||||
{"File"},
|
||||
{"FileList"},
|
||||
{"FileReader"},
|
||||
{"FocusEvent"},
|
||||
{"FontFace"},
|
||||
{"FormData"},
|
||||
{"GainNode"},
|
||||
{"Gamepad"},
|
||||
{"GamepadButton"},
|
||||
{"GamepadEvent"},
|
||||
{"Geolocation"},
|
||||
{"GeolocationPositionError"},
|
||||
{"HTMLAllCollection"},
|
||||
{"HTMLAnchorElement"},
|
||||
{"HTMLAreaElement"},
|
||||
{"HTMLAudioElement"},
|
||||
{"HTMLBRElement"},
|
||||
{"HTMLBaseElement"},
|
||||
{"HTMLBodyElement"},
|
||||
{"HTMLButtonElement"},
|
||||
{"HTMLCanvasElement"},
|
||||
{"HTMLCollection"},
|
||||
{"HTMLDListElement"},
|
||||
{"HTMLDataElement"},
|
||||
{"HTMLDataListElement"},
|
||||
{"HTMLDetailsElement"},
|
||||
{"HTMLDirectoryElement"},
|
||||
{"HTMLDivElement"},
|
||||
{"HTMLDocument"},
|
||||
{"HTMLElement"},
|
||||
{"HTMLEmbedElement"},
|
||||
{"HTMLFieldSetElement"},
|
||||
{"HTMLFontElement"},
|
||||
{"HTMLFormControlsCollection"},
|
||||
{"HTMLFormElement"},
|
||||
{"HTMLFrameElement"},
|
||||
{"HTMLFrameSetElement"},
|
||||
{"HTMLHRElement"},
|
||||
{"HTMLHeadElement"},
|
||||
{"HTMLHeadingElement"},
|
||||
{"HTMLHtmlElement"},
|
||||
{"HTMLIFrameElement"},
|
||||
{"HTMLImageElement"},
|
||||
{"HTMLInputElement"},
|
||||
{"HTMLLIElement"},
|
||||
{"HTMLLabelElement"},
|
||||
{"HTMLLegendElement"},
|
||||
{"HTMLLinkElement"},
|
||||
{"HTMLMapElement"},
|
||||
{"HTMLMarqueeElement"},
|
||||
{"HTMLMediaElement"},
|
||||
{"HTMLMenuElement"},
|
||||
{"HTMLMetaElement"},
|
||||
{"HTMLMeterElement"},
|
||||
{"HTMLModElement"},
|
||||
{"HTMLOListElement"},
|
||||
{"HTMLObjectElement"},
|
||||
{"HTMLOptGroupElement"},
|
||||
{"HTMLOptionElement"},
|
||||
{"HTMLOptionsCollection"},
|
||||
{"HTMLOutputElement"},
|
||||
{"HTMLParagraphElement"},
|
||||
{"HTMLParamElement"},
|
||||
{"HTMLPictureElement"},
|
||||
{"HTMLPreElement"},
|
||||
{"HTMLProgressElement"},
|
||||
{"HTMLQuoteElement"},
|
||||
{"HTMLScriptElement"},
|
||||
{"HTMLSelectElement"},
|
||||
{"HTMLSlotElement"},
|
||||
{"HTMLSourceElement"},
|
||||
{"HTMLSpanElement"},
|
||||
{"HTMLStyleElement"},
|
||||
{"HTMLTableCaptionElement"},
|
||||
{"HTMLTableCellElement"},
|
||||
{"HTMLTableColElement"},
|
||||
{"HTMLTableElement"},
|
||||
{"HTMLTableRowElement"},
|
||||
{"HTMLTableSectionElement"},
|
||||
{"HTMLTemplateElement"},
|
||||
{"HTMLTextAreaElement"},
|
||||
{"HTMLTimeElement"},
|
||||
{"HTMLTitleElement"},
|
||||
{"HTMLTrackElement"},
|
||||
{"HTMLUListElement"},
|
||||
{"HTMLUnknownElement"},
|
||||
{"HTMLVideoElement"},
|
||||
{"HashChangeEvent"},
|
||||
{"Headers"},
|
||||
{"History"},
|
||||
{"IDBCursor"},
|
||||
{"IDBCursorWithValue"},
|
||||
{"IDBDatabase"},
|
||||
{"IDBFactory"},
|
||||
{"IDBIndex"},
|
||||
{"IDBKeyRange"},
|
||||
{"IDBObjectStore"},
|
||||
{"IDBOpenDBRequest"},
|
||||
{"IDBRequest"},
|
||||
{"IDBTransaction"},
|
||||
{"IDBVersionChangeEvent"},
|
||||
{"Image"},
|
||||
{"ImageData"},
|
||||
{"InputEvent"},
|
||||
{"IntersectionObserver"},
|
||||
{"IntersectionObserverEntry"},
|
||||
{"KeyboardEvent"},
|
||||
{"KeyframeEffect"},
|
||||
{"Location"},
|
||||
{"MediaCapabilities"},
|
||||
{"MediaElementAudioSourceNode"},
|
||||
{"MediaEncryptedEvent"},
|
||||
{"MediaError"},
|
||||
{"MediaList"},
|
||||
{"MediaQueryList"},
|
||||
{"MediaQueryListEvent"},
|
||||
{"MediaRecorder"},
|
||||
{"MediaSource"},
|
||||
{"MediaStream"},
|
||||
{"MediaStreamAudioDestinationNode"},
|
||||
{"MediaStreamAudioSourceNode"},
|
||||
{"MediaStreamTrack"},
|
||||
{"MediaStreamTrackEvent"},
|
||||
{"MimeType"},
|
||||
{"MimeTypeArray"},
|
||||
{"MouseEvent"},
|
||||
{"MutationEvent"},
|
||||
{"MutationObserver"},
|
||||
{"MutationRecord"},
|
||||
{"NamedNodeMap"},
|
||||
{"Navigator"},
|
||||
{"Node"},
|
||||
{"NodeFilter"},
|
||||
{"NodeIterator"},
|
||||
{"NodeList"},
|
||||
{"Notification"},
|
||||
{"OfflineAudioCompletionEvent"},
|
||||
{"Option"},
|
||||
{"OscillatorNode"},
|
||||
{"PageTransitionEvent"},
|
||||
{"Path2D"},
|
||||
{"Performance"},
|
||||
{"PerformanceEntry"},
|
||||
{"PerformanceMark"},
|
||||
{"PerformanceMeasure"},
|
||||
{"PerformanceNavigation"},
|
||||
{"PerformanceObserver"},
|
||||
{"PerformanceObserverEntryList"},
|
||||
{"PerformanceResourceTiming"},
|
||||
{"PerformanceTiming"},
|
||||
{"PeriodicWave"},
|
||||
{"Plugin"},
|
||||
{"PluginArray"},
|
||||
{"PointerEvent"},
|
||||
{"PopStateEvent"},
|
||||
{"ProcessingInstruction"},
|
||||
{"ProgressEvent"},
|
||||
{"PromiseRejectionEvent"},
|
||||
{"RTCCertificate"},
|
||||
{"RTCDTMFSender"},
|
||||
{"RTCDTMFToneChangeEvent"},
|
||||
{"RTCDataChannel"},
|
||||
{"RTCDataChannelEvent"},
|
||||
{"RTCIceCandidate"},
|
||||
{"RTCPeerConnection"},
|
||||
{"RTCPeerConnectionIceEvent"},
|
||||
{"RTCRtpReceiver"},
|
||||
{"RTCRtpSender"},
|
||||
{"RTCRtpTransceiver"},
|
||||
{"RTCSessionDescription"},
|
||||
{"RTCStatsReport"},
|
||||
{"RTCTrackEvent"},
|
||||
{"RadioNodeList"},
|
||||
{"Range"},
|
||||
{"ReadableStream"},
|
||||
{"Request"},
|
||||
{"ResizeObserver"},
|
||||
{"ResizeObserverEntry"},
|
||||
{"Response"},
|
||||
{"Screen"},
|
||||
{"ScriptProcessorNode"},
|
||||
{"SecurityPolicyViolationEvent"},
|
||||
{"Selection"},
|
||||
{"ShadowRoot"},
|
||||
{"SourceBuffer"},
|
||||
{"SourceBufferList"},
|
||||
{"SpeechSynthesisEvent"},
|
||||
{"SpeechSynthesisUtterance"},
|
||||
{"StaticRange"},
|
||||
{"Storage"},
|
||||
{"StorageEvent"},
|
||||
{"StyleSheet"},
|
||||
{"StyleSheetList"},
|
||||
{"Text"},
|
||||
{"TextMetrics"},
|
||||
{"TextTrack"},
|
||||
{"TextTrackCue"},
|
||||
{"TextTrackCueList"},
|
||||
{"TextTrackList"},
|
||||
{"TimeRanges"},
|
||||
{"TrackEvent"},
|
||||
{"TransitionEvent"},
|
||||
{"TreeWalker"},
|
||||
{"UIEvent"},
|
||||
{"VTTCue"},
|
||||
{"ValidityState"},
|
||||
{"VisualViewport"},
|
||||
{"WaveShaperNode"},
|
||||
{"WebGLActiveInfo"},
|
||||
{"WebGLBuffer"},
|
||||
{"WebGLContextEvent"},
|
||||
{"WebGLFramebuffer"},
|
||||
{"WebGLProgram"},
|
||||
{"WebGLQuery"},
|
||||
{"WebGLRenderbuffer"},
|
||||
{"WebGLRenderingContext"},
|
||||
{"WebGLSampler"},
|
||||
{"WebGLShader"},
|
||||
{"WebGLShaderPrecisionFormat"},
|
||||
{"WebGLSync"},
|
||||
{"WebGLTexture"},
|
||||
{"WebGLUniformLocation"},
|
||||
{"WebKitCSSMatrix"},
|
||||
{"WebSocket"},
|
||||
{"WheelEvent"},
|
||||
{"Window"},
|
||||
{"Worker"},
|
||||
{"XMLDocument"},
|
||||
{"XMLHttpRequest"},
|
||||
{"XMLHttpRequestEventTarget"},
|
||||
{"XMLHttpRequestUpload"},
|
||||
{"XMLSerializer"},
|
||||
{"XPathEvaluator"},
|
||||
{"XPathExpression"},
|
||||
{"XPathResult"},
|
||||
{"XSLTProcessor"},
|
||||
{"alert"},
|
||||
{"atob"},
|
||||
{"blur"},
|
||||
{"btoa"},
|
||||
{"cancelAnimationFrame"},
|
||||
{"captureEvents"},
|
||||
{"close"},
|
||||
{"closed"},
|
||||
{"confirm"},
|
||||
{"customElements"},
|
||||
{"devicePixelRatio"},
|
||||
{"document"},
|
||||
{"event"},
|
||||
{"fetch"},
|
||||
{"find"},
|
||||
{"focus"},
|
||||
{"frameElement"},
|
||||
{"frames"},
|
||||
{"getComputedStyle"},
|
||||
{"getSelection"},
|
||||
{"history"},
|
||||
{"indexedDB"},
|
||||
{"isSecureContext"},
|
||||
{"length"},
|
||||
{"location"},
|
||||
{"locationbar"},
|
||||
{"matchMedia"},
|
||||
{"menubar"},
|
||||
{"moveBy"},
|
||||
{"moveTo"},
|
||||
{"name"},
|
||||
{"navigator"},
|
||||
{"onabort"},
|
||||
{"onafterprint"},
|
||||
{"onanimationend"},
|
||||
{"onanimationiteration"},
|
||||
{"onanimationstart"},
|
||||
{"onbeforeprint"},
|
||||
{"onbeforeunload"},
|
||||
{"onblur"},
|
||||
{"oncanplay"},
|
||||
{"oncanplaythrough"},
|
||||
{"onchange"},
|
||||
{"onclick"},
|
||||
{"oncontextmenu"},
|
||||
{"oncuechange"},
|
||||
{"ondblclick"},
|
||||
{"ondrag"},
|
||||
{"ondragend"},
|
||||
{"ondragenter"},
|
||||
{"ondragleave"},
|
||||
{"ondragover"},
|
||||
{"ondragstart"},
|
||||
{"ondrop"},
|
||||
{"ondurationchange"},
|
||||
{"onemptied"},
|
||||
{"onended"},
|
||||
{"onerror"},
|
||||
{"onfocus"},
|
||||
{"ongotpointercapture"},
|
||||
{"onhashchange"},
|
||||
{"oninput"},
|
||||
{"oninvalid"},
|
||||
{"onkeydown"},
|
||||
{"onkeypress"},
|
||||
{"onkeyup"},
|
||||
{"onlanguagechange"},
|
||||
{"onload"},
|
||||
{"onloadeddata"},
|
||||
{"onloadedmetadata"},
|
||||
{"onloadstart"},
|
||||
{"onlostpointercapture"},
|
||||
{"onmessage"},
|
||||
{"onmousedown"},
|
||||
{"onmouseenter"},
|
||||
{"onmouseleave"},
|
||||
{"onmousemove"},
|
||||
{"onmouseout"},
|
||||
{"onmouseover"},
|
||||
{"onmouseup"},
|
||||
{"onoffline"},
|
||||
{"ononline"},
|
||||
{"onpagehide"},
|
||||
{"onpageshow"},
|
||||
{"onpause"},
|
||||
{"onplay"},
|
||||
{"onplaying"},
|
||||
{"onpointercancel"},
|
||||
{"onpointerdown"},
|
||||
{"onpointerenter"},
|
||||
{"onpointerleave"},
|
||||
{"onpointermove"},
|
||||
{"onpointerout"},
|
||||
{"onpointerover"},
|
||||
{"onpointerup"},
|
||||
{"onpopstate"},
|
||||
{"onprogress"},
|
||||
{"onratechange"},
|
||||
{"onrejectionhandled"},
|
||||
{"onreset"},
|
||||
{"onresize"},
|
||||
{"onscroll"},
|
||||
{"onseeked"},
|
||||
{"onseeking"},
|
||||
{"onselect"},
|
||||
{"onstalled"},
|
||||
{"onstorage"},
|
||||
{"onsubmit"},
|
||||
{"onsuspend"},
|
||||
{"ontimeupdate"},
|
||||
{"ontoggle"},
|
||||
{"ontransitioncancel"},
|
||||
{"ontransitionend"},
|
||||
{"ontransitionrun"},
|
||||
{"ontransitionstart"},
|
||||
{"onunhandledrejection"},
|
||||
{"onunload"},
|
||||
{"onvolumechange"},
|
||||
{"onwaiting"},
|
||||
{"onwebkitanimationend"},
|
||||
{"onwebkitanimationiteration"},
|
||||
{"onwebkitanimationstart"},
|
||||
{"onwebkittransitionend"},
|
||||
{"onwheel"},
|
||||
{"open"},
|
||||
{"opener"},
|
||||
{"origin"},
|
||||
{"outerHeight"},
|
||||
{"outerWidth"},
|
||||
{"parent"},
|
||||
{"performance"},
|
||||
{"personalbar"},
|
||||
{"postMessage"},
|
||||
{"print"},
|
||||
{"prompt"},
|
||||
{"releaseEvents"},
|
||||
{"requestAnimationFrame"},
|
||||
{"resizeBy"},
|
||||
{"resizeTo"},
|
||||
{"screen"},
|
||||
{"screenLeft"},
|
||||
{"screenTop"},
|
||||
{"screenX"},
|
||||
{"screenY"},
|
||||
{"scroll"},
|
||||
{"scrollBy"},
|
||||
{"scrollTo"},
|
||||
{"scrollbars"},
|
||||
{"self"},
|
||||
{"speechSynthesis"},
|
||||
{"status"},
|
||||
{"statusbar"},
|
||||
{"stop"},
|
||||
{"toolbar"},
|
||||
{"top"},
|
||||
{"webkitURL"},
|
||||
{"window"},
|
||||
}
|
||||
|
||||
type DefineArgs struct {
|
||||
Loc logger.Loc
|
||||
FindSymbol func(logger.Loc, string) js_ast.Ref
|
||||
SymbolForDefine func(int) js_ast.Ref
|
||||
}
|
||||
|
||||
type DefineFunc func(DefineArgs) js_ast.E
|
||||
|
||||
type DefineData struct {
|
||||
DefineFunc DefineFunc
|
||||
|
||||
// True if accessing this value is known to not have any side effects. For
|
||||
// example, a bare reference to "Object.create" can be removed because it
|
||||
// does not have any observable side effects.
|
||||
CanBeRemovedIfUnused bool
|
||||
|
||||
// True if a call to this value is known to not have any side effects. For
|
||||
// example, a bare call to "Object()" can be removed because it does not
|
||||
// have any observable side effects.
|
||||
CallCanBeUnwrappedIfUnused bool
|
||||
}
|
||||
|
||||
func mergeDefineData(old DefineData, new DefineData) DefineData {
|
||||
if old.CanBeRemovedIfUnused {
|
||||
new.CanBeRemovedIfUnused = true
|
||||
}
|
||||
if old.CallCanBeUnwrappedIfUnused {
|
||||
new.CallCanBeUnwrappedIfUnused = true
|
||||
}
|
||||
return new
|
||||
}
|
||||
|
||||
type DotDefine struct {
|
||||
Parts []string
|
||||
Data DefineData
|
||||
}
|
||||
|
||||
type ProcessedDefines struct {
|
||||
IdentifierDefines map[string]DefineData
|
||||
DotDefines map[string][]DotDefine
|
||||
}
|
||||
|
||||
// This transformation is expensive, so we only want to do it once. Make sure
|
||||
// to only call processDefines() once per compilation. Unfortunately Golang
|
||||
// doesn't have an efficient way to copy a map and the overhead of copying
|
||||
// all of the properties into a new map once for every new parser noticeably
|
||||
// slows down our benchmarks.
|
||||
func ProcessDefines(userDefines map[string]DefineData) ProcessedDefines {
|
||||
// Optimization: reuse known globals if there are no user-specified defines
|
||||
hasUserDefines := len(userDefines) != 0
|
||||
if !hasUserDefines {
|
||||
processedGlobalsMutex.Lock()
|
||||
if processedGlobals != nil {
|
||||
defer processedGlobalsMutex.Unlock()
|
||||
return *processedGlobals
|
||||
}
|
||||
processedGlobalsMutex.Unlock()
|
||||
}
|
||||
|
||||
result := ProcessedDefines{
|
||||
IdentifierDefines: make(map[string]DefineData),
|
||||
DotDefines: make(map[string][]DotDefine),
|
||||
}
|
||||
|
||||
// Mark these property accesses as free of side effects. That means they can
|
||||
// be removed if their result is unused. We can't just remove all unused
|
||||
// property accesses since property accesses can have side effects. For
|
||||
// example, the property access "a.b.c" has the side effect of throwing an
|
||||
// exception if "a.b" is undefined.
|
||||
for _, parts := range knownGlobals {
|
||||
tail := parts[len(parts)-1]
|
||||
if len(parts) == 1 {
|
||||
result.IdentifierDefines[tail] = DefineData{CanBeRemovedIfUnused: true}
|
||||
} else {
|
||||
result.DotDefines[tail] = append(result.DotDefines[tail], DotDefine{Parts: parts, Data: DefineData{CanBeRemovedIfUnused: true}})
|
||||
}
|
||||
}
|
||||
|
||||
// Swap in certain literal values because those can be constant folded
|
||||
result.IdentifierDefines["undefined"] = DefineData{
|
||||
DefineFunc: func(DefineArgs) js_ast.E { return js_ast.EUndefinedShared },
|
||||
}
|
||||
result.IdentifierDefines["NaN"] = DefineData{
|
||||
DefineFunc: func(DefineArgs) js_ast.E { return &js_ast.ENumber{Value: math.NaN()} },
|
||||
}
|
||||
result.IdentifierDefines["Infinity"] = DefineData{
|
||||
DefineFunc: func(DefineArgs) js_ast.E { return &js_ast.ENumber{Value: math.Inf(1)} },
|
||||
}
|
||||
|
||||
// Then copy the user-specified defines in afterwards, which will overwrite
|
||||
// any known globals above.
|
||||
for key, data := range userDefines {
|
||||
parts := strings.Split(key, ".")
|
||||
|
||||
// Identifier defines are special-cased
|
||||
if len(parts) == 1 {
|
||||
result.IdentifierDefines[key] = mergeDefineData(result.IdentifierDefines[key], data)
|
||||
continue
|
||||
}
|
||||
|
||||
tail := parts[len(parts)-1]
|
||||
dotDefines := result.DotDefines[tail]
|
||||
found := false
|
||||
|
||||
// Try to merge with existing dot defines first
|
||||
for i, define := range dotDefines {
|
||||
if arePartsEqual(parts, define.Parts) {
|
||||
define := &dotDefines[i]
|
||||
define.Data = mergeDefineData(define.Data, data)
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if !found {
|
||||
dotDefines = append(dotDefines, DotDefine{Parts: parts, Data: data})
|
||||
}
|
||||
result.DotDefines[tail] = dotDefines
|
||||
}
|
||||
|
||||
// Potentially cache the result for next time
|
||||
if !hasUserDefines {
|
||||
processedGlobalsMutex.Lock()
|
||||
defer processedGlobalsMutex.Unlock()
|
||||
if processedGlobals == nil {
|
||||
processedGlobals = &result
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func arePartsEqual(a []string, b []string) bool {
|
||||
if len(a) != len(b) {
|
||||
return false
|
||||
}
|
||||
for i := range a {
|
||||
if a[i] != b[i] {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
Reference in New Issue
Block a user