xhs-mp-pack 1.1.0-beta.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 +1 -0
- package/dist/Compilation.d.ts +239 -0
- package/dist/Compilation.js +3513 -0
- package/dist/Compiler.d.ts +76 -0
- package/dist/Compiler.js +845 -0
- package/dist/ConcatenationScope.d.ts +37 -0
- package/dist/ConcatenationScope.js +69 -0
- package/dist/FileSystemInfo.d.ts +183 -0
- package/dist/FileSystemInfo.js +2896 -0
- package/dist/MPPack.d.ts +33 -0
- package/dist/MPPack.js +163 -0
- package/dist/MPPackSetting.d.ts +52 -0
- package/dist/MPPackSetting.js +85 -0
- package/dist/MultiCompiler.d.ts +25 -0
- package/dist/MultiCompiler.js +387 -0
- package/dist/MultiWatching.d.ts +11 -0
- package/dist/MultiWatching.js +54 -0
- package/dist/PluginManager.d.ts +9 -0
- package/dist/PluginManager.js +359 -0
- package/dist/ResolverFactory.d.ts +7 -0
- package/dist/ResolverFactory.js +84 -0
- package/dist/Watching.d.ts +41 -0
- package/dist/Watching.js +359 -0
- package/dist/base/ArrayHelpers.d.ts +6 -0
- package/dist/base/ArrayHelpers.js +21 -0
- package/dist/base/ArrayQueue.d.ts +29 -0
- package/dist/base/ArrayQueue.js +87 -0
- package/dist/base/AsyncQueue.d.ts +37 -0
- package/dist/base/AsyncQueue.js +263 -0
- package/dist/base/ChunkHelpers.d.ts +3 -0
- package/dist/base/ChunkHelpers.js +26 -0
- package/dist/base/ConditionalInitFragment.d.ts +9 -0
- package/dist/base/ConditionalInitFragment.js +64 -0
- package/dist/base/GraphHelpers.d.ts +6 -0
- package/dist/base/GraphHelpers.js +32 -0
- package/dist/base/Hash.d.ts +6 -0
- package/dist/base/Hash.js +13 -0
- package/dist/base/InitFragment.d.ts +22 -0
- package/dist/base/InitFragment.js +113 -0
- package/dist/base/IterableHelpers.d.ts +4 -0
- package/dist/base/IterableHelpers.js +26 -0
- package/dist/base/LazyBucketSortedSet.d.ts +34 -0
- package/dist/base/LazyBucketSortedSet.js +188 -0
- package/dist/base/LazySet.d.ts +35 -0
- package/dist/base/LazySet.js +155 -0
- package/dist/base/MapHelpers.d.ts +14 -0
- package/dist/base/MapHelpers.js +27 -0
- package/dist/base/ModuleFilenameHelpers.d.ts +95 -0
- package/dist/base/ModuleFilenameHelpers.js +314 -0
- package/dist/base/NodeWatchFileSystem.d.ts +23 -0
- package/dist/base/NodeWatchFileSystem.js +135 -0
- package/dist/base/ParallelismFactorCalculator.d.ts +8 -0
- package/dist/base/ParallelismFactorCalculator.js +52 -0
- package/dist/base/Queue.d.ts +12 -0
- package/dist/base/Queue.js +25 -0
- package/dist/base/RequestShortener.d.ts +6 -0
- package/dist/base/RequestShortener.js +15 -0
- package/dist/base/Semaphore.d.ts +12 -0
- package/dist/base/Semaphore.js +37 -0
- package/dist/base/SetHelpers.d.ts +36 -0
- package/dist/base/SetHelpers.js +94 -0
- package/dist/base/SizeFormatHelpers.d.ts +2 -0
- package/dist/base/SizeFormatHelpers.js +15 -0
- package/dist/base/SizeOnlySource.d.ts +14 -0
- package/dist/base/SizeOnlySource.js +34 -0
- package/dist/base/SortableSet.d.ts +18 -0
- package/dist/base/SortableSet.js +90 -0
- package/dist/base/StackedCacheMap.d.ts +20 -0
- package/dist/base/StackedCacheMap.js +73 -0
- package/dist/base/StackedMap.d.ts +17 -0
- package/dist/base/StackedMap.js +103 -0
- package/dist/base/StartupHelpers.d.ts +4 -0
- package/dist/base/StartupHelpers.js +94 -0
- package/dist/base/StringXor.d.ts +53 -0
- package/dist/base/StringXor.js +94 -0
- package/dist/base/TupleQueue.d.ts +10 -0
- package/dist/base/TupleQueue.js +33 -0
- package/dist/base/TupleSet.d.ts +18 -0
- package/dist/base/TupleSet.js +115 -0
- package/dist/base/URLAbsoluteSpecifier.d.ts +3 -0
- package/dist/base/URLAbsoluteSpecifier.js +57 -0
- package/dist/base/WeakTupleMap.d.ts +20 -0
- package/dist/base/WeakTupleMap.js +124 -0
- package/dist/base/binarySearchBounds.d.ts +23 -0
- package/dist/base/binarySearchBounds.js +105 -0
- package/dist/base/cleverMerge.d.ts +27 -0
- package/dist/base/cleverMerge.js +450 -0
- package/dist/base/common.d.ts +7 -0
- package/dist/base/common.js +25 -0
- package/dist/base/commonjs.d.ts +1 -0
- package/dist/base/commonjs.js +48 -0
- package/dist/base/comparators.d.ts +22 -0
- package/dist/base/comparators.js +279 -0
- package/dist/base/compileBooleanMatcher.d.ts +6 -0
- package/dist/base/compileBooleanMatcher.js +162 -0
- package/dist/base/const.d.ts +29 -0
- package/dist/base/const.js +49 -0
- package/dist/base/copyPatterns.d.ts +14 -0
- package/dist/base/copyPatterns.js +501 -0
- package/dist/base/createHash.d.ts +3 -0
- package/dist/base/createHash.js +131 -0
- package/dist/base/defaults.d.ts +3 -0
- package/dist/base/defaults.js +671 -0
- package/dist/base/deprecation.d.ts +21 -0
- package/dist/base/deprecation.js +165 -0
- package/dist/base/deterministicGrouping.d.ts +8 -0
- package/dist/base/deterministicGrouping.js +395 -0
- package/dist/base/errors/AbstractMethodError.d.ts +5 -0
- package/dist/base/errors/AbstractMethodError.js +23 -0
- package/dist/base/errors/AsyncDependencyToInitialChunkError.d.ts +8 -0
- package/dist/base/errors/AsyncDependencyToInitialChunkError.js +18 -0
- package/dist/base/errors/BaseError.d.ts +17 -0
- package/dist/base/errors/BaseError.js +39 -0
- package/dist/base/errors/BuildCycleError.d.ts +8 -0
- package/dist/base/errors/BuildCycleError.js +17 -0
- package/dist/base/errors/CaseSensitiveModulesWarning.d.ts +5 -0
- package/dist/base/errors/CaseSensitiveModulesWarning.js +42 -0
- package/dist/base/errors/ChunkRenderError.d.ts +6 -0
- package/dist/base/errors/ChunkRenderError.js +18 -0
- package/dist/base/errors/CodeGenerationError.d.ts +8 -0
- package/dist/base/errors/CodeGenerationError.js +20 -0
- package/dist/base/errors/CommentCompilationWarning.d.ts +5 -0
- package/dist/base/errors/CommentCompilationWarning.js +16 -0
- package/dist/base/errors/ConcurrentCompilationError.d.ts +4 -0
- package/dist/base/errors/ConcurrentCompilationError.js +15 -0
- package/dist/base/errors/CriticalDependencyWarning.d.ts +5 -0
- package/dist/base/errors/CriticalDependencyWarning.js +16 -0
- package/dist/base/errors/ErrorHelpers.d.ts +8 -0
- package/dist/base/errors/ErrorHelpers.js +51 -0
- package/dist/base/errors/HarmonyLinkingError.d.ts +4 -0
- package/dist/base/errors/HarmonyLinkingError.js +14 -0
- package/dist/base/errors/HookBaseError.d.ts +10 -0
- package/dist/base/errors/HookBaseError.js +51 -0
- package/dist/base/errors/InvalidDependenciesModuleWarning.d.ts +5 -0
- package/dist/base/errors/InvalidDependenciesModuleWarning.js +26 -0
- package/dist/base/errors/MinMaxSizeWarning.d.ts +5 -0
- package/dist/base/errors/MinMaxSizeWarning.js +45 -0
- package/dist/base/errors/ModuleBuildError.d.ts +9 -0
- package/dist/base/errors/ModuleBuildError.js +62 -0
- package/dist/base/errors/ModuleDependencyError.d.ts +8 -0
- package/dist/base/errors/ModuleDependencyError.js +24 -0
- package/dist/base/errors/ModuleDependencyWarning.d.ts +6 -0
- package/dist/base/errors/ModuleDependencyWarning.js +23 -0
- package/dist/base/errors/ModuleError.d.ts +10 -0
- package/dist/base/errors/ModuleError.js +42 -0
- package/dist/base/errors/ModuleHashingError.d.ts +5 -0
- package/dist/base/errors/ModuleHashingError.js +17 -0
- package/dist/base/errors/ModuleNotFoundError.d.ts +5 -0
- package/dist/base/errors/ModuleNotFoundError.js +69 -0
- package/dist/base/errors/ModuleParseError.d.ts +8 -0
- package/dist/base/errors/ModuleParseError.js +77 -0
- package/dist/base/errors/ModuleRestoreError.d.ts +5 -0
- package/dist/base/errors/ModuleRestoreError.js +33 -0
- package/dist/base/errors/ModuleStoreError.d.ts +5 -0
- package/dist/base/errors/ModuleStoreError.js +33 -0
- package/dist/base/errors/ModuleWarning.d.ts +10 -0
- package/dist/base/errors/ModuleWarning.js +44 -0
- package/dist/base/errors/NodeStuffInWebError.d.ts +5 -0
- package/dist/base/errors/NodeStuffInWebError.js +17 -0
- package/dist/base/errors/UnhandledSchemeError.d.ts +5 -0
- package/dist/base/errors/UnhandledSchemeError.js +18 -0
- package/dist/base/errors/UnsupportedFeatureWarning.d.ts +5 -0
- package/dist/base/errors/UnsupportedFeatureWarning.js +17 -0
- package/dist/base/extractUrlAndGlobal.d.ts +1 -0
- package/dist/base/extractUrlAndGlobal.js +10 -0
- package/dist/base/findGraphRoots.d.ts +2 -0
- package/dist/base/findGraphRoots.js +183 -0
- package/dist/base/formatLocation.d.ts +2 -0
- package/dist/base/formatLocation.js +47 -0
- package/dist/base/fs.d.ts +94 -0
- package/dist/base/fs.js +218 -0
- package/dist/base/hash/BatchedHash.d.ts +11 -0
- package/dist/base/hash/BatchedHash.js +47 -0
- package/dist/base/hash/md4.d.ts +2 -0
- package/dist/base/hash/md4.js +10 -0
- package/dist/base/hash/wasm-hash.d.ts +3 -0
- package/dist/base/hash/wasm-hash.js +138 -0
- package/dist/base/hash/xxhash64.d.ts +2 -0
- package/dist/base/hash/xxhash64.js +10 -0
- package/dist/base/identifier.d.ts +30 -0
- package/dist/base/identifier.js +237 -0
- package/dist/base/logging/Logger.d.ts +40 -0
- package/dist/base/logging/Logger.js +128 -0
- package/dist/base/logging/createConsoleLogger.d.ts +6 -0
- package/dist/base/logging/createConsoleLogger.js +161 -0
- package/dist/base/logging/nodeConsole.d.ts +21 -0
- package/dist/base/logging/nodeConsole.js +109 -0
- package/dist/base/logging/runtime.d.ts +8 -0
- package/dist/base/logging/runtime.js +30 -0
- package/dist/base/logging/truncateArgs.d.ts +2 -0
- package/dist/base/logging/truncateArgs.js +66 -0
- package/dist/base/memoize.d.ts +2 -0
- package/dist/base/memoize.js +18 -0
- package/dist/base/missingModule.d.ts +4 -0
- package/dist/base/missingModule.js +16 -0
- package/dist/base/moduleAlias.d.ts +1 -0
- package/dist/base/moduleAlias.js +8 -0
- package/dist/base/nonNumericOnlyHash.d.ts +7 -0
- package/dist/base/nonNumericOnlyHash.js +16 -0
- package/dist/base/normalization.d.ts +32 -0
- package/dist/base/normalization.js +320 -0
- package/dist/base/numberHash.d.ts +17 -0
- package/dist/base/numberHash.js +72 -0
- package/dist/base/objectToMap.d.ts +1 -0
- package/dist/base/objectToMap.js +6 -0
- package/dist/base/processAsyncTree.d.ts +2 -0
- package/dist/base/processAsyncTree.js +45 -0
- package/dist/base/propertyAccess.d.ts +2 -0
- package/dist/base/propertyAccess.js +20 -0
- package/dist/base/propertyName.d.ts +9 -0
- package/dist/base/propertyName.js +71 -0
- package/dist/base/semver.d.ts +25 -0
- package/dist/base/semver.js +425 -0
- package/dist/base/singletontask.d.ts +27 -0
- package/dist/base/singletontask.js +124 -0
- package/dist/base/smartGrouping.d.ts +2 -0
- package/dist/base/smartGrouping.js +138 -0
- package/dist/base/source.d.ts +2 -0
- package/dist/base/source.js +48 -0
- package/dist/base/stats/MultiStats.d.ts +19 -0
- package/dist/base/stats/MultiStats.js +142 -0
- package/dist/base/stats/Stats.d.ts +13 -0
- package/dist/base/stats/Stats.js +49 -0
- package/dist/base/stats/StatsFactory.d.ts +26 -0
- package/dist/base/stats/StatsFactory.js +163 -0
- package/dist/base/stats/StatsPrinter.d.ts +12 -0
- package/dist/base/stats/StatsPrinter.js +104 -0
- package/dist/base/utils.d.ts +5 -0
- package/dist/base/utils.js +35 -0
- package/dist/cache/AddBuildDependenciesPlugin.d.ts +6 -0
- package/dist/cache/AddBuildDependenciesPlugin.js +13 -0
- package/dist/cache/AddManagedPathsPlugin.d.ts +7 -0
- package/dist/cache/AddManagedPathsPlugin.js +17 -0
- package/dist/cache/Cache.d.ts +15 -0
- package/dist/cache/Cache.js +69 -0
- package/dist/cache/CacheFacade.d.ts +37 -0
- package/dist/cache/CacheFacade.js +187 -0
- package/dist/cache/IdleFileCachePlugin.d.ts +9 -0
- package/dist/cache/IdleFileCachePlugin.js +165 -0
- package/dist/cache/MemoryCachePlugin.d.ts +4 -0
- package/dist/cache/MemoryCachePlugin.js +36 -0
- package/dist/cache/MemoryWithGcCachePlugin.d.ts +8 -0
- package/dist/cache/MemoryWithGcCachePlugin.js +104 -0
- package/dist/cache/PackFileCacheStrategy.d.ts +47 -0
- package/dist/cache/PackFileCacheStrategy.js +1085 -0
- package/dist/cache/ResolverCachePlugin.d.ts +4 -0
- package/dist/cache/ResolverCachePlugin.js +248 -0
- package/dist/cache/getLazyHashedEtag.d.ts +2 -0
- package/dist/cache/getLazyHashedEtag.js +53 -0
- package/dist/cache/mergeEtags.d.ts +2 -0
- package/dist/cache/mergeEtags.js +50 -0
- package/dist/chunk/Chunk.d.ts +75 -0
- package/dist/chunk/Chunk.js +445 -0
- package/dist/chunk/ChunkGraph.d.ts +102 -0
- package/dist/chunk/ChunkGraph.js +1037 -0
- package/dist/chunk/ChunkGroup.d.ts +62 -0
- package/dist/chunk/ChunkGroup.js +341 -0
- package/dist/chunk/CodeGenerationResults.d.ts +13 -0
- package/dist/chunk/CodeGenerationResults.js +82 -0
- package/dist/chunk/Entrypoint.d.ts +22 -0
- package/dist/chunk/Entrypoint.js +56 -0
- package/dist/chunk/GraphHelpers.d.ts +3 -0
- package/dist/chunk/GraphHelpers.js +15 -0
- package/dist/chunk/buildChunkGraph.d.ts +2 -0
- package/dist/chunk/buildChunkGraph.js +1067 -0
- package/dist/chunk/chunkFormat/ArrayPushCallbackChunkFormatPlugin.d.ts +4 -0
- package/dist/chunk/chunkFormat/ArrayPushCallbackChunkFormatPlugin.js +101 -0
- package/dist/chunk/chunkLoading/JsonpChunkLoadingPlugin.d.ts +4 -0
- package/dist/chunk/chunkLoading/JsonpChunkLoadingPlugin.js +98 -0
- package/dist/chunk/chunkLoading/JsonpChunkLoadingRuntimeModule.d.ts +15 -0
- package/dist/chunk/chunkLoading/JsonpChunkLoadingRuntimeModule.js +272 -0
- package/dist/dependencies/AsyncDependenciesBlock.d.ts +14 -0
- package/dist/dependencies/AsyncDependenciesBlock.js +64 -0
- package/dist/dependencies/CreateScriptUrlDependency.d.ts +9 -0
- package/dist/dependencies/CreateScriptUrlDependency.js +60 -0
- package/dist/dependencies/DelegatedSourceDependency.d.ts +7 -0
- package/dist/dependencies/DelegatedSourceDependency.js +20 -0
- package/dist/dependencies/DependenciesBlock.d.ts +29 -0
- package/dist/dependencies/DependenciesBlock.js +66 -0
- package/dist/dependencies/Dependency.d.ts +44 -0
- package/dist/dependencies/Dependency.js +171 -0
- package/dist/dependencies/DependencyTemplate.d.ts +4 -0
- package/dist/dependencies/DependencyTemplate.js +9 -0
- package/dist/dependencies/DependencyTemplates.d.ts +12 -0
- package/dist/dependencies/DependencyTemplates.js +34 -0
- package/dist/dependencies/DynamicExports.d.ts +6 -0
- package/dist/dependencies/DynamicExports.js +48 -0
- package/dist/dependencies/ExportsInfoDependency.d.ts +10 -0
- package/dist/dependencies/ExportsInfoDependency.js +80 -0
- package/dist/dependencies/LocalModule.d.ts +11 -0
- package/dist/dependencies/LocalModule.js +33 -0
- package/dist/dependencies/LocalModuleDependency.d.ts +10 -0
- package/dist/dependencies/LocalModuleDependency.js +42 -0
- package/dist/dependencies/LocalModulesHelpers.d.ts +4 -0
- package/dist/dependencies/LocalModulesHelpers.js +48 -0
- package/dist/dependencies/ModuleDecoratorDependency.d.ts +15 -0
- package/dist/dependencies/ModuleDecoratorDependency.js +85 -0
- package/dist/dependencies/ModuleDependency.d.ts +16 -0
- package/dist/dependencies/ModuleDependency.js +53 -0
- package/dist/dependencies/ModuleDependencyTemplateAsId.d.ts +9 -0
- package/dist/dependencies/ModuleDependencyTemplateAsId.js +21 -0
- package/dist/dependencies/ModuleDependencyTemplateAsRequireId.d.ts +10 -0
- package/dist/dependencies/ModuleDependencyTemplateAsRequireId.js +22 -0
- package/dist/dependencies/NullDependency.d.ts +7 -0
- package/dist/dependencies/NullDependency.js +19 -0
- package/dist/dependencies/PureExpressionDependency.d.ts +12 -0
- package/dist/dependencies/PureExpressionDependency.js +73 -0
- package/dist/dependencies/RequireHeaderDependency.d.ts +8 -0
- package/dist/dependencies/RequireHeaderDependency.js +58 -0
- package/dist/dependencies/RequireResolveContextDependency.d.ts +8 -0
- package/dist/dependencies/RequireResolveContextDependency.js +33 -0
- package/dist/dependencies/RequireResolveDependency.d.ts +10 -0
- package/dist/dependencies/RequireResolveDependency.js +29 -0
- package/dist/dependencies/RequireResolveHeaderDependency.d.ts +8 -0
- package/dist/dependencies/RequireResolveHeaderDependency.js +36 -0
- package/dist/dependencies/RuntimeRequirementsDependency.d.ts +10 -0
- package/dist/dependencies/RuntimeRequirementsDependency.js +40 -0
- package/dist/dependencies/StaticExportsDependency.d.ts +15 -0
- package/dist/dependencies/StaticExportsDependency.js +38 -0
- package/dist/dependencies/URLDependency.d.ts +16 -0
- package/dist/dependencies/URLDependency.js +103 -0
- package/dist/dependencies/URLPlugin.d.ts +4 -0
- package/dist/dependencies/URLPlugin.js +107 -0
- package/dist/dependencies/UnsupportedDependency.d.ts +9 -0
- package/dist/dependencies/UnsupportedDependency.js +36 -0
- package/dist/dependencies/commonjs/CommonJsDependencyHelpers.d.ts +2 -0
- package/dist/dependencies/commonjs/CommonJsDependencyHelpers.js +67 -0
- package/dist/dependencies/commonjs/CommonJsExportRequireDependency.d.ts +46 -0
- package/dist/dependencies/commonjs/CommonJsExportRequireDependency.js +260 -0
- package/dist/dependencies/commonjs/CommonJsExportsDependency.d.ts +19 -0
- package/dist/dependencies/commonjs/CommonJsExportsDependency.js +82 -0
- package/dist/dependencies/commonjs/CommonJsExportsParserPlugin.d.ts +6 -0
- package/dist/dependencies/commonjs/CommonJsExportsParserPlugin.js +314 -0
- package/dist/dependencies/commonjs/CommonJsFullRequireDependency.d.ts +13 -0
- package/dist/dependencies/commonjs/CommonJsFullRequireDependency.js +77 -0
- package/dist/dependencies/commonjs/CommonJsImportsParserPlugin.d.ts +6 -0
- package/dist/dependencies/commonjs/CommonJsImportsParserPlugin.js +500 -0
- package/dist/dependencies/commonjs/CommonJsPlugin.d.ts +4 -0
- package/dist/dependencies/commonjs/CommonJsPlugin.js +170 -0
- package/dist/dependencies/commonjs/CommonJsRequireContextDependency.d.ts +8 -0
- package/dist/dependencies/commonjs/CommonJsRequireContextDependency.js +37 -0
- package/dist/dependencies/commonjs/CommonJsRequireDependency.d.ts +7 -0
- package/dist/dependencies/commonjs/CommonJsRequireDependency.js +24 -0
- package/dist/dependencies/commonjs/CommonJsSelfReferenceDependency.d.ts +15 -0
- package/dist/dependencies/commonjs/CommonJsSelfReferenceDependency.js +112 -0
- package/dist/dependencies/const/CachedConstDependency.d.ts +12 -0
- package/dist/dependencies/const/CachedConstDependency.js +50 -0
- package/dist/dependencies/const/ConstDependency.d.ts +13 -0
- package/dist/dependencies/const/ConstDependency.js +63 -0
- package/dist/dependencies/context/ContextDependency.d.ts +26 -0
- package/dist/dependencies/context/ContextDependency.js +91 -0
- package/dist/dependencies/context/ContextDependencyHelpers.d.ts +2 -0
- package/dist/dependencies/context/ContextDependencyHelpers.js +128 -0
- package/dist/dependencies/context/ContextDependencyTemplateAsId.d.ts +10 -0
- package/dist/dependencies/context/ContextDependencyTemplateAsId.js +37 -0
- package/dist/dependencies/context/ContextDependencyTemplateAsRequireCall.d.ts +10 -0
- package/dist/dependencies/context/ContextDependencyTemplateAsRequireCall.js +39 -0
- package/dist/dependencies/context/ContextElementDependency.d.ts +13 -0
- package/dist/dependencies/context/ContextElementDependency.js +53 -0
- package/dist/dependencies/css/CssExportDependency.d.ts +17 -0
- package/dist/dependencies/css/CssExportDependency.js +49 -0
- package/dist/dependencies/css/CssImportDependency.d.ts +14 -0
- package/dist/dependencies/css/CssImportDependency.js +60 -0
- package/dist/dependencies/css/CssLocalIdentifierDependency.d.ts +12 -0
- package/dist/dependencies/css/CssLocalIdentifierDependency.js +69 -0
- package/dist/dependencies/css/CssSelfLocalIdentifierDependency.d.ts +13 -0
- package/dist/dependencies/css/CssSelfLocalIdentifierDependency.js +53 -0
- package/dist/dependencies/css/CssUrlDependency.d.ts +12 -0
- package/dist/dependencies/css/CssUrlDependency.js +89 -0
- package/dist/dependencies/entry/DynamicEntryPlugin.d.ts +22 -0
- package/dist/dependencies/entry/DynamicEntryPlugin.js +62 -0
- package/dist/dependencies/entry/EntryDependency.d.ts +7 -0
- package/dist/dependencies/entry/EntryDependency.js +20 -0
- package/dist/dependencies/getFunctionExpression.d.ts +10 -0
- package/dist/dependencies/getFunctionExpression.js +42 -0
- package/dist/dependencies/harmony/HarmonyAcceptDependency.d.ts +11 -0
- package/dist/dependencies/harmony/HarmonyAcceptDependency.js +81 -0
- package/dist/dependencies/harmony/HarmonyAcceptImportDependency.d.ts +6 -0
- package/dist/dependencies/harmony/HarmonyAcceptImportDependency.js +20 -0
- package/dist/dependencies/harmony/HarmonyCompatibilityDependency.d.ts +5 -0
- package/dist/dependencies/harmony/HarmonyCompatibilityDependency.js +61 -0
- package/dist/dependencies/harmony/HarmonyDetectionParserPlugin.d.ts +5 -0
- package/dist/dependencies/harmony/HarmonyDetectionParserPlugin.js +102 -0
- package/dist/dependencies/harmony/HarmonyEvaluatedImportSpecifierDependency.d.ts +16 -0
- package/dist/dependencies/harmony/HarmonyEvaluatedImportSpecifierDependency.js +84 -0
- package/dist/dependencies/harmony/HarmonyExportDependencyParserPlugin.d.ts +5 -0
- package/dist/dependencies/harmony/HarmonyExportDependencyParserPlugin.js +143 -0
- package/dist/dependencies/harmony/HarmonyExportExpressionDependency.d.ts +23 -0
- package/dist/dependencies/harmony/HarmonyExportExpressionDependency.js +148 -0
- package/dist/dependencies/harmony/HarmonyExportHeaderDependency.d.ts +10 -0
- package/dist/dependencies/harmony/HarmonyExportHeaderDependency.js +39 -0
- package/dist/dependencies/harmony/HarmonyExportImportedSpecifierDependency.d.ts +140 -0
- package/dist/dependencies/harmony/HarmonyExportImportedSpecifierDependency.js +763 -0
- package/dist/dependencies/harmony/HarmonyExportInitFragment.d.ts +14 -0
- package/dist/dependencies/harmony/HarmonyExportInitFragment.js +147 -0
- package/dist/dependencies/harmony/HarmonyExportSpecifierDependency.d.ts +17 -0
- package/dist/dependencies/harmony/HarmonyExportSpecifierDependency.js +62 -0
- package/dist/dependencies/harmony/HarmonyExports.d.ts +3 -0
- package/dist/dependencies/harmony/HarmonyExports.js +51 -0
- package/dist/dependencies/harmony/HarmonyImportDependency.d.ts +30 -0
- package/dist/dependencies/harmony/HarmonyImportDependency.js +217 -0
- package/dist/dependencies/harmony/HarmonyImportDependencyParserPlugin.d.ts +9 -0
- package/dist/dependencies/harmony/HarmonyImportDependencyParserPlugin.js +202 -0
- package/dist/dependencies/harmony/HarmonyImportSideEffectDependency.d.ts +8 -0
- package/dist/dependencies/harmony/HarmonyImportSideEffectDependency.js +43 -0
- package/dist/dependencies/harmony/HarmonyImportSpecifierDependency.d.ts +33 -0
- package/dist/dependencies/harmony/HarmonyImportSpecifierDependency.js +272 -0
- package/dist/dependencies/harmony/HarmonyModulesPlugin.d.ts +6 -0
- package/dist/dependencies/harmony/HarmonyModulesPlugin.js +57 -0
- package/dist/dependencies/harmony/HarmonyTopLevelThisParserPlugin.d.ts +4 -0
- package/dist/dependencies/harmony/HarmonyTopLevelThisParserPlugin.js +45 -0
- package/dist/dependencies/import/ImportContextDependency.d.ts +9 -0
- package/dist/dependencies/import/ImportContextDependency.js +34 -0
- package/dist/dependencies/import/ImportDependency.d.ts +11 -0
- package/dist/dependencies/import/ImportDependency.js +57 -0
- package/dist/dependencies/import/ImportEagerDependency.d.ts +7 -0
- package/dist/dependencies/import/ImportEagerDependency.js +34 -0
- package/dist/dependencies/import/ImportMetaContextDependency.d.ts +7 -0
- package/dist/dependencies/import/ImportMetaContextDependency.js +23 -0
- package/dist/dependencies/import/ImportMetaContextDependencyParserPlugin.d.ts +3 -0
- package/dist/dependencies/import/ImportMetaContextDependencyParserPlugin.js +207 -0
- package/dist/dependencies/import/ImportMetaContextPlugin.d.ts +4 -0
- package/dist/dependencies/import/ImportMetaContextPlugin.js +27 -0
- package/dist/dependencies/import/ImportMetaHotAcceptDependency.d.ts +7 -0
- package/dist/dependencies/import/ImportMetaHotAcceptDependency.js +24 -0
- package/dist/dependencies/import/ImportMetaHotDeclineDependency.d.ts +7 -0
- package/dist/dependencies/import/ImportMetaHotDeclineDependency.js +24 -0
- package/dist/dependencies/import/ImportMetaPlugin.d.ts +4 -0
- package/dist/dependencies/import/ImportMetaPlugin.js +129 -0
- package/dist/dependencies/import/ImportParserPlugin.d.ts +6 -0
- package/dist/dependencies/import/ImportParserPlugin.js +207 -0
- package/dist/dependencies/import/ImportPlugin.d.ts +4 -0
- package/dist/dependencies/import/ImportPlugin.js +37 -0
- package/dist/dependencies/import/ImportWeakDependency.d.ts +6 -0
- package/dist/dependencies/import/ImportWeakDependency.js +33 -0
- package/dist/dependencies/json/JsonExportsDependency.d.ts +14 -0
- package/dist/dependencies/json/JsonExportsDependency.js +61 -0
- package/dist/dependencies/loader/LoaderDependency.d.ts +8 -0
- package/dist/dependencies/loader/LoaderDependency.js +21 -0
- package/dist/dependencies/loader/LoaderImportDependency.d.ts +8 -0
- package/dist/dependencies/loader/LoaderImportDependency.js +22 -0
- package/dist/dependencies/loader/LoaderPlugin.d.ts +5 -0
- package/dist/dependencies/loader/LoaderPlugin.js +164 -0
- package/dist/dependencies/processExportInfo.d.ts +2 -0
- package/dist/dependencies/processExportInfo.js +32 -0
- package/dist/ids/DeterministicChunkIdsPlugin.d.ts +10 -0
- package/dist/ids/DeterministicChunkIdsPlugin.js +30 -0
- package/dist/ids/DeterministicModuleIdsPlugin.d.ts +6 -0
- package/dist/ids/DeterministicModuleIdsPlugin.js +38 -0
- package/dist/ids/IdHelpers.d.ts +16 -0
- package/dist/ids/IdHelpers.js +259 -0
- package/dist/ids/NamedChunkIdsPlugin.d.ts +11 -0
- package/dist/ids/NamedChunkIdsPlugin.js +34 -0
- package/dist/ids/NamedModuleIdsPlugin.d.ts +6 -0
- package/dist/ids/NamedModuleIdsPlugin.js +25 -0
- package/dist/ids/NaturalChunkIdsPlugin.d.ts +4 -0
- package/dist/ids/NaturalChunkIdsPlugin.js +17 -0
- package/dist/ids/NaturalModuleIdsPlugin.d.ts +4 -0
- package/dist/ids/NaturalModuleIdsPlugin.js +16 -0
- package/dist/index.d.ts +23 -0
- package/dist/index.js +58 -0
- package/dist/library/AbstractLibraryPlugin.d.ts +21 -0
- package/dist/library/AbstractLibraryPlugin.js +177 -0
- package/dist/library/AssignLibraryPlugin.d.ts +53 -0
- package/dist/library/AssignLibraryPlugin.js +201 -0
- package/dist/library/EnableLibraryPlugin.d.ts +8 -0
- package/dist/library/EnableLibraryPlugin.js +174 -0
- package/dist/library/ExportPropertyLibraryPlugin.d.ts +22 -0
- package/dist/library/ExportPropertyLibraryPlugin.js +74 -0
- package/dist/library/JsonpLibraryPlugin.d.ts +19 -0
- package/dist/library/JsonpLibraryPlugin.js +35 -0
- package/dist/library/ModuleLibraryPlugin.d.ts +16 -0
- package/dist/library/ModuleLibraryPlugin.js +73 -0
- package/dist/library/UmdLibraryPlugin.d.ts +22 -0
- package/dist/library/UmdLibraryPlugin.js +161 -0
- package/dist/module/ContextExclusionPlugin.d.ts +6 -0
- package/dist/module/ContextExclusionPlugin.js +13 -0
- package/dist/module/ContextModule.d.ts +75 -0
- package/dist/module/ContextModule.js +844 -0
- package/dist/module/ContextModuleFactory.d.ts +8 -0
- package/dist/module/ContextModuleFactory.js +292 -0
- package/dist/module/ContextReplacementPlugin.d.ts +11 -0
- package/dist/module/ContextReplacementPlugin.js +128 -0
- package/dist/module/CssModule.d.ts +20 -0
- package/dist/module/CssModule.js +105 -0
- package/dist/module/ExportsInfo.d.ts +135 -0
- package/dist/module/ExportsInfo.js +1171 -0
- package/dist/module/ExportsInfoApiPlugin.d.ts +4 -0
- package/dist/module/ExportsInfoApiPlugin.js +38 -0
- package/dist/module/ExternalModule.d.ts +47 -0
- package/dist/module/ExternalModule.js +458 -0
- package/dist/module/ExternalModuleFactoryPlugin.d.ts +7 -0
- package/dist/module/ExternalModuleFactoryPlugin.js +176 -0
- package/dist/module/ExternalsPlugin.d.ts +7 -0
- package/dist/module/ExternalsPlugin.js +18 -0
- package/dist/module/Generator.d.ts +40 -0
- package/dist/module/Generator.js +49 -0
- package/dist/module/IgnoreErrorModuleFactory.d.ts +7 -0
- package/dist/module/IgnoreErrorModuleFactory.js +16 -0
- package/dist/module/JavascriptMetaInfoPlugin.d.ts +4 -0
- package/dist/module/JavascriptMetaInfoPlugin.js +65 -0
- package/dist/module/LazyModuleFactoryPlugin.d.ts +6 -0
- package/dist/module/LazyModuleFactoryPlugin.js +171 -0
- package/dist/module/Module.d.ts +175 -0
- package/dist/module/Module.js +550 -0
- package/dist/module/ModuleFactory.d.ts +25 -0
- package/dist/module/ModuleFactory.js +10 -0
- package/dist/module/ModuleGraph.d.ts +74 -0
- package/dist/module/ModuleGraph.js +470 -0
- package/dist/module/ModuleGraphConnection.d.ts +33 -0
- package/dist/module/ModuleGraphConnection.js +113 -0
- package/dist/module/ModuleProfile.d.ts +40 -0
- package/dist/module/ModuleProfile.js +77 -0
- package/dist/module/ModuleTypeConstants.d.ts +22 -0
- package/dist/module/ModuleTypeConstants.js +45 -0
- package/dist/module/NormalModule.d.ts +104 -0
- package/dist/module/NormalModule.js +904 -0
- package/dist/module/NormalModuleFactory.d.ts +36 -0
- package/dist/module/NormalModuleFactory.js +761 -0
- package/dist/module/Parser.d.ts +4 -0
- package/dist/module/Parser.js +9 -0
- package/dist/module/RawModule.d.ts +29 -0
- package/dist/module/RawModule.js +74 -0
- package/dist/module/RuntimeGlobals.d.ts +310 -0
- package/dist/module/RuntimeGlobals.js +316 -0
- package/dist/module/RuntimeHelpers.d.ts +43 -0
- package/dist/module/RuntimeHelpers.js +548 -0
- package/dist/module/RuntimeModule.d.ts +39 -0
- package/dist/module/RuntimeModule.js +114 -0
- package/dist/module/RuntimePlugin.d.ts +4 -0
- package/dist/module/RuntimePlugin.js +332 -0
- package/dist/module/SelfModuleFactory.d.ts +6 -0
- package/dist/module/SelfModuleFactory.js +14 -0
- package/dist/module/asset/AssetGenerator.d.ts +30 -0
- package/dist/module/asset/AssetGenerator.js +364 -0
- package/dist/module/asset/AssetModulesPlugin.d.ts +4 -0
- package/dist/module/asset/AssetModulesPlugin.js +98 -0
- package/dist/module/asset/AssetParser.d.ts +12 -0
- package/dist/module/asset/AssetParser.js +44 -0
- package/dist/module/asset/AssetSourceGenerator.d.ts +14 -0
- package/dist/module/asset/AssetSourceGenerator.js +74 -0
- package/dist/module/asset/AssetSourceParser.d.ts +5 -0
- package/dist/module/asset/AssetSourceParser.js +19 -0
- package/dist/module/asset/RawDataUrlModule.d.ts +27 -0
- package/dist/module/asset/RawDataUrlModule.js +102 -0
- package/dist/module/async-modules/AwaitDependenciesInitFragment.d.ts +10 -0
- package/dist/module/async-modules/AwaitDependenciesInitFragment.js +68 -0
- package/dist/module/async-modules/InferAsyncModulesPlugin.d.ts +4 -0
- package/dist/module/async-modules/InferAsyncModulesPlugin.js +28 -0
- package/dist/module/javascript/BasicEvaluatedExpression.d.ts +139 -0
- package/dist/module/javascript/BasicEvaluatedExpression.js +481 -0
- package/dist/module/javascript/JavascriptGenerator.d.ts +11 -0
- package/dist/module/javascript/JavascriptGenerator.js +103 -0
- package/dist/module/javascript/JavascriptModulesPlugin.d.ts +17 -0
- package/dist/module/javascript/JavascriptModulesPlugin.js +821 -0
- package/dist/module/javascript/JavascriptParser.d.ts +598 -0
- package/dist/module/javascript/JavascriptParser.js +3579 -0
- package/dist/module/javascript/JavascriptParserHelpers.d.ts +10 -0
- package/dist/module/javascript/JavascriptParserHelpers.js +61 -0
- package/dist/module/json/JsonData.d.ts +9 -0
- package/dist/module/json/JsonData.js +43 -0
- package/dist/module/json/JsonGenerator.d.ts +15 -0
- package/dist/module/json/JsonGenerator.js +137 -0
- package/dist/module/json/JsonModulesPlugin.d.ts +4 -0
- package/dist/module/json/JsonModulesPlugin.js +20 -0
- package/dist/module/json/JsonParser.d.ts +7 -0
- package/dist/module/json/JsonParser.js +41 -0
- package/dist/module/runtime/AsyncModuleRuntimeModule.d.ts +6 -0
- package/dist/module/runtime/AsyncModuleRuntimeModule.js +115 -0
- package/dist/module/runtime/AutoPublicPathRuntimeModule.d.ts +6 -0
- package/dist/module/runtime/AutoPublicPathRuntimeModule.js +81 -0
- package/dist/module/runtime/BaseUriRuntimeModule.d.ts +6 -0
- package/dist/module/runtime/BaseUriRuntimeModule.js +41 -0
- package/dist/module/runtime/ChunkNameRuntimeModule.d.ts +7 -0
- package/dist/module/runtime/ChunkNameRuntimeModule.js +40 -0
- package/dist/module/runtime/CompatGetDefaultExportRuntimeModule.d.ts +6 -0
- package/dist/module/runtime/CompatGetDefaultExportRuntimeModule.js +54 -0
- package/dist/module/runtime/CompatRuntimeModule.d.ts +7 -0
- package/dist/module/runtime/CompatRuntimeModule.js +59 -0
- package/dist/module/runtime/CreateFakeNamespaceObjectRuntimeModule.d.ts +6 -0
- package/dist/module/runtime/CreateFakeNamespaceObjectRuntimeModule.js +77 -0
- package/dist/module/runtime/CreateScriptRuntimeModule.d.ts +6 -0
- package/dist/module/runtime/CreateScriptRuntimeModule.js +44 -0
- package/dist/module/runtime/CreateScriptUrlRuntimeModule.d.ts +6 -0
- package/dist/module/runtime/CreateScriptUrlRuntimeModule.js +44 -0
- package/dist/module/runtime/DefinePropertyGettersRuntimeModule.d.ts +6 -0
- package/dist/module/runtime/DefinePropertyGettersRuntimeModule.js +56 -0
- package/dist/module/runtime/EnsureChunkRuntimeModule.d.ts +7 -0
- package/dist/module/runtime/EnsureChunkRuntimeModule.js +66 -0
- package/dist/module/runtime/GetChunkFilenameRuntimeModule.d.ts +10 -0
- package/dist/module/runtime/GetChunkFilenameRuntimeModule.js +220 -0
- package/dist/module/runtime/GetFullHashRuntimeModule.d.ts +6 -0
- package/dist/module/runtime/GetFullHashRuntimeModule.js +42 -0
- package/dist/module/runtime/GetMainFilenameRuntimeModule.d.ts +8 -0
- package/dist/module/runtime/GetMainFilenameRuntimeModule.js +52 -0
- package/dist/module/runtime/GetTrustedTypesPolicyRuntimeModule.d.ts +7 -0
- package/dist/module/runtime/GetTrustedTypesPolicyRuntimeModule.js +89 -0
- package/dist/module/runtime/GlobalRuntimeModule.d.ts +6 -0
- package/dist/module/runtime/GlobalRuntimeModule.js +61 -0
- package/dist/module/runtime/HasOwnPropertyRuntimeModule.d.ts +6 -0
- package/dist/module/runtime/HasOwnPropertyRuntimeModule.js +44 -0
- package/dist/module/runtime/HelperRuntimeModule.d.ts +5 -0
- package/dist/module/runtime/HelperRuntimeModule.js +12 -0
- package/dist/module/runtime/LoadScriptRuntimeModule.d.ts +9 -0
- package/dist/module/runtime/LoadScriptRuntimeModule.js +129 -0
- package/dist/module/runtime/MakeNamespaceObjectRuntimeModule.d.ts +6 -0
- package/dist/module/runtime/MakeNamespaceObjectRuntimeModule.js +53 -0
- package/dist/module/runtime/NonceRuntimeModule.d.ts +6 -0
- package/dist/module/runtime/NonceRuntimeModule.js +39 -0
- package/dist/module/runtime/OnChunksLoadedRuntimeModule.d.ts +6 -0
- package/dist/module/runtime/OnChunksLoadedRuntimeModule.js +81 -0
- package/dist/module/runtime/PublicPathRuntimeModule.d.ts +7 -0
- package/dist/module/runtime/PublicPathRuntimeModule.js +44 -0
- package/dist/module/runtime/RelativeUrlRuntimeModule.d.ts +6 -0
- package/dist/module/runtime/RelativeUrlRuntimeModule.js +56 -0
- package/dist/module/runtime/RuntimeIdRuntimeModule.d.ts +6 -0
- package/dist/module/runtime/RuntimeIdRuntimeModule.js +45 -0
- package/dist/module/runtime/StartupChunkDependenciesPlugin.d.ts +11 -0
- package/dist/module/runtime/StartupChunkDependenciesPlugin.js +69 -0
- package/dist/module/runtime/StartupChunkDependenciesRuntimeModule.d.ts +7 -0
- package/dist/module/runtime/StartupChunkDependenciesRuntimeModule.js +67 -0
- package/dist/module/runtime/StartupEntrypointRuntimeModule.d.ts +7 -0
- package/dist/module/runtime/StartupEntrypointRuntimeModule.js +58 -0
- package/dist/module/uri/DataUriPlugin.d.ts +4 -0
- package/dist/module/uri/DataUriPlugin.js +46 -0
- package/dist/module/uri/FileUriPlugin.d.ts +4 -0
- package/dist/module/uri/FileUriPlugin.js +31 -0
- package/dist/plugins/APIPlugin.d.ts +9 -0
- package/dist/plugins/APIPlugin.js +230 -0
- package/dist/plugins/CleanPlugin.d.ts +7 -0
- package/dist/plugins/CleanPlugin.js +295 -0
- package/dist/plugins/CompatibilityPlugin.d.ts +4 -0
- package/dist/plugins/CompatibilityPlugin.js +142 -0
- package/dist/plugins/ConstPlugin.d.ts +4 -0
- package/dist/plugins/ConstPlugin.js +409 -0
- package/dist/plugins/DefaultStatsFactoryPlugin.d.ts +4 -0
- package/dist/plugins/DefaultStatsFactoryPlugin.js +1552 -0
- package/dist/plugins/DefaultStatsPresetPlugin.d.ts +4 -0
- package/dist/plugins/DefaultStatsPresetPlugin.js +306 -0
- package/dist/plugins/DefaultStatsPrinterPlugin.d.ts +4 -0
- package/dist/plugins/DefaultStatsPrinterPlugin.js +986 -0
- package/dist/plugins/DefinePlugin.d.ts +15 -0
- package/dist/plugins/DefinePlugin.js +400 -0
- package/dist/plugins/NodeStuffPlugin.d.ts +6 -0
- package/dist/plugins/NodeStuffPlugin.js +134 -0
- package/dist/plugins/ProgressPlugin.d.ts +20 -0
- package/dist/plugins/ProgressPlugin.js +494 -0
- package/dist/plugins/RecordIdsPlugin.d.ts +9 -0
- package/dist/plugins/RecordIdsPlugin.js +175 -0
- package/dist/plugins/UseStrictPlugin.d.ts +4 -0
- package/dist/plugins/UseStrictPlugin.js +35 -0
- package/dist/plugins/WarnCaseSensitiveModulesPlugin.d.ts +4 -0
- package/dist/plugins/WarnCaseSensitiveModulesPlugin.js +37 -0
- package/dist/plugins/WarnDeprecatedOptionPlugin.d.ts +8 -0
- package/dist/plugins/WarnDeprecatedOptionPlugin.js +29 -0
- package/dist/plugins/cssMinimizer/CssMinimizerMinify.js +73 -0
- package/dist/plugins/cssMinimizer/CssMinimizerPlugin.d.ts +11 -0
- package/dist/plugins/cssMinimizer/CssMinimizerPlugin.js +329 -0
- package/dist/plugins/cssMinimizer/CssMinimizerUtils.js +147 -0
- package/dist/plugins/miniCssExtractPlugin/MiniCssExtractLoader.d.ts +1 -0
- package/dist/plugins/miniCssExtractPlugin/MiniCssExtractLoader.js +177 -0
- package/dist/plugins/miniCssExtractPlugin/MiniCssExtractPlugin.d.ts +22 -0
- package/dist/plugins/miniCssExtractPlugin/MiniCssExtractPlugin.js +780 -0
- package/dist/plugins/miniCssExtractPlugin/MiniCssUtils.d.ts +14 -0
- package/dist/plugins/miniCssExtractPlugin/MiniCssUtils.js +132 -0
- package/dist/plugins/optimize/AggressiveMergingPlugin.d.ts +6 -0
- package/dist/plugins/optimize/AggressiveMergingPlugin.js +62 -0
- package/dist/plugins/optimize/AggressiveSplittingPlugin.d.ts +7 -0
- package/dist/plugins/optimize/AggressiveSplittingPlugin.js +247 -0
- package/dist/plugins/optimize/ConcatenatedModule.d.ts +47 -0
- package/dist/plugins/optimize/ConcatenatedModule.js +1221 -0
- package/dist/plugins/optimize/EnsureChunkConditionsPlugin.d.ts +4 -0
- package/dist/plugins/optimize/EnsureChunkConditionsPlugin.js +61 -0
- package/dist/plugins/optimize/FlagAllModulesAsUsedPlugin.d.ts +6 -0
- package/dist/plugins/optimize/FlagAllModulesAsUsedPlugin.js +30 -0
- package/dist/plugins/optimize/FlagDependencyExportsPlugin.d.ts +4 -0
- package/dist/plugins/optimize/FlagDependencyExportsPlugin.js +275 -0
- package/dist/plugins/optimize/FlagDependencyUsagePlugin.d.ts +6 -0
- package/dist/plugins/optimize/FlagDependencyUsagePlugin.js +243 -0
- package/dist/plugins/optimize/FlagEntryExportAsUsedPlugin.d.ts +7 -0
- package/dist/plugins/optimize/FlagEntryExportAsUsedPlugin.js +34 -0
- package/dist/plugins/optimize/FlagIncludedChunksPlugin.d.ts +4 -0
- package/dist/plugins/optimize/FlagIncludedChunksPlugin.js +85 -0
- package/dist/plugins/optimize/InnerGraph.d.ts +20 -0
- package/dist/plugins/optimize/InnerGraph.js +234 -0
- package/dist/plugins/optimize/InnerGraphPlugin.d.ts +4 -0
- package/dist/plugins/optimize/InnerGraphPlugin.js +289 -0
- package/dist/plugins/optimize/LimitChunkCountPlugin.d.ts +6 -0
- package/dist/plugins/optimize/LimitChunkCountPlugin.js +200 -0
- package/dist/plugins/optimize/MangleExportsPlugin.d.ts +6 -0
- package/dist/plugins/optimize/MangleExportsPlugin.js +124 -0
- package/dist/plugins/optimize/MergeDuplicateChunksPlugin.d.ts +4 -0
- package/dist/plugins/optimize/MergeDuplicateChunksPlugin.js +84 -0
- package/dist/plugins/optimize/MinChunkSizePlugin.d.ts +6 -0
- package/dist/plugins/optimize/MinChunkSizePlugin.js +71 -0
- package/dist/plugins/optimize/ModuleConcatenationPlugin.d.ts +8 -0
- package/dist/plugins/optimize/ModuleConcatenationPlugin.js +525 -0
- package/dist/plugins/optimize/ModuleInfoHeaderPlugin.d.ts +6 -0
- package/dist/plugins/optimize/ModuleInfoHeaderPlugin.js +145 -0
- package/dist/plugins/optimize/NoEmitOnErrorsPlugin.d.ts +4 -0
- package/dist/plugins/optimize/NoEmitOnErrorsPlugin.js +17 -0
- package/dist/plugins/optimize/OptimizationStages.d.ts +4 -0
- package/dist/plugins/optimize/OptimizationStages.js +9 -0
- package/dist/plugins/optimize/RealContentHashPlugin.d.ts +11 -0
- package/dist/plugins/optimize/RealContentHashPlugin.js +295 -0
- package/dist/plugins/optimize/RemoveEmptyChunksPlugin.d.ts +4 -0
- package/dist/plugins/optimize/RemoveEmptyChunksPlugin.js +30 -0
- package/dist/plugins/optimize/RemoveParentModulesPlugin.d.ts +4 -0
- package/dist/plugins/optimize/RemoveParentModulesPlugin.js +103 -0
- package/dist/plugins/optimize/RuntimeChunkPlugin.d.ts +6 -0
- package/dist/plugins/optimize/RuntimeChunkPlugin.js +25 -0
- package/dist/plugins/optimize/SideEffectsFlagPlugin.d.ts +7 -0
- package/dist/plugins/optimize/SideEffectsFlagPlugin.js +211 -0
- package/dist/plugins/optimize/SplitChunksPlugin.d.ts +7 -0
- package/dist/plugins/optimize/SplitChunksPlugin.js +1113 -0
- package/dist/rules/BasicEffectRulePlugin.d.ts +7 -0
- package/dist/rules/BasicEffectRulePlugin.js +21 -0
- package/dist/rules/BasicMatcherRulePlugin.d.ts +8 -0
- package/dist/rules/BasicMatcherRulePlugin.js +25 -0
- package/dist/rules/ObjectMatcherRulePlugin.d.ts +7 -0
- package/dist/rules/ObjectMatcherRulePlugin.js +27 -0
- package/dist/rules/RuleSetCompiler.d.ts +20 -0
- package/dist/rules/RuleSetCompiler.js +242 -0
- package/dist/rules/UseEffectRulePlugin.d.ts +5 -0
- package/dist/rules/UseEffectRulePlugin.js +117 -0
- package/dist/serialization/Serialization.d.ts +11 -0
- package/dist/serialization/Serialization.js +95 -0
- package/dist/serialization/Serializer.d.ts +9 -0
- package/dist/serialization/Serializer.js +43 -0
- package/dist/serialization/SerializerMiddleware.d.ts +13 -0
- package/dist/serialization/SerializerMiddleware.js +86 -0
- package/dist/serialization/internalSerializables.d.ts +82 -0
- package/dist/serialization/internalSerializables.js +94 -0
- package/dist/serialization/makeSerializable.d.ts +2 -0
- package/dist/serialization/makeSerializable.js +25 -0
- package/dist/serialization/middlewares/BinaryMiddleware.d.ts +12 -0
- package/dist/serialization/middlewares/BinaryMiddleware.js +955 -0
- package/dist/serialization/middlewares/FileMiddleware.d.ts +9 -0
- package/dist/serialization/middlewares/FileMiddleware.js +546 -0
- package/dist/serialization/middlewares/ObjectMiddleware.d.ts +15 -0
- package/dist/serialization/middlewares/ObjectMiddleware.js +602 -0
- package/dist/serialization/middlewares/SingleItemMiddleware.d.ts +6 -0
- package/dist/serialization/middlewares/SingleItemMiddleware.js +15 -0
- package/dist/serialization/registerExternalSerializer.d.ts +1 -0
- package/dist/serialization/registerExternalSerializer.js +154 -0
- package/dist/serialization/serializers/ArraySerializer.d.ts +5 -0
- package/dist/serialization/serializers/ArraySerializer.js +18 -0
- package/dist/serialization/serializers/DateObjectSerializer.d.ts +5 -0
- package/dist/serialization/serializers/DateObjectSerializer.js +11 -0
- package/dist/serialization/serializers/ErrorObjectSerializer.d.ts +7 -0
- package/dist/serialization/serializers/ErrorObjectSerializer.js +20 -0
- package/dist/serialization/serializers/MapObjectSerializer.d.ts +5 -0
- package/dist/serialization/serializers/MapObjectSerializer.js +26 -0
- package/dist/serialization/serializers/NullPrototypeObjectSerializer.d.ts +5 -0
- package/dist/serialization/serializers/NullPrototypeObjectSerializer.js +28 -0
- package/dist/serialization/serializers/PlainObjectSerializer.d.ts +5 -0
- package/dist/serialization/serializers/PlainObjectSerializer.js +77 -0
- package/dist/serialization/serializers/RegExpObjectSerializer.d.ts +5 -0
- package/dist/serialization/serializers/RegExpObjectSerializer.js +12 -0
- package/dist/serialization/serializers/SetObjectSerializer.d.ts +5 -0
- package/dist/serialization/serializers/SetObjectSerializer.js +19 -0
- package/dist/sourcemap/EvalDevToolModulePlugin.d.ts +8 -0
- package/dist/sourcemap/EvalDevToolModulePlugin.js +97 -0
- package/dist/sourcemap/EvalSourceMapDevToolPlugin.d.ts +9 -0
- package/dist/sourcemap/EvalSourceMapDevToolPlugin.js +167 -0
- package/dist/sourcemap/SourceMapDevToolModuleOptionsPlugin.d.ts +6 -0
- package/dist/sourcemap/SourceMapDevToolModuleOptionsPlugin.js +29 -0
- package/dist/sourcemap/SourceMapDevToolPlugin.d.ts +11 -0
- package/dist/sourcemap/SourceMapDevToolPlugin.js +364 -0
- package/dist/template/ChunkTemplate.d.ts +6 -0
- package/dist/template/ChunkTemplate.js +69 -0
- package/dist/template/LibraryTemplatePlugin.d.ts +6 -0
- package/dist/template/LibraryTemplatePlugin.js +23 -0
- package/dist/template/MainTemplate.d.ts +10 -0
- package/dist/template/MainTemplate.js +177 -0
- package/dist/template/ModuleTemplate.d.ts +7 -0
- package/dist/template/ModuleTemplate.js +46 -0
- package/dist/template/RuntimeTemplate.d.ts +158 -0
- package/dist/template/RuntimeTemplate.js +663 -0
- package/dist/template/Template.d.ts +25 -0
- package/dist/template/Template.js +269 -0
- package/dist/template/TemplatedPathPlugin.d.ts +4 -0
- package/dist/template/TemplatedPathPlugin.js +228 -0
- package/dist/thread/WorkerError.d.ts +4 -0
- package/dist/thread/WorkerError.js +21 -0
- package/dist/thread/WorkerPool.d.ts +52 -0
- package/dist/thread/WorkerPool.js +370 -0
- package/dist/thread/readBuffer.d.ts +1 -0
- package/dist/thread/readBuffer.js +37 -0
- package/dist/thread/serializer.d.ts +2 -0
- package/dist/thread/serializer.js +24 -0
- package/dist/thread/worker.d.ts +1 -0
- package/dist/thread/worker.js +185 -0
- package/dist/thread/workerPools.d.ts +2 -0
- package/dist/thread/workerPools.js +31 -0
- package/dist/types/index.d.ts +58 -0
- package/dist/types/index.js +8 -0
- package/package.json +96 -0
|
@@ -0,0 +1,3579 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.JavascriptParser = exports.ALLOWED_MEMBER_TYPES_ALL = exports.ALLOWED_MEMBER_TYPES_EXPRESSION = exports.ALLOWED_MEMBER_TYPES_CALL_EXPRESSION = void 0;
|
|
7
|
+
const acorn_1 = require("acorn");
|
|
8
|
+
const acorn_import_assertions_1 = require("acorn-import-assertions");
|
|
9
|
+
const tapable_1 = require("tapable");
|
|
10
|
+
const vm_1 = __importDefault(require("vm"));
|
|
11
|
+
const Parser_1 = __importDefault(require("@/module/Parser"));
|
|
12
|
+
const StackedMap_1 = __importDefault(require("@/base/StackedMap"));
|
|
13
|
+
const binarySearchBounds_1 = __importDefault(require("@/base/binarySearchBounds"));
|
|
14
|
+
const memoize_1 = __importDefault(require("@/base/memoize"));
|
|
15
|
+
const BasicEvaluatedExpression_1 = __importDefault(require("./BasicEvaluatedExpression"));
|
|
16
|
+
const EMPTY_ARRAY = [];
|
|
17
|
+
const ALLOWED_MEMBER_TYPES_CALL_EXPRESSION = 0b01;
|
|
18
|
+
exports.ALLOWED_MEMBER_TYPES_CALL_EXPRESSION = ALLOWED_MEMBER_TYPES_CALL_EXPRESSION;
|
|
19
|
+
const ALLOWED_MEMBER_TYPES_EXPRESSION = 0b10;
|
|
20
|
+
exports.ALLOWED_MEMBER_TYPES_EXPRESSION = ALLOWED_MEMBER_TYPES_EXPRESSION;
|
|
21
|
+
const ALLOWED_MEMBER_TYPES_ALL = 0b11;
|
|
22
|
+
exports.ALLOWED_MEMBER_TYPES_ALL = ALLOWED_MEMBER_TYPES_ALL;
|
|
23
|
+
const parser = acorn_1.Parser.extend(acorn_import_assertions_1.importAssertions);
|
|
24
|
+
class VariableInfo {
|
|
25
|
+
constructor(declaredScope, freeName, tagInfo) {
|
|
26
|
+
this.declaredScope = declaredScope;
|
|
27
|
+
this.freeName = freeName;
|
|
28
|
+
this.tagInfo = tagInfo;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Helper function for joining two ranges into a single range. This is useful
|
|
33
|
+
* when working with AST nodes, as it allows you to combine the ranges of child nodes
|
|
34
|
+
* to create the range of the _parent node_.
|
|
35
|
+
*
|
|
36
|
+
* @example
|
|
37
|
+
* ```js
|
|
38
|
+
* const startRange = [0, 5];
|
|
39
|
+
* const endRange = [10, 15];
|
|
40
|
+
* const joinedRange = joinRanges(startRange, endRange);
|
|
41
|
+
* console.log(joinedRange); // [0, 15]
|
|
42
|
+
* ```
|
|
43
|
+
*
|
|
44
|
+
*/
|
|
45
|
+
const joinRanges = (startRange, endRange) => {
|
|
46
|
+
if (!endRange)
|
|
47
|
+
return startRange;
|
|
48
|
+
if (!startRange)
|
|
49
|
+
return endRange;
|
|
50
|
+
return [startRange[0], endRange[1]];
|
|
51
|
+
};
|
|
52
|
+
/**
|
|
53
|
+
* Helper function used to generate a string representation of a
|
|
54
|
+
* [member expression](https://github.com/estree/estree/blob/master/es5.md#memberexpression).
|
|
55
|
+
* @example
|
|
56
|
+
* ```js
|
|
57
|
+
* const membersReversed = ["property1", "property2", "property3"]; // Members parsed from the AST
|
|
58
|
+
* const name = objectAndMembersToName("myObject", membersReversed);
|
|
59
|
+
*
|
|
60
|
+
* console.log(name); // "myObject.property1.property2.property3"
|
|
61
|
+
* ```
|
|
62
|
+
*
|
|
63
|
+
*/
|
|
64
|
+
const objectAndMembersToName = (object, membersReversed) => {
|
|
65
|
+
let name = object;
|
|
66
|
+
for (let i = membersReversed.length - 1; i >= 0; i--) {
|
|
67
|
+
name = `${name}.${membersReversed[i]}`;
|
|
68
|
+
}
|
|
69
|
+
return name;
|
|
70
|
+
};
|
|
71
|
+
/**
|
|
72
|
+
* Grabs the name of a given expression and returns it as a string or undefined. Has particular
|
|
73
|
+
* handling for [Identifiers](https://github.com/estree/estree/blob/master/es5.md#identifier),
|
|
74
|
+
* [ThisExpressions](https://github.com/estree/estree/blob/master/es5.md#identifier), and
|
|
75
|
+
* [MetaProperties](https://github.com/estree/estree/blob/master/es2015.md#metaproperty) which is
|
|
76
|
+
* specifically for handling the `new.target` meta property.
|
|
77
|
+
*/
|
|
78
|
+
const getRootName = expression => {
|
|
79
|
+
switch (expression.type) {
|
|
80
|
+
case 'Identifier':
|
|
81
|
+
return expression.name;
|
|
82
|
+
case 'ThisExpression':
|
|
83
|
+
return 'this';
|
|
84
|
+
case 'MetaProperty':
|
|
85
|
+
return `${expression.meta.name}.${expression.property.name}`;
|
|
86
|
+
default:
|
|
87
|
+
return undefined;
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
const defaultParserOptions = {
|
|
91
|
+
ranges: true,
|
|
92
|
+
locations: true,
|
|
93
|
+
ecmaVersion: 'latest',
|
|
94
|
+
sourceType: 'module',
|
|
95
|
+
// https://github.com/tc39/proposal-hashbang
|
|
96
|
+
allowHashBang: true,
|
|
97
|
+
onComment: null,
|
|
98
|
+
};
|
|
99
|
+
// regexp to match at least one "magic comment"
|
|
100
|
+
const webpackCommentRegExp = new RegExp(/(^|\W)webpack[A-Z]{1,}[A-Za-z]{1,}:/);
|
|
101
|
+
const EMPTY_COMMENT_OPTIONS = {
|
|
102
|
+
options: null,
|
|
103
|
+
errors: null,
|
|
104
|
+
};
|
|
105
|
+
class JavascriptParser extends Parser_1.default {
|
|
106
|
+
constructor(sourceType = 'auto') {
|
|
107
|
+
super();
|
|
108
|
+
this.hooks = Object.freeze({
|
|
109
|
+
evaluateTypeof: new tapable_1.HookMap(() => new tapable_1.SyncBailHook(['expression'])),
|
|
110
|
+
evaluate: new tapable_1.HookMap(() => new tapable_1.SyncBailHook(['expression'])),
|
|
111
|
+
evaluateIdentifier: new tapable_1.HookMap(() => new tapable_1.SyncBailHook(['expression'])),
|
|
112
|
+
evaluateDefinedIdentifier: new tapable_1.HookMap(() => new tapable_1.SyncBailHook(['expression'])),
|
|
113
|
+
evaluateNewExpression: new tapable_1.HookMap(() => new tapable_1.SyncBailHook(['expression'])),
|
|
114
|
+
evaluateCallExpression: new tapable_1.HookMap(() => new tapable_1.SyncBailHook(['expression'])),
|
|
115
|
+
evaluateCallExpressionMember: new tapable_1.HookMap(() => new tapable_1.SyncBailHook(['expression', 'param'])),
|
|
116
|
+
isPure: new tapable_1.HookMap(() => new tapable_1.SyncBailHook(['expression', 'commentsStartPosition'])),
|
|
117
|
+
preStatement: new tapable_1.SyncBailHook(['statement']),
|
|
118
|
+
blockPreStatement: new tapable_1.SyncBailHook(['declaration']),
|
|
119
|
+
statement: new tapable_1.SyncBailHook(['statement']),
|
|
120
|
+
statementIf: new tapable_1.SyncBailHook(['statement']),
|
|
121
|
+
classExtendsExpression: new tapable_1.SyncBailHook(['expression', 'classDefinition']),
|
|
122
|
+
classBodyElement: new tapable_1.SyncBailHook(['element', 'classDefinition']),
|
|
123
|
+
classBodyValue: new tapable_1.SyncBailHook(['expression', 'element', 'classDefinition']),
|
|
124
|
+
label: new tapable_1.HookMap(() => new tapable_1.SyncBailHook(['statement'])),
|
|
125
|
+
import: new tapable_1.SyncBailHook(['statement', 'source']),
|
|
126
|
+
importSpecifier: new tapable_1.SyncBailHook([
|
|
127
|
+
'statement',
|
|
128
|
+
'source',
|
|
129
|
+
'exportName',
|
|
130
|
+
'identifierName',
|
|
131
|
+
]),
|
|
132
|
+
export: new tapable_1.SyncBailHook(['statement']),
|
|
133
|
+
exportImport: new tapable_1.SyncBailHook(['statement', 'source']),
|
|
134
|
+
exportDeclaration: new tapable_1.SyncBailHook(['statement', 'declaration']),
|
|
135
|
+
exportExpression: new tapable_1.SyncBailHook(['statement', 'declaration']),
|
|
136
|
+
exportSpecifier: new tapable_1.SyncBailHook([
|
|
137
|
+
'statement',
|
|
138
|
+
'identifierName',
|
|
139
|
+
'exportName',
|
|
140
|
+
'index',
|
|
141
|
+
]),
|
|
142
|
+
exportImportSpecifier: new tapable_1.SyncBailHook([
|
|
143
|
+
'statement',
|
|
144
|
+
'source',
|
|
145
|
+
'identifierName',
|
|
146
|
+
'exportName',
|
|
147
|
+
'index',
|
|
148
|
+
]),
|
|
149
|
+
preDeclarator: new tapable_1.SyncBailHook(['declarator', 'statement']),
|
|
150
|
+
declarator: new tapable_1.SyncBailHook(['declarator', 'statement']),
|
|
151
|
+
varDeclaration: new tapable_1.HookMap(() => new tapable_1.SyncBailHook(['declaration'])),
|
|
152
|
+
varDeclarationLet: new tapable_1.HookMap(() => new tapable_1.SyncBailHook(['declaration'])),
|
|
153
|
+
varDeclarationConst: new tapable_1.HookMap(() => new tapable_1.SyncBailHook(['declaration'])),
|
|
154
|
+
varDeclarationVar: new tapable_1.HookMap(() => new tapable_1.SyncBailHook(['declaration'])),
|
|
155
|
+
pattern: new tapable_1.HookMap(() => new tapable_1.SyncBailHook(['pattern'])),
|
|
156
|
+
canRename: new tapable_1.HookMap(() => new tapable_1.SyncBailHook(['initExpression'])),
|
|
157
|
+
rename: new tapable_1.HookMap(() => new tapable_1.SyncBailHook(['initExpression'])),
|
|
158
|
+
assign: new tapable_1.HookMap(() => new tapable_1.SyncBailHook(['expression'])),
|
|
159
|
+
assignMemberChain: new tapable_1.HookMap(() => new tapable_1.SyncBailHook(['expression', 'members'])),
|
|
160
|
+
typeof: new tapable_1.HookMap(() => new tapable_1.SyncBailHook(['expression'])),
|
|
161
|
+
importCall: new tapable_1.SyncBailHook(['expression']),
|
|
162
|
+
topLevelAwait: new tapable_1.SyncBailHook(['expression']),
|
|
163
|
+
call: new tapable_1.HookMap(() => new tapable_1.SyncBailHook(['expression'])),
|
|
164
|
+
/** Something like "a.b()" */
|
|
165
|
+
callMemberChain: new tapable_1.HookMap(() => new tapable_1.SyncBailHook([
|
|
166
|
+
'expression',
|
|
167
|
+
'members',
|
|
168
|
+
'membersOptionals',
|
|
169
|
+
'memberRanges',
|
|
170
|
+
])),
|
|
171
|
+
/** Something like "a.b().c.d" */
|
|
172
|
+
memberChainOfCallMemberChain: new tapable_1.HookMap(() => new tapable_1.SyncBailHook([
|
|
173
|
+
'expression',
|
|
174
|
+
'calleeMembers',
|
|
175
|
+
'callExpression',
|
|
176
|
+
'members',
|
|
177
|
+
])),
|
|
178
|
+
/** Something like "a.b().c.d()"" */
|
|
179
|
+
callMemberChainOfCallMemberChain: new tapable_1.HookMap(() => new tapable_1.SyncBailHook([
|
|
180
|
+
'expression',
|
|
181
|
+
'calleeMembers',
|
|
182
|
+
'innerCallExpression',
|
|
183
|
+
'members',
|
|
184
|
+
])),
|
|
185
|
+
optionalChaining: new tapable_1.SyncBailHook(['optionalChaining']),
|
|
186
|
+
new: new tapable_1.HookMap(() => new tapable_1.SyncBailHook(['expression'])),
|
|
187
|
+
binaryExpression: new tapable_1.SyncBailHook(['binaryExpression']),
|
|
188
|
+
expression: new tapable_1.HookMap(() => new tapable_1.SyncBailHook(['expression'])),
|
|
189
|
+
expressionMemberChain: new tapable_1.HookMap(() => new tapable_1.SyncBailHook([
|
|
190
|
+
'expression',
|
|
191
|
+
'members',
|
|
192
|
+
'membersOptionals',
|
|
193
|
+
'memberRanges',
|
|
194
|
+
])),
|
|
195
|
+
unhandledExpressionMemberChain: new tapable_1.HookMap(() => new tapable_1.SyncBailHook(['expression', 'members'])),
|
|
196
|
+
expressionConditionalOperator: new tapable_1.SyncBailHook(['expression']),
|
|
197
|
+
expressionLogicalOperator: new tapable_1.SyncBailHook(['expression']),
|
|
198
|
+
program: new tapable_1.SyncBailHook(['ast', 'comments']),
|
|
199
|
+
finish: new tapable_1.SyncBailHook(['ast', 'comments']),
|
|
200
|
+
});
|
|
201
|
+
this.sourceType = sourceType;
|
|
202
|
+
this.scope = undefined;
|
|
203
|
+
this.state = undefined;
|
|
204
|
+
this.comments = undefined;
|
|
205
|
+
this.semicolons = undefined;
|
|
206
|
+
this.statementPath = undefined;
|
|
207
|
+
this.prevStatement = undefined;
|
|
208
|
+
this.destructuringAssignmentProperties = undefined;
|
|
209
|
+
this.currentTagData = undefined;
|
|
210
|
+
this._initializeEvaluating();
|
|
211
|
+
}
|
|
212
|
+
_initializeEvaluating() {
|
|
213
|
+
this.hooks.evaluate.for('Literal').tap('JavascriptParser', _expr => {
|
|
214
|
+
const expr = _expr;
|
|
215
|
+
switch (typeof expr.value) {
|
|
216
|
+
case 'number':
|
|
217
|
+
return new BasicEvaluatedExpression_1.default().setNumber(expr.value).setRange(expr.range);
|
|
218
|
+
case 'bigint':
|
|
219
|
+
return new BasicEvaluatedExpression_1.default().setBigInt(expr.value).setRange(expr.range);
|
|
220
|
+
case 'string':
|
|
221
|
+
return new BasicEvaluatedExpression_1.default().setString(expr.value).setRange(expr.range);
|
|
222
|
+
case 'boolean':
|
|
223
|
+
return new BasicEvaluatedExpression_1.default().setBoolean(expr.value).setRange(expr.range);
|
|
224
|
+
}
|
|
225
|
+
if (expr.value === null) {
|
|
226
|
+
return new BasicEvaluatedExpression_1.default().setNull().setRange(expr.range);
|
|
227
|
+
}
|
|
228
|
+
if (expr.value instanceof RegExp) {
|
|
229
|
+
return new BasicEvaluatedExpression_1.default().setRegExp(expr.value).setRange(expr.range);
|
|
230
|
+
}
|
|
231
|
+
});
|
|
232
|
+
this.hooks.evaluate.for('NewExpression').tap('JavascriptParser', _expr => {
|
|
233
|
+
const expr = _expr;
|
|
234
|
+
const callee = expr.callee;
|
|
235
|
+
if (callee.type !== 'Identifier')
|
|
236
|
+
return;
|
|
237
|
+
if (callee.name !== 'RegExp') {
|
|
238
|
+
return this.callHooksForName(this.hooks.evaluateNewExpression, callee.name, expr);
|
|
239
|
+
}
|
|
240
|
+
if (expr.arguments.length > 2 || this.getVariableInfo('RegExp') !== 'RegExp')
|
|
241
|
+
return;
|
|
242
|
+
let regExp;
|
|
243
|
+
let flags;
|
|
244
|
+
const arg1 = expr.arguments[0];
|
|
245
|
+
if (arg1) {
|
|
246
|
+
if (arg1.type === 'SpreadElement')
|
|
247
|
+
return;
|
|
248
|
+
const evaluatedRegExp = this.evaluateExpression(arg1);
|
|
249
|
+
if (!evaluatedRegExp)
|
|
250
|
+
return;
|
|
251
|
+
regExp = evaluatedRegExp.asString();
|
|
252
|
+
if (!regExp)
|
|
253
|
+
return;
|
|
254
|
+
}
|
|
255
|
+
else {
|
|
256
|
+
return new BasicEvaluatedExpression_1.default().setRegExp(new RegExp('')).setRange(expr.range);
|
|
257
|
+
}
|
|
258
|
+
const arg2 = expr.arguments[1];
|
|
259
|
+
if (arg2) {
|
|
260
|
+
if (arg2.type === 'SpreadElement')
|
|
261
|
+
return;
|
|
262
|
+
const evaluatedFlags = this.evaluateExpression(arg2);
|
|
263
|
+
if (!evaluatedFlags)
|
|
264
|
+
return;
|
|
265
|
+
if (!evaluatedFlags.isUndefined()) {
|
|
266
|
+
flags = evaluatedFlags.asString();
|
|
267
|
+
if (flags === undefined || !BasicEvaluatedExpression_1.default.isValidRegExpFlags(flags))
|
|
268
|
+
return;
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
return new BasicEvaluatedExpression_1.default()
|
|
272
|
+
.setRegExp(flags ? new RegExp(regExp, flags) : new RegExp(regExp))
|
|
273
|
+
.setRange(expr.range);
|
|
274
|
+
});
|
|
275
|
+
this.hooks.evaluate.for('LogicalExpression').tap('JavascriptParser', _expr => {
|
|
276
|
+
const expr = _expr;
|
|
277
|
+
const left = this.evaluateExpression(expr.left);
|
|
278
|
+
let returnRight = false;
|
|
279
|
+
let allowedRight;
|
|
280
|
+
if (expr.operator === '&&') {
|
|
281
|
+
const leftAsBool = left.asBool();
|
|
282
|
+
if (leftAsBool === false)
|
|
283
|
+
return left.setRange(expr.range);
|
|
284
|
+
returnRight = leftAsBool === true;
|
|
285
|
+
allowedRight = false;
|
|
286
|
+
}
|
|
287
|
+
else if (expr.operator === '||') {
|
|
288
|
+
const leftAsBool = left.asBool();
|
|
289
|
+
if (leftAsBool === true)
|
|
290
|
+
return left.setRange(expr.range);
|
|
291
|
+
returnRight = leftAsBool === false;
|
|
292
|
+
allowedRight = true;
|
|
293
|
+
}
|
|
294
|
+
else if (expr.operator === '??') {
|
|
295
|
+
const leftAsNullish = left.asNullish();
|
|
296
|
+
if (leftAsNullish === false)
|
|
297
|
+
return left.setRange(expr.range);
|
|
298
|
+
if (leftAsNullish !== true)
|
|
299
|
+
return;
|
|
300
|
+
returnRight = true;
|
|
301
|
+
}
|
|
302
|
+
else
|
|
303
|
+
return;
|
|
304
|
+
const right = this.evaluateExpression(expr.right);
|
|
305
|
+
if (returnRight) {
|
|
306
|
+
if (left.couldHaveSideEffects())
|
|
307
|
+
right.setSideEffects();
|
|
308
|
+
return right.setRange(expr.range);
|
|
309
|
+
}
|
|
310
|
+
const asBool = right.asBool();
|
|
311
|
+
if (allowedRight === true && asBool === true) {
|
|
312
|
+
return new BasicEvaluatedExpression_1.default().setRange(expr.range).setTruthy();
|
|
313
|
+
}
|
|
314
|
+
if (allowedRight === false && asBool === false) {
|
|
315
|
+
return new BasicEvaluatedExpression_1.default().setRange(expr.range).setFalsy();
|
|
316
|
+
}
|
|
317
|
+
});
|
|
318
|
+
/**
|
|
319
|
+
* In simple logical cases, we can use valueAsExpression to assist us in evaluating the expression on
|
|
320
|
+
* either side of a [BinaryExpression](https://github.com/estree/estree/blob/master/es5.md#binaryexpression).
|
|
321
|
+
* This supports scenarios in webpack like conditionally `import()`'ing modules based on some simple evaluation:
|
|
322
|
+
*
|
|
323
|
+
* ```js
|
|
324
|
+
* if (1 === 3) {
|
|
325
|
+
* import("./moduleA"); // webpack will auto evaluate this and not import the modules
|
|
326
|
+
* }
|
|
327
|
+
* ```
|
|
328
|
+
*
|
|
329
|
+
* Additional scenarios include evaluation of strings inside of dynamic import statements:
|
|
330
|
+
*
|
|
331
|
+
* ```js
|
|
332
|
+
* const foo = "foo";
|
|
333
|
+
* const bar = "bar";
|
|
334
|
+
*
|
|
335
|
+
* import("./" + foo + bar); // webpack will auto evaluate this into import("./foobar")
|
|
336
|
+
* ```
|
|
337
|
+
* @param {boolean | number | BigInt | string} value the value to convert to an expression
|
|
338
|
+
* @param {BinaryExpression | UnaryExpression} expr the expression being evaluated
|
|
339
|
+
* @param {boolean} sideEffects whether the expression has side effects
|
|
340
|
+
* @returns {BasicEvaluatedExpression | undefined} the evaluated expression
|
|
341
|
+
* @example
|
|
342
|
+
*
|
|
343
|
+
* ```js
|
|
344
|
+
* const binaryExpr = new BinaryExpression("+",
|
|
345
|
+
* { type: "Literal", value: 2 },
|
|
346
|
+
* { type: "Literal", value: 3 }
|
|
347
|
+
* );
|
|
348
|
+
*
|
|
349
|
+
* const leftValue = 2;
|
|
350
|
+
* const rightValue = 3;
|
|
351
|
+
*
|
|
352
|
+
* const leftExpr = valueAsExpression(leftValue, binaryExpr.left, false);
|
|
353
|
+
* const rightExpr = valueAsExpression(rightValue, binaryExpr.right, false);
|
|
354
|
+
* const result = new BasicEvaluatedExpression()
|
|
355
|
+
* .setNumber(leftExpr.number + rightExpr.number)
|
|
356
|
+
* .setRange(binaryExpr.range);
|
|
357
|
+
*
|
|
358
|
+
* console.log(result.number); // Output: 5
|
|
359
|
+
* ```
|
|
360
|
+
*/
|
|
361
|
+
const valueAsExpression = (value, expr, sideEffects) => {
|
|
362
|
+
switch (typeof value) {
|
|
363
|
+
case 'boolean':
|
|
364
|
+
return new BasicEvaluatedExpression_1.default()
|
|
365
|
+
.setBoolean(value)
|
|
366
|
+
.setSideEffects(sideEffects)
|
|
367
|
+
.setRange(expr.range);
|
|
368
|
+
case 'number':
|
|
369
|
+
return new BasicEvaluatedExpression_1.default()
|
|
370
|
+
.setNumber(value)
|
|
371
|
+
.setSideEffects(sideEffects)
|
|
372
|
+
.setRange(expr.range);
|
|
373
|
+
case 'bigint':
|
|
374
|
+
return new BasicEvaluatedExpression_1.default()
|
|
375
|
+
.setBigInt(value)
|
|
376
|
+
.setSideEffects(sideEffects)
|
|
377
|
+
.setRange(expr.range);
|
|
378
|
+
case 'string':
|
|
379
|
+
return new BasicEvaluatedExpression_1.default()
|
|
380
|
+
.setString(value)
|
|
381
|
+
.setSideEffects(sideEffects)
|
|
382
|
+
.setRange(expr.range);
|
|
383
|
+
}
|
|
384
|
+
};
|
|
385
|
+
this.hooks.evaluate.for('BinaryExpression').tap('JavascriptParser', _expr => {
|
|
386
|
+
var _a, _b, _c;
|
|
387
|
+
const expr = _expr;
|
|
388
|
+
/**
|
|
389
|
+
* Evaluates a binary expression if and only if it is a const operation (e.g. 1 + 2, "a" + "b", etc.).
|
|
390
|
+
*
|
|
391
|
+
* @template T
|
|
392
|
+
* @param {(leftOperand: T, rightOperand: T) => boolean | number | BigInt | string} operandHandler the handler for the operation (e.g. (a, b) => a + b)
|
|
393
|
+
* @returns {BasicEvaluatedExpression | undefined} the evaluated expression
|
|
394
|
+
*/
|
|
395
|
+
const handleConstOperation = operandHandler => {
|
|
396
|
+
const left = this.evaluateExpression(expr.left);
|
|
397
|
+
if (!left.isCompileTimeValue())
|
|
398
|
+
return;
|
|
399
|
+
const right = this.evaluateExpression(expr.right);
|
|
400
|
+
if (!right.isCompileTimeValue())
|
|
401
|
+
return;
|
|
402
|
+
const result = operandHandler(left.asCompileTimeValue(), right.asCompileTimeValue());
|
|
403
|
+
return valueAsExpression(result, expr, left.couldHaveSideEffects() || right.couldHaveSideEffects());
|
|
404
|
+
};
|
|
405
|
+
/**
|
|
406
|
+
* Helper function to determine if two booleans are always different. This is used in `handleStrictEqualityComparison`
|
|
407
|
+
* to determine if an expressions boolean or nullish conversion is equal or not.
|
|
408
|
+
*
|
|
409
|
+
* @param {boolean} a first boolean to compare
|
|
410
|
+
* @param {boolean} b second boolean to compare
|
|
411
|
+
* @returns {boolean} true if the two booleans are always different, false otherwise
|
|
412
|
+
*/
|
|
413
|
+
const isAlwaysDifferent = (a, b) => (a === true && b === false) || (a === false && b === true);
|
|
414
|
+
const handleTemplateStringCompare = (left, right, res, eql) => {
|
|
415
|
+
const getPrefix = parts => {
|
|
416
|
+
let value = '';
|
|
417
|
+
for (const p of parts) {
|
|
418
|
+
const v = p.asString();
|
|
419
|
+
if (v !== undefined)
|
|
420
|
+
value += v;
|
|
421
|
+
else
|
|
422
|
+
break;
|
|
423
|
+
}
|
|
424
|
+
return value;
|
|
425
|
+
};
|
|
426
|
+
const getSuffix = parts => {
|
|
427
|
+
let value = '';
|
|
428
|
+
for (let i = parts.length - 1; i >= 0; i--) {
|
|
429
|
+
const v = parts[i].asString();
|
|
430
|
+
if (v !== undefined)
|
|
431
|
+
value = v + value;
|
|
432
|
+
else
|
|
433
|
+
break;
|
|
434
|
+
}
|
|
435
|
+
return value;
|
|
436
|
+
};
|
|
437
|
+
const leftPrefix = getPrefix(left.parts);
|
|
438
|
+
const rightPrefix = getPrefix(right.parts);
|
|
439
|
+
const leftSuffix = getSuffix(left.parts);
|
|
440
|
+
const rightSuffix = getSuffix(right.parts);
|
|
441
|
+
const lenPrefix = Math.min(leftPrefix.length, rightPrefix.length);
|
|
442
|
+
const lenSuffix = Math.min(leftSuffix.length, rightSuffix.length);
|
|
443
|
+
const prefixMismatch = lenPrefix > 0 && leftPrefix.slice(0, lenPrefix) !== rightPrefix.slice(0, lenPrefix);
|
|
444
|
+
const suffixMismatch = lenSuffix > 0 && leftSuffix.slice(-lenSuffix) !== rightSuffix.slice(-lenSuffix);
|
|
445
|
+
if (prefixMismatch || suffixMismatch) {
|
|
446
|
+
return res
|
|
447
|
+
.setBoolean(!eql)
|
|
448
|
+
.setSideEffects(left.couldHaveSideEffects() || right.couldHaveSideEffects());
|
|
449
|
+
}
|
|
450
|
+
};
|
|
451
|
+
/**
|
|
452
|
+
* Helper function to handle BinaryExpressions using strict equality comparisons (e.g. "===" and "!==").
|
|
453
|
+
* @param {boolean} eql true for "===" and false for "!=="
|
|
454
|
+
* @returns {BasicEvaluatedExpression | undefined} the evaluated expression
|
|
455
|
+
*/
|
|
456
|
+
const handleStrictEqualityComparison = eql => {
|
|
457
|
+
const left = this.evaluateExpression(expr.left);
|
|
458
|
+
const right = this.evaluateExpression(expr.right);
|
|
459
|
+
const res = new BasicEvaluatedExpression_1.default();
|
|
460
|
+
res.setRange(expr.range);
|
|
461
|
+
const leftConst = left.isCompileTimeValue();
|
|
462
|
+
const rightConst = right.isCompileTimeValue();
|
|
463
|
+
if (leftConst && rightConst) {
|
|
464
|
+
return res
|
|
465
|
+
.setBoolean(eql === (left.asCompileTimeValue() === right.asCompileTimeValue()))
|
|
466
|
+
.setSideEffects(left.couldHaveSideEffects() || right.couldHaveSideEffects());
|
|
467
|
+
}
|
|
468
|
+
if (left.isArray() && right.isArray()) {
|
|
469
|
+
return res
|
|
470
|
+
.setBoolean(!eql)
|
|
471
|
+
.setSideEffects(left.couldHaveSideEffects() || right.couldHaveSideEffects());
|
|
472
|
+
}
|
|
473
|
+
if (left.isTemplateString() && right.isTemplateString()) {
|
|
474
|
+
return handleTemplateStringCompare(left, right, res, eql);
|
|
475
|
+
}
|
|
476
|
+
const leftPrimitive = left.isPrimitiveType();
|
|
477
|
+
const rightPrimitive = right.isPrimitiveType();
|
|
478
|
+
if (
|
|
479
|
+
// Primitive !== Object or
|
|
480
|
+
// compile-time object types are never equal to something at runtime
|
|
481
|
+
(leftPrimitive === false && (leftConst || rightPrimitive === true)) ||
|
|
482
|
+
(rightPrimitive === false && (rightConst || leftPrimitive === true)) ||
|
|
483
|
+
// Different nullish or boolish status also means not equal
|
|
484
|
+
isAlwaysDifferent(left.asBool(), right.asBool()) ||
|
|
485
|
+
isAlwaysDifferent(left.asNullish(), right.asNullish())) {
|
|
486
|
+
return res
|
|
487
|
+
.setBoolean(!eql)
|
|
488
|
+
.setSideEffects(left.couldHaveSideEffects() || right.couldHaveSideEffects());
|
|
489
|
+
}
|
|
490
|
+
};
|
|
491
|
+
/**
|
|
492
|
+
* Helper function to handle BinaryExpressions using abstract equality comparisons (e.g. "==" and "!=").
|
|
493
|
+
*/
|
|
494
|
+
const handleAbstractEqualityComparison = eql => {
|
|
495
|
+
const left = this.evaluateExpression(expr.left);
|
|
496
|
+
const right = this.evaluateExpression(expr.right);
|
|
497
|
+
const res = new BasicEvaluatedExpression_1.default();
|
|
498
|
+
res.setRange(expr.range);
|
|
499
|
+
const leftConst = left.isCompileTimeValue();
|
|
500
|
+
const rightConst = right.isCompileTimeValue();
|
|
501
|
+
if (leftConst && rightConst) {
|
|
502
|
+
return res
|
|
503
|
+
.setBoolean(eql ===
|
|
504
|
+
// eslint-disable-next-line eqeqeq
|
|
505
|
+
(left.asCompileTimeValue() == right.asCompileTimeValue()))
|
|
506
|
+
.setSideEffects(left.couldHaveSideEffects() || right.couldHaveSideEffects());
|
|
507
|
+
}
|
|
508
|
+
if (left.isArray() && right.isArray()) {
|
|
509
|
+
return res
|
|
510
|
+
.setBoolean(!eql)
|
|
511
|
+
.setSideEffects(left.couldHaveSideEffects() || right.couldHaveSideEffects());
|
|
512
|
+
}
|
|
513
|
+
if (left.isTemplateString() && right.isTemplateString()) {
|
|
514
|
+
return handleTemplateStringCompare(left, right, res, eql);
|
|
515
|
+
}
|
|
516
|
+
};
|
|
517
|
+
if (expr.operator === '+') {
|
|
518
|
+
const left = this.evaluateExpression(expr.left);
|
|
519
|
+
const right = this.evaluateExpression(expr.right);
|
|
520
|
+
const res = new BasicEvaluatedExpression_1.default();
|
|
521
|
+
if (left.isString()) {
|
|
522
|
+
if (right.isString()) {
|
|
523
|
+
res.setString(left.string + right.string);
|
|
524
|
+
}
|
|
525
|
+
else if (right.isNumber()) {
|
|
526
|
+
res.setString(left.string + right.number);
|
|
527
|
+
}
|
|
528
|
+
else if (right.isWrapped() && right.prefix && right.prefix.isString()) {
|
|
529
|
+
// "left" + ("prefix" + inner + "postfix")
|
|
530
|
+
// => ("leftPrefix" + inner + "postfix")
|
|
531
|
+
res.setWrapped(new BasicEvaluatedExpression_1.default()
|
|
532
|
+
.setString(left.string + right.prefix.string)
|
|
533
|
+
.setRange(joinRanges(left.range, right.prefix.range)), right.postfix, right.wrappedInnerExpressions);
|
|
534
|
+
}
|
|
535
|
+
else if (right.isWrapped()) {
|
|
536
|
+
// "left" + ([null] + inner + "postfix")
|
|
537
|
+
// => ("left" + inner + "postfix")
|
|
538
|
+
res.setWrapped(left, right.postfix, right.wrappedInnerExpressions);
|
|
539
|
+
}
|
|
540
|
+
else {
|
|
541
|
+
// "left" + expr
|
|
542
|
+
// => ("left" + expr + "")
|
|
543
|
+
res.setWrapped(left, null, [right]);
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
else if (left.isNumber()) {
|
|
547
|
+
if (right.isString()) {
|
|
548
|
+
res.setString(left.number + right.string);
|
|
549
|
+
}
|
|
550
|
+
else if (right.isNumber()) {
|
|
551
|
+
res.setNumber(left.number + right.number);
|
|
552
|
+
}
|
|
553
|
+
else {
|
|
554
|
+
return;
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
else if (left.isBigInt()) {
|
|
558
|
+
if (right.isBigInt()) {
|
|
559
|
+
res.setBigInt(left.bigint + right.bigint);
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
else if (left.isWrapped()) {
|
|
563
|
+
if (((_a = left.postfix) === null || _a === void 0 ? void 0 : _a.isString()) && right.isString()) {
|
|
564
|
+
// ("prefix" + inner + "postfix") + "right"
|
|
565
|
+
// => ("prefix" + inner + "postfixRight")
|
|
566
|
+
res.setWrapped(left.prefix, new BasicEvaluatedExpression_1.default()
|
|
567
|
+
.setString(left.postfix.string + right.string)
|
|
568
|
+
.setRange(joinRanges(left.postfix.range, right.range)), left.wrappedInnerExpressions);
|
|
569
|
+
}
|
|
570
|
+
else if (((_b = left.postfix) === null || _b === void 0 ? void 0 : _b.isString()) && right.isNumber()) {
|
|
571
|
+
// ("prefix" + inner + "postfix") + 123
|
|
572
|
+
// => ("prefix" + inner + "postfix123")
|
|
573
|
+
res.setWrapped(left.prefix, new BasicEvaluatedExpression_1.default()
|
|
574
|
+
.setString(left.postfix.string + right.number)
|
|
575
|
+
.setRange(joinRanges(left.postfix.range, right.range)), left.wrappedInnerExpressions);
|
|
576
|
+
}
|
|
577
|
+
else if (right.isString()) {
|
|
578
|
+
// ("prefix" + inner + [null]) + "right"
|
|
579
|
+
// => ("prefix" + inner + "right")
|
|
580
|
+
res.setWrapped(left.prefix, right, left.wrappedInnerExpressions);
|
|
581
|
+
}
|
|
582
|
+
else if (right.isNumber()) {
|
|
583
|
+
// ("prefix" + inner + [null]) + 123
|
|
584
|
+
// => ("prefix" + inner + "123")
|
|
585
|
+
res.setWrapped(left.prefix, new BasicEvaluatedExpression_1.default().setString(`${right.number}`).setRange(right.range), left.wrappedInnerExpressions);
|
|
586
|
+
}
|
|
587
|
+
else if (right.isWrapped()) {
|
|
588
|
+
// ("prefix1" + inner1 + "postfix1") + ("prefix2" + inner2 + "postfix2")
|
|
589
|
+
// ("prefix1" + inner1 + "postfix1" + "prefix2" + inner2 + "postfix2")
|
|
590
|
+
res.setWrapped(left.prefix, right.postfix, left.wrappedInnerExpressions &&
|
|
591
|
+
right.wrappedInnerExpressions &&
|
|
592
|
+
left.wrappedInnerExpressions
|
|
593
|
+
.concat(left.postfix ? [left.postfix] : [])
|
|
594
|
+
.concat(right.prefix ? [right.prefix] : [])
|
|
595
|
+
.concat(right.wrappedInnerExpressions));
|
|
596
|
+
}
|
|
597
|
+
else {
|
|
598
|
+
// ("prefix" + inner + postfix) + expr
|
|
599
|
+
// => ("prefix" + inner + postfix + expr + [null])
|
|
600
|
+
res.setWrapped(left.prefix, null, (_c = left.wrappedInnerExpressions) === null || _c === void 0 ? void 0 : _c.concat(left.postfix ? [left.postfix, right] : [right]));
|
|
601
|
+
}
|
|
602
|
+
}
|
|
603
|
+
else if (right.isString()) {
|
|
604
|
+
// left + "right"
|
|
605
|
+
// => ([null] + left + "right")
|
|
606
|
+
res.setWrapped(null, right, [left]);
|
|
607
|
+
}
|
|
608
|
+
else if (right.isWrapped()) {
|
|
609
|
+
// left + (prefix + inner + "postfix")
|
|
610
|
+
// => ([null] + left + prefix + inner + "postfix")
|
|
611
|
+
res.setWrapped(null, right.postfix, right.wrappedInnerExpressions &&
|
|
612
|
+
(right.prefix ? [left, right.prefix] : [left]).concat(right.wrappedInnerExpressions));
|
|
613
|
+
}
|
|
614
|
+
else {
|
|
615
|
+
return;
|
|
616
|
+
}
|
|
617
|
+
if (left.couldHaveSideEffects() || right.couldHaveSideEffects())
|
|
618
|
+
res.setSideEffects();
|
|
619
|
+
res.setRange(expr.range);
|
|
620
|
+
return res;
|
|
621
|
+
}
|
|
622
|
+
if (expr.operator === '-') {
|
|
623
|
+
return handleConstOperation((l, r) => l - r);
|
|
624
|
+
}
|
|
625
|
+
if (expr.operator === '*') {
|
|
626
|
+
return handleConstOperation((l, r) => l * r);
|
|
627
|
+
}
|
|
628
|
+
if (expr.operator === '/') {
|
|
629
|
+
return handleConstOperation((l, r) => l / r);
|
|
630
|
+
}
|
|
631
|
+
if (expr.operator === '**') {
|
|
632
|
+
return handleConstOperation((l, r) => Math.pow(l, r));
|
|
633
|
+
}
|
|
634
|
+
if (expr.operator === '===') {
|
|
635
|
+
return handleStrictEqualityComparison(true);
|
|
636
|
+
}
|
|
637
|
+
if (expr.operator === '==') {
|
|
638
|
+
return handleAbstractEqualityComparison(true);
|
|
639
|
+
}
|
|
640
|
+
if (expr.operator === '!==') {
|
|
641
|
+
return handleStrictEqualityComparison(false);
|
|
642
|
+
}
|
|
643
|
+
if (expr.operator === '!=') {
|
|
644
|
+
return handleAbstractEqualityComparison(false);
|
|
645
|
+
}
|
|
646
|
+
if (expr.operator === '&') {
|
|
647
|
+
return handleConstOperation((l, r) => l & r);
|
|
648
|
+
}
|
|
649
|
+
if (expr.operator === '|') {
|
|
650
|
+
return handleConstOperation((l, r) => l | r);
|
|
651
|
+
}
|
|
652
|
+
if (expr.operator === '^') {
|
|
653
|
+
return handleConstOperation((l, r) => l ^ r);
|
|
654
|
+
}
|
|
655
|
+
if (expr.operator === '>>>') {
|
|
656
|
+
return handleConstOperation((l, r) => l >>> r);
|
|
657
|
+
}
|
|
658
|
+
if (expr.operator === '>>') {
|
|
659
|
+
return handleConstOperation((l, r) => l >> r);
|
|
660
|
+
}
|
|
661
|
+
if (expr.operator === '<<') {
|
|
662
|
+
return handleConstOperation((l, r) => l << r);
|
|
663
|
+
}
|
|
664
|
+
if (expr.operator === '<') {
|
|
665
|
+
return handleConstOperation((l, r) => l < r);
|
|
666
|
+
}
|
|
667
|
+
if (expr.operator === '>') {
|
|
668
|
+
return handleConstOperation((l, r) => l > r);
|
|
669
|
+
}
|
|
670
|
+
if (expr.operator === '<=') {
|
|
671
|
+
return handleConstOperation((l, r) => l <= r);
|
|
672
|
+
}
|
|
673
|
+
if (expr.operator === '>=') {
|
|
674
|
+
return handleConstOperation((l, r) => l >= r);
|
|
675
|
+
}
|
|
676
|
+
});
|
|
677
|
+
this.hooks.evaluate.for('UnaryExpression').tap('JavascriptParser', _expr => {
|
|
678
|
+
const expr = _expr;
|
|
679
|
+
/**
|
|
680
|
+
* Evaluates a UnaryExpression if and only if it is a basic const operator (e.g. +a, -a, ~a).
|
|
681
|
+
*
|
|
682
|
+
* @template T
|
|
683
|
+
* @param {(operand: T) => boolean | number | BigInt | string} operandHandler handler for the operand
|
|
684
|
+
* @returns {BasicEvaluatedExpression | undefined} evaluated expression
|
|
685
|
+
*/
|
|
686
|
+
const handleConstOperation = operandHandler => {
|
|
687
|
+
const argument = this.evaluateExpression(expr.argument);
|
|
688
|
+
if (!argument.isCompileTimeValue())
|
|
689
|
+
return;
|
|
690
|
+
const result = operandHandler(argument.asCompileTimeValue());
|
|
691
|
+
return valueAsExpression(result, expr, argument.couldHaveSideEffects());
|
|
692
|
+
};
|
|
693
|
+
if (expr.operator === 'typeof') {
|
|
694
|
+
switch (expr.argument.type) {
|
|
695
|
+
case 'Identifier': {
|
|
696
|
+
const res = this.callHooksForName(this.hooks.evaluateTypeof, expr.argument.name, expr);
|
|
697
|
+
if (res !== undefined)
|
|
698
|
+
return res;
|
|
699
|
+
break;
|
|
700
|
+
}
|
|
701
|
+
case 'MetaProperty': {
|
|
702
|
+
const res = this.callHooksForName(this.hooks.evaluateTypeof, getRootName(expr.argument), expr);
|
|
703
|
+
if (res !== undefined)
|
|
704
|
+
return res;
|
|
705
|
+
break;
|
|
706
|
+
}
|
|
707
|
+
case 'MemberExpression': {
|
|
708
|
+
const res = this.callHooksForExpression(this.hooks.evaluateTypeof, expr.argument, expr);
|
|
709
|
+
if (res !== undefined)
|
|
710
|
+
return res;
|
|
711
|
+
break;
|
|
712
|
+
}
|
|
713
|
+
case 'ChainExpression': {
|
|
714
|
+
const res = this.callHooksForExpression(this.hooks.evaluateTypeof, expr.argument.expression, expr);
|
|
715
|
+
if (res !== undefined)
|
|
716
|
+
return res;
|
|
717
|
+
break;
|
|
718
|
+
}
|
|
719
|
+
case 'FunctionExpression': {
|
|
720
|
+
return new BasicEvaluatedExpression_1.default().setString('function').setRange(expr.range);
|
|
721
|
+
}
|
|
722
|
+
}
|
|
723
|
+
const arg = this.evaluateExpression(expr.argument);
|
|
724
|
+
if (arg.isUnknown())
|
|
725
|
+
return;
|
|
726
|
+
if (arg.isString()) {
|
|
727
|
+
return new BasicEvaluatedExpression_1.default().setString('string').setRange(expr.range);
|
|
728
|
+
}
|
|
729
|
+
if (arg.isWrapped()) {
|
|
730
|
+
return new BasicEvaluatedExpression_1.default()
|
|
731
|
+
.setString('string')
|
|
732
|
+
.setSideEffects()
|
|
733
|
+
.setRange(expr.range);
|
|
734
|
+
}
|
|
735
|
+
if (arg.isUndefined()) {
|
|
736
|
+
return new BasicEvaluatedExpression_1.default().setString('undefined').setRange(expr.range);
|
|
737
|
+
}
|
|
738
|
+
if (arg.isNumber()) {
|
|
739
|
+
return new BasicEvaluatedExpression_1.default().setString('number').setRange(expr.range);
|
|
740
|
+
}
|
|
741
|
+
if (arg.isBigInt()) {
|
|
742
|
+
return new BasicEvaluatedExpression_1.default().setString('bigint').setRange(expr.range);
|
|
743
|
+
}
|
|
744
|
+
if (arg.isBoolean()) {
|
|
745
|
+
return new BasicEvaluatedExpression_1.default().setString('boolean').setRange(expr.range);
|
|
746
|
+
}
|
|
747
|
+
if (arg.isConstArray() || arg.isRegExp() || arg.isNull()) {
|
|
748
|
+
return new BasicEvaluatedExpression_1.default().setString('object').setRange(expr.range);
|
|
749
|
+
}
|
|
750
|
+
if (arg.isArray()) {
|
|
751
|
+
return new BasicEvaluatedExpression_1.default()
|
|
752
|
+
.setString('object')
|
|
753
|
+
.setSideEffects(arg.couldHaveSideEffects())
|
|
754
|
+
.setRange(expr.range);
|
|
755
|
+
}
|
|
756
|
+
}
|
|
757
|
+
else if (expr.operator === '!') {
|
|
758
|
+
const argument = this.evaluateExpression(expr.argument);
|
|
759
|
+
const bool = argument.asBool();
|
|
760
|
+
if (typeof bool !== 'boolean')
|
|
761
|
+
return;
|
|
762
|
+
return new BasicEvaluatedExpression_1.default()
|
|
763
|
+
.setBoolean(!bool)
|
|
764
|
+
.setSideEffects(argument.couldHaveSideEffects())
|
|
765
|
+
.setRange(expr.range);
|
|
766
|
+
}
|
|
767
|
+
else if (expr.operator === '~') {
|
|
768
|
+
return handleConstOperation(v => ~v);
|
|
769
|
+
}
|
|
770
|
+
else if (expr.operator === '+') {
|
|
771
|
+
return handleConstOperation(v => +v);
|
|
772
|
+
}
|
|
773
|
+
else if (expr.operator === '-') {
|
|
774
|
+
return handleConstOperation(v => -v);
|
|
775
|
+
}
|
|
776
|
+
});
|
|
777
|
+
this.hooks.evaluateTypeof.for('undefined').tap('JavascriptParser', expr => new BasicEvaluatedExpression_1.default().setString('undefined').setRange(expr.range));
|
|
778
|
+
this.hooks.evaluate.for('Identifier').tap('JavascriptParser', expr => {
|
|
779
|
+
if (expr.name === 'undefined') {
|
|
780
|
+
return new BasicEvaluatedExpression_1.default().setUndefined().setRange(expr.range);
|
|
781
|
+
}
|
|
782
|
+
});
|
|
783
|
+
/**
|
|
784
|
+
* @param {string} exprType expression type name
|
|
785
|
+
* @param {function(Expression): GetInfoResult | undefined} getInfo get info
|
|
786
|
+
* @returns {void}
|
|
787
|
+
*/
|
|
788
|
+
const tapEvaluateWithVariableInfo = (exprType, getInfo) => {
|
|
789
|
+
let cachedExpression;
|
|
790
|
+
let cachedInfo;
|
|
791
|
+
this.hooks.evaluate.for(exprType).tap('JavascriptParser', expr => {
|
|
792
|
+
const expression = expr;
|
|
793
|
+
const info = getInfo(expr);
|
|
794
|
+
if (info !== undefined) {
|
|
795
|
+
return this.callHooksForInfoWithFallback(this.hooks.evaluateIdentifier, info.name, name => {
|
|
796
|
+
cachedExpression = expression;
|
|
797
|
+
cachedInfo = info;
|
|
798
|
+
}, name => {
|
|
799
|
+
const hook = this.hooks.evaluateDefinedIdentifier.get(name);
|
|
800
|
+
if (hook !== undefined) {
|
|
801
|
+
return hook.call(expression);
|
|
802
|
+
}
|
|
803
|
+
}, expression);
|
|
804
|
+
}
|
|
805
|
+
});
|
|
806
|
+
this.hooks.evaluate.for(exprType).tap({ name: 'JavascriptParser', stage: 100 }, expr => {
|
|
807
|
+
const info = cachedExpression === expr ? cachedInfo : getInfo(expr);
|
|
808
|
+
if (info !== undefined) {
|
|
809
|
+
return new BasicEvaluatedExpression_1.default()
|
|
810
|
+
.setIdentifier(info.name, info.rootInfo, info.getMembers, info.getMembersOptionals, info.getMemberRanges)
|
|
811
|
+
.setRange(expr.range);
|
|
812
|
+
}
|
|
813
|
+
});
|
|
814
|
+
this.hooks.finish.tap('JavascriptParser', () => {
|
|
815
|
+
// Cleanup for GC
|
|
816
|
+
cachedExpression = cachedInfo = undefined;
|
|
817
|
+
});
|
|
818
|
+
};
|
|
819
|
+
tapEvaluateWithVariableInfo('Identifier', expr => {
|
|
820
|
+
const info = this.getVariableInfo(expr.name);
|
|
821
|
+
if (typeof info === 'string' ||
|
|
822
|
+
(info instanceof VariableInfo && typeof info.freeName === 'string')) {
|
|
823
|
+
return {
|
|
824
|
+
name: info,
|
|
825
|
+
rootInfo: info,
|
|
826
|
+
getMembers: () => [],
|
|
827
|
+
getMembersOptionals: () => [],
|
|
828
|
+
getMemberRanges: () => [],
|
|
829
|
+
};
|
|
830
|
+
}
|
|
831
|
+
});
|
|
832
|
+
tapEvaluateWithVariableInfo('ThisExpression', expr => {
|
|
833
|
+
const info = this.getVariableInfo('this');
|
|
834
|
+
if (typeof info === 'string' ||
|
|
835
|
+
(info instanceof VariableInfo && typeof info.freeName === 'string')) {
|
|
836
|
+
return {
|
|
837
|
+
name: info,
|
|
838
|
+
rootInfo: info,
|
|
839
|
+
getMembers: () => [],
|
|
840
|
+
getMembersOptionals: () => [],
|
|
841
|
+
getMemberRanges: () => [],
|
|
842
|
+
};
|
|
843
|
+
}
|
|
844
|
+
});
|
|
845
|
+
this.hooks.evaluate.for('MetaProperty').tap('JavascriptParser', expr => {
|
|
846
|
+
const metaProperty = expr;
|
|
847
|
+
return this.callHooksForName(this.hooks.evaluateIdentifier, getRootName(expr), metaProperty);
|
|
848
|
+
});
|
|
849
|
+
tapEvaluateWithVariableInfo('MemberExpression', expr => this.getMemberExpressionInfo(expr, ALLOWED_MEMBER_TYPES_EXPRESSION));
|
|
850
|
+
this.hooks.evaluate.for('CallExpression').tap('JavascriptParser', _expr => {
|
|
851
|
+
const expr = _expr;
|
|
852
|
+
if (expr.callee.type === 'MemberExpression' &&
|
|
853
|
+
expr.callee.property.type === (expr.callee.computed ? 'Literal' : 'Identifier')) {
|
|
854
|
+
// type Super also possible here
|
|
855
|
+
const param = this.evaluateExpression(expr.callee.object);
|
|
856
|
+
const property = expr.callee.property.type === 'Literal'
|
|
857
|
+
? `${expr.callee.property.value}`
|
|
858
|
+
: expr.callee.property.name;
|
|
859
|
+
const hook = this.hooks.evaluateCallExpressionMember.get(property);
|
|
860
|
+
if (hook !== undefined) {
|
|
861
|
+
return hook.call(expr, param);
|
|
862
|
+
}
|
|
863
|
+
}
|
|
864
|
+
else if (expr.callee.type === 'Identifier') {
|
|
865
|
+
return this.callHooksForName(this.hooks.evaluateCallExpression, expr.callee.name, expr);
|
|
866
|
+
}
|
|
867
|
+
});
|
|
868
|
+
this.hooks.evaluateCallExpressionMember
|
|
869
|
+
.for('indexOf')
|
|
870
|
+
.tap('JavascriptParser', (expr, param) => {
|
|
871
|
+
if (!param.isString())
|
|
872
|
+
return;
|
|
873
|
+
if (expr.arguments.length === 0)
|
|
874
|
+
return;
|
|
875
|
+
const [arg1, arg2] = expr.arguments;
|
|
876
|
+
if (arg1.type === 'SpreadElement')
|
|
877
|
+
return;
|
|
878
|
+
const arg1Eval = this.evaluateExpression(arg1);
|
|
879
|
+
if (!arg1Eval.isString())
|
|
880
|
+
return;
|
|
881
|
+
const arg1Value = arg1Eval.string;
|
|
882
|
+
let result;
|
|
883
|
+
if (arg2) {
|
|
884
|
+
if (arg2.type === 'SpreadElement')
|
|
885
|
+
return;
|
|
886
|
+
const arg2Eval = this.evaluateExpression(arg2);
|
|
887
|
+
if (!arg2Eval.isNumber())
|
|
888
|
+
return;
|
|
889
|
+
result = param.string.indexOf(arg1Value, arg2Eval.number);
|
|
890
|
+
}
|
|
891
|
+
else {
|
|
892
|
+
result = param.string.indexOf(arg1Value);
|
|
893
|
+
}
|
|
894
|
+
return new BasicEvaluatedExpression_1.default()
|
|
895
|
+
.setNumber(result)
|
|
896
|
+
.setSideEffects(param.couldHaveSideEffects())
|
|
897
|
+
.setRange(expr.range);
|
|
898
|
+
});
|
|
899
|
+
this.hooks.evaluateCallExpressionMember
|
|
900
|
+
.for('replace')
|
|
901
|
+
.tap('JavascriptParser', (expr, param) => {
|
|
902
|
+
if (!param.isString())
|
|
903
|
+
return;
|
|
904
|
+
if (expr.arguments.length !== 2)
|
|
905
|
+
return;
|
|
906
|
+
if (expr.arguments[0].type === 'SpreadElement')
|
|
907
|
+
return;
|
|
908
|
+
if (expr.arguments[1].type === 'SpreadElement')
|
|
909
|
+
return;
|
|
910
|
+
const arg1 = this.evaluateExpression(expr.arguments[0]);
|
|
911
|
+
const arg2 = this.evaluateExpression(expr.arguments[1]);
|
|
912
|
+
if (!arg1.isString() && !arg1.isRegExp())
|
|
913
|
+
return;
|
|
914
|
+
const arg1Value = arg1.regExp || arg1.string;
|
|
915
|
+
if (!arg2.isString())
|
|
916
|
+
return;
|
|
917
|
+
const arg2Value = arg2.string;
|
|
918
|
+
return new BasicEvaluatedExpression_1.default()
|
|
919
|
+
.setString(param.string.replace(arg1Value, arg2Value))
|
|
920
|
+
.setSideEffects(param.couldHaveSideEffects())
|
|
921
|
+
.setRange(expr.range);
|
|
922
|
+
});
|
|
923
|
+
['substr', 'substring', 'slice'].forEach(fn => {
|
|
924
|
+
this.hooks.evaluateCallExpressionMember.for(fn).tap('JavascriptParser', (expr, param) => {
|
|
925
|
+
if (!param.isString())
|
|
926
|
+
return;
|
|
927
|
+
let arg1;
|
|
928
|
+
let result;
|
|
929
|
+
const str = param.string;
|
|
930
|
+
switch (expr.arguments.length) {
|
|
931
|
+
case 1:
|
|
932
|
+
if (expr.arguments[0].type === 'SpreadElement')
|
|
933
|
+
return;
|
|
934
|
+
arg1 = this.evaluateExpression(expr.arguments[0]);
|
|
935
|
+
if (!arg1.isNumber())
|
|
936
|
+
return;
|
|
937
|
+
result = str[fn](arg1.number);
|
|
938
|
+
break;
|
|
939
|
+
case 2: {
|
|
940
|
+
if (expr.arguments[0].type === 'SpreadElement')
|
|
941
|
+
return;
|
|
942
|
+
if (expr.arguments[1].type === 'SpreadElement')
|
|
943
|
+
return;
|
|
944
|
+
arg1 = this.evaluateExpression(expr.arguments[0]);
|
|
945
|
+
const arg2 = this.evaluateExpression(expr.arguments[1]);
|
|
946
|
+
if (!arg1.isNumber())
|
|
947
|
+
return;
|
|
948
|
+
if (!arg2.isNumber())
|
|
949
|
+
return;
|
|
950
|
+
result = str[fn](arg1.number, arg2.number);
|
|
951
|
+
break;
|
|
952
|
+
}
|
|
953
|
+
default:
|
|
954
|
+
return;
|
|
955
|
+
}
|
|
956
|
+
return new BasicEvaluatedExpression_1.default()
|
|
957
|
+
.setString(result)
|
|
958
|
+
.setSideEffects(param.couldHaveSideEffects())
|
|
959
|
+
.setRange(expr.range);
|
|
960
|
+
});
|
|
961
|
+
});
|
|
962
|
+
const getSimplifiedTemplateResult = (kind, templateLiteralExpr) => {
|
|
963
|
+
const quasis = [];
|
|
964
|
+
const parts = [];
|
|
965
|
+
for (let i = 0; i < templateLiteralExpr.quasis.length; i++) {
|
|
966
|
+
const quasiExpr = templateLiteralExpr.quasis[i];
|
|
967
|
+
const quasi = quasiExpr.value[kind];
|
|
968
|
+
if (i > 0) {
|
|
969
|
+
const prevExpr = parts[parts.length - 1];
|
|
970
|
+
const expr = this.evaluateExpression(templateLiteralExpr.expressions[i - 1]);
|
|
971
|
+
const exprAsString = expr.asString();
|
|
972
|
+
if (typeof exprAsString === 'string' && !expr.couldHaveSideEffects()) {
|
|
973
|
+
// We can merge quasi + expr + quasi when expr
|
|
974
|
+
// is a const string
|
|
975
|
+
prevExpr.setString(prevExpr.string + exprAsString + quasi);
|
|
976
|
+
prevExpr.setRange([prevExpr.range[0], quasiExpr.range[1]]);
|
|
977
|
+
// We unset the expression as it doesn't match to a single expression
|
|
978
|
+
prevExpr.setExpression(undefined);
|
|
979
|
+
continue;
|
|
980
|
+
}
|
|
981
|
+
parts.push(expr);
|
|
982
|
+
}
|
|
983
|
+
const part = new BasicEvaluatedExpression_1.default()
|
|
984
|
+
.setString(quasi)
|
|
985
|
+
.setRange(quasiExpr.range)
|
|
986
|
+
.setExpression(quasiExpr);
|
|
987
|
+
quasis.push(part);
|
|
988
|
+
parts.push(part);
|
|
989
|
+
}
|
|
990
|
+
return {
|
|
991
|
+
quasis,
|
|
992
|
+
parts,
|
|
993
|
+
};
|
|
994
|
+
};
|
|
995
|
+
this.hooks.evaluate.for('TemplateLiteral').tap('JavascriptParser', _node => {
|
|
996
|
+
const node = _node;
|
|
997
|
+
const { quasis, parts } = getSimplifiedTemplateResult('cooked', node);
|
|
998
|
+
if (parts.length === 1) {
|
|
999
|
+
return parts[0].setRange(node.range);
|
|
1000
|
+
}
|
|
1001
|
+
return new BasicEvaluatedExpression_1.default()
|
|
1002
|
+
.setTemplateString(quasis, parts, 'cooked')
|
|
1003
|
+
.setRange(node.range);
|
|
1004
|
+
});
|
|
1005
|
+
this.hooks.evaluate.for('TaggedTemplateExpression').tap('JavascriptParser', _node => {
|
|
1006
|
+
const node = _node;
|
|
1007
|
+
const tag = this.evaluateExpression(node.tag);
|
|
1008
|
+
if (tag.isIdentifier() && tag.identifier === 'String.raw') {
|
|
1009
|
+
const { quasis, parts } = getSimplifiedTemplateResult('raw', node.quasi);
|
|
1010
|
+
return new BasicEvaluatedExpression_1.default()
|
|
1011
|
+
.setTemplateString(quasis, parts, 'raw')
|
|
1012
|
+
.setRange(node.range);
|
|
1013
|
+
}
|
|
1014
|
+
});
|
|
1015
|
+
this.hooks.evaluateCallExpressionMember.for('concat').tap('JavascriptParser', (expr, param) => {
|
|
1016
|
+
if (!param.isString() && !param.isWrapped())
|
|
1017
|
+
return;
|
|
1018
|
+
let stringSuffix = null;
|
|
1019
|
+
let hasUnknownParams = false;
|
|
1020
|
+
const innerExpressions = [];
|
|
1021
|
+
for (let i = expr.arguments.length - 1; i >= 0; i--) {
|
|
1022
|
+
const arg = expr.arguments[i];
|
|
1023
|
+
if (arg.type === 'SpreadElement')
|
|
1024
|
+
return;
|
|
1025
|
+
const argExpr = this.evaluateExpression(arg);
|
|
1026
|
+
if (hasUnknownParams || (!argExpr.isString() && !argExpr.isNumber())) {
|
|
1027
|
+
hasUnknownParams = true;
|
|
1028
|
+
innerExpressions.push(argExpr);
|
|
1029
|
+
continue;
|
|
1030
|
+
}
|
|
1031
|
+
const value = argExpr.isString() ? argExpr.string : `${argExpr.number}`;
|
|
1032
|
+
const newString = value + (stringSuffix ? stringSuffix.string : '');
|
|
1033
|
+
const newRange = [argExpr.range[0], (stringSuffix || argExpr).range[1]];
|
|
1034
|
+
stringSuffix = new BasicEvaluatedExpression_1.default()
|
|
1035
|
+
.setString(newString)
|
|
1036
|
+
.setSideEffects((stringSuffix === null || stringSuffix === void 0 ? void 0 : stringSuffix.couldHaveSideEffects()) || argExpr.couldHaveSideEffects())
|
|
1037
|
+
.setRange(newRange);
|
|
1038
|
+
}
|
|
1039
|
+
if (hasUnknownParams) {
|
|
1040
|
+
const prefix = param.isString() ? param : param.prefix;
|
|
1041
|
+
const inner = param.isWrapped() && param.wrappedInnerExpressions
|
|
1042
|
+
? param.wrappedInnerExpressions.concat(innerExpressions.reverse())
|
|
1043
|
+
: innerExpressions.reverse();
|
|
1044
|
+
return new BasicEvaluatedExpression_1.default()
|
|
1045
|
+
.setWrapped(prefix, stringSuffix, inner)
|
|
1046
|
+
.setRange(expr.range);
|
|
1047
|
+
}
|
|
1048
|
+
if (param.isWrapped()) {
|
|
1049
|
+
const postfix = stringSuffix || param.postfix;
|
|
1050
|
+
const inner = param.wrappedInnerExpressions
|
|
1051
|
+
? param.wrappedInnerExpressions.concat(innerExpressions.reverse())
|
|
1052
|
+
: innerExpressions.reverse();
|
|
1053
|
+
return new BasicEvaluatedExpression_1.default()
|
|
1054
|
+
.setWrapped(param.prefix, postfix, inner)
|
|
1055
|
+
.setRange(expr.range);
|
|
1056
|
+
}
|
|
1057
|
+
const newString = param.string + (stringSuffix ? stringSuffix.string : '');
|
|
1058
|
+
return new BasicEvaluatedExpression_1.default()
|
|
1059
|
+
.setString(newString)
|
|
1060
|
+
.setSideEffects((stringSuffix === null || stringSuffix === void 0 ? void 0 : stringSuffix.couldHaveSideEffects()) || param.couldHaveSideEffects())
|
|
1061
|
+
.setRange(expr.range);
|
|
1062
|
+
});
|
|
1063
|
+
this.hooks.evaluateCallExpressionMember.for('split').tap('JavascriptParser', (expr, param) => {
|
|
1064
|
+
if (!param.isString())
|
|
1065
|
+
return;
|
|
1066
|
+
if (expr.arguments.length !== 1)
|
|
1067
|
+
return;
|
|
1068
|
+
if (expr.arguments[0].type === 'SpreadElement')
|
|
1069
|
+
return;
|
|
1070
|
+
let result;
|
|
1071
|
+
const arg = this.evaluateExpression(expr.arguments[0]);
|
|
1072
|
+
if (arg.isString()) {
|
|
1073
|
+
result = param.string.split(arg.string);
|
|
1074
|
+
}
|
|
1075
|
+
else if (arg.isRegExp()) {
|
|
1076
|
+
result = param.string.split(arg.regExp);
|
|
1077
|
+
}
|
|
1078
|
+
else {
|
|
1079
|
+
return;
|
|
1080
|
+
}
|
|
1081
|
+
return new BasicEvaluatedExpression_1.default()
|
|
1082
|
+
.setArray(result)
|
|
1083
|
+
.setSideEffects(param.couldHaveSideEffects())
|
|
1084
|
+
.setRange(expr.range);
|
|
1085
|
+
});
|
|
1086
|
+
this.hooks.evaluate.for('ConditionalExpression').tap('JavascriptParser', _expr => {
|
|
1087
|
+
const expr = _expr;
|
|
1088
|
+
const condition = this.evaluateExpression(expr.test);
|
|
1089
|
+
const conditionValue = condition.asBool();
|
|
1090
|
+
let res;
|
|
1091
|
+
if (conditionValue === undefined) {
|
|
1092
|
+
const consequent = this.evaluateExpression(expr.consequent);
|
|
1093
|
+
const alternate = this.evaluateExpression(expr.alternate);
|
|
1094
|
+
res = new BasicEvaluatedExpression_1.default();
|
|
1095
|
+
if (consequent.isConditional()) {
|
|
1096
|
+
res.setOptions(consequent.options);
|
|
1097
|
+
}
|
|
1098
|
+
else {
|
|
1099
|
+
res.setOptions([consequent]);
|
|
1100
|
+
}
|
|
1101
|
+
if (alternate.isConditional()) {
|
|
1102
|
+
res.addOptions(alternate.options);
|
|
1103
|
+
}
|
|
1104
|
+
else {
|
|
1105
|
+
res.addOptions([alternate]);
|
|
1106
|
+
}
|
|
1107
|
+
}
|
|
1108
|
+
else {
|
|
1109
|
+
res = this.evaluateExpression(conditionValue ? expr.consequent : expr.alternate);
|
|
1110
|
+
if (condition.couldHaveSideEffects())
|
|
1111
|
+
res.setSideEffects();
|
|
1112
|
+
}
|
|
1113
|
+
res.setRange(expr.range);
|
|
1114
|
+
return res;
|
|
1115
|
+
});
|
|
1116
|
+
this.hooks.evaluate.for('ArrayExpression').tap('JavascriptParser', _expr => {
|
|
1117
|
+
const expr = _expr;
|
|
1118
|
+
const items = expr.elements.map(element => (element !== null && element.type !== 'SpreadElement' && this.evaluateExpression(element)));
|
|
1119
|
+
if (!items.every(Boolean))
|
|
1120
|
+
return;
|
|
1121
|
+
return new BasicEvaluatedExpression_1.default().setItems(items).setRange(expr.range);
|
|
1122
|
+
});
|
|
1123
|
+
this.hooks.evaluate.for('ChainExpression').tap('JavascriptParser', _expr => {
|
|
1124
|
+
const expr = _expr;
|
|
1125
|
+
const optionalExpressionsStack = [];
|
|
1126
|
+
let next = expr.expression;
|
|
1127
|
+
while (next.type === 'MemberExpression' || next.type === 'CallExpression') {
|
|
1128
|
+
if (next.type === 'MemberExpression') {
|
|
1129
|
+
if (next.optional) {
|
|
1130
|
+
// SuperNode can not be optional
|
|
1131
|
+
optionalExpressionsStack.push(next.object);
|
|
1132
|
+
}
|
|
1133
|
+
next = next.object;
|
|
1134
|
+
}
|
|
1135
|
+
else {
|
|
1136
|
+
if (next.optional) {
|
|
1137
|
+
// SuperNode can not be optional
|
|
1138
|
+
optionalExpressionsStack.push(next.callee);
|
|
1139
|
+
}
|
|
1140
|
+
next = next.callee;
|
|
1141
|
+
}
|
|
1142
|
+
}
|
|
1143
|
+
while (optionalExpressionsStack.length > 0) {
|
|
1144
|
+
const expression = optionalExpressionsStack.pop();
|
|
1145
|
+
const evaluated = this.evaluateExpression(expression);
|
|
1146
|
+
if (evaluated.asNullish()) {
|
|
1147
|
+
return evaluated.setRange(_expr.range);
|
|
1148
|
+
}
|
|
1149
|
+
}
|
|
1150
|
+
return this.evaluateExpression(expr.expression);
|
|
1151
|
+
});
|
|
1152
|
+
}
|
|
1153
|
+
destructuringAssignmentPropertiesFor(node) {
|
|
1154
|
+
if (!this.destructuringAssignmentProperties)
|
|
1155
|
+
return undefined;
|
|
1156
|
+
return this.destructuringAssignmentProperties.get(node);
|
|
1157
|
+
}
|
|
1158
|
+
getRenameIdentifier(expr) {
|
|
1159
|
+
const result = this.evaluateExpression(expr);
|
|
1160
|
+
if (result.isIdentifier()) {
|
|
1161
|
+
return result.identifier;
|
|
1162
|
+
}
|
|
1163
|
+
}
|
|
1164
|
+
walkClass(classy) {
|
|
1165
|
+
if (classy.superClass) {
|
|
1166
|
+
if (!this.hooks.classExtendsExpression.call(classy.superClass, classy)) {
|
|
1167
|
+
this.walkExpression(classy.superClass);
|
|
1168
|
+
}
|
|
1169
|
+
}
|
|
1170
|
+
if (classy.body && classy.body.type === 'ClassBody') {
|
|
1171
|
+
const scopeParams = [];
|
|
1172
|
+
// Add class name in scope for recursive calls
|
|
1173
|
+
if (classy.id) {
|
|
1174
|
+
scopeParams.push(classy.id);
|
|
1175
|
+
}
|
|
1176
|
+
this.inClassScope(true, scopeParams, () => {
|
|
1177
|
+
for (const classElement of classy.body.body) {
|
|
1178
|
+
if (!this.hooks.classBodyElement.call(classElement, classy)) {
|
|
1179
|
+
if (classElement.computed && classElement.key) {
|
|
1180
|
+
this.walkExpression(classElement.key);
|
|
1181
|
+
}
|
|
1182
|
+
if (classElement.value) {
|
|
1183
|
+
if (!this.hooks.classBodyValue.call(classElement.value, classElement, classy)) {
|
|
1184
|
+
const wasTopLevel = this.scope.topLevelScope;
|
|
1185
|
+
this.scope.topLevelScope = false;
|
|
1186
|
+
this.walkExpression(classElement.value);
|
|
1187
|
+
this.scope.topLevelScope = wasTopLevel;
|
|
1188
|
+
}
|
|
1189
|
+
}
|
|
1190
|
+
else if (classElement.type === 'StaticBlock') {
|
|
1191
|
+
const wasTopLevel = this.scope.topLevelScope;
|
|
1192
|
+
this.scope.topLevelScope = false;
|
|
1193
|
+
this.walkBlockStatement(classElement);
|
|
1194
|
+
this.scope.topLevelScope = wasTopLevel;
|
|
1195
|
+
}
|
|
1196
|
+
}
|
|
1197
|
+
}
|
|
1198
|
+
});
|
|
1199
|
+
}
|
|
1200
|
+
}
|
|
1201
|
+
/**
|
|
1202
|
+
* Pre walking iterates the scope for variable declarations
|
|
1203
|
+
*
|
|
1204
|
+
* @param {(Statement | ModuleDeclaration)[]} statements statements
|
|
1205
|
+
*/
|
|
1206
|
+
preWalkStatements(statements) {
|
|
1207
|
+
for (let index = 0, len = statements.length; index < len; index++) {
|
|
1208
|
+
const statement = statements[index];
|
|
1209
|
+
this.preWalkStatement(statement);
|
|
1210
|
+
}
|
|
1211
|
+
}
|
|
1212
|
+
/**
|
|
1213
|
+
* Block pre walking iterates the scope for block variable declarations
|
|
1214
|
+
*
|
|
1215
|
+
* @param {(Statement | ModuleDeclaration)[]} statements statements
|
|
1216
|
+
*/
|
|
1217
|
+
blockPreWalkStatements(statements) {
|
|
1218
|
+
for (let index = 0, len = statements.length; index < len; index++) {
|
|
1219
|
+
const statement = statements[index];
|
|
1220
|
+
this.blockPreWalkStatement(statement);
|
|
1221
|
+
}
|
|
1222
|
+
}
|
|
1223
|
+
/**
|
|
1224
|
+
* Walking iterates the statements and expressions and processes them
|
|
1225
|
+
*
|
|
1226
|
+
* @param {(Statement | ModuleDeclaration)[]} statements statements
|
|
1227
|
+
*/
|
|
1228
|
+
walkStatements(statements) {
|
|
1229
|
+
for (let index = 0, len = statements.length; index < len; index++) {
|
|
1230
|
+
const statement = statements[index];
|
|
1231
|
+
this.walkStatement(statement);
|
|
1232
|
+
}
|
|
1233
|
+
}
|
|
1234
|
+
/**
|
|
1235
|
+
* Walking iterates the statements and expressions and processes them
|
|
1236
|
+
*
|
|
1237
|
+
* @param {Statement | ModuleDeclaration} statement statement
|
|
1238
|
+
*/
|
|
1239
|
+
preWalkStatement(statement) {
|
|
1240
|
+
this.statementPath.push(statement);
|
|
1241
|
+
if (this.hooks.preStatement.call(statement)) {
|
|
1242
|
+
this.prevStatement = this.statementPath.pop();
|
|
1243
|
+
return;
|
|
1244
|
+
}
|
|
1245
|
+
switch (statement.type) {
|
|
1246
|
+
case 'BlockStatement':
|
|
1247
|
+
this.preWalkBlockStatement(statement);
|
|
1248
|
+
break;
|
|
1249
|
+
case 'DoWhileStatement':
|
|
1250
|
+
this.preWalkDoWhileStatement(statement);
|
|
1251
|
+
break;
|
|
1252
|
+
case 'ForInStatement':
|
|
1253
|
+
this.preWalkForInStatement(statement);
|
|
1254
|
+
break;
|
|
1255
|
+
case 'ForOfStatement':
|
|
1256
|
+
this.preWalkForOfStatement(statement);
|
|
1257
|
+
break;
|
|
1258
|
+
case 'ForStatement':
|
|
1259
|
+
this.preWalkForStatement(statement);
|
|
1260
|
+
break;
|
|
1261
|
+
case 'FunctionDeclaration':
|
|
1262
|
+
this.preWalkFunctionDeclaration(statement);
|
|
1263
|
+
break;
|
|
1264
|
+
case 'IfStatement':
|
|
1265
|
+
this.preWalkIfStatement(statement);
|
|
1266
|
+
break;
|
|
1267
|
+
case 'LabeledStatement':
|
|
1268
|
+
this.preWalkLabeledStatement(statement);
|
|
1269
|
+
break;
|
|
1270
|
+
case 'SwitchStatement':
|
|
1271
|
+
this.preWalkSwitchStatement(statement);
|
|
1272
|
+
break;
|
|
1273
|
+
case 'TryStatement':
|
|
1274
|
+
this.preWalkTryStatement(statement);
|
|
1275
|
+
break;
|
|
1276
|
+
case 'VariableDeclaration':
|
|
1277
|
+
this.preWalkVariableDeclaration(statement);
|
|
1278
|
+
break;
|
|
1279
|
+
case 'WhileStatement':
|
|
1280
|
+
this.preWalkWhileStatement(statement);
|
|
1281
|
+
break;
|
|
1282
|
+
case 'WithStatement':
|
|
1283
|
+
this.preWalkWithStatement(statement);
|
|
1284
|
+
break;
|
|
1285
|
+
}
|
|
1286
|
+
this.prevStatement = this.statementPath.pop();
|
|
1287
|
+
}
|
|
1288
|
+
/**
|
|
1289
|
+
* @param {Statement | ModuleDeclaration} statement statement
|
|
1290
|
+
*/
|
|
1291
|
+
blockPreWalkStatement(statement) {
|
|
1292
|
+
this.statementPath.push(statement);
|
|
1293
|
+
if (this.hooks.blockPreStatement.call(statement)) {
|
|
1294
|
+
this.prevStatement = this.statementPath.pop();
|
|
1295
|
+
return;
|
|
1296
|
+
}
|
|
1297
|
+
switch (statement.type) {
|
|
1298
|
+
case 'ImportDeclaration':
|
|
1299
|
+
this.blockPreWalkImportDeclaration(statement);
|
|
1300
|
+
break;
|
|
1301
|
+
case 'ExportAllDeclaration':
|
|
1302
|
+
this.blockPreWalkExportAllDeclaration(statement);
|
|
1303
|
+
break;
|
|
1304
|
+
case 'ExportDefaultDeclaration':
|
|
1305
|
+
this.blockPreWalkExportDefaultDeclaration(statement);
|
|
1306
|
+
break;
|
|
1307
|
+
case 'ExportNamedDeclaration':
|
|
1308
|
+
this.blockPreWalkExportNamedDeclaration(statement);
|
|
1309
|
+
break;
|
|
1310
|
+
case 'VariableDeclaration':
|
|
1311
|
+
this.blockPreWalkVariableDeclaration(statement);
|
|
1312
|
+
break;
|
|
1313
|
+
case 'ClassDeclaration':
|
|
1314
|
+
this.blockPreWalkClassDeclaration(statement);
|
|
1315
|
+
break;
|
|
1316
|
+
case 'ExpressionStatement':
|
|
1317
|
+
this.blockPreWalkExpressionStatement(statement);
|
|
1318
|
+
}
|
|
1319
|
+
this.prevStatement = this.statementPath.pop();
|
|
1320
|
+
}
|
|
1321
|
+
/**
|
|
1322
|
+
* @param {Statement | ModuleDeclaration} statement statement
|
|
1323
|
+
*/
|
|
1324
|
+
walkStatement(statement) {
|
|
1325
|
+
this.statementPath.push(statement);
|
|
1326
|
+
if (this.hooks.statement.call(statement) !== undefined) {
|
|
1327
|
+
this.prevStatement = this.statementPath.pop();
|
|
1328
|
+
return;
|
|
1329
|
+
}
|
|
1330
|
+
switch (statement.type) {
|
|
1331
|
+
case 'BlockStatement':
|
|
1332
|
+
this.walkBlockStatement(statement);
|
|
1333
|
+
break;
|
|
1334
|
+
case 'ClassDeclaration':
|
|
1335
|
+
this.walkClassDeclaration(statement);
|
|
1336
|
+
break;
|
|
1337
|
+
case 'DoWhileStatement':
|
|
1338
|
+
this.walkDoWhileStatement(statement);
|
|
1339
|
+
break;
|
|
1340
|
+
case 'ExportDefaultDeclaration':
|
|
1341
|
+
this.walkExportDefaultDeclaration(statement);
|
|
1342
|
+
break;
|
|
1343
|
+
case 'ExportNamedDeclaration':
|
|
1344
|
+
this.walkExportNamedDeclaration(statement);
|
|
1345
|
+
break;
|
|
1346
|
+
case 'ExpressionStatement':
|
|
1347
|
+
this.walkExpressionStatement(statement);
|
|
1348
|
+
break;
|
|
1349
|
+
case 'ForInStatement':
|
|
1350
|
+
this.walkForInStatement(statement);
|
|
1351
|
+
break;
|
|
1352
|
+
case 'ForOfStatement':
|
|
1353
|
+
this.walkForOfStatement(statement);
|
|
1354
|
+
break;
|
|
1355
|
+
case 'ForStatement':
|
|
1356
|
+
this.walkForStatement(statement);
|
|
1357
|
+
break;
|
|
1358
|
+
case 'FunctionDeclaration':
|
|
1359
|
+
this.walkFunctionDeclaration(statement);
|
|
1360
|
+
break;
|
|
1361
|
+
case 'IfStatement':
|
|
1362
|
+
this.walkIfStatement(statement);
|
|
1363
|
+
break;
|
|
1364
|
+
case 'LabeledStatement':
|
|
1365
|
+
this.walkLabeledStatement(statement);
|
|
1366
|
+
break;
|
|
1367
|
+
case 'ReturnStatement':
|
|
1368
|
+
this.walkReturnStatement(statement);
|
|
1369
|
+
break;
|
|
1370
|
+
case 'SwitchStatement':
|
|
1371
|
+
this.walkSwitchStatement(statement);
|
|
1372
|
+
break;
|
|
1373
|
+
case 'ThrowStatement':
|
|
1374
|
+
this.walkThrowStatement(statement);
|
|
1375
|
+
break;
|
|
1376
|
+
case 'TryStatement':
|
|
1377
|
+
this.walkTryStatement(statement);
|
|
1378
|
+
break;
|
|
1379
|
+
case 'VariableDeclaration':
|
|
1380
|
+
this.walkVariableDeclaration(statement);
|
|
1381
|
+
break;
|
|
1382
|
+
case 'WhileStatement':
|
|
1383
|
+
this.walkWhileStatement(statement);
|
|
1384
|
+
break;
|
|
1385
|
+
case 'WithStatement':
|
|
1386
|
+
this.walkWithStatement(statement);
|
|
1387
|
+
break;
|
|
1388
|
+
}
|
|
1389
|
+
this.prevStatement = this.statementPath.pop();
|
|
1390
|
+
}
|
|
1391
|
+
/**
|
|
1392
|
+
* Walks a statements that is nested within a parent statement
|
|
1393
|
+
* and can potentially be a non-block statement.
|
|
1394
|
+
* This enforces the nested statement to never be in ASI position.
|
|
1395
|
+
*
|
|
1396
|
+
* @param {Statement} statement the nested statement
|
|
1397
|
+
*/
|
|
1398
|
+
walkNestedStatement(statement) {
|
|
1399
|
+
this.prevStatement = undefined;
|
|
1400
|
+
this.walkStatement(statement);
|
|
1401
|
+
}
|
|
1402
|
+
// Real Statements
|
|
1403
|
+
/**
|
|
1404
|
+
* @param {BlockStatement} statement block statement
|
|
1405
|
+
*/
|
|
1406
|
+
preWalkBlockStatement(statement) {
|
|
1407
|
+
this.preWalkStatements(statement.body);
|
|
1408
|
+
}
|
|
1409
|
+
/**
|
|
1410
|
+
* @param {BlockStatement} statement block statement
|
|
1411
|
+
*/
|
|
1412
|
+
walkBlockStatement(statement) {
|
|
1413
|
+
this.inBlockScope(() => {
|
|
1414
|
+
const body = statement.body;
|
|
1415
|
+
const prev = this.prevStatement;
|
|
1416
|
+
this.blockPreWalkStatements(body);
|
|
1417
|
+
this.prevStatement = prev;
|
|
1418
|
+
this.walkStatements(body);
|
|
1419
|
+
});
|
|
1420
|
+
}
|
|
1421
|
+
/**
|
|
1422
|
+
* @param {ExpressionStatement} statement expression statement
|
|
1423
|
+
*/
|
|
1424
|
+
walkExpressionStatement(statement) {
|
|
1425
|
+
this.walkExpression(statement.expression);
|
|
1426
|
+
}
|
|
1427
|
+
/**
|
|
1428
|
+
* @param {IfStatement} statement if statement
|
|
1429
|
+
*/
|
|
1430
|
+
preWalkIfStatement(statement) {
|
|
1431
|
+
this.preWalkStatement(statement.consequent);
|
|
1432
|
+
if (statement.alternate) {
|
|
1433
|
+
this.preWalkStatement(statement.alternate);
|
|
1434
|
+
}
|
|
1435
|
+
}
|
|
1436
|
+
/**
|
|
1437
|
+
* @param {IfStatement} statement if statement
|
|
1438
|
+
*/
|
|
1439
|
+
walkIfStatement(statement) {
|
|
1440
|
+
const result = this.hooks.statementIf.call(statement);
|
|
1441
|
+
if (result === undefined) {
|
|
1442
|
+
this.walkExpression(statement.test);
|
|
1443
|
+
this.walkNestedStatement(statement.consequent);
|
|
1444
|
+
if (statement.alternate) {
|
|
1445
|
+
this.walkNestedStatement(statement.alternate);
|
|
1446
|
+
}
|
|
1447
|
+
}
|
|
1448
|
+
else if (result) {
|
|
1449
|
+
this.walkNestedStatement(statement.consequent);
|
|
1450
|
+
}
|
|
1451
|
+
else if (statement.alternate) {
|
|
1452
|
+
this.walkNestedStatement(statement.alternate);
|
|
1453
|
+
}
|
|
1454
|
+
}
|
|
1455
|
+
/**
|
|
1456
|
+
* @param {LabeledStatement} statement with statement
|
|
1457
|
+
*/
|
|
1458
|
+
preWalkLabeledStatement(statement) {
|
|
1459
|
+
this.preWalkStatement(statement.body);
|
|
1460
|
+
}
|
|
1461
|
+
/**
|
|
1462
|
+
* @param {LabeledStatement} statement with statement
|
|
1463
|
+
*/
|
|
1464
|
+
walkLabeledStatement(statement) {
|
|
1465
|
+
const hook = this.hooks.label.get(statement.label.name);
|
|
1466
|
+
if (hook !== undefined) {
|
|
1467
|
+
const result = hook.call(statement);
|
|
1468
|
+
if (result === true)
|
|
1469
|
+
return;
|
|
1470
|
+
}
|
|
1471
|
+
this.walkNestedStatement(statement.body);
|
|
1472
|
+
}
|
|
1473
|
+
/**
|
|
1474
|
+
* @param {WithStatement} statement with statement
|
|
1475
|
+
*/
|
|
1476
|
+
preWalkWithStatement(statement) {
|
|
1477
|
+
this.preWalkStatement(statement.body);
|
|
1478
|
+
}
|
|
1479
|
+
/**
|
|
1480
|
+
* @param {WithStatement} statement with statement
|
|
1481
|
+
*/
|
|
1482
|
+
walkWithStatement(statement) {
|
|
1483
|
+
this.walkExpression(statement.object);
|
|
1484
|
+
this.walkNestedStatement(statement.body);
|
|
1485
|
+
}
|
|
1486
|
+
/**
|
|
1487
|
+
* @param {SwitchStatement} statement switch statement
|
|
1488
|
+
*/
|
|
1489
|
+
preWalkSwitchStatement(statement) {
|
|
1490
|
+
this.preWalkSwitchCases(statement.cases);
|
|
1491
|
+
}
|
|
1492
|
+
/**
|
|
1493
|
+
* @param {SwitchStatement} statement switch statement
|
|
1494
|
+
*/
|
|
1495
|
+
walkSwitchStatement(statement) {
|
|
1496
|
+
this.walkExpression(statement.discriminant);
|
|
1497
|
+
this.walkSwitchCases(statement.cases);
|
|
1498
|
+
}
|
|
1499
|
+
/**
|
|
1500
|
+
* @param {ReturnStatement | ThrowStatement} statement return or throw statement
|
|
1501
|
+
*/
|
|
1502
|
+
walkTerminatingStatement(statement) {
|
|
1503
|
+
if (statement.argument)
|
|
1504
|
+
this.walkExpression(statement.argument);
|
|
1505
|
+
}
|
|
1506
|
+
/**
|
|
1507
|
+
* @param {ReturnStatement} statement return statement
|
|
1508
|
+
*/
|
|
1509
|
+
walkReturnStatement(statement) {
|
|
1510
|
+
this.walkTerminatingStatement(statement);
|
|
1511
|
+
}
|
|
1512
|
+
/**
|
|
1513
|
+
* @param {ThrowStatement} statement return statement
|
|
1514
|
+
*/
|
|
1515
|
+
walkThrowStatement(statement) {
|
|
1516
|
+
this.walkTerminatingStatement(statement);
|
|
1517
|
+
}
|
|
1518
|
+
/**
|
|
1519
|
+
* @param {TryStatement} statement try statement
|
|
1520
|
+
*/
|
|
1521
|
+
preWalkTryStatement(statement) {
|
|
1522
|
+
this.preWalkStatement(statement.block);
|
|
1523
|
+
if (statement.handler)
|
|
1524
|
+
this.preWalkCatchClause(statement.handler);
|
|
1525
|
+
if (statement.finalizer)
|
|
1526
|
+
this.preWalkStatement(statement.finalizer);
|
|
1527
|
+
}
|
|
1528
|
+
/**
|
|
1529
|
+
* @param {TryStatement} statement try statement
|
|
1530
|
+
*/
|
|
1531
|
+
walkTryStatement(statement) {
|
|
1532
|
+
if (this.scope.inTry) {
|
|
1533
|
+
this.walkStatement(statement.block);
|
|
1534
|
+
}
|
|
1535
|
+
else {
|
|
1536
|
+
this.scope.inTry = true;
|
|
1537
|
+
this.walkStatement(statement.block);
|
|
1538
|
+
this.scope.inTry = false;
|
|
1539
|
+
}
|
|
1540
|
+
if (statement.handler)
|
|
1541
|
+
this.walkCatchClause(statement.handler);
|
|
1542
|
+
if (statement.finalizer)
|
|
1543
|
+
this.walkStatement(statement.finalizer);
|
|
1544
|
+
}
|
|
1545
|
+
/**
|
|
1546
|
+
* @param {WhileStatement} statement while statement
|
|
1547
|
+
*/
|
|
1548
|
+
preWalkWhileStatement(statement) {
|
|
1549
|
+
this.preWalkStatement(statement.body);
|
|
1550
|
+
}
|
|
1551
|
+
/**
|
|
1552
|
+
* @param {WhileStatement} statement while statement
|
|
1553
|
+
*/
|
|
1554
|
+
walkWhileStatement(statement) {
|
|
1555
|
+
this.walkExpression(statement.test);
|
|
1556
|
+
this.walkNestedStatement(statement.body);
|
|
1557
|
+
}
|
|
1558
|
+
/**
|
|
1559
|
+
* @param {DoWhileStatement} statement do while statement
|
|
1560
|
+
*/
|
|
1561
|
+
preWalkDoWhileStatement(statement) {
|
|
1562
|
+
this.preWalkStatement(statement.body);
|
|
1563
|
+
}
|
|
1564
|
+
/**
|
|
1565
|
+
* @param {DoWhileStatement} statement do while statement
|
|
1566
|
+
*/
|
|
1567
|
+
walkDoWhileStatement(statement) {
|
|
1568
|
+
this.walkNestedStatement(statement.body);
|
|
1569
|
+
this.walkExpression(statement.test);
|
|
1570
|
+
}
|
|
1571
|
+
/**
|
|
1572
|
+
* @param {ForStatement} statement for statement
|
|
1573
|
+
*/
|
|
1574
|
+
preWalkForStatement(statement) {
|
|
1575
|
+
if (statement.init) {
|
|
1576
|
+
if (statement.init.type === 'VariableDeclaration') {
|
|
1577
|
+
this.preWalkStatement(statement.init);
|
|
1578
|
+
}
|
|
1579
|
+
}
|
|
1580
|
+
this.preWalkStatement(statement.body);
|
|
1581
|
+
}
|
|
1582
|
+
/**
|
|
1583
|
+
* @param {ForStatement} statement for statement
|
|
1584
|
+
*/
|
|
1585
|
+
walkForStatement(statement) {
|
|
1586
|
+
this.inBlockScope(() => {
|
|
1587
|
+
if (statement.init) {
|
|
1588
|
+
if (statement.init.type === 'VariableDeclaration') {
|
|
1589
|
+
this.blockPreWalkVariableDeclaration(statement.init);
|
|
1590
|
+
this.prevStatement = undefined;
|
|
1591
|
+
this.walkStatement(statement.init);
|
|
1592
|
+
}
|
|
1593
|
+
else {
|
|
1594
|
+
this.walkExpression(statement.init);
|
|
1595
|
+
}
|
|
1596
|
+
}
|
|
1597
|
+
if (statement.test) {
|
|
1598
|
+
this.walkExpression(statement.test);
|
|
1599
|
+
}
|
|
1600
|
+
if (statement.update) {
|
|
1601
|
+
this.walkExpression(statement.update);
|
|
1602
|
+
}
|
|
1603
|
+
const body = statement.body;
|
|
1604
|
+
if (body.type === 'BlockStatement') {
|
|
1605
|
+
// no need to add additional scope
|
|
1606
|
+
const prev = this.prevStatement;
|
|
1607
|
+
this.blockPreWalkStatements(body.body);
|
|
1608
|
+
this.prevStatement = prev;
|
|
1609
|
+
this.walkStatements(body.body);
|
|
1610
|
+
}
|
|
1611
|
+
else {
|
|
1612
|
+
this.walkNestedStatement(body);
|
|
1613
|
+
}
|
|
1614
|
+
});
|
|
1615
|
+
}
|
|
1616
|
+
/**
|
|
1617
|
+
* @param {ForInStatement} statement for statement
|
|
1618
|
+
*/
|
|
1619
|
+
preWalkForInStatement(statement) {
|
|
1620
|
+
if (statement.left.type === 'VariableDeclaration') {
|
|
1621
|
+
this.preWalkVariableDeclaration(statement.left);
|
|
1622
|
+
}
|
|
1623
|
+
this.preWalkStatement(statement.body);
|
|
1624
|
+
}
|
|
1625
|
+
/**
|
|
1626
|
+
* @param {ForInStatement} statement for statement
|
|
1627
|
+
*/
|
|
1628
|
+
walkForInStatement(statement) {
|
|
1629
|
+
this.inBlockScope(() => {
|
|
1630
|
+
if (statement.left.type === 'VariableDeclaration') {
|
|
1631
|
+
this.blockPreWalkVariableDeclaration(statement.left);
|
|
1632
|
+
this.walkVariableDeclaration(statement.left);
|
|
1633
|
+
}
|
|
1634
|
+
else {
|
|
1635
|
+
this.walkPattern(statement.left);
|
|
1636
|
+
}
|
|
1637
|
+
this.walkExpression(statement.right);
|
|
1638
|
+
const body = statement.body;
|
|
1639
|
+
if (body.type === 'BlockStatement') {
|
|
1640
|
+
// no need to add additional scope
|
|
1641
|
+
const prev = this.prevStatement;
|
|
1642
|
+
this.blockPreWalkStatements(body.body);
|
|
1643
|
+
this.prevStatement = prev;
|
|
1644
|
+
this.walkStatements(body.body);
|
|
1645
|
+
}
|
|
1646
|
+
else {
|
|
1647
|
+
this.walkNestedStatement(body);
|
|
1648
|
+
}
|
|
1649
|
+
});
|
|
1650
|
+
}
|
|
1651
|
+
preWalkForOfStatement(statement) {
|
|
1652
|
+
if (statement.await && this.scope.topLevelScope === true) {
|
|
1653
|
+
this.hooks.topLevelAwait.call(statement);
|
|
1654
|
+
}
|
|
1655
|
+
if (statement.left.type === 'VariableDeclaration') {
|
|
1656
|
+
this.preWalkVariableDeclaration(statement.left);
|
|
1657
|
+
}
|
|
1658
|
+
this.preWalkStatement(statement.body);
|
|
1659
|
+
}
|
|
1660
|
+
/**
|
|
1661
|
+
* @param {ForOfStatement} statement for statement
|
|
1662
|
+
*/
|
|
1663
|
+
walkForOfStatement(statement) {
|
|
1664
|
+
this.inBlockScope(() => {
|
|
1665
|
+
if (statement.left.type === 'VariableDeclaration') {
|
|
1666
|
+
this.blockPreWalkVariableDeclaration(statement.left);
|
|
1667
|
+
this.walkVariableDeclaration(statement.left);
|
|
1668
|
+
}
|
|
1669
|
+
else {
|
|
1670
|
+
this.walkPattern(statement.left);
|
|
1671
|
+
}
|
|
1672
|
+
this.walkExpression(statement.right);
|
|
1673
|
+
const body = statement.body;
|
|
1674
|
+
if (body.type === 'BlockStatement') {
|
|
1675
|
+
// no need to add additional scope
|
|
1676
|
+
const prev = this.prevStatement;
|
|
1677
|
+
this.blockPreWalkStatements(body.body);
|
|
1678
|
+
this.prevStatement = prev;
|
|
1679
|
+
this.walkStatements(body.body);
|
|
1680
|
+
}
|
|
1681
|
+
else {
|
|
1682
|
+
this.walkNestedStatement(body);
|
|
1683
|
+
}
|
|
1684
|
+
});
|
|
1685
|
+
}
|
|
1686
|
+
/**
|
|
1687
|
+
* @param {FunctionDeclaration} statement function declaration
|
|
1688
|
+
*/
|
|
1689
|
+
preWalkFunctionDeclaration(statement) {
|
|
1690
|
+
if (statement.id) {
|
|
1691
|
+
this.defineVariable(statement.id.name);
|
|
1692
|
+
}
|
|
1693
|
+
}
|
|
1694
|
+
/**
|
|
1695
|
+
* @param {FunctionDeclaration} statement function declaration
|
|
1696
|
+
*/
|
|
1697
|
+
walkFunctionDeclaration(statement) {
|
|
1698
|
+
const wasTopLevel = this.scope.topLevelScope;
|
|
1699
|
+
this.scope.topLevelScope = false;
|
|
1700
|
+
this.inFunctionScope(true, statement.params, () => {
|
|
1701
|
+
for (const param of statement.params) {
|
|
1702
|
+
this.walkPattern(param);
|
|
1703
|
+
}
|
|
1704
|
+
if (statement.body.type === 'BlockStatement') {
|
|
1705
|
+
this.detectMode(statement.body.body);
|
|
1706
|
+
const prev = this.prevStatement;
|
|
1707
|
+
this.preWalkStatement(statement.body);
|
|
1708
|
+
this.prevStatement = prev;
|
|
1709
|
+
this.walkStatement(statement.body);
|
|
1710
|
+
}
|
|
1711
|
+
else {
|
|
1712
|
+
this.walkExpression(statement.body);
|
|
1713
|
+
}
|
|
1714
|
+
});
|
|
1715
|
+
this.scope.topLevelScope = wasTopLevel;
|
|
1716
|
+
}
|
|
1717
|
+
/**
|
|
1718
|
+
* @param {ExpressionStatement} statement expression statement
|
|
1719
|
+
*/
|
|
1720
|
+
blockPreWalkExpressionStatement(statement) {
|
|
1721
|
+
const expression = statement.expression;
|
|
1722
|
+
switch (expression.type) {
|
|
1723
|
+
case 'AssignmentExpression':
|
|
1724
|
+
this.preWalkAssignmentExpression(expression);
|
|
1725
|
+
}
|
|
1726
|
+
}
|
|
1727
|
+
/**
|
|
1728
|
+
* @param {AssignmentExpression} expression assignment expression
|
|
1729
|
+
*/
|
|
1730
|
+
preWalkAssignmentExpression(expression) {
|
|
1731
|
+
if (expression.left.type !== 'ObjectPattern' || !this.destructuringAssignmentProperties)
|
|
1732
|
+
return;
|
|
1733
|
+
const keys = this._preWalkObjectPattern(expression.left);
|
|
1734
|
+
if (!keys)
|
|
1735
|
+
return;
|
|
1736
|
+
// check multiple assignments
|
|
1737
|
+
if (this.destructuringAssignmentProperties.has(expression)) {
|
|
1738
|
+
const set = this.destructuringAssignmentProperties.get(expression);
|
|
1739
|
+
this.destructuringAssignmentProperties.delete(expression);
|
|
1740
|
+
for (const id of set)
|
|
1741
|
+
keys.add(id);
|
|
1742
|
+
}
|
|
1743
|
+
this.destructuringAssignmentProperties.set(expression.right.type === 'AwaitExpression' ? expression.right.argument : expression.right, keys);
|
|
1744
|
+
if (expression.right.type === 'AssignmentExpression') {
|
|
1745
|
+
this.preWalkAssignmentExpression(expression.right);
|
|
1746
|
+
}
|
|
1747
|
+
}
|
|
1748
|
+
blockPreWalkImportDeclaration(statement) {
|
|
1749
|
+
const source = statement.source.value;
|
|
1750
|
+
this.hooks.import.call(statement, source);
|
|
1751
|
+
for (const specifier of statement.specifiers) {
|
|
1752
|
+
const name = specifier.local.name;
|
|
1753
|
+
switch (specifier.type) {
|
|
1754
|
+
case 'ImportDefaultSpecifier':
|
|
1755
|
+
if (!this.hooks.importSpecifier.call(statement, source, 'default', name)) {
|
|
1756
|
+
this.defineVariable(name);
|
|
1757
|
+
}
|
|
1758
|
+
break;
|
|
1759
|
+
case 'ImportSpecifier':
|
|
1760
|
+
if (!this.hooks.importSpecifier.call(statement, source, specifier.imported.name || specifier.imported.value, name)) {
|
|
1761
|
+
this.defineVariable(name);
|
|
1762
|
+
}
|
|
1763
|
+
break;
|
|
1764
|
+
case 'ImportNamespaceSpecifier':
|
|
1765
|
+
if (!this.hooks.importSpecifier.call(statement, source, null, name)) {
|
|
1766
|
+
this.defineVariable(name);
|
|
1767
|
+
}
|
|
1768
|
+
break;
|
|
1769
|
+
default:
|
|
1770
|
+
this.defineVariable(name);
|
|
1771
|
+
}
|
|
1772
|
+
}
|
|
1773
|
+
}
|
|
1774
|
+
enterDeclaration(declaration, onIdent) {
|
|
1775
|
+
switch (declaration.type) {
|
|
1776
|
+
case 'VariableDeclaration':
|
|
1777
|
+
for (const declarator of declaration.declarations) {
|
|
1778
|
+
switch (declarator.type) {
|
|
1779
|
+
case 'VariableDeclarator': {
|
|
1780
|
+
this.enterPattern(declarator.id, onIdent);
|
|
1781
|
+
break;
|
|
1782
|
+
}
|
|
1783
|
+
}
|
|
1784
|
+
}
|
|
1785
|
+
break;
|
|
1786
|
+
case 'FunctionDeclaration':
|
|
1787
|
+
this.enterPattern(declaration.id, onIdent);
|
|
1788
|
+
break;
|
|
1789
|
+
case 'ClassDeclaration':
|
|
1790
|
+
this.enterPattern(declaration.id, onIdent);
|
|
1791
|
+
break;
|
|
1792
|
+
}
|
|
1793
|
+
}
|
|
1794
|
+
blockPreWalkExportNamedDeclaration(statement) {
|
|
1795
|
+
let source;
|
|
1796
|
+
if (statement.source) {
|
|
1797
|
+
source = statement.source.value;
|
|
1798
|
+
this.hooks.exportImport.call(statement, source);
|
|
1799
|
+
}
|
|
1800
|
+
else {
|
|
1801
|
+
this.hooks.export.call(statement);
|
|
1802
|
+
}
|
|
1803
|
+
if (statement.declaration) {
|
|
1804
|
+
if (!this.hooks.exportDeclaration.call(statement, statement.declaration)) {
|
|
1805
|
+
const prev = this.prevStatement;
|
|
1806
|
+
this.preWalkStatement(statement.declaration);
|
|
1807
|
+
this.prevStatement = prev;
|
|
1808
|
+
this.blockPreWalkStatement(statement.declaration);
|
|
1809
|
+
let index = 0;
|
|
1810
|
+
this.enterDeclaration(statement.declaration, def => {
|
|
1811
|
+
this.hooks.exportSpecifier.call(statement, def, def, index++);
|
|
1812
|
+
});
|
|
1813
|
+
}
|
|
1814
|
+
}
|
|
1815
|
+
if (statement.specifiers) {
|
|
1816
|
+
for (let specifierIndex = 0; specifierIndex < statement.specifiers.length; specifierIndex++) {
|
|
1817
|
+
const specifier = statement.specifiers[specifierIndex];
|
|
1818
|
+
switch (specifier.type) {
|
|
1819
|
+
case 'ExportSpecifier': {
|
|
1820
|
+
const name = specifier.exported.name || specifier.exported.value;
|
|
1821
|
+
if (source) {
|
|
1822
|
+
this.hooks.exportImportSpecifier.call(statement, source, specifier.local.name, name, specifierIndex);
|
|
1823
|
+
}
|
|
1824
|
+
else {
|
|
1825
|
+
this.hooks.exportSpecifier.call(statement, specifier.local.name, name, specifierIndex);
|
|
1826
|
+
}
|
|
1827
|
+
break;
|
|
1828
|
+
}
|
|
1829
|
+
}
|
|
1830
|
+
}
|
|
1831
|
+
}
|
|
1832
|
+
}
|
|
1833
|
+
/**
|
|
1834
|
+
* @param {ExportNamedDeclaration} statement the statement
|
|
1835
|
+
*/
|
|
1836
|
+
walkExportNamedDeclaration(statement) {
|
|
1837
|
+
if (statement.declaration) {
|
|
1838
|
+
this.walkStatement(statement.declaration);
|
|
1839
|
+
}
|
|
1840
|
+
}
|
|
1841
|
+
blockPreWalkExportDefaultDeclaration(statement) {
|
|
1842
|
+
const prev = this.prevStatement;
|
|
1843
|
+
this.preWalkStatement(statement.declaration);
|
|
1844
|
+
this.prevStatement = prev;
|
|
1845
|
+
this.blockPreWalkStatement(statement.declaration);
|
|
1846
|
+
if (statement.declaration.id &&
|
|
1847
|
+
statement.declaration.type !== 'FunctionExpression' &&
|
|
1848
|
+
statement.declaration.type !== 'ClassExpression') {
|
|
1849
|
+
this.hooks.exportSpecifier.call(statement, statement.declaration.id.name, 'default', undefined);
|
|
1850
|
+
}
|
|
1851
|
+
}
|
|
1852
|
+
walkExportDefaultDeclaration(statement) {
|
|
1853
|
+
this.hooks.export.call(statement);
|
|
1854
|
+
if (statement.declaration.id &&
|
|
1855
|
+
statement.declaration.type !== 'FunctionExpression' &&
|
|
1856
|
+
statement.declaration.type !== 'ClassExpression') {
|
|
1857
|
+
if (!this.hooks.exportDeclaration.call(statement, statement.declaration)) {
|
|
1858
|
+
this.walkStatement(statement.declaration);
|
|
1859
|
+
}
|
|
1860
|
+
}
|
|
1861
|
+
else {
|
|
1862
|
+
// Acorn parses `module.exports = function() {}` as `FunctionDeclaration` and
|
|
1863
|
+
// `module.exports = class {}` as `ClassDeclaration`, both with `id = null`.
|
|
1864
|
+
// These nodes must be treated as expressions.
|
|
1865
|
+
if (statement.declaration.type === 'FunctionDeclaration' ||
|
|
1866
|
+
statement.declaration.type === 'ClassDeclaration') {
|
|
1867
|
+
this.walkStatement(statement.declaration);
|
|
1868
|
+
}
|
|
1869
|
+
else {
|
|
1870
|
+
this.walkExpression(statement.declaration);
|
|
1871
|
+
}
|
|
1872
|
+
if (!this.hooks.exportExpression.call(statement, statement.declaration)) {
|
|
1873
|
+
this.hooks.exportSpecifier.call(statement, statement.declaration, 'default', undefined);
|
|
1874
|
+
}
|
|
1875
|
+
}
|
|
1876
|
+
}
|
|
1877
|
+
blockPreWalkExportAllDeclaration(statement) {
|
|
1878
|
+
const source = statement.source.value;
|
|
1879
|
+
const name = statement.exported ? statement.exported.name : null;
|
|
1880
|
+
this.hooks.exportImport.call(statement, source);
|
|
1881
|
+
this.hooks.exportImportSpecifier.call(statement, source, null, name, 0);
|
|
1882
|
+
}
|
|
1883
|
+
/**
|
|
1884
|
+
* @param {VariableDeclaration} statement variable declaration
|
|
1885
|
+
*/
|
|
1886
|
+
preWalkVariableDeclaration(statement) {
|
|
1887
|
+
if (statement.kind !== 'var')
|
|
1888
|
+
return;
|
|
1889
|
+
this._preWalkVariableDeclaration(statement, this.hooks.varDeclarationVar);
|
|
1890
|
+
}
|
|
1891
|
+
/**
|
|
1892
|
+
* @param {VariableDeclaration} statement variable declaration
|
|
1893
|
+
*/
|
|
1894
|
+
blockPreWalkVariableDeclaration(statement) {
|
|
1895
|
+
if (statement.kind === 'var')
|
|
1896
|
+
return;
|
|
1897
|
+
const hookMap = statement.kind === 'const' ? this.hooks.varDeclarationConst : this.hooks.varDeclarationLet;
|
|
1898
|
+
this._preWalkVariableDeclaration(statement, hookMap);
|
|
1899
|
+
}
|
|
1900
|
+
/**
|
|
1901
|
+
* @param {VariableDeclaration} statement variable declaration
|
|
1902
|
+
* @param {TODO} hookMap map of hooks
|
|
1903
|
+
*/
|
|
1904
|
+
_preWalkVariableDeclaration(statement, hookMap) {
|
|
1905
|
+
for (const declarator of statement.declarations) {
|
|
1906
|
+
switch (declarator.type) {
|
|
1907
|
+
case 'VariableDeclarator': {
|
|
1908
|
+
this.preWalkVariableDeclarator(declarator);
|
|
1909
|
+
if (!this.hooks.preDeclarator.call(declarator, statement)) {
|
|
1910
|
+
this.enterPattern(declarator.id, (name, decl) => {
|
|
1911
|
+
let hook = hookMap.get(name);
|
|
1912
|
+
if (hook === undefined || !hook.call(decl)) {
|
|
1913
|
+
hook = this.hooks.varDeclaration.get(name);
|
|
1914
|
+
if (hook === undefined || !hook.call(decl)) {
|
|
1915
|
+
this.defineVariable(name);
|
|
1916
|
+
}
|
|
1917
|
+
}
|
|
1918
|
+
});
|
|
1919
|
+
}
|
|
1920
|
+
break;
|
|
1921
|
+
}
|
|
1922
|
+
}
|
|
1923
|
+
}
|
|
1924
|
+
}
|
|
1925
|
+
/**
|
|
1926
|
+
* @param {ObjectPattern} objectPattern object pattern
|
|
1927
|
+
* @returns {Set<string> | undefined} set of names or undefined if not all keys are identifiers
|
|
1928
|
+
*/
|
|
1929
|
+
_preWalkObjectPattern(objectPattern) {
|
|
1930
|
+
const ids = new Set();
|
|
1931
|
+
const properties = objectPattern.properties;
|
|
1932
|
+
for (let i = 0; i < properties.length; i++) {
|
|
1933
|
+
const property = properties[i];
|
|
1934
|
+
if (property.type !== 'Property')
|
|
1935
|
+
return;
|
|
1936
|
+
const key = property.key;
|
|
1937
|
+
if (key.type === 'Identifier') {
|
|
1938
|
+
ids.add(key.name);
|
|
1939
|
+
}
|
|
1940
|
+
else {
|
|
1941
|
+
const id = this.evaluateExpression(key);
|
|
1942
|
+
const str = id.asString();
|
|
1943
|
+
if (str) {
|
|
1944
|
+
ids.add(str);
|
|
1945
|
+
}
|
|
1946
|
+
else {
|
|
1947
|
+
// could not evaluate key
|
|
1948
|
+
return;
|
|
1949
|
+
}
|
|
1950
|
+
}
|
|
1951
|
+
}
|
|
1952
|
+
return ids;
|
|
1953
|
+
}
|
|
1954
|
+
/**
|
|
1955
|
+
* @param {VariableDeclarator} declarator variable declarator
|
|
1956
|
+
*/
|
|
1957
|
+
preWalkVariableDeclarator(declarator) {
|
|
1958
|
+
if (!declarator.init ||
|
|
1959
|
+
declarator.id.type !== 'ObjectPattern' ||
|
|
1960
|
+
!this.destructuringAssignmentProperties)
|
|
1961
|
+
return;
|
|
1962
|
+
const keys = this._preWalkObjectPattern(declarator.id);
|
|
1963
|
+
if (!keys)
|
|
1964
|
+
return;
|
|
1965
|
+
this.destructuringAssignmentProperties.set(declarator.init.type === 'AwaitExpression' ? declarator.init.argument : declarator.init, keys);
|
|
1966
|
+
if (declarator.init.type === 'AssignmentExpression') {
|
|
1967
|
+
this.preWalkAssignmentExpression(declarator.init);
|
|
1968
|
+
}
|
|
1969
|
+
}
|
|
1970
|
+
/**
|
|
1971
|
+
* @param {VariableDeclaration} statement variable declaration
|
|
1972
|
+
*/
|
|
1973
|
+
walkVariableDeclaration(statement) {
|
|
1974
|
+
for (const declarator of statement.declarations) {
|
|
1975
|
+
switch (declarator.type) {
|
|
1976
|
+
case 'VariableDeclarator': {
|
|
1977
|
+
const renameIdentifier = declarator.init && this.getRenameIdentifier(declarator.init);
|
|
1978
|
+
if (renameIdentifier && declarator.id.type === 'Identifier') {
|
|
1979
|
+
const hook = this.hooks.canRename.get(renameIdentifier);
|
|
1980
|
+
if (hook === null || hook === void 0 ? void 0 : hook.call(declarator.init)) {
|
|
1981
|
+
// renaming with "var a = b;"
|
|
1982
|
+
const hook = this.hooks.rename.get(renameIdentifier);
|
|
1983
|
+
if (hook === undefined || !hook.call(declarator.init)) {
|
|
1984
|
+
this.setVariable(declarator.id.name, renameIdentifier);
|
|
1985
|
+
}
|
|
1986
|
+
break;
|
|
1987
|
+
}
|
|
1988
|
+
}
|
|
1989
|
+
if (!this.hooks.declarator.call(declarator, statement)) {
|
|
1990
|
+
this.walkPattern(declarator.id);
|
|
1991
|
+
if (declarator.init)
|
|
1992
|
+
this.walkExpression(declarator.init);
|
|
1993
|
+
}
|
|
1994
|
+
break;
|
|
1995
|
+
}
|
|
1996
|
+
}
|
|
1997
|
+
}
|
|
1998
|
+
}
|
|
1999
|
+
/**
|
|
2000
|
+
* @param {ClassDeclaration} statement class declaration
|
|
2001
|
+
*/
|
|
2002
|
+
blockPreWalkClassDeclaration(statement) {
|
|
2003
|
+
if (statement.id) {
|
|
2004
|
+
this.defineVariable(statement.id.name);
|
|
2005
|
+
}
|
|
2006
|
+
}
|
|
2007
|
+
/**
|
|
2008
|
+
* @param {ClassDeclaration} statement class declaration
|
|
2009
|
+
*/
|
|
2010
|
+
walkClassDeclaration(statement) {
|
|
2011
|
+
this.walkClass(statement);
|
|
2012
|
+
}
|
|
2013
|
+
/**
|
|
2014
|
+
* @param {SwitchCase[]} switchCases switch statement
|
|
2015
|
+
*/
|
|
2016
|
+
preWalkSwitchCases(switchCases) {
|
|
2017
|
+
for (let index = 0, len = switchCases.length; index < len; index++) {
|
|
2018
|
+
const switchCase = switchCases[index];
|
|
2019
|
+
this.preWalkStatements(switchCase.consequent);
|
|
2020
|
+
}
|
|
2021
|
+
}
|
|
2022
|
+
/**
|
|
2023
|
+
* @param {SwitchCase[]} switchCases switch statement
|
|
2024
|
+
*/
|
|
2025
|
+
walkSwitchCases(switchCases) {
|
|
2026
|
+
this.inBlockScope(() => {
|
|
2027
|
+
const len = switchCases.length;
|
|
2028
|
+
// we need to pre walk all statements first since we can have invalid code
|
|
2029
|
+
// import A from "module";
|
|
2030
|
+
// switch(1) {
|
|
2031
|
+
// case 1:
|
|
2032
|
+
// console.log(A); // should fail at runtime
|
|
2033
|
+
// case 2:
|
|
2034
|
+
// const A = 1;
|
|
2035
|
+
// }
|
|
2036
|
+
for (let index = 0; index < len; index++) {
|
|
2037
|
+
const switchCase = switchCases[index];
|
|
2038
|
+
if (switchCase.consequent.length > 0) {
|
|
2039
|
+
const prev = this.prevStatement;
|
|
2040
|
+
this.blockPreWalkStatements(switchCase.consequent);
|
|
2041
|
+
this.prevStatement = prev;
|
|
2042
|
+
}
|
|
2043
|
+
}
|
|
2044
|
+
for (let index = 0; index < len; index++) {
|
|
2045
|
+
const switchCase = switchCases[index];
|
|
2046
|
+
if (switchCase.test) {
|
|
2047
|
+
this.walkExpression(switchCase.test);
|
|
2048
|
+
}
|
|
2049
|
+
if (switchCase.consequent.length > 0) {
|
|
2050
|
+
this.walkStatements(switchCase.consequent);
|
|
2051
|
+
}
|
|
2052
|
+
}
|
|
2053
|
+
});
|
|
2054
|
+
}
|
|
2055
|
+
/**
|
|
2056
|
+
* @param {CatchClause} catchClause catch clause
|
|
2057
|
+
*/
|
|
2058
|
+
preWalkCatchClause(catchClause) {
|
|
2059
|
+
this.preWalkStatement(catchClause.body);
|
|
2060
|
+
}
|
|
2061
|
+
/**
|
|
2062
|
+
* @param {CatchClause} catchClause catch clause
|
|
2063
|
+
*/
|
|
2064
|
+
walkCatchClause(catchClause) {
|
|
2065
|
+
this.inBlockScope(() => {
|
|
2066
|
+
// Error binding is optional in catch clause since ECMAScript 2019
|
|
2067
|
+
if (catchClause.param !== null) {
|
|
2068
|
+
this.enterPattern(catchClause.param, ident => {
|
|
2069
|
+
this.defineVariable(ident);
|
|
2070
|
+
});
|
|
2071
|
+
this.walkPattern(catchClause.param);
|
|
2072
|
+
}
|
|
2073
|
+
const prev = this.prevStatement;
|
|
2074
|
+
this.blockPreWalkStatement(catchClause.body);
|
|
2075
|
+
this.prevStatement = prev;
|
|
2076
|
+
this.walkStatement(catchClause.body);
|
|
2077
|
+
});
|
|
2078
|
+
}
|
|
2079
|
+
/**
|
|
2080
|
+
* @param {Pattern} pattern pattern
|
|
2081
|
+
*/
|
|
2082
|
+
walkPattern(pattern) {
|
|
2083
|
+
switch (pattern.type) {
|
|
2084
|
+
case 'ArrayPattern':
|
|
2085
|
+
this.walkArrayPattern(pattern);
|
|
2086
|
+
break;
|
|
2087
|
+
case 'AssignmentPattern':
|
|
2088
|
+
this.walkAssignmentPattern(pattern);
|
|
2089
|
+
break;
|
|
2090
|
+
case 'MemberExpression':
|
|
2091
|
+
this.walkMemberExpression(pattern);
|
|
2092
|
+
break;
|
|
2093
|
+
case 'ObjectPattern':
|
|
2094
|
+
this.walkObjectPattern(pattern);
|
|
2095
|
+
break;
|
|
2096
|
+
case 'RestElement':
|
|
2097
|
+
this.walkRestElement(pattern);
|
|
2098
|
+
break;
|
|
2099
|
+
}
|
|
2100
|
+
}
|
|
2101
|
+
/**
|
|
2102
|
+
* @param {AssignmentPattern} pattern assignment pattern
|
|
2103
|
+
*/
|
|
2104
|
+
walkAssignmentPattern(pattern) {
|
|
2105
|
+
this.walkExpression(pattern.right);
|
|
2106
|
+
this.walkPattern(pattern.left);
|
|
2107
|
+
}
|
|
2108
|
+
walkObjectPattern(pattern) {
|
|
2109
|
+
for (let i = 0, len = pattern.properties.length; i < len; i++) {
|
|
2110
|
+
const prop = pattern.properties[i];
|
|
2111
|
+
if (prop) {
|
|
2112
|
+
if (prop.computed)
|
|
2113
|
+
this.walkExpression(prop.key);
|
|
2114
|
+
if (prop.value)
|
|
2115
|
+
this.walkPattern(prop.value);
|
|
2116
|
+
}
|
|
2117
|
+
}
|
|
2118
|
+
}
|
|
2119
|
+
/**
|
|
2120
|
+
* @param {ArrayPattern} pattern array pattern
|
|
2121
|
+
*/
|
|
2122
|
+
walkArrayPattern(pattern) {
|
|
2123
|
+
for (let i = 0, len = pattern.elements.length; i < len; i++) {
|
|
2124
|
+
const element = pattern.elements[i];
|
|
2125
|
+
if (element)
|
|
2126
|
+
this.walkPattern(element);
|
|
2127
|
+
}
|
|
2128
|
+
}
|
|
2129
|
+
/**
|
|
2130
|
+
* @param {RestElement} pattern rest element
|
|
2131
|
+
*/
|
|
2132
|
+
walkRestElement(pattern) {
|
|
2133
|
+
this.walkPattern(pattern.argument);
|
|
2134
|
+
}
|
|
2135
|
+
/**
|
|
2136
|
+
* @param {(Expression | SpreadElement | null)[]} expressions expressions
|
|
2137
|
+
*/
|
|
2138
|
+
walkExpressions(expressions) {
|
|
2139
|
+
for (const expression of expressions) {
|
|
2140
|
+
if (expression) {
|
|
2141
|
+
this.walkExpression(expression);
|
|
2142
|
+
}
|
|
2143
|
+
}
|
|
2144
|
+
}
|
|
2145
|
+
/**
|
|
2146
|
+
* @param {TODO} expression expression
|
|
2147
|
+
*/
|
|
2148
|
+
walkExpression(expression) {
|
|
2149
|
+
switch (expression.type) {
|
|
2150
|
+
case 'ArrayExpression':
|
|
2151
|
+
this.walkArrayExpression(expression);
|
|
2152
|
+
break;
|
|
2153
|
+
case 'ArrowFunctionExpression':
|
|
2154
|
+
this.walkArrowFunctionExpression(expression);
|
|
2155
|
+
break;
|
|
2156
|
+
case 'AssignmentExpression':
|
|
2157
|
+
this.walkAssignmentExpression(expression);
|
|
2158
|
+
break;
|
|
2159
|
+
case 'AwaitExpression':
|
|
2160
|
+
this.walkAwaitExpression(expression);
|
|
2161
|
+
break;
|
|
2162
|
+
case 'BinaryExpression':
|
|
2163
|
+
this.walkBinaryExpression(expression);
|
|
2164
|
+
break;
|
|
2165
|
+
case 'CallExpression':
|
|
2166
|
+
this.walkCallExpression(expression);
|
|
2167
|
+
break;
|
|
2168
|
+
case 'ChainExpression':
|
|
2169
|
+
this.walkChainExpression(expression);
|
|
2170
|
+
break;
|
|
2171
|
+
case 'ClassExpression':
|
|
2172
|
+
this.walkClassExpression(expression);
|
|
2173
|
+
break;
|
|
2174
|
+
case 'ConditionalExpression':
|
|
2175
|
+
this.walkConditionalExpression(expression);
|
|
2176
|
+
break;
|
|
2177
|
+
case 'FunctionExpression':
|
|
2178
|
+
this.walkFunctionExpression(expression);
|
|
2179
|
+
break;
|
|
2180
|
+
case 'Identifier':
|
|
2181
|
+
this.walkIdentifier(expression);
|
|
2182
|
+
break;
|
|
2183
|
+
case 'ImportExpression':
|
|
2184
|
+
this.walkImportExpression(expression);
|
|
2185
|
+
break;
|
|
2186
|
+
case 'LogicalExpression':
|
|
2187
|
+
this.walkLogicalExpression(expression);
|
|
2188
|
+
break;
|
|
2189
|
+
case 'MetaProperty':
|
|
2190
|
+
this.walkMetaProperty(expression);
|
|
2191
|
+
break;
|
|
2192
|
+
case 'MemberExpression':
|
|
2193
|
+
this.walkMemberExpression(expression);
|
|
2194
|
+
break;
|
|
2195
|
+
case 'NewExpression':
|
|
2196
|
+
this.walkNewExpression(expression);
|
|
2197
|
+
break;
|
|
2198
|
+
case 'ObjectExpression':
|
|
2199
|
+
this.walkObjectExpression(expression);
|
|
2200
|
+
break;
|
|
2201
|
+
case 'SequenceExpression':
|
|
2202
|
+
this.walkSequenceExpression(expression);
|
|
2203
|
+
break;
|
|
2204
|
+
case 'SpreadElement':
|
|
2205
|
+
this.walkSpreadElement(expression);
|
|
2206
|
+
break;
|
|
2207
|
+
case 'TaggedTemplateExpression':
|
|
2208
|
+
this.walkTaggedTemplateExpression(expression);
|
|
2209
|
+
break;
|
|
2210
|
+
case 'TemplateLiteral':
|
|
2211
|
+
this.walkTemplateLiteral(expression);
|
|
2212
|
+
break;
|
|
2213
|
+
case 'ThisExpression':
|
|
2214
|
+
this.walkThisExpression(expression);
|
|
2215
|
+
break;
|
|
2216
|
+
case 'UnaryExpression':
|
|
2217
|
+
this.walkUnaryExpression(expression);
|
|
2218
|
+
break;
|
|
2219
|
+
case 'UpdateExpression':
|
|
2220
|
+
this.walkUpdateExpression(expression);
|
|
2221
|
+
break;
|
|
2222
|
+
case 'YieldExpression':
|
|
2223
|
+
this.walkYieldExpression(expression);
|
|
2224
|
+
break;
|
|
2225
|
+
}
|
|
2226
|
+
}
|
|
2227
|
+
/**
|
|
2228
|
+
* @param {AwaitExpression} expression await expression
|
|
2229
|
+
*/
|
|
2230
|
+
walkAwaitExpression(expression) {
|
|
2231
|
+
if (this.scope.topLevelScope === true)
|
|
2232
|
+
this.hooks.topLevelAwait.call(expression);
|
|
2233
|
+
this.walkExpression(expression.argument);
|
|
2234
|
+
}
|
|
2235
|
+
/**
|
|
2236
|
+
* @param {ArrayExpression} expression array expression
|
|
2237
|
+
*/
|
|
2238
|
+
walkArrayExpression(expression) {
|
|
2239
|
+
if (expression.elements) {
|
|
2240
|
+
this.walkExpressions(expression.elements);
|
|
2241
|
+
}
|
|
2242
|
+
}
|
|
2243
|
+
/**
|
|
2244
|
+
* @param {SpreadElement} expression spread element
|
|
2245
|
+
*/
|
|
2246
|
+
walkSpreadElement(expression) {
|
|
2247
|
+
if (expression.argument) {
|
|
2248
|
+
this.walkExpression(expression.argument);
|
|
2249
|
+
}
|
|
2250
|
+
}
|
|
2251
|
+
/**
|
|
2252
|
+
* @param {ObjectExpression} expression object expression
|
|
2253
|
+
*/
|
|
2254
|
+
walkObjectExpression(expression) {
|
|
2255
|
+
for (let propIndex = 0, len = expression.properties.length; propIndex < len; propIndex++) {
|
|
2256
|
+
const prop = expression.properties[propIndex];
|
|
2257
|
+
this.walkProperty(prop);
|
|
2258
|
+
}
|
|
2259
|
+
}
|
|
2260
|
+
/**
|
|
2261
|
+
* @param {Property | SpreadElement} prop property or spread element
|
|
2262
|
+
*/
|
|
2263
|
+
walkProperty(prop) {
|
|
2264
|
+
if (prop.type === 'SpreadElement') {
|
|
2265
|
+
this.walkExpression(prop.argument);
|
|
2266
|
+
return;
|
|
2267
|
+
}
|
|
2268
|
+
if (prop.computed) {
|
|
2269
|
+
this.walkExpression(prop.key);
|
|
2270
|
+
}
|
|
2271
|
+
if (prop.shorthand && prop.value && prop.value.type === 'Identifier') {
|
|
2272
|
+
this.scope.inShorthand = prop.value.name;
|
|
2273
|
+
this.walkIdentifier(prop.value);
|
|
2274
|
+
this.scope.inShorthand = false;
|
|
2275
|
+
}
|
|
2276
|
+
else {
|
|
2277
|
+
this.walkExpression(prop.value);
|
|
2278
|
+
}
|
|
2279
|
+
}
|
|
2280
|
+
/**
|
|
2281
|
+
* @param {FunctionExpression} expression arrow function expression
|
|
2282
|
+
*/
|
|
2283
|
+
walkFunctionExpression(expression) {
|
|
2284
|
+
const wasTopLevel = this.scope.topLevelScope;
|
|
2285
|
+
this.scope.topLevelScope = false;
|
|
2286
|
+
const scopeParams = [...expression.params];
|
|
2287
|
+
// Add function name in scope for recursive calls
|
|
2288
|
+
if (expression.id) {
|
|
2289
|
+
scopeParams.push(expression.id);
|
|
2290
|
+
}
|
|
2291
|
+
this.inFunctionScope(true, scopeParams, () => {
|
|
2292
|
+
for (const param of expression.params) {
|
|
2293
|
+
this.walkPattern(param);
|
|
2294
|
+
}
|
|
2295
|
+
if (expression.body.type === 'BlockStatement') {
|
|
2296
|
+
this.detectMode(expression.body.body);
|
|
2297
|
+
const prev = this.prevStatement;
|
|
2298
|
+
this.preWalkStatement(expression.body);
|
|
2299
|
+
this.prevStatement = prev;
|
|
2300
|
+
this.walkStatement(expression.body);
|
|
2301
|
+
}
|
|
2302
|
+
else {
|
|
2303
|
+
this.walkExpression(expression.body);
|
|
2304
|
+
}
|
|
2305
|
+
});
|
|
2306
|
+
this.scope.topLevelScope = wasTopLevel;
|
|
2307
|
+
}
|
|
2308
|
+
/**
|
|
2309
|
+
* @param {ArrowFunctionExpression} expression arrow function expression
|
|
2310
|
+
*/
|
|
2311
|
+
walkArrowFunctionExpression(expression) {
|
|
2312
|
+
const wasTopLevel = this.scope.topLevelScope;
|
|
2313
|
+
this.scope.topLevelScope = wasTopLevel ? 'arrow' : false;
|
|
2314
|
+
this.inFunctionScope(false, expression.params, () => {
|
|
2315
|
+
for (const param of expression.params) {
|
|
2316
|
+
this.walkPattern(param);
|
|
2317
|
+
}
|
|
2318
|
+
if (expression.body.type === 'BlockStatement') {
|
|
2319
|
+
this.detectMode(expression.body.body);
|
|
2320
|
+
const prev = this.prevStatement;
|
|
2321
|
+
this.preWalkStatement(expression.body);
|
|
2322
|
+
this.prevStatement = prev;
|
|
2323
|
+
this.walkStatement(expression.body);
|
|
2324
|
+
}
|
|
2325
|
+
else {
|
|
2326
|
+
this.walkExpression(expression.body);
|
|
2327
|
+
}
|
|
2328
|
+
});
|
|
2329
|
+
this.scope.topLevelScope = wasTopLevel;
|
|
2330
|
+
}
|
|
2331
|
+
/**
|
|
2332
|
+
* @param {SequenceExpression} expression the sequence
|
|
2333
|
+
*/
|
|
2334
|
+
walkSequenceExpression(expression) {
|
|
2335
|
+
if (!expression.expressions)
|
|
2336
|
+
return;
|
|
2337
|
+
// We treat sequence expressions like statements when they are one statement level
|
|
2338
|
+
// This has some benefits for optimizations that only work on statement level
|
|
2339
|
+
const currentStatement = this.statementPath[this.statementPath.length - 1];
|
|
2340
|
+
if (currentStatement === expression ||
|
|
2341
|
+
(currentStatement.type === 'ExpressionStatement' &&
|
|
2342
|
+
currentStatement.expression === expression)) {
|
|
2343
|
+
const old = this.statementPath.pop();
|
|
2344
|
+
for (const expr of expression.expressions) {
|
|
2345
|
+
this.statementPath.push(expr);
|
|
2346
|
+
this.walkExpression(expr);
|
|
2347
|
+
this.statementPath.pop();
|
|
2348
|
+
}
|
|
2349
|
+
this.statementPath.push(old);
|
|
2350
|
+
}
|
|
2351
|
+
else {
|
|
2352
|
+
this.walkExpressions(expression.expressions);
|
|
2353
|
+
}
|
|
2354
|
+
}
|
|
2355
|
+
/**
|
|
2356
|
+
* @param {UpdateExpression} expression the update expression
|
|
2357
|
+
*/
|
|
2358
|
+
walkUpdateExpression(expression) {
|
|
2359
|
+
this.walkExpression(expression.argument);
|
|
2360
|
+
}
|
|
2361
|
+
/**
|
|
2362
|
+
* @param {UnaryExpression} expression the unary expression
|
|
2363
|
+
*/
|
|
2364
|
+
walkUnaryExpression(expression) {
|
|
2365
|
+
if (expression.operator === 'typeof') {
|
|
2366
|
+
const result = this.callHooksForExpression(this.hooks.typeof, expression.argument, expression);
|
|
2367
|
+
if (result === true)
|
|
2368
|
+
return;
|
|
2369
|
+
if (expression.argument.type === 'ChainExpression') {
|
|
2370
|
+
const result = this.callHooksForExpression(this.hooks.typeof, expression.argument.expression, expression);
|
|
2371
|
+
if (result === true)
|
|
2372
|
+
return;
|
|
2373
|
+
}
|
|
2374
|
+
}
|
|
2375
|
+
this.walkExpression(expression.argument);
|
|
2376
|
+
}
|
|
2377
|
+
/**
|
|
2378
|
+
* @param {LogicalExpression | BinaryExpression} expression the expression
|
|
2379
|
+
*/
|
|
2380
|
+
walkLeftRightExpression(expression) {
|
|
2381
|
+
this.walkExpression(expression.left);
|
|
2382
|
+
this.walkExpression(expression.right);
|
|
2383
|
+
}
|
|
2384
|
+
/**
|
|
2385
|
+
* @param {BinaryExpression} expression the binary expression
|
|
2386
|
+
*/
|
|
2387
|
+
walkBinaryExpression(expression) {
|
|
2388
|
+
if (this.hooks.binaryExpression.call(expression) === undefined) {
|
|
2389
|
+
this.walkLeftRightExpression(expression);
|
|
2390
|
+
}
|
|
2391
|
+
}
|
|
2392
|
+
/**
|
|
2393
|
+
* @param {LogicalExpression} expression the logical expression
|
|
2394
|
+
*/
|
|
2395
|
+
walkLogicalExpression(expression) {
|
|
2396
|
+
const result = this.hooks.expressionLogicalOperator.call(expression);
|
|
2397
|
+
if (result === undefined) {
|
|
2398
|
+
this.walkLeftRightExpression(expression);
|
|
2399
|
+
}
|
|
2400
|
+
else if (result) {
|
|
2401
|
+
this.walkExpression(expression.right);
|
|
2402
|
+
}
|
|
2403
|
+
}
|
|
2404
|
+
/**
|
|
2405
|
+
* @param {AssignmentExpression} expression assignment expression
|
|
2406
|
+
*/
|
|
2407
|
+
walkAssignmentExpression(expression) {
|
|
2408
|
+
if (expression.left.type === 'Identifier') {
|
|
2409
|
+
const renameIdentifier = this.getRenameIdentifier(expression.right);
|
|
2410
|
+
if (renameIdentifier) {
|
|
2411
|
+
if (this.callHooksForInfo(this.hooks.canRename, renameIdentifier, expression.right)) {
|
|
2412
|
+
// renaming "a = b;"
|
|
2413
|
+
if (!this.callHooksForInfo(this.hooks.rename, renameIdentifier, expression.right)) {
|
|
2414
|
+
this.setVariable(expression.left.name, typeof renameIdentifier === 'string'
|
|
2415
|
+
? this.getVariableInfo(renameIdentifier)
|
|
2416
|
+
: renameIdentifier);
|
|
2417
|
+
}
|
|
2418
|
+
return;
|
|
2419
|
+
}
|
|
2420
|
+
}
|
|
2421
|
+
this.walkExpression(expression.right);
|
|
2422
|
+
this.enterPattern(expression.left, (name, decl) => {
|
|
2423
|
+
if (!this.callHooksForName(this.hooks.assign, name, expression)) {
|
|
2424
|
+
this.walkExpression(expression.left);
|
|
2425
|
+
}
|
|
2426
|
+
});
|
|
2427
|
+
return;
|
|
2428
|
+
}
|
|
2429
|
+
if (expression.left.type.endsWith('Pattern')) {
|
|
2430
|
+
this.walkExpression(expression.right);
|
|
2431
|
+
this.enterPattern(expression.left, (name, decl) => {
|
|
2432
|
+
if (!this.callHooksForName(this.hooks.assign, name, expression)) {
|
|
2433
|
+
this.defineVariable(name);
|
|
2434
|
+
}
|
|
2435
|
+
});
|
|
2436
|
+
this.walkPattern(expression.left);
|
|
2437
|
+
}
|
|
2438
|
+
else if (expression.left.type === 'MemberExpression') {
|
|
2439
|
+
const exprName = this.getMemberExpressionInfo(expression.left, ALLOWED_MEMBER_TYPES_EXPRESSION);
|
|
2440
|
+
if (exprName) {
|
|
2441
|
+
if (this.callHooksForInfo(this.hooks.assignMemberChain, exprName.rootInfo, expression, exprName.getMembers())) {
|
|
2442
|
+
return;
|
|
2443
|
+
}
|
|
2444
|
+
}
|
|
2445
|
+
this.walkExpression(expression.right);
|
|
2446
|
+
this.walkExpression(expression.left);
|
|
2447
|
+
}
|
|
2448
|
+
else {
|
|
2449
|
+
this.walkExpression(expression.right);
|
|
2450
|
+
this.walkExpression(expression.left);
|
|
2451
|
+
}
|
|
2452
|
+
}
|
|
2453
|
+
/**
|
|
2454
|
+
* @param {ConditionalExpression} expression conditional expression
|
|
2455
|
+
*/
|
|
2456
|
+
walkConditionalExpression(expression) {
|
|
2457
|
+
const result = this.hooks.expressionConditionalOperator.call(expression);
|
|
2458
|
+
if (result === undefined) {
|
|
2459
|
+
this.walkExpression(expression.test);
|
|
2460
|
+
this.walkExpression(expression.consequent);
|
|
2461
|
+
if (expression.alternate) {
|
|
2462
|
+
this.walkExpression(expression.alternate);
|
|
2463
|
+
}
|
|
2464
|
+
}
|
|
2465
|
+
else if (result) {
|
|
2466
|
+
this.walkExpression(expression.consequent);
|
|
2467
|
+
}
|
|
2468
|
+
else if (expression.alternate) {
|
|
2469
|
+
this.walkExpression(expression.alternate);
|
|
2470
|
+
}
|
|
2471
|
+
}
|
|
2472
|
+
/**
|
|
2473
|
+
* @param {NewExpression} expression new expression
|
|
2474
|
+
*/
|
|
2475
|
+
walkNewExpression(expression) {
|
|
2476
|
+
const result = this.callHooksForExpression(this.hooks.new, expression.callee, expression);
|
|
2477
|
+
if (result === true)
|
|
2478
|
+
return;
|
|
2479
|
+
this.walkExpression(expression.callee);
|
|
2480
|
+
if (expression.arguments) {
|
|
2481
|
+
this.walkExpressions(expression.arguments);
|
|
2482
|
+
}
|
|
2483
|
+
}
|
|
2484
|
+
/**
|
|
2485
|
+
* @param {YieldExpression} expression yield expression
|
|
2486
|
+
*/
|
|
2487
|
+
walkYieldExpression(expression) {
|
|
2488
|
+
if (expression.argument) {
|
|
2489
|
+
this.walkExpression(expression.argument);
|
|
2490
|
+
}
|
|
2491
|
+
}
|
|
2492
|
+
/**
|
|
2493
|
+
* @param {TemplateLiteral} expression template literal
|
|
2494
|
+
*/
|
|
2495
|
+
walkTemplateLiteral(expression) {
|
|
2496
|
+
if (expression.expressions) {
|
|
2497
|
+
this.walkExpressions(expression.expressions);
|
|
2498
|
+
}
|
|
2499
|
+
}
|
|
2500
|
+
walkTaggedTemplateExpression(expression) {
|
|
2501
|
+
var _a;
|
|
2502
|
+
if (expression.tag) {
|
|
2503
|
+
this.scope.inTaggedTemplateTag = true;
|
|
2504
|
+
this.walkExpression(expression.tag);
|
|
2505
|
+
this.scope.inTaggedTemplateTag = false;
|
|
2506
|
+
}
|
|
2507
|
+
if ((_a = expression.quasi) === null || _a === void 0 ? void 0 : _a.expressions) {
|
|
2508
|
+
this.walkExpressions(expression.quasi.expressions);
|
|
2509
|
+
}
|
|
2510
|
+
}
|
|
2511
|
+
walkClassExpression(expression) {
|
|
2512
|
+
this.walkClass(expression);
|
|
2513
|
+
}
|
|
2514
|
+
walkChainExpression(expression) {
|
|
2515
|
+
const result = this.hooks.optionalChaining.call(expression);
|
|
2516
|
+
if (result === undefined) {
|
|
2517
|
+
if (expression.expression.type === 'CallExpression') {
|
|
2518
|
+
this.walkCallExpression(expression.expression);
|
|
2519
|
+
}
|
|
2520
|
+
else {
|
|
2521
|
+
this.walkMemberExpression(expression.expression);
|
|
2522
|
+
}
|
|
2523
|
+
}
|
|
2524
|
+
}
|
|
2525
|
+
_walkIIFE(functionExpression, options, currentThis) {
|
|
2526
|
+
const getVarInfo = argOrThis => {
|
|
2527
|
+
const renameIdentifier = this.getRenameIdentifier(argOrThis);
|
|
2528
|
+
if (renameIdentifier) {
|
|
2529
|
+
if (this.callHooksForInfo(this.hooks.canRename, renameIdentifier, argOrThis)) {
|
|
2530
|
+
if (!this.callHooksForInfo(this.hooks.rename, renameIdentifier, argOrThis)) {
|
|
2531
|
+
return typeof renameIdentifier === 'string'
|
|
2532
|
+
? this.getVariableInfo(renameIdentifier)
|
|
2533
|
+
: renameIdentifier;
|
|
2534
|
+
}
|
|
2535
|
+
}
|
|
2536
|
+
}
|
|
2537
|
+
this.walkExpression(argOrThis);
|
|
2538
|
+
};
|
|
2539
|
+
const { params, type } = functionExpression;
|
|
2540
|
+
const arrow = type === 'ArrowFunctionExpression';
|
|
2541
|
+
const renameThis = currentThis ? getVarInfo(currentThis) : null;
|
|
2542
|
+
const varInfoForArgs = options.map(getVarInfo);
|
|
2543
|
+
const wasTopLevel = this.scope.topLevelScope;
|
|
2544
|
+
this.scope.topLevelScope = wasTopLevel && arrow ? 'arrow' : false;
|
|
2545
|
+
const scopeParams = params.filter((identifier, idx) => !varInfoForArgs[idx]);
|
|
2546
|
+
// Add function name in scope for recursive calls
|
|
2547
|
+
if (functionExpression.id) {
|
|
2548
|
+
scopeParams.push(functionExpression.id.name);
|
|
2549
|
+
}
|
|
2550
|
+
this.inFunctionScope(true, scopeParams, () => {
|
|
2551
|
+
if (renameThis && !arrow) {
|
|
2552
|
+
this.setVariable('this', renameThis);
|
|
2553
|
+
}
|
|
2554
|
+
for (let i = 0; i < varInfoForArgs.length; i++) {
|
|
2555
|
+
const varInfo = varInfoForArgs[i];
|
|
2556
|
+
if (!varInfo)
|
|
2557
|
+
continue;
|
|
2558
|
+
if (!params[i] || params[i].type !== 'Identifier')
|
|
2559
|
+
continue;
|
|
2560
|
+
this.setVariable(params[i].name, varInfo);
|
|
2561
|
+
}
|
|
2562
|
+
if (functionExpression.body.type === 'BlockStatement') {
|
|
2563
|
+
this.detectMode(functionExpression.body.body);
|
|
2564
|
+
const prev = this.prevStatement;
|
|
2565
|
+
this.preWalkStatement(functionExpression.body);
|
|
2566
|
+
this.prevStatement = prev;
|
|
2567
|
+
this.walkStatement(functionExpression.body);
|
|
2568
|
+
}
|
|
2569
|
+
else {
|
|
2570
|
+
this.walkExpression(functionExpression.body);
|
|
2571
|
+
}
|
|
2572
|
+
});
|
|
2573
|
+
this.scope.topLevelScope = wasTopLevel;
|
|
2574
|
+
}
|
|
2575
|
+
/**
|
|
2576
|
+
* @param {ImportExpression} expression import expression
|
|
2577
|
+
*/
|
|
2578
|
+
walkImportExpression(expression) {
|
|
2579
|
+
const result = this.hooks.importCall.call(expression);
|
|
2580
|
+
if (result === true)
|
|
2581
|
+
return;
|
|
2582
|
+
this.walkExpression(expression.source);
|
|
2583
|
+
}
|
|
2584
|
+
walkCallExpression(expression) {
|
|
2585
|
+
const isSimpleFunction = fn => fn.params.every(p => p.type === 'Identifier');
|
|
2586
|
+
if (expression.callee.type === 'MemberExpression' &&
|
|
2587
|
+
expression.callee.object.type.endsWith('FunctionExpression') &&
|
|
2588
|
+
!expression.callee.computed &&
|
|
2589
|
+
(expression.callee.property.name === 'call' || expression.callee.property.name === 'bind') &&
|
|
2590
|
+
expression.arguments.length > 0 &&
|
|
2591
|
+
isSimpleFunction(expression.callee.object)) {
|
|
2592
|
+
// (function(…) { }.call/bind(?, …))
|
|
2593
|
+
this._walkIIFE(expression.callee.object, expression.arguments.slice(1), expression.arguments[0]);
|
|
2594
|
+
}
|
|
2595
|
+
else if (expression.callee.type.endsWith('FunctionExpression') &&
|
|
2596
|
+
isSimpleFunction(expression.callee)) {
|
|
2597
|
+
// (function(…) { }(…))
|
|
2598
|
+
this._walkIIFE(expression.callee, expression.arguments, null);
|
|
2599
|
+
}
|
|
2600
|
+
else {
|
|
2601
|
+
if (expression.callee.type === 'MemberExpression') {
|
|
2602
|
+
const exprInfo = this.getMemberExpressionInfo(expression.callee, ALLOWED_MEMBER_TYPES_CALL_EXPRESSION);
|
|
2603
|
+
if (exprInfo && exprInfo.type === 'call') {
|
|
2604
|
+
const result = this.callHooksForInfo(this.hooks.callMemberChainOfCallMemberChain, exprInfo.rootInfo, expression, exprInfo.getCalleeMembers(), exprInfo.call, exprInfo.getMembers());
|
|
2605
|
+
if (result === true)
|
|
2606
|
+
return;
|
|
2607
|
+
}
|
|
2608
|
+
}
|
|
2609
|
+
const callee = this.evaluateExpression(expression.callee);
|
|
2610
|
+
if (callee.isIdentifier()) {
|
|
2611
|
+
const result1 = this.callHooksForInfo(this.hooks.callMemberChain, callee.rootInfo, expression, callee.getMembers(), callee.getMembersOptionals
|
|
2612
|
+
? callee.getMembersOptionals()
|
|
2613
|
+
: callee.getMembers().map(() => false), callee.getMemberRanges ? callee.getMemberRanges() : []);
|
|
2614
|
+
if (result1 === true)
|
|
2615
|
+
return;
|
|
2616
|
+
const result2 = this.callHooksForInfo(this.hooks.call, callee.identifier, expression);
|
|
2617
|
+
if (result2 === true)
|
|
2618
|
+
return;
|
|
2619
|
+
}
|
|
2620
|
+
if (expression.callee) {
|
|
2621
|
+
if (expression.callee.type === 'MemberExpression') {
|
|
2622
|
+
// because of call context we need to walk the call context as expression
|
|
2623
|
+
this.walkExpression(expression.callee.object);
|
|
2624
|
+
if (expression.callee.computed === true)
|
|
2625
|
+
this.walkExpression(expression.callee.property);
|
|
2626
|
+
}
|
|
2627
|
+
else {
|
|
2628
|
+
this.walkExpression(expression.callee);
|
|
2629
|
+
}
|
|
2630
|
+
}
|
|
2631
|
+
if (expression.arguments)
|
|
2632
|
+
this.walkExpressions(expression.arguments);
|
|
2633
|
+
}
|
|
2634
|
+
}
|
|
2635
|
+
/**
|
|
2636
|
+
* @param {MemberExpression} expression member expression
|
|
2637
|
+
*/
|
|
2638
|
+
walkMemberExpression(expression) {
|
|
2639
|
+
const exprInfo = this.getMemberExpressionInfo(expression, ALLOWED_MEMBER_TYPES_ALL);
|
|
2640
|
+
if (exprInfo) {
|
|
2641
|
+
switch (exprInfo.type) {
|
|
2642
|
+
case 'expression': {
|
|
2643
|
+
const result1 = this.callHooksForInfo(this.hooks.expression, exprInfo.name, expression);
|
|
2644
|
+
if (result1 === true)
|
|
2645
|
+
return;
|
|
2646
|
+
const members = exprInfo.getMembers();
|
|
2647
|
+
const membersOptionals = exprInfo.getMembersOptionals();
|
|
2648
|
+
const memberRanges = exprInfo.getMemberRanges();
|
|
2649
|
+
const result2 = this.callHooksForInfo(this.hooks.expressionMemberChain, exprInfo.rootInfo, expression, members, membersOptionals, memberRanges);
|
|
2650
|
+
if (result2 === true)
|
|
2651
|
+
return;
|
|
2652
|
+
this.walkMemberExpressionWithExpressionName(expression, exprInfo.name, exprInfo.rootInfo, members.slice(), () => this.callHooksForInfo(this.hooks.unhandledExpressionMemberChain, exprInfo.rootInfo, expression, members));
|
|
2653
|
+
return;
|
|
2654
|
+
}
|
|
2655
|
+
case 'call': {
|
|
2656
|
+
const result = this.callHooksForInfo(this.hooks.memberChainOfCallMemberChain, exprInfo.rootInfo, expression, exprInfo.getCalleeMembers(), exprInfo.call, exprInfo.getMembers());
|
|
2657
|
+
if (result === true)
|
|
2658
|
+
return;
|
|
2659
|
+
// Fast skip over the member chain as we already called memberChainOfCallMemberChain
|
|
2660
|
+
// and call computed property are literals anyway
|
|
2661
|
+
this.walkExpression(exprInfo.call);
|
|
2662
|
+
return;
|
|
2663
|
+
}
|
|
2664
|
+
}
|
|
2665
|
+
}
|
|
2666
|
+
this.walkExpression(expression.object);
|
|
2667
|
+
if (expression.computed === true)
|
|
2668
|
+
this.walkExpression(expression.property);
|
|
2669
|
+
}
|
|
2670
|
+
walkMemberExpressionWithExpressionName(expression, name, rootInfo, members, onUnhandled) {
|
|
2671
|
+
if (expression.object.type === 'MemberExpression') {
|
|
2672
|
+
// optimize the case where expression.object is a MemberExpression too.
|
|
2673
|
+
// we can keep info here when calling walkMemberExpression directly
|
|
2674
|
+
const property = expression.property.name || `${expression.property.value}`;
|
|
2675
|
+
name = name.slice(0, -property.length - 1);
|
|
2676
|
+
members.pop();
|
|
2677
|
+
const result = this.callHooksForInfo(this.hooks.expression, name, expression.object);
|
|
2678
|
+
if (result === true)
|
|
2679
|
+
return;
|
|
2680
|
+
this.walkMemberExpressionWithExpressionName(expression.object, name, rootInfo, members, onUnhandled);
|
|
2681
|
+
}
|
|
2682
|
+
else if (!onUnhandled || !onUnhandled()) {
|
|
2683
|
+
this.walkExpression(expression.object);
|
|
2684
|
+
}
|
|
2685
|
+
if (expression.computed === true)
|
|
2686
|
+
this.walkExpression(expression.property);
|
|
2687
|
+
}
|
|
2688
|
+
/**
|
|
2689
|
+
* @param {ThisExpression} expression this expression
|
|
2690
|
+
*/
|
|
2691
|
+
walkThisExpression(expression) {
|
|
2692
|
+
this.callHooksForName(this.hooks.expression, 'this', expression);
|
|
2693
|
+
}
|
|
2694
|
+
/**
|
|
2695
|
+
* @param {Identifier} expression identifier
|
|
2696
|
+
*/
|
|
2697
|
+
walkIdentifier(expression) {
|
|
2698
|
+
this.callHooksForName(this.hooks.expression, expression.name, expression);
|
|
2699
|
+
}
|
|
2700
|
+
/**
|
|
2701
|
+
* @param {MetaProperty} metaProperty meta property
|
|
2702
|
+
*/
|
|
2703
|
+
walkMetaProperty(metaProperty) {
|
|
2704
|
+
this.hooks.expression.for(getRootName(metaProperty)).call(metaProperty);
|
|
2705
|
+
}
|
|
2706
|
+
callHooksForExpression(hookMap, expr, ...args) {
|
|
2707
|
+
return this.callHooksForExpressionWithFallback(hookMap, expr, undefined, undefined, ...args);
|
|
2708
|
+
}
|
|
2709
|
+
/**
|
|
2710
|
+
* @template T
|
|
2711
|
+
* @template R
|
|
2712
|
+
* @param {HookMap<SyncBailHook<T, R>>} hookMap hooks the should be called
|
|
2713
|
+
* @param {MemberExpression} expr expression info
|
|
2714
|
+
* @param {(function(string, string | ScopeInfo | VariableInfo, function(): string[]): any) | undefined} fallback callback when variable in not handled by hooks
|
|
2715
|
+
* @param {(function(string): any) | undefined} defined callback when variable is defined
|
|
2716
|
+
* @param {AsArray<T>} args args for the hook
|
|
2717
|
+
* @returns {R | undefined} result of hook
|
|
2718
|
+
*/
|
|
2719
|
+
callHooksForExpressionWithFallback(hookMap, expr, fallback, defined, ...args) {
|
|
2720
|
+
const exprName = this.getMemberExpressionInfo(expr, ALLOWED_MEMBER_TYPES_EXPRESSION);
|
|
2721
|
+
if (exprName !== undefined) {
|
|
2722
|
+
const members = exprName.getMembers();
|
|
2723
|
+
return this.callHooksForInfoWithFallback(hookMap, members.length === 0 ? exprName.rootInfo : exprName.name, fallback && (name => fallback(name, exprName.rootInfo, exprName.getMembers)), defined && (() => defined(exprName.name)), ...args);
|
|
2724
|
+
}
|
|
2725
|
+
}
|
|
2726
|
+
/**
|
|
2727
|
+
* @template T
|
|
2728
|
+
* @template R
|
|
2729
|
+
* @param {HookMap<SyncBailHook<T, R>>} hookMap hooks the should be called
|
|
2730
|
+
* @param {string} name key in map
|
|
2731
|
+
* @param {AsArray<T>} args args for the hook
|
|
2732
|
+
* @returns {R | undefined} result of hook
|
|
2733
|
+
*/
|
|
2734
|
+
callHooksForName(hookMap, name, ...args) {
|
|
2735
|
+
return this.callHooksForNameWithFallback(hookMap, name, undefined, undefined, ...args);
|
|
2736
|
+
}
|
|
2737
|
+
/**
|
|
2738
|
+
* @template T
|
|
2739
|
+
* @template R
|
|
2740
|
+
* @param {HookMap<SyncBailHook<T, R>>} hookMap hooks that should be called
|
|
2741
|
+
* @param {ExportedVariableInfo} info variable info
|
|
2742
|
+
* @param {AsArray<T>} args args for the hook
|
|
2743
|
+
* @returns {R | undefined} result of hook
|
|
2744
|
+
*/
|
|
2745
|
+
callHooksForInfo(hookMap, info, ...args) {
|
|
2746
|
+
return this.callHooksForInfoWithFallback(hookMap, info, undefined, undefined, ...args);
|
|
2747
|
+
}
|
|
2748
|
+
/**
|
|
2749
|
+
* @template T
|
|
2750
|
+
* @template R
|
|
2751
|
+
* @param {HookMap<SyncBailHook<T, R>>} hookMap hooks the should be called
|
|
2752
|
+
* @param {ExportedVariableInfo} info variable info
|
|
2753
|
+
* @param {(function(string): any) | undefined} fallback callback when variable in not handled by hooks
|
|
2754
|
+
* @param {(function(): any) | undefined} defined callback when variable is defined
|
|
2755
|
+
* @param {AsArray<T>} args args for the hook
|
|
2756
|
+
* @returns {R | undefined} result of hook
|
|
2757
|
+
*/
|
|
2758
|
+
callHooksForInfoWithFallback(hookMap, info, fallback, defined, ...args) {
|
|
2759
|
+
let name;
|
|
2760
|
+
if (typeof info === 'string') {
|
|
2761
|
+
name = info;
|
|
2762
|
+
}
|
|
2763
|
+
else {
|
|
2764
|
+
if (!(info instanceof VariableInfo)) {
|
|
2765
|
+
if (defined !== undefined) {
|
|
2766
|
+
return defined();
|
|
2767
|
+
}
|
|
2768
|
+
return;
|
|
2769
|
+
}
|
|
2770
|
+
let tagInfo = info.tagInfo;
|
|
2771
|
+
while (tagInfo !== undefined) {
|
|
2772
|
+
const hook = hookMap.get(tagInfo.tag);
|
|
2773
|
+
if (hook !== undefined) {
|
|
2774
|
+
this.currentTagData = tagInfo.data;
|
|
2775
|
+
const result = hook.call(...args);
|
|
2776
|
+
this.currentTagData = undefined;
|
|
2777
|
+
if (result !== undefined)
|
|
2778
|
+
return result;
|
|
2779
|
+
}
|
|
2780
|
+
tagInfo = tagInfo.next;
|
|
2781
|
+
}
|
|
2782
|
+
if (info.freeName === true) {
|
|
2783
|
+
if (defined !== undefined) {
|
|
2784
|
+
return defined();
|
|
2785
|
+
}
|
|
2786
|
+
return;
|
|
2787
|
+
}
|
|
2788
|
+
name = info.freeName;
|
|
2789
|
+
}
|
|
2790
|
+
const hook = hookMap.get(name);
|
|
2791
|
+
if (hook !== undefined) {
|
|
2792
|
+
const result = hook.call(...args);
|
|
2793
|
+
if (result !== undefined)
|
|
2794
|
+
return result;
|
|
2795
|
+
}
|
|
2796
|
+
if (fallback !== undefined) {
|
|
2797
|
+
return fallback(name);
|
|
2798
|
+
}
|
|
2799
|
+
}
|
|
2800
|
+
/**
|
|
2801
|
+
* @template T
|
|
2802
|
+
* @template R
|
|
2803
|
+
* @param {HookMap<SyncBailHook<T, R>>} hookMap hooks the should be called
|
|
2804
|
+
* @param {string} name key in map
|
|
2805
|
+
* @param {(function(string): any) | undefined} fallback callback when variable in not handled by hooks
|
|
2806
|
+
* @param {(function(): any) | undefined} defined callback when variable is defined
|
|
2807
|
+
* @param {AsArray<T>} args args for the hook
|
|
2808
|
+
* @returns {R | undefined} result of hook
|
|
2809
|
+
*/
|
|
2810
|
+
callHooksForNameWithFallback(hookMap, name, fallback, defined, ...args) {
|
|
2811
|
+
return this.callHooksForInfoWithFallback(hookMap, this.getVariableInfo(name), fallback, defined, ...args);
|
|
2812
|
+
}
|
|
2813
|
+
/**
|
|
2814
|
+
* @deprecated
|
|
2815
|
+
* @param {any} params scope params
|
|
2816
|
+
* @param {function(): void} fn inner function
|
|
2817
|
+
* @returns {void}
|
|
2818
|
+
*/
|
|
2819
|
+
inScope(params, fn) {
|
|
2820
|
+
const oldScope = this.scope;
|
|
2821
|
+
this.scope = {
|
|
2822
|
+
topLevelScope: oldScope.topLevelScope,
|
|
2823
|
+
inTry: false,
|
|
2824
|
+
inShorthand: false,
|
|
2825
|
+
inTaggedTemplateTag: false,
|
|
2826
|
+
isStrict: oldScope.isStrict,
|
|
2827
|
+
isAsmJs: oldScope.isAsmJs,
|
|
2828
|
+
definitions: oldScope.definitions.createChild(),
|
|
2829
|
+
};
|
|
2830
|
+
this.undefineVariable('this');
|
|
2831
|
+
this.enterPatterns(params, (ident, pattern) => {
|
|
2832
|
+
this.defineVariable(ident);
|
|
2833
|
+
});
|
|
2834
|
+
fn();
|
|
2835
|
+
this.scope = oldScope;
|
|
2836
|
+
}
|
|
2837
|
+
/**
|
|
2838
|
+
* @param {boolean} hasThis true, when this is defined
|
|
2839
|
+
* @param {any} params scope params
|
|
2840
|
+
* @param {function(): void} fn inner function
|
|
2841
|
+
* @returns {void}
|
|
2842
|
+
*/
|
|
2843
|
+
inClassScope(hasThis, params, fn) {
|
|
2844
|
+
const oldScope = this.scope;
|
|
2845
|
+
this.scope = {
|
|
2846
|
+
topLevelScope: oldScope.topLevelScope,
|
|
2847
|
+
inTry: false,
|
|
2848
|
+
inShorthand: false,
|
|
2849
|
+
inTaggedTemplateTag: false,
|
|
2850
|
+
isStrict: oldScope.isStrict,
|
|
2851
|
+
isAsmJs: oldScope.isAsmJs,
|
|
2852
|
+
definitions: oldScope.definitions.createChild(),
|
|
2853
|
+
};
|
|
2854
|
+
if (hasThis) {
|
|
2855
|
+
this.undefineVariable('this');
|
|
2856
|
+
}
|
|
2857
|
+
this.enterPatterns(params, (ident, pattern) => {
|
|
2858
|
+
this.defineVariable(ident);
|
|
2859
|
+
});
|
|
2860
|
+
fn();
|
|
2861
|
+
this.scope = oldScope;
|
|
2862
|
+
}
|
|
2863
|
+
/**
|
|
2864
|
+
* @param {boolean} hasThis true, when this is defined
|
|
2865
|
+
* @param {any} params scope params
|
|
2866
|
+
* @param {function(): void} fn inner function
|
|
2867
|
+
* @returns {void}
|
|
2868
|
+
*/
|
|
2869
|
+
inFunctionScope(hasThis, params, fn) {
|
|
2870
|
+
const oldScope = this.scope;
|
|
2871
|
+
this.scope = {
|
|
2872
|
+
topLevelScope: oldScope.topLevelScope,
|
|
2873
|
+
inTry: false,
|
|
2874
|
+
inShorthand: false,
|
|
2875
|
+
inTaggedTemplateTag: false,
|
|
2876
|
+
isStrict: oldScope.isStrict,
|
|
2877
|
+
isAsmJs: oldScope.isAsmJs,
|
|
2878
|
+
definitions: oldScope.definitions.createChild(),
|
|
2879
|
+
};
|
|
2880
|
+
if (hasThis) {
|
|
2881
|
+
this.undefineVariable('this');
|
|
2882
|
+
}
|
|
2883
|
+
this.enterPatterns(params, (ident, pattern) => {
|
|
2884
|
+
this.defineVariable(ident);
|
|
2885
|
+
});
|
|
2886
|
+
fn();
|
|
2887
|
+
this.scope = oldScope;
|
|
2888
|
+
}
|
|
2889
|
+
/**
|
|
2890
|
+
* @param {function(): void} fn inner function
|
|
2891
|
+
* @returns {void}
|
|
2892
|
+
*/
|
|
2893
|
+
inBlockScope(fn) {
|
|
2894
|
+
const oldScope = this.scope;
|
|
2895
|
+
this.scope = {
|
|
2896
|
+
topLevelScope: oldScope.topLevelScope,
|
|
2897
|
+
inTry: oldScope.inTry,
|
|
2898
|
+
inShorthand: false,
|
|
2899
|
+
inTaggedTemplateTag: false,
|
|
2900
|
+
isStrict: oldScope.isStrict,
|
|
2901
|
+
isAsmJs: oldScope.isAsmJs,
|
|
2902
|
+
definitions: oldScope.definitions.createChild(),
|
|
2903
|
+
};
|
|
2904
|
+
fn();
|
|
2905
|
+
this.scope = oldScope;
|
|
2906
|
+
}
|
|
2907
|
+
/**
|
|
2908
|
+
* @param {Array<Directive | Statement | ModuleDeclaration>} statements statements
|
|
2909
|
+
*/
|
|
2910
|
+
detectMode(statements) {
|
|
2911
|
+
const isLiteral = statements.length >= 1 &&
|
|
2912
|
+
statements[0].type === 'ExpressionStatement' &&
|
|
2913
|
+
statements[0].expression.type === 'Literal';
|
|
2914
|
+
if (isLiteral && statements[0].expression.value === 'use strict') {
|
|
2915
|
+
this.scope.isStrict = true;
|
|
2916
|
+
}
|
|
2917
|
+
if (isLiteral && statements[0].expression.value === 'use asm') {
|
|
2918
|
+
this.scope.isAsmJs = true;
|
|
2919
|
+
}
|
|
2920
|
+
}
|
|
2921
|
+
enterPatterns(patterns, onIdent) {
|
|
2922
|
+
for (const pattern of patterns) {
|
|
2923
|
+
if (typeof pattern !== 'string') {
|
|
2924
|
+
this.enterPattern(pattern, onIdent);
|
|
2925
|
+
}
|
|
2926
|
+
else if (pattern) {
|
|
2927
|
+
onIdent(pattern);
|
|
2928
|
+
}
|
|
2929
|
+
}
|
|
2930
|
+
}
|
|
2931
|
+
enterPattern(pattern, onIdent) {
|
|
2932
|
+
if (!pattern)
|
|
2933
|
+
return;
|
|
2934
|
+
switch (pattern.type) {
|
|
2935
|
+
case 'ArrayPattern':
|
|
2936
|
+
this.enterArrayPattern(pattern, onIdent);
|
|
2937
|
+
break;
|
|
2938
|
+
case 'AssignmentPattern':
|
|
2939
|
+
this.enterAssignmentPattern(pattern, onIdent);
|
|
2940
|
+
break;
|
|
2941
|
+
case 'Identifier':
|
|
2942
|
+
this.enterIdentifier(pattern, onIdent);
|
|
2943
|
+
break;
|
|
2944
|
+
case 'ObjectPattern':
|
|
2945
|
+
this.enterObjectPattern(pattern, onIdent);
|
|
2946
|
+
break;
|
|
2947
|
+
case 'RestElement':
|
|
2948
|
+
this.enterRestElement(pattern, onIdent);
|
|
2949
|
+
break;
|
|
2950
|
+
case 'Property':
|
|
2951
|
+
if (pattern.shorthand && pattern.value.type === 'Identifier') {
|
|
2952
|
+
this.scope.inShorthand = pattern.value.name;
|
|
2953
|
+
this.enterIdentifier(pattern.value, onIdent);
|
|
2954
|
+
this.scope.inShorthand = false;
|
|
2955
|
+
}
|
|
2956
|
+
else {
|
|
2957
|
+
this.enterPattern(pattern.value, onIdent);
|
|
2958
|
+
}
|
|
2959
|
+
break;
|
|
2960
|
+
}
|
|
2961
|
+
}
|
|
2962
|
+
/**
|
|
2963
|
+
* @param {Identifier} pattern identifier pattern
|
|
2964
|
+
* @param {TODO} onIdent callback
|
|
2965
|
+
*/
|
|
2966
|
+
enterIdentifier(pattern, onIdent) {
|
|
2967
|
+
if (!this.callHooksForName(this.hooks.pattern, pattern.name, pattern)) {
|
|
2968
|
+
onIdent(pattern.name, pattern);
|
|
2969
|
+
}
|
|
2970
|
+
}
|
|
2971
|
+
/**
|
|
2972
|
+
* @param {ObjectPattern} pattern object pattern
|
|
2973
|
+
* @param {TODO} onIdent callback
|
|
2974
|
+
*/
|
|
2975
|
+
enterObjectPattern(pattern, onIdent) {
|
|
2976
|
+
for (let propIndex = 0, len = pattern.properties.length; propIndex < len; propIndex++) {
|
|
2977
|
+
const prop = pattern.properties[propIndex];
|
|
2978
|
+
this.enterPattern(prop, onIdent);
|
|
2979
|
+
}
|
|
2980
|
+
}
|
|
2981
|
+
/**
|
|
2982
|
+
* @param {ArrayPattern} pattern object pattern
|
|
2983
|
+
* @param {TODO} onIdent callback
|
|
2984
|
+
*/
|
|
2985
|
+
enterArrayPattern(pattern, onIdent) {
|
|
2986
|
+
for (let elementIndex = 0, len = pattern.elements.length; elementIndex < len; elementIndex++) {
|
|
2987
|
+
const element = pattern.elements[elementIndex];
|
|
2988
|
+
// TODO check on `null`?
|
|
2989
|
+
this.enterPattern(element, onIdent);
|
|
2990
|
+
}
|
|
2991
|
+
}
|
|
2992
|
+
/**
|
|
2993
|
+
* @param {RestElement} pattern object pattern
|
|
2994
|
+
* @param {TODO} onIdent callback
|
|
2995
|
+
*/
|
|
2996
|
+
enterRestElement(pattern, onIdent) {
|
|
2997
|
+
this.enterPattern(pattern.argument, onIdent);
|
|
2998
|
+
}
|
|
2999
|
+
/**
|
|
3000
|
+
* @param {AssignmentPattern} pattern object pattern
|
|
3001
|
+
* @param {TODO} onIdent callback
|
|
3002
|
+
*/
|
|
3003
|
+
enterAssignmentPattern(pattern, onIdent) {
|
|
3004
|
+
this.enterPattern(pattern.left, onIdent);
|
|
3005
|
+
}
|
|
3006
|
+
/**
|
|
3007
|
+
* @param {TODO} expression expression node
|
|
3008
|
+
* @returns {BasicEvaluatedExpression} evaluation result
|
|
3009
|
+
*/
|
|
3010
|
+
evaluateExpression(expression) {
|
|
3011
|
+
try {
|
|
3012
|
+
const hook = this.hooks.evaluate.get(expression.type);
|
|
3013
|
+
if (hook !== undefined) {
|
|
3014
|
+
const result = hook.call(expression);
|
|
3015
|
+
if (result !== undefined && result !== null) {
|
|
3016
|
+
result.setExpression(expression);
|
|
3017
|
+
return result;
|
|
3018
|
+
}
|
|
3019
|
+
}
|
|
3020
|
+
}
|
|
3021
|
+
catch (e) {
|
|
3022
|
+
console.warn(e);
|
|
3023
|
+
// ignore error
|
|
3024
|
+
}
|
|
3025
|
+
return new BasicEvaluatedExpression_1.default().setRange(expression.range).setExpression(expression);
|
|
3026
|
+
}
|
|
3027
|
+
/**
|
|
3028
|
+
* @param {Expression} expression expression
|
|
3029
|
+
* @returns {string} parsed string
|
|
3030
|
+
*/
|
|
3031
|
+
parseString(expression) {
|
|
3032
|
+
switch (expression.type) {
|
|
3033
|
+
case 'BinaryExpression':
|
|
3034
|
+
if (expression.operator === '+') {
|
|
3035
|
+
return this.parseString(expression.left) + this.parseString(expression.right);
|
|
3036
|
+
}
|
|
3037
|
+
break;
|
|
3038
|
+
case 'Literal':
|
|
3039
|
+
return `${expression.value}`;
|
|
3040
|
+
}
|
|
3041
|
+
throw new Error(`${expression.type} is not supported as parameter for require`);
|
|
3042
|
+
}
|
|
3043
|
+
parseCalculatedString(expression) {
|
|
3044
|
+
switch (expression.type) {
|
|
3045
|
+
case 'BinaryExpression':
|
|
3046
|
+
if (expression.operator === '+') {
|
|
3047
|
+
const left = this.parseCalculatedString(expression.left);
|
|
3048
|
+
const right = this.parseCalculatedString(expression.right);
|
|
3049
|
+
if (left.code) {
|
|
3050
|
+
return {
|
|
3051
|
+
range: left.range,
|
|
3052
|
+
value: left.value,
|
|
3053
|
+
code: true,
|
|
3054
|
+
conditional: false,
|
|
3055
|
+
};
|
|
3056
|
+
}
|
|
3057
|
+
if (right.code) {
|
|
3058
|
+
return {
|
|
3059
|
+
range: [left.range[0], right.range ? right.range[1] : left.range[1]],
|
|
3060
|
+
value: left.value + right.value,
|
|
3061
|
+
code: true,
|
|
3062
|
+
conditional: false,
|
|
3063
|
+
};
|
|
3064
|
+
}
|
|
3065
|
+
return {
|
|
3066
|
+
range: [left.range[0], right.range[1]],
|
|
3067
|
+
value: left.value + right.value,
|
|
3068
|
+
code: false,
|
|
3069
|
+
conditional: false,
|
|
3070
|
+
};
|
|
3071
|
+
}
|
|
3072
|
+
break;
|
|
3073
|
+
case 'ConditionalExpression': {
|
|
3074
|
+
const consequent = this.parseCalculatedString(expression.consequent);
|
|
3075
|
+
const alternate = this.parseCalculatedString(expression.alternate);
|
|
3076
|
+
const items = [];
|
|
3077
|
+
if (consequent.conditional) {
|
|
3078
|
+
items.push(...consequent.conditional);
|
|
3079
|
+
}
|
|
3080
|
+
else if (!consequent.code) {
|
|
3081
|
+
items.push(consequent);
|
|
3082
|
+
}
|
|
3083
|
+
else {
|
|
3084
|
+
break;
|
|
3085
|
+
}
|
|
3086
|
+
if (alternate.conditional) {
|
|
3087
|
+
items.push(...alternate.conditional);
|
|
3088
|
+
}
|
|
3089
|
+
else if (!alternate.code) {
|
|
3090
|
+
items.push(alternate);
|
|
3091
|
+
}
|
|
3092
|
+
else {
|
|
3093
|
+
break;
|
|
3094
|
+
}
|
|
3095
|
+
return {
|
|
3096
|
+
range: undefined,
|
|
3097
|
+
value: '',
|
|
3098
|
+
code: true,
|
|
3099
|
+
conditional: items,
|
|
3100
|
+
};
|
|
3101
|
+
}
|
|
3102
|
+
case 'Literal':
|
|
3103
|
+
return {
|
|
3104
|
+
range: expression.range,
|
|
3105
|
+
value: `${expression.value}`,
|
|
3106
|
+
code: false,
|
|
3107
|
+
conditional: false,
|
|
3108
|
+
};
|
|
3109
|
+
}
|
|
3110
|
+
return {
|
|
3111
|
+
range: undefined,
|
|
3112
|
+
value: '',
|
|
3113
|
+
code: true,
|
|
3114
|
+
conditional: false,
|
|
3115
|
+
};
|
|
3116
|
+
}
|
|
3117
|
+
/**
|
|
3118
|
+
* @param {string | Buffer | PreparsedAst} source the source to parse
|
|
3119
|
+
* @param {ParserState} state the parser state
|
|
3120
|
+
* @returns {ParserState} the parser state
|
|
3121
|
+
*/
|
|
3122
|
+
parse(source, state) {
|
|
3123
|
+
let ast;
|
|
3124
|
+
let comments;
|
|
3125
|
+
const semicolons = new Set();
|
|
3126
|
+
if (source === null) {
|
|
3127
|
+
throw new Error('source must not be null');
|
|
3128
|
+
}
|
|
3129
|
+
if (Buffer.isBuffer(source)) {
|
|
3130
|
+
source = source.toString('utf-8');
|
|
3131
|
+
}
|
|
3132
|
+
if (typeof source === 'object') {
|
|
3133
|
+
ast = source;
|
|
3134
|
+
comments = source.comments;
|
|
3135
|
+
}
|
|
3136
|
+
else {
|
|
3137
|
+
comments = [];
|
|
3138
|
+
ast = JavascriptParser._parse(source, {
|
|
3139
|
+
sourceType: this.sourceType,
|
|
3140
|
+
onComment: comments,
|
|
3141
|
+
onInsertedSemicolon: pos => semicolons.add(pos),
|
|
3142
|
+
});
|
|
3143
|
+
}
|
|
3144
|
+
const oldScope = this.scope;
|
|
3145
|
+
const oldState = this.state;
|
|
3146
|
+
const oldComments = this.comments;
|
|
3147
|
+
const oldSemicolons = this.semicolons;
|
|
3148
|
+
const oldStatementPath = this.statementPath;
|
|
3149
|
+
const oldPrevStatement = this.prevStatement;
|
|
3150
|
+
this.scope = {
|
|
3151
|
+
topLevelScope: true,
|
|
3152
|
+
inTry: false,
|
|
3153
|
+
inShorthand: false,
|
|
3154
|
+
inTaggedTemplateTag: false,
|
|
3155
|
+
isStrict: false,
|
|
3156
|
+
isAsmJs: false,
|
|
3157
|
+
definitions: new StackedMap_1.default(),
|
|
3158
|
+
};
|
|
3159
|
+
this.state = state;
|
|
3160
|
+
this.comments = comments;
|
|
3161
|
+
this.semicolons = semicolons;
|
|
3162
|
+
this.statementPath = [];
|
|
3163
|
+
this.prevStatement = undefined;
|
|
3164
|
+
if (this.hooks.program.call(ast, comments) === undefined) {
|
|
3165
|
+
this.destructuringAssignmentProperties = new WeakMap();
|
|
3166
|
+
this.detectMode(ast.body);
|
|
3167
|
+
this.preWalkStatements(ast.body);
|
|
3168
|
+
this.prevStatement = undefined;
|
|
3169
|
+
this.blockPreWalkStatements(ast.body);
|
|
3170
|
+
this.prevStatement = undefined;
|
|
3171
|
+
this.walkStatements(ast.body);
|
|
3172
|
+
this.destructuringAssignmentProperties = undefined;
|
|
3173
|
+
}
|
|
3174
|
+
this.hooks.finish.call(ast, comments);
|
|
3175
|
+
this.scope = oldScope;
|
|
3176
|
+
this.state = oldState;
|
|
3177
|
+
this.comments = oldComments;
|
|
3178
|
+
this.semicolons = oldSemicolons;
|
|
3179
|
+
this.statementPath = oldStatementPath;
|
|
3180
|
+
this.prevStatement = oldPrevStatement;
|
|
3181
|
+
return state;
|
|
3182
|
+
}
|
|
3183
|
+
/**
|
|
3184
|
+
* @param {string} source source code
|
|
3185
|
+
* @returns {BasicEvaluatedExpression} evaluation result
|
|
3186
|
+
*/
|
|
3187
|
+
evaluate(source) {
|
|
3188
|
+
const ast = JavascriptParser._parse(`(${source})`, {
|
|
3189
|
+
sourceType: this.sourceType,
|
|
3190
|
+
locations: false,
|
|
3191
|
+
});
|
|
3192
|
+
if (ast.body.length !== 1 || ast.body[0].type !== 'ExpressionStatement') {
|
|
3193
|
+
throw new Error('evaluate: Source is not a expression');
|
|
3194
|
+
}
|
|
3195
|
+
return this.evaluateExpression(ast.body[0].expression);
|
|
3196
|
+
}
|
|
3197
|
+
/**
|
|
3198
|
+
* @param {Expression | Declaration | PrivateIdentifier | null | undefined} expr an expression
|
|
3199
|
+
* @param {number} commentsStartPos source position from which annotation comments are checked
|
|
3200
|
+
* @returns {boolean} true, when the expression is pure
|
|
3201
|
+
*/
|
|
3202
|
+
isPure(expr, commentsStartPos) {
|
|
3203
|
+
if (!expr)
|
|
3204
|
+
return true;
|
|
3205
|
+
const result = this.hooks.isPure.for(expr.type).call(expr, commentsStartPos);
|
|
3206
|
+
if (typeof result === 'boolean')
|
|
3207
|
+
return result;
|
|
3208
|
+
switch (expr.type) {
|
|
3209
|
+
// TODO handle more cases
|
|
3210
|
+
case 'ClassDeclaration':
|
|
3211
|
+
case 'ClassExpression': {
|
|
3212
|
+
if (expr.body.type !== 'ClassBody')
|
|
3213
|
+
return false;
|
|
3214
|
+
if (expr.superClass && !this.isPure(expr.superClass, expr.range[0])) {
|
|
3215
|
+
return false;
|
|
3216
|
+
}
|
|
3217
|
+
const items = expr.body.body;
|
|
3218
|
+
return items.every(item => {
|
|
3219
|
+
if (item.computed && item.key && !this.isPure(item.key, item.range[0])) {
|
|
3220
|
+
return false;
|
|
3221
|
+
}
|
|
3222
|
+
if (item.static &&
|
|
3223
|
+
item.value &&
|
|
3224
|
+
!this.isPure(item.value, item.key ? item.key.range[1] : item.range[0])) {
|
|
3225
|
+
return false;
|
|
3226
|
+
}
|
|
3227
|
+
if (item.type === 'StaticBlock') {
|
|
3228
|
+
return false;
|
|
3229
|
+
}
|
|
3230
|
+
return true;
|
|
3231
|
+
});
|
|
3232
|
+
}
|
|
3233
|
+
case 'FunctionDeclaration':
|
|
3234
|
+
case 'FunctionExpression':
|
|
3235
|
+
case 'ArrowFunctionExpression':
|
|
3236
|
+
case 'ThisExpression':
|
|
3237
|
+
case 'Literal':
|
|
3238
|
+
case 'TemplateLiteral':
|
|
3239
|
+
case 'Identifier':
|
|
3240
|
+
case 'PrivateIdentifier':
|
|
3241
|
+
return true;
|
|
3242
|
+
case 'VariableDeclaration':
|
|
3243
|
+
return expr.declarations.every(decl => this.isPure(decl.init, decl.range[0]));
|
|
3244
|
+
case 'ConditionalExpression':
|
|
3245
|
+
return (this.isPure(expr.test, commentsStartPos) &&
|
|
3246
|
+
this.isPure(expr.consequent, expr.test.range[1]) &&
|
|
3247
|
+
this.isPure(expr.alternate, expr.consequent.range[1]));
|
|
3248
|
+
case 'LogicalExpression':
|
|
3249
|
+
return (this.isPure(expr.left, commentsStartPos) && this.isPure(expr.right, expr.left.range[1]));
|
|
3250
|
+
case 'SequenceExpression':
|
|
3251
|
+
return expr.expressions.every(expr => {
|
|
3252
|
+
const pureFlag = this.isPure(expr, commentsStartPos);
|
|
3253
|
+
commentsStartPos = expr.range[1];
|
|
3254
|
+
return pureFlag;
|
|
3255
|
+
});
|
|
3256
|
+
case 'CallExpression': {
|
|
3257
|
+
const pureFlag = expr.range[0] - commentsStartPos > 12 &&
|
|
3258
|
+
this.getComments([commentsStartPos, expr.range[0]]).some((comment) => comment.type === 'Block' && /^\s*(#|@)__PURE__\s*$/.test(comment.value));
|
|
3259
|
+
if (!pureFlag)
|
|
3260
|
+
return false;
|
|
3261
|
+
commentsStartPos = expr.callee.range[1];
|
|
3262
|
+
return expr.arguments.every(arg => {
|
|
3263
|
+
if (arg.type === 'SpreadElement')
|
|
3264
|
+
return false;
|
|
3265
|
+
const pureFlag = this.isPure(arg, commentsStartPos);
|
|
3266
|
+
commentsStartPos = arg.range[1];
|
|
3267
|
+
return pureFlag;
|
|
3268
|
+
});
|
|
3269
|
+
}
|
|
3270
|
+
}
|
|
3271
|
+
const evaluated = this.evaluateExpression(expr);
|
|
3272
|
+
return !evaluated.couldHaveSideEffects();
|
|
3273
|
+
}
|
|
3274
|
+
getComments(range) {
|
|
3275
|
+
const [rangeStart, rangeEnd] = range;
|
|
3276
|
+
const compare = (comment, needle) => comment.range[0] - needle;
|
|
3277
|
+
let idx = binarySearchBounds_1.default.ge(this.comments, rangeStart, compare);
|
|
3278
|
+
const commentsInRange = [];
|
|
3279
|
+
while (this.comments[idx] && this.comments[idx].range[1] <= rangeEnd) {
|
|
3280
|
+
commentsInRange.push(this.comments[idx]);
|
|
3281
|
+
idx++;
|
|
3282
|
+
}
|
|
3283
|
+
return commentsInRange;
|
|
3284
|
+
}
|
|
3285
|
+
isAsiPosition(pos) {
|
|
3286
|
+
const currentStatement = this.statementPath[this.statementPath.length - 1];
|
|
3287
|
+
if (currentStatement === undefined)
|
|
3288
|
+
throw new Error('Not in statement');
|
|
3289
|
+
return (
|
|
3290
|
+
// Either asking directly for the end position of the current statement
|
|
3291
|
+
(currentStatement.range[1] === pos && this.semicolons.has(pos)) ||
|
|
3292
|
+
// Or asking for the start position of the current statement,
|
|
3293
|
+
// here we have to check multiple things
|
|
3294
|
+
(currentStatement.range[0] === pos &&
|
|
3295
|
+
// is there a previous statement which might be relevant?
|
|
3296
|
+
this.prevStatement !== undefined &&
|
|
3297
|
+
// is the end position of the previous statement an ASI position?
|
|
3298
|
+
this.semicolons.has(this.prevStatement.range[1])));
|
|
3299
|
+
}
|
|
3300
|
+
/**
|
|
3301
|
+
* @param {number} pos source code position
|
|
3302
|
+
* @returns {void}
|
|
3303
|
+
*/
|
|
3304
|
+
unsetAsiPosition(pos) {
|
|
3305
|
+
this.semicolons.delete(pos);
|
|
3306
|
+
}
|
|
3307
|
+
/**
|
|
3308
|
+
* @param {Expression} expr expression
|
|
3309
|
+
* @returns {boolean} true, when the expression is a statement level expression
|
|
3310
|
+
*/
|
|
3311
|
+
isStatementLevelExpression(expr) {
|
|
3312
|
+
const currentStatement = this.statementPath[this.statementPath.length - 1];
|
|
3313
|
+
return (expr === currentStatement ||
|
|
3314
|
+
(currentStatement.type === 'ExpressionStatement' && currentStatement.expression === expr));
|
|
3315
|
+
}
|
|
3316
|
+
getTagData(name, tag) {
|
|
3317
|
+
const info = this.scope.definitions.get(name);
|
|
3318
|
+
if (info instanceof VariableInfo) {
|
|
3319
|
+
let tagInfo = info.tagInfo;
|
|
3320
|
+
while (tagInfo !== undefined) {
|
|
3321
|
+
if (tagInfo.tag === tag)
|
|
3322
|
+
return tagInfo.data;
|
|
3323
|
+
tagInfo = tagInfo.next;
|
|
3324
|
+
}
|
|
3325
|
+
}
|
|
3326
|
+
}
|
|
3327
|
+
tagVariable(name, tag, data) {
|
|
3328
|
+
const oldInfo = this.scope.definitions.get(name);
|
|
3329
|
+
let newInfo;
|
|
3330
|
+
if (oldInfo === undefined) {
|
|
3331
|
+
newInfo = new VariableInfo(this.scope, name, {
|
|
3332
|
+
tag,
|
|
3333
|
+
data,
|
|
3334
|
+
next: undefined,
|
|
3335
|
+
});
|
|
3336
|
+
}
|
|
3337
|
+
else if (oldInfo instanceof VariableInfo) {
|
|
3338
|
+
newInfo = new VariableInfo(oldInfo.declaredScope, oldInfo.freeName, {
|
|
3339
|
+
tag,
|
|
3340
|
+
data,
|
|
3341
|
+
next: oldInfo.tagInfo,
|
|
3342
|
+
});
|
|
3343
|
+
}
|
|
3344
|
+
else {
|
|
3345
|
+
newInfo = new VariableInfo(oldInfo, true, {
|
|
3346
|
+
tag,
|
|
3347
|
+
data,
|
|
3348
|
+
next: undefined,
|
|
3349
|
+
});
|
|
3350
|
+
}
|
|
3351
|
+
this.scope.definitions.set(name, newInfo);
|
|
3352
|
+
}
|
|
3353
|
+
defineVariable(name) {
|
|
3354
|
+
const oldInfo = this.scope.definitions.get(name);
|
|
3355
|
+
// Don't redefine variable in same scope to keep existing tags
|
|
3356
|
+
if (oldInfo instanceof VariableInfo && oldInfo.declaredScope === this.scope)
|
|
3357
|
+
return;
|
|
3358
|
+
this.scope.definitions.set(name, this.scope);
|
|
3359
|
+
}
|
|
3360
|
+
undefineVariable(name) {
|
|
3361
|
+
this.scope.definitions.delete(name);
|
|
3362
|
+
}
|
|
3363
|
+
isVariableDefined(name) {
|
|
3364
|
+
const info = this.scope.definitions.get(name);
|
|
3365
|
+
if (info === undefined)
|
|
3366
|
+
return false;
|
|
3367
|
+
if (info instanceof VariableInfo) {
|
|
3368
|
+
return info.freeName === true;
|
|
3369
|
+
}
|
|
3370
|
+
return true;
|
|
3371
|
+
}
|
|
3372
|
+
getVariableInfo(name) {
|
|
3373
|
+
const value = this.scope.definitions.get(name);
|
|
3374
|
+
if (value === undefined) {
|
|
3375
|
+
return name;
|
|
3376
|
+
}
|
|
3377
|
+
return value;
|
|
3378
|
+
}
|
|
3379
|
+
setVariable(name, variableInfo) {
|
|
3380
|
+
if (typeof variableInfo === 'string') {
|
|
3381
|
+
if (variableInfo === name) {
|
|
3382
|
+
this.scope.definitions.delete(name);
|
|
3383
|
+
}
|
|
3384
|
+
else {
|
|
3385
|
+
this.scope.definitions.set(name, new VariableInfo(this.scope, variableInfo, undefined));
|
|
3386
|
+
}
|
|
3387
|
+
}
|
|
3388
|
+
else {
|
|
3389
|
+
this.scope.definitions.set(name, variableInfo);
|
|
3390
|
+
}
|
|
3391
|
+
}
|
|
3392
|
+
evaluatedVariable(tagInfo) {
|
|
3393
|
+
return new VariableInfo(this.scope, undefined, tagInfo);
|
|
3394
|
+
}
|
|
3395
|
+
parseCommentOptions(range) {
|
|
3396
|
+
const comments = this.getComments(range);
|
|
3397
|
+
if (comments.length === 0) {
|
|
3398
|
+
return EMPTY_COMMENT_OPTIONS;
|
|
3399
|
+
}
|
|
3400
|
+
const options = {};
|
|
3401
|
+
const errors = [];
|
|
3402
|
+
for (const comment of comments) {
|
|
3403
|
+
const { value } = comment;
|
|
3404
|
+
if (value && webpackCommentRegExp.test(value)) {
|
|
3405
|
+
// try compile only if webpack options comment is present
|
|
3406
|
+
try {
|
|
3407
|
+
for (let [key, val] of Object.entries(vm_1.default.runInNewContext(`(function(){return {${value}};})()`))) {
|
|
3408
|
+
if (typeof val === 'object' && val !== null) {
|
|
3409
|
+
// @ts-ignore
|
|
3410
|
+
if (val.constructor.name === 'RegExp')
|
|
3411
|
+
val = new RegExp(val);
|
|
3412
|
+
else
|
|
3413
|
+
val = JSON.parse(JSON.stringify(val));
|
|
3414
|
+
}
|
|
3415
|
+
options[key] = val;
|
|
3416
|
+
}
|
|
3417
|
+
}
|
|
3418
|
+
catch (e) {
|
|
3419
|
+
const newErr = new Error(String(e.message));
|
|
3420
|
+
newErr.stack = String(e.stack);
|
|
3421
|
+
Object.assign(newErr, { comment });
|
|
3422
|
+
errors.push(newErr);
|
|
3423
|
+
}
|
|
3424
|
+
}
|
|
3425
|
+
}
|
|
3426
|
+
return { options, errors };
|
|
3427
|
+
}
|
|
3428
|
+
extractMemberExpressionChain(expression) {
|
|
3429
|
+
let expr = expression;
|
|
3430
|
+
const members = [];
|
|
3431
|
+
const membersOptionals = [];
|
|
3432
|
+
const memberRanges = [];
|
|
3433
|
+
while (expr.type === 'MemberExpression') {
|
|
3434
|
+
if (expr.computed) {
|
|
3435
|
+
if (expr.property.type !== 'Literal')
|
|
3436
|
+
break;
|
|
3437
|
+
members.push(`${expr.property.value}`); // the literal
|
|
3438
|
+
memberRanges.push(expr.object.range); // the range of the expression fragment before the literal
|
|
3439
|
+
}
|
|
3440
|
+
else {
|
|
3441
|
+
if (expr.property.type !== 'Identifier')
|
|
3442
|
+
break;
|
|
3443
|
+
members.push(expr.property.name); // the identifier
|
|
3444
|
+
memberRanges.push(expr.object.range); // the range of the expression fragment before the identifier
|
|
3445
|
+
}
|
|
3446
|
+
membersOptionals.push(expr.optional);
|
|
3447
|
+
expr = expr.object;
|
|
3448
|
+
}
|
|
3449
|
+
return {
|
|
3450
|
+
members,
|
|
3451
|
+
membersOptionals,
|
|
3452
|
+
memberRanges,
|
|
3453
|
+
object: expr,
|
|
3454
|
+
};
|
|
3455
|
+
}
|
|
3456
|
+
/**
|
|
3457
|
+
* @param {string} varName variable name
|
|
3458
|
+
* @returns {{name: string, info: VariableInfo | string} | undefined} name of the free variable and variable info for that
|
|
3459
|
+
*/
|
|
3460
|
+
getFreeInfoFromVariable(varName) {
|
|
3461
|
+
const info = this.getVariableInfo(varName);
|
|
3462
|
+
let name;
|
|
3463
|
+
if (info instanceof VariableInfo) {
|
|
3464
|
+
name = info.freeName;
|
|
3465
|
+
if (typeof name !== 'string')
|
|
3466
|
+
return undefined;
|
|
3467
|
+
}
|
|
3468
|
+
else if (typeof info !== 'string') {
|
|
3469
|
+
return undefined;
|
|
3470
|
+
}
|
|
3471
|
+
else {
|
|
3472
|
+
name = info;
|
|
3473
|
+
}
|
|
3474
|
+
return { info, name };
|
|
3475
|
+
}
|
|
3476
|
+
getMemberExpressionInfo(expression, allowedTypes) {
|
|
3477
|
+
const { object, members, membersOptionals, memberRanges } = this.extractMemberExpressionChain(expression);
|
|
3478
|
+
switch (object.type) {
|
|
3479
|
+
case 'CallExpression': {
|
|
3480
|
+
if ((allowedTypes & ALLOWED_MEMBER_TYPES_CALL_EXPRESSION) === 0)
|
|
3481
|
+
return undefined;
|
|
3482
|
+
let callee = object.callee;
|
|
3483
|
+
let rootMembers = EMPTY_ARRAY;
|
|
3484
|
+
if (callee.type === 'MemberExpression') {
|
|
3485
|
+
;
|
|
3486
|
+
({ object: callee, members: rootMembers } = this.extractMemberExpressionChain(callee));
|
|
3487
|
+
}
|
|
3488
|
+
const rootName = getRootName(callee);
|
|
3489
|
+
if (!rootName)
|
|
3490
|
+
return undefined;
|
|
3491
|
+
const result = this.getFreeInfoFromVariable(rootName);
|
|
3492
|
+
if (!result)
|
|
3493
|
+
return undefined;
|
|
3494
|
+
const { info: rootInfo, name: resolvedRoot } = result;
|
|
3495
|
+
const calleeName = objectAndMembersToName(resolvedRoot, rootMembers);
|
|
3496
|
+
return {
|
|
3497
|
+
type: 'call',
|
|
3498
|
+
call: object,
|
|
3499
|
+
calleeName,
|
|
3500
|
+
rootInfo,
|
|
3501
|
+
getCalleeMembers: (0, memoize_1.default)(() => rootMembers.reverse()),
|
|
3502
|
+
name: objectAndMembersToName(`${calleeName}()`, members),
|
|
3503
|
+
getMembers: (0, memoize_1.default)(() => members.reverse()),
|
|
3504
|
+
getMembersOptionals: (0, memoize_1.default)(() => membersOptionals.reverse()),
|
|
3505
|
+
getMemberRanges: (0, memoize_1.default)(() => memberRanges.reverse()),
|
|
3506
|
+
};
|
|
3507
|
+
}
|
|
3508
|
+
case 'Identifier':
|
|
3509
|
+
case 'MetaProperty':
|
|
3510
|
+
case 'ThisExpression': {
|
|
3511
|
+
if ((allowedTypes & ALLOWED_MEMBER_TYPES_EXPRESSION) === 0)
|
|
3512
|
+
return undefined;
|
|
3513
|
+
const rootName = getRootName(object);
|
|
3514
|
+
if (!rootName)
|
|
3515
|
+
return undefined;
|
|
3516
|
+
const result = this.getFreeInfoFromVariable(rootName);
|
|
3517
|
+
if (!result)
|
|
3518
|
+
return undefined;
|
|
3519
|
+
const { info: rootInfo, name: resolvedRoot } = result;
|
|
3520
|
+
return {
|
|
3521
|
+
type: 'expression',
|
|
3522
|
+
name: objectAndMembersToName(resolvedRoot, members),
|
|
3523
|
+
rootInfo,
|
|
3524
|
+
getMembers: (0, memoize_1.default)(() => members.reverse()),
|
|
3525
|
+
getMembersOptionals: (0, memoize_1.default)(() => membersOptionals.reverse()),
|
|
3526
|
+
getMemberRanges: (0, memoize_1.default)(() => memberRanges.reverse()),
|
|
3527
|
+
};
|
|
3528
|
+
}
|
|
3529
|
+
}
|
|
3530
|
+
}
|
|
3531
|
+
/**
|
|
3532
|
+
* @param {MemberExpression} expression an expression
|
|
3533
|
+
* @returns {{ name: string, rootInfo: ExportedVariableInfo, getMembers: () => string[]} | undefined} name info
|
|
3534
|
+
*/
|
|
3535
|
+
getNameForExpression(expression) {
|
|
3536
|
+
return this.getMemberExpressionInfo(expression, ALLOWED_MEMBER_TYPES_EXPRESSION);
|
|
3537
|
+
}
|
|
3538
|
+
/**
|
|
3539
|
+
* @param {string} code source code
|
|
3540
|
+
* @param {ParseOptions} options parsing options
|
|
3541
|
+
* @returns {Program} parsed ast
|
|
3542
|
+
*/
|
|
3543
|
+
static _parse(code, options) {
|
|
3544
|
+
const type = options ? options.sourceType : 'module';
|
|
3545
|
+
const parserOptions = Object.assign(Object.assign(Object.assign(Object.assign({}, defaultParserOptions), { allowReturnOutsideFunction: type === 'script' }), options), { sourceType: type === 'auto' ? 'module' : type });
|
|
3546
|
+
let ast;
|
|
3547
|
+
let error;
|
|
3548
|
+
let threw = false;
|
|
3549
|
+
try {
|
|
3550
|
+
ast = parser.parse(code, parserOptions);
|
|
3551
|
+
}
|
|
3552
|
+
catch (e) {
|
|
3553
|
+
error = e;
|
|
3554
|
+
threw = true;
|
|
3555
|
+
}
|
|
3556
|
+
if (threw && type === 'auto') {
|
|
3557
|
+
parserOptions.sourceType = 'script';
|
|
3558
|
+
if (!('allowReturnOutsideFunction' in options)) {
|
|
3559
|
+
parserOptions.allowReturnOutsideFunction = true;
|
|
3560
|
+
}
|
|
3561
|
+
if (Array.isArray(parserOptions.onComment)) {
|
|
3562
|
+
parserOptions.onComment.length = 0;
|
|
3563
|
+
}
|
|
3564
|
+
try {
|
|
3565
|
+
ast = parser.parse(code, parserOptions);
|
|
3566
|
+
threw = false;
|
|
3567
|
+
}
|
|
3568
|
+
catch (e) {
|
|
3569
|
+
// we use the error from first parse try
|
|
3570
|
+
// so nothing to do here
|
|
3571
|
+
}
|
|
3572
|
+
}
|
|
3573
|
+
if (threw) {
|
|
3574
|
+
throw error;
|
|
3575
|
+
}
|
|
3576
|
+
return ast;
|
|
3577
|
+
}
|
|
3578
|
+
}
|
|
3579
|
+
exports.JavascriptParser = JavascriptParser;
|