@@ -15,7 +15,7 @@ import {List, Map, ListWrapper, MapWrapper} from 'facade/collection';
1515import  { AST ,  AccessMember ,  ImplicitReceiver ,  AstVisitor ,  LiteralPrimitive , 
1616  Binary ,  Formatter ,  MethodCall ,  FunctionCall ,  PrefixNot ,  Conditional , 
1717  LiteralArray ,  LiteralMap ,  KeyedAccess ,  Chain ,  Assignment }  from  './parser/ast' ; 
18- 
18+ import   { ContextWithVariableBindings }   from   './parser/context_with_variable_bindings' ; 
1919
2020export class  ProtoRecordRange  { 
2121  headRecord :ProtoRecord ; 
@@ -304,10 +304,35 @@ export class RecordRange {
304304    for  ( var  record :Record  =  this . headRecord ; 
305305         record  !=  null ; 
306306         record  =  record . next )  { 
307+ 
307308      if  ( record . isImplicitReceiver )  { 
308-         record . updateContext ( context ) ; 
309+         this . _setContextForRecord ( context ,  record ) ; 
310+       } 
311+     } 
312+   } 
313+ 
314+   _setContextForRecord ( context ,  record :Record )   { 
315+     var  proto  =  record . protoRecord ; 
316+ 
317+     while  ( context  instanceof  ContextWithVariableBindings )  { 
318+       if  ( context . hasBinding ( proto . name ) )  { 
319+         this . _setVarBindingGetter ( context ,  record ,  proto ) ; 
320+         return ; 
309321      } 
322+       context  =  context . parent ; 
310323    } 
324+ 
325+     this . _setRegularGetter ( context ,  record ,  proto ) ; 
326+   } 
327+ 
328+   _setVarBindingGetter ( context ,  record :Record ,  proto :ProtoRecord )   { 
329+     record . funcOrValue  =  _mapGetter ( proto . name ) ; 
330+     record . updateContext ( context . varBindings ) ; 
331+   } 
332+ 
333+   _setRegularGetter ( context ,  record :Record ,  proto :ProtoRecord )   { 
334+     record . funcOrValue  =  proto . funcOrValue ; 
335+     record . updateContext ( context ) ; 
311336  } 
312337} 
313338
@@ -353,25 +378,25 @@ class ProtoRecordCreator {
353378  } 
354379
355380  visitLiteralPrimitive ( ast :LiteralPrimitive ,  dest )  { 
356-     this . add ( this . construct ( RECORD_TYPE_CONST ,  ast . value ,  0 ,  dest ) ) ; 
381+     this . add ( this . construct ( RECORD_TYPE_CONST ,  ast . value ,  0 ,  null ,   dest ) ) ; 
357382  } 
358383
359384  visitBinary ( ast :Binary ,  dest )  { 
360385    var  record  =  this . construct ( RECORD_TYPE_INVOKE_PURE_FUNCTION , 
361-                                 _operationToFunction ( ast . operation ) ,  2 ,  dest ) ; 
386+                                 _operationToFunction ( ast . operation ) ,  2 ,  null ,   dest ) ; 
362387    ast . left . visit ( this ,  new  Destination ( record ,  0 ) ) ; 
363388    ast . right . visit ( this ,  new  Destination ( record ,  1 ) ) ; 
364389    this . add ( record ) ; 
365390  } 
366391
367392  visitPrefixNot ( ast :PrefixNot ,  dest )  { 
368-     var  record  =  this . construct ( RECORD_TYPE_INVOKE_PURE_FUNCTION ,  _operation_negate ,  1 ,  dest ) ; 
393+     var  record  =  this . construct ( RECORD_TYPE_INVOKE_PURE_FUNCTION ,  _operation_negate ,  1 ,  null ,   dest ) ; 
369394    ast . expression . visit ( this ,  new  Destination ( record ,  0 ) ) ; 
370395    this . add ( record ) ; 
371396  } 
372397
373398  visitAccessMember ( ast :AccessMember ,  dest )  { 
374-     var  record  =  this . construct ( RECORD_TYPE_PROPERTY ,  ast . getter ,  0 ,  dest ) ; 
399+     var  record  =  this . construct ( RECORD_TYPE_PROPERTY ,  ast . getter ,  0 ,  ast . name ,   dest ) ; 
375400    if  ( ast . receiver  instanceof  ImplicitReceiver )  { 
376401      record . setIsImplicitReceiver ( ) ; 
377402    }  else  { 
@@ -381,15 +406,15 @@ class ProtoRecordCreator {
381406  } 
382407
383408  visitFormatter ( ast :Formatter ,  dest )  { 
384-     var  record  =  this . construct ( RECORD_TYPE_INVOKE_FORMATTER ,  ast . name ,  ast . allArgs . length ,  dest ) ; 
409+     var  record  =  this . construct ( RECORD_TYPE_INVOKE_FORMATTER ,  ast . name ,  ast . allArgs . length ,  null ,   dest ) ; 
385410    for  ( var  i  =  0 ;  i  <  ast . allArgs . length ;  ++ i )  { 
386411      ast . allArgs [ i ] . visit ( this ,  new  Destination ( record ,  i ) ) ; 
387412    } 
388413    this . add ( record ) ; 
389414  } 
390415
391416  visitMethodCall ( ast :MethodCall ,  dest )  { 
392-     var  record  =  this . construct ( RECORD_TYPE_INVOKE_METHOD ,  ast . fn ,  ast . args . length ,  dest ) ; 
417+     var  record  =  this . construct ( RECORD_TYPE_INVOKE_METHOD ,  ast . fn ,  ast . args . length ,  null ,   dest ) ; 
393418    for  ( var  i  =  0 ;  i  <  ast . args . length ;  ++ i )  { 
394419      ast . args [ i ] . visit ( this ,  new  Destination ( record ,  i ) ) ; 
395420    } 
@@ -402,7 +427,7 @@ class ProtoRecordCreator {
402427  } 
403428
404429  visitFunctionCall ( ast :FunctionCall ,  dest )  { 
405-     var  record  =  this . construct ( RECORD_TYPE_INVOKE_CLOSURE ,  null ,  ast . args . length ,  dest ) ; 
430+     var  record  =  this . construct ( RECORD_TYPE_INVOKE_CLOSURE ,  null ,  ast . args . length ,  null ,   dest ) ; 
406431    ast . target . visit ( this ,  new  Destination ( record ,  null ) ) ; 
407432    for  ( var  i  =  0 ;  i  <  ast . args . length ;  ++ i )  { 
408433      ast . args [ i ] . visit ( this ,  new  Destination ( record ,  i ) ) ; 
@@ -411,7 +436,7 @@ class ProtoRecordCreator {
411436  } 
412437
413438  visitConditional ( ast :Conditional ,  dest )  { 
414-     var  record  =  this . construct ( RECORD_TYPE_INVOKE_PURE_FUNCTION ,  _cond ,  3 ,  dest ) ; 
439+     var  record  =  this . construct ( RECORD_TYPE_INVOKE_PURE_FUNCTION ,  _cond ,  3 ,  null ,   dest ) ; 
415440    ast . condition . visit ( this ,  new  Destination ( record ,  0 ) ) ; 
416441    ast . trueExp . visit ( this ,  new  Destination ( record ,  1 ) ) ; 
417442    ast . falseExp . visit ( this ,  new  Destination ( record ,  2 ) ) ; 
@@ -422,7 +447,7 @@ class ProtoRecordCreator {
422447
423448  visitLiteralArray ( ast :LiteralArray ,  dest )  { 
424449    var  length  =  ast . expressions . length ; 
425-     var  record  =  this . construct ( RECORD_TYPE_INVOKE_PURE_FUNCTION ,  _arrayFn ( length ) ,  length ,  dest ) ; 
450+     var  record  =  this . construct ( RECORD_TYPE_INVOKE_PURE_FUNCTION ,  _arrayFn ( length ) ,  length ,  null ,   dest ) ; 
426451    for  ( var  i  =  0 ;  i  <  length ;  ++ i )  { 
427452      ast . expressions [ i ] . visit ( this ,  new  Destination ( record ,  i ) ) ; 
428453    } 
@@ -431,7 +456,7 @@ class ProtoRecordCreator {
431456
432457  visitLiteralMap ( ast :LiteralMap ,  dest )  { 
433458    var  length  =  ast . values . length ; 
434-     var  record  =  this . construct ( RECORD_TYPE_INVOKE_PURE_FUNCTION ,  _mapFn ( ast . keys ,  length ) ,  length ,  dest ) ; 
459+     var  record  =  this . construct ( RECORD_TYPE_INVOKE_PURE_FUNCTION ,  _mapFn ( ast . keys ,  length ) ,  length ,  null ,   dest ) ; 
435460    for  ( var  i  =  0 ;  i  <  length ;  ++ i )  { 
436461      ast . values [ i ] . visit ( this ,  new  Destination ( record ,  i ) ) ; 
437462    } 
@@ -448,8 +473,8 @@ class ProtoRecordCreator {
448473    ast . visit ( this ,  memento ) ; 
449474  } 
450475
451-   construct ( recordType ,  funcOrValue ,  arity ,  dest )  { 
452-     return  new  ProtoRecord ( this . protoRecordRange ,  recordType ,  funcOrValue ,  arity ,  dest ) ; 
476+   construct ( recordType ,  funcOrValue ,  arity ,  name ,   dest )  { 
477+     return  new  ProtoRecord ( this . protoRecordRange ,  recordType ,  funcOrValue ,  arity ,  name ,   dest ) ; 
453478  } 
454479
455480  add ( protoRecord :ProtoRecord )  { 
@@ -540,3 +565,10 @@ function _mapFn(keys:List, length:int) {
540565    default : throw  new  BaseException ( `Does not support literal maps with more than 9 elements` ) ; 
541566  } 
542567} 
568+ 
569+ //TODO: cache the getters 
570+ function  _mapGetter ( key )  { 
571+   return  function ( map )  { 
572+     return  MapWrapper . get ( map ,  key ) ; 
573+   } 
574+ } 
0 commit comments