| 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 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 174 // Parse [PartialClassElement] using a "patch"-aware parser instead | 174 // Parse [PartialClassElement] using a "patch"-aware parser instead |
| 175 // of calling its [parseNode] method. | 175 // of calling its [parseNode] method. |
| 176 if (element.cachedNode != null) return; | 176 if (element.cachedNode != null) return; |
| 177 | 177 |
| 178 return measure(() => compiler.withCurrentElement(element, () { | 178 return measure(() => compiler.withCurrentElement(element, () { |
| 179 PatchMemberListener listener = new PatchMemberListener(compiler, element); | 179 PatchMemberListener listener = new PatchMemberListener(compiler, element); |
| 180 Parser parser = new PatchClassElementParser(listener); | 180 Parser parser = new PatchClassElementParser(listener); |
| 181 Token token = parser.parseTopLevelDeclaration(element.beginToken); | 181 Token token = parser.parseTopLevelDeclaration(element.beginToken); |
| 182 assert(identical(token, element.endToken.next)); | 182 assert(identical(token, element.endToken.next)); |
| 183 element.cachedNode = listener.popNode(); | 183 element.cachedNode = listener.popNode(); |
| 184 assert(listener.nodes.isEmpty()); | 184 assert(listener.nodes.isEmpty); |
| 185 | 185 |
| 186 Link<Element> patches = element.localMembers; | 186 Link<Element> patches = element.localMembers; |
| 187 applyContainerPatch(element.origin, patches); | 187 applyContainerPatch(element.origin, patches); |
| 188 })); | 188 })); |
| 189 } | 189 } |
| 190 | 190 |
| 191 void applyContainerPatch(ScopeContainerElement original, | 191 void applyContainerPatch(ScopeContainerElement original, |
| 192 Link<Element> patches) { | 192 Link<Element> patches) { |
| 193 while (!patches.isEmpty()) { | 193 while (!patches.isEmpty) { |
| 194 Element patchElement = patches.head; | 194 Element patchElement = patches.head; |
| 195 Element originalElement = original.localLookup(patchElement.name); | 195 Element originalElement = original.localLookup(patchElement.name); |
| 196 if (patchElement.isAccessor() && originalElement != null) { | 196 if (patchElement.isAccessor() && originalElement != null) { |
| 197 if (!identical(originalElement.kind, ElementKind.ABSTRACT_FIELD)) { | 197 if (!identical(originalElement.kind, ElementKind.ABSTRACT_FIELD)) { |
| 198 compiler.internalError( | 198 compiler.internalError( |
| 199 "Cannot patch non-getter/setter with getter/setter", | 199 "Cannot patch non-getter/setter with getter/setter", |
| 200 element: originalElement); | 200 element: originalElement); |
| 201 } | 201 } |
| 202 AbstractFieldElement originalField = originalElement; | 202 AbstractFieldElement originalField = originalElement; |
| 203 if (patchElement.isGetter()) { | 203 if (patchElement.isGetter()) { |
| (...skipping 10 matching lines...) Expand all Loading... |
| 214 } else { | 214 } else { |
| 215 patchMember(originalElement, patchElement); | 215 patchMember(originalElement, patchElement); |
| 216 } | 216 } |
| 217 patches = patches.tail; | 217 patches = patches.tail; |
| 218 } | 218 } |
| 219 } | 219 } |
| 220 | 220 |
| 221 bool isPatchElement(Element element) { | 221 bool isPatchElement(Element element) { |
| 222 // TODO(lrn): More checks needed if we introduce metadata for real. | 222 // TODO(lrn): More checks needed if we introduce metadata for real. |
| 223 // In that case, it must have the identifier "native" as metadata. | 223 // In that case, it must have the identifier "native" as metadata. |
| 224 for (Link link = element.metadata; !link.isEmpty(); link = link.tail) { | 224 for (Link link = element.metadata; !link.isEmpty; link = link.tail) { |
| 225 if (link.head is PatchMetadataAnnotation) return true; | 225 if (link.head is PatchMetadataAnnotation) return true; |
| 226 } | 226 } |
| 227 return false; | 227 return false; |
| 228 } | 228 } |
| 229 | 229 |
| 230 void patchMember(Element originalElement, Element patchElement) { | 230 void patchMember(Element originalElement, Element patchElement) { |
| 231 // The original library has an element with the same name as the patch | 231 // The original library has an element with the same name as the patch |
| 232 // library element. | 232 // library element. |
| 233 // In this case, the patch library element must be a function marked as | 233 // In this case, the patch library element must be a function marked as |
| 234 // "patch" and it must have the same signature as the function it patches. | 234 // "patch" and it must have the same signature as the function it patches. |
| (...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 496 super.addMember(element); | 496 super.addMember(element); |
| 497 } | 497 } |
| 498 } | 498 } |
| 499 | 499 |
| 500 // TODO(ahe): Get rid of this class. | 500 // TODO(ahe): Get rid of this class. |
| 501 class PatchMetadataAnnotation extends MetadataAnnotation { | 501 class PatchMetadataAnnotation extends MetadataAnnotation { |
| 502 final leg.Constant value = null; | 502 final leg.Constant value = null; |
| 503 | 503 |
| 504 PatchMetadataAnnotation() : super(STATE_DONE); | 504 PatchMetadataAnnotation() : super(STATE_DONE); |
| 505 } | 505 } |
| OLD | NEW |