mirror of https://github.com/webpack/webpack.git
				
				
				
			move flatter algo into InnerGraph
This commit is contained in:
		
							parent
							
								
									721ce54bdf
								
							
						
					
					
						commit
						68a61677dc
					
				| 
						 | 
					@ -82,12 +82,9 @@ module.exports = class HarmonyImportDependencyParserPlugin {
 | 
				
			||||||
		const addDepToInnerGraph = dep => {
 | 
							const addDepToInnerGraph = dep => {
 | 
				
			||||||
			if (!InnerGraph.isEnabled(parser.state)) return;
 | 
								if (!InnerGraph.isEnabled(parser.state)) return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			const allExportDependentDependencies = InnerGraph.getExportDependentDependencies(
 | 
					 | 
				
			||||||
				parser.state
 | 
					 | 
				
			||||||
			);
 | 
					 | 
				
			||||||
			const currentTopLevelSymbol = InnerGraph.getTopLevelSymbol(parser.state);
 | 
								const currentTopLevelSymbol = InnerGraph.getTopLevelSymbol(parser.state);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			allExportDependentDependencies.add(dep);
 | 
								InnerGraph.addDependency(parser.state, dep);
 | 
				
			||||||
			if (!currentTopLevelSymbol) {
 | 
								if (!currentTopLevelSymbol) {
 | 
				
			||||||
				InnerGraph.setUsage(parser.state, dep, true);
 | 
									InnerGraph.setUsage(parser.state, dep, true);
 | 
				
			||||||
			} else {
 | 
								} else {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -86,13 +86,85 @@ exports.getUsage = (state, symbol) => {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * @param {ParserState} state parser state
 | 
					 * @param {ParserState} state parser state
 | 
				
			||||||
 * @returns {IterableIterator<TopLevelSymbol | Dependency>} graph nodes
 | 
					 * @returns {Map<Dependency, Set<string | TopLevelSymbol> | true>} usage data
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
exports.getNodesIterable = state => {
 | 
					exports.inferDependencyUsage = state => {
 | 
				
			||||||
 | 
						const innerGraphState = getState(state);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!innerGraphState) {
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						const { allExportDependentDependencies, innerGraph } = innerGraphState;
 | 
				
			||||||
 | 
						// flatten graph to terminal nodes (string, undefined or true)
 | 
				
			||||||
 | 
						const nonTerminal = new Set(innerGraph.keys());
 | 
				
			||||||
 | 
						while (nonTerminal.size > 0) {
 | 
				
			||||||
 | 
							for (const key of nonTerminal) {
 | 
				
			||||||
 | 
								/** @type {Set<string|TopLevelSymbol> | true} */
 | 
				
			||||||
 | 
								let newSet = new Set();
 | 
				
			||||||
 | 
								let isTerminal = true;
 | 
				
			||||||
 | 
								const value = innerGraph.get(key);
 | 
				
			||||||
 | 
								if (value !== true && value !== undefined) {
 | 
				
			||||||
 | 
									for (const item of value) {
 | 
				
			||||||
 | 
										if (typeof item === "string") {
 | 
				
			||||||
 | 
											newSet.add(item);
 | 
				
			||||||
 | 
										} else {
 | 
				
			||||||
 | 
											const itemValue = innerGraph.get(item);
 | 
				
			||||||
 | 
											if (itemValue === true) {
 | 
				
			||||||
 | 
												newSet = true;
 | 
				
			||||||
 | 
												break;
 | 
				
			||||||
 | 
											}
 | 
				
			||||||
 | 
											if (itemValue !== undefined) {
 | 
				
			||||||
 | 
												for (const i of itemValue) {
 | 
				
			||||||
 | 
													if (i === key) continue;
 | 
				
			||||||
 | 
													if (value.has(i)) continue;
 | 
				
			||||||
 | 
													newSet.add(i);
 | 
				
			||||||
 | 
													if (typeof i !== "string") {
 | 
				
			||||||
 | 
														isTerminal = false;
 | 
				
			||||||
 | 
													}
 | 
				
			||||||
 | 
												}
 | 
				
			||||||
 | 
											}
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									if (newSet === true) {
 | 
				
			||||||
 | 
										innerGraph.set(key, true);
 | 
				
			||||||
 | 
									} else if (newSet.size === 0) {
 | 
				
			||||||
 | 
										innerGraph.set(key, undefined);
 | 
				
			||||||
 | 
									} else {
 | 
				
			||||||
 | 
										innerGraph.set(key, newSet);
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								if (isTerminal) {
 | 
				
			||||||
 | 
									nonTerminal.delete(key);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (const dep of allExportDependentDependencies) {
 | 
				
			||||||
 | 
							const value = innerGraph.get(dep);
 | 
				
			||||||
 | 
							switch (value) {
 | 
				
			||||||
 | 
								case undefined:
 | 
				
			||||||
 | 
									dep.usedByExports = false;
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
								case true:
 | 
				
			||||||
 | 
									dep.usedByExports = true;
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
								default:
 | 
				
			||||||
 | 
									dep.usedByExports = /** @type {Set<string>} */ (value);
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @param {ParserState} state parser state
 | 
				
			||||||
 | 
					 * @param {PureExpressionDependency|HarmonyImportSpecifierDependency} dep dependency
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					exports.addDependency = (state, dep) => {
 | 
				
			||||||
	const innerGraphState = getState(state);
 | 
						const innerGraphState = getState(state);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (innerGraphState) {
 | 
						if (innerGraphState) {
 | 
				
			||||||
		return innerGraphState.innerGraph.keys();
 | 
							innerGraphState.allExportDependentDependencies.add(dep);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -118,69 +118,7 @@ class InnerGraphPlugin {
 | 
				
			||||||
					parser.hooks.finish.tap("InnerGraphPlugin", () => {
 | 
										parser.hooks.finish.tap("InnerGraphPlugin", () => {
 | 
				
			||||||
						if (!InnerGraph.isEnabled(parser.state)) return;
 | 
											if (!InnerGraph.isEnabled(parser.state)) return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
						const allExportDependentDependencies = InnerGraph.getExportDependentDependencies(
 | 
											InnerGraph.inferDependencyUsage(parser.state);
 | 
				
			||||||
							parser.state
 | 
					 | 
				
			||||||
						);
 | 
					 | 
				
			||||||
						// flatten graph to terminal nodes (string, undefined or true)
 | 
					 | 
				
			||||||
						const nonTerminal = new Set(
 | 
					 | 
				
			||||||
							InnerGraph.getNodesIterable(parser.state)
 | 
					 | 
				
			||||||
						);
 | 
					 | 
				
			||||||
						while (nonTerminal.size > 0) {
 | 
					 | 
				
			||||||
							for (const key of nonTerminal) {
 | 
					 | 
				
			||||||
								/** @type {Set<string|TopLevelSymbol> | true} */
 | 
					 | 
				
			||||||
								let newSet = new Set();
 | 
					 | 
				
			||||||
								let isTerminal = true;
 | 
					 | 
				
			||||||
								const value = InnerGraph.getUsage(parser.state, key);
 | 
					 | 
				
			||||||
								if (value !== true && value !== undefined) {
 | 
					 | 
				
			||||||
									for (const item of value) {
 | 
					 | 
				
			||||||
										if (typeof item === "string") {
 | 
					 | 
				
			||||||
											newSet.add(item);
 | 
					 | 
				
			||||||
										} else {
 | 
					 | 
				
			||||||
											const itemValue = InnerGraph.getUsage(parser.state, item);
 | 
					 | 
				
			||||||
											if (itemValue === true) {
 | 
					 | 
				
			||||||
												newSet = true;
 | 
					 | 
				
			||||||
												break;
 | 
					 | 
				
			||||||
											}
 | 
					 | 
				
			||||||
											if (itemValue !== undefined) {
 | 
					 | 
				
			||||||
												for (const i of itemValue) {
 | 
					 | 
				
			||||||
													if (i === key) continue;
 | 
					 | 
				
			||||||
													if (value.has(i)) continue;
 | 
					 | 
				
			||||||
													newSet.add(i);
 | 
					 | 
				
			||||||
													if (typeof i !== "string") {
 | 
					 | 
				
			||||||
														isTerminal = false;
 | 
					 | 
				
			||||||
													}
 | 
					 | 
				
			||||||
												}
 | 
					 | 
				
			||||||
											}
 | 
					 | 
				
			||||||
										}
 | 
					 | 
				
			||||||
									}
 | 
					 | 
				
			||||||
									if (newSet === true) {
 | 
					 | 
				
			||||||
										InnerGraph.setUsage(parser.state, key, true);
 | 
					 | 
				
			||||||
									} else if (newSet.size === 0) {
 | 
					 | 
				
			||||||
										InnerGraph.setUsage(parser.state, key, undefined);
 | 
					 | 
				
			||||||
									} else {
 | 
					 | 
				
			||||||
										InnerGraph.setUsage(parser.state, key, newSet);
 | 
					 | 
				
			||||||
									}
 | 
					 | 
				
			||||||
								}
 | 
					 | 
				
			||||||
								if (isTerminal) {
 | 
					 | 
				
			||||||
									nonTerminal.delete(key);
 | 
					 | 
				
			||||||
								}
 | 
					 | 
				
			||||||
							}
 | 
					 | 
				
			||||||
						}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
						for (const dep of allExportDependentDependencies) {
 | 
					 | 
				
			||||||
							const value = InnerGraph.getUsage(parser.state, dep);
 | 
					 | 
				
			||||||
							switch (value) {
 | 
					 | 
				
			||||||
								case undefined:
 | 
					 | 
				
			||||||
									dep.usedByExports = false;
 | 
					 | 
				
			||||||
									break;
 | 
					 | 
				
			||||||
								case true:
 | 
					 | 
				
			||||||
									dep.usedByExports = true;
 | 
					 | 
				
			||||||
									break;
 | 
					 | 
				
			||||||
								default:
 | 
					 | 
				
			||||||
									dep.usedByExports = /** @type {Set<string>} */ (value);
 | 
					 | 
				
			||||||
									break;
 | 
					 | 
				
			||||||
							}
 | 
					 | 
				
			||||||
						}
 | 
					 | 
				
			||||||
					});
 | 
										});
 | 
				
			||||||
					/** @type {WeakMap<{}, TopLevelSymbol>} */
 | 
										/** @type {WeakMap<{}, TopLevelSymbol>} */
 | 
				
			||||||
					const statementWithTopLevelSymbol = new WeakMap();
 | 
										const statementWithTopLevelSymbol = new WeakMap();
 | 
				
			||||||
| 
						 | 
					@ -285,9 +223,6 @@ class InnerGraphPlugin {
 | 
				
			||||||
					});
 | 
										});
 | 
				
			||||||
					parser.hooks.declarator.tap("InnerGraphPlugin", (decl, statement) => {
 | 
										parser.hooks.declarator.tap("InnerGraphPlugin", (decl, statement) => {
 | 
				
			||||||
						if (!InnerGraph.isEnabled(parser.state)) return;
 | 
											if (!InnerGraph.isEnabled(parser.state)) return;
 | 
				
			||||||
						const allExportDependentDependencies = InnerGraph.getExportDependentDependencies(
 | 
					 | 
				
			||||||
							parser.state
 | 
					 | 
				
			||||||
						);
 | 
					 | 
				
			||||||
						const fn = declWithTopLevelSymbol.get(decl);
 | 
											const fn = declWithTopLevelSymbol.get(decl);
 | 
				
			||||||
						if (fn) {
 | 
											if (fn) {
 | 
				
			||||||
							if (pureDeclarators.has(decl)) {
 | 
												if (pureDeclarators.has(decl)) {
 | 
				
			||||||
| 
						 | 
					@ -295,7 +230,7 @@ class InnerGraphPlugin {
 | 
				
			||||||
								dep.loc = decl.loc;
 | 
													dep.loc = decl.loc;
 | 
				
			||||||
								parser.state.module.addDependency(dep);
 | 
													parser.state.module.addDependency(dep);
 | 
				
			||||||
								InnerGraph.setUsage(parser.state, dep, new Set([fn]));
 | 
													InnerGraph.setUsage(parser.state, dep, new Set([fn]));
 | 
				
			||||||
								allExportDependentDependencies.add(dep);
 | 
													InnerGraph.addDependency(parser.state, dep);
 | 
				
			||||||
							}
 | 
												}
 | 
				
			||||||
							InnerGraph.setTopLevelSymbol(parser.state, fn);
 | 
												InnerGraph.setTopLevelSymbol(parser.state, fn);
 | 
				
			||||||
							parser.walkExpression(decl.init);
 | 
												parser.walkExpression(decl.init);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue