Bug:Fix file validation issue
[vnfsdk/refrepo.git] / vnfmarket / src / main / webapp / vnfmarket / node_modules / estraverse / estraverse.js
1 /*
2   Copyright (C) 2012-2013 Yusuke Suzuki <utatane.tea@gmail.com>
3   Copyright (C) 2012 Ariya Hidayat <ariya.hidayat@gmail.com>
4
5   Redistribution and use in source and binary forms, with or without
6   modification, are permitted provided that the following conditions are met:
7
8     * Redistributions of source code must retain the above copyright
9       notice, this list of conditions and the following disclaimer.
10     * Redistributions in binary form must reproduce the above copyright
11       notice, this list of conditions and the following disclaimer in the
12       documentation and/or other materials provided with the distribution.
13
14   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17   ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
18   DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19   (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
20   LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
21   ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23   THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25 /*jslint vars:false, bitwise:true*/
26 /*jshint indent:4*/
27 /*global exports:true, define:true*/
28 (function (root, factory) {
29     'use strict';
30
31     // Universal Module Definition (UMD) to support AMD, CommonJS/Node.js,
32     // and plain browser loading,
33     if (typeof define === 'function' && define.amd) {
34         define(['exports'], factory);
35     } else if (typeof exports !== 'undefined') {
36         factory(exports);
37     } else {
38         factory((root.estraverse = {}));
39     }
40 }(this, function (exports) {
41     'use strict';
42
43     var Syntax,
44         isArray,
45         VisitorOption,
46         VisitorKeys,
47         objectCreate,
48         objectKeys,
49         BREAK,
50         SKIP,
51         REMOVE;
52
53     function ignoreJSHintError() { }
54
55     isArray = Array.isArray;
56     if (!isArray) {
57         isArray = function isArray(array) {
58             return Object.prototype.toString.call(array) === '[object Array]';
59         };
60     }
61
62     function deepCopy(obj) {
63         var ret = {}, key, val;
64         for (key in obj) {
65             if (obj.hasOwnProperty(key)) {
66                 val = obj[key];
67                 if (typeof val === 'object' && val !== null) {
68                     ret[key] = deepCopy(val);
69                 } else {
70                     ret[key] = val;
71                 }
72             }
73         }
74         return ret;
75     }
76
77     function shallowCopy(obj) {
78         var ret = {}, key;
79         for (key in obj) {
80             if (obj.hasOwnProperty(key)) {
81                 ret[key] = obj[key];
82             }
83         }
84         return ret;
85     }
86     ignoreJSHintError(shallowCopy);
87
88     // based on LLVM libc++ upper_bound / lower_bound
89     // MIT License
90
91     function upperBound(array, func) {
92         var diff, len, i, current;
93
94         len = array.length;
95         i = 0;
96
97         while (len) {
98             diff = len >>> 1;
99             current = i + diff;
100             if (func(array[current])) {
101                 len = diff;
102             } else {
103                 i = current + 1;
104                 len -= diff + 1;
105             }
106         }
107         return i;
108     }
109
110     function lowerBound(array, func) {
111         var diff, len, i, current;
112
113         len = array.length;
114         i = 0;
115
116         while (len) {
117             diff = len >>> 1;
118             current = i + diff;
119             if (func(array[current])) {
120                 i = current + 1;
121                 len -= diff + 1;
122             } else {
123                 len = diff;
124             }
125         }
126         return i;
127     }
128     ignoreJSHintError(lowerBound);
129
130     objectCreate = Object.create || (function () {
131         function F() { }
132
133         return function (o) {
134             F.prototype = o;
135             return new F();
136         };
137     })();
138
139     objectKeys = Object.keys || function (o) {
140         var keys = [], key;
141         for (key in o) {
142             keys.push(key);
143         }
144         return keys;
145     };
146
147     function extend(to, from) {
148         objectKeys(from).forEach(function (key) {
149             to[key] = from[key];
150         });
151         return to;
152     }
153
154     Syntax = {
155         AssignmentExpression: 'AssignmentExpression',
156         ArrayExpression: 'ArrayExpression',
157         ArrayPattern: 'ArrayPattern',
158         ArrowFunctionExpression: 'ArrowFunctionExpression',
159         BlockStatement: 'BlockStatement',
160         BinaryExpression: 'BinaryExpression',
161         BreakStatement: 'BreakStatement',
162         CallExpression: 'CallExpression',
163         CatchClause: 'CatchClause',
164         ClassBody: 'ClassBody',
165         ClassDeclaration: 'ClassDeclaration',
166         ClassExpression: 'ClassExpression',
167         ComprehensionBlock: 'ComprehensionBlock',  // CAUTION: It's deferred to ES7.
168         ComprehensionExpression: 'ComprehensionExpression',  // CAUTION: It's deferred to ES7.
169         ConditionalExpression: 'ConditionalExpression',
170         ContinueStatement: 'ContinueStatement',
171         DebuggerStatement: 'DebuggerStatement',
172         DirectiveStatement: 'DirectiveStatement',
173         DoWhileStatement: 'DoWhileStatement',
174         EmptyStatement: 'EmptyStatement',
175         ExportBatchSpecifier: 'ExportBatchSpecifier',
176         ExportDeclaration: 'ExportDeclaration',
177         ExportSpecifier: 'ExportSpecifier',
178         ExpressionStatement: 'ExpressionStatement',
179         ForStatement: 'ForStatement',
180         ForInStatement: 'ForInStatement',
181         ForOfStatement: 'ForOfStatement',
182         FunctionDeclaration: 'FunctionDeclaration',
183         FunctionExpression: 'FunctionExpression',
184         GeneratorExpression: 'GeneratorExpression',  // CAUTION: It's deferred to ES7.
185         Identifier: 'Identifier',
186         IfStatement: 'IfStatement',
187         ImportDeclaration: 'ImportDeclaration',
188         ImportDefaultSpecifier: 'ImportDefaultSpecifier',
189         ImportNamespaceSpecifier: 'ImportNamespaceSpecifier',
190         ImportSpecifier: 'ImportSpecifier',
191         Literal: 'Literal',
192         LabeledStatement: 'LabeledStatement',
193         LogicalExpression: 'LogicalExpression',
194         MemberExpression: 'MemberExpression',
195         MethodDefinition: 'MethodDefinition',
196         ModuleSpecifier: 'ModuleSpecifier',
197         NewExpression: 'NewExpression',
198         ObjectExpression: 'ObjectExpression',
199         ObjectPattern: 'ObjectPattern',
200         Program: 'Program',
201         Property: 'Property',
202         ReturnStatement: 'ReturnStatement',
203         SequenceExpression: 'SequenceExpression',
204         SpreadElement: 'SpreadElement',
205         SwitchStatement: 'SwitchStatement',
206         SwitchCase: 'SwitchCase',
207         TaggedTemplateExpression: 'TaggedTemplateExpression',
208         TemplateElement: 'TemplateElement',
209         TemplateLiteral: 'TemplateLiteral',
210         ThisExpression: 'ThisExpression',
211         ThrowStatement: 'ThrowStatement',
212         TryStatement: 'TryStatement',
213         UnaryExpression: 'UnaryExpression',
214         UpdateExpression: 'UpdateExpression',
215         VariableDeclaration: 'VariableDeclaration',
216         VariableDeclarator: 'VariableDeclarator',
217         WhileStatement: 'WhileStatement',
218         WithStatement: 'WithStatement',
219         YieldExpression: 'YieldExpression'
220     };
221
222     VisitorKeys = {
223         AssignmentExpression: ['left', 'right'],
224         ArrayExpression: ['elements'],
225         ArrayPattern: ['elements'],
226         ArrowFunctionExpression: ['params', 'defaults', 'rest', 'body'],
227         BlockStatement: ['body'],
228         BinaryExpression: ['left', 'right'],
229         BreakStatement: ['label'],
230         CallExpression: ['callee', 'arguments'],
231         CatchClause: ['param', 'body'],
232         ClassBody: ['body'],
233         ClassDeclaration: ['id', 'body', 'superClass'],
234         ClassExpression: ['id', 'body', 'superClass'],
235         ComprehensionBlock: ['left', 'right'],  // CAUTION: It's deferred to ES7.
236         ComprehensionExpression: ['blocks', 'filter', 'body'],  // CAUTION: It's deferred to ES7.
237         ConditionalExpression: ['test', 'consequent', 'alternate'],
238         ContinueStatement: ['label'],
239         DebuggerStatement: [],
240         DirectiveStatement: [],
241         DoWhileStatement: ['body', 'test'],
242         EmptyStatement: [],
243         ExportBatchSpecifier: [],
244         ExportDeclaration: ['declaration', 'specifiers', 'source'],
245         ExportSpecifier: ['id', 'name'],
246         ExpressionStatement: ['expression'],
247         ForStatement: ['init', 'test', 'update', 'body'],
248         ForInStatement: ['left', 'right', 'body'],
249         ForOfStatement: ['left', 'right', 'body'],
250         FunctionDeclaration: ['id', 'params', 'defaults', 'rest', 'body'],
251         FunctionExpression: ['id', 'params', 'defaults', 'rest', 'body'],
252         GeneratorExpression: ['blocks', 'filter', 'body'],  // CAUTION: It's deferred to ES7.
253         Identifier: [],
254         IfStatement: ['test', 'consequent', 'alternate'],
255         ImportDeclaration: ['specifiers', 'source'],
256         ImportDefaultSpecifier: ['id'],
257         ImportNamespaceSpecifier: ['id'],
258         ImportSpecifier: ['id', 'name'],
259         Literal: [],
260         LabeledStatement: ['label', 'body'],
261         LogicalExpression: ['left', 'right'],
262         MemberExpression: ['object', 'property'],
263         MethodDefinition: ['key', 'value'],
264         ModuleSpecifier: [],
265         NewExpression: ['callee', 'arguments'],
266         ObjectExpression: ['properties'],
267         ObjectPattern: ['properties'],
268         Program: ['body'],
269         Property: ['key', 'value'],
270         ReturnStatement: ['argument'],
271         SequenceExpression: ['expressions'],
272         SpreadElement: ['argument'],
273         SwitchStatement: ['discriminant', 'cases'],
274         SwitchCase: ['test', 'consequent'],
275         TaggedTemplateExpression: ['tag', 'quasi'],
276         TemplateElement: [],
277         TemplateLiteral: ['quasis', 'expressions'],
278         ThisExpression: [],
279         ThrowStatement: ['argument'],
280         TryStatement: ['block', 'handlers', 'handler', 'guardedHandlers', 'finalizer'],
281         UnaryExpression: ['argument'],
282         UpdateExpression: ['argument'],
283         VariableDeclaration: ['declarations'],
284         VariableDeclarator: ['id', 'init'],
285         WhileStatement: ['test', 'body'],
286         WithStatement: ['object', 'body'],
287         YieldExpression: ['argument']
288     };
289
290     // unique id
291     BREAK = {};
292     SKIP = {};
293     REMOVE = {};
294
295     VisitorOption = {
296         Break: BREAK,
297         Skip: SKIP,
298         Remove: REMOVE
299     };
300
301     function Reference(parent, key) {
302         this.parent = parent;
303         this.key = key;
304     }
305
306     Reference.prototype.replace = function replace(node) {
307         this.parent[this.key] = node;
308     };
309
310     Reference.prototype.remove = function remove() {
311         if (isArray(this.parent)) {
312             this.parent.splice(this.key, 1);
313             return true;
314         } else {
315             this.replace(null);
316             return false;
317         }
318     };
319
320     function Element(node, path, wrap, ref) {
321         this.node = node;
322         this.path = path;
323         this.wrap = wrap;
324         this.ref = ref;
325     }
326
327     function Controller() { }
328
329     // API:
330     // return property path array from root to current node
331     Controller.prototype.path = function path() {
332         var i, iz, j, jz, result, element;
333
334         function addToPath(result, path) {
335             if (isArray(path)) {
336                 for (j = 0, jz = path.length; j < jz; ++j) {
337                     result.push(path[j]);
338                 }
339             } else {
340                 result.push(path);
341             }
342         }
343
344         // root node
345         if (!this.__current.path) {
346             return null;
347         }
348
349         // first node is sentinel, second node is root element
350         result = [];
351         for (i = 2, iz = this.__leavelist.length; i < iz; ++i) {
352             element = this.__leavelist[i];
353             addToPath(result, element.path);
354         }
355         addToPath(result, this.__current.path);
356         return result;
357     };
358
359     // API:
360     // return type of current node
361     Controller.prototype.type = function () {
362         var node = this.current();
363         return node.type || this.__current.wrap;
364     };
365
366     // API:
367     // return array of parent elements
368     Controller.prototype.parents = function parents() {
369         var i, iz, result;
370
371         // first node is sentinel
372         result = [];
373         for (i = 1, iz = this.__leavelist.length; i < iz; ++i) {
374             result.push(this.__leavelist[i].node);
375         }
376
377         return result;
378     };
379
380     // API:
381     // return current node
382     Controller.prototype.current = function current() {
383         return this.__current.node;
384     };
385
386     Controller.prototype.__execute = function __execute(callback, element) {
387         var previous, result;
388
389         result = undefined;
390
391         previous  = this.__current;
392         this.__current = element;
393         this.__state = null;
394         if (callback) {
395             result = callback.call(this, element.node, this.__leavelist[this.__leavelist.length - 1].node);
396         }
397         this.__current = previous;
398
399         return result;
400     };
401
402     // API:
403     // notify control skip / break
404     Controller.prototype.notify = function notify(flag) {
405         this.__state = flag;
406     };
407
408     // API:
409     // skip child nodes of current node
410     Controller.prototype.skip = function () {
411         this.notify(SKIP);
412     };
413
414     // API:
415     // break traversals
416     Controller.prototype['break'] = function () {
417         this.notify(BREAK);
418     };
419
420     // API:
421     // remove node
422     Controller.prototype.remove = function () {
423         this.notify(REMOVE);
424     };
425
426     Controller.prototype.__initialize = function(root, visitor) {
427         this.visitor = visitor;
428         this.root = root;
429         this.__worklist = [];
430         this.__leavelist = [];
431         this.__current = null;
432         this.__state = null;
433         this.__fallback = visitor.fallback === 'iteration';
434         this.__keys = VisitorKeys;
435         if (visitor.keys) {
436             this.__keys = extend(objectCreate(this.__keys), visitor.keys);
437         }
438     };
439
440     function isNode(node) {
441         if (node == null) {
442             return false;
443         }
444         return typeof node === 'object' && typeof node.type === 'string';
445     }
446
447     function isProperty(nodeType, key) {
448         return (nodeType === Syntax.ObjectExpression || nodeType === Syntax.ObjectPattern) && 'properties' === key;
449     }
450
451     Controller.prototype.traverse = function traverse(root, visitor) {
452         var worklist,
453             leavelist,
454             element,
455             node,
456             nodeType,
457             ret,
458             key,
459             current,
460             current2,
461             candidates,
462             candidate,
463             sentinel;
464
465         this.__initialize(root, visitor);
466
467         sentinel = {};
468
469         // reference
470         worklist = this.__worklist;
471         leavelist = this.__leavelist;
472
473         // initialize
474         worklist.push(new Element(root, null, null, null));
475         leavelist.push(new Element(null, null, null, null));
476
477         while (worklist.length) {
478             element = worklist.pop();
479
480             if (element === sentinel) {
481                 element = leavelist.pop();
482
483                 ret = this.__execute(visitor.leave, element);
484
485                 if (this.__state === BREAK || ret === BREAK) {
486                     return;
487                 }
488                 continue;
489             }
490
491             if (element.node) {
492
493                 ret = this.__execute(visitor.enter, element);
494
495                 if (this.__state === BREAK || ret === BREAK) {
496                     return;
497                 }
498
499                 worklist.push(sentinel);
500                 leavelist.push(element);
501
502                 if (this.__state === SKIP || ret === SKIP) {
503                     continue;
504                 }
505
506                 node = element.node;
507                 nodeType = element.wrap || node.type;
508                 candidates = this.__keys[nodeType];
509                 if (!candidates) {
510                     if (this.__fallback) {
511                         candidates = objectKeys(node);
512                     } else {
513                         throw new Error('Unknown node type ' + nodeType + '.');
514                     }
515                 }
516
517                 current = candidates.length;
518                 while ((current -= 1) >= 0) {
519                     key = candidates[current];
520                     candidate = node[key];
521                     if (!candidate) {
522                         continue;
523                     }
524
525                     if (isArray(candidate)) {
526                         current2 = candidate.length;
527                         while ((current2 -= 1) >= 0) {
528                             if (!candidate[current2]) {
529                                 continue;
530                             }
531                             if (isProperty(nodeType, candidates[current])) {
532                                 element = new Element(candidate[current2], [key, current2], 'Property', null);
533                             } else if (isNode(candidate[current2])) {
534                                 element = new Element(candidate[current2], [key, current2], null, null);
535                             } else {
536                                 continue;
537                             }
538                             worklist.push(element);
539                         }
540                     } else if (isNode(candidate)) {
541                         worklist.push(new Element(candidate, key, null, null));
542                     }
543                 }
544             }
545         }
546     };
547
548     Controller.prototype.replace = function replace(root, visitor) {
549         function removeElem(element) {
550             var i,
551                 key,
552                 nextElem,
553                 parent;
554
555             if (element.ref.remove()) {
556                 // When the reference is an element of an array.
557                 key = element.ref.key;
558                 parent = element.ref.parent;
559
560                 // If removed from array, then decrease following items' keys.
561                 i = worklist.length;
562                 while (i--) {
563                     nextElem = worklist[i];
564                     if (nextElem.ref && nextElem.ref.parent === parent) {
565                         if  (nextElem.ref.key < key) {
566                             break;
567                         }
568                         --nextElem.ref.key;
569                     }
570                 }
571             }
572         }
573
574         var worklist,
575             leavelist,
576             node,
577             nodeType,
578             target,
579             element,
580             current,
581             current2,
582             candidates,
583             candidate,
584             sentinel,
585             outer,
586             key;
587
588         this.__initialize(root, visitor);
589
590         sentinel = {};
591
592         // reference
593         worklist = this.__worklist;
594         leavelist = this.__leavelist;
595
596         // initialize
597         outer = {
598             root: root
599         };
600         element = new Element(root, null, null, new Reference(outer, 'root'));
601         worklist.push(element);
602         leavelist.push(element);
603
604         while (worklist.length) {
605             element = worklist.pop();
606
607             if (element === sentinel) {
608                 element = leavelist.pop();
609
610                 target = this.__execute(visitor.leave, element);
611
612                 // node may be replaced with null,
613                 // so distinguish between undefined and null in this place
614                 if (target !== undefined && target !== BREAK && target !== SKIP && target !== REMOVE) {
615                     // replace
616                     element.ref.replace(target);
617                 }
618
619                 if (this.__state === REMOVE || target === REMOVE) {
620                     removeElem(element);
621                 }
622
623                 if (this.__state === BREAK || target === BREAK) {
624                     return outer.root;
625                 }
626                 continue;
627             }
628
629             target = this.__execute(visitor.enter, element);
630
631             // node may be replaced with null,
632             // so distinguish between undefined and null in this place
633             if (target !== undefined && target !== BREAK && target !== SKIP && target !== REMOVE) {
634                 // replace
635                 element.ref.replace(target);
636                 element.node = target;
637             }
638
639             if (this.__state === REMOVE || target === REMOVE) {
640                 removeElem(element);
641                 element.node = null;
642             }
643
644             if (this.__state === BREAK || target === BREAK) {
645                 return outer.root;
646             }
647
648             // node may be null
649             node = element.node;
650             if (!node) {
651                 continue;
652             }
653
654             worklist.push(sentinel);
655             leavelist.push(element);
656
657             if (this.__state === SKIP || target === SKIP) {
658                 continue;
659             }
660
661             nodeType = element.wrap || node.type;
662             candidates = this.__keys[nodeType];
663             if (!candidates) {
664                 if (this.__fallback) {
665                     candidates = objectKeys(node);
666                 } else {
667                     throw new Error('Unknown node type ' + nodeType + '.');
668                 }
669             }
670
671             current = candidates.length;
672             while ((current -= 1) >= 0) {
673                 key = candidates[current];
674                 candidate = node[key];
675                 if (!candidate) {
676                     continue;
677                 }
678
679                 if (isArray(candidate)) {
680                     current2 = candidate.length;
681                     while ((current2 -= 1) >= 0) {
682                         if (!candidate[current2]) {
683                             continue;
684                         }
685                         if (isProperty(nodeType, candidates[current])) {
686                             element = new Element(candidate[current2], [key, current2], 'Property', new Reference(candidate, current2));
687                         } else if (isNode(candidate[current2])) {
688                             element = new Element(candidate[current2], [key, current2], null, new Reference(candidate, current2));
689                         } else {
690                             continue;
691                         }
692                         worklist.push(element);
693                     }
694                 } else if (isNode(candidate)) {
695                     worklist.push(new Element(candidate, key, null, new Reference(node, key)));
696                 }
697             }
698         }
699
700         return outer.root;
701     };
702
703     function traverse(root, visitor) {
704         var controller = new Controller();
705         return controller.traverse(root, visitor);
706     }
707
708     function replace(root, visitor) {
709         var controller = new Controller();
710         return controller.replace(root, visitor);
711     }
712
713     function extendCommentRange(comment, tokens) {
714         var target;
715
716         target = upperBound(tokens, function search(token) {
717             return token.range[0] > comment.range[0];
718         });
719
720         comment.extendedRange = [comment.range[0], comment.range[1]];
721
722         if (target !== tokens.length) {
723             comment.extendedRange[1] = tokens[target].range[0];
724         }
725
726         target -= 1;
727         if (target >= 0) {
728             comment.extendedRange[0] = tokens[target].range[1];
729         }
730
731         return comment;
732     }
733
734     function attachComments(tree, providedComments, tokens) {
735         // At first, we should calculate extended comment ranges.
736         var comments = [], comment, len, i, cursor;
737
738         if (!tree.range) {
739             throw new Error('attachComments needs range information');
740         }
741
742         // tokens array is empty, we attach comments to tree as 'leadingComments'
743         if (!tokens.length) {
744             if (providedComments.length) {
745                 for (i = 0, len = providedComments.length; i < len; i += 1) {
746                     comment = deepCopy(providedComments[i]);
747                     comment.extendedRange = [0, tree.range[0]];
748                     comments.push(comment);
749                 }
750                 tree.leadingComments = comments;
751             }
752             return tree;
753         }
754
755         for (i = 0, len = providedComments.length; i < len; i += 1) {
756             comments.push(extendCommentRange(deepCopy(providedComments[i]), tokens));
757         }
758
759         // This is based on John Freeman's implementation.
760         cursor = 0;
761         traverse(tree, {
762             enter: function (node) {
763                 var comment;
764
765                 while (cursor < comments.length) {
766                     comment = comments[cursor];
767                     if (comment.extendedRange[1] > node.range[0]) {
768                         break;
769                     }
770
771                     if (comment.extendedRange[1] === node.range[0]) {
772                         if (!node.leadingComments) {
773                             node.leadingComments = [];
774                         }
775                         node.leadingComments.push(comment);
776                         comments.splice(cursor, 1);
777                     } else {
778                         cursor += 1;
779                     }
780                 }
781
782                 // already out of owned node
783                 if (cursor === comments.length) {
784                     return VisitorOption.Break;
785                 }
786
787                 if (comments[cursor].extendedRange[0] > node.range[1]) {
788                     return VisitorOption.Skip;
789                 }
790             }
791         });
792
793         cursor = 0;
794         traverse(tree, {
795             leave: function (node) {
796                 var comment;
797
798                 while (cursor < comments.length) {
799                     comment = comments[cursor];
800                     if (node.range[1] < comment.extendedRange[0]) {
801                         break;
802                     }
803
804                     if (node.range[1] === comment.extendedRange[0]) {
805                         if (!node.trailingComments) {
806                             node.trailingComments = [];
807                         }
808                         node.trailingComments.push(comment);
809                         comments.splice(cursor, 1);
810                     } else {
811                         cursor += 1;
812                     }
813                 }
814
815                 // already out of owned node
816                 if (cursor === comments.length) {
817                     return VisitorOption.Break;
818                 }
819
820                 if (comments[cursor].extendedRange[0] > node.range[1]) {
821                     return VisitorOption.Skip;
822                 }
823             }
824         });
825
826         return tree;
827     }
828
829     exports.version = '1.8.0';
830     exports.Syntax = Syntax;
831     exports.traverse = traverse;
832     exports.replace = replace;
833     exports.attachComments = attachComments;
834     exports.VisitorKeys = VisitorKeys;
835     exports.VisitorOption = VisitorOption;
836     exports.Controller = Controller;
837 }));
838 /* vim: set sw=4 ts=4 et tw=80 : */