blob: 5b6249597a053cbcc87f679adbe872a710256a72 [file] [log] [blame]
// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
// Tests that static fields are properly reset after hot restarts.
// Requirements=nnbd
import 'dart:_runtime' as dart show hotRestart, resetFields;
import 'package:expect/expect.dart';
String? noInitializer;
int withInitializer = 1;
class Statics {
static String? noInitializer;
static int withInitializer = 2;
}
class StaticsGeneric<T> {
static String? noInitializer;
static int withInitializer = 3;
}
class StaticsSetter {
static int counter = 0;
static const field = 5;
static const field2 = null;
static set field(int value) => StaticsSetter.counter += 1;
static set field2(value) => 42;
}
void main() {
testStaticFields();
testStaticSetterOfConstField();
}
void testStaticFields() {
var resetFieldCount = dart.resetFields.length;
// Set static fields without explicit initializers. Avoid calling getters for
// these statics to ensure they are reset even if they are never accessed.
noInitializer = 'set via setter';
Statics.noInitializer = 'Statics set via setter';
StaticsGeneric.noInitializer = 'StaticsGeneric set via setter';
// Initialized statics should contain their values.
Expect.equals(1, withInitializer);
Expect.equals(2, Statics.withInitializer);
Expect.equals(3, StaticsGeneric.withInitializer);
// Six new field resets from 3 setter calls and 3 getter calls.
var expectedResets = resetFieldCount + 6;
Expect.equals(expectedResets, dart.resetFields.length);
dart.hotRestart();
resetFieldCount = dart.resetFields.length;
// Uninitialized statics have been reset to their implicit null initial state.
Expect.equals(null, noInitializer);
Expect.equals(null, Statics.noInitializer);
Expect.equals(null, StaticsGeneric.noInitializer);
noInitializer = 'set via setter';
Statics.noInitializer = 'Statics set via setter';
StaticsGeneric.noInitializer = 'StaticsGeneric set via setter';
// All statics should contain their set values.
Expect.equals('set via setter', noInitializer);
Expect.equals('Statics set via setter', Statics.noInitializer);
Expect.equals('StaticsGeneric set via setter', StaticsGeneric.noInitializer);
Expect.equals(1, withInitializer);
Expect.equals(2, Statics.withInitializer);
Expect.equals(3, StaticsGeneric.withInitializer);
// Six total new field resets despite getter and setter calls on the same
// static fields.
expectedResets = resetFieldCount + 6;
Expect.equals(expectedResets, dart.resetFields.length);
dart.hotRestart();
dart.hotRestart();
resetFieldCount = dart.resetFields.length;
// All statics should contain their initial values.
Expect.equals(null, noInitializer);
Expect.equals(null, Statics.noInitializer);
Expect.equals(null, StaticsGeneric.noInitializer);
Expect.equals(1, withInitializer);
Expect.equals(2, Statics.withInitializer);
Expect.equals(3, StaticsGeneric.withInitializer);
// Six new field resets from 6 getter calls.
expectedResets = resetFieldCount + 6;
Expect.equals(expectedResets, dart.resetFields.length);
}
void testStaticSetterOfConstField() {
var resetFieldCount = dart.resetFields.length;
// Static setters of const fields should behave according to spec.
Expect.equals(StaticsSetter.counter, 0);
Expect.equals(StaticsSetter.field, 5);
StaticsSetter.field = 100;
StaticsSetter.field = 100;
StaticsSetter.field = 100;
Expect.equals(StaticsSetter.field, 5);
Expect.equals(StaticsSetter.counter, 3);
// 2 new field resets: [StaticsSetter.counter] and [StaticsSetter.field].
var expectedResets = resetFieldCount + 2;
Expect.equals(expectedResets, dart.resetFields.length);
dart.hotRestart();
resetFieldCount = dart.resetFields.length;
// Static setters of const fields should be properly reset.
Expect.equals(StaticsSetter.counter, 0);
Expect.equals(StaticsSetter.field, 5);
StaticsSetter.field = 100;
StaticsSetter.field = 100;
StaticsSetter.field = 100;
Expect.equals(StaticsSetter.field, 5);
Expect.equals(StaticsSetter.counter, 3);
// 2 new field resets: [StaticsSetter.counter] and [StaticsSetter.field].
expectedResets = resetFieldCount + 2;
Expect.equals(expectedResets, dart.resetFields.length);
dart.hotRestart();
dart.hotRestart();
resetFieldCount = dart.resetFields.length;
// Invoke the static setter but not the getter.
StaticsSetter.field2 = 100;
StaticsSetter.field2 = 100;
StaticsSetter.field2 = 100;
// 1 new field reset: [StaticsSetter.field2].
expectedResets = resetFieldCount + 1;
Expect.equals(expectedResets, dart.resetFields.length);
}