| 
									
										
										
										
											2013-09-13 17:17:57 +08:00
										 |  |  | /* | 
					
						
							|  |  |  | 	MIT License http://www.opensource.org/licenses/mit-license.php
 | 
					
						
							|  |  |  | 	Author Tobias Koppers @sokra | 
					
						
							|  |  |  | */ | 
					
						
							|  |  |  | var ConstDependency = require("./dependencies/ConstDependency"); | 
					
						
							|  |  |  | var BasicEvaluatedExpression = require("./BasicEvaluatedExpression"); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-16 21:18:49 +08:00
										 |  |  | var NullFactory = require("./NullFactory"); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-09-13 17:17:57 +08:00
										 |  |  | function DefinePlugin(definitions) { | 
					
						
							|  |  |  | 	this.definitions = definitions; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | module.exports = DefinePlugin; | 
					
						
							|  |  |  | DefinePlugin.prototype.apply = function(compiler) { | 
					
						
							| 
									
										
										
										
											2015-04-24 05:55:50 +08:00
										 |  |  | 	compiler.plugin("compilation", function(compilation) { | 
					
						
							| 
									
										
										
										
											2014-06-16 21:18:49 +08:00
										 |  |  | 		compilation.dependencyFactories.set(ConstDependency, new NullFactory()); | 
					
						
							|  |  |  | 		compilation.dependencyTemplates.set(ConstDependency, new ConstDependency.Template()); | 
					
						
							|  |  |  | 	}); | 
					
						
							| 
									
										
										
										
											2013-09-24 21:07:55 +08:00
										 |  |  | 	(function walkDefinitions(definitions, prefix) { | 
					
						
							|  |  |  | 		Object.keys(definitions).forEach(function(key) { | 
					
						
							|  |  |  | 			var code = definitions[key]; | 
					
						
							| 
									
										
										
										
											2015-02-24 05:57:10 +08:00
										 |  |  | 			if(code && typeof code === "object" && !(code instanceof RegExp)) { | 
					
						
							| 
									
										
										
										
											2014-11-12 20:33:18 +08:00
										 |  |  | 				walkDefinitions(code, prefix + key + "."); | 
					
						
							|  |  |  | 				applyObjectDefine(prefix + key, code); | 
					
						
							| 
									
										
										
										
											2013-09-24 21:07:55 +08:00
										 |  |  | 				return; | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2015-02-28 07:26:44 +08:00
										 |  |  | 			applyDefineKey(prefix, key); | 
					
						
							| 
									
										
										
										
											2013-09-24 21:07:55 +08:00
										 |  |  | 			applyDefine(prefix + key, code); | 
					
						
							|  |  |  | 		}); | 
					
						
							|  |  |  | 	}(this.definitions, "")); | 
					
						
							| 
									
										
										
										
											2015-07-13 06:20:09 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-21 20:19:08 +08:00
										 |  |  | 	function stringifyObj(obj) { | 
					
						
							|  |  |  | 		return "{" + Object.keys(obj).map(function(key) { | 
					
						
							|  |  |  | 			var code = obj[key]; | 
					
						
							|  |  |  | 			return JSON.stringify(key) + ":" + toCode(code); | 
					
						
							|  |  |  | 		}).join(",") + "}"; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-07-13 06:20:09 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-21 20:19:08 +08:00
										 |  |  | 	function toCode(code) { | 
					
						
							|  |  |  | 		if(code === null) return "null"; | 
					
						
							|  |  |  | 		else if(code === undefined) return "undefined"; | 
					
						
							|  |  |  | 		else if(code instanceof RegExp && code.toString) return code.toString(); | 
					
						
							| 
									
										
										
										
											2015-04-15 05:16:09 +08:00
										 |  |  | 		else if(typeof code === "function" && code.toString) return "(" + code.toString() + ")"; | 
					
						
							| 
									
										
										
										
											2015-02-21 20:19:08 +08:00
										 |  |  | 		else if(typeof code === "object") return stringifyObj(code); | 
					
						
							|  |  |  | 		else return code + ""; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-07-13 06:20:09 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-28 07:26:44 +08:00
										 |  |  | 	function applyDefineKey(prefix, key) { | 
					
						
							|  |  |  | 		var splittedKey = key.split("."); | 
					
						
							|  |  |  | 		splittedKey.slice(1).forEach(function(_, i) { | 
					
						
							| 
									
										
										
										
											2015-04-24 05:55:50 +08:00
										 |  |  | 			var fullKey = prefix + splittedKey.slice(0, i + 1).join("."); | 
					
						
							| 
									
										
										
										
											2015-07-13 06:20:09 +08:00
										 |  |  | 			compiler.parser.plugin("can-rename " + fullKey, function() { | 
					
						
							|  |  |  | 				return true; | 
					
						
							|  |  |  | 			}); | 
					
						
							| 
									
										
										
										
											2015-02-28 07:26:44 +08:00
										 |  |  | 		}); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-07-13 06:20:09 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-09-24 20:49:39 +08:00
										 |  |  | 	function applyDefine(key, code) { | 
					
						
							| 
									
										
										
										
											2014-05-26 18:48:16 +08:00
										 |  |  | 		var isTypeof = /^typeof\s+/.test(key); | 
					
						
							|  |  |  | 		if(isTypeof) key = key.replace(/^typeof\s+/, ""); | 
					
						
							| 
									
										
										
										
											2013-09-24 20:49:39 +08:00
										 |  |  | 		var recurse = false; | 
					
						
							|  |  |  | 		var recurseTypeof = false; | 
					
						
							| 
									
										
										
										
											2015-02-21 20:19:08 +08:00
										 |  |  | 		code = toCode(code); | 
					
						
							| 
									
										
										
										
											2014-05-26 18:48:16 +08:00
										 |  |  | 		if(!isTypeof) { | 
					
						
							| 
									
										
										
										
											2015-04-24 05:55:50 +08:00
										 |  |  | 			compiler.parser.plugin("can-rename " + key, function() { | 
					
						
							| 
									
										
										
										
											2014-05-26 18:48:16 +08:00
										 |  |  | 				return true; | 
					
						
							|  |  |  | 			}); | 
					
						
							|  |  |  | 			compiler.parser.plugin("evaluate Identifier " + key, function(expr) { | 
					
						
							|  |  |  | 				if(recurse) return; | 
					
						
							|  |  |  | 				recurse = true; | 
					
						
							|  |  |  | 				var res = compiler.parser.evaluate(code); | 
					
						
							|  |  |  | 				recurse = false; | 
					
						
							|  |  |  | 				res.setRange(expr.range); | 
					
						
							|  |  |  | 				return res; | 
					
						
							|  |  |  | 			}); | 
					
						
							|  |  |  | 			compiler.parser.plugin("expression " + key, function(expr) { | 
					
						
							| 
									
										
										
										
											2015-03-06 04:49:22 +08:00
										 |  |  | 				var dep = new ConstDependency(code, expr.range); | 
					
						
							| 
									
										
										
										
											2014-05-26 18:48:16 +08:00
										 |  |  | 				dep.loc = expr.loc; | 
					
						
							|  |  |  | 				this.state.current.addDependency(dep); | 
					
						
							|  |  |  | 				return true; | 
					
						
							|  |  |  | 			}); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2015-02-21 20:19:08 +08:00
										 |  |  | 		var typeofCode = isTypeof ? code : "typeof (" + code + ")"; | 
					
						
							| 
									
										
										
										
											2013-09-13 17:17:57 +08:00
										 |  |  | 		compiler.parser.plugin("evaluate typeof " + key, function(expr) { | 
					
						
							| 
									
										
										
										
											2013-09-24 20:49:39 +08:00
										 |  |  | 			if(recurseTypeof) return; | 
					
						
							|  |  |  | 			recurseTypeof = true; | 
					
						
							| 
									
										
										
										
											2014-05-26 18:48:16 +08:00
										 |  |  | 			var res = compiler.parser.evaluate(typeofCode); | 
					
						
							| 
									
										
										
										
											2013-09-24 20:49:39 +08:00
										 |  |  | 			recurseTypeof = false; | 
					
						
							| 
									
										
										
										
											2013-09-13 17:17:57 +08:00
										 |  |  | 			res.setRange(expr.range); | 
					
						
							|  |  |  | 			return res; | 
					
						
							|  |  |  | 		}); | 
					
						
							|  |  |  | 		compiler.parser.plugin("typeof " + key, function(expr) { | 
					
						
							| 
									
										
										
										
											2014-05-26 18:48:16 +08:00
										 |  |  | 			var res = compiler.parser.evaluate(typeofCode); | 
					
						
							| 
									
										
										
										
											2013-09-24 20:49:39 +08:00
										 |  |  | 			if(!res.isString()) return; | 
					
						
							|  |  |  | 			var dep = new ConstDependency(JSON.stringify(res.string), expr.range); | 
					
						
							| 
									
										
										
										
											2013-09-13 17:17:57 +08:00
										 |  |  | 			dep.loc = expr.loc; | 
					
						
							|  |  |  | 			this.state.current.addDependency(dep); | 
					
						
							|  |  |  | 			return true; | 
					
						
							|  |  |  | 		}); | 
					
						
							| 
									
										
										
										
											2013-09-24 20:49:39 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-07-13 06:20:09 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-09-24 21:07:55 +08:00
										 |  |  | 	function applyObjectDefine(key, obj) { | 
					
						
							| 
									
										
										
										
											2015-02-21 20:19:08 +08:00
										 |  |  | 		var code = stringifyObj(obj); | 
					
						
							| 
									
										
										
										
											2015-04-24 05:55:50 +08:00
										 |  |  | 		compiler.parser.plugin("can-rename " + key, function() { | 
					
						
							| 
									
										
										
										
											2014-01-31 21:09:08 +08:00
										 |  |  | 			return true; | 
					
						
							|  |  |  | 		}); | 
					
						
							| 
									
										
										
										
											2013-09-24 21:07:55 +08:00
										 |  |  | 		compiler.parser.plugin("evaluate Identifier " + key, function(expr) { | 
					
						
							|  |  |  | 			return new BasicEvaluatedExpression().setRange(expr.range); | 
					
						
							|  |  |  | 		}); | 
					
						
							|  |  |  | 		compiler.parser.plugin("evaluate typeof " + key, function(expr) { | 
					
						
							|  |  |  | 			return new BasicEvaluatedExpression().setString("object").setRange(expr.range); | 
					
						
							|  |  |  | 		}); | 
					
						
							|  |  |  | 		compiler.parser.plugin("expression " + key, function(expr) { | 
					
						
							| 
									
										
										
										
											2015-03-06 04:49:22 +08:00
										 |  |  | 			var dep = new ConstDependency(code, expr.range); | 
					
						
							| 
									
										
										
										
											2013-09-24 21:07:55 +08:00
										 |  |  | 			dep.loc = expr.loc; | 
					
						
							|  |  |  | 			this.state.current.addDependency(dep); | 
					
						
							|  |  |  | 			return true; | 
					
						
							|  |  |  | 		}); | 
					
						
							|  |  |  | 		compiler.parser.plugin("typeof " + key, function(expr) { | 
					
						
							|  |  |  | 			var dep = new ConstDependency("\"object\"", expr.range); | 
					
						
							|  |  |  | 			dep.loc = expr.loc; | 
					
						
							|  |  |  | 			this.state.current.addDependency(dep); | 
					
						
							|  |  |  | 			return true; | 
					
						
							|  |  |  | 		}); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-11-12 20:33:18 +08:00
										 |  |  | }; |