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 |