Chromium Code Reviews| Index: lib/compiler/implementation/patch_parser.dart |
| diff --git a/lib/compiler/implementation/patch_parser.dart b/lib/compiler/implementation/patch_parser.dart |
| index cfc78f8531f9f1925856482c32bf1e7e5905a4b1..ca7aa9b4a8ae64c32541ccd4f906ecc6a261bae8 100644 |
| --- a/lib/compiler/implementation/patch_parser.dart |
| +++ b/lib/compiler/implementation/patch_parser.dart |
| @@ -2,9 +2,111 @@ |
| // for details. All rights reserved. Use of this source code is governed by a |
| // BSD-style license that can be found in the LICENSE file. |
| +/** |
|
ahe
2012/09/18 11:25:54
Add something like:
TOOO(johnniwinther): The term
Johnni Winther
2012/09/20 08:12:23
Done.
|
| + * 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.
|
| + * |
| + * Three types of elements can be patched: [LibraryElement], [ClassElement], |
| + * [FunctionElement]. Patches are introduced in patch libraries which are loaded |
| + * together with the corresponding origin library. Which libraries that are |
| + * patched is determined by the [dart2jsPatchPath] field of [LibraryInfo] found |
| + * in [:lib/_internal/libraries.dart:]. |
| + * |
| + * Patch libraries are parsed like regular library and thus provided with their |
| + * own elements. These elements which are distinct from the elements from the |
| + * patched library and the relation between patched and patch elements is |
| + * established through the [:patch:] and [:origin:] fields found on |
| + * [LibraryElement], [ClassElement] and [FunctionElement]. The [:patch:] fields |
| + * are set on the patched elements to point to their corresponding patch |
| + * element, and the [:origin:] elements are set on the patch elements to point |
| + * their corresponding patched elements. |
| + * |
| + * 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
|
| + * whether the [:patch:] or [:origin:] field, respectively, has been set on an |
| + * element, regardless of whether the element is one of the three patchable |
| + * element types or not. |
| + * |
| + * ## Variants of Classes and Functions ## |
| + * |
| + * With patches there are four variants of classes and function: |
| + * |
| + * Regular: A class or function which is not declared in a patch library and |
| + * which has no corresponding patch. |
| + * Origin: A class or function which is not declared in a patch library and |
| + * which has a corresponding patch. Origin functions must use the [:external:] |
| + * modifier and can have no body. Origin classes and functions are also |
| + * called 'patched'. |
| + * Patch: A class or function which is declared in a patch library and which |
| + * has a corresponding origin. Both patch classes and patch functions must use |
| + * the [:patch:] modifier. |
| + * 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.
|
| + * patch library and which has no corresponding origin. A ghost can not use |
| + * the [:patch:] modifier. Ghost elements are never visible from outside the |
| + * patch library in which they have been declared. For this reason, ghosts are |
| + * often declared private and therefore called 'patch private'. |
| + * |
| + * Examples of the variants is shown in the code below: |
| + * |
| + * // In the origin library: |
| + * class RegularClass { // A regular class. |
| + * void regularMethod() {} // A regular method. |
| + * } |
| + * class PatchedClass { // The origin class. |
|
ahe
2012/09/18 11:25:54
The -> An.
Johnni Winther
2012/09/20 08:12:23
Done.
|
| + * int regularField; // A regular field. |
| + * void regularMethod() {} // A regular method. |
| + * external void patchedMethod(); // The origin method. |
|
ahe
2012/09/18 11:25:54
The -> An.
Johnni Winther
2012/09/20 08:12:23
Done.
|
| + * } |
| + * |
| + * // In the patch library: |
| + * class _GhostClass { // A ghost class. |
| + * void _ghostMethod() {} // A ghost method. |
| + * } |
| + * patch class PatchedClass { // The patch class. |
|
ahe
2012/09/18 11:25:54
The -> An.
Johnni Winther
2012/09/20 08:12:23
Done.
|
| + * int _ghostField; { // A ghost field. |
| + * patch void patchedMethod() {} // The patch method. |
|
ahe
2012/09/18 11:25:54
The -> An.
Johnni Winther
2012/09/20 08:12:23
Done.
|
| + * } |
| + * |
| + * |
| + * ## Declaration and Implementation ## |
| + * |
| + * 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.
|
| + * introduces the entity and defines its interface, and as the 'implementation' |
| + * which defines the actual implementation of the entity. |
| + * |
| + * Every element has a 'declaration' and an 'implementation' element. For |
| + * regular and ghost elements these are the same. For origin elements the |
| + * declaration is the element itself and the implementation is the patch element |
| + * found through its [:patch:] field. For patch elements the implementation is |
| + * the element itself and the declaration is the origin element found through |
| + * its [:origin:] field. The declaration and implementation of any element is |
| + * conveniently available through the [Element.declaration:] and |
|
ngeoffray
2012/09/17 12:46:24
Remove ':'
Johnni Winther
2012/09/20 08:12:23
Done.
|
| + * [Element.implementation] getters. |
| + * |
| + * Most patch-related invariants enforced through-out the compiler are defined |
| + * in terms of 'declaration' and 'implementation', and tested through the |
| + * predicate getters [Element.isDeclaration] and [Element.isImplementation]. |
| + * Patch invariants are stated both in comments and as assertions. |
| + * |
| + * |
| + * ## General invariant guidelines ## |
| + * |
| + * For [LibraryElement] we always use declarations. This means the |
| + * [Element.getLibrary] method will only return library declarations. Patch |
| + * library implementations are only accessed through calls to |
| + * [Element.getImplementationLibrary] which is used to setup the correct |
| + * [Element.enclosingElement] relation between patch/ghost elements and the |
| + * patch library. |
| + * |
| + * 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
|
| + * - Worklist only contain declaration elements. |
| + * - Most maps and sets use declarations exclusively, and their individual |
| + * invariants are stated in the field comments. |
| + * - [TreeElements] only map to patch elements from inside a patch library. |
| + * - Builders shift between declaration and implementation depending on usages. |
| + * - Compile-time constants use constructor implementation exclusively. |
| + */ |
| #library("patchparser"); |
| -#import("dart:uri"); |
| +#import("dart:uri"); |
| #import("tree/tree.dart", prefix: "tree"); |
| #import("leg.dart", prefix: 'leg'); // CompilerTask, Compiler. |
| #import("apiimpl.dart"); |