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 'package:expect/expect.dart'; | 6 import 'package:expect/expect.dart'; |
7 import 'package:async_helper/async_helper.dart'; | 7 import 'package:async_helper/async_helper.dart'; |
8 import 'package:compiler/src/compiler.dart'; | 8 import 'package:compiler/src/compiler.dart'; |
9 import 'package:compiler/src/diagnostics/messages.dart' show | 9 import 'package:compiler/src/diagnostics/messages.dart' show MessageKind; |
10 MessageKind; | |
11 import 'package:compiler/src/elements/elements.dart'; | 10 import 'package:compiler/src/elements/elements.dart'; |
12 import 'package:compiler/src/elements/modelx.dart'; | 11 import 'package:compiler/src/elements/modelx.dart'; |
13 import 'package:compiler/src/tree/tree.dart'; | 12 import 'package:compiler/src/tree/tree.dart'; |
14 import 'package:compiler/src/types/types.dart'; | 13 import 'package:compiler/src/types/types.dart'; |
15 import 'package:compiler/src/universe/call_structure.dart' show | 14 import 'package:compiler/src/universe/call_structure.dart' show CallStructure; |
16 CallStructure; | 15 import 'package:compiler/src/universe/selector.dart' show Selector; |
17 import 'package:compiler/src/universe/selector.dart' show | |
18 Selector; | |
19 import 'package:compiler/src/world.dart'; | 16 import 'package:compiler/src/world.dart'; |
20 | 17 |
21 import 'mock_compiler.dart'; | 18 import 'mock_compiler.dart'; |
22 import 'mock_libraries.dart'; | 19 import 'mock_libraries.dart'; |
23 | 20 |
24 Future<Compiler> applyPatch(String script, String patch, | 21 Future<Compiler> applyPatch(String script, String patch, |
25 {bool analyzeAll: false, | 22 {bool analyzeAll: false, |
26 bool analyzeOnly: false, | 23 bool analyzeOnly: false, |
27 bool runCompiler: false, | 24 bool runCompiler: false, |
28 String main: "", | 25 String main: "", |
29 String patchVersion}) { | 26 String patchVersion}) { |
30 Map<String, String> core = <String, String>{'script': script}; | 27 Map<String, String> core = <String, String>{'script': script}; |
31 MockCompiler compiler = new MockCompiler.internal(coreSource: core, | 28 MockCompiler compiler = new MockCompiler.internal( |
32 analyzeAll: analyzeAll, | 29 coreSource: core, |
33 analyzeOnly: analyzeOnly, | 30 analyzeAll: analyzeAll, |
34 patchVersion: patchVersion); | 31 analyzeOnly: analyzeOnly, |
| 32 patchVersion: patchVersion); |
35 compiler.diagnosticHandler = createHandler(compiler, ''); | 33 compiler.diagnosticHandler = createHandler(compiler, ''); |
36 var uri = Uri.parse("patch:core"); | 34 var uri = Uri.parse("patch:core"); |
37 compiler.registerSource(uri, "$DEFAULT_PATCH_CORE_SOURCE\n$patch"); | 35 compiler.registerSource(uri, "$DEFAULT_PATCH_CORE_SOURCE\n$patch"); |
38 var future; | 36 var future; |
39 if (runCompiler) { | 37 if (runCompiler) { |
40 future = compiler.run(null, main); | 38 future = compiler.run(null, main); |
41 } else { | 39 } else { |
42 future = compiler.init(main); | 40 future = compiler.init(main); |
43 } | 41 } |
44 return future.then((_) => compiler); | 42 return future.then((_) => compiler); |
45 } | 43 } |
46 | 44 |
47 void expectHasBody(compiler, ElementX element) { | 45 void expectHasBody(compiler, ElementX element) { |
48 var node = element.parseNode(compiler.parsingContext); | 46 var node = element.parseNode(compiler.parsingContext); |
49 Expect.isNotNull(node, "Element isn't parseable, when a body was expected"); | 47 Expect.isNotNull(node, "Element isn't parseable, when a body was expected"); |
50 Expect.isNotNull(node.body); | 48 Expect.isNotNull(node.body); |
51 // If the element has a body it is either a Block or a Return statement, | 49 // If the element has a body it is either a Block or a Return statement, |
52 // both with different begin and end tokens. | 50 // both with different begin and end tokens. |
53 Expect.isTrue(node.body is Block || node.body is Return); | 51 Expect.isTrue(node.body is Block || node.body is Return); |
54 Expect.notEquals(node.body.getBeginToken(), node.body.getEndToken()); | 52 Expect.notEquals(node.body.getBeginToken(), node.body.getEndToken()); |
55 } | 53 } |
56 | 54 |
57 void expectHasNoBody(compiler, ElementX element) { | 55 void expectHasNoBody(compiler, ElementX element) { |
58 var node = element.parseNode(compiler.parsingContext); | 56 var node = element.parseNode(compiler.parsingContext); |
59 Expect.isNotNull(node, "Element isn't parseable, when a body was expected"); | 57 Expect.isNotNull(node, "Element isn't parseable, when a body was expected"); |
60 Expect.isFalse(node.hasBody); | 58 Expect.isFalse(node.hasBody); |
61 } | 59 } |
62 | 60 |
63 Element ensure(compiler, | 61 Element ensure(compiler, String name, Element lookup(name), |
64 String name, | 62 {bool expectIsPatched: false, |
65 Element lookup(name), | 63 bool expectIsPatch: false, |
66 {bool expectIsPatched: false, | 64 bool checkHasBody: false, |
67 bool expectIsPatch: false, | 65 bool expectIsGetter: false, |
68 bool checkHasBody: false, | 66 bool expectIsFound: true, |
69 bool expectIsGetter: false, | 67 bool expectIsRegular: false}) { |
70 bool expectIsFound: true, | |
71 bool expectIsRegular: false}) { | |
72 var element = lookup(name); | 68 var element = lookup(name); |
73 if (!expectIsFound) { | 69 if (!expectIsFound) { |
74 Expect.isNull(element); | 70 Expect.isNull(element); |
75 return element; | 71 return element; |
76 } | 72 } |
77 Expect.isNotNull(element); | 73 Expect.isNotNull(element); |
78 if (expectIsGetter) { | 74 if (expectIsGetter) { |
79 Expect.isTrue(element is AbstractFieldElement); | 75 Expect.isTrue(element is AbstractFieldElement); |
80 Expect.isNotNull(element.getter); | 76 Expect.isNotNull(element.getter); |
81 element = element.getter; | 77 element = element.getter; |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
121 if (checkHasBody) { | 117 if (checkHasBody) { |
122 expectHasBody(compiler, element); | 118 expectHasBody(compiler, element); |
123 } | 119 } |
124 } | 120 } |
125 Expect.isFalse(element.isPatched && element.isPatch); | 121 Expect.isFalse(element.isPatched && element.isPatch); |
126 return element; | 122 return element; |
127 } | 123 } |
128 | 124 |
129 Future testPatchFunction() async { | 125 Future testPatchFunction() async { |
130 var compiler = await applyPatch( | 126 var compiler = await applyPatch( |
131 "external test();", | 127 "external test();", "@patch test() { return 'string'; } "); |
132 "@patch test() { return 'string'; } "); | |
133 ensure(compiler, "test", compiler.commonElements.coreLibrary.find, | 128 ensure(compiler, "test", compiler.commonElements.coreLibrary.find, |
134 expectIsPatched: true, checkHasBody: true); | 129 expectIsPatched: true, checkHasBody: true); |
135 ensure(compiler, "test", compiler.commonElements.coreLibrary.patch.find, | 130 ensure(compiler, "test", compiler.commonElements.coreLibrary.patch.find, |
136 expectIsPatch: true, checkHasBody: true); | 131 expectIsPatch: true, checkHasBody: true); |
137 | 132 |
138 DiagnosticCollector collector = compiler.diagnosticCollector; | 133 DiagnosticCollector collector = compiler.diagnosticCollector; |
139 Expect.isTrue(collector.warnings.isEmpty, | 134 Expect.isTrue( |
140 "Unexpected warnings: ${collector.warnings}"); | 135 collector.warnings.isEmpty, "Unexpected warnings: ${collector.warnings}"); |
141 Expect.isTrue(collector.errors.isEmpty, | 136 Expect.isTrue( |
142 "Unexpected errors: ${collector.errors}"); | 137 collector.errors.isEmpty, "Unexpected errors: ${collector.errors}"); |
143 } | 138 } |
144 | 139 |
145 Future testPatchFunctionMetadata() async { | 140 Future testPatchFunctionMetadata() async { |
146 var compiler = await applyPatch( | 141 var compiler = await applyPatch( |
147 """ | 142 """ |
148 const a = 0; | 143 const a = 0; |
149 @a external test(); | 144 @a external test(); |
150 """, | 145 """, |
151 """ | 146 """ |
152 const _b = 1; | 147 const _b = 1; |
153 @patch @_b test() {} | 148 @patch @_b test() {} |
154 """); | 149 """); |
155 Element origin = ensure(compiler, "test", | 150 Element origin = ensure( |
156 compiler.commonElements.coreLibrary.find, | 151 compiler, "test", compiler.commonElements.coreLibrary.find, |
157 expectIsPatched: true, checkHasBody: true); | 152 expectIsPatched: true, checkHasBody: true); |
158 Element patch = ensure(compiler, "test", | 153 Element patch = ensure( |
159 compiler.commonElements.coreLibrary.patch.find, | 154 compiler, "test", compiler.commonElements.coreLibrary.patch.find, |
160 expectIsPatch: true, checkHasBody: true); | 155 expectIsPatch: true, checkHasBody: true); |
161 | 156 |
162 DiagnosticCollector collector = compiler.diagnosticCollector; | 157 DiagnosticCollector collector = compiler.diagnosticCollector; |
163 Expect.isTrue(collector.warnings.isEmpty, | 158 Expect.isTrue( |
164 "Unexpected warnings: ${collector.warnings}"); | 159 collector.warnings.isEmpty, "Unexpected warnings: ${collector.warnings}"); |
165 Expect.isTrue(collector.errors.isEmpty, | 160 Expect.isTrue( |
166 "Unexpected errors: ${collector.errors}"); | 161 collector.errors.isEmpty, "Unexpected errors: ${collector.errors}"); |
167 | 162 |
168 Expect.equals(1, origin.metadata.length, | 163 Expect.equals(1, origin.metadata.length, |
169 "Unexpected origin metadata: ${origin.metadata}."); | 164 "Unexpected origin metadata: ${origin.metadata}."); |
170 Expect.equals(3, patch.metadata.length, | 165 Expect.equals(3, patch.metadata.length, |
171 "Unexpected patch metadata: ${patch.metadata}."); | 166 "Unexpected patch metadata: ${patch.metadata}."); |
172 } | 167 } |
173 | 168 |
174 | |
175 Future testPatchVersioned() async { | 169 Future testPatchVersioned() async { |
176 String fullPatch = "test(){return 'string';}"; | 170 String fullPatch = "test(){return 'string';}"; |
177 String lazyPatch = "test(){return 'new and improved string';}"; | 171 String lazyPatch = "test(){return 'new and improved string';}"; |
178 | 172 |
179 String patchSource = | 173 String patchSource = """ |
180 """ | |
181 @patch_full $fullPatch | 174 @patch_full $fullPatch |
182 @patch_lazy $lazyPatch | 175 @patch_lazy $lazyPatch |
183 """; | 176 """; |
184 | 177 |
185 Future test(String patchVersion, | 178 Future test(String patchVersion, |
186 {String patchText, | 179 {String patchText, |
187 bool expectIsPatched: true, | 180 bool expectIsPatched: true, |
188 String expectedError, | 181 String expectedError, |
189 String defaultPatch: '', | 182 String defaultPatch: '', |
190 String expectedInternalError}) async { | 183 String expectedInternalError}) async { |
191 return applyPatch( | 184 return applyPatch( |
192 "external test();", | 185 "external test();", |
193 """ | 186 """ |
194 $defaultPatch | 187 $defaultPatch |
195 $patchSource | 188 $patchSource |
196 """, | 189 """, |
197 patchVersion: patchVersion).then((compiler) { | 190 patchVersion: patchVersion).then((compiler) { |
198 Element origin = ensure(compiler, "test", | 191 Element origin = ensure( |
199 compiler.commonElements.coreLibrary.find, | 192 compiler, "test", compiler.commonElements.coreLibrary.find, |
200 expectIsPatched: expectIsPatched, checkHasBody: true); | 193 expectIsPatched: expectIsPatched, checkHasBody: true); |
201 if (expectIsPatched) { | 194 if (expectIsPatched) { |
202 AstElement patch = ensure(compiler, "test", | 195 AstElement patch = ensure( |
203 compiler.commonElements.coreLibrary.patch.find, | 196 compiler, "test", compiler.commonElements.coreLibrary.patch.find, |
204 expectIsPatch: true, checkHasBody: true); | 197 expectIsPatch: true, checkHasBody: true); |
205 Expect.equals(origin.patch, patch); | 198 Expect.equals(origin.patch, patch); |
206 Expect.equals(patch.origin, origin); | 199 Expect.equals(patch.origin, origin); |
207 Expect.equals(patchText, patch.node.toString()); | 200 Expect.equals(patchText, patch.node.toString()); |
208 } | 201 } |
209 | 202 |
210 compiler.analyzeElement(origin); | 203 compiler.analyzeElement(origin); |
211 compiler.enqueuer.resolution.emptyDeferredQueueForTesting(); | 204 compiler.enqueuer.resolution.emptyDeferredQueueForTesting(); |
212 | 205 |
213 DiagnosticCollector collector = compiler.diagnosticCollector; | 206 DiagnosticCollector collector = compiler.diagnosticCollector; |
214 Expect.isTrue(collector.warnings.isEmpty, | 207 Expect.isTrue(collector.warnings.isEmpty, |
215 "Unexpected warnings: ${collector.warnings}"); | 208 "Unexpected warnings: ${collector.warnings}"); |
216 if (expectedError != null) { | 209 if (expectedError != null) { |
217 Expect.equals(expectedError, | 210 Expect.equals(expectedError, collector.errors.first.message.toString()); |
218 collector.errors.first.message.toString()); | 211 } else { |
219 } else { | 212 Expect.isTrue( |
220 Expect.isTrue(collector.errors.isEmpty, | 213 collector.errors.isEmpty, "Unexpected errors: ${collector.errors}"); |
221 "Unexpected errors: ${collector.errors}"); | 214 } |
222 } | 215 }).catchError((error) { |
223 }).catchError((error) { | 216 if (expectedInternalError != null) { |
224 if (expectedInternalError != null) { | 217 Expect.equals( |
225 Expect.equals( | 218 'Internal Error: $expectedInternalError', error.toString()); |
226 'Internal Error: $expectedInternalError', error.toString()); | 219 } else { |
227 } else { | 220 throw error; |
228 throw error; | 221 } |
229 } | 222 }); |
230 }); | |
231 } | 223 } |
232 | 224 |
233 await test('full', patchText: fullPatch); | 225 await test('full', patchText: fullPatch); |
234 await test('lazy', patchText: lazyPatch); | 226 await test('lazy', patchText: lazyPatch); |
235 await test('unknown', expectIsPatched: false, | 227 await test('unknown', |
236 expectedError: 'External method without an implementation.'); | 228 expectIsPatched: false, |
| 229 expectedError: 'External method without an implementation.'); |
237 await test('full', | 230 await test('full', |
238 defaultPatch: "@patch test(){}", | 231 defaultPatch: "@patch test(){}", |
239 expectedInternalError: "Trying to patch a function more than once."); | 232 expectedInternalError: "Trying to patch a function more than once."); |
240 } | 233 } |
241 | 234 |
242 Future testPatchConstructor() async { | 235 Future testPatchConstructor() async { |
243 var compiler = await applyPatch( | 236 var compiler = await applyPatch( |
244 """ | 237 """ |
245 class Class { | 238 class Class { |
246 external Class(); | 239 external Class(); |
247 } | 240 } |
248 """, | 241 """, |
249 """ | 242 """ |
250 @patch class Class { | 243 @patch class Class { |
251 @patch Class(); | 244 @patch Class(); |
252 } | 245 } |
253 """); | 246 """); |
254 var classOrigin = ensure(compiler, "Class", | 247 var classOrigin = ensure( |
255 compiler.commonElements.coreLibrary.find, expectIsPatched: true); | 248 compiler, "Class", compiler.commonElements.coreLibrary.find, |
| 249 expectIsPatched: true); |
256 classOrigin.ensureResolved(compiler.resolution); | 250 classOrigin.ensureResolved(compiler.resolution); |
257 var classPatch = ensure(compiler, "Class", | 251 var classPatch = ensure( |
258 compiler.commonElements.coreLibrary.patch.find, expectIsPatch: true); | 252 compiler, "Class", compiler.commonElements.coreLibrary.patch.find, |
| 253 expectIsPatch: true); |
259 | 254 |
260 Expect.equals(classPatch, classOrigin.patch); | 255 Expect.equals(classPatch, classOrigin.patch); |
261 Expect.equals(classOrigin, classPatch.origin); | 256 Expect.equals(classOrigin, classPatch.origin); |
262 | 257 |
263 var constructorOrigin = ensure(compiler, "", | 258 var constructorOrigin = ensure( |
264 (name) => classOrigin.localLookup(name), | 259 compiler, "", (name) => classOrigin.localLookup(name), |
265 expectIsPatched: true); | 260 expectIsPatched: true); |
266 var constructorPatch = ensure(compiler, "", | 261 var constructorPatch = ensure( |
267 (name) => classPatch.localLookup(name), | 262 compiler, "", (name) => classPatch.localLookup(name), |
268 expectIsPatch: true); | 263 expectIsPatch: true); |
269 | 264 |
270 Expect.equals(constructorPatch, constructorOrigin.patch); | 265 Expect.equals(constructorPatch, constructorOrigin.patch); |
271 Expect.equals(constructorOrigin, constructorPatch.origin); | 266 Expect.equals(constructorOrigin, constructorPatch.origin); |
272 | 267 |
273 DiagnosticCollector collector = compiler.diagnosticCollector; | 268 DiagnosticCollector collector = compiler.diagnosticCollector; |
274 Expect.isTrue(collector.warnings.isEmpty, | 269 Expect.isTrue( |
275 "Unexpected warnings: ${collector.warnings}"); | 270 collector.warnings.isEmpty, "Unexpected warnings: ${collector.warnings}"); |
276 Expect.isTrue(collector.errors.isEmpty, | 271 Expect.isTrue( |
277 "Unexpected errors: ${collector.errors}"); | 272 collector.errors.isEmpty, "Unexpected errors: ${collector.errors}"); |
278 } | 273 } |
279 | 274 |
280 Future testPatchRedirectingConstructor() async { | 275 Future testPatchRedirectingConstructor() async { |
281 var compiler = await applyPatch( | 276 var compiler = await applyPatch( |
282 """ | 277 """ |
283 class Class { | 278 class Class { |
284 Class(x) : this._(x, false); | 279 Class(x) : this._(x, false); |
285 | 280 |
286 external Class._(x, y); | 281 external Class._(x, y); |
287 } | 282 } |
288 """, | 283 """, |
289 r""" | 284 r""" |
290 @patch class Class { | 285 @patch class Class { |
291 @patch Class._(x, y) { print('$x,$y'); } | 286 @patch Class._(x, y) { print('$x,$y'); } |
292 } | 287 } |
293 """); | 288 """); |
294 var classOrigin = ensure(compiler, "Class", | 289 var classOrigin = ensure( |
295 compiler.commonElements.coreLibrary.find, expectIsPatched: true); | 290 compiler, "Class", compiler.commonElements.coreLibrary.find, |
| 291 expectIsPatched: true); |
296 classOrigin.ensureResolved(compiler.resolution); | 292 classOrigin.ensureResolved(compiler.resolution); |
297 | 293 |
298 var classPatch = ensure(compiler, "Class", | 294 var classPatch = ensure( |
299 compiler.commonElements.coreLibrary.patch.find, expectIsPatch: true); | 295 compiler, "Class", compiler.commonElements.coreLibrary.patch.find, |
| 296 expectIsPatch: true); |
300 | 297 |
301 Expect.equals(classOrigin, classPatch.origin); | 298 Expect.equals(classOrigin, classPatch.origin); |
302 Expect.equals(classPatch, classOrigin.patch); | 299 Expect.equals(classPatch, classOrigin.patch); |
303 | 300 |
304 var constructorRedirecting = | 301 var constructorRedirecting = |
305 ensure(compiler, "", | 302 ensure(compiler, "", (name) => classOrigin.localLookup(name)); |
306 (name) => classOrigin.localLookup(name)); | 303 var constructorOrigin = ensure( |
307 var constructorOrigin = | 304 compiler, "_", (name) => classOrigin.localLookup(name), |
308 ensure(compiler, "_", | 305 expectIsPatched: true); |
309 (name) => classOrigin.localLookup(name), | 306 var constructorPatch = ensure( |
310 expectIsPatched: true); | 307 compiler, "_", (name) => classPatch.localLookup(name), |
311 var constructorPatch = | 308 expectIsPatch: true); |
312 ensure(compiler, "_", | |
313 (name) => classPatch.localLookup(name), | |
314 expectIsPatch: true); | |
315 Expect.equals(constructorOrigin, constructorPatch.origin); | 309 Expect.equals(constructorOrigin, constructorPatch.origin); |
316 Expect.equals(constructorPatch, constructorOrigin.patch); | 310 Expect.equals(constructorPatch, constructorOrigin.patch); |
317 | 311 |
318 compiler.resolver.resolve(constructorRedirecting); | 312 compiler.resolver.resolve(constructorRedirecting); |
319 | 313 |
320 DiagnosticCollector collector = compiler.diagnosticCollector; | 314 DiagnosticCollector collector = compiler.diagnosticCollector; |
321 Expect.isTrue(collector.warnings.isEmpty, | 315 Expect.isTrue( |
322 "Unexpected warnings: ${collector.warnings}"); | 316 collector.warnings.isEmpty, "Unexpected warnings: ${collector.warnings}"); |
323 Expect.isTrue(collector.errors.isEmpty, | 317 Expect.isTrue( |
324 "Unexpected errors: ${collector.errors}"); | 318 collector.errors.isEmpty, "Unexpected errors: ${collector.errors}"); |
325 } | 319 } |
326 | 320 |
327 Future testPatchMember() async { | 321 Future testPatchMember() async { |
328 var compiler = await applyPatch( | 322 var compiler = await applyPatch( |
329 """ | 323 """ |
330 class Class { | 324 class Class { |
331 external String toString(); | 325 external String toString(); |
332 } | 326 } |
333 """, | 327 """, |
334 """ | 328 """ |
335 @patch class Class { | 329 @patch class Class { |
336 @patch String toString() => 'string'; | 330 @patch String toString() => 'string'; |
337 } | 331 } |
338 """); | 332 """); |
339 var container = ensure(compiler, "Class", | 333 var container = ensure( |
340 compiler.commonElements.coreLibrary.find, expectIsPatched: true); | 334 compiler, "Class", compiler.commonElements.coreLibrary.find, |
| 335 expectIsPatched: true); |
341 container.parseNode(compiler.parsingContext); | 336 container.parseNode(compiler.parsingContext); |
342 ensure(compiler, "Class", compiler.commonElements.coreLibrary.patch.find, | 337 ensure(compiler, "Class", compiler.commonElements.coreLibrary.patch.find, |
343 expectIsPatch: true); | 338 expectIsPatch: true); |
344 | 339 |
345 ensure(compiler, "toString", container.lookupLocalMember, | 340 ensure(compiler, "toString", container.lookupLocalMember, |
346 expectIsPatched: true, checkHasBody: true); | 341 expectIsPatched: true, checkHasBody: true); |
347 ensure(compiler, "toString", container.patch.lookupLocalMember, | 342 ensure(compiler, "toString", container.patch.lookupLocalMember, |
348 expectIsPatch: true, checkHasBody: true); | 343 expectIsPatch: true, checkHasBody: true); |
349 | 344 |
350 DiagnosticCollector collector = compiler.diagnosticCollector; | 345 DiagnosticCollector collector = compiler.diagnosticCollector; |
351 Expect.isTrue(collector.warnings.isEmpty, | 346 Expect.isTrue( |
352 "Unexpected warnings: ${collector.warnings}"); | 347 collector.warnings.isEmpty, "Unexpected warnings: ${collector.warnings}"); |
353 Expect.isTrue(collector.errors.isEmpty, | 348 Expect.isTrue( |
354 "Unexpected errors: ${collector.errors}"); | 349 collector.errors.isEmpty, "Unexpected errors: ${collector.errors}"); |
355 } | 350 } |
356 | 351 |
357 Future testPatchGetter() async { | 352 Future testPatchGetter() async { |
358 var compiler = await applyPatch( | 353 var compiler = await applyPatch( |
359 """ | 354 """ |
360 class Class { | 355 class Class { |
361 external int get field; | 356 external int get field; |
362 } | 357 } |
363 """, | 358 """, |
364 """ | 359 """ |
365 @patch class Class { | 360 @patch class Class { |
366 @patch int get field => 5; | 361 @patch int get field => 5; |
367 } | 362 } |
368 """); | 363 """); |
369 var container = ensure(compiler, "Class", | 364 var container = ensure( |
370 compiler.commonElements.coreLibrary.find, expectIsPatched: true); | 365 compiler, "Class", compiler.commonElements.coreLibrary.find, |
| 366 expectIsPatched: true); |
371 container.parseNode(compiler.parsingContext); | 367 container.parseNode(compiler.parsingContext); |
372 ensure(compiler, | 368 ensure(compiler, "field", container.lookupLocalMember, |
373 "field", | 369 expectIsGetter: true, expectIsPatched: true, checkHasBody: true); |
374 container.lookupLocalMember, | 370 ensure(compiler, "field", container.patch.lookupLocalMember, |
375 expectIsGetter: true, | 371 expectIsGetter: true, expectIsPatch: true, checkHasBody: true); |
376 expectIsPatched: true, | |
377 checkHasBody: true); | |
378 ensure(compiler, | |
379 "field", | |
380 container.patch.lookupLocalMember, | |
381 expectIsGetter: true, | |
382 expectIsPatch: true, | |
383 checkHasBody: true); | |
384 | 372 |
385 DiagnosticCollector collector = compiler.diagnosticCollector; | 373 DiagnosticCollector collector = compiler.diagnosticCollector; |
386 Expect.isTrue(collector.warnings.isEmpty, | 374 Expect.isTrue( |
387 "Unexpected warnings: ${collector.warnings}"); | 375 collector.warnings.isEmpty, "Unexpected warnings: ${collector.warnings}"); |
388 Expect.isTrue(collector.errors.isEmpty, | 376 Expect.isTrue( |
389 "Unexpected errors: ${collector.errors}"); | 377 collector.errors.isEmpty, "Unexpected errors: ${collector.errors}"); |
390 } | 378 } |
391 | 379 |
392 Future testRegularMember() async { | 380 Future testRegularMember() async { |
393 var compiler = await applyPatch( | 381 var compiler = await applyPatch( |
394 """ | 382 """ |
395 class Class { | 383 class Class { |
396 void regular() {} | 384 void regular() {} |
397 } | 385 } |
398 """, | 386 """, |
399 """ | 387 """ |
400 @patch class Class { | 388 @patch class Class { |
401 } | 389 } |
402 """); | 390 """); |
403 var container = ensure(compiler, "Class", | 391 var container = ensure( |
404 compiler.commonElements.coreLibrary.find, expectIsPatched: true); | 392 compiler, "Class", compiler.commonElements.coreLibrary.find, |
| 393 expectIsPatched: true); |
405 container.parseNode(compiler.parsingContext); | 394 container.parseNode(compiler.parsingContext); |
406 ensure(compiler, "Class", compiler.commonElements.coreLibrary.patch.find, | 395 ensure(compiler, "Class", compiler.commonElements.coreLibrary.patch.find, |
407 expectIsPatch: true); | 396 expectIsPatch: true); |
408 | 397 |
409 ensure(compiler, "regular", container.lookupLocalMember, | 398 ensure(compiler, "regular", container.lookupLocalMember, |
410 checkHasBody: true, expectIsRegular: true); | 399 checkHasBody: true, expectIsRegular: true); |
411 ensure(compiler, "regular", container.patch.lookupLocalMember, | 400 ensure(compiler, "regular", container.patch.lookupLocalMember, |
412 checkHasBody: true, expectIsRegular: true); | 401 checkHasBody: true, expectIsRegular: true); |
413 | 402 |
414 DiagnosticCollector collector = compiler.diagnosticCollector; | 403 DiagnosticCollector collector = compiler.diagnosticCollector; |
415 Expect.isTrue(collector.warnings.isEmpty, | 404 Expect.isTrue( |
416 "Unexpected warnings: ${collector.warnings}"); | 405 collector.warnings.isEmpty, "Unexpected warnings: ${collector.warnings}"); |
417 Expect.isTrue(collector.errors.isEmpty, | 406 Expect.isTrue( |
418 "Unexpected errors: ${collector.errors}"); | 407 collector.errors.isEmpty, "Unexpected errors: ${collector.errors}"); |
419 } | 408 } |
420 | 409 |
421 Future testInjectedMember() async { | 410 Future testInjectedMember() async { |
422 var compiler = await applyPatch( | 411 var compiler = await applyPatch( |
423 """ | 412 """ |
424 class Class { | 413 class Class { |
425 } | 414 } |
426 """, | 415 """, |
427 """ | 416 """ |
428 @patch class Class { | 417 @patch class Class { |
429 void _injected() {} | 418 void _injected() {} |
430 } | 419 } |
431 """); | 420 """); |
432 var container = ensure(compiler, "Class", | 421 var container = ensure( |
433 compiler.commonElements.coreLibrary.find, expectIsPatched: true); | 422 compiler, "Class", compiler.commonElements.coreLibrary.find, |
| 423 expectIsPatched: true); |
434 container.parseNode(compiler.parsingContext); | 424 container.parseNode(compiler.parsingContext); |
435 ensure(compiler, "Class", compiler.commonElements.coreLibrary.patch.find, | 425 ensure(compiler, "Class", compiler.commonElements.coreLibrary.patch.find, |
436 expectIsPatch: true); | 426 expectIsPatch: true); |
437 | 427 |
438 ensure(compiler, "_injected", container.lookupLocalMember, | 428 ensure(compiler, "_injected", container.lookupLocalMember, |
439 expectIsFound: false); | 429 expectIsFound: false); |
440 ensure(compiler, "_injected", container.patch.lookupLocalMember, | 430 ensure(compiler, "_injected", container.patch.lookupLocalMember, |
441 checkHasBody: true, expectIsRegular: true); | 431 checkHasBody: true, expectIsRegular: true); |
442 | 432 |
443 DiagnosticCollector collector = compiler.diagnosticCollector; | 433 DiagnosticCollector collector = compiler.diagnosticCollector; |
444 Expect.isTrue(collector.warnings.isEmpty, | 434 Expect.isTrue( |
445 "Unexpected warnings: ${collector.warnings}"); | 435 collector.warnings.isEmpty, "Unexpected warnings: ${collector.warnings}"); |
446 Expect.isTrue(collector.errors.isEmpty, | 436 Expect.isTrue( |
447 "Unexpected errors: ${collector.errors}"); | 437 collector.errors.isEmpty, "Unexpected errors: ${collector.errors}"); |
448 } | 438 } |
449 | 439 |
450 Future testInjectedPublicMember() async { | 440 Future testInjectedPublicMember() async { |
451 var compiler = await applyPatch( | 441 var compiler = await applyPatch( |
452 """ | 442 """ |
453 class Class { | 443 class Class { |
454 } | 444 } |
455 """, | 445 """, |
456 """ | 446 """ |
457 @patch class Class { | 447 @patch class Class { |
458 void injected() {} | 448 void injected() {} |
459 } | 449 } |
460 """); | 450 """); |
461 var container = ensure(compiler, "Class", | 451 var container = ensure( |
462 compiler.commonElements.coreLibrary.find, expectIsPatched: true); | 452 compiler, "Class", compiler.commonElements.coreLibrary.find, |
| 453 expectIsPatched: true); |
463 container.parseNode(compiler.parsingContext); | 454 container.parseNode(compiler.parsingContext); |
464 ensure(compiler, "Class", compiler.commonElements.coreLibrary.patch.find, | 455 ensure(compiler, "Class", compiler.commonElements.coreLibrary.patch.find, |
465 expectIsPatch: true); | 456 expectIsPatch: true); |
466 | 457 |
467 ensure(compiler, "injected", container.lookupLocalMember, | 458 ensure(compiler, "injected", container.lookupLocalMember, |
468 expectIsFound: false); | 459 expectIsFound: false); |
469 ensure(compiler, "injected", container.patch.lookupLocalMember, | 460 ensure(compiler, "injected", container.patch.lookupLocalMember, |
470 checkHasBody: true, expectIsRegular: true); | 461 checkHasBody: true, expectIsRegular: true); |
471 | 462 |
472 DiagnosticCollector collector = compiler.diagnosticCollector; | 463 DiagnosticCollector collector = compiler.diagnosticCollector; |
473 Expect.isTrue(collector.warnings.isEmpty, | |
474 "Unexpected warnings: ${collector.warnings}"); | |
475 Expect.equals(1, collector.errors.length, | |
476 "Unexpected errors: ${collector.errors}"); | |
477 Expect.isTrue( | 464 Expect.isTrue( |
478 collector.errors.first.message.kind == | 465 collector.warnings.isEmpty, "Unexpected warnings: ${collector.warnings}"); |
479 MessageKind.INJECTED_PUBLIC_MEMBER); | 466 Expect.equals( |
| 467 1, collector.errors.length, "Unexpected errors: ${collector.errors}"); |
| 468 Expect.isTrue(collector.errors.first.message.kind == |
| 469 MessageKind.INJECTED_PUBLIC_MEMBER); |
480 } | 470 } |
481 | 471 |
482 Future testInjectedFunction() async { | 472 Future testInjectedFunction() async { |
483 var compiler = await applyPatch( | 473 var compiler = await applyPatch("", "int _function() => 5;"); |
484 "", | 474 ensure(compiler, "_function", compiler.commonElements.coreLibrary.find, |
485 "int _function() => 5;"); | 475 expectIsFound: false); |
486 ensure(compiler, | 476 ensure(compiler, "_function", compiler.commonElements.coreLibrary.patch.find, |
487 "_function", | 477 checkHasBody: true, expectIsRegular: true); |
488 compiler.commonElements.coreLibrary.find, | |
489 expectIsFound: false); | |
490 ensure(compiler, | |
491 "_function", | |
492 compiler.commonElements.coreLibrary.patch.find, | |
493 checkHasBody: true, expectIsRegular: true); | |
494 | 478 |
495 DiagnosticCollector collector = compiler.diagnosticCollector; | 479 DiagnosticCollector collector = compiler.diagnosticCollector; |
496 Expect.isTrue(collector.warnings.isEmpty, | 480 Expect.isTrue( |
497 "Unexpected warnings: ${collector.warnings}"); | 481 collector.warnings.isEmpty, "Unexpected warnings: ${collector.warnings}"); |
498 Expect.isTrue(collector.errors.isEmpty, | 482 Expect.isTrue( |
499 "Unexpected errors: ${collector.errors}"); | 483 collector.errors.isEmpty, "Unexpected errors: ${collector.errors}"); |
500 } | 484 } |
501 | 485 |
502 Future testInjectedPublicFunction() async { | 486 Future testInjectedPublicFunction() async { |
503 var compiler = await applyPatch( | 487 var compiler = await applyPatch("", "int function() => 5;"); |
504 "", | 488 ensure(compiler, "function", compiler.commonElements.coreLibrary.find, |
505 "int function() => 5;"); | 489 expectIsFound: false); |
506 ensure(compiler, | 490 ensure(compiler, "function", compiler.commonElements.coreLibrary.patch.find, |
507 "function", | 491 checkHasBody: true, expectIsRegular: true); |
508 compiler.commonElements.coreLibrary.find, | |
509 expectIsFound: false); | |
510 ensure(compiler, | |
511 "function", | |
512 compiler.commonElements.coreLibrary.patch.find, | |
513 checkHasBody: true, expectIsRegular: true); | |
514 | 492 |
515 DiagnosticCollector collector = compiler.diagnosticCollector; | 493 DiagnosticCollector collector = compiler.diagnosticCollector; |
516 Expect.isTrue(collector.warnings.isEmpty, | |
517 "Unexpected warnings: ${collector.warnings}"); | |
518 Expect.equals(1, collector.errors.length, | |
519 "Unexpected errors: ${collector.errors}"); | |
520 Expect.isTrue( | 494 Expect.isTrue( |
521 collector.errors.first.message.kind == | 495 collector.warnings.isEmpty, "Unexpected warnings: ${collector.warnings}"); |
522 MessageKind.INJECTED_PUBLIC_MEMBER); | 496 Expect.equals( |
| 497 1, collector.errors.length, "Unexpected errors: ${collector.errors}"); |
| 498 Expect.isTrue(collector.errors.first.message.kind == |
| 499 MessageKind.INJECTED_PUBLIC_MEMBER); |
523 } | 500 } |
524 | 501 |
525 Future testPatchSignatureCheck() async { | 502 Future testPatchSignatureCheck() async { |
526 var compiler = await applyPatch( | 503 var compiler = await applyPatch( |
527 """ | 504 """ |
528 class Class { | 505 class Class { |
529 external String method1(); | 506 external String method1(); |
530 external void method2(String str); | 507 external void method2(String str); |
531 external void method3(String s1); | 508 external void method3(String s1); |
532 external void method4([String str]); | 509 external void method4([String str]); |
(...skipping 14 matching lines...) Expand all Loading... |
547 @patch void method4([String str, int i]) {} | 524 @patch void method4([String str, int i]) {} |
548 @patch void method5() {} | 525 @patch void method5() {} |
549 @patch void method6([String str]) {} | 526 @patch void method6([String str]) {} |
550 @patch void method7([String s2]) {} | 527 @patch void method7([String s2]) {} |
551 @patch void method8({String s2}) {} | 528 @patch void method8({String s2}) {} |
552 @patch void method9(int str) {} | 529 @patch void method9(int str) {} |
553 @patch void method10([int str]) {} | 530 @patch void method10([int str]) {} |
554 @patch void method11({int str}) {} | 531 @patch void method11({int str}) {} |
555 } | 532 } |
556 """); | 533 """); |
557 var container = ensure(compiler, "Class", | 534 var container = ensure( |
558 compiler.commonElements.coreLibrary.find, expectIsPatched: true); | 535 compiler, "Class", compiler.commonElements.coreLibrary.find, |
| 536 expectIsPatched: true); |
559 container.ensureResolved(compiler.resolution); | 537 container.ensureResolved(compiler.resolution); |
560 container.parseNode(compiler.parsingContext); | 538 container.parseNode(compiler.parsingContext); |
561 DiagnosticCollector collector = compiler.diagnosticCollector; | 539 DiagnosticCollector collector = compiler.diagnosticCollector; |
562 | 540 |
563 void expect(String methodName, List infos, List errors) { | 541 void expect(String methodName, List infos, List errors) { |
564 collector.clear(); | 542 collector.clear(); |
565 compiler.resolver.resolveMethodElement( | 543 compiler.resolver.resolveMethodElement(ensure( |
566 ensure(compiler, methodName, container.lookupLocalMember, | 544 compiler, methodName, container.lookupLocalMember, |
567 expectIsPatched: true, checkHasBody: true)); | 545 expectIsPatched: true, checkHasBody: true)); |
568 Expect.equals(0, collector.warnings.length); | 546 Expect.equals(0, collector.warnings.length); |
569 Expect.equals(infos.length, collector.infos.length, | 547 Expect.equals(infos.length, collector.infos.length, |
570 "Unexpected infos: ${collector.infos} on $methodName"); | 548 "Unexpected infos: ${collector.infos} on $methodName"); |
571 for (int i = 0 ; i < infos.length ; i++) { | 549 for (int i = 0; i < infos.length; i++) { |
572 Expect.equals(infos[i], collector.infos.elementAt(i).message.kind); | 550 Expect.equals(infos[i], collector.infos.elementAt(i).message.kind); |
573 } | 551 } |
574 Expect.equals(errors.length, collector.errors.length, | 552 Expect.equals(errors.length, collector.errors.length, |
575 "Unexpected errors: ${collector.errors} on $methodName"); | 553 "Unexpected errors: ${collector.errors} on $methodName"); |
576 for (int i = 0 ; i < errors.length ; i++) { | 554 for (int i = 0; i < errors.length; i++) { |
577 Expect.equals(errors[i], collector.errors.elementAt(i).message.kind); | 555 Expect.equals(errors[i], collector.errors.elementAt(i).message.kind); |
578 } | 556 } |
579 } | 557 } |
580 | 558 |
581 expect("method1", [], [MessageKind.PATCH_RETURN_TYPE_MISMATCH]); | 559 expect("method1", [], [MessageKind.PATCH_RETURN_TYPE_MISMATCH]); |
582 expect("method2", [], | 560 expect("method2", [], [MessageKind.PATCH_REQUIRED_PARAMETER_COUNT_MISMATCH]); |
583 [MessageKind.PATCH_REQUIRED_PARAMETER_COUNT_MISMATCH]); | |
584 expect("method3", [MessageKind.PATCH_POINT_TO_PARAMETER], | 561 expect("method3", [MessageKind.PATCH_POINT_TO_PARAMETER], |
585 [MessageKind.PATCH_PARAMETER_MISMATCH]); | 562 [MessageKind.PATCH_PARAMETER_MISMATCH]); |
586 expect("method4", [], | 563 expect("method4", [], [MessageKind.PATCH_OPTIONAL_PARAMETER_COUNT_MISMATCH]); |
587 [MessageKind.PATCH_OPTIONAL_PARAMETER_COUNT_MISMATCH]); | 564 expect("method5", [], [MessageKind.PATCH_OPTIONAL_PARAMETER_COUNT_MISMATCH]); |
588 expect("method5", [], | 565 expect("method6", [], [MessageKind.PATCH_OPTIONAL_PARAMETER_NAMED_MISMATCH]); |
589 [MessageKind.PATCH_OPTIONAL_PARAMETER_COUNT_MISMATCH]); | |
590 expect("method6", [], | |
591 [MessageKind.PATCH_OPTIONAL_PARAMETER_NAMED_MISMATCH]); | |
592 expect("method7", [MessageKind.PATCH_POINT_TO_PARAMETER], | 566 expect("method7", [MessageKind.PATCH_POINT_TO_PARAMETER], |
593 [MessageKind.PATCH_PARAMETER_MISMATCH]); | 567 [MessageKind.PATCH_PARAMETER_MISMATCH]); |
594 expect("method8", [MessageKind.PATCH_POINT_TO_PARAMETER], | 568 expect("method8", [MessageKind.PATCH_POINT_TO_PARAMETER], |
595 [MessageKind.PATCH_PARAMETER_MISMATCH]); | 569 [MessageKind.PATCH_PARAMETER_MISMATCH]); |
596 expect("method9", [MessageKind.PATCH_POINT_TO_PARAMETER], | 570 expect("method9", [MessageKind.PATCH_POINT_TO_PARAMETER], |
597 [MessageKind.PATCH_PARAMETER_TYPE_MISMATCH]); | 571 [MessageKind.PATCH_PARAMETER_TYPE_MISMATCH]); |
598 expect("method10", [MessageKind.PATCH_POINT_TO_PARAMETER], | 572 expect("method10", [MessageKind.PATCH_POINT_TO_PARAMETER], |
599 [MessageKind.PATCH_PARAMETER_TYPE_MISMATCH]); | 573 [MessageKind.PATCH_PARAMETER_TYPE_MISMATCH]); |
600 expect("method11", [MessageKind.PATCH_POINT_TO_PARAMETER], | 574 expect("method11", [MessageKind.PATCH_POINT_TO_PARAMETER], |
601 [MessageKind.PATCH_PARAMETER_TYPE_MISMATCH]); | 575 [MessageKind.PATCH_PARAMETER_TYPE_MISMATCH]); |
602 } | 576 } |
603 | 577 |
604 Future testExternalWithoutImplementationTopLevel() async { | 578 Future testExternalWithoutImplementationTopLevel() async { |
605 var compiler = await applyPatch( | 579 var compiler = await applyPatch( |
606 """ | 580 """ |
607 external void foo(); | 581 external void foo(); |
608 """, | 582 """, |
609 """ | 583 """ |
610 // @patch void foo() {} | 584 // @patch void foo() {} |
611 """); | 585 """); |
612 var function = ensure(compiler, "foo", | 586 var function = |
613 compiler.commonElements.coreLibrary.find); | 587 ensure(compiler, "foo", compiler.commonElements.coreLibrary.find); |
614 compiler.resolver.resolve(function); | 588 compiler.resolver.resolve(function); |
615 DiagnosticCollector collector = compiler.diagnosticCollector; | 589 DiagnosticCollector collector = compiler.diagnosticCollector; |
616 Expect.isTrue(collector.warnings.isEmpty, | 590 Expect.isTrue( |
617 "Unexpected warnings: ${collector.warnings}"); | 591 collector.warnings.isEmpty, "Unexpected warnings: ${collector.warnings}"); |
618 print('testExternalWithoutImplementationTopLevel:${collector.errors}'); | 592 print('testExternalWithoutImplementationTopLevel:${collector.errors}'); |
619 Expect.equals(1, collector.errors.length); | 593 Expect.equals(1, collector.errors.length); |
620 Expect.isTrue( | 594 Expect.isTrue(collector.errors.first.message.kind == |
621 collector.errors.first.message.kind == | 595 MessageKind.PATCH_EXTERNAL_WITHOUT_IMPLEMENTATION); |
622 MessageKind.PATCH_EXTERNAL_WITHOUT_IMPLEMENTATION); | |
623 Expect.stringEquals('External method without an implementation.', | 596 Expect.stringEquals('External method without an implementation.', |
624 collector.errors.first.message.toString()); | 597 collector.errors.first.message.toString()); |
625 } | 598 } |
626 | 599 |
627 Future testExternalWithoutImplementationMember() async { | 600 Future testExternalWithoutImplementationMember() async { |
628 var compiler = await applyPatch( | 601 var compiler = await applyPatch( |
629 """ | 602 """ |
630 class Class { | 603 class Class { |
631 external void foo(); | 604 external void foo(); |
632 } | 605 } |
633 """, | 606 """, |
634 """ | 607 """ |
635 @patch class Class { | 608 @patch class Class { |
636 // @patch void foo() {} | 609 // @patch void foo() {} |
637 } | 610 } |
638 """); | 611 """); |
639 var container = ensure(compiler, "Class", | 612 var container = ensure( |
640 compiler.commonElements.coreLibrary.find, expectIsPatched: true); | 613 compiler, "Class", compiler.commonElements.coreLibrary.find, |
| 614 expectIsPatched: true); |
641 container.parseNode(compiler.parsingContext); | 615 container.parseNode(compiler.parsingContext); |
642 DiagnosticCollector collector = compiler.diagnosticCollector; | 616 DiagnosticCollector collector = compiler.diagnosticCollector; |
643 collector.clear(); | 617 collector.clear(); |
644 compiler.resolver.resolveMethodElement( | 618 compiler.resolver.resolveMethodElement( |
645 ensure(compiler, "foo", container.lookupLocalMember)); | 619 ensure(compiler, "foo", container.lookupLocalMember)); |
646 Expect.isTrue(collector.warnings.isEmpty, | 620 Expect.isTrue( |
647 "Unexpected warnings: ${collector.warnings}"); | 621 collector.warnings.isEmpty, "Unexpected warnings: ${collector.warnings}"); |
648 print('testExternalWithoutImplementationMember:${collector.errors}'); | 622 print('testExternalWithoutImplementationMember:${collector.errors}'); |
649 Expect.equals(1, collector.errors.length); | 623 Expect.equals(1, collector.errors.length); |
650 Expect.isTrue( | 624 Expect.isTrue(collector.errors.first.message.kind == |
651 collector.errors.first.message.kind == | 625 MessageKind.PATCH_EXTERNAL_WITHOUT_IMPLEMENTATION); |
652 MessageKind.PATCH_EXTERNAL_WITHOUT_IMPLEMENTATION); | |
653 Expect.stringEquals('External method without an implementation.', | 626 Expect.stringEquals('External method without an implementation.', |
654 collector.errors.first.message.toString()); | 627 collector.errors.first.message.toString()); |
655 } | 628 } |
656 | 629 |
657 Future testIsSubclass() async { | 630 Future testIsSubclass() async { |
658 var compiler = await applyPatch( | 631 var compiler = await applyPatch( |
659 """ | 632 """ |
660 class A {} | 633 class A {} |
661 """, | 634 """, |
662 """ | 635 """ |
663 @patch class A {} | 636 @patch class A {} |
664 """); | 637 """); |
665 ClassElement cls = ensure(compiler, "A", | 638 ClassElement cls = ensure( |
666 compiler.commonElements.coreLibrary.find, expectIsPatched: true); | 639 compiler, "A", compiler.commonElements.coreLibrary.find, |
| 640 expectIsPatched: true); |
667 ClassElement patch = cls.patch; | 641 ClassElement patch = cls.patch; |
668 Expect.isTrue(cls != patch); | 642 Expect.isTrue(cls != patch); |
669 Expect.isTrue(cls.isSubclassOf(patch)); | 643 Expect.isTrue(cls.isSubclassOf(patch)); |
670 Expect.isTrue(patch.isSubclassOf(cls)); | 644 Expect.isTrue(patch.isSubclassOf(cls)); |
671 } | 645 } |
672 | 646 |
673 Future testPatchNonExistingTopLevel() async { | 647 Future testPatchNonExistingTopLevel() async { |
674 var compiler = await applyPatch( | 648 var compiler = await applyPatch( |
675 """ | 649 """ |
676 // class Class {} | 650 // class Class {} |
677 """, | 651 """, |
678 """ | 652 """ |
679 @patch class Class {} | 653 @patch class Class {} |
680 """); | 654 """); |
681 DiagnosticCollector collector = compiler.diagnosticCollector; | 655 DiagnosticCollector collector = compiler.diagnosticCollector; |
682 Expect.isTrue(collector.warnings.isEmpty, | 656 Expect.isTrue( |
683 "Unexpected warnings: ${collector.warnings}"); | 657 collector.warnings.isEmpty, "Unexpected warnings: ${collector.warnings}"); |
684 print('testPatchNonExistingTopLevel:${collector.errors}'); | 658 print('testPatchNonExistingTopLevel:${collector.errors}'); |
685 Expect.equals(1, collector.errors.length); | 659 Expect.equals(1, collector.errors.length); |
686 Expect.isTrue( | 660 Expect.isTrue( |
687 collector.errors.first.message.kind == MessageKind.PATCH_NON_EXISTING); | 661 collector.errors.first.message.kind == MessageKind.PATCH_NON_EXISTING); |
688 } | 662 } |
689 | 663 |
690 Future testPatchNonExistingMember() async { | 664 Future testPatchNonExistingMember() async { |
691 var compiler = await applyPatch( | 665 var compiler = await applyPatch( |
692 """ | 666 """ |
693 class Class {} | 667 class Class {} |
694 """, | 668 """, |
695 """ | 669 """ |
696 @patch class Class { | 670 @patch class Class { |
697 @patch void foo() {} | 671 @patch void foo() {} |
698 } | 672 } |
699 """); | 673 """); |
700 var container = ensure(compiler, "Class", | 674 var container = ensure( |
701 compiler.commonElements.coreLibrary.find, expectIsPatched: true); | 675 compiler, "Class", compiler.commonElements.coreLibrary.find, |
| 676 expectIsPatched: true); |
702 container.parseNode(compiler.parsingContext); | 677 container.parseNode(compiler.parsingContext); |
703 DiagnosticCollector collector = compiler.diagnosticCollector; | 678 DiagnosticCollector collector = compiler.diagnosticCollector; |
704 | 679 |
705 Expect.isTrue(collector.warnings.isEmpty, | 680 Expect.isTrue( |
706 "Unexpected warnings: ${collector.warnings}"); | 681 collector.warnings.isEmpty, "Unexpected warnings: ${collector.warnings}"); |
707 print('testPatchNonExistingMember:${collector.errors}'); | 682 print('testPatchNonExistingMember:${collector.errors}'); |
708 Expect.equals(1, collector.errors.length); | 683 Expect.equals(1, collector.errors.length); |
709 Expect.isTrue( | 684 Expect.isTrue( |
710 collector.errors.first.message.kind == MessageKind.PATCH_NON_EXISTING); | 685 collector.errors.first.message.kind == MessageKind.PATCH_NON_EXISTING); |
711 } | 686 } |
712 | 687 |
713 Future testPatchNonPatchablePatch() async { | 688 Future testPatchNonPatchablePatch() async { |
714 var compiler = await applyPatch( | 689 var compiler = await applyPatch( |
715 """ | 690 """ |
716 external get foo; | 691 external get foo; |
717 """, | 692 """, |
718 """ | 693 """ |
719 @patch var foo; | 694 @patch var foo; |
720 """); | 695 """); |
721 ensure(compiler, "foo", compiler.commonElements.coreLibrary.find); | 696 ensure(compiler, "foo", compiler.commonElements.coreLibrary.find); |
722 | 697 |
723 DiagnosticCollector collector = compiler.diagnosticCollector; | 698 DiagnosticCollector collector = compiler.diagnosticCollector; |
724 Expect.isTrue(collector.warnings.isEmpty, | 699 Expect.isTrue( |
725 "Unexpected warnings: ${collector.warnings}"); | 700 collector.warnings.isEmpty, "Unexpected warnings: ${collector.warnings}"); |
726 print('testPatchNonPatchablePatch:${collector.errors}'); | 701 print('testPatchNonPatchablePatch:${collector.errors}'); |
727 Expect.equals(1, collector.errors.length); | 702 Expect.equals(1, collector.errors.length); |
728 Expect.isTrue( | 703 Expect.isTrue( |
729 collector.errors.first.message.kind == MessageKind.PATCH_NONPATCHABLE); | 704 collector.errors.first.message.kind == MessageKind.PATCH_NONPATCHABLE); |
730 } | 705 } |
731 | 706 |
732 Future testPatchNonPatchableOrigin() async { | 707 Future testPatchNonPatchableOrigin() async { |
733 var compiler = await applyPatch( | 708 var compiler = await applyPatch( |
734 """ | 709 """ |
735 external var foo; | 710 external var foo; |
736 """, | 711 """, |
737 """ | 712 """ |
738 @patch get foo => 0; | 713 @patch get foo => 0; |
739 """); | 714 """); |
740 ensure(compiler, "foo", compiler.commonElements.coreLibrary.find); | 715 ensure(compiler, "foo", compiler.commonElements.coreLibrary.find); |
741 | 716 |
742 DiagnosticCollector collector = compiler.diagnosticCollector; | 717 DiagnosticCollector collector = compiler.diagnosticCollector; |
743 Expect.isTrue(collector.warnings.isEmpty, | 718 Expect.isTrue( |
744 "Unexpected warnings: ${collector.warnings}"); | 719 collector.warnings.isEmpty, "Unexpected warnings: ${collector.warnings}"); |
745 print('testPatchNonPatchableOrigin:${collector.errors}'); | 720 print('testPatchNonPatchableOrigin:${collector.errors}'); |
746 Expect.equals(2, collector.errors.length); | 721 Expect.equals(2, collector.errors.length); |
747 Expect.equals( | 722 Expect.equals( |
748 MessageKind.EXTRANEOUS_MODIFIER, collector.errors.first.message.kind); | 723 MessageKind.EXTRANEOUS_MODIFIER, collector.errors.first.message.kind); |
749 Expect.equals( | 724 Expect.equals( |
750 // TODO(ahe): Eventually, this error should be removed as it will be | 725 // TODO(ahe): Eventually, this error should be removed as it will be |
751 // handled by the regular parser. | 726 // handled by the regular parser. |
752 MessageKind.PATCH_NONPATCHABLE, | 727 MessageKind.PATCH_NONPATCHABLE, |
753 collector.errors.elementAt(1).message.kind); | 728 collector.errors.elementAt(1).message.kind); |
754 } | 729 } |
(...skipping 23 matching lines...) Expand all Loading... |
778 """ | 753 """ |
779 class Class { | 754 class Class { |
780 void foo() {} | 755 void foo() {} |
781 } | 756 } |
782 """, | 757 """, |
783 """ | 758 """ |
784 @patch class Class { | 759 @patch class Class { |
785 @patch void foo() {} | 760 @patch void foo() {} |
786 } | 761 } |
787 """); | 762 """); |
788 var container = ensure(compiler, "Class", | 763 var container = ensure( |
789 compiler.commonElements.coreLibrary.find, expectIsPatched: true); | 764 compiler, "Class", compiler.commonElements.coreLibrary.find, |
| 765 expectIsPatched: true); |
790 container.parseNode(compiler.parsingContext); | 766 container.parseNode(compiler.parsingContext); |
791 | 767 |
792 DiagnosticCollector collector = compiler.diagnosticCollector; | 768 DiagnosticCollector collector = compiler.diagnosticCollector; |
793 print('testPatchNonExternalMember.errors:${collector.errors}'); | 769 print('testPatchNonExternalMember.errors:${collector.errors}'); |
794 print('testPatchNonExternalMember.warnings:${collector.warnings}'); | 770 print('testPatchNonExternalMember.warnings:${collector.warnings}'); |
795 Expect.equals(1, collector.errors.length); | 771 Expect.equals(1, collector.errors.length); |
796 Expect.isTrue( | 772 Expect.isTrue( |
797 collector.errors.first.message.kind == MessageKind.PATCH_NON_EXTERNAL); | 773 collector.errors.first.message.kind == MessageKind.PATCH_NON_EXTERNAL); |
798 Expect.equals(0, collector.warnings.length); | 774 Expect.equals(0, collector.warnings.length); |
799 Expect.equals(1, collector.infos.length); | 775 Expect.equals(1, collector.infos.length); |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
910 @patch void foo() {} | 886 @patch void foo() {} |
911 """); | 887 """); |
912 DiagnosticCollector collector = compiler.diagnosticCollector; | 888 DiagnosticCollector collector = compiler.diagnosticCollector; |
913 print('testPatchNonClass.errors:${collector.errors}'); | 889 print('testPatchNonClass.errors:${collector.errors}'); |
914 print('testPatchNonClass.warnings:${collector.warnings}'); | 890 print('testPatchNonClass.warnings:${collector.warnings}'); |
915 Expect.equals(1, collector.errors.length); | 891 Expect.equals(1, collector.errors.length); |
916 Expect.isTrue( | 892 Expect.isTrue( |
917 collector.errors.first.message.kind == MessageKind.PATCH_NON_FUNCTION); | 893 collector.errors.first.message.kind == MessageKind.PATCH_NON_FUNCTION); |
918 Expect.equals(0, collector.warnings.length); | 894 Expect.equals(0, collector.warnings.length); |
919 Expect.equals(1, collector.infos.length); | 895 Expect.equals(1, collector.infos.length); |
920 Expect.isTrue( | 896 Expect.isTrue(collector.infos.first.message.kind == |
921 collector.infos.first.message.kind == | 897 MessageKind.PATCH_POINT_TO_FUNCTION); |
922 MessageKind.PATCH_POINT_TO_FUNCTION); | |
923 } | 898 } |
924 | 899 |
925 Future testPatchAndSelector() async { | 900 Future testPatchAndSelector() async { |
926 var compiler = await applyPatch( | 901 var compiler = await applyPatch( |
927 """ | 902 """ |
928 class A { | 903 class A { |
929 external void clear(); | 904 external void clear(); |
930 } | 905 } |
931 class B extends A { | 906 class B extends A { |
932 } | 907 } |
933 """, | 908 """, |
934 """ | 909 """ |
935 @patch class A { | 910 @patch class A { |
936 int method() => 0; | 911 int method() => 0; |
937 @patch void clear() {} | 912 @patch void clear() {} |
938 } | 913 } |
939 """, | 914 """, |
940 main: """ | 915 main: """ |
941 main () { | 916 main () { |
942 new A(); // ensure A and B are instantiated | 917 new A(); // ensure A and B are instantiated |
943 new B(); | 918 new B(); |
944 } | 919 } |
945 """, | 920 """, |
946 runCompiler: true, analyzeOnly: true); | 921 runCompiler: true, |
| 922 analyzeOnly: true); |
947 World world = compiler.world; | 923 World world = compiler.world; |
948 world.populate(); | 924 world.populate(); |
949 | 925 |
950 ClassElement cls = ensure(compiler, "A", | 926 ClassElement cls = ensure( |
951 compiler.commonElements.coreLibrary.find, expectIsPatched: true); | 927 compiler, "A", compiler.commonElements.coreLibrary.find, |
| 928 expectIsPatched: true); |
952 cls.ensureResolved(compiler.resolution); | 929 cls.ensureResolved(compiler.resolution); |
953 | 930 |
954 ensure(compiler, "method", cls.patch.lookupLocalMember, | 931 ensure(compiler, "method", cls.patch.lookupLocalMember, |
955 checkHasBody: true, expectIsRegular: true); | 932 checkHasBody: true, expectIsRegular: true); |
956 | 933 |
957 ensure(compiler, "clear", cls.lookupLocalMember, | 934 ensure(compiler, "clear", cls.lookupLocalMember, |
958 checkHasBody: true, expectIsPatched: true); | 935 checkHasBody: true, expectIsPatched: true); |
959 | 936 |
960 compiler.phase = Compiler.PHASE_DONE_RESOLVING; | 937 compiler.phase = Compiler.PHASE_DONE_RESOLVING; |
961 | 938 |
962 // Check that a method just in the patch class is a target for a | 939 // Check that a method just in the patch class is a target for a |
963 // typed selector. | 940 // typed selector. |
964 Selector selector = | 941 Selector selector = |
965 new Selector.call(const PublicName('method'), CallStructure.NO_ARGS); | 942 new Selector.call(const PublicName('method'), CallStructure.NO_ARGS); |
966 TypeMask typeMask = new TypeMask.exact(cls, world); | 943 TypeMask typeMask = new TypeMask.exact(cls, world); |
967 FunctionElement method = cls.implementation.lookupLocalMember('method'); | 944 FunctionElement method = cls.implementation.lookupLocalMember('method'); |
968 method.computeType(compiler.resolution); | 945 method.computeType(compiler.resolution); |
(...skipping 19 matching lines...) Expand all Loading... |
988 Expect.isTrue(typeMask.canHit(method, selector, world)); | 965 Expect.isTrue(typeMask.canHit(method, selector, world)); |
989 } | 966 } |
990 | 967 |
991 Future testAnalyzeAllInjectedMembers() async { | 968 Future testAnalyzeAllInjectedMembers() async { |
992 Future expect(String patchText, [expectedWarnings]) async { | 969 Future expect(String patchText, [expectedWarnings]) async { |
993 if (expectedWarnings == null) expectedWarnings = []; | 970 if (expectedWarnings == null) expectedWarnings = []; |
994 if (expectedWarnings is! List) { | 971 if (expectedWarnings is! List) { |
995 expectedWarnings = <MessageKind>[expectedWarnings]; | 972 expectedWarnings = <MessageKind>[expectedWarnings]; |
996 } | 973 } |
997 | 974 |
998 var compiler = await applyPatch('', patchText, analyzeAll: true, | 975 var compiler = |
999 analyzeOnly: true); | 976 await applyPatch('', patchText, analyzeAll: true, analyzeOnly: true); |
1000 compiler.librariesToAnalyzeWhenRun = [Uri.parse('dart:core')]; | 977 compiler.librariesToAnalyzeWhenRun = [Uri.parse('dart:core')]; |
1001 await compiler.run(null); | 978 await compiler.run(null); |
1002 DiagnosticCollector collector = compiler.diagnosticCollector; | 979 DiagnosticCollector collector = compiler.diagnosticCollector; |
1003 compareWarningKinds(patchText, expectedWarnings, collector.warnings); | 980 compareWarningKinds(patchText, expectedWarnings, collector.warnings); |
1004 } | 981 } |
1005 | 982 |
1006 await expect('String s = 0;', MessageKind.NOT_ASSIGNABLE); | 983 await expect('String s = 0;', MessageKind.NOT_ASSIGNABLE); |
1007 await expect('void method() { String s = 0; }', MessageKind.NOT_ASSIGNABLE); | 984 await expect('void method() { String s = 0; }', MessageKind.NOT_ASSIGNABLE); |
1008 await expect(''' | 985 await expect( |
| 986 ''' |
1009 class Class { | 987 class Class { |
1010 String s = 0; | 988 String s = 0; |
1011 } | 989 } |
1012 ''', | 990 ''', |
1013 MessageKind.NOT_ASSIGNABLE); | 991 MessageKind.NOT_ASSIGNABLE); |
1014 await expect(''' | 992 await expect( |
| 993 ''' |
1015 class Class { | 994 class Class { |
1016 void method() { | 995 void method() { |
1017 String s = 0; | 996 String s = 0; |
1018 } | 997 } |
1019 } | 998 } |
1020 ''', | 999 ''', |
1021 MessageKind.NOT_ASSIGNABLE); | 1000 MessageKind.NOT_ASSIGNABLE); |
1022 } | 1001 } |
1023 | 1002 |
1024 Future testEffectiveTarget() async { | 1003 Future testEffectiveTarget() async { |
1025 String origin = """ | 1004 String origin = """ |
1026 class A { | 1005 class A { |
1027 A() : super(); | 1006 A() : super(); |
1028 factory A.forward() = B.patchTarget; | 1007 factory A.forward() = B.patchTarget; |
1029 factory A.forwardOne() = B.patchFactory; | 1008 factory A.forwardOne() = B.patchFactory; |
1030 factory A.forwardTwo() = B.reflectBack; | 1009 factory A.forwardTwo() = B.reflectBack; |
1031 factory A.forwardThree() = B.patchInjected; | 1010 factory A.forwardThree() = B.patchInjected; |
(...skipping 16 matching lines...) Expand all Loading... |
1048 @patch | 1027 @patch |
1049 factory B.reflectBack() = B.originTarget; | 1028 factory B.reflectBack() = B.originTarget; |
1050 @patch | 1029 @patch |
1051 factory B.patchInjected() = _C.injected; | 1030 factory B.patchInjected() = _C.injected; |
1052 } | 1031 } |
1053 class _C extends B { | 1032 class _C extends B { |
1054 _C.injected() : super.patchTarget(); | 1033 _C.injected() : super.patchTarget(); |
1055 } | 1034 } |
1056 """; | 1035 """; |
1057 | 1036 |
1058 var compiler = await applyPatch(origin, patch, analyzeAll: true, | 1037 var compiler = await applyPatch(origin, patch, |
1059 analyzeOnly: true, runCompiler: true); | 1038 analyzeAll: true, analyzeOnly: true, runCompiler: true); |
1060 ClassElement clsA = compiler.commonElements.coreLibrary.find("A"); | 1039 ClassElement clsA = compiler.commonElements.coreLibrary.find("A"); |
1061 ClassElement clsB = compiler.commonElements.coreLibrary.find("B"); | 1040 ClassElement clsB = compiler.commonElements.coreLibrary.find("B"); |
1062 | 1041 |
1063 ConstructorElement forward = clsA.lookupConstructor("forward"); | 1042 ConstructorElement forward = clsA.lookupConstructor("forward"); |
1064 ConstructorElement target = forward.effectiveTarget; | 1043 ConstructorElement target = forward.effectiveTarget; |
1065 Expect.isTrue(target.isPatched, "Unexpected target $target for $forward"); | 1044 Expect.isTrue(target.isPatched, "Unexpected target $target for $forward"); |
1066 Expect.isFalse(target.isPatch, "Unexpected target $target for $forward"); | 1045 Expect.isFalse(target.isPatch, "Unexpected target $target for $forward"); |
1067 Expect.equals("patchTarget", target.name); | 1046 Expect.equals("patchTarget", target.name); |
1068 | 1047 |
1069 ConstructorElement forwardOne = clsA.lookupConstructor("forwardOne"); | 1048 ConstructorElement forwardOne = clsA.lookupConstructor("forwardOne"); |
1070 target = forwardOne.effectiveTarget; | 1049 target = forwardOne.effectiveTarget; |
1071 Expect.isFalse(forwardOne.isMalformed); | 1050 Expect.isFalse(forwardOne.isMalformed); |
1072 Expect.isFalse(target.isPatch, "Unexpected target $target for $forwardOne"); | 1051 Expect.isFalse(target.isPatch, "Unexpected target $target for $forwardOne"); |
1073 Expect.equals("patchFactory", target.name); | 1052 Expect.equals("patchFactory", target.name); |
1074 | 1053 |
1075 ConstructorElement forwardTwo = clsA.lookupConstructor("forwardTwo"); | 1054 ConstructorElement forwardTwo = clsA.lookupConstructor("forwardTwo"); |
1076 target = forwardTwo.effectiveTarget; | 1055 target = forwardTwo.effectiveTarget; |
1077 Expect.isFalse(forwardTwo.isMalformed); | 1056 Expect.isFalse(forwardTwo.isMalformed); |
1078 Expect.isFalse(target.isPatch, "Unexpected target $target for $forwardTwo"); | 1057 Expect.isFalse(target.isPatch, "Unexpected target $target for $forwardTwo"); |
1079 Expect.equals("originTarget", target.name); | 1058 Expect.equals("originTarget", target.name); |
1080 | 1059 |
1081 ConstructorElement forwardThree = clsA.lookupConstructor("forwardThree"); | 1060 ConstructorElement forwardThree = clsA.lookupConstructor("forwardThree"); |
1082 target = forwardThree.effectiveTarget; | 1061 target = forwardThree.effectiveTarget; |
1083 Expect.isFalse(forwardThree.isMalformed); | 1062 Expect.isFalse(forwardThree.isMalformed); |
1084 Expect.isTrue(target.isInjected, | 1063 Expect.isTrue( |
1085 "Unexpected target $target for $forwardThree"); | 1064 target.isInjected, "Unexpected target $target for $forwardThree"); |
1086 Expect.equals("injected", target.name); | 1065 Expect.equals("injected", target.name); |
1087 } | 1066 } |
1088 | 1067 |
1089 Future testTypecheckPatchedMembers() async { | 1068 Future testTypecheckPatchedMembers() async { |
1090 String originText = "external void method();"; | 1069 String originText = "external void method();"; |
1091 String patchText = """ | 1070 String patchText = """ |
1092 @patch void method() { | 1071 @patch void method() { |
1093 String s = 0; | 1072 String s = 0; |
1094 } | 1073 } |
1095 """; | 1074 """; |
1096 var compiler = await applyPatch(originText, patchText, | 1075 var compiler = await applyPatch(originText, patchText, |
1097 analyzeAll: true, analyzeOnly: true); | 1076 analyzeAll: true, analyzeOnly: true); |
1098 compiler.librariesToAnalyzeWhenRun = [Uri.parse('dart:core')]; | 1077 compiler.librariesToAnalyzeWhenRun = [Uri.parse('dart:core')]; |
1099 await compiler.run(null); | 1078 await compiler.run(null); |
1100 DiagnosticCollector collector = compiler.diagnosticCollector; | 1079 DiagnosticCollector collector = compiler.diagnosticCollector; |
1101 compareWarningKinds(patchText, | 1080 compareWarningKinds( |
1102 [MessageKind.NOT_ASSIGNABLE], collector.warnings); | 1081 patchText, [MessageKind.NOT_ASSIGNABLE], collector.warnings); |
1103 } | 1082 } |
1104 | 1083 |
1105 main() { | 1084 main() { |
1106 asyncTest(() async { | 1085 asyncTest(() async { |
1107 await testPatchConstructor(); | 1086 await testPatchConstructor(); |
1108 await testPatchRedirectingConstructor(); | 1087 await testPatchRedirectingConstructor(); |
1109 await testPatchFunction(); | 1088 await testPatchFunction(); |
1110 await testPatchFunctionMetadata(); | 1089 await testPatchFunctionMetadata(); |
1111 await testPatchMember(); | 1090 await testPatchMember(); |
1112 await testPatchGetter(); | 1091 await testPatchGetter(); |
(...skipping 25 matching lines...) Expand all Loading... |
1138 await testPatchNonFunction(); | 1117 await testPatchNonFunction(); |
1139 | 1118 |
1140 await testPatchAndSelector(); | 1119 await testPatchAndSelector(); |
1141 | 1120 |
1142 await testEffectiveTarget(); | 1121 await testEffectiveTarget(); |
1143 | 1122 |
1144 await testAnalyzeAllInjectedMembers(); | 1123 await testAnalyzeAllInjectedMembers(); |
1145 await testTypecheckPatchedMembers(); | 1124 await testTypecheckPatchedMembers(); |
1146 }); | 1125 }); |
1147 } | 1126 } |
OLD | NEW |