@depup/webpack 5.106.0-depup.0 → 5.109.0-depup.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -11
- package/changes.json +16 -24
- package/hot/dev-server.js +2 -0
- package/lib/APIPlugin.js +60 -35
- package/lib/AsyncDependenciesBlock.js +3 -0
- package/lib/AutomaticPrefetchPlugin.js +6 -1
- package/lib/BannerPlugin.js +13 -5
- package/lib/Cache.js +27 -5
- package/lib/CacheFacade.js +41 -0
- package/lib/Chunk.js +71 -25
- package/lib/ChunkGraph.js +141 -9
- package/lib/ChunkGroup.js +115 -28
- package/lib/ChunkTemplate.js +9 -0
- package/lib/CircularModulesPlugin.js +190 -0
- package/lib/CleanPlugin.js +23 -26
- package/lib/CodeGenerationResults.js +19 -0
- package/lib/CompatibilityPlugin.js +54 -37
- package/lib/Compilation.js +635 -107
- package/lib/Compiler.js +93 -31
- package/lib/ConcatenationScope.js +34 -4
- package/lib/ConditionalInitFragment.js +6 -0
- package/lib/ConstPlugin.js +15 -12
- package/lib/ContextExclusionPlugin.js +3 -1
- package/lib/ContextModule.js +345 -55
- package/lib/ContextModuleFactory.js +193 -51
- package/lib/ContextReplacementPlugin.js +8 -1
- package/lib/DefinePlugin.js +498 -127
- package/lib/DependenciesBlock.js +6 -1
- package/lib/Dependency.js +159 -11
- package/lib/DependencyTemplate.js +7 -1
- package/lib/DependencyTemplates.js +4 -0
- package/lib/DotenvPlugin.js +3 -0
- package/lib/DynamicEntryPlugin.js +3 -1
- package/lib/EntryOptionPlugin.js +42 -2
- package/lib/EntryPlugin.js +4 -1
- package/lib/Entrypoint.js +5 -1
- package/lib/EnvironmentPlugin.js +3 -2
- package/lib/ErrorHelpers.js +7 -0
- package/lib/EvalDevToolModulePlugin.js +3 -1
- package/lib/EvalSourceMapDevToolPlugin.js +11 -11
- package/lib/ExportsInfo.js +399 -108
- package/lib/ExportsInfoApiPlugin.js +4 -3
- package/lib/ExternalModule.js +376 -78
- package/lib/ExternalModuleFactoryPlugin.js +75 -3
- package/lib/ExternalsPlugin.js +3 -1
- package/lib/FileSystemInfo.js +575 -149
- package/lib/FlagAllModulesAsUsedPlugin.js +3 -6
- package/lib/FlagDependencyExportsPlugin.js +82 -9
- package/lib/FlagDependencyUsagePlugin.js +92 -6
- package/lib/FlagEntryExportAsUsedPlugin.js +4 -1
- package/lib/Generator.js +24 -3
- package/lib/HotModuleReplacementPlugin.js +110 -44
- package/lib/IgnorePlugin.js +5 -2
- package/lib/IgnoreWarningsPlugin.js +2 -1
- package/lib/InitFragment.js +15 -0
- package/lib/JavascriptMetaInfoPlugin.js +9 -6
- package/lib/LazyBarrel.js +389 -0
- package/lib/LibraryTemplatePlugin.js +2 -1
- package/lib/LoaderOptionsPlugin.js +3 -1
- package/lib/LoaderTargetPlugin.js +3 -1
- package/lib/MainTemplate.js +15 -0
- package/lib/ManifestPlugin.js +9 -2
- package/lib/Module.js +121 -60
- package/lib/ModuleFactory.js +6 -1
- package/lib/ModuleFilenameHelpers.js +5 -2
- package/lib/ModuleGraph.js +69 -2
- package/lib/ModuleGraphConnection.js +9 -0
- package/lib/ModuleInfoHeaderPlugin.js +5 -0
- package/lib/ModuleNotFoundError.js +3 -83
- package/lib/ModuleProfile.js +27 -1
- package/lib/ModuleSourceTypeConstants.js +52 -19
- package/lib/ModuleTemplate.js +10 -0
- package/lib/ModuleTypeConstants.js +20 -4
- package/lib/MultiCompiler.js +59 -4
- package/lib/MultiStats.js +9 -0
- package/lib/MultiWatching.js +6 -0
- package/lib/NoEmitOnErrorsPlugin.js +1 -1
- package/lib/NodeStuffPlugin.js +78 -46
- package/lib/NormalModule.js +485 -181
- package/lib/NormalModuleFactory.js +148 -29
- package/lib/NormalModuleReplacementPlugin.js +3 -1
- package/lib/NullFactory.js +1 -0
- package/lib/OptionsApply.js +1 -0
- package/lib/Parser.js +3 -1
- package/lib/PlatformPlugin.js +2 -1
- package/lib/PrefetchPlugin.js +4 -1
- package/lib/ProgressPlugin.js +351 -161
- package/lib/ProvidePlugin.js +6 -3
- package/lib/RawModule.js +32 -16
- package/lib/RecordIdsPlugin.js +9 -0
- package/lib/RequestShortener.js +8 -0
- package/lib/ResolverFactory.js +5 -0
- package/lib/RuntimeGlobals.js +58 -5
- package/lib/RuntimeModule.js +22 -7
- package/lib/RuntimePlugin.js +104 -26
- package/lib/RuntimeTemplate.js +616 -37
- package/lib/SelfModuleFactory.js +3 -0
- package/lib/SourceMapDevToolModuleOptionsPlugin.js +2 -0
- package/lib/SourceMapDevToolPlugin.js +341 -63
- package/lib/Stats.js +6 -0
- package/lib/Template.js +29 -3
- package/lib/TemplatedPathPlugin.js +505 -138
- package/lib/UseStrictPlugin.js +3 -2
- package/lib/WarnCaseSensitiveModulesPlugin.js +72 -3
- package/lib/WarnDeprecatedOptionPlugin.js +6 -2
- package/lib/WarnNoModeSetPlugin.js +18 -2
- package/lib/WatchIgnorePlugin.js +5 -1
- package/lib/Watching.js +25 -3
- package/lib/WebpackError.js +3 -74
- package/lib/WebpackIsIncludedPlugin.js +4 -2
- package/lib/WebpackOptionsApply.js +88 -25
- package/lib/WebpackOptionsDefaulter.js +1 -0
- package/lib/asset/AssetBytesGenerator.js +28 -10
- package/lib/asset/AssetBytesParser.js +1 -0
- package/lib/asset/AssetGenerator.js +199 -60
- package/lib/asset/AssetModule.js +47 -0
- package/lib/asset/AssetModulesPlugin.js +115 -24
- package/lib/asset/AssetParser.js +4 -2
- package/lib/asset/AssetSourceGenerator.js +26 -8
- package/lib/asset/AssetSourceParser.js +1 -0
- package/lib/asset/RawDataUrlModule.js +23 -13
- package/lib/asset/WebManifestGenerator.js +164 -0
- package/lib/asset/WebManifestParser.js +130 -0
- package/lib/async-modules/AsyncModuleHelpers.js +1 -0
- package/lib/async-modules/AwaitDependenciesInitFragment.js +18 -4
- package/lib/async-modules/InferAsyncModulesPlugin.js +1 -1
- package/lib/async-modules/isGeneratorLowered.js +26 -0
- package/lib/buildChunkGraph.js +107 -15
- package/lib/bun/BunTargetPlugin.js +42 -0
- package/lib/cache/AddBuildDependenciesPlugin.js +3 -1
- package/lib/cache/AddManagedPathsPlugin.js +5 -1
- package/lib/cache/IdleFileCachePlugin.js +6 -1
- package/lib/cache/MemoryCachePlugin.js +1 -1
- package/lib/cache/MemoryWithGcCachePlugin.js +4 -1
- package/lib/cache/PackFileCacheStrategy.js +43 -7
- package/lib/cache/ResolverCachePlugin.js +12 -1
- package/lib/cache/getLazyHashedEtag.js +13 -2
- package/lib/cache/mergeEtags.js +4 -0
- package/lib/cli.js +142 -20
- package/lib/config/browserslistTargetHandler.js +141 -0
- package/lib/config/defaults.js +591 -41
- package/lib/config/defineConfig.js +31 -0
- package/lib/config/normalization.js +46 -1
- package/lib/config/target.js +200 -2
- package/lib/container/ContainerEntryDependency.js +2 -0
- package/lib/container/ContainerEntryModule.js +27 -14
- package/lib/container/ContainerEntryModuleFactory.js +1 -0
- package/lib/container/ContainerExposedDependency.js +6 -2
- package/lib/container/ContainerPlugin.js +2 -1
- package/lib/container/ContainerReferencePlugin.js +3 -2
- package/lib/container/FallbackDependency.js +9 -7
- package/lib/container/FallbackItemDependency.js +1 -0
- package/lib/container/FallbackModule.js +22 -9
- package/lib/container/FallbackModuleFactory.js +1 -0
- package/lib/container/ModuleFederationPlugin.js +12 -26
- package/lib/container/RemoteModule.js +33 -10
- package/lib/container/RemoteRuntimeModule.js +15 -12
- package/lib/container/RemoteToExternalDependency.js +1 -0
- package/lib/container/options.js +7 -0
- package/lib/css/CssGenerator.js +534 -272
- package/lib/css/CssInjectStyleRuntimeModule.js +86 -70
- package/lib/css/CssLoadingRuntimeModule.js +156 -77
- package/lib/{CssModule.js → css/CssModule.js} +72 -37
- package/lib/css/CssModulesPlugin.js +356 -204
- package/lib/css/CssParser.js +3452 -1950
- package/lib/css/syntax.js +4058 -0
- package/lib/debug/ProfilingPlugin.js +33 -2
- package/lib/deno/DenoTargetPlugin.js +41 -0
- package/lib/dependencies/AMDDefineDependency.js +29 -17
- package/lib/dependencies/AMDDefineDependencyParserPlugin.js +19 -6
- package/lib/dependencies/AMDPlugin.js +6 -3
- package/lib/dependencies/AMDRequireArrayDependency.js +13 -11
- package/lib/dependencies/AMDRequireContextDependency.js +10 -11
- package/lib/dependencies/AMDRequireDependenciesBlock.js +1 -0
- package/lib/dependencies/AMDRequireDependenciesBlockParserPlugin.js +28 -14
- package/lib/dependencies/AMDRequireDependency.js +28 -20
- package/lib/dependencies/AMDRequireItemDependency.js +1 -0
- package/lib/dependencies/AMDRuntimeModules.js +3 -0
- package/lib/dependencies/CachedConstDependency.js +9 -1
- package/lib/dependencies/CommonJsDependencyHelpers.js +104 -0
- package/lib/dependencies/CommonJsExportRequireDependency.js +138 -38
- package/lib/dependencies/CommonJsExportsDependency.js +74 -20
- package/lib/dependencies/CommonJsExportsParserPlugin.js +246 -15
- package/lib/dependencies/CommonJsFullRequireDependency.js +62 -27
- package/lib/dependencies/CommonJsImportsParserPlugin.js +187 -24
- package/lib/dependencies/CommonJsPlugin.js +7 -4
- package/lib/dependencies/CommonJsRequireContextDependency.js +13 -13
- package/lib/dependencies/CommonJsRequireDependency.js +135 -13
- package/lib/dependencies/CommonJsSelfReferenceDependency.js +60 -16
- package/lib/dependencies/ConstDependency.js +22 -12
- package/lib/dependencies/ContextDependency.js +13 -2
- package/lib/dependencies/ContextDependencyHelpers.js +7 -4
- package/lib/dependencies/ContextDependencyTemplateAsId.js +2 -1
- package/lib/dependencies/ContextDependencyTemplateAsRequireCall.js +1 -0
- package/lib/dependencies/ContextElementDependency.js +27 -14
- package/lib/dependencies/CreateRequireParserPlugin.js +14 -7
- package/lib/dependencies/CreateScriptUrlDependency.js +9 -7
- package/lib/dependencies/CriticalDependencyWarning.js +3 -1
- package/lib/dependencies/CssIcssExportDependency.js +682 -368
- package/lib/dependencies/CssIcssImportDependency.js +62 -17
- package/lib/dependencies/CssIcssSymbolDependency.js +36 -17
- package/lib/dependencies/CssImportDependency.js +37 -1
- package/lib/dependencies/CssUrlDependency.js +87 -14
- package/lib/dependencies/DelegatedSourceDependency.js +1 -0
- package/lib/dependencies/DllEntryDependency.js +12 -13
- package/lib/dependencies/DynamicExports.js +5 -0
- package/lib/dependencies/EntryDependency.js +1 -0
- package/lib/dependencies/ExportBindingInitFragment.js +164 -0
- package/lib/dependencies/ExportsInfoDependency.js +18 -12
- package/lib/dependencies/ExternalModuleDependency.js +13 -5
- package/lib/dependencies/ExternalModuleInitFragment.js +10 -5
- package/lib/dependencies/ExternalModuleInitFragmentDependency.js +19 -12
- package/lib/dependencies/HarmonyAcceptDependency.js +24 -26
- package/lib/dependencies/HarmonyAcceptImportDependency.js +2 -0
- package/lib/dependencies/HarmonyCompatibilityDependency.js +33 -14
- package/lib/dependencies/HarmonyDetectionParserPlugin.js +108 -30
- package/lib/dependencies/HarmonyEvaluatedImportSpecifierDependency.js +32 -2
- package/lib/dependencies/HarmonyExportDependencyParserPlugin.js +70 -33
- package/lib/dependencies/HarmonyExportExpressionDependency.js +140 -46
- package/lib/dependencies/HarmonyExportHeaderDependency.js +11 -9
- package/lib/dependencies/HarmonyExportImportedSpecifierDependency.js +253 -37
- package/lib/dependencies/HarmonyExportInitFragment.js +28 -20
- package/lib/dependencies/HarmonyExportSpecifierDependency.js +88 -18
- package/lib/dependencies/HarmonyExports.js +6 -1
- package/lib/dependencies/HarmonyImportDependency.js +59 -3
- package/lib/dependencies/HarmonyImportDependencyParserPlugin.js +139 -146
- package/lib/dependencies/HarmonyImportGuard.js +426 -0
- package/lib/dependencies/HarmonyImportSideEffectDependency.js +22 -1
- package/lib/dependencies/HarmonyImportSpecifierDependency.js +136 -17
- package/lib/{HarmonyLinkingError.js → dependencies/HarmonyLinkingError.js} +6 -3
- package/lib/dependencies/HarmonyModulesPlugin.js +11 -1
- package/lib/dependencies/HarmonyTopLevelThisParserPlugin.js +2 -1
- package/lib/dependencies/HtmlEntryDependency.js +1295 -0
- package/lib/dependencies/HtmlInlineHtmlDependency.js +107 -0
- package/lib/dependencies/HtmlInlineScriptDependency.js +126 -0
- package/lib/dependencies/HtmlInlineStyleDependency.js +152 -0
- package/lib/dependencies/HtmlSourceDependency.js +172 -0
- package/lib/dependencies/ImportContextDependency.js +9 -9
- package/lib/dependencies/ImportDependency.js +92 -3
- package/lib/dependencies/ImportEagerDependency.js +2 -0
- package/lib/dependencies/ImportMetaContextDependency.js +1 -0
- package/lib/dependencies/ImportMetaContextDependencyParserPlugin.js +35 -19
- package/lib/dependencies/ImportMetaContextPlugin.js +40 -8
- package/lib/dependencies/ImportMetaGlobDependency.js +81 -0
- package/lib/dependencies/ImportMetaGlobDependencyParserPlugin.js +78 -0
- package/lib/dependencies/ImportMetaGlobHelpers.js +660 -0
- package/lib/dependencies/ImportMetaHotAcceptDependency.js +2 -0
- package/lib/dependencies/ImportMetaHotDeclineDependency.js +2 -0
- package/lib/dependencies/ImportMetaPlugin.js +595 -209
- package/lib/dependencies/ImportMetaResolveDependency.js +90 -0
- package/lib/dependencies/ImportParserPlugin.js +114 -27
- package/lib/dependencies/ImportPhase.js +17 -11
- package/lib/dependencies/ImportPlugin.js +2 -1
- package/lib/dependencies/ImportWeakDependency.js +3 -0
- package/lib/dependencies/JsonExportsDependency.js +15 -10
- package/lib/dependencies/LoaderDependency.js +2 -0
- package/lib/dependencies/LoaderImportDependency.js +3 -0
- package/lib/dependencies/LoaderPlugin.js +9 -2
- package/lib/dependencies/LocalModule.js +15 -12
- package/lib/dependencies/LocalModuleDependency.js +15 -13
- package/lib/dependencies/LocalModulesHelpers.js +3 -0
- package/lib/dependencies/ModuleDecoratorDependency.js +16 -10
- package/lib/dependencies/ModuleDependency.js +14 -0
- package/lib/dependencies/ModuleDependencyTemplateAsId.js +1 -0
- package/lib/dependencies/ModuleDependencyTemplateAsRequireId.js +1 -0
- package/lib/dependencies/ModuleHotAcceptDependency.js +2 -0
- package/lib/dependencies/ModuleHotDeclineDependency.js +2 -0
- package/lib/dependencies/ModuleInitFragmentDependency.js +19 -11
- package/lib/dependencies/NullDependency.js +2 -0
- package/lib/dependencies/PrefetchDependency.js +1 -0
- package/lib/dependencies/ProvidedDependency.js +36 -27
- package/lib/dependencies/PureExpressionDependency.js +14 -10
- package/lib/dependencies/RequireContextDependency.js +1 -0
- package/lib/dependencies/RequireContextDependencyParserPlugin.js +2 -1
- package/lib/dependencies/RequireContextPlugin.js +2 -1
- package/lib/dependencies/RequireEnsureDependenciesBlock.js +1 -0
- package/lib/dependencies/RequireEnsureDependenciesBlockParserPlugin.js +4 -6
- package/lib/dependencies/RequireEnsureDependency.js +16 -13
- package/lib/dependencies/RequireEnsureItemDependency.js +1 -0
- package/lib/dependencies/RequireEnsurePlugin.js +2 -1
- package/lib/dependencies/RequireHeaderDependency.js +7 -4
- package/lib/dependencies/RequireIncludeDependency.js +2 -0
- package/lib/dependencies/RequireIncludeDependencyParserPlugin.js +11 -12
- package/lib/dependencies/RequireIncludePlugin.js +2 -1
- package/lib/{RequireJsStuffPlugin.js → dependencies/RequireJsStuffPlugin.js} +9 -8
- package/lib/dependencies/RequireResolveContextDependency.js +10 -11
- package/lib/dependencies/RequireResolveDependency.js +2 -0
- package/lib/dependencies/RequireResolveHeaderDependency.js +8 -5
- package/lib/dependencies/RuntimeRequirementsDependency.js +11 -8
- package/lib/dependencies/StaticExportsDependency.js +13 -10
- package/lib/dependencies/SystemPlugin.js +9 -6
- package/lib/dependencies/SystemRuntimeModule.js +1 -0
- package/lib/dependencies/TopLevelAwaitDependency.js +93 -0
- package/lib/dependencies/URLContextDependency.js +8 -7
- package/lib/dependencies/URLDependency.js +157 -33
- package/lib/dependencies/URLPlugin.js +2 -0
- package/lib/dependencies/UnsupportedDependency.js +12 -13
- package/lib/dependencies/WebAssemblyExportImportedDependency.js +15 -16
- package/lib/dependencies/WebAssemblyImportDependency.js +19 -18
- package/lib/dependencies/WebpackIsIncludedDependency.js +3 -0
- package/lib/dependencies/{WorkerPlugin.js → WorkerAndWorkletPlugin.js} +364 -114
- package/lib/dependencies/WorkerDependency.js +111 -27
- package/lib/dependencies/WorkletDependency.js +278 -0
- package/lib/dependencies/getFunctionExpression.js +1 -0
- package/lib/dependencies/processExportInfo.js +14 -11
- package/lib/{DelegatedModule.js → dll/DelegatedModule.js} +71 -44
- package/lib/{DelegatedModuleFactoryPlugin.js → dll/DelegatedModuleFactoryPlugin.js} +27 -4
- package/lib/{DelegatedPlugin.js → dll/DelegatedPlugin.js} +5 -3
- package/lib/{DllEntryPlugin.js → dll/DllEntryPlugin.js} +9 -5
- package/lib/{DllModule.js → dll/DllModule.js} +36 -24
- package/lib/{DllModuleFactory.js → dll/DllModuleFactory.js} +5 -4
- package/lib/{DllPlugin.js → dll/DllPlugin.js} +24 -6
- package/lib/{DllReferencePlugin.js → dll/DllReferencePlugin.js} +26 -18
- package/lib/{LibManifestPlugin.js → dll/LibManifestPlugin.js} +14 -10
- package/lib/electron/ElectronTargetPlugin.js +24 -5
- package/lib/{AbstractMethodError.js → errors/AbstractMethodError.js} +10 -1
- package/lib/{AsyncDependencyToInitialChunkError.js → errors/AsyncDependencyToInitialChunkError.js} +8 -3
- package/lib/errors/BuildCycleError.js +1 -1
- package/lib/{ChunkRenderError.js → errors/ChunkRenderError.js} +1 -1
- package/lib/{CodeGenerationError.js → errors/CodeGenerationError.js} +1 -1
- package/lib/{CommentCompilationWarning.js → errors/CommentCompilationWarning.js} +9 -3
- package/lib/{ConcurrentCompilationError.js → errors/ConcurrentCompilationError.js} +5 -2
- package/lib/{EnvironmentNotSupportAsyncWarning.js → errors/EnvironmentNotSupportAsyncWarning.js} +5 -5
- package/lib/{HookWebpackError.js → errors/HookWebpackError.js} +20 -16
- package/lib/{IgnoreErrorModuleFactory.js → errors/IgnoreErrorModuleFactory.js} +7 -4
- package/lib/{InvalidDependenciesModuleWarning.js → errors/InvalidDependenciesModuleWarning.js} +6 -3
- package/lib/errors/JSONParseError.js +115 -0
- package/lib/errors/LoaderLoadingError.js +20 -0
- package/lib/{ModuleBuildError.js → errors/ModuleBuildError.js} +22 -16
- package/lib/{ModuleDependencyError.js → errors/ModuleDependencyError.js} +10 -3
- package/lib/{ModuleDependencyWarning.js → errors/ModuleDependencyWarning.js} +13 -5
- package/lib/{ModuleError.js → errors/ModuleError.js} +10 -14
- package/lib/{ModuleHashingError.js → errors/ModuleHashingError.js} +5 -1
- package/lib/errors/ModuleNotFoundError.js +94 -0
- package/lib/errors/ModuleParseError.js +141 -0
- package/lib/{ModuleRestoreError.js → errors/ModuleRestoreError.js} +4 -1
- package/lib/{ModuleStoreError.js → errors/ModuleStoreError.js} +5 -1
- package/lib/{ModuleWarning.js → errors/ModuleWarning.js} +13 -14
- package/lib/{NodeStuffInWebError.js → errors/NodeStuffInWebError.js} +7 -5
- package/lib/errors/NonErrorEmittedError.js +30 -0
- package/lib/{UnhandledSchemeError.js → errors/UnhandledSchemeError.js} +9 -2
- package/lib/{UnsupportedFeatureWarning.js → errors/UnsupportedFeatureWarning.js} +4 -3
- package/lib/errors/WebpackError.js +84 -0
- package/lib/esm/ExportWebpackRequireRuntimeModule.js +2 -0
- package/lib/esm/ModuleChunkFormatPlugin.js +52 -15
- package/lib/esm/ModuleChunkLoadingPlugin.js +11 -3
- package/lib/esm/ModuleChunkLoadingRuntimeModule.js +71 -49
- package/lib/hmr/HotModuleReplacement.runtime.js +175 -30
- package/lib/hmr/HotModuleReplacementRuntimeModule.js +8 -0
- package/lib/hmr/JavascriptHotModuleReplacement.runtime.js +173 -26
- package/lib/hmr/JavascriptHotModuleReplacementHelper.js +1 -0
- package/lib/hmr/LazyCompilationPlugin.js +154 -7
- package/lib/hmr/lazyCompilationBackend.js +34 -8
- package/lib/html/HtmlGenerator.js +1470 -0
- package/lib/html/HtmlModule.js +41 -0
- package/lib/html/HtmlModulesPlugin.js +1111 -0
- package/lib/html/HtmlParser.js +1970 -0
- package/lib/html/favicon.svg +1 -0
- package/lib/html/syntax.js +9020 -0
- package/lib/ids/ChunkModuleIdRangePlugin.js +3 -1
- package/lib/ids/DeterministicChunkIdsPlugin.js +3 -1
- package/lib/ids/DeterministicModuleIdsPlugin.js +3 -1
- package/lib/ids/HashedModuleIdsPlugin.js +2 -1
- package/lib/ids/IdHelpers.js +25 -2
- package/lib/ids/NamedChunkIdsPlugin.js +3 -1
- package/lib/ids/NamedModuleIdsPlugin.js +3 -1
- package/lib/ids/NaturalChunkIdsPlugin.js +1 -1
- package/lib/ids/NaturalModuleIdsPlugin.js +1 -1
- package/lib/ids/OccurrenceChunkIdsPlugin.js +2 -1
- package/lib/ids/OccurrenceModuleIdsPlugin.js +4 -1
- package/lib/ids/SyncModuleIdsPlugin.js +3 -1
- package/lib/index.js +66 -15
- package/lib/javascript/ArrayPushCallbackChunkFormatPlugin.js +5 -6
- package/lib/javascript/BasicEvaluatedExpression.js +370 -49
- package/lib/javascript/ChunkFormatHelpers.js +2 -1
- package/lib/javascript/ChunkHelpers.js +1 -0
- package/lib/javascript/CommonJsChunkFormatPlugin.js +1 -1
- package/lib/javascript/EnableChunkLoadingPlugin.js +6 -1
- package/lib/javascript/JavascriptGenerator.js +213 -51
- package/lib/javascript/JavascriptModule.js +54 -0
- package/lib/javascript/JavascriptModulesPlugin.js +579 -183
- package/lib/javascript/JavascriptParser.js +1289 -462
- package/lib/javascript/JavascriptParserHelpers.js +10 -7
- package/lib/javascript/StartupHelpers.js +5 -0
- package/lib/javascript/syntax.js +4380 -0
- package/lib/json/JsonData.js +5 -0
- package/lib/json/JsonGenerator.js +21 -0
- package/lib/json/JsonModule.js +40 -0
- package/lib/json/JsonModulesPlugin.js +8 -1
- package/lib/json/JsonParser.js +18 -27
- package/lib/library/AbstractLibraryPlugin.js +17 -2
- package/lib/library/AmdLibraryPlugin.js +8 -0
- package/lib/library/AssignLibraryPlugin.js +21 -3
- package/lib/library/EnableLibraryPlugin.js +8 -2
- package/lib/library/ExportPropertyLibraryPlugin.js +10 -0
- package/lib/{FalseIIFEUmdWarning.js → library/FalseIIFEUmdWarning.js} +2 -1
- package/lib/library/JsonpLibraryPlugin.js +8 -0
- package/lib/library/ModuleLibraryPlugin.js +154 -7
- package/lib/library/SystemLibraryPlugin.js +11 -3
- package/lib/library/UmdLibraryPlugin.js +16 -0
- package/lib/loaders/LoaderRunner.js +714 -0
- package/lib/loaders/loadLoader.js +100 -0
- package/lib/logging/Logger.js +17 -0
- package/lib/logging/createConsoleLogger.js +7 -0
- package/lib/logging/runtime.js +2 -0
- package/lib/logging/truncateArgs.js +2 -0
- package/lib/node/CommonJsChunkLoadingPlugin.js +5 -1
- package/lib/node/NodeEnvironmentPlugin.js +7 -3
- package/lib/node/NodeSourcePlugin.js +1 -1
- package/lib/node/NodeTargetPlugin.js +4 -63
- package/lib/node/NodeTemplatePlugin.js +3 -1
- package/lib/node/NodeWatchFileSystem.js +40 -22
- package/lib/node/ReadFileChunkLoadingRuntimeModule.js +13 -9
- package/lib/node/ReadFileCompileAsyncWasmPlugin.js +23 -1
- package/lib/node/ReadFileCompileWasmPlugin.js +18 -1
- package/lib/node/RequireChunkLoadingRuntimeModule.js +21 -16
- package/lib/node/nodeBuiltins.js +80 -0
- package/lib/node/nodeConsole.js +116 -64
- package/lib/optimize/AggressiveMergingPlugin.js +3 -1
- package/lib/optimize/AggressiveSplittingPlugin.js +6 -1
- package/lib/optimize/ConcatenatedModule.js +585 -116
- package/lib/optimize/ConstExportsPlugin.js +211 -0
- package/lib/optimize/EnsureChunkConditionsPlugin.js +2 -1
- package/lib/optimize/FlagIncludedChunksPlugin.js +15 -4
- package/lib/optimize/InlineExports.js +178 -0
- package/lib/optimize/InnerGraph.js +374 -262
- package/lib/optimize/InnerGraphPlugin.js +246 -117
- package/lib/optimize/LimitChunkCountPlugin.js +9 -0
- package/lib/optimize/MangleExportsPlugin.js +5 -1
- package/lib/optimize/MergeDuplicateChunksPlugin.js +2 -0
- package/lib/optimize/MinChunkSizePlugin.js +2 -1
- package/lib/optimize/MinMaxSizeWarning.js +5 -4
- package/lib/optimize/ModuleConcatenationPlugin.js +159 -34
- package/lib/optimize/RealContentHashPlugin.js +125 -50
- package/lib/optimize/RemoveEmptyChunksPlugin.js +2 -1
- package/lib/optimize/RemoveParentModulesPlugin.js +3 -1
- package/lib/optimize/RuntimeChunkPlugin.js +2 -1
- package/lib/optimize/SideEffectsFlagPlugin.js +381 -55
- package/lib/optimize/SplitChunksPlugin.js +54 -6
- package/lib/performance/AssetsOverSizeLimitWarning.js +3 -2
- package/lib/performance/EntrypointsOverSizeLimitWarning.js +3 -2
- package/lib/performance/NoAsyncChunksWarning.js +5 -3
- package/lib/performance/SizeLimitsPlugin.js +8 -2
- package/lib/prefetch/ChunkPrefetchFunctionRuntimeModule.js +1 -0
- package/lib/prefetch/ChunkPrefetchPreloadPlugin.js +21 -0
- package/lib/prefetch/ChunkPrefetchStartupRuntimeModule.js +1 -0
- package/lib/prefetch/ChunkPrefetchTriggerRuntimeModule.js +5 -1
- package/lib/prefetch/ChunkPreloadTriggerRuntimeModule.js +25 -13
- package/lib/prefetch/ResourceHintPlugin.js +663 -0
- package/lib/prefetch/ResourceHintRuntimeModule.js +149 -0
- package/lib/prefetch/StartupAssetHintRuntimeModule.js +210 -0
- package/lib/prefetch/parseResourceHintOptions.js +103 -0
- package/lib/rules/BasicEffectRulePlugin.js +3 -0
- package/lib/rules/BasicMatcherRulePlugin.js +3 -0
- package/lib/rules/ObjectMatcherRulePlugin.js +3 -0
- package/lib/rules/RuleSetCompiler.js +132 -0
- package/lib/rules/UseEffectRulePlugin.js +10 -3
- package/lib/runtime/AsyncModuleGeneratorRuntimeModule.js +56 -0
- package/lib/runtime/AsyncModuleRuntimeModule.js +52 -33
- package/lib/runtime/AutoPublicPathRuntimeModule.js +22 -9
- package/lib/runtime/BaseUriRuntimeModule.js +1 -0
- package/lib/runtime/ChunkNameRuntimeModule.js +1 -0
- package/lib/runtime/CommonJsWrapRuntimeModule.js +37 -0
- package/lib/runtime/CompatGetDefaultExportRuntimeModule.js +2 -1
- package/lib/runtime/CompatRuntimeModule.js +2 -0
- package/lib/runtime/CreateFakeNamespaceObjectRuntimeModule.js +7 -4
- package/lib/runtime/CreateScriptRuntimeModule.js +1 -0
- package/lib/runtime/CreateScriptUrlRuntimeModule.js +1 -0
- package/lib/runtime/DefinePropertyGettersRuntimeModule.js +34 -4
- package/lib/runtime/EnsureChunkRuntimeModule.js +1 -0
- package/lib/runtime/GetChunkFilenameRuntimeModule.js +88 -8
- package/lib/runtime/GetFullHashRuntimeModule.js +1 -0
- package/lib/runtime/GetMainFilenameRuntimeModule.js +1 -0
- package/lib/runtime/GetTrustedTypesPolicyRuntimeModule.js +2 -1
- package/lib/runtime/GetWorkletBootstrapRuntimeModule.js +59 -0
- package/lib/runtime/GlobalRuntimeModule.js +1 -0
- package/lib/runtime/HasOwnPropertyRuntimeModule.js +2 -1
- package/lib/runtime/HelperRuntimeModule.js +5 -0
- package/lib/runtime/LoadScriptRuntimeModule.js +28 -37
- package/lib/runtime/MakeDeferredNamespaceObjectRuntime.js +354 -37
- package/lib/runtime/MakeNamespaceObjectRuntimeModule.js +2 -1
- package/lib/runtime/NonceRuntimeModule.js +1 -0
- package/lib/runtime/OnChunksLoadedRuntimeModule.js +5 -4
- package/lib/runtime/PublicPathRuntimeModule.js +1 -0
- package/lib/runtime/RelativeUrlRuntimeModule.js +4 -2
- package/lib/runtime/RuntimeIdRuntimeModule.js +1 -0
- package/lib/runtime/SetAnonymousDefaultNameRuntimeModule.js +38 -0
- package/lib/runtime/StartupChunkDependenciesPlugin.js +13 -1
- package/lib/runtime/StartupChunkDependenciesRuntimeModule.js +2 -1
- package/lib/runtime/StartupEntrypointRuntimeModule.js +5 -3
- package/lib/runtime/SystemContextRuntimeModule.js +1 -0
- package/lib/runtime/ToBinaryRuntimeModule.js +1 -0
- package/lib/runtime/WorkerRuntimeModule.js +33 -0
- package/lib/schemes/DataUriPlugin.js +14 -2
- package/lib/schemes/FileUriPlugin.js +1 -1
- package/lib/schemes/HttpUriPlugin.js +86 -4
- package/lib/schemes/VirtualUrlPlugin.js +8 -4
- package/lib/serialization/AggregateErrorSerializer.js +9 -6
- package/lib/serialization/ArraySerializer.js +6 -8
- package/lib/serialization/BinaryMiddleware.js +552 -463
- package/lib/serialization/DateObjectSerializer.js +4 -2
- package/lib/serialization/ErrorObjectSerializer.js +10 -6
- package/lib/serialization/FileMiddleware.js +50 -3
- package/lib/serialization/MapObjectSerializer.js +7 -9
- package/lib/serialization/NullPrototypeObjectSerializer.js +9 -9
- package/lib/serialization/ObjectMiddleware.js +73 -13
- package/lib/serialization/PlainObjectSerializer.js +16 -8
- package/lib/serialization/RegExpObjectSerializer.js +4 -2
- package/lib/serialization/Serializer.js +6 -0
- package/lib/serialization/SerializerMiddleware.js +14 -2
- package/lib/serialization/SetObjectSerializer.js +6 -8
- package/lib/serialization/SingleItemMiddleware.js +3 -0
- package/lib/sharing/ConsumeSharedFallbackDependency.js +1 -0
- package/lib/sharing/ConsumeSharedModule.js +21 -7
- package/lib/sharing/ConsumeSharedPlugin.js +11 -11
- package/lib/sharing/ConsumeSharedRuntimeModule.js +55 -45
- package/lib/sharing/ProvideForSharedDependency.js +1 -0
- package/lib/sharing/ProvideSharedDependency.js +34 -15
- package/lib/sharing/ProvideSharedModule.js +42 -12
- package/lib/sharing/ProvideSharedModuleFactory.js +1 -0
- package/lib/sharing/ProvideSharedPlugin.js +13 -8
- package/lib/sharing/SharePlugin.js +5 -1
- package/lib/sharing/ShareRuntimeModule.js +19 -16
- package/lib/sharing/resolveMatchedConfigs.js +6 -2
- package/lib/sharing/utils.js +9 -1
- package/lib/stats/DefaultStatsFactoryPlugin.js +94 -12
- package/lib/stats/DefaultStatsPresetPlugin.js +14 -2
- package/lib/stats/DefaultStatsPrinterPlugin.js +64 -18
- package/lib/stats/StatsFactory.js +39 -18
- package/lib/stats/StatsPrinter.js +16 -2
- package/lib/typescript/TypeScriptPlugin.js +210 -0
- package/lib/url/URLParserPlugin.js +111 -23
- package/lib/util/ArrayHelpers.js +1 -0
- package/lib/util/ArrayQueue.js +10 -5
- package/lib/util/AsyncQueue.js +154 -74
- package/lib/util/Hash.js +2 -2
- package/lib/util/IterableHelpers.js +3 -0
- package/lib/util/LazyBucketSortedSet.js +26 -0
- package/lib/util/LazySet.js +45 -4
- package/lib/util/LocConverter.js +64 -0
- package/lib/util/ParallelismFactorCalculator.js +1 -0
- package/lib/util/Queue.js +6 -3
- package/lib/util/Semaphore.js +15 -1
- package/lib/util/SetHelpers.js +4 -1
- package/lib/util/SortableSet.js +7 -1
- package/lib/util/SourceProcessor.js +119 -0
- package/lib/util/StackedCacheMap.js +20 -3
- package/lib/util/StackedMap.js +162 -43
- package/lib/util/StringXor.js +1 -1
- package/lib/util/TupleQueue.js +7 -3
- package/lib/util/TupleSet.js +14 -0
- package/lib/util/URLAbsoluteSpecifier.js +1 -0
- package/lib/util/WeakTupleMap.js +60 -1
- package/lib/util/binarySearchBounds.js +3 -2
- package/lib/util/chainedImports.js +3 -3
- package/lib/util/cleverMerge.js +19 -2
- package/lib/util/comparators.js +35 -4
- package/lib/util/compileBooleanMatcher.js +9 -0
- package/lib/util/concatenate.js +80 -24
- package/lib/util/conventions.js +46 -1
- package/lib/util/createHash.js +0 -1
- package/lib/util/createHooksRegistry.js +43 -0
- package/lib/util/createMappings.js +118 -0
- package/lib/util/dataURL.js +3 -2
- package/lib/util/deprecation.js +19 -0
- package/lib/util/deterministicGrouping.js +46 -17
- package/lib/util/extractSourceMap.js +2 -1
- package/lib/util/extractUrlAndGlobal.js +1 -0
- package/lib/util/findGraphRoots.js +7 -0
- package/lib/{formatLocation.js → util/formatLocation.js} +4 -2
- package/lib/{SizeFormatHelpers.js → util/formatSize.js} +10 -3
- package/lib/util/fs.js +87 -14
- package/lib/util/generateDebugId.js +1 -0
- package/lib/util/globUtils.js +710 -0
- package/lib/util/hash/BatchedHash.js +1 -0
- package/lib/util/hash/BulkUpdateHash.js +1 -0
- package/lib/util/hash/DebugHash.js +1 -0
- package/lib/util/hash/hash-digest.js +32 -15
- package/lib/util/hash/md4.js +1 -1
- package/lib/util/hash/wasm-hash.js +5 -0
- package/lib/util/hash/xxhash64.js +1 -1
- package/lib/util/identifier.js +97 -6
- package/lib/util/implicitTypeLoaderFallback.js +62 -0
- package/lib/util/internalSerializables.js +102 -60
- package/lib/util/magicComment.js +149 -7
- package/lib/util/makeSerializable.js +7 -0
- package/lib/util/memoize.js +2 -0
- package/lib/util/mimeTypes.js +176 -0
- package/lib/util/nonNumericOnlyHash.js +31 -1
- package/lib/util/numberHash.js +2 -2
- package/lib/util/parseJson.js +41 -0
- package/lib/util/processAsyncTree.js +8 -0
- package/lib/util/property.js +9 -2
- package/lib/util/publicPathPlaceholder.js +64 -0
- package/lib/util/registerExternalSerializer.js +24 -4
- package/lib/util/removeBOM.js +1 -0
- package/lib/util/runtime.js +32 -0
- package/lib/util/semver.js +15 -0
- package/lib/util/serialization.js +2 -0
- package/lib/util/smartGrouping.js +8 -0
- package/lib/util/source.js +23 -0
- package/lib/util/topologicalSort.js +69 -0
- package/lib/validateSchema.js +1 -0
- package/lib/wasm/EnableWasmLoadingPlugin.js +15 -1
- package/lib/wasm-async/AsyncWasmCompileRuntimeModule.js +25 -18
- package/lib/wasm-async/AsyncWasmLoadingRuntimeModule.js +34 -22
- package/lib/wasm-async/AsyncWasmModule.js +77 -0
- package/lib/wasm-async/AsyncWebAssemblyGenerator.js +6 -0
- package/lib/wasm-async/AsyncWebAssemblyJavascriptGenerator.js +6 -1
- package/lib/wasm-async/AsyncWebAssemblyModulesPlugin.js +22 -126
- package/lib/wasm-async/AsyncWebAssemblyParser.js +3 -2
- package/lib/wasm-async/UniversalCompileAsyncWasmPlugin.js +13 -2
- package/lib/wasm-sync/SyncWasmModule.js +39 -0
- package/lib/wasm-sync/UnsupportedWebAssemblyFeatureError.js +7 -3
- package/lib/wasm-sync/WasmChunkLoadingRuntimeModule.js +86 -19
- package/lib/wasm-sync/WasmFinalizeExportsPlugin.js +4 -3
- package/lib/wasm-sync/WebAssemblyGenerator.js +27 -1
- package/lib/wasm-sync/WebAssemblyInInitialChunkError.js +9 -3
- package/lib/wasm-sync/WebAssemblyJavascriptGenerator.js +4 -0
- package/lib/wasm-sync/WebAssemblyModulesPlugin.js +20 -1
- package/lib/wasm-sync/WebAssemblyParser.js +9 -3
- package/lib/wasm-sync/WebAssemblyUtils.js +2 -0
- package/lib/web/FetchCompileAsyncWasmPlugin.js +29 -1
- package/lib/web/FetchCompileWasmPlugin.js +27 -1
- package/lib/web/JsonpChunkLoadingPlugin.js +11 -1
- package/lib/web/JsonpChunkLoadingRuntimeModule.js +58 -64
- package/lib/web/JsonpTemplatePlugin.js +2 -1
- package/lib/webpack.js +78 -1
- package/lib/webworker/ImportScriptsChunkLoadingPlugin.js +10 -1
- package/lib/webworker/ImportScriptsChunkLoadingRuntimeModule.js +15 -10
- package/lib/webworker/WebWorkerTemplatePlugin.js +1 -1
- package/module.d.ts +21 -0
- package/package.json +79 -77
- package/schemas/WebpackOptions.check.js +1 -1
- package/schemas/WebpackOptions.json +1117 -79
- package/schemas/plugins/{DllPlugin.check.d.ts → HtmlGeneratorOptions.check.d.ts} +1 -1
- package/schemas/plugins/HtmlGeneratorOptions.check.js +6 -0
- package/schemas/plugins/HtmlGeneratorOptions.json +3 -0
- package/schemas/plugins/{DllReferencePlugin.check.d.ts → HtmlParserOptions.check.d.ts} +1 -1
- package/schemas/plugins/HtmlParserOptions.check.js +6 -0
- package/schemas/plugins/HtmlParserOptions.json +3 -0
- package/schemas/plugins/ProgressPlugin.check.js +1 -1
- package/schemas/plugins/ProgressPlugin.json +38 -0
- package/schemas/plugins/container/ContainerReferencePlugin.check.js +1 -1
- package/schemas/plugins/container/ContainerReferencePlugin.json +2 -0
- package/schemas/plugins/container/ExternalsType.check.js +1 -1
- package/schemas/plugins/container/ModuleFederationPlugin.check.js +1 -1
- package/schemas/plugins/container/ModuleFederationPlugin.json +2 -0
- package/schemas/plugins/css/CssAutoOrModuleParserOptions.check.d.ts +7 -0
- package/schemas/plugins/css/CssAutoOrModuleParserOptions.check.js +6 -0
- package/schemas/plugins/css/CssAutoOrModuleParserOptions.json +3 -0
- package/schemas/plugins/css/CssModuleParserOptions.check.js +1 -1
- package/schemas/plugins/css/CssParserOptions.check.js +1 -1
- package/schemas/plugins/dll/DllPlugin.check.d.ts +7 -0
- package/schemas/plugins/dll/DllReferencePlugin.check.d.ts +7 -0
- package/types.d.ts +8608 -1159
- package/lib/CaseSensitiveModulesWarning.js +0 -72
- package/lib/GraphHelpers.js +0 -46
- package/lib/ModuleParseError.js +0 -125
- package/lib/NoModeWarning.js +0 -23
- package/lib/css/CssMergeStyleSheetsRuntimeModule.js +0 -56
- package/lib/css/walkCssTokens.js +0 -1843
- package/lib/util/AppendOnlyStackedSet.js +0 -78
- /package/schemas/plugins/{DllPlugin.check.js → dll/DllPlugin.check.js} +0 -0
- /package/schemas/plugins/{DllPlugin.json → dll/DllPlugin.json} +0 -0
- /package/schemas/plugins/{DllReferencePlugin.check.js → dll/DllReferencePlugin.check.js} +0 -0
- /package/schemas/plugins/{DllReferencePlugin.json → dll/DllReferencePlugin.json} +0 -0
|
@@ -5,20 +5,27 @@
|
|
|
5
5
|
|
|
6
6
|
"use strict";
|
|
7
7
|
|
|
8
|
-
const vm = require("vm");
|
|
9
|
-
const { Parser: AcornParser, tokTypes } = require("acorn");
|
|
10
8
|
const { HookMap, SyncBailHook } = require("tapable");
|
|
11
9
|
const NormalModule = require("../NormalModule");
|
|
12
10
|
const Parser = require("../Parser");
|
|
11
|
+
const WebpackError = require("../WebpackError");
|
|
13
12
|
const StackedMap = require("../util/StackedMap");
|
|
14
|
-
const binarySearchBounds = require("../util/binarySearchBounds");
|
|
15
13
|
const {
|
|
14
|
+
CompilerHintNotationRegExp,
|
|
16
15
|
createMagicCommentContext,
|
|
17
|
-
|
|
16
|
+
getCommentsInRange,
|
|
17
|
+
parseCommentOptionsInRange
|
|
18
18
|
} = require("../util/magicComment");
|
|
19
|
-
const memoize = require("../util/memoize");
|
|
20
19
|
const BasicEvaluatedExpression = require("./BasicEvaluatedExpression");
|
|
21
|
-
|
|
20
|
+
const {
|
|
21
|
+
LEGACY_ASSERT_ATTRIBUTES,
|
|
22
|
+
WebpackParser,
|
|
23
|
+
buildLineStarts,
|
|
24
|
+
hasOctalEscape,
|
|
25
|
+
positionAt
|
|
26
|
+
} = require("./syntax");
|
|
27
|
+
|
|
28
|
+
/** @typedef {typeof import("acorn").Parser} AcornParser */
|
|
22
29
|
/** @typedef {import("acorn").Options} AcornOptions */
|
|
23
30
|
/** @typedef {import("acorn").ecmaVersion} EcmaVersion */
|
|
24
31
|
/** @typedef {import("estree").AssignmentExpression} AssignmentExpression */
|
|
@@ -32,7 +39,9 @@ const BasicEvaluatedExpression = require("./BasicEvaluatedExpression");
|
|
|
32
39
|
/** @typedef {import("estree").SwitchStatement} SwitchStatement */
|
|
33
40
|
/** @typedef {import("estree").ClassExpression} ClassExpression */
|
|
34
41
|
/** @typedef {import("estree").SourceLocation} SourceLocation */
|
|
35
|
-
/** @typedef {import("
|
|
42
|
+
/** @typedef {import("../Dependency").DependencyLocation} DependencyLocation */
|
|
43
|
+
/** @typedef {import("../Dependency").SourcePosition} SourcePosition */
|
|
44
|
+
/** @typedef {import("estree").Comment & { start: number, end: number, loc?: SourceLocation | null }} Comment */
|
|
36
45
|
/** @typedef {import("estree").ConditionalExpression} ConditionalExpression */
|
|
37
46
|
/** @typedef {import("estree").Declaration} Declaration */
|
|
38
47
|
/** @typedef {import("estree").PrivateIdentifier} PrivateIdentifier */
|
|
@@ -94,6 +103,7 @@ const BasicEvaluatedExpression = require("./BasicEvaluatedExpression");
|
|
|
94
103
|
/** @typedef {import("estree").MaybeNamedFunctionDeclaration} MaybeNamedFunctionDeclaration */
|
|
95
104
|
/** @typedef {import("estree").MaybeNamedClassDeclaration} MaybeNamedClassDeclaration */
|
|
96
105
|
/**
|
|
106
|
+
* Defines the shared type used by this module.
|
|
97
107
|
* @template T
|
|
98
108
|
* @typedef {import("tapable").AsArray<T>} AsArray<T>
|
|
99
109
|
*/
|
|
@@ -104,6 +114,7 @@ const BasicEvaluatedExpression = require("./BasicEvaluatedExpression");
|
|
|
104
114
|
/** @typedef {import("../dependencies/HarmonyExportImportedSpecifierDependency").HarmonyStarExportsList} HarmonyStarExportsList */
|
|
105
115
|
|
|
106
116
|
/**
|
|
117
|
+
* Defines the known javascript parser state type used by this module.
|
|
107
118
|
* @typedef {object} KnownJavascriptParserState
|
|
108
119
|
* @property {Set<string>=} harmonyNamedExports
|
|
109
120
|
* @property {HarmonyStarExportsList=} harmonyStarExports
|
|
@@ -117,6 +128,7 @@ const BasicEvaluatedExpression = require("./BasicEvaluatedExpression");
|
|
|
117
128
|
/** @typedef {import("../Module")} Module */
|
|
118
129
|
|
|
119
130
|
/** @typedef {{ name: string | VariableInfo, rootInfo: string | VariableInfo, getMembers: () => Members, getMembersOptionals: () => MembersOptionals, getMemberRanges: () => MemberRanges }} GetInfoResult */
|
|
131
|
+
/** @typedef {{ consequent?: EXPECTED_OBJECT, alternate?: EXPECTED_OBJECT }} GuardCollection per-branch guard frames pushed onto the parser state guard stack */
|
|
120
132
|
/** @typedef {Statement | ModuleDeclaration | Expression | MaybeNamedFunctionDeclaration | MaybeNamedClassDeclaration} StatementPathItem */
|
|
121
133
|
/** @typedef {(ident: string) => void} OnIdentString */
|
|
122
134
|
/** @typedef {(ident: string, identifier: Identifier) => void} OnIdent */
|
|
@@ -124,86 +136,52 @@ const BasicEvaluatedExpression = require("./BasicEvaluatedExpression");
|
|
|
124
136
|
|
|
125
137
|
/** @typedef {Set<DestructuringAssignmentProperty>} DestructuringAssignmentProperties */
|
|
126
138
|
|
|
127
|
-
// TODO remove cast when @types/estree has been updated to import
|
|
139
|
+
// TODO remove cast when @types/estree has been updated to import phases
|
|
128
140
|
/** @typedef {import("estree").ImportExpression & { phase?: "defer" | "source" }} ImportExpression */
|
|
129
141
|
|
|
130
142
|
/** @type {string[]} */
|
|
131
143
|
const EMPTY_ARRAY = [];
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Getter that reverses `arr` in place on first access and caches it. Lighter
|
|
147
|
+
* than `memoize(() => arr.reverse())` (one closure instead of two) and called
|
|
148
|
+
* per member expression on hot parse paths.
|
|
149
|
+
* @template T
|
|
150
|
+
* @param {T[]} arr array reversed lazily on first access
|
|
151
|
+
* @returns {() => T[]} getter returning the reversed array
|
|
152
|
+
*/
|
|
153
|
+
const lazyReverse = (arr) => {
|
|
154
|
+
let reversed = false;
|
|
155
|
+
return () => {
|
|
156
|
+
if (!reversed) {
|
|
157
|
+
arr.reverse();
|
|
158
|
+
reversed = true;
|
|
159
|
+
}
|
|
160
|
+
return arr;
|
|
161
|
+
};
|
|
162
|
+
};
|
|
163
|
+
|
|
132
164
|
const ALLOWED_MEMBER_TYPES_CALL_EXPRESSION = 0b01;
|
|
133
165
|
const ALLOWED_MEMBER_TYPES_EXPRESSION = 0b10;
|
|
134
166
|
const ALLOWED_MEMBER_TYPES_ALL = 0b11;
|
|
135
167
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
const importAssertions = (Parser) =>
|
|
140
|
-
class extends Parser {
|
|
141
|
-
/**
|
|
142
|
-
* @this {InstanceType<AcornParser>}
|
|
143
|
-
* @returns {ImportAttribute[]} import attributes
|
|
144
|
-
*/
|
|
145
|
-
parseWithClause() {
|
|
146
|
-
/** @type {ImportAttribute[]} */
|
|
147
|
-
const nodes = [];
|
|
148
|
-
|
|
149
|
-
const isAssertLegacy = this.value === "assert";
|
|
150
|
-
|
|
151
|
-
if (isAssertLegacy) {
|
|
152
|
-
if (!this.eat(tokTypes.name)) {
|
|
153
|
-
return nodes;
|
|
154
|
-
}
|
|
155
|
-
} else if (!this.eat(tokTypes._with)) {
|
|
156
|
-
return nodes;
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
this.expect(tokTypes.braceL);
|
|
160
|
-
|
|
161
|
-
/** @type {Record<string, boolean>} */
|
|
162
|
-
const attributeKeys = {};
|
|
163
|
-
let first = true;
|
|
164
|
-
|
|
165
|
-
while (!this.eat(tokTypes.braceR)) {
|
|
166
|
-
if (!first) {
|
|
167
|
-
this.expect(tokTypes.comma);
|
|
168
|
-
if (this.afterTrailingComma(tokTypes.braceR)) {
|
|
169
|
-
break;
|
|
170
|
-
}
|
|
171
|
-
} else {
|
|
172
|
-
first = false;
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
const attr =
|
|
176
|
-
/** @type {ImportAttribute} */
|
|
177
|
-
this.parseImportAttribute();
|
|
178
|
-
const keyName =
|
|
179
|
-
attr.key.type === "Identifier" ? attr.key.name : attr.key.value;
|
|
180
|
-
|
|
181
|
-
if (Object.prototype.hasOwnProperty.call(attributeKeys, keyName)) {
|
|
182
|
-
this.raiseRecoverable(
|
|
183
|
-
attr.key.start,
|
|
184
|
-
`Duplicate attribute key '${keyName}'`
|
|
185
|
-
);
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
attributeKeys[keyName] = true;
|
|
189
|
-
nodes.push(attr);
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
if (isAssertLegacy) {
|
|
193
|
-
/** @type {EXPECTED_ANY} */
|
|
194
|
-
(nodes)[LEGACY_ASSERT_ATTRIBUTES] = true;
|
|
195
|
-
}
|
|
168
|
+
// Shared `() => false` so the members-optionals fallback in walkCallExpression
|
|
169
|
+
// doesn't allocate a fresh closure per identifier-rooted call.
|
|
170
|
+
const RETURN_FALSE = () => false;
|
|
196
171
|
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
172
|
+
// Shared `() => []` for the member-less identifier/this evaluation results,
|
|
173
|
+
// replacing three fresh closures per evaluated free variable.
|
|
174
|
+
const RETURN_EMPTY_ARRAY = () => [];
|
|
200
175
|
|
|
201
176
|
// Syntax: https://developer.mozilla.org/en/SpiderMonkey/Parser_API
|
|
202
|
-
let parser = AcornParser
|
|
177
|
+
let parser = /** @type {AcornParser} */ (WebpackParser);
|
|
203
178
|
|
|
204
179
|
/** @typedef {Record<string, string> & { _isLegacyAssert?: boolean }} ImportAttributes */
|
|
205
180
|
|
|
181
|
+
// Conceptually pairs with ./syntax's LEGACY_ASSERT_ATTRIBUTES marker, but is
|
|
182
|
+
// pinned here by its public `JavascriptParser.getImportAttributes` typing.
|
|
206
183
|
/**
|
|
184
|
+
* Gets import attributes.
|
|
207
185
|
* @param {ImportDeclaration | ExportNamedDeclaration | ExportAllDeclaration | ImportExpression} node node with assertions
|
|
208
186
|
* @returns {ImportAttributes | undefined} import attributes
|
|
209
187
|
*/
|
|
@@ -287,19 +265,25 @@ const VariableInfoFlags = Object.freeze({
|
|
|
287
265
|
|
|
288
266
|
class VariableInfo {
|
|
289
267
|
/**
|
|
268
|
+
* Creates an instance of VariableInfo.
|
|
290
269
|
* @param {ScopeInfo} declaredScope scope in which the variable is declared
|
|
291
270
|
* @param {string | undefined} name which name the variable use, defined name or free name or tagged name
|
|
292
271
|
* @param {VariableInfoFlagsType} flags how the variable is created
|
|
293
272
|
* @param {TagInfo | undefined} tagInfo info about tags
|
|
294
273
|
*/
|
|
295
274
|
constructor(declaredScope, name, flags, tagInfo) {
|
|
275
|
+
/** @type {ScopeInfo} */
|
|
296
276
|
this.declaredScope = declaredScope;
|
|
277
|
+
/** @type {string | undefined} */
|
|
297
278
|
this.name = name;
|
|
279
|
+
/** @type {VariableInfoFlagsType} */
|
|
298
280
|
this.flags = flags;
|
|
281
|
+
/** @type {TagInfo | undefined} */
|
|
299
282
|
this.tagInfo = tagInfo;
|
|
300
283
|
}
|
|
301
284
|
|
|
302
285
|
/**
|
|
286
|
+
* Checks whether this variable info is free.
|
|
303
287
|
* @returns {boolean} the variable is free or not
|
|
304
288
|
*/
|
|
305
289
|
isFree() {
|
|
@@ -307,6 +291,7 @@ class VariableInfo {
|
|
|
307
291
|
}
|
|
308
292
|
|
|
309
293
|
/**
|
|
294
|
+
* Checks whether this variable info is tagged.
|
|
310
295
|
* @returns {boolean} the variable is tagged by tagVariable or not
|
|
311
296
|
*/
|
|
312
297
|
isTagged() {
|
|
@@ -318,45 +303,51 @@ class VariableInfo {
|
|
|
318
303
|
/** @typedef {Literal | string | null | undefined} ImportSource */
|
|
319
304
|
|
|
320
305
|
/**
|
|
306
|
+
* Defines the internal parse options type used by this module.
|
|
321
307
|
* @typedef {Omit<ParseOptions, "sourceType" | "ecmaVersion"> & { sourceType: "module" | "script" | "auto" }} InternalParseOptions
|
|
322
308
|
*/
|
|
323
309
|
|
|
324
310
|
/**
|
|
311
|
+
* Defines the parse options type used by this module.
|
|
325
312
|
* @typedef {object} ParseOptions
|
|
326
313
|
* @property {"module" | "script"} sourceType
|
|
327
314
|
* @property {EcmaVersion} ecmaVersion
|
|
328
315
|
* @property {boolean=} locations
|
|
329
316
|
* @property {boolean=} comments
|
|
330
317
|
* @property {boolean=} ranges
|
|
331
|
-
* @property {boolean=} semicolons
|
|
332
318
|
* @property {boolean=} allowHashBang
|
|
333
319
|
* @property {boolean=} allowReturnOutsideFunction
|
|
320
|
+
* @property {boolean=} lazyNodes internal: serve `range` lazily and skip acorn's location/range tracking
|
|
321
|
+
* @property {Comment[]=} lazyComments internal: collect comments here without slicing their text eagerly
|
|
322
|
+
* @property {boolean=} importPhases enable parsing of the import phase proposals (import defer / import source)
|
|
323
|
+
* @property {boolean=} moduleFallback internal: for `auto`, let the parser downgrade module->script in place instead of re-parsing
|
|
334
324
|
*/
|
|
335
325
|
|
|
336
326
|
/**
|
|
327
|
+
* Defines the parse result type used by this module.
|
|
337
328
|
* @typedef {object} ParseResult
|
|
338
329
|
* @property {Program} ast
|
|
339
330
|
* @property {Comment[]} comments
|
|
340
|
-
* @property {Set<number>} semicolons
|
|
341
331
|
*/
|
|
342
332
|
|
|
343
333
|
/**
|
|
334
|
+
* Defines the parse function type used by this module.
|
|
344
335
|
* @typedef {(code: string, options: ParseOptions) => ParseResult} ParseFunction
|
|
345
336
|
*/
|
|
346
337
|
|
|
347
338
|
/** @typedef {symbol} Tag */
|
|
348
339
|
|
|
349
340
|
/** @typedef {import("../dependencies/HarmonyImportDependencyParserPlugin").HarmonySettings} HarmonySettings */
|
|
350
|
-
/** @typedef {import("../dependencies/HarmonyImportDependencyParserPlugin").HarmonySpecifierGuards} HarmonySpecifierGuards */
|
|
351
341
|
/** @typedef {import("../dependencies/ImportParserPlugin").ImportSettings} ImportSettings */
|
|
352
342
|
/** @typedef {import("../dependencies/CommonJsImportsParserPlugin").CommonJsImportSettings} CommonJsImportSettings */
|
|
353
343
|
/** @typedef {import("../CompatibilityPlugin").CompatibilitySettings} CompatibilitySettings */
|
|
354
344
|
/** @typedef {import("../optimize/InnerGraph").TopLevelSymbol} TopLevelSymbol */
|
|
355
345
|
|
|
356
|
-
/** @typedef {HarmonySettings | ImportSettings | CommonJsImportSettings | TopLevelSymbol | CompatibilitySettings
|
|
346
|
+
/** @typedef {HarmonySettings | ImportSettings | CommonJsImportSettings | TopLevelSymbol | CompatibilitySettings} KnownTagData */
|
|
357
347
|
/** @typedef {KnownTagData | Record<string, EXPECTED_ANY>} TagData */
|
|
358
348
|
|
|
359
349
|
/**
|
|
350
|
+
* Defines the tag info type used by this module.
|
|
360
351
|
* @typedef {object} TagInfo
|
|
361
352
|
* @property {Tag} tag
|
|
362
353
|
* @property {TagData=} data
|
|
@@ -372,6 +363,7 @@ const SCOPE_INFO_TERMINATED_RETURN = 1;
|
|
|
372
363
|
const SCOPE_INFO_TERMINATED_THROW = 2;
|
|
373
364
|
|
|
374
365
|
/**
|
|
366
|
+
* Defines the scope info type used by this module.
|
|
375
367
|
* @typedef {object} ScopeInfo
|
|
376
368
|
* @property {StackedMap<string, VariableInfo | ScopeInfo>} definitions
|
|
377
369
|
* @property {boolean | "arrow"} topLevelScope
|
|
@@ -386,10 +378,11 @@ const SCOPE_INFO_TERMINATED_THROW = 2;
|
|
|
386
378
|
/** @typedef {[number, number]} Range */
|
|
387
379
|
|
|
388
380
|
/**
|
|
381
|
+
* Defines the destructuring assignment property type used by this module.
|
|
382
|
+
* Carries only the range — consumers derive line/column via `getLocation`.
|
|
389
383
|
* @typedef {object} DestructuringAssignmentProperty
|
|
390
384
|
* @property {string} id
|
|
391
385
|
* @property {Range} range
|
|
392
|
-
* @property {SourceLocation} loc
|
|
393
386
|
* @property {Set<DestructuringAssignmentProperty> | undefined=} pattern
|
|
394
387
|
* @property {boolean | string} shorthand
|
|
395
388
|
*/
|
|
@@ -459,6 +452,25 @@ const getRootName = (expression) => {
|
|
|
459
452
|
}
|
|
460
453
|
};
|
|
461
454
|
|
|
455
|
+
/**
|
|
456
|
+
* @param {string} type AST node type
|
|
457
|
+
* @returns {boolean} true for FunctionExpression or ArrowFunctionExpression
|
|
458
|
+
*/
|
|
459
|
+
const isFunctionExpression = (type) =>
|
|
460
|
+
type === "FunctionExpression" || type === "ArrowFunctionExpression";
|
|
461
|
+
|
|
462
|
+
/**
|
|
463
|
+
* @param {FunctionExpression | ArrowFunctionExpression} fn function
|
|
464
|
+
* @returns {boolean} true when all params are plain identifiers
|
|
465
|
+
*/
|
|
466
|
+
const isSimpleFunction = (fn) => {
|
|
467
|
+
const params = fn.params;
|
|
468
|
+
for (let i = 0; i < params.length; i++) {
|
|
469
|
+
if (params[i].type !== "Identifier") return false;
|
|
470
|
+
}
|
|
471
|
+
return true;
|
|
472
|
+
};
|
|
473
|
+
|
|
462
474
|
/** @type {ParseOptions} */
|
|
463
475
|
const defaultParserOptions = {
|
|
464
476
|
sourceType: "module",
|
|
@@ -470,17 +482,24 @@ const defaultParserOptions = {
|
|
|
470
482
|
allowHashBang: true
|
|
471
483
|
};
|
|
472
484
|
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
485
|
+
// reused by _parse for every non-custom parse — all fields are reset per parse
|
|
486
|
+
/** @type {ParseOptions} */
|
|
487
|
+
const REUSED_PARSER_OPTIONS = { ...defaultParserOptions };
|
|
488
|
+
|
|
489
|
+
// Read-only snippet ASTs for `evaluate()`, released with the compilation;
|
|
490
|
+
// DefinePlugin evaluates the same strings once per usage per module.
|
|
491
|
+
/** @type {WeakMap<Compilation, Map<string, Program>>} */
|
|
492
|
+
const evaluateAstCaches = new WeakMap();
|
|
493
|
+
// The inner map is strong while the compilation lives, so cap it
|
|
494
|
+
const EVALUATE_AST_CACHE_LIMIT = 4096;
|
|
477
495
|
|
|
478
496
|
const CLASS_NAME = "JavascriptParser";
|
|
479
497
|
|
|
480
498
|
class JavascriptParser extends Parser {
|
|
481
499
|
/**
|
|
500
|
+
* Creates an instance of JavascriptParser.
|
|
482
501
|
* @param {"module" | "script" | "auto"=} sourceType default source type
|
|
483
|
-
* @param {{ parse?: ParseFunction }=} options parser options
|
|
502
|
+
* @param {{ parse?: ParseFunction, typescript?: boolean, importPhases?: boolean, strictModeViolations?: "error" | "warn" | false }=} options parser options
|
|
484
503
|
*/
|
|
485
504
|
constructor(sourceType = "auto", options = {}) {
|
|
486
505
|
super();
|
|
@@ -513,14 +532,20 @@ class JavascriptParser extends Parser {
|
|
|
513
532
|
),
|
|
514
533
|
/** @type {SyncBailHook<[Statement | ModuleDeclaration | MaybeNamedClassDeclaration | MaybeNamedFunctionDeclaration], boolean | void>} */
|
|
515
534
|
preStatement: new SyncBailHook(["statement"]),
|
|
535
|
+
/** @type {HookMap<SyncBailHook<[Statement | ModuleDeclaration | MaybeNamedClassDeclaration | MaybeNamedFunctionDeclaration], boolean | void>>} */
|
|
536
|
+
preStatementByType: new HookMap(() => new SyncBailHook(["statement"])),
|
|
516
537
|
|
|
517
538
|
/** @type {SyncBailHook<[Statement | ModuleDeclaration | MaybeNamedClassDeclaration | MaybeNamedFunctionDeclaration], boolean | void>} */
|
|
518
539
|
blockPreStatement: new SyncBailHook(["declaration"]),
|
|
540
|
+
/** @type {HookMap<SyncBailHook<[Statement | ModuleDeclaration | MaybeNamedClassDeclaration | MaybeNamedFunctionDeclaration], boolean | void>>} */
|
|
541
|
+
blockPreStatementByType: new HookMap(
|
|
542
|
+
() => new SyncBailHook(["declaration"])
|
|
543
|
+
),
|
|
519
544
|
/** @type {SyncBailHook<[Statement | ModuleDeclaration | MaybeNamedFunctionDeclaration | MaybeNamedClassDeclaration], boolean | void>} */
|
|
520
545
|
statement: new SyncBailHook(["statement"]),
|
|
521
546
|
/** @type {SyncBailHook<[IfStatement], boolean | void>} */
|
|
522
547
|
statementIf: new SyncBailHook(["statement"]),
|
|
523
|
-
/** @type {SyncBailHook<[Expression],
|
|
548
|
+
/** @type {SyncBailHook<[Expression], GuardCollection | void>} */
|
|
524
549
|
collectGuards: new SyncBailHook(["expression"]),
|
|
525
550
|
/** @type {SyncBailHook<[Expression, ClassExpression | ClassDeclaration | MaybeNamedClassDeclaration], boolean | void>} */
|
|
526
551
|
classExtendsExpression: new SyncBailHook([
|
|
@@ -569,7 +594,7 @@ class JavascriptParser extends Parser {
|
|
|
569
594
|
"exportName",
|
|
570
595
|
"index"
|
|
571
596
|
]),
|
|
572
|
-
/** @type {SyncBailHook<[VariableDeclarator,
|
|
597
|
+
/** @type {SyncBailHook<[VariableDeclarator, VariableDeclaration], boolean | void>} */
|
|
573
598
|
preDeclarator: new SyncBailHook(["declarator", "statement"]),
|
|
574
599
|
/** @type {SyncBailHook<[VariableDeclarator, Statement], boolean | void>} */
|
|
575
600
|
declarator: new SyncBailHook(["declarator", "statement"]),
|
|
@@ -686,7 +711,10 @@ class JavascriptParser extends Parser {
|
|
|
686
711
|
this.state = /** @type {EXPECTED_ANY} */ (undefined);
|
|
687
712
|
/** @type {Comment[] | undefined} */
|
|
688
713
|
this.comments = undefined;
|
|
689
|
-
|
|
714
|
+
// ASI overrides keyed by statement-end offset: true forces an ASI
|
|
715
|
+
// position, false forces a real semicolon. Absent offsets are derived
|
|
716
|
+
// from the source text. Allocated lazily by set/unsetAsiPosition.
|
|
717
|
+
/** @type {Map<number, boolean> | undefined} */
|
|
690
718
|
this.semicolons = undefined;
|
|
691
719
|
/** @type {StatementPath | undefined} */
|
|
692
720
|
this.statementPath = undefined;
|
|
@@ -696,8 +724,39 @@ class JavascriptParser extends Parser {
|
|
|
696
724
|
this.destructuringAssignmentProperties = undefined;
|
|
697
725
|
/** @type {TagData | undefined} */
|
|
698
726
|
this.currentTagData = undefined;
|
|
727
|
+
// True while parsing a loose module whose code is emitted as strict ESM.
|
|
728
|
+
this._strictInModuleOutput = false;
|
|
729
|
+
// Source text of the current parse, for offset → line/column mapping.
|
|
730
|
+
/** @type {string | undefined} */
|
|
731
|
+
this._source = undefined;
|
|
732
|
+
// Offset of each line's first character, built on first getLocation use.
|
|
733
|
+
/** @type {number[] | undefined} */
|
|
734
|
+
this._lineStarts = undefined;
|
|
735
|
+
// True while only the parser's own taps sit on evaluate.for("Identifier");
|
|
736
|
+
// recomputed per parse, gates the defined-identifier fast paths.
|
|
737
|
+
this._evalIdentOwnTaps = false;
|
|
699
738
|
this.magicCommentContext = createMagicCommentContext();
|
|
739
|
+
// Reused for enterPatterns on every scope entry to avoid per-scope closures.
|
|
740
|
+
/** @type {OnIdentString} */
|
|
741
|
+
this._defineVariable = (ident) => this.defineVariable(ident);
|
|
700
742
|
this._initializeEvaluating();
|
|
743
|
+
// keyed taps are free for every other member chain, and a shadowed
|
|
744
|
+
// `arguments` binding never dispatches the free-variable hooks
|
|
745
|
+
this.hooks.expressionMemberChain
|
|
746
|
+
.for("arguments")
|
|
747
|
+
.tap(CLASS_NAME, (expression, members) => {
|
|
748
|
+
if (this._strictInModuleOutput) {
|
|
749
|
+
this._checkStrictModeArgumentsMember(members[0], expression);
|
|
750
|
+
}
|
|
751
|
+
});
|
|
752
|
+
this.hooks.callMemberChain
|
|
753
|
+
.for("arguments")
|
|
754
|
+
.tap(CLASS_NAME, (expression, members) => {
|
|
755
|
+
// longer chains re-enter the member walk, which reports them
|
|
756
|
+
if (this._strictInModuleOutput && members.length === 1) {
|
|
757
|
+
this._checkStrictModeArgumentsMember(members[0], expression);
|
|
758
|
+
}
|
|
759
|
+
});
|
|
701
760
|
}
|
|
702
761
|
|
|
703
762
|
_initializeEvaluating() {
|
|
@@ -956,6 +1015,7 @@ class JavascriptParser extends Parser {
|
|
|
956
1015
|
(a === true && b === false) || (a === false && b === true);
|
|
957
1016
|
|
|
958
1017
|
/**
|
|
1018
|
+
* Handle template string compare.
|
|
959
1019
|
* @param {BasicEvaluatedExpression} left left
|
|
960
1020
|
* @param {BasicEvaluatedExpression} right right
|
|
961
1021
|
* @param {BasicEvaluatedExpression} res res
|
|
@@ -964,6 +1024,7 @@ class JavascriptParser extends Parser {
|
|
|
964
1024
|
*/
|
|
965
1025
|
const handleTemplateStringCompare = (left, right, res, eql) => {
|
|
966
1026
|
/**
|
|
1027
|
+
* Returns value.
|
|
967
1028
|
* @param {BasicEvaluatedExpression[]} parts parts
|
|
968
1029
|
* @returns {string} value
|
|
969
1030
|
*/
|
|
@@ -977,6 +1038,7 @@ class JavascriptParser extends Parser {
|
|
|
977
1038
|
return value;
|
|
978
1039
|
};
|
|
979
1040
|
/**
|
|
1041
|
+
* Returns value.
|
|
980
1042
|
* @param {BasicEvaluatedExpression[]} parts parts
|
|
981
1043
|
* @returns {string} value
|
|
982
1044
|
*/
|
|
@@ -1319,6 +1381,16 @@ class JavascriptParser extends Parser {
|
|
|
1319
1381
|
return handleConstOperation((l, r) => l <= r);
|
|
1320
1382
|
} else if (expr.operator === ">=") {
|
|
1321
1383
|
return handleConstOperation((l, r) => l >= r);
|
|
1384
|
+
} else if (expr.operator === "in") {
|
|
1385
|
+
// `x in y` always evaluates to a boolean, so it is never nullish
|
|
1386
|
+
const left = this.evaluateExpression(expr.left);
|
|
1387
|
+
const right = this.evaluateExpression(expr.right);
|
|
1388
|
+
return new BasicEvaluatedExpression()
|
|
1389
|
+
.setNullish(false)
|
|
1390
|
+
.setSideEffects(
|
|
1391
|
+
left.couldHaveSideEffects() || right.couldHaveSideEffects()
|
|
1392
|
+
)
|
|
1393
|
+
.setRange(/** @type {Range} */ (expr.range));
|
|
1322
1394
|
}
|
|
1323
1395
|
});
|
|
1324
1396
|
this.hooks.evaluate.for("UnaryExpression").tap(CLASS_NAME, (_expr) => {
|
|
@@ -1460,6 +1532,7 @@ class JavascriptParser extends Parser {
|
|
|
1460
1532
|
}
|
|
1461
1533
|
});
|
|
1462
1534
|
/**
|
|
1535
|
+
* Tap evaluate with variable info.
|
|
1463
1536
|
* @param {"Identifier" | "ThisExpression" | "MemberExpression"} exprType expression type name
|
|
1464
1537
|
* @param {(node: Expression | SpreadElement) => GetInfoResult | undefined} getInfo get info
|
|
1465
1538
|
* @returns {void}
|
|
@@ -1474,15 +1547,16 @@ class JavascriptParser extends Parser {
|
|
|
1474
1547
|
/** @type {Identifier | ThisExpression | MemberExpression} */ (expr);
|
|
1475
1548
|
|
|
1476
1549
|
const info = getInfo(expression);
|
|
1550
|
+
// Cache the result (even when undefined) so the stage-100 tap below
|
|
1551
|
+
// reuses it instead of recomputing getInfo — getMemberExpressionInfo
|
|
1552
|
+
// is expensive and previously ran twice for every rejected member.
|
|
1553
|
+
cachedExpression = expression;
|
|
1554
|
+
cachedInfo = info;
|
|
1477
1555
|
if (info !== undefined) {
|
|
1478
1556
|
return this.callHooksForInfoWithFallback(
|
|
1479
1557
|
this.hooks.evaluateIdentifier,
|
|
1480
1558
|
info.name,
|
|
1481
|
-
(_name) =>
|
|
1482
|
-
cachedExpression = expression;
|
|
1483
|
-
cachedInfo = info;
|
|
1484
|
-
return undefined;
|
|
1485
|
-
},
|
|
1559
|
+
(_name) => undefined,
|
|
1486
1560
|
(name) => {
|
|
1487
1561
|
const hook = this.hooks.evaluateDefinedIdentifier.get(name);
|
|
1488
1562
|
if (hook !== undefined) {
|
|
@@ -1522,14 +1596,18 @@ class JavascriptParser extends Parser {
|
|
|
1522
1596
|
const info = this.getVariableInfo(/** @type {Identifier} */ (expr).name);
|
|
1523
1597
|
if (
|
|
1524
1598
|
typeof info === "string" ||
|
|
1525
|
-
(info instanceof VariableInfo &&
|
|
1599
|
+
(info instanceof VariableInfo &&
|
|
1600
|
+
(info.isFree() ||
|
|
1601
|
+
info.isTagged() ||
|
|
1602
|
+
// Walk `tagInfo` in `callHooksForInfo` if tagInfo is present.
|
|
1603
|
+
info.tagInfo !== undefined))
|
|
1526
1604
|
) {
|
|
1527
1605
|
return {
|
|
1528
1606
|
name: info,
|
|
1529
1607
|
rootInfo: info,
|
|
1530
|
-
getMembers:
|
|
1531
|
-
getMembersOptionals:
|
|
1532
|
-
getMemberRanges:
|
|
1608
|
+
getMembers: RETURN_EMPTY_ARRAY,
|
|
1609
|
+
getMembersOptionals: RETURN_EMPTY_ARRAY,
|
|
1610
|
+
getMemberRanges: RETURN_EMPTY_ARRAY
|
|
1533
1611
|
};
|
|
1534
1612
|
}
|
|
1535
1613
|
});
|
|
@@ -1542,9 +1620,9 @@ class JavascriptParser extends Parser {
|
|
|
1542
1620
|
return {
|
|
1543
1621
|
name: info,
|
|
1544
1622
|
rootInfo: info,
|
|
1545
|
-
getMembers:
|
|
1546
|
-
getMembersOptionals:
|
|
1547
|
-
getMemberRanges:
|
|
1623
|
+
getMembers: RETURN_EMPTY_ARRAY,
|
|
1624
|
+
getMembersOptionals: RETURN_EMPTY_ARRAY,
|
|
1625
|
+
getMemberRanges: RETURN_EMPTY_ARRAY
|
|
1548
1626
|
};
|
|
1549
1627
|
}
|
|
1550
1628
|
});
|
|
@@ -1565,8 +1643,8 @@ class JavascriptParser extends Parser {
|
|
|
1565
1643
|
)
|
|
1566
1644
|
);
|
|
1567
1645
|
|
|
1568
|
-
this.hooks.evaluate.for("CallExpression").tap(CLASS_NAME, (
|
|
1569
|
-
const expr = /** @type {CallExpression} */ (
|
|
1646
|
+
this.hooks.evaluate.for("CallExpression").tap(CLASS_NAME, (expression) => {
|
|
1647
|
+
const expr = /** @type {CallExpression} */ (expression);
|
|
1570
1648
|
if (
|
|
1571
1649
|
expr.callee.type === "MemberExpression" &&
|
|
1572
1650
|
expr.callee.property.type ===
|
|
@@ -1687,6 +1765,7 @@ class JavascriptParser extends Parser {
|
|
|
1687
1765
|
}
|
|
1688
1766
|
|
|
1689
1767
|
/**
|
|
1768
|
+
* Gets simplified template result.
|
|
1690
1769
|
* @param {"cooked" | "raw"} kind kind of values to get
|
|
1691
1770
|
* @param {TemplateLiteral} templateLiteralExpr TemplateLiteral expr
|
|
1692
1771
|
* @returns {{ quasis: BasicEvaluatedExpression[], parts: BasicEvaluatedExpression[] }} Simplified template
|
|
@@ -1959,9 +2038,25 @@ class JavascriptParser extends Parser {
|
|
|
1959
2038
|
}
|
|
1960
2039
|
return this.evaluateExpression(expr.expression);
|
|
1961
2040
|
});
|
|
2041
|
+
this.hooks.evaluate.for("SequenceExpression").tap(CLASS_NAME, (_expr) => {
|
|
2042
|
+
const expr = /** @type {SequenceExpression} */ (_expr);
|
|
2043
|
+
if (!expr.range) return;
|
|
2044
|
+
let commentsStartPos = /** @type {Range} */ (expr.range)[0];
|
|
2045
|
+
for (let i = 0; i < expr.expressions.length - 1; i++) {
|
|
2046
|
+
const item = expr.expressions[i];
|
|
2047
|
+
if (!item.range) return;
|
|
2048
|
+
if (!this.isPure(item, commentsStartPos)) return;
|
|
2049
|
+
commentsStartPos = /** @type {Range} */ (item.range)[1];
|
|
2050
|
+
}
|
|
2051
|
+
const last = expr.expressions[expr.expressions.length - 1];
|
|
2052
|
+
const evaluated = this.evaluateExpression(last);
|
|
2053
|
+
if (!evaluated.isCompileTimeValue()) return;
|
|
2054
|
+
return evaluated.setRange(/** @type {Range} */ (expr.range));
|
|
2055
|
+
});
|
|
1962
2056
|
}
|
|
1963
2057
|
|
|
1964
2058
|
/**
|
|
2059
|
+
* Destructuring assignment properties for.
|
|
1965
2060
|
* @param {Expression} node node
|
|
1966
2061
|
* @returns {DestructuringAssignmentProperties | undefined} destructured identifiers
|
|
1967
2062
|
*/
|
|
@@ -1971,10 +2066,20 @@ class JavascriptParser extends Parser {
|
|
|
1971
2066
|
}
|
|
1972
2067
|
|
|
1973
2068
|
/**
|
|
2069
|
+
* Gets rename identifier.
|
|
1974
2070
|
* @param {Expression | SpreadElement} expr expression
|
|
1975
2071
|
* @returns {string | VariableInfo | undefined} identifier
|
|
1976
2072
|
*/
|
|
1977
2073
|
getRenameIdentifier(expr) {
|
|
2074
|
+
if (
|
|
2075
|
+
expr.type === "Identifier" &&
|
|
2076
|
+
this._evalIdentOwnTaps &&
|
|
2077
|
+
expr.name !== "undefined" &&
|
|
2078
|
+
this._isDefinedPlainVariable(expr.name)
|
|
2079
|
+
) {
|
|
2080
|
+
// the evaluation could only fall through — never an identifier result
|
|
2081
|
+
return;
|
|
2082
|
+
}
|
|
1978
2083
|
const result = this.evaluateExpression(expr);
|
|
1979
2084
|
if (result.isIdentifier()) {
|
|
1980
2085
|
return result.identifier;
|
|
@@ -1982,6 +2087,7 @@ class JavascriptParser extends Parser {
|
|
|
1982
2087
|
}
|
|
1983
2088
|
|
|
1984
2089
|
/**
|
|
2090
|
+
* Processes the provided classy.
|
|
1985
2091
|
* @param {ClassExpression | ClassDeclaration | MaybeNamedClassDeclaration} classy a class node
|
|
1986
2092
|
* @returns {void}
|
|
1987
2093
|
*/
|
|
@@ -2113,49 +2219,60 @@ class JavascriptParser extends Parser {
|
|
|
2113
2219
|
preWalkStatement(statement) {
|
|
2114
2220
|
/** @type {StatementPath} */
|
|
2115
2221
|
(this.statementPath).push(statement);
|
|
2116
|
-
|
|
2222
|
+
const { preStatement, preStatementByType } = this.hooks;
|
|
2223
|
+
// skip the broadcast entirely when nothing taps it; type-keyed taps
|
|
2224
|
+
// only run for their statement type
|
|
2225
|
+
let bail =
|
|
2226
|
+
preStatement.taps.length !== 0 ? preStatement.call(statement) : undefined;
|
|
2227
|
+
if (!bail) {
|
|
2228
|
+
const typed = preStatementByType.get(statement.type);
|
|
2229
|
+
if (typed !== undefined) bail = typed.call(statement);
|
|
2230
|
+
}
|
|
2231
|
+
if (bail) {
|
|
2117
2232
|
this.prevStatement =
|
|
2118
2233
|
/** @type {StatementPath} */
|
|
2119
2234
|
(this.statementPath).pop();
|
|
2120
2235
|
return;
|
|
2121
2236
|
}
|
|
2237
|
+
// cases ordered by measured statement frequency; the commonest statements
|
|
2238
|
+
// (expressions, returns) intentionally match nothing here
|
|
2122
2239
|
switch (statement.type) {
|
|
2123
|
-
case "
|
|
2124
|
-
this.
|
|
2125
|
-
break;
|
|
2126
|
-
case "DoWhileStatement":
|
|
2127
|
-
this.preWalkDoWhileStatement(statement);
|
|
2128
|
-
break;
|
|
2129
|
-
case "ForInStatement":
|
|
2130
|
-
this.preWalkForInStatement(statement);
|
|
2240
|
+
case "VariableDeclaration":
|
|
2241
|
+
this.preWalkVariableDeclaration(statement);
|
|
2131
2242
|
break;
|
|
2132
|
-
case "
|
|
2133
|
-
this.
|
|
2243
|
+
case "IfStatement":
|
|
2244
|
+
this.preWalkIfStatement(statement);
|
|
2134
2245
|
break;
|
|
2135
|
-
case "
|
|
2136
|
-
this.
|
|
2246
|
+
case "BlockStatement":
|
|
2247
|
+
this.preWalkBlockStatement(statement);
|
|
2137
2248
|
break;
|
|
2138
2249
|
case "FunctionDeclaration":
|
|
2139
2250
|
this.preWalkFunctionDeclaration(statement);
|
|
2140
2251
|
break;
|
|
2141
|
-
case "
|
|
2142
|
-
this.
|
|
2143
|
-
break;
|
|
2144
|
-
case "LabeledStatement":
|
|
2145
|
-
this.preWalkLabeledStatement(statement);
|
|
2146
|
-
break;
|
|
2147
|
-
case "SwitchStatement":
|
|
2148
|
-
this.preWalkSwitchStatement(statement);
|
|
2252
|
+
case "ForStatement":
|
|
2253
|
+
this.preWalkForStatement(statement);
|
|
2149
2254
|
break;
|
|
2150
2255
|
case "TryStatement":
|
|
2151
2256
|
this.preWalkTryStatement(statement);
|
|
2152
2257
|
break;
|
|
2153
|
-
case "
|
|
2154
|
-
this.
|
|
2258
|
+
case "SwitchStatement":
|
|
2259
|
+
this.preWalkSwitchStatement(statement);
|
|
2155
2260
|
break;
|
|
2156
2261
|
case "WhileStatement":
|
|
2157
2262
|
this.preWalkWhileStatement(statement);
|
|
2158
2263
|
break;
|
|
2264
|
+
case "ForInStatement":
|
|
2265
|
+
this.preWalkForInStatement(statement);
|
|
2266
|
+
break;
|
|
2267
|
+
case "ForOfStatement":
|
|
2268
|
+
this.preWalkForOfStatement(statement);
|
|
2269
|
+
break;
|
|
2270
|
+
case "DoWhileStatement":
|
|
2271
|
+
this.preWalkDoWhileStatement(statement);
|
|
2272
|
+
break;
|
|
2273
|
+
case "LabeledStatement":
|
|
2274
|
+
this.preWalkLabeledStatement(statement);
|
|
2275
|
+
break;
|
|
2159
2276
|
case "WithStatement":
|
|
2160
2277
|
this.preWalkWithStatement(statement);
|
|
2161
2278
|
break;
|
|
@@ -2166,32 +2283,43 @@ class JavascriptParser extends Parser {
|
|
|
2166
2283
|
}
|
|
2167
2284
|
|
|
2168
2285
|
/**
|
|
2286
|
+
* Block pre walk statement.
|
|
2169
2287
|
* @param {Statement | ModuleDeclaration | MaybeNamedClassDeclaration | MaybeNamedFunctionDeclaration} statement statement
|
|
2170
2288
|
*/
|
|
2171
2289
|
blockPreWalkStatement(statement) {
|
|
2172
2290
|
/** @type {StatementPath} */
|
|
2173
2291
|
(this.statementPath).push(statement);
|
|
2174
|
-
|
|
2292
|
+
const { blockPreStatement, blockPreStatementByType } = this.hooks;
|
|
2293
|
+
let bail =
|
|
2294
|
+
blockPreStatement.taps.length !== 0
|
|
2295
|
+
? blockPreStatement.call(statement)
|
|
2296
|
+
: undefined;
|
|
2297
|
+
if (!bail) {
|
|
2298
|
+
const typed = blockPreStatementByType.get(statement.type);
|
|
2299
|
+
if (typed !== undefined) bail = typed.call(statement);
|
|
2300
|
+
}
|
|
2301
|
+
if (bail) {
|
|
2175
2302
|
this.prevStatement =
|
|
2176
2303
|
/** @type {StatementPath} */
|
|
2177
2304
|
(this.statementPath).pop();
|
|
2178
2305
|
return;
|
|
2179
2306
|
}
|
|
2307
|
+
// cases ordered by measured statement frequency
|
|
2180
2308
|
switch (statement.type) {
|
|
2181
|
-
case "ExportDefaultDeclaration":
|
|
2182
|
-
this.blockPreWalkExportDefaultDeclaration(statement);
|
|
2183
|
-
break;
|
|
2184
|
-
case "ExportNamedDeclaration":
|
|
2185
|
-
this.blockPreWalkExportNamedDeclaration(statement);
|
|
2186
|
-
break;
|
|
2187
2309
|
case "VariableDeclaration":
|
|
2188
2310
|
this.blockPreWalkVariableDeclaration(statement);
|
|
2189
2311
|
break;
|
|
2312
|
+
case "ExpressionStatement":
|
|
2313
|
+
this.blockPreWalkExpressionStatement(statement);
|
|
2314
|
+
break;
|
|
2190
2315
|
case "ClassDeclaration":
|
|
2191
2316
|
this.blockPreWalkClassDeclaration(statement);
|
|
2192
2317
|
break;
|
|
2193
|
-
case "
|
|
2194
|
-
this.
|
|
2318
|
+
case "ExportNamedDeclaration":
|
|
2319
|
+
this.blockPreWalkExportNamedDeclaration(statement);
|
|
2320
|
+
break;
|
|
2321
|
+
case "ExportDefaultDeclaration":
|
|
2322
|
+
this.blockPreWalkExportDefaultDeclaration(statement);
|
|
2195
2323
|
}
|
|
2196
2324
|
this.prevStatement =
|
|
2197
2325
|
/** @type {StatementPath} */
|
|
@@ -2199,56 +2327,48 @@ class JavascriptParser extends Parser {
|
|
|
2199
2327
|
}
|
|
2200
2328
|
|
|
2201
2329
|
/**
|
|
2330
|
+
* Processes the provided statement.
|
|
2202
2331
|
* @param {Statement | ModuleDeclaration | MaybeNamedFunctionDeclaration | MaybeNamedClassDeclaration} statement statement
|
|
2203
2332
|
*/
|
|
2204
2333
|
walkStatement(statement) {
|
|
2205
2334
|
/** @type {StatementPath} */
|
|
2206
2335
|
(this.statementPath).push(statement);
|
|
2207
|
-
|
|
2336
|
+
const { statement: statementHook } = this.hooks;
|
|
2337
|
+
if (
|
|
2338
|
+
statementHook.taps.length !== 0 &&
|
|
2339
|
+
statementHook.call(statement) !== undefined
|
|
2340
|
+
) {
|
|
2208
2341
|
this.prevStatement =
|
|
2209
2342
|
/** @type {StatementPath} */
|
|
2210
2343
|
(this.statementPath).pop();
|
|
2211
2344
|
return;
|
|
2212
2345
|
}
|
|
2346
|
+
// cases ordered by measured statement frequency; V8 compiles this to
|
|
2347
|
+
// sequential compares, so hot types must come first
|
|
2213
2348
|
switch (statement.type) {
|
|
2214
|
-
case "BlockStatement":
|
|
2215
|
-
this.walkBlockStatement(statement);
|
|
2216
|
-
break;
|
|
2217
|
-
case "ClassDeclaration":
|
|
2218
|
-
this.walkClassDeclaration(statement);
|
|
2219
|
-
break;
|
|
2220
|
-
case "DoWhileStatement":
|
|
2221
|
-
this.walkDoWhileStatement(statement);
|
|
2222
|
-
break;
|
|
2223
|
-
case "ExportDefaultDeclaration":
|
|
2224
|
-
this.walkExportDefaultDeclaration(statement);
|
|
2225
|
-
break;
|
|
2226
|
-
case "ExportNamedDeclaration":
|
|
2227
|
-
this.walkExportNamedDeclaration(statement);
|
|
2228
|
-
break;
|
|
2229
2349
|
case "ExpressionStatement":
|
|
2230
2350
|
this.walkExpressionStatement(statement);
|
|
2231
2351
|
break;
|
|
2232
|
-
case "
|
|
2233
|
-
this.
|
|
2352
|
+
case "VariableDeclaration":
|
|
2353
|
+
this.walkVariableDeclaration(statement);
|
|
2234
2354
|
break;
|
|
2235
|
-
case "
|
|
2236
|
-
this.
|
|
2355
|
+
case "ReturnStatement":
|
|
2356
|
+
this.walkReturnStatement(statement);
|
|
2237
2357
|
break;
|
|
2238
|
-
case "
|
|
2239
|
-
this.
|
|
2358
|
+
case "IfStatement":
|
|
2359
|
+
this.walkIfStatement(statement);
|
|
2360
|
+
break;
|
|
2361
|
+
case "BlockStatement":
|
|
2362
|
+
this.walkBlockStatement(statement);
|
|
2240
2363
|
break;
|
|
2241
2364
|
case "FunctionDeclaration":
|
|
2242
2365
|
this.walkFunctionDeclaration(statement);
|
|
2243
2366
|
break;
|
|
2244
|
-
case "
|
|
2245
|
-
this.
|
|
2246
|
-
break;
|
|
2247
|
-
case "LabeledStatement":
|
|
2248
|
-
this.walkLabeledStatement(statement);
|
|
2367
|
+
case "ForStatement":
|
|
2368
|
+
this.walkForStatement(statement);
|
|
2249
2369
|
break;
|
|
2250
|
-
case "
|
|
2251
|
-
this.
|
|
2370
|
+
case "TryStatement":
|
|
2371
|
+
this.walkTryStatement(statement);
|
|
2252
2372
|
break;
|
|
2253
2373
|
case "SwitchStatement":
|
|
2254
2374
|
this.walkSwitchStatement(statement);
|
|
@@ -2256,15 +2376,30 @@ class JavascriptParser extends Parser {
|
|
|
2256
2376
|
case "ThrowStatement":
|
|
2257
2377
|
this.walkThrowStatement(statement);
|
|
2258
2378
|
break;
|
|
2259
|
-
case "TryStatement":
|
|
2260
|
-
this.walkTryStatement(statement);
|
|
2261
|
-
break;
|
|
2262
|
-
case "VariableDeclaration":
|
|
2263
|
-
this.walkVariableDeclaration(statement);
|
|
2264
|
-
break;
|
|
2265
2379
|
case "WhileStatement":
|
|
2266
2380
|
this.walkWhileStatement(statement);
|
|
2267
2381
|
break;
|
|
2382
|
+
case "ClassDeclaration":
|
|
2383
|
+
this.walkClassDeclaration(statement);
|
|
2384
|
+
break;
|
|
2385
|
+
case "ForInStatement":
|
|
2386
|
+
this.walkForInStatement(statement);
|
|
2387
|
+
break;
|
|
2388
|
+
case "ForOfStatement":
|
|
2389
|
+
this.walkForOfStatement(statement);
|
|
2390
|
+
break;
|
|
2391
|
+
case "DoWhileStatement":
|
|
2392
|
+
this.walkDoWhileStatement(statement);
|
|
2393
|
+
break;
|
|
2394
|
+
case "ExportNamedDeclaration":
|
|
2395
|
+
this.walkExportNamedDeclaration(statement);
|
|
2396
|
+
break;
|
|
2397
|
+
case "ExportDefaultDeclaration":
|
|
2398
|
+
this.walkExportDefaultDeclaration(statement);
|
|
2399
|
+
break;
|
|
2400
|
+
case "LabeledStatement":
|
|
2401
|
+
this.walkLabeledStatement(statement);
|
|
2402
|
+
break;
|
|
2268
2403
|
case "WithStatement":
|
|
2269
2404
|
this.walkWithStatement(statement);
|
|
2270
2405
|
break;
|
|
@@ -2287,6 +2422,7 @@ class JavascriptParser extends Parser {
|
|
|
2287
2422
|
|
|
2288
2423
|
// Real Statements
|
|
2289
2424
|
/**
|
|
2425
|
+
* Pre walk block statement.
|
|
2290
2426
|
* @param {BlockStatement} statement block statement
|
|
2291
2427
|
*/
|
|
2292
2428
|
preWalkBlockStatement(statement) {
|
|
@@ -2294,6 +2430,7 @@ class JavascriptParser extends Parser {
|
|
|
2294
2430
|
}
|
|
2295
2431
|
|
|
2296
2432
|
/**
|
|
2433
|
+
* Walk block statement.
|
|
2297
2434
|
* @param {BlockStatement | StaticBlock} statement block statement
|
|
2298
2435
|
*/
|
|
2299
2436
|
walkBlockStatement(statement) {
|
|
@@ -2307,6 +2444,7 @@ class JavascriptParser extends Parser {
|
|
|
2307
2444
|
}
|
|
2308
2445
|
|
|
2309
2446
|
/**
|
|
2447
|
+
* Walk expression statement.
|
|
2310
2448
|
* @param {ExpressionStatement} statement expression statement
|
|
2311
2449
|
*/
|
|
2312
2450
|
walkExpressionStatement(statement) {
|
|
@@ -2314,6 +2452,7 @@ class JavascriptParser extends Parser {
|
|
|
2314
2452
|
}
|
|
2315
2453
|
|
|
2316
2454
|
/**
|
|
2455
|
+
* Pre walk if statement.
|
|
2317
2456
|
* @param {IfStatement} statement if statement
|
|
2318
2457
|
*/
|
|
2319
2458
|
preWalkIfStatement(statement) {
|
|
@@ -2324,27 +2463,47 @@ class JavascriptParser extends Parser {
|
|
|
2324
2463
|
}
|
|
2325
2464
|
|
|
2326
2465
|
/**
|
|
2466
|
+
* Walks a conditional branch with its guard frame (if any) pushed onto the
|
|
2467
|
+
* parser-state guard stack for the duration of the branch body.
|
|
2468
|
+
* @param {EXPECTED_OBJECT | undefined | null} frame guard frame, or falsy when the branch is unguarded
|
|
2469
|
+
* @param {() => void} walk branch walk
|
|
2470
|
+
* @returns {void}
|
|
2471
|
+
*/
|
|
2472
|
+
walkGuardedBranch(frame, walk) {
|
|
2473
|
+
if (!frame) {
|
|
2474
|
+
walk();
|
|
2475
|
+
return;
|
|
2476
|
+
}
|
|
2477
|
+
const stack = this.state.guardStack || (this.state.guardStack = []);
|
|
2478
|
+
stack.push(frame);
|
|
2479
|
+
try {
|
|
2480
|
+
walk();
|
|
2481
|
+
} finally {
|
|
2482
|
+
stack.pop();
|
|
2483
|
+
}
|
|
2484
|
+
}
|
|
2485
|
+
|
|
2486
|
+
/**
|
|
2487
|
+
* Processes the provided statement.
|
|
2327
2488
|
* @param {IfStatement} statement if statement
|
|
2328
2489
|
*/
|
|
2329
2490
|
walkIfStatement(statement) {
|
|
2330
2491
|
const result = this.hooks.statementIf.call(statement);
|
|
2331
2492
|
if (result === undefined) {
|
|
2332
|
-
const
|
|
2333
|
-
|
|
2334
|
-
|
|
2335
|
-
|
|
2336
|
-
|
|
2337
|
-
});
|
|
2338
|
-
} else {
|
|
2339
|
-
this.walkExpression(statement.test);
|
|
2340
|
-
this.walkNestedStatement(statement.consequent);
|
|
2341
|
-
}
|
|
2493
|
+
const guard = this.hooks.collectGuards.call(statement.test);
|
|
2494
|
+
this.walkExpression(statement.test);
|
|
2495
|
+
this.walkGuardedBranch(guard ? guard.consequent : undefined, () =>
|
|
2496
|
+
this.walkNestedStatement(statement.consequent)
|
|
2497
|
+
);
|
|
2342
2498
|
|
|
2343
2499
|
const consequentTerminated = this.scope.terminated;
|
|
2344
2500
|
this.scope.terminated = undefined;
|
|
2345
2501
|
|
|
2346
2502
|
if (statement.alternate) {
|
|
2347
|
-
|
|
2503
|
+
const alternate = statement.alternate;
|
|
2504
|
+
this.walkGuardedBranch(guard ? guard.alternate : undefined, () =>
|
|
2505
|
+
this.walkNestedStatement(alternate)
|
|
2506
|
+
);
|
|
2348
2507
|
}
|
|
2349
2508
|
|
|
2350
2509
|
const alternateTerminated = this.scope.terminated;
|
|
@@ -2361,6 +2520,7 @@ class JavascriptParser extends Parser {
|
|
|
2361
2520
|
}
|
|
2362
2521
|
|
|
2363
2522
|
/**
|
|
2523
|
+
* Pre walk labeled statement.
|
|
2364
2524
|
* @param {LabeledStatement} statement with statement
|
|
2365
2525
|
*/
|
|
2366
2526
|
preWalkLabeledStatement(statement) {
|
|
@@ -2368,6 +2528,7 @@ class JavascriptParser extends Parser {
|
|
|
2368
2528
|
}
|
|
2369
2529
|
|
|
2370
2530
|
/**
|
|
2531
|
+
* Walk labeled statement.
|
|
2371
2532
|
* @param {LabeledStatement} statement with statement
|
|
2372
2533
|
*/
|
|
2373
2534
|
walkLabeledStatement(statement) {
|
|
@@ -2382,6 +2543,7 @@ class JavascriptParser extends Parser {
|
|
|
2382
2543
|
}
|
|
2383
2544
|
|
|
2384
2545
|
/**
|
|
2546
|
+
* Pre walk with statement.
|
|
2385
2547
|
* @param {WithStatement} statement with statement
|
|
2386
2548
|
*/
|
|
2387
2549
|
preWalkWithStatement(statement) {
|
|
@@ -2389,9 +2551,16 @@ class JavascriptParser extends Parser {
|
|
|
2389
2551
|
}
|
|
2390
2552
|
|
|
2391
2553
|
/**
|
|
2554
|
+
* Walk with statement.
|
|
2392
2555
|
* @param {WithStatement} statement with statement
|
|
2393
2556
|
*/
|
|
2394
2557
|
walkWithStatement(statement) {
|
|
2558
|
+
if (this._strictInModuleOutput) {
|
|
2559
|
+
this._reportStrictModeViolation(
|
|
2560
|
+
"`with` statements are not allowed",
|
|
2561
|
+
statement
|
|
2562
|
+
);
|
|
2563
|
+
}
|
|
2395
2564
|
this.inBlockScope(() => {
|
|
2396
2565
|
this.walkExpression(statement.object);
|
|
2397
2566
|
this.walkNestedStatement(statement.body);
|
|
@@ -2399,6 +2568,7 @@ class JavascriptParser extends Parser {
|
|
|
2399
2568
|
}
|
|
2400
2569
|
|
|
2401
2570
|
/**
|
|
2571
|
+
* Pre walk switch statement.
|
|
2402
2572
|
* @param {SwitchStatement} statement switch statement
|
|
2403
2573
|
*/
|
|
2404
2574
|
preWalkSwitchStatement(statement) {
|
|
@@ -2406,6 +2576,7 @@ class JavascriptParser extends Parser {
|
|
|
2406
2576
|
}
|
|
2407
2577
|
|
|
2408
2578
|
/**
|
|
2579
|
+
* Walk switch statement.
|
|
2409
2580
|
* @param {SwitchStatement} statement switch statement
|
|
2410
2581
|
*/
|
|
2411
2582
|
walkSwitchStatement(statement) {
|
|
@@ -2414,6 +2585,7 @@ class JavascriptParser extends Parser {
|
|
|
2414
2585
|
}
|
|
2415
2586
|
|
|
2416
2587
|
/**
|
|
2588
|
+
* Walk terminating statement.
|
|
2417
2589
|
* @param {ReturnStatement | ThrowStatement} statement return or throw statement
|
|
2418
2590
|
*/
|
|
2419
2591
|
walkTerminatingStatement(statement) {
|
|
@@ -2429,6 +2601,7 @@ class JavascriptParser extends Parser {
|
|
|
2429
2601
|
}
|
|
2430
2602
|
|
|
2431
2603
|
/**
|
|
2604
|
+
* Walk return statement.
|
|
2432
2605
|
* @param {ReturnStatement} statement return statement
|
|
2433
2606
|
*/
|
|
2434
2607
|
walkReturnStatement(statement) {
|
|
@@ -2436,6 +2609,7 @@ class JavascriptParser extends Parser {
|
|
|
2436
2609
|
}
|
|
2437
2610
|
|
|
2438
2611
|
/**
|
|
2612
|
+
* Walk throw statement.
|
|
2439
2613
|
* @param {ThrowStatement} statement return statement
|
|
2440
2614
|
*/
|
|
2441
2615
|
walkThrowStatement(statement) {
|
|
@@ -2443,6 +2617,7 @@ class JavascriptParser extends Parser {
|
|
|
2443
2617
|
}
|
|
2444
2618
|
|
|
2445
2619
|
/**
|
|
2620
|
+
* Pre walk try statement.
|
|
2446
2621
|
* @param {TryStatement} statement try statement
|
|
2447
2622
|
*/
|
|
2448
2623
|
preWalkTryStatement(statement) {
|
|
@@ -2452,6 +2627,7 @@ class JavascriptParser extends Parser {
|
|
|
2452
2627
|
}
|
|
2453
2628
|
|
|
2454
2629
|
/**
|
|
2630
|
+
* Walk try statement.
|
|
2455
2631
|
* @param {TryStatement} statement try statement
|
|
2456
2632
|
*/
|
|
2457
2633
|
walkTryStatement(statement) {
|
|
@@ -2489,6 +2665,7 @@ class JavascriptParser extends Parser {
|
|
|
2489
2665
|
}
|
|
2490
2666
|
|
|
2491
2667
|
/**
|
|
2668
|
+
* Pre walk while statement.
|
|
2492
2669
|
* @param {WhileStatement} statement while statement
|
|
2493
2670
|
*/
|
|
2494
2671
|
preWalkWhileStatement(statement) {
|
|
@@ -2496,6 +2673,7 @@ class JavascriptParser extends Parser {
|
|
|
2496
2673
|
}
|
|
2497
2674
|
|
|
2498
2675
|
/**
|
|
2676
|
+
* Walk while statement.
|
|
2499
2677
|
* @param {WhileStatement} statement while statement
|
|
2500
2678
|
*/
|
|
2501
2679
|
walkWhileStatement(statement) {
|
|
@@ -2506,6 +2684,7 @@ class JavascriptParser extends Parser {
|
|
|
2506
2684
|
}
|
|
2507
2685
|
|
|
2508
2686
|
/**
|
|
2687
|
+
* Pre walk do while statement.
|
|
2509
2688
|
* @param {DoWhileStatement} statement do while statement
|
|
2510
2689
|
*/
|
|
2511
2690
|
preWalkDoWhileStatement(statement) {
|
|
@@ -2513,6 +2692,7 @@ class JavascriptParser extends Parser {
|
|
|
2513
2692
|
}
|
|
2514
2693
|
|
|
2515
2694
|
/**
|
|
2695
|
+
* Walk do while statement.
|
|
2516
2696
|
* @param {DoWhileStatement} statement do while statement
|
|
2517
2697
|
*/
|
|
2518
2698
|
walkDoWhileStatement(statement) {
|
|
@@ -2523,6 +2703,7 @@ class JavascriptParser extends Parser {
|
|
|
2523
2703
|
}
|
|
2524
2704
|
|
|
2525
2705
|
/**
|
|
2706
|
+
* Pre walk for statement.
|
|
2526
2707
|
* @param {ForStatement} statement for statement
|
|
2527
2708
|
*/
|
|
2528
2709
|
preWalkForStatement(statement) {
|
|
@@ -2533,6 +2714,7 @@ class JavascriptParser extends Parser {
|
|
|
2533
2714
|
}
|
|
2534
2715
|
|
|
2535
2716
|
/**
|
|
2717
|
+
* Walk for statement.
|
|
2536
2718
|
* @param {ForStatement} statement for statement
|
|
2537
2719
|
*/
|
|
2538
2720
|
walkForStatement(statement) {
|
|
@@ -2568,6 +2750,7 @@ class JavascriptParser extends Parser {
|
|
|
2568
2750
|
}
|
|
2569
2751
|
|
|
2570
2752
|
/**
|
|
2753
|
+
* Pre walk for in statement.
|
|
2571
2754
|
* @param {ForInStatement} statement for statement
|
|
2572
2755
|
*/
|
|
2573
2756
|
preWalkForInStatement(statement) {
|
|
@@ -2578,6 +2761,7 @@ class JavascriptParser extends Parser {
|
|
|
2578
2761
|
}
|
|
2579
2762
|
|
|
2580
2763
|
/**
|
|
2764
|
+
* Walk for in statement.
|
|
2581
2765
|
* @param {ForInStatement} statement for statement
|
|
2582
2766
|
*/
|
|
2583
2767
|
walkForInStatement(statement) {
|
|
@@ -2606,6 +2790,7 @@ class JavascriptParser extends Parser {
|
|
|
2606
2790
|
}
|
|
2607
2791
|
|
|
2608
2792
|
/**
|
|
2793
|
+
* Pre walk for of statement.
|
|
2609
2794
|
* @param {ForOfStatement} statement statement
|
|
2610
2795
|
*/
|
|
2611
2796
|
preWalkForOfStatement(statement) {
|
|
@@ -2619,6 +2804,7 @@ class JavascriptParser extends Parser {
|
|
|
2619
2804
|
}
|
|
2620
2805
|
|
|
2621
2806
|
/**
|
|
2807
|
+
* Walk for of statement.
|
|
2622
2808
|
* @param {ForOfStatement} statement for statement
|
|
2623
2809
|
*/
|
|
2624
2810
|
walkForOfStatement(statement) {
|
|
@@ -2647,6 +2833,7 @@ class JavascriptParser extends Parser {
|
|
|
2647
2833
|
}
|
|
2648
2834
|
|
|
2649
2835
|
/**
|
|
2836
|
+
* Pre walk function declaration.
|
|
2650
2837
|
* @param {FunctionDeclaration | MaybeNamedFunctionDeclaration} statement function declaration
|
|
2651
2838
|
*/
|
|
2652
2839
|
preWalkFunctionDeclaration(statement) {
|
|
@@ -2656,11 +2843,15 @@ class JavascriptParser extends Parser {
|
|
|
2656
2843
|
}
|
|
2657
2844
|
|
|
2658
2845
|
/**
|
|
2846
|
+
* Walk function declaration.
|
|
2659
2847
|
* @param {FunctionDeclaration | MaybeNamedFunctionDeclaration} statement function declaration
|
|
2660
2848
|
*/
|
|
2661
2849
|
walkFunctionDeclaration(statement) {
|
|
2662
2850
|
const wasTopLevel = this.scope.topLevelScope;
|
|
2663
2851
|
this.scope.topLevelScope = false;
|
|
2852
|
+
if (this._strictInModuleOutput) {
|
|
2853
|
+
this._checkStrictModeParams(statement.params);
|
|
2854
|
+
}
|
|
2664
2855
|
this.inFunctionScope(true, statement.params, () => {
|
|
2665
2856
|
for (const param of statement.params) {
|
|
2666
2857
|
this.walkPattern(param);
|
|
@@ -2678,6 +2869,7 @@ class JavascriptParser extends Parser {
|
|
|
2678
2869
|
}
|
|
2679
2870
|
|
|
2680
2871
|
/**
|
|
2872
|
+
* Block pre walk expression statement.
|
|
2681
2873
|
* @param {ExpressionStatement} statement expression statement
|
|
2682
2874
|
*/
|
|
2683
2875
|
blockPreWalkExpressionStatement(statement) {
|
|
@@ -2689,6 +2881,7 @@ class JavascriptParser extends Parser {
|
|
|
2689
2881
|
}
|
|
2690
2882
|
|
|
2691
2883
|
/**
|
|
2884
|
+
* Pre walk assignment expression.
|
|
2692
2885
|
* @param {AssignmentExpression} expression assignment expression
|
|
2693
2886
|
*/
|
|
2694
2887
|
preWalkAssignmentExpression(expression) {
|
|
@@ -2696,6 +2889,7 @@ class JavascriptParser extends Parser {
|
|
|
2696
2889
|
}
|
|
2697
2890
|
|
|
2698
2891
|
/**
|
|
2892
|
+
* Enter destructuring assignment.
|
|
2699
2893
|
* @param {Pattern} pattern pattern
|
|
2700
2894
|
* @param {Expression} expression assignment expression
|
|
2701
2895
|
* @returns {Expression | undefined} destructuring expression
|
|
@@ -2737,6 +2931,7 @@ class JavascriptParser extends Parser {
|
|
|
2737
2931
|
}
|
|
2738
2932
|
|
|
2739
2933
|
/**
|
|
2934
|
+
* Module pre walk import declaration.
|
|
2740
2935
|
* @param {ImportDeclaration} statement statement
|
|
2741
2936
|
*/
|
|
2742
2937
|
modulePreWalkImportDeclaration(statement) {
|
|
@@ -2782,6 +2977,7 @@ class JavascriptParser extends Parser {
|
|
|
2782
2977
|
}
|
|
2783
2978
|
|
|
2784
2979
|
/**
|
|
2980
|
+
* Processes the provided declaration.
|
|
2785
2981
|
* @param {Declaration} declaration declaration
|
|
2786
2982
|
* @param {OnIdent} onIdent on ident callback
|
|
2787
2983
|
*/
|
|
@@ -2807,6 +3003,7 @@ class JavascriptParser extends Parser {
|
|
|
2807
3003
|
}
|
|
2808
3004
|
|
|
2809
3005
|
/**
|
|
3006
|
+
* Module pre walk export named declaration.
|
|
2810
3007
|
* @param {ExportNamedDeclaration} statement statement
|
|
2811
3008
|
*/
|
|
2812
3009
|
modulePreWalkExportNamedDeclaration(statement) {
|
|
@@ -2847,6 +3044,7 @@ class JavascriptParser extends Parser {
|
|
|
2847
3044
|
}
|
|
2848
3045
|
|
|
2849
3046
|
/**
|
|
3047
|
+
* Block pre walk export named declaration.
|
|
2850
3048
|
* @param {ExportNamedDeclaration} statement statement
|
|
2851
3049
|
*/
|
|
2852
3050
|
blockPreWalkExportNamedDeclaration(statement) {
|
|
@@ -2898,6 +3096,7 @@ class JavascriptParser extends Parser {
|
|
|
2898
3096
|
}
|
|
2899
3097
|
|
|
2900
3098
|
/**
|
|
3099
|
+
* Walk export named declaration.
|
|
2901
3100
|
* @param {ExportNamedDeclaration} statement the statement
|
|
2902
3101
|
*/
|
|
2903
3102
|
walkExportNamedDeclaration(statement) {
|
|
@@ -2907,6 +3106,7 @@ class JavascriptParser extends Parser {
|
|
|
2907
3106
|
}
|
|
2908
3107
|
|
|
2909
3108
|
/**
|
|
3109
|
+
* Block pre walk export default declaration.
|
|
2910
3110
|
* @param {ExportDefaultDeclaration} statement statement
|
|
2911
3111
|
*/
|
|
2912
3112
|
blockPreWalkExportDefaultDeclaration(statement) {
|
|
@@ -2942,6 +3142,7 @@ class JavascriptParser extends Parser {
|
|
|
2942
3142
|
}
|
|
2943
3143
|
|
|
2944
3144
|
/**
|
|
3145
|
+
* Walk export default declaration.
|
|
2945
3146
|
* @param {ExportDefaultDeclaration} statement statement
|
|
2946
3147
|
*/
|
|
2947
3148
|
walkExportDefaultDeclaration(statement) {
|
|
@@ -2976,6 +3177,7 @@ class JavascriptParser extends Parser {
|
|
|
2976
3177
|
}
|
|
2977
3178
|
|
|
2978
3179
|
/**
|
|
3180
|
+
* Module pre walk export all declaration.
|
|
2979
3181
|
* @param {ExportAllDeclaration} statement statement
|
|
2980
3182
|
*/
|
|
2981
3183
|
modulePreWalkExportAllDeclaration(statement) {
|
|
@@ -2991,6 +3193,7 @@ class JavascriptParser extends Parser {
|
|
|
2991
3193
|
}
|
|
2992
3194
|
|
|
2993
3195
|
/**
|
|
3196
|
+
* Pre walk variable declaration.
|
|
2994
3197
|
* @param {VariableDeclaration} statement variable declaration
|
|
2995
3198
|
*/
|
|
2996
3199
|
preWalkVariableDeclaration(statement) {
|
|
@@ -2999,6 +3202,7 @@ class JavascriptParser extends Parser {
|
|
|
2999
3202
|
}
|
|
3000
3203
|
|
|
3001
3204
|
/**
|
|
3205
|
+
* Block pre walk variable declaration.
|
|
3002
3206
|
* @param {VariableDeclaration} statement variable declaration
|
|
3003
3207
|
*/
|
|
3004
3208
|
blockPreWalkVariableDeclaration(statement) {
|
|
@@ -3014,32 +3218,53 @@ class JavascriptParser extends Parser {
|
|
|
3014
3218
|
}
|
|
3015
3219
|
|
|
3016
3220
|
/**
|
|
3221
|
+
* Pre walk variable declaration.
|
|
3017
3222
|
* @param {VariableDeclaration} statement variable declaration
|
|
3018
3223
|
* @param {HookMap<SyncBailHook<[Identifier], boolean | void>>} hookMap map of hooks
|
|
3019
3224
|
*/
|
|
3020
3225
|
_preWalkVariableDeclaration(statement, hookMap) {
|
|
3226
|
+
/** @type {OnIdent | undefined} */
|
|
3227
|
+
let onIdent;
|
|
3021
3228
|
for (const declarator of statement.declarations) {
|
|
3022
|
-
|
|
3023
|
-
|
|
3024
|
-
|
|
3025
|
-
|
|
3026
|
-
|
|
3027
|
-
|
|
3028
|
-
|
|
3029
|
-
|
|
3030
|
-
|
|
3031
|
-
|
|
3032
|
-
|
|
3033
|
-
|
|
3034
|
-
|
|
3035
|
-
|
|
3036
|
-
break;
|
|
3229
|
+
if (declarator.type !== "VariableDeclarator") continue;
|
|
3230
|
+
this.preWalkVariableDeclarator(declarator);
|
|
3231
|
+
if (this.hooks.preDeclarator.call(declarator, statement)) continue;
|
|
3232
|
+
const id = declarator.id;
|
|
3233
|
+
if (id.type === "Identifier") {
|
|
3234
|
+
// fast path: plain `const x =` skips the enterPattern dispatch and
|
|
3235
|
+
// the per-declaration onIdent closure (only patterns need it)
|
|
3236
|
+
if (!this.callHooksForName(this.hooks.pattern, id.name, id)) {
|
|
3237
|
+
this._defineVariableForDeclaration(id.name, id, hookMap);
|
|
3238
|
+
}
|
|
3239
|
+
} else {
|
|
3240
|
+
if (onIdent === undefined) {
|
|
3241
|
+
onIdent = (name, ident) =>
|
|
3242
|
+
this._defineVariableForDeclaration(name, ident, hookMap);
|
|
3037
3243
|
}
|
|
3244
|
+
this.enterPattern(id, onIdent);
|
|
3038
3245
|
}
|
|
3039
3246
|
}
|
|
3040
3247
|
}
|
|
3041
3248
|
|
|
3042
3249
|
/**
|
|
3250
|
+
* Defines a declared variable unless a declaration hook handles it.
|
|
3251
|
+
* @param {string} name variable name
|
|
3252
|
+
* @param {Identifier} ident identifier node
|
|
3253
|
+
* @param {HookMap<SyncBailHook<[Identifier], boolean | void>>} hookMap kind-specific declaration hooks
|
|
3254
|
+
* @returns {void}
|
|
3255
|
+
*/
|
|
3256
|
+
_defineVariableForDeclaration(name, ident, hookMap) {
|
|
3257
|
+
let hook = hookMap.get(name);
|
|
3258
|
+
if (hook === undefined || !hook.call(ident)) {
|
|
3259
|
+
hook = this.hooks.varDeclaration.get(name);
|
|
3260
|
+
if (hook === undefined || !hook.call(ident)) {
|
|
3261
|
+
this.defineVariable(name);
|
|
3262
|
+
}
|
|
3263
|
+
}
|
|
3264
|
+
}
|
|
3265
|
+
|
|
3266
|
+
/**
|
|
3267
|
+
* Pre walk object pattern.
|
|
3043
3268
|
* @param {ObjectPattern} objectPattern object pattern
|
|
3044
3269
|
* @returns {DestructuringAssignmentProperties | undefined} set of names or undefined if not all keys are identifiers
|
|
3045
3270
|
*/
|
|
@@ -3071,7 +3296,6 @@ class JavascriptParser extends Parser {
|
|
|
3071
3296
|
props.add({
|
|
3072
3297
|
id: key.name,
|
|
3073
3298
|
range: /** @type {Range} */ (key.range),
|
|
3074
|
-
loc: /** @type {SourceLocation} */ (key.loc),
|
|
3075
3299
|
pattern,
|
|
3076
3300
|
shorthand: this.scope.inShorthand
|
|
3077
3301
|
});
|
|
@@ -3088,7 +3312,6 @@ class JavascriptParser extends Parser {
|
|
|
3088
3312
|
props.add({
|
|
3089
3313
|
id: str,
|
|
3090
3314
|
range: /** @type {Range} */ (key.range),
|
|
3091
|
-
loc: /** @type {SourceLocation} */ (key.loc),
|
|
3092
3315
|
pattern,
|
|
3093
3316
|
shorthand: this.scope.inShorthand
|
|
3094
3317
|
});
|
|
@@ -3104,6 +3327,7 @@ class JavascriptParser extends Parser {
|
|
|
3104
3327
|
}
|
|
3105
3328
|
|
|
3106
3329
|
/**
|
|
3330
|
+
* Pre walk array pattern.
|
|
3107
3331
|
* @param {ArrayPattern} arrayPattern array pattern
|
|
3108
3332
|
* @returns {Set<DestructuringAssignmentProperty> | undefined} set of names or undefined if not all keys are identifiers
|
|
3109
3333
|
*/
|
|
@@ -3124,7 +3348,6 @@ class JavascriptParser extends Parser {
|
|
|
3124
3348
|
props.add({
|
|
3125
3349
|
id: `${i}`,
|
|
3126
3350
|
range: /** @type {Range} */ (element.range),
|
|
3127
|
-
loc: /** @type {SourceLocation} */ (element.loc),
|
|
3128
3351
|
pattern,
|
|
3129
3352
|
shorthand: false
|
|
3130
3353
|
});
|
|
@@ -3134,6 +3357,7 @@ class JavascriptParser extends Parser {
|
|
|
3134
3357
|
}
|
|
3135
3358
|
|
|
3136
3359
|
/**
|
|
3360
|
+
* Pre walk variable declarator.
|
|
3137
3361
|
* @param {VariableDeclarator} declarator variable declarator
|
|
3138
3362
|
*/
|
|
3139
3363
|
preWalkVariableDeclarator(declarator) {
|
|
@@ -3143,6 +3367,7 @@ class JavascriptParser extends Parser {
|
|
|
3143
3367
|
}
|
|
3144
3368
|
|
|
3145
3369
|
/**
|
|
3370
|
+
* Walk variable declaration.
|
|
3146
3371
|
* @param {VariableDeclaration} statement variable declaration
|
|
3147
3372
|
*/
|
|
3148
3373
|
walkVariableDeclaration(statement) {
|
|
@@ -3179,6 +3404,7 @@ class JavascriptParser extends Parser {
|
|
|
3179
3404
|
}
|
|
3180
3405
|
|
|
3181
3406
|
/**
|
|
3407
|
+
* Block pre walk class declaration.
|
|
3182
3408
|
* @param {ClassDeclaration | MaybeNamedClassDeclaration} statement class declaration
|
|
3183
3409
|
*/
|
|
3184
3410
|
blockPreWalkClassDeclaration(statement) {
|
|
@@ -3188,6 +3414,7 @@ class JavascriptParser extends Parser {
|
|
|
3188
3414
|
}
|
|
3189
3415
|
|
|
3190
3416
|
/**
|
|
3417
|
+
* Walk class declaration.
|
|
3191
3418
|
* @param {ClassDeclaration | MaybeNamedClassDeclaration} statement class declaration
|
|
3192
3419
|
*/
|
|
3193
3420
|
walkClassDeclaration(statement) {
|
|
@@ -3195,6 +3422,7 @@ class JavascriptParser extends Parser {
|
|
|
3195
3422
|
}
|
|
3196
3423
|
|
|
3197
3424
|
/**
|
|
3425
|
+
* Pre walk switch cases.
|
|
3198
3426
|
* @param {SwitchCase[]} switchCases switch statement
|
|
3199
3427
|
*/
|
|
3200
3428
|
preWalkSwitchCases(switchCases) {
|
|
@@ -3205,6 +3433,7 @@ class JavascriptParser extends Parser {
|
|
|
3205
3433
|
}
|
|
3206
3434
|
|
|
3207
3435
|
/**
|
|
3436
|
+
* Processes the provided switch case.
|
|
3208
3437
|
* @param {SwitchCase[]} switchCases switch statement
|
|
3209
3438
|
*/
|
|
3210
3439
|
walkSwitchCases(switchCases) {
|
|
@@ -3245,6 +3474,7 @@ class JavascriptParser extends Parser {
|
|
|
3245
3474
|
}
|
|
3246
3475
|
|
|
3247
3476
|
/**
|
|
3477
|
+
* Pre walk catch clause.
|
|
3248
3478
|
* @param {CatchClause} catchClause catch clause
|
|
3249
3479
|
*/
|
|
3250
3480
|
preWalkCatchClause(catchClause) {
|
|
@@ -3252,6 +3482,7 @@ class JavascriptParser extends Parser {
|
|
|
3252
3482
|
}
|
|
3253
3483
|
|
|
3254
3484
|
/**
|
|
3485
|
+
* Processes the provided catch clause.
|
|
3255
3486
|
* @param {CatchClause} catchClause catch clause
|
|
3256
3487
|
*/
|
|
3257
3488
|
walkCatchClause(catchClause) {
|
|
@@ -3271,10 +3502,17 @@ class JavascriptParser extends Parser {
|
|
|
3271
3502
|
}
|
|
3272
3503
|
|
|
3273
3504
|
/**
|
|
3505
|
+
* Processes the provided pattern.
|
|
3274
3506
|
* @param {Pattern} pattern pattern
|
|
3275
3507
|
*/
|
|
3276
3508
|
walkPattern(pattern) {
|
|
3277
3509
|
switch (pattern.type) {
|
|
3510
|
+
// plain identifier bindings are the common case and walk nothing
|
|
3511
|
+
case "Identifier":
|
|
3512
|
+
break;
|
|
3513
|
+
case "ObjectPattern":
|
|
3514
|
+
this.walkObjectPattern(pattern);
|
|
3515
|
+
break;
|
|
3278
3516
|
case "ArrayPattern":
|
|
3279
3517
|
this.walkArrayPattern(pattern);
|
|
3280
3518
|
break;
|
|
@@ -3284,9 +3522,6 @@ class JavascriptParser extends Parser {
|
|
|
3284
3522
|
case "MemberExpression":
|
|
3285
3523
|
this.walkMemberExpression(pattern);
|
|
3286
3524
|
break;
|
|
3287
|
-
case "ObjectPattern":
|
|
3288
|
-
this.walkObjectPattern(pattern);
|
|
3289
|
-
break;
|
|
3290
3525
|
case "RestElement":
|
|
3291
3526
|
this.walkRestElement(pattern);
|
|
3292
3527
|
break;
|
|
@@ -3294,6 +3529,7 @@ class JavascriptParser extends Parser {
|
|
|
3294
3529
|
}
|
|
3295
3530
|
|
|
3296
3531
|
/**
|
|
3532
|
+
* Walk assignment pattern.
|
|
3297
3533
|
* @param {AssignmentPattern} pattern assignment pattern
|
|
3298
3534
|
*/
|
|
3299
3535
|
walkAssignmentPattern(pattern) {
|
|
@@ -3302,6 +3538,7 @@ class JavascriptParser extends Parser {
|
|
|
3302
3538
|
}
|
|
3303
3539
|
|
|
3304
3540
|
/**
|
|
3541
|
+
* Walk object pattern.
|
|
3305
3542
|
* @param {ObjectPattern} pattern pattern
|
|
3306
3543
|
*/
|
|
3307
3544
|
walkObjectPattern(pattern) {
|
|
@@ -3318,6 +3555,7 @@ class JavascriptParser extends Parser {
|
|
|
3318
3555
|
}
|
|
3319
3556
|
|
|
3320
3557
|
/**
|
|
3558
|
+
* Walk array pattern.
|
|
3321
3559
|
* @param {ArrayPattern} pattern array pattern
|
|
3322
3560
|
*/
|
|
3323
3561
|
walkArrayPattern(pattern) {
|
|
@@ -3328,6 +3566,7 @@ class JavascriptParser extends Parser {
|
|
|
3328
3566
|
}
|
|
3329
3567
|
|
|
3330
3568
|
/**
|
|
3569
|
+
* Processes the provided pattern.
|
|
3331
3570
|
* @param {RestElement} pattern rest element
|
|
3332
3571
|
*/
|
|
3333
3572
|
walkRestElement(pattern) {
|
|
@@ -3335,10 +3574,12 @@ class JavascriptParser extends Parser {
|
|
|
3335
3574
|
}
|
|
3336
3575
|
|
|
3337
3576
|
/**
|
|
3577
|
+
* Processes the provided expression.
|
|
3338
3578
|
* @param {(Expression | SpreadElement | null)[]} expressions expressions
|
|
3339
3579
|
*/
|
|
3340
3580
|
walkExpressions(expressions) {
|
|
3341
|
-
for (
|
|
3581
|
+
for (let i = 0, len = expressions.length; i < len; i++) {
|
|
3582
|
+
const expression = expressions[i];
|
|
3342
3583
|
if (expression) {
|
|
3343
3584
|
this.walkExpression(expression);
|
|
3344
3585
|
}
|
|
@@ -3346,81 +3587,90 @@ class JavascriptParser extends Parser {
|
|
|
3346
3587
|
}
|
|
3347
3588
|
|
|
3348
3589
|
/**
|
|
3590
|
+
* Processes the provided expression.
|
|
3349
3591
|
* @param {Expression | SpreadElement | PrivateIdentifier | Super} expression expression
|
|
3350
3592
|
*/
|
|
3351
3593
|
walkExpression(expression) {
|
|
3594
|
+
// cases ordered by measured node frequency (identifiers are ~40% of all
|
|
3595
|
+
// expressions) — V8 compiles this to sequential compares, so hot types
|
|
3596
|
+
// must come first
|
|
3352
3597
|
switch (expression.type) {
|
|
3353
|
-
case "
|
|
3354
|
-
this.
|
|
3598
|
+
case "Identifier":
|
|
3599
|
+
this.walkIdentifier(expression);
|
|
3355
3600
|
break;
|
|
3356
|
-
case "
|
|
3357
|
-
this.
|
|
3601
|
+
case "MemberExpression":
|
|
3602
|
+
this.walkMemberExpression(expression);
|
|
3358
3603
|
break;
|
|
3359
|
-
case "
|
|
3360
|
-
this.
|
|
3604
|
+
case "Literal":
|
|
3605
|
+
if (this._strictInModuleOutput) {
|
|
3606
|
+
this._checkStrictModeLiteral(expression);
|
|
3607
|
+
}
|
|
3361
3608
|
break;
|
|
3362
|
-
case "
|
|
3363
|
-
this.
|
|
3609
|
+
case "CallExpression":
|
|
3610
|
+
this.walkCallExpression(expression);
|
|
3364
3611
|
break;
|
|
3365
3612
|
case "BinaryExpression":
|
|
3366
3613
|
this.walkBinaryExpression(expression);
|
|
3367
3614
|
break;
|
|
3368
|
-
case "
|
|
3369
|
-
this.
|
|
3370
|
-
break;
|
|
3371
|
-
case "ChainExpression":
|
|
3372
|
-
this.walkChainExpression(expression);
|
|
3615
|
+
case "AssignmentExpression":
|
|
3616
|
+
this.walkAssignmentExpression(expression);
|
|
3373
3617
|
break;
|
|
3374
|
-
case "
|
|
3375
|
-
this.
|
|
3618
|
+
case "UnaryExpression":
|
|
3619
|
+
this.walkUnaryExpression(expression);
|
|
3376
3620
|
break;
|
|
3377
|
-
case "
|
|
3378
|
-
this.
|
|
3621
|
+
case "LogicalExpression":
|
|
3622
|
+
this.walkLogicalExpression(expression);
|
|
3379
3623
|
break;
|
|
3380
|
-
case "
|
|
3381
|
-
this.
|
|
3624
|
+
case "ArrowFunctionExpression":
|
|
3625
|
+
this.walkArrowFunctionExpression(expression);
|
|
3382
3626
|
break;
|
|
3383
|
-
case "
|
|
3384
|
-
this.
|
|
3627
|
+
case "ThisExpression":
|
|
3628
|
+
this.walkThisExpression(expression);
|
|
3385
3629
|
break;
|
|
3386
|
-
case "
|
|
3387
|
-
this.
|
|
3630
|
+
case "ConditionalExpression":
|
|
3631
|
+
this.walkConditionalExpression(expression);
|
|
3388
3632
|
break;
|
|
3389
|
-
case "
|
|
3390
|
-
this.
|
|
3633
|
+
case "ArrayExpression":
|
|
3634
|
+
this.walkArrayExpression(expression);
|
|
3391
3635
|
break;
|
|
3392
|
-
case "
|
|
3393
|
-
this.
|
|
3636
|
+
case "ObjectExpression":
|
|
3637
|
+
this.walkObjectExpression(expression);
|
|
3394
3638
|
break;
|
|
3395
|
-
case "
|
|
3396
|
-
this.
|
|
3639
|
+
case "FunctionExpression":
|
|
3640
|
+
this.walkFunctionExpression(expression);
|
|
3397
3641
|
break;
|
|
3398
3642
|
case "NewExpression":
|
|
3399
3643
|
this.walkNewExpression(expression);
|
|
3400
3644
|
break;
|
|
3401
|
-
case "
|
|
3402
|
-
this.
|
|
3645
|
+
case "TemplateLiteral":
|
|
3646
|
+
this.walkTemplateLiteral(expression);
|
|
3647
|
+
break;
|
|
3648
|
+
case "SpreadElement":
|
|
3649
|
+
this.walkSpreadElement(expression);
|
|
3403
3650
|
break;
|
|
3404
3651
|
case "SequenceExpression":
|
|
3405
3652
|
this.walkSequenceExpression(expression);
|
|
3406
3653
|
break;
|
|
3407
|
-
case "
|
|
3408
|
-
this.
|
|
3654
|
+
case "UpdateExpression":
|
|
3655
|
+
this.walkUpdateExpression(expression);
|
|
3409
3656
|
break;
|
|
3410
|
-
case "
|
|
3411
|
-
this.
|
|
3657
|
+
case "AwaitExpression":
|
|
3658
|
+
this.walkAwaitExpression(expression);
|
|
3412
3659
|
break;
|
|
3413
|
-
case "
|
|
3414
|
-
this.
|
|
3660
|
+
case "ChainExpression":
|
|
3661
|
+
this.walkChainExpression(expression);
|
|
3415
3662
|
break;
|
|
3416
|
-
case "
|
|
3417
|
-
this.
|
|
3663
|
+
case "ClassExpression":
|
|
3664
|
+
this.walkClassExpression(expression);
|
|
3418
3665
|
break;
|
|
3419
|
-
case "
|
|
3420
|
-
this.
|
|
3666
|
+
case "ImportExpression":
|
|
3667
|
+
this.walkImportExpression(expression);
|
|
3421
3668
|
break;
|
|
3422
|
-
case "
|
|
3423
|
-
this.
|
|
3669
|
+
case "MetaProperty":
|
|
3670
|
+
this.walkMetaProperty(expression);
|
|
3671
|
+
break;
|
|
3672
|
+
case "TaggedTemplateExpression":
|
|
3673
|
+
this.walkTaggedTemplateExpression(expression);
|
|
3424
3674
|
break;
|
|
3425
3675
|
case "YieldExpression":
|
|
3426
3676
|
this.walkYieldExpression(expression);
|
|
@@ -3429,6 +3679,36 @@ class JavascriptParser extends Parser {
|
|
|
3429
3679
|
}
|
|
3430
3680
|
|
|
3431
3681
|
/**
|
|
3682
|
+
* Reports octal number literals (`0777`) and octal string escapes (`"\47"`),
|
|
3683
|
+
* both SyntaxErrors in strict-mode ESM output.
|
|
3684
|
+
* @param {Literal} expression literal
|
|
3685
|
+
*/
|
|
3686
|
+
_checkStrictModeLiteral(expression) {
|
|
3687
|
+
const raw = /** @type {string | undefined} */ (expression.raw);
|
|
3688
|
+
if (raw === undefined) return;
|
|
3689
|
+
if (typeof expression.value === "number") {
|
|
3690
|
+
// Legacy octal (`0777`) or non-octal decimal (`08`) integer literal.
|
|
3691
|
+
if (
|
|
3692
|
+
raw.length > 1 &&
|
|
3693
|
+
raw.charCodeAt(0) === 48 &&
|
|
3694
|
+
raw.charCodeAt(1) >= 48 &&
|
|
3695
|
+
raw.charCodeAt(1) <= 57
|
|
3696
|
+
) {
|
|
3697
|
+
this._reportStrictModeViolation(
|
|
3698
|
+
"Octal literals are not allowed",
|
|
3699
|
+
expression
|
|
3700
|
+
);
|
|
3701
|
+
}
|
|
3702
|
+
} else if (typeof expression.value === "string" && hasOctalEscape(raw)) {
|
|
3703
|
+
this._reportStrictModeViolation(
|
|
3704
|
+
"Octal escape sequences are not allowed",
|
|
3705
|
+
expression
|
|
3706
|
+
);
|
|
3707
|
+
}
|
|
3708
|
+
}
|
|
3709
|
+
|
|
3710
|
+
/**
|
|
3711
|
+
* Walk await expression.
|
|
3432
3712
|
* @param {AwaitExpression} expression await expression
|
|
3433
3713
|
*/
|
|
3434
3714
|
walkAwaitExpression(expression) {
|
|
@@ -3439,6 +3719,7 @@ class JavascriptParser extends Parser {
|
|
|
3439
3719
|
}
|
|
3440
3720
|
|
|
3441
3721
|
/**
|
|
3722
|
+
* Walk array expression.
|
|
3442
3723
|
* @param {ArrayExpression} expression array expression
|
|
3443
3724
|
*/
|
|
3444
3725
|
walkArrayExpression(expression) {
|
|
@@ -3448,6 +3729,7 @@ class JavascriptParser extends Parser {
|
|
|
3448
3729
|
}
|
|
3449
3730
|
|
|
3450
3731
|
/**
|
|
3732
|
+
* Walk spread element.
|
|
3451
3733
|
* @param {SpreadElement} expression spread element
|
|
3452
3734
|
*/
|
|
3453
3735
|
walkSpreadElement(expression) {
|
|
@@ -3457,6 +3739,7 @@ class JavascriptParser extends Parser {
|
|
|
3457
3739
|
}
|
|
3458
3740
|
|
|
3459
3741
|
/**
|
|
3742
|
+
* Walk object expression.
|
|
3460
3743
|
* @param {ObjectExpression} expression object expression
|
|
3461
3744
|
*/
|
|
3462
3745
|
walkObjectExpression(expression) {
|
|
@@ -3471,6 +3754,7 @@ class JavascriptParser extends Parser {
|
|
|
3471
3754
|
}
|
|
3472
3755
|
|
|
3473
3756
|
/**
|
|
3757
|
+
* Processes the provided prop.
|
|
3474
3758
|
* @param {Property | SpreadElement} prop property or spread element
|
|
3475
3759
|
*/
|
|
3476
3760
|
walkProperty(prop) {
|
|
@@ -3494,18 +3778,21 @@ class JavascriptParser extends Parser {
|
|
|
3494
3778
|
}
|
|
3495
3779
|
|
|
3496
3780
|
/**
|
|
3781
|
+
* Walk function expression.
|
|
3497
3782
|
* @param {FunctionExpression} expression arrow function expression
|
|
3498
3783
|
*/
|
|
3499
3784
|
walkFunctionExpression(expression) {
|
|
3500
3785
|
const wasTopLevel = this.scope.topLevelScope;
|
|
3501
3786
|
this.scope.topLevelScope = false;
|
|
3502
|
-
|
|
3503
|
-
|
|
3504
|
-
|
|
3505
|
-
|
|
3506
|
-
|
|
3787
|
+
// Only copy params when the function name must be added (recursive calls);
|
|
3788
|
+
// inFunctionScope reads params without mutating, like arrow functions.
|
|
3789
|
+
const scopeParams = expression.id
|
|
3790
|
+
? [...expression.params, expression.id]
|
|
3791
|
+
: expression.params;
|
|
3792
|
+
|
|
3793
|
+
if (this._strictInModuleOutput) {
|
|
3794
|
+
this._checkStrictModeParams(expression.params);
|
|
3507
3795
|
}
|
|
3508
|
-
|
|
3509
3796
|
this.inFunctionScope(true, scopeParams, () => {
|
|
3510
3797
|
for (const param of expression.params) {
|
|
3511
3798
|
this.walkPattern(param);
|
|
@@ -3523,11 +3810,15 @@ class JavascriptParser extends Parser {
|
|
|
3523
3810
|
}
|
|
3524
3811
|
|
|
3525
3812
|
/**
|
|
3813
|
+
* Walk arrow function expression.
|
|
3526
3814
|
* @param {ArrowFunctionExpression} expression arrow function expression
|
|
3527
3815
|
*/
|
|
3528
3816
|
walkArrowFunctionExpression(expression) {
|
|
3529
3817
|
const wasTopLevel = this.scope.topLevelScope;
|
|
3530
3818
|
this.scope.topLevelScope = wasTopLevel ? "arrow" : false;
|
|
3819
|
+
if (this._strictInModuleOutput) {
|
|
3820
|
+
this._checkStrictModeParams(expression.params);
|
|
3821
|
+
}
|
|
3531
3822
|
this.inFunctionScope(false, expression.params, () => {
|
|
3532
3823
|
for (const param of expression.params) {
|
|
3533
3824
|
this.walkPattern(param);
|
|
@@ -3546,6 +3837,7 @@ class JavascriptParser extends Parser {
|
|
|
3546
3837
|
}
|
|
3547
3838
|
|
|
3548
3839
|
/**
|
|
3840
|
+
* Walk sequence expression.
|
|
3549
3841
|
* @param {SequenceExpression} expression the sequence
|
|
3550
3842
|
*/
|
|
3551
3843
|
walkSequenceExpression(expression) {
|
|
@@ -3584,13 +3876,90 @@ class JavascriptParser extends Parser {
|
|
|
3584
3876
|
}
|
|
3585
3877
|
|
|
3586
3878
|
/**
|
|
3879
|
+
* Walk update expression.
|
|
3587
3880
|
* @param {UpdateExpression} expression the update expression
|
|
3588
3881
|
*/
|
|
3589
3882
|
walkUpdateExpression(expression) {
|
|
3883
|
+
if (
|
|
3884
|
+
this._strictInModuleOutput &&
|
|
3885
|
+
expression.argument.type === "Identifier"
|
|
3886
|
+
) {
|
|
3887
|
+
this._checkStrictModeAssignTarget(expression.argument.name, expression);
|
|
3888
|
+
}
|
|
3590
3889
|
this.walkExpression(expression.argument);
|
|
3591
3890
|
}
|
|
3592
3891
|
|
|
3593
3892
|
/**
|
|
3893
|
+
* Reports `arguments.callee` / `arguments.caller` — both throw a TypeError
|
|
3894
|
+
* once the module runs in strict-mode ESM output.
|
|
3895
|
+
* @param {string} name accessed member name
|
|
3896
|
+
* @param {Expression} node node to report the violation at
|
|
3897
|
+
*/
|
|
3898
|
+
_checkStrictModeArgumentsMember(name, node) {
|
|
3899
|
+
if ((name === "callee" || name === "caller") && !this.scope.isStrict) {
|
|
3900
|
+
this._reportStrictModeViolation(
|
|
3901
|
+
`Accessing "arguments.${name}" is not allowed`,
|
|
3902
|
+
node
|
|
3903
|
+
);
|
|
3904
|
+
}
|
|
3905
|
+
}
|
|
3906
|
+
|
|
3907
|
+
/**
|
|
3908
|
+
* Reports an assignment or update target that breaks in strict-mode ESM
|
|
3909
|
+
* output: `eval` / `arguments` are a SyntaxError, the read-only globals
|
|
3910
|
+
* (`undefined`, `NaN`, `Infinity`) a TypeError instead of a silent no-op.
|
|
3911
|
+
* @param {string} name target identifier name
|
|
3912
|
+
* @param {AssignmentExpression | UpdateExpression} node node to report the violation at
|
|
3913
|
+
*/
|
|
3914
|
+
_checkStrictModeAssignTarget(name, node) {
|
|
3915
|
+
if (name === "eval" || name === "arguments") {
|
|
3916
|
+
this._reportStrictModeViolation(
|
|
3917
|
+
`Assigning to "${name}" is not allowed`,
|
|
3918
|
+
node
|
|
3919
|
+
);
|
|
3920
|
+
} else if (
|
|
3921
|
+
(name === "undefined" || name === "NaN" || name === "Infinity") &&
|
|
3922
|
+
!this.scope.isStrict &&
|
|
3923
|
+
!this.isVariableDefined(name)
|
|
3924
|
+
) {
|
|
3925
|
+
this._reportStrictModeViolation(
|
|
3926
|
+
`Assigning to the read-only global "${name}" is not allowed`,
|
|
3927
|
+
node
|
|
3928
|
+
);
|
|
3929
|
+
}
|
|
3930
|
+
}
|
|
3931
|
+
|
|
3932
|
+
/**
|
|
3933
|
+
* Reports strict-mode-only errors in a function's parameter list: a duplicate
|
|
3934
|
+
* simple parameter, or a parameter named `eval` / `arguments`.
|
|
3935
|
+
* @param {(import("estree").Pattern)[]} params function parameters
|
|
3936
|
+
*/
|
|
3937
|
+
_checkStrictModeParams(params) {
|
|
3938
|
+
/** @type {Set<string> | undefined} */
|
|
3939
|
+
let seen;
|
|
3940
|
+
for (const param of params) {
|
|
3941
|
+
if (param.type !== "Identifier") continue;
|
|
3942
|
+
const name = param.name;
|
|
3943
|
+
if (name === "eval" || name === "arguments") {
|
|
3944
|
+
this._reportStrictModeViolation(
|
|
3945
|
+
`"${name}" is not allowed as a parameter name`,
|
|
3946
|
+
param
|
|
3947
|
+
);
|
|
3948
|
+
}
|
|
3949
|
+
if (seen === undefined) seen = new Set();
|
|
3950
|
+
if (seen.has(name)) {
|
|
3951
|
+
this._reportStrictModeViolation(
|
|
3952
|
+
`Duplicate parameter name "${name}" is not allowed`,
|
|
3953
|
+
param
|
|
3954
|
+
);
|
|
3955
|
+
} else {
|
|
3956
|
+
seen.add(name);
|
|
3957
|
+
}
|
|
3958
|
+
}
|
|
3959
|
+
}
|
|
3960
|
+
|
|
3961
|
+
/**
|
|
3962
|
+
* Walk unary expression.
|
|
3594
3963
|
* @param {UnaryExpression} expression the unary expression
|
|
3595
3964
|
*/
|
|
3596
3965
|
walkUnaryExpression(expression) {
|
|
@@ -3609,11 +3978,41 @@ class JavascriptParser extends Parser {
|
|
|
3609
3978
|
);
|
|
3610
3979
|
if (result === true) return;
|
|
3611
3980
|
}
|
|
3981
|
+
} else if (
|
|
3982
|
+
this._strictInModuleOutput &&
|
|
3983
|
+
expression.operator === "delete" &&
|
|
3984
|
+
expression.argument.type === "Identifier"
|
|
3985
|
+
) {
|
|
3986
|
+
this._reportStrictModeViolation(
|
|
3987
|
+
`Deleting the unqualified identifier "${expression.argument.name}" is not allowed`,
|
|
3988
|
+
expression
|
|
3989
|
+
);
|
|
3612
3990
|
}
|
|
3613
3991
|
this.walkExpression(expression.argument);
|
|
3614
3992
|
}
|
|
3615
3993
|
|
|
3616
3994
|
/**
|
|
3995
|
+
* Reports a construct that a loose script allows but that breaks once the
|
|
3996
|
+
* module is emitted as strict-mode ESM output. Severity comes from the
|
|
3997
|
+
* `strictModeViolations` parser option (`false` disables the checks upfront).
|
|
3998
|
+
* The location is computed here, on the rare violation path only.
|
|
3999
|
+
* @param {string} reason what is not allowed
|
|
4000
|
+
* @param {Statement | Expression | Identifier} node node to report the violation at
|
|
4001
|
+
*/
|
|
4002
|
+
_reportStrictModeViolation(reason, node) {
|
|
4003
|
+
const diagnostic = new WebpackError(
|
|
4004
|
+
`${reason}. The output is an ES module, which runs in strict mode.`
|
|
4005
|
+
);
|
|
4006
|
+
diagnostic.loc = this.getLocation(node);
|
|
4007
|
+
if (this.options.strictModeViolations === "error") {
|
|
4008
|
+
this.state.module.addError(diagnostic);
|
|
4009
|
+
} else {
|
|
4010
|
+
this.state.module.addWarning(diagnostic);
|
|
4011
|
+
}
|
|
4012
|
+
}
|
|
4013
|
+
|
|
4014
|
+
/**
|
|
4015
|
+
* Walk left right expression.
|
|
3617
4016
|
* @param {LogicalExpression | BinaryExpression} expression the expression
|
|
3618
4017
|
*/
|
|
3619
4018
|
walkLeftRightExpression(expression) {
|
|
@@ -3622,6 +4021,7 @@ class JavascriptParser extends Parser {
|
|
|
3622
4021
|
}
|
|
3623
4022
|
|
|
3624
4023
|
/**
|
|
4024
|
+
* Walk binary expression.
|
|
3625
4025
|
* @param {BinaryExpression} expression the binary expression
|
|
3626
4026
|
*/
|
|
3627
4027
|
walkBinaryExpression(expression) {
|
|
@@ -3631,6 +4031,7 @@ class JavascriptParser extends Parser {
|
|
|
3631
4031
|
}
|
|
3632
4032
|
|
|
3633
4033
|
/**
|
|
4034
|
+
* Walk logical expression.
|
|
3634
4035
|
* @param {LogicalExpression} expression the logical expression
|
|
3635
4036
|
*/
|
|
3636
4037
|
walkLogicalExpression(expression) {
|
|
@@ -3643,10 +4044,14 @@ class JavascriptParser extends Parser {
|
|
|
3643
4044
|
}
|
|
3644
4045
|
|
|
3645
4046
|
/**
|
|
4047
|
+
* Walk assignment expression.
|
|
3646
4048
|
* @param {AssignmentExpression} expression assignment expression
|
|
3647
4049
|
*/
|
|
3648
4050
|
walkAssignmentExpression(expression) {
|
|
3649
4051
|
if (expression.left.type === "Identifier") {
|
|
4052
|
+
if (this._strictInModuleOutput) {
|
|
4053
|
+
this._checkStrictModeAssignTarget(expression.left.name, expression);
|
|
4054
|
+
}
|
|
3650
4055
|
const renameIdentifier = this.getRenameIdentifier(expression.right);
|
|
3651
4056
|
if (
|
|
3652
4057
|
renameIdentifier &&
|
|
@@ -3718,24 +4123,23 @@ class JavascriptParser extends Parser {
|
|
|
3718
4123
|
}
|
|
3719
4124
|
|
|
3720
4125
|
/**
|
|
4126
|
+
* Walk conditional expression.
|
|
3721
4127
|
* @param {ConditionalExpression} expression conditional expression
|
|
3722
4128
|
*/
|
|
3723
4129
|
walkConditionalExpression(expression) {
|
|
3724
4130
|
const result = this.hooks.expressionConditionalOperator.call(expression);
|
|
3725
4131
|
if (result === undefined) {
|
|
3726
|
-
const
|
|
3727
|
-
|
|
3728
|
-
|
|
3729
|
-
|
|
3730
|
-
|
|
3731
|
-
});
|
|
3732
|
-
} else {
|
|
3733
|
-
this.walkExpression(expression.test);
|
|
3734
|
-
this.walkExpression(expression.consequent);
|
|
3735
|
-
}
|
|
4132
|
+
const guard = this.hooks.collectGuards.call(expression.test);
|
|
4133
|
+
this.walkExpression(expression.test);
|
|
4134
|
+
this.walkGuardedBranch(guard ? guard.consequent : undefined, () =>
|
|
4135
|
+
this.walkExpression(expression.consequent)
|
|
4136
|
+
);
|
|
3736
4137
|
|
|
3737
4138
|
if (expression.alternate) {
|
|
3738
|
-
|
|
4139
|
+
const alternate = expression.alternate;
|
|
4140
|
+
this.walkGuardedBranch(guard ? guard.alternate : undefined, () =>
|
|
4141
|
+
this.walkExpression(alternate)
|
|
4142
|
+
);
|
|
3739
4143
|
}
|
|
3740
4144
|
} else if (result) {
|
|
3741
4145
|
this.walkExpression(expression.consequent);
|
|
@@ -3745,6 +4149,7 @@ class JavascriptParser extends Parser {
|
|
|
3745
4149
|
}
|
|
3746
4150
|
|
|
3747
4151
|
/**
|
|
4152
|
+
* Walk new expression.
|
|
3748
4153
|
* @param {NewExpression} expression new expression
|
|
3749
4154
|
*/
|
|
3750
4155
|
walkNewExpression(expression) {
|
|
@@ -3761,6 +4166,7 @@ class JavascriptParser extends Parser {
|
|
|
3761
4166
|
}
|
|
3762
4167
|
|
|
3763
4168
|
/**
|
|
4169
|
+
* Walk yield expression.
|
|
3764
4170
|
* @param {YieldExpression} expression yield expression
|
|
3765
4171
|
*/
|
|
3766
4172
|
walkYieldExpression(expression) {
|
|
@@ -3770,6 +4176,7 @@ class JavascriptParser extends Parser {
|
|
|
3770
4176
|
}
|
|
3771
4177
|
|
|
3772
4178
|
/**
|
|
4179
|
+
* Walk template literal.
|
|
3773
4180
|
* @param {TemplateLiteral} expression template literal
|
|
3774
4181
|
*/
|
|
3775
4182
|
walkTemplateLiteral(expression) {
|
|
@@ -3779,6 +4186,7 @@ class JavascriptParser extends Parser {
|
|
|
3779
4186
|
}
|
|
3780
4187
|
|
|
3781
4188
|
/**
|
|
4189
|
+
* Walk tagged template expression.
|
|
3782
4190
|
* @param {TaggedTemplateExpression} expression tagged template expression
|
|
3783
4191
|
*/
|
|
3784
4192
|
walkTaggedTemplateExpression(expression) {
|
|
@@ -3793,6 +4201,7 @@ class JavascriptParser extends Parser {
|
|
|
3793
4201
|
}
|
|
3794
4202
|
|
|
3795
4203
|
/**
|
|
4204
|
+
* Walk class expression.
|
|
3796
4205
|
* @param {ClassExpression} expression the class expression
|
|
3797
4206
|
*/
|
|
3798
4207
|
walkClassExpression(expression) {
|
|
@@ -3800,6 +4209,7 @@ class JavascriptParser extends Parser {
|
|
|
3800
4209
|
}
|
|
3801
4210
|
|
|
3802
4211
|
/**
|
|
4212
|
+
* Walk chain expression.
|
|
3803
4213
|
* @param {ChainExpression} expression expression
|
|
3804
4214
|
*/
|
|
3805
4215
|
walkChainExpression(expression) {
|
|
@@ -3815,6 +4225,7 @@ class JavascriptParser extends Parser {
|
|
|
3815
4225
|
}
|
|
3816
4226
|
|
|
3817
4227
|
/**
|
|
4228
|
+
* Processes the provided function expression.
|
|
3818
4229
|
* @private
|
|
3819
4230
|
* @param {FunctionExpression | ArrowFunctionExpression} functionExpression function expression
|
|
3820
4231
|
* @param {(Expression | SpreadElement)[]} options options
|
|
@@ -3822,6 +4233,7 @@ class JavascriptParser extends Parser {
|
|
|
3822
4233
|
*/
|
|
3823
4234
|
_walkIIFE(functionExpression, options, currentThis) {
|
|
3824
4235
|
/**
|
|
4236
|
+
* Returns var info.
|
|
3825
4237
|
* @param {Expression | SpreadElement} argOrThis arg or this
|
|
3826
4238
|
* @returns {string | VariableInfo | undefined} var info
|
|
3827
4239
|
*/
|
|
@@ -3890,6 +4302,7 @@ class JavascriptParser extends Parser {
|
|
|
3890
4302
|
}
|
|
3891
4303
|
|
|
3892
4304
|
/**
|
|
4305
|
+
* Walk import expression.
|
|
3893
4306
|
* @param {ImportExpression} expression import expression
|
|
3894
4307
|
*/
|
|
3895
4308
|
walkImportExpression(expression) {
|
|
@@ -3900,18 +4313,13 @@ class JavascriptParser extends Parser {
|
|
|
3900
4313
|
}
|
|
3901
4314
|
|
|
3902
4315
|
/**
|
|
4316
|
+
* Walk call expression.
|
|
3903
4317
|
* @param {CallExpression} expression expression
|
|
3904
4318
|
*/
|
|
3905
4319
|
walkCallExpression(expression) {
|
|
3906
|
-
/**
|
|
3907
|
-
* @param {FunctionExpression | ArrowFunctionExpression} fn function
|
|
3908
|
-
* @returns {boolean} true when simple function
|
|
3909
|
-
*/
|
|
3910
|
-
const isSimpleFunction = (fn) =>
|
|
3911
|
-
fn.params.every((p) => p.type === "Identifier");
|
|
3912
4320
|
if (
|
|
3913
4321
|
expression.callee.type === "MemberExpression" &&
|
|
3914
|
-
expression.callee.object.type
|
|
4322
|
+
isFunctionExpression(expression.callee.object.type) &&
|
|
3915
4323
|
!expression.callee.computed &&
|
|
3916
4324
|
/** @type {boolean} */
|
|
3917
4325
|
(
|
|
@@ -3934,7 +4342,7 @@ class JavascriptParser extends Parser {
|
|
|
3934
4342
|
expression.arguments[0]
|
|
3935
4343
|
);
|
|
3936
4344
|
} else if (
|
|
3937
|
-
expression.callee.type
|
|
4345
|
+
isFunctionExpression(expression.callee.type) &&
|
|
3938
4346
|
isSimpleFunction(
|
|
3939
4347
|
/** @type {FunctionExpression | ArrowFunctionExpression} */
|
|
3940
4348
|
(expression.callee)
|
|
@@ -3949,21 +4357,29 @@ class JavascriptParser extends Parser {
|
|
|
3949
4357
|
);
|
|
3950
4358
|
} else {
|
|
3951
4359
|
if (expression.callee.type === "MemberExpression") {
|
|
3952
|
-
|
|
3953
|
-
|
|
3954
|
-
|
|
3955
|
-
|
|
3956
|
-
|
|
3957
|
-
|
|
3958
|
-
|
|
3959
|
-
|
|
3960
|
-
expression,
|
|
3961
|
-
|
|
3962
|
-
exprInfo.call,
|
|
3963
|
-
exprInfo.getMembers(),
|
|
3964
|
-
exprInfo.getMemberRanges()
|
|
4360
|
+
// callMemberChainOfCallMemberChain only applies to call-rooted
|
|
4361
|
+
// chains (e.g. `a().b()`); for the common identifier/this-rooted
|
|
4362
|
+
// callee the CALL lookup always rejects, so gate on the cheap root.
|
|
4363
|
+
if (
|
|
4364
|
+
this.getMemberExpressionRoot(expression.callee).type ===
|
|
4365
|
+
"CallExpression"
|
|
4366
|
+
) {
|
|
4367
|
+
const exprInfo = this.getMemberExpressionInfo(
|
|
4368
|
+
expression.callee,
|
|
4369
|
+
ALLOWED_MEMBER_TYPES_CALL_EXPRESSION
|
|
3965
4370
|
);
|
|
3966
|
-
if (
|
|
4371
|
+
if (exprInfo && exprInfo.type === "call") {
|
|
4372
|
+
const result = this.callHooksForInfo(
|
|
4373
|
+
this.hooks.callMemberChainOfCallMemberChain,
|
|
4374
|
+
exprInfo.rootInfo,
|
|
4375
|
+
expression,
|
|
4376
|
+
exprInfo.getCalleeMembers(),
|
|
4377
|
+
exprInfo.call,
|
|
4378
|
+
exprInfo.getMembers(),
|
|
4379
|
+
exprInfo.getMemberRanges()
|
|
4380
|
+
);
|
|
4381
|
+
if (result === true) return;
|
|
4382
|
+
}
|
|
3967
4383
|
}
|
|
3968
4384
|
// import("./m").then(m => { ... })
|
|
3969
4385
|
if (
|
|
@@ -3978,19 +4394,33 @@ class JavascriptParser extends Parser {
|
|
|
3978
4394
|
if (result === true) return;
|
|
3979
4395
|
}
|
|
3980
4396
|
}
|
|
4397
|
+
if (
|
|
4398
|
+
expression.callee.type === "Identifier" &&
|
|
4399
|
+
this._evalIdentOwnTaps &&
|
|
4400
|
+
expression.callee.name !== "undefined" &&
|
|
4401
|
+
this._isDefinedPlainVariable(expression.callee.name)
|
|
4402
|
+
) {
|
|
4403
|
+
// a defined, untagged callee can only evaluate to the fallthrough
|
|
4404
|
+
// result, so no call hooks apply — walk callee and arguments
|
|
4405
|
+
// directly, skipping the hook dispatch and its result object
|
|
4406
|
+
this.walkExpression(expression.callee);
|
|
4407
|
+
if (expression.arguments) this.walkExpressions(expression.arguments);
|
|
4408
|
+
return;
|
|
4409
|
+
}
|
|
3981
4410
|
const callee = this.evaluateExpression(expression.callee);
|
|
3982
4411
|
if (callee.isIdentifier()) {
|
|
4412
|
+
const members =
|
|
4413
|
+
/** @type {NonNullable<BasicEvaluatedExpression["getMembers"]>} */
|
|
4414
|
+
(callee.getMembers)();
|
|
3983
4415
|
const result1 = this.callHooksForInfo(
|
|
3984
4416
|
this.hooks.callMemberChain,
|
|
3985
4417
|
/** @type {NonNullable<BasicEvaluatedExpression["rootInfo"]>} */
|
|
3986
4418
|
(callee.rootInfo),
|
|
3987
4419
|
expression,
|
|
3988
|
-
|
|
3989
|
-
(callee.getMembers)(),
|
|
4420
|
+
members,
|
|
3990
4421
|
callee.getMembersOptionals
|
|
3991
4422
|
? callee.getMembersOptionals()
|
|
3992
|
-
:
|
|
3993
|
-
(callee.getMembers)().map(() => false),
|
|
4423
|
+
: members.map(RETURN_FALSE),
|
|
3994
4424
|
callee.getMemberRanges ? callee.getMemberRanges() : []
|
|
3995
4425
|
);
|
|
3996
4426
|
if (result1 === true) return;
|
|
@@ -4019,6 +4449,7 @@ class JavascriptParser extends Parser {
|
|
|
4019
4449
|
}
|
|
4020
4450
|
|
|
4021
4451
|
/**
|
|
4452
|
+
* Walk member expression.
|
|
4022
4453
|
* @param {MemberExpression} expression member expression
|
|
4023
4454
|
*/
|
|
4024
4455
|
walkMemberExpression(expression) {
|
|
@@ -4085,6 +4516,7 @@ class JavascriptParser extends Parser {
|
|
|
4085
4516
|
}
|
|
4086
4517
|
|
|
4087
4518
|
/**
|
|
4519
|
+
* Walk member expression with expression name.
|
|
4088
4520
|
* @template R
|
|
4089
4521
|
* @param {MemberExpression} expression member expression
|
|
4090
4522
|
* @param {string} name name
|
|
@@ -4102,10 +4534,10 @@ class JavascriptParser extends Parser {
|
|
|
4102
4534
|
if (expression.object.type === "MemberExpression") {
|
|
4103
4535
|
// optimize the case where expression.object is a MemberExpression too.
|
|
4104
4536
|
// we can keep info here when calling walkMemberExpression directly
|
|
4105
|
-
|
|
4106
|
-
|
|
4107
|
-
|
|
4108
|
-
|
|
4537
|
+
// Read the property from `members` (already extracted by
|
|
4538
|
+
// extractMemberExpressionChain) since the AST node may be a
|
|
4539
|
+
// TemplateLiteral, which has neither .name nor .value.
|
|
4540
|
+
const property = members[members.length - 1];
|
|
4109
4541
|
name = name.slice(0, -property.length - 1);
|
|
4110
4542
|
members.pop();
|
|
4111
4543
|
const result = this.callHooksForInfo(
|
|
@@ -4128,6 +4560,7 @@ class JavascriptParser extends Parser {
|
|
|
4128
4560
|
}
|
|
4129
4561
|
|
|
4130
4562
|
/**
|
|
4563
|
+
* Walk this expression.
|
|
4131
4564
|
* @param {ThisExpression} expression this expression
|
|
4132
4565
|
*/
|
|
4133
4566
|
walkThisExpression(expression) {
|
|
@@ -4135,6 +4568,7 @@ class JavascriptParser extends Parser {
|
|
|
4135
4568
|
}
|
|
4136
4569
|
|
|
4137
4570
|
/**
|
|
4571
|
+
* Processes the provided expression.
|
|
4138
4572
|
* @param {Identifier} expression identifier
|
|
4139
4573
|
*/
|
|
4140
4574
|
walkIdentifier(expression) {
|
|
@@ -4142,6 +4576,7 @@ class JavascriptParser extends Parser {
|
|
|
4142
4576
|
}
|
|
4143
4577
|
|
|
4144
4578
|
/**
|
|
4579
|
+
* Walk meta property.
|
|
4145
4580
|
* @param {MetaProperty} metaProperty meta property
|
|
4146
4581
|
*/
|
|
4147
4582
|
walkMetaProperty(metaProperty) {
|
|
@@ -4149,6 +4584,7 @@ class JavascriptParser extends Parser {
|
|
|
4149
4584
|
}
|
|
4150
4585
|
|
|
4151
4586
|
/**
|
|
4587
|
+
* Call hooks for expression.
|
|
4152
4588
|
* @template T
|
|
4153
4589
|
* @template R
|
|
4154
4590
|
* @param {HookMap<SyncBailHook<T, R>>} hookMap hooks the should be called
|
|
@@ -4167,6 +4603,7 @@ class JavascriptParser extends Parser {
|
|
|
4167
4603
|
}
|
|
4168
4604
|
|
|
4169
4605
|
/**
|
|
4606
|
+
* Call hooks for expression with fallback.
|
|
4170
4607
|
* @template T
|
|
4171
4608
|
* @template R
|
|
4172
4609
|
* @param {HookMap<SyncBailHook<T, R>>} hookMap hooks the should be called
|
|
@@ -4201,6 +4638,7 @@ class JavascriptParser extends Parser {
|
|
|
4201
4638
|
}
|
|
4202
4639
|
|
|
4203
4640
|
/**
|
|
4641
|
+
* Call hooks for name.
|
|
4204
4642
|
* @template T
|
|
4205
4643
|
* @template R
|
|
4206
4644
|
* @param {HookMap<SyncBailHook<T, R>>} hookMap hooks the should be called
|
|
@@ -4209,16 +4647,17 @@ class JavascriptParser extends Parser {
|
|
|
4209
4647
|
* @returns {R | undefined} result of hook
|
|
4210
4648
|
*/
|
|
4211
4649
|
callHooksForName(hookMap, name, ...args) {
|
|
4212
|
-
return this.
|
|
4650
|
+
return this._callHooksForInfo(
|
|
4213
4651
|
hookMap,
|
|
4214
|
-
name,
|
|
4652
|
+
this.getVariableInfo(name),
|
|
4215
4653
|
undefined,
|
|
4216
4654
|
undefined,
|
|
4217
|
-
|
|
4655
|
+
args
|
|
4218
4656
|
);
|
|
4219
4657
|
}
|
|
4220
4658
|
|
|
4221
4659
|
/**
|
|
4660
|
+
* Call hooks for info.
|
|
4222
4661
|
* @template T
|
|
4223
4662
|
* @template R
|
|
4224
4663
|
* @param {HookMap<SyncBailHook<T, R>>} hookMap hooks that should be called
|
|
@@ -4227,16 +4666,11 @@ class JavascriptParser extends Parser {
|
|
|
4227
4666
|
* @returns {R | undefined} result of hook
|
|
4228
4667
|
*/
|
|
4229
4668
|
callHooksForInfo(hookMap, info, ...args) {
|
|
4230
|
-
return this.
|
|
4231
|
-
hookMap,
|
|
4232
|
-
info,
|
|
4233
|
-
undefined,
|
|
4234
|
-
undefined,
|
|
4235
|
-
...args
|
|
4236
|
-
);
|
|
4669
|
+
return this._callHooksForInfo(hookMap, info, undefined, undefined, args);
|
|
4237
4670
|
}
|
|
4238
4671
|
|
|
4239
4672
|
/**
|
|
4673
|
+
* Call hooks for info with fallback.
|
|
4240
4674
|
* @template T
|
|
4241
4675
|
* @template R
|
|
4242
4676
|
* @param {HookMap<SyncBailHook<T, R>>} hookMap hooks the should be called
|
|
@@ -4247,6 +4681,23 @@ class JavascriptParser extends Parser {
|
|
|
4247
4681
|
* @returns {R | undefined} result of hook
|
|
4248
4682
|
*/
|
|
4249
4683
|
callHooksForInfoWithFallback(hookMap, info, fallback, defined, ...args) {
|
|
4684
|
+
return this._callHooksForInfo(hookMap, info, fallback, defined, args);
|
|
4685
|
+
}
|
|
4686
|
+
|
|
4687
|
+
/**
|
|
4688
|
+
* Shared core for the callHooksFor* helpers. Takes `args` as an already
|
|
4689
|
+
* collected array so the public wrappers each allocate it once instead of
|
|
4690
|
+
* re-collecting it through several rest-parameter layers (hot per identifier).
|
|
4691
|
+
* @template T
|
|
4692
|
+
* @template R
|
|
4693
|
+
* @param {HookMap<SyncBailHook<T, R>>} hookMap hooks that should be called
|
|
4694
|
+
* @param {ExportedVariableInfo} info variable info
|
|
4695
|
+
* @param {((name: string) => R | undefined) | undefined} fallback callback when variable is not handled by hooks
|
|
4696
|
+
* @param {((result?: string) => R | undefined) | undefined} defined callback when variable is defined
|
|
4697
|
+
* @param {AsArray<T>} args args for the hook
|
|
4698
|
+
* @returns {R | undefined} result of hook
|
|
4699
|
+
*/
|
|
4700
|
+
_callHooksForInfo(hookMap, info, fallback, defined, args) {
|
|
4250
4701
|
/** @type {string} */
|
|
4251
4702
|
let name;
|
|
4252
4703
|
if (typeof info === "string") {
|
|
@@ -4288,6 +4739,7 @@ class JavascriptParser extends Parser {
|
|
|
4288
4739
|
}
|
|
4289
4740
|
|
|
4290
4741
|
/**
|
|
4742
|
+
* Call hooks for name with fallback.
|
|
4291
4743
|
* @template T
|
|
4292
4744
|
* @template R
|
|
4293
4745
|
* @param {HookMap<SyncBailHook<T, R>>} hookMap hooks the should be called
|
|
@@ -4298,16 +4750,17 @@ class JavascriptParser extends Parser {
|
|
|
4298
4750
|
* @returns {R | undefined} result of hook
|
|
4299
4751
|
*/
|
|
4300
4752
|
callHooksForNameWithFallback(hookMap, name, fallback, defined, ...args) {
|
|
4301
|
-
return this.
|
|
4753
|
+
return this._callHooksForInfo(
|
|
4302
4754
|
hookMap,
|
|
4303
4755
|
this.getVariableInfo(name),
|
|
4304
4756
|
fallback,
|
|
4305
4757
|
defined,
|
|
4306
|
-
|
|
4758
|
+
args
|
|
4307
4759
|
);
|
|
4308
4760
|
}
|
|
4309
4761
|
|
|
4310
4762
|
/**
|
|
4763
|
+
* Processes the provided param.
|
|
4311
4764
|
* @deprecated
|
|
4312
4765
|
* @param {(string | Pattern | Property)[]} params scope params
|
|
4313
4766
|
* @param {() => void} fn inner function
|
|
@@ -4328,9 +4781,7 @@ class JavascriptParser extends Parser {
|
|
|
4328
4781
|
|
|
4329
4782
|
this.undefineVariable("this");
|
|
4330
4783
|
|
|
4331
|
-
this.enterPatterns(params,
|
|
4332
|
-
this.defineVariable(ident);
|
|
4333
|
-
});
|
|
4784
|
+
this.enterPatterns(params, this._defineVariable);
|
|
4334
4785
|
|
|
4335
4786
|
fn();
|
|
4336
4787
|
|
|
@@ -4338,6 +4789,7 @@ class JavascriptParser extends Parser {
|
|
|
4338
4789
|
}
|
|
4339
4790
|
|
|
4340
4791
|
/**
|
|
4792
|
+
* Processes the provided has thi.
|
|
4341
4793
|
* @param {boolean} hasThis true, when this is defined
|
|
4342
4794
|
* @param {Identifier[]} params scope params
|
|
4343
4795
|
* @param {() => void} fn inner function
|
|
@@ -4360,9 +4812,7 @@ class JavascriptParser extends Parser {
|
|
|
4360
4812
|
this.undefineVariable("this");
|
|
4361
4813
|
}
|
|
4362
4814
|
|
|
4363
|
-
this.enterPatterns(params,
|
|
4364
|
-
this.defineVariable(ident);
|
|
4365
|
-
});
|
|
4815
|
+
this.enterPatterns(params, this._defineVariable);
|
|
4366
4816
|
|
|
4367
4817
|
fn();
|
|
4368
4818
|
|
|
@@ -4370,6 +4820,7 @@ class JavascriptParser extends Parser {
|
|
|
4370
4820
|
}
|
|
4371
4821
|
|
|
4372
4822
|
/**
|
|
4823
|
+
* Processes the provided has thi.
|
|
4373
4824
|
* @param {boolean} hasThis true, when this is defined
|
|
4374
4825
|
* @param {(Pattern | string)[]} params scope params
|
|
4375
4826
|
* @param {() => void} fn inner function
|
|
@@ -4392,9 +4843,7 @@ class JavascriptParser extends Parser {
|
|
|
4392
4843
|
this.undefineVariable("this");
|
|
4393
4844
|
}
|
|
4394
4845
|
|
|
4395
|
-
this.enterPatterns(params,
|
|
4396
|
-
this.defineVariable(ident);
|
|
4397
|
-
});
|
|
4846
|
+
this.enterPatterns(params, this._defineVariable);
|
|
4398
4847
|
|
|
4399
4848
|
fn();
|
|
4400
4849
|
|
|
@@ -4402,6 +4851,7 @@ class JavascriptParser extends Parser {
|
|
|
4402
4851
|
}
|
|
4403
4852
|
|
|
4404
4853
|
/**
|
|
4854
|
+
* Processes the provided fn.
|
|
4405
4855
|
* @param {() => void} fn inner function
|
|
4406
4856
|
* @param {boolean} inExecutedPath executed state
|
|
4407
4857
|
* @returns {void}
|
|
@@ -4431,37 +4881,34 @@ class JavascriptParser extends Parser {
|
|
|
4431
4881
|
}
|
|
4432
4882
|
|
|
4433
4883
|
/**
|
|
4884
|
+
* Processes the provided statement.
|
|
4434
4885
|
* @param {(Directive | Statement | ModuleDeclaration)[]} statements statements
|
|
4435
4886
|
*/
|
|
4436
4887
|
detectMode(statements) {
|
|
4437
|
-
const
|
|
4438
|
-
statements.length >= 1 &&
|
|
4439
|
-
statements[0].type === "ExpressionStatement" &&
|
|
4440
|
-
statements[0].expression.type === "Literal";
|
|
4888
|
+
const statement = statements.length >= 1 ? statements[0] : undefined;
|
|
4441
4889
|
if (
|
|
4442
|
-
|
|
4443
|
-
|
|
4444
|
-
|
|
4445
|
-
"use strict"
|
|
4890
|
+
statement === undefined ||
|
|
4891
|
+
statement.type !== "ExpressionStatement" ||
|
|
4892
|
+
statement.expression.type !== "Literal"
|
|
4446
4893
|
) {
|
|
4447
|
-
|
|
4894
|
+
return;
|
|
4448
4895
|
}
|
|
4449
|
-
|
|
4450
|
-
|
|
4451
|
-
|
|
4452
|
-
|
|
4453
|
-
"use asm"
|
|
4454
|
-
) {
|
|
4896
|
+
const value = /** @type {Literal} */ (statement.expression).value;
|
|
4897
|
+
if (value === "use strict") {
|
|
4898
|
+
this.scope.isStrict = true;
|
|
4899
|
+
} else if (value === "use asm") {
|
|
4455
4900
|
this.scope.isAsmJs = true;
|
|
4456
4901
|
}
|
|
4457
4902
|
}
|
|
4458
4903
|
|
|
4459
4904
|
/**
|
|
4905
|
+
* Processes the provided pattern.
|
|
4460
4906
|
* @param {(string | Pattern | Property)[]} patterns patterns
|
|
4461
4907
|
* @param {OnIdentString} onIdent on ident callback
|
|
4462
4908
|
*/
|
|
4463
4909
|
enterPatterns(patterns, onIdent) {
|
|
4464
|
-
for (
|
|
4910
|
+
for (let i = 0, len = patterns.length; i < len; i++) {
|
|
4911
|
+
const pattern = patterns[i];
|
|
4465
4912
|
if (typeof pattern !== "string") {
|
|
4466
4913
|
this.enterPattern(pattern, onIdent);
|
|
4467
4914
|
} else if (pattern) {
|
|
@@ -4471,27 +4918,20 @@ class JavascriptParser extends Parser {
|
|
|
4471
4918
|
}
|
|
4472
4919
|
|
|
4473
4920
|
/**
|
|
4921
|
+
* Processes the provided pattern.
|
|
4474
4922
|
* @param {Pattern | Property} pattern pattern
|
|
4475
4923
|
* @param {OnIdent} onIdent on ident callback
|
|
4476
4924
|
*/
|
|
4477
4925
|
enterPattern(pattern, onIdent) {
|
|
4478
4926
|
if (!pattern) return;
|
|
4927
|
+
// plain identifiers dominate bindings, so match them first
|
|
4479
4928
|
switch (pattern.type) {
|
|
4480
|
-
case "ArrayPattern":
|
|
4481
|
-
this.enterArrayPattern(pattern, onIdent);
|
|
4482
|
-
break;
|
|
4483
|
-
case "AssignmentPattern":
|
|
4484
|
-
this.enterAssignmentPattern(pattern, onIdent);
|
|
4485
|
-
break;
|
|
4486
4929
|
case "Identifier":
|
|
4487
4930
|
this.enterIdentifier(pattern, onIdent);
|
|
4488
4931
|
break;
|
|
4489
4932
|
case "ObjectPattern":
|
|
4490
4933
|
this.enterObjectPattern(pattern, onIdent);
|
|
4491
4934
|
break;
|
|
4492
|
-
case "RestElement":
|
|
4493
|
-
this.enterRestElement(pattern, onIdent);
|
|
4494
|
-
break;
|
|
4495
4935
|
case "Property":
|
|
4496
4936
|
if (pattern.shorthand && pattern.value.type === "Identifier") {
|
|
4497
4937
|
this.scope.inShorthand = pattern.value.name;
|
|
@@ -4501,10 +4941,20 @@ class JavascriptParser extends Parser {
|
|
|
4501
4941
|
this.enterPattern(/** @type {Pattern} */ (pattern.value), onIdent);
|
|
4502
4942
|
}
|
|
4503
4943
|
break;
|
|
4944
|
+
case "ArrayPattern":
|
|
4945
|
+
this.enterArrayPattern(pattern, onIdent);
|
|
4946
|
+
break;
|
|
4947
|
+
case "AssignmentPattern":
|
|
4948
|
+
this.enterAssignmentPattern(pattern, onIdent);
|
|
4949
|
+
break;
|
|
4950
|
+
case "RestElement":
|
|
4951
|
+
this.enterRestElement(pattern, onIdent);
|
|
4952
|
+
break;
|
|
4504
4953
|
}
|
|
4505
4954
|
}
|
|
4506
4955
|
|
|
4507
4956
|
/**
|
|
4957
|
+
* Processes the provided pattern.
|
|
4508
4958
|
* @param {Identifier} pattern identifier pattern
|
|
4509
4959
|
* @param {OnIdent} onIdent callback
|
|
4510
4960
|
*/
|
|
@@ -4515,6 +4965,7 @@ class JavascriptParser extends Parser {
|
|
|
4515
4965
|
}
|
|
4516
4966
|
|
|
4517
4967
|
/**
|
|
4968
|
+
* Enter object pattern.
|
|
4518
4969
|
* @param {ObjectPattern} pattern object pattern
|
|
4519
4970
|
* @param {OnIdent} onIdent callback
|
|
4520
4971
|
*/
|
|
@@ -4530,6 +4981,7 @@ class JavascriptParser extends Parser {
|
|
|
4530
4981
|
}
|
|
4531
4982
|
|
|
4532
4983
|
/**
|
|
4984
|
+
* Enter array pattern.
|
|
4533
4985
|
* @param {ArrayPattern} pattern object pattern
|
|
4534
4986
|
* @param {OnIdent} onIdent callback
|
|
4535
4987
|
*/
|
|
@@ -4548,6 +5000,7 @@ class JavascriptParser extends Parser {
|
|
|
4548
5000
|
}
|
|
4549
5001
|
|
|
4550
5002
|
/**
|
|
5003
|
+
* Enter rest element.
|
|
4551
5004
|
* @param {RestElement} pattern object pattern
|
|
4552
5005
|
* @param {OnIdent} onIdent callback
|
|
4553
5006
|
*/
|
|
@@ -4556,6 +5009,7 @@ class JavascriptParser extends Parser {
|
|
|
4556
5009
|
}
|
|
4557
5010
|
|
|
4558
5011
|
/**
|
|
5012
|
+
* Enter assignment pattern.
|
|
4559
5013
|
* @param {AssignmentPattern} pattern object pattern
|
|
4560
5014
|
* @param {OnIdent} onIdent callback
|
|
4561
5015
|
*/
|
|
@@ -4564,6 +5018,7 @@ class JavascriptParser extends Parser {
|
|
|
4564
5018
|
}
|
|
4565
5019
|
|
|
4566
5020
|
/**
|
|
5021
|
+
* Evaluate expression.
|
|
4567
5022
|
* @param {Expression | SpreadElement | PrivateIdentifier | Super} expression expression node
|
|
4568
5023
|
* @returns {BasicEvaluatedExpression} evaluation result
|
|
4569
5024
|
*/
|
|
@@ -4582,12 +5037,13 @@ class JavascriptParser extends Parser {
|
|
|
4582
5037
|
console.warn(err);
|
|
4583
5038
|
// ignore error
|
|
4584
5039
|
}
|
|
4585
|
-
|
|
4586
|
-
|
|
4587
|
-
|
|
5040
|
+
// no setRange: the range is served lazily from the expression on first
|
|
5041
|
+
// read, so plain results don't materialize the node's range array at all
|
|
5042
|
+
return new BasicEvaluatedExpression().setExpression(expression);
|
|
4588
5043
|
}
|
|
4589
5044
|
|
|
4590
5045
|
/**
|
|
5046
|
+
* Returns parsed string.
|
|
4591
5047
|
* @param {Expression} expression expression
|
|
4592
5048
|
* @returns {string} parsed string
|
|
4593
5049
|
*/
|
|
@@ -4612,6 +5068,7 @@ class JavascriptParser extends Parser {
|
|
|
4612
5068
|
/** @typedef {{ range?: Range, value: string, code: boolean, conditional: false | CalculatedStringResult[] }} CalculatedStringResult */
|
|
4613
5069
|
|
|
4614
5070
|
/**
|
|
5071
|
+
* Parses calculated string.
|
|
4615
5072
|
* @param {Expression} expression expression
|
|
4616
5073
|
* @returns {CalculatedStringResult} result
|
|
4617
5074
|
*/
|
|
@@ -4701,6 +5158,7 @@ class JavascriptParser extends Parser {
|
|
|
4701
5158
|
}
|
|
4702
5159
|
|
|
4703
5160
|
/**
|
|
5161
|
+
* Parses the provided source and updates the parser state.
|
|
4704
5162
|
* @param {string | Buffer | PreparsedAst} source the source to parse
|
|
4705
5163
|
* @param {ParserState} state the parser state
|
|
4706
5164
|
* @returns {ParserState} the parser state
|
|
@@ -4712,35 +5170,29 @@ class JavascriptParser extends Parser {
|
|
|
4712
5170
|
|
|
4713
5171
|
if (Buffer.isBuffer(source)) {
|
|
4714
5172
|
source = source.toString("utf8");
|
|
5173
|
+
// Keep `state.source` as a string so downstream walkers can read
|
|
5174
|
+
// the original text without re-decoding the Buffer on every use.
|
|
5175
|
+
state.source = source;
|
|
4715
5176
|
}
|
|
4716
5177
|
|
|
4717
5178
|
let ast;
|
|
4718
5179
|
/** @type {Comment[]} */
|
|
4719
5180
|
let comments;
|
|
4720
|
-
/** @type {Set<number>} */
|
|
4721
|
-
let semicolons;
|
|
4722
5181
|
|
|
4723
5182
|
if (typeof source === "object") {
|
|
4724
|
-
semicolons = new Set();
|
|
4725
|
-
|
|
4726
5183
|
ast = /** @type {Program} */ (source);
|
|
4727
5184
|
comments = source.comments;
|
|
4728
|
-
if (source.semicolons) {
|
|
4729
|
-
// Forward semicolon information from the preparsed AST if present
|
|
4730
|
-
// This ensures the output is consistent with that of a fresh AST
|
|
4731
|
-
for (const pos of source.semicolons) {
|
|
4732
|
-
semicolons.add(pos);
|
|
4733
|
-
}
|
|
4734
|
-
}
|
|
4735
5185
|
} else {
|
|
4736
|
-
({ ast, comments
|
|
5186
|
+
({ ast, comments } = JavascriptParser._parse(
|
|
4737
5187
|
source,
|
|
4738
5188
|
{
|
|
4739
5189
|
sourceType: this.sourceType,
|
|
4740
|
-
locations
|
|
5190
|
+
// line/column locations are derived from node offsets via
|
|
5191
|
+
// getLocation — parsers never need to track them
|
|
5192
|
+
locations: false,
|
|
4741
5193
|
ranges: true,
|
|
4742
5194
|
comments: true,
|
|
4743
|
-
|
|
5195
|
+
importPhases: this.options.importPhases === true
|
|
4744
5196
|
},
|
|
4745
5197
|
this.options.parse
|
|
4746
5198
|
));
|
|
@@ -4752,6 +5204,18 @@ class JavascriptParser extends Parser {
|
|
|
4752
5204
|
const oldSemicolons = this.semicolons;
|
|
4753
5205
|
const oldStatementPath = this.statementPath;
|
|
4754
5206
|
const oldPrevStatement = this.prevStatement;
|
|
5207
|
+
const oldStrictInModuleOutput = this._strictInModuleOutput;
|
|
5208
|
+
const oldSource = this._source;
|
|
5209
|
+
const oldLineStarts = this._lineStarts;
|
|
5210
|
+
// a preparsed AST carries no text, but the build passes the module
|
|
5211
|
+
// source in the state — offsets still map for it
|
|
5212
|
+
this._source =
|
|
5213
|
+
typeof source === "string"
|
|
5214
|
+
? source
|
|
5215
|
+
: typeof state.source === "string"
|
|
5216
|
+
? state.source
|
|
5217
|
+
: undefined;
|
|
5218
|
+
this._lineStarts = undefined;
|
|
4755
5219
|
this.scope = {
|
|
4756
5220
|
topLevelScope: true,
|
|
4757
5221
|
inTry: false,
|
|
@@ -4764,13 +5228,34 @@ class JavascriptParser extends Parser {
|
|
|
4764
5228
|
};
|
|
4765
5229
|
this.state = state;
|
|
4766
5230
|
this.comments = comments;
|
|
4767
|
-
this.semicolons =
|
|
5231
|
+
this.semicolons = undefined;
|
|
5232
|
+
// evaluating a defined, untagged identifier can only fall through when
|
|
5233
|
+
// every `evaluate.for("Identifier")` tap is the parser's own — plugins
|
|
5234
|
+
// tapping or intercepting it disable the callee/rename fast paths
|
|
5235
|
+
const identifierEvalHook = this.hooks.evaluate.get("Identifier");
|
|
5236
|
+
this._evalIdentOwnTaps =
|
|
5237
|
+
identifierEvalHook !== undefined &&
|
|
5238
|
+
identifierEvalHook.interceptors.length === 0 &&
|
|
5239
|
+
identifierEvalHook.taps.every((tap) => tap.name === CLASS_NAME);
|
|
4768
5240
|
this.statementPath = [];
|
|
4769
5241
|
this.prevStatement = undefined;
|
|
5242
|
+
// The output is emitted as strict-mode ESM, but this module was parsed as
|
|
5243
|
+
// a loose script — acorn skipped the strict early errors that will break
|
|
5244
|
+
// the bundle at runtime. Enables the strict-mode diagnostics below.
|
|
5245
|
+
this._strictInModuleOutput =
|
|
5246
|
+
this.options.strictModeViolations !== false &&
|
|
5247
|
+
state.compilation !== undefined &&
|
|
5248
|
+
state.compilation.runtimeTemplate.isModule();
|
|
4770
5249
|
if (this.hooks.program.call(ast, comments) === undefined) {
|
|
4771
5250
|
this.destructuringAssignmentProperties = new WeakMap();
|
|
4772
5251
|
this.detectMode(ast.body);
|
|
5252
|
+
// a strict program (ESM source, `"use strict"`) keeps its behavior in
|
|
5253
|
+
// strict output — drop the flag so the walk pays no per-node checks
|
|
5254
|
+
if (this._strictInModuleOutput && this.scope.isStrict) {
|
|
5255
|
+
this._strictInModuleOutput = false;
|
|
5256
|
+
}
|
|
4773
5257
|
this.modulePreWalkStatements(ast.body);
|
|
5258
|
+
this.prevStatement = undefined;
|
|
4774
5259
|
this.preWalkStatements(ast.body);
|
|
4775
5260
|
this.prevStatement = undefined;
|
|
4776
5261
|
this.blockPreWalkStatements(ast.body);
|
|
@@ -4785,19 +5270,54 @@ class JavascriptParser extends Parser {
|
|
|
4785
5270
|
this.semicolons = oldSemicolons;
|
|
4786
5271
|
this.statementPath = oldStatementPath;
|
|
4787
5272
|
this.prevStatement = oldPrevStatement;
|
|
5273
|
+
this._strictInModuleOutput = oldStrictInModuleOutput;
|
|
5274
|
+
// release — these retain the whole source string and its line table
|
|
5275
|
+
this._source = oldSource;
|
|
5276
|
+
this._lineStarts = oldLineStarts;
|
|
4788
5277
|
return state;
|
|
4789
5278
|
}
|
|
4790
5279
|
|
|
4791
5280
|
/**
|
|
5281
|
+
* Returns evaluation result.
|
|
4792
5282
|
* @param {string} source source code
|
|
4793
5283
|
* @returns {BasicEvaluatedExpression} evaluation result
|
|
4794
5284
|
*/
|
|
4795
5285
|
evaluate(source) {
|
|
4796
|
-
const
|
|
4797
|
-
|
|
4798
|
-
|
|
4799
|
-
|
|
4800
|
-
|
|
5286
|
+
const importPhases = this.options.importPhases === true;
|
|
5287
|
+
const compilation = this.state && this.state.compilation;
|
|
5288
|
+
/** @type {Map<string, Program> | undefined} */
|
|
5289
|
+
let cache;
|
|
5290
|
+
// custom parse functions are not necessarily pure, do not cache for them
|
|
5291
|
+
if (compilation !== undefined && typeof this.options.parse !== "function") {
|
|
5292
|
+
cache = evaluateAstCaches.get(compilation);
|
|
5293
|
+
if (cache === undefined) {
|
|
5294
|
+
cache = new Map();
|
|
5295
|
+
evaluateAstCaches.set(compilation, cache);
|
|
5296
|
+
}
|
|
5297
|
+
}
|
|
5298
|
+
const cacheKey =
|
|
5299
|
+
cache === undefined
|
|
5300
|
+
? undefined
|
|
5301
|
+
: `${this.sourceType}|${importPhases}|${source}`;
|
|
5302
|
+
let ast =
|
|
5303
|
+
cacheKey === undefined
|
|
5304
|
+
? undefined
|
|
5305
|
+
: /** @type {Map<string, Program>} */ (cache).get(cacheKey);
|
|
5306
|
+
if (ast === undefined) {
|
|
5307
|
+
({ ast } = JavascriptParser._parse(
|
|
5308
|
+
`(${source})`,
|
|
5309
|
+
{
|
|
5310
|
+
sourceType: this.sourceType,
|
|
5311
|
+
importPhases
|
|
5312
|
+
},
|
|
5313
|
+
this.options.parse
|
|
5314
|
+
));
|
|
5315
|
+
if (cacheKey !== undefined) {
|
|
5316
|
+
const map = /** @type {Map<string, Program>} */ (cache);
|
|
5317
|
+
if (map.size >= EVALUATE_AST_CACHE_LIMIT) map.clear();
|
|
5318
|
+
map.set(cacheKey, ast);
|
|
5319
|
+
}
|
|
5320
|
+
}
|
|
4801
5321
|
if (ast.body.length !== 1 || ast.body[0].type !== "ExpressionStatement") {
|
|
4802
5322
|
throw new Error("evaluate: Source is not a expression");
|
|
4803
5323
|
}
|
|
@@ -4805,6 +5325,7 @@ class JavascriptParser extends Parser {
|
|
|
4805
5325
|
}
|
|
4806
5326
|
|
|
4807
5327
|
/**
|
|
5328
|
+
* Checks whether this javascript parser is pure.
|
|
4808
5329
|
* @param {Expression | Declaration | PrivateIdentifier | MaybeNamedFunctionDeclaration | MaybeNamedClassDeclaration | null | undefined} expr an expression
|
|
4809
5330
|
* @param {number} commentsStartPos source position from which annotation comments are checked
|
|
4810
5331
|
* @returns {boolean} true, when the expression is pure
|
|
@@ -4816,7 +5337,6 @@ class JavascriptParser extends Parser {
|
|
|
4816
5337
|
.call(expr, commentsStartPos);
|
|
4817
5338
|
if (typeof result === "boolean") return result;
|
|
4818
5339
|
switch (expr.type) {
|
|
4819
|
-
// TODO handle more cases
|
|
4820
5340
|
case "ClassDeclaration":
|
|
4821
5341
|
case "ClassExpression": {
|
|
4822
5342
|
if (expr.body.type !== "ClassBody") return false;
|
|
@@ -4869,9 +5389,15 @@ class JavascriptParser extends Parser {
|
|
|
4869
5389
|
});
|
|
4870
5390
|
}
|
|
4871
5391
|
case "TemplateLiteral":
|
|
4872
|
-
|
|
4873
|
-
|
|
4874
|
-
)
|
|
5392
|
+
// Thread `commentsStartPos` through the interpolations so a
|
|
5393
|
+
// /*#__PURE__*/ comment that sits inside `${ ... }` (or before
|
|
5394
|
+
// the first interpolation) is part of the scanned range when
|
|
5395
|
+
// the inner expression's purity is evaluated.
|
|
5396
|
+
return expr.expressions.every((e) => {
|
|
5397
|
+
const pureFlag = this.isPure(e, commentsStartPos);
|
|
5398
|
+
commentsStartPos = /** @type {Range} */ (e.range)[1];
|
|
5399
|
+
return pureFlag;
|
|
5400
|
+
});
|
|
4875
5401
|
case "FunctionDeclaration":
|
|
4876
5402
|
case "FunctionExpression":
|
|
4877
5403
|
case "ArrowFunctionExpression":
|
|
@@ -4886,6 +5412,78 @@ class JavascriptParser extends Parser {
|
|
|
4886
5412
|
this.isPure(decl.init, /** @type {Range} */ (decl.range)[0])
|
|
4887
5413
|
);
|
|
4888
5414
|
|
|
5415
|
+
case "ArrayExpression":
|
|
5416
|
+
return expr.elements.every((element) => {
|
|
5417
|
+
if (element === null) return true;
|
|
5418
|
+
if (element.type === "SpreadElement") return false;
|
|
5419
|
+
const pureFlag = this.isPure(element, commentsStartPos);
|
|
5420
|
+
commentsStartPos = /** @type {Range} */ (element.range)[1];
|
|
5421
|
+
return pureFlag;
|
|
5422
|
+
});
|
|
5423
|
+
|
|
5424
|
+
case "ObjectExpression": {
|
|
5425
|
+
return expr.properties.every((property) => {
|
|
5426
|
+
if (property.type === "SpreadElement") return false;
|
|
5427
|
+
|
|
5428
|
+
if (
|
|
5429
|
+
property.computed &&
|
|
5430
|
+
!this.isPure(property.key, commentsStartPos)
|
|
5431
|
+
) {
|
|
5432
|
+
return false;
|
|
5433
|
+
}
|
|
5434
|
+
|
|
5435
|
+
const pureFlag = this.isPure(
|
|
5436
|
+
/** @type {Exclude<Property["value"], AssignmentPattern | ObjectPattern | ArrayPattern | RestElement>} */
|
|
5437
|
+
(property.value),
|
|
5438
|
+
/** @type {Range} */ (property.key.range)[1]
|
|
5439
|
+
);
|
|
5440
|
+
commentsStartPos = /** @type {Range} */ (property.range)[1];
|
|
5441
|
+
return pureFlag;
|
|
5442
|
+
});
|
|
5443
|
+
}
|
|
5444
|
+
|
|
5445
|
+
case "ChainExpression":
|
|
5446
|
+
return this.isPure(expr.expression, commentsStartPos);
|
|
5447
|
+
|
|
5448
|
+
case "UnaryExpression":
|
|
5449
|
+
// Safe unary operators — produce their result without invoking
|
|
5450
|
+
// user code on the operand:
|
|
5451
|
+
// - `typeof` returns a type tag and never throws, even for
|
|
5452
|
+
// undeclared identifiers; no coercion.
|
|
5453
|
+
// - `void` evaluates the operand and discards it, returning
|
|
5454
|
+
// `undefined`; pure iff the operand is pure.
|
|
5455
|
+
// - `!` coerces via ToBoolean, which is defined to not call
|
|
5456
|
+
// any user code (objects → true, etc.).
|
|
5457
|
+
// Other operators (`+`, `-`, `~`, `delete`) fall through to
|
|
5458
|
+
// the generic evaluator which can still recognize literal
|
|
5459
|
+
// cases (e.g. `-1`, `+5`).
|
|
5460
|
+
if (
|
|
5461
|
+
expr.operator === "typeof" ||
|
|
5462
|
+
expr.operator === "void" ||
|
|
5463
|
+
expr.operator === "!"
|
|
5464
|
+
) {
|
|
5465
|
+
return this.isPure(expr.argument, commentsStartPos);
|
|
5466
|
+
}
|
|
5467
|
+
break;
|
|
5468
|
+
|
|
5469
|
+
case "MetaProperty":
|
|
5470
|
+
return true;
|
|
5471
|
+
|
|
5472
|
+
case "BinaryExpression":
|
|
5473
|
+
// Strict (in)equality compares without coercion and never invokes
|
|
5474
|
+
// user code on its operands, so the result is pure iff both sides
|
|
5475
|
+
// are pure. All other binary operators may invoke `valueOf` /
|
|
5476
|
+
// `toString` / `[Symbol.hasInstance]` / Proxy traps and fall through
|
|
5477
|
+
// to the generic evaluator, which can still recognize the cases
|
|
5478
|
+
// where both sides evaluate to known primitive literals.
|
|
5479
|
+
if (expr.operator === "===" || expr.operator === "!==") {
|
|
5480
|
+
return (
|
|
5481
|
+
this.isPure(expr.left, commentsStartPos) &&
|
|
5482
|
+
this.isPure(expr.right, /** @type {Range} */ (expr.left.range)[1])
|
|
5483
|
+
);
|
|
5484
|
+
}
|
|
5485
|
+
break;
|
|
5486
|
+
|
|
4889
5487
|
case "ConditionalExpression":
|
|
4890
5488
|
return (
|
|
4891
5489
|
this.isPure(expr.test, commentsStartPos) &&
|
|
@@ -4921,7 +5519,7 @@ class JavascriptParser extends Parser {
|
|
|
4921
5519
|
]).some(
|
|
4922
5520
|
(comment) =>
|
|
4923
5521
|
comment.type === "Block" &&
|
|
4924
|
-
|
|
5522
|
+
CompilerHintNotationRegExp.Pure.test(comment.value)
|
|
4925
5523
|
);
|
|
4926
5524
|
if (!pureFlag) return false;
|
|
4927
5525
|
commentsStartPos = /** @type {Range} */ (expr.callee.range)[1];
|
|
@@ -4932,40 +5530,177 @@ class JavascriptParser extends Parser {
|
|
|
4932
5530
|
return pureFlag;
|
|
4933
5531
|
});
|
|
4934
5532
|
}
|
|
5533
|
+
|
|
5534
|
+
case "NewExpression": {
|
|
5535
|
+
const pureFlag =
|
|
5536
|
+
/** @type {Range} */ (expr.range)[0] - commentsStartPos > 12 &&
|
|
5537
|
+
this.getComments([
|
|
5538
|
+
commentsStartPos,
|
|
5539
|
+
/** @type {Range} */ (expr.range)[0]
|
|
5540
|
+
]).some(
|
|
5541
|
+
(comment) =>
|
|
5542
|
+
comment.type === "Block" &&
|
|
5543
|
+
CompilerHintNotationRegExp.Pure.test(comment.value)
|
|
5544
|
+
);
|
|
5545
|
+
if (!pureFlag) return false;
|
|
5546
|
+
commentsStartPos = /** @type {Range} */ (expr.callee.range)[1];
|
|
5547
|
+
return expr.arguments.every((arg) => {
|
|
5548
|
+
if (arg.type === "SpreadElement") return false;
|
|
5549
|
+
const pureFlag = this.isPure(arg, commentsStartPos);
|
|
5550
|
+
commentsStartPos = /** @type {Range} */ (arg.range)[1];
|
|
5551
|
+
return pureFlag;
|
|
5552
|
+
});
|
|
5553
|
+
}
|
|
5554
|
+
|
|
5555
|
+
case "TaggedTemplateExpression": {
|
|
5556
|
+
const pureFlag =
|
|
5557
|
+
/** @type {Range} */ (expr.range)[0] - commentsStartPos > 12 &&
|
|
5558
|
+
this.getComments([
|
|
5559
|
+
commentsStartPos,
|
|
5560
|
+
/** @type {Range} */ (expr.range)[0]
|
|
5561
|
+
]).some(
|
|
5562
|
+
(comment) =>
|
|
5563
|
+
comment.type === "Block" &&
|
|
5564
|
+
CompilerHintNotationRegExp.Pure.test(comment.value)
|
|
5565
|
+
);
|
|
5566
|
+
if (!pureFlag) return false;
|
|
5567
|
+
commentsStartPos = /** @type {Range} */ (expr.tag.range)[1];
|
|
5568
|
+
return expr.quasi.expressions.every((e) => {
|
|
5569
|
+
const pureFlag = this.isPure(e, commentsStartPos);
|
|
5570
|
+
commentsStartPos = /** @type {Range} */ (e.range)[1];
|
|
5571
|
+
return pureFlag;
|
|
5572
|
+
});
|
|
5573
|
+
}
|
|
4935
5574
|
}
|
|
4936
5575
|
const evaluated = this.evaluateExpression(expr);
|
|
4937
5576
|
return !evaluated.couldHaveSideEffects();
|
|
4938
5577
|
}
|
|
4939
5578
|
|
|
4940
5579
|
/**
|
|
5580
|
+
* Returns the location of a node or comment, computed from its offsets so
|
|
5581
|
+
* ASTs from parsers without location support work too. Falls back to the
|
|
5582
|
+
* node's own `loc` only when no source text is available (preparsed ASTs).
|
|
5583
|
+
* Offsets can only be mapped while parsing — callbacks deferred past the
|
|
5584
|
+
* `parse()` call must take the location upfront.
|
|
5585
|
+
* @param {{ start?: number, end?: number, range?: Range, loc?: SourceLocation | null }} node node or comment
|
|
5586
|
+
* @returns {DependencyLocation} location of the node
|
|
5587
|
+
*/
|
|
5588
|
+
getLocation(node) {
|
|
5589
|
+
const source = this._source;
|
|
5590
|
+
if (source !== undefined) {
|
|
5591
|
+
const start =
|
|
5592
|
+
typeof node.start === "number"
|
|
5593
|
+
? node.start
|
|
5594
|
+
: node.range
|
|
5595
|
+
? node.range[0]
|
|
5596
|
+
: undefined;
|
|
5597
|
+
if (start !== undefined) {
|
|
5598
|
+
const end =
|
|
5599
|
+
typeof node.end === "number"
|
|
5600
|
+
? node.end
|
|
5601
|
+
: node.range
|
|
5602
|
+
? node.range[1]
|
|
5603
|
+
: start;
|
|
5604
|
+
const lineStarts =
|
|
5605
|
+
this._lineStarts || (this._lineStarts = buildLineStarts(source));
|
|
5606
|
+
return {
|
|
5607
|
+
start: positionAt(lineStarts, start),
|
|
5608
|
+
end: positionAt(lineStarts, end)
|
|
5609
|
+
};
|
|
5610
|
+
}
|
|
5611
|
+
}
|
|
5612
|
+
return /** @type {DependencyLocation} */ (node.loc);
|
|
5613
|
+
}
|
|
5614
|
+
|
|
5615
|
+
/**
|
|
5616
|
+
* Returns comments in the range.
|
|
4941
5617
|
* @param {Range} range range
|
|
4942
5618
|
* @returns {Comment[]} comments in the range
|
|
4943
5619
|
*/
|
|
4944
5620
|
getComments(range) {
|
|
4945
|
-
|
|
4946
|
-
|
|
4947
|
-
|
|
4948
|
-
|
|
4949
|
-
|
|
4950
|
-
|
|
4951
|
-
|
|
4952
|
-
|
|
4953
|
-
|
|
4954
|
-
|
|
4955
|
-
|
|
4956
|
-
|
|
4957
|
-
|
|
4958
|
-
|
|
4959
|
-
|
|
4960
|
-
) {
|
|
4961
|
-
|
|
4962
|
-
|
|
5621
|
+
return getCommentsInRange(
|
|
5622
|
+
/** @type {(Comment & { range: [number, number] })[]} */ (this.comments),
|
|
5623
|
+
range
|
|
5624
|
+
);
|
|
5625
|
+
}
|
|
5626
|
+
|
|
5627
|
+
/**
|
|
5628
|
+
* First significant char code at or after `pos`, skipping whitespace and
|
|
5629
|
+
* comments, or -1 at end of source.
|
|
5630
|
+
* @param {string} source source text
|
|
5631
|
+
* @param {number} pos start offset
|
|
5632
|
+
* @returns {number} char code of the next token, or -1
|
|
5633
|
+
*/
|
|
5634
|
+
_nextTokenCharCode(source, pos) {
|
|
5635
|
+
const len = source.length;
|
|
5636
|
+
for (let i = pos; i < len; i++) {
|
|
5637
|
+
const c = source.charCodeAt(i);
|
|
5638
|
+
// whitespace and line terminators acorn skips between tokens
|
|
5639
|
+
if (
|
|
5640
|
+
c === 32 ||
|
|
5641
|
+
c === 9 ||
|
|
5642
|
+
c === 10 ||
|
|
5643
|
+
c === 13 ||
|
|
5644
|
+
c === 11 ||
|
|
5645
|
+
c === 12 ||
|
|
5646
|
+
c === 0xa0 ||
|
|
5647
|
+
c === 0xfeff ||
|
|
5648
|
+
c === 0x2028 ||
|
|
5649
|
+
c === 0x2029
|
|
5650
|
+
) {
|
|
5651
|
+
continue;
|
|
5652
|
+
}
|
|
5653
|
+
if (c === 47 /* / */) {
|
|
5654
|
+
const n = source.charCodeAt(i + 1);
|
|
5655
|
+
if (n === 47 /* / */) {
|
|
5656
|
+
i += 2;
|
|
5657
|
+
while (i < len) {
|
|
5658
|
+
const cc = source.charCodeAt(i);
|
|
5659
|
+
if (cc === 10 || cc === 13 || cc === 0x2028 || cc === 0x2029) break;
|
|
5660
|
+
i++;
|
|
5661
|
+
}
|
|
5662
|
+
continue;
|
|
5663
|
+
}
|
|
5664
|
+
if (n === 42 /* * */) {
|
|
5665
|
+
i += 2;
|
|
5666
|
+
while (
|
|
5667
|
+
i < len &&
|
|
5668
|
+
!(source.charCodeAt(i) === 42 && source.charCodeAt(i + 1) === 47)
|
|
5669
|
+
) {
|
|
5670
|
+
i++;
|
|
5671
|
+
}
|
|
5672
|
+
i++;
|
|
5673
|
+
continue;
|
|
5674
|
+
}
|
|
5675
|
+
}
|
|
5676
|
+
return c;
|
|
4963
5677
|
}
|
|
5678
|
+
return -1;
|
|
5679
|
+
}
|
|
4964
5680
|
|
|
4965
|
-
|
|
5681
|
+
/**
|
|
5682
|
+
* Whether a statement ending at `pos` relies on ASI (no real separator).
|
|
5683
|
+
* Derived from the source text unless overridden by set/unsetAsiPosition.
|
|
5684
|
+
* A statement terminated by a real `;` or continued by a `,` (a sequence
|
|
5685
|
+
* element) is not an ASI position; anything else (newline, `}`, eof) is.
|
|
5686
|
+
* @param {number} pos statement end offset
|
|
5687
|
+
* @returns {boolean} true when ASI inserts a semicolon at this position
|
|
5688
|
+
*/
|
|
5689
|
+
_isAsiPosition(pos) {
|
|
5690
|
+
if (this.semicolons !== undefined) {
|
|
5691
|
+
const override = this.semicolons.get(pos);
|
|
5692
|
+
if (override !== undefined) return override;
|
|
5693
|
+
}
|
|
5694
|
+
const source = this._source;
|
|
5695
|
+
if (source === undefined) return true;
|
|
5696
|
+
// a real semicolon is the statement's last char (exclusive end at pos)
|
|
5697
|
+
if (source.charCodeAt(pos - 1) === 59 /* ; */) return false;
|
|
5698
|
+
const next = this._nextTokenCharCode(source, pos);
|
|
5699
|
+
return next !== 44 /* , */ && next !== 59; /* ; */
|
|
4966
5700
|
}
|
|
4967
5701
|
|
|
4968
5702
|
/**
|
|
5703
|
+
* Checks whether this javascript parser is asi position.
|
|
4969
5704
|
* @param {number} pos source code position
|
|
4970
5705
|
* @returns {boolean} true when a semicolon has been inserted before this position, false if not
|
|
4971
5706
|
*/
|
|
@@ -4981,37 +5716,37 @@ class JavascriptParser extends Parser {
|
|
|
4981
5716
|
|
|
4982
5717
|
return (
|
|
4983
5718
|
// Either asking directly for the end position of the current statement
|
|
4984
|
-
(range[1] === pos &&
|
|
4985
|
-
/** @type {Set<number>} */ (this.semicolons).has(pos)) ||
|
|
5719
|
+
(range[1] === pos && this._isAsiPosition(pos)) ||
|
|
4986
5720
|
// Or asking for the start position of the current statement,
|
|
4987
5721
|
// here we have to check multiple things
|
|
4988
5722
|
(range[0] === pos &&
|
|
4989
5723
|
// is there a previous statement which might be relevant?
|
|
4990
5724
|
this.prevStatement !== undefined &&
|
|
4991
5725
|
// is the end position of the previous statement an ASI position?
|
|
4992
|
-
/** @type {
|
|
4993
|
-
/** @type {Range} */ (this.prevStatement.range)[1]
|
|
4994
|
-
))
|
|
5726
|
+
this._isAsiPosition(/** @type {Range} */ (this.prevStatement.range)[1]))
|
|
4995
5727
|
);
|
|
4996
5728
|
}
|
|
4997
5729
|
|
|
4998
5730
|
/**
|
|
5731
|
+
* Updates asi position using the provided po.
|
|
4999
5732
|
* @param {number} pos source code position
|
|
5000
5733
|
* @returns {void}
|
|
5001
5734
|
*/
|
|
5002
5735
|
setAsiPosition(pos) {
|
|
5003
|
-
|
|
5736
|
+
(this.semicolons || (this.semicolons = new Map())).set(pos, true);
|
|
5004
5737
|
}
|
|
5005
5738
|
|
|
5006
5739
|
/**
|
|
5740
|
+
* Unset asi position.
|
|
5007
5741
|
* @param {number} pos source code position
|
|
5008
5742
|
* @returns {void}
|
|
5009
5743
|
*/
|
|
5010
5744
|
unsetAsiPosition(pos) {
|
|
5011
|
-
|
|
5745
|
+
(this.semicolons || (this.semicolons = new Map())).set(pos, false);
|
|
5012
5746
|
}
|
|
5013
5747
|
|
|
5014
5748
|
/**
|
|
5749
|
+
* Checks whether this javascript parser is statement level expression.
|
|
5015
5750
|
* @param {Expression} expr expression
|
|
5016
5751
|
* @returns {boolean} true, when the expression is a statement level expression
|
|
5017
5752
|
*/
|
|
@@ -5030,6 +5765,7 @@ class JavascriptParser extends Parser {
|
|
|
5030
5765
|
}
|
|
5031
5766
|
|
|
5032
5767
|
/**
|
|
5768
|
+
* Returns tag data.
|
|
5033
5769
|
* @param {string} name name
|
|
5034
5770
|
* @param {Tag} tag tag info
|
|
5035
5771
|
* @returns {TagData | undefined} tag data
|
|
@@ -5046,6 +5782,7 @@ class JavascriptParser extends Parser {
|
|
|
5046
5782
|
}
|
|
5047
5783
|
|
|
5048
5784
|
/**
|
|
5785
|
+
* Processes the provided name.
|
|
5049
5786
|
* @param {string} name name
|
|
5050
5787
|
* @param {Tag} tag tag info
|
|
5051
5788
|
* @param {TagData=} data data
|
|
@@ -5083,6 +5820,7 @@ class JavascriptParser extends Parser {
|
|
|
5083
5820
|
}
|
|
5084
5821
|
|
|
5085
5822
|
/**
|
|
5823
|
+
* Processes the provided name.
|
|
5086
5824
|
* @param {string} name variable name
|
|
5087
5825
|
*/
|
|
5088
5826
|
defineVariable(name) {
|
|
@@ -5098,6 +5836,7 @@ class JavascriptParser extends Parser {
|
|
|
5098
5836
|
}
|
|
5099
5837
|
|
|
5100
5838
|
/**
|
|
5839
|
+
* Processes the provided name.
|
|
5101
5840
|
* @param {string} name variable name
|
|
5102
5841
|
*/
|
|
5103
5842
|
undefineVariable(name) {
|
|
@@ -5105,6 +5844,7 @@ class JavascriptParser extends Parser {
|
|
|
5105
5844
|
}
|
|
5106
5845
|
|
|
5107
5846
|
/**
|
|
5847
|
+
* Checks whether this javascript parser is variable defined.
|
|
5108
5848
|
* @param {string} name variable name
|
|
5109
5849
|
* @returns {boolean} true, when variable is defined
|
|
5110
5850
|
*/
|
|
@@ -5118,6 +5858,23 @@ class JavascriptParser extends Parser {
|
|
|
5118
5858
|
}
|
|
5119
5859
|
|
|
5120
5860
|
/**
|
|
5861
|
+
* Whether evaluating an identifier of this name can only fall through:
|
|
5862
|
+
* the exact negative of the identifier evaluator's `getInfo` — defined in
|
|
5863
|
+
* some scope and neither free nor tagged nor carrying tag info.
|
|
5864
|
+
* @param {string} name variable name
|
|
5865
|
+
* @returns {boolean} true when the identifier evaluates to nothing
|
|
5866
|
+
*/
|
|
5867
|
+
_isDefinedPlainVariable(name) {
|
|
5868
|
+
const info = this.scope.definitions.get(name);
|
|
5869
|
+
if (info === undefined) return false;
|
|
5870
|
+
if (info instanceof VariableInfo) {
|
|
5871
|
+
return !(info.isFree() || info.isTagged() || info.tagInfo !== undefined);
|
|
5872
|
+
}
|
|
5873
|
+
return true;
|
|
5874
|
+
}
|
|
5875
|
+
|
|
5876
|
+
/**
|
|
5877
|
+
* Gets variable info.
|
|
5121
5878
|
* @param {string} name variable name
|
|
5122
5879
|
* @returns {ExportedVariableInfo} info for this variable
|
|
5123
5880
|
*/
|
|
@@ -5130,6 +5887,7 @@ class JavascriptParser extends Parser {
|
|
|
5130
5887
|
}
|
|
5131
5888
|
|
|
5132
5889
|
/**
|
|
5890
|
+
* Updates variable using the provided name.
|
|
5133
5891
|
* @param {string} name variable name
|
|
5134
5892
|
* @param {ExportedVariableInfo} variableInfo new info for this variable
|
|
5135
5893
|
* @returns {void}
|
|
@@ -5155,6 +5913,7 @@ class JavascriptParser extends Parser {
|
|
|
5155
5913
|
}
|
|
5156
5914
|
|
|
5157
5915
|
/**
|
|
5916
|
+
* Evaluated variable.
|
|
5158
5917
|
* @param {TagInfo} tagInfo tag info
|
|
5159
5918
|
* @returns {VariableInfo} variable info
|
|
5160
5919
|
*/
|
|
@@ -5168,49 +5927,54 @@ class JavascriptParser extends Parser {
|
|
|
5168
5927
|
}
|
|
5169
5928
|
|
|
5170
5929
|
/**
|
|
5930
|
+
* Parses comment options.
|
|
5171
5931
|
* @param {Range} range range of the comment
|
|
5172
5932
|
* @returns {{ options: Record<string, EXPECTED_ANY> | null, errors: (Error & { comment: Comment })[] | null }} result
|
|
5173
5933
|
*/
|
|
5174
5934
|
parseCommentOptions(range) {
|
|
5175
|
-
|
|
5176
|
-
|
|
5177
|
-
|
|
5178
|
-
|
|
5179
|
-
|
|
5180
|
-
|
|
5181
|
-
|
|
5182
|
-
|
|
5183
|
-
|
|
5184
|
-
|
|
5185
|
-
|
|
5186
|
-
|
|
5187
|
-
|
|
5188
|
-
|
|
5189
|
-
|
|
5190
|
-
|
|
5191
|
-
|
|
5192
|
-
|
|
5193
|
-
|
|
5194
|
-
|
|
5195
|
-
|
|
5196
|
-
|
|
5197
|
-
|
|
5198
|
-
|
|
5199
|
-
|
|
5200
|
-
|
|
5201
|
-
|
|
5202
|
-
|
|
5203
|
-
|
|
5204
|
-
|
|
5205
|
-
|
|
5206
|
-
|
|
5935
|
+
return parseCommentOptionsInRange(
|
|
5936
|
+
/** @type {(Comment & { range: [number, number], value: string })[]} */ (
|
|
5937
|
+
this.comments
|
|
5938
|
+
),
|
|
5939
|
+
range,
|
|
5940
|
+
this.magicCommentContext
|
|
5941
|
+
);
|
|
5942
|
+
}
|
|
5943
|
+
|
|
5944
|
+
/**
|
|
5945
|
+
* Finds the root object of a member expression chain without allocating the
|
|
5946
|
+
* member arrays. The traversal/break logic must stay in sync with
|
|
5947
|
+
* `extractMemberExpressionChain`; it lets `getMemberExpressionInfo` reject
|
|
5948
|
+
* unrecognized roots (~77% of calls) before paying for the arrays.
|
|
5949
|
+
* @param {Expression | Super} expression a member expression
|
|
5950
|
+
* @returns {Expression | Super} the root object of the chain
|
|
5951
|
+
*/
|
|
5952
|
+
getMemberExpressionRoot(expression) {
|
|
5953
|
+
/** @type {Node} */
|
|
5954
|
+
let expr = expression;
|
|
5955
|
+
while (expr.type === "MemberExpression") {
|
|
5956
|
+
if (expr.computed) {
|
|
5957
|
+
const prop = expr.property;
|
|
5958
|
+
if (
|
|
5959
|
+
prop.type !== "Literal" &&
|
|
5960
|
+
!(
|
|
5961
|
+
prop.type === "TemplateLiteral" &&
|
|
5962
|
+
prop.expressions.length === 0 &&
|
|
5963
|
+
typeof prop.quasis[0].value.cooked === "string"
|
|
5964
|
+
)
|
|
5965
|
+
) {
|
|
5966
|
+
break;
|
|
5207
5967
|
}
|
|
5968
|
+
} else if (expr.property.type !== "Identifier") {
|
|
5969
|
+
break;
|
|
5208
5970
|
}
|
|
5971
|
+
expr = expr.object;
|
|
5209
5972
|
}
|
|
5210
|
-
return {
|
|
5973
|
+
return /** @type {Expression | Super} */ (expr);
|
|
5211
5974
|
}
|
|
5212
5975
|
|
|
5213
5976
|
/**
|
|
5977
|
+
* Extract member expression chain.
|
|
5214
5978
|
* @param {Expression | Super} expression a member expression
|
|
5215
5979
|
* @returns {{ members: Members, object: Expression | Super, membersOptionals: MembersOptionals, memberRanges: MemberRanges }} member names (reverse order) and remaining object
|
|
5216
5980
|
*/
|
|
@@ -5225,9 +5989,20 @@ class JavascriptParser extends Parser {
|
|
|
5225
5989
|
const memberRanges = [];
|
|
5226
5990
|
while (expr.type === "MemberExpression") {
|
|
5227
5991
|
if (expr.computed) {
|
|
5228
|
-
|
|
5229
|
-
|
|
5230
|
-
|
|
5992
|
+
const prop = expr.property;
|
|
5993
|
+
if (prop.type === "Literal") {
|
|
5994
|
+
members.push(`${prop.value}`); // the literal
|
|
5995
|
+
} else if (
|
|
5996
|
+
prop.type === "TemplateLiteral" &&
|
|
5997
|
+
prop.expressions.length === 0 &&
|
|
5998
|
+
typeof prop.quasis[0].value.cooked === "string"
|
|
5999
|
+
) {
|
|
6000
|
+
// `[`url`]` is statically a string just like `["url"]`
|
|
6001
|
+
members.push(prop.quasis[0].value.cooked);
|
|
6002
|
+
} else {
|
|
6003
|
+
break;
|
|
6004
|
+
}
|
|
6005
|
+
memberRanges.push(/** @type {Range} */ (expr.object.range)); // the range of the expression fragment before the property
|
|
5231
6006
|
} else {
|
|
5232
6007
|
if (expr.property.type !== "Identifier") break;
|
|
5233
6008
|
members.push(expr.property.name); // the identifier
|
|
@@ -5246,6 +6021,7 @@ class JavascriptParser extends Parser {
|
|
|
5246
6021
|
}
|
|
5247
6022
|
|
|
5248
6023
|
/**
|
|
6024
|
+
* Gets free info from variable.
|
|
5249
6025
|
* @param {string} varName variable name
|
|
5250
6026
|
* @returns {{ name: string, info: VariableInfo | string } | undefined} name of the free variable and variable info for that
|
|
5251
6027
|
*/
|
|
@@ -5265,6 +6041,7 @@ class JavascriptParser extends Parser {
|
|
|
5265
6041
|
}
|
|
5266
6042
|
|
|
5267
6043
|
/**
|
|
6044
|
+
* Gets name info from variable.
|
|
5268
6045
|
* @param {string} varName variable name
|
|
5269
6046
|
* @returns {{ name: string, info: VariableInfo | string } | undefined} name of the free variable and variable info for that
|
|
5270
6047
|
*/
|
|
@@ -5287,38 +6064,45 @@ class JavascriptParser extends Parser {
|
|
|
5287
6064
|
/** @typedef {{ type: "expression", rootInfo: string | VariableInfo, name: string, getMembers: () => Members, getMembersOptionals: () => MembersOptionals, getMemberRanges: () => MemberRanges }} ExpressionExpressionInfo */
|
|
5288
6065
|
|
|
5289
6066
|
/**
|
|
6067
|
+
* Gets member expression info.
|
|
5290
6068
|
* @param {Expression | Super} expression a member expression
|
|
5291
6069
|
* @param {number} allowedTypes which types should be returned, presented in bit mask
|
|
5292
6070
|
* @returns {CallExpressionInfo | ExpressionExpressionInfo | undefined} expression info
|
|
5293
6071
|
*/
|
|
5294
6072
|
getMemberExpressionInfo(expression, allowedTypes) {
|
|
5295
|
-
|
|
5296
|
-
|
|
6073
|
+
// Resolve the root first (no allocation); most calls reject here and so
|
|
6074
|
+
// never build the member arrays via extractMemberExpressionChain.
|
|
6075
|
+
const object = this.getMemberExpressionRoot(expression);
|
|
5297
6076
|
switch (object.type) {
|
|
5298
6077
|
case "CallExpression": {
|
|
5299
6078
|
if ((allowedTypes & ALLOWED_MEMBER_TYPES_CALL_EXPRESSION) === 0) return;
|
|
5300
|
-
|
|
5301
|
-
|
|
5302
|
-
|
|
5303
|
-
|
|
5304
|
-
|
|
5305
|
-
}
|
|
6079
|
+
const calleeExpr = object.callee;
|
|
6080
|
+
const callee =
|
|
6081
|
+
calleeExpr.type === "MemberExpression"
|
|
6082
|
+
? this.getMemberExpressionRoot(calleeExpr)
|
|
6083
|
+
: calleeExpr;
|
|
5306
6084
|
const rootName = getRootName(callee);
|
|
5307
6085
|
if (!rootName) return;
|
|
5308
6086
|
const result = this.getNameInfoFromVariable(rootName);
|
|
5309
6087
|
if (!result) return;
|
|
5310
6088
|
const { info: rootInfo, name: resolvedRoot } = result;
|
|
6089
|
+
const rootMembers =
|
|
6090
|
+
calleeExpr.type === "MemberExpression"
|
|
6091
|
+
? this.extractMemberExpressionChain(calleeExpr).members
|
|
6092
|
+
: EMPTY_ARRAY;
|
|
6093
|
+
const { members, membersOptionals, memberRanges } =
|
|
6094
|
+
this.extractMemberExpressionChain(expression);
|
|
5311
6095
|
const calleeName = objectAndMembersToName(resolvedRoot, rootMembers);
|
|
5312
6096
|
return {
|
|
5313
6097
|
type: "call",
|
|
5314
6098
|
call: object,
|
|
5315
6099
|
calleeName,
|
|
5316
6100
|
rootInfo,
|
|
5317
|
-
getCalleeMembers:
|
|
6101
|
+
getCalleeMembers: lazyReverse(rootMembers),
|
|
5318
6102
|
name: objectAndMembersToName(`${calleeName}()`, members),
|
|
5319
|
-
getMembers:
|
|
5320
|
-
getMembersOptionals:
|
|
5321
|
-
getMemberRanges:
|
|
6103
|
+
getMembers: lazyReverse(members),
|
|
6104
|
+
getMembersOptionals: lazyReverse(membersOptionals),
|
|
6105
|
+
getMemberRanges: lazyReverse(memberRanges)
|
|
5322
6106
|
};
|
|
5323
6107
|
}
|
|
5324
6108
|
case "Identifier":
|
|
@@ -5331,19 +6115,22 @@ class JavascriptParser extends Parser {
|
|
|
5331
6115
|
const result = this.getNameInfoFromVariable(rootName);
|
|
5332
6116
|
if (!result) return;
|
|
5333
6117
|
const { info: rootInfo, name: resolvedRoot } = result;
|
|
6118
|
+
const { members, membersOptionals, memberRanges } =
|
|
6119
|
+
this.extractMemberExpressionChain(expression);
|
|
5334
6120
|
return {
|
|
5335
6121
|
type: "expression",
|
|
5336
6122
|
name: objectAndMembersToName(resolvedRoot, members),
|
|
5337
6123
|
rootInfo,
|
|
5338
|
-
getMembers:
|
|
5339
|
-
getMembersOptionals:
|
|
5340
|
-
getMemberRanges:
|
|
6124
|
+
getMembers: lazyReverse(members),
|
|
6125
|
+
getMembersOptionals: lazyReverse(membersOptionals),
|
|
6126
|
+
getMemberRanges: lazyReverse(memberRanges)
|
|
5341
6127
|
};
|
|
5342
6128
|
}
|
|
5343
6129
|
}
|
|
5344
6130
|
}
|
|
5345
6131
|
|
|
5346
6132
|
/**
|
|
6133
|
+
* Gets name for expression.
|
|
5347
6134
|
* @param {Expression} expression an expression
|
|
5348
6135
|
* @returns {{ name: string, rootInfo: ExportedVariableInfo, getMembers: () => Members } | undefined} name info
|
|
5349
6136
|
*/
|
|
@@ -5355,6 +6142,7 @@ class JavascriptParser extends Parser {
|
|
|
5355
6142
|
}
|
|
5356
6143
|
|
|
5357
6144
|
/**
|
|
6145
|
+
* Get module parse function.
|
|
5358
6146
|
* @param {Compilation} compilation compilation
|
|
5359
6147
|
* @param {Module} module module
|
|
5360
6148
|
* @returns {ParseFunction | undefined} parser
|
|
@@ -5375,6 +6163,7 @@ class JavascriptParser extends Parser {
|
|
|
5375
6163
|
}
|
|
5376
6164
|
|
|
5377
6165
|
/**
|
|
6166
|
+
* Returns parse result.
|
|
5378
6167
|
* @param {string} code source code
|
|
5379
6168
|
* @param {InternalParseOptions} options parsing options
|
|
5380
6169
|
* @param {ParseFunction=} customParse custom function to parse
|
|
@@ -5383,13 +6172,32 @@ class JavascriptParser extends Parser {
|
|
|
5383
6172
|
static _parse(code, options, customParse) {
|
|
5384
6173
|
const type = options ? options.sourceType : "module";
|
|
5385
6174
|
/** @type {ParseOptions} */
|
|
5386
|
-
|
|
5387
|
-
|
|
5388
|
-
|
|
5389
|
-
|
|
5390
|
-
|
|
5391
|
-
|
|
6175
|
+
let parserOptions;
|
|
6176
|
+
if (typeof customParse === "function") {
|
|
6177
|
+
// a user parse function may retain the options object — keep it fresh
|
|
6178
|
+
parserOptions = {
|
|
6179
|
+
...defaultParserOptions,
|
|
6180
|
+
allowReturnOutsideFunction: type === "script",
|
|
6181
|
+
...options,
|
|
6182
|
+
sourceType: type === "auto" ? "module" : type
|
|
6183
|
+
};
|
|
6184
|
+
} else {
|
|
6185
|
+
// reuse one options object across parses (parsing is synchronous) to
|
|
6186
|
+
// skip re-materializing it per module; acorn copies it via getOptions.
|
|
6187
|
+
// Every non-default key a caller may pass must be reset here.
|
|
6188
|
+
parserOptions = REUSED_PARSER_OPTIONS;
|
|
6189
|
+
parserOptions.importPhases = false;
|
|
6190
|
+
Object.assign(parserOptions, defaultParserOptions);
|
|
6191
|
+
parserOptions.allowReturnOutsideFunction = type === "script";
|
|
6192
|
+
if (options) Object.assign(parserOptions, options);
|
|
6193
|
+
parserOptions.sourceType = type === "auto" ? "module" : type;
|
|
6194
|
+
// let WebpackParser downgrade module->script in place on script-only
|
|
6195
|
+
// syntax so `auto` avoids a second full parse in the common case
|
|
6196
|
+
parserOptions.moduleFallback = type === "auto";
|
|
6197
|
+
}
|
|
6198
|
+
const wantRanges = parserOptions.ranges === true;
|
|
5392
6199
|
/**
|
|
6200
|
+
* Returns parse result.
|
|
5393
6201
|
* @param {string} code source code
|
|
5394
6202
|
* @param {ParseOptions} options parsing options
|
|
5395
6203
|
* @returns {ParseResult} parse result
|
|
@@ -5402,36 +6210,46 @@ class JavascriptParser extends Parser {
|
|
|
5402
6210
|
/** @type {Comment[]} */
|
|
5403
6211
|
const comments = [];
|
|
5404
6212
|
|
|
5405
|
-
|
|
5406
|
-
|
|
5407
|
-
|
|
6213
|
+
// Whenever ranges are wanted (the main parse path and the concatenation
|
|
6214
|
+
// re-parse), have the parser plugin serve `range` on demand instead of
|
|
6215
|
+
// eagerly. `wantRanges` is hoisted since the auto-fallback re-enters
|
|
6216
|
+
// with the same (mutated) options object.
|
|
6217
|
+
options.lazyNodes = wantRanges;
|
|
6218
|
+
if (wantRanges) {
|
|
6219
|
+
// the lazy plugin replaces acorn's native tracking — disabling it
|
|
6220
|
+
// here lets WebpackParser skip its defensive options copy
|
|
6221
|
+
options.locations = false;
|
|
6222
|
+
options.ranges = false;
|
|
5408
6223
|
}
|
|
5409
6224
|
|
|
5410
|
-
|
|
5411
|
-
|
|
5412
|
-
|
|
5413
|
-
|
|
5414
|
-
|
|
5415
|
-
|
|
6225
|
+
if (options.comments) {
|
|
6226
|
+
if (wantRanges) {
|
|
6227
|
+
// the parser plugin collects the comments itself, deferring the
|
|
6228
|
+
// text slice until some hook actually reads `value`
|
|
6229
|
+
options.lazyComments = comments;
|
|
6230
|
+
} else {
|
|
6231
|
+
/** @type {AcornOptions} */
|
|
6232
|
+
(options).onComment =
|
|
6233
|
+
/** @type {import("acorn").Comment[]} */
|
|
6234
|
+
(/** @type {unknown} */ (comments));
|
|
6235
|
+
}
|
|
5416
6236
|
}
|
|
5417
6237
|
|
|
5418
6238
|
const ast =
|
|
5419
6239
|
/** @type {Program} */
|
|
5420
6240
|
(parser.parse(code, /** @type {AcornOptions} */ (options)));
|
|
5421
6241
|
|
|
5422
|
-
return { ast, comments
|
|
6242
|
+
return { ast, comments };
|
|
5423
6243
|
};
|
|
5424
6244
|
|
|
5425
6245
|
/** @type {Program | undefined} */
|
|
5426
6246
|
let ast;
|
|
5427
6247
|
/** @type {Comment[] | undefined} */
|
|
5428
6248
|
let comments;
|
|
5429
|
-
/** @type {Set<number> | undefined} */
|
|
5430
|
-
let semicolons;
|
|
5431
6249
|
let error;
|
|
5432
6250
|
let threw = false;
|
|
5433
6251
|
try {
|
|
5434
|
-
({ ast, comments
|
|
6252
|
+
({ ast, comments } = internalParse(code, parserOptions));
|
|
5435
6253
|
} catch (err) {
|
|
5436
6254
|
error = err;
|
|
5437
6255
|
threw = true;
|
|
@@ -5440,9 +6258,11 @@ class JavascriptParser extends Parser {
|
|
|
5440
6258
|
if (threw && type === "auto") {
|
|
5441
6259
|
parserOptions.sourceType = "script";
|
|
5442
6260
|
parserOptions.allowReturnOutsideFunction = true;
|
|
6261
|
+
// the retry is already a full script parse — no in-place downgrade
|
|
6262
|
+
parserOptions.moduleFallback = false;
|
|
5443
6263
|
|
|
5444
6264
|
try {
|
|
5445
|
-
({ ast, comments
|
|
6265
|
+
({ ast, comments } = internalParse(code, parserOptions));
|
|
5446
6266
|
threw = false;
|
|
5447
6267
|
} catch (_err) {
|
|
5448
6268
|
// we use the error from first parse try
|
|
@@ -5450,15 +6270,22 @@ class JavascriptParser extends Parser {
|
|
|
5450
6270
|
}
|
|
5451
6271
|
}
|
|
5452
6272
|
|
|
6273
|
+
// release per-parse state retained on the (possibly reused) options
|
|
6274
|
+
// object — the comments array retains source text slices
|
|
6275
|
+
parserOptions.lazyComments = undefined;
|
|
6276
|
+
/** @type {AcornOptions} */
|
|
6277
|
+
(parserOptions).onComment = undefined;
|
|
6278
|
+
|
|
5453
6279
|
if (threw) {
|
|
5454
6280
|
throw error;
|
|
5455
6281
|
}
|
|
5456
6282
|
|
|
5457
|
-
return /** @type {ParseResult} */ ({ ast, comments
|
|
6283
|
+
return /** @type {ParseResult} */ ({ ast, comments });
|
|
5458
6284
|
}
|
|
5459
6285
|
|
|
5460
6286
|
/**
|
|
5461
|
-
*
|
|
6287
|
+
* Returns parser.
|
|
6288
|
+
* @param {((BaseParser: AcornParser) => AcornParser)[]} plugins parser plugin
|
|
5462
6289
|
* @returns {typeof JavascriptParser} parser
|
|
5463
6290
|
*/
|
|
5464
6291
|
static extend(...plugins) {
|