Chromium Code Reviews| 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 /** | |
|
ahe
2012/09/18 11:25:54
Add something like:
TOOO(johnniwinther): The term
Johnni Winther
2012/09/20 08:12:23
Done.
| |
| 6 * This library contains the infrastructure to parse and integrate patches. | |
|
ahe
2012/09/18 11:25:54
patches -> patch file.
Johnni Winther
2012/09/20 08:12:23
Done.
| |
| 7 * | |
| 8 * Three types of elements can be patched: [LibraryElement], [ClassElement], | |
| 9 * [FunctionElement]. Patches are introduced in patch libraries which are loaded | |
| 10 * together with the corresponding origin library. Which libraries that are | |
| 11 * patched is determined by the [dart2jsPatchPath] field of [LibraryInfo] found | |
| 12 * in [:lib/_internal/libraries.dart:]. | |
| 13 * | |
| 14 * Patch libraries are parsed like regular library and thus provided with their | |
| 15 * own elements. These elements which are distinct from the elements from the | |
| 16 * patched library and the relation between patched and patch elements is | |
| 17 * established through the [:patch:] and [:origin:] fields found on | |
| 18 * [LibraryElement], [ClassElement] and [FunctionElement]. The [:patch:] fields | |
| 19 * are set on the patched elements to point to their corresponding patch | |
| 20 * element, and the [:origin:] elements are set on the patch elements to point | |
| 21 * their corresponding patched elements. | |
| 22 * | |
| 23 * The fields [Element.isPatched] and [Element.isPatch] can be used to determine | |
|
ngeoffray
2012/09/17 12:46:24
Should isPatched be isExternal?
Johnni Winther
2012/09/20 08:12:23
That would only be fitting for functions. Class an
| |
| 24 * whether the [:patch:] or [:origin:] field, respectively, has been set on an | |
| 25 * element, regardless of whether the element is one of the three patchable | |
| 26 * element types or not. | |
| 27 * | |
| 28 * ## Variants of Classes and Functions ## | |
| 29 * | |
| 30 * With patches there are four variants of classes and function: | |
| 31 * | |
| 32 * Regular: A class or function which is not declared in a patch library and | |
| 33 * which has no corresponding patch. | |
| 34 * Origin: A class or function which is not declared in a patch library and | |
| 35 * which has a corresponding patch. Origin functions must use the [:external:] | |
| 36 * modifier and can have no body. Origin classes and functions are also | |
| 37 * called 'patched'. | |
| 38 * Patch: A class or function which is declared in a patch library and which | |
| 39 * has a corresponding origin. Both patch classes and patch functions must use | |
| 40 * the [:patch:] modifier. | |
| 41 * Ghost: A class or function (or even field) which is declared in a | |
|
ahe
2012/09/18 11:25:54
I don't like this terminology. I have heard Anders
Johnni Winther
2012/09/20 08:12:23
I'll change to injected.
| |
| 42 * patch library and which has no corresponding origin. A ghost can not use | |
| 43 * the [:patch:] modifier. Ghost elements are never visible from outside the | |
| 44 * patch library in which they have been declared. For this reason, ghosts are | |
| 45 * often declared private and therefore called 'patch private'. | |
| 46 * | |
| 47 * Examples of the variants is shown in the code below: | |
| 48 * | |
| 49 * // In the origin library: | |
| 50 * class RegularClass { // A regular class. | |
| 51 * void regularMethod() {} // A regular method. | |
| 52 * } | |
| 53 * class PatchedClass { // The origin class. | |
|
ahe
2012/09/18 11:25:54
The -> An.
Johnni Winther
2012/09/20 08:12:23
Done.
| |
| 54 * int regularField; // A regular field. | |
| 55 * void regularMethod() {} // A regular method. | |
| 56 * external void patchedMethod(); // The origin method. | |
|
ahe
2012/09/18 11:25:54
The -> An.
Johnni Winther
2012/09/20 08:12:23
Done.
| |
| 57 * } | |
| 58 * | |
| 59 * // In the patch library: | |
| 60 * class _GhostClass { // A ghost class. | |
| 61 * void _ghostMethod() {} // A ghost method. | |
| 62 * } | |
| 63 * patch class PatchedClass { // The patch class. | |
|
ahe
2012/09/18 11:25:54
The -> An.
Johnni Winther
2012/09/20 08:12:23
Done.
| |
| 64 * int _ghostField; { // A ghost field. | |
| 65 * patch void patchedMethod() {} // The patch method. | |
|
ahe
2012/09/18 11:25:54
The -> An.
Johnni Winther
2012/09/20 08:12:23
Done.
| |
| 66 * } | |
| 67 * | |
| 68 * | |
| 69 * ## Declaration and Implementation ## | |
| 70 * | |
| 71 * With patches we have two views on elements: As the 'declaration' which | |
|
ngeoffray
2012/09/17 12:46:24
As -> as
Johnni Winther
2012/09/20 08:12:23
Done.
| |
| 72 * introduces the entity and defines its interface, and as the 'implementation' | |
| 73 * which defines the actual implementation of the entity. | |
| 74 * | |
| 75 * Every element has a 'declaration' and an 'implementation' element. For | |
| 76 * regular and ghost elements these are the same. For origin elements the | |
| 77 * declaration is the element itself and the implementation is the patch element | |
| 78 * found through its [:patch:] field. For patch elements the implementation is | |
| 79 * the element itself and the declaration is the origin element found through | |
| 80 * its [:origin:] field. The declaration and implementation of any element is | |
| 81 * conveniently available through the [Element.declaration:] and | |
|
ngeoffray
2012/09/17 12:46:24
Remove ':'
Johnni Winther
2012/09/20 08:12:23
Done.
| |
| 82 * [Element.implementation] getters. | |
| 83 * | |
| 84 * Most patch-related invariants enforced through-out the compiler are defined | |
| 85 * in terms of 'declaration' and 'implementation', and tested through the | |
| 86 * predicate getters [Element.isDeclaration] and [Element.isImplementation]. | |
| 87 * Patch invariants are stated both in comments and as assertions. | |
| 88 * | |
| 89 * | |
| 90 * ## General invariant guidelines ## | |
| 91 * | |
| 92 * For [LibraryElement] we always use declarations. This means the | |
| 93 * [Element.getLibrary] method will only return library declarations. Patch | |
| 94 * library implementations are only accessed through calls to | |
| 95 * [Element.getImplementationLibrary] which is used to setup the correct | |
| 96 * [Element.enclosingElement] relation between patch/ghost elements and the | |
| 97 * patch library. | |
| 98 * | |
| 99 * For [ClassElement] and [FunctionElement] we mostly use declarations. | |
|
ahe
2012/09/18 11:25:54
I don't see it this way. Yes, we mostly store decl
Johnni Winther
2012/09/20 08:12:23
Updated
| |
| 100 * - Worklist only contain declaration elements. | |
| 101 * - Most maps and sets use declarations exclusively, and their individual | |
| 102 * invariants are stated in the field comments. | |
| 103 * - [TreeElements] only map to patch elements from inside a patch library. | |
| 104 * - Builders shift between declaration and implementation depending on usages. | |
| 105 * - Compile-time constants use constructor implementation exclusively. | |
| 106 */ | |
| 5 #library("patchparser"); | 107 #library("patchparser"); |
| 108 | |
| 6 #import("dart:uri"); | 109 #import("dart:uri"); |
| 7 | |
| 8 #import("tree/tree.dart", prefix: "tree"); | 110 #import("tree/tree.dart", prefix: "tree"); |
| 9 #import("leg.dart", prefix: 'leg'); // CompilerTask, Compiler. | 111 #import("leg.dart", prefix: 'leg'); // CompilerTask, Compiler. |
| 10 #import("apiimpl.dart"); | 112 #import("apiimpl.dart"); |
| 11 #import("scanner/scannerlib.dart"); // Scanner, Parsers, Listeners | 113 #import("scanner/scannerlib.dart"); // Scanner, Parsers, Listeners |
| 12 #import("elements/elements.dart"); | 114 #import("elements/elements.dart"); |
| 13 #import('util/util.dart'); | 115 #import('util/util.dart'); |
| 14 | 116 |
| 15 class PatchParserTask extends leg.CompilerTask { | 117 class PatchParserTask extends leg.CompilerTask { |
| 16 PatchParserTask(leg.Compiler compiler): super(compiler); | 118 PatchParserTask(leg.Compiler compiler): super(compiler); |
| 17 final String name = "Patching Parser"; | 119 final String name = "Patching Parser"; |
| (...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 290 super.addMember(element); | 392 super.addMember(element); |
| 291 } | 393 } |
| 292 } | 394 } |
| 293 | 395 |
| 294 // TODO(ahe): Get rid of this class. | 396 // TODO(ahe): Get rid of this class. |
| 295 class PatchMetadataAnnotation extends MetadataAnnotation { | 397 class PatchMetadataAnnotation extends MetadataAnnotation { |
| 296 final leg.Constant value = null; | 398 final leg.Constant value = null; |
| 297 | 399 |
| 298 PatchMetadataAnnotation() : super(STATE_DONE); | 400 PatchMetadataAnnotation() : super(STATE_DONE); |
| 299 } | 401 } |
| OLD | NEW |