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 |