PageRenderTime 59ms CodeModel.GetById 15ms app.highlight 36ms RepoModel.GetById 1ms app.codeStats 0ms

/documentation/docs/scope.html

http://github.com/jashkenas/coffee-script
HTML | 392 lines | 265 code | 127 blank | 0 comment | 0 complexity | db2b0b333c46bf2db8b59d105095c30f MD5 | raw file
  1<!DOCTYPE html>
  2
  3<html>
  4<head>
  5  <title>scope.litcoffee</title>
  6  <meta http-equiv="content-type" content="text/html; charset=UTF-8">
  7  <meta name="viewport" content="width=device-width, target-densitydpi=160dpi, initial-scale=1.0; maximum-scale=1.0; user-scalable=0;">
  8  <link rel="stylesheet" media="all" href="docco.css" />
  9</head>
 10<body>
 11  <div id="container">
 12    <div id="background"></div>
 13    
 14      <ul id="jump_to">
 15        <li>
 16          <a class="large" href="javascript:void(0);">Jump To &hellip;</a>
 17          <a class="small" href="javascript:void(0);">+</a>
 18          <div id="jump_wrapper">
 19          <div id="jump_page_wrapper">
 20            <div id="jump_page">
 21              
 22                
 23                <a class="source" href="browser.html">
 24                  browser.coffee
 25                </a>
 26              
 27                
 28                <a class="source" href="cake.html">
 29                  cake.coffee
 30                </a>
 31              
 32                
 33                <a class="source" href="coffee-script.html">
 34                  coffee-script.coffee
 35                </a>
 36              
 37                
 38                <a class="source" href="command.html">
 39                  command.coffee
 40                </a>
 41              
 42                
 43                <a class="source" href="grammar.html">
 44                  grammar.coffee
 45                </a>
 46              
 47                
 48                <a class="source" href="helpers.html">
 49                  helpers.coffee
 50                </a>
 51              
 52                
 53                <a class="source" href="index.html">
 54                  index.coffee
 55                </a>
 56              
 57                
 58                <a class="source" href="lexer.html">
 59                  lexer.coffee
 60                </a>
 61              
 62                
 63                <a class="source" href="nodes.html">
 64                  nodes.coffee
 65                </a>
 66              
 67                
 68                <a class="source" href="optparse.html">
 69                  optparse.coffee
 70                </a>
 71              
 72                
 73                <a class="source" href="register.html">
 74                  register.coffee
 75                </a>
 76              
 77                
 78                <a class="source" href="repl.html">
 79                  repl.coffee
 80                </a>
 81              
 82                
 83                <a class="source" href="rewriter.html">
 84                  rewriter.coffee
 85                </a>
 86              
 87                
 88                <a class="source" href="scope.html">
 89                  scope.litcoffee
 90                </a>
 91              
 92                
 93                <a class="source" href="sourcemap.html">
 94                  sourcemap.litcoffee
 95                </a>
 96              
 97            </div>
 98          </div>
 99        </li>
100      </ul>
101    
102    <ul class="sections">
103        
104          <li id="title">
105              <div class="annotation">
106                  <h1>scope.litcoffee</h1>
107              </div>
108          </li>
109        
110        
111        
112        <li id="section-1">
113            <div class="annotation">
114              
115              <div class="pilwrap ">
116                <a class="pilcrow" href="#section-1">&#182;</a>
117              </div>
118              <p>The <strong>Scope</strong> class regulates lexical scoping within CoffeeScript. As you
119generate code, you create a tree of scopes in the same shape as the nested
120function bodies. Each scope knows about the variables declared within it,
121and has a reference to its parent enclosing scope. In this way, we know which
122variables are new and need to be declared with <code>var</code>, and which are shared
123with external scopes.</p>
124
125            </div>
126            
127            <div class="content"><div class='highlight'><pre><span class="hljs-built_in">exports</span>.Scope = <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Scope</span></span></pre></div></div>
128            
129        </li>
130        
131        
132        <li id="section-2">
133            <div class="annotation">
134              
135              <div class="pilwrap ">
136                <a class="pilcrow" href="#section-2">&#182;</a>
137              </div>
138              <p>Initialize a scope with its parent, for lookups up the chain,
139as well as a reference to the <strong>Block</strong> node it belongs to, which is
140where it should declare its variables, a reference to the function that
141it belongs to, and a list of variables referenced in the source code
142and therefore should be avoided when generating variables.</p>
143
144            </div>
145            
146            <div class="content"><div class='highlight'><pre>  <span class="hljs-attribute">constructor</span>: <span class="hljs-function"><span class="hljs-params">(<span class="hljs-property">@parent</span>, <span class="hljs-property">@expressions</span>, <span class="hljs-property">@method</span>, <span class="hljs-property">@referencedVars</span>)</span> -&gt;</span>
147    <span class="hljs-property">@variables</span> = [{<span class="hljs-attribute">name</span>: <span class="hljs-string">'arguments'</span>, <span class="hljs-attribute">type</span>: <span class="hljs-string">'arguments'</span>}]
148    <span class="hljs-property">@positions</span> = {}
149    <span class="hljs-property">@utilities</span> = {} <span class="hljs-keyword">unless</span> <span class="hljs-property">@parent</span></pre></div></div>
150            
151        </li>
152        
153        
154        <li id="section-3">
155            <div class="annotation">
156              
157              <div class="pilwrap ">
158                <a class="pilcrow" href="#section-3">&#182;</a>
159              </div>
160              <p>The <code>@root</code> is the top-level <strong>Scope</strong> object for a given file.</p>
161
162            </div>
163            
164            <div class="content"><div class='highlight'><pre>    <span class="hljs-property">@root</span> = <span class="hljs-property">@parent</span>?.root ? <span class="hljs-keyword">this</span></pre></div></div>
165            
166        </li>
167        
168        
169        <li id="section-4">
170            <div class="annotation">
171              
172              <div class="pilwrap ">
173                <a class="pilcrow" href="#section-4">&#182;</a>
174              </div>
175              <p>Adds a new variable or overrides an existing one.</p>
176
177            </div>
178            
179            <div class="content"><div class='highlight'><pre>  <span class="hljs-attribute">add</span>: <span class="hljs-function"><span class="hljs-params">(name, type, immediate)</span> -&gt;</span>
180    <span class="hljs-keyword">return</span> <span class="hljs-property">@parent</span>.add name, type, immediate <span class="hljs-keyword">if</span> <span class="hljs-property">@shared</span> <span class="hljs-keyword">and</span> <span class="hljs-keyword">not</span> immediate
181    <span class="hljs-keyword">if</span> <span class="hljs-attribute">Object</span>::hasOwnProperty.call <span class="hljs-property">@positions</span>, name
182      <span class="hljs-property">@variables</span>[<span class="hljs-property">@positions</span>[name]].type = type
183    <span class="hljs-keyword">else</span>
184      <span class="hljs-property">@positions</span>[name] = <span class="hljs-property">@variables</span>.push({name, type}) - <span class="hljs-number">1</span></pre></div></div>
185            
186        </li>
187        
188        
189        <li id="section-5">
190            <div class="annotation">
191              
192              <div class="pilwrap ">
193                <a class="pilcrow" href="#section-5">&#182;</a>
194              </div>
195              <p>When <code>super</code> is called, we need to find the name of the current method we’re
196in, so that we know how to invoke the same method of the parent class. This
197can get complicated if super is being called from an inner function.
198<code>namedMethod</code> will walk up the scope tree until it either finds the first
199function object that has a name filled in, or bottoms out.</p>
200
201            </div>
202            
203            <div class="content"><div class='highlight'><pre>  <span class="hljs-attribute">namedMethod</span>:<span class="hljs-function"> -&gt;</span>
204    <span class="hljs-keyword">return</span> <span class="hljs-property">@method</span> <span class="hljs-keyword">if</span> <span class="hljs-property">@method</span>?.name <span class="hljs-keyword">or</span> !<span class="hljs-property">@parent</span>
205    <span class="hljs-property">@parent</span>.namedMethod()</pre></div></div>
206            
207        </li>
208        
209        
210        <li id="section-6">
211            <div class="annotation">
212              
213              <div class="pilwrap ">
214                <a class="pilcrow" href="#section-6">&#182;</a>
215              </div>
216              <p>Look up a variable name in lexical scope, and declare it if it does not
217already exist.</p>
218
219            </div>
220            
221            <div class="content"><div class='highlight'><pre>  <span class="hljs-attribute">find</span>: <span class="hljs-function"><span class="hljs-params">(name)</span> -&gt;</span>
222    <span class="hljs-keyword">return</span> <span class="hljs-literal">yes</span> <span class="hljs-keyword">if</span> <span class="hljs-property">@check</span> name
223    <span class="hljs-property">@add</span> name, <span class="hljs-string">'var'</span>
224    <span class="hljs-literal">no</span></pre></div></div>
225            
226        </li>
227        
228        
229        <li id="section-7">
230            <div class="annotation">
231              
232              <div class="pilwrap ">
233                <a class="pilcrow" href="#section-7">&#182;</a>
234              </div>
235              <p>Reserve a variable name as originating from a function parameter for this
236scope. No <code>var</code> required for internal references.</p>
237
238            </div>
239            
240            <div class="content"><div class='highlight'><pre>  <span class="hljs-attribute">parameter</span>: <span class="hljs-function"><span class="hljs-params">(name)</span> -&gt;</span>
241    <span class="hljs-keyword">return</span> <span class="hljs-keyword">if</span> <span class="hljs-property">@shared</span> <span class="hljs-keyword">and</span> <span class="hljs-property">@parent</span>.check name, <span class="hljs-literal">yes</span>
242    <span class="hljs-property">@add</span> name, <span class="hljs-string">'param'</span></pre></div></div>
243            
244        </li>
245        
246        
247        <li id="section-8">
248            <div class="annotation">
249              
250              <div class="pilwrap ">
251                <a class="pilcrow" href="#section-8">&#182;</a>
252              </div>
253              <p>Just check to see if a variable has already been declared, without reserving,
254walks up to the root scope.</p>
255
256            </div>
257            
258            <div class="content"><div class='highlight'><pre>  <span class="hljs-attribute">check</span>: <span class="hljs-function"><span class="hljs-params">(name)</span> -&gt;</span>
259    !!(<span class="hljs-property">@type</span>(name) <span class="hljs-keyword">or</span> <span class="hljs-property">@parent</span>?.check(name))</pre></div></div>
260            
261        </li>
262        
263        
264        <li id="section-9">
265            <div class="annotation">
266              
267              <div class="pilwrap ">
268                <a class="pilcrow" href="#section-9">&#182;</a>
269              </div>
270              <p>Generate a temporary variable name at the given index.</p>
271
272            </div>
273            
274            <div class="content"><div class='highlight'><pre>  <span class="hljs-attribute">temporary</span>: <span class="hljs-function"><span class="hljs-params">(name, index, single=<span class="hljs-literal">false</span>)</span> -&gt;</span>
275    <span class="hljs-keyword">if</span> single
276      (index + parseInt name, <span class="hljs-number">36</span>).toString(<span class="hljs-number">36</span>).replace <span class="hljs-regexp">/\d/g</span>, <span class="hljs-string">'a'</span>
277    <span class="hljs-keyword">else</span>
278      name + (index <span class="hljs-keyword">or</span> <span class="hljs-string">''</span>)</pre></div></div>
279            
280        </li>
281        
282        
283        <li id="section-10">
284            <div class="annotation">
285              
286              <div class="pilwrap ">
287                <a class="pilcrow" href="#section-10">&#182;</a>
288              </div>
289              <p>Gets the type of a variable.</p>
290
291            </div>
292            
293            <div class="content"><div class='highlight'><pre>  <span class="hljs-attribute">type</span>: <span class="hljs-function"><span class="hljs-params">(name)</span> -&gt;</span>
294    <span class="hljs-keyword">return</span> v.type <span class="hljs-keyword">for</span> v <span class="hljs-keyword">in</span> <span class="hljs-property">@variables</span> <span class="hljs-keyword">when</span> v.name <span class="hljs-keyword">is</span> name
295    <span class="hljs-literal">null</span></pre></div></div>
296            
297        </li>
298        
299        
300        <li id="section-11">
301            <div class="annotation">
302              
303              <div class="pilwrap ">
304                <a class="pilcrow" href="#section-11">&#182;</a>
305              </div>
306              <p>If we need to store an intermediate result, find an available name for a
307compiler-generated variable. <code>_var</code>, <code>_var2</code>, and so on…</p>
308
309            </div>
310            
311            <div class="content"><div class='highlight'><pre>  <span class="hljs-attribute">freeVariable</span>: <span class="hljs-function"><span class="hljs-params">(name, options={})</span> -&gt;</span>
312    index = <span class="hljs-number">0</span>
313    <span class="hljs-keyword">loop</span>
314      temp = <span class="hljs-property">@temporary</span> name, index, options.single
315      <span class="hljs-keyword">break</span> <span class="hljs-keyword">unless</span> <span class="hljs-property">@check</span>(temp) <span class="hljs-keyword">or</span> temp <span class="hljs-keyword">in</span> <span class="hljs-property">@root</span>.referencedVars
316      index++
317    <span class="hljs-property">@add</span> temp, <span class="hljs-string">'var'</span>, <span class="hljs-literal">yes</span> <span class="hljs-keyword">if</span> options.reserve ? <span class="hljs-literal">true</span>
318    temp</pre></div></div>
319            
320        </li>
321        
322        
323        <li id="section-12">
324            <div class="annotation">
325              
326              <div class="pilwrap ">
327                <a class="pilcrow" href="#section-12">&#182;</a>
328              </div>
329              <p>Ensure that an assignment is made at the top of this scope
330(or at the top-level scope, if requested).</p>
331
332            </div>
333            
334            <div class="content"><div class='highlight'><pre>  <span class="hljs-attribute">assign</span>: <span class="hljs-function"><span class="hljs-params">(name, value)</span> -&gt;</span>
335    <span class="hljs-property">@add</span> name, {value, <span class="hljs-attribute">assigned</span>: <span class="hljs-literal">yes</span>}, <span class="hljs-literal">yes</span>
336    <span class="hljs-property">@hasAssignments</span> = <span class="hljs-literal">yes</span></pre></div></div>
337            
338        </li>
339        
340        
341        <li id="section-13">
342            <div class="annotation">
343              
344              <div class="pilwrap ">
345                <a class="pilcrow" href="#section-13">&#182;</a>
346              </div>
347              <p>Does this scope have any declared variables?</p>
348
349            </div>
350            
351            <div class="content"><div class='highlight'><pre>  <span class="hljs-attribute">hasDeclarations</span>:<span class="hljs-function"> -&gt;</span>
352    !!<span class="hljs-property">@declaredVariables</span>().length</pre></div></div>
353            
354        </li>
355        
356        
357        <li id="section-14">
358            <div class="annotation">
359              
360              <div class="pilwrap ">
361                <a class="pilcrow" href="#section-14">&#182;</a>
362              </div>
363              <p>Return the list of variables first declared in this scope.</p>
364
365            </div>
366            
367            <div class="content"><div class='highlight'><pre>  <span class="hljs-attribute">declaredVariables</span>:<span class="hljs-function"> -&gt;</span>
368    (v.name <span class="hljs-keyword">for</span> v <span class="hljs-keyword">in</span> <span class="hljs-property">@variables</span> <span class="hljs-keyword">when</span> v.type <span class="hljs-keyword">is</span> <span class="hljs-string">'var'</span>).sort()</pre></div></div>
369            
370        </li>
371        
372        
373        <li id="section-15">
374            <div class="annotation">
375              
376              <div class="pilwrap ">
377                <a class="pilcrow" href="#section-15">&#182;</a>
378              </div>
379              <p>Return the list of assignments that are supposed to be made at the top
380of this scope.</p>
381
382            </div>
383            
384            <div class="content"><div class='highlight'><pre>  <span class="hljs-attribute">assignedVariables</span>:<span class="hljs-function"> -&gt;</span>
385    <span class="hljs-string">"<span class="hljs-subst">#{v.name}</span> = <span class="hljs-subst">#{v.type.value}</span>"</span> <span class="hljs-keyword">for</span> v <span class="hljs-keyword">in</span> <span class="hljs-property">@variables</span> <span class="hljs-keyword">when</span> v.type.assigned</pre></div></div>
386            
387        </li>
388        
389    </ul>
390  </div>
391</body>
392</html>