webpack 5.76.1 → 5.88.2
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.
Potentially problematic release.
This version of webpack might be problematic. Click here for more details.
- package/README.md +10 -4
- package/bin/webpack.js +26 -2
- package/hot/dev-server.js +2 -1
- package/hot/lazy-compilation-node.js +10 -0
- package/hot/lazy-compilation-web.js +9 -0
- package/hot/log-apply-result.js +5 -0
- package/hot/log.js +22 -0
- package/hot/only-dev-server.js +2 -1
- package/hot/poll.js +3 -0
- package/hot/signal.js +4 -0
- package/lib/APIPlugin.js +174 -116
- package/lib/AsyncDependenciesBlock.js +13 -5
- package/lib/AutomaticPrefetchPlugin.js +1 -0
- package/lib/BannerPlugin.js +6 -1
- package/lib/CacheFacade.js +4 -0
- package/lib/CaseSensitiveModulesWarning.js +3 -1
- package/lib/Chunk.js +36 -18
- package/lib/ChunkGraph.js +4 -4
- package/lib/ChunkGroup.js +25 -10
- package/lib/CleanPlugin.js +30 -7
- package/lib/CodeGenerationResults.js +2 -2
- package/lib/CompatibilityPlugin.js +85 -46
- package/lib/Compilation.js +17 -8
- package/lib/Compiler.js +18 -14
- package/lib/ConcatenationScope.js +2 -2
- package/lib/ConditionalInitFragment.js +11 -1
- package/lib/ConstPlugin.js +95 -47
- package/lib/ContextModule.js +20 -6
- package/lib/ContextModuleFactory.js +2 -1
- package/lib/ContextReplacementPlugin.js +13 -0
- package/lib/CssModule.js +169 -0
- package/lib/DefinePlugin.js +152 -86
- package/lib/DelegatedModule.js +22 -4
- package/lib/DelegatedModuleFactoryPlugin.js +6 -0
- package/lib/DependenciesBlock.js +17 -1
- package/lib/Dependency.js +19 -5
- package/lib/DependencyTemplates.js +1 -1
- package/lib/DllEntryPlugin.js +16 -1
- package/lib/DllModule.js +17 -2
- package/lib/DllModuleFactory.js +1 -1
- package/lib/DllReferencePlugin.js +13 -1
- package/lib/Entrypoint.js +1 -1
- package/lib/ErrorHelpers.js +62 -22
- package/lib/EvalSourceMapDevToolPlugin.js +9 -2
- package/lib/ExportsInfo.js +25 -4
- package/lib/ExportsInfoApiPlugin.js +30 -14
- package/lib/ExternalModule.js +30 -9
- package/lib/FileSystemInfo.js +61 -25
- package/lib/FlagAllModulesAsUsedPlugin.js +27 -27
- package/lib/FlagDependencyExportsPlugin.js +336 -348
- package/lib/FlagDependencyUsagePlugin.js +9 -9
- package/lib/FlagEntryExportAsUsedPlugin.js +26 -23
- package/lib/Generator.js +7 -0
- package/lib/HookWebpackError.js +1 -1
- package/lib/HotModuleReplacementPlugin.js +60 -46
- package/lib/IgnoreErrorModuleFactory.js +1 -1
- package/lib/InitFragment.js +28 -5
- package/lib/JavascriptMetaInfoPlugin.js +27 -15
- package/lib/LibManifestPlugin.js +22 -5
- package/lib/LoaderOptionsPlugin.js +12 -2
- package/lib/MainTemplate.js +2 -2
- package/lib/Module.js +44 -12
- package/lib/ModuleBuildError.js +9 -0
- package/lib/ModuleDependencyError.js +4 -2
- package/lib/ModuleDependencyWarning.js +4 -2
- package/lib/ModuleError.js +9 -0
- package/lib/ModuleFactory.js +1 -1
- package/lib/ModuleFilenameHelpers.js +114 -4
- package/lib/ModuleGraph.js +33 -23
- package/lib/ModuleGraphConnection.js +19 -6
- package/lib/ModuleInfoHeaderPlugin.js +9 -2
- package/lib/ModuleNotFoundError.js +5 -2
- package/lib/ModuleParseError.js +9 -0
- package/lib/ModuleProfile.js +1 -0
- package/lib/ModuleRestoreError.js +2 -0
- package/lib/ModuleStoreError.js +2 -1
- package/lib/ModuleTypeConstants.js +169 -0
- package/lib/ModuleWarning.js +9 -0
- package/lib/MultiWatching.js +4 -0
- package/lib/NodeStuffPlugin.js +65 -35
- package/lib/NormalModule.js +12 -2
- package/lib/NormalModuleFactory.js +56 -8
- package/lib/NormalModuleReplacementPlugin.js +5 -3
- package/lib/NullFactory.js +1 -1
- package/lib/PrefetchPlugin.js +4 -0
- package/lib/ProgressPlugin.js +71 -15
- package/lib/ProvidePlugin.js +30 -14
- package/lib/RawModule.js +13 -2
- package/lib/RecordIdsPlugin.js +4 -4
- package/lib/RequireJsStuffPlugin.js +22 -15
- package/lib/RuntimeGlobals.js +5 -0
- package/lib/RuntimeModule.js +12 -11
- package/lib/RuntimePlugin.js +10 -3
- package/lib/RuntimeTemplate.js +29 -11
- package/lib/SelfModuleFactory.js +12 -0
- package/lib/SourceMapDevToolModuleOptionsPlugin.js +4 -0
- package/lib/SourceMapDevToolPlugin.js +47 -11
- package/lib/Template.js +5 -3
- package/lib/UseStrictPlugin.js +29 -11
- package/lib/WarnCaseSensitiveModulesPlugin.js +12 -0
- package/lib/WarnDeprecatedOptionPlugin.js +7 -0
- package/lib/WatchIgnorePlugin.js +4 -0
- package/lib/Watching.js +62 -25
- package/lib/WebpackError.js +14 -5
- package/lib/WebpackIsIncludedPlugin.js +22 -13
- package/lib/WebpackOptionsApply.js +41 -44
- package/lib/WebpackOptionsDefaulter.js +10 -3
- package/lib/asset/AssetGenerator.js +24 -9
- package/lib/asset/AssetModulesPlugin.js +28 -12
- package/lib/asset/AssetParser.js +15 -7
- package/lib/asset/AssetSourceParser.js +8 -3
- package/lib/asset/RawDataUrlModule.js +15 -4
- package/lib/async-modules/AwaitDependenciesInitFragment.js +4 -0
- package/lib/async-modules/InferAsyncModulesPlugin.js +1 -1
- package/lib/buildChunkGraph.js +37 -21
- package/lib/cache/IdleFileCachePlugin.js +2 -1
- package/lib/cache/MemoryWithGcCachePlugin.js +2 -0
- package/lib/cache/PackFileCacheStrategy.js +59 -22
- package/lib/cache/ResolverCachePlugin.js +3 -0
- package/lib/config/browserslistTargetHandler.js +10 -10
- package/lib/config/defaults.js +306 -105
- package/lib/config/normalization.js +110 -71
- package/lib/config/target.js +37 -10
- package/lib/container/ContainerEntryModule.js +11 -1
- package/lib/container/ContainerEntryModuleFactory.js +1 -1
- package/lib/container/ContainerExposedDependency.js +9 -0
- package/lib/container/ContainerPlugin.js +3 -1
- package/lib/container/FallbackDependency.js +13 -0
- package/lib/container/FallbackItemDependency.js +3 -0
- package/lib/container/FallbackModule.js +12 -2
- package/lib/container/FallbackModuleFactory.js +1 -1
- package/lib/container/RemoteModule.js +11 -1
- package/lib/container/RemoteRuntimeModule.js +3 -2
- package/lib/container/RemoteToExternalDependency.js +3 -0
- package/lib/css/CssExportsGenerator.js +9 -0
- package/lib/css/CssGenerator.js +5 -1
- package/lib/css/CssLoadingRuntimeModule.js +53 -22
- package/lib/css/CssModulesPlugin.js +253 -74
- package/lib/css/CssParser.js +697 -282
- package/lib/css/walkCssTokens.js +269 -138
- package/lib/debug/ProfilingPlugin.js +33 -12
- package/lib/dependencies/AMDDefineDependency.js +54 -10
- package/lib/dependencies/AMDDefineDependencyParserPlugin.js +13 -2
- package/lib/dependencies/AMDPlugin.js +33 -20
- package/lib/dependencies/AMDRequireArrayDependency.js +13 -0
- package/lib/dependencies/AMDRequireContextDependency.js +15 -0
- package/lib/dependencies/AMDRequireDependenciesBlock.js +6 -0
- package/lib/dependencies/AMDRequireDependenciesBlockParserPlugin.js +8 -2
- package/lib/dependencies/AMDRequireDependency.js +16 -1
- package/lib/dependencies/AMDRequireItemDependency.js +6 -0
- package/lib/dependencies/AMDRuntimeModules.js +2 -2
- package/lib/dependencies/CachedConstDependency.js +14 -0
- package/lib/dependencies/CommonJsDependencyHelpers.js +9 -0
- package/lib/dependencies/CommonJsExportRequireDependency.js +19 -0
- package/lib/dependencies/CommonJsExportsDependency.js +16 -0
- package/lib/dependencies/CommonJsExportsParserPlugin.js +77 -5
- package/lib/dependencies/CommonJsFullRequireDependency.js +10 -1
- package/lib/dependencies/CommonJsImportsParserPlugin.js +174 -63
- package/lib/dependencies/CommonJsPlugin.js +51 -26
- package/lib/dependencies/CommonJsRequireContextDependency.js +17 -0
- package/lib/dependencies/CommonJsRequireDependency.js +7 -0
- package/lib/dependencies/CommonJsSelfReferenceDependency.js +16 -0
- package/lib/dependencies/ConstDependency.js +11 -2
- package/lib/dependencies/ContextDependency.js +15 -2
- package/lib/dependencies/ContextDependencyHelpers.js +3 -3
- package/lib/dependencies/ContextElementDependency.js +8 -0
- package/lib/dependencies/CreateScriptUrlDependency.js +10 -1
- package/lib/dependencies/CriticalDependencyWarning.js +3 -0
- package/lib/dependencies/CssExportDependency.js +8 -0
- package/lib/dependencies/CssImportDependency.js +55 -3
- package/lib/dependencies/CssLocalIdentifierDependency.js +18 -1
- package/lib/dependencies/CssSelfLocalIdentifierDependency.js +10 -1
- package/lib/dependencies/CssUrlDependency.js +46 -16
- package/lib/dependencies/DelegatedSourceDependency.js +3 -0
- package/lib/dependencies/DllEntryDependency.js +14 -0
- package/lib/dependencies/DynamicExports.js +10 -6
- package/lib/dependencies/ExportsInfoDependency.js +25 -4
- package/lib/dependencies/HarmonyAcceptDependency.js +10 -1
- package/lib/dependencies/HarmonyAcceptImportDependency.js +3 -0
- package/lib/dependencies/HarmonyCompatibilityDependency.js +2 -1
- package/lib/dependencies/HarmonyDetectionParserPlugin.js +22 -2
- package/lib/dependencies/HarmonyEvaluatedImportSpecifierDependency.js +32 -6
- package/lib/dependencies/HarmonyExportDependencyParserPlugin.js +5 -0
- package/lib/dependencies/HarmonyExportExpressionDependency.js +20 -3
- package/lib/dependencies/HarmonyExportHeaderDependency.js +13 -0
- package/lib/dependencies/HarmonyExportImportedSpecifierDependency.js +22 -6
- package/lib/dependencies/HarmonyExportInitFragment.js +2 -1
- package/lib/dependencies/HarmonyExportSpecifierDependency.js +12 -0
- package/lib/dependencies/HarmonyExports.js +11 -5
- package/lib/dependencies/HarmonyImportDependency.js +10 -1
- package/lib/dependencies/HarmonyImportDependencyParserPlugin.js +53 -22
- package/lib/dependencies/HarmonyImportSideEffectDependency.js +7 -2
- package/lib/dependencies/HarmonyImportSpecifierDependency.js +139 -16
- package/lib/dependencies/HarmonyModulesPlugin.js +23 -5
- package/lib/dependencies/HarmonyTopLevelThisParserPlugin.js +15 -3
- package/lib/dependencies/ImportContextDependency.js +15 -0
- package/lib/dependencies/ImportDependency.js +15 -4
- package/lib/dependencies/ImportEagerDependency.js +7 -4
- package/lib/dependencies/ImportMetaContextDependencyParserPlugin.js +51 -13
- package/lib/dependencies/ImportMetaContextPlugin.js +18 -5
- package/lib/dependencies/ImportMetaHotAcceptDependency.js +6 -0
- package/lib/dependencies/ImportMetaHotDeclineDependency.js +6 -0
- package/lib/dependencies/ImportMetaPlugin.js +103 -51
- package/lib/dependencies/ImportParserPlugin.js +83 -25
- package/lib/dependencies/ImportPlugin.js +21 -7
- package/lib/dependencies/ImportWeakDependency.js +7 -4
- package/lib/dependencies/JsonExportsDependency.js +9 -1
- package/lib/dependencies/LocalModule.js +16 -0
- package/lib/dependencies/LocalModuleDependency.js +15 -0
- package/lib/dependencies/LocalModulesHelpers.js +18 -0
- package/lib/dependencies/ModuleDecoratorDependency.js +8 -0
- package/lib/dependencies/ModuleDependency.js +9 -1
- package/lib/dependencies/ModuleDependencyTemplateAsId.js +2 -1
- package/lib/dependencies/ModuleHotAcceptDependency.js +6 -0
- package/lib/dependencies/ModuleHotDeclineDependency.js +6 -0
- package/lib/dependencies/PrefetchDependency.js +3 -0
- package/lib/dependencies/ProvidedDependency.js +14 -2
- package/lib/dependencies/PureExpressionDependency.js +10 -1
- package/lib/dependencies/RequireContextDependency.js +6 -0
- package/lib/dependencies/RequireContextDependencyParserPlugin.js +13 -5
- package/lib/dependencies/RequireContextPlugin.js +19 -6
- package/lib/dependencies/RequireEnsureDependenciesBlock.js +7 -0
- package/lib/dependencies/RequireEnsureDependenciesBlockParserPlugin.js +6 -1
- package/lib/dependencies/RequireEnsureDependency.js +16 -2
- package/lib/dependencies/RequireEnsureItemDependency.js +3 -0
- package/lib/dependencies/RequireEnsurePlugin.js +27 -7
- package/lib/dependencies/RequireHeaderDependency.js +14 -1
- package/lib/dependencies/RequireIncludeDependency.js +5 -0
- package/lib/dependencies/RequireIncludeDependencyParserPlugin.js +29 -5
- package/lib/dependencies/RequireIncludePlugin.js +25 -5
- package/lib/dependencies/RequireResolveContextDependency.js +17 -0
- package/lib/dependencies/RequireResolveDependency.js +6 -0
- package/lib/dependencies/RequireResolveHeaderDependency.js +18 -0
- package/lib/dependencies/RuntimeRequirementsDependency.js +8 -0
- package/lib/dependencies/StaticExportsDependency.js +8 -0
- package/lib/dependencies/SystemPlugin.js +48 -21
- package/lib/dependencies/SystemRuntimeModule.js +1 -1
- package/lib/dependencies/URLDependency.js +13 -4
- package/lib/dependencies/URLPlugin.js +31 -18
- package/lib/dependencies/UnsupportedDependency.js +13 -0
- package/lib/dependencies/WebAssemblyExportImportedDependency.js +14 -0
- package/lib/dependencies/WebAssemblyImportDependency.js +9 -1
- package/lib/dependencies/WebpackIsIncludedDependency.js +5 -0
- package/lib/dependencies/WorkerDependency.js +47 -3
- package/lib/dependencies/WorkerPlugin.js +105 -32
- package/lib/dependencies/getFunctionExpression.js +7 -0
- package/lib/esm/ExportWebpackRequireRuntimeModule.js +3 -2
- package/lib/esm/ModuleChunkFormatPlugin.js +21 -8
- package/lib/esm/ModuleChunkLoadingPlugin.js +9 -0
- package/lib/esm/ModuleChunkLoadingRuntimeModule.js +19 -12
- package/lib/hmr/HotModuleReplacementRuntimeModule.js +1 -1
- package/lib/hmr/LazyCompilationPlugin.js +14 -5
- package/lib/ids/ChunkModuleIdRangePlugin.js +11 -0
- package/lib/ids/DeterministicChunkIdsPlugin.js +11 -2
- package/lib/ids/DeterministicModuleIdsPlugin.js +11 -7
- package/lib/ids/HashedModuleIdsPlugin.js +9 -2
- package/lib/ids/IdHelpers.js +6 -0
- package/lib/ids/NamedChunkIdsPlugin.js +13 -1
- package/lib/ids/NamedModuleIdsPlugin.js +14 -3
- package/lib/ids/OccurrenceChunkIdsPlugin.js +6 -2
- package/lib/ids/OccurrenceModuleIdsPlugin.js +1 -1
- package/lib/ids/SyncModuleIdsPlugin.js +3 -2
- package/lib/index.js +8 -0
- package/lib/javascript/ArrayPushCallbackChunkFormatPlugin.js +3 -3
- package/lib/javascript/BasicEvaluatedExpression.js +137 -11
- package/lib/javascript/ChunkHelpers.js +2 -2
- package/lib/javascript/CommonJsChunkFormatPlugin.js +7 -3
- package/lib/javascript/EnableChunkLoadingPlugin.js +4 -0
- package/lib/javascript/JavascriptModulesPlugin.js +217 -198
- package/lib/javascript/JavascriptParser.js +941 -256
- package/lib/javascript/JavascriptParserHelpers.js +37 -15
- package/lib/javascript/StartupHelpers.js +2 -2
- package/lib/json/JsonData.js +26 -1
- package/lib/json/JsonGenerator.js +21 -7
- package/lib/json/JsonModulesPlugin.js +14 -5
- package/lib/json/JsonParser.js +27 -13
- package/lib/library/AbstractLibraryPlugin.js +4 -0
- package/lib/library/AmdLibraryPlugin.js +22 -6
- package/lib/library/AssignLibraryPlugin.js +19 -5
- package/lib/library/EnableLibraryPlugin.js +4 -0
- package/lib/library/ExportPropertyLibraryPlugin.js +4 -1
- package/lib/library/ModuleLibraryPlugin.js +8 -4
- package/lib/library/SystemLibraryPlugin.js +2 -1
- package/lib/library/UmdLibraryPlugin.js +24 -2
- package/lib/logging/runtime.js +1 -1
- package/lib/logging/truncateArgs.js +4 -0
- package/lib/node/CommonJsChunkLoadingPlugin.js +17 -2
- package/lib/node/NodeTargetPlugin.js +3 -0
- package/lib/node/NodeTemplatePlugin.js +10 -2
- package/lib/node/NodeWatchFileSystem.js +1 -1
- package/lib/node/ReadFileChunkLoadingRuntimeModule.js +18 -9
- package/lib/node/ReadFileCompileAsyncWasmPlugin.js +12 -2
- package/lib/node/ReadFileCompileWasmPlugin.js +21 -3
- package/lib/node/RequireChunkLoadingRuntimeModule.js +15 -8
- package/lib/node/nodeConsole.js +2 -4
- package/lib/optimize/AggressiveMergingPlugin.js +8 -0
- package/lib/optimize/AggressiveSplittingPlugin.js +9 -2
- package/lib/optimize/ConcatenatedModule.js +8 -6
- package/lib/optimize/EnsureChunkConditionsPlugin.js +3 -0
- package/lib/optimize/FlagIncludedChunksPlugin.js +11 -5
- package/lib/optimize/InnerGraph.js +5 -5
- package/lib/optimize/InnerGraphPlugin.js +57 -48
- package/lib/optimize/LimitChunkCountPlugin.js +29 -4
- package/lib/optimize/MangleExportsPlugin.js +1 -1
- package/lib/optimize/MinMaxSizeWarning.js +5 -0
- package/lib/optimize/ModuleConcatenationPlugin.js +59 -2
- package/lib/optimize/RealContentHashPlugin.js +86 -30
- package/lib/optimize/RemoveParentModulesPlugin.js +6 -0
- package/lib/optimize/RuntimeChunkPlugin.js +9 -1
- package/lib/optimize/SideEffectsFlagPlugin.js +53 -44
- package/lib/optimize/SplitChunksPlugin.js +71 -31
- package/lib/performance/SizeLimitsPlugin.js +7 -4
- package/lib/prefetch/ChunkPrefetchFunctionRuntimeModule.js +4 -2
- package/lib/prefetch/ChunkPrefetchPreloadPlugin.js +3 -1
- package/lib/prefetch/ChunkPrefetchStartupRuntimeModule.js +6 -3
- package/lib/prefetch/ChunkPrefetchTriggerRuntimeModule.js +4 -2
- package/lib/prefetch/ChunkPreloadTriggerRuntimeModule.js +4 -2
- package/lib/rules/BasicEffectRulePlugin.js +4 -0
- package/lib/rules/BasicMatcherRulePlugin.js +5 -0
- package/lib/rules/RuleSetCompiler.js +3 -3
- package/lib/rules/UseEffectRulePlugin.js +6 -4
- package/lib/runtime/AsyncModuleRuntimeModule.js +9 -6
- package/lib/runtime/AutoPublicPathRuntimeModule.js +16 -5
- package/lib/runtime/BaseUriRuntimeModule.js +8 -4
- package/lib/runtime/ChunkNameRuntimeModule.js +1 -1
- package/lib/runtime/CompatGetDefaultExportRuntimeModule.js +5 -2
- package/lib/runtime/CompatRuntimeModule.js +7 -2
- package/lib/runtime/CreateFakeNamespaceObjectRuntimeModule.js +5 -2
- package/lib/runtime/CreateScriptRuntimeModule.js +4 -2
- package/lib/runtime/CreateScriptUrlRuntimeModule.js +4 -2
- package/lib/runtime/DefinePropertyGettersRuntimeModule.js +5 -2
- package/lib/runtime/EnsureChunkRuntimeModule.js +18 -4
- package/lib/runtime/GetChunkFilenameRuntimeModule.js +45 -26
- package/lib/runtime/GetFullHashRuntimeModule.js +4 -3
- package/lib/runtime/GetMainFilenameRuntimeModule.js +5 -2
- package/lib/runtime/GetTrustedTypesPolicyRuntimeModule.js +27 -6
- package/lib/runtime/GlobalRuntimeModule.js +1 -1
- package/lib/runtime/HasOwnPropertyRuntimeModule.js +5 -2
- package/lib/runtime/LoadScriptRuntimeModule.js +65 -50
- package/lib/runtime/MakeNamespaceObjectRuntimeModule.js +5 -2
- package/lib/runtime/NonceRuntimeModule.js +1 -1
- package/lib/runtime/OnChunksLoadedRuntimeModule.js +4 -2
- package/lib/runtime/PublicPathRuntimeModule.js +9 -2
- package/lib/runtime/RelativeUrlRuntimeModule.js +5 -2
- package/lib/runtime/RuntimeIdRuntimeModule.js +6 -2
- package/lib/runtime/StartupChunkDependenciesPlugin.js +15 -0
- package/lib/runtime/StartupChunkDependenciesRuntimeModule.js +13 -4
- package/lib/runtime/StartupEntrypointRuntimeModule.js +11 -7
- package/lib/runtime/SystemContextRuntimeModule.js +1 -1
- package/lib/schemes/DataUriPlugin.js +16 -3
- package/lib/schemes/HttpUriPlugin.js +38 -0
- package/lib/serialization/ArraySerializer.js +22 -6
- package/lib/serialization/BinaryMiddleware.js +164 -1
- package/lib/serialization/DateObjectSerializer.js +15 -4
- package/lib/serialization/ErrorObjectSerializer.js +23 -8
- package/lib/serialization/FileMiddleware.js +17 -0
- package/lib/serialization/MapObjectSerializer.js +24 -8
- package/lib/serialization/NullPrototypeObjectSerializer.js +25 -8
- package/lib/serialization/ObjectMiddleware.js +33 -2
- package/lib/serialization/PlainObjectSerializer.js +23 -12
- package/lib/serialization/RegExpObjectSerializer.js +16 -5
- package/lib/serialization/SetObjectSerializer.js +21 -6
- package/lib/serialization/types.js +1 -1
- package/lib/sharing/ConsumeSharedFallbackDependency.js +3 -0
- package/lib/sharing/ConsumeSharedModule.js +13 -2
- package/lib/sharing/ConsumeSharedPlugin.js +4 -0
- package/lib/sharing/ConsumeSharedRuntimeModule.js +22 -7
- package/lib/sharing/ProvideSharedDependency.js +17 -0
- package/lib/sharing/ProvideSharedModule.js +11 -1
- package/lib/sharing/ProvideSharedModuleFactory.js +1 -1
- package/lib/sharing/ProvideSharedPlugin.js +22 -21
- package/lib/sharing/ShareRuntimeModule.js +19 -9
- package/lib/sharing/resolveMatchedConfigs.js +1 -1
- package/lib/sharing/utils.js +320 -7
- package/lib/stats/DefaultStatsFactoryPlugin.js +105 -29
- package/lib/stats/DefaultStatsPresetPlugin.js +9 -0
- package/lib/stats/DefaultStatsPrinterPlugin.js +43 -0
- package/lib/util/AsyncQueue.js +4 -2
- package/lib/util/LazySet.js +10 -2
- package/lib/util/MapHelpers.js +19 -5
- package/lib/util/ParallelismFactorCalculator.js +10 -0
- package/lib/util/Semaphore.js +1 -1
- package/lib/util/StackedCacheMap.js +7 -1
- package/lib/util/StringXor.js +51 -0
- package/lib/util/URLAbsoluteSpecifier.js +1 -1
- package/lib/util/binarySearchBounds.js +49 -0
- package/lib/util/compileBooleanMatcher.js +31 -0
- package/lib/util/createHash.js +35 -13
- package/lib/util/deprecation.js +18 -3
- package/lib/util/deterministicGrouping.js +50 -11
- package/lib/util/findGraphRoots.js +4 -2
- package/lib/util/hash/md4.js +2 -2
- package/lib/util/hash/xxhash64.js +1 -1
- package/lib/util/identifier.js +4 -0
- package/lib/util/internalSerializables.js +1 -0
- package/lib/util/makeSerializable.js +7 -0
- package/lib/util/memoize.js +3 -3
- package/lib/util/numberHash.js +75 -21
- package/lib/util/processAsyncTree.js +7 -1
- package/lib/util/propertyAccess.js +9 -54
- package/lib/util/propertyName.js +79 -0
- package/lib/util/registerExternalSerializer.js +1 -1
- package/lib/util/runtime.js +84 -21
- package/lib/util/semver.js +2 -1
- package/lib/util/serialization.js +10 -0
- package/lib/util/smartGrouping.js +1 -1
- package/lib/validateSchema.js +6 -2
- package/lib/wasm/EnableWasmLoadingPlugin.js +4 -0
- package/lib/wasm-async/AsyncWasmLoadingRuntimeModule.js +15 -2
- package/lib/wasm-async/AsyncWebAssemblyGenerator.js +9 -1
- package/lib/wasm-async/AsyncWebAssemblyJavascriptGenerator.js +14 -3
- package/lib/wasm-async/AsyncWebAssemblyModulesPlugin.js +28 -8
- package/lib/wasm-async/AsyncWebAssemblyParser.js +11 -4
- package/lib/wasm-sync/WasmChunkLoadingRuntimeModule.js +39 -8
- package/lib/wasm-sync/WasmFinalizeExportsPlugin.js +17 -6
- package/lib/wasm-sync/WebAssemblyGenerator.js +19 -5
- package/lib/wasm-sync/WebAssemblyJavascriptGenerator.js +1 -1
- package/lib/wasm-sync/WebAssemblyModulesPlugin.js +53 -43
- package/lib/wasm-sync/WebAssemblyParser.js +15 -4
- package/lib/wasm-sync/WebAssemblyUtils.js +1 -1
- package/lib/web/FetchCompileAsyncWasmPlugin.js +11 -1
- package/lib/web/FetchCompileWasmPlugin.js +59 -42
- package/lib/web/JsonpChunkLoadingPlugin.js +9 -0
- package/lib/web/JsonpChunkLoadingRuntimeModule.js +26 -9
- package/lib/webpack.js +12 -3
- package/lib/webworker/ImportScriptsChunkLoadingPlugin.js +9 -0
- package/lib/webworker/ImportScriptsChunkLoadingRuntimeModule.js +20 -17
- package/module.d.ts +55 -37
- package/package.json +59 -56
- package/schemas/WebpackOptions.check.js +1 -1
- package/schemas/WebpackOptions.json +133 -6
- package/schemas/plugins/ProgressPlugin.check.js +1 -1
- package/schemas/plugins/SourceMapDevToolPlugin.check.js +1 -1
- package/schemas/plugins/SourceMapDevToolPlugin.json +4 -0
- package/schemas/plugins/container/ContainerPlugin.check.js +1 -1
- package/schemas/plugins/container/ContainerPlugin.json +8 -0
- package/schemas/plugins/container/ModuleFederationPlugin.check.js +1 -1
- package/schemas/plugins/container/ModuleFederationPlugin.json +8 -0
- package/schemas/plugins/css/CssGeneratorOptions.json +1 -1
- package/schemas/plugins/css/CssParserOptions.json +1 -1
- package/schemas/plugins/sharing/SharePlugin.check.js +1 -1
- package/types.d.ts +1629 -683
@@ -16,48 +16,83 @@ const memoize = require("../util/memoize");
|
|
16
16
|
const BasicEvaluatedExpression = require("./BasicEvaluatedExpression");
|
17
17
|
|
18
18
|
/** @typedef {import("acorn").Options} AcornOptions */
|
19
|
-
/** @typedef {import("estree").
|
20
|
-
/** @typedef {import("estree").BinaryExpression}
|
21
|
-
/** @typedef {import("estree").BlockStatement}
|
22
|
-
/** @typedef {import("estree").SequenceExpression}
|
23
|
-
/** @typedef {import("estree").CallExpression}
|
24
|
-
/** @typedef {import("estree").
|
25
|
-
/** @typedef {import("estree").
|
26
|
-
/** @typedef {import("estree").
|
27
|
-
/** @typedef {import("estree").
|
28
|
-
/** @typedef {import("estree").
|
29
|
-
/** @typedef {import("estree").
|
30
|
-
/** @typedef {import("estree").
|
31
|
-
/** @typedef {import("estree").
|
32
|
-
/** @typedef {import("estree").
|
33
|
-
/** @typedef {import("estree").
|
34
|
-
/** @typedef {import("estree").
|
35
|
-
/** @typedef {import("estree").
|
36
|
-
/** @typedef {import("estree").
|
37
|
-
/** @typedef {import("estree").
|
38
|
-
/** @typedef {import("estree").
|
39
|
-
/** @typedef {import("estree").
|
40
|
-
/** @typedef {import("estree").
|
41
|
-
/** @typedef {import("estree").
|
42
|
-
/** @typedef {import("estree").
|
19
|
+
/** @typedef {import("estree").AssignmentExpression} AssignmentExpression */
|
20
|
+
/** @typedef {import("estree").BinaryExpression} BinaryExpression */
|
21
|
+
/** @typedef {import("estree").BlockStatement} BlockStatement */
|
22
|
+
/** @typedef {import("estree").SequenceExpression} SequenceExpression */
|
23
|
+
/** @typedef {import("estree").CallExpression} CallExpression */
|
24
|
+
/** @typedef {import("estree").BaseCallExpression} BaseCallExpression */
|
25
|
+
/** @typedef {import("estree").StaticBlock} StaticBlock */
|
26
|
+
/** @typedef {import("estree").ImportExpression} ImportExpression */
|
27
|
+
/** @typedef {import("estree").ClassDeclaration} ClassDeclaration */
|
28
|
+
/** @typedef {import("estree").ForStatement} ForStatement */
|
29
|
+
/** @typedef {import("estree").SwitchStatement} SwitchStatement */
|
30
|
+
/** @typedef {import("estree").ExportNamedDeclaration} ExportNamedDeclaration */
|
31
|
+
/** @typedef {import("estree").ClassExpression} ClassExpression */
|
32
|
+
/** @typedef {import("estree").Comment} Comment */
|
33
|
+
/** @typedef {import("estree").ConditionalExpression} ConditionalExpression */
|
34
|
+
/** @typedef {import("estree").Declaration} Declaration */
|
35
|
+
/** @typedef {import("estree").PrivateIdentifier} PrivateIdentifier */
|
36
|
+
/** @typedef {import("estree").PropertyDefinition} PropertyDefinition */
|
37
|
+
/** @typedef {import("estree").Expression} Expression */
|
38
|
+
/** @typedef {import("estree").Identifier} Identifier */
|
39
|
+
/** @typedef {import("estree").VariableDeclaration} VariableDeclaration */
|
40
|
+
/** @typedef {import("estree").IfStatement} IfStatement */
|
41
|
+
/** @typedef {import("estree").LabeledStatement} LabeledStatement */
|
42
|
+
/** @typedef {import("estree").Literal} Literal */
|
43
|
+
/** @typedef {import("estree").LogicalExpression} LogicalExpression */
|
44
|
+
/** @typedef {import("estree").ChainExpression} ChainExpression */
|
45
|
+
/** @typedef {import("estree").MemberExpression} MemberExpression */
|
46
|
+
/** @typedef {import("estree").YieldExpression} YieldExpression */
|
47
|
+
/** @typedef {import("estree").MetaProperty} MetaProperty */
|
48
|
+
/** @typedef {import("estree").Property} Property */
|
49
|
+
/** @typedef {import("estree").AssignmentPattern} AssignmentPattern */
|
50
|
+
/** @typedef {import("estree").ChainElement} ChainElement */
|
51
|
+
/** @typedef {import("estree").Pattern} Pattern */
|
52
|
+
/** @typedef {import("estree").UpdateExpression} UpdateExpression */
|
53
|
+
/** @typedef {import("estree").ObjectExpression} ObjectExpression */
|
54
|
+
/** @typedef {import("estree").UnaryExpression} UnaryExpression */
|
55
|
+
/** @typedef {import("estree").ArrayExpression} ArrayExpression */
|
56
|
+
/** @typedef {import("estree").ArrayPattern} ArrayPattern */
|
57
|
+
/** @typedef {import("estree").AwaitExpression} AwaitExpression */
|
58
|
+
/** @typedef {import("estree").ThisExpression} ThisExpression */
|
59
|
+
/** @typedef {import("estree").RestElement} RestElement */
|
60
|
+
/** @typedef {import("estree").ObjectPattern} ObjectPattern */
|
61
|
+
/** @typedef {import("estree").SwitchCase} SwitchCase */
|
62
|
+
/** @typedef {import("estree").CatchClause} CatchClause */
|
63
|
+
/** @typedef {import("estree").VariableDeclarator} VariableDeclarator */
|
64
|
+
/** @typedef {import("estree").ForInStatement} ForInStatement */
|
65
|
+
/** @typedef {import("estree").ForOfStatement} ForOfStatement */
|
66
|
+
/** @typedef {import("estree").ReturnStatement} ReturnStatement */
|
67
|
+
/** @typedef {import("estree").WithStatement} WithStatement */
|
68
|
+
/** @typedef {import("estree").ThrowStatement} ThrowStatement */
|
69
|
+
/** @typedef {import("estree").MethodDefinition} MethodDefinition */
|
70
|
+
/** @typedef {import("estree").ModuleDeclaration} ModuleDeclaration */
|
71
|
+
/** @typedef {import("estree").NewExpression} NewExpression */
|
72
|
+
/** @typedef {import("estree").SpreadElement} SpreadElement */
|
73
|
+
/** @typedef {import("estree").FunctionExpression} FunctionExpression */
|
74
|
+
/** @typedef {import("estree").WhileStatement} WhileStatement */
|
75
|
+
/** @typedef {import("estree").ArrowFunctionExpression} ArrowFunctionExpression */
|
76
|
+
/** @typedef {import("estree").ExpressionStatement} ExpressionStatement */
|
77
|
+
/** @typedef {import("estree").FunctionDeclaration} FunctionDeclaration */
|
78
|
+
/** @typedef {import("estree").DoWhileStatement} DoWhileStatement */
|
79
|
+
/** @typedef {import("estree").TryStatement} TryStatement */
|
43
80
|
/** @typedef {import("estree").Node} AnyNode */
|
44
|
-
/** @typedef {import("estree").Program}
|
45
|
-
/** @typedef {import("estree").
|
46
|
-
/** @typedef {import("estree").
|
47
|
-
/** @typedef {import("estree").
|
48
|
-
/** @typedef {import("estree").ExportDefaultDeclaration}
|
49
|
-
/** @typedef {import("estree").ExportAllDeclaration}
|
50
|
-
/** @typedef {import("estree").Super}
|
51
|
-
/** @typedef {import("estree").TaggedTemplateExpression}
|
52
|
-
/** @typedef {import("estree").TemplateLiteral}
|
53
|
-
/** @typedef {
|
54
|
-
/** @typedef {import("estree").UnaryExpression} UnaryExpressionNode */
|
55
|
-
/** @typedef {import("estree").VariableDeclarator} VariableDeclaratorNode */
|
81
|
+
/** @typedef {import("estree").Program} Program */
|
82
|
+
/** @typedef {import("estree").Directive} Directive */
|
83
|
+
/** @typedef {import("estree").Statement} Statement */
|
84
|
+
/** @typedef {import("estree").ImportDeclaration} ImportDeclaration */
|
85
|
+
/** @typedef {import("estree").ExportDefaultDeclaration} ExportDefaultDeclaration */
|
86
|
+
/** @typedef {import("estree").ExportAllDeclaration} ExportAllDeclaration */
|
87
|
+
/** @typedef {import("estree").Super} Super */
|
88
|
+
/** @typedef {import("estree").TaggedTemplateExpression} TaggedTemplateExpression */
|
89
|
+
/** @typedef {import("estree").TemplateLiteral} TemplateLiteral */
|
90
|
+
/** @typedef {Record<string, any>} Assertions */
|
56
91
|
/** @template T @typedef {import("tapable").AsArray<T>} AsArray<T> */
|
57
92
|
/** @typedef {import("../Parser").ParserState} ParserState */
|
58
93
|
/** @typedef {import("../Parser").PreparsedAst} PreparsedAst */
|
59
94
|
/** @typedef {{declaredScope: ScopeInfo, freeName: string | true, tagInfo: TagInfo | undefined}} VariableInfoInterface */
|
60
|
-
/** @typedef {{ name: string | VariableInfo, rootInfo: string | VariableInfo, getMembers: () => string[], getMembersOptionals: () => boolean[] }} GetInfoResult */
|
95
|
+
/** @typedef {{ name: string | VariableInfo, rootInfo: string | VariableInfo, getMembers: () => string[], getMembersOptionals: () => boolean[], getMemberRanges: () => Range[] }} GetInfoResult */
|
61
96
|
|
62
97
|
const EMPTY_ARRAY = [];
|
63
98
|
const ALLOWED_MEMBER_TYPES_CALL_EXPRESSION = 0b01;
|
@@ -71,7 +106,7 @@ const parser = AcornParser.extend(importAssertions);
|
|
71
106
|
class VariableInfo {
|
72
107
|
/**
|
73
108
|
* @param {ScopeInfo} declaredScope scope in which the variable is declared
|
74
|
-
* @param {string | true} freeName which free name the variable aliases, or true when none
|
109
|
+
* @param {string | true | undefined} freeName which free name the variable aliases, or true when none
|
75
110
|
* @param {TagInfo | undefined} tagInfo info about tags
|
76
111
|
*/
|
77
112
|
constructor(declaredScope, freeName, tagInfo) {
|
@@ -82,7 +117,7 @@ class VariableInfo {
|
|
82
117
|
}
|
83
118
|
|
84
119
|
/** @typedef {string | ScopeInfo | VariableInfo} ExportedVariableInfo */
|
85
|
-
/** @typedef {
|
120
|
+
/** @typedef {Literal | string | null | undefined} ImportSource */
|
86
121
|
/** @typedef {Omit<AcornOptions, "sourceType" | "ecmaVersion"> & { sourceType: "module" | "script" | "auto", ecmaVersion?: AcornOptions["ecmaVersion"] }} ParseOptions */
|
87
122
|
|
88
123
|
/**
|
@@ -96,18 +131,55 @@ class VariableInfo {
|
|
96
131
|
* @typedef {Object} ScopeInfo
|
97
132
|
* @property {StackedMap<string, VariableInfo | ScopeInfo>} definitions
|
98
133
|
* @property {boolean | "arrow"} topLevelScope
|
99
|
-
* @property {boolean} inShorthand
|
134
|
+
* @property {boolean | string} inShorthand
|
135
|
+
* @property {boolean} inTaggedTemplateTag
|
136
|
+
* @property {boolean} inTry
|
100
137
|
* @property {boolean} isStrict
|
101
138
|
* @property {boolean} isAsmJs
|
102
|
-
* @property {boolean} inTry
|
103
139
|
*/
|
104
140
|
|
141
|
+
/** @typedef {[number, number]} Range */
|
142
|
+
|
143
|
+
/**
|
144
|
+
* Helper function for joining two ranges into a single range. This is useful
|
145
|
+
* when working with AST nodes, as it allows you to combine the ranges of child nodes
|
146
|
+
* to create the range of the _parent node_.
|
147
|
+
*
|
148
|
+
* @param {[number, number]} startRange start range to join
|
149
|
+
* @param {[number, number]} endRange end range to join
|
150
|
+
* @returns {[number, number]} joined range
|
151
|
+
*
|
152
|
+
* @example
|
153
|
+
* ```js
|
154
|
+
* const startRange = [0, 5];
|
155
|
+
* const endRange = [10, 15];
|
156
|
+
* const joinedRange = joinRanges(startRange, endRange);
|
157
|
+
* console.log(joinedRange); // [0, 15]
|
158
|
+
* ```
|
159
|
+
*
|
160
|
+
*/
|
105
161
|
const joinRanges = (startRange, endRange) => {
|
106
162
|
if (!endRange) return startRange;
|
107
163
|
if (!startRange) return endRange;
|
108
164
|
return [startRange[0], endRange[1]];
|
109
165
|
};
|
110
166
|
|
167
|
+
/**
|
168
|
+
* Helper function used to generate a string representation of a
|
169
|
+
* [member expression](https://github.com/estree/estree/blob/master/es5.md#memberexpression).
|
170
|
+
*
|
171
|
+
* @param {string} object object to name
|
172
|
+
* @param {string[]} membersReversed reversed list of members
|
173
|
+
* @returns {string} member expression as a string
|
174
|
+
* @example
|
175
|
+
* ```js
|
176
|
+
* const membersReversed = ["property1", "property2", "property3"]; // Members parsed from the AST
|
177
|
+
* const name = objectAndMembersToName("myObject", membersReversed);
|
178
|
+
*
|
179
|
+
* console.log(name); // "myObject.property1.property2.property3"
|
180
|
+
* ```
|
181
|
+
*
|
182
|
+
*/
|
111
183
|
const objectAndMembersToName = (object, membersReversed) => {
|
112
184
|
let name = object;
|
113
185
|
for (let i = membersReversed.length - 1; i >= 0; i--) {
|
@@ -116,6 +188,16 @@ const objectAndMembersToName = (object, membersReversed) => {
|
|
116
188
|
return name;
|
117
189
|
};
|
118
190
|
|
191
|
+
/**
|
192
|
+
* Grabs the name of a given expression and returns it as a string or undefined. Has particular
|
193
|
+
* handling for [Identifiers](https://github.com/estree/estree/blob/master/es5.md#identifier),
|
194
|
+
* [ThisExpressions](https://github.com/estree/estree/blob/master/es5.md#identifier), and
|
195
|
+
* [MetaProperties](https://github.com/estree/estree/blob/master/es2015.md#metaproperty) which is
|
196
|
+
* specifically for handling the `new.target` meta property.
|
197
|
+
*
|
198
|
+
* @param {Expression | Super} expression expression
|
199
|
+
* @returns {string | "this" | undefined} name or variable info
|
200
|
+
*/
|
119
201
|
const getRootName = expression => {
|
120
202
|
switch (expression.type) {
|
121
203
|
case "Identifier":
|
@@ -155,81 +237,81 @@ class JavascriptParser extends Parser {
|
|
155
237
|
constructor(sourceType = "auto") {
|
156
238
|
super();
|
157
239
|
this.hooks = Object.freeze({
|
158
|
-
/** @type {HookMap<SyncBailHook<[
|
240
|
+
/** @type {HookMap<SyncBailHook<[UnaryExpression], BasicEvaluatedExpression | undefined | null>>} */
|
159
241
|
evaluateTypeof: new HookMap(() => new SyncBailHook(["expression"])),
|
160
|
-
/** @type {HookMap<SyncBailHook<[
|
242
|
+
/** @type {HookMap<SyncBailHook<[Expression], BasicEvaluatedExpression | undefined | null>>} */
|
161
243
|
evaluate: new HookMap(() => new SyncBailHook(["expression"])),
|
162
|
-
/** @type {HookMap<SyncBailHook<[
|
244
|
+
/** @type {HookMap<SyncBailHook<[Identifier | ThisExpression | MemberExpression | MetaProperty], BasicEvaluatedExpression | undefined | null>>} */
|
163
245
|
evaluateIdentifier: new HookMap(() => new SyncBailHook(["expression"])),
|
164
|
-
/** @type {HookMap<SyncBailHook<[
|
246
|
+
/** @type {HookMap<SyncBailHook<[Identifier | ThisExpression | MemberExpression], BasicEvaluatedExpression | undefined | null>>} */
|
165
247
|
evaluateDefinedIdentifier: new HookMap(
|
166
248
|
() => new SyncBailHook(["expression"])
|
167
249
|
),
|
168
|
-
/** @type {HookMap<SyncBailHook<[
|
250
|
+
/** @type {HookMap<SyncBailHook<[NewExpression], BasicEvaluatedExpression | undefined | null>>} */
|
169
251
|
evaluateNewExpression: new HookMap(
|
170
252
|
() => new SyncBailHook(["expression"])
|
171
253
|
),
|
172
|
-
/** @type {HookMap<SyncBailHook<[
|
254
|
+
/** @type {HookMap<SyncBailHook<[CallExpression], BasicEvaluatedExpression | undefined | null>>} */
|
173
255
|
evaluateCallExpression: new HookMap(
|
174
256
|
() => new SyncBailHook(["expression"])
|
175
257
|
),
|
176
|
-
/** @type {HookMap<SyncBailHook<[
|
258
|
+
/** @type {HookMap<SyncBailHook<[CallExpression, BasicEvaluatedExpression | undefined], BasicEvaluatedExpression | undefined | null>>} */
|
177
259
|
evaluateCallExpressionMember: new HookMap(
|
178
260
|
() => new SyncBailHook(["expression", "param"])
|
179
261
|
),
|
180
|
-
/** @type {HookMap<SyncBailHook<[
|
262
|
+
/** @type {HookMap<SyncBailHook<[Expression | Declaration | PrivateIdentifier, number], boolean | void>>} */
|
181
263
|
isPure: new HookMap(
|
182
264
|
() => new SyncBailHook(["expression", "commentsStartPosition"])
|
183
265
|
),
|
184
|
-
/** @type {SyncBailHook<[
|
266
|
+
/** @type {SyncBailHook<[Statement | ModuleDeclaration], boolean | void>} */
|
185
267
|
preStatement: new SyncBailHook(["statement"]),
|
186
268
|
|
187
|
-
/** @type {SyncBailHook<[
|
269
|
+
/** @type {SyncBailHook<[Statement | ModuleDeclaration], boolean | void>} */
|
188
270
|
blockPreStatement: new SyncBailHook(["declaration"]),
|
189
|
-
/** @type {SyncBailHook<[
|
271
|
+
/** @type {SyncBailHook<[Statement | ModuleDeclaration], boolean | void>} */
|
190
272
|
statement: new SyncBailHook(["statement"]),
|
191
|
-
/** @type {SyncBailHook<[
|
273
|
+
/** @type {SyncBailHook<[IfStatement], boolean | void>} */
|
192
274
|
statementIf: new SyncBailHook(["statement"]),
|
193
|
-
/** @type {SyncBailHook<[
|
275
|
+
/** @type {SyncBailHook<[Expression, ClassExpression | ClassDeclaration], boolean | void>} */
|
194
276
|
classExtendsExpression: new SyncBailHook([
|
195
277
|
"expression",
|
196
278
|
"classDefinition"
|
197
279
|
]),
|
198
|
-
/** @type {SyncBailHook<[
|
280
|
+
/** @type {SyncBailHook<[MethodDefinition | PropertyDefinition | StaticBlock, ClassExpression | ClassDeclaration], boolean | void>} */
|
199
281
|
classBodyElement: new SyncBailHook(["element", "classDefinition"]),
|
200
|
-
/** @type {SyncBailHook<[
|
282
|
+
/** @type {SyncBailHook<[Expression, MethodDefinition | PropertyDefinition, ClassExpression | ClassDeclaration], boolean | void>} */
|
201
283
|
classBodyValue: new SyncBailHook([
|
202
284
|
"expression",
|
203
285
|
"element",
|
204
286
|
"classDefinition"
|
205
287
|
]),
|
206
|
-
/** @type {HookMap<SyncBailHook<[
|
288
|
+
/** @type {HookMap<SyncBailHook<[LabeledStatement], boolean | void>>} */
|
207
289
|
label: new HookMap(() => new SyncBailHook(["statement"])),
|
208
|
-
/** @type {SyncBailHook<[
|
290
|
+
/** @type {SyncBailHook<[ImportDeclaration, ImportSource], boolean | void>} */
|
209
291
|
import: new SyncBailHook(["statement", "source"]),
|
210
|
-
/** @type {SyncBailHook<[
|
292
|
+
/** @type {SyncBailHook<[ImportDeclaration, ImportSource, string, string], boolean | void>} */
|
211
293
|
importSpecifier: new SyncBailHook([
|
212
294
|
"statement",
|
213
295
|
"source",
|
214
296
|
"exportName",
|
215
297
|
"identifierName"
|
216
298
|
]),
|
217
|
-
/** @type {SyncBailHook<[
|
299
|
+
/** @type {SyncBailHook<[ExportNamedDeclaration | ExportAllDeclaration], boolean | void>} */
|
218
300
|
export: new SyncBailHook(["statement"]),
|
219
|
-
/** @type {SyncBailHook<[
|
301
|
+
/** @type {SyncBailHook<[ExportNamedDeclaration | ExportAllDeclaration, ImportSource], boolean | void>} */
|
220
302
|
exportImport: new SyncBailHook(["statement", "source"]),
|
221
|
-
/** @type {SyncBailHook<[
|
303
|
+
/** @type {SyncBailHook<[ExportNamedDeclaration | ExportAllDeclaration, Declaration], boolean | void>} */
|
222
304
|
exportDeclaration: new SyncBailHook(["statement", "declaration"]),
|
223
|
-
/** @type {SyncBailHook<[
|
305
|
+
/** @type {SyncBailHook<[ExportDefaultDeclaration, Declaration], boolean | void>} */
|
224
306
|
exportExpression: new SyncBailHook(["statement", "declaration"]),
|
225
|
-
/** @type {SyncBailHook<[
|
307
|
+
/** @type {SyncBailHook<[ExportNamedDeclaration | ExportAllDeclaration, string, string, number | undefined], boolean | void>} */
|
226
308
|
exportSpecifier: new SyncBailHook([
|
227
309
|
"statement",
|
228
310
|
"identifierName",
|
229
311
|
"exportName",
|
230
312
|
"index"
|
231
313
|
]),
|
232
|
-
/** @type {SyncBailHook<[
|
314
|
+
/** @type {SyncBailHook<[ExportNamedDeclaration | ExportAllDeclaration, ImportSource, string, string, number | undefined], boolean | void>} */
|
233
315
|
exportImportSpecifier: new SyncBailHook([
|
234
316
|
"statement",
|
235
317
|
"source",
|
@@ -237,45 +319,51 @@ class JavascriptParser extends Parser {
|
|
237
319
|
"exportName",
|
238
320
|
"index"
|
239
321
|
]),
|
240
|
-
/** @type {SyncBailHook<[
|
322
|
+
/** @type {SyncBailHook<[VariableDeclarator, Statement], boolean | void>} */
|
241
323
|
preDeclarator: new SyncBailHook(["declarator", "statement"]),
|
242
|
-
/** @type {SyncBailHook<[
|
324
|
+
/** @type {SyncBailHook<[VariableDeclarator, Statement], boolean | void>} */
|
243
325
|
declarator: new SyncBailHook(["declarator", "statement"]),
|
244
|
-
/** @type {HookMap<SyncBailHook<[
|
326
|
+
/** @type {HookMap<SyncBailHook<[Declaration], boolean | void>>} */
|
245
327
|
varDeclaration: new HookMap(() => new SyncBailHook(["declaration"])),
|
246
|
-
/** @type {HookMap<SyncBailHook<[
|
328
|
+
/** @type {HookMap<SyncBailHook<[Declaration], boolean | void>>} */
|
247
329
|
varDeclarationLet: new HookMap(() => new SyncBailHook(["declaration"])),
|
248
|
-
/** @type {HookMap<SyncBailHook<[
|
330
|
+
/** @type {HookMap<SyncBailHook<[Declaration], boolean | void>>} */
|
249
331
|
varDeclarationConst: new HookMap(() => new SyncBailHook(["declaration"])),
|
250
|
-
/** @type {HookMap<SyncBailHook<[
|
332
|
+
/** @type {HookMap<SyncBailHook<[Declaration], boolean | void>>} */
|
251
333
|
varDeclarationVar: new HookMap(() => new SyncBailHook(["declaration"])),
|
252
|
-
/** @type {HookMap<SyncBailHook<[
|
334
|
+
/** @type {HookMap<SyncBailHook<[Identifier], boolean | void>>} */
|
253
335
|
pattern: new HookMap(() => new SyncBailHook(["pattern"])),
|
254
|
-
/** @type {HookMap<SyncBailHook<[
|
336
|
+
/** @type {HookMap<SyncBailHook<[Expression], boolean | void>>} */
|
255
337
|
canRename: new HookMap(() => new SyncBailHook(["initExpression"])),
|
256
|
-
/** @type {HookMap<SyncBailHook<[
|
338
|
+
/** @type {HookMap<SyncBailHook<[Expression], boolean | void>>} */
|
257
339
|
rename: new HookMap(() => new SyncBailHook(["initExpression"])),
|
258
|
-
/** @type {HookMap<SyncBailHook<[
|
340
|
+
/** @type {HookMap<SyncBailHook<[AssignmentExpression], boolean | void>>} */
|
259
341
|
assign: new HookMap(() => new SyncBailHook(["expression"])),
|
260
|
-
/** @type {HookMap<SyncBailHook<[
|
342
|
+
/** @type {HookMap<SyncBailHook<[AssignmentExpression, string[]], boolean | void>>} */
|
261
343
|
assignMemberChain: new HookMap(
|
262
344
|
() => new SyncBailHook(["expression", "members"])
|
263
345
|
),
|
264
|
-
/** @type {HookMap<SyncBailHook<[
|
346
|
+
/** @type {HookMap<SyncBailHook<[Expression], boolean | void>>} */
|
265
347
|
typeof: new HookMap(() => new SyncBailHook(["expression"])),
|
266
|
-
/** @type {SyncBailHook<[
|
348
|
+
/** @type {SyncBailHook<[ImportExpression], boolean | void>} */
|
267
349
|
importCall: new SyncBailHook(["expression"]),
|
268
|
-
/** @type {SyncBailHook<[
|
350
|
+
/** @type {SyncBailHook<[Expression], boolean | void>} */
|
269
351
|
topLevelAwait: new SyncBailHook(["expression"]),
|
270
|
-
/** @type {HookMap<SyncBailHook<[
|
352
|
+
/** @type {HookMap<SyncBailHook<[CallExpression], boolean | void>>} */
|
271
353
|
call: new HookMap(() => new SyncBailHook(["expression"])),
|
272
354
|
/** Something like "a.b()" */
|
273
|
-
/** @type {HookMap<SyncBailHook<[
|
355
|
+
/** @type {HookMap<SyncBailHook<[CallExpression, string[], boolean[], Range[]], boolean | void>>} */
|
274
356
|
callMemberChain: new HookMap(
|
275
|
-
() =>
|
357
|
+
() =>
|
358
|
+
new SyncBailHook([
|
359
|
+
"expression",
|
360
|
+
"members",
|
361
|
+
"membersOptionals",
|
362
|
+
"memberRanges"
|
363
|
+
])
|
276
364
|
),
|
277
365
|
/** Something like "a.b().c.d" */
|
278
|
-
/** @type {HookMap<SyncBailHook<[
|
366
|
+
/** @type {HookMap<SyncBailHook<[Expression, string[], CallExpression, string[]], boolean | void>>} */
|
279
367
|
memberChainOfCallMemberChain: new HookMap(
|
280
368
|
() =>
|
281
369
|
new SyncBailHook([
|
@@ -286,7 +374,7 @@ class JavascriptParser extends Parser {
|
|
286
374
|
])
|
287
375
|
),
|
288
376
|
/** Something like "a.b().c.d()"" */
|
289
|
-
/** @type {HookMap<SyncBailHook<[
|
377
|
+
/** @type {HookMap<SyncBailHook<[CallExpression, string[], CallExpression, string[]], boolean | void>>} */
|
290
378
|
callMemberChainOfCallMemberChain: new HookMap(
|
291
379
|
() =>
|
292
380
|
new SyncBailHook([
|
@@ -296,29 +384,35 @@ class JavascriptParser extends Parser {
|
|
296
384
|
"members"
|
297
385
|
])
|
298
386
|
),
|
299
|
-
/** @type {SyncBailHook<[
|
387
|
+
/** @type {SyncBailHook<[ChainExpression], boolean | void>} */
|
300
388
|
optionalChaining: new SyncBailHook(["optionalChaining"]),
|
301
|
-
/** @type {HookMap<SyncBailHook<[
|
389
|
+
/** @type {HookMap<SyncBailHook<[NewExpression], boolean | void>>} */
|
302
390
|
new: new HookMap(() => new SyncBailHook(["expression"])),
|
303
|
-
/** @type {SyncBailHook<[
|
391
|
+
/** @type {SyncBailHook<[BinaryExpression], boolean | void>} */
|
304
392
|
binaryExpression: new SyncBailHook(["binaryExpression"]),
|
305
|
-
/** @type {HookMap<SyncBailHook<[
|
393
|
+
/** @type {HookMap<SyncBailHook<[Expression], boolean | void>>} */
|
306
394
|
expression: new HookMap(() => new SyncBailHook(["expression"])),
|
307
|
-
/** @type {HookMap<SyncBailHook<[
|
395
|
+
/** @type {HookMap<SyncBailHook<[MemberExpression, string[], boolean[], Range[]], boolean | void>>} */
|
308
396
|
expressionMemberChain: new HookMap(
|
309
|
-
() =>
|
397
|
+
() =>
|
398
|
+
new SyncBailHook([
|
399
|
+
"expression",
|
400
|
+
"members",
|
401
|
+
"membersOptionals",
|
402
|
+
"memberRanges"
|
403
|
+
])
|
310
404
|
),
|
311
|
-
/** @type {HookMap<SyncBailHook<[
|
405
|
+
/** @type {HookMap<SyncBailHook<[MemberExpression, string[]], boolean | void>>} */
|
312
406
|
unhandledExpressionMemberChain: new HookMap(
|
313
407
|
() => new SyncBailHook(["expression", "members"])
|
314
408
|
),
|
315
|
-
/** @type {SyncBailHook<[
|
409
|
+
/** @type {SyncBailHook<[ConditionalExpression], boolean | void>} */
|
316
410
|
expressionConditionalOperator: new SyncBailHook(["expression"]),
|
317
|
-
/** @type {SyncBailHook<[
|
411
|
+
/** @type {SyncBailHook<[LogicalExpression], boolean | void>} */
|
318
412
|
expressionLogicalOperator: new SyncBailHook(["expression"]),
|
319
|
-
/** @type {SyncBailHook<[
|
413
|
+
/** @type {SyncBailHook<[Program, Comment[]], boolean | void>} */
|
320
414
|
program: new SyncBailHook(["ast", "comments"]),
|
321
|
-
/** @type {SyncBailHook<[
|
415
|
+
/** @type {SyncBailHook<[Program, Comment[]], boolean | void>} */
|
322
416
|
finish: new SyncBailHook(["ast", "comments"])
|
323
417
|
});
|
324
418
|
this.sourceType = sourceType;
|
@@ -328,46 +422,51 @@ class JavascriptParser extends Parser {
|
|
328
422
|
this.state = undefined;
|
329
423
|
this.comments = undefined;
|
330
424
|
this.semicolons = undefined;
|
331
|
-
/** @type {(
|
425
|
+
/** @type {(Statement | ModuleDeclaration | Expression)[]} */
|
332
426
|
this.statementPath = undefined;
|
427
|
+
/** @type {Statement | ModuleDeclaration | Expression | undefined} */
|
333
428
|
this.prevStatement = undefined;
|
429
|
+
/** @type {WeakMap<Expression, Set<string>>} */
|
430
|
+
this.destructuringAssignmentProperties = undefined;
|
334
431
|
this.currentTagData = undefined;
|
335
432
|
this._initializeEvaluating();
|
336
433
|
}
|
337
434
|
|
338
435
|
_initializeEvaluating() {
|
339
436
|
this.hooks.evaluate.for("Literal").tap("JavascriptParser", _expr => {
|
340
|
-
const expr = /** @type {
|
437
|
+
const expr = /** @type {Literal} */ (_expr);
|
341
438
|
|
342
439
|
switch (typeof expr.value) {
|
343
440
|
case "number":
|
344
441
|
return new BasicEvaluatedExpression()
|
345
442
|
.setNumber(expr.value)
|
346
|
-
.setRange(expr.range);
|
443
|
+
.setRange(/** @type {Range} */ (expr.range));
|
347
444
|
case "bigint":
|
348
445
|
return new BasicEvaluatedExpression()
|
349
446
|
.setBigInt(expr.value)
|
350
|
-
.setRange(expr.range);
|
447
|
+
.setRange(/** @type {Range} */ (expr.range));
|
351
448
|
case "string":
|
352
449
|
return new BasicEvaluatedExpression()
|
353
450
|
.setString(expr.value)
|
354
|
-
.setRange(expr.range);
|
451
|
+
.setRange(/** @type {Range} */ (expr.range));
|
355
452
|
case "boolean":
|
356
453
|
return new BasicEvaluatedExpression()
|
357
454
|
.setBoolean(expr.value)
|
358
|
-
.setRange(expr.range);
|
455
|
+
.setRange(/** @type {Range} */ (expr.range));
|
359
456
|
}
|
360
457
|
if (expr.value === null) {
|
361
|
-
return new BasicEvaluatedExpression()
|
458
|
+
return new BasicEvaluatedExpression()
|
459
|
+
.setNull()
|
460
|
+
.setRange(/** @type {Range} */ (expr.range));
|
362
461
|
}
|
363
462
|
if (expr.value instanceof RegExp) {
|
364
463
|
return new BasicEvaluatedExpression()
|
365
464
|
.setRegExp(expr.value)
|
366
|
-
.setRange(expr.range);
|
465
|
+
.setRange(/** @type {Range} */ (expr.range));
|
367
466
|
}
|
368
467
|
});
|
369
468
|
this.hooks.evaluate.for("NewExpression").tap("JavascriptParser", _expr => {
|
370
|
-
const expr = /** @type {
|
469
|
+
const expr = /** @type {NewExpression} */ (_expr);
|
371
470
|
const callee = expr.callee;
|
372
471
|
if (callee.type !== "Identifier") return;
|
373
472
|
if (callee.name !== "RegExp") {
|
@@ -398,7 +497,7 @@ class JavascriptParser extends Parser {
|
|
398
497
|
} else {
|
399
498
|
return new BasicEvaluatedExpression()
|
400
499
|
.setRegExp(new RegExp(""))
|
401
|
-
.setRange(expr.range);
|
500
|
+
.setRange(/** @type {Range} */ (expr.range));
|
402
501
|
}
|
403
502
|
|
404
503
|
const arg2 = expr.arguments[1];
|
@@ -423,12 +522,12 @@ class JavascriptParser extends Parser {
|
|
423
522
|
|
424
523
|
return new BasicEvaluatedExpression()
|
425
524
|
.setRegExp(flags ? new RegExp(regExp, flags) : new RegExp(regExp))
|
426
|
-
.setRange(expr.range);
|
525
|
+
.setRange(/** @type {Range} */ (expr.range));
|
427
526
|
});
|
428
527
|
this.hooks.evaluate
|
429
528
|
.for("LogicalExpression")
|
430
529
|
.tap("JavascriptParser", _expr => {
|
431
|
-
const expr = /** @type {
|
530
|
+
const expr = /** @type {LogicalExpression} */ (_expr);
|
432
531
|
|
433
532
|
const left = this.evaluateExpression(expr.left);
|
434
533
|
let returnRight = false;
|
@@ -467,44 +566,94 @@ class JavascriptParser extends Parser {
|
|
467
566
|
}
|
468
567
|
});
|
469
568
|
|
569
|
+
/**
|
570
|
+
* In simple logical cases, we can use valueAsExpression to assist us in evaluating the expression on
|
571
|
+
* either side of a [BinaryExpression](https://github.com/estree/estree/blob/master/es5.md#binaryexpression).
|
572
|
+
* This supports scenarios in webpack like conditionally `import()`'ing modules based on some simple evaluation:
|
573
|
+
*
|
574
|
+
* ```js
|
575
|
+
* if (1 === 3) {
|
576
|
+
* import("./moduleA"); // webpack will auto evaluate this and not import the modules
|
577
|
+
* }
|
578
|
+
* ```
|
579
|
+
*
|
580
|
+
* Additional scenarios include evaluation of strings inside of dynamic import statements:
|
581
|
+
*
|
582
|
+
* ```js
|
583
|
+
* const foo = "foo";
|
584
|
+
* const bar = "bar";
|
585
|
+
*
|
586
|
+
* import("./" + foo + bar); // webpack will auto evaluate this into import("./foobar")
|
587
|
+
* ```
|
588
|
+
* @param {boolean | number | BigInt | string} value the value to convert to an expression
|
589
|
+
* @param {BinaryExpression | UnaryExpression} expr the expression being evaluated
|
590
|
+
* @param {boolean} sideEffects whether the expression has side effects
|
591
|
+
* @returns {BasicEvaluatedExpression | undefined} the evaluated expression
|
592
|
+
* @example
|
593
|
+
*
|
594
|
+
* ```js
|
595
|
+
* const binaryExpr = new BinaryExpression("+",
|
596
|
+
* { type: "Literal", value: 2 },
|
597
|
+
* { type: "Literal", value: 3 }
|
598
|
+
* );
|
599
|
+
*
|
600
|
+
* const leftValue = 2;
|
601
|
+
* const rightValue = 3;
|
602
|
+
*
|
603
|
+
* const leftExpr = valueAsExpression(leftValue, binaryExpr.left, false);
|
604
|
+
* const rightExpr = valueAsExpression(rightValue, binaryExpr.right, false);
|
605
|
+
* const result = new BasicEvaluatedExpression()
|
606
|
+
* .setNumber(leftExpr.number + rightExpr.number)
|
607
|
+
* .setRange(binaryExpr.range);
|
608
|
+
*
|
609
|
+
* console.log(result.number); // Output: 5
|
610
|
+
* ```
|
611
|
+
*/
|
470
612
|
const valueAsExpression = (value, expr, sideEffects) => {
|
471
613
|
switch (typeof value) {
|
472
614
|
case "boolean":
|
473
615
|
return new BasicEvaluatedExpression()
|
474
616
|
.setBoolean(value)
|
475
617
|
.setSideEffects(sideEffects)
|
476
|
-
.setRange(expr.range);
|
618
|
+
.setRange(/** @type {Range} */ (expr.range));
|
477
619
|
case "number":
|
478
620
|
return new BasicEvaluatedExpression()
|
479
621
|
.setNumber(value)
|
480
622
|
.setSideEffects(sideEffects)
|
481
|
-
.setRange(expr.range);
|
623
|
+
.setRange(/** @type {Range} */ (expr.range));
|
482
624
|
case "bigint":
|
483
625
|
return new BasicEvaluatedExpression()
|
484
626
|
.setBigInt(value)
|
485
627
|
.setSideEffects(sideEffects)
|
486
|
-
.setRange(expr.range);
|
628
|
+
.setRange(/** @type {Range} */ (expr.range));
|
487
629
|
case "string":
|
488
630
|
return new BasicEvaluatedExpression()
|
489
631
|
.setString(value)
|
490
632
|
.setSideEffects(sideEffects)
|
491
|
-
.setRange(expr.range);
|
633
|
+
.setRange(/** @type {Range} */ (expr.range));
|
492
634
|
}
|
493
635
|
};
|
494
636
|
|
495
637
|
this.hooks.evaluate
|
496
638
|
.for("BinaryExpression")
|
497
639
|
.tap("JavascriptParser", _expr => {
|
498
|
-
const expr = /** @type {
|
499
|
-
|
500
|
-
|
640
|
+
const expr = /** @type {BinaryExpression} */ (_expr);
|
641
|
+
|
642
|
+
/**
|
643
|
+
* Evaluates a binary expression if and only if it is a const operation (e.g. 1 + 2, "a" + "b", etc.).
|
644
|
+
*
|
645
|
+
* @template T
|
646
|
+
* @param {(leftOperand: T, rightOperand: T) => boolean | number | BigInt | string} operandHandler the handler for the operation (e.g. (a, b) => a + b)
|
647
|
+
* @returns {BasicEvaluatedExpression | undefined} the evaluated expression
|
648
|
+
*/
|
649
|
+
const handleConstOperation = operandHandler => {
|
501
650
|
const left = this.evaluateExpression(expr.left);
|
502
651
|
if (!left.isCompileTimeValue()) return;
|
503
652
|
|
504
653
|
const right = this.evaluateExpression(expr.right);
|
505
654
|
if (!right.isCompileTimeValue()) return;
|
506
655
|
|
507
|
-
const result =
|
656
|
+
const result = operandHandler(
|
508
657
|
left.asCompileTimeValue(),
|
509
658
|
right.asCompileTimeValue()
|
510
659
|
);
|
@@ -515,6 +664,14 @@ class JavascriptParser extends Parser {
|
|
515
664
|
);
|
516
665
|
};
|
517
666
|
|
667
|
+
/**
|
668
|
+
* Helper function to determine if two booleans are always different. This is used in `handleStrictEqualityComparison`
|
669
|
+
* to determine if an expressions boolean or nullish conversion is equal or not.
|
670
|
+
*
|
671
|
+
* @param {boolean} a first boolean to compare
|
672
|
+
* @param {boolean} b second boolean to compare
|
673
|
+
* @returns {boolean} true if the two booleans are always different, false otherwise
|
674
|
+
*/
|
518
675
|
const isAlwaysDifferent = (a, b) =>
|
519
676
|
(a === true && b === false) || (a === false && b === true);
|
520
677
|
|
@@ -543,11 +700,13 @@ class JavascriptParser extends Parser {
|
|
543
700
|
const rightSuffix = getSuffix(right.parts);
|
544
701
|
const lenPrefix = Math.min(leftPrefix.length, rightPrefix.length);
|
545
702
|
const lenSuffix = Math.min(leftSuffix.length, rightSuffix.length);
|
546
|
-
|
547
|
-
|
548
|
-
|
549
|
-
|
550
|
-
|
703
|
+
const prefixMismatch =
|
704
|
+
lenPrefix > 0 &&
|
705
|
+
leftPrefix.slice(0, lenPrefix) !== rightPrefix.slice(0, lenPrefix);
|
706
|
+
const suffixMismatch =
|
707
|
+
lenSuffix > 0 &&
|
708
|
+
leftSuffix.slice(-lenSuffix) !== rightSuffix.slice(-lenSuffix);
|
709
|
+
if (prefixMismatch || suffixMismatch) {
|
551
710
|
return res
|
552
711
|
.setBoolean(!eql)
|
553
712
|
.setSideEffects(
|
@@ -556,11 +715,16 @@ class JavascriptParser extends Parser {
|
|
556
715
|
}
|
557
716
|
};
|
558
717
|
|
718
|
+
/**
|
719
|
+
* Helper function to handle BinaryExpressions using strict equality comparisons (e.g. "===" and "!==").
|
720
|
+
* @param {boolean} eql true for "===" and false for "!=="
|
721
|
+
* @returns {BasicEvaluatedExpression | undefined} the evaluated expression
|
722
|
+
*/
|
559
723
|
const handleStrictEqualityComparison = eql => {
|
560
724
|
const left = this.evaluateExpression(expr.left);
|
561
725
|
const right = this.evaluateExpression(expr.right);
|
562
726
|
const res = new BasicEvaluatedExpression();
|
563
|
-
res.setRange(expr.range);
|
727
|
+
res.setRange(/** @type {Range} */ (expr.range));
|
564
728
|
|
565
729
|
const leftConst = left.isCompileTimeValue();
|
566
730
|
const rightConst = right.isCompileTimeValue();
|
@@ -598,8 +762,14 @@ class JavascriptParser extends Parser {
|
|
598
762
|
(rightPrimitive === false &&
|
599
763
|
(rightConst || leftPrimitive === true)) ||
|
600
764
|
// Different nullish or boolish status also means not equal
|
601
|
-
isAlwaysDifferent(
|
602
|
-
|
765
|
+
isAlwaysDifferent(
|
766
|
+
/** @type {boolean} */ (left.asBool()),
|
767
|
+
/** @type {boolean} */ (right.asBool())
|
768
|
+
) ||
|
769
|
+
isAlwaysDifferent(
|
770
|
+
/** @type {boolean} */ (left.asNullish()),
|
771
|
+
/** @type {boolean} */ (right.asNullish())
|
772
|
+
)
|
603
773
|
) {
|
604
774
|
return res
|
605
775
|
.setBoolean(!eql)
|
@@ -609,6 +779,11 @@ class JavascriptParser extends Parser {
|
|
609
779
|
}
|
610
780
|
};
|
611
781
|
|
782
|
+
/**
|
783
|
+
* Helper function to handle BinaryExpressions using abstract equality comparisons (e.g. "==" and "!=").
|
784
|
+
* @param {boolean} eql true for "==" and false for "!="
|
785
|
+
* @returns {BasicEvaluatedExpression | undefined} the evaluated expression
|
786
|
+
*/
|
612
787
|
const handleAbstractEqualityComparison = eql => {
|
613
788
|
const left = this.evaluateExpression(expr.left);
|
614
789
|
const right = this.evaluateExpression(expr.right);
|
@@ -819,12 +994,19 @@ class JavascriptParser extends Parser {
|
|
819
994
|
this.hooks.evaluate
|
820
995
|
.for("UnaryExpression")
|
821
996
|
.tap("JavascriptParser", _expr => {
|
822
|
-
const expr = /** @type {
|
823
|
-
|
824
|
-
|
997
|
+
const expr = /** @type {UnaryExpression} */ (_expr);
|
998
|
+
|
999
|
+
/**
|
1000
|
+
* Evaluates a UnaryExpression if and only if it is a basic const operator (e.g. +a, -a, ~a).
|
1001
|
+
*
|
1002
|
+
* @template T
|
1003
|
+
* @param {(operand: T) => boolean | number | BigInt | string} operandHandler handler for the operand
|
1004
|
+
* @returns {BasicEvaluatedExpression | undefined} evaluated expression
|
1005
|
+
*/
|
1006
|
+
const handleConstOperation = operandHandler => {
|
825
1007
|
const argument = this.evaluateExpression(expr.argument);
|
826
1008
|
if (!argument.isCompileTimeValue()) return;
|
827
|
-
const result =
|
1009
|
+
const result = operandHandler(argument.asCompileTimeValue());
|
828
1010
|
return valueAsExpression(
|
829
1011
|
result,
|
830
1012
|
expr,
|
@@ -942,7 +1124,7 @@ class JavascriptParser extends Parser {
|
|
942
1124
|
.setRange(expr.range);
|
943
1125
|
});
|
944
1126
|
this.hooks.evaluate.for("Identifier").tap("JavascriptParser", expr => {
|
945
|
-
if (/** @type {
|
1127
|
+
if (/** @type {Identifier} */ (expr).name === "undefined") {
|
946
1128
|
return new BasicEvaluatedExpression()
|
947
1129
|
.setUndefined()
|
948
1130
|
.setRange(expr.range);
|
@@ -950,16 +1132,16 @@ class JavascriptParser extends Parser {
|
|
950
1132
|
});
|
951
1133
|
/**
|
952
1134
|
* @param {string} exprType expression type name
|
953
|
-
* @param {function(
|
1135
|
+
* @param {function(Expression): GetInfoResult | undefined} getInfo get info
|
954
1136
|
* @returns {void}
|
955
1137
|
*/
|
956
1138
|
const tapEvaluateWithVariableInfo = (exprType, getInfo) => {
|
957
|
-
/** @type {
|
1139
|
+
/** @type {Expression | undefined} */
|
958
1140
|
let cachedExpression = undefined;
|
959
1141
|
/** @type {GetInfoResult | undefined} */
|
960
1142
|
let cachedInfo = undefined;
|
961
1143
|
this.hooks.evaluate.for(exprType).tap("JavascriptParser", expr => {
|
962
|
-
const expression = /** @type {
|
1144
|
+
const expression = /** @type {MemberExpression} */ (expr);
|
963
1145
|
|
964
1146
|
const info = getInfo(expr);
|
965
1147
|
if (info !== undefined) {
|
@@ -990,7 +1172,8 @@ class JavascriptParser extends Parser {
|
|
990
1172
|
info.name,
|
991
1173
|
info.rootInfo,
|
992
1174
|
info.getMembers,
|
993
|
-
info.getMembersOptionals
|
1175
|
+
info.getMembersOptionals,
|
1176
|
+
info.getMemberRanges
|
994
1177
|
)
|
995
1178
|
.setRange(expr.range);
|
996
1179
|
}
|
@@ -1001,9 +1184,7 @@ class JavascriptParser extends Parser {
|
|
1001
1184
|
});
|
1002
1185
|
};
|
1003
1186
|
tapEvaluateWithVariableInfo("Identifier", expr => {
|
1004
|
-
const info = this.getVariableInfo(
|
1005
|
-
/** @type {IdentifierNode} */ (expr).name
|
1006
|
-
);
|
1187
|
+
const info = this.getVariableInfo(/** @type {Identifier} */ (expr).name);
|
1007
1188
|
if (
|
1008
1189
|
typeof info === "string" ||
|
1009
1190
|
(info instanceof VariableInfo && typeof info.freeName === "string")
|
@@ -1012,7 +1193,8 @@ class JavascriptParser extends Parser {
|
|
1012
1193
|
name: info,
|
1013
1194
|
rootInfo: info,
|
1014
1195
|
getMembers: () => [],
|
1015
|
-
getMembersOptionals: () => []
|
1196
|
+
getMembersOptionals: () => [],
|
1197
|
+
getMemberRanges: () => []
|
1016
1198
|
};
|
1017
1199
|
}
|
1018
1200
|
});
|
@@ -1026,12 +1208,13 @@ class JavascriptParser extends Parser {
|
|
1026
1208
|
name: info,
|
1027
1209
|
rootInfo: info,
|
1028
1210
|
getMembers: () => [],
|
1029
|
-
getMembersOptionals: () => []
|
1211
|
+
getMembersOptionals: () => [],
|
1212
|
+
getMemberRanges: () => []
|
1030
1213
|
};
|
1031
1214
|
}
|
1032
1215
|
});
|
1033
1216
|
this.hooks.evaluate.for("MetaProperty").tap("JavascriptParser", expr => {
|
1034
|
-
const metaProperty = /** @type {
|
1217
|
+
const metaProperty = /** @type {MetaProperty} */ (expr);
|
1035
1218
|
|
1036
1219
|
return this.callHooksForName(
|
1037
1220
|
this.hooks.evaluateIdentifier,
|
@@ -1041,13 +1224,13 @@ class JavascriptParser extends Parser {
|
|
1041
1224
|
});
|
1042
1225
|
tapEvaluateWithVariableInfo("MemberExpression", expr =>
|
1043
1226
|
this.getMemberExpressionInfo(
|
1044
|
-
/** @type {
|
1227
|
+
/** @type {MemberExpression} */ (expr),
|
1045
1228
|
ALLOWED_MEMBER_TYPES_EXPRESSION
|
1046
1229
|
)
|
1047
1230
|
);
|
1048
1231
|
|
1049
1232
|
this.hooks.evaluate.for("CallExpression").tap("JavascriptParser", _expr => {
|
1050
|
-
const expr = /** @type {
|
1233
|
+
const expr = /** @type {CallExpression} */ (_expr);
|
1051
1234
|
if (
|
1052
1235
|
expr.callee.type === "MemberExpression" &&
|
1053
1236
|
expr.callee.property.type ===
|
@@ -1055,7 +1238,7 @@ class JavascriptParser extends Parser {
|
|
1055
1238
|
) {
|
1056
1239
|
// type Super also possible here
|
1057
1240
|
const param = this.evaluateExpression(
|
1058
|
-
/** @type {
|
1241
|
+
/** @type {Expression} */ (expr.callee.object)
|
1059
1242
|
);
|
1060
1243
|
const property =
|
1061
1244
|
expr.callee.property.type === "Literal"
|
@@ -1153,7 +1336,7 @@ class JavascriptParser extends Parser {
|
|
1153
1336
|
|
1154
1337
|
/**
|
1155
1338
|
* @param {"cooked" | "raw"} kind kind of values to get
|
1156
|
-
* @param {
|
1339
|
+
* @param {TemplateLiteral} templateLiteralExpr TemplateLiteral expr
|
1157
1340
|
* @returns {{quasis: BasicEvaluatedExpression[], parts: BasicEvaluatedExpression[]}} Simplified template
|
1158
1341
|
*/
|
1159
1342
|
const getSimplifiedTemplateResult = (kind, templateLiteralExpr) => {
|
@@ -1190,7 +1373,7 @@ class JavascriptParser extends Parser {
|
|
1190
1373
|
|
1191
1374
|
const part = new BasicEvaluatedExpression()
|
1192
1375
|
.setString(quasi)
|
1193
|
-
.setRange(quasiExpr.range)
|
1376
|
+
.setRange(/** @type {Range} */ (quasiExpr.range))
|
1194
1377
|
.setExpression(quasiExpr);
|
1195
1378
|
quasis.push(part);
|
1196
1379
|
parts.push(part);
|
@@ -1204,20 +1387,20 @@ class JavascriptParser extends Parser {
|
|
1204
1387
|
this.hooks.evaluate
|
1205
1388
|
.for("TemplateLiteral")
|
1206
1389
|
.tap("JavascriptParser", _node => {
|
1207
|
-
const node = /** @type {
|
1390
|
+
const node = /** @type {TemplateLiteral} */ (_node);
|
1208
1391
|
|
1209
1392
|
const { quasis, parts } = getSimplifiedTemplateResult("cooked", node);
|
1210
1393
|
if (parts.length === 1) {
|
1211
|
-
return parts[0].setRange(node.range);
|
1394
|
+
return parts[0].setRange(/** @type {Range} */ (node.range));
|
1212
1395
|
}
|
1213
1396
|
return new BasicEvaluatedExpression()
|
1214
1397
|
.setTemplateString(quasis, parts, "cooked")
|
1215
|
-
.setRange(node.range);
|
1398
|
+
.setRange(/** @type {Range} */ (node.range));
|
1216
1399
|
});
|
1217
1400
|
this.hooks.evaluate
|
1218
1401
|
.for("TaggedTemplateExpression")
|
1219
1402
|
.tap("JavascriptParser", _node => {
|
1220
|
-
const node = /** @type {
|
1403
|
+
const node = /** @type {TaggedTemplateExpression} */ (_node);
|
1221
1404
|
const tag = this.evaluateExpression(node.tag);
|
1222
1405
|
|
1223
1406
|
if (tag.isIdentifier() && tag.identifier === "String.raw") {
|
@@ -1227,7 +1410,7 @@ class JavascriptParser extends Parser {
|
|
1227
1410
|
);
|
1228
1411
|
return new BasicEvaluatedExpression()
|
1229
1412
|
.setTemplateString(quasis, parts, "raw")
|
1230
|
-
.setRange(node.range);
|
1413
|
+
.setRange(/** @type {Range} */ (node.range));
|
1231
1414
|
}
|
1232
1415
|
});
|
1233
1416
|
|
@@ -1257,10 +1440,10 @@ class JavascriptParser extends Parser {
|
|
1257
1440
|
: "" + argExpr.number;
|
1258
1441
|
|
1259
1442
|
const newString = value + (stringSuffix ? stringSuffix.string : "");
|
1260
|
-
const newRange = [
|
1443
|
+
const newRange = /** @type {Range} */ ([
|
1261
1444
|
argExpr.range[0],
|
1262
1445
|
(stringSuffix || argExpr).range[1]
|
1263
|
-
];
|
1446
|
+
]);
|
1264
1447
|
stringSuffix = new BasicEvaluatedExpression()
|
1265
1448
|
.setString(newString)
|
1266
1449
|
.setSideEffects(
|
@@ -1317,12 +1500,12 @@ class JavascriptParser extends Parser {
|
|
1317
1500
|
return new BasicEvaluatedExpression()
|
1318
1501
|
.setArray(result)
|
1319
1502
|
.setSideEffects(param.couldHaveSideEffects())
|
1320
|
-
.setRange(expr.range);
|
1503
|
+
.setRange(/** @type {Range} */ (expr.range));
|
1321
1504
|
});
|
1322
1505
|
this.hooks.evaluate
|
1323
1506
|
.for("ConditionalExpression")
|
1324
1507
|
.tap("JavascriptParser", _expr => {
|
1325
|
-
const expr = /** @type {
|
1508
|
+
const expr = /** @type {ConditionalExpression} */ (_expr);
|
1326
1509
|
|
1327
1510
|
const condition = this.evaluateExpression(expr.test);
|
1328
1511
|
const conditionValue = condition.asBool();
|
@@ -1332,12 +1515,16 @@ class JavascriptParser extends Parser {
|
|
1332
1515
|
const alternate = this.evaluateExpression(expr.alternate);
|
1333
1516
|
res = new BasicEvaluatedExpression();
|
1334
1517
|
if (consequent.isConditional()) {
|
1335
|
-
res.setOptions(
|
1518
|
+
res.setOptions(
|
1519
|
+
/** @type {BasicEvaluatedExpression[]} */ (consequent.options)
|
1520
|
+
);
|
1336
1521
|
} else {
|
1337
1522
|
res.setOptions([consequent]);
|
1338
1523
|
}
|
1339
1524
|
if (alternate.isConditional()) {
|
1340
|
-
res.addOptions(
|
1525
|
+
res.addOptions(
|
1526
|
+
/** @type {BasicEvaluatedExpression[]} */ (alternate.options)
|
1527
|
+
);
|
1341
1528
|
} else {
|
1342
1529
|
res.addOptions([alternate]);
|
1343
1530
|
}
|
@@ -1347,13 +1534,13 @@ class JavascriptParser extends Parser {
|
|
1347
1534
|
);
|
1348
1535
|
if (condition.couldHaveSideEffects()) res.setSideEffects();
|
1349
1536
|
}
|
1350
|
-
res.setRange(expr.range);
|
1537
|
+
res.setRange(/** @type {Range} */ (expr.range));
|
1351
1538
|
return res;
|
1352
1539
|
});
|
1353
1540
|
this.hooks.evaluate
|
1354
1541
|
.for("ArrayExpression")
|
1355
1542
|
.tap("JavascriptParser", _expr => {
|
1356
|
-
const expr = /** @type {
|
1543
|
+
const expr = /** @type {ArrayExpression} */ (_expr);
|
1357
1544
|
|
1358
1545
|
const items = expr.elements.map(element => {
|
1359
1546
|
return (
|
@@ -1365,15 +1552,15 @@ class JavascriptParser extends Parser {
|
|
1365
1552
|
if (!items.every(Boolean)) return;
|
1366
1553
|
return new BasicEvaluatedExpression()
|
1367
1554
|
.setItems(items)
|
1368
|
-
.setRange(expr.range);
|
1555
|
+
.setRange(/** @type {Range} */ (expr.range));
|
1369
1556
|
});
|
1370
1557
|
this.hooks.evaluate
|
1371
1558
|
.for("ChainExpression")
|
1372
1559
|
.tap("JavascriptParser", _expr => {
|
1373
|
-
const expr = /** @type {
|
1374
|
-
/** @type {
|
1560
|
+
const expr = /** @type {ChainExpression} */ (_expr);
|
1561
|
+
/** @type {Expression[]} */
|
1375
1562
|
const optionalExpressionsStack = [];
|
1376
|
-
/** @type {
|
1563
|
+
/** @type {Expression|Super} */
|
1377
1564
|
let next = expr.expression;
|
1378
1565
|
|
1379
1566
|
while (
|
@@ -1384,7 +1571,7 @@ class JavascriptParser extends Parser {
|
|
1384
1571
|
if (next.optional) {
|
1385
1572
|
// SuperNode can not be optional
|
1386
1573
|
optionalExpressionsStack.push(
|
1387
|
-
/** @type {
|
1574
|
+
/** @type {Expression} */ (next.object)
|
1388
1575
|
);
|
1389
1576
|
}
|
1390
1577
|
next = next.object;
|
@@ -1392,7 +1579,7 @@ class JavascriptParser extends Parser {
|
|
1392
1579
|
if (next.optional) {
|
1393
1580
|
// SuperNode can not be optional
|
1394
1581
|
optionalExpressionsStack.push(
|
1395
|
-
/** @type {
|
1582
|
+
/** @type {Expression} */ (next.callee)
|
1396
1583
|
);
|
1397
1584
|
}
|
1398
1585
|
next = next.callee;
|
@@ -1400,17 +1587,32 @@ class JavascriptParser extends Parser {
|
|
1400
1587
|
}
|
1401
1588
|
|
1402
1589
|
while (optionalExpressionsStack.length > 0) {
|
1403
|
-
const expression =
|
1590
|
+
const expression =
|
1591
|
+
/** @type {Expression} */
|
1592
|
+
(optionalExpressionsStack.pop());
|
1404
1593
|
const evaluated = this.evaluateExpression(expression);
|
1405
1594
|
|
1406
1595
|
if (evaluated.asNullish()) {
|
1407
|
-
return evaluated.setRange(_expr.range);
|
1596
|
+
return evaluated.setRange(/** @type {Range} */ (_expr.range));
|
1408
1597
|
}
|
1409
1598
|
}
|
1410
1599
|
return this.evaluateExpression(expr.expression);
|
1411
1600
|
});
|
1412
1601
|
}
|
1413
1602
|
|
1603
|
+
/**
|
1604
|
+
* @param {Expression} node node
|
1605
|
+
* @returns {Set<string>|undefined} destructured identifiers
|
1606
|
+
*/
|
1607
|
+
destructuringAssignmentPropertiesFor(node) {
|
1608
|
+
if (!this.destructuringAssignmentProperties) return undefined;
|
1609
|
+
return this.destructuringAssignmentProperties.get(node);
|
1610
|
+
}
|
1611
|
+
|
1612
|
+
/**
|
1613
|
+
* @param {Expression} expr expression
|
1614
|
+
* @returns {string | VariableInfoInterface | undefined} identifier
|
1615
|
+
*/
|
1414
1616
|
getRenameIdentifier(expr) {
|
1415
1617
|
const result = this.evaluateExpression(expr);
|
1416
1618
|
if (result.isIdentifier()) {
|
@@ -1419,7 +1621,7 @@ class JavascriptParser extends Parser {
|
|
1419
1621
|
}
|
1420
1622
|
|
1421
1623
|
/**
|
1422
|
-
* @param {
|
1624
|
+
* @param {ClassExpression | ClassDeclaration} classy a class node
|
1423
1625
|
* @returns {void}
|
1424
1626
|
*/
|
1425
1627
|
walkClass(classy) {
|
@@ -1429,36 +1631,47 @@ class JavascriptParser extends Parser {
|
|
1429
1631
|
}
|
1430
1632
|
}
|
1431
1633
|
if (classy.body && classy.body.type === "ClassBody") {
|
1432
|
-
|
1433
|
-
|
1434
|
-
|
1435
|
-
|
1436
|
-
|
1437
|
-
|
1438
|
-
|
1439
|
-
|
1440
|
-
|
1441
|
-
|
1442
|
-
|
1443
|
-
|
1444
|
-
|
1634
|
+
const scopeParams = [];
|
1635
|
+
// Add class name in scope for recursive calls
|
1636
|
+
if (classy.id) {
|
1637
|
+
scopeParams.push(classy.id);
|
1638
|
+
}
|
1639
|
+
this.inClassScope(true, scopeParams, () => {
|
1640
|
+
for (const classElement of /** @type {TODO} */ (classy.body.body)) {
|
1641
|
+
if (!this.hooks.classBodyElement.call(classElement, classy)) {
|
1642
|
+
if (classElement.computed && classElement.key) {
|
1643
|
+
this.walkExpression(classElement.key);
|
1644
|
+
}
|
1645
|
+
if (classElement.value) {
|
1646
|
+
if (
|
1647
|
+
!this.hooks.classBodyValue.call(
|
1648
|
+
classElement.value,
|
1649
|
+
classElement,
|
1650
|
+
classy
|
1651
|
+
)
|
1652
|
+
) {
|
1653
|
+
const wasTopLevel = this.scope.topLevelScope;
|
1654
|
+
this.scope.topLevelScope = false;
|
1655
|
+
this.walkExpression(classElement.value);
|
1656
|
+
this.scope.topLevelScope = wasTopLevel;
|
1657
|
+
}
|
1658
|
+
} else if (classElement.type === "StaticBlock") {
|
1445
1659
|
const wasTopLevel = this.scope.topLevelScope;
|
1446
1660
|
this.scope.topLevelScope = false;
|
1447
|
-
this.
|
1661
|
+
this.walkBlockStatement(classElement);
|
1448
1662
|
this.scope.topLevelScope = wasTopLevel;
|
1449
1663
|
}
|
1450
|
-
} else if (classElement.type === "StaticBlock") {
|
1451
|
-
const wasTopLevel = this.scope.topLevelScope;
|
1452
|
-
this.scope.topLevelScope = false;
|
1453
|
-
this.walkBlockStatement(classElement);
|
1454
|
-
this.scope.topLevelScope = wasTopLevel;
|
1455
1664
|
}
|
1456
1665
|
}
|
1457
|
-
}
|
1666
|
+
});
|
1458
1667
|
}
|
1459
1668
|
}
|
1460
1669
|
|
1461
|
-
|
1670
|
+
/**
|
1671
|
+
* Pre walking iterates the scope for variable declarations
|
1672
|
+
*
|
1673
|
+
* @param {(Statement | ModuleDeclaration)[]} statements statements
|
1674
|
+
*/
|
1462
1675
|
preWalkStatements(statements) {
|
1463
1676
|
for (let index = 0, len = statements.length; index < len; index++) {
|
1464
1677
|
const statement = statements[index];
|
@@ -1466,7 +1679,11 @@ class JavascriptParser extends Parser {
|
|
1466
1679
|
}
|
1467
1680
|
}
|
1468
1681
|
|
1469
|
-
|
1682
|
+
/**
|
1683
|
+
* Block pre walking iterates the scope for block variable declarations
|
1684
|
+
*
|
1685
|
+
* @param {(Statement | ModuleDeclaration)[]} statements statements
|
1686
|
+
*/
|
1470
1687
|
blockPreWalkStatements(statements) {
|
1471
1688
|
for (let index = 0, len = statements.length; index < len; index++) {
|
1472
1689
|
const statement = statements[index];
|
@@ -1474,7 +1691,11 @@ class JavascriptParser extends Parser {
|
|
1474
1691
|
}
|
1475
1692
|
}
|
1476
1693
|
|
1477
|
-
|
1694
|
+
/**
|
1695
|
+
* Walking iterates the statements and expressions and processes them
|
1696
|
+
*
|
1697
|
+
* @param {(Statement | ModuleDeclaration)[]} statements statements
|
1698
|
+
*/
|
1478
1699
|
walkStatements(statements) {
|
1479
1700
|
for (let index = 0, len = statements.length; index < len; index++) {
|
1480
1701
|
const statement = statements[index];
|
@@ -1482,6 +1703,11 @@ class JavascriptParser extends Parser {
|
|
1482
1703
|
}
|
1483
1704
|
}
|
1484
1705
|
|
1706
|
+
/**
|
1707
|
+
* Walking iterates the statements and expressions and processes them
|
1708
|
+
*
|
1709
|
+
* @param {Statement | ModuleDeclaration} statement statement
|
1710
|
+
*/
|
1485
1711
|
preWalkStatement(statement) {
|
1486
1712
|
this.statementPath.push(statement);
|
1487
1713
|
if (this.hooks.preStatement.call(statement)) {
|
@@ -1532,6 +1758,9 @@ class JavascriptParser extends Parser {
|
|
1532
1758
|
this.prevStatement = this.statementPath.pop();
|
1533
1759
|
}
|
1534
1760
|
|
1761
|
+
/**
|
1762
|
+
* @param {Statement | ModuleDeclaration} statement statement
|
1763
|
+
*/
|
1535
1764
|
blockPreWalkStatement(statement) {
|
1536
1765
|
this.statementPath.push(statement);
|
1537
1766
|
if (this.hooks.blockPreStatement.call(statement)) {
|
@@ -1557,10 +1786,15 @@ class JavascriptParser extends Parser {
|
|
1557
1786
|
case "ClassDeclaration":
|
1558
1787
|
this.blockPreWalkClassDeclaration(statement);
|
1559
1788
|
break;
|
1789
|
+
case "ExpressionStatement":
|
1790
|
+
this.blockPreWalkExpressionStatement(statement);
|
1560
1791
|
}
|
1561
1792
|
this.prevStatement = this.statementPath.pop();
|
1562
1793
|
}
|
1563
1794
|
|
1795
|
+
/**
|
1796
|
+
* @param {Statement | ModuleDeclaration} statement statement
|
1797
|
+
*/
|
1564
1798
|
walkStatement(statement) {
|
1565
1799
|
this.statementPath.push(statement);
|
1566
1800
|
if (this.hooks.statement.call(statement) !== undefined) {
|
@@ -1633,8 +1867,8 @@ class JavascriptParser extends Parser {
|
|
1633
1867
|
* Walks a statements that is nested within a parent statement
|
1634
1868
|
* and can potentially be a non-block statement.
|
1635
1869
|
* This enforces the nested statement to never be in ASI position.
|
1636
|
-
*
|
1637
|
-
* @
|
1870
|
+
*
|
1871
|
+
* @param {Statement} statement the nested statement
|
1638
1872
|
*/
|
1639
1873
|
walkNestedStatement(statement) {
|
1640
1874
|
this.prevStatement = undefined;
|
@@ -1642,10 +1876,16 @@ class JavascriptParser extends Parser {
|
|
1642
1876
|
}
|
1643
1877
|
|
1644
1878
|
// Real Statements
|
1879
|
+
/**
|
1880
|
+
* @param {BlockStatement} statement block statement
|
1881
|
+
*/
|
1645
1882
|
preWalkBlockStatement(statement) {
|
1646
1883
|
this.preWalkStatements(statement.body);
|
1647
1884
|
}
|
1648
1885
|
|
1886
|
+
/**
|
1887
|
+
* @param {BlockStatement} statement block statement
|
1888
|
+
*/
|
1649
1889
|
walkBlockStatement(statement) {
|
1650
1890
|
this.inBlockScope(() => {
|
1651
1891
|
const body = statement.body;
|
@@ -1656,10 +1896,16 @@ class JavascriptParser extends Parser {
|
|
1656
1896
|
});
|
1657
1897
|
}
|
1658
1898
|
|
1899
|
+
/**
|
1900
|
+
* @param {ExpressionStatement} statement expression statement
|
1901
|
+
*/
|
1659
1902
|
walkExpressionStatement(statement) {
|
1660
1903
|
this.walkExpression(statement.expression);
|
1661
1904
|
}
|
1662
1905
|
|
1906
|
+
/**
|
1907
|
+
* @param {IfStatement} statement if statement
|
1908
|
+
*/
|
1663
1909
|
preWalkIfStatement(statement) {
|
1664
1910
|
this.preWalkStatement(statement.consequent);
|
1665
1911
|
if (statement.alternate) {
|
@@ -1667,6 +1913,9 @@ class JavascriptParser extends Parser {
|
|
1667
1913
|
}
|
1668
1914
|
}
|
1669
1915
|
|
1916
|
+
/**
|
1917
|
+
* @param {IfStatement} statement if statement
|
1918
|
+
*/
|
1670
1919
|
walkIfStatement(statement) {
|
1671
1920
|
const result = this.hooks.statementIf.call(statement);
|
1672
1921
|
if (result === undefined) {
|
@@ -1684,10 +1933,16 @@ class JavascriptParser extends Parser {
|
|
1684
1933
|
}
|
1685
1934
|
}
|
1686
1935
|
|
1936
|
+
/**
|
1937
|
+
* @param {LabeledStatement} statement with statement
|
1938
|
+
*/
|
1687
1939
|
preWalkLabeledStatement(statement) {
|
1688
1940
|
this.preWalkStatement(statement.body);
|
1689
1941
|
}
|
1690
1942
|
|
1943
|
+
/**
|
1944
|
+
* @param {LabeledStatement} statement with statement
|
1945
|
+
*/
|
1691
1946
|
walkLabeledStatement(statement) {
|
1692
1947
|
const hook = this.hooks.label.get(statement.label.name);
|
1693
1948
|
if (hook !== undefined) {
|
@@ -1697,42 +1952,69 @@ class JavascriptParser extends Parser {
|
|
1697
1952
|
this.walkNestedStatement(statement.body);
|
1698
1953
|
}
|
1699
1954
|
|
1955
|
+
/**
|
1956
|
+
* @param {WithStatement} statement with statement
|
1957
|
+
*/
|
1700
1958
|
preWalkWithStatement(statement) {
|
1701
1959
|
this.preWalkStatement(statement.body);
|
1702
1960
|
}
|
1703
1961
|
|
1962
|
+
/**
|
1963
|
+
* @param {WithStatement} statement with statement
|
1964
|
+
*/
|
1704
1965
|
walkWithStatement(statement) {
|
1705
1966
|
this.walkExpression(statement.object);
|
1706
1967
|
this.walkNestedStatement(statement.body);
|
1707
1968
|
}
|
1708
1969
|
|
1970
|
+
/**
|
1971
|
+
* @param {SwitchStatement} statement switch statement
|
1972
|
+
*/
|
1709
1973
|
preWalkSwitchStatement(statement) {
|
1710
1974
|
this.preWalkSwitchCases(statement.cases);
|
1711
1975
|
}
|
1712
1976
|
|
1977
|
+
/**
|
1978
|
+
* @param {SwitchStatement} statement switch statement
|
1979
|
+
*/
|
1713
1980
|
walkSwitchStatement(statement) {
|
1714
1981
|
this.walkExpression(statement.discriminant);
|
1715
1982
|
this.walkSwitchCases(statement.cases);
|
1716
1983
|
}
|
1717
1984
|
|
1985
|
+
/**
|
1986
|
+
* @param {ReturnStatement | ThrowStatement} statement return or throw statement
|
1987
|
+
*/
|
1718
1988
|
walkTerminatingStatement(statement) {
|
1719
1989
|
if (statement.argument) this.walkExpression(statement.argument);
|
1720
1990
|
}
|
1721
1991
|
|
1992
|
+
/**
|
1993
|
+
* @param {ReturnStatement} statement return statement
|
1994
|
+
*/
|
1722
1995
|
walkReturnStatement(statement) {
|
1723
1996
|
this.walkTerminatingStatement(statement);
|
1724
1997
|
}
|
1725
1998
|
|
1999
|
+
/**
|
2000
|
+
* @param {ThrowStatement} statement return statement
|
2001
|
+
*/
|
1726
2002
|
walkThrowStatement(statement) {
|
1727
2003
|
this.walkTerminatingStatement(statement);
|
1728
2004
|
}
|
1729
2005
|
|
2006
|
+
/**
|
2007
|
+
* @param {TryStatement} statement try statement
|
2008
|
+
*/
|
1730
2009
|
preWalkTryStatement(statement) {
|
1731
2010
|
this.preWalkStatement(statement.block);
|
1732
2011
|
if (statement.handler) this.preWalkCatchClause(statement.handler);
|
1733
|
-
if (statement.
|
2012
|
+
if (statement.finalizer) this.preWalkStatement(statement.finalizer);
|
1734
2013
|
}
|
1735
2014
|
|
2015
|
+
/**
|
2016
|
+
* @param {TryStatement} statement try statement
|
2017
|
+
*/
|
1736
2018
|
walkTryStatement(statement) {
|
1737
2019
|
if (this.scope.inTry) {
|
1738
2020
|
this.walkStatement(statement.block);
|
@@ -1745,24 +2027,39 @@ class JavascriptParser extends Parser {
|
|
1745
2027
|
if (statement.finalizer) this.walkStatement(statement.finalizer);
|
1746
2028
|
}
|
1747
2029
|
|
2030
|
+
/**
|
2031
|
+
* @param {WhileStatement} statement while statement
|
2032
|
+
*/
|
1748
2033
|
preWalkWhileStatement(statement) {
|
1749
2034
|
this.preWalkStatement(statement.body);
|
1750
2035
|
}
|
1751
2036
|
|
2037
|
+
/**
|
2038
|
+
* @param {WhileStatement} statement while statement
|
2039
|
+
*/
|
1752
2040
|
walkWhileStatement(statement) {
|
1753
2041
|
this.walkExpression(statement.test);
|
1754
2042
|
this.walkNestedStatement(statement.body);
|
1755
2043
|
}
|
1756
2044
|
|
2045
|
+
/**
|
2046
|
+
* @param {DoWhileStatement} statement do while statement
|
2047
|
+
*/
|
1757
2048
|
preWalkDoWhileStatement(statement) {
|
1758
2049
|
this.preWalkStatement(statement.body);
|
1759
2050
|
}
|
1760
2051
|
|
2052
|
+
/**
|
2053
|
+
* @param {DoWhileStatement} statement do while statement
|
2054
|
+
*/
|
1761
2055
|
walkDoWhileStatement(statement) {
|
1762
2056
|
this.walkNestedStatement(statement.body);
|
1763
2057
|
this.walkExpression(statement.test);
|
1764
2058
|
}
|
1765
2059
|
|
2060
|
+
/**
|
2061
|
+
* @param {ForStatement} statement for statement
|
2062
|
+
*/
|
1766
2063
|
preWalkForStatement(statement) {
|
1767
2064
|
if (statement.init) {
|
1768
2065
|
if (statement.init.type === "VariableDeclaration") {
|
@@ -1772,6 +2069,9 @@ class JavascriptParser extends Parser {
|
|
1772
2069
|
this.preWalkStatement(statement.body);
|
1773
2070
|
}
|
1774
2071
|
|
2072
|
+
/**
|
2073
|
+
* @param {ForStatement} statement for statement
|
2074
|
+
*/
|
1775
2075
|
walkForStatement(statement) {
|
1776
2076
|
this.inBlockScope(() => {
|
1777
2077
|
if (statement.init) {
|
@@ -1802,6 +2102,9 @@ class JavascriptParser extends Parser {
|
|
1802
2102
|
});
|
1803
2103
|
}
|
1804
2104
|
|
2105
|
+
/**
|
2106
|
+
* @param {ForInStatement} statement for statement
|
2107
|
+
*/
|
1805
2108
|
preWalkForInStatement(statement) {
|
1806
2109
|
if (statement.left.type === "VariableDeclaration") {
|
1807
2110
|
this.preWalkVariableDeclaration(statement.left);
|
@@ -1809,6 +2112,9 @@ class JavascriptParser extends Parser {
|
|
1809
2112
|
this.preWalkStatement(statement.body);
|
1810
2113
|
}
|
1811
2114
|
|
2115
|
+
/**
|
2116
|
+
* @param {ForInStatement} statement for statement
|
2117
|
+
*/
|
1812
2118
|
walkForInStatement(statement) {
|
1813
2119
|
this.inBlockScope(() => {
|
1814
2120
|
if (statement.left.type === "VariableDeclaration") {
|
@@ -1841,6 +2147,9 @@ class JavascriptParser extends Parser {
|
|
1841
2147
|
this.preWalkStatement(statement.body);
|
1842
2148
|
}
|
1843
2149
|
|
2150
|
+
/**
|
2151
|
+
* @param {ForOfStatement} statement for statement
|
2152
|
+
*/
|
1844
2153
|
walkForOfStatement(statement) {
|
1845
2154
|
this.inBlockScope(() => {
|
1846
2155
|
if (statement.left.type === "VariableDeclaration") {
|
@@ -1863,13 +2172,18 @@ class JavascriptParser extends Parser {
|
|
1863
2172
|
});
|
1864
2173
|
}
|
1865
2174
|
|
1866
|
-
|
2175
|
+
/**
|
2176
|
+
* @param {FunctionDeclaration} statement function declaration
|
2177
|
+
*/
|
1867
2178
|
preWalkFunctionDeclaration(statement) {
|
1868
2179
|
if (statement.id) {
|
1869
2180
|
this.defineVariable(statement.id.name);
|
1870
2181
|
}
|
1871
2182
|
}
|
1872
2183
|
|
2184
|
+
/**
|
2185
|
+
* @param {FunctionDeclaration} statement function declaration
|
2186
|
+
*/
|
1873
2187
|
walkFunctionDeclaration(statement) {
|
1874
2188
|
const wasTopLevel = this.scope.topLevelScope;
|
1875
2189
|
this.scope.topLevelScope = false;
|
@@ -1890,6 +2204,48 @@ class JavascriptParser extends Parser {
|
|
1890
2204
|
this.scope.topLevelScope = wasTopLevel;
|
1891
2205
|
}
|
1892
2206
|
|
2207
|
+
/**
|
2208
|
+
* @param {ExpressionStatement} statement expression statement
|
2209
|
+
*/
|
2210
|
+
blockPreWalkExpressionStatement(statement) {
|
2211
|
+
const expression = statement.expression;
|
2212
|
+
switch (expression.type) {
|
2213
|
+
case "AssignmentExpression":
|
2214
|
+
this.preWalkAssignmentExpression(expression);
|
2215
|
+
}
|
2216
|
+
}
|
2217
|
+
|
2218
|
+
/**
|
2219
|
+
* @param {AssignmentExpression} expression assignment expression
|
2220
|
+
*/
|
2221
|
+
preWalkAssignmentExpression(expression) {
|
2222
|
+
if (
|
2223
|
+
expression.left.type !== "ObjectPattern" ||
|
2224
|
+
!this.destructuringAssignmentProperties
|
2225
|
+
)
|
2226
|
+
return;
|
2227
|
+
const keys = this._preWalkObjectPattern(expression.left);
|
2228
|
+
if (!keys) return;
|
2229
|
+
|
2230
|
+
// check multiple assignments
|
2231
|
+
if (this.destructuringAssignmentProperties.has(expression)) {
|
2232
|
+
const set = this.destructuringAssignmentProperties.get(expression);
|
2233
|
+
this.destructuringAssignmentProperties.delete(expression);
|
2234
|
+
for (const id of set) keys.add(id);
|
2235
|
+
}
|
2236
|
+
|
2237
|
+
this.destructuringAssignmentProperties.set(
|
2238
|
+
expression.right.type === "AwaitExpression"
|
2239
|
+
? expression.right.argument
|
2240
|
+
: expression.right,
|
2241
|
+
keys
|
2242
|
+
);
|
2243
|
+
|
2244
|
+
if (expression.right.type === "AssignmentExpression") {
|
2245
|
+
this.preWalkAssignmentExpression(expression.right);
|
2246
|
+
}
|
2247
|
+
}
|
2248
|
+
|
1893
2249
|
blockPreWalkImportDeclaration(statement) {
|
1894
2250
|
const source = statement.source.value;
|
1895
2251
|
this.hooks.import.call(statement, source);
|
@@ -2002,6 +2358,9 @@ class JavascriptParser extends Parser {
|
|
2002
2358
|
}
|
2003
2359
|
}
|
2004
2360
|
|
2361
|
+
/**
|
2362
|
+
* @param {ExportNamedDeclaration} statement the statement
|
2363
|
+
*/
|
2005
2364
|
walkExportNamedDeclaration(statement) {
|
2006
2365
|
if (statement.declaration) {
|
2007
2366
|
this.walkStatement(statement.declaration);
|
@@ -2069,11 +2428,17 @@ class JavascriptParser extends Parser {
|
|
2069
2428
|
this.hooks.exportImportSpecifier.call(statement, source, null, name, 0);
|
2070
2429
|
}
|
2071
2430
|
|
2431
|
+
/**
|
2432
|
+
* @param {VariableDeclaration} statement variable declaration
|
2433
|
+
*/
|
2072
2434
|
preWalkVariableDeclaration(statement) {
|
2073
2435
|
if (statement.kind !== "var") return;
|
2074
2436
|
this._preWalkVariableDeclaration(statement, this.hooks.varDeclarationVar);
|
2075
2437
|
}
|
2076
2438
|
|
2439
|
+
/**
|
2440
|
+
* @param {VariableDeclaration} statement variable declaration
|
2441
|
+
*/
|
2077
2442
|
blockPreWalkVariableDeclaration(statement) {
|
2078
2443
|
if (statement.kind === "var") return;
|
2079
2444
|
const hookMap =
|
@@ -2083,10 +2448,15 @@ class JavascriptParser extends Parser {
|
|
2083
2448
|
this._preWalkVariableDeclaration(statement, hookMap);
|
2084
2449
|
}
|
2085
2450
|
|
2451
|
+
/**
|
2452
|
+
* @param {VariableDeclaration} statement variable declaration
|
2453
|
+
* @param {TODO} hookMap map of hooks
|
2454
|
+
*/
|
2086
2455
|
_preWalkVariableDeclaration(statement, hookMap) {
|
2087
2456
|
for (const declarator of statement.declarations) {
|
2088
2457
|
switch (declarator.type) {
|
2089
2458
|
case "VariableDeclarator": {
|
2459
|
+
this.preWalkVariableDeclarator(declarator);
|
2090
2460
|
if (!this.hooks.preDeclarator.call(declarator, statement)) {
|
2091
2461
|
this.enterPattern(declarator.id, (name, decl) => {
|
2092
2462
|
let hook = hookMap.get(name);
|
@@ -2104,6 +2474,62 @@ class JavascriptParser extends Parser {
|
|
2104
2474
|
}
|
2105
2475
|
}
|
2106
2476
|
|
2477
|
+
/**
|
2478
|
+
* @param {ObjectPattern} objectPattern object pattern
|
2479
|
+
* @returns {Set<string> | undefined} set of names or undefined if not all keys are identifiers
|
2480
|
+
*/
|
2481
|
+
_preWalkObjectPattern(objectPattern) {
|
2482
|
+
const ids = new Set();
|
2483
|
+
const properties = objectPattern.properties;
|
2484
|
+
for (let i = 0; i < properties.length; i++) {
|
2485
|
+
const property = properties[i];
|
2486
|
+
if (property.type !== "Property") return;
|
2487
|
+
const key = property.key;
|
2488
|
+
if (key.type === "Identifier") {
|
2489
|
+
ids.add(key.name);
|
2490
|
+
} else {
|
2491
|
+
const id = this.evaluateExpression(key);
|
2492
|
+
const str = id.asString();
|
2493
|
+
if (str) {
|
2494
|
+
ids.add(str);
|
2495
|
+
} else {
|
2496
|
+
// could not evaluate key
|
2497
|
+
return;
|
2498
|
+
}
|
2499
|
+
}
|
2500
|
+
}
|
2501
|
+
|
2502
|
+
return ids;
|
2503
|
+
}
|
2504
|
+
|
2505
|
+
/**
|
2506
|
+
* @param {VariableDeclarator} declarator variable declarator
|
2507
|
+
*/
|
2508
|
+
preWalkVariableDeclarator(declarator) {
|
2509
|
+
if (
|
2510
|
+
!declarator.init ||
|
2511
|
+
declarator.id.type !== "ObjectPattern" ||
|
2512
|
+
!this.destructuringAssignmentProperties
|
2513
|
+
)
|
2514
|
+
return;
|
2515
|
+
const keys = this._preWalkObjectPattern(declarator.id);
|
2516
|
+
|
2517
|
+
if (!keys) return;
|
2518
|
+
this.destructuringAssignmentProperties.set(
|
2519
|
+
declarator.init.type === "AwaitExpression"
|
2520
|
+
? declarator.init.argument
|
2521
|
+
: declarator.init,
|
2522
|
+
keys
|
2523
|
+
);
|
2524
|
+
|
2525
|
+
if (declarator.init.type === "AssignmentExpression") {
|
2526
|
+
this.preWalkAssignmentExpression(declarator.init);
|
2527
|
+
}
|
2528
|
+
}
|
2529
|
+
|
2530
|
+
/**
|
2531
|
+
* @param {VariableDeclaration} statement variable declaration
|
2532
|
+
*/
|
2107
2533
|
walkVariableDeclaration(statement) {
|
2108
2534
|
for (const declarator of statement.declarations) {
|
2109
2535
|
switch (declarator.type) {
|
@@ -2131,16 +2557,25 @@ class JavascriptParser extends Parser {
|
|
2131
2557
|
}
|
2132
2558
|
}
|
2133
2559
|
|
2560
|
+
/**
|
2561
|
+
* @param {ClassDeclaration} statement class declaration
|
2562
|
+
*/
|
2134
2563
|
blockPreWalkClassDeclaration(statement) {
|
2135
2564
|
if (statement.id) {
|
2136
2565
|
this.defineVariable(statement.id.name);
|
2137
2566
|
}
|
2138
2567
|
}
|
2139
2568
|
|
2569
|
+
/**
|
2570
|
+
* @param {ClassDeclaration} statement class declaration
|
2571
|
+
*/
|
2140
2572
|
walkClassDeclaration(statement) {
|
2141
2573
|
this.walkClass(statement);
|
2142
2574
|
}
|
2143
2575
|
|
2576
|
+
/**
|
2577
|
+
* @param {SwitchCase[]} switchCases switch statement
|
2578
|
+
*/
|
2144
2579
|
preWalkSwitchCases(switchCases) {
|
2145
2580
|
for (let index = 0, len = switchCases.length; index < len; index++) {
|
2146
2581
|
const switchCase = switchCases[index];
|
@@ -2148,6 +2583,9 @@ class JavascriptParser extends Parser {
|
|
2148
2583
|
}
|
2149
2584
|
}
|
2150
2585
|
|
2586
|
+
/**
|
2587
|
+
* @param {SwitchCase[]} switchCases switch statement
|
2588
|
+
*/
|
2151
2589
|
walkSwitchCases(switchCases) {
|
2152
2590
|
this.inBlockScope(() => {
|
2153
2591
|
const len = switchCases.length;
|
@@ -2183,10 +2621,16 @@ class JavascriptParser extends Parser {
|
|
2183
2621
|
});
|
2184
2622
|
}
|
2185
2623
|
|
2624
|
+
/**
|
2625
|
+
* @param {CatchClause} catchClause catch clause
|
2626
|
+
*/
|
2186
2627
|
preWalkCatchClause(catchClause) {
|
2187
2628
|
this.preWalkStatement(catchClause.body);
|
2188
2629
|
}
|
2189
2630
|
|
2631
|
+
/**
|
2632
|
+
* @param {CatchClause} catchClause catch clause
|
2633
|
+
*/
|
2190
2634
|
walkCatchClause(catchClause) {
|
2191
2635
|
this.inBlockScope(() => {
|
2192
2636
|
// Error binding is optional in catch clause since ECMAScript 2019
|
@@ -2203,6 +2647,9 @@ class JavascriptParser extends Parser {
|
|
2203
2647
|
});
|
2204
2648
|
}
|
2205
2649
|
|
2650
|
+
/**
|
2651
|
+
* @param {Pattern} pattern pattern
|
2652
|
+
*/
|
2206
2653
|
walkPattern(pattern) {
|
2207
2654
|
switch (pattern.type) {
|
2208
2655
|
case "ArrayPattern":
|
@@ -2223,6 +2670,9 @@ class JavascriptParser extends Parser {
|
|
2223
2670
|
}
|
2224
2671
|
}
|
2225
2672
|
|
2673
|
+
/**
|
2674
|
+
* @param {AssignmentPattern} pattern assignment pattern
|
2675
|
+
*/
|
2226
2676
|
walkAssignmentPattern(pattern) {
|
2227
2677
|
this.walkExpression(pattern.right);
|
2228
2678
|
this.walkPattern(pattern.left);
|
@@ -2238,6 +2688,9 @@ class JavascriptParser extends Parser {
|
|
2238
2688
|
}
|
2239
2689
|
}
|
2240
2690
|
|
2691
|
+
/**
|
2692
|
+
* @param {ArrayPattern} pattern array pattern
|
2693
|
+
*/
|
2241
2694
|
walkArrayPattern(pattern) {
|
2242
2695
|
for (let i = 0, len = pattern.elements.length; i < len; i++) {
|
2243
2696
|
const element = pattern.elements[i];
|
@@ -2245,10 +2698,16 @@ class JavascriptParser extends Parser {
|
|
2245
2698
|
}
|
2246
2699
|
}
|
2247
2700
|
|
2701
|
+
/**
|
2702
|
+
* @param {RestElement} pattern rest element
|
2703
|
+
*/
|
2248
2704
|
walkRestElement(pattern) {
|
2249
2705
|
this.walkPattern(pattern.argument);
|
2250
2706
|
}
|
2251
2707
|
|
2708
|
+
/**
|
2709
|
+
* @param {(Expression | SpreadElement | null)[]} expressions expressions
|
2710
|
+
*/
|
2252
2711
|
walkExpressions(expressions) {
|
2253
2712
|
for (const expression of expressions) {
|
2254
2713
|
if (expression) {
|
@@ -2257,6 +2716,9 @@ class JavascriptParser extends Parser {
|
|
2257
2716
|
}
|
2258
2717
|
}
|
2259
2718
|
|
2719
|
+
/**
|
2720
|
+
* @param {TODO} expression expression
|
2721
|
+
*/
|
2260
2722
|
walkExpression(expression) {
|
2261
2723
|
switch (expression.type) {
|
2262
2724
|
case "ArrayExpression":
|
@@ -2337,24 +2799,36 @@ class JavascriptParser extends Parser {
|
|
2337
2799
|
}
|
2338
2800
|
}
|
2339
2801
|
|
2802
|
+
/**
|
2803
|
+
* @param {AwaitExpression} expression await expression
|
2804
|
+
*/
|
2340
2805
|
walkAwaitExpression(expression) {
|
2341
2806
|
if (this.scope.topLevelScope === true)
|
2342
2807
|
this.hooks.topLevelAwait.call(expression);
|
2343
2808
|
this.walkExpression(expression.argument);
|
2344
2809
|
}
|
2345
2810
|
|
2811
|
+
/**
|
2812
|
+
* @param {ArrayExpression} expression array expression
|
2813
|
+
*/
|
2346
2814
|
walkArrayExpression(expression) {
|
2347
2815
|
if (expression.elements) {
|
2348
2816
|
this.walkExpressions(expression.elements);
|
2349
2817
|
}
|
2350
2818
|
}
|
2351
2819
|
|
2820
|
+
/**
|
2821
|
+
* @param {SpreadElement} expression spread element
|
2822
|
+
*/
|
2352
2823
|
walkSpreadElement(expression) {
|
2353
2824
|
if (expression.argument) {
|
2354
2825
|
this.walkExpression(expression.argument);
|
2355
2826
|
}
|
2356
2827
|
}
|
2357
2828
|
|
2829
|
+
/**
|
2830
|
+
* @param {ObjectExpression} expression object expression
|
2831
|
+
*/
|
2358
2832
|
walkObjectExpression(expression) {
|
2359
2833
|
for (
|
2360
2834
|
let propIndex = 0, len = expression.properties.length;
|
@@ -2366,6 +2840,9 @@ class JavascriptParser extends Parser {
|
|
2366
2840
|
}
|
2367
2841
|
}
|
2368
2842
|
|
2843
|
+
/**
|
2844
|
+
* @param {Property | SpreadElement} prop property or spread element
|
2845
|
+
*/
|
2369
2846
|
walkProperty(prop) {
|
2370
2847
|
if (prop.type === "SpreadElement") {
|
2371
2848
|
this.walkExpression(prop.argument);
|
@@ -2383,14 +2860,17 @@ class JavascriptParser extends Parser {
|
|
2383
2860
|
}
|
2384
2861
|
}
|
2385
2862
|
|
2863
|
+
/**
|
2864
|
+
* @param {FunctionExpression} expression arrow function expression
|
2865
|
+
*/
|
2386
2866
|
walkFunctionExpression(expression) {
|
2387
2867
|
const wasTopLevel = this.scope.topLevelScope;
|
2388
2868
|
this.scope.topLevelScope = false;
|
2389
|
-
const scopeParams = expression.params;
|
2869
|
+
const scopeParams = [...expression.params];
|
2390
2870
|
|
2391
2871
|
// Add function name in scope for recursive calls
|
2392
2872
|
if (expression.id) {
|
2393
|
-
scopeParams.push(expression.id
|
2873
|
+
scopeParams.push(expression.id);
|
2394
2874
|
}
|
2395
2875
|
|
2396
2876
|
this.inFunctionScope(true, scopeParams, () => {
|
@@ -2410,6 +2890,9 @@ class JavascriptParser extends Parser {
|
|
2410
2890
|
this.scope.topLevelScope = wasTopLevel;
|
2411
2891
|
}
|
2412
2892
|
|
2893
|
+
/**
|
2894
|
+
* @param {ArrowFunctionExpression} expression arrow function expression
|
2895
|
+
*/
|
2413
2896
|
walkArrowFunctionExpression(expression) {
|
2414
2897
|
const wasTopLevel = this.scope.topLevelScope;
|
2415
2898
|
this.scope.topLevelScope = wasTopLevel ? "arrow" : false;
|
@@ -2431,7 +2914,7 @@ class JavascriptParser extends Parser {
|
|
2431
2914
|
}
|
2432
2915
|
|
2433
2916
|
/**
|
2434
|
-
* @param {
|
2917
|
+
* @param {SequenceExpression} expression the sequence
|
2435
2918
|
*/
|
2436
2919
|
walkSequenceExpression(expression) {
|
2437
2920
|
if (!expression.expressions) return;
|
@@ -2455,10 +2938,16 @@ class JavascriptParser extends Parser {
|
|
2455
2938
|
}
|
2456
2939
|
}
|
2457
2940
|
|
2941
|
+
/**
|
2942
|
+
* @param {UpdateExpression} expression the update expression
|
2943
|
+
*/
|
2458
2944
|
walkUpdateExpression(expression) {
|
2459
2945
|
this.walkExpression(expression.argument);
|
2460
2946
|
}
|
2461
2947
|
|
2948
|
+
/**
|
2949
|
+
* @param {UnaryExpression} expression the unary expression
|
2950
|
+
*/
|
2462
2951
|
walkUnaryExpression(expression) {
|
2463
2952
|
if (expression.operator === "typeof") {
|
2464
2953
|
const result = this.callHooksForExpression(
|
@@ -2479,17 +2968,26 @@ class JavascriptParser extends Parser {
|
|
2479
2968
|
this.walkExpression(expression.argument);
|
2480
2969
|
}
|
2481
2970
|
|
2971
|
+
/**
|
2972
|
+
* @param {LogicalExpression | BinaryExpression} expression the expression
|
2973
|
+
*/
|
2482
2974
|
walkLeftRightExpression(expression) {
|
2483
2975
|
this.walkExpression(expression.left);
|
2484
2976
|
this.walkExpression(expression.right);
|
2485
2977
|
}
|
2486
2978
|
|
2979
|
+
/**
|
2980
|
+
* @param {BinaryExpression} expression the binary expression
|
2981
|
+
*/
|
2487
2982
|
walkBinaryExpression(expression) {
|
2488
2983
|
if (this.hooks.binaryExpression.call(expression) === undefined) {
|
2489
2984
|
this.walkLeftRightExpression(expression);
|
2490
2985
|
}
|
2491
2986
|
}
|
2492
2987
|
|
2988
|
+
/**
|
2989
|
+
* @param {LogicalExpression} expression the logical expression
|
2990
|
+
*/
|
2493
2991
|
walkLogicalExpression(expression) {
|
2494
2992
|
const result = this.hooks.expressionLogicalOperator.call(expression);
|
2495
2993
|
if (result === undefined) {
|
@@ -2501,6 +2999,9 @@ class JavascriptParser extends Parser {
|
|
2501
2999
|
}
|
2502
3000
|
}
|
2503
3001
|
|
3002
|
+
/**
|
3003
|
+
* @param {AssignmentExpression} expression assignment expression
|
3004
|
+
*/
|
2504
3005
|
walkAssignmentExpression(expression) {
|
2505
3006
|
if (expression.left.type === "Identifier") {
|
2506
3007
|
const renameIdentifier = this.getRenameIdentifier(expression.right);
|
@@ -2571,6 +3072,9 @@ class JavascriptParser extends Parser {
|
|
2571
3072
|
}
|
2572
3073
|
}
|
2573
3074
|
|
3075
|
+
/**
|
3076
|
+
* @param {ConditionalExpression} expression conditional expression
|
3077
|
+
*/
|
2574
3078
|
walkConditionalExpression(expression) {
|
2575
3079
|
const result = this.hooks.expressionConditionalOperator.call(expression);
|
2576
3080
|
if (result === undefined) {
|
@@ -2588,6 +3092,9 @@ class JavascriptParser extends Parser {
|
|
2588
3092
|
}
|
2589
3093
|
}
|
2590
3094
|
|
3095
|
+
/**
|
3096
|
+
* @param {NewExpression} expression new expression
|
3097
|
+
*/
|
2591
3098
|
walkNewExpression(expression) {
|
2592
3099
|
const result = this.callHooksForExpression(
|
2593
3100
|
this.hooks.new,
|
@@ -2601,33 +3108,47 @@ class JavascriptParser extends Parser {
|
|
2601
3108
|
}
|
2602
3109
|
}
|
2603
3110
|
|
3111
|
+
/**
|
3112
|
+
* @param {YieldExpression} expression yield expression
|
3113
|
+
*/
|
2604
3114
|
walkYieldExpression(expression) {
|
2605
3115
|
if (expression.argument) {
|
2606
3116
|
this.walkExpression(expression.argument);
|
2607
3117
|
}
|
2608
3118
|
}
|
2609
3119
|
|
3120
|
+
/**
|
3121
|
+
* @param {TemplateLiteral} expression template literal
|
3122
|
+
*/
|
2610
3123
|
walkTemplateLiteral(expression) {
|
2611
3124
|
if (expression.expressions) {
|
2612
3125
|
this.walkExpressions(expression.expressions);
|
2613
3126
|
}
|
2614
3127
|
}
|
2615
3128
|
|
3129
|
+
/**
|
3130
|
+
* @param {TaggedTemplateExpression} expression tagged template expression
|
3131
|
+
*/
|
2616
3132
|
walkTaggedTemplateExpression(expression) {
|
2617
3133
|
if (expression.tag) {
|
3134
|
+
this.scope.inTaggedTemplateTag = true;
|
2618
3135
|
this.walkExpression(expression.tag);
|
3136
|
+
this.scope.inTaggedTemplateTag = false;
|
2619
3137
|
}
|
2620
3138
|
if (expression.quasi && expression.quasi.expressions) {
|
2621
3139
|
this.walkExpressions(expression.quasi.expressions);
|
2622
3140
|
}
|
2623
3141
|
}
|
2624
3142
|
|
3143
|
+
/**
|
3144
|
+
* @param {ClassExpression} expression the class expression
|
3145
|
+
*/
|
2625
3146
|
walkClassExpression(expression) {
|
2626
3147
|
this.walkClass(expression);
|
2627
3148
|
}
|
2628
3149
|
|
2629
3150
|
/**
|
2630
|
-
* @param {
|
3151
|
+
* @param {ChainExpression} expression expression
|
2631
3152
|
*/
|
2632
3153
|
walkChainExpression(expression) {
|
2633
3154
|
const result = this.hooks.optionalChaining.call(expression);
|
@@ -2705,6 +3226,9 @@ class JavascriptParser extends Parser {
|
|
2705
3226
|
this.scope.topLevelScope = wasTopLevel;
|
2706
3227
|
}
|
2707
3228
|
|
3229
|
+
/**
|
3230
|
+
* @param {ImportExpression} expression import expression
|
3231
|
+
*/
|
2708
3232
|
walkImportExpression(expression) {
|
2709
3233
|
let result = this.hooks.importCall.call(expression);
|
2710
3234
|
if (result === true) return;
|
@@ -2764,7 +3288,8 @@ class JavascriptParser extends Parser {
|
|
2764
3288
|
callee.getMembers(),
|
2765
3289
|
callee.getMembersOptionals
|
2766
3290
|
? callee.getMembersOptionals()
|
2767
|
-
: callee.getMembers().map(() => false)
|
3291
|
+
: callee.getMembers().map(() => false),
|
3292
|
+
callee.getMemberRanges ? callee.getMemberRanges() : []
|
2768
3293
|
);
|
2769
3294
|
if (result1 === true) return;
|
2770
3295
|
const result2 = this.callHooksForInfo(
|
@@ -2789,6 +3314,9 @@ class JavascriptParser extends Parser {
|
|
2789
3314
|
}
|
2790
3315
|
}
|
2791
3316
|
|
3317
|
+
/**
|
3318
|
+
* @param {MemberExpression} expression member expression
|
3319
|
+
*/
|
2792
3320
|
walkMemberExpression(expression) {
|
2793
3321
|
const exprInfo = this.getMemberExpressionInfo(
|
2794
3322
|
expression,
|
@@ -2805,12 +3333,14 @@ class JavascriptParser extends Parser {
|
|
2805
3333
|
if (result1 === true) return;
|
2806
3334
|
const members = exprInfo.getMembers();
|
2807
3335
|
const membersOptionals = exprInfo.getMembersOptionals();
|
3336
|
+
const memberRanges = exprInfo.getMemberRanges();
|
2808
3337
|
const result2 = this.callHooksForInfo(
|
2809
3338
|
this.hooks.expressionMemberChain,
|
2810
3339
|
exprInfo.rootInfo,
|
2811
3340
|
expression,
|
2812
3341
|
members,
|
2813
|
-
membersOptionals
|
3342
|
+
membersOptionals,
|
3343
|
+
memberRanges
|
2814
3344
|
);
|
2815
3345
|
if (result2 === true) return;
|
2816
3346
|
this.walkMemberExpressionWithExpressionName(
|
@@ -2882,16 +3412,22 @@ class JavascriptParser extends Parser {
|
|
2882
3412
|
if (expression.computed === true) this.walkExpression(expression.property);
|
2883
3413
|
}
|
2884
3414
|
|
3415
|
+
/**
|
3416
|
+
* @param {ThisExpression} expression this expression
|
3417
|
+
*/
|
2885
3418
|
walkThisExpression(expression) {
|
2886
3419
|
this.callHooksForName(this.hooks.expression, "this", expression);
|
2887
3420
|
}
|
2888
3421
|
|
3422
|
+
/**
|
3423
|
+
* @param {Identifier} expression identifier
|
3424
|
+
*/
|
2889
3425
|
walkIdentifier(expression) {
|
2890
3426
|
this.callHooksForName(this.hooks.expression, expression.name, expression);
|
2891
3427
|
}
|
2892
3428
|
|
2893
3429
|
/**
|
2894
|
-
* @param {
|
3430
|
+
* @param {MetaProperty} metaProperty meta property
|
2895
3431
|
*/
|
2896
3432
|
walkMetaProperty(metaProperty) {
|
2897
3433
|
this.hooks.expression.for(getRootName(metaProperty)).call(metaProperty);
|
@@ -2911,11 +3447,11 @@ class JavascriptParser extends Parser {
|
|
2911
3447
|
* @template T
|
2912
3448
|
* @template R
|
2913
3449
|
* @param {HookMap<SyncBailHook<T, R>>} hookMap hooks the should be called
|
2914
|
-
* @param {
|
2915
|
-
* @param {function(string, string | ScopeInfo | VariableInfo, function(): string[]): any} fallback callback when variable in not handled by hooks
|
2916
|
-
* @param {function(string): any} defined callback when variable is defined
|
3450
|
+
* @param {MemberExpression} expr expression info
|
3451
|
+
* @param {(function(string, string | ScopeInfo | VariableInfo, function(): string[]): any) | undefined} fallback callback when variable in not handled by hooks
|
3452
|
+
* @param {(function(string): any) | undefined} defined callback when variable is defined
|
2917
3453
|
* @param {AsArray<T>} args args for the hook
|
2918
|
-
* @returns {R} result of hook
|
3454
|
+
* @returns {R | undefined} result of hook
|
2919
3455
|
*/
|
2920
3456
|
callHooksForExpressionWithFallback(
|
2921
3457
|
hookMap,
|
@@ -2947,7 +3483,7 @@ class JavascriptParser extends Parser {
|
|
2947
3483
|
* @param {HookMap<SyncBailHook<T, R>>} hookMap hooks the should be called
|
2948
3484
|
* @param {string} name key in map
|
2949
3485
|
* @param {AsArray<T>} args args for the hook
|
2950
|
-
* @returns {R} result of hook
|
3486
|
+
* @returns {R | undefined} result of hook
|
2951
3487
|
*/
|
2952
3488
|
callHooksForName(hookMap, name, ...args) {
|
2953
3489
|
return this.callHooksForNameWithFallback(
|
@@ -2965,7 +3501,7 @@ class JavascriptParser extends Parser {
|
|
2965
3501
|
* @param {HookMap<SyncBailHook<T, R>>} hookMap hooks that should be called
|
2966
3502
|
* @param {ExportedVariableInfo} info variable info
|
2967
3503
|
* @param {AsArray<T>} args args for the hook
|
2968
|
-
* @returns {R} result of hook
|
3504
|
+
* @returns {R | undefined} result of hook
|
2969
3505
|
*/
|
2970
3506
|
callHooksForInfo(hookMap, info, ...args) {
|
2971
3507
|
return this.callHooksForInfoWithFallback(
|
@@ -2982,10 +3518,10 @@ class JavascriptParser extends Parser {
|
|
2982
3518
|
* @template R
|
2983
3519
|
* @param {HookMap<SyncBailHook<T, R>>} hookMap hooks the should be called
|
2984
3520
|
* @param {ExportedVariableInfo} info variable info
|
2985
|
-
* @param {function(string): any} fallback callback when variable in not handled by hooks
|
2986
|
-
* @param {function(): any} defined callback when variable is defined
|
3521
|
+
* @param {(function(string): any) | undefined} fallback callback when variable in not handled by hooks
|
3522
|
+
* @param {(function(): any) | undefined} defined callback when variable is defined
|
2987
3523
|
* @param {AsArray<T>} args args for the hook
|
2988
|
-
* @returns {R} result of hook
|
3524
|
+
* @returns {R | undefined} result of hook
|
2989
3525
|
*/
|
2990
3526
|
callHooksForInfoWithFallback(hookMap, info, fallback, defined, ...args) {
|
2991
3527
|
let name;
|
@@ -3032,10 +3568,10 @@ class JavascriptParser extends Parser {
|
|
3032
3568
|
* @template R
|
3033
3569
|
* @param {HookMap<SyncBailHook<T, R>>} hookMap hooks the should be called
|
3034
3570
|
* @param {string} name key in map
|
3035
|
-
* @param {function(string): any} fallback callback when variable in not handled by hooks
|
3036
|
-
* @param {function(): any} defined callback when variable is defined
|
3571
|
+
* @param {(function(string): any) | undefined} fallback callback when variable in not handled by hooks
|
3572
|
+
* @param {(function(): any) | undefined} defined callback when variable is defined
|
3037
3573
|
* @param {AsArray<T>} args args for the hook
|
3038
|
-
* @returns {R} result of hook
|
3574
|
+
* @returns {R | undefined} result of hook
|
3039
3575
|
*/
|
3040
3576
|
callHooksForNameWithFallback(hookMap, name, fallback, defined, ...args) {
|
3041
3577
|
return this.callHooksForInfoWithFallback(
|
@@ -3059,6 +3595,7 @@ class JavascriptParser extends Parser {
|
|
3059
3595
|
topLevelScope: oldScope.topLevelScope,
|
3060
3596
|
inTry: false,
|
3061
3597
|
inShorthand: false,
|
3598
|
+
inTaggedTemplateTag: false,
|
3062
3599
|
isStrict: oldScope.isStrict,
|
3063
3600
|
isAsmJs: oldScope.isAsmJs,
|
3064
3601
|
definitions: oldScope.definitions.createChild()
|
@@ -3075,12 +3612,50 @@ class JavascriptParser extends Parser {
|
|
3075
3612
|
this.scope = oldScope;
|
3076
3613
|
}
|
3077
3614
|
|
3615
|
+
/**
|
3616
|
+
* @param {boolean} hasThis true, when this is defined
|
3617
|
+
* @param {any} params scope params
|
3618
|
+
* @param {function(): void} fn inner function
|
3619
|
+
* @returns {void}
|
3620
|
+
*/
|
3621
|
+
inClassScope(hasThis, params, fn) {
|
3622
|
+
const oldScope = this.scope;
|
3623
|
+
this.scope = {
|
3624
|
+
topLevelScope: oldScope.topLevelScope,
|
3625
|
+
inTry: false,
|
3626
|
+
inShorthand: false,
|
3627
|
+
inTaggedTemplateTag: false,
|
3628
|
+
isStrict: oldScope.isStrict,
|
3629
|
+
isAsmJs: oldScope.isAsmJs,
|
3630
|
+
definitions: oldScope.definitions.createChild()
|
3631
|
+
};
|
3632
|
+
|
3633
|
+
if (hasThis) {
|
3634
|
+
this.undefineVariable("this");
|
3635
|
+
}
|
3636
|
+
|
3637
|
+
this.enterPatterns(params, (ident, pattern) => {
|
3638
|
+
this.defineVariable(ident);
|
3639
|
+
});
|
3640
|
+
|
3641
|
+
fn();
|
3642
|
+
|
3643
|
+
this.scope = oldScope;
|
3644
|
+
}
|
3645
|
+
|
3646
|
+
/**
|
3647
|
+
* @param {boolean} hasThis true, when this is defined
|
3648
|
+
* @param {any} params scope params
|
3649
|
+
* @param {function(): void} fn inner function
|
3650
|
+
* @returns {void}
|
3651
|
+
*/
|
3078
3652
|
inFunctionScope(hasThis, params, fn) {
|
3079
3653
|
const oldScope = this.scope;
|
3080
3654
|
this.scope = {
|
3081
3655
|
topLevelScope: oldScope.topLevelScope,
|
3082
3656
|
inTry: false,
|
3083
3657
|
inShorthand: false,
|
3658
|
+
inTaggedTemplateTag: false,
|
3084
3659
|
isStrict: oldScope.isStrict,
|
3085
3660
|
isAsmJs: oldScope.isAsmJs,
|
3086
3661
|
definitions: oldScope.definitions.createChild()
|
@@ -3099,12 +3674,17 @@ class JavascriptParser extends Parser {
|
|
3099
3674
|
this.scope = oldScope;
|
3100
3675
|
}
|
3101
3676
|
|
3677
|
+
/**
|
3678
|
+
* @param {function(): void} fn inner function
|
3679
|
+
* @returns {void}
|
3680
|
+
*/
|
3102
3681
|
inBlockScope(fn) {
|
3103
3682
|
const oldScope = this.scope;
|
3104
3683
|
this.scope = {
|
3105
3684
|
topLevelScope: oldScope.topLevelScope,
|
3106
3685
|
inTry: oldScope.inTry,
|
3107
3686
|
inShorthand: false,
|
3687
|
+
inTaggedTemplateTag: false,
|
3108
3688
|
isStrict: oldScope.isStrict,
|
3109
3689
|
isAsmJs: oldScope.isAsmJs,
|
3110
3690
|
definitions: oldScope.definitions.createChild()
|
@@ -3115,15 +3695,28 @@ class JavascriptParser extends Parser {
|
|
3115
3695
|
this.scope = oldScope;
|
3116
3696
|
}
|
3117
3697
|
|
3698
|
+
/**
|
3699
|
+
* @param {Array<Directive | Statement | ModuleDeclaration>} statements statements
|
3700
|
+
*/
|
3118
3701
|
detectMode(statements) {
|
3119
3702
|
const isLiteral =
|
3120
3703
|
statements.length >= 1 &&
|
3121
3704
|
statements[0].type === "ExpressionStatement" &&
|
3122
3705
|
statements[0].expression.type === "Literal";
|
3123
|
-
if (
|
3706
|
+
if (
|
3707
|
+
isLiteral &&
|
3708
|
+
/** @type {Literal} */
|
3709
|
+
(/** @type {ExpressionStatement} */ (statements[0]).expression).value ===
|
3710
|
+
"use strict"
|
3711
|
+
) {
|
3124
3712
|
this.scope.isStrict = true;
|
3125
3713
|
}
|
3126
|
-
if (
|
3714
|
+
if (
|
3715
|
+
isLiteral &&
|
3716
|
+
/** @type {Literal} */
|
3717
|
+
(/** @type {ExpressionStatement} */ (statements[0]).expression).value ===
|
3718
|
+
"use asm"
|
3719
|
+
) {
|
3127
3720
|
this.scope.isAsmJs = true;
|
3128
3721
|
}
|
3129
3722
|
}
|
@@ -3168,12 +3761,20 @@ class JavascriptParser extends Parser {
|
|
3168
3761
|
}
|
3169
3762
|
}
|
3170
3763
|
|
3764
|
+
/**
|
3765
|
+
* @param {Identifier} pattern identifier pattern
|
3766
|
+
* @param {TODO} onIdent callback
|
3767
|
+
*/
|
3171
3768
|
enterIdentifier(pattern, onIdent) {
|
3172
3769
|
if (!this.callHooksForName(this.hooks.pattern, pattern.name, pattern)) {
|
3173
3770
|
onIdent(pattern.name, pattern);
|
3174
3771
|
}
|
3175
3772
|
}
|
3176
3773
|
|
3774
|
+
/**
|
3775
|
+
* @param {ObjectPattern} pattern object pattern
|
3776
|
+
* @param {TODO} onIdent callback
|
3777
|
+
*/
|
3177
3778
|
enterObjectPattern(pattern, onIdent) {
|
3178
3779
|
for (
|
3179
3780
|
let propIndex = 0, len = pattern.properties.length;
|
@@ -3185,6 +3786,10 @@ class JavascriptParser extends Parser {
|
|
3185
3786
|
}
|
3186
3787
|
}
|
3187
3788
|
|
3789
|
+
/**
|
3790
|
+
* @param {ArrayPattern} pattern object pattern
|
3791
|
+
* @param {TODO} onIdent callback
|
3792
|
+
*/
|
3188
3793
|
enterArrayPattern(pattern, onIdent) {
|
3189
3794
|
for (
|
3190
3795
|
let elementIndex = 0, len = pattern.elements.length;
|
@@ -3192,20 +3797,29 @@ class JavascriptParser extends Parser {
|
|
3192
3797
|
elementIndex++
|
3193
3798
|
) {
|
3194
3799
|
const element = pattern.elements[elementIndex];
|
3800
|
+
// TODO check on `null`?
|
3195
3801
|
this.enterPattern(element, onIdent);
|
3196
3802
|
}
|
3197
3803
|
}
|
3198
3804
|
|
3805
|
+
/**
|
3806
|
+
* @param {RestElement} pattern object pattern
|
3807
|
+
* @param {TODO} onIdent callback
|
3808
|
+
*/
|
3199
3809
|
enterRestElement(pattern, onIdent) {
|
3200
3810
|
this.enterPattern(pattern.argument, onIdent);
|
3201
3811
|
}
|
3202
3812
|
|
3813
|
+
/**
|
3814
|
+
* @param {AssignmentPattern} pattern object pattern
|
3815
|
+
* @param {TODO} onIdent callback
|
3816
|
+
*/
|
3203
3817
|
enterAssignmentPattern(pattern, onIdent) {
|
3204
3818
|
this.enterPattern(pattern.left, onIdent);
|
3205
3819
|
}
|
3206
3820
|
|
3207
3821
|
/**
|
3208
|
-
* @param {
|
3822
|
+
* @param {TODO} expression expression node
|
3209
3823
|
* @returns {BasicEvaluatedExpression} evaluation result
|
3210
3824
|
*/
|
3211
3825
|
evaluateExpression(expression) {
|
@@ -3223,10 +3837,14 @@ class JavascriptParser extends Parser {
|
|
3223
3837
|
// ignore error
|
3224
3838
|
}
|
3225
3839
|
return new BasicEvaluatedExpression()
|
3226
|
-
.setRange(expression.range)
|
3840
|
+
.setRange(/** @type {Range} */ (expression.range))
|
3227
3841
|
.setExpression(expression);
|
3228
3842
|
}
|
3229
3843
|
|
3844
|
+
/**
|
3845
|
+
* @param {Expression} expression expression
|
3846
|
+
* @returns {string} parsed string
|
3847
|
+
*/
|
3230
3848
|
parseString(expression) {
|
3231
3849
|
switch (expression.type) {
|
3232
3850
|
case "BinaryExpression":
|
@@ -3335,7 +3953,7 @@ class JavascriptParser extends Parser {
|
|
3335
3953
|
source = source.toString("utf-8");
|
3336
3954
|
}
|
3337
3955
|
if (typeof source === "object") {
|
3338
|
-
ast = /** @type {
|
3956
|
+
ast = /** @type {Program} */ (source);
|
3339
3957
|
comments = source.comments;
|
3340
3958
|
} else {
|
3341
3959
|
comments = [];
|
@@ -3356,6 +3974,7 @@ class JavascriptParser extends Parser {
|
|
3356
3974
|
topLevelScope: true,
|
3357
3975
|
inTry: false,
|
3358
3976
|
inShorthand: false,
|
3977
|
+
inTaggedTemplateTag: false,
|
3359
3978
|
isStrict: false,
|
3360
3979
|
isAsmJs: false,
|
3361
3980
|
definitions: new StackedMap()
|
@@ -3367,12 +3986,14 @@ class JavascriptParser extends Parser {
|
|
3367
3986
|
this.statementPath = [];
|
3368
3987
|
this.prevStatement = undefined;
|
3369
3988
|
if (this.hooks.program.call(ast, comments) === undefined) {
|
3989
|
+
this.destructuringAssignmentProperties = new WeakMap();
|
3370
3990
|
this.detectMode(ast.body);
|
3371
3991
|
this.preWalkStatements(ast.body);
|
3372
3992
|
this.prevStatement = undefined;
|
3373
3993
|
this.blockPreWalkStatements(ast.body);
|
3374
3994
|
this.prevStatement = undefined;
|
3375
3995
|
this.walkStatements(ast.body);
|
3996
|
+
this.destructuringAssignmentProperties = undefined;
|
3376
3997
|
}
|
3377
3998
|
this.hooks.finish.call(ast, comments);
|
3378
3999
|
this.scope = oldScope;
|
@@ -3401,7 +4022,7 @@ class JavascriptParser extends Parser {
|
|
3401
4022
|
}
|
3402
4023
|
|
3403
4024
|
/**
|
3404
|
-
* @param {
|
4025
|
+
* @param {Expression | Declaration | PrivateIdentifier | null | undefined} expr an expression
|
3405
4026
|
* @param {number} commentsStartPos source position from which annotation comments are checked
|
3406
4027
|
* @returns {boolean} true, when the expression is pure
|
3407
4028
|
*/
|
@@ -3412,6 +4033,7 @@ class JavascriptParser extends Parser {
|
|
3412
4033
|
.call(expr, commentsStartPos);
|
3413
4034
|
if (typeof result === "boolean") return result;
|
3414
4035
|
switch (expr.type) {
|
4036
|
+
// TODO handle more cases
|
3415
4037
|
case "ClassDeclaration":
|
3416
4038
|
case "ClassExpression": {
|
3417
4039
|
if (expr.body.type !== "ClassBody") return false;
|
@@ -3419,63 +4041,94 @@ class JavascriptParser extends Parser {
|
|
3419
4041
|
return false;
|
3420
4042
|
}
|
3421
4043
|
const items =
|
3422
|
-
/** @type {
|
3423
|
-
|
3424
|
-
|
3425
|
-
|
3426
|
-
|
3427
|
-
|
3428
|
-
|
3429
|
-
|
3430
|
-
|
3431
|
-
|
3432
|
-
|
3433
|
-
|
3434
|
-
|
3435
|
-
|
3436
|
-
|
4044
|
+
/** @type {TODO[]} */
|
4045
|
+
(expr.body.body);
|
4046
|
+
return items.every(item => {
|
4047
|
+
if (
|
4048
|
+
item.computed &&
|
4049
|
+
item.key &&
|
4050
|
+
!this.isPure(item.key, item.range[0])
|
4051
|
+
) {
|
4052
|
+
return false;
|
4053
|
+
}
|
4054
|
+
|
4055
|
+
if (
|
4056
|
+
item.static &&
|
4057
|
+
item.value &&
|
4058
|
+
!this.isPure(
|
4059
|
+
item.value,
|
4060
|
+
item.key ? item.key.range[1] : item.range[0]
|
4061
|
+
)
|
4062
|
+
) {
|
4063
|
+
return false;
|
4064
|
+
}
|
4065
|
+
|
4066
|
+
if (item.type === "StaticBlock") {
|
4067
|
+
return false;
|
4068
|
+
}
|
4069
|
+
|
4070
|
+
return true;
|
4071
|
+
});
|
3437
4072
|
}
|
3438
4073
|
|
3439
4074
|
case "FunctionDeclaration":
|
3440
4075
|
case "FunctionExpression":
|
3441
4076
|
case "ArrowFunctionExpression":
|
4077
|
+
case "ThisExpression":
|
3442
4078
|
case "Literal":
|
4079
|
+
case "TemplateLiteral":
|
4080
|
+
case "Identifier":
|
3443
4081
|
case "PrivateIdentifier":
|
3444
4082
|
return true;
|
3445
4083
|
|
3446
4084
|
case "VariableDeclaration":
|
3447
4085
|
return expr.declarations.every(decl =>
|
3448
|
-
this.isPure(decl.init, decl.range[0])
|
4086
|
+
this.isPure(decl.init, /** @type {Range} */ (decl.range)[0])
|
3449
4087
|
);
|
3450
4088
|
|
3451
4089
|
case "ConditionalExpression":
|
3452
4090
|
return (
|
3453
4091
|
this.isPure(expr.test, commentsStartPos) &&
|
3454
|
-
this.isPure(
|
3455
|
-
|
4092
|
+
this.isPure(
|
4093
|
+
expr.consequent,
|
4094
|
+
/** @type {Range} */ (expr.test.range)[1]
|
4095
|
+
) &&
|
4096
|
+
this.isPure(
|
4097
|
+
expr.alternate,
|
4098
|
+
/** @type {Range} */ (expr.consequent.range)[1]
|
4099
|
+
)
|
4100
|
+
);
|
4101
|
+
|
4102
|
+
case "LogicalExpression":
|
4103
|
+
return (
|
4104
|
+
this.isPure(expr.left, commentsStartPos) &&
|
4105
|
+
this.isPure(expr.right, /** @type {Range} */ (expr.left.range)[1])
|
3456
4106
|
);
|
3457
4107
|
|
3458
4108
|
case "SequenceExpression":
|
3459
4109
|
return expr.expressions.every(expr => {
|
3460
4110
|
const pureFlag = this.isPure(expr, commentsStartPos);
|
3461
|
-
commentsStartPos = expr.range[1];
|
4111
|
+
commentsStartPos = /** @type {Range} */ (expr.range)[1];
|
3462
4112
|
return pureFlag;
|
3463
4113
|
});
|
3464
4114
|
|
3465
4115
|
case "CallExpression": {
|
3466
4116
|
const pureFlag =
|
3467
|
-
expr.range[0] - commentsStartPos > 12 &&
|
3468
|
-
this.getComments([
|
4117
|
+
/** @type {Range} */ (expr.range)[0] - commentsStartPos > 12 &&
|
4118
|
+
this.getComments([
|
4119
|
+
commentsStartPos,
|
4120
|
+
/** @type {Range} */ (expr.range)[0]
|
4121
|
+
]).some(
|
3469
4122
|
comment =>
|
3470
4123
|
comment.type === "Block" &&
|
3471
4124
|
/^\s*(#|@)__PURE__\s*$/.test(comment.value)
|
3472
4125
|
);
|
3473
4126
|
if (!pureFlag) return false;
|
3474
|
-
commentsStartPos = expr.callee.range[1];
|
4127
|
+
commentsStartPos = /** @type {Range} */ (expr.callee.range)[1];
|
3475
4128
|
return expr.arguments.every(arg => {
|
3476
4129
|
if (arg.type === "SpreadElement") return false;
|
3477
4130
|
const pureFlag = this.isPure(arg, commentsStartPos);
|
3478
|
-
commentsStartPos = arg.range[1];
|
4131
|
+
commentsStartPos = /** @type {Range} */ (arg.range)[1];
|
3479
4132
|
return pureFlag;
|
3480
4133
|
});
|
3481
4134
|
}
|
@@ -3484,6 +4137,10 @@ class JavascriptParser extends Parser {
|
|
3484
4137
|
return !evaluated.couldHaveSideEffects();
|
3485
4138
|
}
|
3486
4139
|
|
4140
|
+
/**
|
4141
|
+
* @param {Range} range range
|
4142
|
+
* @returns {TODO[]} comments in the range
|
4143
|
+
*/
|
3487
4144
|
getComments(range) {
|
3488
4145
|
const [rangeStart, rangeEnd] = range;
|
3489
4146
|
const compare = (comment, needle) => comment.range[0] - needle;
|
@@ -3525,6 +4182,10 @@ class JavascriptParser extends Parser {
|
|
3525
4182
|
this.semicolons.delete(pos);
|
3526
4183
|
}
|
3527
4184
|
|
4185
|
+
/**
|
4186
|
+
* @param {Expression} expr expression
|
4187
|
+
* @returns {boolean} true, when the expression is a statement level expression
|
4188
|
+
*/
|
3528
4189
|
isStatementLevelExpression(expr) {
|
3529
4190
|
const currentStatement = this.statementPath[this.statementPath.length - 1];
|
3530
4191
|
return (
|
@@ -3571,6 +4232,9 @@ class JavascriptParser extends Parser {
|
|
3571
4232
|
this.scope.definitions.set(name, newInfo);
|
3572
4233
|
}
|
3573
4234
|
|
4235
|
+
/**
|
4236
|
+
* @param {string} name variable name
|
4237
|
+
*/
|
3574
4238
|
defineVariable(name) {
|
3575
4239
|
const oldInfo = this.scope.definitions.get(name);
|
3576
4240
|
// Don't redefine variable in same scope to keep existing tags
|
@@ -3579,10 +4243,17 @@ class JavascriptParser extends Parser {
|
|
3579
4243
|
this.scope.definitions.set(name, this.scope);
|
3580
4244
|
}
|
3581
4245
|
|
4246
|
+
/**
|
4247
|
+
* @param {string} name variable name
|
4248
|
+
*/
|
3582
4249
|
undefineVariable(name) {
|
3583
4250
|
this.scope.definitions.delete(name);
|
3584
4251
|
}
|
3585
4252
|
|
4253
|
+
/**
|
4254
|
+
* @param {string} name variable name
|
4255
|
+
* @returns {boolean} true, when variable is defined
|
4256
|
+
*/
|
3586
4257
|
isVariableDefined(name) {
|
3587
4258
|
const info = this.scope.definitions.get(name);
|
3588
4259
|
if (info === undefined) return false;
|
@@ -3625,10 +4296,18 @@ class JavascriptParser extends Parser {
|
|
3625
4296
|
}
|
3626
4297
|
}
|
3627
4298
|
|
4299
|
+
/**
|
4300
|
+
* @param {TagInfo} tagInfo tag info
|
4301
|
+
* @returns {VariableInfo} variable info
|
4302
|
+
*/
|
3628
4303
|
evaluatedVariable(tagInfo) {
|
3629
4304
|
return new VariableInfo(this.scope, undefined, tagInfo);
|
3630
4305
|
}
|
3631
4306
|
|
4307
|
+
/**
|
4308
|
+
* @param {Range} range range of the comment
|
4309
|
+
* @returns {TODO} TODO
|
4310
|
+
*/
|
3632
4311
|
parseCommentOptions(range) {
|
3633
4312
|
const comments = this.getComments(range);
|
3634
4313
|
if (comments.length === 0) {
|
@@ -3663,21 +4342,24 @@ class JavascriptParser extends Parser {
|
|
3663
4342
|
}
|
3664
4343
|
|
3665
4344
|
/**
|
3666
|
-
* @param {
|
3667
|
-
* @returns {{ members: string[], object:
|
4345
|
+
* @param {MemberExpression} expression a member expression
|
4346
|
+
* @returns {{ members: string[], object: Expression | Super, membersOptionals: boolean[], memberRanges: Range[] }} member names (reverse order) and remaining object
|
3668
4347
|
*/
|
3669
4348
|
extractMemberExpressionChain(expression) {
|
3670
4349
|
/** @type {AnyNode} */
|
3671
4350
|
let expr = expression;
|
3672
4351
|
const members = [];
|
3673
4352
|
const membersOptionals = [];
|
4353
|
+
const memberRanges = [];
|
3674
4354
|
while (expr.type === "MemberExpression") {
|
3675
4355
|
if (expr.computed) {
|
3676
4356
|
if (expr.property.type !== "Literal") break;
|
3677
|
-
members.push(`${expr.property.value}`);
|
4357
|
+
members.push(`${expr.property.value}`); // the literal
|
4358
|
+
memberRanges.push(expr.object.range); // the range of the expression fragment before the literal
|
3678
4359
|
} else {
|
3679
4360
|
if (expr.property.type !== "Identifier") break;
|
3680
|
-
members.push(expr.property.name);
|
4361
|
+
members.push(expr.property.name); // the identifier
|
4362
|
+
memberRanges.push(expr.object.range); // the range of the expression fragment before the identifier
|
3681
4363
|
}
|
3682
4364
|
membersOptionals.push(expr.optional);
|
3683
4365
|
expr = expr.object;
|
@@ -3686,13 +4368,14 @@ class JavascriptParser extends Parser {
|
|
3686
4368
|
return {
|
3687
4369
|
members,
|
3688
4370
|
membersOptionals,
|
4371
|
+
memberRanges,
|
3689
4372
|
object: expr
|
3690
4373
|
};
|
3691
4374
|
}
|
3692
4375
|
|
3693
4376
|
/**
|
3694
4377
|
* @param {string} varName variable name
|
3695
|
-
* @returns {{name: string, info: VariableInfo | string}} name of the free variable and variable info for that
|
4378
|
+
* @returns {{name: string, info: VariableInfo | string} | undefined} name of the free variable and variable info for that
|
3696
4379
|
*/
|
3697
4380
|
getFreeInfoFromVariable(varName) {
|
3698
4381
|
const info = this.getVariableInfo(varName);
|
@@ -3708,16 +4391,16 @@ class JavascriptParser extends Parser {
|
|
3708
4391
|
return { info, name };
|
3709
4392
|
}
|
3710
4393
|
|
3711
|
-
/** @typedef {{ type: "call", call:
|
3712
|
-
/** @typedef {{ type: "expression", rootInfo: string | VariableInfo, name: string, getMembers: () => string[], getMembersOptionals: () => boolean[]}} ExpressionExpressionInfo */
|
4394
|
+
/** @typedef {{ type: "call", call: CallExpression, calleeName: string, rootInfo: string | VariableInfo, getCalleeMembers: () => string[], name: string, getMembers: () => string[], getMembersOptionals: () => boolean[], getMemberRanges: () => Range[]}} CallExpressionInfo */
|
4395
|
+
/** @typedef {{ type: "expression", rootInfo: string | VariableInfo, name: string, getMembers: () => string[], getMembersOptionals: () => boolean[], getMemberRanges: () => Range[]}} ExpressionExpressionInfo */
|
3713
4396
|
|
3714
4397
|
/**
|
3715
|
-
* @param {
|
4398
|
+
* @param {MemberExpression} expression a member expression
|
3716
4399
|
* @param {number} allowedTypes which types should be returned, presented in bit mask
|
3717
4400
|
* @returns {CallExpressionInfo | ExpressionExpressionInfo | undefined} expression info
|
3718
4401
|
*/
|
3719
4402
|
getMemberExpressionInfo(expression, allowedTypes) {
|
3720
|
-
const { object, members, membersOptionals } =
|
4403
|
+
const { object, members, membersOptionals, memberRanges } =
|
3721
4404
|
this.extractMemberExpressionChain(expression);
|
3722
4405
|
switch (object.type) {
|
3723
4406
|
case "CallExpression": {
|
@@ -3743,7 +4426,8 @@ class JavascriptParser extends Parser {
|
|
3743
4426
|
getCalleeMembers: memoize(() => rootMembers.reverse()),
|
3744
4427
|
name: objectAndMembersToName(`${calleeName}()`, members),
|
3745
4428
|
getMembers: memoize(() => members.reverse()),
|
3746
|
-
getMembersOptionals: memoize(() => membersOptionals.reverse())
|
4429
|
+
getMembersOptionals: memoize(() => membersOptionals.reverse()),
|
4430
|
+
getMemberRanges: memoize(() => memberRanges.reverse())
|
3747
4431
|
};
|
3748
4432
|
}
|
3749
4433
|
case "Identifier":
|
@@ -3762,15 +4446,16 @@ class JavascriptParser extends Parser {
|
|
3762
4446
|
name: objectAndMembersToName(resolvedRoot, members),
|
3763
4447
|
rootInfo,
|
3764
4448
|
getMembers: memoize(() => members.reverse()),
|
3765
|
-
getMembersOptionals: memoize(() => membersOptionals.reverse())
|
4449
|
+
getMembersOptionals: memoize(() => membersOptionals.reverse()),
|
4450
|
+
getMemberRanges: memoize(() => memberRanges.reverse())
|
3766
4451
|
};
|
3767
4452
|
}
|
3768
4453
|
}
|
3769
4454
|
}
|
3770
4455
|
|
3771
4456
|
/**
|
3772
|
-
* @param {
|
3773
|
-
* @returns {{ name: string, rootInfo: ExportedVariableInfo, getMembers: () => string[]}} name info
|
4457
|
+
* @param {MemberExpression} expression an expression
|
4458
|
+
* @returns {{ name: string, rootInfo: ExportedVariableInfo, getMembers: () => string[]} | undefined} name info
|
3774
4459
|
*/
|
3775
4460
|
getNameForExpression(expression) {
|
3776
4461
|
return this.getMemberExpressionInfo(
|
@@ -3782,7 +4467,7 @@ class JavascriptParser extends Parser {
|
|
3782
4467
|
/**
|
3783
4468
|
* @param {string} code source code
|
3784
4469
|
* @param {ParseOptions} options parsing options
|
3785
|
-
* @returns {
|
4470
|
+
* @returns {Program} parsed ast
|
3786
4471
|
*/
|
3787
4472
|
static _parse(code, options) {
|
3788
4473
|
const type = options ? options.sourceType : "module";
|
@@ -3794,7 +4479,7 @@ class JavascriptParser extends Parser {
|
|
3794
4479
|
sourceType: type === "auto" ? "module" : type
|
3795
4480
|
};
|
3796
4481
|
|
3797
|
-
/** @type {AnyNode} */
|
4482
|
+
/** @type {AnyNode | undefined} */
|
3798
4483
|
let ast;
|
3799
4484
|
let error;
|
3800
4485
|
let threw = false;
|
@@ -3826,7 +4511,7 @@ class JavascriptParser extends Parser {
|
|
3826
4511
|
throw error;
|
3827
4512
|
}
|
3828
4513
|
|
3829
|
-
return /** @type {
|
4514
|
+
return /** @type {Program} */ (ast);
|
3830
4515
|
}
|
3831
4516
|
}
|
3832
4517
|
|