mirror of
				https://github.com/flynx/features.js.git
				synced 2025-10-30 19:00:10 +00:00 
			
		
		
		
	almost ready...
Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
		
							parent
							
								
									c4e6e48756
								
							
						
					
					
						commit
						cad40b850e
					
				
							
								
								
									
										117
									
								
								features.js
									
									
									
									
									
								
							
							
						
						
									
										117
									
								
								features.js
									
									
									
									
									
								
							| @ -1019,7 +1019,7 @@ var FeatureSetProto = { | |||||||
| 	// 					- if not ??? (XXX)
 | 	// 					- if not ??? (XXX)
 | ||||||
| 	// XXX should we report stuff here???
 | 	// XXX should we report stuff here???
 | ||||||
| 	// XXX TODO:
 | 	// XXX TODO:
 | ||||||
| 	// 		- resolve exclusive aliases and conflicts...
 | 	// 		- wrapper to pass in applicability filter...
 | ||||||
| 	_buildFeatureListReorder: function(lst, filter){ | 	_buildFeatureListReorder: function(lst, filter){ | ||||||
| 		var all = this.features | 		var all = this.features | ||||||
| 		lst = (lst == null || lst == '*') ? all : lst | 		lst = (lst == null || lst == '*') ? all : lst | ||||||
| @ -1071,10 +1071,10 @@ var FeatureSetProto = { | |||||||
| 				// normalize the list -- remove non-features and resolve aliases...
 | 				// normalize the list -- remove non-features and resolve aliases...
 | ||||||
| 				.map(function(n){  | 				.map(function(n){  | ||||||
| 					var f = that[n] | 					var f = that[n] | ||||||
| 					// resolve exclusive tags...
 | 					// exclusive tags...
 | ||||||
| 					while(f == null && data.exclusive && n in data.exclusive){ | 					if(f == null && data.exclusive && n in data.exclusive){ | ||||||
| 						var n = data.exclusive[n][0] | 						store[n] = null | ||||||
| 						f = that[n] | 						return false | ||||||
| 					} | 					} | ||||||
| 					// feature not defined or is not a feature...
 | 					// feature not defined or is not a feature...
 | ||||||
| 					if(f == null){ | 					if(f == null){ | ||||||
| @ -1116,10 +1116,6 @@ var FeatureSetProto = { | |||||||
| 
 | 
 | ||||||
| 						// traverse down...
 | 						// traverse down...
 | ||||||
| 						expand(target, _lst, store, data, _seen.concat([f])) | 						expand(target, _lst, store, data, _seen.concat([f])) | ||||||
| 
 |  | ||||||
| 						// XXX makes sense to push the dep here -- at the tail of the recursion...
 |  | ||||||
| 						data.list |  | ||||||
| 							&& data.list.push(f) |  | ||||||
| 					} | 					} | ||||||
| 				}) | 				}) | ||||||
| 
 | 
 | ||||||
| @ -1143,22 +1139,30 @@ var FeatureSetProto = { | |||||||
| 		// 		...we need to do this on the build stage to include correct
 | 		// 		...we need to do this on the build stage to include correct
 | ||||||
| 		// 		deps and suggesntions...
 | 		// 		deps and suggesntions...
 | ||||||
| 		var exclusive = {} | 		var exclusive = {} | ||||||
|  | 		var rev_exclusive = {} | ||||||
| 		all | 		all | ||||||
| 			.filter(function(f){ return !!that[f].exclusive }) | 			.filter(function(f){ return !!that[f].exclusive }) | ||||||
| 			.forEach(function(k){ | 			.forEach(function(k){ | ||||||
| 				(that[k].exclusive || []) | 				(that[k].exclusive || []) | ||||||
| 					.forEach(function(e){ | 					.forEach(function(e){ | ||||||
| 						exclusive[e] = (exclusive[e] || []).concat([k]) }) }) | 						exclusive[e] = (exclusive[e] || []).concat([k])  | ||||||
|  | 						rev_exclusive[k] = (rev_exclusive[k] || []).concat([e]) }) }) | ||||||
|  | 
 | ||||||
|  | 		// XXX revise:
 | ||||||
|  | 		// 		- should this be this depending on closure so much???
 | ||||||
|  | 		var expandFeatures = function(lst, features){ | ||||||
|  | 			features = features || {} | ||||||
| 
 | 
 | ||||||
| 			// feature tree...
 | 			// feature tree...
 | ||||||
| 		var features = expand('depends', lst, {},  | 			var expand_data = { | ||||||
| 			{ |  | ||||||
| 				loops: loops,  | 				loops: loops,  | ||||||
| 				disable_loops: disable_loops,  |  | ||||||
| 				disabled: disabled,  | 				disabled: disabled,  | ||||||
|  | 				disable_loops: disable_loops,  | ||||||
| 				missing: missing, | 				missing: missing, | ||||||
| 				exclusive: exclusive, | 				exclusive: exclusive, | ||||||
| 			}) | 			} | ||||||
|  | 
 | ||||||
|  | 			features = expand('depends', lst, features, expand_data) | ||||||
| 
 | 
 | ||||||
| 			// suggestion list...
 | 			// suggestion list...
 | ||||||
| 			//	...this will be used to check if we need to break on missing 
 | 			//	...this will be used to check if we need to break on missing 
 | ||||||
| @ -1167,33 +1171,89 @@ var FeatureSetProto = { | |||||||
| 			//
 | 			//
 | ||||||
| 			// NOTE: this stage does not track suggested feature dependencies...
 | 			// NOTE: this stage does not track suggested feature dependencies...
 | ||||||
| 			// NOTE: we do not need loop detection active here...
 | 			// NOTE: we do not need loop detection active here...
 | ||||||
| 		var suggested = Object.keys( | 			var s = Object.keys( | ||||||
| 					expand('suggested', Object.keys(features), {}, { disabled: disabled })) | 					expand('suggested', Object.keys(features), {}, { disabled: disabled })) | ||||||
| 				.filter(function(f){ return !(f in features) }) | 				.filter(function(f){ return !(f in features) }) | ||||||
| 			// get suggestion dependencies...
 | 			// get suggestion dependencies...
 | ||||||
| 		suggested = expand('depends', suggested, {},  | 			// NOTE: we do not care bout missing here...
 | ||||||
|  | 			s = expand('depends', s, {},  | ||||||
| 				{  | 				{  | ||||||
| 					loops: loops,  | 					loops: loops,  | ||||||
| 					disabled: disabled,  | 					disabled: disabled,  | ||||||
|  | 					disable_loops: disable_loops,  | ||||||
|  | 					exclusive: exclusive, | ||||||
| 				}) | 				}) | ||||||
| 		Object.keys(suggested) | 			Object.keys(s) | ||||||
| 				.forEach(function(f){  | 				.forEach(function(f){  | ||||||
| 					// keep only suggested features -- diff with features...
 | 					// keep only suggested features -- diff with features...
 | ||||||
| 					if(f in features){ | 					if(f in features){ | ||||||
| 			  		delete suggested[f] | 						delete s[f] | ||||||
| 
 | 
 | ||||||
| 					// mix suggested into features...
 | 					// mix suggested into features...
 | ||||||
| 					} else { | 					} else { | ||||||
| 					features[f] = suggested[f] | 						features[f] = s[f] | ||||||
| 					} | 					} | ||||||
| 				}) | 				}) | ||||||
|  | 		} | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| 		// check/resolve for exclusivity conflicts and aliases...
 | 		var features = {} | ||||||
| 		// XXX
 | 		expandFeatures(lst, features) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| 		// reverse dependencies -- who pulled who in... (index)
 | 		// check for exclusivity conflicts and aliases...
 | ||||||
|  | 		var conflicts = {} | ||||||
|  | 		Object.keys(features) | ||||||
|  | 			.forEach(function(f){ | ||||||
|  | 				// alias...
 | ||||||
|  | 				while(f in exclusive){ | ||||||
|  | 					var candidates = (exclusive[f] || []) | ||||||
|  | 						.filter(function(c){ return c in features }) | ||||||
|  | 
 | ||||||
|  | 					// resolve alias to non-included feature...
 | ||||||
|  | 					if(candidates.length == 0){ | ||||||
|  | 						var target = exclusive[f][0] | ||||||
|  | 
 | ||||||
|  | 						// expand target...
 | ||||||
|  | 						expandFeatures([target], features) | ||||||
|  | 
 | ||||||
|  | 					// link alias to existing feature...
 | ||||||
|  | 					} else { | ||||||
|  | 						var target = candidates[0] | ||||||
|  | 					} | ||||||
|  | 
 | ||||||
|  | 					// remove the alias...
 | ||||||
|  | 					delete features[f] | ||||||
|  | 					// replace dependencies...
 | ||||||
|  | 					Object.keys(features) | ||||||
|  | 						.forEach(function(e){ | ||||||
|  | 							var i = features[e].indexOf(f) | ||||||
|  | 							i >= 0 | ||||||
|  | 								&& features[e].splice(i, 1, target) | ||||||
|  | 						}) | ||||||
|  | 					f = target | ||||||
|  | 				} | ||||||
|  | 				 | ||||||
|  | 				// exclusive feature...
 | ||||||
|  | 				if(f in rev_exclusive){ | ||||||
|  | 					// XXX handle multiple groups... (???)
 | ||||||
|  | 					var group = rev_exclusive[f] | ||||||
|  | 					var candidates = (exclusive[group] || []) | ||||||
|  | 						.filter(function(c){ return c in features }) | ||||||
|  | 
 | ||||||
|  | 					if(!(group in conflicts) && candidates.length > 1){ | ||||||
|  | 						conflicts[group] = candidates | ||||||
|  | 					} | ||||||
|  | 				} | ||||||
|  | 			}) | ||||||
|  | 		// resolve any conflicts found...
 | ||||||
|  | 		Object.keys(conflicts) | ||||||
|  | 			.forEach(function(group){ | ||||||
|  | 				// XXX is this how we decide which feature to keep???
 | ||||||
|  | 				disabled = disabled.concat(conflicts[group].slice(1))}) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 		// reverse dependency index...
 | ||||||
| 		// 	...this is used to clear out orphaned features later and for
 | 		// 	...this is used to clear out orphaned features later and for
 | ||||||
| 		// 	introspection...
 | 		// 	introspection...
 | ||||||
| 		var rev_features = {} | 		var rev_features = {} | ||||||
| @ -1289,11 +1349,12 @@ var FeatureSetProto = { | |||||||
| 		// NOTE: this requires the list to be ordered from high to low 
 | 		// NOTE: this requires the list to be ordered from high to low 
 | ||||||
| 		// 		priority, i.e. the same order they should be loaded in...
 | 		// 		priority, i.e. the same order they should be loaded in...
 | ||||||
| 		// NOTE: dependency loops will throw this into and "infinite" loop...
 | 		// NOTE: dependency loops will throw this into and "infinite" loop...
 | ||||||
| 		//
 | 		var loop_limit = list.length + 1 | ||||||
| 		// XXX need a better loop detection strategy...
 |  | ||||||
| 		var loop_limit = list.length |  | ||||||
| 		do { | 		do { | ||||||
| 			var moves = 0 | 			var moves = 0 | ||||||
|  | 			if(list.length == 0){ | ||||||
|  | 				break | ||||||
|  | 			} | ||||||
| 			list | 			list | ||||||
| 				.slice() | 				.slice() | ||||||
| 				.forEach(function(e){ | 				.forEach(function(e){ | ||||||
| @ -1333,15 +1394,19 @@ var FeatureSetProto = { | |||||||
| 		// report loop limit...
 | 		// report loop limit...
 | ||||||
| 		loop_limit <= 0 | 		loop_limit <= 0 | ||||||
| 			&& console.error('Hit loop limit while sorting dependencies!') | 			&& console.error('Hit loop limit while sorting dependencies!') | ||||||
|  | 		// report conflicts...
 | ||||||
|  | 		Object.keys(conflicts) | ||||||
|  | 			.forEach(function(group){ | ||||||
|  | 				console.error('Exclusive "'+ group +'" conflict at:', conflicts[group]) }) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| 		return { | 		return { | ||||||
| 			list: list, | 			list: list, | ||||||
| 
 | 
 | ||||||
| 			suggested: Object.keys(suggested), |  | ||||||
| 			features: features, | 			features: features, | ||||||
| 			rev_features: rev_features, | 			rev_features: rev_features, | ||||||
| 			exclusive: exclusive, | 			exclusive: exclusive, | ||||||
|  | 			conflicts: conflicts, | ||||||
| 			missing: missing, | 			missing: missing, | ||||||
| 			loops: loops, | 			loops: loops, | ||||||
| 			filtered_out: filtered_out, | 			filtered_out: filtered_out, | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user