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

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: 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 1774 matching lines...) Expand 10 before | Expand all | Expand 10 after
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 */ 1792 */
1793 void set enclosingElement(Element element) { 1793 void set enclosingElement(Element element) {
1794 _enclosingElement = element as ElementImpl; 1794 _enclosingElement = element as ElementImpl;
1795 _cachedLocation = null; 1795 _updateCaches();
1796 _cachedHashCode = null;
1797 } 1796 }
1798 1797
1799 @override 1798 @override
1800 int get hashCode { 1799 int get hashCode {
1801 // TODO: We might want to re-visit this optimization in the future. 1800 // 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. 1801 // We cache the hash code value as this is a very frequently called method.
1803 if (_cachedHashCode == null) { 1802 if (_cachedHashCode == null) {
1804 _cachedHashCode = location.hashCode; 1803 _cachedHashCode = location.hashCode;
1805 } 1804 }
1806 return _cachedHashCode; 1805 return _cachedHashCode;
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
1860 _cachedLocation = new ElementLocationImpl.con1(this); 1859 _cachedLocation = new ElementLocationImpl.con1(this);
1861 } 1860 }
1862 return _cachedLocation; 1861 return _cachedLocation;
1863 } 1862 }
1864 1863
1865 @override 1864 @override
1866 String get name => _name; 1865 String get name => _name;
1867 1866
1868 void set name(String name) { 1867 void set name(String name) {
1869 this._name = name; 1868 this._name = name;
1870 _cachedLocation = null; 1869 _updateCaches();
1871 _cachedHashCode = null;
1872 } 1870 }
1873 1871
1874 @override 1872 @override
1875 int get nameLength => displayName != null ? displayName.length : 0; 1873 int get nameLength => displayName != null ? displayName.length : 0;
1876 1874
1877 @override 1875 @override
1878 int get nameOffset => _nameOffset; 1876 int get nameOffset => _nameOffset;
1879 1877
1880 /** 1878 /**
1881 * Sets the offset of the name of this element in the file that contains the 1879 * Sets the offset of the name of this element in the file that contains the
1882 * declaration of this element. 1880 * declaration of this element.
1883 */ 1881 */
1884 void set nameOffset(int offset) { 1882 void set nameOffset(int offset) {
1885 _nameOffset = offset; 1883 _nameOffset = offset;
1886 _cachedHashCode = null; 1884 _updateCaches();
1887 _cachedLocation = null;
1888 } 1885 }
1889 1886
1890 @override 1887 @override
1891 Source get source { 1888 Source get source {
1892 if (_enclosingElement == null) { 1889 if (_enclosingElement == null) {
1893 return null; 1890 return null;
1894 } 1891 }
1895 return _enclosingElement.source; 1892 return _enclosingElement.source;
1896 } 1893 }
1897 1894
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
2038 String toString() { 2035 String toString() {
2039 StringBuffer buffer = new StringBuffer(); 2036 StringBuffer buffer = new StringBuffer();
2040 appendTo(buffer); 2037 appendTo(buffer);
2041 return buffer.toString(); 2038 return buffer.toString();
2042 } 2039 }
2043 2040
2044 @override 2041 @override
2045 void visitChildren(ElementVisitor visitor) { 2042 void visitChildren(ElementVisitor visitor) {
2046 // There are no children to visit 2043 // There are no children to visit
2047 } 2044 }
2045
2046 /**
2047 * Updates cached values after an input changed.
2048 */
2049 void _updateCaches() {
2050 if (!hasModifier(Modifier.CACHE_KEY)) {
2051 // Fast path.
2052 _cachedLocation = null;
2053 _cachedHashCode = null;
2054 return;
2055 }
2056
2057 // Save originals.
2058 ElementLocation oldLocation = _cachedLocation;
2059 int oldHashCode = _cachedHashCode;
2060
2061 _cachedLocation = null;
2062 _cachedHashCode = null;
2063
2064 if (oldHashCode != hashCode) {
2065 // Prevent cache corruption by restoring originals.
2066 _cachedLocation = oldLocation;
2067 _cachedHashCode = oldHashCode;
2068 throw new StateError(
2069 "can't update hashCode for a cache key: $this ($runtimeType)");
2070 }
2071 }
2048 } 2072 }
2049 2073
2050 /** 2074 /**
2051 * A concrete implementation of an [ElementLocation]. 2075 * A concrete implementation of an [ElementLocation].
2052 */ 2076 */
2053 class ElementLocationImpl implements ElementLocation { 2077 class ElementLocationImpl implements ElementLocation {
2054 /** 2078 /**
2055 * The character used to separate components in the encoded form. 2079 * The character used to separate components in the encoded form.
2056 */ 2080 */
2057 static int _SEPARATOR_CHAR = 0x3B; 2081 static int _SEPARATOR_CHAR = 0x3B;
(...skipping 1750 matching lines...) Expand 10 before | Expand all | Expand 10 after
3808 static const Modifier STATIC = const Modifier('STATIC', 17); 3832 static const Modifier STATIC = const Modifier('STATIC', 17);
3809 3833
3810 /** 3834 /**
3811 * Indicates that the element does not appear in the source code but was 3835 * 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 3836 * implicitly created. For example, if a class does not define any
3813 * constructors, an implicit zero-argument constructor will be created and it 3837 * constructors, an implicit zero-argument constructor will be created and it
3814 * will be marked as being synthetic. 3838 * will be marked as being synthetic.
3815 */ 3839 */
3816 static const Modifier SYNTHETIC = const Modifier('SYNTHETIC', 18); 3840 static const Modifier SYNTHETIC = const Modifier('SYNTHETIC', 18);
3817 3841
3818 static const List<Modifier> values = const [ 3842 /**
3843 * Indicates that this element is being used as an analyzer cache key.
3844 */
3845 static const Modifier CACHE_KEY = const Modifier('CACHE_KEY', 19);
3846
3847 static const List<Modifier> persistedValues = const [
3819 ABSTRACT, 3848 ABSTRACT,
3820 ASYNCHRONOUS, 3849 ASYNCHRONOUS,
3821 CONST, 3850 CONST,
3822 DEFERRED, 3851 DEFERRED,
3823 ENUM, 3852 ENUM,
3824 EXTERNAL, 3853 EXTERNAL,
3825 FACTORY, 3854 FACTORY,
3826 FINAL, 3855 FINAL,
3827 GENERATOR, 3856 GENERATOR,
3828 GETTER, 3857 GETTER,
3829 HAS_EXT_URI, 3858 HAS_EXT_URI,
3830 IMPLICIT_TYPE, 3859 IMPLICIT_TYPE,
3831 MIXIN_APPLICATION, 3860 MIXIN_APPLICATION,
3832 POTENTIALLY_MUTATED_IN_CONTEXT, 3861 POTENTIALLY_MUTATED_IN_CONTEXT,
3833 POTENTIALLY_MUTATED_IN_SCOPE, 3862 POTENTIALLY_MUTATED_IN_SCOPE,
3834 REFERENCES_SUPER, 3863 REFERENCES_SUPER,
3835 SETTER, 3864 SETTER,
3836 STATIC, 3865 STATIC,
3837 SYNTHETIC 3866 SYNTHETIC
3838 ]; 3867 ];
3839 3868
3869 static const List<Modifier> transientValues = const [CACHE_KEY];
3870
3871 static final values = new List.unmodifiable(
3872 []..addAll(persistedValues)..addAll(transientValues));
3873
3840 const Modifier(String name, int ordinal) : super(name, ordinal); 3874 const Modifier(String name, int ordinal) : super(name, ordinal);
3841 } 3875 }
3842 3876
3843 /** 3877 /**
3844 * A concrete implementation of a [MultiplyDefinedElement]. 3878 * A concrete implementation of a [MultiplyDefinedElement].
3845 */ 3879 */
3846 class MultiplyDefinedElementImpl implements MultiplyDefinedElement { 3880 class MultiplyDefinedElementImpl implements MultiplyDefinedElement {
3847 /** 3881 /**
3848 * The unique integer identifier of this element. 3882 * The unique integer identifier of this element.
3849 */ 3883 */
(...skipping 941 matching lines...) Expand 10 before | Expand all | Expand 10 after
4791 4825
4792 @override 4826 @override
4793 void visitElement(Element element) { 4827 void visitElement(Element element) {
4794 int offset = element.nameOffset; 4828 int offset = element.nameOffset;
4795 if (offset != -1) { 4829 if (offset != -1) {
4796 map[offset] = element; 4830 map[offset] = element;
4797 } 4831 }
4798 super.visitElement(element); 4832 super.visitElement(element);
4799 } 4833 }
4800 } 4834 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698