Blame view

node_modules/recast/example/to-while 2.19 KB
ce4c83ff   wxy   初始提交
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
  #!/usr/bin/env node
  
  // This script converts for and do-while loops into equivalent while loops.
  // Note that for-in statements are left unmodified, as they do not have a
  // simple analogy to while loops. Also note that labeled continue statements
  // are not correctly handled at this point, and will trigger an assertion
  // failure if encountered.
  
  var assert = require("assert");
  var recast = require("recast");
  var types = recast.types;
  var n = types.namedTypes;
  var b = types.builders;
  
  recast.run(function(ast, callback) {
      recast.visit(ast, {
          visitForStatement: function(path) {
              var fst = path.node;
  
              path.replace(
                  fst.init,
                  b.whileStatement(
                      fst.test,
                      insertBeforeLoopback(fst, fst.update)
                  )
              );
  
              this.traverse(path);
          },
  
          visitDoWhileStatement: function(path) {
              var dwst = path.node;
              return b.whileStatement(
                  b.literal(true),
                  insertBeforeLoopback(
                      dwst,
                      b.ifStatement(
                          dwst.test,
                          b.breakStatement()
                      )
                  )
              );
          }
      });
  
      callback(ast);
  });
  
  function insertBeforeLoopback(loop, toInsert) {
      var body = loop.body;
  
      if (!n.Statement.check(toInsert)) {
          toInsert = b.expressionStatement(toInsert);
      }
  
      if (n.BlockStatement.check(body)) {
          body.body.push(toInsert);
      } else {
          body = b.blockStatement([body, toInsert]);
          loop.body = body;
      }
  
      recast.visit(body, {
          visitContinueStatement: function(path) {
              var cst = path.node;
  
              assert.equal(
                  cst.label, null,
                  "Labeled continue statements are not yet supported."
              );
  
              path.replace(toInsert, path.node);
              return false;
          },
  
          // Do not descend into nested loops.
          visitWhileStatement: function() {},
          visitForStatement: function() {},
          visitForInStatement: function() {},
          visitDoWhileStatement: function() {}
      });
  
      return body;
  }