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

Side by Side 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 unified diff | Download patch
OLDNEW
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, 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 library analyzer.src.dart.element.element; 5 library analyzer.src.dart.element.element;
6 6
7 import 'dart:collection'; 7 import 'dart:collection';
8 import 'dart:math' show min; 8 import 'dart:math' show min;
9 9
10 import 'package:analyzer/dart/ast/ast.dart'; 10 import 'package:analyzer/dart/ast/ast.dart';
(...skipping 1771 matching lines...) Expand 10 before | Expand all | Expand 10 after
1782 */ 1782 */
1783 void set documentationComment(String doc) { 1783 void set documentationComment(String doc) {
1784 _docComment = doc?.replaceAll('\r\n', '\n'); 1784 _docComment = doc?.replaceAll('\r\n', '\n');
1785 } 1785 }
1786 1786
1787 @override 1787 @override
1788 Element get enclosingElement => _enclosingElement; 1788 Element get enclosingElement => _enclosingElement;
1789 1789
1790 /** 1790 /**
1791 * Set the enclosing element of this element to the given [element]. 1791 * Set the enclosing element of this element to the given [element].
1792 *
1793 * Throws [FrozenHashCodeException] if the hashCode can't be changed.
1792 */ 1794 */
1793 void set enclosingElement(Element element) { 1795 void set enclosingElement(Element element) {
1794 _enclosingElement = element as ElementImpl; 1796 _enclosingElement = element as ElementImpl;
1795 _cachedLocation = null; 1797 _updateCaches();
1796 _cachedHashCode = null;
1797 } 1798 }
1798 1799
1799 @override 1800 @override
1800 int get hashCode { 1801 int get hashCode {
1801 // TODO: We might want to re-visit this optimization in the future. 1802 // TODO: We might want to re-visit this optimization in the future.
1802 // We cache the hash code value as this is a very frequently called method. 1803 // We cache the hash code value as this is a very frequently called method.
1803 if (_cachedHashCode == null) { 1804 if (_cachedHashCode == null) {
1804 _cachedHashCode = location.hashCode; 1805 _cachedHashCode = location.hashCode;
1805 } 1806 }
1806 return _cachedHashCode; 1807 return _cachedHashCode;
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
1858 return new ElementLocationImpl.con1(this); 1859 return new ElementLocationImpl.con1(this);
1859 } 1860 }
1860 _cachedLocation = new ElementLocationImpl.con1(this); 1861 _cachedLocation = new ElementLocationImpl.con1(this);
1861 } 1862 }
1862 return _cachedLocation; 1863 return _cachedLocation;
1863 } 1864 }
1864 1865
1865 @override 1866 @override
1866 String get name => _name; 1867 String get name => _name;
1867 1868
1869
1870 /**
1871 * Changes the name of this element.
1872 *
1873 * Throws [FrozenHashCodeException] if the hashCode can't be changed.
1874 */
1868 void set name(String name) { 1875 void set name(String name) {
1869 this._name = name; 1876 this._name = name;
1870 _cachedLocation = null; 1877 _updateCaches();
1871 _cachedHashCode = null;
1872 } 1878 }
1873 1879
1874 @override 1880 @override
1875 int get nameLength => displayName != null ? displayName.length : 0; 1881 int get nameLength => displayName != null ? displayName.length : 0;
1876 1882
1877 @override 1883 @override
1878 int get nameOffset => _nameOffset; 1884 int get nameOffset => _nameOffset;
1879 1885
1880 /** 1886 /**
1881 * Sets the offset of the name of this element in the file that contains the 1887 * Sets the offset of the name of this element in the file that contains the
1882 * declaration of this element. 1888 * declaration of this element.
1889 *
1890 * Throws [FrozenHashCodeException] if the hashCode can't be changed.
1883 */ 1891 */
1884 void set nameOffset(int offset) { 1892 void set nameOffset(int offset) {
1885 _nameOffset = offset; 1893 _nameOffset = offset;
1886 _cachedHashCode = null; 1894 _updateCaches();
1887 _cachedLocation = null;
1888 } 1895 }
1889 1896
1890 @override 1897 @override
1891 Source get source { 1898 Source get source {
1892 if (_enclosingElement == null) { 1899 if (_enclosingElement == null) {
1893 return null; 1900 return null;
1894 } 1901 }
1895 return _enclosingElement.source; 1902 return _enclosingElement.source;
1896 } 1903 }
1897 1904
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
2038 String toString() { 2045 String toString() {
2039 StringBuffer buffer = new StringBuffer(); 2046 StringBuffer buffer = new StringBuffer();
2040 appendTo(buffer); 2047 appendTo(buffer);
2041 return buffer.toString(); 2048 return buffer.toString();
2042 } 2049 }
2043 2050
2044 @override 2051 @override
2045 void visitChildren(ElementVisitor visitor) { 2052 void visitChildren(ElementVisitor visitor) {
2046 // There are no children to visit 2053 // There are no children to visit
2047 } 2054 }
2055
2056 /**
2057 * Updates cached values after an input changed.
2058 *
2059 * Throws [FrozenHashCodeException] if not allowed.
2060 */
2061 void _updateCaches() {
2062 if (!hasModifier(Modifier.CACHE_KEY)) {
2063 // Fast path.
2064 _cachedLocation = null;
2065 _cachedHashCode = null;
2066 return;
2067 }
2068
2069 // Save originals.
2070 ElementLocation oldLocation = _cachedLocation;
2071 int oldHashCode = _cachedHashCode;
2072
2073 _cachedLocation = null;
2074 _cachedHashCode = null;
2075
2076 if (oldHashCode != hashCode) {
2077 // Prevent cache corruption by restoring originals.
2078 _cachedLocation = oldLocation;
2079 _cachedHashCode = oldHashCode;
2080 throw new FrozenHashCodeException(
2081 "can't update hashCode for a cache key: $this ($runtimeType)");
2082 }
2083 }
2048 } 2084 }
2049 2085
2050 /** 2086 /**
2051 * A concrete implementation of an [ElementLocation]. 2087 * A concrete implementation of an [ElementLocation].
2052 */ 2088 */
2053 class ElementLocationImpl implements ElementLocation { 2089 class ElementLocationImpl implements ElementLocation {
2054 /** 2090 /**
2055 * The character used to separate components in the encoded form. 2091 * The character used to separate components in the encoded form.
2056 */ 2092 */
2057 static int _SEPARATOR_CHAR = 0x3B; 2093 static int _SEPARATOR_CHAR = 0x3B;
(...skipping 510 matching lines...) Expand 10 before | Expand all | Expand 10 after
2568 2604
2569 @override 2605 @override
2570 bool get isInitializingFormal => true; 2606 bool get isInitializingFormal => true;
2571 2607
2572 @override 2608 @override
2573 accept(ElementVisitor visitor) => 2609 accept(ElementVisitor visitor) =>
2574 visitor.visitFieldFormalParameterElement(this); 2610 visitor.visitFieldFormalParameterElement(this);
2575 } 2611 }
2576 2612
2577 /** 2613 /**
2614 * Indicates that an ElementImpl's hashCode cannot currently be changed.
2615 */
2616 class FrozenHashCodeException implements Exception {
2617 final String _message;
2618
2619 FrozenHashCodeException(this._message);
2620
2621 @override
2622 String toString() => "FrozenHashCodeException($_message)";
2623 }
2624
2625 /**
2578 * A concrete implementation of a [FunctionElement]. 2626 * A concrete implementation of a [FunctionElement].
2579 */ 2627 */
2580 class FunctionElementImpl extends ExecutableElementImpl 2628 class FunctionElementImpl extends ExecutableElementImpl
2581 implements FunctionElement { 2629 implements FunctionElement {
2582 /** 2630 /**
2583 * The offset to the beginning of the visible range for this element. 2631 * The offset to the beginning of the visible range for this element.
2584 */ 2632 */
2585 int _visibleRangeOffset = 0; 2633 int _visibleRangeOffset = 0;
2586 2634
2587 /** 2635 /**
(...skipping 1220 matching lines...) Expand 10 before | Expand all | Expand 10 after
3808 static const Modifier STATIC = const Modifier('STATIC', 17); 3856 static const Modifier STATIC = const Modifier('STATIC', 17);
3809 3857
3810 /** 3858 /**
3811 * Indicates that the element does not appear in the source code but was 3859 * Indicates that the element does not appear in the source code but was
3812 * implicitly created. For example, if a class does not define any 3860 * implicitly created. For example, if a class does not define any
3813 * constructors, an implicit zero-argument constructor will be created and it 3861 * constructors, an implicit zero-argument constructor will be created and it
3814 * will be marked as being synthetic. 3862 * will be marked as being synthetic.
3815 */ 3863 */
3816 static const Modifier SYNTHETIC = const Modifier('SYNTHETIC', 18); 3864 static const Modifier SYNTHETIC = const Modifier('SYNTHETIC', 18);
3817 3865
3818 static const List<Modifier> values = const [ 3866 /**
3867 * Indicates that this element is being used as an analyzer cache key.
3868 */
3869 static const Modifier CACHE_KEY = const Modifier('CACHE_KEY', 19);
3870
3871 static const List<Modifier> persistedValues = const [
3819 ABSTRACT, 3872 ABSTRACT,
3820 ASYNCHRONOUS, 3873 ASYNCHRONOUS,
3821 CONST, 3874 CONST,
3822 DEFERRED, 3875 DEFERRED,
3823 ENUM, 3876 ENUM,
3824 EXTERNAL, 3877 EXTERNAL,
3825 FACTORY, 3878 FACTORY,
3826 FINAL, 3879 FINAL,
3827 GENERATOR, 3880 GENERATOR,
3828 GETTER, 3881 GETTER,
3829 HAS_EXT_URI, 3882 HAS_EXT_URI,
3830 IMPLICIT_TYPE, 3883 IMPLICIT_TYPE,
3831 MIXIN_APPLICATION, 3884 MIXIN_APPLICATION,
3832 POTENTIALLY_MUTATED_IN_CONTEXT, 3885 POTENTIALLY_MUTATED_IN_CONTEXT,
3833 POTENTIALLY_MUTATED_IN_SCOPE, 3886 POTENTIALLY_MUTATED_IN_SCOPE,
3834 REFERENCES_SUPER, 3887 REFERENCES_SUPER,
3835 SETTER, 3888 SETTER,
3836 STATIC, 3889 STATIC,
3837 SYNTHETIC 3890 SYNTHETIC
3838 ]; 3891 ];
3839 3892
3893 static const List<Modifier> transientValues = const [CACHE_KEY];
3894
3895 static final values = new List.unmodifiable(
3896 []..addAll(persistedValues)..addAll(transientValues));
3897
3840 const Modifier(String name, int ordinal) : super(name, ordinal); 3898 const Modifier(String name, int ordinal) : super(name, ordinal);
3841 } 3899 }
3842 3900
3843 /** 3901 /**
3844 * A concrete implementation of a [MultiplyDefinedElement]. 3902 * A concrete implementation of a [MultiplyDefinedElement].
3845 */ 3903 */
3846 class MultiplyDefinedElementImpl implements MultiplyDefinedElement { 3904 class MultiplyDefinedElementImpl implements MultiplyDefinedElement {
3847 /** 3905 /**
3848 * The unique integer identifier of this element. 3906 * The unique integer identifier of this element.
3849 */ 3907 */
(...skipping 941 matching lines...) Expand 10 before | Expand all | Expand 10 after
4791 4849
4792 @override 4850 @override
4793 void visitElement(Element element) { 4851 void visitElement(Element element) {
4794 int offset = element.nameOffset; 4852 int offset = element.nameOffset;
4795 if (offset != -1) { 4853 if (offset != -1) {
4796 map[offset] = element; 4854 map[offset] = element;
4797 } 4855 }
4798 super.visitElement(element); 4856 super.visitElement(element);
4799 } 4857 }
4800 } 4858 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698