Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(227)

Unified Diff: sdk/lib/_internal/compiler/implementation/elements/modelx.dart

Issue 266193004: Clean patch implementation. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Updated cf. comments. Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: sdk/lib/_internal/compiler/implementation/elements/modelx.dart
diff --git a/sdk/lib/_internal/compiler/implementation/elements/modelx.dart b/sdk/lib/_internal/compiler/implementation/elements/modelx.dart
index 4a5ffb7e3a9c9c97c3ad625166ad4563de32c19f..7fb55a09ead40268987361e04e6d96917dea9a1e 100644
--- a/sdk/lib/_internal/compiler/implementation/elements/modelx.dart
+++ b/sdk/lib/_internal/compiler/implementation/elements/modelx.dart
@@ -5,6 +5,7 @@
library elements.modelx;
import 'elements.dart';
+import '../helpers/helpers.dart';
import '../tree/tree.dart';
import '../util/util.dart';
import '../resolution/resolution.dart';
@@ -110,59 +111,17 @@ abstract class ElementX implements Element {
/** See [WarnOnUseElement] for documentation. */
bool isWarnOnUse() => false;
- /**
- * Is [:true:] if this element has a corresponding patch.
- *
- * If [:true:] this element has a non-null [patch] field.
- *
- * See [:patch_parser.dart:] for a description of the terminology.
- */
bool get isPatched => false;
- /**
- * Is [:true:] if this element is a patch.
- *
- * If [:true:] this element has a non-null [origin] field.
- *
- * See [:patch_parser.dart:] for a description of the terminology.
- */
bool get isPatch => false;
- /**
- * Is [:true:] if this element defines the implementation for the entity of
- * this element.
- *
- * See [:patch_parser.dart:] for a description of the terminology.
- */
- bool get isImplementation => !isPatched;
-
- /**
- * Is [:true:] if this element introduces the entity of this element.
- *
- * See [:patch_parser.dart:] for a description of the terminology.
- */
- bool get isDeclaration => !isPatch;
+ bool get isImplementation => true;
- bool get isSynthesized => false;
+ bool get isDeclaration => true;
- bool get isForwardingConstructor => false;
+ Element get implementation => this;
- bool get isMixinApplication => false;
-
- /**
- * Returns the element which defines the implementation for the entity of this
- * element.
- *
- * See [:patch_parser.dart:] for a description of the terminology.
- */
- Element get implementation => isPatched ? patch : this;
-
- /**
- * Returns the element which introduces the entity of this element.
- *
- * See [:patch_parser.dart:] for a description of the terminology.
- */
- Element get declaration => isPatch ? origin : this;
+ Element get declaration => this;
Element get patch {
throw new UnsupportedError('patch is not supported on $this');
@@ -172,6 +131,12 @@ abstract class ElementX implements Element {
throw new UnsupportedError('origin is not supported on $this');
}
+ bool get isSynthesized => false;
+
+ bool get isForwardingConstructor => false;
+
+ bool get isMixinApplication => false;
+
// TODO(johnniwinther): This breaks for libraries (for which enclosing
// elements are null) and is invalid for top level variable declarations for
// which the enclosing element is a VariableDeclarations and not a compilation
@@ -350,15 +315,9 @@ class ErroneousElementX extends ElementX implements ErroneousElement {
bool get isRedirectingFactory => unsupported();
- setPatch(patch) => unsupported();
computeSignature(compiler) => unsupported();
- requiredParameterCount(compiler) => unsupported();
- optionalParameterCount(compiler) => unsupported();
- parameterCount(compiler) => unsupported();
// TODO(kasperl): These seem unnecessary.
- set patch(value) => unsupported();
- set origin(value) => unsupported();
set defaultImplementation(value) => unsupported();
get redirectionTarget => this;
@@ -769,7 +728,8 @@ class ImportScope {
Element operator [](String name) => importScope[name];
}
-class LibraryElementX extends ElementX with AnalyzableElement
+class LibraryElementX
+ extends ElementX with AnalyzableElement, PatchMixin<LibraryElementX>
implements LibraryElement {
final Uri canonicalUri;
CompilationUnitElement entryCompilationUnit;
@@ -782,20 +742,6 @@ class LibraryElementX extends ElementX with AnalyzableElement
final ScopeX localScope = new ScopeX();
final ImportScope importScope = new ImportScope();
- /**
- * If this library is patched, [patch] points to the patch library.
- *
- * See [:patch_parser.dart:] for a description of the terminology.
- */
- LibraryElementX patch = null;
-
- /**
- * If this is a patch library, [origin] points to the origin library.
- *
- * See [:patch_parser.dart:] for a description of the terminology.
- */
- final LibraryElementX origin;
-
/// A mapping from an imported element to the "import" tag.
final Importers importers = new Importers();
@@ -812,22 +758,17 @@ class LibraryElementX extends ElementX with AnalyzableElement
final Map<LibraryDependency, LibraryElement> tagMapping =
new Map<LibraryDependency, LibraryElement>();
- LibraryElementX(Script script, [Uri canonicalUri, LibraryElement this.origin])
+ LibraryElementX(Script script,
+ [Uri canonicalUri, LibraryElementX origin])
: this.canonicalUri =
((canonicalUri == null) ? script.readableUri : canonicalUri),
super(script.name, ElementKind.LIBRARY, null) {
entryCompilationUnit = new CompilationUnitElementX(script, this);
- if (isPatch) {
- origin.patch = this;
+ if (origin != null) {
+ origin.applyPatch(this);
}
}
- bool get isPatched => patch != null;
- bool get isPatch => origin != null;
-
- LibraryElement get declaration => super.declaration;
- LibraryElement get implementation => super.implementation;
-
Link<MetadataAnnotation> get metadata {
return (libraryTag == null) ? super.metadata : libraryTag.metadata;
}
@@ -858,7 +799,8 @@ class LibraryElementX extends ElementX with AnalyzableElement
* Adds [element] to the import scope of this library.
*
* If an element by the same name is already in the imported scope, an
- * [ErroneousElement] will be put in the imported scope, allowing for detection of ambiguous uses of imported names.
+ * [ErroneousElement] will be put in the imported scope, allowing for
+ * detection of ambiguous uses of imported names.
*/
void addImport(Element element, Import import, DiagnosticListener listener) {
importScope.addImport(this, element, import, listener);
@@ -1034,6 +976,10 @@ class LibraryElementX extends ElementX with AnalyzableElement
}
accept(ElementVisitor visitor) => visitor.visitLibraryElement(this);
+
+ // TODO(johnniwinther): Remove these when issue 18630 is fixed.
+ LibraryElementX get patch => super.patch;
+ LibraryElementX get origin => super.origin;
}
class PrefixElementX extends ElementX implements PrefixElement {
@@ -1284,7 +1230,8 @@ class FieldParameterElementX extends ParameterElementX
/// patched with the corresponding parameter of the patch method. This is done
/// to ensure that default values on parameters are computed once (on the
/// origin parameter) but can be found through both the origin and the patch.
-class ParameterElementX extends ElementX implements ParameterElement {
+class ParameterElementX extends ElementX with PatchMixin<ParameterElement>
+ implements ParameterElement {
final VariableDefinitions definitions;
final Identifier identifier;
final Expression initializer;
@@ -1334,12 +1281,6 @@ class ParameterElementX extends ElementX implements ParameterElement {
FunctionType get functionType => type;
accept(ElementVisitor visitor) => visitor.visitVariableElement(this);
-
- ParameterElementX patch = null;
- ParameterElementX origin = null;
-
- bool get isPatch => origin != null;
- bool get isPatched => patch != null;
}
class AbstractFieldElementX extends ElementX implements AbstractFieldElement {
@@ -1486,7 +1427,8 @@ class FunctionSignatureX implements FunctionSignature {
}
}
-class FunctionElementX extends ElementX with AnalyzableElement
+class FunctionElementX
+ extends ElementX with AnalyzableElement, PatchMixin<FunctionElement>
implements FunctionElement {
FunctionExpression cachedNode;
DartType typeCache;
@@ -1496,14 +1438,6 @@ class FunctionElementX extends ElementX with AnalyzableElement
FunctionSignature functionSignatureCache;
- /**
- * A function declaration that should be parsed instead of the current one.
- * The patch should be parsed as if it was in the current scope. Its
- * signature must match this function's signature.
- */
- FunctionElement patch = null;
- FunctionElement origin = null;
-
final bool _hasNoBody;
AbstractFieldElement abstractField;
@@ -1545,9 +1479,6 @@ class FunctionElementX extends ElementX with AnalyzableElement
defaultImplementation = this;
}
- bool get isPatched => patch != null;
- bool get isPatch => origin != null;
-
bool get isRedirectingFactory => defaultImplementation != this;
/// This field is set by the post process queue when checking for cycles.
@@ -1575,18 +1506,6 @@ class FunctionElementX extends ElementX with AnalyzableElement
return redirectionTargetType.substByContext(newType);
}
- /**
- * Applies a patch function to this function. The patch function's body
- * is used as replacement when parsing this function's body.
- * This method must not be called after the function has been parsed,
- * and it must be called at most once.
- */
- void setPatch(FunctionElement patchElement) {
- // Sanity checks. The caller must check these things before calling.
- assert(patch == null);
- this.patch = patchElement;
- }
-
bool isInstanceMember() {
return isMember()
&& !isConstructor()
@@ -1911,6 +1830,7 @@ abstract class TypeDeclarationElementX<T extends GenericType>
abstract class BaseClassElementX extends ElementX
with AnalyzableElement,
TypeDeclarationElementX<InterfaceType>,
+ PatchMixin<ClassElement>,
ClassMemberMixin
implements ClassElement {
final int id;
@@ -1943,10 +1863,6 @@ abstract class BaseClassElementX extends ElementX
super(name, ElementKind.CLASS, enclosing);
int get hashCode => id;
- ClassElement get patch => super.patch;
- ClassElement get origin => super.origin;
- ClassElement get declaration => super.declaration;
- ClassElement get implementation => super.implementation;
bool get hasBackendMembers => !backendMembers.isEmpty;
@@ -2297,13 +2213,13 @@ abstract class BaseClassElementX extends ElementX
lookupInterfaceMember(const PublicName(Compiler.CALL_OPERATOR_NAME));
return member != null && member.isMethod ? member.type : null;
}
+
+ // TODO(johnniwinther): Remove these when issue 18630 is fixed.
+ ClassElement get patch => super.patch;
+ ClassElement get origin => super.origin;
}
abstract class ClassElementX extends BaseClassElementX {
- // Lazily applied patch of class members.
- ClassElement patch = null;
- ClassElement origin = null;
-
Link<Element> localMembers = const Link<Element>();
final ScopeX localScope = new ScopeX();
@@ -2313,8 +2229,6 @@ abstract class ClassElementX extends BaseClassElementX {
ClassNode parseNode(Compiler compiler);
bool get isMixinApplication => false;
- bool get isPatched => patch != null;
- bool get isPatch => origin != null;
bool get hasLocalScopeMembers => !localScope.isEmpty;
void addMember(Element element, DiagnosticListener listener) {
@@ -2393,16 +2307,9 @@ class MixinApplicationElementX extends BaseClassElementX
bool get hasConstructor => !constructors.isEmpty;
bool get hasLocalScopeMembers => !constructors.isEmpty;
- unsupported(message) {
- throw new UnsupportedError('$message is not supported on $this');
- }
-
get patch => null;
get origin => null;
- set patch(value) => unsupported('set patch');
- set origin(value) => unsupported('set origin');
-
Token position() => node.getBeginToken();
Node parseNode(DiagnosticListener listener) => node;
@@ -2626,3 +2533,34 @@ class ParameterMetadataAnnotation extends MetadataAnnotationX {
Token get endToken => metadata.getEndToken();
}
+/// Mixin for the implementation of patched elements.
+///
+/// See [:patch_parser.dart:] for a description of the terminology.
+abstract class PatchMixin<E extends Element> implements Element {
+ // TODO(johnniwinther): Use type variables when issue 18630 is fixed.
+ Element/*E*/ patch = null;
+ Element/*E*/ origin = null;
+
+ bool get isPatch => origin != null;
+ bool get isPatched => patch != null;
+
+ bool get isImplementation => !isPatched;
+ bool get isDeclaration => !isPatch;
+
+ Element/*E*/ get implementation => isPatched ? patch : this;
+ Element/*E*/ get declaration => isPatch ? origin : this;
+
+ /// Applies a patch to this element. This method must be called at most once.
+ void applyPatch(PatchMixin<E> patch) {
+ assert(invariant(this, this.patch == null,
+ message: "Element is patched twice."));
+ assert(invariant(this, this.origin == null,
+ message: "Origin element is a patch."));
+ assert(invariant(patch, patch.origin == null,
+ message: "Element is patched twice."));
+ assert(invariant(patch, patch.patch == null,
+ message: "Patch element is patched."));
+ this.patch = patch;
+ patch.origin = this;
+ }
+}

Powered by Google App Engine
This is Rietveld 408576698