Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
  • 2 commits
  • 2 files changed
  • 0 comments
  • 1 contributor
Oct 05, 2012
Brandon Benvie replace the one place where I cheat and parse code, make some conveni…
…ence bindings, clean up and DRY the destructurer
56bbf49
Brandon Benvie change all the builtins to use CPS, implement "interpret" and "refere…
…nce" basic versions, implement a number of the ASTNode executors, and holy hell it actuall executes code
7f78aae
269  lib/interpretor.js
@@ -3,7 +3,8 @@ var descriptor = require('./descriptor'),
3 3
     define = require('./utility').define,
4 4
     hasOwn = {}.hasOwnProperty,
5 5
     create = Object.create,
6  
-    defineProperty = Object.defineProperty;
  6
+    defineProperty = Object.defineProperty,
  7
+    defineProperties = Object.defineProperties;
7 8
 
8 9
 
9 10
 
@@ -48,7 +49,8 @@ define(Reference.prototype, [
48 49
 
49 50
 
50 51
 var functions = new WeakMap,
51  
-    primitiveWrappers = new WeakMap;
  52
+    primitiveWrappers = new WeakMap,
  53
+    argumentObjects = new WeakMap;
52 54
 
53 55
 
54 56
 // #############
@@ -137,52 +139,52 @@ var builtins = (function(builtins){
137 139
     return builtins[def.name] = new BuiltinType(def);
138 140
   }
139 141
 
140  
-  function makeCollection(name, Ctor){
  142
+  function makeCollection(Ctor){
141 143
     var collections = new WeakMap,
142  
-        prototype = name + 'Prototype',
  144
+        prototype = Ctor.name + 'Prototype',
143 145
         Builtin;
144 146
 
145 147
     return Builtin = register({
146  
-      name: name,
147  
-      call: function(context, args){
  148
+      name: Ctor.name,
  149
+      call: function(context, args, complete){
148 150
         if (args.receiver == null)
149  
-          return Builtin.construct(context, args);
  151
+          return complete(Builtin.construct(context, args));
150 152
 
151 153
         var target = ToObject(context, args.receiver);
152 154
         if (collections.has(target))
153  
-          throw new TypeError('Object is already a Set');
  155
+          return context.error('type', 'Object is already a Set');
154 156
 
155 157
         collections.set(target, new Ctor);
156  
-        return target;
  158
+        complete(target);
157 159
       },
158  
-      construct: function(context, args){
  160
+      construct: function(context, args, complete){
159 161
         var self = create(context.global[prototype]);
160 162
         collections.set(self, new Ctor);
161  
-        return self;
  163
+        complete(self);
162 164
       }
163 165
     });
164 166
   }
165 167
 
166  
-  function makePrimitive(name, coerce){
  168
+  function makePrimitive(Ctor){
167 169
     var primitives = new WeakMap,
168  
-        prototype = name + 'Prototype';
  170
+        prototype = Ctor.name + 'Prototype';
169 171
 
170 172
     return register({
171  
-      name: name,
172  
-      call: function(context, args){
173  
-        return coerce(args[0]);
  173
+      name: Ctor.name,
  174
+      call: function(context, args, complete){
  175
+        complete(Ctor(args[0]));
174 176
       },
175  
-      construct: function(context, args){
  177
+      construct: function(context, args, complete){
176 178
         var self = create(context.global[prototype]);
177  
-        primitives.set(self, coerce(args[0]));
178  
-        return self;
  179
+        primitives.set(self, Ctor(args[0]));
  180
+        complete(self);
179 181
       }
180 182
     });
181 183
   }
182 184
 
183 185
   BuiltinArray = register({
184 186
     name: 'Array',
185  
-    construct: function(context, args){
  187
+    construct: function(context, args, complete){
186 188
       var self = create(context.global.ArrayPrototype);
187 189
       if (args.length === 1 && typeof args[0] === 'number') {
188 190
         var len = args[0];
@@ -191,39 +193,45 @@ var builtins = (function(builtins){
191 193
           self[i] = args[i];
192 194
         var len = args.length;
193 195
       }
194  
-      return defineProperty(self, 'length', descriptor('length', args.length));
  196
+      defineProperty(self, 'length', descriptor('length', args.length));
  197
+      complete(self);
195 198
     }
196 199
   });
197 200
 
198  
-  BuiltinBoolean = makePrimitive('Boolean', Boolean);
  201
+  BuiltinBoolean = makePrimitive(Boolean);
199 202
 
200 203
   BuiltinFunction = register({
201 204
     name: 'Function',
202  
-    construct: function(context, args){}
  205
+    construct: function(context, args, complete){
  206
+      var body = args.pop();
  207
+      var src = 'function anonymous('+args+') {\n'+body+'\n}';
  208
+      var self = new Thunk('anonymous', args.length, parse(src), null, Thunk.NORMAL).instantiate(context);
  209
+      complete(self);
  210
+    }
203 211
   });
204 212
 
205  
-  BuiltinMap = makeCollection('Map', Map);
  213
+  BuiltinMap = makeCollection(Map);
206 214
 
207  
-  BuiltinNumber = makePrimitive('String', String);
  215
+  BuiltinNumber = makePrimitive(String);
208 216
 
209 217
   BuiltinObject = register({
210 218
     name: 'Object',
211  
-    call: function(context, args){
212  
-      return ToObject(context, args[0]);
  219
+    call: function(context, args, complete){
  220
+      complete(ToObject(context, args[0]));
213 221
     },
214  
-    construct: function(context, args){
215  
-      return create(context.global.ObjectPrototype);
  222
+    construct: function(context, args, complete){
  223
+      complete(create(context.global.ObjectPrototype));
216 224
     }
217 225
   });
218 226
 
219 227
   BuiltinRegExp = register({
220 228
     name: 'RegExp',
221  
-    construct: function(context, args){}
  229
+    construct: function(context, args, complete){}
222 230
   });
223 231
 
224  
-  BuiltinSet = makeCollection('Set', Set);
  232
+  BuiltinSet = makeCollection(Set);
225 233
 
226  
-  BuiltinWeakMap = makeCollection('WeakMap', WeakMap);
  234
+  BuiltinWeakMap = makeCollection(WeakMap);
227 235
 
228 236
   return builtins;
229 237
 }({}));
@@ -282,6 +290,19 @@ define(Scope.prototype, [
282 290
   },
283 291
   function create(Type, args){
284 292
     return builtins[Type].construct(this, args ? args : []);
  293
+  },
  294
+  function makeArguments(args){
  295
+    var obj = create(this.global.ObjectPrototype);
  296
+    argumentObjects.set(obj, true);
  297
+
  298
+    if (args) {
  299
+      for (var i=0; i < args.length; i++)
  300
+        obj[i] = args[i];
  301
+    }
  302
+
  303
+    return defineProperty(obj, 'length', {
  304
+      value: i
  305
+    });
285 306
   }
286 307
 ]);
287 308
 
@@ -307,7 +328,9 @@ function GlobalScope(){
307 328
     });
308 329
   }
309 330
 
  331
+
310 332
   this.record = record;
  333
+  this.receiver = this.record;
311 334
 }
312 335
 
313 336
 inherit(GlobalScope, Scope);
@@ -360,29 +383,40 @@ inherit(BlockScope, Scope, [
360 383
   },
361 384
 ]);
362 385
 
363  
-var glob = new GlobalScope();
364  
-var block = glob.child(FunctionScope).child(BlockScope);
365  
-block.declare('let', 'Function', 'whetver')
366  
-block.declare('var', 'Function', 'x')
367  
-console.log(block);
  386
+
  387
+
  388
+function interpret(node, context, complete){
  389
+  console.log('interpreting ' + node.type);
  390
+  interpretors[node.type](node, context, complete);
  391
+}
  392
+
  393
+function reference(node, context, complete){
  394
+  if (node.type === 'MemberExpression') {
  395
+    interpret(node.object, context, function(object){
  396
+      interpret(node.property, context, function(property){
  397
+        complete(new Reference(object, property));
  398
+      });
  399
+    });
  400
+  } else if (node.type === 'Identifier') {
  401
+    complete(context.reference(node.name));
  402
+  }
  403
+}
368 404
 
369 405
 
370 406
 var interpretors = {
371 407
   ArrayExpression: function(node, context, complete){
372  
-    var count = node.elements.length,
373  
-        array = BuiltinArray.construct(context, [count]);
374  
-
375  
-    if (!count)
376  
-      return complete(array);
  408
+    var count = node.elements.length;
377 409
 
378  
-    function each(i, value){
379  
-      array[i] = value;
380  
-      if (!--count)
381  
-        complete(array);
382  
-    }
  410
+    BuiltinArray.construct(context, [count], function(array){
  411
+      if (!count) return complete(array);
383 412
 
384  
-    for (var i=0; i < node.elements; i++)
385  
-      interpret(node.elements[i], context, each.bind(null, i));
  413
+      for (var i=0; i < count; i++) {
  414
+        interpret(node.elements[i], context, function(value){
  415
+          array[i] = value;
  416
+          if (i === count - 1) complete(array);
  417
+        });
  418
+      }
  419
+    });
386 420
   },
387 421
   ArrayPattern: function(node, context){},
388 422
   ArrowFunctionExpression: function(node, context){},
@@ -437,9 +471,39 @@ var interpretors = {
437 471
       });
438 472
     });
439 473
   },
440  
-  BlockStatement: function(node, context){},
441  
-  BreakStatement: function(node, context){},
442  
-  CallExpression: function(node, context){},
  474
+  BlockStatement: function(node, context, complete){
  475
+    var body = node.body,
  476
+        count = body.length,
  477
+        statement;
  478
+
  479
+    context = context.child(BlockScope);
  480
+
  481
+    for (var i=0; statement = body[i]; i++) {
  482
+      interpret(statement, context, function(result){
  483
+        if (i === count - 1)
  484
+          complete(result);
  485
+      });
  486
+    }
  487
+  },
  488
+  BreakStatement: function(node, context, complete){
  489
+
  490
+  },
  491
+  CallExpression: function(node, context, complete){
  492
+    var argv = node.arguments,
  493
+        argc = argv.length,
  494
+        args = [],
  495
+        arg;
  496
+
  497
+    for (var i=0; arg = argv[i]; i++) {
  498
+      interpret(arg, context, function(result){
  499
+        args.push(result);
  500
+      });
  501
+    }
  502
+
  503
+    interpret(node.callee, context, function(result){
  504
+      functions.get(result).call(context, context.createArguments(args), complete);
  505
+    });
  506
+  },
443 507
   CatchClause: function(node, context){},
444 508
   ClassBody: function(node, context){},
445 509
   ClassDeclaration: function(node, context){},
@@ -449,18 +513,27 @@ var interpretors = {
449 513
   ContinueStatement: function(node, context){},
450 514
   DebuggerStatement: function(node, context){},
451 515
   DoWhileStatement: function(node, context){},
452  
-  EmptyStatement: function(node, context){},
  516
+  EmptyStatement: function(node, context, complete){
  517
+    complete();
  518
+  },
453 519
   ExportDeclaration: function(node, context){},
454 520
   ExportSpecifier: function(node, context){},
455 521
   ExportSpecifierSet: function(node, context){},
456  
-  ExpressionStatement: function(node, context){},
  522
+  ExpressionStatement: function(node, context, complete){
  523
+    if (node.expression.type === 'Identifier')
  524
+      complete(context.get(node.expression.name));
  525
+    else
  526
+      interpret(node.expression, context, complete);
  527
+  },
457 528
   ForInStatement: function(node, context){},
458 529
   ForOfStatement: function(node, context){},
459 530
   ForStatement: function(node, context){},
460 531
   FunctionDeclaration: function(node, context){},
461 532
   FunctionExpression: function(node, context){},
462 533
   Glob: function(node, context){},
463  
-  Identifier: function(node, context){},
  534
+  Identifier: function(node, context, complete){
  535
+    complete(node.name);
  536
+  },
464 537
   IfStatement: function(node, context){},
465 538
   ImmediatelyInvokedFunctionExpression: function(node, context){},
466 539
   ImportDeclaration: function(node, context){},
@@ -470,43 +543,76 @@ var interpretors = {
470 543
     complete(node.value);
471 544
   },
472 545
   LogicalExpression: function(node, context){},
473  
-  MemberExpression: function(node, context){},
  546
+  MemberExpression: function(node, context, complete){
  547
+    interpret(node.object, context, function(object){
  548
+      interpret(node.property, context, function(property){
  549
+        complete(object[property]);
  550
+      });
  551
+    });
  552
+  },
474 553
   MethodDefinition: function(node, context){},
475 554
   ModuleDeclaration: function(node, context){},
476  
-  NewExpression: function(node, context){},
  555
+  NewExpression: function(node, context, complete){
  556
+    var argv = node.arguments,
  557
+        argc = argv.length,
  558
+        args = [],
  559
+        arg;
  560
+
  561
+    for (var i=0; arg = argv[i]; i++) {
  562
+      interpret(arg, context, function(result){
  563
+        args.push(result);
  564
+      });
  565
+    }
  566
+
  567
+    reference(node.callee, context, function(result){
  568
+      functions.get(result.get()).construct(context, context.makeArguments(args), complete);
  569
+    });
  570
+  },
477 571
   ObjectExpression: function(node, context, complete){
478 572
     var properties = {},
479  
-        count = node.properties.length,
480  
-        object = BuiltinObject.construct(context);
  573
+        property,
  574
+        count = node.properties.length;
481 575
 
482  
-    if (!count)
483  
-      return complete(object);
484 576
 
485  
-    function each(property, value){
486  
-      if (properties[property.key])
487  
-        properties[property.key][property.type] = value;
488  
-      else
489  
-        properties[property.key] = descriptor(property.type, value);
  577
+    BuiltinObject.construct(context, null, function(object){
  578
+      if (!count)
  579
+        return complete(object);
490 580
 
491  
-      if (!--count)
492  
-        complete(defineProperties(object, properties));
493  
-    }
494 581
 
495  
-    node.properties.forEach(function(property){
496  
-      properties[property.key] = null;
497  
-      interpret(property.value, context, each.bind(null, property));
  582
+
  583
+      for (var i=0; property = node.properties[i]; i++) {
  584
+        interpret(property.key, context, function(key){
  585
+          interpret(property.value, context, function(value){
  586
+            if (properties[key])
  587
+              properties[key][property.kind] = value;
  588
+            else
  589
+              properties[key] = descriptor(property.kind, value);
  590
+
  591
+            if (!--count)
  592
+              complete(defineProperties(object, properties));
  593
+          });
  594
+        });
  595
+      }
498 596
     });
499 597
   },
500 598
   ObjectPattern: function(node, context){},
501 599
   Path: function(node, context){},
502 600
   Program: function(node, context, complete){
  601
+    var body = node.body,
  602
+        statement;
  603
+
503 604
     context = context || new GlobalScope;
504  
-    for (var i=0; i < node.body.length; i++) {
505 605
 
  606
+    for (var i=0; statement = body[i]; i++) {
  607
+      interpret(statement, context, function(value){
  608
+        if (i === body.length - 1)
  609
+          complete(value);
  610
+      });
506 611
     }
  612
+    console.log(context);
507 613
   },
508 614
   Property: function(node, context, complete){
509  
-
  615
+    interpret(node.value, context, complete);
510 616
   },
511 617
   ReturnStatement: function(node, context){},
512 618
   SequenceExpression: function(node, context){},
@@ -515,8 +621,8 @@ var interpretors = {
515 621
   TaggedTemplateExpression: function(node, context){},
516 622
   TemplateElement: function(node, context){},
517 623
   TemplateLiteral: function(node, context){},
518  
-  ThisExpression: function(node, context){
519  
-    return context.receiver;
  624
+  ThisExpression: function(node, context, complete){
  625
+    complete(context.receiver);
520 626
   },
521 627
   ThrowStatement: function(node, context){},
522 628
   TryStatement: function(node, context){},
@@ -528,3 +634,14 @@ var interpretors = {
528 634
   WithStatement: function(node, context){},
529 635
   YieldExpression: function(node, context){},
530 636
 };
  637
+
  638
+// var glob = new GlobalScope();
  639
+// var block = glob.child(FunctionScope).child(BlockScope);
  640
+// block.declare('let', 'Function', 'whetver')
  641
+// block.declare('var', 'Function', 'x')
  642
+// console.log(block);
  643
+
  644
+
  645
+var AST = require('./AST');
  646
+var ast = new AST(0, 0, 'y = ({ x: [[[1], [new Set], [], 4]] }); y').toJSON();
  647
+console.log(interpret(ast, null, console.log))
152  transformers/es6.js
... ...
@@ -1,13 +1,13 @@
1 1
 var ASTNode = require('astify').ASTNode,
2 2
     $ = ASTNode.createNode,
3 3
     converters = {},
  4
+    define = require('../lib/utility').define,
4 5
     freeze = $('Object').get('freeze'),
5 6
     defaultQuasi = ASTNode.parse(function(r){
6 7
       for (var i=0, o=''; r[i]; o += r[i].raw + (++i === r.length ? '' : arguments[i]));
7 8
       return o;
8 9
     });
9 10
 
10  
-
11 11
 module.exports = function(ast){
12 12
   for (var k in converters) {
13 13
     ast.find(k).forEach(function(item){
@@ -18,15 +18,39 @@ module.exports = function(ast){
18 18
   return ast;
19 19
 }
20 20
 
21  
-var define = $('Object').get('defineProperty'),
  21
+function typeOF(name, type){
  22
+  return $('#binary', '===', $('#unary', 'typeof', $(name)), $('#literal', type));
  23
+}
  24
+
  25
+function ternary(check, either, or){
  26
+  return $('#conditional', check, either, or);
  27
+}
  28
+
  29
+function object(){
  30
+  return $('#object');
  31
+}
  32
+
  33
+function get(path){
  34
+  if (typeof path === 'string')
  35
+    path = path.split('.');
  36
+  var base = typeof path[0] === 'string' ? $(path[0]) : path[0];
  37
+  for (var i=1; i < path.length; i++)
  38
+    base = base.get(path[i]);
  39
+  return base;
  40
+}
  41
+
  42
+
  43
+var defineProperty = get('Object.defineProperty'),
22 44
     constructor = $('#literal', 'constructor'),
23  
-    hidden = $('#object', { enumerable: false });
  45
+    hidden = $('#object', { enumerable: false }),
  46
+    arraySlice = get('Array.prototype.slice.call');
  47
+
  48
+
24 49
 
25 50
 function addConverter(type, callback){
26 51
   converters[type] = callback;
27 52
 }
28 53
 
29  
-var arraySlice = $('Array').get('prototype').get('slice').get('call');
30 54
 
31 55
 
32 56
 addConverter('function[rest!=null]', function(node){
@@ -44,7 +68,7 @@ addConverter('class', function(node){
44 68
     var superclass = node.superClass && node.superClass.clone();
45 69
     node.find('member[object=super]').forEach(function(superCall){
46 70
       var call = superCall.parent;
47  
-      call.callee = superclass.get('prototype').get(superCall.property);
  71
+      call.callee = get(superclass, 'prototype', superCall.property);
48 72
       call.call();
49 73
     });
50 74
     node.find('call[callee=super]').forEach(function(superCall){
@@ -69,7 +93,7 @@ addConverter('class', function(node){
69 93
   });
70 94
 
71 95
   closure.append(node.id.set('prototype', prototype));
72  
-  closure.append(define.call([ctor.id.get('prototype'), constructor, hidden]));
  96
+  closure.append(defineProperty.call([ctor.id.get('prototype'), constructor, hidden]));
73 97
   closure.append(ret);
74 98
 
75 99
   if (node.matches('class')) {
@@ -97,7 +121,7 @@ addConverter('arrow', function(node){
97 121
 addConverter('module', function(node){
98 122
   node.find('export').forEach(converters.export);
99 123
   var closure = $('#functionexpr', null, ['global', 'exports'], node.body.clone());
100  
-  var args = [$('#this'), $('#this'), ASTNode.parse('typeof exports === "undefined" ? {} : exports')];
  124
+  var args = [$('#this'), $('#this'), ternary(typeOF('exports', 'undefined'), object(), $('exports'))];
101 125
   closure.returns('exports');
102 126
   var decl = freeze.call(closure.get('call').call(args)).declaration(node.id);
103 127
   node.replaceWith(decl);
@@ -150,66 +174,72 @@ function destructure(node, parent, value){
150 174
   handler.run(node);
151 175
 }
152 176
 
153  
-Destructurer.prototype = new process.EventEmitter;
154  
-
155  
-Destructurer.prototype.run = function run(node){
156  
-  this.iife.addArgument(this.root, this.value);
157  
-  this.handle(node, []);
158  
-  this.container.insertAfter(this.closure, this.parent);
159  
-  if (this.decl !== this.parent && this.decl.declarations.length)
160  
-    this.container.insertAfter(this.decl, this.parent);
161  
-  if (!this.parent.matches('var') || this.parent.declarations.length === 0)
162  
-    this.container.remove(this.parent);
163  
-}
164  
-
165  
-Destructurer.prototype.handle = function handle(node, path){
166  
-  if (node.matches('arraypattern')) {
167  
-    node.elements.forEach(function(subnode, index){
168  
-      this.handle(subnode, path.concat(index));
169  
-    }, this);
170  
-    if (node.parent.matches('decl'))
171  
-      node.parent.parent.remove(node.parent);
172  
-  } else if (node.matches('objectpattern')) {
173  
-    node.properties.forEach(function(prop){
174  
-      this.handle(prop.value, path.concat(prop.key.name));
175  
-    }, this);
176  
-    if (node.parent.matches('decl'))
177  
-      node.parent.parent.remove(node.parent);
178  
-  } else {
179  
-    var resolved = this.resolve(path);
180  
-    if (node.matches('ident')) {
181  
-      this.decl.append($('#decl', node.clone()));
182  
-    }
183  
-    else if (node.matches('member'))
184  
-      node = this.checkForThis(node)
185  
-    this.iife.append(node.set(resolved));
  177
+var interpretPattern = {
  178
+  ArrayPattern: function(node, index, array){
  179
+    this.handle(node, array.path.concat(index));
  180
+  },
  181
+  ObjectPattern: function(prop, index, array){
  182
+    this.handle(prop.value, array.path.concat(prop.key.name));
186 183
   }
187 184
 };
188 185
 
189  
-Destructurer.prototype.checkForThis = function checkForThis(node){
190  
-  var obj = node;
191  
-  while (obj.parent && obj.parent.matches('member'))
192  
-    obj = obj.parent;
193 186
 
194  
-  if (obj.object.matches('this')) {
195  
-    this.usesThis();
196  
-    node = node.clone();
197  
-    node.object.replaceWith($('$this'));
198  
-  }
199  
-  return node;
200  
-}
201 187
 
202  
-Destructurer.prototype.usesThis = function usesThis(){
203  
-  this.iife.addArgument($('$this'), $('#this'));
204  
-  this.usesThis = function(){}
205  
-};
  188
+define(Destructurer.prototype, [
  189
+  function run(node){
  190
+    this.iife.addArgument(this.root, this.value);
  191
+    this.handle(node, []);
  192
+    this.container.insertAfter(this.closure, this.parent);
206 193
 
207  
-Destructurer.prototype.resolve = function resolve(path){
208  
-  var root = this.root;
209  
-  for (var i=0; i < path.length; i++)
210  
-    root = root.get(path[i]);
211  
-  return root;
212  
-}
  194
+    if (this.decl !== this.parent && this.decl.declarations.length)
  195
+      this.container.insertAfter(this.decl, this.parent);
  196
+
  197
+    if (!this.parent.matches('var') || this.parent.declarations.length === 0)
  198
+      this.container.remove(this.parent);
  199
+  },
  200
+  function handle(node, path){
  201
+    if (node.matches('pattern')) {
  202
+      var components = node.elements || node.properties;
  203
+      components.path = path;
  204
+      components.forEach(interpretPattern[node.type], this);
  205
+
  206
+      if (node.parent.matches('decl'))
  207
+      node.parent.parent.remove(node.parent);
  208
+
  209
+    } else {
  210
+      var resolved = this.resolve(path);
  211
+
  212
+      if (node.matches('ident'))
  213
+        this.decl.append($('#decl', node.clone()));
  214
+      else if (node.matches('member'))
  215
+        node = this.checkForThis(node)
  216
+
  217
+      this.iife.append(node.set(resolved));
  218
+    }
  219
+  },
  220
+  function checkForThis(node){
  221
+    var obj = node;
  222
+    while (obj.parent && obj.parent.matches('member'))
  223
+      obj = obj.parent;
  224
+
  225
+    if (obj.object.matches('this')) {
  226
+      this.usesThis();
  227
+      node = node.clone();
  228
+      node.object.replaceWith($('$this'));
  229
+    }
  230
+    return node;
  231
+  },
  232
+  function usesThis(){
  233
+    this.iife.addArgument($('$this'), $('#this'));
  234
+    this.usesThis = function(){}
  235
+  },
  236
+  function resolve(path){
  237
+    var root = this.root;
  238
+    for (var i=0; i < path.length; i++)
  239
+      root = root.get(path[i]);
  240
+    return root;
  241
+  }
  242
+]);
213 243
 
214 244
 
215 245
 function patterns(node){

No commit comments for this range

Something went wrong with that request. Please try again.