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

Unified Diff: pkg/analyzer/lib/src/dart/element/element.dart

Issue 1696193003: Fix cache corruption in incremental resolver (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: post-review cleanup Created 4 years, 10 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: pkg/analyzer/lib/src/dart/element/element.dart
diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart
index 9677e893fea33b68fae76034c98569be2a5fee91..4b031464d10b1cabaeda8af3d800bd811258c55a 100644
--- a/pkg/analyzer/lib/src/dart/element/element.dart
+++ b/pkg/analyzer/lib/src/dart/element/element.dart
@@ -1789,11 +1789,12 @@ abstract class ElementImpl implements Element {
/**
* Set the enclosing element of this element to the given [element].
+ *
+ * Throws [FrozenHashCodeException] if the hashCode can't be changed.
*/
void set enclosingElement(Element element) {
_enclosingElement = element as ElementImpl;
- _cachedLocation = null;
- _cachedHashCode = null;
+ _updateCaches();
}
@override
@@ -1865,10 +1866,15 @@ abstract class ElementImpl implements Element {
@override
String get name => _name;
+
+ /**
+ * Changes the name of this element.
+ *
+ * Throws [FrozenHashCodeException] if the hashCode can't be changed.
+ */
void set name(String name) {
this._name = name;
- _cachedLocation = null;
- _cachedHashCode = null;
+ _updateCaches();
}
@override
@@ -1880,11 +1886,12 @@ abstract class ElementImpl implements Element {
/**
* Sets the offset of the name of this element in the file that contains the
* declaration of this element.
+ *
+ * Throws [FrozenHashCodeException] if the hashCode can't be changed.
*/
void set nameOffset(int offset) {
_nameOffset = offset;
- _cachedHashCode = null;
- _cachedLocation = null;
+ _updateCaches();
}
@override
@@ -2045,6 +2052,35 @@ abstract class ElementImpl implements Element {
void visitChildren(ElementVisitor visitor) {
// There are no children to visit
}
+
+ /**
+ * Updates cached values after an input changed.
+ *
+ * Throws [FrozenHashCodeException] if not allowed.
+ */
+ void _updateCaches() {
+ if (!hasModifier(Modifier.CACHE_KEY)) {
+ // Fast path.
+ _cachedLocation = null;
+ _cachedHashCode = null;
+ return;
+ }
+
+ // Save originals.
+ ElementLocation oldLocation = _cachedLocation;
+ int oldHashCode = _cachedHashCode;
+
+ _cachedLocation = null;
+ _cachedHashCode = null;
+
+ if (oldHashCode != hashCode) {
+ // Prevent cache corruption by restoring originals.
+ _cachedLocation = oldLocation;
+ _cachedHashCode = oldHashCode;
+ throw new FrozenHashCodeException(
+ "can't update hashCode for a cache key: $this ($runtimeType)");
+ }
+ }
}
/**
@@ -2575,6 +2611,18 @@ class FieldFormalParameterElementImpl extends ParameterElementImpl
}
/**
+ * Indicates that an ElementImpl's hashCode cannot currently be changed.
+ */
+class FrozenHashCodeException implements Exception {
+ final String _message;
+
+ FrozenHashCodeException(this._message);
+
+ @override
+ String toString() => "FrozenHashCodeException($_message)";
+}
+
+/**
* A concrete implementation of a [FunctionElement].
*/
class FunctionElementImpl extends ExecutableElementImpl
@@ -3815,7 +3863,12 @@ class Modifier extends Enum<Modifier> {
*/
static const Modifier SYNTHETIC = const Modifier('SYNTHETIC', 18);
- static const List<Modifier> values = const [
+ /**
+ * Indicates that this element is being used as an analyzer cache key.
+ */
+ static const Modifier CACHE_KEY = const Modifier('CACHE_KEY', 19);
+
+ static const List<Modifier> persistedValues = const [
ABSTRACT,
ASYNCHRONOUS,
CONST,
@@ -3837,6 +3890,11 @@ class Modifier extends Enum<Modifier> {
SYNTHETIC
];
+ static const List<Modifier> transientValues = const [CACHE_KEY];
+
+ static final values = new List.unmodifiable(
+ []..addAll(persistedValues)..addAll(transientValues));
+
const Modifier(String name, int ordinal) : super(name, ordinal);
}

Powered by Google App Engine
This is Rietveld 408576698