Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
View | Details | Raw Unified | Return to bug 431946
Collapse All | Expand All

(-)a/bundles/org.eclipse.orion.client.javascript/web/javascript/contentAssist/esprimaVisitor.js (-40 / +17 lines)
Lines 1-6 Link Here
1
/*******************************************************************************
1
/*******************************************************************************
2
 * @license
2
 * @license
3
 * Copyright (c) 2012, 2013 VMware, Inc. and others.
3
 * Copyright (c) 2012, 2014 VMware, Inc. and others.
4
 * All Rights Reserved. This program and the accompanying materials are made 
4
 * All Rights Reserved. This program and the accompanying materials are made 
5
 * available under the terms of the Eclipse Public License v1.0 
5
 * available under the terms of the Eclipse Public License v1.0 
6
 * (http://www.eclipse.org/legal/epl-v10.html), and the Eclipse Distribution 
6
 * (http://www.eclipse.org/legal/epl-v10.html), and the Eclipse Distribution 
Lines 8-13 Link Here
8
 *
8
 *
9
 * Contributors:
9
 * Contributors:
10
 *     Andrew Eisenberg (VMware) - initial API and implementation
10
 *     Andrew Eisenberg (VMware) - initial API and implementation
11
 * 	   IBM Corporation - bug fixes / improvements
11
 ******************************************************************************/
12
 ******************************************************************************/
12
13
13
/*global define esprima */
14
/*global define esprima */
Lines 16-80 Link Here
16
17
17
	return {
18
	return {
18
19
20
		restricted: {range:true, errors:true, target:true, extras:true, comments:true, parent:true, tokens:true},
21
		
19
		/**
22
		/**
20
		 * Generic AST visitor.  Visits all children in source order, if they have a range property.
23
		 * Generic AST visitor.  Visits all typed children in source order
21
		 *
24
		 *
22
		 * @param node The AST node to visit
25
		 * @param {Object} node The AST node to visit
23
		 * @param {rhsVisit:Boolean,...} context any extra data required to pass between operations.  Set rhsVisit to true if the rhs of
26
		 * @param {Object} context Extra data required to pass between operations.  Set rhsVisit to true if the rhs of
24
		 * assignments and variable declarators should be visited before the lhs
27
		 * assignments and variable declarators should be visited before the lhs
25
		 * @param operation function(node, context, [isInitialOp]) an operation on the AST node and the data.  Return falsy if
28
		 * @param {Function} operation An operation on the AST node and the data. Return false if
26
		 * the visit should no longer continue. Return truthy to continue.
29
		 * the visit should no longer continue. Return true to continue.
27
		 * @param [postoperation] (optional) function(node, context, [isInitialOp]) an operation that is exectuted after visiting the current node's children.
30
		 * @param {Function} postoperation (optional) An operation that is exectuted after visiting the current node's children.
28
		 * will only be invoked if operation returns true for the current node
31
		 * will only be invoked iff the operation returns true for the current node
29
		 */
32
		 */
30
		visit: function(node, context, operation, postoperation) {
33
		visit: function(node, context, operation, postoperation) {
31
			var i, key, child, children;
32
33
			if (operation(node, context, true)) {
34
			if (operation(node, context, true)) {
34
				// gather children to visit
35
				// gather children to visit
35
				children = [];
36
				var i, key;
37
				var children = [];
36
				for (key in node) {
38
				for (key in node) {
37
					if (key !== "range" && key !== "errors" && key !== "target" && key !== "extras" && 
39
					if (!this.restricted[key]) {
38
						key !== "comments" && key !== 'parent') {
40
						var child = node[key];
39
						child = node[key];
40
						if (child instanceof Array) {
41
						if (child instanceof Array) {
41
							for (i = 0; i < child.length; i++) {
42
							for (i = 0; i < child.length; i++) {
42
								if (child[i] && child[i].hasOwnProperty("type")) {
43
								if (child[i] && child[i].type) {
43
									children.push(child[i]);
44
									children.push(child[i]);
44
								} else if (key === "properties") {
45
									// might be key-value pair of an object expression
46
									// in old versions of the parser, the 'properties' property did not have a 'type' or a 'range'
47
									// so we must explicitly visit the children here.
48
									// in new versions of the parser, this is fixed, and this branch will never be taken.
49
									if (child[i].hasOwnProperty("key") && child[i].hasOwnProperty("value")) {
50
										children.push(child[i].key);
51
										children.push(child[i].value);
52
									}
53
								}
45
								}
54
							}
46
							}
55
						} else {
47
						} else {
56
							if (child && child.hasOwnProperty("type")) {
48
							if (child && child.type) {
57
								children.push(child);
49
								children.push(child);
58
							}
50
							}
59
						}
51
						}
60
					}
52
					}
61
				}
53
				}
62
63
				if (children.length > 0) {
54
				if (children.length > 0) {
64
					// sort children by source location
65
					// children with no source location are visited first
66
					children.sort(function(left, right) {
67
						if (left.range && right.range) {
68
							return left.range[0] - right.range[0];
69
						} else if (left.range) {
70
							return 1;
71
						} else if (right.range) {
72
							return -1;
73
						} else {
74
							return 0;
75
						}
76
					});
77
78
					// visit children in order
55
					// visit children in order
79
					for (i = 0; i < children.length; i++) {
56
					for (i = 0; i < children.length; i++) {
80
						this.visit(children[i], context, operation, postoperation);
57
						this.visit(children[i], context, operation, postoperation);

Return to bug 431946