Don't write initializers of static final fields.

This was causing one of the new crashes in summaries.

Change-Id: I50e33a83d680070d1863f27b8ee276163b84c9d9
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/175905
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
This commit is contained in:
Konstantin Shcheglov
2020-12-12 07:27:40 +00:00
committed by commit-bot@chromium.org
parent 3d67e6f998
commit dd8401ac16
3 changed files with 49 additions and 13 deletions
@@ -85,7 +85,7 @@ typedef WorkToWaitAfterComputingResult = Future<void> Function(String path);
/// TODO(scheglov) Clean up the list of implicitly analyzed files.
class AnalysisDriver implements AnalysisDriverGeneric {
/// The version of data format, should be incremented on every format change.
static const int DATA_VERSION = 116;
static const int DATA_VERSION = 117;
/// The length of the list returned by [_computeDeclaredVariablesSignature].
static const int _declaredVariablesSignatureLength = 4;
@@ -34,9 +34,7 @@ class AstBinaryWriter extends ThrowingAstVisitor<void> {
/// for [_classMemberIndexItems]?
final List<_UnitMemberIndexItem> unitMemberIndexItems = [];
final List<_ClassMemberIndexItem> _classMemberIndexItems = [];
bool _isConstField = false;
bool _isFinalField = false;
bool _isConstTopLevelVariable = false;
bool _shouldStoreVariableInitializers = false;
bool _hasConstConstructor = false;
int _nextUnnamedExtensionId = 0;
@@ -571,13 +569,12 @@ class AstBinaryWriter extends ThrowingAstVisitor<void> {
var resolutionIndex = _getNextResolutionIndex();
_isConstField = node.fields.isConst;
_isFinalField = node.fields.isFinal;
_shouldStoreVariableInitializers = node.fields.isConst ||
_hasConstConstructor && node.fields.isFinal && !node.isStatic;
try {
_writeNode(node.fields);
} finally {
_isConstField = false;
_isFinalField = false;
_shouldStoreVariableInitializers = false;
}
_storeClassMember(node);
@@ -1440,11 +1437,11 @@ class AstBinaryWriter extends ThrowingAstVisitor<void> {
var resolutionIndex = _getNextResolutionIndex();
_isConstTopLevelVariable = node.variables.isConst;
_shouldStoreVariableInitializers = node.variables.isConst;
try {
_writeNode(node.variables);
} finally {
_isConstTopLevelVariable = false;
_shouldStoreVariableInitializers = false;
}
_storeCompilationUnitMember(node);
@@ -1522,9 +1519,7 @@ class AstBinaryWriter extends ThrowingAstVisitor<void> {
}
Expression initializerToWrite;
if (_isConstField ||
_hasConstConstructor && _isFinalField ||
_isConstTopLevelVariable) {
if (_shouldStoreVariableInitializers) {
var initializer = node.initializer;
if (_isSerializableExpression(initializer)) {
initializerToWrite = initializer;
@@ -22,6 +22,47 @@ class AnalysisDriverCachingTest extends PubPackageResolutionTest {
return driver.test.libraryContext.linkedCycles;
}
test_change_field_staticFinal_hasConstConstructor_changeInitializer() async {
useEmptyByteStore();
newFile(testFilePath, content: r'''
class A {
static const a = 0;
static const b = 1;
static final Set<int> f = {a};
const A {}
}
''');
await resolveTestFile();
assertType(findElement.field('f').type, 'Set<int>');
// The summary for the library was linked.
_assertContainsLinkedCycle({testFilePath}, andClear: true);
// Dispose the collection, with its driver.
// The next analysis will recreate it.
// We will reuse the byte store, so can reuse summaries.
disposeAnalysisContextCollection();
newFile(testFilePath, content: r'''
class A {
static const a = 0;
static const b = 1;
static final Set<int> f = <int>{a, b, 2};
const A {}
}
''');
await resolveTestFile();
assertType(findElement.field('f').type, 'Set<int>');
// We changed the initializer of the final field. But it is static, so
// even though the class hsa a constant constructor, we don't need its
// initializer, so nothing should be linked.
_assertNoLinkedCycles();
}
test_change_functionBody() async {
useEmptyByteStore();