OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 import 'dart:async'; | 5 import 'dart:async'; |
6 import 'dart:collection'; | 6 import 'dart:collection'; |
7 | 7 |
8 import 'package:async_helper/async_helper.dart'; | 8 import 'package:async_helper/async_helper.dart'; |
9 import 'package:expect/expect.dart'; | 9 import 'package:expect/expect.dart'; |
10 import 'package:compiler/src/constants/expressions.dart'; | 10 import 'package:compiler/src/constants/expressions.dart'; |
11 import 'package:compiler/src/dart_types.dart'; | 11 import 'package:compiler/src/dart_types.dart'; |
12 import 'package:compiler/src/elements/modelx.dart'; | 12 import 'package:compiler/src/elements/modelx.dart'; |
13 import 'package:compiler/src/resolution/constructors.dart'; | 13 import 'package:compiler/src/resolution/constructors.dart'; |
14 import 'package:compiler/src/resolution/members.dart'; | 14 import 'package:compiler/src/resolution/members.dart'; |
15 import 'package:compiler/src/resolution/registry.dart'; | 15 import 'package:compiler/src/resolution/registry.dart'; |
16 import 'package:compiler/src/resolution/resolution_result.dart'; | 16 import 'package:compiler/src/resolution/resolution_result.dart'; |
17 import 'package:compiler/src/resolution/scope.dart'; | 17 import 'package:compiler/src/resolution/scope.dart'; |
18 import 'package:compiler/src/resolution/tree_elements.dart'; | 18 import 'package:compiler/src/resolution/tree_elements.dart'; |
19 | 19 |
20 import 'compiler_helper.dart'; | 20 import 'compiler_helper.dart'; |
21 import 'link_helper.dart'; | 21 import 'link_helper.dart'; |
22 import 'parser_helper.dart'; | 22 import 'parser_helper.dart'; |
23 | 23 |
24 Node buildIdentifier(String name) => new Identifier(scan(name)); | 24 Node buildIdentifier(String name) => new Identifier(scan(name)); |
25 | 25 |
26 Node buildInitialization(String name) => | 26 Node buildInitialization(String name) => parseBodyCode('$name = 1', |
27 parseBodyCode('$name = 1', | 27 (parser, tokens) => parser.parseOptionallyInitializedIdentifier(tokens)); |
28 (parser, tokens) => parser.parseOptionallyInitializedIdentifier(tokens)); | |
29 | 28 |
30 createLocals(List variables) { | 29 createLocals(List variables) { |
31 var locals = <Node>[]; | 30 var locals = <Node>[]; |
32 for (final variable in variables) { | 31 for (final variable in variables) { |
33 String name = variable[0]; | 32 String name = variable[0]; |
34 bool init = variable[1]; | 33 bool init = variable[1]; |
35 if (init) { | 34 if (init) { |
36 locals.add(buildInitialization(name)); | 35 locals.add(buildInitialization(name)); |
37 } else { | 36 } else { |
38 locals.add(buildIdentifier(name)); | 37 locals.add(buildIdentifier(name)); |
(...skipping 18 matching lines...) Expand all Loading... |
57 final VariableElement variableElement = result.element; | 56 final VariableElement variableElement = result.element; |
58 MethodScope scope = visitor.scope; | 57 MethodScope scope = visitor.scope; |
59 Expect.equals(variableElement, scope.elements[name]); | 58 Expect.equals(variableElement, scope.elements[name]); |
60 } | 59 } |
61 return compiler; | 60 return compiler; |
62 }); | 61 }); |
63 } | 62 } |
64 | 63 |
65 main() { | 64 main() { |
66 asyncTest(() => Future.forEach([ | 65 asyncTest(() => Future.forEach([ |
67 testLocalsOne, | 66 testLocalsOne, |
68 testLocalsTwo, | 67 testLocalsTwo, |
69 testLocalsThree, | 68 testLocalsThree, |
70 testLocalsFour, | 69 testLocalsFour, |
71 testLocalsFive, | 70 testLocalsFive, |
72 testParametersOne, | 71 testParametersOne, |
73 testFor, | 72 testFor, |
74 testTypeAnnotation, | 73 testTypeAnnotation, |
75 testSuperclass, | 74 testSuperclass, |
76 // testVarSuperclass, // The parser crashes with 'class Foo extends var'. | 75 // testVarSuperclass, // The parser crashes with 'class Foo extends var'
. |
77 // testOneInterface, // Generates unexpected error message. | 76 // testOneInterface, // Generates unexpected error message. |
78 // testTwoInterfaces, // Generates unexpected error message. | 77 // testTwoInterfaces, // Generates unexpected error message. |
79 testFunctionExpression, | 78 testFunctionExpression, |
80 testNewExpression, | 79 testNewExpression, |
81 testTopLevelFields, | 80 testTopLevelFields, |
82 testClassHierarchy, | 81 testClassHierarchy, |
83 testEnumDeclaration, | 82 testEnumDeclaration, |
84 testInitializers, | 83 testInitializers, |
85 testThis, | 84 testThis, |
86 testSuperCalls, | 85 testSuperCalls, |
87 testSwitch, | 86 testSwitch, |
88 testTypeVariables, | 87 testTypeVariables, |
89 testToString, | 88 testToString, |
90 testIndexedOperator, | 89 testIndexedOperator, |
91 testIncrementsAndDecrements, | 90 testIncrementsAndDecrements, |
92 testOverrideHashCodeCheck, | 91 testOverrideHashCodeCheck, |
93 testSupertypeOrder, | 92 testSupertypeOrder, |
94 testConstConstructorAndNonFinalFields, | 93 testConstConstructorAndNonFinalFields, |
95 testCantAssignMethods, | 94 testCantAssignMethods, |
96 testCantAssignFinalAndConsts, | 95 testCantAssignFinalAndConsts, |
97 testAwaitHint, | 96 testAwaitHint, |
98 testConstantExpressions, | 97 testConstantExpressions, |
99 ], (f) => f())); | 98 ], (f) => f())); |
100 } | 99 } |
101 | 100 |
102 Future testSupertypeOrder() { | 101 Future testSupertypeOrder() { |
103 return Future.wait([ | 102 return Future.wait([ |
104 MockCompiler.create((MockCompiler compiler) { | 103 MockCompiler.create((MockCompiler compiler) { |
105 compiler.parseScript(""" | 104 compiler.parseScript(""" |
106 class I1 {} | 105 class I1 {} |
107 class I2 {} | 106 class I2 {} |
108 class J1 extends K1 {} | 107 class J1 extends K1 {} |
109 class J2 implements K2 {} | 108 class J2 implements K2 {} |
110 class K1 {} | 109 class K1 {} |
111 class K2 {} | 110 class K2 {} |
112 class L1 {} | 111 class L1 {} |
113 class A implements I1, I2 {} | 112 class A implements I1, I2 {} |
114 class B extends A implements J1, J2 {} | 113 class B extends A implements J1, J2 {} |
115 class C extends B implements L1 {} | 114 class C extends B implements L1 {} |
116 """); | 115 """); |
117 compiler.resolveStatement("C c;"); | 116 compiler.resolveStatement("C c;"); |
118 ClassElement classA = compiler.mainApp.find("A"); | 117 ClassElement classA = compiler.mainApp.find("A"); |
119 ClassElement classB = compiler.mainApp.find("B"); | 118 ClassElement classB = compiler.mainApp.find("B"); |
120 ClassElement classC = compiler.mainApp.find("C"); | 119 ClassElement classC = compiler.mainApp.find("C"); |
121 Expect.equals('[ I2, I1, Object ]', classA.allSupertypes.toString()); | 120 Expect.equals('[ I2, I1, Object ]', classA.allSupertypes.toString()); |
122 Expect.equals('[ A, J2, J1, I2, I1, K2, K1, Object ]', | 121 Expect.equals('[ A, J2, J1, I2, I1, K2, K1, Object ]', |
123 classB.allSupertypes.toString()); | 122 classB.allSupertypes.toString()); |
124 Expect.equals('[ B, L1, A, J2, J1, I2, I1, K2, K1, Object ]', | 123 Expect.equals('[ B, L1, A, J2, J1, I2, I1, K2, K1, Object ]', |
125 classC.allSupertypes.toString()); | 124 classC.allSupertypes.toString()); |
126 }), | 125 }), |
127 MockCompiler.create((MockCompiler compiler) { | 126 MockCompiler.create((MockCompiler compiler) { |
128 compiler.parseScript(""" | 127 compiler.parseScript(""" |
129 class X<T> {} | 128 class X<T> {} |
130 class Foo extends X<Foo> {} | 129 class Foo extends X<Foo> {} |
131 class Bar extends Foo implements X<Bar> {} | 130 class Bar extends Foo implements X<Bar> {} |
132 """); | 131 """); |
133 compiler.resolveStatement("Bar bar;"); | 132 compiler.resolveStatement("Bar bar;"); |
134 ClassElement classBar = compiler.mainApp.find("Bar"); | 133 ClassElement classBar = compiler.mainApp.find("Bar"); |
135 DiagnosticCollector collector = compiler.diagnosticCollector; | 134 DiagnosticCollector collector = compiler.diagnosticCollector; |
136 Expect.equals(0, collector.warnings.length); | 135 Expect.equals(0, collector.warnings.length); |
137 Expect.equals(1, collector.errors.length); | 136 Expect.equals(1, collector.errors.length); |
138 Expect.equals(MessageKind.MULTI_INHERITANCE, | 137 Expect.equals( |
139 collector.errors.first.message.kind); | 138 MessageKind.MULTI_INHERITANCE, collector.errors.first.message.kind); |
140 Expect.equals(0, collector.crashes.length); | 139 Expect.equals(0, collector.crashes.length); |
141 }), | 140 }), |
142 ]); | 141 ]); |
143 } | 142 } |
144 | 143 |
145 Future testTypeVariables() { | 144 Future testTypeVariables() { |
146 matchResolvedTypes(visitor, text, name, expectedElements) { | 145 matchResolvedTypes(visitor, text, name, expectedElements) { |
147 VariableDefinitions definition = parseStatement(text); | 146 VariableDefinitions definition = parseStatement(text); |
148 visitor.visit(definition.type); | 147 visitor.visit(definition.type); |
149 InterfaceType type = visitor.registry.mapping.getType(definition.type); | 148 InterfaceType type = visitor.registry.mapping.getType(definition.type); |
150 Expect.equals(definition.type.typeArguments.slowLength(), | 149 Expect.equals( |
151 type.typeArguments.length); | 150 definition.type.typeArguments.slowLength(), type.typeArguments.length); |
152 int index = 0; | 151 int index = 0; |
153 for (DartType argument in type.typeArguments) { | 152 for (DartType argument in type.typeArguments) { |
154 Expect.equals(true, index < expectedElements.length); | 153 Expect.equals(true, index < expectedElements.length); |
155 Expect.equals(expectedElements[index], argument.element); | 154 Expect.equals(expectedElements[index], argument.element); |
156 index++; | 155 index++; |
157 } | 156 } |
158 Expect.equals(index, expectedElements.length); | 157 Expect.equals(index, expectedElements.length); |
159 } | 158 } |
160 | 159 |
161 return Future.wait([ | 160 return Future.wait([ |
162 MockCompiler.create((MockCompiler compiler) { | 161 MockCompiler.create((MockCompiler compiler) { |
163 ResolverVisitor visitor = compiler.resolverVisitor(); | 162 ResolverVisitor visitor = compiler.resolverVisitor(); |
164 compiler.parseScript('class Foo<T, U> {}'); | 163 compiler.parseScript('class Foo<T, U> {}'); |
165 ClassElement foo = compiler.mainApp.find('Foo'); | 164 ClassElement foo = compiler.mainApp.find('Foo'); |
166 matchResolvedTypes(visitor, 'Foo<int, String> x;', 'Foo', | 165 matchResolvedTypes(visitor, 'Foo<int, String> x;', 'Foo', |
167 [compiler.coreClasses.intClass, | 166 [compiler.coreClasses.intClass, compiler.coreClasses.stringClass]); |
168 compiler.coreClasses.stringClass]); | 167 matchResolvedTypes(visitor, 'Foo<Foo, Foo> x;', 'Foo', [foo, foo]); |
169 matchResolvedTypes(visitor, 'Foo<Foo, Foo> x;', 'Foo', | |
170 [foo, foo]); | |
171 }), | 168 }), |
172 | |
173 MockCompiler.create((MockCompiler compiler) { | 169 MockCompiler.create((MockCompiler compiler) { |
174 compiler.parseScript('class Foo<T, U> {}'); | 170 compiler.parseScript('class Foo<T, U> {}'); |
175 compiler.resolveStatement('Foo<notype, int> x;'); | 171 compiler.resolveStatement('Foo<notype, int> x;'); |
176 DiagnosticCollector collector = compiler.diagnosticCollector; | 172 DiagnosticCollector collector = compiler.diagnosticCollector; |
177 Expect.equals(1, collector.warnings.length); | 173 Expect.equals(1, collector.warnings.length); |
178 Expect.equals(MessageKind.CANNOT_RESOLVE_TYPE, | 174 Expect.equals(MessageKind.CANNOT_RESOLVE_TYPE, |
179 collector.warnings.first.message.kind); | 175 collector.warnings.first.message.kind); |
180 Expect.equals(0, collector.errors.length); | 176 Expect.equals(0, collector.errors.length); |
181 }), | 177 }), |
182 | |
183 MockCompiler.create((MockCompiler compiler) { | 178 MockCompiler.create((MockCompiler compiler) { |
184 compiler.parseScript('class Foo<T, U> {}'); | 179 compiler.parseScript('class Foo<T, U> {}'); |
185 compiler.resolveStatement('var x = new Foo<notype, int>();'); | 180 compiler.resolveStatement('var x = new Foo<notype, int>();'); |
186 DiagnosticCollector collector = compiler.diagnosticCollector; | 181 DiagnosticCollector collector = compiler.diagnosticCollector; |
187 Expect.equals(1, collector.warnings.length); | 182 Expect.equals(1, collector.warnings.length); |
188 Expect.equals(0, collector.errors.length); | 183 Expect.equals(0, collector.errors.length); |
189 Expect.equals(MessageKind.CANNOT_RESOLVE_TYPE, | 184 Expect.equals(MessageKind.CANNOT_RESOLVE_TYPE, |
190 collector.warnings.first.message.kind); | 185 collector.warnings.first.message.kind); |
191 }), | 186 }), |
192 | |
193 MockCompiler.create((MockCompiler compiler) { | 187 MockCompiler.create((MockCompiler compiler) { |
194 compiler.parseScript('class Foo<T> {' | 188 compiler.parseScript('class Foo<T> {' |
195 ' Foo<T> t;' | 189 ' Foo<T> t;' |
196 ' foo(Foo<T> f) {}' | 190 ' foo(Foo<T> f) {}' |
197 ' bar() { g(Foo<T> f) {}; g(); }' | 191 ' bar() { g(Foo<T> f) {}; g(); }' |
198 '}'); | 192 '}'); |
199 ClassElement foo = compiler.mainApp.find('Foo'); | 193 ClassElement foo = compiler.mainApp.find('Foo'); |
200 foo.ensureResolved(compiler.resolution); | 194 foo.ensureResolved(compiler.resolution); |
201 MemberElement tMember = foo.lookupLocalMember('t'); | 195 MemberElement tMember = foo.lookupLocalMember('t'); |
202 tMember.computeType(compiler.resolution); | 196 tMember.computeType(compiler.resolution); |
203 MemberElement fooMember = foo.lookupLocalMember('foo'); | 197 MemberElement fooMember = foo.lookupLocalMember('foo'); |
204 fooMember.computeType(compiler.resolution); | 198 fooMember.computeType(compiler.resolution); |
205 compiler.resolver.resolve(foo.lookupLocalMember('bar')); | 199 compiler.resolver.resolve(foo.lookupLocalMember('bar')); |
206 DiagnosticCollector collector = compiler.diagnosticCollector; | 200 DiagnosticCollector collector = compiler.diagnosticCollector; |
207 Expect.equals(0, collector.warnings.length); | 201 Expect.equals(0, collector.warnings.length); |
208 Expect.equals(0, collector.errors.length); | 202 Expect.equals(0, collector.errors.length); |
(...skipping 10 matching lines...) Expand all Loading... |
219 | 213 |
220 ClassElement classB = compiler.mainApp.find("B"); | 214 ClassElement classB = compiler.mainApp.find("B"); |
221 FunctionElement fooB = classB.lookupLocalMember("foo"); | 215 FunctionElement fooB = classB.lookupLocalMember("foo"); |
222 ClassElement classA = compiler.mainApp.find("A"); | 216 ClassElement classA = compiler.mainApp.find("A"); |
223 FunctionElement fooA = classA.lookupLocalMember("foo"); | 217 FunctionElement fooA = classA.lookupLocalMember("foo"); |
224 | 218 |
225 ResolverVisitor visitor = new ResolverVisitor( | 219 ResolverVisitor visitor = new ResolverVisitor( |
226 compiler.resolution, | 220 compiler.resolution, |
227 fooB, | 221 fooB, |
228 new ResolutionRegistry( | 222 new ResolutionRegistry( |
229 compiler.backend, | 223 compiler.backend, new CollectingTreeElements(fooB)), |
230 new CollectingTreeElements(fooB)), | |
231 scope: new MockTypeVariablesScope(classB.buildScope())); | 224 scope: new MockTypeVariablesScope(classB.buildScope())); |
232 FunctionExpression node = | 225 FunctionExpression node = |
233 (fooB as FunctionElementX).parseNode(compiler.parsingContext); | 226 (fooB as FunctionElementX).parseNode(compiler.parsingContext); |
234 visitor.visit(node.body); | 227 visitor.visit(node.body); |
235 Map mapping = map(visitor); | 228 Map mapping = map(visitor); |
236 | 229 |
237 Send superCall = node.body.asReturn().expression; | 230 Send superCall = node.body.asReturn().expression; |
238 FunctionElement called = mapping[superCall]; | 231 FunctionElement called = mapping[superCall]; |
239 Expect.isNotNull(called); | 232 Expect.isNotNull(called); |
240 Expect.equals(fooA, called); | 233 Expect.equals(fooA, called); |
241 }); | 234 }); |
242 } | 235 } |
243 | 236 |
244 Future testSwitch() { | 237 Future testSwitch() { |
245 return MockCompiler.create((MockCompiler compiler) { | 238 return MockCompiler.create((MockCompiler compiler) { |
246 compiler.parseScript("class Foo { foo() {" | 239 compiler.parseScript("class Foo { foo() {" |
247 "switch (null) { case '': break; case 2: break; } } }"); | 240 "switch (null) { case '': break; case 2: break; } } }"); |
248 compiler.resolveStatement("Foo foo;"); | 241 compiler.resolveStatement("Foo foo;"); |
249 ClassElement fooElement = compiler.mainApp.find("Foo"); | 242 ClassElement fooElement = compiler.mainApp.find("Foo"); |
250 FunctionElement funElement = fooElement.lookupLocalMember("foo"); | 243 FunctionElement funElement = fooElement.lookupLocalMember("foo"); |
251 compiler.processQueue(compiler.enqueuer.resolution, funElement); | 244 compiler.processQueue(compiler.enqueuer.resolution, funElement); |
252 DiagnosticCollector collector = compiler.diagnosticCollector; | 245 DiagnosticCollector collector = compiler.diagnosticCollector; |
253 Expect.equals(0, collector.warnings.length); | 246 Expect.equals(0, collector.warnings.length); |
254 Expect.equals(1, collector.errors.length); | 247 Expect.equals(1, collector.errors.length); |
255 Expect.equals(MessageKind.SWITCH_CASE_TYPES_NOT_EQUAL, | 248 Expect.equals(MessageKind.SWITCH_CASE_TYPES_NOT_EQUAL, |
256 collector.errors.first.message.kind); | 249 collector.errors.first.message.kind); |
257 Expect.equals(2, collector.infos.length); | 250 Expect.equals(2, collector.infos.length); |
258 Expect.equals(MessageKind.SWITCH_CASE_TYPES_NOT_EQUAL_CASE, | 251 Expect.equals(MessageKind.SWITCH_CASE_TYPES_NOT_EQUAL_CASE, |
259 collector.infos.first.message.kind); | 252 collector.infos.first.message.kind); |
260 Expect.equals(MessageKind.SWITCH_CASE_TYPES_NOT_EQUAL_CASE, | 253 Expect.equals(MessageKind.SWITCH_CASE_TYPES_NOT_EQUAL_CASE, |
261 collector.infos.elementAt(1).message.kind); | 254 collector.infos.elementAt(1).message.kind); |
262 }); | 255 }); |
263 } | 256 } |
264 | 257 |
265 Future testThis() { | 258 Future testThis() { |
266 return Future.wait([ | 259 return Future.wait([ |
267 MockCompiler.create((MockCompiler compiler) { | 260 MockCompiler.create((MockCompiler compiler) { |
268 compiler.parseScript("class Foo { foo() { return this; } }"); | 261 compiler.parseScript("class Foo { foo() { return this; } }"); |
269 compiler.resolveStatement("Foo foo;"); | 262 compiler.resolveStatement("Foo foo;"); |
270 ClassElement fooElement = compiler.mainApp.find("Foo"); | 263 ClassElement fooElement = compiler.mainApp.find("Foo"); |
271 FunctionElement funElement = fooElement.lookupLocalMember("foo"); | 264 FunctionElement funElement = fooElement.lookupLocalMember("foo"); |
(...skipping 11 matching lines...) Expand all Loading... |
283 DiagnosticCollector collector = compiler.diagnosticCollector; | 276 DiagnosticCollector collector = compiler.diagnosticCollector; |
284 Expect.equals(0, mapping.length); | 277 Expect.equals(0, mapping.length); |
285 Expect.equals(0, collector.warnings.length); | 278 Expect.equals(0, collector.warnings.length); |
286 }), | 279 }), |
287 MockCompiler.create((MockCompiler compiler) { | 280 MockCompiler.create((MockCompiler compiler) { |
288 compiler.resolveStatement("main() { return this; }"); | 281 compiler.resolveStatement("main() { return this; }"); |
289 DiagnosticCollector collector = compiler.diagnosticCollector; | 282 DiagnosticCollector collector = compiler.diagnosticCollector; |
290 Expect.equals(0, collector.warnings.length); | 283 Expect.equals(0, collector.warnings.length); |
291 Expect.equals(1, collector.errors.length); | 284 Expect.equals(1, collector.errors.length); |
292 Expect.equals(MessageKind.NO_INSTANCE_AVAILABLE, | 285 Expect.equals(MessageKind.NO_INSTANCE_AVAILABLE, |
293 collector.errors.first.message.kind); | 286 collector.errors.first.message.kind); |
294 }), | 287 }), |
295 MockCompiler.create((MockCompiler compiler) { | 288 MockCompiler.create((MockCompiler compiler) { |
296 compiler.parseScript("class Foo { static foo() { return this; } }"); | 289 compiler.parseScript("class Foo { static foo() { return this; } }"); |
297 compiler.resolveStatement("Foo foo;"); | 290 compiler.resolveStatement("Foo foo;"); |
298 ClassElement fooElement = compiler.mainApp.find("Foo"); | 291 ClassElement fooElement = compiler.mainApp.find("Foo"); |
299 FunctionElement funElement = fooElement.lookupLocalMember("foo"); | 292 FunctionElement funElement = fooElement.lookupLocalMember("foo"); |
300 ResolverVisitor visitor = new ResolverVisitor( | 293 ResolverVisitor visitor = new ResolverVisitor( |
301 compiler.resolution, | 294 compiler.resolution, |
302 funElement, | 295 funElement, |
303 new ResolutionRegistry( | 296 new ResolutionRegistry( |
304 compiler.backend, new CollectingTreeElements(funElement)), | 297 compiler.backend, new CollectingTreeElements(funElement)), |
305 scope: new MockTypeVariablesScope(fooElement.buildScope())); | 298 scope: new MockTypeVariablesScope(fooElement.buildScope())); |
306 FunctionExpression function = | 299 FunctionExpression function = |
307 (funElement as FunctionElementX).parseNode(compiler.parsingContext); | 300 (funElement as FunctionElementX).parseNode(compiler.parsingContext); |
308 visitor.visit(function.body); | 301 visitor.visit(function.body); |
309 DiagnosticCollector collector = compiler.diagnosticCollector; | 302 DiagnosticCollector collector = compiler.diagnosticCollector; |
310 Expect.equals(0, collector.warnings.length); | 303 Expect.equals(0, collector.warnings.length); |
311 Expect.equals(1, collector.errors.length); | 304 Expect.equals(1, collector.errors.length); |
312 Expect.equals(MessageKind.NO_INSTANCE_AVAILABLE, | 305 Expect.equals(MessageKind.NO_INSTANCE_AVAILABLE, |
313 collector.errors.first.message.kind); | 306 collector.errors.first.message.kind); |
314 }), | 307 }), |
315 ]); | 308 ]); |
316 } | 309 } |
317 | 310 |
318 Future testLocalsOne() { | 311 Future testLocalsOne() { |
319 return Future.forEach([ | 312 return Future.forEach([ |
320 () => testLocals([["foo", false]]), | 313 () => testLocals([ |
321 () => testLocals([["foo", false], ["bar", false]]), | 314 ["foo", false] |
322 () => testLocals([["foo", false], ["bar", false], ["foobar", false]]), | 315 ]), |
323 | 316 () => testLocals([ |
324 () => testLocals([["foo", true]]), | 317 ["foo", false], |
325 () => testLocals([["foo", false], ["bar", true]]), | 318 ["bar", false] |
326 () => testLocals([["foo", true], ["bar", true]]), | 319 ]), |
327 | 320 () => testLocals([ |
328 () => testLocals([["foo", false], ["bar", false], ["foobar", true]]), | 321 ["foo", false], |
329 () => testLocals([["foo", false], ["bar", true], ["foobar", true]]), | 322 ["bar", false], |
330 () => testLocals([["foo", true], ["bar", true], ["foobar", true]]), | 323 ["foobar", false] |
331 | 324 ]), |
332 () => testLocals([["foo", false], ["foo", false]]) | 325 () => testLocals([ |
333 .then((MockCompiler compiler) { | 326 ["foo", true] |
334 DiagnosticCollector collector = compiler.diagnosticCollector; | 327 ]), |
335 Expect.equals(1, collector.errors.length); | 328 () => testLocals([ |
336 Expect.equals( | 329 ["foo", false], |
337 new Message( | 330 ["bar", true] |
338 MessageTemplate.TEMPLATES[MessageKind.DUPLICATE_DEFINITION], | 331 ]), |
339 {'name': 'foo'}, false), | 332 () => testLocals([ |
340 collector.errors.first.message); | 333 ["foo", true], |
341 })], (f) => f()); | 334 ["bar", true] |
| 335 ]), |
| 336 () => testLocals([ |
| 337 ["foo", false], |
| 338 ["bar", false], |
| 339 ["foobar", true] |
| 340 ]), |
| 341 () => testLocals([ |
| 342 ["foo", false], |
| 343 ["bar", true], |
| 344 ["foobar", true] |
| 345 ]), |
| 346 () => testLocals([ |
| 347 ["foo", true], |
| 348 ["bar", true], |
| 349 ["foobar", true] |
| 350 ]), |
| 351 () => testLocals([ |
| 352 ["foo", false], |
| 353 ["foo", false] |
| 354 ]).then((MockCompiler compiler) { |
| 355 DiagnosticCollector collector = compiler.diagnosticCollector; |
| 356 Expect.equals(1, collector.errors.length); |
| 357 Expect.equals( |
| 358 new Message( |
| 359 MessageTemplate.TEMPLATES[MessageKind.DUPLICATE_DEFINITION], |
| 360 {'name': 'foo'}, |
| 361 false), |
| 362 collector.errors.first.message); |
| 363 }) |
| 364 ], (f) => f()); |
342 } | 365 } |
343 | 366 |
344 | |
345 Future testLocalsTwo() { | 367 Future testLocalsTwo() { |
346 return MockCompiler.create((MockCompiler compiler) { | 368 return MockCompiler.create((MockCompiler compiler) { |
347 ResolverVisitor visitor = compiler.resolverVisitor(); | 369 ResolverVisitor visitor = compiler.resolverVisitor(); |
348 Node tree = parseStatement("if (true) { var a = 1; var b = 2; }"); | 370 Node tree = parseStatement("if (true) { var a = 1; var b = 2; }"); |
349 ResolutionResult result = visitor.visit(tree); | 371 ResolutionResult result = visitor.visit(tree); |
350 Expect.equals(const NoneResult(), result); | 372 Expect.equals(const NoneResult(), result); |
351 MethodScope scope = visitor.scope; | 373 MethodScope scope = visitor.scope; |
352 Expect.equals(0, scope.elements.length); | 374 Expect.equals(0, scope.elements.length); |
353 Expect.equals(2, map(visitor).length); | 375 Expect.equals(2, map(visitor).length); |
354 | 376 |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
393 ResolutionResult result = visitor.visit(tree); | 415 ResolutionResult result = visitor.visit(tree); |
394 Expect.equals(const NoneResult(), result); | 416 Expect.equals(const NoneResult(), result); |
395 MethodScope scope = visitor.scope; | 417 MethodScope scope = visitor.scope; |
396 Expect.equals(0, scope.elements.length); | 418 Expect.equals(0, scope.elements.length); |
397 Expect.equals(4, map(visitor).length); | 419 Expect.equals(4, map(visitor).length); |
398 | 420 |
399 Block thenPart = tree.thenPart; | 421 Block thenPart = tree.thenPart; |
400 List statements1 = thenPart.statements.nodes.toList(); | 422 List statements1 = thenPart.statements.nodes.toList(); |
401 Node def1 = statements1[0].definitions.nodes.head; | 423 Node def1 = statements1[0].definitions.nodes.head; |
402 Node id1 = statements1[1].expression; | 424 Node id1 = statements1[1].expression; |
403 Expect.equals(visitor.registry.mapping[def1], | 425 Expect.equals( |
404 visitor.registry.mapping[id1]); | 426 visitor.registry.mapping[def1], visitor.registry.mapping[id1]); |
405 | 427 |
406 Block elsePart = tree.elsePart; | 428 Block elsePart = tree.elsePart; |
407 List statements2 = elsePart.statements.nodes.toList(); | 429 List statements2 = elsePart.statements.nodes.toList(); |
408 Node def2 = statements2[0].definitions.nodes.head; | 430 Node def2 = statements2[0].definitions.nodes.head; |
409 Node id2 = statements2[1].expression; | 431 Node id2 = statements2[1].expression; |
410 Expect.equals(visitor.registry.mapping[def2], | 432 Expect.equals( |
411 visitor.registry.mapping[id2]); | 433 visitor.registry.mapping[def2], visitor.registry.mapping[id2]); |
412 | 434 |
413 Expect.notEquals(visitor.registry.mapping[def1], | 435 Expect.notEquals( |
414 visitor.registry.mapping[def2]); | 436 visitor.registry.mapping[def1], visitor.registry.mapping[def2]); |
415 Expect.notEquals(visitor.registry.mapping[id1], | 437 Expect.notEquals( |
416 visitor.registry.mapping[id2]); | 438 visitor.registry.mapping[id1], visitor.registry.mapping[id2]); |
417 }); | 439 }); |
418 } | 440 } |
419 | 441 |
420 Future testParametersOne() { | 442 Future testParametersOne() { |
421 return MockCompiler.create((MockCompiler compiler) { | 443 return MockCompiler.create((MockCompiler compiler) { |
422 ResolverVisitor visitor = compiler.resolverVisitor(); | 444 ResolverVisitor visitor = compiler.resolverVisitor(); |
423 FunctionExpression tree = | 445 FunctionExpression tree = |
424 parseFunction("void foo(int a) { return a; }", compiler); | 446 parseFunction("void foo(int a) { return a; }", compiler); |
425 visitor.visit(tree); | 447 visitor.visit(tree); |
426 | 448 |
427 // Check that an element has been created for the parameter. | 449 // Check that an element has been created for the parameter. |
428 VariableDefinitions vardef = tree.parameters.nodes.head; | 450 VariableDefinitions vardef = tree.parameters.nodes.head; |
429 Node param = vardef.definitions.nodes.head; | 451 Node param = vardef.definitions.nodes.head; |
430 Expect.equals(ElementKind.PARAMETER, visitor.registry.mapping[param].kind); | 452 Expect.equals(ElementKind.PARAMETER, visitor.registry.mapping[param].kind); |
431 | 453 |
432 // Check that 'a' in 'return a' is resolved to the parameter. | 454 // Check that 'a' in 'return a' is resolved to the parameter. |
433 Block body = tree.body; | 455 Block body = tree.body; |
434 Return ret = body.statements.nodes.head; | 456 Return ret = body.statements.nodes.head; |
435 Send use = ret.expression; | 457 Send use = ret.expression; |
436 Expect.equals(ElementKind.PARAMETER, visitor.registry.mapping[use].kind); | 458 Expect.equals(ElementKind.PARAMETER, visitor.registry.mapping[use].kind); |
437 Expect.equals(visitor.registry.mapping[param], | 459 Expect.equals( |
438 visitor.registry.mapping[use]); | 460 visitor.registry.mapping[param], visitor.registry.mapping[use]); |
439 }); | 461 }); |
440 } | 462 } |
441 | 463 |
442 Future testFor() { | 464 Future testFor() { |
443 return MockCompiler.create((MockCompiler compiler) { | 465 return MockCompiler.create((MockCompiler compiler) { |
444 ResolverVisitor visitor = compiler.resolverVisitor(); | 466 ResolverVisitor visitor = compiler.resolverVisitor(); |
445 For tree = parseStatement("for (int i = 0; i < 10; i = i + 1) { i = 5; }"); | 467 For tree = parseStatement("for (int i = 0; i < 10; i = i + 1) { i = 5; }"); |
446 visitor.visit(tree); | 468 visitor.visit(tree); |
447 | 469 |
448 MethodScope scope = visitor.scope; | 470 MethodScope scope = visitor.scope; |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
481 }); | 503 }); |
482 } | 504 } |
483 | 505 |
484 checkIdentifier(Element expected, Node node, Element actual) { | 506 checkIdentifier(Element expected, Node node, Element actual) { |
485 Expect.isTrue(node is Identifier, node.toDebugString()); | 507 Expect.isTrue(node is Identifier, node.toDebugString()); |
486 Expect.equals(expected, actual); | 508 Expect.equals(expected, actual); |
487 } | 509 } |
488 | 510 |
489 checkSend(Element expected, Node node, Element actual) { | 511 checkSend(Element expected, Node node, Element actual) { |
490 Expect.isTrue(node is Send, node.toDebugString()); | 512 Expect.isTrue(node is Send, node.toDebugString()); |
491 Expect.isTrue(node is !SendSet, node.toDebugString()); | 513 Expect.isTrue(node is! SendSet, node.toDebugString()); |
492 Expect.equals(expected, actual); | 514 Expect.equals(expected, actual); |
493 } | 515 } |
494 | 516 |
495 checkSendSet(Element expected, Node node, Element actual) { | 517 checkSendSet(Element expected, Node node, Element actual) { |
496 Expect.isTrue(node is SendSet, node.toDebugString()); | 518 Expect.isTrue(node is SendSet, node.toDebugString()); |
497 Expect.equals(expected, actual); | 519 Expect.equals(expected, actual); |
498 } | 520 } |
499 | 521 |
500 Future testTypeAnnotation() { | 522 Future testTypeAnnotation() { |
501 return MockCompiler.create((MockCompiler compiler) { | 523 return MockCompiler.create((MockCompiler compiler) { |
502 String statement = "Foo bar;"; | 524 String statement = "Foo bar;"; |
503 | 525 |
504 // Test that we get a warning when Foo is not defined. | 526 // Test that we get a warning when Foo is not defined. |
505 Map mapping = compiler.resolveStatement(statement).map; | 527 Map mapping = compiler.resolveStatement(statement).map; |
506 | 528 |
507 Expect.equals(1, mapping.length); // Only [bar] has an element. | 529 Expect.equals(1, mapping.length); // Only [bar] has an element. |
508 DiagnosticCollector collector = compiler.diagnosticCollector; | 530 DiagnosticCollector collector = compiler.diagnosticCollector; |
509 Expect.equals(1, collector.warnings.length); | 531 Expect.equals(1, collector.warnings.length); |
510 | 532 |
511 Expect.equals( | 533 Expect.equals( |
512 new Message( | 534 new Message(MessageTemplate.TEMPLATES[MessageKind.CANNOT_RESOLVE_TYPE], |
513 MessageTemplate.TEMPLATES[MessageKind.CANNOT_RESOLVE_TYPE], | |
514 {'typeName': 'Foo'}, false), | 535 {'typeName': 'Foo'}, false), |
515 collector.warnings.first.message); | 536 collector.warnings.first.message); |
516 collector.clear(); | 537 collector.clear(); |
517 | 538 |
518 // Test that there is no warning after defining Foo. | 539 // Test that there is no warning after defining Foo. |
519 compiler.parseScript("class Foo {}"); | 540 compiler.parseScript("class Foo {}"); |
520 mapping = compiler.resolveStatement(statement).map; | 541 mapping = compiler.resolveStatement(statement).map; |
521 Expect.equals(1, mapping.length); | 542 Expect.equals(1, mapping.length); |
522 Expect.equals(0, collector.warnings.length); | 543 Expect.equals(0, collector.warnings.length); |
523 | 544 |
524 // Test that 'var' does not create a warning. | 545 // Test that 'var' does not create a warning. |
525 mapping = compiler.resolveStatement("var foo;").map; | 546 mapping = compiler.resolveStatement("var foo;").map; |
526 Expect.equals(1, mapping.length); | 547 Expect.equals(1, mapping.length); |
527 Expect.equals(0, collector.warnings.length); | 548 Expect.equals(0, collector.warnings.length); |
528 }); | 549 }); |
529 } | 550 } |
530 | 551 |
531 Future testSuperclass() { | 552 Future testSuperclass() { |
532 return Future.wait([ | 553 return Future.wait([ |
533 MockCompiler.create((MockCompiler compiler) { | 554 MockCompiler.create((MockCompiler compiler) { |
534 compiler.parseScript("class Foo extends Bar {}"); | 555 compiler.parseScript("class Foo extends Bar {}"); |
535 compiler.resolveStatement("Foo bar;"); | 556 compiler.resolveStatement("Foo bar;"); |
536 DiagnosticCollector collector = compiler.diagnosticCollector; | 557 DiagnosticCollector collector = compiler.diagnosticCollector; |
537 Expect.equals(1, collector.errors.length); | 558 Expect.equals(1, collector.errors.length); |
538 var cannotResolveBar = new Message( | 559 var cannotResolveBar = new Message( |
539 MessageTemplate.TEMPLATES[MessageKind.CANNOT_EXTEND_MALFORMED], | 560 MessageTemplate.TEMPLATES[MessageKind.CANNOT_EXTEND_MALFORMED], |
540 {'className': 'Foo', 'malformedType': 'Bar'}, false); | 561 {'className': 'Foo', 'malformedType': 'Bar'}, |
| 562 false); |
541 Expect.equals(cannotResolveBar, collector.errors.first.message); | 563 Expect.equals(cannotResolveBar, collector.errors.first.message); |
542 collector.clear(); | 564 collector.clear(); |
543 }), | 565 }), |
544 MockCompiler.create((MockCompiler compiler) { | 566 MockCompiler.create((MockCompiler compiler) { |
545 compiler.parseScript("class Foo extends Bar {}"); | 567 compiler.parseScript("class Foo extends Bar {}"); |
546 compiler.parseScript("class Bar {}"); | 568 compiler.parseScript("class Bar {}"); |
547 Map mapping = compiler.resolveStatement("Foo bar;").map; | 569 Map mapping = compiler.resolveStatement("Foo bar;").map; |
548 Expect.equals(1, mapping.length); | 570 Expect.equals(1, mapping.length); |
549 | 571 |
550 ClassElement fooElement = compiler.mainApp.find('Foo'); | 572 ClassElement fooElement = compiler.mainApp.find('Foo'); |
551 ClassElement barElement = compiler.mainApp.find('Bar'); | 573 ClassElement barElement = compiler.mainApp.find('Bar'); |
552 Expect.equals(barElement.computeType(compiler.resolution), | 574 Expect.equals( |
553 fooElement.supertype); | 575 barElement.computeType(compiler.resolution), fooElement.supertype); |
554 Expect.isTrue(fooElement.interfaces.isEmpty); | 576 Expect.isTrue(fooElement.interfaces.isEmpty); |
555 Expect.isTrue(barElement.interfaces.isEmpty); | 577 Expect.isTrue(barElement.interfaces.isEmpty); |
556 }), | 578 }), |
557 ]); | 579 ]); |
558 } | 580 } |
559 | 581 |
560 Future testVarSuperclass() { | 582 Future testVarSuperclass() { |
561 return MockCompiler.create((MockCompiler compiler) { | 583 return MockCompiler.create((MockCompiler compiler) { |
562 compiler.parseScript("class Foo extends var {}"); | 584 compiler.parseScript("class Foo extends var {}"); |
563 compiler.resolveStatement("Foo bar;"); | 585 compiler.resolveStatement("Foo bar;"); |
564 DiagnosticCollector collector = compiler.diagnosticCollector; | 586 DiagnosticCollector collector = compiler.diagnosticCollector; |
565 Expect.equals(1, collector.errors.length); | 587 Expect.equals(1, collector.errors.length); |
566 Expect.equals( | 588 Expect.equals( |
567 new Message( | 589 new Message(MessageTemplate.TEMPLATES[MessageKind.CANNOT_RESOLVE_TYPE], |
568 MessageTemplate.TEMPLATES[MessageKind.CANNOT_RESOLVE_TYPE], | |
569 {'typeName': 'var'}, false), | 590 {'typeName': 'var'}, false), |
570 collector.errors.first.message); | 591 collector.errors.first.message); |
571 collector.clear(); | 592 collector.clear(); |
572 }); | 593 }); |
573 } | 594 } |
574 | 595 |
575 Future testOneInterface() { | 596 Future testOneInterface() { |
576 return MockCompiler.create((MockCompiler compiler) { | 597 return MockCompiler.create((MockCompiler compiler) { |
577 compiler.parseScript("class Foo implements Bar {}"); | 598 compiler.parseScript("class Foo implements Bar {}"); |
578 compiler.resolveStatement("Foo bar;"); | 599 compiler.resolveStatement("Foo bar;"); |
579 DiagnosticCollector collector = compiler.diagnosticCollector; | 600 DiagnosticCollector collector = compiler.diagnosticCollector; |
580 Expect.equals(1, collector.errors.length); | 601 Expect.equals(1, collector.errors.length); |
581 Expect.equals( | 602 Expect.equals( |
582 new Message( | 603 new Message(MessageTemplate.TEMPLATES[MessageKind.CANNOT_RESOLVE_TYPE], |
583 MessageTemplate.TEMPLATES[MessageKind.CANNOT_RESOLVE_TYPE], | |
584 {'typeName': 'bar'}, false), | 604 {'typeName': 'bar'}, false), |
585 collector.errors.first.message); | 605 collector.errors.first.message); |
586 collector.clear(); | 606 collector.clear(); |
587 | 607 |
588 // Add the abstract class to the world and make sure everything is setup | 608 // Add the abstract class to the world and make sure everything is setup |
589 // correctly. | 609 // correctly. |
590 compiler.parseScript("abstract class Bar {}"); | 610 compiler.parseScript("abstract class Bar {}"); |
591 | 611 |
592 ResolverVisitor visitor = new ResolverVisitor( | 612 ResolverVisitor visitor = new ResolverVisitor( |
593 compiler.resolution, | 613 compiler.resolution, |
594 null, | 614 null, |
595 new ResolutionRegistry( | 615 new ResolutionRegistry( |
596 compiler.backend, | 616 compiler.backend, new CollectingTreeElements(null))); |
597 new CollectingTreeElements(null))); | |
598 compiler.resolveStatement("Foo bar;"); | 617 compiler.resolveStatement("Foo bar;"); |
599 | 618 |
600 ClassElement fooElement = compiler.mainApp.find('Foo'); | 619 ClassElement fooElement = compiler.mainApp.find('Foo'); |
601 ClassElement barElement = compiler.mainApp.find('Bar'); | 620 ClassElement barElement = compiler.mainApp.find('Bar'); |
602 | 621 |
603 Expect.equals(null, barElement.supertype); | 622 Expect.equals(null, barElement.supertype); |
604 Expect.isTrue(barElement.interfaces.isEmpty); | 623 Expect.isTrue(barElement.interfaces.isEmpty); |
605 | 624 |
606 Expect.equals(barElement.computeType(compiler.resolution), | 625 Expect.equals(barElement.computeType(compiler.resolution), |
607 fooElement.interfaces.head); | 626 fooElement.interfaces.head); |
608 Expect.equals(1, length(fooElement.interfaces)); | 627 Expect.equals(1, length(fooElement.interfaces)); |
609 }); | 628 }); |
610 } | 629 } |
611 | 630 |
612 Future testTwoInterfaces() { | 631 Future testTwoInterfaces() { |
613 return MockCompiler.create((MockCompiler compiler) { | 632 return MockCompiler.create((MockCompiler compiler) { |
614 compiler.parseScript( | 633 compiler.parseScript("""abstract class I1 {} |
615 """abstract class I1 {} | |
616 abstract class I2 {} | 634 abstract class I2 {} |
617 class C implements I1, I2 {}"""); | 635 class C implements I1, I2 {}"""); |
618 compiler.resolveStatement("Foo bar;"); | 636 compiler.resolveStatement("Foo bar;"); |
619 | 637 |
620 ClassElement c = compiler.mainApp.find('C'); | 638 ClassElement c = compiler.mainApp.find('C'); |
621 ClassElement i1 = compiler.mainApp.find('I1'); | 639 ClassElement i1 = compiler.mainApp.find('I1'); |
622 ClassElement i2 = compiler.mainApp.find('I2'); | 640 ClassElement i2 = compiler.mainApp.find('I2'); |
623 | 641 |
624 Expect.equals(2, length(c.interfaces)); | 642 Expect.equals(2, length(c.interfaces)); |
625 Expect.equals(i1.computeType(compiler.resolution), at(c.interfaces, 0)); | 643 Expect.equals(i1.computeType(compiler.resolution), at(c.interfaces, 0)); |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
688 VariableDefinitions bNode = | 706 VariableDefinitions bNode = |
689 bElement.variables.parseNode(bElement, compiler.parsingContext); | 707 bElement.variables.parseNode(bElement, compiler.parsingContext); |
690 VariableDefinitions cNode = | 708 VariableDefinitions cNode = |
691 cElement.variables.parseNode(cElement, compiler.parsingContext); | 709 cElement.variables.parseNode(cElement, compiler.parsingContext); |
692 Expect.equals(bNode, cNode); | 710 Expect.equals(bNode, cNode); |
693 Expect.isNull(bNode.type); | 711 Expect.isNull(bNode.type); |
694 Expect.isTrue(bNode.modifiers.isVar); | 712 Expect.isTrue(bNode.modifiers.isVar); |
695 }); | 713 }); |
696 } | 714 } |
697 | 715 |
698 Future resolveConstructor( | 716 Future resolveConstructor(String script, String statement, String className, |
699 String script, String statement, String className, | |
700 String constructor, int expectedElementCount, | 717 String constructor, int expectedElementCount, |
701 {List expectedWarnings: const [], | 718 {List expectedWarnings: const [], |
702 List expectedErrors: const [], | 719 List expectedErrors: const [], |
703 List expectedInfos: const [], | 720 List expectedInfos: const [], |
704 Map<String, String> corelib}) { | 721 Map<String, String> corelib}) { |
705 MockCompiler compiler = new MockCompiler.internal(coreSource: corelib); | 722 MockCompiler compiler = new MockCompiler.internal(coreSource: corelib); |
706 return compiler.init().then((_) { | 723 return compiler.init().then((_) { |
707 compiler.parseScript(script); | 724 compiler.parseScript(script); |
708 compiler.resolveStatement(statement); | 725 compiler.resolveStatement(statement); |
709 ClassElement classElement = compiler.mainApp.find(className); | 726 ClassElement classElement = compiler.mainApp.find(className); |
710 Element element; | 727 Element element; |
711 element = classElement.lookupConstructor(constructor); | 728 element = classElement.lookupConstructor(constructor); |
712 FunctionExpression tree = (element as FunctionElement).node; | 729 FunctionExpression tree = (element as FunctionElement).node; |
713 ResolverVisitor visitor = new ResolverVisitor( | 730 ResolverVisitor visitor = new ResolverVisitor( |
714 compiler.resolution, | 731 compiler.resolution, |
715 element, | 732 element, |
716 new ResolutionRegistry( | 733 new ResolutionRegistry( |
717 compiler.backend, | 734 compiler.backend, new CollectingTreeElements(element)), |
718 new CollectingTreeElements(element)), | |
719 scope: classElement.buildScope()); | 735 scope: classElement.buildScope()); |
720 new InitializerResolver(visitor, element, tree).resolveInitializers(); | 736 new InitializerResolver(visitor, element, tree).resolveInitializers(); |
721 visitor.visit(tree.body); | 737 visitor.visit(tree.body); |
722 Expect.equals(expectedElementCount, map(visitor).length, | 738 Expect.equals(expectedElementCount, map(visitor).length, |
723 "${map(visitor).values} for '$statement' in context of `$script`"); | 739 "${map(visitor).values} for '$statement' in context of `$script`"); |
724 | 740 |
725 DiagnosticCollector collector = compiler.diagnosticCollector; | 741 DiagnosticCollector collector = compiler.diagnosticCollector; |
726 compareWarningKinds(script, expectedWarnings, collector.warnings); | 742 compareWarningKinds(script, expectedWarnings, collector.warnings); |
727 compareWarningKinds(script, expectedErrors, collector.errors); | 743 compareWarningKinds(script, expectedErrors, collector.errors); |
728 compareWarningKinds(script, expectedInfos, collector.infos); | 744 compareWarningKinds(script, expectedInfos, collector.infos); |
729 }); | 745 }); |
730 } | 746 } |
731 | 747 |
732 Future testClassHierarchy() { | 748 Future testClassHierarchy() { |
733 final MAIN = "main"; | 749 final MAIN = "main"; |
734 return Future.wait([ | 750 return Future.wait([ |
735 MockCompiler.create((MockCompiler compiler) { | 751 MockCompiler.create((MockCompiler compiler) { |
736 compiler.parseScript("""class A extends A {} | 752 compiler.parseScript("""class A extends A {} |
737 main() { return new A(); }"""); | 753 main() { return new A(); }"""); |
738 FunctionElement mainElement = compiler.mainApp.find(MAIN); | 754 FunctionElement mainElement = compiler.mainApp.find(MAIN); |
739 compiler.resolver.resolve(mainElement); | 755 compiler.resolver.resolve(mainElement); |
740 DiagnosticCollector collector = compiler.diagnosticCollector; | 756 DiagnosticCollector collector = compiler.diagnosticCollector; |
741 Expect.equals(0, collector.warnings.length); | 757 Expect.equals(0, collector.warnings.length); |
742 Expect.equals(1, collector.errors.length); | 758 Expect.equals(1, collector.errors.length); |
743 Expect.equals(MessageKind.CYCLIC_CLASS_HIERARCHY, | 759 Expect.equals(MessageKind.CYCLIC_CLASS_HIERARCHY, |
744 collector.errors.first.message.kind); | 760 collector.errors.first.message.kind); |
745 }), | 761 }), |
746 MockCompiler.create((MockCompiler compiler) { | 762 MockCompiler.create((MockCompiler compiler) { |
747 compiler.parseScript("""class A extends B {} | 763 compiler.parseScript("""class A extends B {} |
748 class B extends A {} | 764 class B extends A {} |
749 main() { return new A(); }"""); | 765 main() { return new A(); }"""); |
750 FunctionElement mainElement = compiler.mainApp.find(MAIN); | 766 FunctionElement mainElement = compiler.mainApp.find(MAIN); |
751 compiler.resolver.resolve(mainElement); | 767 compiler.resolver.resolve(mainElement); |
752 DiagnosticCollector collector = compiler.diagnosticCollector; | 768 DiagnosticCollector collector = compiler.diagnosticCollector; |
753 Expect.equals(0, collector.warnings.length); | 769 Expect.equals(0, collector.warnings.length); |
754 Expect.equals(2, collector.errors.length); | 770 Expect.equals(2, collector.errors.length); |
755 Expect.equals(MessageKind.CYCLIC_CLASS_HIERARCHY, | 771 Expect.equals(MessageKind.CYCLIC_CLASS_HIERARCHY, |
756 collector.errors.first.message.kind); | 772 collector.errors.first.message.kind); |
757 Expect.equals(MessageKind.CANNOT_FIND_UNNAMED_CONSTRUCTOR, | 773 Expect.equals(MessageKind.CANNOT_FIND_UNNAMED_CONSTRUCTOR, |
758 collector.errors.elementAt(1).message.kind); | 774 collector.errors.elementAt(1).message.kind); |
759 }), | 775 }), |
760 MockCompiler.create((MockCompiler compiler) { | 776 MockCompiler.create((MockCompiler compiler) { |
761 compiler.parseScript("""abstract class A extends B {} | 777 compiler.parseScript("""abstract class A extends B {} |
762 abstract class B extends A {} | 778 abstract class B extends A {} |
763 class C implements A {} | 779 class C implements A {} |
764 main() { return new C(); }"""); | 780 main() { return new C(); }"""); |
765 FunctionElement mainElement = compiler.mainApp.find(MAIN); | 781 FunctionElement mainElement = compiler.mainApp.find(MAIN); |
766 compiler.resolver.resolve(mainElement); | 782 compiler.resolver.resolve(mainElement); |
767 DiagnosticCollector collector = compiler.diagnosticCollector; | 783 DiagnosticCollector collector = compiler.diagnosticCollector; |
768 Expect.equals(0, collector.warnings.length); | 784 Expect.equals(0, collector.warnings.length); |
769 Expect.equals(1, collector.errors.length); | 785 Expect.equals(1, collector.errors.length); |
770 Expect.equals(MessageKind.CYCLIC_CLASS_HIERARCHY, | 786 Expect.equals(MessageKind.CYCLIC_CLASS_HIERARCHY, |
771 collector.errors.first.message.kind); | 787 collector.errors.first.message.kind); |
772 }), | 788 }), |
773 MockCompiler.create((MockCompiler compiler) { | 789 MockCompiler.create((MockCompiler compiler) { |
774 compiler.parseScript("""class A extends B {} | 790 compiler.parseScript("""class A extends B {} |
775 class B extends C {} | 791 class B extends C {} |
776 class C {} | 792 class C {} |
777 main() { return new A(); }"""); | 793 main() { return new A(); }"""); |
778 FunctionElement mainElement = compiler.mainApp.find(MAIN); | 794 FunctionElement mainElement = compiler.mainApp.find(MAIN); |
779 compiler.resolver.resolve(mainElement); | 795 compiler.resolver.resolve(mainElement); |
780 DiagnosticCollector collector = compiler.diagnosticCollector; | 796 DiagnosticCollector collector = compiler.diagnosticCollector; |
781 Expect.equals(0, collector.warnings.length); | 797 Expect.equals(0, collector.warnings.length); |
782 Expect.equals(0, collector.errors.length); | 798 Expect.equals(0, collector.errors.length); |
783 ClassElement aElement = compiler.mainApp.find("A"); | 799 ClassElement aElement = compiler.mainApp.find("A"); |
784 Link<DartType> supertypes = aElement.allSupertypes; | 800 Link<DartType> supertypes = aElement.allSupertypes; |
785 Expect.equals(<String>['B', 'C', 'Object'].toString(), | 801 Expect.equals(<String>['B', 'C', 'Object'].toString(), |
786 asSortedStrings(supertypes).toString()); | 802 asSortedStrings(supertypes).toString()); |
787 }), | 803 }), |
788 MockCompiler.create((MockCompiler compiler) { | 804 MockCompiler.create((MockCompiler compiler) { |
789 compiler.parseScript("""class A<T> {} | 805 compiler.parseScript("""class A<T> {} |
790 class B<Z,W> extends A<int> | 806 class B<Z,W> extends A<int> |
791 implements I<Z,List<W>> {} | 807 implements I<Z,List<W>> {} |
792 class I<X,Y> {} | 808 class I<X,Y> {} |
793 class C extends B<bool,String> {} | 809 class C extends B<bool,String> {} |
794 main() { return new C(); }"""); | 810 main() { return new C(); }"""); |
795 FunctionElement mainElement = compiler.mainApp.find(MAIN); | 811 FunctionElement mainElement = compiler.mainApp.find(MAIN); |
796 compiler.resolver.resolve(mainElement); | 812 compiler.resolver.resolve(mainElement); |
797 DiagnosticCollector collector = compiler.diagnosticCollector; | 813 DiagnosticCollector collector = compiler.diagnosticCollector; |
798 Expect.equals(0, collector.warnings.length); | 814 Expect.equals(0, collector.warnings.length); |
799 Expect.equals(0, collector.errors.length); | 815 Expect.equals(0, collector.errors.length); |
800 ClassElement aElement = compiler.mainApp.find("C"); | 816 ClassElement aElement = compiler.mainApp.find("C"); |
801 Link<DartType> supertypes = aElement.allSupertypes; | 817 Link<DartType> supertypes = aElement.allSupertypes; |
802 // Object is once per inheritance path, that is from both A and I. | 818 // Object is once per inheritance path, that is from both A and I. |
803 Expect.equals(<String>['A<int>', 'B<bool, String>', | 819 Expect.equals( |
804 'I<bool, List<String>>', 'Object'].toString(), | 820 <String>[ |
805 asSortedStrings(supertypes).toString()); | 821 'A<int>', |
| 822 'B<bool, String>', |
| 823 'I<bool, List<String>>', |
| 824 'Object' |
| 825 ].toString(), |
| 826 asSortedStrings(supertypes).toString()); |
806 }), | 827 }), |
807 MockCompiler.create((MockCompiler compiler) { | 828 MockCompiler.create((MockCompiler compiler) { |
808 compiler.parseScript("""class A<T> {} | 829 compiler.parseScript("""class A<T> {} |
809 class D extends A<E> {} | 830 class D extends A<E> {} |
810 class E extends D {} | 831 class E extends D {} |
811 main() { return new E(); }"""); | 832 main() { return new E(); }"""); |
812 FunctionElement mainElement = compiler.mainApp.find(MAIN); | 833 FunctionElement mainElement = compiler.mainApp.find(MAIN); |
813 compiler.resolver.resolve(mainElement); | 834 compiler.resolver.resolve(mainElement); |
814 DiagnosticCollector collector = compiler.diagnosticCollector; | 835 DiagnosticCollector collector = compiler.diagnosticCollector; |
815 Expect.equals(0, collector.warnings.length); | 836 Expect.equals(0, collector.warnings.length); |
816 Expect.equals(0, collector.errors.length); | 837 Expect.equals(0, collector.errors.length); |
817 ClassElement aElement = compiler.mainApp.find("E"); | 838 ClassElement aElement = compiler.mainApp.find("E"); |
818 Link<DartType> supertypes = aElement.allSupertypes; | 839 Link<DartType> supertypes = aElement.allSupertypes; |
819 Expect.equals(<String>['A<E>', 'D', 'Object'].toString(), | 840 Expect.equals(<String>['A<E>', 'D', 'Object'].toString(), |
820 asSortedStrings(supertypes).toString()); | 841 asSortedStrings(supertypes).toString()); |
821 }), | 842 }), |
822 MockCompiler.create((MockCompiler compiler) { | 843 MockCompiler.create((MockCompiler compiler) { |
823 compiler.parseScript("""class A<T> {} | 844 compiler.parseScript("""class A<T> {} |
824 class D extends A<int> implements A<double> {} | 845 class D extends A<int> implements A<double> {} |
825 main() { return new D(); }"""); | 846 main() { return new D(); }"""); |
826 FunctionElement mainElement = compiler.mainApp.find(MAIN); | 847 FunctionElement mainElement = compiler.mainApp.find(MAIN); |
827 compiler.resolver.resolve(mainElement); | 848 compiler.resolver.resolve(mainElement); |
828 DiagnosticCollector collector = compiler.diagnosticCollector; | 849 DiagnosticCollector collector = compiler.diagnosticCollector; |
829 Expect.equals(0, collector.warnings.length); | 850 Expect.equals(0, collector.warnings.length); |
830 Expect.equals(1, collector.errors.length); | 851 Expect.equals(1, collector.errors.length); |
831 Expect.equals(MessageKind.MULTI_INHERITANCE, | 852 Expect.equals( |
832 collector.errors.first.message.kind); | 853 MessageKind.MULTI_INHERITANCE, collector.errors.first.message.kind); |
833 Expect.equals(0, collector.crashes.length); | 854 Expect.equals(0, collector.crashes.length); |
834 }), | 855 }), |
835 ]); | 856 ]); |
836 } | 857 } |
837 | 858 |
838 Future testEnumDeclaration() { | 859 Future testEnumDeclaration() { |
839 final MAIN = "main"; | 860 final MAIN = "main"; |
840 return Future.wait([ | 861 return Future.wait([ |
841 MockCompiler.create((MockCompiler compiler) { | 862 MockCompiler.create((MockCompiler compiler) { |
842 compiler.parseScript("""enum Enum {} | 863 compiler.parseScript("""enum Enum {} |
843 main() { Enum e; }"""); | 864 main() { Enum e; }"""); |
844 FunctionElement mainElement = compiler.mainApp.find(MAIN); | 865 FunctionElement mainElement = compiler.mainApp.find(MAIN); |
845 compiler.resolver.resolve(mainElement); | 866 compiler.resolver.resolve(mainElement); |
846 DiagnosticCollector collector = compiler.diagnosticCollector; | 867 DiagnosticCollector collector = compiler.diagnosticCollector; |
847 Expect.equals(0, collector.warnings.length, | 868 Expect.equals(0, collector.warnings.length, |
848 'Unexpected warnings: ${collector.warnings}'); | 869 'Unexpected warnings: ${collector.warnings}'); |
849 Expect.equals(1, collector.errors.length, | 870 Expect.equals( |
850 'Unexpected errors: ${collector.errors}'); | 871 1, collector.errors.length, 'Unexpected errors: ${collector.errors}'); |
851 }), | 872 }), |
852 | |
853 MockCompiler.create((MockCompiler compiler) { | 873 MockCompiler.create((MockCompiler compiler) { |
854 compiler.parseScript("""enum Enum { A } | 874 compiler.parseScript("""enum Enum { A } |
855 main() { Enum e = Enum.A; }"""); | 875 main() { Enum e = Enum.A; }"""); |
856 FunctionElement mainElement = compiler.mainApp.find(MAIN); | 876 FunctionElement mainElement = compiler.mainApp.find(MAIN); |
857 compiler.resolver.resolve(mainElement); | 877 compiler.resolver.resolve(mainElement); |
858 DiagnosticCollector collector = compiler.diagnosticCollector; | 878 DiagnosticCollector collector = compiler.diagnosticCollector; |
859 Expect.equals(0, collector.warnings.length, | 879 Expect.equals(0, collector.warnings.length, |
860 'Unexpected warnings: ${collector.warnings}'); | 880 'Unexpected warnings: ${collector.warnings}'); |
861 Expect.equals(0, collector.errors.length, | 881 Expect.equals( |
862 'Unexpected errors: ${collector.errors}'); | 882 0, collector.errors.length, 'Unexpected errors: ${collector.errors}'); |
863 }), | 883 }), |
864 | |
865 MockCompiler.create((MockCompiler compiler) { | 884 MockCompiler.create((MockCompiler compiler) { |
866 compiler.parseScript("""enum Enum { A } | 885 compiler.parseScript("""enum Enum { A } |
867 main() { Enum e = Enum.B; }"""); | 886 main() { Enum e = Enum.B; }"""); |
868 FunctionElement mainElement = compiler.mainApp.find(MAIN); | 887 FunctionElement mainElement = compiler.mainApp.find(MAIN); |
869 compiler.resolver.resolve(mainElement); | 888 compiler.resolver.resolve(mainElement); |
870 DiagnosticCollector collector = compiler.diagnosticCollector; | 889 DiagnosticCollector collector = compiler.diagnosticCollector; |
871 Expect.equals(1, collector.warnings.length, | 890 Expect.equals(1, collector.warnings.length, |
872 'Unexpected warnings: ${collector.warnings}'); | 891 'Unexpected warnings: ${collector.warnings}'); |
873 Expect.equals(MessageKind.UNDEFINED_GETTER, | 892 Expect.equals( |
874 collector.warnings.first.message.kind); | 893 MessageKind.UNDEFINED_GETTER, collector.warnings.first.message.kind); |
875 Expect.equals(0, collector.errors.length, | 894 Expect.equals( |
876 'Unexpected errors: ${collector.errors}'); | 895 0, collector.errors.length, 'Unexpected errors: ${collector.errors}'); |
877 }), | 896 }), |
878 | |
879 MockCompiler.create((MockCompiler compiler) { | 897 MockCompiler.create((MockCompiler compiler) { |
880 compiler.parseScript("""enum Enum { A } | 898 compiler.parseScript("""enum Enum { A } |
881 main() { List values = Enum.values; }"""); | 899 main() { List values = Enum.values; }"""); |
882 FunctionElement mainElement = compiler.mainApp.find(MAIN); | 900 FunctionElement mainElement = compiler.mainApp.find(MAIN); |
883 compiler.resolver.resolve(mainElement); | 901 compiler.resolver.resolve(mainElement); |
884 DiagnosticCollector collector = compiler.diagnosticCollector; | 902 DiagnosticCollector collector = compiler.diagnosticCollector; |
885 Expect.equals(0, collector.warnings.length, | 903 Expect.equals(0, collector.warnings.length, |
886 'Unexpected warnings: ${collector.warnings}'); | 904 'Unexpected warnings: ${collector.warnings}'); |
887 Expect.equals(0, collector.errors.length, | 905 Expect.equals( |
888 'Unexpected errors: ${collector.errors}'); | 906 0, collector.errors.length, 'Unexpected errors: ${collector.errors}'); |
889 }), | 907 }), |
890 | |
891 MockCompiler.create((MockCompiler compiler) { | 908 MockCompiler.create((MockCompiler compiler) { |
892 compiler.parseScript("""enum Enum { A } | 909 compiler.parseScript("""enum Enum { A } |
893 main() { new Enum(0, ''); }"""); | 910 main() { new Enum(0, ''); }"""); |
894 FunctionElement mainElement = compiler.mainApp.find(MAIN); | 911 FunctionElement mainElement = compiler.mainApp.find(MAIN); |
895 compiler.resolver.resolve(mainElement); | 912 compiler.resolver.resolve(mainElement); |
896 DiagnosticCollector collector = compiler.diagnosticCollector; | 913 DiagnosticCollector collector = compiler.diagnosticCollector; |
897 Expect.equals(0, collector.warnings.length, | 914 Expect.equals(0, collector.warnings.length, |
898 'Unexpected warnings: ${collector.warnings}'); | 915 'Unexpected warnings: ${collector.warnings}'); |
899 Expect.equals(1, collector.errors.length, | 916 Expect.equals( |
900 'Unexpected errors: ${collector.errors}'); | 917 1, collector.errors.length, 'Unexpected errors: ${collector.errors}'); |
901 Expect.equals(MessageKind.CANNOT_INSTANTIATE_ENUM, | 918 Expect.equals(MessageKind.CANNOT_INSTANTIATE_ENUM, |
902 collector.errors.first.message.kind); | 919 collector.errors.first.message.kind); |
903 }), | 920 }), |
904 | |
905 MockCompiler.create((MockCompiler compiler) { | 921 MockCompiler.create((MockCompiler compiler) { |
906 compiler.parseScript("""enum Enum { A } | 922 compiler.parseScript("""enum Enum { A } |
907 main() { const Enum(0, ''); }"""); | 923 main() { const Enum(0, ''); }"""); |
908 FunctionElement mainElement = compiler.mainApp.find(MAIN); | 924 FunctionElement mainElement = compiler.mainApp.find(MAIN); |
909 compiler.resolver.resolve(mainElement); | 925 compiler.resolver.resolve(mainElement); |
910 DiagnosticCollector collector = compiler.diagnosticCollector; | 926 DiagnosticCollector collector = compiler.diagnosticCollector; |
911 Expect.equals(0, collector.warnings.length, | 927 Expect.equals(0, collector.warnings.length, |
912 'Unexpected warnings: ${collector.warnings}'); | 928 'Unexpected warnings: ${collector.warnings}'); |
913 Expect.equals(1, collector.errors.length, | 929 Expect.equals( |
914 'Unexpected errors: ${collector.errors}'); | 930 1, collector.errors.length, 'Unexpected errors: ${collector.errors}'); |
915 Expect.equals(MessageKind.CANNOT_INSTANTIATE_ENUM, | 931 Expect.equals(MessageKind.CANNOT_INSTANTIATE_ENUM, |
916 collector.errors.first.message.kind); | 932 collector.errors.first.message.kind); |
917 }), | 933 }), |
918 ]); | 934 ]); |
919 } | 935 } |
920 | 936 |
921 Future testInitializers() { | 937 Future testInitializers() { |
922 return Future.forEach([ | 938 return Future.forEach([ |
923 () { | 939 () { |
924 String script = | 940 String script = """class A { |
925 """class A { | |
926 int foo; int bar; | 941 int foo; int bar; |
927 A() : this.foo = 1, bar = 2; | 942 A() : this.foo = 1, bar = 2; |
928 }"""; | 943 }"""; |
929 return resolveConstructor(script, "A a = new A();", "A", "", 2); | 944 return resolveConstructor(script, "A a = new A();", "A", "", 2); |
930 }, | 945 }, |
931 () { | 946 () { |
932 String script = | 947 String script = """class A { |
933 """class A { | |
934 int foo; A a; | 948 int foo; A a; |
935 A() : a.foo = 1; | 949 A() : a.foo = 1; |
936 }"""; | 950 }"""; |
937 return resolveConstructor(script, "A a = new A();", "A", "", 0, | 951 return resolveConstructor(script, "A a = new A();", "A", "", 0, |
938 expectedWarnings: [], | 952 expectedWarnings: [], |
939 expectedErrors: [MessageKind.INVALID_RECEIVER_IN_INITIALIZER]); | 953 expectedErrors: [MessageKind.INVALID_RECEIVER_IN_INITIALIZER]); |
940 }, | 954 }, |
941 () { | 955 () { |
942 String script = | 956 String script = """class A { |
943 """class A { | |
944 int foo; | 957 int foo; |
945 A() : this.foo = 1, this.foo = 2; | 958 A() : this.foo = 1, this.foo = 2; |
946 }"""; | 959 }"""; |
947 return resolveConstructor(script, "A a = new A();", "A", "", 2, | 960 return resolveConstructor(script, "A a = new A();", "A", "", 2, |
948 expectedInfos: [MessageKind.ALREADY_INITIALIZED], | 961 expectedInfos: [MessageKind.ALREADY_INITIALIZED], |
949 expectedErrors: [MessageKind.DUPLICATE_INITIALIZER]); | 962 expectedErrors: [MessageKind.DUPLICATE_INITIALIZER]); |
950 }, | 963 }, |
951 () { | 964 () { |
952 String script = | 965 String script = """class A { |
953 """class A { | |
954 A() : this.foo = 1; | 966 A() : this.foo = 1; |
955 }"""; | 967 }"""; |
956 return resolveConstructor(script, "A a = new A();", "A", "", 1, | 968 return resolveConstructor(script, "A a = new A();", "A", "", 1, |
957 expectedWarnings: [], | 969 expectedWarnings: [], expectedErrors: [MessageKind.CANNOT_RESOLVE]); |
958 expectedErrors: [MessageKind.CANNOT_RESOLVE]); | |
959 }, | 970 }, |
960 () { | 971 () { |
961 String script = | 972 String script = """class A { |
962 """class A { | |
963 int foo; | 973 int foo; |
964 int bar; | 974 int bar; |
965 A() : this.foo = bar; | 975 A() : this.foo = bar; |
966 }"""; | 976 }"""; |
967 return resolveConstructor(script, "A a = new A();", "A", "", 2, | 977 return resolveConstructor(script, "A a = new A();", "A", "", 2, |
968 expectedWarnings: [], | 978 expectedWarnings: [], |
969 expectedErrors: [MessageKind.NO_INSTANCE_AVAILABLE]); | 979 expectedErrors: [MessageKind.NO_INSTANCE_AVAILABLE]); |
970 }, | 980 }, |
971 () { | 981 () { |
972 String script = | 982 String script = """class A { |
973 """class A { | |
974 int foo() => 42; | 983 int foo() => 42; |
975 A() : foo(); | 984 A() : foo(); |
976 }"""; | 985 }"""; |
977 return resolveConstructor(script, "A a = new A();", "A", "", 0, | 986 return resolveConstructor(script, "A a = new A();", "A", "", 0, |
978 expectedWarnings: [], | 987 expectedWarnings: [], |
979 expectedErrors: [MessageKind.CONSTRUCTOR_CALL_EXPECTED]); | 988 expectedErrors: [MessageKind.CONSTRUCTOR_CALL_EXPECTED]); |
980 }, | 989 }, |
981 () { | 990 () { |
982 String script = | 991 String script = """class A { |
983 """class A { | |
984 int i; | 992 int i; |
985 A.a() : this.b(0); | 993 A.a() : this.b(0); |
986 A.b(int i); | 994 A.b(int i); |
987 }"""; | 995 }"""; |
988 return resolveConstructor(script, "A a = new A.a();", "A", "a", 1); | 996 return resolveConstructor(script, "A a = new A.a();", "A", "a", 1); |
989 }, | 997 }, |
990 () { | 998 () { |
991 String script = | 999 String script = """class A { |
992 """class A { | |
993 int i; | 1000 int i; |
994 A.a() : i = 42, this(0); | 1001 A.a() : i = 42, this(0); |
995 A(int i); | 1002 A(int i); |
996 }"""; | 1003 }"""; |
997 return resolveConstructor(script, "A a = new A.a();", "A", "a", 2, | 1004 return resolveConstructor(script, "A a = new A.a();", "A", "a", 2, |
998 expectedWarnings: [], | 1005 expectedWarnings: [], |
999 expectedErrors: | 1006 expectedErrors: [ |
1000 [MessageKind.REDIRECTING_CONSTRUCTOR_HAS_INITIALIZER]); | 1007 MessageKind.REDIRECTING_CONSTRUCTOR_HAS_INITIALIZER |
| 1008 ]); |
1001 }, | 1009 }, |
1002 () { | 1010 () { |
1003 String script = | 1011 String script = """class A { |
1004 """class A { | |
1005 int i; | 1012 int i; |
1006 A(i); | 1013 A(i); |
1007 } | 1014 } |
1008 class B extends A { | 1015 class B extends A { |
1009 B() : super(0); | 1016 B() : super(0); |
1010 }"""; | 1017 }"""; |
1011 return resolveConstructor(script, "B a = new B();", "B", "", 1); | 1018 return resolveConstructor(script, "B a = new B();", "B", "", 1); |
1012 }, | 1019 }, |
1013 () { | 1020 () { |
1014 String script = | 1021 String script = """class A { |
1015 """class A { | |
1016 int i; | 1022 int i; |
1017 A(i); | 1023 A(i); |
1018 } | 1024 } |
1019 class B extends A { | 1025 class B extends A { |
1020 B() : super(0), super(1); | 1026 B() : super(0), super(1); |
1021 }"""; | 1027 }"""; |
1022 return resolveConstructor(script, "B b = new B();", "B", "", 2, | 1028 return resolveConstructor(script, "B b = new B();", "B", "", 2, |
1023 expectedWarnings: [], | 1029 expectedWarnings: [], |
1024 expectedErrors: [MessageKind.DUPLICATE_SUPER_INITIALIZER]); | 1030 expectedErrors: [MessageKind.DUPLICATE_SUPER_INITIALIZER]); |
1025 }, | 1031 }, |
1026 () { | 1032 () { |
1027 String script = ""; | 1033 String script = ""; |
1028 final INVALID_OBJECT = | 1034 final INVALID_OBJECT = const { |
1029 const { 'Object': 'class Object { Object() : super(); }' }; | 1035 'Object': 'class Object { Object() : super(); }' |
1030 return resolveConstructor(script, | 1036 }; |
1031 "Object o = new Object();", "Object", "", 1, | 1037 return resolveConstructor( |
| 1038 script, "Object o = new Object();", "Object", "", 1, |
1032 expectedWarnings: [], | 1039 expectedWarnings: [], |
1033 expectedErrors: [MessageKind.SUPER_INITIALIZER_IN_OBJECT], | 1040 expectedErrors: [MessageKind.SUPER_INITIALIZER_IN_OBJECT], |
1034 corelib: INVALID_OBJECT); | 1041 corelib: INVALID_OBJECT); |
1035 }, | 1042 }, |
1036 ], (f) => f()); | 1043 ], (f) => f()); |
1037 } | 1044 } |
1038 | 1045 |
1039 Future testConstantExpressions() { | 1046 Future testConstantExpressions() { |
1040 const Map<String, List<String>> testedConstants = const { | 1047 const Map<String, List<String>> testedConstants = const { |
1041 'null': const ['null'], | 1048 'null': const ['null'], |
(...skipping 15 matching lines...) Expand all Loading... |
1057 r'"a${0}b${1}"': const ['"a"', '0', '"b"', '1', '""', r'"a${0}b${1}"'], | 1064 r'"a${0}b${1}"': const ['"a"', '0', '"b"', '1', '""', r'"a${0}b${1}"'], |
1058 'true || false': const ['true', 'false', 'true || false'], | 1065 'true || false': const ['true', 'false', 'true || false'], |
1059 'true && false': const ['true', 'false', 'true && false'], | 1066 'true && false': const ['true', 'false', 'true && false'], |
1060 '!true': const ['true', '!true'], | 1067 '!true': const ['true', '!true'], |
1061 'const []': const ['const []'], | 1068 'const []': const ['const []'], |
1062 'const <int>[]': const ['const <int>[]'], | 1069 'const <int>[]': const ['const <int>[]'], |
1063 'const [0, 1, 2]': const ['0', '1', '2', 'const [0, 1, 2]'], | 1070 'const [0, 1, 2]': const ['0', '1', '2', 'const [0, 1, 2]'], |
1064 'const <int>[0, 1, 2]': const ['0', '1', '2', 'const <int>[0, 1, 2]'], | 1071 'const <int>[0, 1, 2]': const ['0', '1', '2', 'const <int>[0, 1, 2]'], |
1065 'const {}': const ['const {}'], | 1072 'const {}': const ['const {}'], |
1066 'const <String, int>{}': const ['const <String, int>{}'], | 1073 'const <String, int>{}': const ['const <String, int>{}'], |
1067 'const {"a": 0, "b": 1, "c": 2}': | 1074 'const {"a": 0, "b": 1, "c": 2}': const [ |
1068 const ['"a"', '0', '"b"', '1', '"c"', '2', | 1075 '"a"', |
1069 'const {"a": 0, "b": 1, "c": 2}'], | 1076 '0', |
1070 'const <String, int>{"a": 0, "b": 1, "c": 2}': | 1077 '"b"', |
1071 const ['"a"', '0', '"b"', '1', '"c"', '2', | 1078 '1', |
1072 'const <String, int>{"a": 0, "b": 1, "c": 2}'], | 1079 '"c"', |
| 1080 '2', |
| 1081 'const {"a": 0, "b": 1, "c": 2}' |
| 1082 ], |
| 1083 'const <String, int>{"a": 0, "b": 1, "c": 2}': const [ |
| 1084 '"a"', |
| 1085 '0', |
| 1086 '"b"', |
| 1087 '1', |
| 1088 '"c"', |
| 1089 '2', |
| 1090 'const <String, int>{"a": 0, "b": 1, "c": 2}' |
| 1091 ], |
1073 }; | 1092 }; |
1074 return Future.forEach(testedConstants.keys, (String constant) { | 1093 return Future.forEach(testedConstants.keys, (String constant) { |
1075 return MockCompiler.create((MockCompiler compiler) { | 1094 return MockCompiler.create((MockCompiler compiler) { |
1076 CollectingTreeElements elements = | 1095 CollectingTreeElements elements = |
1077 compiler.resolveStatement("main() => $constant;"); | 1096 compiler.resolveStatement("main() => $constant;"); |
1078 List<String> expectedConstants = testedConstants[constant]; | 1097 List<String> expectedConstants = testedConstants[constant]; |
1079 DiagnosticCollector collector = compiler.diagnosticCollector; | 1098 DiagnosticCollector collector = compiler.diagnosticCollector; |
1080 Expect.equals(0, collector.warnings.length); | 1099 Expect.equals(0, collector.warnings.length); |
1081 Expect.equals(0, collector.errors.length); | 1100 Expect.equals(0, collector.errors.length); |
1082 List<ConstantExpression> constants = elements.constants; | 1101 List<ConstantExpression> constants = elements.constants; |
1083 String constantsText = | 1102 String constantsText = |
1084 '[${constants.map((c) => c.toDartText()).join(', ')}]'; | 1103 '[${constants.map((c) => c.toDartText()).join(', ')}]'; |
1085 Expect.equals(expectedConstants.length, constants.length, | 1104 Expect.equals( |
| 1105 expectedConstants.length, |
| 1106 constants.length, |
1086 "Expected ${expectedConstants.length} constants for `${constant}` " | 1107 "Expected ${expectedConstants.length} constants for `${constant}` " |
1087 "found $constantsText."); | 1108 "found $constantsText."); |
1088 for (int index = 0; index < expectedConstants.length; index++) { | 1109 for (int index = 0; index < expectedConstants.length; index++) { |
1089 Expect.equals(expectedConstants[index], constants[index].toDartText(), | 1110 Expect.equals( |
| 1111 expectedConstants[index], |
| 1112 constants[index].toDartText(), |
1090 "Expected ${expectedConstants} for `$constant`, " | 1113 "Expected ${expectedConstants} for `$constant`, " |
1091 "found $constantsText."); | 1114 "found $constantsText."); |
1092 } | 1115 } |
1093 }); | 1116 }); |
1094 }); | 1117 }); |
1095 } | 1118 } |
1096 | 1119 |
1097 map(ResolverVisitor visitor) { | 1120 map(ResolverVisitor visitor) { |
1098 CollectingTreeElements elements = visitor.registry.mapping; | 1121 CollectingTreeElements elements = visitor.registry.mapping; |
1099 return elements.map; | 1122 return elements.map; |
(...skipping 14 matching lines...) Expand all Loading... |
1114 compiler.diagnosticHandler = createHandler(compiler, source); | 1137 compiler.diagnosticHandler = createHandler(compiler, source); |
1115 return compiler.run(uri).then((_) { | 1138 return compiler.run(uri).then((_) { |
1116 return compiler; | 1139 return compiler; |
1117 }); | 1140 }); |
1118 } | 1141 } |
1119 | 1142 |
1120 checkMemberResolved(compiler, className, memberName) { | 1143 checkMemberResolved(compiler, className, memberName) { |
1121 ClassElement cls = findElement(compiler, className); | 1144 ClassElement cls = findElement(compiler, className); |
1122 Element memberElement = cls.lookupLocalMember(memberName); | 1145 Element memberElement = cls.lookupLocalMember(memberName); |
1123 Expect.isNotNull(memberElement); | 1146 Expect.isNotNull(memberElement); |
1124 Expect.isTrue( | 1147 Expect.isTrue(compiler.enqueuer.resolution.hasBeenProcessed(memberElement)); |
1125 compiler.enqueuer.resolution.hasBeenProcessed(memberElement)); | |
1126 } | 1148 } |
1127 | 1149 |
1128 testToString() { | 1150 testToString() { |
1129 final script = r"class C { toString() => 'C'; } main() { '${new C()}'; }"; | 1151 final script = r"class C { toString() => 'C'; } main() { '${new C()}'; }"; |
1130 asyncTest(() => compileScript(script).then((compiler) { | 1152 asyncTest(() => compileScript(script).then((compiler) { |
1131 checkMemberResolved(compiler, 'C', 'toString'); | 1153 checkMemberResolved(compiler, 'C', 'toString'); |
1132 })); | 1154 })); |
1133 } | 1155 } |
1134 | 1156 |
1135 operatorName(op, isUnary) { | 1157 operatorName(op, isUnary) { |
1136 return Elements.constructOperatorName(op, isUnary); | 1158 return Elements.constructOperatorName(op, isUnary); |
1137 } | 1159 } |
1138 | 1160 |
1139 testIndexedOperator() { | 1161 testIndexedOperator() { |
1140 final script = r""" | 1162 final script = r""" |
1141 class C { | 1163 class C { |
1142 operator[](ix) => ix; | 1164 operator[](ix) => ix; |
1143 operator[]=(ix, v) {} | 1165 operator[]=(ix, v) {} |
1144 } | 1166 } |
1145 main() { var c = new C(); c[0]++; }"""; | 1167 main() { var c = new C(); c[0]++; }"""; |
1146 asyncTest(() => compileScript(script).then((compiler) { | 1168 asyncTest(() => compileScript(script).then((compiler) { |
1147 checkMemberResolved(compiler, 'C', operatorName('[]', false)); | 1169 checkMemberResolved(compiler, 'C', operatorName('[]', false)); |
1148 checkMemberResolved(compiler, 'C', operatorName('[]=', false)); | 1170 checkMemberResolved(compiler, 'C', operatorName('[]=', false)); |
1149 })); | 1171 })); |
1150 } | 1172 } |
1151 | 1173 |
1152 testIncrementsAndDecrements() { | 1174 testIncrementsAndDecrements() { |
1153 final script = r""" | 1175 final script = r""" |
1154 class A { operator+(o)=>null; } | 1176 class A { operator+(o)=>null; } |
1155 class B { operator+(o)=>null; } | 1177 class B { operator+(o)=>null; } |
1156 class C { operator-(o)=>null; } | 1178 class C { operator-(o)=>null; } |
1157 class D { operator-(o)=>null; } | 1179 class D { operator-(o)=>null; } |
1158 main() { | 1180 main() { |
1159 var a = new A(); | 1181 var a = new A(); |
1160 a++; | 1182 a++; |
1161 var b = new B(); | 1183 var b = new B(); |
1162 ++b; | 1184 ++b; |
1163 var c = new C(); | 1185 var c = new C(); |
1164 c--; | 1186 c--; |
1165 var d = new D(); | 1187 var d = new D(); |
1166 --d; | 1188 --d; |
1167 }"""; | 1189 }"""; |
1168 asyncTest(() => compileScript(script).then((compiler) { | 1190 asyncTest(() => compileScript(script).then((compiler) { |
1169 checkMemberResolved(compiler, 'A', operatorName('+', false)); | 1191 checkMemberResolved(compiler, 'A', operatorName('+', false)); |
1170 checkMemberResolved(compiler, 'B', operatorName('+', false)); | 1192 checkMemberResolved(compiler, 'B', operatorName('+', false)); |
1171 checkMemberResolved(compiler, 'C', operatorName('-', false)); | 1193 checkMemberResolved(compiler, 'C', operatorName('-', false)); |
1172 checkMemberResolved(compiler, 'D', operatorName('-', false)); | 1194 checkMemberResolved(compiler, 'D', operatorName('-', false)); |
1173 })); | 1195 })); |
1174 } | 1196 } |
1175 | 1197 |
1176 testOverrideHashCodeCheck() { | 1198 testOverrideHashCodeCheck() { |
1177 final script = r""" | 1199 final script = r""" |
1178 class A { | 1200 class A { |
1179 operator==(other) => true; | 1201 operator==(other) => true; |
1180 } | 1202 } |
1181 class B { | 1203 class B { |
1182 operator==(other) => true; | 1204 operator==(other) => true; |
1183 get hashCode => 0; | 1205 get hashCode => 0; |
1184 } | 1206 } |
1185 main() { | 1207 main() { |
1186 new A() == new B(); | 1208 new A() == new B(); |
1187 }"""; | 1209 }"""; |
1188 asyncTest(() => compileScript(script).then((compiler) { | 1210 asyncTest(() => compileScript(script).then((compiler) { |
1189 DiagnosticCollector collector = compiler.diagnosticCollector; | 1211 DiagnosticCollector collector = compiler.diagnosticCollector; |
1190 Expect.equals(0, collector.warnings.length); | 1212 Expect.equals(0, collector.warnings.length); |
1191 Expect.equals(0, collector.infos.length); | 1213 Expect.equals(0, collector.infos.length); |
1192 Expect.equals(1, collector.hints.length); | 1214 Expect.equals(1, collector.hints.length); |
1193 Expect.equals(MessageKind.OVERRIDE_EQUALS_NOT_HASH_CODE, | 1215 Expect.equals(MessageKind.OVERRIDE_EQUALS_NOT_HASH_CODE, |
1194 collector.hints.first.message.kind); | 1216 collector.hints.first.message.kind); |
1195 Expect.equals(0, collector.errors.length); | 1217 Expect.equals(0, collector.errors.length); |
1196 })); | 1218 })); |
1197 } | 1219 } |
1198 | 1220 |
1199 testConstConstructorAndNonFinalFields() { | 1221 testConstConstructorAndNonFinalFields() { |
1200 void expect(compiler, List errors, List infos) { | 1222 void expect(compiler, List errors, List infos) { |
1201 DiagnosticCollector collector = compiler.diagnosticCollector; | 1223 DiagnosticCollector collector = compiler.diagnosticCollector; |
1202 Expect.equals(errors.length, collector.errors.length); | 1224 Expect.equals(errors.length, collector.errors.length); |
1203 for (int i = 0 ; i < errors.length ; i++) { | 1225 for (int i = 0; i < errors.length; i++) { |
1204 Expect.equals(errors[i], collector.errors.elementAt(i).message.kind); | 1226 Expect.equals(errors[i], collector.errors.elementAt(i).message.kind); |
1205 } | 1227 } |
1206 Expect.equals(0, collector.warnings.length); | 1228 Expect.equals(0, collector.warnings.length); |
1207 Expect.equals(infos.length, collector.infos.length); | 1229 Expect.equals(infos.length, collector.infos.length); |
1208 for (int i = 0 ; i < infos.length ; i++) { | 1230 for (int i = 0; i < infos.length; i++) { |
1209 Expect.equals(infos[i], collector.infos.elementAt(i).message.kind); | 1231 Expect.equals(infos[i], collector.infos.elementAt(i).message.kind); |
1210 } | 1232 } |
1211 } | 1233 } |
1212 | 1234 |
1213 final script1 = r""" | 1235 final script1 = r""" |
1214 class A { | 1236 class A { |
1215 var a; | 1237 var a; |
1216 const A(this.a); | 1238 const A(this.a); |
1217 } | 1239 } |
1218 main() { | 1240 main() { |
1219 new A(0); | 1241 new A(0); |
1220 }"""; | 1242 }"""; |
1221 asyncTest(() => compileScript(script1).then((compiler) { | 1243 asyncTest(() => compileScript(script1).then((compiler) { |
1222 expect(compiler, | 1244 expect(compiler, [MessageKind.CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS], |
1223 [MessageKind.CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS], | 1245 [MessageKind.CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS_FIELD]); |
1224 [MessageKind.CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS_FIELD]); | 1246 })); |
1225 })); | |
1226 | 1247 |
1227 final script2 = r""" | 1248 final script2 = r""" |
1228 class A { | 1249 class A { |
1229 var a; | 1250 var a; |
1230 var b; | 1251 var b; |
1231 const A(this.a, this.b); | 1252 const A(this.a, this.b); |
1232 const A.named(this.a, this.b); | 1253 const A.named(this.a, this.b); |
1233 } | 1254 } |
1234 main() { | 1255 main() { |
1235 new A(0, 1); | 1256 new A(0, 1); |
1236 }"""; | 1257 }"""; |
1237 asyncTest(() => compileScript(script2).then((compiler) { | 1258 asyncTest(() => compileScript(script2).then((compiler) { |
1238 expect(compiler, | 1259 expect(compiler, [ |
1239 [MessageKind.CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS], | 1260 MessageKind.CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS |
1240 [MessageKind.CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS_CONSTRUCTOR, | 1261 ], [ |
1241 MessageKind.CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS_CONSTRUCTOR, | 1262 MessageKind.CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS_CONSTRUCTOR, |
1242 MessageKind.CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS_FIELD, | 1263 MessageKind.CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS_CONSTRUCTOR, |
1243 MessageKind.CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS_FIELD]); | 1264 MessageKind.CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS_FIELD, |
1244 })); | 1265 MessageKind.CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS_FIELD |
| 1266 ]); |
| 1267 })); |
1245 } | 1268 } |
1246 | 1269 |
1247 testCantAssignMethods() { | 1270 testCantAssignMethods() { |
1248 // Can't override local functions | 1271 // Can't override local functions |
1249 checkWarningOn(''' | 1272 checkWarningOn( |
| 1273 ''' |
1250 main() { | 1274 main() { |
1251 mname() { mname = 2; }; | 1275 mname() { mname = 2; }; |
1252 mname(); | 1276 mname(); |
1253 } | 1277 } |
1254 ''', [MessageKind.ASSIGNING_METHOD]); | 1278 ''', |
| 1279 [MessageKind.ASSIGNING_METHOD]); |
1255 | 1280 |
1256 checkWarningOn(''' | 1281 checkWarningOn( |
| 1282 ''' |
1257 main() { | 1283 main() { |
1258 mname() { }; | 1284 mname() { }; |
1259 mname = 3; | 1285 mname = 3; |
1260 } | 1286 } |
1261 ''', [MessageKind.ASSIGNING_METHOD]); | 1287 ''', |
| 1288 [MessageKind.ASSIGNING_METHOD]); |
1262 | 1289 |
1263 // Can't override top-level functions | 1290 // Can't override top-level functions |
1264 checkWarningOn(''' | 1291 checkWarningOn( |
| 1292 ''' |
1265 m() {} | 1293 m() {} |
1266 main() { m = 4; } | 1294 main() { m = 4; } |
1267 ''', [MessageKind.ASSIGNING_METHOD, | 1295 ''', |
1268 // TODO(johnniwinther): Avoid duplicate warnings. | 1296 [ |
1269 MessageKind.NOT_ASSIGNABLE]); | 1297 MessageKind.ASSIGNING_METHOD, |
| 1298 // TODO(johnniwinther): Avoid duplicate warnings. |
| 1299 MessageKind.NOT_ASSIGNABLE |
| 1300 ]); |
1270 | 1301 |
1271 // Can't override instance methods | 1302 // Can't override instance methods |
1272 checkWarningOn(''' | 1303 checkWarningOn( |
| 1304 ''' |
1273 main() { new B().bar(); } | 1305 main() { new B().bar(); } |
1274 class B { | 1306 class B { |
1275 mname() {} | 1307 mname() {} |
1276 bar() { | 1308 bar() { |
1277 mname = () => null; | 1309 mname = () => null; |
1278 } | 1310 } |
1279 } | 1311 } |
1280 ''', [MessageKind.UNDEFINED_SETTER]); | 1312 ''', |
1281 checkWarningOn(''' | 1313 [MessageKind.UNDEFINED_SETTER]); |
| 1314 checkWarningOn( |
| 1315 ''' |
1282 main() { new B().bar(); } | 1316 main() { new B().bar(); } |
1283 class B { | 1317 class B { |
1284 mname() {} | 1318 mname() {} |
1285 bar() { | 1319 bar() { |
1286 this.mname = () => null; | 1320 this.mname = () => null; |
1287 } | 1321 } |
1288 } | 1322 } |
1289 ''', [MessageKind.UNDEFINED_SETTER]); | 1323 ''', |
| 1324 [MessageKind.UNDEFINED_SETTER]); |
1290 | 1325 |
1291 // Can't override super methods | 1326 // Can't override super methods |
1292 checkWarningOn(''' | 1327 checkWarningOn( |
| 1328 ''' |
1293 main() { new B().bar(); } | 1329 main() { new B().bar(); } |
1294 class A { | 1330 class A { |
1295 mname() {} | 1331 mname() {} |
1296 } | 1332 } |
1297 class B extends A { | 1333 class B extends A { |
1298 bar() { | 1334 bar() { |
1299 super.mname = () => 6; | 1335 super.mname = () => 6; |
1300 } | 1336 } |
1301 } | 1337 } |
1302 ''', [MessageKind.ASSIGNING_METHOD_IN_SUPER, | 1338 ''', |
1303 // TODO(johnniwinther): Avoid duplicate warnings. | 1339 [ |
1304 MessageKind.UNDEFINED_SETTER]); | 1340 MessageKind.ASSIGNING_METHOD_IN_SUPER, |
| 1341 // TODO(johnniwinther): Avoid duplicate warnings. |
| 1342 MessageKind.UNDEFINED_SETTER |
| 1343 ]); |
1305 | 1344 |
1306 // But index operators should be OK | 1345 // But index operators should be OK |
1307 checkWarningOn(''' | 1346 checkWarningOn( |
| 1347 ''' |
1308 main() { new B().bar(); } | 1348 main() { new B().bar(); } |
1309 class B { | 1349 class B { |
1310 operator[]=(x, y) {} | 1350 operator[]=(x, y) {} |
1311 bar() { | 1351 bar() { |
1312 this[1] = 3; // This is OK | 1352 this[1] = 3; // This is OK |
1313 } | 1353 } |
1314 } | 1354 } |
1315 ''', []); | 1355 ''', |
1316 checkWarningOn(''' | 1356 []); |
| 1357 checkWarningOn( |
| 1358 ''' |
1317 main() { new B().bar(); } | 1359 main() { new B().bar(); } |
1318 class A { | 1360 class A { |
1319 operator[]=(x, y) {} | 1361 operator[]=(x, y) {} |
1320 } | 1362 } |
1321 class B extends A { | 1363 class B extends A { |
1322 bar() { | 1364 bar() { |
1323 super[1] = 3; // This is OK | 1365 super[1] = 3; // This is OK |
1324 } | 1366 } |
1325 } | 1367 } |
1326 ''', []); | 1368 ''', |
| 1369 []); |
1327 } | 1370 } |
1328 | 1371 |
1329 testCantAssignFinalAndConsts() { | 1372 testCantAssignFinalAndConsts() { |
1330 // Can't write final or const locals. | 1373 // Can't write final or const locals. |
1331 checkWarningOn(''' | 1374 checkWarningOn( |
| 1375 ''' |
1332 main() { | 1376 main() { |
1333 final x = 1; | 1377 final x = 1; |
1334 x = 2; | 1378 x = 2; |
1335 } | 1379 } |
1336 ''', [MessageKind.UNDEFINED_STATIC_SETTER_BUT_GETTER]); | 1380 ''', |
1337 checkWarningOn(''' | 1381 [MessageKind.UNDEFINED_STATIC_SETTER_BUT_GETTER]); |
| 1382 checkWarningOn( |
| 1383 ''' |
1338 main() { | 1384 main() { |
1339 const x = 1; | 1385 const x = 1; |
1340 x = 2; | 1386 x = 2; |
1341 } | 1387 } |
1342 ''', [MessageKind.UNDEFINED_STATIC_SETTER_BUT_GETTER]); | 1388 ''', |
1343 checkWarningOn(''' | 1389 [MessageKind.UNDEFINED_STATIC_SETTER_BUT_GETTER]); |
| 1390 checkWarningOn( |
| 1391 ''' |
1344 final x = 1; | 1392 final x = 1; |
1345 main() { x = 3; } | 1393 main() { x = 3; } |
1346 ''', [MessageKind.UNDEFINED_STATIC_SETTER_BUT_GETTER]); | 1394 ''', |
| 1395 [MessageKind.UNDEFINED_STATIC_SETTER_BUT_GETTER]); |
1347 | 1396 |
1348 checkWarningOn(''' | 1397 checkWarningOn( |
| 1398 ''' |
1349 const x = 1; | 1399 const x = 1; |
1350 main() { x = 3; } | 1400 main() { x = 3; } |
1351 ''', [MessageKind.UNDEFINED_STATIC_SETTER_BUT_GETTER]); | 1401 ''', |
| 1402 [MessageKind.UNDEFINED_STATIC_SETTER_BUT_GETTER]); |
1352 | 1403 |
1353 // Detect assignments to final fields: | 1404 // Detect assignments to final fields: |
1354 checkWarningOn(''' | 1405 checkWarningOn( |
| 1406 ''' |
1355 main() => new B().m(); | 1407 main() => new B().m(); |
1356 class B { | 1408 class B { |
1357 final x = 1; | 1409 final x = 1; |
1358 m() { x = 2; } | 1410 m() { x = 2; } |
1359 } | 1411 } |
1360 ''', [MessageKind.UNDEFINED_SETTER]); | 1412 ''', |
| 1413 [MessageKind.UNDEFINED_SETTER]); |
1361 | 1414 |
1362 // ... even if 'this' is explicit: | 1415 // ... even if 'this' is explicit: |
1363 checkWarningOn(''' | 1416 checkWarningOn( |
| 1417 ''' |
1364 main() => new B().m(); | 1418 main() => new B().m(); |
1365 class B { | 1419 class B { |
1366 final x = 1; | 1420 final x = 1; |
1367 m() { this.x = 2; } | 1421 m() { this.x = 2; } |
1368 } | 1422 } |
1369 ''', [MessageKind.UNDEFINED_SETTER]); | 1423 ''', |
| 1424 [MessageKind.UNDEFINED_SETTER]); |
1370 | 1425 |
1371 // ... and in super class: | 1426 // ... and in super class: |
1372 checkWarningOn(''' | 1427 checkWarningOn( |
| 1428 ''' |
1373 main() => new B().m(); | 1429 main() => new B().m(); |
1374 class A { | 1430 class A { |
1375 final x = 1; | 1431 final x = 1; |
1376 } | 1432 } |
1377 class B extends A { | 1433 class B extends A { |
1378 m() { super.x = 2; } | 1434 m() { super.x = 2; } |
1379 } | 1435 } |
1380 ''', [MessageKind.ASSIGNING_FINAL_FIELD_IN_SUPER, | 1436 ''', |
1381 // TODO(johnniwinther): Avoid duplicate warnings. | 1437 [ |
1382 MessageKind.UNDEFINED_SETTER]); | 1438 MessageKind.ASSIGNING_FINAL_FIELD_IN_SUPER, |
| 1439 // TODO(johnniwinther): Avoid duplicate warnings. |
| 1440 MessageKind.UNDEFINED_SETTER |
| 1441 ]); |
1383 | 1442 |
1384 // But non-final fields are OK: | 1443 // But non-final fields are OK: |
1385 checkWarningOn(''' | 1444 checkWarningOn( |
| 1445 ''' |
1386 main() => new B().m(); | 1446 main() => new B().m(); |
1387 class A { | 1447 class A { |
1388 int x = 1; | 1448 int x = 1; |
1389 } | 1449 } |
1390 class B extends A { | 1450 class B extends A { |
1391 m() { super.x = 2; } | 1451 m() { super.x = 2; } |
1392 } | 1452 } |
1393 ''', []); | 1453 ''', |
| 1454 []); |
1394 | 1455 |
1395 // Check getter without setter. | 1456 // Check getter without setter. |
1396 checkWarningOn(''' | 1457 checkWarningOn( |
| 1458 ''' |
1397 main() => new B().m(); | 1459 main() => new B().m(); |
1398 class A { | 1460 class A { |
1399 get x => 1; | 1461 get x => 1; |
1400 } | 1462 } |
1401 class B extends A { | 1463 class B extends A { |
1402 m() { super.x = 2; } | 1464 m() { super.x = 2; } |
1403 } | 1465 } |
1404 ''', [MessageKind.UNDEFINED_SUPER_SETTER, | 1466 ''', |
1405 // TODO(johnniwinther): Avoid duplicate warnings. | 1467 [ |
1406 MessageKind.UNDEFINED_SETTER]); | 1468 MessageKind.UNDEFINED_SUPER_SETTER, |
| 1469 // TODO(johnniwinther): Avoid duplicate warnings. |
| 1470 MessageKind.UNDEFINED_SETTER |
| 1471 ]); |
1407 } | 1472 } |
1408 | 1473 |
1409 /// Helper to test that [script] produces all the given [warnings]. | 1474 /// Helper to test that [script] produces all the given [warnings]. |
1410 checkWarningOn(String script, List<MessageKind> warnings) { | 1475 checkWarningOn(String script, List<MessageKind> warnings) { |
1411 Expect.isTrue(warnings.length >= 0 && warnings.length <= 2); | 1476 Expect.isTrue(warnings.length >= 0 && warnings.length <= 2); |
1412 asyncTest(() => compileScript(script).then((compiler) { | 1477 asyncTest(() => compileScript(script).then((compiler) { |
1413 DiagnosticCollector collector = compiler.diagnosticCollector; | 1478 DiagnosticCollector collector = compiler.diagnosticCollector; |
1414 Expect.equals(0, collector.errors.length, | 1479 Expect.equals(0, collector.errors.length, |
1415 'Unexpected errors in\n$script\n${collector.errors}'); | 1480 'Unexpected errors in\n$script\n${collector.errors}'); |
1416 Expect.equals(warnings.length, collector.warnings.length, | 1481 Expect.equals( |
1417 'Unexpected warnings in\n$script\n' | 1482 warnings.length, |
1418 'Expected:$warnings\nFound:${collector.warnings}'); | 1483 collector.warnings.length, |
1419 for (int i = 0; i < warnings.length; i++) { | 1484 'Unexpected warnings in\n$script\n' |
1420 Expect.equals(warnings[i], collector.warnings.elementAt(i).message.kind); | 1485 'Expected:$warnings\nFound:${collector.warnings}'); |
1421 } | 1486 for (int i = 0; i < warnings.length; i++) { |
1422 })); | 1487 Expect.equals( |
| 1488 warnings[i], collector.warnings.elementAt(i).message.kind); |
| 1489 } |
| 1490 })); |
1423 } | 1491 } |
1424 | 1492 |
1425 testAwaitHint() { | 1493 testAwaitHint() { |
1426 check(String script, {String className, String functionName}) { | 1494 check(String script, {String className, String functionName}) { |
1427 var prefix = className == null | 1495 var prefix = className == null |
1428 ? "Cannot resolve 'await'" | 1496 ? "Cannot resolve 'await'" |
1429 : "No member named 'await' in class '$className'"; | 1497 : "No member named 'await' in class '$className'"; |
1430 var where = functionName == null | 1498 var where = |
1431 ? 'the enclosing function' : "'$functionName'"; | 1499 functionName == null ? 'the enclosing function' : "'$functionName'"; |
1432 asyncTest(() => compileScript(script).then((compiler) { | 1500 asyncTest(() => compileScript(script).then((compiler) { |
1433 DiagnosticCollector collector = compiler.diagnosticCollector; | 1501 DiagnosticCollector collector = compiler.diagnosticCollector; |
1434 Expect.equals(0, collector.errors.length); | 1502 Expect.equals(0, collector.errors.length); |
1435 Expect.equals(1, collector.warnings.length); | 1503 Expect.equals(1, collector.warnings.length); |
1436 Expect.equals("$prefix.\n" | 1504 Expect.equals( |
1437 "Did you mean to add the 'async' marker to $where?", | 1505 "$prefix.\n" |
1438 '${collector.warnings.first.message}'); | 1506 "Did you mean to add the 'async' marker to $where?", |
1439 })); | 1507 '${collector.warnings.first.message}'); |
| 1508 })); |
1440 } | 1509 } |
| 1510 |
1441 check('main() { await -3; }', functionName: 'main'); | 1511 check('main() { await -3; }', functionName: 'main'); |
1442 check('main() { () => await -3; }'); | 1512 check('main() { () => await -3; }'); |
1443 check('foo() => await -3; main() => foo();', functionName: 'foo'); | 1513 check('foo() => await -3; main() => foo();', functionName: 'foo'); |
1444 check(''' | 1514 check( |
| 1515 ''' |
1445 class A { | 1516 class A { |
1446 m() => await - 3; | 1517 m() => await - 3; |
1447 } | 1518 } |
1448 main() => new A().m(); | 1519 main() => new A().m(); |
1449 ''', className: 'A', functionName: 'm'); | 1520 ''', |
1450 check(''' | 1521 className: 'A', |
| 1522 functionName: 'm'); |
| 1523 check( |
| 1524 ''' |
1451 class A { | 1525 class A { |
1452 static m() => await - 3; | 1526 static m() => await - 3; |
1453 } | 1527 } |
1454 main() => A.m(); | 1528 main() => A.m(); |
1455 ''', functionName: 'm'); | 1529 ''', |
1456 check(''' | 1530 functionName: 'm'); |
| 1531 check( |
| 1532 ''' |
1457 class A { | 1533 class A { |
1458 m() => () => await - 3; | 1534 m() => () => await - 3; |
1459 } | 1535 } |
1460 main() => new A().m(); | 1536 main() => new A().m(); |
1461 ''', className: 'A'); | 1537 ''', |
| 1538 className: 'A'); |
1462 } | 1539 } |
OLD | NEW |