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

Unified Diff: runtime/vm/isolate_reload_test.cc

Issue 2489723003: Run field initializers for new instance fields after a reload (Closed)
Patch Set: Fix a comment Created 4 years, 1 month 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
« no previous file with comments | « runtime/vm/isolate_reload.cc ('k') | runtime/vm/object.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/isolate_reload_test.cc
diff --git a/runtime/vm/isolate_reload_test.cc b/runtime/vm/isolate_reload_test.cc
index 7c7daa63cfb6db736c954fab8f6b6761c58f37fd..e9a3e7c2026c8047b088429c233c39d88fe5d6a5 100644
--- a/runtime/vm/isolate_reload_test.cc
+++ b/runtime/vm/isolate_reload_test.cc
@@ -3123,6 +3123,297 @@ TEST_CASE(IsolateReload_ConstFieldUpdate) {
EXPECT_STREQ("value=0:00:02.000000", SimpleInvokeStr(lib, "main"));
}
+
+TEST_CASE(IsolateReload_RunNewFieldInitializers) {
+ const char* kScript =
+ "class Foo {\n"
+ " int x = 4;\n"
+ "}\n"
+ "Foo value;\n"
+ "main() {\n"
+ " value = new Foo();\n"
+ " return value.x;\n"
+ "}\n";
+
+ Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL);
+ EXPECT_VALID(lib);
+ EXPECT_EQ(4, SimpleInvoke(lib, "main"));
+
+ // Add the field y.
+ const char* kReloadScript =
+ "class Foo {\n"
+ " int x = 4;\n"
+ " int y = 7;\n"
+ "}\n"
+ "Foo value;\n"
+ "main() {\n"
+ " return value.y;\n"
+ "}\n";
+
+ lib = TestCase::ReloadTestScript(kReloadScript);
+ EXPECT_VALID(lib);
+ // Verify that we ran field initializers on existing instances.
+ EXPECT_EQ(7, SimpleInvoke(lib, "main"));
+}
+
+
+TEST_CASE(IsolateReload_RunNewFieldInitializersReferenceStaticField) {
+ const char* kScript =
+ "int myInitialValue = 8 * 7;\n"
+ "class Foo {\n"
+ " int x = 4;\n"
+ "}\n"
+ "Foo value;\n"
+ "main() {\n"
+ " value = new Foo();\n"
+ " return value.x;\n"
+ "}\n";
+
+ Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL);
+ EXPECT_VALID(lib);
+ EXPECT_EQ(4, SimpleInvoke(lib, "main"));
+
+ // Add the field y.
+ const char* kReloadScript =
+ "int myInitialValue = 8 * 7;\n"
+ "class Foo {\n"
+ " int x = 4;\n"
+ " int y = myInitialValue;\n"
+ "}\n"
+ "Foo value;\n"
+ "main() {\n"
+ " return value.y;\n"
+ "}\n";
+
+ lib = TestCase::ReloadTestScript(kReloadScript);
+ EXPECT_VALID(lib);
+ // Verify that we ran field initializers on existing instances.
+ EXPECT_EQ(56, SimpleInvoke(lib, "main"));
+}
+
+
+TEST_CASE(IsolateReload_RunNewFieldInitializersMutateStaticField) {
+ const char* kScript =
+ "int myInitialValue = 8 * 7;\n"
+ "class Foo {\n"
+ " int x = 4;\n"
+ "}\n"
+ "Foo value;\n"
+ "Foo value1;\n"
+ "main() {\n"
+ " value = new Foo();\n"
+ " value1 = new Foo();\n"
+ " return value.x;\n"
+ "}\n";
+
+ Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL);
+ EXPECT_VALID(lib);
+ EXPECT_EQ(4, SimpleInvoke(lib, "main"));
+
+ // Add the field y.
+ const char* kReloadScript =
+ "int myInitialValue = 8 * 7;\n"
+ "class Foo {\n"
+ " int x = 4;\n"
+ " int y = myInitialValue++;\n"
+ "}\n"
+ "Foo value;\n"
+ "Foo value1;\n"
+ "main() {\n"
+ " return myInitialValue;\n"
+ "}\n";
+
+ lib = TestCase::ReloadTestScript(kReloadScript);
+ EXPECT_VALID(lib);
+ // Verify that we ran field initializers on existing instances and that
+ // they affected the value of the field myInitialValue.
+ EXPECT_EQ(58, SimpleInvoke(lib, "main"));
+}
+
+
+// When an initializer expression throws, we leave the field as null.
+TEST_CASE(IsolateReload_RunNewFieldInitializersThrows) {
+ const char* kScript =
+ "class Foo {\n"
+ " int x = 4;\n"
+ "}\n"
+ "Foo value;\n"
+ "main() {\n"
+ " value = new Foo();\n"
+ " return value.x;\n"
+ "}\n";
+
+ Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL);
+ EXPECT_VALID(lib);
+ EXPECT_EQ(4, SimpleInvoke(lib, "main"));
+
+ // Add the field y.
+ const char* kReloadScript =
+ "class Foo {\n"
+ " int x = 4;\n"
+ " int y = throw 'a';\n"
+ "}\n"
+ "Foo value;\n"
+ "main() {\n"
+ " return '${value.y == null}';"
+ "}\n";
+
+ lib = TestCase::ReloadTestScript(kReloadScript);
+ EXPECT_VALID(lib);
+ // Verify that we ran field initializers on existing instances.
+ EXPECT_STREQ("true", SimpleInvokeStr(lib, "main"));
+}
+
+
+// When an initializer expression has a syntax error, we detect it at reload
+// time.
+TEST_CASE(IsolateReload_RunNewFieldInitializersSyntaxError) {
+ const char* kScript =
+ "class Foo {\n"
+ " int x = 4;\n"
+ "}\n"
+ "Foo value;\n"
+ "main() {\n"
+ " value = new Foo();\n"
+ " return value.x;\n"
+ "}\n";
+
+ Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL);
+ EXPECT_VALID(lib);
+ EXPECT_EQ(4, SimpleInvoke(lib, "main"));
+
+ // Add the field y with a syntax error in the initializing expression.
+ const char* kReloadScript =
+ "class Foo {\n"
+ " int x = 4;\n"
+ " int y = ......;\n"
+ "}\n"
+ "Foo value;\n"
+ "main() {\n"
+ " return '${value.y == null}';"
+ "}\n";
+
+ // The reload fails because the initializing expression is parsed at
+ // class finalization time.
+ lib = TestCase::ReloadTestScript(kReloadScript);
+ EXPECT_ERROR(lib, "......");
+}
+
+
+// When an initializer expression has a syntax error, we detect it at reload
+// time.
+TEST_CASE(IsolateReload_RunNewFieldInitializersSyntaxError2) {
+ const char* kScript =
+ "class Foo {\n"
+ " Foo() { /* default constructor */ }\n"
+ " int x = 4;\n"
+ "}\n"
+ "Foo value;\n"
+ "main() {\n"
+ " value = new Foo();\n"
+ " return value.x;\n"
+ "}\n";
+
+ Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL);
+ EXPECT_VALID(lib);
+ EXPECT_EQ(4, SimpleInvoke(lib, "main"));
+
+ // Add the field y with a syntax error in the initializing expression.
+ const char* kReloadScript =
+ "class Foo {\n"
+ " Foo() { /* default constructor */ }\n"
+ " int x = 4;\n"
+ " int y = ......;\n"
+ "}\n"
+ "Foo value;\n"
+ "main() {\n"
+ " return '${value.y == null}';"
+ "}\n";
+
+ // The reload fails because the initializing expression is parsed at
+ // class finalization time.
+ lib = TestCase::ReloadTestScript(kReloadScript);
+ EXPECT_ERROR(lib, "......");
+}
+
+
+// When an initializer expression has a syntax error, we detect it at reload
+// time.
+TEST_CASE(IsolateReload_RunNewFieldInitializersSyntaxError3) {
+ const char* kScript =
+ "class Foo {\n"
+ " Foo() { /* default constructor */ }\n"
+ " int x = 4;\n"
+ "}\n"
+ "Foo value;\n"
+ "main() {\n"
+ " value = new Foo();\n"
+ " return value.x;\n"
+ "}\n";
+
+ Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL);
+ EXPECT_VALID(lib);
+ EXPECT_EQ(4, SimpleInvoke(lib, "main"));
+
+ // Add the field y with a syntax error in the initializing expression.
+ const char* kReloadScript =
+ "class Foo {\n"
+ " Foo() { /* default constructor */ }\n"
+ " int x = 4;\n"
+ " int y = ......\n"
+ "}\n"
+ "Foo value;\n"
+ "main() {\n"
+ " return '${value.y == null}';"
+ "}\n";
+
+ // The reload fails because the initializing expression is parsed at
+ // class finalization time.
+ lib = TestCase::ReloadTestScript(kReloadScript);
+ EXPECT_ERROR(lib, "......");
+}
+
+
+TEST_CASE(IsolateREload_RunNewFieldInitialiazersSuperClass) {
+ const char* kScript =
+ "class Super {\n"
+ " static var foo = 'right';\n"
+ "}\n"
+ "class Foo extends Super {\n"
+ " static var foo = 'wrong';\n"
+ "}\n"
+ "Foo value;\n"
+ "main() {\n"
+ " Super.foo;\n"
+ " Foo.foo;\n"
+ " value = new Foo();\n"
+ " return 0;\n"
+ "}\n";
+
+ Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL);
+ EXPECT_VALID(lib);
+ EXPECT_EQ(0, SimpleInvoke(lib, "main"));
+
+ const char* kReloadScript =
+ "class Super {\n"
+ " static var foo = 'right';\n"
+ " var newField = foo;\n"
+ "}\n"
+ "class Foo extends Super {\n"
+ " static var foo = 'wrong';\n"
+ "}\n"
+ "Foo value;\n"
+ "main() {\n"
+ " return value.newField;\n"
+ "}\n";
+
+ lib = TestCase::ReloadTestScript(kReloadScript);
+ EXPECT_VALID(lib);
+ // Verify that we ran field initializers on existing instances in the
+ // correct scope.
+ EXPECT_STREQ("right", SimpleInvokeStr(lib, "main"));
+}
+
#endif // !PRODUCT
} // namespace dart
« no previous file with comments | « runtime/vm/isolate_reload.cc ('k') | runtime/vm/object.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698