webpack 5.59.0 → 5.94.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +48 -38
- package/bin/webpack.js +34 -10
- package/hot/dev-server.js +19 -5
- package/hot/lazy-compilation-node.js +13 -1
- package/hot/lazy-compilation-web.js +9 -0
- package/hot/log-apply-result.js +5 -0
- package/hot/log.js +23 -4
- package/hot/only-dev-server.js +3 -2
- package/hot/poll.js +5 -2
- package/hot/signal.js +6 -2
- package/lib/APIPlugin.js +226 -122
- package/lib/AbstractMethodError.js +10 -5
- package/lib/AsyncDependenciesBlock.js +13 -5
- package/lib/AutomaticPrefetchPlugin.js +2 -1
- package/lib/BannerPlugin.js +33 -12
- package/lib/Cache.js +16 -12
- package/lib/CacheFacade.js +13 -16
- package/lib/CaseSensitiveModulesWarning.js +8 -8
- package/lib/Chunk.js +60 -33
- package/lib/ChunkGraph.js +207 -72
- package/lib/ChunkGroup.js +40 -20
- package/lib/ChunkTemplate.js +43 -0
- package/lib/CleanPlugin.js +117 -32
- package/lib/CodeGenerationResults.js +8 -7
- package/lib/CommentCompilationWarning.js +0 -1
- package/lib/CompatibilityPlugin.js +85 -46
- package/lib/Compilation.js +712 -392
- package/lib/Compiler.js +393 -172
- package/lib/ConcatenationScope.js +10 -13
- package/lib/ConditionalInitFragment.js +22 -14
- package/lib/ConstPlugin.js +104 -64
- package/lib/ContextExclusionPlugin.js +3 -3
- package/lib/ContextModule.js +283 -108
- package/lib/ContextModuleFactory.js +151 -63
- package/lib/ContextReplacementPlugin.js +25 -10
- package/lib/CssModule.js +166 -0
- package/lib/DefinePlugin.js +254 -148
- package/lib/DelegatedModule.js +29 -6
- package/lib/DelegatedModuleFactoryPlugin.js +42 -22
- package/lib/DelegatedPlugin.js +4 -0
- package/lib/DependenciesBlock.js +17 -2
- package/lib/Dependency.js +58 -29
- package/lib/DependencyTemplate.js +24 -3
- package/lib/DependencyTemplates.js +2 -2
- package/lib/DllEntryPlugin.js +18 -1
- package/lib/DllModule.js +21 -4
- package/lib/DllModuleFactory.js +2 -1
- package/lib/DllPlugin.js +9 -7
- package/lib/DllReferencePlugin.js +50 -19
- package/lib/EntryOptionPlugin.js +6 -1
- package/lib/EntryPlugin.js +7 -4
- package/lib/Entrypoint.js +2 -2
- package/lib/EnvironmentNotSupportAsyncWarning.js +52 -0
- package/lib/EnvironmentPlugin.js +5 -2
- package/lib/ErrorHelpers.js +65 -26
- package/lib/EvalDevToolModulePlugin.js +37 -13
- package/lib/EvalSourceMapDevToolPlugin.js +50 -20
- package/lib/ExportsInfo.js +234 -133
- package/lib/ExportsInfoApiPlugin.js +31 -15
- package/lib/ExternalModule.js +391 -129
- package/lib/ExternalModuleFactoryPlugin.js +65 -17
- package/lib/FileSystemInfo.js +1038 -523
- package/lib/FlagAllModulesAsUsedPlugin.js +27 -27
- package/lib/FlagDependencyExportsPlugin.js +352 -349
- package/lib/FlagDependencyUsagePlugin.js +10 -10
- package/lib/FlagEntryExportAsUsedPlugin.js +26 -23
- package/lib/Generator.js +16 -8
- package/lib/GraphHelpers.js +3 -2
- package/lib/HookWebpackError.js +11 -13
- package/lib/HotModuleReplacementPlugin.js +221 -128
- package/lib/IgnoreErrorModuleFactory.js +4 -4
- package/lib/IgnorePlugin.js +5 -4
- package/lib/IgnoreWarningsPlugin.js +6 -9
- package/lib/InitFragment.js +39 -15
- package/lib/JavascriptMetaInfoPlugin.js +27 -15
- package/lib/LibManifestPlugin.js +45 -16
- package/lib/LoaderOptionsPlugin.js +13 -3
- package/lib/MainTemplate.js +74 -21
- package/lib/Module.js +155 -34
- package/lib/ModuleBuildError.js +13 -11
- package/lib/ModuleDependencyError.js +6 -4
- package/lib/ModuleDependencyWarning.js +6 -4
- package/lib/ModuleError.js +10 -5
- package/lib/ModuleFactory.js +4 -4
- package/lib/ModuleFilenameHelpers.js +164 -54
- package/lib/ModuleGraph.js +93 -53
- package/lib/ModuleGraphConnection.js +27 -13
- package/lib/ModuleHashingError.js +29 -0
- package/lib/ModuleInfoHeaderPlugin.js +92 -33
- package/lib/ModuleNotFoundError.js +5 -2
- package/lib/ModuleParseError.js +17 -9
- package/lib/ModuleProfile.js +1 -0
- package/lib/ModuleRestoreError.js +3 -1
- package/lib/ModuleStoreError.js +3 -2
- package/lib/ModuleTemplate.js +33 -1
- package/lib/ModuleTypeConstants.js +168 -0
- package/lib/ModuleWarning.js +10 -5
- package/lib/MultiCompiler.js +115 -38
- package/lib/MultiStats.js +75 -33
- package/lib/MultiWatching.js +6 -2
- package/lib/NodeStuffPlugin.js +136 -37
- package/lib/NormalModule.js +437 -194
- package/lib/NormalModuleFactory.js +313 -116
- package/lib/NormalModuleReplacementPlugin.js +10 -4
- package/lib/NullFactory.js +1 -1
- package/lib/OptimizationStages.js +3 -3
- package/lib/Parser.js +1 -1
- package/lib/PlatformPlugin.js +39 -0
- package/lib/PrefetchPlugin.js +4 -0
- package/lib/ProgressPlugin.js +83 -28
- package/lib/ProvidePlugin.js +37 -19
- package/lib/RawModule.js +18 -5
- package/lib/RecordIdsPlugin.js +8 -8
- package/lib/RequireJsStuffPlugin.js +22 -15
- package/lib/ResolverFactory.js +8 -4
- package/lib/RuntimeGlobals.js +99 -65
- package/lib/RuntimeModule.js +17 -15
- package/lib/RuntimePlugin.js +116 -13
- package/lib/RuntimeTemplate.js +304 -102
- package/lib/SelfModuleFactory.js +12 -0
- package/lib/SizeFormatHelpers.js +2 -4
- package/lib/SourceMapDevToolModuleOptionsPlugin.js +4 -0
- package/lib/SourceMapDevToolPlugin.js +89 -42
- package/lib/Stats.js +12 -7
- package/lib/Template.js +30 -33
- package/lib/TemplatedPathPlugin.js +102 -34
- package/lib/UseStrictPlugin.js +37 -12
- package/lib/WarnCaseSensitiveModulesPlugin.js +12 -0
- package/lib/WarnDeprecatedOptionPlugin.js +6 -0
- package/lib/WatchIgnorePlugin.js +46 -13
- package/lib/Watching.js +139 -76
- package/lib/WebpackError.js +14 -5
- package/lib/WebpackIsIncludedPlugin.js +22 -13
- package/lib/WebpackOptionsApply.js +162 -56
- package/lib/WebpackOptionsDefaulter.js +10 -3
- package/lib/asset/AssetGenerator.js +351 -99
- package/lib/asset/AssetModulesPlugin.js +57 -33
- package/lib/asset/AssetParser.js +15 -6
- package/lib/asset/AssetSourceGenerator.js +30 -10
- package/lib/asset/AssetSourceParser.js +8 -2
- package/lib/asset/RawDataUrlModule.js +162 -0
- package/lib/async-modules/AwaitDependenciesInitFragment.js +16 -13
- package/lib/async-modules/InferAsyncModulesPlugin.js +1 -1
- package/lib/buildChunkGraph.js +376 -420
- package/lib/cache/AddManagedPathsPlugin.js +6 -1
- package/lib/cache/IdleFileCachePlugin.js +26 -13
- package/lib/cache/MemoryCachePlugin.js +1 -1
- package/lib/cache/MemoryWithGcCachePlugin.js +13 -7
- package/lib/cache/PackFileCacheStrategy.js +172 -94
- package/lib/cache/ResolverCachePlugin.js +115 -43
- package/lib/cache/getLazyHashedEtag.js +2 -2
- package/lib/cache/mergeEtags.js +16 -21
- package/lib/cli.js +195 -110
- package/lib/config/browserslistTargetHandler.js +106 -41
- package/lib/config/defaults.js +572 -154
- package/lib/config/normalization.js +361 -322
- package/lib/config/target.js +105 -66
- package/lib/container/ContainerEntryDependency.js +2 -1
- package/lib/container/ContainerEntryModule.js +27 -11
- package/lib/container/ContainerEntryModuleFactory.js +1 -1
- package/lib/container/ContainerExposedDependency.js +9 -0
- package/lib/container/ContainerPlugin.js +18 -12
- package/lib/container/ContainerReferencePlugin.js +1 -1
- package/lib/container/FallbackDependency.js +13 -0
- package/lib/container/FallbackItemDependency.js +3 -0
- package/lib/container/FallbackModule.js +19 -8
- package/lib/container/FallbackModuleFactory.js +1 -1
- package/lib/container/ModuleFederationPlugin.js +2 -0
- package/lib/container/RemoteModule.js +17 -4
- package/lib/container/RemoteRuntimeModule.js +31 -17
- package/lib/container/RemoteToExternalDependency.js +3 -0
- package/lib/container/options.js +18 -4
- package/lib/css/CssExportsGenerator.js +203 -0
- package/lib/css/CssGenerator.js +151 -0
- package/lib/css/CssLoadingRuntimeModule.js +592 -0
- package/lib/css/CssModulesPlugin.js +888 -0
- package/lib/css/CssParser.js +1049 -0
- package/lib/css/walkCssTokens.js +775 -0
- package/lib/debug/ProfilingPlugin.js +102 -54
- package/lib/dependencies/AMDDefineDependency.js +54 -10
- package/lib/dependencies/AMDDefineDependencyParserPlugin.js +204 -61
- package/lib/dependencies/AMDPlugin.js +44 -24
- package/lib/dependencies/AMDRequireArrayDependency.js +34 -10
- package/lib/dependencies/AMDRequireContextDependency.js +15 -0
- package/lib/dependencies/AMDRequireDependenciesBlock.js +6 -0
- package/lib/dependencies/AMDRequireDependenciesBlockParserPlugin.js +185 -54
- package/lib/dependencies/AMDRequireDependency.js +21 -6
- package/lib/dependencies/AMDRequireItemDependency.js +6 -0
- package/lib/dependencies/AMDRuntimeModules.js +4 -4
- package/lib/dependencies/CachedConstDependency.js +22 -1
- package/lib/dependencies/CommonJsDependencyHelpers.js +16 -2
- package/lib/dependencies/CommonJsExportRequireDependency.js +77 -47
- package/lib/dependencies/CommonJsExportsDependency.js +28 -5
- package/lib/dependencies/CommonJsExportsParserPlugin.js +111 -39
- package/lib/dependencies/CommonJsFullRequireDependency.js +42 -8
- package/lib/dependencies/CommonJsImportsParserPlugin.js +530 -130
- package/lib/dependencies/CommonJsPlugin.js +51 -26
- package/lib/dependencies/CommonJsRequireContextDependency.js +23 -2
- package/lib/dependencies/CommonJsRequireDependency.js +9 -1
- package/lib/dependencies/CommonJsSelfReferenceDependency.js +22 -8
- package/lib/dependencies/ConstDependency.js +12 -3
- package/lib/dependencies/ContextDependency.js +32 -5
- package/lib/dependencies/ContextDependencyHelpers.js +92 -62
- package/lib/dependencies/ContextDependencyTemplateAsRequireCall.js +4 -1
- package/lib/dependencies/ContextElementDependency.js +41 -4
- package/lib/dependencies/CreateScriptUrlDependency.js +22 -1
- package/lib/dependencies/CriticalDependencyWarning.js +4 -1
- package/lib/dependencies/CssExportDependency.js +156 -0
- package/lib/dependencies/CssImportDependency.js +125 -0
- package/lib/dependencies/CssLocalIdentifierDependency.js +245 -0
- package/lib/dependencies/CssSelfLocalIdentifierDependency.js +111 -0
- package/lib/dependencies/CssUrlDependency.js +164 -0
- package/lib/dependencies/DelegatedSourceDependency.js +3 -0
- package/lib/dependencies/DllEntryDependency.js +14 -0
- package/lib/dependencies/DynamicExports.js +15 -11
- package/lib/dependencies/ExportsInfoDependency.js +26 -5
- package/lib/dependencies/ExternalModuleDependency.js +109 -0
- package/lib/dependencies/ExternalModuleInitFragment.js +133 -0
- package/lib/dependencies/HarmonyAcceptDependency.js +11 -2
- package/lib/dependencies/HarmonyAcceptImportDependency.js +9 -4
- package/lib/dependencies/HarmonyCompatibilityDependency.js +6 -5
- package/lib/dependencies/HarmonyDetectionParserPlugin.js +29 -3
- package/lib/dependencies/HarmonyEvaluatedImportSpecifierDependency.js +152 -0
- package/lib/dependencies/HarmonyExportDependencyParserPlugin.js +96 -51
- package/lib/dependencies/HarmonyExportExpressionDependency.js +21 -4
- package/lib/dependencies/HarmonyExportHeaderDependency.js +13 -0
- package/lib/dependencies/HarmonyExportImportedSpecifierDependency.js +216 -108
- package/lib/dependencies/HarmonyExportInitFragment.js +21 -9
- package/lib/dependencies/HarmonyExportSpecifierDependency.js +12 -0
- package/lib/dependencies/HarmonyExports.js +13 -7
- package/lib/dependencies/HarmonyImportDependency.js +65 -19
- package/lib/dependencies/HarmonyImportDependencyParserPlugin.js +268 -74
- package/lib/dependencies/HarmonyImportSideEffectDependency.js +11 -5
- package/lib/dependencies/HarmonyImportSpecifierDependency.js +180 -36
- package/lib/dependencies/HarmonyModulesPlugin.js +33 -5
- package/lib/dependencies/HarmonyTopLevelThisParserPlugin.js +15 -3
- package/lib/dependencies/ImportContextDependency.js +15 -2
- package/lib/dependencies/ImportDependency.js +50 -12
- package/lib/dependencies/ImportEagerDependency.js +11 -6
- package/lib/dependencies/ImportMetaContextDependency.js +42 -0
- package/lib/dependencies/ImportMetaContextDependencyParserPlugin.js +301 -0
- package/lib/dependencies/ImportMetaContextPlugin.js +72 -0
- package/lib/dependencies/ImportMetaHotAcceptDependency.js +6 -0
- package/lib/dependencies/ImportMetaHotDeclineDependency.js +6 -0
- package/lib/dependencies/ImportMetaPlugin.js +128 -59
- package/lib/dependencies/ImportParserPlugin.js +153 -83
- package/lib/dependencies/ImportPlugin.js +21 -7
- package/lib/dependencies/ImportWeakDependency.js +11 -6
- package/lib/dependencies/JsonExportsDependency.js +38 -30
- package/lib/dependencies/LoaderDependency.js +14 -0
- package/lib/dependencies/LoaderImportDependency.js +14 -0
- package/lib/dependencies/LoaderPlugin.js +54 -40
- package/lib/dependencies/LocalModule.js +17 -1
- package/lib/dependencies/LocalModuleDependency.js +15 -0
- package/lib/dependencies/LocalModulesHelpers.js +22 -4
- package/lib/dependencies/ModuleDecoratorDependency.js +9 -1
- package/lib/dependencies/ModuleDependency.js +24 -7
- 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 +43 -8
- package/lib/dependencies/PureExpressionDependency.js +73 -39
- package/lib/dependencies/RequireContextDependency.js +6 -16
- package/lib/dependencies/RequireContextDependencyParserPlugin.js +14 -6
- package/lib/dependencies/RequireContextPlugin.js +20 -7
- package/lib/dependencies/RequireEnsureDependenciesBlock.js +7 -0
- package/lib/dependencies/RequireEnsureDependenciesBlockParserPlugin.js +29 -12
- 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 +6 -1
- package/lib/dependencies/RequireIncludeDependencyParserPlugin.js +29 -5
- package/lib/dependencies/RequireIncludePlugin.js +25 -5
- package/lib/dependencies/RequireResolveContextDependency.js +19 -2
- package/lib/dependencies/RequireResolveDependency.js +8 -1
- package/lib/dependencies/RequireResolveHeaderDependency.js +18 -0
- package/lib/dependencies/RuntimeRequirementsDependency.js +9 -1
- package/lib/dependencies/StaticExportsDependency.js +8 -0
- package/lib/dependencies/SystemPlugin.js +49 -22
- package/lib/dependencies/SystemRuntimeModule.js +1 -1
- package/lib/dependencies/URLDependency.js +20 -13
- package/lib/dependencies/URLPlugin.js +115 -27
- 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 +6 -1
- package/lib/dependencies/WorkerDependency.js +47 -3
- package/lib/dependencies/WorkerPlugin.js +143 -59
- package/lib/dependencies/getFunctionExpression.js +9 -0
- package/lib/dependencies/processExportInfo.js +3 -1
- package/lib/electron/ElectronTargetPlugin.js +1 -0
- package/lib/esm/ExportWebpackRequireRuntimeModule.js +3 -2
- package/lib/esm/ModuleChunkFormatPlugin.js +92 -55
- package/lib/esm/ModuleChunkLoadingPlugin.js +12 -1
- package/lib/esm/ModuleChunkLoadingRuntimeModule.js +141 -25
- package/lib/formatLocation.js +1 -2
- package/lib/hmr/HotModuleReplacement.runtime.js +37 -25
- package/lib/hmr/HotModuleReplacementRuntimeModule.js +2 -1
- package/lib/hmr/JavascriptHotModuleReplacement.runtime.js +13 -15
- package/lib/hmr/LazyCompilationPlugin.js +94 -41
- package/lib/hmr/lazyCompilationBackend.js +107 -44
- package/lib/ids/ChunkModuleIdRangePlugin.js +12 -3
- package/lib/ids/DeterministicChunkIdsPlugin.js +13 -6
- package/lib/ids/DeterministicModuleIdsPlugin.js +59 -35
- package/lib/ids/HashedModuleIdsPlugin.js +24 -16
- package/lib/ids/IdHelpers.js +59 -49
- package/lib/ids/NamedChunkIdsPlugin.js +13 -1
- package/lib/ids/NamedModuleIdsPlugin.js +20 -12
- package/lib/ids/NaturalModuleIdsPlugin.js +10 -13
- package/lib/ids/OccurrenceChunkIdsPlugin.js +6 -2
- package/lib/ids/OccurrenceModuleIdsPlugin.js +14 -11
- package/lib/ids/SyncModuleIdsPlugin.js +146 -0
- package/lib/index.js +44 -5
- package/lib/javascript/ArrayPushCallbackChunkFormatPlugin.js +9 -7
- package/lib/javascript/BasicEvaluatedExpression.js +133 -19
- package/lib/javascript/ChunkHelpers.js +33 -0
- package/lib/javascript/CommonJsChunkFormatPlugin.js +18 -15
- package/lib/javascript/EnableChunkLoadingPlugin.js +11 -6
- package/lib/javascript/JavascriptGenerator.js +37 -6
- package/lib/javascript/JavascriptModulesPlugin.js +523 -295
- package/lib/javascript/JavascriptParser.js +1591 -574
- package/lib/javascript/JavascriptParserHelpers.js +58 -37
- package/lib/javascript/StartupHelpers.js +69 -47
- package/lib/json/JsonData.js +33 -0
- package/lib/json/JsonGenerator.js +29 -21
- package/lib/json/JsonModulesPlugin.js +13 -7
- package/lib/json/JsonParser.js +30 -16
- package/lib/library/AbstractLibraryPlugin.js +6 -2
- package/lib/library/AmdLibraryPlugin.js +34 -18
- package/lib/library/AssignLibraryPlugin.js +68 -32
- package/lib/library/EnableLibraryPlugin.js +39 -14
- package/lib/library/ExportPropertyLibraryPlugin.js +14 -5
- package/lib/library/JsonpLibraryPlugin.js +4 -3
- package/lib/library/ModernModuleLibraryPlugin.js +144 -0
- package/lib/library/ModuleLibraryPlugin.js +12 -7
- package/lib/library/SystemLibraryPlugin.js +6 -4
- package/lib/library/UmdLibraryPlugin.js +119 -100
- package/lib/logging/Logger.js +59 -6
- package/lib/logging/createConsoleLogger.js +25 -40
- package/lib/logging/runtime.js +8 -9
- package/lib/logging/truncateArgs.js +9 -8
- package/lib/node/CommonJsChunkLoadingPlugin.js +18 -2
- package/lib/node/NodeEnvironmentPlugin.js +14 -8
- package/lib/node/NodeTargetPlugin.js +7 -0
- package/lib/node/NodeTemplatePlugin.js +10 -2
- package/lib/node/NodeWatchFileSystem.js +100 -50
- package/lib/node/ReadFileChunkLoadingRuntimeModule.js +51 -26
- package/lib/node/ReadFileCompileAsyncWasmPlugin.js +13 -2
- package/lib/node/ReadFileCompileWasmPlugin.js +21 -3
- package/lib/node/RequireChunkLoadingRuntimeModule.js +49 -26
- package/lib/node/nodeConsole.js +48 -31
- package/lib/optimize/AggressiveMergingPlugin.js +10 -4
- package/lib/optimize/AggressiveSplittingPlugin.js +26 -21
- package/lib/optimize/ConcatenatedModule.js +353 -212
- package/lib/optimize/EnsureChunkConditionsPlugin.js +4 -1
- package/lib/optimize/FlagIncludedChunksPlugin.js +14 -8
- package/lib/optimize/InnerGraph.js +30 -25
- package/lib/optimize/InnerGraphPlugin.js +105 -64
- package/lib/optimize/LimitChunkCountPlugin.js +32 -9
- package/lib/optimize/MangleExportsPlugin.js +7 -2
- package/lib/optimize/MinMaxSizeWarning.js +6 -1
- package/lib/optimize/ModuleConcatenationPlugin.js +150 -83
- package/lib/optimize/RealContentHashPlugin.js +99 -43
- package/lib/optimize/RemoveParentModulesPlugin.js +131 -48
- package/lib/optimize/RuntimeChunkPlugin.js +15 -2
- package/lib/optimize/SideEffectsFlagPlugin.js +119 -63
- package/lib/optimize/SplitChunksPlugin.js +129 -78
- package/lib/performance/SizeLimitsPlugin.js +22 -8
- package/lib/prefetch/ChunkPrefetchFunctionRuntimeModule.js +4 -2
- package/lib/prefetch/ChunkPrefetchPreloadPlugin.js +4 -1
- package/lib/prefetch/ChunkPrefetchStartupRuntimeModule.js +8 -5
- package/lib/prefetch/ChunkPrefetchTriggerRuntimeModule.js +5 -3
- package/lib/prefetch/ChunkPreloadTriggerRuntimeModule.js +5 -3
- package/lib/rules/BasicEffectRulePlugin.js +7 -1
- package/lib/rules/BasicMatcherRulePlugin.js +8 -1
- package/lib/rules/ObjectMatcherRulePlugin.js +19 -2
- package/lib/rules/RuleSetCompiler.js +53 -32
- package/lib/rules/UseEffectRulePlugin.js +42 -36
- package/lib/runtime/AsyncModuleRuntimeModule.js +56 -69
- package/lib/runtime/AutoPublicPathRuntimeModule.js +25 -9
- package/lib/runtime/BaseUriRuntimeModule.js +35 -0
- 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 +7 -4
- package/lib/runtime/CreateScriptRuntimeModule.js +38 -0
- package/lib/runtime/CreateScriptUrlRuntimeModule.js +13 -36
- package/lib/runtime/DefinePropertyGettersRuntimeModule.js +6 -3
- package/lib/runtime/EnsureChunkRuntimeModule.js +29 -15
- package/lib/runtime/GetChunkFilenameRuntimeModule.js +56 -43
- package/lib/runtime/GetFullHashRuntimeModule.js +4 -3
- package/lib/runtime/GetMainFilenameRuntimeModule.js +5 -2
- package/lib/runtime/GetTrustedTypesPolicyRuntimeModule.js +98 -0
- package/lib/runtime/GlobalRuntimeModule.js +1 -1
- package/lib/runtime/HasOwnPropertyRuntimeModule.js +5 -2
- package/lib/runtime/LoadScriptRuntimeModule.js +61 -45
- package/lib/runtime/MakeNamespaceObjectRuntimeModule.js +5 -2
- package/lib/runtime/NonceRuntimeModule.js +24 -0
- 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 +36 -28
- package/lib/runtime/StartupEntrypointRuntimeModule.js +13 -9
- package/lib/runtime/SystemContextRuntimeModule.js +1 -1
- package/lib/schemes/DataUriPlugin.js +16 -3
- package/lib/schemes/HttpUriPlugin.js +336 -120
- package/lib/serialization/ArraySerializer.js +22 -6
- package/lib/serialization/BinaryMiddleware.js +212 -33
- package/lib/serialization/DateObjectSerializer.js +16 -4
- package/lib/serialization/ErrorObjectSerializer.js +23 -6
- package/lib/serialization/FileMiddleware.js +187 -86
- package/lib/serialization/MapObjectSerializer.js +25 -8
- package/lib/serialization/NullPrototypeObjectSerializer.js +26 -8
- package/lib/serialization/ObjectMiddleware.js +96 -66
- package/lib/serialization/PlainObjectSerializer.js +51 -14
- package/lib/serialization/RegExpObjectSerializer.js +17 -5
- package/lib/serialization/Serializer.js +23 -5
- package/lib/serialization/SerializerMiddleware.js +8 -8
- package/lib/serialization/SetObjectSerializer.js +22 -6
- package/lib/serialization/SingleItemMiddleware.js +2 -2
- package/lib/serialization/types.js +2 -2
- package/lib/sharing/ConsumeSharedFallbackDependency.js +3 -0
- package/lib/sharing/ConsumeSharedModule.js +40 -17
- package/lib/sharing/ConsumeSharedPlugin.js +139 -102
- package/lib/sharing/ConsumeSharedRuntimeModule.js +144 -130
- package/lib/sharing/ProvideForSharedDependency.js +0 -1
- package/lib/sharing/ProvideSharedDependency.js +17 -0
- package/lib/sharing/ProvideSharedModule.js +19 -6
- package/lib/sharing/ProvideSharedModuleFactory.js +1 -1
- package/lib/sharing/ProvideSharedPlugin.js +37 -30
- package/lib/sharing/SharePlugin.js +2 -2
- package/lib/sharing/ShareRuntimeModule.js +20 -10
- package/lib/sharing/resolveMatchedConfigs.js +6 -5
- package/lib/sharing/utils.js +338 -34
- package/lib/stats/DefaultStatsFactoryPlugin.js +660 -396
- package/lib/stats/DefaultStatsPresetPlugin.js +85 -25
- package/lib/stats/DefaultStatsPrinterPlugin.js +525 -145
- package/lib/stats/StatsFactory.js +128 -57
- package/lib/stats/StatsPrinter.js +77 -46
- package/lib/util/ArrayHelpers.js +35 -1
- package/lib/util/ArrayQueue.js +15 -22
- package/lib/util/AsyncQueue.js +37 -16
- package/lib/util/IterableHelpers.js +3 -4
- package/lib/util/LazyBucketSortedSet.js +60 -44
- package/lib/util/LazySet.js +11 -2
- package/lib/util/MapHelpers.js +17 -5
- package/lib/util/ParallelismFactorCalculator.js +11 -1
- package/lib/util/Queue.js +9 -3
- package/lib/util/Semaphore.js +4 -7
- package/lib/util/SetHelpers.js +5 -5
- package/lib/util/SortableSet.js +19 -6
- package/lib/util/StackedCacheMap.js +33 -3
- package/lib/util/StackedMap.js +1 -3
- package/lib/util/StringXor.js +46 -0
- package/lib/util/TupleQueue.js +9 -3
- package/lib/util/TupleSet.js +15 -5
- package/lib/util/URLAbsoluteSpecifier.js +8 -8
- package/lib/util/WeakTupleMap.js +70 -28
- package/lib/util/binarySearchBounds.js +51 -9
- package/lib/util/chainedImports.js +97 -0
- package/lib/util/cleverMerge.js +51 -36
- package/lib/util/comparators.js +146 -83
- package/lib/util/compileBooleanMatcher.js +35 -7
- package/lib/util/conventions.js +126 -0
- package/lib/util/create-schema-validation.js +9 -2
- package/lib/util/createHash.js +49 -14
- package/lib/util/deprecation.js +48 -15
- package/lib/util/deterministicGrouping.js +71 -39
- package/lib/util/extractUrlAndGlobal.js +3 -0
- package/lib/util/findGraphRoots.js +7 -5
- package/lib/util/fs.js +419 -94
- package/lib/util/hash/BatchedHash.js +10 -4
- package/lib/util/hash/md4.js +20 -0
- package/lib/util/hash/wasm-hash.js +163 -0
- package/lib/util/hash/xxhash64.js +7 -141
- package/lib/util/identifier.js +140 -93
- package/lib/util/internalSerializables.js +22 -0
- package/lib/util/makeSerializable.js +7 -0
- package/lib/util/memoize.js +10 -10
- package/lib/util/mergeScope.js +76 -0
- package/lib/util/nonNumericOnlyHash.js +22 -0
- package/lib/util/numberHash.js +84 -34
- package/lib/util/objectToMap.js +0 -1
- package/lib/util/processAsyncTree.js +7 -1
- package/lib/util/propertyAccess.js +7 -55
- package/lib/util/propertyName.js +77 -0
- package/lib/util/registerExternalSerializer.js +2 -2
- package/lib/util/runtime.js +188 -133
- package/lib/util/semver.js +64 -56
- package/lib/util/serialization.js +26 -1
- package/lib/util/smartGrouping.js +10 -10
- package/lib/util/source.js +1 -1
- package/lib/validateSchema.js +6 -2
- package/lib/wasm/EnableWasmLoadingPlugin.js +9 -4
- package/lib/wasm-async/AsyncWasmLoadingRuntimeModule.js +70 -30
- package/lib/wasm-async/AsyncWebAssemblyGenerator.js +9 -1
- package/lib/wasm-async/AsyncWebAssemblyJavascriptGenerator.js +34 -16
- package/lib/wasm-async/AsyncWebAssemblyModulesPlugin.js +32 -12
- package/lib/wasm-async/AsyncWebAssemblyParser.js +17 -4
- package/lib/wasm-sync/WasmChunkLoadingRuntimeModule.js +72 -31
- package/lib/wasm-sync/WasmFinalizeExportsPlugin.js +17 -6
- package/lib/wasm-sync/WebAssemblyGenerator.js +72 -52
- package/lib/wasm-sync/WebAssemblyJavascriptGenerator.js +5 -4
- package/lib/wasm-sync/WebAssemblyModulesPlugin.js +53 -43
- package/lib/wasm-sync/WebAssemblyParser.js +23 -9
- package/lib/wasm-sync/WebAssemblyUtils.js +5 -4
- 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 +71 -41
- package/lib/webpack.js +43 -12
- package/lib/webworker/ImportScriptsChunkLoadingPlugin.js +15 -12
- package/lib/webworker/ImportScriptsChunkLoadingRuntimeModule.js +55 -40
- package/module.d.ts +233 -0
- package/package.json +85 -139
- package/schemas/WebpackOptions.check.js +1 -1
- package/schemas/WebpackOptions.json +679 -47
- package/schemas/plugins/BannerPlugin.check.js +1 -1
- package/schemas/plugins/BannerPlugin.json +9 -1
- package/schemas/plugins/DllReferencePlugin.check.js +1 -1
- package/schemas/plugins/HashedModuleIdsPlugin.check.js +1 -1
- 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/asset/AssetGeneratorOptions.check.js +1 -1
- package/schemas/plugins/asset/AssetInlineGeneratorOptions.check.js +1 -1
- package/schemas/plugins/asset/AssetParserOptions.check.js +1 -1
- package/schemas/plugins/asset/AssetResourceGeneratorOptions.check.js +1 -1
- package/schemas/plugins/container/ContainerPlugin.check.js +1 -1
- package/schemas/plugins/container/ContainerPlugin.json +10 -1
- package/schemas/plugins/container/ContainerReferencePlugin.check.js +1 -1
- package/schemas/plugins/container/ContainerReferencePlugin.json +2 -0
- package/schemas/plugins/container/ExternalsType.check.js +1 -1
- package/schemas/plugins/container/ModuleFederationPlugin.check.js +1 -1
- package/schemas/plugins/container/ModuleFederationPlugin.json +12 -1
- package/schemas/plugins/css/CssAutoGeneratorOptions.check.d.ts +7 -0
- package/schemas/plugins/css/CssAutoGeneratorOptions.check.js +6 -0
- package/schemas/plugins/css/CssAutoGeneratorOptions.json +3 -0
- package/schemas/plugins/css/CssAutoParserOptions.check.d.ts +7 -0
- package/schemas/plugins/css/CssAutoParserOptions.check.js +6 -0
- package/schemas/plugins/css/CssAutoParserOptions.json +3 -0
- package/schemas/plugins/css/CssGeneratorOptions.check.d.ts +7 -0
- package/schemas/plugins/css/CssGeneratorOptions.check.js +6 -0
- package/schemas/plugins/css/CssGeneratorOptions.json +3 -0
- package/schemas/plugins/css/CssGlobalGeneratorOptions.check.d.ts +7 -0
- package/schemas/plugins/css/CssGlobalGeneratorOptions.check.js +6 -0
- package/schemas/plugins/css/CssGlobalGeneratorOptions.json +3 -0
- package/schemas/plugins/css/CssGlobalParserOptions.check.d.ts +7 -0
- package/schemas/plugins/css/CssGlobalParserOptions.check.js +6 -0
- package/schemas/plugins/css/CssGlobalParserOptions.json +3 -0
- package/schemas/plugins/css/CssModuleGeneratorOptions.check.d.ts +7 -0
- package/schemas/plugins/css/CssModuleGeneratorOptions.check.js +6 -0
- package/schemas/plugins/css/CssModuleGeneratorOptions.json +3 -0
- package/schemas/plugins/css/CssModuleParserOptions.check.d.ts +7 -0
- package/schemas/plugins/css/CssModuleParserOptions.check.js +6 -0
- package/schemas/plugins/css/CssModuleParserOptions.json +3 -0
- package/schemas/plugins/css/CssParserOptions.check.d.ts +7 -0
- package/schemas/plugins/css/CssParserOptions.check.js +6 -0
- package/schemas/plugins/css/CssParserOptions.json +3 -0
- package/schemas/plugins/optimize/AggressiveSplittingPlugin.check.js +1 -1
- package/schemas/plugins/optimize/LimitChunkCountPlugin.check.js +1 -1
- package/schemas/plugins/optimize/MinChunkSizePlugin.check.js +1 -1
- package/schemas/plugins/schemes/HttpUriPlugin.check.js +1 -1
- package/schemas/plugins/schemes/HttpUriPlugin.json +4 -0
- package/schemas/plugins/sharing/SharePlugin.check.js +1 -1
- package/types.d.ts +5026 -1756
@@ -6,7 +6,7 @@
|
|
6
6
|
"use strict";
|
7
7
|
|
8
8
|
const { Parser: AcornParser } = require("acorn");
|
9
|
-
const {
|
9
|
+
const { importAttributesOrAssertions } = require("acorn-import-attributes");
|
10
10
|
const { SyncBailHook, HookMap } = require("tapable");
|
11
11
|
const vm = require("vm");
|
12
12
|
const Parser = require("../Parser");
|
@@ -16,49 +16,92 @@ 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 {import("estree").
|
54
|
-
/**
|
55
|
-
|
56
|
-
|
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 {import("estree").AssignmentProperty} AssignmentProperty */
|
91
|
+
/**
|
92
|
+
* @template T
|
93
|
+
* @typedef {import("tapable").AsArray<T>} AsArray<T>
|
94
|
+
*/
|
57
95
|
/** @typedef {import("../Parser").ParserState} ParserState */
|
58
96
|
/** @typedef {import("../Parser").PreparsedAst} PreparsedAst */
|
59
97
|
/** @typedef {{declaredScope: ScopeInfo, freeName: string | true, tagInfo: TagInfo | undefined}} VariableInfoInterface */
|
60
|
-
/** @typedef {{ name: string | VariableInfo, rootInfo: string | VariableInfo, getMembers: () => string[] }} GetInfoResult */
|
98
|
+
/** @typedef {{ name: string | VariableInfo, rootInfo: string | VariableInfo, getMembers: () => string[], getMembersOptionals: () => boolean[], getMemberRanges: () => Range[] }} GetInfoResult */
|
99
|
+
/** @typedef {Statement | ModuleDeclaration | Expression} StatementPathItem */
|
100
|
+
/** @typedef {TODO} OnIdent */
|
61
101
|
|
102
|
+
/** @typedef {Record<string, string> & { _isLegacyAssert?: boolean }} ImportAttributes */
|
103
|
+
|
104
|
+
/** @type {string[]} */
|
62
105
|
const EMPTY_ARRAY = [];
|
63
106
|
const ALLOWED_MEMBER_TYPES_CALL_EXPRESSION = 0b01;
|
64
107
|
const ALLOWED_MEMBER_TYPES_EXPRESSION = 0b10;
|
@@ -66,12 +109,12 @@ const ALLOWED_MEMBER_TYPES_ALL = 0b11;
|
|
66
109
|
|
67
110
|
// Syntax: https://developer.mozilla.org/en/SpiderMonkey/Parser_API
|
68
111
|
|
69
|
-
const parser = AcornParser.extend(
|
112
|
+
const parser = AcornParser.extend(importAttributesOrAssertions);
|
70
113
|
|
71
114
|
class VariableInfo {
|
72
115
|
/**
|
73
116
|
* @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
|
117
|
+
* @param {string | true | undefined} freeName which free name the variable aliases, or true when none
|
75
118
|
* @param {TagInfo | undefined} tagInfo info about tags
|
76
119
|
*/
|
77
120
|
constructor(declaredScope, freeName, tagInfo) {
|
@@ -82,40 +125,88 @@ class VariableInfo {
|
|
82
125
|
}
|
83
126
|
|
84
127
|
/** @typedef {string | ScopeInfo | VariableInfo} ExportedVariableInfo */
|
85
|
-
/** @typedef {
|
128
|
+
/** @typedef {Literal | string | null | undefined} ImportSource */
|
86
129
|
/** @typedef {Omit<AcornOptions, "sourceType" | "ecmaVersion"> & { sourceType: "module" | "script" | "auto", ecmaVersion?: AcornOptions["ecmaVersion"] }} ParseOptions */
|
87
130
|
|
88
131
|
/**
|
89
|
-
* @typedef {
|
132
|
+
* @typedef {object} TagInfo
|
90
133
|
* @property {any} tag
|
91
134
|
* @property {any} data
|
92
135
|
* @property {TagInfo | undefined} next
|
93
136
|
*/
|
94
137
|
|
95
138
|
/**
|
96
|
-
* @typedef {
|
139
|
+
* @typedef {object} ScopeInfo
|
97
140
|
* @property {StackedMap<string, VariableInfo | ScopeInfo>} definitions
|
98
141
|
* @property {boolean | "arrow"} topLevelScope
|
99
|
-
* @property {boolean} inShorthand
|
142
|
+
* @property {boolean | string} inShorthand
|
143
|
+
* @property {boolean} inTaggedTemplateTag
|
144
|
+
* @property {boolean} inTry
|
100
145
|
* @property {boolean} isStrict
|
101
146
|
* @property {boolean} isAsmJs
|
102
|
-
* @property {boolean} inTry
|
103
147
|
*/
|
104
148
|
|
149
|
+
/** @typedef {[number, number]} Range */
|
150
|
+
|
151
|
+
/**
|
152
|
+
* @typedef {object} DestructuringAssignmentProperty
|
153
|
+
* @property {string} id
|
154
|
+
* @property {Range | undefined=} range
|
155
|
+
* @property {boolean | string} shorthand
|
156
|
+
*/
|
157
|
+
|
158
|
+
/**
|
159
|
+
* Helper function for joining two ranges into a single range. This is useful
|
160
|
+
* when working with AST nodes, as it allows you to combine the ranges of child nodes
|
161
|
+
* to create the range of the _parent node_.
|
162
|
+
* @param {[number, number]} startRange start range to join
|
163
|
+
* @param {[number, number]} endRange end range to join
|
164
|
+
* @returns {[number, number]} joined range
|
165
|
+
* @example
|
166
|
+
* ```js
|
167
|
+
* const startRange = [0, 5];
|
168
|
+
* const endRange = [10, 15];
|
169
|
+
* const joinedRange = joinRanges(startRange, endRange);
|
170
|
+
* console.log(joinedRange); // [0, 15]
|
171
|
+
* ```
|
172
|
+
*/
|
105
173
|
const joinRanges = (startRange, endRange) => {
|
106
174
|
if (!endRange) return startRange;
|
107
175
|
if (!startRange) return endRange;
|
108
176
|
return [startRange[0], endRange[1]];
|
109
177
|
};
|
110
178
|
|
179
|
+
/**
|
180
|
+
* Helper function used to generate a string representation of a
|
181
|
+
* [member expression](https://github.com/estree/estree/blob/master/es5.md#memberexpression).
|
182
|
+
* @param {string} object object to name
|
183
|
+
* @param {string[]} membersReversed reversed list of members
|
184
|
+
* @returns {string} member expression as a string
|
185
|
+
* @example
|
186
|
+
* ```js
|
187
|
+
* const membersReversed = ["property1", "property2", "property3"]; // Members parsed from the AST
|
188
|
+
* const name = objectAndMembersToName("myObject", membersReversed);
|
189
|
+
*
|
190
|
+
* console.log(name); // "myObject.property1.property2.property3"
|
191
|
+
* ```
|
192
|
+
*/
|
111
193
|
const objectAndMembersToName = (object, membersReversed) => {
|
112
194
|
let name = object;
|
113
195
|
for (let i = membersReversed.length - 1; i >= 0; i--) {
|
114
|
-
name = name
|
196
|
+
name = `${name}.${membersReversed[i]}`;
|
115
197
|
}
|
116
198
|
return name;
|
117
199
|
};
|
118
200
|
|
201
|
+
/**
|
202
|
+
* Grabs the name of a given expression and returns it as a string or undefined. Has particular
|
203
|
+
* handling for [Identifiers](https://github.com/estree/estree/blob/master/es5.md#identifier),
|
204
|
+
* [ThisExpressions](https://github.com/estree/estree/blob/master/es5.md#identifier), and
|
205
|
+
* [MetaProperties](https://github.com/estree/estree/blob/master/es2015.md#metaproperty) which is
|
206
|
+
* specifically for handling the `new.target` meta property.
|
207
|
+
* @param {Expression | SpreadElement | Super} expression expression
|
208
|
+
* @returns {string | "this" | undefined} name or variable info
|
209
|
+
*/
|
119
210
|
const getRootName = expression => {
|
120
211
|
switch (expression.type) {
|
121
212
|
case "Identifier":
|
@@ -155,73 +246,81 @@ class JavascriptParser extends Parser {
|
|
155
246
|
constructor(sourceType = "auto") {
|
156
247
|
super();
|
157
248
|
this.hooks = Object.freeze({
|
158
|
-
/** @type {HookMap<SyncBailHook<[
|
249
|
+
/** @type {HookMap<SyncBailHook<[UnaryExpression], BasicEvaluatedExpression | undefined | null>>} */
|
159
250
|
evaluateTypeof: new HookMap(() => new SyncBailHook(["expression"])),
|
160
|
-
/** @type {HookMap<SyncBailHook<[
|
251
|
+
/** @type {HookMap<SyncBailHook<[Expression | SpreadElement], BasicEvaluatedExpression | undefined | null>>} */
|
161
252
|
evaluate: new HookMap(() => new SyncBailHook(["expression"])),
|
162
|
-
/** @type {HookMap<SyncBailHook<[
|
253
|
+
/** @type {HookMap<SyncBailHook<[Identifier | ThisExpression | MemberExpression | MetaProperty], BasicEvaluatedExpression | undefined | null>>} */
|
163
254
|
evaluateIdentifier: new HookMap(() => new SyncBailHook(["expression"])),
|
164
|
-
/** @type {HookMap<SyncBailHook<[
|
255
|
+
/** @type {HookMap<SyncBailHook<[Identifier | ThisExpression | MemberExpression], BasicEvaluatedExpression | undefined | null>>} */
|
165
256
|
evaluateDefinedIdentifier: new HookMap(
|
166
257
|
() => new SyncBailHook(["expression"])
|
167
258
|
),
|
168
|
-
/** @type {HookMap<SyncBailHook<[
|
259
|
+
/** @type {HookMap<SyncBailHook<[NewExpression], BasicEvaluatedExpression | undefined | null>>} */
|
260
|
+
evaluateNewExpression: new HookMap(
|
261
|
+
() => new SyncBailHook(["expression"])
|
262
|
+
),
|
263
|
+
/** @type {HookMap<SyncBailHook<[CallExpression], BasicEvaluatedExpression | undefined | null>>} */
|
264
|
+
evaluateCallExpression: new HookMap(
|
265
|
+
() => new SyncBailHook(["expression"])
|
266
|
+
),
|
267
|
+
/** @type {HookMap<SyncBailHook<[CallExpression, BasicEvaluatedExpression], BasicEvaluatedExpression | undefined | null>>} */
|
169
268
|
evaluateCallExpressionMember: new HookMap(
|
170
269
|
() => new SyncBailHook(["expression", "param"])
|
171
270
|
),
|
172
|
-
/** @type {HookMap<SyncBailHook<[
|
271
|
+
/** @type {HookMap<SyncBailHook<[Expression | Declaration | PrivateIdentifier, number], boolean | void>>} */
|
173
272
|
isPure: new HookMap(
|
174
273
|
() => new SyncBailHook(["expression", "commentsStartPosition"])
|
175
274
|
),
|
176
|
-
/** @type {SyncBailHook<[
|
275
|
+
/** @type {SyncBailHook<[Statement | ModuleDeclaration], boolean | void>} */
|
177
276
|
preStatement: new SyncBailHook(["statement"]),
|
178
277
|
|
179
|
-
/** @type {SyncBailHook<[
|
278
|
+
/** @type {SyncBailHook<[Statement | ModuleDeclaration], boolean | void>} */
|
180
279
|
blockPreStatement: new SyncBailHook(["declaration"]),
|
181
|
-
/** @type {SyncBailHook<[
|
280
|
+
/** @type {SyncBailHook<[Statement | ModuleDeclaration], boolean | void>} */
|
182
281
|
statement: new SyncBailHook(["statement"]),
|
183
|
-
/** @type {SyncBailHook<[
|
282
|
+
/** @type {SyncBailHook<[IfStatement], boolean | void>} */
|
184
283
|
statementIf: new SyncBailHook(["statement"]),
|
185
|
-
/** @type {SyncBailHook<[
|
284
|
+
/** @type {SyncBailHook<[Expression, ClassExpression | ClassDeclaration], boolean | void>} */
|
186
285
|
classExtendsExpression: new SyncBailHook([
|
187
286
|
"expression",
|
188
287
|
"classDefinition"
|
189
288
|
]),
|
190
|
-
/** @type {SyncBailHook<[
|
289
|
+
/** @type {SyncBailHook<[MethodDefinition | PropertyDefinition | StaticBlock, ClassExpression | ClassDeclaration], boolean | void>} */
|
191
290
|
classBodyElement: new SyncBailHook(["element", "classDefinition"]),
|
192
|
-
/** @type {SyncBailHook<[
|
291
|
+
/** @type {SyncBailHook<[Expression, MethodDefinition | PropertyDefinition, ClassExpression | ClassDeclaration], boolean | void>} */
|
193
292
|
classBodyValue: new SyncBailHook([
|
194
293
|
"expression",
|
195
294
|
"element",
|
196
295
|
"classDefinition"
|
197
296
|
]),
|
198
|
-
/** @type {HookMap<SyncBailHook<[
|
297
|
+
/** @type {HookMap<SyncBailHook<[LabeledStatement], boolean | void>>} */
|
199
298
|
label: new HookMap(() => new SyncBailHook(["statement"])),
|
200
|
-
/** @type {SyncBailHook<[
|
299
|
+
/** @type {SyncBailHook<[ImportDeclaration, ImportSource], boolean | void>} */
|
201
300
|
import: new SyncBailHook(["statement", "source"]),
|
202
|
-
/** @type {SyncBailHook<[
|
301
|
+
/** @type {SyncBailHook<[ImportDeclaration, ImportSource, string, string], boolean | void>} */
|
203
302
|
importSpecifier: new SyncBailHook([
|
204
303
|
"statement",
|
205
304
|
"source",
|
206
305
|
"exportName",
|
207
306
|
"identifierName"
|
208
307
|
]),
|
209
|
-
/** @type {SyncBailHook<[
|
308
|
+
/** @type {SyncBailHook<[ExportDefaultDeclaration | ExportNamedDeclaration], boolean | void>} */
|
210
309
|
export: new SyncBailHook(["statement"]),
|
211
|
-
/** @type {SyncBailHook<[
|
310
|
+
/** @type {SyncBailHook<[ExportNamedDeclaration | ExportAllDeclaration, ImportSource], boolean | void>} */
|
212
311
|
exportImport: new SyncBailHook(["statement", "source"]),
|
213
|
-
/** @type {SyncBailHook<[
|
312
|
+
/** @type {SyncBailHook<[ExportDefaultDeclaration | ExportNamedDeclaration | ExportAllDeclaration, Declaration], boolean | void>} */
|
214
313
|
exportDeclaration: new SyncBailHook(["statement", "declaration"]),
|
215
|
-
/** @type {SyncBailHook<[
|
314
|
+
/** @type {SyncBailHook<[ExportDefaultDeclaration, FunctionDeclaration | ClassDeclaration], boolean | void>} */
|
216
315
|
exportExpression: new SyncBailHook(["statement", "declaration"]),
|
217
|
-
/** @type {SyncBailHook<[
|
316
|
+
/** @type {SyncBailHook<[ExportDefaultDeclaration | ExportNamedDeclaration | ExportAllDeclaration, string, string, number | undefined], boolean | void>} */
|
218
317
|
exportSpecifier: new SyncBailHook([
|
219
318
|
"statement",
|
220
319
|
"identifierName",
|
221
320
|
"exportName",
|
222
321
|
"index"
|
223
322
|
]),
|
224
|
-
/** @type {SyncBailHook<[
|
323
|
+
/** @type {SyncBailHook<[ExportNamedDeclaration | ExportAllDeclaration, ImportSource, string, string, number | undefined], boolean | void>} */
|
225
324
|
exportImportSpecifier: new SyncBailHook([
|
226
325
|
"statement",
|
227
326
|
"source",
|
@@ -229,86 +328,102 @@ class JavascriptParser extends Parser {
|
|
229
328
|
"exportName",
|
230
329
|
"index"
|
231
330
|
]),
|
232
|
-
/** @type {SyncBailHook<[
|
331
|
+
/** @type {SyncBailHook<[VariableDeclarator, Statement], boolean | void>} */
|
233
332
|
preDeclarator: new SyncBailHook(["declarator", "statement"]),
|
234
|
-
/** @type {SyncBailHook<[
|
333
|
+
/** @type {SyncBailHook<[VariableDeclarator, Statement], boolean | void>} */
|
235
334
|
declarator: new SyncBailHook(["declarator", "statement"]),
|
236
|
-
/** @type {HookMap<SyncBailHook<[
|
335
|
+
/** @type {HookMap<SyncBailHook<[Declaration], boolean | void>>} */
|
237
336
|
varDeclaration: new HookMap(() => new SyncBailHook(["declaration"])),
|
238
|
-
/** @type {HookMap<SyncBailHook<[
|
337
|
+
/** @type {HookMap<SyncBailHook<[Declaration], boolean | void>>} */
|
239
338
|
varDeclarationLet: new HookMap(() => new SyncBailHook(["declaration"])),
|
240
|
-
/** @type {HookMap<SyncBailHook<[
|
339
|
+
/** @type {HookMap<SyncBailHook<[Declaration], boolean | void>>} */
|
241
340
|
varDeclarationConst: new HookMap(() => new SyncBailHook(["declaration"])),
|
242
|
-
/** @type {HookMap<SyncBailHook<[
|
341
|
+
/** @type {HookMap<SyncBailHook<[Declaration], boolean | void>>} */
|
243
342
|
varDeclarationVar: new HookMap(() => new SyncBailHook(["declaration"])),
|
244
|
-
/** @type {HookMap<SyncBailHook<[
|
343
|
+
/** @type {HookMap<SyncBailHook<[Identifier], boolean | void>>} */
|
245
344
|
pattern: new HookMap(() => new SyncBailHook(["pattern"])),
|
246
|
-
/** @type {HookMap<SyncBailHook<[
|
345
|
+
/** @type {HookMap<SyncBailHook<[Expression], boolean | void>>} */
|
247
346
|
canRename: new HookMap(() => new SyncBailHook(["initExpression"])),
|
248
|
-
/** @type {HookMap<SyncBailHook<[
|
347
|
+
/** @type {HookMap<SyncBailHook<[Expression], boolean | void>>} */
|
249
348
|
rename: new HookMap(() => new SyncBailHook(["initExpression"])),
|
250
|
-
/** @type {HookMap<SyncBailHook<[
|
349
|
+
/** @type {HookMap<SyncBailHook<[AssignmentExpression], boolean | void>>} */
|
251
350
|
assign: new HookMap(() => new SyncBailHook(["expression"])),
|
252
|
-
/** @type {HookMap<SyncBailHook<[
|
351
|
+
/** @type {HookMap<SyncBailHook<[AssignmentExpression, string[]], boolean | void>>} */
|
253
352
|
assignMemberChain: new HookMap(
|
254
353
|
() => new SyncBailHook(["expression", "members"])
|
255
354
|
),
|
256
|
-
/** @type {HookMap<SyncBailHook<[
|
355
|
+
/** @type {HookMap<SyncBailHook<[Expression], boolean | void>>} */
|
257
356
|
typeof: new HookMap(() => new SyncBailHook(["expression"])),
|
258
|
-
/** @type {SyncBailHook<[
|
357
|
+
/** @type {SyncBailHook<[ImportExpression], boolean | void>} */
|
259
358
|
importCall: new SyncBailHook(["expression"]),
|
260
|
-
/** @type {SyncBailHook<[
|
359
|
+
/** @type {SyncBailHook<[Expression | ForOfStatement], boolean | void>} */
|
261
360
|
topLevelAwait: new SyncBailHook(["expression"]),
|
262
|
-
/** @type {HookMap<SyncBailHook<[
|
361
|
+
/** @type {HookMap<SyncBailHook<[CallExpression], boolean | void>>} */
|
263
362
|
call: new HookMap(() => new SyncBailHook(["expression"])),
|
264
363
|
/** Something like "a.b()" */
|
265
|
-
/** @type {HookMap<SyncBailHook<[
|
364
|
+
/** @type {HookMap<SyncBailHook<[CallExpression, string[], boolean[], Range[]], boolean | void>>} */
|
266
365
|
callMemberChain: new HookMap(
|
267
|
-
() =>
|
366
|
+
() =>
|
367
|
+
new SyncBailHook([
|
368
|
+
"expression",
|
369
|
+
"members",
|
370
|
+
"membersOptionals",
|
371
|
+
"memberRanges"
|
372
|
+
])
|
268
373
|
),
|
269
374
|
/** Something like "a.b().c.d" */
|
270
|
-
/** @type {HookMap<SyncBailHook<[
|
375
|
+
/** @type {HookMap<SyncBailHook<[Expression, string[], CallExpression, string[], Range[]], boolean | void>>} */
|
271
376
|
memberChainOfCallMemberChain: new HookMap(
|
272
377
|
() =>
|
273
378
|
new SyncBailHook([
|
274
379
|
"expression",
|
275
380
|
"calleeMembers",
|
276
381
|
"callExpression",
|
277
|
-
"members"
|
382
|
+
"members",
|
383
|
+
"memberRanges"
|
278
384
|
])
|
279
385
|
),
|
280
386
|
/** Something like "a.b().c.d()"" */
|
281
|
-
/** @type {HookMap<SyncBailHook<[
|
387
|
+
/** @type {HookMap<SyncBailHook<[CallExpression, string[], CallExpression, string[], Range[]], boolean | void>>} */
|
282
388
|
callMemberChainOfCallMemberChain: new HookMap(
|
283
389
|
() =>
|
284
390
|
new SyncBailHook([
|
285
391
|
"expression",
|
286
392
|
"calleeMembers",
|
287
393
|
"innerCallExpression",
|
288
|
-
"members"
|
394
|
+
"members",
|
395
|
+
"memberRanges"
|
289
396
|
])
|
290
397
|
),
|
291
|
-
/** @type {SyncBailHook<[
|
398
|
+
/** @type {SyncBailHook<[ChainExpression], boolean | void>} */
|
292
399
|
optionalChaining: new SyncBailHook(["optionalChaining"]),
|
293
|
-
/** @type {HookMap<SyncBailHook<[
|
400
|
+
/** @type {HookMap<SyncBailHook<[NewExpression], boolean | void>>} */
|
294
401
|
new: new HookMap(() => new SyncBailHook(["expression"])),
|
295
|
-
/** @type {
|
402
|
+
/** @type {SyncBailHook<[BinaryExpression], boolean | void>} */
|
403
|
+
binaryExpression: new SyncBailHook(["binaryExpression"]),
|
404
|
+
/** @type {HookMap<SyncBailHook<[Expression], boolean | void>>} */
|
296
405
|
expression: new HookMap(() => new SyncBailHook(["expression"])),
|
297
|
-
/** @type {HookMap<SyncBailHook<[
|
406
|
+
/** @type {HookMap<SyncBailHook<[MemberExpression, string[], boolean[], Range[]], boolean | void>>} */
|
298
407
|
expressionMemberChain: new HookMap(
|
299
|
-
() =>
|
408
|
+
() =>
|
409
|
+
new SyncBailHook([
|
410
|
+
"expression",
|
411
|
+
"members",
|
412
|
+
"membersOptionals",
|
413
|
+
"memberRanges"
|
414
|
+
])
|
300
415
|
),
|
301
|
-
/** @type {HookMap<SyncBailHook<[
|
416
|
+
/** @type {HookMap<SyncBailHook<[MemberExpression, string[]], boolean | void>>} */
|
302
417
|
unhandledExpressionMemberChain: new HookMap(
|
303
418
|
() => new SyncBailHook(["expression", "members"])
|
304
419
|
),
|
305
|
-
/** @type {SyncBailHook<[
|
420
|
+
/** @type {SyncBailHook<[ConditionalExpression], boolean | void>} */
|
306
421
|
expressionConditionalOperator: new SyncBailHook(["expression"]),
|
307
|
-
/** @type {SyncBailHook<[
|
422
|
+
/** @type {SyncBailHook<[LogicalExpression], boolean | void>} */
|
308
423
|
expressionLogicalOperator: new SyncBailHook(["expression"]),
|
309
|
-
/** @type {SyncBailHook<[
|
424
|
+
/** @type {SyncBailHook<[Program, Comment[]], boolean | void>} */
|
310
425
|
program: new SyncBailHook(["ast", "comments"]),
|
311
|
-
/** @type {SyncBailHook<[
|
426
|
+
/** @type {SyncBailHook<[Program, Comment[]], boolean | void>} */
|
312
427
|
finish: new SyncBailHook(["ast", "comments"])
|
313
428
|
});
|
314
429
|
this.sourceType = sourceType;
|
@@ -316,58 +431,74 @@ class JavascriptParser extends Parser {
|
|
316
431
|
this.scope = undefined;
|
317
432
|
/** @type {ParserState} */
|
318
433
|
this.state = undefined;
|
434
|
+
/** @type {Comment[] | undefined} */
|
319
435
|
this.comments = undefined;
|
436
|
+
/** @type {Set<number> | undefined} */
|
320
437
|
this.semicolons = undefined;
|
321
|
-
/** @type {
|
438
|
+
/** @type {StatementPathItem[]} */
|
322
439
|
this.statementPath = undefined;
|
440
|
+
/** @type {Statement | ModuleDeclaration | Expression | undefined} */
|
323
441
|
this.prevStatement = undefined;
|
442
|
+
/** @type {WeakMap<Expression, Set<DestructuringAssignmentProperty>> | undefined} */
|
443
|
+
this.destructuringAssignmentProperties = undefined;
|
324
444
|
this.currentTagData = undefined;
|
445
|
+
this.magicCommentContext = vm.createContext(undefined, {
|
446
|
+
name: "Webpack Magic Comment Parser",
|
447
|
+
codeGeneration: { strings: false, wasm: false }
|
448
|
+
});
|
325
449
|
this._initializeEvaluating();
|
326
450
|
}
|
327
451
|
|
328
452
|
_initializeEvaluating() {
|
329
453
|
this.hooks.evaluate.for("Literal").tap("JavascriptParser", _expr => {
|
330
|
-
const expr = /** @type {
|
454
|
+
const expr = /** @type {Literal} */ (_expr);
|
331
455
|
|
332
456
|
switch (typeof expr.value) {
|
333
457
|
case "number":
|
334
458
|
return new BasicEvaluatedExpression()
|
335
459
|
.setNumber(expr.value)
|
336
|
-
.setRange(expr.range);
|
460
|
+
.setRange(/** @type {Range} */ (expr.range));
|
337
461
|
case "bigint":
|
338
462
|
return new BasicEvaluatedExpression()
|
339
463
|
.setBigInt(expr.value)
|
340
|
-
.setRange(expr.range);
|
464
|
+
.setRange(/** @type {Range} */ (expr.range));
|
341
465
|
case "string":
|
342
466
|
return new BasicEvaluatedExpression()
|
343
467
|
.setString(expr.value)
|
344
|
-
.setRange(expr.range);
|
468
|
+
.setRange(/** @type {Range} */ (expr.range));
|
345
469
|
case "boolean":
|
346
470
|
return new BasicEvaluatedExpression()
|
347
471
|
.setBoolean(expr.value)
|
348
|
-
.setRange(expr.range);
|
472
|
+
.setRange(/** @type {Range} */ (expr.range));
|
349
473
|
}
|
350
474
|
if (expr.value === null) {
|
351
|
-
return new BasicEvaluatedExpression()
|
475
|
+
return new BasicEvaluatedExpression()
|
476
|
+
.setNull()
|
477
|
+
.setRange(/** @type {Range} */ (expr.range));
|
352
478
|
}
|
353
479
|
if (expr.value instanceof RegExp) {
|
354
480
|
return new BasicEvaluatedExpression()
|
355
481
|
.setRegExp(expr.value)
|
356
|
-
.setRange(expr.range);
|
482
|
+
.setRange(/** @type {Range} */ (expr.range));
|
357
483
|
}
|
358
484
|
});
|
359
485
|
this.hooks.evaluate.for("NewExpression").tap("JavascriptParser", _expr => {
|
360
|
-
const expr = /** @type {
|
486
|
+
const expr = /** @type {NewExpression} */ (_expr);
|
361
487
|
const callee = expr.callee;
|
362
|
-
if (
|
363
|
-
|
364
|
-
|
488
|
+
if (callee.type !== "Identifier") return;
|
489
|
+
if (callee.name !== "RegExp") {
|
490
|
+
return this.callHooksForName(
|
491
|
+
this.hooks.evaluateNewExpression,
|
492
|
+
callee.name,
|
493
|
+
expr
|
494
|
+
);
|
495
|
+
} else if (
|
365
496
|
expr.arguments.length > 2 ||
|
366
497
|
this.getVariableInfo("RegExp") !== "RegExp"
|
367
498
|
)
|
368
499
|
return;
|
369
500
|
|
370
|
-
let regExp
|
501
|
+
let regExp;
|
371
502
|
const arg1 = expr.arguments[0];
|
372
503
|
|
373
504
|
if (arg1) {
|
@@ -381,11 +512,15 @@ class JavascriptParser extends Parser {
|
|
381
512
|
|
382
513
|
if (!regExp) return;
|
383
514
|
} else {
|
384
|
-
return
|
385
|
-
|
386
|
-
|
515
|
+
return (
|
516
|
+
new BasicEvaluatedExpression()
|
517
|
+
// eslint-disable-next-line prefer-regex-literals
|
518
|
+
.setRegExp(new RegExp(""))
|
519
|
+
.setRange(/** @type {Range} */ (expr.range))
|
520
|
+
);
|
387
521
|
}
|
388
522
|
|
523
|
+
let flags;
|
389
524
|
const arg2 = expr.arguments[1];
|
390
525
|
|
391
526
|
if (arg2) {
|
@@ -408,90 +543,142 @@ class JavascriptParser extends Parser {
|
|
408
543
|
|
409
544
|
return new BasicEvaluatedExpression()
|
410
545
|
.setRegExp(flags ? new RegExp(regExp, flags) : new RegExp(regExp))
|
411
|
-
.setRange(expr.range);
|
546
|
+
.setRange(/** @type {Range} */ (expr.range));
|
412
547
|
});
|
413
548
|
this.hooks.evaluate
|
414
549
|
.for("LogicalExpression")
|
415
550
|
.tap("JavascriptParser", _expr => {
|
416
|
-
const expr = /** @type {
|
551
|
+
const expr = /** @type {LogicalExpression} */ (_expr);
|
417
552
|
|
418
553
|
const left = this.evaluateExpression(expr.left);
|
419
|
-
if (!left) return;
|
420
554
|
let returnRight = false;
|
421
555
|
/** @type {boolean|undefined} */
|
422
556
|
let allowedRight;
|
423
557
|
if (expr.operator === "&&") {
|
424
558
|
const leftAsBool = left.asBool();
|
425
|
-
if (leftAsBool === false)
|
559
|
+
if (leftAsBool === false)
|
560
|
+
return left.setRange(/** @type {Range} */ (expr.range));
|
426
561
|
returnRight = leftAsBool === true;
|
427
562
|
allowedRight = false;
|
428
563
|
} else if (expr.operator === "||") {
|
429
564
|
const leftAsBool = left.asBool();
|
430
|
-
if (leftAsBool === true)
|
565
|
+
if (leftAsBool === true)
|
566
|
+
return left.setRange(/** @type {Range} */ (expr.range));
|
431
567
|
returnRight = leftAsBool === false;
|
432
568
|
allowedRight = true;
|
433
569
|
} else if (expr.operator === "??") {
|
434
570
|
const leftAsNullish = left.asNullish();
|
435
|
-
if (leftAsNullish === false)
|
571
|
+
if (leftAsNullish === false)
|
572
|
+
return left.setRange(/** @type {Range} */ (expr.range));
|
436
573
|
if (leftAsNullish !== true) return;
|
437
574
|
returnRight = true;
|
438
575
|
} else return;
|
439
576
|
const right = this.evaluateExpression(expr.right);
|
440
|
-
if (!right) return;
|
441
577
|
if (returnRight) {
|
442
578
|
if (left.couldHaveSideEffects()) right.setSideEffects();
|
443
|
-
return right.setRange(expr.range);
|
579
|
+
return right.setRange(/** @type {Range} */ (expr.range));
|
444
580
|
}
|
445
581
|
|
446
582
|
const asBool = right.asBool();
|
447
583
|
|
448
584
|
if (allowedRight === true && asBool === true) {
|
449
585
|
return new BasicEvaluatedExpression()
|
450
|
-
.setRange(expr.range)
|
586
|
+
.setRange(/** @type {Range} */ (expr.range))
|
451
587
|
.setTruthy();
|
452
588
|
} else if (allowedRight === false && asBool === false) {
|
453
|
-
return new BasicEvaluatedExpression()
|
589
|
+
return new BasicEvaluatedExpression()
|
590
|
+
.setRange(/** @type {Range} */ (expr.range))
|
591
|
+
.setFalsy();
|
454
592
|
}
|
455
593
|
});
|
456
594
|
|
595
|
+
/**
|
596
|
+
* In simple logical cases, we can use valueAsExpression to assist us in evaluating the expression on
|
597
|
+
* either side of a [BinaryExpression](https://github.com/estree/estree/blob/master/es5.md#binaryexpression).
|
598
|
+
* This supports scenarios in webpack like conditionally `import()`'ing modules based on some simple evaluation:
|
599
|
+
*
|
600
|
+
* ```js
|
601
|
+
* if (1 === 3) {
|
602
|
+
* import("./moduleA"); // webpack will auto evaluate this and not import the modules
|
603
|
+
* }
|
604
|
+
* ```
|
605
|
+
*
|
606
|
+
* Additional scenarios include evaluation of strings inside of dynamic import statements:
|
607
|
+
*
|
608
|
+
* ```js
|
609
|
+
* const foo = "foo";
|
610
|
+
* const bar = "bar";
|
611
|
+
*
|
612
|
+
* import("./" + foo + bar); // webpack will auto evaluate this into import("./foobar")
|
613
|
+
* ```
|
614
|
+
* @param {boolean | number | bigint | string} value the value to convert to an expression
|
615
|
+
* @param {BinaryExpression | UnaryExpression} expr the expression being evaluated
|
616
|
+
* @param {boolean} sideEffects whether the expression has side effects
|
617
|
+
* @returns {BasicEvaluatedExpression | undefined} the evaluated expression
|
618
|
+
* @example
|
619
|
+
*
|
620
|
+
* ```js
|
621
|
+
* const binaryExpr = new BinaryExpression("+",
|
622
|
+
* { type: "Literal", value: 2 },
|
623
|
+
* { type: "Literal", value: 3 }
|
624
|
+
* );
|
625
|
+
*
|
626
|
+
* const leftValue = 2;
|
627
|
+
* const rightValue = 3;
|
628
|
+
*
|
629
|
+
* const leftExpr = valueAsExpression(leftValue, binaryExpr.left, false);
|
630
|
+
* const rightExpr = valueAsExpression(rightValue, binaryExpr.right, false);
|
631
|
+
* const result = new BasicEvaluatedExpression()
|
632
|
+
* .setNumber(leftExpr.number + rightExpr.number)
|
633
|
+
* .setRange(binaryExpr.range);
|
634
|
+
*
|
635
|
+
* console.log(result.number); // Output: 5
|
636
|
+
* ```
|
637
|
+
*/
|
457
638
|
const valueAsExpression = (value, expr, sideEffects) => {
|
458
639
|
switch (typeof value) {
|
459
640
|
case "boolean":
|
460
641
|
return new BasicEvaluatedExpression()
|
461
642
|
.setBoolean(value)
|
462
643
|
.setSideEffects(sideEffects)
|
463
|
-
.setRange(expr.range);
|
644
|
+
.setRange(/** @type {Range} */ (expr.range));
|
464
645
|
case "number":
|
465
646
|
return new BasicEvaluatedExpression()
|
466
647
|
.setNumber(value)
|
467
648
|
.setSideEffects(sideEffects)
|
468
|
-
.setRange(expr.range);
|
649
|
+
.setRange(/** @type {Range} */ (expr.range));
|
469
650
|
case "bigint":
|
470
651
|
return new BasicEvaluatedExpression()
|
471
652
|
.setBigInt(value)
|
472
653
|
.setSideEffects(sideEffects)
|
473
|
-
.setRange(expr.range);
|
654
|
+
.setRange(/** @type {Range} */ (expr.range));
|
474
655
|
case "string":
|
475
656
|
return new BasicEvaluatedExpression()
|
476
657
|
.setString(value)
|
477
658
|
.setSideEffects(sideEffects)
|
478
|
-
.setRange(expr.range);
|
659
|
+
.setRange(/** @type {Range} */ (expr.range));
|
479
660
|
}
|
480
661
|
};
|
481
662
|
|
482
663
|
this.hooks.evaluate
|
483
664
|
.for("BinaryExpression")
|
484
665
|
.tap("JavascriptParser", _expr => {
|
485
|
-
const expr = /** @type {
|
486
|
-
|
487
|
-
|
666
|
+
const expr = /** @type {BinaryExpression} */ (_expr);
|
667
|
+
|
668
|
+
/**
|
669
|
+
* Evaluates a binary expression if and only if it is a const operation (e.g. 1 + 2, "a" + "b", etc.).
|
670
|
+
* @template T
|
671
|
+
* @param {(leftOperand: T, rightOperand: T) => boolean | number | bigint | string} operandHandler the handler for the operation (e.g. (a, b) => a + b)
|
672
|
+
* @returns {BasicEvaluatedExpression | undefined} the evaluated expression
|
673
|
+
*/
|
674
|
+
const handleConstOperation = operandHandler => {
|
488
675
|
const left = this.evaluateExpression(expr.left);
|
489
|
-
if (!left
|
676
|
+
if (!left.isCompileTimeValue()) return;
|
490
677
|
|
491
678
|
const right = this.evaluateExpression(expr.right);
|
492
|
-
if (!right
|
679
|
+
if (!right.isCompileTimeValue()) return;
|
493
680
|
|
494
|
-
const result =
|
681
|
+
const result = operandHandler(
|
495
682
|
left.asCompileTimeValue(),
|
496
683
|
right.asCompileTimeValue()
|
497
684
|
);
|
@@ -502,10 +689,28 @@ class JavascriptParser extends Parser {
|
|
502
689
|
);
|
503
690
|
};
|
504
691
|
|
692
|
+
/**
|
693
|
+
* Helper function to determine if two booleans are always different. This is used in `handleStrictEqualityComparison`
|
694
|
+
* to determine if an expressions boolean or nullish conversion is equal or not.
|
695
|
+
* @param {boolean} a first boolean to compare
|
696
|
+
* @param {boolean} b second boolean to compare
|
697
|
+
* @returns {boolean} true if the two booleans are always different, false otherwise
|
698
|
+
*/
|
505
699
|
const isAlwaysDifferent = (a, b) =>
|
506
700
|
(a === true && b === false) || (a === false && b === true);
|
507
701
|
|
702
|
+
/**
|
703
|
+
* @param {BasicEvaluatedExpression} left left
|
704
|
+
* @param {BasicEvaluatedExpression} right right
|
705
|
+
* @param {BasicEvaluatedExpression} res res
|
706
|
+
* @param {boolean} eql true for "===" and false for "!=="
|
707
|
+
* @returns {BasicEvaluatedExpression | undefined} result
|
708
|
+
*/
|
508
709
|
const handleTemplateStringCompare = (left, right, res, eql) => {
|
710
|
+
/**
|
711
|
+
* @param {BasicEvaluatedExpression[]} parts parts
|
712
|
+
* @returns {string} value
|
713
|
+
*/
|
509
714
|
const getPrefix = parts => {
|
510
715
|
let value = "";
|
511
716
|
for (const p of parts) {
|
@@ -515,6 +720,10 @@ class JavascriptParser extends Parser {
|
|
515
720
|
}
|
516
721
|
return value;
|
517
722
|
};
|
723
|
+
/**
|
724
|
+
* @param {BasicEvaluatedExpression[]} parts parts
|
725
|
+
* @returns {string} value
|
726
|
+
*/
|
518
727
|
const getSuffix = parts => {
|
519
728
|
let value = "";
|
520
729
|
for (let i = parts.length - 1; i >= 0; i--) {
|
@@ -524,17 +733,27 @@ class JavascriptParser extends Parser {
|
|
524
733
|
}
|
525
734
|
return value;
|
526
735
|
};
|
527
|
-
const leftPrefix = getPrefix(
|
528
|
-
|
529
|
-
|
530
|
-
const
|
736
|
+
const leftPrefix = getPrefix(
|
737
|
+
/** @type {BasicEvaluatedExpression[]} */ (left.parts)
|
738
|
+
);
|
739
|
+
const rightPrefix = getPrefix(
|
740
|
+
/** @type {BasicEvaluatedExpression[]} */ (right.parts)
|
741
|
+
);
|
742
|
+
const leftSuffix = getSuffix(
|
743
|
+
/** @type {BasicEvaluatedExpression[]} */ (left.parts)
|
744
|
+
);
|
745
|
+
const rightSuffix = getSuffix(
|
746
|
+
/** @type {BasicEvaluatedExpression[]} */ (right.parts)
|
747
|
+
);
|
531
748
|
const lenPrefix = Math.min(leftPrefix.length, rightPrefix.length);
|
532
749
|
const lenSuffix = Math.min(leftSuffix.length, rightSuffix.length);
|
533
|
-
|
534
|
-
|
535
|
-
|
536
|
-
|
537
|
-
|
750
|
+
const prefixMismatch =
|
751
|
+
lenPrefix > 0 &&
|
752
|
+
leftPrefix.slice(0, lenPrefix) !== rightPrefix.slice(0, lenPrefix);
|
753
|
+
const suffixMismatch =
|
754
|
+
lenSuffix > 0 &&
|
755
|
+
leftSuffix.slice(-lenSuffix) !== rightSuffix.slice(-lenSuffix);
|
756
|
+
if (prefixMismatch || suffixMismatch) {
|
538
757
|
return res
|
539
758
|
.setBoolean(!eql)
|
540
759
|
.setSideEffects(
|
@@ -543,13 +762,16 @@ class JavascriptParser extends Parser {
|
|
543
762
|
}
|
544
763
|
};
|
545
764
|
|
765
|
+
/**
|
766
|
+
* Helper function to handle BinaryExpressions using strict equality comparisons (e.g. "===" and "!==").
|
767
|
+
* @param {boolean} eql true for "===" and false for "!=="
|
768
|
+
* @returns {BasicEvaluatedExpression | undefined} the evaluated expression
|
769
|
+
*/
|
546
770
|
const handleStrictEqualityComparison = eql => {
|
547
771
|
const left = this.evaluateExpression(expr.left);
|
548
|
-
if (!left) return;
|
549
772
|
const right = this.evaluateExpression(expr.right);
|
550
|
-
if (!right) return;
|
551
773
|
const res = new BasicEvaluatedExpression();
|
552
|
-
res.setRange(expr.range);
|
774
|
+
res.setRange(/** @type {Range} */ (expr.range));
|
553
775
|
|
554
776
|
const leftConst = left.isCompileTimeValue();
|
555
777
|
const rightConst = right.isCompileTimeValue();
|
@@ -587,8 +809,14 @@ class JavascriptParser extends Parser {
|
|
587
809
|
(rightPrimitive === false &&
|
588
810
|
(rightConst || leftPrimitive === true)) ||
|
589
811
|
// Different nullish or boolish status also means not equal
|
590
|
-
isAlwaysDifferent(
|
591
|
-
|
812
|
+
isAlwaysDifferent(
|
813
|
+
/** @type {boolean} */ (left.asBool()),
|
814
|
+
/** @type {boolean} */ (right.asBool())
|
815
|
+
) ||
|
816
|
+
isAlwaysDifferent(
|
817
|
+
/** @type {boolean} */ (left.asNullish()),
|
818
|
+
/** @type {boolean} */ (right.asNullish())
|
819
|
+
)
|
592
820
|
) {
|
593
821
|
return res
|
594
822
|
.setBoolean(!eql)
|
@@ -598,13 +826,16 @@ class JavascriptParser extends Parser {
|
|
598
826
|
}
|
599
827
|
};
|
600
828
|
|
829
|
+
/**
|
830
|
+
* Helper function to handle BinaryExpressions using abstract equality comparisons (e.g. "==" and "!=").
|
831
|
+
* @param {boolean} eql true for "==" and false for "!="
|
832
|
+
* @returns {BasicEvaluatedExpression | undefined} the evaluated expression
|
833
|
+
*/
|
601
834
|
const handleAbstractEqualityComparison = eql => {
|
602
835
|
const left = this.evaluateExpression(expr.left);
|
603
|
-
if (!left) return;
|
604
836
|
const right = this.evaluateExpression(expr.right);
|
605
|
-
if (!right) return;
|
606
837
|
const res = new BasicEvaluatedExpression();
|
607
|
-
res.setRange(expr.range);
|
838
|
+
res.setRange(/** @type {Range} */ (expr.range));
|
608
839
|
|
609
840
|
const leftConst = left.isCompileTimeValue();
|
610
841
|
const rightConst = right.isCompileTimeValue();
|
@@ -635,15 +866,16 @@ class JavascriptParser extends Parser {
|
|
635
866
|
|
636
867
|
if (expr.operator === "+") {
|
637
868
|
const left = this.evaluateExpression(expr.left);
|
638
|
-
if (!left) return;
|
639
869
|
const right = this.evaluateExpression(expr.right);
|
640
|
-
if (!right) return;
|
641
870
|
const res = new BasicEvaluatedExpression();
|
642
871
|
if (left.isString()) {
|
643
872
|
if (right.isString()) {
|
644
|
-
res.setString(
|
873
|
+
res.setString(
|
874
|
+
/** @type {string} */ (left.string) +
|
875
|
+
/** @type {string} */ (right.string)
|
876
|
+
);
|
645
877
|
} else if (right.isNumber()) {
|
646
|
-
res.setString(left.string + right.number);
|
878
|
+
res.setString(/** @type {string} */ (left.string) + right.number);
|
647
879
|
} else if (
|
648
880
|
right.isWrapped() &&
|
649
881
|
right.prefix &&
|
@@ -653,8 +885,16 @@ class JavascriptParser extends Parser {
|
|
653
885
|
// => ("leftPrefix" + inner + "postfix")
|
654
886
|
res.setWrapped(
|
655
887
|
new BasicEvaluatedExpression()
|
656
|
-
.setString(
|
657
|
-
|
888
|
+
.setString(
|
889
|
+
/** @type {string} */ (left.string) +
|
890
|
+
/** @type {string} */ (right.prefix.string)
|
891
|
+
)
|
892
|
+
.setRange(
|
893
|
+
joinRanges(
|
894
|
+
/** @type {Range} */ (left.range),
|
895
|
+
/** @type {Range} */ (right.prefix.range)
|
896
|
+
)
|
897
|
+
),
|
658
898
|
right.postfix,
|
659
899
|
right.wrappedInnerExpressions
|
660
900
|
);
|
@@ -673,15 +913,21 @@ class JavascriptParser extends Parser {
|
|
673
913
|
}
|
674
914
|
} else if (left.isNumber()) {
|
675
915
|
if (right.isString()) {
|
676
|
-
res.setString(left.number + right.string);
|
916
|
+
res.setString(left.number + /** @type {string} */ (right.string));
|
677
917
|
} else if (right.isNumber()) {
|
678
|
-
res.setNumber(
|
918
|
+
res.setNumber(
|
919
|
+
/** @type {number} */ (left.number) +
|
920
|
+
/** @type {number} */ (right.number)
|
921
|
+
);
|
679
922
|
} else {
|
680
923
|
return;
|
681
924
|
}
|
682
925
|
} else if (left.isBigInt()) {
|
683
926
|
if (right.isBigInt()) {
|
684
|
-
res.setBigInt(
|
927
|
+
res.setBigInt(
|
928
|
+
/** @type {bigint} */ (left.bigint) +
|
929
|
+
/** @type {bigint} */ (right.bigint)
|
930
|
+
);
|
685
931
|
}
|
686
932
|
} else if (left.isWrapped()) {
|
687
933
|
if (left.postfix && left.postfix.isString() && right.isString()) {
|
@@ -690,8 +936,16 @@ class JavascriptParser extends Parser {
|
|
690
936
|
res.setWrapped(
|
691
937
|
left.prefix,
|
692
938
|
new BasicEvaluatedExpression()
|
693
|
-
.setString(
|
694
|
-
|
939
|
+
.setString(
|
940
|
+
/** @type {string} */ (left.postfix.string) +
|
941
|
+
/** @type {string} */ (right.string)
|
942
|
+
)
|
943
|
+
.setRange(
|
944
|
+
joinRanges(
|
945
|
+
/** @type {Range} */ (left.postfix.range),
|
946
|
+
/** @type {Range} */ (right.range)
|
947
|
+
)
|
948
|
+
),
|
695
949
|
left.wrappedInnerExpressions
|
696
950
|
);
|
697
951
|
} else if (
|
@@ -704,8 +958,16 @@ class JavascriptParser extends Parser {
|
|
704
958
|
res.setWrapped(
|
705
959
|
left.prefix,
|
706
960
|
new BasicEvaluatedExpression()
|
707
|
-
.setString(
|
708
|
-
|
961
|
+
.setString(
|
962
|
+
/** @type {string} */ (left.postfix.string) +
|
963
|
+
/** @type {number} */ (right.number)
|
964
|
+
)
|
965
|
+
.setRange(
|
966
|
+
joinRanges(
|
967
|
+
/** @type {Range} */ (left.postfix.range),
|
968
|
+
/** @type {Range} */ (right.range)
|
969
|
+
)
|
970
|
+
),
|
709
971
|
left.wrappedInnerExpressions
|
710
972
|
);
|
711
973
|
} else if (right.isString()) {
|
@@ -718,8 +980,8 @@ class JavascriptParser extends Parser {
|
|
718
980
|
res.setWrapped(
|
719
981
|
left.prefix,
|
720
982
|
new BasicEvaluatedExpression()
|
721
|
-
.setString(right.number
|
722
|
-
.setRange(right.range),
|
983
|
+
.setString(String(right.number))
|
984
|
+
.setRange(/** @type {Range} */ (right.range)),
|
723
985
|
left.wrappedInnerExpressions
|
724
986
|
);
|
725
987
|
} else if (right.isWrapped()) {
|
@@ -747,29 +1009,27 @@ class JavascriptParser extends Parser {
|
|
747
1009
|
)
|
748
1010
|
);
|
749
1011
|
}
|
1012
|
+
} else if (right.isString()) {
|
1013
|
+
// left + "right"
|
1014
|
+
// => ([null] + left + "right")
|
1015
|
+
res.setWrapped(null, right, [left]);
|
1016
|
+
} else if (right.isWrapped()) {
|
1017
|
+
// left + (prefix + inner + "postfix")
|
1018
|
+
// => ([null] + left + prefix + inner + "postfix")
|
1019
|
+
res.setWrapped(
|
1020
|
+
null,
|
1021
|
+
right.postfix,
|
1022
|
+
right.wrappedInnerExpressions &&
|
1023
|
+
(right.prefix ? [left, right.prefix] : [left]).concat(
|
1024
|
+
right.wrappedInnerExpressions
|
1025
|
+
)
|
1026
|
+
);
|
750
1027
|
} else {
|
751
|
-
|
752
|
-
// left + "right"
|
753
|
-
// => ([null] + left + "right")
|
754
|
-
res.setWrapped(null, right, [left]);
|
755
|
-
} else if (right.isWrapped()) {
|
756
|
-
// left + (prefix + inner + "postfix")
|
757
|
-
// => ([null] + left + prefix + inner + "postfix")
|
758
|
-
res.setWrapped(
|
759
|
-
null,
|
760
|
-
right.postfix,
|
761
|
-
right.wrappedInnerExpressions &&
|
762
|
-
(right.prefix ? [left, right.prefix] : [left]).concat(
|
763
|
-
right.wrappedInnerExpressions
|
764
|
-
)
|
765
|
-
);
|
766
|
-
} else {
|
767
|
-
return;
|
768
|
-
}
|
1028
|
+
return;
|
769
1029
|
}
|
770
1030
|
if (left.couldHaveSideEffects() || right.couldHaveSideEffects())
|
771
1031
|
res.setSideEffects();
|
772
|
-
res.setRange(expr.range);
|
1032
|
+
res.setRange(/** @type {Range} */ (expr.range));
|
773
1033
|
return res;
|
774
1034
|
} else if (expr.operator === "-") {
|
775
1035
|
return handleConstOperation((l, r) => l - r);
|
@@ -812,12 +1072,18 @@ class JavascriptParser extends Parser {
|
|
812
1072
|
this.hooks.evaluate
|
813
1073
|
.for("UnaryExpression")
|
814
1074
|
.tap("JavascriptParser", _expr => {
|
815
|
-
const expr = /** @type {
|
816
|
-
|
817
|
-
|
1075
|
+
const expr = /** @type {UnaryExpression} */ (_expr);
|
1076
|
+
|
1077
|
+
/**
|
1078
|
+
* Evaluates a UnaryExpression if and only if it is a basic const operator (e.g. +a, -a, ~a).
|
1079
|
+
* @template T
|
1080
|
+
* @param {(operand: T) => boolean | number | bigint | string} operandHandler handler for the operand
|
1081
|
+
* @returns {BasicEvaluatedExpression | undefined} evaluated expression
|
1082
|
+
*/
|
1083
|
+
const handleConstOperation = operandHandler => {
|
818
1084
|
const argument = this.evaluateExpression(expr.argument);
|
819
|
-
if (!argument
|
820
|
-
const result =
|
1085
|
+
if (!argument.isCompileTimeValue()) return;
|
1086
|
+
const result = operandHandler(argument.asCompileTimeValue());
|
821
1087
|
return valueAsExpression(
|
822
1088
|
result,
|
823
1089
|
expr,
|
@@ -866,7 +1132,7 @@ class JavascriptParser extends Parser {
|
|
866
1132
|
case "FunctionExpression": {
|
867
1133
|
return new BasicEvaluatedExpression()
|
868
1134
|
.setString("function")
|
869
|
-
.setRange(expr.range);
|
1135
|
+
.setRange(/** @type {Range} */ (expr.range));
|
870
1136
|
}
|
871
1137
|
}
|
872
1138
|
const arg = this.evaluateExpression(expr.argument);
|
@@ -874,79 +1140,88 @@ class JavascriptParser extends Parser {
|
|
874
1140
|
if (arg.isString()) {
|
875
1141
|
return new BasicEvaluatedExpression()
|
876
1142
|
.setString("string")
|
877
|
-
.setRange(expr.range);
|
1143
|
+
.setRange(/** @type {Range} */ (expr.range));
|
878
1144
|
}
|
879
1145
|
if (arg.isWrapped()) {
|
880
1146
|
return new BasicEvaluatedExpression()
|
881
1147
|
.setString("string")
|
882
1148
|
.setSideEffects()
|
883
|
-
.setRange(expr.range);
|
1149
|
+
.setRange(/** @type {Range} */ (expr.range));
|
884
1150
|
}
|
885
1151
|
if (arg.isUndefined()) {
|
886
1152
|
return new BasicEvaluatedExpression()
|
887
1153
|
.setString("undefined")
|
888
|
-
.setRange(expr.range);
|
1154
|
+
.setRange(/** @type {Range} */ (expr.range));
|
889
1155
|
}
|
890
1156
|
if (arg.isNumber()) {
|
891
1157
|
return new BasicEvaluatedExpression()
|
892
1158
|
.setString("number")
|
893
|
-
.setRange(expr.range);
|
1159
|
+
.setRange(/** @type {Range} */ (expr.range));
|
894
1160
|
}
|
895
1161
|
if (arg.isBigInt()) {
|
896
1162
|
return new BasicEvaluatedExpression()
|
897
1163
|
.setString("bigint")
|
898
|
-
.setRange(expr.range);
|
1164
|
+
.setRange(/** @type {Range} */ (expr.range));
|
899
1165
|
}
|
900
1166
|
if (arg.isBoolean()) {
|
901
1167
|
return new BasicEvaluatedExpression()
|
902
1168
|
.setString("boolean")
|
903
|
-
.setRange(expr.range);
|
1169
|
+
.setRange(/** @type {Range} */ (expr.range));
|
904
1170
|
}
|
905
1171
|
if (arg.isConstArray() || arg.isRegExp() || arg.isNull()) {
|
906
1172
|
return new BasicEvaluatedExpression()
|
907
1173
|
.setString("object")
|
908
|
-
.setRange(expr.range);
|
1174
|
+
.setRange(/** @type {Range} */ (expr.range));
|
909
1175
|
}
|
910
1176
|
if (arg.isArray()) {
|
911
1177
|
return new BasicEvaluatedExpression()
|
912
1178
|
.setString("object")
|
913
1179
|
.setSideEffects(arg.couldHaveSideEffects())
|
914
|
-
.setRange(expr.range);
|
1180
|
+
.setRange(/** @type {Range} */ (expr.range));
|
915
1181
|
}
|
916
1182
|
} else if (expr.operator === "!") {
|
917
1183
|
const argument = this.evaluateExpression(expr.argument);
|
918
|
-
if (!argument) return;
|
919
1184
|
const bool = argument.asBool();
|
920
1185
|
if (typeof bool !== "boolean") return;
|
921
1186
|
return new BasicEvaluatedExpression()
|
922
1187
|
.setBoolean(!bool)
|
923
1188
|
.setSideEffects(argument.couldHaveSideEffects())
|
924
|
-
.setRange(expr.range);
|
1189
|
+
.setRange(/** @type {Range} */ (expr.range));
|
925
1190
|
} else if (expr.operator === "~") {
|
926
1191
|
return handleConstOperation(v => ~v);
|
927
1192
|
} else if (expr.operator === "+") {
|
1193
|
+
// eslint-disable-next-line no-implicit-coercion
|
928
1194
|
return handleConstOperation(v => +v);
|
929
1195
|
} else if (expr.operator === "-") {
|
930
1196
|
return handleConstOperation(v => -v);
|
931
1197
|
}
|
932
1198
|
});
|
933
|
-
this.hooks.evaluateTypeof
|
934
|
-
|
935
|
-
|
936
|
-
|
1199
|
+
this.hooks.evaluateTypeof
|
1200
|
+
.for("undefined")
|
1201
|
+
.tap("JavascriptParser", expr =>
|
1202
|
+
new BasicEvaluatedExpression()
|
1203
|
+
.setString("undefined")
|
1204
|
+
.setRange(/** @type {Range} */ (expr.range))
|
1205
|
+
);
|
1206
|
+
this.hooks.evaluate.for("Identifier").tap("JavascriptParser", expr => {
|
1207
|
+
if (/** @type {Identifier} */ (expr).name === "undefined") {
|
1208
|
+
return new BasicEvaluatedExpression()
|
1209
|
+
.setUndefined()
|
1210
|
+
.setRange(/** @type {Range} */ (expr.range));
|
1211
|
+
}
|
937
1212
|
});
|
938
1213
|
/**
|
939
1214
|
* @param {string} exprType expression type name
|
940
|
-
* @param {function(
|
1215
|
+
* @param {function(Expression | SpreadElement): GetInfoResult | undefined} getInfo get info
|
941
1216
|
* @returns {void}
|
942
1217
|
*/
|
943
1218
|
const tapEvaluateWithVariableInfo = (exprType, getInfo) => {
|
944
|
-
/** @type {
|
945
|
-
let cachedExpression
|
1219
|
+
/** @type {Expression | undefined} */
|
1220
|
+
let cachedExpression;
|
946
1221
|
/** @type {GetInfoResult | undefined} */
|
947
|
-
let cachedInfo
|
1222
|
+
let cachedInfo;
|
948
1223
|
this.hooks.evaluate.for(exprType).tap("JavascriptParser", expr => {
|
949
|
-
const expression = /** @type {
|
1224
|
+
const expression = /** @type {MemberExpression} */ (expr);
|
950
1225
|
|
951
1226
|
const info = getInfo(expr);
|
952
1227
|
if (info !== undefined) {
|
@@ -973,8 +1248,14 @@ class JavascriptParser extends Parser {
|
|
973
1248
|
const info = cachedExpression === expr ? cachedInfo : getInfo(expr);
|
974
1249
|
if (info !== undefined) {
|
975
1250
|
return new BasicEvaluatedExpression()
|
976
|
-
.setIdentifier(
|
977
|
-
|
1251
|
+
.setIdentifier(
|
1252
|
+
info.name,
|
1253
|
+
info.rootInfo,
|
1254
|
+
info.getMembers,
|
1255
|
+
info.getMembersOptionals,
|
1256
|
+
info.getMemberRanges
|
1257
|
+
)
|
1258
|
+
.setRange(/** @type {Range} */ (expr.range));
|
978
1259
|
}
|
979
1260
|
});
|
980
1261
|
this.hooks.finish.tap("JavascriptParser", () => {
|
@@ -983,14 +1264,18 @@ class JavascriptParser extends Parser {
|
|
983
1264
|
});
|
984
1265
|
};
|
985
1266
|
tapEvaluateWithVariableInfo("Identifier", expr => {
|
986
|
-
const info = this.getVariableInfo(
|
987
|
-
/** @type {IdentifierNode} */ (expr).name
|
988
|
-
);
|
1267
|
+
const info = this.getVariableInfo(/** @type {Identifier} */ (expr).name);
|
989
1268
|
if (
|
990
1269
|
typeof info === "string" ||
|
991
1270
|
(info instanceof VariableInfo && typeof info.freeName === "string")
|
992
1271
|
) {
|
993
|
-
return {
|
1272
|
+
return {
|
1273
|
+
name: info,
|
1274
|
+
rootInfo: info,
|
1275
|
+
getMembers: () => [],
|
1276
|
+
getMembersOptionals: () => [],
|
1277
|
+
getMemberRanges: () => []
|
1278
|
+
};
|
994
1279
|
}
|
995
1280
|
});
|
996
1281
|
tapEvaluateWithVariableInfo("ThisExpression", expr => {
|
@@ -999,11 +1284,17 @@ class JavascriptParser extends Parser {
|
|
999
1284
|
typeof info === "string" ||
|
1000
1285
|
(info instanceof VariableInfo && typeof info.freeName === "string")
|
1001
1286
|
) {
|
1002
|
-
return {
|
1287
|
+
return {
|
1288
|
+
name: info,
|
1289
|
+
rootInfo: info,
|
1290
|
+
getMembers: () => [],
|
1291
|
+
getMembersOptionals: () => [],
|
1292
|
+
getMemberRanges: () => []
|
1293
|
+
};
|
1003
1294
|
}
|
1004
1295
|
});
|
1005
1296
|
this.hooks.evaluate.for("MetaProperty").tap("JavascriptParser", expr => {
|
1006
|
-
const metaProperty = /** @type {
|
1297
|
+
const metaProperty = /** @type {MetaProperty} */ (expr);
|
1007
1298
|
|
1008
1299
|
return this.callHooksForName(
|
1009
1300
|
this.hooks.evaluateIdentifier,
|
@@ -1013,33 +1304,36 @@ class JavascriptParser extends Parser {
|
|
1013
1304
|
});
|
1014
1305
|
tapEvaluateWithVariableInfo("MemberExpression", expr =>
|
1015
1306
|
this.getMemberExpressionInfo(
|
1016
|
-
/** @type {
|
1307
|
+
/** @type {MemberExpression} */ (expr),
|
1017
1308
|
ALLOWED_MEMBER_TYPES_EXPRESSION
|
1018
1309
|
)
|
1019
1310
|
);
|
1020
1311
|
|
1021
1312
|
this.hooks.evaluate.for("CallExpression").tap("JavascriptParser", _expr => {
|
1022
|
-
const expr = /** @type {
|
1313
|
+
const expr = /** @type {CallExpression} */ (_expr);
|
1023
1314
|
if (
|
1024
|
-
expr.callee.type
|
1025
|
-
expr.callee.property.type
|
1315
|
+
expr.callee.type === "MemberExpression" &&
|
1316
|
+
expr.callee.property.type ===
|
1026
1317
|
(expr.callee.computed ? "Literal" : "Identifier")
|
1027
1318
|
) {
|
1028
|
-
|
1029
|
-
|
1030
|
-
|
1031
|
-
|
1032
|
-
|
1033
|
-
|
1034
|
-
|
1035
|
-
|
1036
|
-
|
1037
|
-
|
1038
|
-
|
1039
|
-
|
1040
|
-
|
1041
|
-
|
1042
|
-
|
1319
|
+
// type Super also possible here
|
1320
|
+
const param = this.evaluateExpression(
|
1321
|
+
/** @type {Expression} */ (expr.callee.object)
|
1322
|
+
);
|
1323
|
+
const property =
|
1324
|
+
expr.callee.property.type === "Literal"
|
1325
|
+
? `${expr.callee.property.value}`
|
1326
|
+
: expr.callee.property.name;
|
1327
|
+
const hook = this.hooks.evaluateCallExpressionMember.get(property);
|
1328
|
+
if (hook !== undefined) {
|
1329
|
+
return hook.call(expr, param);
|
1330
|
+
}
|
1331
|
+
} else if (expr.callee.type === "Identifier") {
|
1332
|
+
return this.callHooksForName(
|
1333
|
+
this.hooks.evaluateCallExpression,
|
1334
|
+
expr.callee.name,
|
1335
|
+
expr
|
1336
|
+
);
|
1043
1337
|
}
|
1044
1338
|
});
|
1045
1339
|
this.hooks.evaluateCallExpressionMember
|
@@ -1051,21 +1345,24 @@ class JavascriptParser extends Parser {
|
|
1051
1345
|
if (arg1.type === "SpreadElement") return;
|
1052
1346
|
const arg1Eval = this.evaluateExpression(arg1);
|
1053
1347
|
if (!arg1Eval.isString()) return;
|
1054
|
-
const arg1Value = arg1Eval.string;
|
1348
|
+
const arg1Value = /** @type {string} */ (arg1Eval.string);
|
1055
1349
|
|
1056
1350
|
let result;
|
1057
1351
|
if (arg2) {
|
1058
1352
|
if (arg2.type === "SpreadElement") return;
|
1059
1353
|
const arg2Eval = this.evaluateExpression(arg2);
|
1060
1354
|
if (!arg2Eval.isNumber()) return;
|
1061
|
-
result = param.string.indexOf(
|
1355
|
+
result = /** @type {string} */ (param.string).indexOf(
|
1356
|
+
arg1Value,
|
1357
|
+
arg2Eval.number
|
1358
|
+
);
|
1062
1359
|
} else {
|
1063
|
-
result = param.string.indexOf(arg1Value);
|
1360
|
+
result = /** @type {string} */ (param.string).indexOf(arg1Value);
|
1064
1361
|
}
|
1065
1362
|
return new BasicEvaluatedExpression()
|
1066
1363
|
.setNumber(result)
|
1067
1364
|
.setSideEffects(param.couldHaveSideEffects())
|
1068
|
-
.setRange(expr.range);
|
1365
|
+
.setRange(/** @type {Range} */ (expr.range));
|
1069
1366
|
});
|
1070
1367
|
this.hooks.evaluateCallExpressionMember
|
1071
1368
|
.for("replace")
|
@@ -1074,31 +1371,37 @@ class JavascriptParser extends Parser {
|
|
1074
1371
|
if (expr.arguments.length !== 2) return;
|
1075
1372
|
if (expr.arguments[0].type === "SpreadElement") return;
|
1076
1373
|
if (expr.arguments[1].type === "SpreadElement") return;
|
1077
|
-
|
1078
|
-
|
1374
|
+
const arg1 = this.evaluateExpression(expr.arguments[0]);
|
1375
|
+
const arg2 = this.evaluateExpression(expr.arguments[1]);
|
1079
1376
|
if (!arg1.isString() && !arg1.isRegExp()) return;
|
1080
|
-
const arg1Value =
|
1377
|
+
const arg1Value = /** @type {string | RegExp} */ (
|
1378
|
+
arg1.regExp || arg1.string
|
1379
|
+
);
|
1081
1380
|
if (!arg2.isString()) return;
|
1082
|
-
const arg2Value = arg2.string;
|
1381
|
+
const arg2Value = /** @type {string} */ (arg2.string);
|
1083
1382
|
return new BasicEvaluatedExpression()
|
1084
|
-
.setString(
|
1383
|
+
.setString(
|
1384
|
+
/** @type {string} */ (param.string).replace(arg1Value, arg2Value)
|
1385
|
+
)
|
1085
1386
|
.setSideEffects(param.couldHaveSideEffects())
|
1086
|
-
.setRange(expr.range);
|
1387
|
+
.setRange(/** @type {Range} */ (expr.range));
|
1087
1388
|
});
|
1088
|
-
["substr", "substring", "slice"]
|
1389
|
+
for (const fn of ["substr", "substring", "slice"]) {
|
1089
1390
|
this.hooks.evaluateCallExpressionMember
|
1090
1391
|
.for(fn)
|
1091
1392
|
.tap("JavascriptParser", (expr, param) => {
|
1092
1393
|
if (!param.isString()) return;
|
1093
1394
|
let arg1;
|
1094
|
-
let result
|
1095
|
-
|
1395
|
+
let result;
|
1396
|
+
const str = /** @type {string} */ (param.string);
|
1096
1397
|
switch (expr.arguments.length) {
|
1097
1398
|
case 1:
|
1098
1399
|
if (expr.arguments[0].type === "SpreadElement") return;
|
1099
1400
|
arg1 = this.evaluateExpression(expr.arguments[0]);
|
1100
1401
|
if (!arg1.isNumber()) return;
|
1101
|
-
result = str[
|
1402
|
+
result = str[
|
1403
|
+
/** @type {"substr" | "substring" | "slice"} */ (fn)
|
1404
|
+
](/** @type {number} */ (arg1.number));
|
1102
1405
|
break;
|
1103
1406
|
case 2: {
|
1104
1407
|
if (expr.arguments[0].type === "SpreadElement") return;
|
@@ -1107,7 +1410,12 @@ class JavascriptParser extends Parser {
|
|
1107
1410
|
const arg2 = this.evaluateExpression(expr.arguments[1]);
|
1108
1411
|
if (!arg1.isNumber()) return;
|
1109
1412
|
if (!arg2.isNumber()) return;
|
1110
|
-
result = str[
|
1413
|
+
result = str[
|
1414
|
+
/** @type {"substr" | "substring" | "slice"} */ (fn)
|
1415
|
+
](
|
1416
|
+
/** @type {number} */ (arg1.number),
|
1417
|
+
/** @type {number} */ (arg2.number)
|
1418
|
+
);
|
1111
1419
|
break;
|
1112
1420
|
}
|
1113
1421
|
default:
|
@@ -1116,13 +1424,13 @@ class JavascriptParser extends Parser {
|
|
1116
1424
|
return new BasicEvaluatedExpression()
|
1117
1425
|
.setString(result)
|
1118
1426
|
.setSideEffects(param.couldHaveSideEffects())
|
1119
|
-
.setRange(expr.range);
|
1427
|
+
.setRange(/** @type {Range} */ (expr.range));
|
1120
1428
|
});
|
1121
|
-
}
|
1429
|
+
}
|
1122
1430
|
|
1123
1431
|
/**
|
1124
1432
|
* @param {"cooked" | "raw"} kind kind of values to get
|
1125
|
-
* @param {
|
1433
|
+
* @param {TemplateLiteral} templateLiteralExpr TemplateLiteral expr
|
1126
1434
|
* @returns {{quasis: BasicEvaluatedExpression[], parts: BasicEvaluatedExpression[]}} Simplified template
|
1127
1435
|
*/
|
1128
1436
|
const getSimplifiedTemplateResult = (kind, templateLiteralExpr) => {
|
@@ -1149,7 +1457,10 @@ class JavascriptParser extends Parser {
|
|
1149
1457
|
// is a const string
|
1150
1458
|
|
1151
1459
|
prevExpr.setString(prevExpr.string + exprAsString + quasi);
|
1152
|
-
prevExpr.setRange([
|
1460
|
+
prevExpr.setRange([
|
1461
|
+
/** @type {Range} */ (prevExpr.range)[0],
|
1462
|
+
/** @type {Range} */ (quasiExpr.range)[1]
|
1463
|
+
]);
|
1153
1464
|
// We unset the expression as it doesn't match to a single expression
|
1154
1465
|
prevExpr.setExpression(undefined);
|
1155
1466
|
continue;
|
@@ -1158,8 +1469,8 @@ class JavascriptParser extends Parser {
|
|
1158
1469
|
}
|
1159
1470
|
|
1160
1471
|
const part = new BasicEvaluatedExpression()
|
1161
|
-
.setString(quasi)
|
1162
|
-
.setRange(quasiExpr.range)
|
1472
|
+
.setString(/** @type {string} */ (quasi))
|
1473
|
+
.setRange(/** @type {Range} */ (quasiExpr.range))
|
1163
1474
|
.setExpression(quasiExpr);
|
1164
1475
|
quasis.push(part);
|
1165
1476
|
parts.push(part);
|
@@ -1173,37 +1484,37 @@ class JavascriptParser extends Parser {
|
|
1173
1484
|
this.hooks.evaluate
|
1174
1485
|
.for("TemplateLiteral")
|
1175
1486
|
.tap("JavascriptParser", _node => {
|
1176
|
-
const node = /** @type {
|
1487
|
+
const node = /** @type {TemplateLiteral} */ (_node);
|
1177
1488
|
|
1178
1489
|
const { quasis, parts } = getSimplifiedTemplateResult("cooked", node);
|
1179
1490
|
if (parts.length === 1) {
|
1180
|
-
return parts[0].setRange(node.range);
|
1491
|
+
return parts[0].setRange(/** @type {Range} */ (node.range));
|
1181
1492
|
}
|
1182
1493
|
return new BasicEvaluatedExpression()
|
1183
1494
|
.setTemplateString(quasis, parts, "cooked")
|
1184
|
-
.setRange(node.range);
|
1495
|
+
.setRange(/** @type {Range} */ (node.range));
|
1185
1496
|
});
|
1186
1497
|
this.hooks.evaluate
|
1187
1498
|
.for("TaggedTemplateExpression")
|
1188
1499
|
.tap("JavascriptParser", _node => {
|
1189
|
-
const node = /** @type {
|
1500
|
+
const node = /** @type {TaggedTemplateExpression} */ (_node);
|
1190
1501
|
const tag = this.evaluateExpression(node.tag);
|
1191
1502
|
|
1192
|
-
if (tag.isIdentifier() && tag.identifier
|
1193
|
-
|
1194
|
-
|
1195
|
-
|
1196
|
-
|
1197
|
-
|
1198
|
-
|
1199
|
-
|
1503
|
+
if (tag.isIdentifier() && tag.identifier === "String.raw") {
|
1504
|
+
const { quasis, parts } = getSimplifiedTemplateResult(
|
1505
|
+
"raw",
|
1506
|
+
node.quasi
|
1507
|
+
);
|
1508
|
+
return new BasicEvaluatedExpression()
|
1509
|
+
.setTemplateString(quasis, parts, "raw")
|
1510
|
+
.setRange(/** @type {Range} */ (node.range));
|
1511
|
+
}
|
1200
1512
|
});
|
1201
1513
|
|
1202
1514
|
this.hooks.evaluateCallExpressionMember
|
1203
1515
|
.for("concat")
|
1204
1516
|
.tap("JavascriptParser", (expr, param) => {
|
1205
1517
|
if (!param.isString() && !param.isWrapped()) return;
|
1206
|
-
|
1207
1518
|
let stringSuffix = null;
|
1208
1519
|
let hasUnknownParams = false;
|
1209
1520
|
const innerExpressions = [];
|
@@ -1220,15 +1531,17 @@ class JavascriptParser extends Parser {
|
|
1220
1531
|
continue;
|
1221
1532
|
}
|
1222
1533
|
|
1534
|
+
/** @type {string} */
|
1223
1535
|
const value = argExpr.isString()
|
1224
|
-
? argExpr.string
|
1225
|
-
:
|
1536
|
+
? /** @type {string} */ (argExpr.string)
|
1537
|
+
: String(/** @type {number} */ (argExpr.number));
|
1226
1538
|
|
1539
|
+
/** @type {string} */
|
1227
1540
|
const newString = value + (stringSuffix ? stringSuffix.string : "");
|
1228
|
-
const newRange = [
|
1229
|
-
argExpr.range[0],
|
1230
|
-
(stringSuffix || argExpr).range[1]
|
1231
|
-
];
|
1541
|
+
const newRange = /** @type {Range} */ ([
|
1542
|
+
/** @type {Range} */ (argExpr.range)[0],
|
1543
|
+
/** @type {Range} */ ((stringSuffix || argExpr).range)[1]
|
1544
|
+
]);
|
1232
1545
|
stringSuffix = new BasicEvaluatedExpression()
|
1233
1546
|
.setString(newString)
|
1234
1547
|
.setSideEffects(
|
@@ -1246,7 +1559,7 @@ class JavascriptParser extends Parser {
|
|
1246
1559
|
: innerExpressions.reverse();
|
1247
1560
|
return new BasicEvaluatedExpression()
|
1248
1561
|
.setWrapped(prefix, stringSuffix, inner)
|
1249
|
-
.setRange(expr.range);
|
1562
|
+
.setRange(/** @type {Range} */ (expr.range));
|
1250
1563
|
} else if (param.isWrapped()) {
|
1251
1564
|
const postfix = stringSuffix || param.postfix;
|
1252
1565
|
const inner = param.wrappedInnerExpressions
|
@@ -1254,18 +1567,18 @@ class JavascriptParser extends Parser {
|
|
1254
1567
|
: innerExpressions.reverse();
|
1255
1568
|
return new BasicEvaluatedExpression()
|
1256
1569
|
.setWrapped(param.prefix, postfix, inner)
|
1257
|
-
.setRange(expr.range);
|
1258
|
-
} else {
|
1259
|
-
const newString =
|
1260
|
-
param.string + (stringSuffix ? stringSuffix.string : "");
|
1261
|
-
return new BasicEvaluatedExpression()
|
1262
|
-
.setString(newString)
|
1263
|
-
.setSideEffects(
|
1264
|
-
(stringSuffix && stringSuffix.couldHaveSideEffects()) ||
|
1265
|
-
param.couldHaveSideEffects()
|
1266
|
-
)
|
1267
|
-
.setRange(expr.range);
|
1570
|
+
.setRange(/** @type {Range} */ (expr.range));
|
1268
1571
|
}
|
1572
|
+
const newString =
|
1573
|
+
/** @type {string} */ (param.string) +
|
1574
|
+
(stringSuffix ? stringSuffix.string : "");
|
1575
|
+
return new BasicEvaluatedExpression()
|
1576
|
+
.setString(newString)
|
1577
|
+
.setSideEffects(
|
1578
|
+
(stringSuffix && stringSuffix.couldHaveSideEffects()) ||
|
1579
|
+
param.couldHaveSideEffects()
|
1580
|
+
)
|
1581
|
+
.setRange(/** @type {Range} */ (expr.range));
|
1269
1582
|
});
|
1270
1583
|
this.hooks.evaluateCallExpressionMember
|
1271
1584
|
.for("split")
|
@@ -1276,21 +1589,25 @@ class JavascriptParser extends Parser {
|
|
1276
1589
|
let result;
|
1277
1590
|
const arg = this.evaluateExpression(expr.arguments[0]);
|
1278
1591
|
if (arg.isString()) {
|
1279
|
-
result =
|
1592
|
+
result =
|
1593
|
+
/** @type {string} */
|
1594
|
+
(param.string).split(/** @type {string} */ (arg.string));
|
1280
1595
|
} else if (arg.isRegExp()) {
|
1281
|
-
result = param.string.split(
|
1596
|
+
result = /** @type {string} */ (param.string).split(
|
1597
|
+
/** @type {RegExp} */ (arg.regExp)
|
1598
|
+
);
|
1282
1599
|
} else {
|
1283
1600
|
return;
|
1284
1601
|
}
|
1285
1602
|
return new BasicEvaluatedExpression()
|
1286
1603
|
.setArray(result)
|
1287
1604
|
.setSideEffects(param.couldHaveSideEffects())
|
1288
|
-
.setRange(expr.range);
|
1605
|
+
.setRange(/** @type {Range} */ (expr.range));
|
1289
1606
|
});
|
1290
1607
|
this.hooks.evaluate
|
1291
1608
|
.for("ConditionalExpression")
|
1292
1609
|
.tap("JavascriptParser", _expr => {
|
1293
|
-
const expr = /** @type {
|
1610
|
+
const expr = /** @type {ConditionalExpression} */ (_expr);
|
1294
1611
|
|
1295
1612
|
const condition = this.evaluateExpression(expr.test);
|
1296
1613
|
const conditionValue = condition.asBool();
|
@@ -1298,15 +1615,18 @@ class JavascriptParser extends Parser {
|
|
1298
1615
|
if (conditionValue === undefined) {
|
1299
1616
|
const consequent = this.evaluateExpression(expr.consequent);
|
1300
1617
|
const alternate = this.evaluateExpression(expr.alternate);
|
1301
|
-
if (!consequent || !alternate) return;
|
1302
1618
|
res = new BasicEvaluatedExpression();
|
1303
1619
|
if (consequent.isConditional()) {
|
1304
|
-
res.setOptions(
|
1620
|
+
res.setOptions(
|
1621
|
+
/** @type {BasicEvaluatedExpression[]} */ (consequent.options)
|
1622
|
+
);
|
1305
1623
|
} else {
|
1306
1624
|
res.setOptions([consequent]);
|
1307
1625
|
}
|
1308
1626
|
if (alternate.isConditional()) {
|
1309
|
-
res.addOptions(
|
1627
|
+
res.addOptions(
|
1628
|
+
/** @type {BasicEvaluatedExpression[]} */ (alternate.options)
|
1629
|
+
);
|
1310
1630
|
} else {
|
1311
1631
|
res.addOptions([alternate]);
|
1312
1632
|
}
|
@@ -1316,33 +1636,32 @@ class JavascriptParser extends Parser {
|
|
1316
1636
|
);
|
1317
1637
|
if (condition.couldHaveSideEffects()) res.setSideEffects();
|
1318
1638
|
}
|
1319
|
-
res.setRange(expr.range);
|
1639
|
+
res.setRange(/** @type {Range} */ (expr.range));
|
1320
1640
|
return res;
|
1321
1641
|
});
|
1322
1642
|
this.hooks.evaluate
|
1323
1643
|
.for("ArrayExpression")
|
1324
1644
|
.tap("JavascriptParser", _expr => {
|
1325
|
-
const expr = /** @type {
|
1645
|
+
const expr = /** @type {ArrayExpression} */ (_expr);
|
1326
1646
|
|
1327
|
-
const items = expr.elements.map(
|
1328
|
-
|
1647
|
+
const items = expr.elements.map(
|
1648
|
+
element =>
|
1329
1649
|
element !== null &&
|
1330
1650
|
element.type !== "SpreadElement" &&
|
1331
1651
|
this.evaluateExpression(element)
|
1332
|
-
|
1333
|
-
});
|
1652
|
+
);
|
1334
1653
|
if (!items.every(Boolean)) return;
|
1335
1654
|
return new BasicEvaluatedExpression()
|
1336
|
-
.setItems(items)
|
1337
|
-
.setRange(expr.range);
|
1655
|
+
.setItems(/** @type {BasicEvaluatedExpression[]} */ (items))
|
1656
|
+
.setRange(/** @type {Range} */ (expr.range));
|
1338
1657
|
});
|
1339
1658
|
this.hooks.evaluate
|
1340
1659
|
.for("ChainExpression")
|
1341
1660
|
.tap("JavascriptParser", _expr => {
|
1342
|
-
const expr = /** @type {
|
1343
|
-
/** @type {
|
1661
|
+
const expr = /** @type {ChainExpression} */ (_expr);
|
1662
|
+
/** @type {Expression[]} */
|
1344
1663
|
const optionalExpressionsStack = [];
|
1345
|
-
/** @type {
|
1664
|
+
/** @type {Expression|Super} */
|
1346
1665
|
let next = expr.expression;
|
1347
1666
|
|
1348
1667
|
while (
|
@@ -1353,7 +1672,7 @@ class JavascriptParser extends Parser {
|
|
1353
1672
|
if (next.optional) {
|
1354
1673
|
// SuperNode can not be optional
|
1355
1674
|
optionalExpressionsStack.push(
|
1356
|
-
/** @type {
|
1675
|
+
/** @type {Expression} */ (next.object)
|
1357
1676
|
);
|
1358
1677
|
}
|
1359
1678
|
next = next.object;
|
@@ -1361,7 +1680,7 @@ class JavascriptParser extends Parser {
|
|
1361
1680
|
if (next.optional) {
|
1362
1681
|
// SuperNode can not be optional
|
1363
1682
|
optionalExpressionsStack.push(
|
1364
|
-
/** @type {
|
1683
|
+
/** @type {Expression} */ (next.callee)
|
1365
1684
|
);
|
1366
1685
|
}
|
1367
1686
|
next = next.callee;
|
@@ -1369,60 +1688,91 @@ class JavascriptParser extends Parser {
|
|
1369
1688
|
}
|
1370
1689
|
|
1371
1690
|
while (optionalExpressionsStack.length > 0) {
|
1372
|
-
const expression =
|
1691
|
+
const expression =
|
1692
|
+
/** @type {Expression} */
|
1693
|
+
(optionalExpressionsStack.pop());
|
1373
1694
|
const evaluated = this.evaluateExpression(expression);
|
1374
1695
|
|
1375
|
-
if (evaluated
|
1376
|
-
return evaluated.setRange(_expr.range);
|
1696
|
+
if (evaluated.asNullish()) {
|
1697
|
+
return evaluated.setRange(/** @type {Range} */ (_expr.range));
|
1377
1698
|
}
|
1378
1699
|
}
|
1379
1700
|
return this.evaluateExpression(expr.expression);
|
1380
1701
|
});
|
1381
1702
|
}
|
1382
1703
|
|
1704
|
+
/**
|
1705
|
+
* @param {Expression} node node
|
1706
|
+
* @returns {Set<DestructuringAssignmentProperty> | undefined} destructured identifiers
|
1707
|
+
*/
|
1708
|
+
destructuringAssignmentPropertiesFor(node) {
|
1709
|
+
if (!this.destructuringAssignmentProperties) return;
|
1710
|
+
return this.destructuringAssignmentProperties.get(node);
|
1711
|
+
}
|
1712
|
+
|
1713
|
+
/**
|
1714
|
+
* @param {Expression} expr expression
|
1715
|
+
* @returns {string | VariableInfoInterface | undefined} identifier
|
1716
|
+
*/
|
1383
1717
|
getRenameIdentifier(expr) {
|
1384
1718
|
const result = this.evaluateExpression(expr);
|
1385
|
-
if (result
|
1719
|
+
if (result.isIdentifier()) {
|
1386
1720
|
return result.identifier;
|
1387
1721
|
}
|
1388
1722
|
}
|
1389
1723
|
|
1390
1724
|
/**
|
1391
|
-
* @param {
|
1725
|
+
* @param {ClassExpression | ClassDeclaration} classy a class node
|
1392
1726
|
* @returns {void}
|
1393
1727
|
*/
|
1394
1728
|
walkClass(classy) {
|
1395
|
-
if (
|
1396
|
-
|
1397
|
-
|
1398
|
-
|
1729
|
+
if (
|
1730
|
+
classy.superClass &&
|
1731
|
+
!this.hooks.classExtendsExpression.call(classy.superClass, classy)
|
1732
|
+
) {
|
1733
|
+
this.walkExpression(classy.superClass);
|
1399
1734
|
}
|
1400
1735
|
if (classy.body && classy.body.type === "ClassBody") {
|
1401
|
-
|
1402
|
-
|
1403
|
-
|
1404
|
-
|
1405
|
-
|
1406
|
-
|
1407
|
-
|
1408
|
-
|
1409
|
-
|
1410
|
-
|
1411
|
-
|
1412
|
-
|
1413
|
-
|
1736
|
+
const scopeParams = [];
|
1737
|
+
// Add class name in scope for recursive calls
|
1738
|
+
if (classy.id) {
|
1739
|
+
scopeParams.push(classy.id);
|
1740
|
+
}
|
1741
|
+
this.inClassScope(true, scopeParams, () => {
|
1742
|
+
for (const classElement of /** @type {TODO} */ (classy.body.body)) {
|
1743
|
+
if (!this.hooks.classBodyElement.call(classElement, classy)) {
|
1744
|
+
if (classElement.computed && classElement.key) {
|
1745
|
+
this.walkExpression(classElement.key);
|
1746
|
+
}
|
1747
|
+
if (classElement.value) {
|
1748
|
+
if (
|
1749
|
+
!this.hooks.classBodyValue.call(
|
1750
|
+
classElement.value,
|
1751
|
+
classElement,
|
1752
|
+
classy
|
1753
|
+
)
|
1754
|
+
) {
|
1755
|
+
const wasTopLevel = this.scope.topLevelScope;
|
1756
|
+
this.scope.topLevelScope = false;
|
1757
|
+
this.walkExpression(classElement.value);
|
1758
|
+
this.scope.topLevelScope = wasTopLevel;
|
1759
|
+
}
|
1760
|
+
} else if (classElement.type === "StaticBlock") {
|
1414
1761
|
const wasTopLevel = this.scope.topLevelScope;
|
1415
1762
|
this.scope.topLevelScope = false;
|
1416
|
-
this.
|
1763
|
+
this.walkBlockStatement(classElement);
|
1417
1764
|
this.scope.topLevelScope = wasTopLevel;
|
1418
1765
|
}
|
1419
1766
|
}
|
1420
1767
|
}
|
1421
|
-
}
|
1768
|
+
});
|
1422
1769
|
}
|
1423
1770
|
}
|
1424
1771
|
|
1425
|
-
|
1772
|
+
/**
|
1773
|
+
* Pre walking iterates the scope for variable declarations
|
1774
|
+
* @param {(Statement | ModuleDeclaration)[]} statements statements
|
1775
|
+
*/
|
1426
1776
|
preWalkStatements(statements) {
|
1427
1777
|
for (let index = 0, len = statements.length; index < len; index++) {
|
1428
1778
|
const statement = statements[index];
|
@@ -1430,7 +1780,10 @@ class JavascriptParser extends Parser {
|
|
1430
1780
|
}
|
1431
1781
|
}
|
1432
1782
|
|
1433
|
-
|
1783
|
+
/**
|
1784
|
+
* Block pre walking iterates the scope for block variable declarations
|
1785
|
+
* @param {(Statement | ModuleDeclaration)[]} statements statements
|
1786
|
+
*/
|
1434
1787
|
blockPreWalkStatements(statements) {
|
1435
1788
|
for (let index = 0, len = statements.length; index < len; index++) {
|
1436
1789
|
const statement = statements[index];
|
@@ -1438,7 +1791,10 @@ class JavascriptParser extends Parser {
|
|
1438
1791
|
}
|
1439
1792
|
}
|
1440
1793
|
|
1441
|
-
|
1794
|
+
/**
|
1795
|
+
* Walking iterates the statements and expressions and processes them
|
1796
|
+
* @param {(Statement | ModuleDeclaration)[]} statements statements
|
1797
|
+
*/
|
1442
1798
|
walkStatements(statements) {
|
1443
1799
|
for (let index = 0, len = statements.length; index < len; index++) {
|
1444
1800
|
const statement = statements[index];
|
@@ -1446,6 +1802,10 @@ class JavascriptParser extends Parser {
|
|
1446
1802
|
}
|
1447
1803
|
}
|
1448
1804
|
|
1805
|
+
/**
|
1806
|
+
* Walking iterates the statements and expressions and processes them
|
1807
|
+
* @param {Statement | ModuleDeclaration} statement statement
|
1808
|
+
*/
|
1449
1809
|
preWalkStatement(statement) {
|
1450
1810
|
this.statementPath.push(statement);
|
1451
1811
|
if (this.hooks.preStatement.call(statement)) {
|
@@ -1496,6 +1856,9 @@ class JavascriptParser extends Parser {
|
|
1496
1856
|
this.prevStatement = this.statementPath.pop();
|
1497
1857
|
}
|
1498
1858
|
|
1859
|
+
/**
|
1860
|
+
* @param {Statement | ModuleDeclaration} statement statement
|
1861
|
+
*/
|
1499
1862
|
blockPreWalkStatement(statement) {
|
1500
1863
|
this.statementPath.push(statement);
|
1501
1864
|
if (this.hooks.blockPreStatement.call(statement)) {
|
@@ -1521,10 +1884,15 @@ class JavascriptParser extends Parser {
|
|
1521
1884
|
case "ClassDeclaration":
|
1522
1885
|
this.blockPreWalkClassDeclaration(statement);
|
1523
1886
|
break;
|
1887
|
+
case "ExpressionStatement":
|
1888
|
+
this.blockPreWalkExpressionStatement(statement);
|
1524
1889
|
}
|
1525
1890
|
this.prevStatement = this.statementPath.pop();
|
1526
1891
|
}
|
1527
1892
|
|
1893
|
+
/**
|
1894
|
+
* @param {Statement | ModuleDeclaration} statement statement
|
1895
|
+
*/
|
1528
1896
|
walkStatement(statement) {
|
1529
1897
|
this.statementPath.push(statement);
|
1530
1898
|
if (this.hooks.statement.call(statement) !== undefined) {
|
@@ -1597,8 +1965,7 @@ class JavascriptParser extends Parser {
|
|
1597
1965
|
* Walks a statements that is nested within a parent statement
|
1598
1966
|
* and can potentially be a non-block statement.
|
1599
1967
|
* This enforces the nested statement to never be in ASI position.
|
1600
|
-
* @param {
|
1601
|
-
* @returns {void}
|
1968
|
+
* @param {Statement} statement the nested statement
|
1602
1969
|
*/
|
1603
1970
|
walkNestedStatement(statement) {
|
1604
1971
|
this.prevStatement = undefined;
|
@@ -1606,10 +1973,16 @@ class JavascriptParser extends Parser {
|
|
1606
1973
|
}
|
1607
1974
|
|
1608
1975
|
// Real Statements
|
1976
|
+
/**
|
1977
|
+
* @param {BlockStatement} statement block statement
|
1978
|
+
*/
|
1609
1979
|
preWalkBlockStatement(statement) {
|
1610
1980
|
this.preWalkStatements(statement.body);
|
1611
1981
|
}
|
1612
1982
|
|
1983
|
+
/**
|
1984
|
+
* @param {BlockStatement} statement block statement
|
1985
|
+
*/
|
1613
1986
|
walkBlockStatement(statement) {
|
1614
1987
|
this.inBlockScope(() => {
|
1615
1988
|
const body = statement.body;
|
@@ -1620,10 +1993,16 @@ class JavascriptParser extends Parser {
|
|
1620
1993
|
});
|
1621
1994
|
}
|
1622
1995
|
|
1996
|
+
/**
|
1997
|
+
* @param {ExpressionStatement} statement expression statement
|
1998
|
+
*/
|
1623
1999
|
walkExpressionStatement(statement) {
|
1624
2000
|
this.walkExpression(statement.expression);
|
1625
2001
|
}
|
1626
2002
|
|
2003
|
+
/**
|
2004
|
+
* @param {IfStatement} statement if statement
|
2005
|
+
*/
|
1627
2006
|
preWalkIfStatement(statement) {
|
1628
2007
|
this.preWalkStatement(statement.consequent);
|
1629
2008
|
if (statement.alternate) {
|
@@ -1631,6 +2010,9 @@ class JavascriptParser extends Parser {
|
|
1631
2010
|
}
|
1632
2011
|
}
|
1633
2012
|
|
2013
|
+
/**
|
2014
|
+
* @param {IfStatement} statement if statement
|
2015
|
+
*/
|
1634
2016
|
walkIfStatement(statement) {
|
1635
2017
|
const result = this.hooks.statementIf.call(statement);
|
1636
2018
|
if (result === undefined) {
|
@@ -1639,19 +2021,23 @@ class JavascriptParser extends Parser {
|
|
1639
2021
|
if (statement.alternate) {
|
1640
2022
|
this.walkNestedStatement(statement.alternate);
|
1641
2023
|
}
|
1642
|
-
} else {
|
1643
|
-
|
1644
|
-
|
1645
|
-
|
1646
|
-
this.walkNestedStatement(statement.alternate);
|
1647
|
-
}
|
2024
|
+
} else if (result) {
|
2025
|
+
this.walkNestedStatement(statement.consequent);
|
2026
|
+
} else if (statement.alternate) {
|
2027
|
+
this.walkNestedStatement(statement.alternate);
|
1648
2028
|
}
|
1649
2029
|
}
|
1650
2030
|
|
2031
|
+
/**
|
2032
|
+
* @param {LabeledStatement} statement with statement
|
2033
|
+
*/
|
1651
2034
|
preWalkLabeledStatement(statement) {
|
1652
2035
|
this.preWalkStatement(statement.body);
|
1653
2036
|
}
|
1654
2037
|
|
2038
|
+
/**
|
2039
|
+
* @param {LabeledStatement} statement with statement
|
2040
|
+
*/
|
1655
2041
|
walkLabeledStatement(statement) {
|
1656
2042
|
const hook = this.hooks.label.get(statement.label.name);
|
1657
2043
|
if (hook !== undefined) {
|
@@ -1661,42 +2047,69 @@ class JavascriptParser extends Parser {
|
|
1661
2047
|
this.walkNestedStatement(statement.body);
|
1662
2048
|
}
|
1663
2049
|
|
2050
|
+
/**
|
2051
|
+
* @param {WithStatement} statement with statement
|
2052
|
+
*/
|
1664
2053
|
preWalkWithStatement(statement) {
|
1665
2054
|
this.preWalkStatement(statement.body);
|
1666
2055
|
}
|
1667
2056
|
|
2057
|
+
/**
|
2058
|
+
* @param {WithStatement} statement with statement
|
2059
|
+
*/
|
1668
2060
|
walkWithStatement(statement) {
|
1669
2061
|
this.walkExpression(statement.object);
|
1670
2062
|
this.walkNestedStatement(statement.body);
|
1671
2063
|
}
|
1672
2064
|
|
2065
|
+
/**
|
2066
|
+
* @param {SwitchStatement} statement switch statement
|
2067
|
+
*/
|
1673
2068
|
preWalkSwitchStatement(statement) {
|
1674
2069
|
this.preWalkSwitchCases(statement.cases);
|
1675
2070
|
}
|
1676
2071
|
|
2072
|
+
/**
|
2073
|
+
* @param {SwitchStatement} statement switch statement
|
2074
|
+
*/
|
1677
2075
|
walkSwitchStatement(statement) {
|
1678
2076
|
this.walkExpression(statement.discriminant);
|
1679
2077
|
this.walkSwitchCases(statement.cases);
|
1680
2078
|
}
|
1681
2079
|
|
2080
|
+
/**
|
2081
|
+
* @param {ReturnStatement | ThrowStatement} statement return or throw statement
|
2082
|
+
*/
|
1682
2083
|
walkTerminatingStatement(statement) {
|
1683
2084
|
if (statement.argument) this.walkExpression(statement.argument);
|
1684
2085
|
}
|
1685
2086
|
|
2087
|
+
/**
|
2088
|
+
* @param {ReturnStatement} statement return statement
|
2089
|
+
*/
|
1686
2090
|
walkReturnStatement(statement) {
|
1687
2091
|
this.walkTerminatingStatement(statement);
|
1688
2092
|
}
|
1689
2093
|
|
2094
|
+
/**
|
2095
|
+
* @param {ThrowStatement} statement return statement
|
2096
|
+
*/
|
1690
2097
|
walkThrowStatement(statement) {
|
1691
2098
|
this.walkTerminatingStatement(statement);
|
1692
2099
|
}
|
1693
2100
|
|
2101
|
+
/**
|
2102
|
+
* @param {TryStatement} statement try statement
|
2103
|
+
*/
|
1694
2104
|
preWalkTryStatement(statement) {
|
1695
2105
|
this.preWalkStatement(statement.block);
|
1696
2106
|
if (statement.handler) this.preWalkCatchClause(statement.handler);
|
1697
|
-
if (statement.
|
2107
|
+
if (statement.finalizer) this.preWalkStatement(statement.finalizer);
|
1698
2108
|
}
|
1699
2109
|
|
2110
|
+
/**
|
2111
|
+
* @param {TryStatement} statement try statement
|
2112
|
+
*/
|
1700
2113
|
walkTryStatement(statement) {
|
1701
2114
|
if (this.scope.inTry) {
|
1702
2115
|
this.walkStatement(statement.block);
|
@@ -1709,33 +2122,49 @@ class JavascriptParser extends Parser {
|
|
1709
2122
|
if (statement.finalizer) this.walkStatement(statement.finalizer);
|
1710
2123
|
}
|
1711
2124
|
|
2125
|
+
/**
|
2126
|
+
* @param {WhileStatement} statement while statement
|
2127
|
+
*/
|
1712
2128
|
preWalkWhileStatement(statement) {
|
1713
2129
|
this.preWalkStatement(statement.body);
|
1714
2130
|
}
|
1715
2131
|
|
2132
|
+
/**
|
2133
|
+
* @param {WhileStatement} statement while statement
|
2134
|
+
*/
|
1716
2135
|
walkWhileStatement(statement) {
|
1717
2136
|
this.walkExpression(statement.test);
|
1718
2137
|
this.walkNestedStatement(statement.body);
|
1719
2138
|
}
|
1720
2139
|
|
2140
|
+
/**
|
2141
|
+
* @param {DoWhileStatement} statement do while statement
|
2142
|
+
*/
|
1721
2143
|
preWalkDoWhileStatement(statement) {
|
1722
2144
|
this.preWalkStatement(statement.body);
|
1723
2145
|
}
|
1724
2146
|
|
2147
|
+
/**
|
2148
|
+
* @param {DoWhileStatement} statement do while statement
|
2149
|
+
*/
|
1725
2150
|
walkDoWhileStatement(statement) {
|
1726
2151
|
this.walkNestedStatement(statement.body);
|
1727
2152
|
this.walkExpression(statement.test);
|
1728
2153
|
}
|
1729
2154
|
|
2155
|
+
/**
|
2156
|
+
* @param {ForStatement} statement for statement
|
2157
|
+
*/
|
1730
2158
|
preWalkForStatement(statement) {
|
1731
|
-
if (statement.init) {
|
1732
|
-
|
1733
|
-
this.preWalkStatement(statement.init);
|
1734
|
-
}
|
2159
|
+
if (statement.init && statement.init.type === "VariableDeclaration") {
|
2160
|
+
this.preWalkStatement(statement.init);
|
1735
2161
|
}
|
1736
2162
|
this.preWalkStatement(statement.body);
|
1737
2163
|
}
|
1738
2164
|
|
2165
|
+
/**
|
2166
|
+
* @param {ForStatement} statement for statement
|
2167
|
+
*/
|
1739
2168
|
walkForStatement(statement) {
|
1740
2169
|
this.inBlockScope(() => {
|
1741
2170
|
if (statement.init) {
|
@@ -1766,6 +2195,9 @@ class JavascriptParser extends Parser {
|
|
1766
2195
|
});
|
1767
2196
|
}
|
1768
2197
|
|
2198
|
+
/**
|
2199
|
+
* @param {ForInStatement} statement for statement
|
2200
|
+
*/
|
1769
2201
|
preWalkForInStatement(statement) {
|
1770
2202
|
if (statement.left.type === "VariableDeclaration") {
|
1771
2203
|
this.preWalkVariableDeclaration(statement.left);
|
@@ -1773,6 +2205,9 @@ class JavascriptParser extends Parser {
|
|
1773
2205
|
this.preWalkStatement(statement.body);
|
1774
2206
|
}
|
1775
2207
|
|
2208
|
+
/**
|
2209
|
+
* @param {ForInStatement} statement for statement
|
2210
|
+
*/
|
1776
2211
|
walkForInStatement(statement) {
|
1777
2212
|
this.inBlockScope(() => {
|
1778
2213
|
if (statement.left.type === "VariableDeclaration") {
|
@@ -1795,6 +2230,9 @@ class JavascriptParser extends Parser {
|
|
1795
2230
|
});
|
1796
2231
|
}
|
1797
2232
|
|
2233
|
+
/**
|
2234
|
+
* @param {ForOfStatement} statement statement
|
2235
|
+
*/
|
1798
2236
|
preWalkForOfStatement(statement) {
|
1799
2237
|
if (statement.await && this.scope.topLevelScope === true) {
|
1800
2238
|
this.hooks.topLevelAwait.call(statement);
|
@@ -1805,6 +2243,9 @@ class JavascriptParser extends Parser {
|
|
1805
2243
|
this.preWalkStatement(statement.body);
|
1806
2244
|
}
|
1807
2245
|
|
2246
|
+
/**
|
2247
|
+
* @param {ForOfStatement} statement for statement
|
2248
|
+
*/
|
1808
2249
|
walkForOfStatement(statement) {
|
1809
2250
|
this.inBlockScope(() => {
|
1810
2251
|
if (statement.left.type === "VariableDeclaration") {
|
@@ -1827,13 +2268,18 @@ class JavascriptParser extends Parser {
|
|
1827
2268
|
});
|
1828
2269
|
}
|
1829
2270
|
|
1830
|
-
|
2271
|
+
/**
|
2272
|
+
* @param {FunctionDeclaration} statement function declaration
|
2273
|
+
*/
|
1831
2274
|
preWalkFunctionDeclaration(statement) {
|
1832
2275
|
if (statement.id) {
|
1833
2276
|
this.defineVariable(statement.id.name);
|
1834
2277
|
}
|
1835
2278
|
}
|
1836
2279
|
|
2280
|
+
/**
|
2281
|
+
* @param {FunctionDeclaration} statement function declaration
|
2282
|
+
*/
|
1837
2283
|
walkFunctionDeclaration(statement) {
|
1838
2284
|
const wasTopLevel = this.scope.topLevelScope;
|
1839
2285
|
this.scope.topLevelScope = false;
|
@@ -1854,8 +2300,55 @@ class JavascriptParser extends Parser {
|
|
1854
2300
|
this.scope.topLevelScope = wasTopLevel;
|
1855
2301
|
}
|
1856
2302
|
|
2303
|
+
/**
|
2304
|
+
* @param {ExpressionStatement} statement expression statement
|
2305
|
+
*/
|
2306
|
+
blockPreWalkExpressionStatement(statement) {
|
2307
|
+
const expression = statement.expression;
|
2308
|
+
switch (expression.type) {
|
2309
|
+
case "AssignmentExpression":
|
2310
|
+
this.preWalkAssignmentExpression(expression);
|
2311
|
+
}
|
2312
|
+
}
|
2313
|
+
|
2314
|
+
/**
|
2315
|
+
* @param {AssignmentExpression} expression assignment expression
|
2316
|
+
*/
|
2317
|
+
preWalkAssignmentExpression(expression) {
|
2318
|
+
if (
|
2319
|
+
expression.left.type !== "ObjectPattern" ||
|
2320
|
+
!this.destructuringAssignmentProperties
|
2321
|
+
)
|
2322
|
+
return;
|
2323
|
+
const keys = this._preWalkObjectPattern(expression.left);
|
2324
|
+
if (!keys) return;
|
2325
|
+
|
2326
|
+
// check multiple assignments
|
2327
|
+
if (this.destructuringAssignmentProperties.has(expression)) {
|
2328
|
+
const set =
|
2329
|
+
/** @type {Set<DestructuringAssignmentProperty>} */
|
2330
|
+
(this.destructuringAssignmentProperties.get(expression));
|
2331
|
+
this.destructuringAssignmentProperties.delete(expression);
|
2332
|
+
for (const id of set) keys.add(id);
|
2333
|
+
}
|
2334
|
+
|
2335
|
+
this.destructuringAssignmentProperties.set(
|
2336
|
+
expression.right.type === "AwaitExpression"
|
2337
|
+
? expression.right.argument
|
2338
|
+
: expression.right,
|
2339
|
+
keys
|
2340
|
+
);
|
2341
|
+
|
2342
|
+
if (expression.right.type === "AssignmentExpression") {
|
2343
|
+
this.preWalkAssignmentExpression(expression.right);
|
2344
|
+
}
|
2345
|
+
}
|
2346
|
+
|
2347
|
+
/**
|
2348
|
+
* @param {ImportDeclaration} statement statement
|
2349
|
+
*/
|
1857
2350
|
blockPreWalkImportDeclaration(statement) {
|
1858
|
-
const source = statement.source.value;
|
2351
|
+
const source = /** @type {ImportSource} */ (statement.source.value);
|
1859
2352
|
this.hooks.import.call(statement, source);
|
1860
2353
|
for (const specifier of statement.specifiers) {
|
1861
2354
|
const name = specifier.local.name;
|
@@ -1872,7 +2365,12 @@ class JavascriptParser extends Parser {
|
|
1872
2365
|
!this.hooks.importSpecifier.call(
|
1873
2366
|
statement,
|
1874
2367
|
source,
|
1875
|
-
specifier.imported.name
|
2368
|
+
specifier.imported.name ||
|
2369
|
+
// eslint-disable-next-line no-warning-comments
|
2370
|
+
// @ts-ignore
|
2371
|
+
// Old version of acorn used it
|
2372
|
+
// TODO drop it in webpack@6
|
2373
|
+
specifier.imported.value,
|
1876
2374
|
name
|
1877
2375
|
)
|
1878
2376
|
) {
|
@@ -1890,6 +2388,10 @@ class JavascriptParser extends Parser {
|
|
1890
2388
|
}
|
1891
2389
|
}
|
1892
2390
|
|
2391
|
+
/**
|
2392
|
+
* @param {Declaration} declaration declaration
|
2393
|
+
* @param {OnIdent} onIdent on ident callback
|
2394
|
+
*/
|
1893
2395
|
enterDeclaration(declaration, onIdent) {
|
1894
2396
|
switch (declaration.type) {
|
1895
2397
|
case "VariableDeclaration":
|
@@ -1911,27 +2413,29 @@ class JavascriptParser extends Parser {
|
|
1911
2413
|
}
|
1912
2414
|
}
|
1913
2415
|
|
2416
|
+
/**
|
2417
|
+
* @param {ExportNamedDeclaration} statement statement
|
2418
|
+
*/
|
1914
2419
|
blockPreWalkExportNamedDeclaration(statement) {
|
1915
2420
|
let source;
|
1916
2421
|
if (statement.source) {
|
1917
|
-
source = statement.source.value;
|
2422
|
+
source = /** @type {ImportSource} */ (statement.source.value);
|
1918
2423
|
this.hooks.exportImport.call(statement, source);
|
1919
2424
|
} else {
|
1920
2425
|
this.hooks.export.call(statement);
|
1921
2426
|
}
|
1922
|
-
if (
|
1923
|
-
|
1924
|
-
|
1925
|
-
|
1926
|
-
|
1927
|
-
|
1928
|
-
|
1929
|
-
|
1930
|
-
|
1931
|
-
|
1932
|
-
|
1933
|
-
|
1934
|
-
}
|
2427
|
+
if (
|
2428
|
+
statement.declaration &&
|
2429
|
+
!this.hooks.exportDeclaration.call(statement, statement.declaration)
|
2430
|
+
) {
|
2431
|
+
const prev = this.prevStatement;
|
2432
|
+
this.preWalkStatement(statement.declaration);
|
2433
|
+
this.prevStatement = prev;
|
2434
|
+
this.blockPreWalkStatement(statement.declaration);
|
2435
|
+
let index = 0;
|
2436
|
+
this.enterDeclaration(statement.declaration, def => {
|
2437
|
+
this.hooks.exportSpecifier.call(statement, def, def, index++);
|
2438
|
+
});
|
1935
2439
|
}
|
1936
2440
|
if (statement.specifiers) {
|
1937
2441
|
for (
|
@@ -1942,7 +2446,13 @@ class JavascriptParser extends Parser {
|
|
1942
2446
|
const specifier = statement.specifiers[specifierIndex];
|
1943
2447
|
switch (specifier.type) {
|
1944
2448
|
case "ExportSpecifier": {
|
1945
|
-
const name =
|
2449
|
+
const name =
|
2450
|
+
specifier.exported.name ||
|
2451
|
+
// eslint-disable-next-line no-warning-comments
|
2452
|
+
// @ts-ignore
|
2453
|
+
// Old version of acorn used it
|
2454
|
+
// TODO drop it in webpack@6
|
2455
|
+
specifier.exported.value;
|
1946
2456
|
if (source) {
|
1947
2457
|
this.hooks.exportImportSpecifier.call(
|
1948
2458
|
statement,
|
@@ -1966,42 +2476,59 @@ class JavascriptParser extends Parser {
|
|
1966
2476
|
}
|
1967
2477
|
}
|
1968
2478
|
|
2479
|
+
/**
|
2480
|
+
* @param {ExportNamedDeclaration} statement the statement
|
2481
|
+
*/
|
1969
2482
|
walkExportNamedDeclaration(statement) {
|
1970
2483
|
if (statement.declaration) {
|
1971
2484
|
this.walkStatement(statement.declaration);
|
1972
2485
|
}
|
1973
2486
|
}
|
1974
2487
|
|
2488
|
+
/**
|
2489
|
+
* @param {TODO} statement statement
|
2490
|
+
*/
|
1975
2491
|
blockPreWalkExportDefaultDeclaration(statement) {
|
1976
2492
|
const prev = this.prevStatement;
|
1977
2493
|
this.preWalkStatement(statement.declaration);
|
1978
2494
|
this.prevStatement = prev;
|
1979
2495
|
this.blockPreWalkStatement(statement.declaration);
|
1980
2496
|
if (
|
1981
|
-
|
2497
|
+
/** @type {FunctionDeclaration | ClassDeclaration} */ (
|
2498
|
+
statement.declaration
|
2499
|
+
).id &&
|
1982
2500
|
statement.declaration.type !== "FunctionExpression" &&
|
1983
2501
|
statement.declaration.type !== "ClassExpression"
|
1984
2502
|
) {
|
2503
|
+
const declaration =
|
2504
|
+
/** @type {FunctionDeclaration | ClassDeclaration} */
|
2505
|
+
(statement.declaration);
|
1985
2506
|
this.hooks.exportSpecifier.call(
|
1986
2507
|
statement,
|
1987
|
-
|
2508
|
+
declaration.id.name,
|
1988
2509
|
"default",
|
1989
2510
|
undefined
|
1990
2511
|
);
|
1991
2512
|
}
|
1992
2513
|
}
|
1993
2514
|
|
2515
|
+
/**
|
2516
|
+
* @param {ExportDefaultDeclaration} statement statement
|
2517
|
+
*/
|
1994
2518
|
walkExportDefaultDeclaration(statement) {
|
1995
2519
|
this.hooks.export.call(statement);
|
1996
2520
|
if (
|
1997
|
-
|
2521
|
+
/** @type {FunctionDeclaration | ClassDeclaration} */ (
|
2522
|
+
statement.declaration
|
2523
|
+
).id &&
|
1998
2524
|
statement.declaration.type !== "FunctionExpression" &&
|
1999
2525
|
statement.declaration.type !== "ClassExpression"
|
2000
2526
|
) {
|
2001
|
-
|
2002
|
-
|
2003
|
-
|
2004
|
-
|
2527
|
+
const declaration =
|
2528
|
+
/** @type {FunctionDeclaration | ClassDeclaration} */
|
2529
|
+
(statement.declaration);
|
2530
|
+
if (!this.hooks.exportDeclaration.call(statement, declaration)) {
|
2531
|
+
this.walkStatement(declaration);
|
2005
2532
|
}
|
2006
2533
|
} else {
|
2007
2534
|
// Acorn parses `export default function() {}` as `FunctionDeclaration` and
|
@@ -2011,14 +2538,23 @@ class JavascriptParser extends Parser {
|
|
2011
2538
|
statement.declaration.type === "FunctionDeclaration" ||
|
2012
2539
|
statement.declaration.type === "ClassDeclaration"
|
2013
2540
|
) {
|
2014
|
-
this.walkStatement(
|
2541
|
+
this.walkStatement(
|
2542
|
+
/** @type {FunctionDeclaration | ClassDeclaration} */
|
2543
|
+
(statement.declaration)
|
2544
|
+
);
|
2015
2545
|
} else {
|
2016
2546
|
this.walkExpression(statement.declaration);
|
2017
2547
|
}
|
2018
|
-
|
2548
|
+
|
2549
|
+
if (
|
2550
|
+
!this.hooks.exportExpression.call(
|
2551
|
+
statement,
|
2552
|
+
/** @type {TODO} */ (statement).declaration
|
2553
|
+
)
|
2554
|
+
) {
|
2019
2555
|
this.hooks.exportSpecifier.call(
|
2020
2556
|
statement,
|
2021
|
-
statement.declaration,
|
2557
|
+
/** @type {TODO} */ (statement.declaration),
|
2022
2558
|
"default",
|
2023
2559
|
undefined
|
2024
2560
|
);
|
@@ -2026,18 +2562,27 @@ class JavascriptParser extends Parser {
|
|
2026
2562
|
}
|
2027
2563
|
}
|
2028
2564
|
|
2029
|
-
|
2030
|
-
|
2565
|
+
/**
|
2566
|
+
* @param {ExportAllDeclaration} statement statement
|
2567
|
+
*/
|
2568
|
+
blockPreWalkExportAllDeclaration(statement) {
|
2569
|
+
const source = /** @type {ImportSource} */ (statement.source.value);
|
2031
2570
|
const name = statement.exported ? statement.exported.name : null;
|
2032
2571
|
this.hooks.exportImport.call(statement, source);
|
2033
2572
|
this.hooks.exportImportSpecifier.call(statement, source, null, name, 0);
|
2034
2573
|
}
|
2035
2574
|
|
2575
|
+
/**
|
2576
|
+
* @param {VariableDeclaration} statement variable declaration
|
2577
|
+
*/
|
2036
2578
|
preWalkVariableDeclaration(statement) {
|
2037
2579
|
if (statement.kind !== "var") return;
|
2038
2580
|
this._preWalkVariableDeclaration(statement, this.hooks.varDeclarationVar);
|
2039
2581
|
}
|
2040
2582
|
|
2583
|
+
/**
|
2584
|
+
* @param {VariableDeclaration} statement variable declaration
|
2585
|
+
*/
|
2041
2586
|
blockPreWalkVariableDeclaration(statement) {
|
2042
2587
|
if (statement.kind === "var") return;
|
2043
2588
|
const hookMap =
|
@@ -2047,10 +2592,15 @@ class JavascriptParser extends Parser {
|
|
2047
2592
|
this._preWalkVariableDeclaration(statement, hookMap);
|
2048
2593
|
}
|
2049
2594
|
|
2595
|
+
/**
|
2596
|
+
* @param {VariableDeclaration} statement variable declaration
|
2597
|
+
* @param {TODO} hookMap map of hooks
|
2598
|
+
*/
|
2050
2599
|
_preWalkVariableDeclaration(statement, hookMap) {
|
2051
2600
|
for (const declarator of statement.declarations) {
|
2052
2601
|
switch (declarator.type) {
|
2053
2602
|
case "VariableDeclarator": {
|
2603
|
+
this.preWalkVariableDeclarator(declarator);
|
2054
2604
|
if (!this.hooks.preDeclarator.call(declarator, statement)) {
|
2055
2605
|
this.enterPattern(declarator.id, (name, decl) => {
|
2056
2606
|
let hook = hookMap.get(name);
|
@@ -2068,6 +2618,75 @@ class JavascriptParser extends Parser {
|
|
2068
2618
|
}
|
2069
2619
|
}
|
2070
2620
|
|
2621
|
+
/**
|
2622
|
+
* @param {ObjectPattern} objectPattern object pattern
|
2623
|
+
* @returns {Set<DestructuringAssignmentProperty> | undefined} set of names or undefined if not all keys are identifiers
|
2624
|
+
*/
|
2625
|
+
_preWalkObjectPattern(objectPattern) {
|
2626
|
+
/** @type {Set<DestructuringAssignmentProperty>} */
|
2627
|
+
const props = new Set();
|
2628
|
+
const properties = objectPattern.properties;
|
2629
|
+
for (let i = 0; i < properties.length; i++) {
|
2630
|
+
const property = properties[i];
|
2631
|
+
if (property.type !== "Property") return;
|
2632
|
+
if (property.shorthand && property.value.type === "Identifier") {
|
2633
|
+
this.scope.inShorthand = property.value.name;
|
2634
|
+
}
|
2635
|
+
const key = property.key;
|
2636
|
+
if (key.type === "Identifier") {
|
2637
|
+
props.add({
|
2638
|
+
id: key.name,
|
2639
|
+
range: key.range,
|
2640
|
+
shorthand: this.scope.inShorthand
|
2641
|
+
});
|
2642
|
+
} else {
|
2643
|
+
const id = this.evaluateExpression(/** @type {TODO} */ (key));
|
2644
|
+
const str = id.asString();
|
2645
|
+
if (str) {
|
2646
|
+
props.add({
|
2647
|
+
id: str,
|
2648
|
+
range: key.range,
|
2649
|
+
shorthand: this.scope.inShorthand
|
2650
|
+
});
|
2651
|
+
} else {
|
2652
|
+
// could not evaluate key
|
2653
|
+
return;
|
2654
|
+
}
|
2655
|
+
}
|
2656
|
+
this.scope.inShorthand = false;
|
2657
|
+
}
|
2658
|
+
|
2659
|
+
return props;
|
2660
|
+
}
|
2661
|
+
|
2662
|
+
/**
|
2663
|
+
* @param {VariableDeclarator} declarator variable declarator
|
2664
|
+
*/
|
2665
|
+
preWalkVariableDeclarator(declarator) {
|
2666
|
+
if (
|
2667
|
+
!declarator.init ||
|
2668
|
+
declarator.id.type !== "ObjectPattern" ||
|
2669
|
+
!this.destructuringAssignmentProperties
|
2670
|
+
)
|
2671
|
+
return;
|
2672
|
+
const keys = this._preWalkObjectPattern(declarator.id);
|
2673
|
+
|
2674
|
+
if (!keys) return;
|
2675
|
+
this.destructuringAssignmentProperties.set(
|
2676
|
+
declarator.init.type === "AwaitExpression"
|
2677
|
+
? declarator.init.argument
|
2678
|
+
: declarator.init,
|
2679
|
+
keys
|
2680
|
+
);
|
2681
|
+
|
2682
|
+
if (declarator.init.type === "AssignmentExpression") {
|
2683
|
+
this.preWalkAssignmentExpression(declarator.init);
|
2684
|
+
}
|
2685
|
+
}
|
2686
|
+
|
2687
|
+
/**
|
2688
|
+
* @param {VariableDeclaration} statement variable declaration
|
2689
|
+
*/
|
2071
2690
|
walkVariableDeclaration(statement) {
|
2072
2691
|
for (const declarator of statement.declarations) {
|
2073
2692
|
switch (declarator.type) {
|
@@ -2076,10 +2695,16 @@ class JavascriptParser extends Parser {
|
|
2076
2695
|
declarator.init && this.getRenameIdentifier(declarator.init);
|
2077
2696
|
if (renameIdentifier && declarator.id.type === "Identifier") {
|
2078
2697
|
const hook = this.hooks.canRename.get(renameIdentifier);
|
2079
|
-
if (
|
2698
|
+
if (
|
2699
|
+
hook !== undefined &&
|
2700
|
+
hook.call(/** @type {Expression} */ (declarator.init))
|
2701
|
+
) {
|
2080
2702
|
// renaming with "var a = b;"
|
2081
2703
|
const hook = this.hooks.rename.get(renameIdentifier);
|
2082
|
-
if (
|
2704
|
+
if (
|
2705
|
+
hook === undefined ||
|
2706
|
+
!hook.call(/** @type {Expression} */ (declarator.init))
|
2707
|
+
) {
|
2083
2708
|
this.setVariable(declarator.id.name, renameIdentifier);
|
2084
2709
|
}
|
2085
2710
|
break;
|
@@ -2095,16 +2720,25 @@ class JavascriptParser extends Parser {
|
|
2095
2720
|
}
|
2096
2721
|
}
|
2097
2722
|
|
2723
|
+
/**
|
2724
|
+
* @param {ClassDeclaration} statement class declaration
|
2725
|
+
*/
|
2098
2726
|
blockPreWalkClassDeclaration(statement) {
|
2099
2727
|
if (statement.id) {
|
2100
2728
|
this.defineVariable(statement.id.name);
|
2101
2729
|
}
|
2102
2730
|
}
|
2103
2731
|
|
2732
|
+
/**
|
2733
|
+
* @param {ClassDeclaration} statement class declaration
|
2734
|
+
*/
|
2104
2735
|
walkClassDeclaration(statement) {
|
2105
2736
|
this.walkClass(statement);
|
2106
2737
|
}
|
2107
2738
|
|
2739
|
+
/**
|
2740
|
+
* @param {SwitchCase[]} switchCases switch statement
|
2741
|
+
*/
|
2108
2742
|
preWalkSwitchCases(switchCases) {
|
2109
2743
|
for (let index = 0, len = switchCases.length; index < len; index++) {
|
2110
2744
|
const switchCase = switchCases[index];
|
@@ -2112,6 +2746,9 @@ class JavascriptParser extends Parser {
|
|
2112
2746
|
}
|
2113
2747
|
}
|
2114
2748
|
|
2749
|
+
/**
|
2750
|
+
* @param {SwitchCase[]} switchCases switch statement
|
2751
|
+
*/
|
2115
2752
|
walkSwitchCases(switchCases) {
|
2116
2753
|
this.inBlockScope(() => {
|
2117
2754
|
const len = switchCases.length;
|
@@ -2147,10 +2784,16 @@ class JavascriptParser extends Parser {
|
|
2147
2784
|
});
|
2148
2785
|
}
|
2149
2786
|
|
2787
|
+
/**
|
2788
|
+
* @param {CatchClause} catchClause catch clause
|
2789
|
+
*/
|
2150
2790
|
preWalkCatchClause(catchClause) {
|
2151
2791
|
this.preWalkStatement(catchClause.body);
|
2152
2792
|
}
|
2153
2793
|
|
2794
|
+
/**
|
2795
|
+
* @param {CatchClause} catchClause catch clause
|
2796
|
+
*/
|
2154
2797
|
walkCatchClause(catchClause) {
|
2155
2798
|
this.inBlockScope(() => {
|
2156
2799
|
// Error binding is optional in catch clause since ECMAScript 2019
|
@@ -2167,6 +2810,9 @@ class JavascriptParser extends Parser {
|
|
2167
2810
|
});
|
2168
2811
|
}
|
2169
2812
|
|
2813
|
+
/**
|
2814
|
+
* @param {Pattern} pattern pattern
|
2815
|
+
*/
|
2170
2816
|
walkPattern(pattern) {
|
2171
2817
|
switch (pattern.type) {
|
2172
2818
|
case "ArrayPattern":
|
@@ -2187,21 +2833,33 @@ class JavascriptParser extends Parser {
|
|
2187
2833
|
}
|
2188
2834
|
}
|
2189
2835
|
|
2836
|
+
/**
|
2837
|
+
* @param {AssignmentPattern} pattern assignment pattern
|
2838
|
+
*/
|
2190
2839
|
walkAssignmentPattern(pattern) {
|
2191
2840
|
this.walkExpression(pattern.right);
|
2192
2841
|
this.walkPattern(pattern.left);
|
2193
2842
|
}
|
2194
2843
|
|
2844
|
+
/**
|
2845
|
+
* @param {ObjectPattern} pattern pattern
|
2846
|
+
*/
|
2195
2847
|
walkObjectPattern(pattern) {
|
2196
2848
|
for (let i = 0, len = pattern.properties.length; i < len; i++) {
|
2197
2849
|
const prop = pattern.properties[i];
|
2198
2850
|
if (prop) {
|
2851
|
+
if (prop.type === "RestElement") {
|
2852
|
+
continue;
|
2853
|
+
}
|
2199
2854
|
if (prop.computed) this.walkExpression(prop.key);
|
2200
2855
|
if (prop.value) this.walkPattern(prop.value);
|
2201
2856
|
}
|
2202
2857
|
}
|
2203
2858
|
}
|
2204
2859
|
|
2860
|
+
/**
|
2861
|
+
* @param {ArrayPattern} pattern array pattern
|
2862
|
+
*/
|
2205
2863
|
walkArrayPattern(pattern) {
|
2206
2864
|
for (let i = 0, len = pattern.elements.length; i < len; i++) {
|
2207
2865
|
const element = pattern.elements[i];
|
@@ -2209,10 +2867,16 @@ class JavascriptParser extends Parser {
|
|
2209
2867
|
}
|
2210
2868
|
}
|
2211
2869
|
|
2870
|
+
/**
|
2871
|
+
* @param {RestElement} pattern rest element
|
2872
|
+
*/
|
2212
2873
|
walkRestElement(pattern) {
|
2213
2874
|
this.walkPattern(pattern.argument);
|
2214
2875
|
}
|
2215
2876
|
|
2877
|
+
/**
|
2878
|
+
* @param {(Expression | SpreadElement | null)[]} expressions expressions
|
2879
|
+
*/
|
2216
2880
|
walkExpressions(expressions) {
|
2217
2881
|
for (const expression of expressions) {
|
2218
2882
|
if (expression) {
|
@@ -2221,6 +2885,9 @@ class JavascriptParser extends Parser {
|
|
2221
2885
|
}
|
2222
2886
|
}
|
2223
2887
|
|
2888
|
+
/**
|
2889
|
+
* @param {TODO} expression expression
|
2890
|
+
*/
|
2224
2891
|
walkExpression(expression) {
|
2225
2892
|
switch (expression.type) {
|
2226
2893
|
case "ArrayExpression":
|
@@ -2301,24 +2968,36 @@ class JavascriptParser extends Parser {
|
|
2301
2968
|
}
|
2302
2969
|
}
|
2303
2970
|
|
2971
|
+
/**
|
2972
|
+
* @param {AwaitExpression} expression await expression
|
2973
|
+
*/
|
2304
2974
|
walkAwaitExpression(expression) {
|
2305
2975
|
if (this.scope.topLevelScope === true)
|
2306
2976
|
this.hooks.topLevelAwait.call(expression);
|
2307
2977
|
this.walkExpression(expression.argument);
|
2308
2978
|
}
|
2309
2979
|
|
2980
|
+
/**
|
2981
|
+
* @param {ArrayExpression} expression array expression
|
2982
|
+
*/
|
2310
2983
|
walkArrayExpression(expression) {
|
2311
2984
|
if (expression.elements) {
|
2312
2985
|
this.walkExpressions(expression.elements);
|
2313
2986
|
}
|
2314
2987
|
}
|
2315
2988
|
|
2989
|
+
/**
|
2990
|
+
* @param {SpreadElement} expression spread element
|
2991
|
+
*/
|
2316
2992
|
walkSpreadElement(expression) {
|
2317
2993
|
if (expression.argument) {
|
2318
2994
|
this.walkExpression(expression.argument);
|
2319
2995
|
}
|
2320
2996
|
}
|
2321
2997
|
|
2998
|
+
/**
|
2999
|
+
* @param {ObjectExpression} expression object expression
|
3000
|
+
*/
|
2322
3001
|
walkObjectExpression(expression) {
|
2323
3002
|
for (
|
2324
3003
|
let propIndex = 0, len = expression.properties.length;
|
@@ -2330,6 +3009,9 @@ class JavascriptParser extends Parser {
|
|
2330
3009
|
}
|
2331
3010
|
}
|
2332
3011
|
|
3012
|
+
/**
|
3013
|
+
* @param {Property | SpreadElement} prop property or spread element
|
3014
|
+
*/
|
2333
3015
|
walkProperty(prop) {
|
2334
3016
|
if (prop.type === "SpreadElement") {
|
2335
3017
|
this.walkExpression(prop.argument);
|
@@ -2347,14 +3029,17 @@ class JavascriptParser extends Parser {
|
|
2347
3029
|
}
|
2348
3030
|
}
|
2349
3031
|
|
3032
|
+
/**
|
3033
|
+
* @param {FunctionExpression} expression arrow function expression
|
3034
|
+
*/
|
2350
3035
|
walkFunctionExpression(expression) {
|
2351
3036
|
const wasTopLevel = this.scope.topLevelScope;
|
2352
3037
|
this.scope.topLevelScope = false;
|
2353
|
-
const scopeParams = expression.params;
|
3038
|
+
const scopeParams = [...expression.params];
|
2354
3039
|
|
2355
3040
|
// Add function name in scope for recursive calls
|
2356
3041
|
if (expression.id) {
|
2357
|
-
scopeParams.push(expression.id
|
3042
|
+
scopeParams.push(expression.id);
|
2358
3043
|
}
|
2359
3044
|
|
2360
3045
|
this.inFunctionScope(true, scopeParams, () => {
|
@@ -2374,6 +3059,9 @@ class JavascriptParser extends Parser {
|
|
2374
3059
|
this.scope.topLevelScope = wasTopLevel;
|
2375
3060
|
}
|
2376
3061
|
|
3062
|
+
/**
|
3063
|
+
* @param {ArrowFunctionExpression} expression arrow function expression
|
3064
|
+
*/
|
2377
3065
|
walkArrowFunctionExpression(expression) {
|
2378
3066
|
const wasTopLevel = this.scope.topLevelScope;
|
2379
3067
|
this.scope.topLevelScope = wasTopLevel ? "arrow" : false;
|
@@ -2395,7 +3083,7 @@ class JavascriptParser extends Parser {
|
|
2395
3083
|
}
|
2396
3084
|
|
2397
3085
|
/**
|
2398
|
-
* @param {
|
3086
|
+
* @param {SequenceExpression} expression the sequence
|
2399
3087
|
*/
|
2400
3088
|
walkSequenceExpression(expression) {
|
2401
3089
|
if (!expression.expressions) return;
|
@@ -2407,22 +3095,30 @@ class JavascriptParser extends Parser {
|
|
2407
3095
|
(currentStatement.type === "ExpressionStatement" &&
|
2408
3096
|
currentStatement.expression === expression)
|
2409
3097
|
) {
|
2410
|
-
const old = this.statementPath.pop();
|
3098
|
+
const old = /** @type {StatementPathItem} */ (this.statementPath.pop());
|
3099
|
+
const prev = this.prevStatement;
|
2411
3100
|
for (const expr of expression.expressions) {
|
2412
3101
|
this.statementPath.push(expr);
|
2413
3102
|
this.walkExpression(expr);
|
2414
|
-
this.statementPath.pop();
|
3103
|
+
this.prevStatement = this.statementPath.pop();
|
2415
3104
|
}
|
3105
|
+
this.prevStatement = prev;
|
2416
3106
|
this.statementPath.push(old);
|
2417
3107
|
} else {
|
2418
3108
|
this.walkExpressions(expression.expressions);
|
2419
3109
|
}
|
2420
3110
|
}
|
2421
3111
|
|
3112
|
+
/**
|
3113
|
+
* @param {UpdateExpression} expression the update expression
|
3114
|
+
*/
|
2422
3115
|
walkUpdateExpression(expression) {
|
2423
3116
|
this.walkExpression(expression.argument);
|
2424
3117
|
}
|
2425
3118
|
|
3119
|
+
/**
|
3120
|
+
* @param {UnaryExpression} expression the unary expression
|
3121
|
+
*/
|
2426
3122
|
walkUnaryExpression(expression) {
|
2427
3123
|
if (expression.operator === "typeof") {
|
2428
3124
|
const result = this.callHooksForExpression(
|
@@ -2443,52 +3139,65 @@ class JavascriptParser extends Parser {
|
|
2443
3139
|
this.walkExpression(expression.argument);
|
2444
3140
|
}
|
2445
3141
|
|
3142
|
+
/**
|
3143
|
+
* @param {LogicalExpression | BinaryExpression} expression the expression
|
3144
|
+
*/
|
2446
3145
|
walkLeftRightExpression(expression) {
|
2447
3146
|
this.walkExpression(expression.left);
|
2448
3147
|
this.walkExpression(expression.right);
|
2449
3148
|
}
|
2450
3149
|
|
3150
|
+
/**
|
3151
|
+
* @param {BinaryExpression} expression the binary expression
|
3152
|
+
*/
|
2451
3153
|
walkBinaryExpression(expression) {
|
2452
|
-
this.
|
3154
|
+
if (this.hooks.binaryExpression.call(expression) === undefined) {
|
3155
|
+
this.walkLeftRightExpression(expression);
|
3156
|
+
}
|
2453
3157
|
}
|
2454
3158
|
|
3159
|
+
/**
|
3160
|
+
* @param {LogicalExpression} expression the logical expression
|
3161
|
+
*/
|
2455
3162
|
walkLogicalExpression(expression) {
|
2456
3163
|
const result = this.hooks.expressionLogicalOperator.call(expression);
|
2457
3164
|
if (result === undefined) {
|
2458
3165
|
this.walkLeftRightExpression(expression);
|
2459
|
-
} else {
|
2460
|
-
|
2461
|
-
this.walkExpression(expression.right);
|
2462
|
-
}
|
3166
|
+
} else if (result) {
|
3167
|
+
this.walkExpression(expression.right);
|
2463
3168
|
}
|
2464
3169
|
}
|
2465
3170
|
|
3171
|
+
/**
|
3172
|
+
* @param {AssignmentExpression} expression assignment expression
|
3173
|
+
*/
|
2466
3174
|
walkAssignmentExpression(expression) {
|
2467
3175
|
if (expression.left.type === "Identifier") {
|
2468
3176
|
const renameIdentifier = this.getRenameIdentifier(expression.right);
|
2469
|
-
if (
|
3177
|
+
if (
|
3178
|
+
renameIdentifier &&
|
3179
|
+
this.callHooksForInfo(
|
3180
|
+
this.hooks.canRename,
|
3181
|
+
renameIdentifier,
|
3182
|
+
expression.right
|
3183
|
+
)
|
3184
|
+
) {
|
3185
|
+
// renaming "a = b;"
|
2470
3186
|
if (
|
2471
|
-
this.callHooksForInfo(
|
2472
|
-
this.hooks.
|
3187
|
+
!this.callHooksForInfo(
|
3188
|
+
this.hooks.rename,
|
2473
3189
|
renameIdentifier,
|
2474
3190
|
expression.right
|
2475
3191
|
)
|
2476
3192
|
) {
|
2477
|
-
|
2478
|
-
|
2479
|
-
|
2480
|
-
this.
|
2481
|
-
renameIdentifier
|
2482
|
-
|
2483
|
-
)
|
2484
|
-
) {
|
2485
|
-
this.setVariable(
|
2486
|
-
expression.left.name,
|
2487
|
-
this.getVariableInfo(renameIdentifier)
|
2488
|
-
);
|
2489
|
-
}
|
2490
|
-
return;
|
3193
|
+
this.setVariable(
|
3194
|
+
expression.left.name,
|
3195
|
+
typeof renameIdentifier === "string"
|
3196
|
+
? this.getVariableInfo(renameIdentifier)
|
3197
|
+
: renameIdentifier
|
3198
|
+
);
|
2491
3199
|
}
|
3200
|
+
return;
|
2492
3201
|
}
|
2493
3202
|
this.walkExpression(expression.right);
|
2494
3203
|
this.enterPattern(expression.left, (name, decl) => {
|
@@ -2511,17 +3220,16 @@ class JavascriptParser extends Parser {
|
|
2511
3220
|
expression.left,
|
2512
3221
|
ALLOWED_MEMBER_TYPES_EXPRESSION
|
2513
3222
|
);
|
2514
|
-
if (
|
2515
|
-
|
2516
|
-
|
2517
|
-
|
2518
|
-
|
2519
|
-
|
2520
|
-
|
2521
|
-
|
2522
|
-
|
2523
|
-
|
2524
|
-
}
|
3223
|
+
if (
|
3224
|
+
exprName &&
|
3225
|
+
this.callHooksForInfo(
|
3226
|
+
this.hooks.assignMemberChain,
|
3227
|
+
exprName.rootInfo,
|
3228
|
+
expression,
|
3229
|
+
exprName.getMembers()
|
3230
|
+
)
|
3231
|
+
) {
|
3232
|
+
return;
|
2525
3233
|
}
|
2526
3234
|
this.walkExpression(expression.right);
|
2527
3235
|
this.walkExpression(expression.left);
|
@@ -2531,6 +3239,9 @@ class JavascriptParser extends Parser {
|
|
2531
3239
|
}
|
2532
3240
|
}
|
2533
3241
|
|
3242
|
+
/**
|
3243
|
+
* @param {ConditionalExpression} expression conditional expression
|
3244
|
+
*/
|
2534
3245
|
walkConditionalExpression(expression) {
|
2535
3246
|
const result = this.hooks.expressionConditionalOperator.call(expression);
|
2536
3247
|
if (result === undefined) {
|
@@ -2539,15 +3250,16 @@ class JavascriptParser extends Parser {
|
|
2539
3250
|
if (expression.alternate) {
|
2540
3251
|
this.walkExpression(expression.alternate);
|
2541
3252
|
}
|
2542
|
-
} else {
|
2543
|
-
|
2544
|
-
|
2545
|
-
|
2546
|
-
this.walkExpression(expression.alternate);
|
2547
|
-
}
|
3253
|
+
} else if (result) {
|
3254
|
+
this.walkExpression(expression.consequent);
|
3255
|
+
} else if (expression.alternate) {
|
3256
|
+
this.walkExpression(expression.alternate);
|
2548
3257
|
}
|
2549
3258
|
}
|
2550
3259
|
|
3260
|
+
/**
|
3261
|
+
* @param {NewExpression} expression new expression
|
3262
|
+
*/
|
2551
3263
|
walkNewExpression(expression) {
|
2552
3264
|
const result = this.callHooksForExpression(
|
2553
3265
|
this.hooks.new,
|
@@ -2561,33 +3273,47 @@ class JavascriptParser extends Parser {
|
|
2561
3273
|
}
|
2562
3274
|
}
|
2563
3275
|
|
3276
|
+
/**
|
3277
|
+
* @param {YieldExpression} expression yield expression
|
3278
|
+
*/
|
2564
3279
|
walkYieldExpression(expression) {
|
2565
3280
|
if (expression.argument) {
|
2566
3281
|
this.walkExpression(expression.argument);
|
2567
3282
|
}
|
2568
3283
|
}
|
2569
3284
|
|
3285
|
+
/**
|
3286
|
+
* @param {TemplateLiteral} expression template literal
|
3287
|
+
*/
|
2570
3288
|
walkTemplateLiteral(expression) {
|
2571
3289
|
if (expression.expressions) {
|
2572
3290
|
this.walkExpressions(expression.expressions);
|
2573
3291
|
}
|
2574
3292
|
}
|
2575
3293
|
|
3294
|
+
/**
|
3295
|
+
* @param {TaggedTemplateExpression} expression tagged template expression
|
3296
|
+
*/
|
2576
3297
|
walkTaggedTemplateExpression(expression) {
|
2577
3298
|
if (expression.tag) {
|
3299
|
+
this.scope.inTaggedTemplateTag = true;
|
2578
3300
|
this.walkExpression(expression.tag);
|
3301
|
+
this.scope.inTaggedTemplateTag = false;
|
2579
3302
|
}
|
2580
3303
|
if (expression.quasi && expression.quasi.expressions) {
|
2581
3304
|
this.walkExpressions(expression.quasi.expressions);
|
2582
3305
|
}
|
2583
3306
|
}
|
2584
3307
|
|
3308
|
+
/**
|
3309
|
+
* @param {ClassExpression} expression the class expression
|
3310
|
+
*/
|
2585
3311
|
walkClassExpression(expression) {
|
2586
3312
|
this.walkClass(expression);
|
2587
3313
|
}
|
2588
3314
|
|
2589
3315
|
/**
|
2590
|
-
* @param {
|
3316
|
+
* @param {ChainExpression} expression expression
|
2591
3317
|
*/
|
2592
3318
|
walkChainExpression(expression) {
|
2593
3319
|
const result = this.hooks.optionalChaining.call(expression);
|
@@ -2601,27 +3327,33 @@ class JavascriptParser extends Parser {
|
|
2601
3327
|
}
|
2602
3328
|
}
|
2603
3329
|
|
3330
|
+
/**
|
3331
|
+
* @private
|
3332
|
+
* @param {FunctionExpression | ArrowFunctionExpression} functionExpression function expression
|
3333
|
+
* @param {(Expression | SpreadElement)[]} options options
|
3334
|
+
* @param {Expression | SpreadElement | null} currentThis current this
|
3335
|
+
*/
|
2604
3336
|
_walkIIFE(functionExpression, options, currentThis) {
|
3337
|
+
/**
|
3338
|
+
* @param {Expression | SpreadElement} argOrThis arg or this
|
3339
|
+
* @returns {string | VariableInfoInterface | undefined} var info
|
3340
|
+
*/
|
2605
3341
|
const getVarInfo = argOrThis => {
|
2606
|
-
const renameIdentifier = this.getRenameIdentifier(
|
2607
|
-
|
2608
|
-
|
2609
|
-
|
2610
|
-
|
2611
|
-
|
2612
|
-
|
2613
|
-
|
2614
|
-
|
2615
|
-
|
2616
|
-
|
2617
|
-
|
2618
|
-
|
2619
|
-
|
2620
|
-
|
2621
|
-
) {
|
2622
|
-
return this.getVariableInfo(renameIdentifier);
|
2623
|
-
}
|
2624
|
-
}
|
3342
|
+
const renameIdentifier = this.getRenameIdentifier(
|
3343
|
+
/** @type {Expression} */ (argOrThis)
|
3344
|
+
);
|
3345
|
+
if (
|
3346
|
+
renameIdentifier &&
|
3347
|
+
this.callHooksForInfo(
|
3348
|
+
this.hooks.canRename,
|
3349
|
+
renameIdentifier,
|
3350
|
+
argOrThis
|
3351
|
+
) &&
|
3352
|
+
!this.callHooksForInfo(this.hooks.rename, renameIdentifier, argOrThis)
|
3353
|
+
) {
|
3354
|
+
return typeof renameIdentifier === "string"
|
3355
|
+
? /** @type {string} */ (this.getVariableInfo(renameIdentifier))
|
3356
|
+
: renameIdentifier;
|
2625
3357
|
}
|
2626
3358
|
this.walkExpression(argOrThis);
|
2627
3359
|
};
|
@@ -2631,12 +3363,15 @@ class JavascriptParser extends Parser {
|
|
2631
3363
|
const varInfoForArgs = options.map(getVarInfo);
|
2632
3364
|
const wasTopLevel = this.scope.topLevelScope;
|
2633
3365
|
this.scope.topLevelScope = wasTopLevel && arrow ? "arrow" : false;
|
2634
|
-
const scopeParams =
|
2635
|
-
(
|
2636
|
-
|
3366
|
+
const scopeParams =
|
3367
|
+
/** @type {(Identifier | string)[]} */
|
3368
|
+
(params.filter((identifier, idx) => !varInfoForArgs[idx]));
|
2637
3369
|
|
2638
3370
|
// Add function name in scope for recursive calls
|
2639
|
-
if (
|
3371
|
+
if (
|
3372
|
+
functionExpression.type === "FunctionExpression" &&
|
3373
|
+
functionExpression.id
|
3374
|
+
) {
|
2640
3375
|
scopeParams.push(functionExpression.id.name);
|
2641
3376
|
}
|
2642
3377
|
|
@@ -2648,7 +3383,7 @@ class JavascriptParser extends Parser {
|
|
2648
3383
|
const varInfo = varInfoForArgs[i];
|
2649
3384
|
if (!varInfo) continue;
|
2650
3385
|
if (!params[i] || params[i].type !== "Identifier") continue;
|
2651
|
-
this.setVariable(params[i].name, varInfo);
|
3386
|
+
this.setVariable(/** @type {Identifier} */ (params[i]).name, varInfo);
|
2652
3387
|
}
|
2653
3388
|
if (functionExpression.body.type === "BlockStatement") {
|
2654
3389
|
this.detectMode(functionExpression.body.body);
|
@@ -2663,29 +3398,40 @@ class JavascriptParser extends Parser {
|
|
2663
3398
|
this.scope.topLevelScope = wasTopLevel;
|
2664
3399
|
}
|
2665
3400
|
|
3401
|
+
/**
|
3402
|
+
* @param {ImportExpression} expression import expression
|
3403
|
+
*/
|
2666
3404
|
walkImportExpression(expression) {
|
2667
|
-
|
3405
|
+
const result = this.hooks.importCall.call(expression);
|
2668
3406
|
if (result === true) return;
|
2669
3407
|
|
2670
3408
|
this.walkExpression(expression.source);
|
2671
3409
|
}
|
2672
3410
|
|
3411
|
+
/**
|
3412
|
+
* @param {CallExpression} expression expression
|
3413
|
+
*/
|
2673
3414
|
walkCallExpression(expression) {
|
2674
|
-
const isSimpleFunction = fn =>
|
2675
|
-
|
2676
|
-
};
|
3415
|
+
const isSimpleFunction = fn =>
|
3416
|
+
fn.params.every(p => p.type === "Identifier");
|
2677
3417
|
if (
|
2678
3418
|
expression.callee.type === "MemberExpression" &&
|
2679
3419
|
expression.callee.object.type.endsWith("FunctionExpression") &&
|
2680
3420
|
!expression.callee.computed &&
|
3421
|
+
// eslint-disable-next-line no-warning-comments
|
3422
|
+
// @ts-ignore
|
3423
|
+
// TODO check me and handle more cases
|
2681
3424
|
(expression.callee.property.name === "call" ||
|
3425
|
+
// eslint-disable-next-line no-warning-comments
|
3426
|
+
// @ts-ignore
|
2682
3427
|
expression.callee.property.name === "bind") &&
|
2683
3428
|
expression.arguments.length > 0 &&
|
2684
3429
|
isSimpleFunction(expression.callee.object)
|
2685
3430
|
) {
|
2686
3431
|
// (function(…) { }.call/bind(?, …))
|
2687
3432
|
this._walkIIFE(
|
2688
|
-
|
3433
|
+
/** @type {FunctionExpression | ArrowFunctionExpression} */
|
3434
|
+
(expression.callee.object),
|
2689
3435
|
expression.arguments.slice(1),
|
2690
3436
|
expression.arguments[0]
|
2691
3437
|
);
|
@@ -2694,7 +3440,12 @@ class JavascriptParser extends Parser {
|
|
2694
3440
|
isSimpleFunction(expression.callee)
|
2695
3441
|
) {
|
2696
3442
|
// (function(…) { }(…))
|
2697
|
-
this._walkIIFE(
|
3443
|
+
this._walkIIFE(
|
3444
|
+
/** @type {FunctionExpression | ArrowFunctionExpression} */
|
3445
|
+
(expression.callee),
|
3446
|
+
expression.arguments,
|
3447
|
+
null
|
3448
|
+
);
|
2698
3449
|
} else {
|
2699
3450
|
if (expression.callee.type === "MemberExpression") {
|
2700
3451
|
const exprInfo = this.getMemberExpressionInfo(
|
@@ -2708,18 +3459,25 @@ class JavascriptParser extends Parser {
|
|
2708
3459
|
expression,
|
2709
3460
|
exprInfo.getCalleeMembers(),
|
2710
3461
|
exprInfo.call,
|
2711
|
-
exprInfo.getMembers()
|
3462
|
+
exprInfo.getMembers(),
|
3463
|
+
exprInfo.getMemberRanges()
|
2712
3464
|
);
|
2713
3465
|
if (result === true) return;
|
2714
3466
|
}
|
2715
3467
|
}
|
2716
|
-
const callee = this.evaluateExpression(
|
3468
|
+
const callee = this.evaluateExpression(
|
3469
|
+
/** @type {TODO} */ (expression.callee)
|
3470
|
+
);
|
2717
3471
|
if (callee.isIdentifier()) {
|
2718
3472
|
const result1 = this.callHooksForInfo(
|
2719
3473
|
this.hooks.callMemberChain,
|
2720
3474
|
callee.rootInfo,
|
2721
3475
|
expression,
|
2722
|
-
callee.getMembers()
|
3476
|
+
callee.getMembers(),
|
3477
|
+
callee.getMembersOptionals
|
3478
|
+
? callee.getMembersOptionals()
|
3479
|
+
: callee.getMembers().map(() => false),
|
3480
|
+
callee.getMemberRanges ? callee.getMemberRanges() : []
|
2723
3481
|
);
|
2724
3482
|
if (result1 === true) return;
|
2725
3483
|
const result2 = this.callHooksForInfo(
|
@@ -2744,6 +3502,9 @@ class JavascriptParser extends Parser {
|
|
2744
3502
|
}
|
2745
3503
|
}
|
2746
3504
|
|
3505
|
+
/**
|
3506
|
+
* @param {MemberExpression} expression member expression
|
3507
|
+
*/
|
2747
3508
|
walkMemberExpression(expression) {
|
2748
3509
|
const exprInfo = this.getMemberExpressionInfo(
|
2749
3510
|
expression,
|
@@ -2759,11 +3520,15 @@ class JavascriptParser extends Parser {
|
|
2759
3520
|
);
|
2760
3521
|
if (result1 === true) return;
|
2761
3522
|
const members = exprInfo.getMembers();
|
3523
|
+
const membersOptionals = exprInfo.getMembersOptionals();
|
3524
|
+
const memberRanges = exprInfo.getMemberRanges();
|
2762
3525
|
const result2 = this.callHooksForInfo(
|
2763
3526
|
this.hooks.expressionMemberChain,
|
2764
3527
|
exprInfo.rootInfo,
|
2765
3528
|
expression,
|
2766
|
-
members
|
3529
|
+
members,
|
3530
|
+
membersOptionals,
|
3531
|
+
memberRanges
|
2767
3532
|
);
|
2768
3533
|
if (result2 === true) return;
|
2769
3534
|
this.walkMemberExpressionWithExpressionName(
|
@@ -2788,7 +3553,8 @@ class JavascriptParser extends Parser {
|
|
2788
3553
|
expression,
|
2789
3554
|
exprInfo.getCalleeMembers(),
|
2790
3555
|
exprInfo.call,
|
2791
|
-
exprInfo.getMembers()
|
3556
|
+
exprInfo.getMembers(),
|
3557
|
+
exprInfo.getMemberRanges()
|
2792
3558
|
);
|
2793
3559
|
if (result === true) return;
|
2794
3560
|
// Fast skip over the member chain as we already called memberChainOfCallMemberChain
|
@@ -2802,6 +3568,13 @@ class JavascriptParser extends Parser {
|
|
2802
3568
|
if (expression.computed === true) this.walkExpression(expression.property);
|
2803
3569
|
}
|
2804
3570
|
|
3571
|
+
/**
|
3572
|
+
* @param {TODO} expression member expression
|
3573
|
+
* @param {string} name name
|
3574
|
+
* @param {string | VariableInfo} rootInfo root info
|
3575
|
+
* @param {string[]} members members
|
3576
|
+
* @param {TODO} onUnhandled on unhandled callback
|
3577
|
+
*/
|
2805
3578
|
walkMemberExpressionWithExpressionName(
|
2806
3579
|
expression,
|
2807
3580
|
name,
|
@@ -2835,21 +3608,35 @@ class JavascriptParser extends Parser {
|
|
2835
3608
|
if (expression.computed === true) this.walkExpression(expression.property);
|
2836
3609
|
}
|
2837
3610
|
|
3611
|
+
/**
|
3612
|
+
* @param {ThisExpression} expression this expression
|
3613
|
+
*/
|
2838
3614
|
walkThisExpression(expression) {
|
2839
3615
|
this.callHooksForName(this.hooks.expression, "this", expression);
|
2840
3616
|
}
|
2841
3617
|
|
3618
|
+
/**
|
3619
|
+
* @param {Identifier} expression identifier
|
3620
|
+
*/
|
2842
3621
|
walkIdentifier(expression) {
|
2843
3622
|
this.callHooksForName(this.hooks.expression, expression.name, expression);
|
2844
3623
|
}
|
2845
3624
|
|
2846
3625
|
/**
|
2847
|
-
* @param {
|
3626
|
+
* @param {MetaProperty} metaProperty meta property
|
2848
3627
|
*/
|
2849
3628
|
walkMetaProperty(metaProperty) {
|
2850
3629
|
this.hooks.expression.for(getRootName(metaProperty)).call(metaProperty);
|
2851
3630
|
}
|
2852
3631
|
|
3632
|
+
/**
|
3633
|
+
* @template T
|
3634
|
+
* @template R
|
3635
|
+
* @param {HookMap<SyncBailHook<T, R>>} hookMap hooks the should be called
|
3636
|
+
* @param {TODO} expr expression
|
3637
|
+
* @param {AsArray<T>} args args for the hook
|
3638
|
+
* @returns {R | undefined} result of hook
|
3639
|
+
*/
|
2853
3640
|
callHooksForExpression(hookMap, expr, ...args) {
|
2854
3641
|
return this.callHooksForExpressionWithFallback(
|
2855
3642
|
hookMap,
|
@@ -2864,11 +3651,11 @@ class JavascriptParser extends Parser {
|
|
2864
3651
|
* @template T
|
2865
3652
|
* @template R
|
2866
3653
|
* @param {HookMap<SyncBailHook<T, R>>} hookMap hooks the should be called
|
2867
|
-
* @param {
|
2868
|
-
* @param {function(string, string | ScopeInfo | VariableInfo, function(): string[]): any} fallback callback when variable in not handled by hooks
|
2869
|
-
* @param {function(string): any} defined callback when variable is defined
|
3654
|
+
* @param {MemberExpression} expr expression info
|
3655
|
+
* @param {(function(string, string | ScopeInfo | VariableInfo, function(): string[]): any) | undefined} fallback callback when variable in not handled by hooks
|
3656
|
+
* @param {(function(string): any) | undefined} defined callback when variable is defined
|
2870
3657
|
* @param {AsArray<T>} args args for the hook
|
2871
|
-
* @returns {R} result of hook
|
3658
|
+
* @returns {R | undefined} result of hook
|
2872
3659
|
*/
|
2873
3660
|
callHooksForExpressionWithFallback(
|
2874
3661
|
hookMap,
|
@@ -2900,7 +3687,7 @@ class JavascriptParser extends Parser {
|
|
2900
3687
|
* @param {HookMap<SyncBailHook<T, R>>} hookMap hooks the should be called
|
2901
3688
|
* @param {string} name key in map
|
2902
3689
|
* @param {AsArray<T>} args args for the hook
|
2903
|
-
* @returns {R} result of hook
|
3690
|
+
* @returns {R | undefined} result of hook
|
2904
3691
|
*/
|
2905
3692
|
callHooksForName(hookMap, name, ...args) {
|
2906
3693
|
return this.callHooksForNameWithFallback(
|
@@ -2918,7 +3705,7 @@ class JavascriptParser extends Parser {
|
|
2918
3705
|
* @param {HookMap<SyncBailHook<T, R>>} hookMap hooks that should be called
|
2919
3706
|
* @param {ExportedVariableInfo} info variable info
|
2920
3707
|
* @param {AsArray<T>} args args for the hook
|
2921
|
-
* @returns {R} result of hook
|
3708
|
+
* @returns {R | undefined} result of hook
|
2922
3709
|
*/
|
2923
3710
|
callHooksForInfo(hookMap, info, ...args) {
|
2924
3711
|
return this.callHooksForInfoWithFallback(
|
@@ -2935,10 +3722,10 @@ class JavascriptParser extends Parser {
|
|
2935
3722
|
* @template R
|
2936
3723
|
* @param {HookMap<SyncBailHook<T, R>>} hookMap hooks the should be called
|
2937
3724
|
* @param {ExportedVariableInfo} info variable info
|
2938
|
-
* @param {function(string): any} fallback callback when variable in not handled by hooks
|
2939
|
-
* @param {function(): any} defined callback when variable is defined
|
3725
|
+
* @param {(function(string): any) | undefined} fallback callback when variable in not handled by hooks
|
3726
|
+
* @param {(function(): any) | undefined} defined callback when variable is defined
|
2940
3727
|
* @param {AsArray<T>} args args for the hook
|
2941
|
-
* @returns {R} result of hook
|
3728
|
+
* @returns {R | undefined} result of hook
|
2942
3729
|
*/
|
2943
3730
|
callHooksForInfoWithFallback(hookMap, info, fallback, defined, ...args) {
|
2944
3731
|
let name;
|
@@ -2985,10 +3772,10 @@ class JavascriptParser extends Parser {
|
|
2985
3772
|
* @template R
|
2986
3773
|
* @param {HookMap<SyncBailHook<T, R>>} hookMap hooks the should be called
|
2987
3774
|
* @param {string} name key in map
|
2988
|
-
* @param {function(string): any} fallback callback when variable in not handled by hooks
|
2989
|
-
* @param {function(): any} defined callback when variable is defined
|
3775
|
+
* @param {(function(string): any) | undefined} fallback callback when variable in not handled by hooks
|
3776
|
+
* @param {(function(): any) | undefined} defined callback when variable is defined
|
2990
3777
|
* @param {AsArray<T>} args args for the hook
|
2991
|
-
* @returns {R} result of hook
|
3778
|
+
* @returns {R | undefined} result of hook
|
2992
3779
|
*/
|
2993
3780
|
callHooksForNameWithFallback(hookMap, name, fallback, defined, ...args) {
|
2994
3781
|
return this.callHooksForInfoWithFallback(
|
@@ -3012,6 +3799,7 @@ class JavascriptParser extends Parser {
|
|
3012
3799
|
topLevelScope: oldScope.topLevelScope,
|
3013
3800
|
inTry: false,
|
3014
3801
|
inShorthand: false,
|
3802
|
+
inTaggedTemplateTag: false,
|
3015
3803
|
isStrict: oldScope.isStrict,
|
3016
3804
|
isAsmJs: oldScope.isAsmJs,
|
3017
3805
|
definitions: oldScope.definitions.createChild()
|
@@ -3028,12 +3816,50 @@ class JavascriptParser extends Parser {
|
|
3028
3816
|
this.scope = oldScope;
|
3029
3817
|
}
|
3030
3818
|
|
3819
|
+
/**
|
3820
|
+
* @param {boolean} hasThis true, when this is defined
|
3821
|
+
* @param {any} params scope params
|
3822
|
+
* @param {function(): void} fn inner function
|
3823
|
+
* @returns {void}
|
3824
|
+
*/
|
3825
|
+
inClassScope(hasThis, params, fn) {
|
3826
|
+
const oldScope = this.scope;
|
3827
|
+
this.scope = {
|
3828
|
+
topLevelScope: oldScope.topLevelScope,
|
3829
|
+
inTry: false,
|
3830
|
+
inShorthand: false,
|
3831
|
+
inTaggedTemplateTag: false,
|
3832
|
+
isStrict: oldScope.isStrict,
|
3833
|
+
isAsmJs: oldScope.isAsmJs,
|
3834
|
+
definitions: oldScope.definitions.createChild()
|
3835
|
+
};
|
3836
|
+
|
3837
|
+
if (hasThis) {
|
3838
|
+
this.undefineVariable("this");
|
3839
|
+
}
|
3840
|
+
|
3841
|
+
this.enterPatterns(params, (ident, pattern) => {
|
3842
|
+
this.defineVariable(ident);
|
3843
|
+
});
|
3844
|
+
|
3845
|
+
fn();
|
3846
|
+
|
3847
|
+
this.scope = oldScope;
|
3848
|
+
}
|
3849
|
+
|
3850
|
+
/**
|
3851
|
+
* @param {boolean} hasThis true, when this is defined
|
3852
|
+
* @param {any} params scope params
|
3853
|
+
* @param {function(): void} fn inner function
|
3854
|
+
* @returns {void}
|
3855
|
+
*/
|
3031
3856
|
inFunctionScope(hasThis, params, fn) {
|
3032
3857
|
const oldScope = this.scope;
|
3033
3858
|
this.scope = {
|
3034
3859
|
topLevelScope: oldScope.topLevelScope,
|
3035
3860
|
inTry: false,
|
3036
3861
|
inShorthand: false,
|
3862
|
+
inTaggedTemplateTag: false,
|
3037
3863
|
isStrict: oldScope.isStrict,
|
3038
3864
|
isAsmJs: oldScope.isAsmJs,
|
3039
3865
|
definitions: oldScope.definitions.createChild()
|
@@ -3052,12 +3878,17 @@ class JavascriptParser extends Parser {
|
|
3052
3878
|
this.scope = oldScope;
|
3053
3879
|
}
|
3054
3880
|
|
3881
|
+
/**
|
3882
|
+
* @param {function(): void} fn inner function
|
3883
|
+
* @returns {void}
|
3884
|
+
*/
|
3055
3885
|
inBlockScope(fn) {
|
3056
3886
|
const oldScope = this.scope;
|
3057
3887
|
this.scope = {
|
3058
3888
|
topLevelScope: oldScope.topLevelScope,
|
3059
3889
|
inTry: oldScope.inTry,
|
3060
3890
|
inShorthand: false,
|
3891
|
+
inTaggedTemplateTag: false,
|
3061
3892
|
isStrict: oldScope.isStrict,
|
3062
3893
|
isAsmJs: oldScope.isAsmJs,
|
3063
3894
|
definitions: oldScope.definitions.createChild()
|
@@ -3068,19 +3899,36 @@ class JavascriptParser extends Parser {
|
|
3068
3899
|
this.scope = oldScope;
|
3069
3900
|
}
|
3070
3901
|
|
3902
|
+
/**
|
3903
|
+
* @param {Array<Directive | Statement | ModuleDeclaration>} statements statements
|
3904
|
+
*/
|
3071
3905
|
detectMode(statements) {
|
3072
3906
|
const isLiteral =
|
3073
3907
|
statements.length >= 1 &&
|
3074
3908
|
statements[0].type === "ExpressionStatement" &&
|
3075
3909
|
statements[0].expression.type === "Literal";
|
3076
|
-
if (
|
3910
|
+
if (
|
3911
|
+
isLiteral &&
|
3912
|
+
/** @type {Literal} */
|
3913
|
+
(/** @type {ExpressionStatement} */ (statements[0]).expression).value ===
|
3914
|
+
"use strict"
|
3915
|
+
) {
|
3077
3916
|
this.scope.isStrict = true;
|
3078
3917
|
}
|
3079
|
-
if (
|
3918
|
+
if (
|
3919
|
+
isLiteral &&
|
3920
|
+
/** @type {Literal} */
|
3921
|
+
(/** @type {ExpressionStatement} */ (statements[0]).expression).value ===
|
3922
|
+
"use asm"
|
3923
|
+
) {
|
3080
3924
|
this.scope.isAsmJs = true;
|
3081
3925
|
}
|
3082
3926
|
}
|
3083
3927
|
|
3928
|
+
/**
|
3929
|
+
* @param {(string | Pattern | Property)[]} patterns patterns
|
3930
|
+
* @param {OnIdent} onIdent on ident callback
|
3931
|
+
*/
|
3084
3932
|
enterPatterns(patterns, onIdent) {
|
3085
3933
|
for (const pattern of patterns) {
|
3086
3934
|
if (typeof pattern !== "string") {
|
@@ -3091,6 +3939,10 @@ class JavascriptParser extends Parser {
|
|
3091
3939
|
}
|
3092
3940
|
}
|
3093
3941
|
|
3942
|
+
/**
|
3943
|
+
* @param {Pattern | Property} pattern pattern
|
3944
|
+
* @param {OnIdent} onIdent on ident callback
|
3945
|
+
*/
|
3094
3946
|
enterPattern(pattern, onIdent) {
|
3095
3947
|
if (!pattern) return;
|
3096
3948
|
switch (pattern.type) {
|
@@ -3115,18 +3967,26 @@ class JavascriptParser extends Parser {
|
|
3115
3967
|
this.enterIdentifier(pattern.value, onIdent);
|
3116
3968
|
this.scope.inShorthand = false;
|
3117
3969
|
} else {
|
3118
|
-
this.enterPattern(pattern.value, onIdent);
|
3970
|
+
this.enterPattern(/** @type {Identifier} */ (pattern.value), onIdent);
|
3119
3971
|
}
|
3120
3972
|
break;
|
3121
3973
|
}
|
3122
3974
|
}
|
3123
3975
|
|
3976
|
+
/**
|
3977
|
+
* @param {Identifier} pattern identifier pattern
|
3978
|
+
* @param {OnIdent} onIdent callback
|
3979
|
+
*/
|
3124
3980
|
enterIdentifier(pattern, onIdent) {
|
3125
3981
|
if (!this.callHooksForName(this.hooks.pattern, pattern.name, pattern)) {
|
3126
3982
|
onIdent(pattern.name, pattern);
|
3127
3983
|
}
|
3128
3984
|
}
|
3129
3985
|
|
3986
|
+
/**
|
3987
|
+
* @param {ObjectPattern} pattern object pattern
|
3988
|
+
* @param {OnIdent} onIdent callback
|
3989
|
+
*/
|
3130
3990
|
enterObjectPattern(pattern, onIdent) {
|
3131
3991
|
for (
|
3132
3992
|
let propIndex = 0, len = pattern.properties.length;
|
@@ -3138,6 +3998,10 @@ class JavascriptParser extends Parser {
|
|
3138
3998
|
}
|
3139
3999
|
}
|
3140
4000
|
|
4001
|
+
/**
|
4002
|
+
* @param {ArrayPattern} pattern object pattern
|
4003
|
+
* @param {OnIdent} onIdent callback
|
4004
|
+
*/
|
3141
4005
|
enterArrayPattern(pattern, onIdent) {
|
3142
4006
|
for (
|
3143
4007
|
let elementIndex = 0, len = pattern.elements.length;
|
@@ -3145,43 +4009,56 @@ class JavascriptParser extends Parser {
|
|
3145
4009
|
elementIndex++
|
3146
4010
|
) {
|
3147
4011
|
const element = pattern.elements[elementIndex];
|
3148
|
-
|
4012
|
+
|
4013
|
+
if (element) {
|
4014
|
+
this.enterPattern(element, onIdent);
|
4015
|
+
}
|
3149
4016
|
}
|
3150
4017
|
}
|
3151
4018
|
|
4019
|
+
/**
|
4020
|
+
* @param {RestElement} pattern object pattern
|
4021
|
+
* @param {OnIdent} onIdent callback
|
4022
|
+
*/
|
3152
4023
|
enterRestElement(pattern, onIdent) {
|
3153
4024
|
this.enterPattern(pattern.argument, onIdent);
|
3154
4025
|
}
|
3155
4026
|
|
4027
|
+
/**
|
4028
|
+
* @param {AssignmentPattern} pattern object pattern
|
4029
|
+
* @param {OnIdent} onIdent callback
|
4030
|
+
*/
|
3156
4031
|
enterAssignmentPattern(pattern, onIdent) {
|
3157
4032
|
this.enterPattern(pattern.left, onIdent);
|
3158
4033
|
}
|
3159
4034
|
|
3160
4035
|
/**
|
3161
|
-
* @param {
|
3162
|
-
* @returns {BasicEvaluatedExpression
|
4036
|
+
* @param {Expression | SpreadElement} expression expression node
|
4037
|
+
* @returns {BasicEvaluatedExpression} evaluation result
|
3163
4038
|
*/
|
3164
4039
|
evaluateExpression(expression) {
|
3165
4040
|
try {
|
3166
4041
|
const hook = this.hooks.evaluate.get(expression.type);
|
3167
4042
|
if (hook !== undefined) {
|
3168
4043
|
const result = hook.call(expression);
|
3169
|
-
if (result !== undefined) {
|
3170
|
-
|
3171
|
-
result.setExpression(expression);
|
3172
|
-
}
|
4044
|
+
if (result !== undefined && result !== null) {
|
4045
|
+
result.setExpression(expression);
|
3173
4046
|
return result;
|
3174
4047
|
}
|
3175
4048
|
}
|
3176
|
-
} catch (
|
3177
|
-
console.warn(
|
4049
|
+
} catch (err) {
|
4050
|
+
console.warn(err);
|
3178
4051
|
// ignore error
|
3179
4052
|
}
|
3180
4053
|
return new BasicEvaluatedExpression()
|
3181
|
-
.setRange(expression.range)
|
4054
|
+
.setRange(/** @type {Range} */ (expression.range))
|
3182
4055
|
.setExpression(expression);
|
3183
4056
|
}
|
3184
4057
|
|
4058
|
+
/**
|
4059
|
+
* @param {Expression} expression expression
|
4060
|
+
* @returns {string} parsed string
|
4061
|
+
*/
|
3185
4062
|
parseString(expression) {
|
3186
4063
|
switch (expression.type) {
|
3187
4064
|
case "BinaryExpression":
|
@@ -3193,13 +4070,17 @@ class JavascriptParser extends Parser {
|
|
3193
4070
|
}
|
3194
4071
|
break;
|
3195
4072
|
case "Literal":
|
3196
|
-
return expression.value
|
4073
|
+
return String(expression.value);
|
3197
4074
|
}
|
3198
4075
|
throw new Error(
|
3199
|
-
expression.type
|
4076
|
+
`${expression.type} is not supported as parameter for require`
|
3200
4077
|
);
|
3201
4078
|
}
|
3202
4079
|
|
4080
|
+
/**
|
4081
|
+
* @param {Expression} expression expression
|
4082
|
+
* @returns {TODO} result
|
4083
|
+
*/
|
3203
4084
|
parseCalculatedString(expression) {
|
3204
4085
|
switch (expression.type) {
|
3205
4086
|
case "BinaryExpression":
|
@@ -3223,14 +4104,13 @@ class JavascriptParser extends Parser {
|
|
3223
4104
|
code: true,
|
3224
4105
|
conditional: false
|
3225
4106
|
};
|
3226
|
-
} else {
|
3227
|
-
return {
|
3228
|
-
range: [left.range[0], right.range[1]],
|
3229
|
-
value: left.value + right.value,
|
3230
|
-
code: false,
|
3231
|
-
conditional: false
|
3232
|
-
};
|
3233
4107
|
}
|
4108
|
+
return {
|
4109
|
+
range: [left.range[0], right.range[1]],
|
4110
|
+
value: left.value + right.value,
|
4111
|
+
code: false,
|
4112
|
+
conditional: false
|
4113
|
+
};
|
3234
4114
|
}
|
3235
4115
|
break;
|
3236
4116
|
case "ConditionalExpression": {
|
@@ -3261,7 +4141,7 @@ class JavascriptParser extends Parser {
|
|
3261
4141
|
case "Literal":
|
3262
4142
|
return {
|
3263
4143
|
range: expression.range,
|
3264
|
-
value: expression.value
|
4144
|
+
value: String(expression.value),
|
3265
4145
|
code: false,
|
3266
4146
|
conditional: false
|
3267
4147
|
};
|
@@ -3290,7 +4170,7 @@ class JavascriptParser extends Parser {
|
|
3290
4170
|
source = source.toString("utf-8");
|
3291
4171
|
}
|
3292
4172
|
if (typeof source === "object") {
|
3293
|
-
ast = /** @type {
|
4173
|
+
ast = /** @type {Program} */ (source);
|
3294
4174
|
comments = source.comments;
|
3295
4175
|
} else {
|
3296
4176
|
comments = [];
|
@@ -3311,6 +4191,7 @@ class JavascriptParser extends Parser {
|
|
3311
4191
|
topLevelScope: true,
|
3312
4192
|
inTry: false,
|
3313
4193
|
inShorthand: false,
|
4194
|
+
inTaggedTemplateTag: false,
|
3314
4195
|
isStrict: false,
|
3315
4196
|
isAsmJs: false,
|
3316
4197
|
definitions: new StackedMap()
|
@@ -3322,12 +4203,14 @@ class JavascriptParser extends Parser {
|
|
3322
4203
|
this.statementPath = [];
|
3323
4204
|
this.prevStatement = undefined;
|
3324
4205
|
if (this.hooks.program.call(ast, comments) === undefined) {
|
4206
|
+
this.destructuringAssignmentProperties = new WeakMap();
|
3325
4207
|
this.detectMode(ast.body);
|
3326
4208
|
this.preWalkStatements(ast.body);
|
3327
4209
|
this.prevStatement = undefined;
|
3328
4210
|
this.blockPreWalkStatements(ast.body);
|
3329
4211
|
this.prevStatement = undefined;
|
3330
4212
|
this.walkStatements(ast.body);
|
4213
|
+
this.destructuringAssignmentProperties = undefined;
|
3331
4214
|
}
|
3332
4215
|
this.hooks.finish.call(ast, comments);
|
3333
4216
|
this.scope = oldScope;
|
@@ -3340,8 +4223,12 @@ class JavascriptParser extends Parser {
|
|
3340
4223
|
return state;
|
3341
4224
|
}
|
3342
4225
|
|
4226
|
+
/**
|
4227
|
+
* @param {string} source source code
|
4228
|
+
* @returns {BasicEvaluatedExpression} evaluation result
|
4229
|
+
*/
|
3343
4230
|
evaluate(source) {
|
3344
|
-
const ast = JavascriptParser._parse(
|
4231
|
+
const ast = JavascriptParser._parse(`(${source})`, {
|
3345
4232
|
sourceType: this.sourceType,
|
3346
4233
|
locations: false
|
3347
4234
|
});
|
@@ -3352,7 +4239,7 @@ class JavascriptParser extends Parser {
|
|
3352
4239
|
}
|
3353
4240
|
|
3354
4241
|
/**
|
3355
|
-
* @param {
|
4242
|
+
* @param {Expression | Declaration | PrivateIdentifier | null | undefined} expr an expression
|
3356
4243
|
* @param {number} commentsStartPos source position from which annotation comments are checked
|
3357
4244
|
* @returns {boolean} true, when the expression is pure
|
3358
4245
|
*/
|
@@ -3363,70 +4250,113 @@ class JavascriptParser extends Parser {
|
|
3363
4250
|
.call(expr, commentsStartPos);
|
3364
4251
|
if (typeof result === "boolean") return result;
|
3365
4252
|
switch (expr.type) {
|
4253
|
+
// TODO handle more cases
|
3366
4254
|
case "ClassDeclaration":
|
3367
4255
|
case "ClassExpression": {
|
3368
4256
|
if (expr.body.type !== "ClassBody") return false;
|
3369
|
-
if (
|
4257
|
+
if (
|
4258
|
+
expr.superClass &&
|
4259
|
+
!this.isPure(expr.superClass, /** @type {Range} */ (expr.range)[0])
|
4260
|
+
) {
|
3370
4261
|
return false;
|
3371
4262
|
}
|
3372
4263
|
const items =
|
3373
|
-
/** @type {
|
3374
|
-
|
3375
|
-
|
3376
|
-
|
3377
|
-
|
3378
|
-
|
3379
|
-
|
3380
|
-
|
3381
|
-
|
3382
|
-
|
3383
|
-
|
3384
|
-
|
3385
|
-
|
3386
|
-
|
3387
|
-
|
4264
|
+
/** @type {TODO[]} */
|
4265
|
+
(expr.body.body);
|
4266
|
+
return items.every(item => {
|
4267
|
+
if (
|
4268
|
+
item.computed &&
|
4269
|
+
item.key &&
|
4270
|
+
!this.isPure(item.key, item.range[0])
|
4271
|
+
) {
|
4272
|
+
return false;
|
4273
|
+
}
|
4274
|
+
|
4275
|
+
if (
|
4276
|
+
item.static &&
|
4277
|
+
item.value &&
|
4278
|
+
!this.isPure(
|
4279
|
+
item.value,
|
4280
|
+
item.key ? item.key.range[1] : item.range[0]
|
4281
|
+
)
|
4282
|
+
) {
|
4283
|
+
return false;
|
4284
|
+
}
|
4285
|
+
|
4286
|
+
if (item.type === "StaticBlock") {
|
4287
|
+
return false;
|
4288
|
+
}
|
4289
|
+
|
4290
|
+
if (
|
4291
|
+
expr.superClass &&
|
4292
|
+
item.type === "MethodDefinition" &&
|
4293
|
+
item.kind === "constructor"
|
4294
|
+
) {
|
4295
|
+
return false;
|
4296
|
+
}
|
4297
|
+
|
4298
|
+
return true;
|
4299
|
+
});
|
3388
4300
|
}
|
3389
4301
|
|
3390
4302
|
case "FunctionDeclaration":
|
3391
4303
|
case "FunctionExpression":
|
3392
4304
|
case "ArrowFunctionExpression":
|
4305
|
+
case "ThisExpression":
|
3393
4306
|
case "Literal":
|
4307
|
+
case "TemplateLiteral":
|
4308
|
+
case "Identifier":
|
3394
4309
|
case "PrivateIdentifier":
|
3395
4310
|
return true;
|
3396
4311
|
|
3397
4312
|
case "VariableDeclaration":
|
3398
4313
|
return expr.declarations.every(decl =>
|
3399
|
-
this.isPure(decl.init, decl.range[0])
|
4314
|
+
this.isPure(decl.init, /** @type {Range} */ (decl.range)[0])
|
3400
4315
|
);
|
3401
4316
|
|
3402
4317
|
case "ConditionalExpression":
|
3403
4318
|
return (
|
3404
4319
|
this.isPure(expr.test, commentsStartPos) &&
|
3405
|
-
this.isPure(
|
3406
|
-
|
4320
|
+
this.isPure(
|
4321
|
+
expr.consequent,
|
4322
|
+
/** @type {Range} */ (expr.test.range)[1]
|
4323
|
+
) &&
|
4324
|
+
this.isPure(
|
4325
|
+
expr.alternate,
|
4326
|
+
/** @type {Range} */ (expr.consequent.range)[1]
|
4327
|
+
)
|
4328
|
+
);
|
4329
|
+
|
4330
|
+
case "LogicalExpression":
|
4331
|
+
return (
|
4332
|
+
this.isPure(expr.left, commentsStartPos) &&
|
4333
|
+
this.isPure(expr.right, /** @type {Range} */ (expr.left.range)[1])
|
3407
4334
|
);
|
3408
4335
|
|
3409
4336
|
case "SequenceExpression":
|
3410
4337
|
return expr.expressions.every(expr => {
|
3411
4338
|
const pureFlag = this.isPure(expr, commentsStartPos);
|
3412
|
-
commentsStartPos = expr.range[1];
|
4339
|
+
commentsStartPos = /** @type {Range} */ (expr.range)[1];
|
3413
4340
|
return pureFlag;
|
3414
4341
|
});
|
3415
4342
|
|
3416
4343
|
case "CallExpression": {
|
3417
4344
|
const pureFlag =
|
3418
|
-
expr.range[0] - commentsStartPos > 12 &&
|
3419
|
-
this.getComments([
|
4345
|
+
/** @type {Range} */ (expr.range)[0] - commentsStartPos > 12 &&
|
4346
|
+
this.getComments([
|
4347
|
+
commentsStartPos,
|
4348
|
+
/** @type {Range} */ (expr.range)[0]
|
4349
|
+
]).some(
|
3420
4350
|
comment =>
|
3421
4351
|
comment.type === "Block" &&
|
3422
4352
|
/^\s*(#|@)__PURE__\s*$/.test(comment.value)
|
3423
4353
|
);
|
3424
4354
|
if (!pureFlag) return false;
|
3425
|
-
commentsStartPos = expr.callee.range[1];
|
4355
|
+
commentsStartPos = /** @type {Range} */ (expr.callee.range)[1];
|
3426
4356
|
return expr.arguments.every(arg => {
|
3427
4357
|
if (arg.type === "SpreadElement") return false;
|
3428
4358
|
const pureFlag = this.isPure(arg, commentsStartPos);
|
3429
|
-
commentsStartPos = arg.range[1];
|
4359
|
+
commentsStartPos = /** @type {Range} */ (arg.range)[1];
|
3430
4360
|
return pureFlag;
|
3431
4361
|
});
|
3432
4362
|
}
|
@@ -3435,13 +4365,28 @@ class JavascriptParser extends Parser {
|
|
3435
4365
|
return !evaluated.couldHaveSideEffects();
|
3436
4366
|
}
|
3437
4367
|
|
4368
|
+
/**
|
4369
|
+
* @param {Range} range range
|
4370
|
+
* @returns {Comment[]} comments in the range
|
4371
|
+
*/
|
3438
4372
|
getComments(range) {
|
3439
4373
|
const [rangeStart, rangeEnd] = range;
|
3440
|
-
|
3441
|
-
|
3442
|
-
|
3443
|
-
|
3444
|
-
|
4374
|
+
/**
|
4375
|
+
* @param {Comment} comment comment
|
4376
|
+
* @param {number} needle needle
|
4377
|
+
* @returns {number} compared
|
4378
|
+
*/
|
4379
|
+
const compare = (comment, needle) =>
|
4380
|
+
/** @type {Range} */ (comment.range)[0] - needle;
|
4381
|
+
const comments = /** @type {Comment[]} */ (this.comments);
|
4382
|
+
let idx = binarySearchBounds.ge(comments, rangeStart, compare);
|
4383
|
+
/** @type {Comment[]} */
|
4384
|
+
const commentsInRange = [];
|
4385
|
+
while (
|
4386
|
+
comments[idx] &&
|
4387
|
+
/** @type {Range} */ (comments[idx].range)[1] <= rangeEnd
|
4388
|
+
) {
|
4389
|
+
commentsInRange.push(comments[idx]);
|
3445
4390
|
idx++;
|
3446
4391
|
}
|
3447
4392
|
|
@@ -3457,25 +4402,40 @@ class JavascriptParser extends Parser {
|
|
3457
4402
|
if (currentStatement === undefined) throw new Error("Not in statement");
|
3458
4403
|
return (
|
3459
4404
|
// Either asking directly for the end position of the current statement
|
3460
|
-
(currentStatement.range[1] === pos &&
|
4405
|
+
(currentStatement.range[1] === pos &&
|
4406
|
+
/** @type {Set<number>} */ (this.semicolons).has(pos)) ||
|
3461
4407
|
// Or asking for the start position of the current statement,
|
3462
4408
|
// here we have to check multiple things
|
3463
4409
|
(currentStatement.range[0] === pos &&
|
3464
4410
|
// is there a previous statement which might be relevant?
|
3465
4411
|
this.prevStatement !== undefined &&
|
3466
4412
|
// is the end position of the previous statement an ASI position?
|
3467
|
-
this.semicolons.has(
|
4413
|
+
/** @type {Set<number>} */ (this.semicolons).has(
|
4414
|
+
this.prevStatement.range[1]
|
4415
|
+
))
|
3468
4416
|
);
|
3469
4417
|
}
|
3470
4418
|
|
4419
|
+
/**
|
4420
|
+
* @param {number} pos source code position
|
4421
|
+
* @returns {void}
|
4422
|
+
*/
|
4423
|
+
setAsiPosition(pos) {
|
4424
|
+
/** @type {Set<number>} */ (this.semicolons).add(pos);
|
4425
|
+
}
|
4426
|
+
|
3471
4427
|
/**
|
3472
4428
|
* @param {number} pos source code position
|
3473
4429
|
* @returns {void}
|
3474
4430
|
*/
|
3475
4431
|
unsetAsiPosition(pos) {
|
3476
|
-
this.semicolons.delete(pos);
|
4432
|
+
/** @type {Set<number>} */ (this.semicolons).delete(pos);
|
3477
4433
|
}
|
3478
4434
|
|
4435
|
+
/**
|
4436
|
+
* @param {Expression} expr expression
|
4437
|
+
* @returns {boolean} true, when the expression is a statement level expression
|
4438
|
+
*/
|
3479
4439
|
isStatementLevelExpression(expr) {
|
3480
4440
|
const currentStatement = this.statementPath[this.statementPath.length - 1];
|
3481
4441
|
return (
|
@@ -3485,6 +4445,11 @@ class JavascriptParser extends Parser {
|
|
3485
4445
|
);
|
3486
4446
|
}
|
3487
4447
|
|
4448
|
+
/**
|
4449
|
+
* @param {string} name name
|
4450
|
+
* @param {TODO} tag tag info
|
4451
|
+
* @returns {TODO} tag data
|
4452
|
+
*/
|
3488
4453
|
getTagData(name, tag) {
|
3489
4454
|
const info = this.scope.definitions.get(name);
|
3490
4455
|
if (info instanceof VariableInfo) {
|
@@ -3496,6 +4461,11 @@ class JavascriptParser extends Parser {
|
|
3496
4461
|
}
|
3497
4462
|
}
|
3498
4463
|
|
4464
|
+
/**
|
4465
|
+
* @param {string} name name
|
4466
|
+
* @param {TODO} tag tag info
|
4467
|
+
* @param {TODO=} data data
|
4468
|
+
*/
|
3499
4469
|
tagVariable(name, tag, data) {
|
3500
4470
|
const oldInfo = this.scope.definitions.get(name);
|
3501
4471
|
/** @type {VariableInfo} */
|
@@ -3522,6 +4492,9 @@ class JavascriptParser extends Parser {
|
|
3522
4492
|
this.scope.definitions.set(name, newInfo);
|
3523
4493
|
}
|
3524
4494
|
|
4495
|
+
/**
|
4496
|
+
* @param {string} name variable name
|
4497
|
+
*/
|
3525
4498
|
defineVariable(name) {
|
3526
4499
|
const oldInfo = this.scope.definitions.get(name);
|
3527
4500
|
// Don't redefine variable in same scope to keep existing tags
|
@@ -3530,10 +4503,17 @@ class JavascriptParser extends Parser {
|
|
3530
4503
|
this.scope.definitions.set(name, this.scope);
|
3531
4504
|
}
|
3532
4505
|
|
4506
|
+
/**
|
4507
|
+
* @param {string} name variable name
|
4508
|
+
*/
|
3533
4509
|
undefineVariable(name) {
|
3534
4510
|
this.scope.definitions.delete(name);
|
3535
4511
|
}
|
3536
4512
|
|
4513
|
+
/**
|
4514
|
+
* @param {string} name variable name
|
4515
|
+
* @returns {boolean} true, when variable is defined
|
4516
|
+
*/
|
3537
4517
|
isVariableDefined(name) {
|
3538
4518
|
const info = this.scope.definitions.get(name);
|
3539
4519
|
if (info === undefined) return false;
|
@@ -3545,20 +4525,19 @@ class JavascriptParser extends Parser {
|
|
3545
4525
|
|
3546
4526
|
/**
|
3547
4527
|
* @param {string} name variable name
|
3548
|
-
* @returns {ExportedVariableInfo} info for this variable
|
4528
|
+
* @returns {string | ExportedVariableInfo} info for this variable
|
3549
4529
|
*/
|
3550
4530
|
getVariableInfo(name) {
|
3551
4531
|
const value = this.scope.definitions.get(name);
|
3552
4532
|
if (value === undefined) {
|
3553
4533
|
return name;
|
3554
|
-
} else {
|
3555
|
-
return value;
|
3556
4534
|
}
|
4535
|
+
return value;
|
3557
4536
|
}
|
3558
4537
|
|
3559
4538
|
/**
|
3560
4539
|
* @param {string} name variable name
|
3561
|
-
* @param {ExportedVariableInfo} variableInfo new info for this variable
|
4540
|
+
* @param {string | ExportedVariableInfo} variableInfo new info for this variable
|
3562
4541
|
* @returns {void}
|
3563
4542
|
*/
|
3564
4543
|
setVariable(name, variableInfo) {
|
@@ -3576,23 +4555,50 @@ class JavascriptParser extends Parser {
|
|
3576
4555
|
}
|
3577
4556
|
}
|
3578
4557
|
|
4558
|
+
/**
|
4559
|
+
* @param {TagInfo} tagInfo tag info
|
4560
|
+
* @returns {VariableInfo} variable info
|
4561
|
+
*/
|
4562
|
+
evaluatedVariable(tagInfo) {
|
4563
|
+
return new VariableInfo(this.scope, undefined, tagInfo);
|
4564
|
+
}
|
4565
|
+
|
4566
|
+
/**
|
4567
|
+
* @param {Range} range range of the comment
|
4568
|
+
* @returns {TODO} TODO
|
4569
|
+
*/
|
3579
4570
|
parseCommentOptions(range) {
|
3580
4571
|
const comments = this.getComments(range);
|
3581
4572
|
if (comments.length === 0) {
|
3582
4573
|
return EMPTY_COMMENT_OPTIONS;
|
3583
4574
|
}
|
3584
|
-
|
3585
|
-
|
4575
|
+
const options = {};
|
4576
|
+
/** @type {unknown[]} */
|
4577
|
+
const errors = [];
|
3586
4578
|
for (const comment of comments) {
|
3587
4579
|
const { value } = comment;
|
3588
4580
|
if (value && webpackCommentRegExp.test(value)) {
|
3589
4581
|
// try compile only if webpack options comment is present
|
3590
4582
|
try {
|
3591
|
-
|
3592
|
-
|
3593
|
-
|
3594
|
-
|
3595
|
-
|
4583
|
+
for (let [key, val] of Object.entries(
|
4584
|
+
vm.runInContext(
|
4585
|
+
`(function(){return {${value}};})()`,
|
4586
|
+
this.magicCommentContext
|
4587
|
+
)
|
4588
|
+
)) {
|
4589
|
+
if (typeof val === "object" && val !== null) {
|
4590
|
+
val =
|
4591
|
+
val.constructor.name === "RegExp"
|
4592
|
+
? new RegExp(val)
|
4593
|
+
: JSON.parse(JSON.stringify(val));
|
4594
|
+
}
|
4595
|
+
options[key] = val;
|
4596
|
+
}
|
4597
|
+
} catch (err) {
|
4598
|
+
const newErr = new Error(String(err.message));
|
4599
|
+
newErr.stack = String(err.stack);
|
4600
|
+
Object.assign(newErr, { comment });
|
4601
|
+
errors.push(newErr);
|
3596
4602
|
}
|
3597
4603
|
}
|
3598
4604
|
}
|
@@ -3600,61 +4606,69 @@ class JavascriptParser extends Parser {
|
|
3600
4606
|
}
|
3601
4607
|
|
3602
4608
|
/**
|
3603
|
-
* @param {
|
3604
|
-
* @returns {{ members: string[], object:
|
4609
|
+
* @param {MemberExpression} expression a member expression
|
4610
|
+
* @returns {{ members: string[], object: Expression | Super, membersOptionals: boolean[], memberRanges: Range[] }} member names (reverse order) and remaining object
|
3605
4611
|
*/
|
3606
4612
|
extractMemberExpressionChain(expression) {
|
3607
4613
|
/** @type {AnyNode} */
|
3608
4614
|
let expr = expression;
|
3609
4615
|
const members = [];
|
4616
|
+
const membersOptionals = [];
|
4617
|
+
const memberRanges = [];
|
3610
4618
|
while (expr.type === "MemberExpression") {
|
3611
4619
|
if (expr.computed) {
|
3612
4620
|
if (expr.property.type !== "Literal") break;
|
3613
|
-
members.push(`${expr.property.value}`);
|
4621
|
+
members.push(`${expr.property.value}`); // the literal
|
4622
|
+
memberRanges.push(/** @type {Range} */ (expr.object.range)); // the range of the expression fragment before the literal
|
3614
4623
|
} else {
|
3615
4624
|
if (expr.property.type !== "Identifier") break;
|
3616
|
-
members.push(expr.property.name);
|
4625
|
+
members.push(expr.property.name); // the identifier
|
4626
|
+
memberRanges.push(/** @type {Range} */ (expr.object.range)); // the range of the expression fragment before the identifier
|
3617
4627
|
}
|
4628
|
+
membersOptionals.push(expr.optional);
|
3618
4629
|
expr = expr.object;
|
3619
4630
|
}
|
4631
|
+
|
3620
4632
|
return {
|
3621
4633
|
members,
|
4634
|
+
membersOptionals,
|
4635
|
+
memberRanges,
|
3622
4636
|
object: expr
|
3623
4637
|
};
|
3624
4638
|
}
|
3625
4639
|
|
3626
4640
|
/**
|
3627
4641
|
* @param {string} varName variable name
|
3628
|
-
* @returns {{name: string, info: VariableInfo | string}} name of the free variable and variable info for that
|
4642
|
+
* @returns {{name: string, info: VariableInfo | string} | undefined} name of the free variable and variable info for that
|
3629
4643
|
*/
|
3630
4644
|
getFreeInfoFromVariable(varName) {
|
3631
4645
|
const info = this.getVariableInfo(varName);
|
3632
4646
|
let name;
|
3633
4647
|
if (info instanceof VariableInfo) {
|
3634
4648
|
name = info.freeName;
|
3635
|
-
if (typeof name !== "string") return
|
4649
|
+
if (typeof name !== "string") return;
|
3636
4650
|
} else if (typeof info !== "string") {
|
3637
|
-
return
|
4651
|
+
return;
|
3638
4652
|
} else {
|
3639
4653
|
name = info;
|
3640
4654
|
}
|
3641
4655
|
return { info, name };
|
3642
4656
|
}
|
3643
4657
|
|
3644
|
-
/** @typedef {{ type: "call", call:
|
3645
|
-
/** @typedef {{ type: "expression", rootInfo: string | VariableInfo, name: string, getMembers: () => string[]}} ExpressionExpressionInfo */
|
4658
|
+
/** @typedef {{ type: "call", call: CallExpression, calleeName: string, rootInfo: string | VariableInfo, getCalleeMembers: () => string[], name: string, getMembers: () => string[], getMembersOptionals: () => boolean[], getMemberRanges: () => Range[]}} CallExpressionInfo */
|
4659
|
+
/** @typedef {{ type: "expression", rootInfo: string | VariableInfo, name: string, getMembers: () => string[], getMembersOptionals: () => boolean[], getMemberRanges: () => Range[]}} ExpressionExpressionInfo */
|
3646
4660
|
|
3647
4661
|
/**
|
3648
|
-
* @param {
|
4662
|
+
* @param {MemberExpression} expression a member expression
|
3649
4663
|
* @param {number} allowedTypes which types should be returned, presented in bit mask
|
3650
4664
|
* @returns {CallExpressionInfo | ExpressionExpressionInfo | undefined} expression info
|
3651
4665
|
*/
|
3652
4666
|
getMemberExpressionInfo(expression, allowedTypes) {
|
3653
|
-
const { object, members } =
|
4667
|
+
const { object, members, membersOptionals, memberRanges } =
|
4668
|
+
this.extractMemberExpressionChain(expression);
|
3654
4669
|
switch (object.type) {
|
3655
4670
|
case "CallExpression": {
|
3656
|
-
if ((allowedTypes & ALLOWED_MEMBER_TYPES_CALL_EXPRESSION) === 0)
|
3657
|
-
return undefined;
|
4671
|
+
if ((allowedTypes & ALLOWED_MEMBER_TYPES_CALL_EXPRESSION) === 0) return;
|
3658
4672
|
let callee = object.callee;
|
3659
4673
|
let rootMembers = EMPTY_ARRAY;
|
3660
4674
|
if (callee.type === "MemberExpression") {
|
@@ -3662,9 +4676,9 @@ class JavascriptParser extends Parser {
|
|
3662
4676
|
this.extractMemberExpressionChain(callee));
|
3663
4677
|
}
|
3664
4678
|
const rootName = getRootName(callee);
|
3665
|
-
if (!rootName) return
|
4679
|
+
if (!rootName) return;
|
3666
4680
|
const result = this.getFreeInfoFromVariable(rootName);
|
3667
|
-
if (!result) return
|
4681
|
+
if (!result) return;
|
3668
4682
|
const { info: rootInfo, name: resolvedRoot } = result;
|
3669
4683
|
const calleeName = objectAndMembersToName(resolvedRoot, rootMembers);
|
3670
4684
|
return {
|
@@ -3674,33 +4688,36 @@ class JavascriptParser extends Parser {
|
|
3674
4688
|
rootInfo,
|
3675
4689
|
getCalleeMembers: memoize(() => rootMembers.reverse()),
|
3676
4690
|
name: objectAndMembersToName(`${calleeName}()`, members),
|
3677
|
-
getMembers: memoize(() => members.reverse())
|
4691
|
+
getMembers: memoize(() => members.reverse()),
|
4692
|
+
getMembersOptionals: memoize(() => membersOptionals.reverse()),
|
4693
|
+
getMemberRanges: memoize(() => memberRanges.reverse())
|
3678
4694
|
};
|
3679
4695
|
}
|
3680
4696
|
case "Identifier":
|
3681
4697
|
case "MetaProperty":
|
3682
4698
|
case "ThisExpression": {
|
3683
|
-
if ((allowedTypes & ALLOWED_MEMBER_TYPES_EXPRESSION) === 0)
|
3684
|
-
return undefined;
|
4699
|
+
if ((allowedTypes & ALLOWED_MEMBER_TYPES_EXPRESSION) === 0) return;
|
3685
4700
|
const rootName = getRootName(object);
|
3686
|
-
if (!rootName) return
|
4701
|
+
if (!rootName) return;
|
3687
4702
|
|
3688
4703
|
const result = this.getFreeInfoFromVariable(rootName);
|
3689
|
-
if (!result) return
|
4704
|
+
if (!result) return;
|
3690
4705
|
const { info: rootInfo, name: resolvedRoot } = result;
|
3691
4706
|
return {
|
3692
4707
|
type: "expression",
|
3693
4708
|
name: objectAndMembersToName(resolvedRoot, members),
|
3694
4709
|
rootInfo,
|
3695
|
-
getMembers: memoize(() => members.reverse())
|
4710
|
+
getMembers: memoize(() => members.reverse()),
|
4711
|
+
getMembersOptionals: memoize(() => membersOptionals.reverse()),
|
4712
|
+
getMemberRanges: memoize(() => memberRanges.reverse())
|
3696
4713
|
};
|
3697
4714
|
}
|
3698
4715
|
}
|
3699
4716
|
}
|
3700
4717
|
|
3701
4718
|
/**
|
3702
|
-
* @param {
|
3703
|
-
* @returns {{ name: string, rootInfo: ExportedVariableInfo, getMembers: () => string[]}} name info
|
4719
|
+
* @param {MemberExpression} expression an expression
|
4720
|
+
* @returns {{ name: string, rootInfo: ExportedVariableInfo, getMembers: () => string[]} | undefined} name info
|
3704
4721
|
*/
|
3705
4722
|
getNameForExpression(expression) {
|
3706
4723
|
return this.getMemberExpressionInfo(
|
@@ -3712,7 +4729,7 @@ class JavascriptParser extends Parser {
|
|
3712
4729
|
/**
|
3713
4730
|
* @param {string} code source code
|
3714
4731
|
* @param {ParseOptions} options parsing options
|
3715
|
-
* @returns {
|
4732
|
+
* @returns {Program} parsed ast
|
3716
4733
|
*/
|
3717
4734
|
static _parse(code, options) {
|
3718
4735
|
const type = options ? options.sourceType : "module";
|
@@ -3724,14 +4741,14 @@ class JavascriptParser extends Parser {
|
|
3724
4741
|
sourceType: type === "auto" ? "module" : type
|
3725
4742
|
};
|
3726
4743
|
|
3727
|
-
/** @type {AnyNode} */
|
4744
|
+
/** @type {AnyNode | undefined} */
|
3728
4745
|
let ast;
|
3729
4746
|
let error;
|
3730
4747
|
let threw = false;
|
3731
4748
|
try {
|
3732
4749
|
ast = /** @type {AnyNode} */ (parser.parse(code, parserOptions));
|
3733
|
-
} catch (
|
3734
|
-
error =
|
4750
|
+
} catch (err) {
|
4751
|
+
error = err;
|
3735
4752
|
threw = true;
|
3736
4753
|
}
|
3737
4754
|
|
@@ -3746,7 +4763,7 @@ class JavascriptParser extends Parser {
|
|
3746
4763
|
try {
|
3747
4764
|
ast = /** @type {AnyNode} */ (parser.parse(code, parserOptions));
|
3748
4765
|
threw = false;
|
3749
|
-
} catch (
|
4766
|
+
} catch (_err) {
|
3750
4767
|
// we use the error from first parse try
|
3751
4768
|
// so nothing to do here
|
3752
4769
|
}
|
@@ -3756,7 +4773,7 @@ class JavascriptParser extends Parser {
|
|
3756
4773
|
throw error;
|
3757
4774
|
}
|
3758
4775
|
|
3759
|
-
return /** @type {
|
4776
|
+
return /** @type {Program} */ (ast);
|
3760
4777
|
}
|
3761
4778
|
}
|
3762
4779
|
|