initial import
[vuplus_webkit] / Source / JavaScriptCore / tests / mozilla / ecma_3 / Function / scope-002.js
1 /*
2 * The contents of this file are subject to the Netscape Public
3 * License Version 1.1 (the "License"); you may not use this file
4 * except in compliance with the License. You may obtain a copy of
5 * the License at http://www.mozilla.org/NPL/
6 *
7 * Software distributed under the License is distributed on an "AS
8 * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
9 * implied. See the License for the specific language governing
10 * rights and limitations under the License.
11 *
12 * The Original Code is mozilla.org code.
13 *
14 * The Initial Developer of the Original Code is Netscape
15 * Communications Corporation.  Portions created by Netscape are
16 * Copyright (C) 1998 Netscape Communications Corporation. All
17 * Rights Reserved.
18 *
19 * Contributor(s): pschwartau@netscape.com, rogerl@netscape.com
20 * Date: 28 May 2001
21 *
22 * SUMMARY:  Functions are scoped statically, not dynamically
23 *
24 * See ECMA Section 10.1.4 Scope Chain and Identifier Resolution
25 * (This section defines the scope chain of an execution context)
26 *
27 * See ECMA Section 12.10 The with Statement
28 *
29 * See ECMA Section 13 Function Definition
30 * (This section defines the scope chain of a function object as that
31 *  of the running execution context when the function was declared)
32 *
33 * Like scope-001.js, but using assignment var f = function expression
34 * instead of a function declaration: function f() {} etc.
35 */
36 //-------------------------------------------------------------------------------------------------
37 var UBound = 0;
38 var bug = '(none)';
39 var summary = 'Testing that functions are scoped statically, not dynamically';
40 var self = this;  // capture a reference to the global object
41 var status = '';
42 var statusitems = [ ];
43 var actual = '';
44 var actualvalues = [ ];
45 var expect= '';
46 var expectedvalues = [ ];
47
48
49 /*
50  * In this section the expected value is 1, not 2.
51  *
52  * Why? f captures its scope chain from when it's declared, and imposes that chain
53  * when it's executed. In other words, f's scope chain is from when it was compiled.
54  * Since f is a top-level function, this is the global object only. Hence 'a' resolves to 1.
55  */
56 status = 'Section A of test';
57 var a = 1;
58 var f = function () {return a;};
59 var obj = {a:2};
60 with (obj)
61 {
62   actual = f();
63 }
64 expect = 1;
65 addThis();
66
67
68 /*
69  * In this section the expected value is 2, not 1. That is because here
70  * f's associated scope chain now includes 'obj' before the global object.
71  */
72 status = 'Section B of test';
73 var a = 1;
74 var obj = {a:2};
75 with (obj)
76 {
77   var f = function () {return a;};
78   actual = f();
79 }
80 expect = 2;
81 addThis();
82
83
84 /*
85  * Like Section B , except that we call f outside the with block.
86  * By the principles explained above, we still expect 2 -
87  */
88 status = 'Section C of test';
89 var a = 1;
90 var obj = {a:2};
91 with (obj)
92 {
93   var f = function () {return a;};
94 }
95 actual = f();
96 expect = 2;
97 addThis();
98
99
100 /*
101  * Like Section C, but with one more level of indirection -
102  */
103 status = 'Section D of test';
104 var a = 1;
105 var obj = {a:2, obj:{a:3}};
106 with (obj)
107 {
108   with (obj)
109   {
110     var f = function () {return a;};
111   }
112 }
113 actual = f();
114 expect = 3;
115 addThis();
116
117
118 /*
119  * Like Section C, but here we actually delete obj before calling f.
120  * We still expect 2 -
121  */
122 status = 'Section E of test';
123 var a = 1;
124 var obj = {a:2};
125 with (obj)
126 {
127   var f = function () {return a;};
128 }
129 delete obj;
130 actual = f();
131 expect = 2;
132 addThis();
133
134
135 /*
136  * Like Section E. Here we redefine obj and call f under with (obj) -
137  * We still expect 2 -
138  */
139 status = 'Section F of test';
140 var a = 1;
141 var obj = {a:2};
142 with (obj)
143 {
144   var f = function () {return a;};
145 }
146 delete obj;
147 var obj = {a:3};
148 with (obj)
149 {
150   actual = f();
151 }
152 expect = 2;  // NOT 3 !!!
153 addThis();
154
155
156 /*
157  * Explicitly verify that f exists at global level, even though
158  * it was defined under the with(obj) block -
159  */
160 status = 'Section G of test';
161 var a = 1;
162 var obj = {a:2};
163 with (obj)
164 {
165   var f = function () {return a;};
166 }
167 actual = String([obj.hasOwnProperty('f'), self.hasOwnProperty('f')]);
168 expect = String([false, true]);
169 addThis();
170
171
172 /*
173  * Explicitly verify that f exists at global level, even though
174  * it was defined under the with(obj) block -
175  */
176 status = 'Section H of test';
177 var a = 1;
178 var obj = {a:2};
179 with (obj)
180 {
181   var f = function () {return a;};
182 }
183 actual = String(['f' in obj, 'f' in self]);
184 expect = String([false, true]);
185 addThis();
186
187
188
189 //-------------------------------------------------------------------------------------------------
190 test();
191 //-------------------------------------------------------------------------------------------------
192
193
194 function addThis()
195 {
196   statusitems[UBound] = status;
197   actualvalues[UBound] = actual;
198   expectedvalues[UBound] = expect;
199   UBound++;
200   resetTestVars();
201 }
202
203
204 function resetTestVars()
205 {
206   delete a;
207   delete obj;
208   delete f;
209 }
210
211
212 function test()
213 {
214   enterFunc ('test');
215   printBugNumber (bug);
216   printStatus (summary);
217  
218   for (var i = 0; i < UBound; i++)
219   {
220     reportCompare(expectedvalues[i], actualvalues[i], statusitems[i]);
221   }
222
223   exitFunc ('test');
224 }