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 /** | 5 /** |
6 * This library contains the infrastructure to parse and integrate patch files. | 6 * This library contains the infrastructure to parse and integrate patch files. |
7 * | 7 * |
8 * Three types of elements can be patched: [LibraryElement], [ClassElement], | 8 * Three types of elements can be patched: [LibraryElement], [ClassElement], |
9 * [FunctionElement]. Patches are introduced in patch libraries which are loaded | 9 * [FunctionElement]. Patches are introduced in patch libraries which are loaded |
10 * together with the corresponding origin library. Which libraries that are | 10 * together with the corresponding origin library. Which libraries that are |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
115 library dart2js.patchparser; | 115 library dart2js.patchparser; |
116 | 116 |
117 import 'dart:async'; | 117 import 'dart:async'; |
118 | 118 |
119 import 'constants/values.dart' show | 119 import 'constants/values.dart' show |
120 ConstantValue; | 120 ConstantValue; |
121 import 'compiler.dart' show | 121 import 'compiler.dart' show |
122 Compiler; | 122 Compiler; |
123 import 'common/tasks.dart' show | 123 import 'common/tasks.dart' show |
124 CompilerTask; | 124 CompilerTask; |
| 125 import 'dart_types.dart' show |
| 126 DartType; |
125 import 'diagnostics/diagnostic_listener.dart'; | 127 import 'diagnostics/diagnostic_listener.dart'; |
126 import 'diagnostics/messages.dart' show | 128 import 'diagnostics/messages.dart' show |
127 MessageKind; | 129 MessageKind; |
128 import 'elements/elements.dart'; | 130 import 'elements/elements.dart'; |
129 import 'elements/modelx.dart' show | 131 import 'elements/modelx.dart' show |
130 BaseFunctionElementX, | 132 BaseFunctionElementX, |
131 ClassElementX, | 133 ClassElementX, |
132 GetterElementX, | 134 GetterElementX, |
133 LibraryElementX, | 135 LibraryElementX, |
134 MetadataAnnotationX, | 136 MetadataAnnotationX, |
(...skipping 28 matching lines...) Expand all Loading... |
163 /** | 165 /** |
164 * Scans a library patch file, applies the method patches and | 166 * Scans a library patch file, applies the method patches and |
165 * injections to the library, and returns a list of class | 167 * injections to the library, and returns a list of class |
166 * patches. | 168 * patches. |
167 */ | 169 */ |
168 Future patchLibrary(LibraryLoader loader, | 170 Future patchLibrary(LibraryLoader loader, |
169 Uri patchUri, LibraryElement originLibrary) { | 171 Uri patchUri, LibraryElement originLibrary) { |
170 return compiler.readScript(originLibrary, patchUri) | 172 return compiler.readScript(originLibrary, patchUri) |
171 .then((Script script) { | 173 .then((Script script) { |
172 var patchLibrary = new LibraryElementX(script, null, originLibrary); | 174 var patchLibrary = new LibraryElementX(script, null, originLibrary); |
173 return compiler.withCurrentElement(patchLibrary, () { | 175 return reporter.withCurrentElement(patchLibrary, () { |
174 loader.registerNewLibrary(patchLibrary); | 176 loader.registerNewLibrary(patchLibrary); |
175 compiler.withCurrentElement(patchLibrary.entryCompilationUnit, () { | 177 reporter.withCurrentElement(patchLibrary.entryCompilationUnit, () { |
176 // This patches the elements of the patch library into [library]. | 178 // This patches the elements of the patch library into [library]. |
177 // Injected elements are added directly under the compilation unit. | 179 // Injected elements are added directly under the compilation unit. |
178 // Patch elements are stored on the patched functions or classes. | 180 // Patch elements are stored on the patched functions or classes. |
179 scanLibraryElements(patchLibrary.entryCompilationUnit); | 181 scanLibraryElements(patchLibrary.entryCompilationUnit); |
180 }); | 182 }); |
181 return loader.processLibraryTags(patchLibrary); | 183 return loader.processLibraryTags(patchLibrary); |
182 }); | 184 }); |
183 }); | 185 }); |
184 } | 186 } |
185 | 187 |
186 void scanLibraryElements(CompilationUnitElement compilationUnit) { | 188 void scanLibraryElements(CompilationUnitElement compilationUnit) { |
187 measure(() { | 189 measure(() { |
188 // TODO(johnniwinther): Test that parts and exports are handled correctly. | 190 // TODO(johnniwinther): Test that parts and exports are handled correctly. |
189 Script script = compilationUnit.script; | 191 Script script = compilationUnit.script; |
190 Token tokens = new Scanner(script.file).tokenize(); | 192 Token tokens = new Scanner(script.file).tokenize(); |
191 Function idGenerator = compiler.getNextFreeClassId; | 193 Function idGenerator = compiler.getNextFreeClassId; |
192 Listener patchListener = new PatchElementListener(compiler, | 194 Listener patchListener = new PatchElementListener(compiler, |
193 compilationUnit, | 195 compilationUnit, |
194 idGenerator); | 196 idGenerator); |
195 try { | 197 try { |
196 new PartialParser(patchListener).parseUnit(tokens); | 198 new PartialParser(patchListener).parseUnit(tokens); |
197 } on ParserError catch (e) { | 199 } on ParserError catch (e) { |
198 // No need to recover from a parser error in platform libraries, user | 200 // No need to recover from a parser error in platform libraries, user |
199 // will never see this if the libraries are tested correctly. | 201 // will never see this if the libraries are tested correctly. |
200 compiler.internalError( | 202 reporter.internalError( |
201 compilationUnit, "Parser error in patch file: $e"); | 203 compilationUnit, "Parser error in patch file: $e"); |
202 } | 204 } |
203 }); | 205 }); |
204 } | 206 } |
205 | 207 |
206 void parsePatchClassNode(PartialClassElement cls) { | 208 void parsePatchClassNode(PartialClassElement cls) { |
207 // Parse [PartialClassElement] using a "patch"-aware parser instead | 209 // Parse [PartialClassElement] using a "patch"-aware parser instead |
208 // of calling its [parseNode] method. | 210 // of calling its [parseNode] method. |
209 if (cls.cachedNode != null) return; | 211 if (cls.cachedNode != null) return; |
210 | 212 |
211 measure(() => compiler.withCurrentElement(cls, () { | 213 measure(() => reporter.withCurrentElement(cls, () { |
212 MemberListener listener = new PatchMemberListener(compiler, cls); | 214 MemberListener listener = new PatchMemberListener(compiler, cls); |
213 Parser parser = new PatchClassElementParser(listener); | 215 Parser parser = new PatchClassElementParser(listener); |
214 try { | 216 try { |
215 Token token = parser.parseTopLevelDeclaration(cls.beginToken); | 217 Token token = parser.parseTopLevelDeclaration(cls.beginToken); |
216 assert(identical(token, cls.endToken.next)); | 218 assert(identical(token, cls.endToken.next)); |
217 } on ParserError catch (e) { | 219 } on ParserError catch (e) { |
218 // No need to recover from a parser error in platform libraries, user | 220 // No need to recover from a parser error in platform libraries, user |
219 // will never see this if the libraries are tested correctly. | 221 // will never see this if the libraries are tested correctly. |
220 compiler.internalError( | 222 reporter.internalError( |
221 cls, "Parser error in patch file: $e"); | 223 cls, "Parser error in patch file: $e"); |
222 } | 224 } |
223 cls.cachedNode = listener.popNode(); | 225 cls.cachedNode = listener.popNode(); |
224 assert(listener.nodes.isEmpty); | 226 assert(listener.nodes.isEmpty); |
225 })); | 227 })); |
226 } | 228 } |
227 } | 229 } |
228 | 230 |
229 class PatchMemberListener extends MemberListener { | 231 class PatchMemberListener extends MemberListener { |
230 final Compiler compiler; | 232 final Compiler compiler; |
231 | 233 |
232 PatchMemberListener(Compiler compiler, ClassElement enclosingClass) | 234 PatchMemberListener(Compiler compiler, ClassElement enclosingClass) |
233 : this.compiler = compiler, | 235 : this.compiler = compiler, |
234 super(compiler, enclosingClass); | 236 super(compiler.reporter, enclosingClass); |
235 | 237 |
236 @override | 238 @override |
237 void addMember(Element patch) { | 239 void addMember(Element patch) { |
238 addMetadata(patch); | 240 addMetadata(patch); |
239 | 241 |
240 PatchVersion patchVersion = getPatchVersion(compiler, patch); | 242 PatchVersion patchVersion = getPatchVersion(compiler, patch); |
241 if (patchVersion != null) { | 243 if (patchVersion != null) { |
242 if (patchVersion.isActive(compiler.patchVersion)) { | 244 if (patchVersion.isActive(compiler.patchVersion)) { |
243 Element origin = enclosingClass.origin.localLookup(patch.name); | 245 Element origin = enclosingClass.origin.localLookup(patch.name); |
244 patchElement(compiler, origin, patch); | 246 patchElement(compiler, reporter, origin, patch); |
245 enclosingClass.addMember(patch, listener); | 247 enclosingClass.addMember(patch, reporter); |
246 } else { | 248 } else { |
247 // Skip this element. | 249 // Skip this element. |
248 } | 250 } |
249 } else { | 251 } else { |
250 enclosingClass.addMember(patch, listener); | 252 enclosingClass.addMember(patch, reporter); |
251 } | 253 } |
252 } | 254 } |
253 } | 255 } |
254 | 256 |
255 /** | 257 /** |
256 * Partial parser for patch files that also handles the members of class | 258 * Partial parser for patch files that also handles the members of class |
257 * declarations. | 259 * declarations. |
258 */ | 260 */ |
259 class PatchClassElementParser extends PartialParser { | 261 class PatchClassElementParser extends PartialParser { |
260 PatchClassElementParser(Listener listener) : super(listener); | 262 PatchClassElementParser(Listener listener) : super(listener); |
261 | 263 |
262 Token parseClassBody(Token token) => fullParseClassBody(token); | 264 Token parseClassBody(Token token) => fullParseClassBody(token); |
263 } | 265 } |
264 | 266 |
265 /** | 267 /** |
266 * Extension of [ElementListener] for parsing patch files. | 268 * Extension of [ElementListener] for parsing patch files. |
267 */ | 269 */ |
268 class PatchElementListener extends ElementListener implements Listener { | 270 class PatchElementListener extends ElementListener implements Listener { |
269 final Compiler compiler; | 271 final Compiler compiler; |
270 | 272 |
271 PatchElementListener(Compiler compiler, | 273 PatchElementListener(Compiler compiler, |
272 CompilationUnitElement patchElement, | 274 CompilationUnitElement patchElement, |
273 int idGenerator()) | 275 int idGenerator()) |
274 : this.compiler = compiler, | 276 : this.compiler = compiler, |
275 super(compiler, patchElement, idGenerator); | 277 super(compiler.reporter, patchElement, idGenerator); |
276 | 278 |
277 @override | 279 @override |
278 void pushElement(Element patch) { | 280 void pushElement(Element patch) { |
279 popMetadata(patch); | 281 popMetadata(patch); |
280 | 282 |
281 PatchVersion patchVersion = getPatchVersion(compiler, patch); | 283 PatchVersion patchVersion = getPatchVersion(compiler, patch); |
282 if (patchVersion != null) { | 284 if (patchVersion != null) { |
283 if (patchVersion.isActive(compiler.patchVersion)) { | 285 if (patchVersion.isActive(compiler.patchVersion)) { |
284 LibraryElement originLibrary = compilationUnitElement.library; | 286 LibraryElement originLibrary = compilationUnitElement.library; |
285 assert(originLibrary.isPatched); | 287 assert(originLibrary.isPatched); |
286 Element origin = originLibrary.localLookup(patch.name); | 288 Element origin = originLibrary.localLookup(patch.name); |
287 patchElement(listener, origin, patch); | 289 patchElement(compiler, reporter, origin, patch); |
288 compilationUnitElement.addMember(patch, listener); | 290 compilationUnitElement.addMember(patch, reporter); |
289 } else { | 291 } else { |
290 // Skip this element. | 292 // Skip this element. |
291 } | 293 } |
292 } else { | 294 } else { |
293 compilationUnitElement.addMember(patch, listener); | 295 compilationUnitElement.addMember(patch, reporter); |
294 } | 296 } |
295 } | 297 } |
296 } | 298 } |
297 | 299 |
298 void patchElement(Compiler compiler, | 300 void patchElement(Compiler compiler, |
| 301 DiagnosticReporter reporter, |
299 Element origin, | 302 Element origin, |
300 Element patch) { | 303 Element patch) { |
301 if (origin == null) { | 304 if (origin == null) { |
302 compiler.reportErrorMessage( | 305 reporter.reportErrorMessage( |
303 patch, MessageKind.PATCH_NON_EXISTING, {'name': patch.name}); | 306 patch, MessageKind.PATCH_NON_EXISTING, {'name': patch.name}); |
304 return; | 307 return; |
305 } | 308 } |
306 if (!(origin.isClass || | 309 if (!(origin.isClass || |
307 origin.isConstructor || | 310 origin.isConstructor || |
308 origin.isFunction || | 311 origin.isFunction || |
309 origin.isAbstractField)) { | 312 origin.isAbstractField)) { |
310 // TODO(ahe): Remove this error when the parser rejects all bad modifiers. | 313 // TODO(ahe): Remove this error when the parser rejects all bad modifiers. |
311 compiler.reportErrorMessage(origin, MessageKind.PATCH_NONPATCHABLE); | 314 reporter.reportErrorMessage(origin, MessageKind.PATCH_NONPATCHABLE); |
312 return; | 315 return; |
313 } | 316 } |
314 if (patch.isClass) { | 317 if (patch.isClass) { |
315 tryPatchClass(compiler, origin, patch); | 318 tryPatchClass(compiler, reporter, origin, patch); |
316 } else if (patch.isGetter) { | 319 } else if (patch.isGetter) { |
317 tryPatchGetter(compiler, origin, patch); | 320 tryPatchGetter(reporter, origin, patch); |
318 } else if (patch.isSetter) { | 321 } else if (patch.isSetter) { |
319 tryPatchSetter(compiler, origin, patch); | 322 tryPatchSetter(reporter, origin, patch); |
320 } else if (patch.isConstructor) { | 323 } else if (patch.isConstructor) { |
321 tryPatchConstructor(compiler, origin, patch); | 324 tryPatchConstructor(reporter, origin, patch); |
322 } else if(patch.isFunction) { | 325 } else if(patch.isFunction) { |
323 tryPatchFunction(compiler, origin, patch); | 326 tryPatchFunction(reporter, origin, patch); |
324 } else { | 327 } else { |
325 // TODO(ahe): Remove this error when the parser rejects all bad modifiers. | 328 // TODO(ahe): Remove this error when the parser rejects all bad modifiers. |
326 compiler.reportErrorMessage(patch, MessageKind.PATCH_NONPATCHABLE); | 329 reporter.reportErrorMessage(patch, MessageKind.PATCH_NONPATCHABLE); |
327 } | 330 } |
328 } | 331 } |
329 | 332 |
330 void tryPatchClass(Compiler compiler, | 333 void tryPatchClass(Compiler compiler, |
| 334 DiagnosticReporter reporter, |
331 Element origin, | 335 Element origin, |
332 ClassElement patch) { | 336 ClassElement patch) { |
333 if (!origin.isClass) { | 337 if (!origin.isClass) { |
334 compiler.reportError( | 338 reporter.reportError( |
335 compiler.createMessage( | 339 reporter.createMessage( |
336 origin, | 340 origin, |
337 MessageKind.PATCH_NON_CLASS, | 341 MessageKind.PATCH_NON_CLASS, |
338 {'className': patch.name}), | 342 {'className': patch.name}), |
339 <DiagnosticMessage>[ | 343 <DiagnosticMessage>[ |
340 compiler.createMessage( | 344 reporter.createMessage( |
341 patch, | 345 patch, |
342 MessageKind.PATCH_POINT_TO_CLASS, | 346 MessageKind.PATCH_POINT_TO_CLASS, |
343 {'className': patch.name}), | 347 {'className': patch.name}), |
344 ]); | 348 ]); |
345 return; | 349 return; |
346 } | 350 } |
347 patchClass(compiler, origin, patch); | 351 patchClass(compiler, reporter, origin, patch); |
348 } | 352 } |
349 | 353 |
350 void patchClass(Compiler compiler, | 354 void patchClass(Compiler compiler, |
| 355 DiagnosticReporter reporter, |
351 ClassElementX origin, | 356 ClassElementX origin, |
352 ClassElementX patch) { | 357 ClassElementX patch) { |
353 if (origin.isPatched) { | 358 if (origin.isPatched) { |
354 compiler.internalError(origin, | 359 reporter.internalError(origin, |
355 "Patching the same class more than once."); | 360 "Patching the same class more than once."); |
356 } | 361 } |
357 origin.applyPatch(patch); | 362 origin.applyPatch(patch); |
358 checkNativeAnnotation(compiler, patch); | 363 checkNativeAnnotation(compiler, patch); |
359 } | 364 } |
360 | 365 |
361 /// Check whether [cls] has a `@Native(...)` annotation, and if so, set its | 366 /// Check whether [cls] has a `@Native(...)` annotation, and if so, set its |
362 /// native name from the annotation. | 367 /// native name from the annotation. |
363 checkNativeAnnotation(Compiler compiler, ClassElement cls) { | 368 checkNativeAnnotation(Compiler compiler, ClassElement cls) { |
364 EagerAnnotationHandler.checkAnnotation(compiler, cls, | 369 EagerAnnotationHandler.checkAnnotation(compiler, cls, |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
438 return native; | 443 return native; |
439 } | 444 } |
440 } | 445 } |
441 return null; | 446 return null; |
442 } | 447 } |
443 | 448 |
444 void validate(Compiler compiler, | 449 void validate(Compiler compiler, |
445 Element element, | 450 Element element, |
446 MetadataAnnotation annotation, | 451 MetadataAnnotation annotation, |
447 ConstantValue constant) { | 452 ConstantValue constant) { |
448 if (constant.getType(compiler.coreTypes).element != | 453 DartType annotationType = constant.getType(compiler.coreTypes); |
449 compiler.nativeAnnotationClass) { | 454 if (annotationType.element != compiler.nativeAnnotationClass) { |
450 compiler.internalError(annotation, 'Invalid @Native(...) annotation.'); | 455 DiagnosticReporter reporter = compiler.reporter; |
| 456 reporter.internalError(annotation, 'Invalid @Native(...) annotation.'); |
451 } | 457 } |
452 } | 458 } |
453 } | 459 } |
454 | 460 |
455 /// Annotation handler for pre-resolution detection of `@patch` annotations. | 461 /// Annotation handler for pre-resolution detection of `@patch` annotations. |
456 class PatchAnnotationHandler implements EagerAnnotationHandler<PatchVersion> { | 462 class PatchAnnotationHandler implements EagerAnnotationHandler<PatchVersion> { |
457 const PatchAnnotationHandler(); | 463 const PatchAnnotationHandler(); |
458 | 464 |
459 PatchVersion getPatchVersion(MetadataAnnotation annotation) { | 465 PatchVersion getPatchVersion(MetadataAnnotation annotation) { |
460 if (annotation.beginToken != null) { | 466 if (annotation.beginToken != null) { |
(...skipping 15 matching lines...) Expand all Loading... |
476 Element element, | 482 Element element, |
477 MetadataAnnotation annotation) { | 483 MetadataAnnotation annotation) { |
478 return getPatchVersion(annotation); | 484 return getPatchVersion(annotation); |
479 } | 485 } |
480 | 486 |
481 @override | 487 @override |
482 void validate(Compiler compiler, | 488 void validate(Compiler compiler, |
483 Element element, | 489 Element element, |
484 MetadataAnnotation annotation, | 490 MetadataAnnotation annotation, |
485 ConstantValue constant) { | 491 ConstantValue constant) { |
486 if (constant.getType(compiler.coreTypes).element != | 492 DartType annotationType = constant.getType(compiler.coreTypes); |
487 compiler.patchAnnotationClass) { | 493 if (annotationType.element != compiler.patchAnnotationClass) { |
488 compiler.internalError(annotation, 'Invalid patch annotation.'); | 494 DiagnosticReporter reporter = compiler.reporter; |
| 495 reporter.internalError(annotation, 'Invalid patch annotation.'); |
489 } | 496 } |
490 } | 497 } |
491 } | 498 } |
492 | 499 |
493 | 500 |
494 void tryPatchGetter(DiagnosticListener listener, | 501 void tryPatchGetter(DiagnosticReporter reporter, |
495 Element origin, | 502 Element origin, |
496 FunctionElement patch) { | 503 FunctionElement patch) { |
497 if (!origin.isAbstractField) { | 504 if (!origin.isAbstractField) { |
498 listener.reportError( | 505 reporter.reportError( |
499 listener.createMessage( | 506 reporter.createMessage( |
500 origin, | 507 origin, |
501 MessageKind.PATCH_NON_GETTER, | 508 MessageKind.PATCH_NON_GETTER, |
502 {'name': origin.name}), | 509 {'name': origin.name}), |
503 <DiagnosticMessage>[ | 510 <DiagnosticMessage>[ |
504 listener.createMessage( | 511 reporter.createMessage( |
505 patch, | 512 patch, |
506 MessageKind.PATCH_POINT_TO_GETTER, | 513 MessageKind.PATCH_POINT_TO_GETTER, |
507 {'getterName': patch.name}), | 514 {'getterName': patch.name}), |
508 ]); | 515 ]); |
509 return; | 516 return; |
510 } | 517 } |
511 AbstractFieldElement originField = origin; | 518 AbstractFieldElement originField = origin; |
512 if (originField.getter == null) { | 519 if (originField.getter == null) { |
513 listener.reportError( | 520 reporter.reportError( |
514 listener.createMessage( | 521 reporter.createMessage( |
515 origin, | 522 origin, |
516 MessageKind.PATCH_NO_GETTER, | 523 MessageKind.PATCH_NO_GETTER, |
517 {'getterName': patch.name}), | 524 {'getterName': patch.name}), |
518 <DiagnosticMessage>[ | 525 <DiagnosticMessage>[ |
519 listener.createMessage( | 526 reporter.createMessage( |
520 patch, | 527 patch, |
521 MessageKind.PATCH_POINT_TO_GETTER, | 528 MessageKind.PATCH_POINT_TO_GETTER, |
522 {'getterName': patch.name}), | 529 {'getterName': patch.name}), |
523 ]); | 530 ]); |
524 return; | 531 return; |
525 } | 532 } |
526 GetterElementX getter = originField.getter; | 533 GetterElementX getter = originField.getter; |
527 patchFunction(listener, getter, patch); | 534 patchFunction(reporter, getter, patch); |
528 } | 535 } |
529 | 536 |
530 void tryPatchSetter(DiagnosticListener listener, | 537 void tryPatchSetter(DiagnosticReporter reporter, |
531 Element origin, | 538 Element origin, |
532 FunctionElement patch) { | 539 FunctionElement patch) { |
533 if (!origin.isAbstractField) { | 540 if (!origin.isAbstractField) { |
534 listener.reportError( | 541 reporter.reportError( |
535 listener.createMessage( | 542 reporter.createMessage( |
536 origin, | 543 origin, |
537 MessageKind.PATCH_NON_SETTER, | 544 MessageKind.PATCH_NON_SETTER, |
538 {'name': origin.name}), | 545 {'name': origin.name}), |
539 <DiagnosticMessage>[ | 546 <DiagnosticMessage>[ |
540 listener.createMessage( | 547 reporter.createMessage( |
541 patch, | 548 patch, |
542 MessageKind.PATCH_POINT_TO_SETTER, | 549 MessageKind.PATCH_POINT_TO_SETTER, |
543 {'setterName': patch.name}), | 550 {'setterName': patch.name}), |
544 ]); | 551 ]); |
545 return; | 552 return; |
546 } | 553 } |
547 AbstractFieldElement originField = origin; | 554 AbstractFieldElement originField = origin; |
548 if (originField.setter == null) { | 555 if (originField.setter == null) { |
549 listener.reportError( | 556 reporter.reportError( |
550 listener.createMessage( | 557 reporter.createMessage( |
551 origin, | 558 origin, |
552 MessageKind.PATCH_NO_SETTER, | 559 MessageKind.PATCH_NO_SETTER, |
553 {'setterName': patch.name}), | 560 {'setterName': patch.name}), |
554 <DiagnosticMessage>[ | 561 <DiagnosticMessage>[ |
555 listener.createMessage( | 562 reporter.createMessage( |
556 patch, | 563 patch, |
557 MessageKind.PATCH_POINT_TO_SETTER, | 564 MessageKind.PATCH_POINT_TO_SETTER, |
558 {'setterName': patch.name}), | 565 {'setterName': patch.name}), |
559 ]); | 566 ]); |
560 return; | 567 return; |
561 } | 568 } |
562 SetterElementX setter = originField.setter; | 569 SetterElementX setter = originField.setter; |
563 patchFunction(listener, setter, patch); | 570 patchFunction(reporter, setter, patch); |
564 } | 571 } |
565 | 572 |
566 void tryPatchConstructor(DiagnosticListener listener, | 573 void tryPatchConstructor(DiagnosticReporter reporter, |
567 Element origin, | 574 Element origin, |
568 FunctionElement patch) { | 575 FunctionElement patch) { |
569 if (!origin.isConstructor) { | 576 if (!origin.isConstructor) { |
570 listener.reportError( | 577 reporter.reportError( |
571 listener.createMessage( | 578 reporter.createMessage( |
572 origin, | 579 origin, |
573 MessageKind.PATCH_NON_CONSTRUCTOR, | 580 MessageKind.PATCH_NON_CONSTRUCTOR, |
574 {'constructorName': patch.name}), | 581 {'constructorName': patch.name}), |
575 <DiagnosticMessage>[ | 582 <DiagnosticMessage>[ |
576 listener.createMessage( | 583 reporter.createMessage( |
577 patch, | 584 patch, |
578 MessageKind.PATCH_POINT_TO_CONSTRUCTOR, | 585 MessageKind.PATCH_POINT_TO_CONSTRUCTOR, |
579 {'constructorName': patch.name}), | 586 {'constructorName': patch.name}), |
580 ]); | 587 ]); |
581 return; | 588 return; |
582 } | 589 } |
583 patchFunction(listener, origin, patch); | 590 patchFunction(reporter, origin, patch); |
584 } | 591 } |
585 | 592 |
586 void tryPatchFunction(DiagnosticListener listener, | 593 void tryPatchFunction(DiagnosticReporter reporter, |
587 Element origin, | 594 Element origin, |
588 FunctionElement patch) { | 595 FunctionElement patch) { |
589 if (!origin.isFunction) { | 596 if (!origin.isFunction) { |
590 listener.reportError( | 597 reporter.reportError( |
591 listener.createMessage( | 598 reporter.createMessage( |
592 origin, | 599 origin, |
593 MessageKind.PATCH_NON_FUNCTION, | 600 MessageKind.PATCH_NON_FUNCTION, |
594 {'functionName': patch.name}), | 601 {'functionName': patch.name}), |
595 <DiagnosticMessage>[ | 602 <DiagnosticMessage>[ |
596 listener.createMessage( | 603 reporter.createMessage( |
597 patch, | 604 patch, |
598 MessageKind.PATCH_POINT_TO_FUNCTION, | 605 MessageKind.PATCH_POINT_TO_FUNCTION, |
599 {'functionName': patch.name}), | 606 {'functionName': patch.name}), |
600 ]); | 607 ]); |
601 return; | 608 return; |
602 } | 609 } |
603 patchFunction(listener, origin, patch); | 610 patchFunction(reporter, origin, patch); |
604 } | 611 } |
605 | 612 |
606 void patchFunction(DiagnosticListener listener, | 613 void patchFunction(DiagnosticReporter reporter, |
607 BaseFunctionElementX origin, | 614 BaseFunctionElementX origin, |
608 BaseFunctionElementX patch) { | 615 BaseFunctionElementX patch) { |
609 if (!origin.modifiers.isExternal) { | 616 if (!origin.modifiers.isExternal) { |
610 listener.reportError( | 617 reporter.reportError( |
611 listener.createMessage(origin, MessageKind.PATCH_NON_EXTERNAL), | 618 reporter.createMessage(origin, MessageKind.PATCH_NON_EXTERNAL), |
612 <DiagnosticMessage>[ | 619 <DiagnosticMessage>[ |
613 listener.createMessage( | 620 reporter.createMessage( |
614 patch, | 621 patch, |
615 MessageKind.PATCH_POINT_TO_FUNCTION, | 622 MessageKind.PATCH_POINT_TO_FUNCTION, |
616 {'functionName': patch.name}), | 623 {'functionName': patch.name}), |
617 ]); | 624 ]); |
618 return; | 625 return; |
619 } | 626 } |
620 if (origin.isPatched) { | 627 if (origin.isPatched) { |
621 listener.internalError(origin, | 628 reporter.internalError(origin, |
622 "Trying to patch a function more than once."); | 629 "Trying to patch a function more than once."); |
623 } | 630 } |
624 origin.applyPatch(patch); | 631 origin.applyPatch(patch); |
625 } | 632 } |
626 | 633 |
627 PatchVersion getPatchVersion(Compiler compiler, Element element) { | 634 PatchVersion getPatchVersion(Compiler compiler, Element element) { |
628 return EagerAnnotationHandler.checkAnnotation(compiler, element, | 635 return EagerAnnotationHandler.checkAnnotation(compiler, element, |
629 const PatchAnnotationHandler()); | 636 const PatchAnnotationHandler()); |
630 } | 637 } |
631 | 638 |
632 class PatchVersion { | 639 class PatchVersion { |
633 final String tag; | 640 final String tag; |
634 | 641 |
635 const PatchVersion(this.tag); | 642 const PatchVersion(this.tag); |
636 | 643 |
637 bool isActive(String patchTag) => tag == null || tag == patchTag; | 644 bool isActive(String patchTag) => tag == null || tag == patchTag; |
638 | 645 |
639 String toString() => 'PatchVersion($tag)'; | 646 String toString() => 'PatchVersion($tag)'; |
640 } | 647 } |
OLD | NEW |