| 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 311 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 322 */ | 322 */ |
| 323 bool allowLibraryTags() => true; | 323 bool allowLibraryTags() => true; |
| 324 | 324 |
| 325 void addLibraryTag(tree.LibraryTag tag) { | 325 void addLibraryTag(tree.LibraryTag tag) { |
| 326 super.addLibraryTag(tag); | 326 super.addLibraryTag(tag); |
| 327 imports.addLast(tag); | 327 imports.addLast(tag); |
| 328 } | 328 } |
| 329 | 329 |
| 330 void pushElement(Element patch) { | 330 void pushElement(Element patch) { |
| 331 if (isMemberPatch || (isClassPatch && patch is ClassElement)) { | 331 if (isMemberPatch || (isClassPatch && patch is ClassElement)) { |
| 332 // Apply patch. | |
| 333 patch.addMetadata(popMetadata()); | 332 patch.addMetadata(popMetadata()); |
| 334 LibraryElement originLibrary = compilationUnitElement.getLibrary(); | 333 applyPatch(patch); |
| 335 assert(originLibrary.isPatched); | |
| 336 Element origin = originLibrary.localLookup(patch.name); | |
| 337 _patchElement(listener, origin, patch); | |
| 338 } | 334 } |
| 339 super.pushElement(patch); | 335 super.pushElement(patch); |
| 340 } | 336 } |
| 337 |
| 338 void applyPatch(Element patch) { |
| 339 LibraryElement originLibrary = compilationUnitElement.getLibrary(); |
| 340 assert(originLibrary.isPatched); |
| 341 Element origin = originLibrary.localLookup(patch.name); |
| 342 _patchElement(listener, origin, patch); |
| 343 } |
| 341 } | 344 } |
| 342 | 345 |
| 343 /** | 346 /** |
| 344 * Extension of [MemberListener] for parsing patch class bodies. | 347 * Extension of [MemberListener] for parsing patch class bodies. |
| 345 */ | 348 */ |
| 346 class PatchMemberListener extends MemberListener implements PatchListener { | 349 class PatchMemberListener extends MemberListener implements PatchListener { |
| 347 bool isMemberPatch = false; | 350 bool isMemberPatch = false; |
| 348 bool isClassPatch = false; | 351 bool isClassPatch = false; |
| 349 PatchMemberListener(leg.DiagnosticListener listener, | 352 PatchMemberListener(leg.DiagnosticListener listener, |
| 350 Element enclosingElement) | 353 Element enclosingElement) |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 383 | 386 |
| 384 // TODO(ahe): Get rid of this class. | 387 // TODO(ahe): Get rid of this class. |
| 385 class PatchMetadataAnnotation extends MetadataAnnotationX { | 388 class PatchMetadataAnnotation extends MetadataAnnotationX { |
| 386 final leg.Constant value = null; | 389 final leg.Constant value = null; |
| 387 | 390 |
| 388 PatchMetadataAnnotation() : super(STATE_DONE); | 391 PatchMetadataAnnotation() : super(STATE_DONE); |
| 389 | 392 |
| 390 Token get beginToken => null; | 393 Token get beginToken => null; |
| 391 } | 394 } |
| 392 | 395 |
| 396 void patchElement(leg.DiagnosticListener listener, |
| 397 Element origin, |
| 398 Element patch) { |
| 399 _patchElement(listener, origin, patch); |
| 400 } |
| 401 |
| 393 void _patchElement(leg.DiagnosticListener listener, | 402 void _patchElement(leg.DiagnosticListener listener, |
| 394 Element origin, | 403 Element origin, |
| 395 Element patch) { | 404 Element patch) { |
| 396 if (origin == null) { | 405 if (origin == null) { |
| 397 listener.reportMessage( | 406 listener.reportMessage( |
| 398 listener.spanFromSpannable(patch), | 407 listener.spanFromSpannable(patch), |
| 399 leg.MessageKind.PATCH_NON_EXISTING.error([patch.name]), | 408 leg.MessageKind.PATCH_NON_EXISTING.error([patch.name]), |
| 400 api.Diagnostic.ERROR); | 409 api.Diagnostic.ERROR); |
| 401 return; | 410 return; |
| 402 } | 411 } |
| (...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 582 } | 591 } |
| 583 | 592 |
| 584 bool _isPatchElement(Element element) { | 593 bool _isPatchElement(Element element) { |
| 585 // TODO(lrn): More checks needed if we introduce metadata for real. | 594 // TODO(lrn): More checks needed if we introduce metadata for real. |
| 586 // In that case, it must have the identifier "native" as metadata. | 595 // In that case, it must have the identifier "native" as metadata. |
| 587 for (Link link = element.metadata; !link.isEmpty; link = link.tail) { | 596 for (Link link = element.metadata; !link.isEmpty; link = link.tail) { |
| 588 if (link.head is PatchMetadataAnnotation) return true; | 597 if (link.head is PatchMetadataAnnotation) return true; |
| 589 } | 598 } |
| 590 return false; | 599 return false; |
| 591 } | 600 } |
| 601 |
| 602 bool isPatchElement(Element element) => _isPatchElement(element); |
| OLD | NEW |