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