From c4b7097e97f4e270901ff436f46c54b62d548e3a Mon Sep 17 00:00:00 2001 From: Ben Konyi Date: Tue, 26 May 2020 22:40:52 +0000 Subject: [PATCH] [ VM ] Migrate VM tests to support null safety and return errors from Dart_GetType and Dart_NewListOf when --null-safety is enabled These methods return legacy types, which aren't valid with null safety enabled. Fixes https://github.com/dart-lang/sdk/issues/41154 Change-Id: I1181f0f3b9a8df156dea4dc4c82fef8afdf97ab9 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/148685 Commit-Queue: Ben Konyi Reviewed-by: Siva Annamalai Reviewed-by: Ryan Macnak --- .../tool/dartdevc_nnbd_sdk_error_golden.txt | 4 +- pkg/test_runner/lib/src/test_suite.dart | 5 +- runtime/bin/dartutils.cc | 4 +- runtime/bin/main.cc | 6 +- runtime/bin/platform.cc | 5 +- runtime/vm/benchmark_test.cc | 8 +- runtime/vm/code_descriptors_test.cc | 2 +- runtime/vm/compiler/backend/bce_test.cc | 6 +- runtime/vm/compiler/backend/il_test.cc | 28 +- .../backend/reachability_fence_test.cc | 53 +- .../backend/redundancy_elimination_test.cc | 2 +- .../write_barrier_elimination_test.cc | 61 +- runtime/vm/dart_api_impl.cc | 12 +- runtime/vm/dart_api_impl_test.cc | 459 +++---- runtime/vm/guard_field_test.cc | 18 +- runtime/vm/heap/heap_test.cc | 2 +- runtime/vm/isolate_reload_test.cc | 1087 ++++++++++------- runtime/vm/isolate_test.cc | 4 +- runtime/vm/object_test.cc | 86 +- runtime/vm/profiler_test.cc | 20 +- runtime/vm/snapshot_test.cc | 200 +-- runtime/vm/stack_frame_test.cc | 169 +-- sdk/lib/core/string.dart | 1 + sdk_nnbd/lib/core/string.dart | 1 + 24 files changed, 1288 insertions(+), 955 deletions(-) diff --git a/pkg/dev_compiler/tool/dartdevc_nnbd_sdk_error_golden.txt b/pkg/dev_compiler/tool/dartdevc_nnbd_sdk_error_golden.txt index 6004fc5b9c6..d213c3abba6 100644 --- a/pkg/dev_compiler/tool/dartdevc_nnbd_sdk_error_golden.txt +++ b/pkg/dev_compiler/tool/dartdevc_nnbd_sdk_error_golden.txt @@ -1,8 +1,8 @@ ERROR|COMPILE_TIME_ERROR|CONST_CONSTRUCTOR_THROWS_EXCEPTION|lib/core/core.dart|3719|5|94|Const constructors can't throw exceptions. -ERROR|COMPILE_TIME_ERROR|CONST_CONSTRUCTOR_THROWS_EXCEPTION|lib/core/core.dart|7908|5|97|Const constructors can't throw exceptions. +ERROR|COMPILE_TIME_ERROR|CONST_CONSTRUCTOR_THROWS_EXCEPTION|lib/core/core.dart|7909|5|97|Const constructors can't throw exceptions. ERROR|COMPILE_TIME_ERROR|CONST_CONSTRUCTOR_THROWS_EXCEPTION|lib/core/core.dart|940|5|95|Const constructors can't throw exceptions. ERROR|COMPILE_TIME_ERROR|CONST_CONSTRUCTOR_THROWS_EXCEPTION|lib/core/core.dart|973|5|94|Const constructors can't throw exceptions. ERROR|SYNTACTIC_ERROR|CONST_FACTORY|lib/core/core.dart|3717|3|5|Only redirecting factory constructors can be declared to be 'const'. -ERROR|SYNTACTIC_ERROR|CONST_FACTORY|lib/core/core.dart|7906|3|5|Only redirecting factory constructors can be declared to be 'const'. +ERROR|SYNTACTIC_ERROR|CONST_FACTORY|lib/core/core.dart|7907|3|5|Only redirecting factory constructors can be declared to be 'const'. ERROR|SYNTACTIC_ERROR|CONST_FACTORY|lib/core/core.dart|938|3|5|Only redirecting factory constructors can be declared to be 'const'. ERROR|SYNTACTIC_ERROR|CONST_FACTORY|lib/core/core.dart|971|3|5|Only redirecting factory constructors can be declared to be 'const'. diff --git a/pkg/test_runner/lib/src/test_suite.dart b/pkg/test_runner/lib/src/test_suite.dart index c75180ca5b3..540dfd2326f 100644 --- a/pkg/test_runner/lib/src/test_suite.dart +++ b/pkg/test_runner/lib/src/test_suite.dart @@ -305,15 +305,16 @@ class VMTestSuite extends TestSuite { hasRuntimeError: testExpectation == Expectation.runtimeError, hasStaticWarning: false, hasCrash: testExpectation == Expectation.crash); - var filename = configuration.architecture == Architecture.x64 ? '$buildDir/gen/kernel-service.dart.snapshot' : '$buildDir/gen/kernel_service.dill'; var dfePath = Path(filename).absolute.toNativePath(); var args = [ - if (expectations.contains(Expectation.crash)) '--suppress-core-dump', // '--dfe' has to be the first argument for run_vm_test to pick it up. '--dfe=$dfePath', + if (expectations.contains(Expectation.crash)) '--suppress-core-dump', + if (configuration.experiments.isNotEmpty) + '--enable-experiment=${configuration.experiments.join(",")}', ...configuration.standardOptions, ...configuration.vmOptions, test.name diff --git a/runtime/bin/dartutils.cc b/runtime/bin/dartutils.cc index 71d0437623c..f1eeeb2a946 100644 --- a/runtime/bin/dartutils.cc +++ b/runtime/bin/dartutils.cc @@ -652,8 +652,8 @@ bool DartUtils::PostInt64(Dart_Port port_id, int64_t value) { Dart_Handle DartUtils::GetDartType(const char* library_url, const char* class_name) { - return Dart_GetType(Dart_LookupLibrary(NewString(library_url)), - NewString(class_name), 0, NULL); + return Dart_GetNonNullableType(Dart_LookupLibrary(NewString(library_url)), + NewString(class_name), 0, NULL); } Dart_Handle DartUtils::NewDartOSError() { diff --git a/runtime/bin/main.cc b/runtime/bin/main.cc index 8742d98c401..3a49f5db837 100644 --- a/runtime/bin/main.cc +++ b/runtime/bin/main.cc @@ -76,8 +76,12 @@ static void ReadFile(const char* filename, uint8_t** buffer, intptr_t* size); static Dart_Handle CreateRuntimeOptions(CommandLineOptions* options) { int options_count = options->count(); + Dart_Handle string_type = DartUtils::GetDartType("dart:core", "String"); + if (Dart_IsError(string_type)) { + return string_type; + } Dart_Handle dart_arguments = - Dart_NewListOf(Dart_CoreType_String, options_count); + Dart_NewListOfTypeFilled(string_type, Dart_EmptyString(), options_count); if (Dart_IsError(dart_arguments)) { return dart_arguments; } diff --git a/runtime/bin/platform.cc b/runtime/bin/platform.cc index 20003a08fc4..1b04cfcb7eb 100644 --- a/runtime/bin/platform.cc +++ b/runtime/bin/platform.cc @@ -72,7 +72,10 @@ void FUNCTION_NAME(Platform_ResolvedExecutableName)(Dart_NativeArguments args) { void FUNCTION_NAME(Platform_ExecutableArguments)(Dart_NativeArguments args) { int end = Platform::GetScriptIndex(); char** argv = Platform::GetArgv(); - Dart_Handle result = Dart_NewListOf(Dart_CoreType_String, end - 1); + Dart_Handle string_type = DartUtils::GetDartType("dart:core", "String"); + ThrowIfError(string_type); + Dart_Handle result = + Dart_NewListOfTypeFilled(string_type, Dart_EmptyString(), end - 1); for (intptr_t i = 1; i < end; i++) { Dart_Handle str = DartUtils::NewString(argv[i]); ThrowIfError(str); diff --git a/runtime/vm/benchmark_test.cc b/runtime/vm/benchmark_test.cc index 11527a780a0..c7512c4ca28 100644 --- a/runtime/vm/benchmark_test.cc +++ b/runtime/vm/benchmark_test.cc @@ -268,12 +268,12 @@ BENCHMARK(UseDartApi) { const char* kScriptChars = "import 'dart:nativewrappers';\n" "class Class extends NativeFieldWrapperClass1 {\n" - " int init() native 'init';\n" + " void init() native 'init';\n" " int method(int param1, int param2) native 'method';\n" "}\n" "\n" "void benchmark(int count) {\n" - " Class c = new Class();\n" + " Class c = Class();\n" " c.init();\n" " for (int i = 0; i < count; i++) {\n" " c.method(i,7);\n" @@ -359,6 +359,10 @@ static Dart_NativeFunction NativeResolver(Dart_Handle name, // Measure compile of all kernel Service(CFE) functions. // BENCHMARK(KernelServiceCompileAll) { + if (FLAG_null_safety == kNullSafetyOptionStrong) { + // TODO(bkonyi): remove this check when we build the CFE in strong mode. + return; + } bin::Builtin::SetNativeResolver(bin::Builtin::kBuiltinLibrary); bin::Builtin::SetNativeResolver(bin::Builtin::kIOLibrary); bin::Builtin::SetNativeResolver(bin::Builtin::kCLILibrary); diff --git a/runtime/vm/code_descriptors_test.cc b/runtime/vm/code_descriptors_test.cc index 512537e0b9e..20c0e5ef36d 100644 --- a/runtime/vm/code_descriptors_test.cc +++ b/runtime/vm/code_descriptors_test.cc @@ -52,7 +52,7 @@ TEST_CASE(StackMapGC) { " i = 10; s1 = 'abcd'; k = 20; s2 = 'B'; s3 = 'C';" " func(i, k);" " return i + k; }" - " static int moo() {" + " static void moo() {" " var i = A.foo();" " if (i != 30) throw '$i != 30';" " }\n" diff --git a/runtime/vm/compiler/backend/bce_test.cc b/runtime/vm/compiler/backend/bce_test.cc index 44bc798d2f2..4567e630a00 100644 --- a/runtime/vm/compiler/backend/bce_test.cc +++ b/runtime/vm/compiler/backend/bce_test.cc @@ -145,7 +145,7 @@ ISOLATE_UNIT_TEST_CASE(BCEModulo) { const char* kScriptChars = R"( foo(int i) { - var l = new List(3); + var l = List.filled(3, 0); return l[i % 3] ?? l[i % (-3)]; } main() { @@ -278,7 +278,7 @@ ISOLATE_UNIT_TEST_CASE(BCEListNamedAndPlainLength) { const char* kScriptChars = R"( List foo(int count) { - var x = new List(count); + var x = new List.filled(count, 42); for (int i = 0; i < count; i++) { x[i] = 0; } @@ -291,7 +291,7 @@ ISOLATE_UNIT_TEST_CASE(BCEListNamedAndPlainLength) { foo(100); } )"; - TestScriptJIT(kScriptChars, 2, 0); + TestScriptJIT(kScriptChars, 2, 1); } } // namespace dart diff --git a/runtime/vm/compiler/backend/il_test.cc b/runtime/vm/compiler/backend/il_test.cc index e76478045d3..ad763a33d97 100644 --- a/runtime/vm/compiler/backend/il_test.cc +++ b/runtime/vm/compiler/backend/il_test.cc @@ -6,6 +6,7 @@ #include +#include "platform/utils.h" #include "vm/compiler/backend/il_test_helper.h" #include "vm/unit_test.h" @@ -45,26 +46,28 @@ ISOLATE_UNIT_TEST_CASE(OptimizationTests) { } ISOLATE_UNIT_TEST_CASE(IRTest_EliminateWriteBarrier) { - const char* kScript = - R"( + const char* tag = (FLAG_null_safety == kNullSafetyOptionStrong) ? "?" : ""; + // clang-format off + auto kScript = Utils::CStringUniquePtr(OS::SCreate(nullptr, R"( class Container { operator []=(var index, var value) { return data[index] = value; } - List data = new List()..length = 10; + List data = List.filled(10, null); } - Container x = new Container(); + Container x = Container(); foo() { for (int i = 0; i < 10; ++i) { x[i] = i; } } - )"; + )", tag, tag), std::free); + // clang-format on - const auto& root_library = Library::Handle(LoadTestScript(kScript)); + const auto& root_library = Library::Handle(LoadTestScript(kScript.get())); const auto& function = Function::Handle(GetFunction(root_library, "foo")); Invoke(root_library, "foo"); @@ -128,7 +131,9 @@ static void RunInitializingStoresTest( } ISOLATE_UNIT_TEST_CASE(IRTest_InitializingStores) { - const char* kScript = R"( + const char* tag = (FLAG_null_safety == kNullSafetyOptionStrong) ? "?" : ""; + // clang-format off + auto kScript = Utils::CStringUniquePtr(OS::SCreate(nullptr, R"( class Bar { var f; var g; @@ -140,7 +145,7 @@ ISOLATE_UNIT_TEST_CASE(IRTest_InitializingStores) { f3() { return () { }; } - f4({T value}) { + f4({T%s value}) { return () { return value; }; } main() { @@ -149,8 +154,11 @@ ISOLATE_UNIT_TEST_CASE(IRTest_InitializingStores) { f3(); f4(); } - )"; - const auto& root_library = Library::Handle(LoadTestScript(kScript)); + )", + tag), std::free); + // clang-format on + + const auto& root_library = Library::Handle(LoadTestScript(kScript.get())); Invoke(root_library, "main"); RunInitializingStoresTest(root_library, "f1", CompilerPass::kJIT, diff --git a/runtime/vm/compiler/backend/reachability_fence_test.cc b/runtime/vm/compiler/backend/reachability_fence_test.cc index 782bc02d3f9..d0e6e8f30a6 100644 --- a/runtime/vm/compiler/backend/reachability_fence_test.cc +++ b/runtime/vm/compiler/backend/reachability_fence_test.cc @@ -15,14 +15,19 @@ namespace dart { ISOLATE_UNIT_TEST_CASE(ReachabilityFence_Simple) { - const char* kScript = - R"( + const bool null_safety = (FLAG_null_safety == kNullSafetyOptionStrong); + const char* nullableTag = null_safety ? "?" : ""; + const char* nullAssertTag = null_safety ? "!" : ""; + // clang-format off + auto kScript = + Utils::CStringUniquePtr(OS::SCreate(nullptr, + R"( import 'dart:_internal' show reachabilityFence; int someGlobal = 0; class A { - int a; + int%s a; } void someFunction(int arg) { @@ -31,12 +36,14 @@ ISOLATE_UNIT_TEST_CASE(ReachabilityFence_Simple) { main() { final object = A()..a = 10; - someFunction(object.a); + someFunction(object.a%s); reachabilityFence(object); } - )"; + )", + nullableTag, nullAssertTag), std::free); + // clang-format on - const auto& root_library = Library::Handle(LoadTestScript(kScript)); + const auto& root_library = Library::Handle(LoadTestScript(kScript.get())); Invoke(root_library, "main"); @@ -71,14 +78,18 @@ ISOLATE_UNIT_TEST_CASE(ReachabilityFence_Simple) { } ISOLATE_UNIT_TEST_CASE(ReachabilityFence_Loop) { - const char* kScript = - R"( + const bool null_safety = (FLAG_null_safety == kNullSafetyOptionStrong); + const char* nullableTag = null_safety ? "?" : ""; + const char* nullAssertTag = null_safety ? "!" : ""; + // clang-format off + auto kScript = + Utils::CStringUniquePtr(OS::SCreate(nullptr, R"( import 'dart:_internal' show reachabilityFence; int someGlobal = 0; class A { - int a; + int%s a; } @pragma('vm:never-inline') @@ -93,13 +104,14 @@ ISOLATE_UNIT_TEST_CASE(ReachabilityFence_Loop) { main() { final object = makeSomeA(); for(int i = 0; i < 100000; i++) { - someFunction(object.a); + someFunction(object.a%s); reachabilityFence(object); } } - )"; + )", nullableTag, nullAssertTag), std::free); + // clang-format on - const auto& root_library = Library::Handle(LoadTestScript(kScript)); + const auto& root_library = Library::Handle(LoadTestScript(kScript.get())); Invoke(root_library, "main"); @@ -134,14 +146,18 @@ ISOLATE_UNIT_TEST_CASE(ReachabilityFence_Loop) { } ISOLATE_UNIT_TEST_CASE(ReachabilityFence_NoCanonicalize) { - const char* kScript = - R"( + const bool null_safety = (FLAG_null_safety == kNullSafetyOptionStrong); + const char* nullableTag = null_safety ? "?" : ""; + const char* nullAssertTag = null_safety ? "!" : ""; + // clang-format off + auto kScript = + Utils::CStringUniquePtr(OS::SCreate(nullptr, R"( import 'dart:_internal' show reachabilityFence; int someGlobal = 0; class A { - int a; + int%s a; } @pragma('vm:never-inline') @@ -157,15 +173,16 @@ ISOLATE_UNIT_TEST_CASE(ReachabilityFence_NoCanonicalize) { final object = makeSomeA(); reachabilityFence(object); for(int i = 0; i < 100000; i++) { - someFunction(object.a); + someFunction(object.a%s); reachabilityFence(object); } reachabilityFence(object); reachabilityFence(object); } - )"; + )", nullableTag, nullAssertTag), std::free); + // clang-format on - const auto& root_library = Library::Handle(LoadTestScript(kScript)); + const auto& root_library = Library::Handle(LoadTestScript(kScript.get())); Invoke(root_library, "main"); diff --git a/runtime/vm/compiler/backend/redundancy_elimination_test.cc b/runtime/vm/compiler/backend/redundancy_elimination_test.cc index fdbd9578490..5027e275e38 100644 --- a/runtime/vm/compiler/backend/redundancy_elimination_test.cc +++ b/runtime/vm/compiler/backend/redundancy_elimination_test.cc @@ -905,7 +905,7 @@ ISOLATE_UNIT_TEST_CASE(LoadOptimizer_RedundantStoresAndLoads) { const char* kScript = R"( class Bar { Bar() { a = null; } - Object a; + dynamic a; } Bar foo() { diff --git a/runtime/vm/compiler/write_barrier_elimination_test.cc b/runtime/vm/compiler/write_barrier_elimination_test.cc index 737e21328d5..53b16e88ff8 100644 --- a/runtime/vm/compiler/write_barrier_elimination_test.cc +++ b/runtime/vm/compiler/write_barrier_elimination_test.cc @@ -13,28 +13,32 @@ DEBUG_ONLY(DECLARE_FLAG(bool, trace_write_barrier_elimination);) ISOLATE_UNIT_TEST_CASE(IRTest_WriteBarrierElimination_JoinSuccessors) { DEBUG_ONLY(FLAG_trace_write_barrier_elimination = true); + const bool null_safety = (FLAG_null_safety == kNullSafetyOptionStrong); + const char* nullableTag = null_safety ? "?" : ""; + const char* nullAssertTag = null_safety ? "!" : ""; // This is a regression test for a bug where we were using // JoinEntry::SuccessorCount() to determine the number of outgoing blocks // from the join block. JoinEntry::SuccessorCount() is in fact always 0; // JoinEntry::last_instruction()->SuccessorCount() should be used instead. - const char* kScript = - R"( + // clang-format off + auto kScript = Utils::CStringUniquePtr( + OS::SCreate(nullptr, R"( class C { - int value; - C next; - C prev; + int%s value; + C%s next; + C%s prev; } @pragma("vm:never-inline") fn() {} foo(int x) { - C prev = C(); - C next; + C%s prev = C(); + C%s next; while (x --> 0) { next = C(); - next.prev = prev; + next%s.prev = prev; prev?.next = next; prev = next; fn(); @@ -43,9 +47,12 @@ ISOLATE_UNIT_TEST_CASE(IRTest_WriteBarrierElimination_JoinSuccessors) { } main() { foo(10); } - )"; + )", + nullableTag, nullableTag, nullableTag, nullableTag, + nullableTag, nullAssertTag), std::free); + // clang-format on - const auto& root_library = Library::Handle(LoadTestScript(kScript)); + const auto& root_library = Library::Handle(LoadTestScript(kScript.get())); Invoke(root_library, "main"); @@ -77,15 +84,17 @@ ISOLATE_UNIT_TEST_CASE(IRTest_WriteBarrierElimination_JoinSuccessors) { ISOLATE_UNIT_TEST_CASE(IRTest_WriteBarrierElimination_AtLeastOnce) { DEBUG_ONLY(FLAG_trace_write_barrier_elimination = true); - + const bool null_safety = (FLAG_null_safety == kNullSafetyOptionStrong); + const char* lateTag = null_safety ? "late" : ""; // Ensure that we process every block at least once during the analysis // phase so that the out-sets will be initialized. If we don't process // each block at least once, the store "c.next = n" will be marked // NoWriteBarrier. - const char* kScript = - R"( + // clang-format off + auto kScript = Utils::CStringUniquePtr(OS::SCreate(nullptr, + R"( class C { - C next; + %s C next; } @pragma("vm:never-inline") @@ -102,9 +111,9 @@ ISOLATE_UNIT_TEST_CASE(IRTest_WriteBarrierElimination_AtLeastOnce) { } main() { foo(0); foo(10); } - )"; - - const auto& root_library = Library::Handle(LoadTestScript(kScript)); + )", lateTag), std::free); + // clang-format on + const auto& root_library = Library::Handle(LoadTestScript(kScript.get())); Invoke(root_library, "main"); @@ -133,13 +142,18 @@ ISOLATE_UNIT_TEST_CASE(IRTest_WriteBarrierElimination_AtLeastOnce) { ISOLATE_UNIT_TEST_CASE(IRTest_WriteBarrierElimination_Arrays) { DEBUG_ONLY(FLAG_trace_write_barrier_elimination = true); + const bool null_safety = (FLAG_null_safety == kNullSafetyOptionStrong); + const char* nullableTag = null_safety ? "?" : ""; + const char* lateTag = null_safety ? "late" : ""; + // Test that array allocations are not considered usable after a // may-trigger-GC instruction (in this case CheckStackOverflow), unlike // normal allocations, which are only interruped by a Dart call. - const char* kScript = - R"( + // clang-format off + auto kScript = + Utils::CStringUniquePtr(OS::SCreate(nullptr, R"( class C { - C next; + %s C next; } @pragma("vm:never-inline") @@ -148,7 +162,7 @@ ISOLATE_UNIT_TEST_CASE(IRTest_WriteBarrierElimination_Arrays) { foo(int x) { C c = C(); C n = C(); - List array = List(1); + List array = List.filled(1, null); while (x --> 0) { c.next = n; n = c; @@ -159,9 +173,10 @@ ISOLATE_UNIT_TEST_CASE(IRTest_WriteBarrierElimination_Arrays) { } main() { foo(10); } - )"; + )", lateTag, nullableTag, nullableTag), std::free); + // clang-format on - const auto& root_library = Library::Handle(LoadTestScript(kScript)); + const auto& root_library = Library::Handle(LoadTestScript(kScript.get())); Invoke(root_library, "main"); diff --git a/runtime/vm/dart_api_impl.cc b/runtime/vm/dart_api_impl.cc index a6cdea74c33..f8467df5727 100644 --- a/runtime/vm/dart_api_impl.cc +++ b/runtime/vm/dart_api_impl.cc @@ -3033,12 +3033,17 @@ static TypeArgumentsPtr TypeArgumentsForElementType( return store->type_argument_legacy_string(); } UNREACHABLE(); - return NULL; + return TypeArguments::null(); } DART_EXPORT Dart_Handle Dart_NewListOf(Dart_CoreType_Id element_type_id, intptr_t length) { DARTSCOPE(Thread::Current()); + if (T->isolate()->null_safety() && element_type_id != Dart_CoreType_Dynamic) { + return Api::NewError( + "Cannot use legacy types with --null-safety enabled. " + "Use Dart_NewListOfType or Dart_NewListOfTypeFilled instead."); + } CHECK_LENGTH(length, Array::kMaxElements); CHECK_CALLBACK_STATE(T); const Array& arr = Array::Handle(Z, Array::New(length)); @@ -5584,6 +5589,11 @@ DART_EXPORT Dart_Handle Dart_GetType(Dart_Handle library, Dart_Handle class_name, intptr_t number_of_type_arguments, Dart_Handle* type_arguments) { + if (Thread::Current()->isolate()->null_safety()) { + return Api::NewError( + "Cannot use legacy types with --null-safety enabled. " + "Use Dart_GetNullableType or Dart_GetNonNullableType instead."); + } return GetTypeCommon(library, class_name, number_of_type_arguments, type_arguments, Nullability::kLegacy); } diff --git a/runtime/vm/dart_api_impl_test.cc b/runtime/vm/dart_api_impl_test.cc index 4f1551d22b1..6b501e6406d 100644 --- a/runtime/vm/dart_api_impl_test.cc +++ b/runtime/vm/dart_api_impl_test.cc @@ -1079,7 +1079,7 @@ TEST_CASE(DartAPI_FunctionIsStatic) { EXPECT_VALID(result); EXPECT(is_static); - Dart_Handle klass = Dart_GetType(lib, NewString("Foo"), 0, NULL); + Dart_Handle klass = Dart_GetNonNullableType(lib, NewString("Foo"), 0, NULL); EXPECT_VALID(klass); Dart_Handle instance = Dart_Allocate(klass); @@ -1174,7 +1174,7 @@ TEST_CASE(DartAPI_GetStaticMethodClosure) { TEST_CASE(DartAPI_ClassLibrary) { Dart_Handle lib = Dart_LookupLibrary(NewString("dart:core")); EXPECT_VALID(lib); - Dart_Handle type = Dart_GetType(lib, NewString("int"), 0, NULL); + Dart_Handle type = Dart_GetNonNullableType(lib, NewString("int"), 0, NULL); EXPECT_VALID(type); Dart_Handle result = Dart_ClassLibrary(type); EXPECT_VALID(result); @@ -1695,7 +1695,7 @@ TEST_CASE(DartAPI_ExternalTypedDataPretenure) { TEST_CASE(DartAPI_ListAccess) { const char* kScriptChars = "List testMain() {" - " List a = new List();" + " List a = List.empty(growable: true);" " a.add(10);" " a.add(20);" " a.add(30);" @@ -4034,7 +4034,9 @@ TEST_CASE(DartAPI_TypeGetParameterizedTypes) { EXPECT_VALID(double_type); EXPECT_VALID(Dart_ListSetAt(type_args, 1, double_type)); Dart_Handle myclass0_type = - Dart_GetType(lib, NewString("MyClass0"), 2, &type_args); + (FLAG_null_safety == kNullSafetyOptionStrong) + ? Dart_GetNonNullableType(lib, NewString("MyClass0"), 2, &type_args) + : Dart_GetType(lib, NewString("MyClass0"), 2, &type_args); EXPECT_VALID(myclass0_type); type_args = Dart_NewList(2); @@ -4046,7 +4048,9 @@ TEST_CASE(DartAPI_TypeGetParameterizedTypes) { EXPECT_VALID(list_type); EXPECT_VALID(Dart_ListSetAt(type_args, 1, list_type)); Dart_Handle myclass1_type = - Dart_GetType(lib, NewString("MyClass1"), 2, &type_args); + (FLAG_null_safety == kNullSafetyOptionStrong) + ? Dart_GetNonNullableType(lib, NewString("MyClass1"), 2, &type_args) + : Dart_GetType(lib, NewString("MyClass1"), 2, &type_args); EXPECT_VALID(myclass1_type); // Now create objects of the type and validate the object type matches @@ -4220,7 +4224,7 @@ TEST_CASE(DartAPI_FieldAccess) { // Shared setup. Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL); - Dart_Handle type = Dart_GetType(lib, NewString("Fields"), 0, NULL); + Dart_Handle type = Dart_GetNonNullableType(lib, NewString("Fields"), 0, NULL); EXPECT_VALID(type); Dart_Handle instance = Dart_Invoke(lib, NewString("test"), 0, NULL); EXPECT_VALID(instance); @@ -4413,7 +4417,9 @@ TEST_CASE(DartAPI_SetField_FunnyValue) { } TEST_CASE(DartAPI_SetField_BadType) { - const char* kScriptChars = "int foo;\n"; + const char* kScriptChars = (FLAG_null_safety == kNullSafetyOptionStrong) + ? "late int foo;\n" + : "int foo;\n"; Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL); Dart_Handle name = NewString("foo"); Dart_Handle result = Dart_SetField(lib, name, Dart_True()); @@ -4435,22 +4441,29 @@ static Dart_NativeFunction native_field_lookup(Dart_Handle name, } TEST_CASE(DartAPI_InjectNativeFields2) { - const char* kScriptChars = - "class NativeFields extends NativeFieldsWrapper {\n" - " NativeFields(int i, int j) : fld1 = i, fld2 = j {}\n" - " int fld1;\n" - " final int fld2;\n" - " static int fld3;\n" - " static const int fld4 = 10;\n" - "}\n" - "NativeFields testMain() {\n" - " NativeFields obj = new NativeFields(10, 20);\n" - " return obj;\n" - "}\n"; + bool null_safety = (FLAG_null_safety == kNullSafetyOptionStrong); + const char* nullableTag = null_safety ? "?" : ""; + // clang-format off + auto kScriptChars = Utils::CStringUniquePtr( + OS::SCreate(nullptr, + "class NativeFields extends NativeFieldsWrapper {\n" + " NativeFields(int i, int j) : fld1 = i, fld2 = j {}\n" + " int fld1;\n" + " final int fld;\n" + " static int%s fld3;\n" + " static const int fld4 = 10;\n" + "}\n" + "NativeFields testMain() {\n" + " NativeFields obj = new NativeFields(10, 20);\n" + " return obj;\n" + "}\n", + nullableTag), std::free); + // clang-format on + Dart_Handle result; // Create a test library and Load up a test script in it. Dart_Handle lib = - TestCase::LoadTestScript(kScriptChars, NULL, USER_TEST_URI, false); + TestCase::LoadTestScript(kScriptChars.get(), NULL, USER_TEST_URI, false); // Invoke a function which returns an object of type NativeFields. result = Dart_Invoke(lib, NewString("testMain"), 0, NULL); @@ -4462,24 +4475,31 @@ TEST_CASE(DartAPI_InjectNativeFields2) { } TEST_CASE(DartAPI_InjectNativeFields3) { - const char* kScriptChars = - "import 'dart:nativewrappers';" - "class NativeFields extends NativeFieldWrapperClass2 {\n" - " NativeFields(int i, int j) : fld1 = i, fld2 = j {}\n" - " int fld1;\n" - " final int fld2;\n" - " static int fld3;\n" - " static const int fld4 = 10;\n" - "}\n" - "NativeFields testMain() {\n" - " NativeFields obj = new NativeFields(10, 20);\n" - " return obj;\n" - "}\n"; + bool null_safety = (FLAG_null_safety == kNullSafetyOptionStrong); + const char* nullableTag = null_safety ? "?" : ""; + // clang-format off + auto kScriptChars = Utils::CStringUniquePtr( + OS::SCreate(nullptr, + "import 'dart:nativewrappers';" + "class NativeFields extends NativeFieldWrapperClass2 {\n" + " NativeFields(int i, int j) : fld1 = i, fld2 = j {}\n" + " int fld1;\n" + " final int fld2;\n" + " static int%s fld3;\n" + " static const int fld4 = 10;\n" + "}\n" + "NativeFields testMain() {\n" + " NativeFields obj = new NativeFields(10, 20);\n" + " return obj;\n" + "}\n", + nullableTag), std::free); + // clang-format on Dart_Handle result; const int kNumNativeFields = 2; // Load up a test script in the test library. - Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, native_field_lookup); + Dart_Handle lib = + TestCase::LoadTestScript(kScriptChars.get(), native_field_lookup); // Invoke a function which returns an object of type NativeFields. result = Dart_Invoke(lib, NewString("testMain"), 0, NULL); @@ -4504,22 +4524,27 @@ TEST_CASE(DartAPI_InjectNativeFields3) { } TEST_CASE(DartAPI_InjectNativeFields4) { - const char* kScriptChars = - "import 'dart:nativewrappers';" - "class NativeFields extends NativeFieldWrapperClass2 {\n" - " NativeFields(int i, int j) : fld1 = i, fld2 = j {}\n" - " int fld1;\n" - " final int fld2;\n" - " static int fld3;\n" - " static const int fld4 = 10;\n" - "}\n" - "NativeFields testMain() {\n" - " NativeFields obj = new NativeFields(10, 20);\n" - " return obj;\n" - "}\n"; + bool null_safety = (FLAG_null_safety == kNullSafetyOptionStrong); + const char* nullableTag = null_safety ? "?" : ""; + // clang-format off + auto kScriptChars = Utils::CStringUniquePtr( + OS::SCreate(nullptr, + "class NativeFields extends NativeFieldsWrapperClass2 {\n" + " NativeFields(int i, int j) : fld1 = i, fld2 = j {}\n" + " int fld1;\n" + " final int fld;\n" + " static int%s fld3;\n" + " static const int fld4 = 10;\n" + "}\n" + "NativeFields testMain() {\n" + " NativeFields obj = new NativeFields(10, 20);\n" + " return obj;\n" + "}\n", + nullableTag), std::free); + // clang-format on Dart_Handle result; // Load up a test script in the test library. - Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL); + Dart_Handle lib = TestCase::LoadTestScript(kScriptChars.get(), NULL); // Invoke a function which returns an object of type NativeFields. result = Dart_Invoke(lib, NewString("testMain"), 0, NULL); @@ -4585,27 +4610,36 @@ static Dart_NativeFunction TestNativeFieldsAccess_lookup(Dart_Handle name, } TEST_CASE(DartAPI_TestNativeFieldsAccess) { - const char* kScriptChars = - "import 'dart:nativewrappers';" - "class NativeFields extends NativeFieldWrapperClass2 {\n" - " NativeFields(int i, int j) : fld1 = i, fld2 = j {}\n" - " int fld1;\n" - " final int fld2;\n" - " static int fld3;\n" - " static const int fld4 = 10;\n" - " int initNativeFlds() native 'TestNativeFieldsAccess_init';\n" - " int accessNativeFlds(int i) native 'TestNativeFieldsAccess_access';\n" - "}\n" - "NativeFields testMain() {\n" - " NativeFields obj = new NativeFields(10, 20);\n" - " obj.initNativeFlds();\n" - " obj.accessNativeFlds(null);\n" - " return obj;\n" - "}\n"; + bool null_safety = (FLAG_null_safety == kNullSafetyOptionStrong); + const char* nullableTag = null_safety ? "?" : ""; + // clang-format off + auto kScriptChars = Utils::CStringUniquePtr( + OS::SCreate( + nullptr, + "import 'dart:nativewrappers';" + "class NativeFields extends NativeFieldWrapperClass2 {\n" + " NativeFields(int i, int j) : fld1 = i, fld2 = j {}\n" + " int fld1;\n" + " final int fld2;\n" + " static int%s fld3;\n" + " static const int fld4 = 10;\n" + " int%s initNativeFlds() native 'TestNativeFieldsAccess_init';\n" + " int%s accessNativeFlds(int%s i) native " + "'TestNativeFieldsAccess_access';\n" + "}\n" + "NativeFields testMain() {\n" + " NativeFields obj = new NativeFields(10, 20);\n" + " obj.initNativeFlds();\n" + " obj.accessNativeFlds(null);\n" + " return obj;\n" + "}\n", + nullableTag, nullableTag, nullableTag, nullableTag), + std::free); + // clang-format on // Load up a test script in the test library. - Dart_Handle lib = - TestCase::LoadTestScript(kScriptChars, TestNativeFieldsAccess_lookup); + Dart_Handle lib = TestCase::LoadTestScript(kScriptChars.get(), + TestNativeFieldsAccess_lookup); // Invoke a function which returns an object of type NativeFields. Dart_Handle result = Dart_Invoke(lib, NewString("testMain"), 0, NULL); @@ -4717,22 +4751,30 @@ static void TestNativeFields(Dart_Handle retobj) { } TEST_CASE(DartAPI_ImplicitNativeFieldAccess) { - const char* kScriptChars = - "import 'dart:nativewrappers';" - "class NativeFields extends NativeFieldWrapperClass4 {\n" - " NativeFields(int i, int j) : fld1 = i, fld2 = j {}\n" - " int fld0;\n" - " int fld1;\n" - " final int fld2;\n" - " static int fld3;\n" - " static const int fld4 = 10;\n" - "}\n" - "NativeFields testMain() {\n" - " NativeFields obj = new NativeFields(10, 20);\n" - " return obj;\n" - "}\n"; + bool null_safety = (FLAG_null_safety == kNullSafetyOptionStrong); + const char* nullableTag = null_safety ? "?" : ""; + // clang-format off + auto kScriptChars = Utils::CStringUniquePtr( + OS::SCreate(nullptr, + "import 'dart:nativewrappers';" + "class NativeFields extends NativeFieldWrapperClass4 {\n" + " NativeFields(int i, int j) : fld1 = i, fld2 = j {}\n" + " int%s fld0;\n" + " int fld1;\n" + " final int fld2;\n" + " static int%s fld3;\n" + " static const int fld4 = 10;\n" + "}\n" + "NativeFields testMain() {\n" + " NativeFields obj = new NativeFields(10, 20);\n" + " return obj;\n" + "}\n", + nullableTag, nullableTag), + std::free); + // clang-format on // Load up a test script in the test library. - Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, native_field_lookup); + Dart_Handle lib = + TestCase::LoadTestScript(kScriptChars.get(), native_field_lookup); // Invoke a function which returns an object of type NativeFields. Dart_Handle retobj = Dart_Invoke(lib, NewString("testMain"), 0, NULL); @@ -4743,26 +4785,35 @@ TEST_CASE(DartAPI_ImplicitNativeFieldAccess) { } TEST_CASE(DartAPI_NegativeNativeFieldAccess) { - const char* kScriptChars = - "class NativeFields {\n" - " NativeFields(int i, int j) : fld1 = i, fld2 = j {}\n" - " int fld1;\n" - " final int fld2;\n" - " static int fld3;\n" - " static const int fld4 = 10;\n" - "}\n" - "NativeFields testMain1() {\n" - " NativeFields obj = new NativeFields(10, 20);\n" - " return obj;\n" - "}\n" - "Function testMain2() {\n" - " return () {};\n" - "}\n"; + bool null_safety = (FLAG_null_safety == kNullSafetyOptionStrong); + const char* nullableTag = null_safety ? "?" : ""; + // clang-format off + auto kScriptChars = Utils::CStringUniquePtr( + OS::SCreate(nullptr, + "import 'dart:nativewrappers';\n" + "class NativeFields {\n" + " NativeFields(int i, int j) : fld1 = i, fld2 = j {}\n" + " int fld1;\n" + " final int fld2;\n" + " static int%s fld3;\n" + " static const int fld4 = 10;\n" + "}\n" + "NativeFields testMain1() {\n" + " NativeFields obj = new NativeFields(10, 20);\n" + " return obj;\n" + "}\n" + "Function testMain2() {\n" + " return () {};\n" + "}\n", + nullableTag), + std::free); + // clang-format on + Dart_Handle result; CHECK_API_SCOPE(thread); // Create a test library and Load up a test script in it. - Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL); + Dart_Handle lib = TestCase::LoadTestScript(kScriptChars.get(), NULL); // Invoke a function which returns an object of type NativeFields. Dart_Handle retobj = Dart_Invoke(lib, NewString("testMain1"), 0, NULL); @@ -4823,7 +4874,8 @@ TEST_CASE(DartAPI_GetStaticField_RunsInitializer) { Dart_Handle result; // Create a test library and Load up a test script in it. Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL); - Dart_Handle type = Dart_GetType(lib, NewString("TestClass"), 0, NULL); + Dart_Handle type = + Dart_GetNonNullableType(lib, NewString("TestClass"), 0, NULL); EXPECT_VALID(type); // Invoke a function which returns an object. @@ -4865,7 +4917,8 @@ TEST_CASE(DartAPI_GetField_CheckIsolate) { // Create a test library and Load up a test script in it. Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL); - Dart_Handle type = Dart_GetType(lib, NewString("TestClass"), 0, NULL); + Dart_Handle type = + Dart_GetNonNullableType(lib, NewString("TestClass"), 0, NULL); EXPECT_VALID(type); result = Dart_GetField(type, NewString("fld2")); @@ -4886,7 +4939,8 @@ TEST_CASE(DartAPI_SetField_CheckIsolate) { // Create a test library and Load up a test script in it. Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL); - Dart_Handle type = Dart_GetType(lib, NewString("TestClass"), 0, NULL); + Dart_Handle type = + Dart_GetNonNullableType(lib, NewString("TestClass"), 0, NULL); EXPECT_VALID(type); result = Dart_SetField(type, NewString("fld2"), Dart_NewInteger(13)); @@ -4927,9 +4981,11 @@ TEST_CASE(DartAPI_New) { "}\n"; Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL); - Dart_Handle type = Dart_GetType(lib, NewString("MyClass"), 0, NULL); + Dart_Handle type = + Dart_GetNonNullableType(lib, NewString("MyClass"), 0, NULL); EXPECT_VALID(type); - Dart_Handle intf = Dart_GetType(lib, NewString("MyInterface"), 0, NULL); + Dart_Handle intf = + Dart_GetNonNullableType(lib, NewString("MyInterface"), 0, NULL); EXPECT_VALID(intf); Dart_Handle args[1]; args[0] = Dart_NewInteger(11); @@ -5135,7 +5191,8 @@ TEST_CASE(DartAPI_New_Issue2971) { // factories. Dart_Handle core_lib = Dart_LookupLibrary(NewString("dart:core")); EXPECT_VALID(core_lib); - Dart_Handle list_type = Dart_GetType(core_lib, NewString("List"), 0, NULL); + Dart_Handle list_type = + Dart_GetNonNullableType(core_lib, NewString("List"), 0, NULL); EXPECT_VALID(list_type); const int kNumArgs = 1; @@ -5156,16 +5213,21 @@ TEST_CASE(DartAPI_NewListOf) { const int kNumArgs = 1; Dart_Handle args[kNumArgs]; const char* str; - + Dart_Handle result; Dart_Handle string_list = Dart_NewListOf(Dart_CoreType_String, 1); - EXPECT_VALID(string_list); - args[0] = string_list; - Dart_Handle result = - Dart_Invoke(lib, NewString("expectListOfString"), kNumArgs, args); - EXPECT_VALID(result); - result = Dart_StringToCString(result, &str); - EXPECT_VALID(result); - EXPECT_STREQ("null", str); + if (!Dart_IsError(string_list)) { + args[0] = string_list; + Dart_Handle result = + Dart_Invoke(lib, NewString("expectListOfString"), kNumArgs, args); + EXPECT_VALID(result); + result = Dart_StringToCString(result, &str); + EXPECT_VALID(result); + EXPECT_STREQ("null", str); + } else { + EXPECT_ERROR(string_list, + "Cannot use legacy types with --null-safety enabled. " + "Use Dart_NewListOfType or Dart_NewListOfTypeFilled instead."); + } Dart_Handle dynamic_list = Dart_NewListOf(Dart_CoreType_Dynamic, 1); EXPECT_VALID(dynamic_list); @@ -5176,12 +5238,17 @@ TEST_CASE(DartAPI_NewListOf) { EXPECT_STREQ("null", str); Dart_Handle int_list = Dart_NewListOf(Dart_CoreType_Int, 1); - EXPECT_VALID(int_list); - args[0] = int_list; - result = Dart_Invoke(lib, NewString("expectListOfInt"), kNumArgs, args); - EXPECT_VALID(result); - result = Dart_StringToCString(result, &str); - EXPECT_STREQ("null", str); + if (!Dart_IsError(int_list)) { + args[0] = int_list; + result = Dart_Invoke(lib, NewString("expectListOfInt"), kNumArgs, args); + EXPECT_VALID(result); + result = Dart_StringToCString(result, &str); + EXPECT_STREQ("null", str); + } else { + EXPECT_ERROR(int_list, + "Cannot use legacy types with --null-safety enabled. " + "Use Dart_NewListOfType or Dart_NewListOfTypeFilled instead."); + } } TEST_CASE(DartAPI_NewListOfType) { @@ -5197,7 +5264,8 @@ TEST_CASE(DartAPI_NewListOfType) { "void expectListOfNever(List _) {}\n"; Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL); - Dart_Handle zxhandle_type = Dart_GetType(lib, NewString("ZXHandle"), 0, NULL); + Dart_Handle zxhandle_type = + Dart_GetNullableType(lib, NewString("ZXHandle"), 0, NULL); EXPECT_VALID(zxhandle_type); Dart_Handle zxhandle = Dart_New(zxhandle_type, Dart_Null(), 0, NULL); @@ -5209,7 +5277,7 @@ TEST_CASE(DartAPI_NewListOfType) { EXPECT_VALID(Dart_ListSetAt(zxhandle_list, 0, zxhandle)); Dart_Handle readresult_type = - Dart_GetType(lib, NewString("ChannelReadResult"), 0, NULL); + Dart_GetNonNullableType(lib, NewString("ChannelReadResult"), 0, NULL); EXPECT_VALID(zxhandle_type); const int kNumArgs = 1; @@ -5228,7 +5296,7 @@ TEST_CASE(DartAPI_NewListOfType) { EXPECT_VALID(dart_core); Dart_Handle string_type = - Dart_GetType(dart_core, NewString("String"), 0, NULL); + Dart_GetNonNullableType(dart_core, NewString("String"), 0, NULL); EXPECT_VALID(string_type); Dart_Handle string_list = Dart_NewListOfType(string_type, 0); EXPECT_VALID(string_list); @@ -5293,7 +5361,7 @@ TEST_CASE(DartAPI_NewListOfTypeFilled) { EXPECT(Dart_IdentityEquals(result, zxhandle)); Dart_Handle readresult_type = - Dart_GetType(lib, NewString("ChannelReadResult"), 0, NULL); + Dart_GetNonNullableType(lib, NewString("ChannelReadResult"), 0, NULL); EXPECT_VALID(zxhandle_type); const int kNumArgs = 1; @@ -5355,7 +5423,8 @@ TEST_CASE(DartAPI_Invoke) { // Shared setup. Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL); - Dart_Handle type = Dart_GetType(lib, NewString("Methods"), 0, NULL); + Dart_Handle type = + Dart_GetNonNullableType(lib, NewString("Methods"), 0, NULL); EXPECT_VALID(type); Dart_Handle instance = Dart_Invoke(lib, NewString("test"), 0, NULL); EXPECT_VALID(instance); @@ -5461,7 +5530,8 @@ TEST_CASE(DartAPI_Invoke_PrivateStatic) { // Shared setup. Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL); - Dart_Handle type = Dart_GetType(lib, NewString("Methods"), 0, NULL); + Dart_Handle type = + Dart_GetNonNullableType(lib, NewString("Methods"), 0, NULL); Dart_Handle result; EXPECT_VALID(type); Dart_Handle name = NewString("_staticMethod"); @@ -5554,7 +5624,8 @@ TEST_CASE(DartAPI_Invoke_BadArgs) { // Shared setup. Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL); - Dart_Handle type = Dart_GetType(lib, NewString("Methods"), 0, NULL); + Dart_Handle type = + Dart_GetNonNullableType(lib, NewString("Methods"), 0, NULL); EXPECT_VALID(type); Dart_Handle instance = Dart_Invoke(lib, NewString("test"), 0, NULL); EXPECT_VALID(instance); @@ -5672,7 +5743,8 @@ TEST_CASE(DartAPI_InvokeNoSuchMethod) { // Create a test library and Load up a test script in it. // The test library must have a dart: url so it can import dart:_internal. Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL); - Dart_Handle type = Dart_GetType(lib, NewString("TestClass"), 0, NULL); + Dart_Handle type = + Dart_GetNonNullableType(lib, NewString("TestClass"), 0, NULL); EXPECT_VALID(type); // Invoke a function which returns an object. @@ -5806,7 +5878,8 @@ static intptr_t kNativeArgumentNativeField2Value = 40; static intptr_t native_arg_str_peer = 100; static void NativeArgumentCreate(Dart_NativeArguments args) { Dart_Handle lib = Dart_LookupLibrary(NewString(TestCase::url())); - Dart_Handle type = Dart_GetType(lib, NewString("MyObject"), 0, NULL); + Dart_Handle type = + Dart_GetNonNullableType(lib, NewString("MyObject"), 0, NULL); EXPECT_VALID(type); // Allocate without a constructor. @@ -6038,94 +6111,53 @@ TEST_CASE(DartAPI_TypeToNullability) { const Dart_Handle name = NewString("Class"); // Lookup the legacy type for Class. Dart_Handle type = Dart_GetType(lib, name, 0, NULL); - EXPECT_VALID(type); - bool result = false; - EXPECT_VALID(Dart_IsLegacyType(type, &result)); - EXPECT(result); + Dart_Handle nonNullableType; + Dart_Handle nullableType; + if (Dart_IsError(type)) { + EXPECT_ERROR( + type, + "Cannot use legacy types with --null-safety enabled. " + "Use Dart_GetNullableType or Dart_GetNonNullableType instead."); - // Legacy -> Nullable - Dart_Handle nullableType = Dart_TypeToNullableType(type); - EXPECT_VALID(nullableType); - result = false; - EXPECT_VALID(Dart_IsNullableType(nullableType, &result)); - EXPECT(result); - EXPECT(Dart_IdentityEquals(nullableType, - Dart_GetNullableType(lib, name, 0, nullptr))); + nonNullableType = Dart_GetNonNullableType(lib, name, 0, nullptr); + EXPECT_VALID(nonNullableType); + nullableType = Dart_GetNullableType(lib, name, 0, nullptr); + } else { + EXPECT_VALID(type); + bool result = false; + EXPECT_VALID(Dart_IsLegacyType(type, &result)); + EXPECT(result); - // Legacy -> Non-Nullable - Dart_Handle nonNullableType = Dart_TypeToNonNullableType(type); - EXPECT_VALID(nonNullableType); - result = false; - EXPECT_VALID(Dart_IsNonNullableType(nonNullableType, &result)); - EXPECT(result); - EXPECT(Dart_IdentityEquals(nonNullableType, - Dart_GetNonNullableType(lib, name, 0, nullptr))); + // Legacy -> Nullable + nullableType = Dart_TypeToNullableType(type); + EXPECT_VALID(nullableType); + result = false; + EXPECT_VALID(Dart_IsNullableType(nullableType, &result)); + EXPECT(result); + EXPECT(Dart_IdentityEquals(nullableType, + Dart_GetNullableType(lib, name, 0, nullptr))); + + // Legacy -> Non-Nullable + nonNullableType = Dart_TypeToNonNullableType(type); + EXPECT_VALID(nonNullableType); + result = false; + EXPECT_VALID(Dart_IsNonNullableType(nonNullableType, &result)); + EXPECT(result); + EXPECT(Dart_IdentityEquals(nonNullableType, + Dart_GetNonNullableType(lib, name, 0, nullptr))); + } // Nullable -> Non-Nullable EXPECT(Dart_IdentityEquals( nonNullableType, Dart_TypeToNonNullableType(Dart_GetNullableType(lib, name, 0, nullptr)))); - // Nullable -> Non-Nullable + // Non-Nullable -> Nullable EXPECT(Dart_IdentityEquals( nullableType, Dart_TypeToNullableType(Dart_GetNonNullableType(lib, name, 0, nullptr)))); } -TEST_CASE(DartAPI_GetType) { - const char* kScriptChars = - "library testlib;\n" - "class Class {\n" - " static var name = 'Class';\n" - "}\n" - "\n" - "class _Class {\n" - " static var name = '_Class';\n" - "}\n"; - - Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL); - - // Lookup a class. - Dart_Handle type = Dart_GetType(lib, NewString("Class"), 0, NULL); - EXPECT_VALID(type); - bool result = false; - EXPECT_VALID(Dart_IsLegacyType(type, &result)); - EXPECT(result); - Dart_Handle name = Dart_GetField(type, NewString("name")); - EXPECT_VALID(name); - const char* name_cstr = ""; - EXPECT_VALID(Dart_StringToCString(name, &name_cstr)); - EXPECT_STREQ("Class", name_cstr); - - // Lookup a private class. - type = Dart_GetType(lib, NewString("_Class"), 0, NULL); - EXPECT_VALID(type); - result = false; - EXPECT_VALID(Dart_IsLegacyType(type, &result)); - EXPECT(result); - name = Dart_GetField(type, NewString("name")); - EXPECT_VALID(name); - name_cstr = ""; - EXPECT_VALID(Dart_StringToCString(name, &name_cstr)); - EXPECT_STREQ("_Class", name_cstr); - - // Lookup a class that does not exist. - type = Dart_GetType(lib, NewString("DoesNotExist"), 0, NULL); - EXPECT(Dart_IsError(type)); - EXPECT_STREQ("Type 'DoesNotExist' not found in library 'testlib'.", - Dart_GetError(type)); - - // Lookup a class from an error library. The error propagates. - type = Dart_GetType(Api::NewError("myerror"), NewString("Class"), 0, NULL); - EXPECT(Dart_IsError(type)); - EXPECT_STREQ("myerror", Dart_GetError(type)); - - // Lookup a type using an error class name. The error propagates. - type = Dart_GetType(lib, Api::NewError("myerror"), 0, NULL); - EXPECT(Dart_IsError(type)); - EXPECT_STREQ("myerror", Dart_GetError(type)); -} - TEST_CASE(DartAPI_GetNullableType) { const char* kScriptChars = "library testlib;\n" @@ -6263,7 +6295,8 @@ TEST_CASE(DartAPI_InstanceOf) { Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL); // Fetch InstanceOfTest class. - Dart_Handle type = Dart_GetType(lib, NewString("InstanceOfTest"), 0, NULL); + Dart_Handle type = + Dart_GetNonNullableType(lib, NewString("InstanceOfTest"), 0, NULL); EXPECT_VALID(type); // Invoke a function which returns an object of type InstanceOf.. @@ -6279,7 +6312,8 @@ TEST_CASE(DartAPI_InstanceOf) { EXPECT(is_instance); // Fetch OtherClass and check if instanceOfTestObj is instance of it. - Dart_Handle otherType = Dart_GetType(lib, NewString("OtherClass"), 0, NULL); + Dart_Handle otherType = + Dart_GetNonNullableType(lib, NewString("OtherClass"), 0, NULL); EXPECT_VALID(otherType); result = Dart_ObjectIsType(instanceOfTestObj, otherType, &is_instance); @@ -6472,7 +6506,7 @@ TEST_CASE(DartAPI_SetNativeResolver) { result = Dart_FinalizeLoading(false); EXPECT_VALID(result); EXPECT(Dart_IsLibrary(lib)); - Dart_Handle type = Dart_GetType(lib, NewString("Test"), 0, NULL); + Dart_Handle type = Dart_GetNonNullableType(lib, NewString("Test"), 0, NULL); EXPECT_VALID(type); result = Dart_SetNativeResolver(Dart_Null(), &MyNativeResolver1, NULL); @@ -8206,9 +8240,9 @@ TEST_CASE(DartAPI_NotifyIdleShort) { "void main() {\n" " var v;\n" " for (var i = 0; i < 100; i++) {\n" - " var t = new List();\n" + " var t = [];\n" " for (var j = 0; j < 10000; j++) {\n" - " t.add(new List(100));\n" + " t.add(List.filled(100, null));\n" " }\n" " v = t;\n" " notifyIdle();\n" @@ -8237,9 +8271,9 @@ TEST_CASE(DartAPI_NotifyIdleLong) { "void main() {\n" " var v;\n" " for (var i = 0; i < 100; i++) {\n" - " var t = new List();\n" + " var t = [];\n" " for (var j = 0; j < 10000; j++) {\n" - " t.add(new List(100));\n" + " t.add(List.filled(100, null));\n" " }\n" " v = t;\n" " notifyIdle();\n" @@ -8269,9 +8303,9 @@ TEST_CASE(DartAPI_NotifyLowMemory) { "void main() {\n" " var v;\n" " for (var i = 0; i < 100; i++) {\n" - " var t = new List();\n" + " var t = [];\n" " for (var j = 0; j < 10000; j++) {\n" - " t.add(new List(100));\n" + " t.add(List.filled(100, null));\n" " }\n" " v = t;\n" " notifyLowMemory();\n" @@ -8346,6 +8380,7 @@ TEST_CASE(DartAPI_InvokeVMServiceMethod) { if (!condition) { throw 'Failed to validate InvokeVMServiceMethod() response.'; } + return false; } bool validateResult(Uint8List bytes) { final map = json.decode(utf8.decode(bytes)); diff --git a/runtime/vm/guard_field_test.cc b/runtime/vm/guard_field_test.cc index 3334ea1c4cc..5c13efecff6 100644 --- a/runtime/vm/guard_field_test.cc +++ b/runtime/vm/guard_field_test.cc @@ -32,7 +32,7 @@ TEST_CASE(GuardFieldSimpleTest) { "class A {\n" " var f1 = 3.0;\n" " dynamic f2 = 3;\n" - " var f3 = new List(4);\n" + " var f3 = List.filled(4, null);\n" " foo() {\n" " f1 = f1 + f1;\n" " }\n" @@ -43,14 +43,14 @@ TEST_CASE(GuardFieldSimpleTest) { "}\n" "\n" "runFoo() {\n" - " var a = new A();\n" + " var a = A();\n" " for (int i = 0; i < 2000; i++) {\n" " a.foo();\n" " }\n" "}\n" "\n" "runBar() {\n" - " var a = new A();\n" + " var a = A();\n" " for (int i = 0; i < 2000; i++) {\n" " a.bar();\n" " }\n" @@ -83,7 +83,7 @@ TEST_CASE(GuardFieldFinalListTest) { "class A {\n" " var f1 = 3.0;\n" " dynamic f2 = 3;\n" - " final f3 = new List(4);\n" + " final f3 = List.filled(4, null);\n" " foo() {\n" " f1 = f1 + f1;\n" " }\n" @@ -94,14 +94,14 @@ TEST_CASE(GuardFieldFinalListTest) { "}\n" "\n" "runFoo() {\n" - " var a = new A();\n" + " var a = A();\n" " for (int i = 0; i < 2000; i++) {\n" " a.foo();\n" " }\n" "}\n" "\n" "runBar() {\n" - " var a = new A();\n" + " var a = A();\n" " for (int i = 0; i < 2000; i++) {\n" " a.bar();\n" " }\n" @@ -136,7 +136,7 @@ TEST_CASE(GuardFieldFinalVariableLengthListTest) { "class A {\n" " var f1 = 3.0;\n" " dynamic f2 = 3;\n" - " final f3 = new List();\n" + " final f3 = List.empty(growable: true);\n" " foo() {\n" " f1 = f1 + f1;\n" " }\n" @@ -147,14 +147,14 @@ TEST_CASE(GuardFieldFinalVariableLengthListTest) { "}\n" "\n" "runFoo() {\n" - " var a = new A();\n" + " var a = A();\n" " for (int i = 0; i < 2000; i++) {\n" " a.foo();\n" " }\n" "}\n" "\n" "runBar() {\n" - " var a = new A();\n" + " var a = A();\n" " for (int i = 0; i < 2000; i++) {\n" " a.bar();\n" " }\n" diff --git a/runtime/vm/heap/heap_test.cc b/runtime/vm/heap/heap_test.cc index 33c8500ccad..461513d447b 100644 --- a/runtime/vm/heap/heap_test.cc +++ b/runtime/vm/heap/heap_test.cc @@ -68,7 +68,7 @@ TEST_CASE(OldGC_Unsync) { TEST_CASE(LargeSweep) { const char* kScriptChars = "main() {\n" - " return new List(8 * 1024 * 1024);\n" + " return List.filled(8 * 1024 * 1024, null);\n" "}\n"; NOT_IN_PRODUCT(FLAG_verbose_gc = true); Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL); diff --git a/runtime/vm/isolate_reload_test.cc b/runtime/vm/isolate_reload_test.cc index 72411fb00c4..da66a907b4c 100644 --- a/runtime/vm/isolate_reload_test.cc +++ b/runtime/vm/isolate_reload_test.cc @@ -274,36 +274,44 @@ TEST_CASE(IsolateReload_KernelIncrementalCompileGenerics) { } TEST_CASE(IsolateReload_KernelIncrementalCompileBaseClass) { + const bool null_safety = (FLAG_null_safety == kNullSafetyOptionStrong); + const char* nullableTag = null_safety ? "?" : ""; // clang-format off - Dart_SourceFile sourcefiles[] = { + auto kSourceFile1 = + Utils::CStringUniquePtr(OS::SCreate(nullptr, + "class State {\n" + " T%s t;\n" + " U%s u;\n" + " State(List l) {\n" + " t = l[0] is T ? l[0] : null;\n" + " u = l[1] is U ? l[1] : null;\n" + " }\n" + "}\n", + nullableTag, nullableTag), + std::free); + Dart_SourceFile sourcefiles[3] = { { "file:///test-app.dart", "import 'test-util.dart';\n" "main() {\n" " var v = doWork();" - " return v == 42 ? 1: v == null ? -1: 0;\n" + " return v == 42 ? 1 : v == null ? -1 : 0;\n" "}\n", }, { "file:///test-lib.dart", - "class State {\n" - " T t;\n" - " U u;\n" - " State(List l) {\n" - " t = l[0] is T? l[0]: null;\n" - " u = l[1] is U? l[1]: null;\n" - " }\n" - "}\n", + kSourceFile1.get() }, { - "file:///test-util.dart", - "import 'test-lib.dart';\n" - "class MyAccountState extends State {\n" - " MyAccountState(List l): super(l) {}\n" - " first() => t;\n" - "}\n" - "doWork() => new MyAccountState([42, 'abc']).first();\n" - }}; + "file:///test-util.dart", + "import 'test-lib.dart';\n" + "class MyAccountState extends State {\n" + " MyAccountState(List l): super(l) {}\n" + " first() => t;\n" + "}\n" + "doWork() => new MyAccountState([42, 'abc']).first();\n" + } + }; // clang-format on Dart_Handle lib = TestCase::LoadTestScriptWithDFE( @@ -316,20 +324,22 @@ TEST_CASE(IsolateReload_KernelIncrementalCompileBaseClass) { EXPECT_VALID(result); EXPECT_EQ(1, value); - // clang-format off - Dart_SourceFile updated_sourcefiles[] = { - { - "file:///test-lib.dart", - "class State {\n" - " T t;\n" - " U u;\n" - " State(List l) {\n" - " t = l[0] is T? l[0]: null;\n" - " u = l[1] is U? l[1]: null;\n" - " }\n" - "}\n", - }}; - // clang-format on + auto kUpdatedSourceFile = + Utils::CStringUniquePtr(OS::SCreate(nullptr, + "class State {\n" + " T%s t;\n" + " U%s u;\n" + " State(List l) {\n" + " t = l[0] is T ? l[0] : null;\n" + " u = l[1] is U ? l[1] : null;\n" + " }\n" + "}\n", + nullableTag, nullableTag), + std::free); + Dart_SourceFile updated_sourcefiles[1] = {{ + "file:///test-lib.dart", + kUpdatedSourceFile.get(), + }}; { const uint8_t* kernel_buffer = NULL; intptr_t kernel_buffer_size = 0; @@ -717,34 +727,46 @@ TEST_CASE(IsolateReload_ImplicitConstructorChanged) { } TEST_CASE(IsolateReload_ConstructorChanged) { - const char* kScript = - "class A {\n" - " int field;\n" - " A() { field = 20; }\n" - "}\n" - "var savedA = new A();\n" - "main() {\n" - " var newA = new A();\n" - " return 'saved:${savedA.field} new:${newA.field}';\n" - "}\n"; + const bool null_safety = (FLAG_null_safety == kNullSafetyOptionStrong); + const char* lateTag = null_safety ? "late" : ""; + // clang-format off + auto kScript = Utils::CStringUniquePtr( + OS::SCreate(nullptr, + "class A {\n" + " %s int field;\n" + " A() { field = 20; }\n" + "}\n" + "var savedA = A();\n" + "main() {\n" + " var newA = A();\n" + " return 'saved:${savedA.field} new:${newA.field}';\n" + "}\n", + lateTag), + std::free); + // clang-format on - Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL); + Dart_Handle lib = TestCase::LoadTestScript(kScript.get(), NULL); EXPECT_VALID(lib); EXPECT_STREQ("saved:20 new:20", SimpleInvokeStr(lib, "main")); - const char* kReloadScript = - "var _unused;" - "class A {\n" - " int field;\n" - " A() { field = 10; }\n" - "}\n" - "var savedA = new A();\n" - "main() {\n" - " var newA = new A();\n" - " return 'saved:${savedA.field} new:${newA.field}';\n" - "}\n"; + // clang-format off + auto kReloadScript = Utils::CStringUniquePtr( + OS::SCreate(nullptr, + "var _unused;" + "class A {\n" + " %s int field;\n" + " A() { field = 10; }\n" + "}\n" + "var savedA = A();\n" + "main() {\n" + " var newA = A();\n" + " return 'saved:${savedA.field} new:${newA.field}';\n" + "}\n", + lateTag), + std::free); + // clang-format on - lib = TestCase::ReloadTestScript(kReloadScript); + lib = TestCase::ReloadTestScript(kReloadScript.get()); EXPECT_VALID(lib); EXPECT_STREQ("saved:20 new:10", SimpleInvokeStr(lib, "main")); } @@ -1823,10 +1845,10 @@ TEST_CASE(IsolateReload_TearOff_List_Set) { "class C {\n" " foo() => 'old';\n" "}\n" - "List list = new List(2);\n" - "Set set = new Set();\n" + "List list = List.filled(2, null);\n" + "Set set = Set();\n" "main() {\n" - " var c = new C();\n" + " var c = C();\n" " list[0] = c.foo;\n" " list[1] = c.foo;\n" " set.add(c.foo);\n" @@ -1851,10 +1873,10 @@ TEST_CASE(IsolateReload_TearOff_List_Set) { "class C {\n" " foo() => 'new';\n" "}\n" - "List list = new List(2);\n" - "Set set = new Set();\n" + "List list = List.filled(2, null);\n" + "Set set = Set();\n" "main() {\n" - " var c = new C();\n" + " var c = C();\n" " list[0] = c.foo;\n" " list[1] = c.foo;\n" " set.add(c.foo);\n" @@ -3423,120 +3445,161 @@ TEST_CASE(IsolateReload_ConstFieldUpdate) { } 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"; + const bool null_safety = (FLAG_null_safety == kNullSafetyOptionStrong); + const char* lateTag = null_safety ? "late" : ""; + // clang-format off + auto kScript = Utils::CStringUniquePtr(OS::SCreate(nullptr, + "class Foo {\n" + " int x = 4;\n" + "}\n" + "%s Foo value;\n" + "main() {\n" + " value = Foo();\n" + " return value.x;\n" + "}\n", + lateTag), + std::free); + // clang-format on - Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL); + Dart_Handle lib = TestCase::LoadTestScript(kScript.get(), 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"; + // clang-format off + auto kReloadScript = Utils::CStringUniquePtr(OS::SCreate(nullptr, + "class Foo {\n" + " int x = 4;\n" + " int y = 7;\n" + "}\n" + "%s Foo value;\n" + "main() {\n" + " return value.y;\n" + "}\n", + lateTag), + std::free); + // clang-format on - lib = TestCase::ReloadTestScript(kReloadScript); + lib = TestCase::ReloadTestScript(kReloadScript.get()); 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"; + const bool null_safety = (FLAG_null_safety == kNullSafetyOptionStrong); + const char* lateTag = null_safety ? "late" : ""; + // clang-format off + auto kScript = + Utils::CStringUniquePtr(OS::SCreate(nullptr, + "int myInitialValue = 8 * 7;\n" + "class Foo {\n" + " int x = 4;\n" + "}\n" + "%s Foo value;\n" + "main() {\n" + " value = Foo();\n" + " return value.x;\n" + "}\n", + lateTag), + std::free); + // clang-format on - Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL); + Dart_Handle lib = TestCase::LoadTestScript(kScript.get(), 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"; + // clang-format off + auto kReloadScript = + Utils::CStringUniquePtr(OS::SCreate(nullptr, + "int myInitialValue = 8 * 7;\n" + "class Foo {\n" + " int x = 4;\n" + " int y = myInitialValue;\n" + "}\n" + "%s Foo value;\n" + "main() {\n" + " return value.y;\n" + "}\n", + lateTag), + std::free); + // clang-format on - lib = TestCase::ReloadTestScript(kReloadScript); + lib = TestCase::ReloadTestScript(kReloadScript.get()); EXPECT_VALID(lib); // Verify that we ran field initializers on existing instances. EXPECT_EQ(56, SimpleInvoke(lib, "main")); } TEST_CASE(IsolateReload_RunNewFieldInitializersLazy) { - 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"; + const bool null_safety = (FLAG_null_safety == kNullSafetyOptionStrong); + const char* lateTag = null_safety ? "late" : ""; + // clang-format off + auto kScript = + Utils::CStringUniquePtr(OS::SCreate(nullptr, + "int myInitialValue = 8 * 7;\n" + "class Foo {\n" + " int x = 4;\n" + "}\n" + "%s Foo value;\n" + "%s Foo value1;\n" + "main() {\n" + " value = Foo();\n" + " value1 = Foo();\n" + " return value.x;\n" + "}\n", + lateTag, lateTag), + std::free); + // clang-format on - Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL); + Dart_Handle lib = TestCase::LoadTestScript(kScript.get(), 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} ${value.y} ${value1.y} ${myInitialValue}';\n" - "}\n"; + // clang-format off + auto kReloadScript = Utils::CStringUniquePtr( + OS::SCreate(nullptr, + "int myInitialValue = 8 * 7;\n" + "class Foo {\n" + " int x = 4;\n" + " int y = myInitialValue++;\n" + "}\n" + "%s Foo value;\n" + "%s Foo value1;\n" + "main() {\n" + " return '${myInitialValue} ${value.y} ${value1.y} " + "${myInitialValue}';\n" + "}\n", + lateTag, lateTag), + std::free); + // clang-format on - lib = TestCase::ReloadTestScript(kReloadScript); + lib = TestCase::ReloadTestScript(kReloadScript.get()); EXPECT_VALID(lib); // Verify that field initializers ran lazily. EXPECT_STREQ("56 56 57 58", SimpleInvokeStr(lib, "main")); } TEST_CASE(IsolateReload_RunNewFieldInitializersLazyConst) { - 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"; + const bool null_safety = (FLAG_null_safety == kNullSafetyOptionStrong); + const char* lateTag = null_safety ? "late" : ""; + // clang-format off + auto kScript = Utils::CStringUniquePtr(OS::SCreate(nullptr, + "class Foo {\n" + " int x = 4;\n" + "}\n" + "%s Foo value;\n" + "main() {\n" + " value = Foo();\n" + " return value.x;\n" + "}\n", + lateTag), + std::free); + // clang-format on - Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL); + Dart_Handle lib = TestCase::LoadTestScript(kScript.get(), NULL); EXPECT_VALID(lib); EXPECT_EQ(4, SimpleInvoke(lib, "main")); @@ -3544,158 +3607,204 @@ TEST_CASE(IsolateReload_RunNewFieldInitializersLazyConst) { // function in the VM because the initializer is a literal, but we should not // eagerly initialize with the literal so that the behavior doesn't depend on // this optimization. - const char* kReloadScript = - "class Foo {\n" - " int x = 4;\n" - " int y = 5;\n" - "}\n" - "Foo value;\n" - "main() {\n" - " return 0;\n" - "}\n"; + // clang-format off + auto kReloadScript = Utils::CStringUniquePtr(OS::SCreate(nullptr, + "class Foo {\n" + " int x = 4;\n" + " int y = 5;\n" + "}\n" + "%s Foo value;\n" + "main() {\n" + " return 0;\n" + "}\n", + lateTag), + std::free); + // clang-format on - lib = TestCase::ReloadTestScript(kReloadScript); + lib = TestCase::ReloadTestScript(kReloadScript.get()); EXPECT_VALID(lib); EXPECT_EQ(0, SimpleInvoke(lib, "main")); // Change y's initializer and check this new initializer is used. - const char* kReloadScript2 = - "class Foo {\n" - " int x = 4;\n" - " int y = 6;\n" - "}\n" - "Foo value;\n" - "main() {\n" - " return value.y;\n" - "}\n"; + auto kReloadScript2 = + Utils::CStringUniquePtr(OS::SCreate(nullptr, + "class Foo {\n" + " int x = 4;\n" + " int y = 6;\n" + "}\n" + "%s Foo value;\n" + "main() {\n" + " return value.y;\n" + "}\n", + lateTag), + std::free); - lib = TestCase::ReloadTestScript(kReloadScript2); + lib = TestCase::ReloadTestScript(kReloadScript2.get()); EXPECT_VALID(lib); EXPECT_EQ(6, SimpleInvoke(lib, "main")); } TEST_CASE(IsolateReload_RunNewFieldInitializersLazyTransitive) { - 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"; + const bool null_safety = (FLAG_null_safety == kNullSafetyOptionStrong); + const char* lateTag = null_safety ? "late" : ""; + // clang-format off + auto kScript = + Utils::CStringUniquePtr(OS::SCreate(nullptr, + "int myInitialValue = 8 * 7;\n" + "class Foo {\n" + " int x = 4;\n" + "}\n" + "%s Foo value;\n" + "%s Foo value1;\n" + "main() {\n" + " value = Foo();\n" + " value1 = Foo();\n" + " return value.x;\n" + "}\n", + lateTag, lateTag), + std::free); + // clang-format on - Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL); + Dart_Handle lib = TestCase::LoadTestScript(kScript.get(), NULL); EXPECT_VALID(lib); EXPECT_EQ(4, SimpleInvoke(lib, "main")); // Add the field y. Do not touch 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"; + // clang-format off + auto kReloadScript = + Utils::CStringUniquePtr(OS::SCreate(nullptr, + "int myInitialValue = 8 * 7;\n" + "class Foo {\n" + " int x = 4;\n" + " int y = myInitialValue++;\n" + "}\n" + "%s Foo value;\n" + "%s Foo value1;\n" + "main() {\n" + " return '${myInitialValue}';\n" + "}\n", + lateTag, lateTag), + std::free); + // clang-format on - lib = TestCase::ReloadTestScript(kReloadScript); + lib = TestCase::ReloadTestScript(kReloadScript.get()); EXPECT_VALID(lib); EXPECT_STREQ("56", SimpleInvokeStr(lib, "main")); // Reload again. Field y's getter still needs to keep for initialization even // though it is no longer new. - const char* kReloadScript2 = - "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} ${value.y} ${value1.y} ${myInitialValue}';\n" - "}\n"; + // clang-format off + auto kReloadScript2 = Utils::CStringUniquePtr( + OS::SCreate(nullptr, + "int myInitialValue = 8 * 7;\n" + "class Foo {\n" + " int x = 4;\n" + " int y = myInitialValue++;\n" + "}\n" + "%s Foo value;\n" + "%s Foo value1;\n" + "main() {\n" + " return '${myInitialValue} ${value.y} ${value1.y} " + "${myInitialValue}';\n" + "}\n", + lateTag, lateTag), + std::free); + // clang-format on - lib = TestCase::ReloadTestScript(kReloadScript2); + lib = TestCase::ReloadTestScript(kReloadScript2.get()); EXPECT_VALID(lib); // Verify that field initializers ran lazily. EXPECT_STREQ("56 56 57 58", SimpleInvokeStr(lib, "main")); } 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"; + const bool null_safety = (FLAG_null_safety == kNullSafetyOptionStrong); + const char* lateTag = null_safety ? "late" : ""; + // clang-format off + auto kScript = Utils::CStringUniquePtr(OS::SCreate(nullptr, + "class Foo {\n" + " int x = 4;\n" + "}\n" + "%s Foo value;\n" + "main() {\n" + " value = Foo();\n" + " return value.x;\n" + "}\n", + lateTag), + std::free); + // clang-format on - Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL); + Dart_Handle lib = TestCase::LoadTestScript(kScript.get(), 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 'exception';\n" - "}\n" - "Foo value;\n" - "main() {\n" - " try {\n" - " return value.y.toString();\n" - " } catch (e) {\n" - " return e.toString();\n" - " }\n" - "}\n"; + // clang-format off + auto kReloadScript = + Utils::CStringUniquePtr(OS::SCreate(nullptr, + "class Foo {\n" + " int x = 4;\n" + " int y = throw 'exception';\n" + "}\n" + "%s Foo value;\n" + "main() {\n" + " try {\n" + " return value.y.toString();\n" + " } catch (e) {\n" + " return e.toString();\n" + " }\n" + "}\n", + lateTag), + std::free); + // clang-format on - lib = TestCase::ReloadTestScript(kReloadScript); + lib = TestCase::ReloadTestScript(kReloadScript.get()); EXPECT_VALID(lib); // Verify that we ran field initializers on existing instances. EXPECT_STREQ("exception", SimpleInvokeStr(lib, "main")); } TEST_CASE(IsolateReload_RunNewFieldInitializersCyclicInitialization) { - 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"; + const bool null_safety = (FLAG_null_safety == kNullSafetyOptionStrong); + const char* lateTag = null_safety ? "late" : ""; + // clang-format off + auto kScript = Utils::CStringUniquePtr(OS::SCreate(nullptr, + "class Foo {\n" + " int x = 4;\n" + "}\n" + "%s Foo value;\n" + "main() {\n" + " value = Foo();\n" + " return value.x;\n" + "}\n", + lateTag), + std::free); + // clang-format on - Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL); + Dart_Handle lib = TestCase::LoadTestScript(kScript.get(), 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 = value.y;\n" - "}\n" - "Foo value;\n" - "main() {\n" - " try {\n" - " return value.y.toString();\n" - " } catch (e) {\n" - " return e.toString();\n" - " }\n" - "}\n"; - - lib = TestCase::ReloadTestScript(kReloadScript); + // clang-format off + auto kReloadScript = + Utils::CStringUniquePtr(OS::SCreate(nullptr, + "class Foo {\n" + " int x = 4;\n" + " int y = value.y;\n" + "}\n" + "%s Foo value;\n" + "main() {\n" + " try {\n" + " return value.y.toString();\n" + " } catch (e) {\n" + " return e.toString();\n" + " }\n" + "}\n", + lateTag), + std::free); + // clang-format on + lib = TestCase::ReloadTestScript(kReloadScript.get()); EXPECT_VALID(lib); EXPECT_STREQ("Stack Overflow", SimpleInvokeStr(lib, "main")); } @@ -3703,143 +3812,190 @@ TEST_CASE(IsolateReload_RunNewFieldInitializersCyclicInitialization) { // 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"; + const bool null_safety = (FLAG_null_safety == kNullSafetyOptionStrong); + const char* lateTag = null_safety ? "late" : ""; + // clang-format off + auto kScript = Utils::CStringUniquePtr(OS::SCreate(nullptr, + "class Foo {\n" + " int x = 4;\n" + "}\n" + "%s Foo value;\n" + "main() {\n" + " value = Foo();\n" + " return value.x;\n" + "}\n", + lateTag), + std::free); + // clang-format on - Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL); + Dart_Handle lib = TestCase::LoadTestScript(kScript.get(), 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"; + // clang-format off + auto kReloadScript = + Utils::CStringUniquePtr(OS::SCreate(nullptr, + "class Foo {\n" + " int x = 4;\n" + " int y = ......;\n" + "}\n" + "%s Foo value;\n" + "main() {\n" + " return '${value.y == null}';" + "}\n", + lateTag), + std::free); + // clang-format on // The reload fails because the initializing expression is parsed at // class finalization time. - lib = TestCase::ReloadTestScript(kReloadScript); + lib = TestCase::ReloadTestScript(kReloadScript.get()); 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"; + const bool null_safety = (FLAG_null_safety == kNullSafetyOptionStrong); + const char* lateTag = null_safety ? "late" : ""; + // clang-format off + auto kScript = Utils::CStringUniquePtr( + OS::SCreate(nullptr, + "class Foo {\n" + " Foo() { /* default constructor */ }\n" + " int x = 4;\n" + "}\n" + "%s Foo value;\n" + "main() {\n" + " value = Foo();\n" + " return value.x;\n" + "}\n", + lateTag), + std::free); + // clang-format on - Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL); + Dart_Handle lib = TestCase::LoadTestScript(kScript.get(), 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"; + // clang-format off + auto kReloadScript = Utils::CStringUniquePtr( + OS::SCreate(nullptr, + "class Foo {\n" + " Foo() { /* default constructor */ }\n" + " int x = 4;\n" + " int y = ......;\n" + "}\n" + "%s Foo value;\n" + "main() {\n" + " return '${value.y == null}';" + "}\n", + lateTag), + std::free); + // clang-format on // The reload fails because the initializing expression is parsed at // class finalization time. - lib = TestCase::ReloadTestScript(kReloadScript); + lib = TestCase::ReloadTestScript(kReloadScript.get()); 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"; + const bool null_safety = (FLAG_null_safety == kNullSafetyOptionStrong); + const char* lateTag = null_safety ? "late" : ""; + // clang-format off + auto kScript = Utils::CStringUniquePtr( + OS::SCreate(nullptr, + "class Foo {\n" + " Foo() { /* default constructor */ }\n" + " int x = 4;\n" + "}\n" + "%s Foo value;\n" + "main() {\n" + " value = Foo();\n" + " return value.x;\n" + "}\n", + lateTag), + std::free); + // clang-format on - Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL); + Dart_Handle lib = TestCase::LoadTestScript(kScript.get(), 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"; + // clang-format off + auto kReloadScript = Utils::CStringUniquePtr( + OS::SCreate(nullptr, + "class Foo {\n" + " Foo() { /* default constructor */ }\n" + " int x = 4;\n" + " int y = ......\n" + "}\n" + "%s Foo value;\n" + "main() {\n" + " return '${value.y == null}';" + "}\n", + lateTag), + std::free); + // clang-format on // The reload fails because the initializing expression is parsed at // class finalization time. - lib = TestCase::ReloadTestScript(kReloadScript); + lib = TestCase::ReloadTestScript(kReloadScript.get()); EXPECT_ERROR(lib, "......"); } TEST_CASE(IsolateReload_RunNewFieldInitializersSuperClass) { - 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"; + const bool null_safety = (FLAG_null_safety == kNullSafetyOptionStrong); + const char* lateTag = null_safety ? "late" : ""; + // clang-format off + auto kScript = + Utils::CStringUniquePtr(OS::SCreate(nullptr, + "class Super {\n" + " static var foo = 'right';\n" + "}\n" + "class Foo extends Super {\n" + " static var foo = 'wrong';\n" + "}\n" + "%s Foo value;\n" + "main() {\n" + " Super.foo;\n" + " Foo.foo;\n" + " value = Foo();\n" + " return 0;\n" + "}\n", + lateTag), + std::free); + // clang-format on - Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL); + Dart_Handle lib = TestCase::LoadTestScript(kScript.get(), 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"; + // clang-format on + auto kReloadScript = + Utils::CStringUniquePtr(OS::SCreate(nullptr, + "class Super {\n" + " static var foo = 'right';\n" + " var newField = foo;\n" + "}\n" + "class Foo extends Super {\n" + " static var foo = 'wrong';\n" + "}\n" + "%s Foo value;\n" + "main() {\n" + " return value.newField;\n" + "}\n", + lateTag), + std::free); + // clang-format off - lib = TestCase::ReloadTestScript(kReloadScript); + lib = TestCase::ReloadTestScript(kReloadScript.get()); EXPECT_VALID(lib); // Verify that we ran field initializers on existing instances in the // correct scope. @@ -3851,50 +4007,62 @@ TEST_CASE(IsolateReload_RunNewFieldInitializersSuperClass) { } TEST_CASE(IsolateReload_RunNewFieldInitializersWithConsts) { - const char* kScript = - "class C {\n" - " final x;\n" - " const C(this.x);\n" - "}\n" - "var a = const C(const C(1));\n" - "var b = const C(const C(2));\n" - "var c = const C(const C(3));\n" - "var d = const C(const C(4));\n" - "class Foo {\n" - "}\n" - "Foo value;\n" - "main() {\n" - " value = new Foo();\n" - " a; b; c; d;\n" - " return 'Okay';\n" - "}\n"; + const bool null_safety = (FLAG_null_safety == kNullSafetyOptionStrong); + const char* lateTag = null_safety ? "late" : ""; + // clang-format off + auto kScript = + Utils::CStringUniquePtr(OS::SCreate(nullptr, + "class C {\n" + " final x;\n" + " const C(this.x);\n" + "}\n" + "var a = const C(const C(1));\n" + "var b = const C(const C(2));\n" + "var c = const C(const C(3));\n" + "var d = const C(const C(4));\n" + "class Foo {\n" + "}\n" + "%s Foo value;\n" + "main() {\n" + " value = Foo();\n" + " a; b; c; d;\n" + " return 'Okay';\n" + "}\n", + lateTag), + std::free); + // clang-format on - Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL); + Dart_Handle lib = TestCase::LoadTestScript(kScript.get(), nullptr); EXPECT_VALID(lib); EXPECT_STREQ("Okay", SimpleInvokeStr(lib, "main")); - const char* kReloadScript = - "class C {\n" - " final x;\n" - " const C(this.x);\n" - "}\n" - "var a = const C(const C(1));\n" - "var b = const C(const C(2));\n" - "var c = const C(const C(3));\n" - "var d = const C(const C(4));\n" - "class Foo {\n" - " var d = const C(const C(4));\n" - " var c = const C(const C(3));\n" - " var b = const C(const C(2));\n" - " var a = const C(const C(1));\n" - "}\n" - "Foo value;\n" - "main() {\n" - " return '${identical(a, value.a)} ${identical(b, value.b)}'" - " ' ${identical(c, value.c)} ${identical(d, value.d)}';\n" - "}\n"; - - lib = TestCase::ReloadTestScript(kReloadScript); + // clang-format off + auto kReloadScript = Utils::CStringUniquePtr( + OS::SCreate( + nullptr, + "class C {\n" + " final x;\n" + " const C(this.x);\n" + "}\n" + "var a = const C(const C(1));\n" + "var b = const C(const C(2));\n" + "var c = const C(const C(3));\n" + "var d = const C(const C(4));\n" + "class Foo {\n" + " var d = const C(const C(4));\n" + " var c = const C(const C(3));\n" + " var b = const C(const C(2));\n" + " var a = const C(const C(1));\n" + "}\n" + "%s Foo value;\n" + "main() {\n" + " return '${identical(a, value.a)} ${identical(b, value.b)}'" + " ' ${identical(c, value.c)} ${identical(d, value.d)}';\n" + "}\n", + lateTag), + std::free); + // clang-format on + lib = TestCase::ReloadTestScript(kReloadScript.get()); EXPECT_VALID(lib); // Verify that we ran field initializers on existing instances and the const // expressions were properly canonicalized. @@ -3902,36 +4070,49 @@ TEST_CASE(IsolateReload_RunNewFieldInitializersWithConsts) { } TEST_CASE(IsolateReload_RunNewFieldInitializersWithGenerics) { - const char* kScript = - "class Foo {\n" - " T x;\n" - "}\n" - "Foo value1;\n" - "Foo value2;\n" - "main() {\n" - " value1 = new Foo();\n" - " value2 = new Foo();\n" - " return 'Okay';\n" - "}\n"; + const bool null_safety = (FLAG_null_safety == kNullSafetyOptionStrong); + const char* nullableTag = null_safety ? "?" : ""; + const char* lateTag = null_safety ? "late" : ""; + // clang-format off + auto kScript = + Utils::CStringUniquePtr(OS::SCreate(nullptr, + "class Foo {\n" + " T%s x;\n" + "}\n" + "%s Foo value1;\n" + "%s Foo value2;\n" + "main() {\n" + " value1 = Foo();\n" + " value2 = Foo();\n" + " return 'Okay';\n" + "}\n", + nullableTag, lateTag, lateTag), + std::free); + // clang-format on - Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL); + Dart_Handle lib = TestCase::LoadTestScript(kScript.get(), NULL); EXPECT_VALID(lib); EXPECT_STREQ("Okay", SimpleInvokeStr(lib, "main")); - const char* kReloadScript = - "class Foo {\n" - " T x;\n" - " List y = new List();" - " dynamic z = {};" - "}\n" - "Foo value1;\n" - "Foo value2;\n" - "main() {\n" - " return '${value1.y.runtimeType} ${value1.z.runtimeType}'" - " ' ${value2.y.runtimeType} ${value2.z.runtimeType}';\n" - "}\n"; + // clang-format off + auto kReloadScript = Utils::CStringUniquePtr( + OS::SCreate(nullptr, + "class Foo {\n" + " T%s x;\n" + " List y = List.empty();" + " dynamic z = {};" + "}\n" + "%s Foo value1;\n" + "%s Foo value2;\n" + "main() {\n" + " return '${value1.y.runtimeType} ${value1.z.runtimeType}'" + " ' ${value2.y.runtimeType} ${value2.z.runtimeType}';\n" + "}\n", + nullableTag, lateTag, lateTag), + std::free); + // clang-format on - lib = TestCase::ReloadTestScript(kReloadScript); + lib = TestCase::ReloadTestScript(kReloadScript.get()); EXPECT_VALID(lib); // Verify that we ran field initializers on existing instances and // correct type arguments were used. @@ -4066,26 +4247,33 @@ TEST_CASE(IsolateReload_DeleteStaticField) { } TEST_CASE(IsolateReload_ExistingFieldChangesType) { - const char* kScript = R"( + const bool null_safety = (FLAG_null_safety == kNullSafetyOptionStrong); + const char* lateTag = null_safety ? "late" : ""; + // clang-format off + auto kScript = Utils::CStringUniquePtr(OS::SCreate(nullptr, + R"( class Foo { int x = 42; } - Foo value; + %s Foo value; main() { - value = new Foo(); + value = Foo(); return 'Okay'; } - )"; + )", + lateTag), std::free); + // clang-format on - Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL); + Dart_Handle lib = TestCase::LoadTestScript(kScript.get(), NULL); EXPECT_VALID(lib); EXPECT_STREQ("Okay", SimpleInvokeStr(lib, "main")); - const char* kReloadScript = R"( + // clang-format off + auto kReloadScript = Utils::CStringUniquePtr(OS::SCreate(nullptr, R"( class Foo { double x = 42.0; } - Foo value; + %s Foo value; main() { try { return value.x.toString(); @@ -4093,9 +4281,11 @@ TEST_CASE(IsolateReload_ExistingFieldChangesType) { return e.toString(); } } - )"; + )", + lateTag), std::free); + // clang-format on - lib = TestCase::ReloadTestScript(kReloadScript); + lib = TestCase::ReloadTestScript(kReloadScript.get()); EXPECT_VALID(lib); EXPECT_STREQ( "type 'int' is not a subtype of type 'double' of 'function result'", @@ -4135,33 +4325,38 @@ TEST_CASE(IsolateReload_ExistingStaticFieldChangesType) { } TEST_CASE(IsolateReload_ExistingFieldChangesTypeIndirect) { - const char* kScript = R"( + const bool null_safety = (FLAG_null_safety == kNullSafetyOptionStrong); + const char* lateTag = null_safety ? "late" : ""; + // clang-format off + auto kScript = Utils::CStringUniquePtr(OS::SCreate(nullptr, R"( class A {} class B extends A {} class Foo { A x; Foo(this.x); } - Foo value; + %s Foo value; main() { - value = new Foo(new B()); + value = Foo(B()); return 'Okay'; } - )"; + )", lateTag), std::free); + // clang-format on - Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL); + Dart_Handle lib = TestCase::LoadTestScript(kScript.get(), NULL); EXPECT_VALID(lib); EXPECT_STREQ("Okay", SimpleInvokeStr(lib, "main")); // B is no longer a subtype of A. - const char* kReloadScript = R"( + // clang-format off + auto kReloadScript = Utils::CStringUniquePtr(OS::SCreate(nullptr, R"( class A {} class B {} class Foo { A x; Foo(this.x); } - Foo value; + %s Foo value; main() { try { return value.x.toString(); @@ -4169,9 +4364,10 @@ TEST_CASE(IsolateReload_ExistingFieldChangesTypeIndirect) { return e.toString(); } } - )"; + )", lateTag), std::free); + // clang-format on - lib = TestCase::ReloadTestScript(kReloadScript); + lib = TestCase::ReloadTestScript(kReloadScript.get()); EXPECT_VALID(lib); EXPECT_STREQ("type 'B' is not a subtype of type 'A' of 'function result'", SimpleInvokeStr(lib, "main")); @@ -4214,33 +4410,38 @@ TEST_CASE(IsolateReload_ExistingStaticFieldChangesTypeIndirect) { } TEST_CASE(IsolateReload_ExistingFieldChangesTypeIndirectGeneric) { - const char* kScript = R"( + const bool null_safety = (FLAG_null_safety == kNullSafetyOptionStrong); + const char* lateTag = null_safety ? "late" : ""; + // clang-format off + auto kScript = Utils::CStringUniquePtr(OS::SCreate(nullptr, R"( class A {} class B extends A {} class Foo { List x; Foo(this.x); } - Foo value; + %s Foo value; main() { - value = new Foo(new List()); + value = Foo(List.empty()); return 'Okay'; } - )"; + )", lateTag), std::free); + // clang-format on - Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL); + Dart_Handle lib = TestCase::LoadTestScript(kScript.get(), NULL); EXPECT_VALID(lib); EXPECT_STREQ("Okay", SimpleInvokeStr(lib, "main")); // B is no longer a subtype of A. - const char* kReloadScript = R"( + // clang-format off + auto kReloadScript = Utils::CStringUniquePtr(OS::SCreate(nullptr, R"( class A {} class B {} class Foo { List x; Foo(this.x); } - Foo value; + %s Foo value; main() { try { return value.x.toString(); @@ -4248,9 +4449,10 @@ TEST_CASE(IsolateReload_ExistingFieldChangesTypeIndirectGeneric) { return e.toString(); } } - )"; + )", lateTag), std::free); + // clang-format on - lib = TestCase::ReloadTestScript(kReloadScript); + lib = TestCase::ReloadTestScript(kReloadScript.get()); EXPECT_VALID(lib); EXPECT_STREQ( "type 'List' is not a subtype of type 'List' of 'function result'", @@ -4262,7 +4464,7 @@ TEST_CASE(IsolateReload_ExistingStaticFieldChangesTypeIndirectGeneric) { class A {} class B extends A {} List value = init(); - init() => new List(); + init() => List.empty(); main() { return value.toString(); } @@ -4277,7 +4479,7 @@ TEST_CASE(IsolateReload_ExistingStaticFieldChangesTypeIndirectGeneric) { class A {} class B {} List value = init(); - init() => new List(); + init() => List.empty(); main() { try { return value.toString(); @@ -4295,7 +4497,11 @@ TEST_CASE(IsolateReload_ExistingStaticFieldChangesTypeIndirectGeneric) { } TEST_CASE(IsolateReload_ExistingFieldChangesTypeIndirectFunction) { - const char* kScript = R"( + const bool null_safety = (FLAG_null_safety == kNullSafetyOptionStrong); + const char* lateTag = null_safety ? "late" : ""; + + // clang-format off + auto kScript = Utils::CStringUniquePtr(OS::SCreate(nullptr, R"( class A {} class B extends A {} typedef bool Predicate(B b); @@ -4303,19 +4509,21 @@ TEST_CASE(IsolateReload_ExistingFieldChangesTypeIndirectFunction) { Predicate x; Foo(this.x); } - Foo value; + %s Foo value; main() { - value = new Foo((A a) => true); + value = Foo((A a) => true); return 'Okay'; } - )"; + )", lateTag), std::free); + // clang-format on - Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL); + Dart_Handle lib = TestCase::LoadTestScript(kScript.get(), NULL); EXPECT_VALID(lib); EXPECT_STREQ("Okay", SimpleInvokeStr(lib, "main")); // B is no longer a subtype of A. - const char* kReloadScript = R"( + // clang-format off + auto kReloadScript = Utils::CStringUniquePtr(OS::SCreate(nullptr, R"( class A {} class B {} typedef bool Predicate(B b); @@ -4323,7 +4531,7 @@ TEST_CASE(IsolateReload_ExistingFieldChangesTypeIndirectFunction) { Predicate x; Foo(this.x); } - Foo value; + %s Foo value; main() { try { return value.x.toString(); @@ -4331,9 +4539,10 @@ TEST_CASE(IsolateReload_ExistingFieldChangesTypeIndirectFunction) { return e.toString(); } } - )"; + )", lateTag), std::free); + // clang-format on - lib = TestCase::ReloadTestScript(kReloadScript); + lib = TestCase::ReloadTestScript(kReloadScript.get()); EXPECT_VALID(lib); EXPECT_STREQ( "type '(A) => bool' is not a subtype of type '(B) => bool' of 'function " diff --git a/runtime/vm/isolate_test.cc b/runtime/vm/isolate_test.cc index d4dc8f3f96f..10a09c98c33 100644 --- a/runtime/vm/isolate_test.cc +++ b/runtime/vm/isolate_test.cc @@ -28,11 +28,11 @@ TEST_CASE(IsolateSpawn) { // Ignores printed lines. "var _nullPrintClosure = (String line) {};\n" "void entry(message) {}\n" - "int testMain() {\n" + "void testMain() {\n" " Isolate.spawn(entry, null);\n" // TODO(floitsch): the following code is only to bump the event loop // so it executes asynchronous microtasks. - " var rp = new RawReceivePort();\n" + " var rp = RawReceivePort();\n" " rp.sendPort.send(null);\n" " rp.handler = (_) { rp.close(); };\n" "}\n"; diff --git a/runtime/vm/object_test.cc b/runtime/vm/object_test.cc index 210d32c32d6..d09eace83de 100644 --- a/runtime/vm/object_test.cc +++ b/runtime/vm/object_test.cc @@ -1814,8 +1814,8 @@ static void TestIllegalArrayLength(intptr_t length) { char buffer[1024]; Utils::SNPrint(buffer, sizeof(buffer), "main() {\n" - " new List(%" Pd - ");\n" + " List.filled(%" Pd + ", null);\n" "}\n", length); Dart_Handle lib = TestCase::LoadTestScript(buffer, NULL); @@ -1843,8 +1843,8 @@ TEST_CASE(ArrayLengthOneTooMany) { char buffer[1024]; Utils::SNPrint(buffer, sizeof(buffer), "main() {\n" - " return new List(%" Pd - ");\n" + " return List.filled(%" Pd + ", null);\n" "}\n", kOneTooMany); Dart_Handle lib = TestCase::LoadTestScript(buffer, NULL); @@ -1857,8 +1857,8 @@ TEST_CASE(ArrayLengthMaxElements) { char buffer[1024]; Utils::SNPrint(buffer, sizeof(buffer), "main() {\n" - " return new List(%" Pd - ");\n" + " return List.filled(%" Pd + ", null);\n" "}\n", Array::kMaxElements); Dart_Handle lib = TestCase::LoadTestScript(buffer, NULL); @@ -3748,39 +3748,45 @@ static void PrintMetadata(const char* name, const Object& data) { } TEST_CASE(Metadata) { - const char* kScriptChars = - "@metafoo \n" - "class Meta { \n" - " final m; \n" - " const Meta(this.m); \n" - "} \n" - " \n" - "const metafoo = 'metafoo'; \n" - "const metabar = 'meta' 'bar'; \n" - " \n" - "@metafoo \n" - "@Meta(0) String gVar; \n" - " \n" - "@metafoo \n" - "get tlGetter => gVar; \n" - " \n" - "@metabar \n" - "class A { \n" - " @metafoo \n" - " @metabar \n" - " @Meta('baz') \n" - " var aField; \n" - " \n" - " @metabar @Meta('baa') \n" - " int aFunc(a,b) => a + b; \n" - "} \n" - " \n" - "@Meta('main') \n" - "A main() { \n" - " return new A(); \n" - "} \n"; + bool nullSafety = (FLAG_null_safety == kNullSafetyOptionStrong); + const char* nullableTag = nullSafety ? "?" : ""; + // clang-format off + auto kScriptChars = + Utils::CStringUniquePtr(OS::SCreate(nullptr, + "@metafoo \n" + "class Meta { \n" + " final m; \n" + " const Meta(this.m); \n" + "} \n" + " \n" + "const metafoo = 'metafoo'; \n" + "const metabar = 'meta' 'bar'; \n" + " \n" + "@metafoo \n" + "@Meta(0) String%s gVar; \n" + " \n" + "@metafoo \n" + "get tlGetter => gVar; \n" + " \n" + "@metabar \n" + "class A { \n" + " @metafoo \n" + " @metabar \n" + " @Meta('baz') \n" + " var aField; \n" + " \n" + " @metabar @Meta('baa') \n" + " int aFunc(a,b) => a + b; \n" + "} \n" + " \n" + "@Meta('main') \n" + "A main() { \n" + " return A(); \n" + "} \n", + nullableTag), std::free); + // clang-format on - Dart_Handle h_lib = TestCase::LoadTestScript(kScriptChars, NULL); + Dart_Handle h_lib = TestCase::LoadTestScript(kScriptChars.get(), NULL); EXPECT_VALID(h_lib); Dart_Handle result = Dart_Invoke(h_lib, NewString("main"), 0, NULL); EXPECT_VALID(result); @@ -4412,8 +4418,8 @@ TEST_CASE(LinkedHashMap) { const char* kScript = "import 'dart:collection';\n" "makeMap() {\n" - " Function eq = (a, b) => true;\n" - " Function hc = (a) => 42;\n" + " bool Function(dynamic, dynamic) eq = (a, b) => true;\n" + " int Function(dynamic) hc = (a) => 42;\n" " return new LinkedHashMap(equals: eq, hashCode: hc);\n" "}"; Dart_Handle h_lib = TestCase::LoadTestScript(kScript, NULL); diff --git a/runtime/vm/profiler_test.cc b/runtime/vm/profiler_test.cc index 62167d580e0..211367b592e 100644 --- a/runtime/vm/profiler_test.cc +++ b/runtime/vm/profiler_test.cc @@ -936,8 +936,8 @@ ISOLATE_UNIT_TEST_CASE(Profiler_ArrayAllocation) { DisableNativeProfileScope dnps; DisableBackgroundCompilationScope dbcs; const char* kScript = - "List foo() => new List(4);\n" - "List bar() => new List();\n"; + "List foo() => List.filled(4, null);\n" + "List bar() => List.empty(growable: true);\n"; const Library& root_library = Library::Handle(LoadTestScript(kScript)); Isolate* isolate = thread->isolate(); @@ -2437,20 +2437,20 @@ static uword FindPCForTokenPosition(const Code& code, TokenPosition tp) { ISOLATE_UNIT_TEST_CASE(Profiler_GetSourceReport) { EnableProfiler(); const char* kScript = - "doWork(i) => i * i;\n" - "main() {\n" - " var sum = 0;\n" - " for (var i = 0; i < 100; i++) {\n" + "int doWork(i) => i * i;\n" + "int main() {\n" + " int sum = 0;\n" + " for (int i = 0; i < 100; i++) {\n" " sum += doWork(i);\n" " }\n" " return sum;\n" "}\n"; // Token position of * in `i * i`. - const TokenPosition squarePosition = TokenPosition(15); + const TokenPosition squarePosition = TokenPosition(19); // Token position of the call to `doWork`. - const TokenPosition callPosition = TokenPosition(90); + const TokenPosition callPosition = TokenPosition(95); DisableNativeProfileScope dnps; // Disable profiling for this thread. @@ -2542,14 +2542,14 @@ ISOLATE_UNIT_TEST_CASE(Profiler_GetSourceReport) { } // Verify positions in do_work. - EXPECT_SUBSTRING("\"positions\":[\"ControlFlow\",15]", js.ToCString()); + EXPECT_SUBSTRING("\"positions\":[\"ControlFlow\",19]", js.ToCString()); // Verify exclusive ticks in do_work. EXPECT_SUBSTRING("\"exclusiveTicks\":[1,2]", js.ToCString()); // Verify inclusive ticks in do_work. EXPECT_SUBSTRING("\"inclusiveTicks\":[1,2]", js.ToCString()); // Verify positions in main. - EXPECT_SUBSTRING("\"positions\":[90]", js.ToCString()); + EXPECT_SUBSTRING("\"positions\":[95]", js.ToCString()); // Verify exclusive ticks in main. EXPECT_SUBSTRING("\"exclusiveTicks\":[0]", js.ToCString()); // Verify inclusive ticks in main. diff --git a/runtime/vm/snapshot_test.cc b/runtime/vm/snapshot_test.cc index 4be78c668e9..44a52c10c40 100644 --- a/runtime/vm/snapshot_test.cc +++ b/runtime/vm/snapshot_test.cc @@ -699,29 +699,37 @@ ISOLATE_UNIT_TEST_CASE(SerializeEmptyByteArray) { } VM_UNIT_TEST_CASE(FullSnapshot) { - const char* kScriptChars = - "class Fields {\n" - " Fields(int i, int j) : fld1 = i, fld2 = j {}\n" - " int fld1;\n" - " final int fld2;\n" - " final int bigint_fld = 0xfffffffffff;\n" - " static int fld3;\n" - " static const int smi_sfld = 10;\n" - " static const int bigint_sfld = 0xfffffffffff;\n" - "}\n" - "class Expect {\n" - " static void equals(x, y) {\n" - " if (x != y) throw new ArgumentError('not equal');\n" - " }\n" - "}\n" - "class FieldsTest {\n" - " static Fields testMain() {\n" - " Expect.equals(true, Fields.bigint_sfld == 0xfffffffffff);\n" - " Fields obj = new Fields(10, 20);\n" - " Expect.equals(true, obj.bigint_fld == 0xfffffffffff);\n" - " return obj;\n" - " }\n" - "}\n"; + bool nullSafety = (FLAG_null_safety == kNullSafetyOptionStrong); + const char* nullableTag = nullSafety ? "?" : ""; + // clang-format off + auto kScriptChars = Utils::CStringUniquePtr( + OS::SCreate( + nullptr, + "class Fields {\n" + " Fields(int i, int j) : fld1 = i, fld2 = j {}\n" + " int fld1;\n" + " final int fld2;\n" + " final int bigint_fld = 0xfffffffffff;\n" + " static int%s fld3;\n" + " static const int smi_sfld = 10;\n" + " static const int bigint_sfld = 0xfffffffffff;\n" + "}\n" + "class Expect {\n" + " static void equals(x, y) {\n" + " if (x != y) throw new ArgumentError('not equal');\n" + " }\n" + "}\n" + "class FieldsTest {\n" + " static Fields testMain() {\n" + " Expect.equals(true, Fields.bigint_sfld == 0xfffffffffff);\n" + " Fields obj = new Fields(10, 20);\n" + " Expect.equals(true, obj.bigint_fld == 0xfffffffffff);\n" + " return obj;\n" + " }\n" + "}\n", + nullableTag), + std::free); + // clang-format on Dart_Handle result; uint8_t* isolate_snapshot_data_buffer; @@ -733,7 +741,7 @@ VM_UNIT_TEST_CASE(FullSnapshot) { TestIsolateScope __test_isolate__; // Create a test library and Load up a test script in it. - TestCase::LoadTestScript(kScriptChars, NULL); + TestCase::LoadTestScript(kScriptChars.get(), NULL); Thread* thread = Thread::Current(); TransitionNativeToVM transition(thread); @@ -848,19 +856,19 @@ VM_UNIT_TEST_CASE(DartGeneratedMessages) { " return \"\\u{10000}\\u{1F601}\\u{1F637}\\u{20000}\";\n" "}\n" "getLeadSurrogateString() {\n" - " return new String.fromCharCodes([0xd800]);\n" + " return String.fromCharCodes([0xd800]);\n" "}\n" "getTrailSurrogateString() {\n" " return \"\\u{10000}\".substring(1);\n" "}\n" "getSurrogatesString() {\n" - " return new String.fromCharCodes([0xdc00, 0xdc00, 0xd800, 0xd800]);\n" + " return String.fromCharCodes([0xdc00, 0xdc00, 0xd800, 0xd800]);\n" "}\n" "getCrappyString() {\n" - " return new String.fromCharCodes([0xd800, 32, 0xdc00, 32]);\n" + " return String.fromCharCodes([0xd800, 32, 0xdc00, 32]);\n" "}\n" "getList() {\n" - " return new List(kArrayLength);\n" + " return List.filled(kArrayLength, null);\n" "}\n"; TestCase::CreateTestIsolate(); @@ -959,20 +967,20 @@ VM_UNIT_TEST_CASE(DartGeneratedListMessages) { static const char* kScriptChars = "final int kArrayLength = 10;\n" "getList() {\n" - " return new List(kArrayLength);\n" + " return List.filled(kArrayLength, null);\n" "}\n" "getIntList() {\n" - " var list = new List(kArrayLength);\n" + " var list = List.filled(kArrayLength, 0);\n" " for (var i = 0; i < kArrayLength; i++) list[i] = i;\n" " return list;\n" "}\n" "getStringList() {\n" - " var list = new List(kArrayLength);\n" + " var list = List.filled(kArrayLength, '');\n" " for (var i = 0; i < kArrayLength; i++) list[i] = i.toString();\n" " return list;\n" "}\n" "getMixedList() {\n" - " var list = new List(kArrayLength);\n" + " var list = List.filled(kArrayLength, null);\n" " list[0] = 0;\n" " list[1] = '1';\n" " list[2] = 2.2;\n" @@ -1291,46 +1299,46 @@ VM_UNIT_TEST_CASE(DartGeneratedListMessagesWithBackref) { "final int kArrayLength = 10;\n" "getStringList() {\n" " var s = 'Hello, world!';\n" - " var list = new List(kArrayLength);\n" + " var list = List.filled(kArrayLength, '');\n" " for (var i = 0; i < kArrayLength; i++) list[i] = s;\n" " return list;\n" "}\n" "getMintList() {\n" " var mint = 0x7FFFFFFFFFFFFFFF;\n" - " var list = new List(kArrayLength);\n" + " var list = List.filled(kArrayLength, 0);\n" " for (var i = 0; i < kArrayLength; i++) list[i] = mint;\n" " return list;\n" "}\n" "getDoubleList() {\n" " var d = 3.14;\n" - " var list = new List(kArrayLength);\n" + " var list = List.filled(kArrayLength, 0.0);\n" " for (var i = 0; i < kArrayLength; i++) list[i] = d;\n" " return list;\n" "}\n" "getTypedDataList() {\n" - " var byte_array = new Uint8List(256);\n" - " var list = new List(kArrayLength);\n" + " var byte_array = Uint8List(256);\n" + " var list = List.filled(kArrayLength, null);\n" " for (var i = 0; i < kArrayLength; i++) list[i] = byte_array;\n" " return list;\n" "}\n" "getTypedDataViewList() {\n" - " var uint8_list = new Uint8List(256);\n" + " var uint8_list = Uint8List(256);\n" " uint8_list[64] = 1;\n" " var uint8_list_view =\n" - " new Uint8List.view(uint8_list.buffer, 64, 128);\n" - " var list = new List(kArrayLength);\n" + " Uint8List.view(uint8_list.buffer, 64, 128);\n" + " var list = List.filled(kArrayLength, null);\n" " for (var i = 0; i < kArrayLength; i++) list[i] = uint8_list_view;\n" " return list;\n" "}\n" "getMixedList() {\n" - " var list = new List(kArrayLength);\n" + " var list = List.filled(kArrayLength, null);\n" " for (var i = 0; i < kArrayLength; i++) {\n" " list[i] = ((i % 2) == 0) ? 'A' : 2.72;\n" " }\n" " return list;\n" "}\n" "getSelfRefList() {\n" - " var list = new List(kArrayLength);\n" + " var list = List.filled(kArrayLength, null, growable: true);\n" " for (var i = 0; i < kArrayLength; i++) {\n" " list[i] = list;\n" " }\n" @@ -1697,71 +1705,71 @@ VM_UNIT_TEST_CASE(DartGeneratedListMessagesWithTypedData) { static const char* kScriptChars = "import 'dart:typed_data';\n" "getTypedDataList() {\n" - " var list = new List(10);\n" + " var list = List.filled(10, null);\n" " var index = 0;\n" - " list[index++] = new Int8List(256);\n" - " list[index++] = new Uint8List(256);\n" - " list[index++] = new Int16List(256);\n" - " list[index++] = new Uint16List(256);\n" - " list[index++] = new Int32List(256);\n" - " list[index++] = new Uint32List(256);\n" - " list[index++] = new Int64List(256);\n" - " list[index++] = new Uint64List(256);\n" - " list[index++] = new Float32List(256);\n" - " list[index++] = new Float64List(256);\n" + " list[index++] = Int8List(256);\n" + " list[index++] = Uint8List(256);\n" + " list[index++] = Int16List(256);\n" + " list[index++] = Uint16List(256);\n" + " list[index++] = Int32List(256);\n" + " list[index++] = Uint32List(256);\n" + " list[index++] = Int64List(256);\n" + " list[index++] = Uint64List(256);\n" + " list[index++] = Float32List(256);\n" + " list[index++] = Float64List(256);\n" " return list;\n" "}\n" "getTypedDataViewList() {\n" - " var list = new List(30);\n" + " var list = List.filled(30, null);\n" " var index = 0;\n" - " list[index++] = new Int8List.view(new Int8List(256).buffer);\n" - " list[index++] = new Uint8List.view(new Uint8List(256).buffer);\n" - " list[index++] = new Int16List.view(new Int16List(256).buffer);\n" - " list[index++] = new Uint16List.view(new Uint16List(256).buffer);\n" - " list[index++] = new Int32List.view(new Int32List(256).buffer);\n" - " list[index++] = new Uint32List.view(new Uint32List(256).buffer);\n" - " list[index++] = new Int64List.view(new Int64List(256).buffer);\n" - " list[index++] = new Uint64List.view(new Uint64List(256).buffer);\n" - " list[index++] = new Float32List.view(new Float32List(256).buffer);\n" - " list[index++] = new Float64List.view(new Float64List(256).buffer);\n" + " list[index++] = Int8List.view(Int8List(256).buffer);\n" + " list[index++] = Uint8List.view(Uint8List(256).buffer);\n" + " list[index++] = Int16List.view(new Int16List(256).buffer);\n" + " list[index++] = Uint16List.view(new Uint16List(256).buffer);\n" + " list[index++] = Int32List.view(new Int32List(256).buffer);\n" + " list[index++] = Uint32List.view(new Uint32List(256).buffer);\n" + " list[index++] = Int64List.view(new Int64List(256).buffer);\n" + " list[index++] = Uint64List.view(new Uint64List(256).buffer);\n" + " list[index++] = Float32List.view(new Float32List(256).buffer);\n" + " list[index++] = Float64List.view(new Float64List(256).buffer);\n" - " list[index++] = new Int8List.view(new Int16List(256).buffer);\n" - " list[index++] = new Uint8List.view(new Uint16List(256).buffer);\n" - " list[index++] = new Int8List.view(new Int32List(256).buffer);\n" - " list[index++] = new Uint8List.view(new Uint32List(256).buffer);\n" - " list[index++] = new Int8List.view(new Int64List(256).buffer);\n" - " list[index++] = new Uint8List.view(new Uint64List(256).buffer);\n" - " list[index++] = new Int8List.view(new Float32List(256).buffer);\n" - " list[index++] = new Uint8List.view(new Float32List(256).buffer);\n" - " list[index++] = new Int8List.view(new Float64List(256).buffer);\n" - " list[index++] = new Uint8List.view(new Float64List(256).buffer);\n" + " list[index++] = Int8List.view(new Int16List(256).buffer);\n" + " list[index++] = Uint8List.view(new Uint16List(256).buffer);\n" + " list[index++] = Int8List.view(new Int32List(256).buffer);\n" + " list[index++] = Uint8List.view(new Uint32List(256).buffer);\n" + " list[index++] = Int8List.view(new Int64List(256).buffer);\n" + " list[index++] = Uint8List.view(new Uint64List(256).buffer);\n" + " list[index++] = Int8List.view(new Float32List(256).buffer);\n" + " list[index++] = Uint8List.view(new Float32List(256).buffer);\n" + " list[index++] = Int8List.view(new Float64List(256).buffer);\n" + " list[index++] = Uint8List.view(new Float64List(256).buffer);\n" - " list[index++] = new Int16List.view(new Int8List(256).buffer);\n" - " list[index++] = new Uint16List.view(new Uint8List(256).buffer);\n" - " list[index++] = new Int16List.view(new Int32List(256).buffer);\n" - " list[index++] = new Uint16List.view(new Uint32List(256).buffer);\n" - " list[index++] = new Int16List.view(new Int64List(256).buffer);\n" - " list[index++] = new Uint16List.view(new Uint64List(256).buffer);\n" - " list[index++] = new Int16List.view(new Float32List(256).buffer);\n" - " list[index++] = new Uint16List.view(new Float32List(256).buffer);\n" - " list[index++] = new Int16List.view(new Float64List(256).buffer);\n" - " list[index++] = new Uint16List.view(new Float64List(256).buffer);\n" + " list[index++] = Int16List.view(new Int8List(256).buffer);\n" + " list[index++] = Uint16List.view(new Uint8List(256).buffer);\n" + " list[index++] = Int16List.view(new Int32List(256).buffer);\n" + " list[index++] = Uint16List.view(new Uint32List(256).buffer);\n" + " list[index++] = Int16List.view(new Int64List(256).buffer);\n" + " list[index++] = Uint16List.view(new Uint64List(256).buffer);\n" + " list[index++] = Int16List.view(new Float32List(256).buffer);\n" + " list[index++] = Uint16List.view(new Float32List(256).buffer);\n" + " list[index++] = Int16List.view(new Float64List(256).buffer);\n" + " list[index++] = Uint16List.view(new Float64List(256).buffer);\n" " return list;\n" "}\n" "getMultipleTypedDataViewList() {\n" - " var list = new List(10);\n" + " var list = List.filled(10, null);\n" " var index = 0;\n" - " var data = new Uint8List(256).buffer;\n" - " list[index++] = new Int8List.view(data);\n" - " list[index++] = new Uint8List.view(data);\n" - " list[index++] = new Int16List.view(data);\n" - " list[index++] = new Uint16List.view(data);\n" - " list[index++] = new Int32List.view(data);\n" - " list[index++] = new Uint32List.view(data);\n" - " list[index++] = new Int64List.view(data);\n" - " list[index++] = new Uint64List.view(data);\n" - " list[index++] = new Float32List.view(data);\n" - " list[index++] = new Float64List.view(data);\n" + " var data = Uint8List(256).buffer;\n" + " list[index++] = Int8List.view(data);\n" + " list[index++] = Uint8List.view(data);\n" + " list[index++] = Int16List.view(data);\n" + " list[index++] = Uint16List.view(data);\n" + " list[index++] = Int32List.view(data);\n" + " list[index++] = Uint32List.view(data);\n" + " list[index++] = Int64List.view(data);\n" + " list[index++] = Uint64List.view(data);\n" + " list[index++] = Float32List.view(data);\n" + " list[index++] = Float64List.view(data);\n" " return list;\n" "}\n"; diff --git a/runtime/vm/stack_frame_test.cc b/runtime/vm/stack_frame_test.cc index 15800b7e3e5..4b474f56eff 100644 --- a/runtime/vm/stack_frame_test.cc +++ b/runtime/vm/stack_frame_test.cc @@ -159,86 +159,97 @@ static Dart_NativeFunction native_lookup(Dart_Handle name, // Unit test case to verify stack frame iteration. TEST_CASE(ValidateStackFrameIteration) { - const char* kScriptChars = - "class StackFrame {" - " static equals(var obj1, var obj2) native \"StackFrame_equals\";" - " static int frameCount() native \"StackFrame_frameCount\";" - " static int dartFrameCount() native \"StackFrame_dartFrameCount\";" - " static validateFrame(int index," - " String name) native \"StackFrame_validateFrame\";" - "} " - "class First {" - " First() { }" - " int method1(int param) {" - " if (param == 1) {" - " param = method2(200);" - " } else {" - " param = method2(100);" - " }" - " }" - " int method2(int param) {" - " if (param == 200) {" - " First.staticmethod(this, param);" - " } else {" - " First.staticmethod(this, 10);" - " }" - " }" - " static int staticmethod(First obj, int param) {" - " if (param == 10) {" - " obj.method3(10);" - " } else {" - " obj.method3(200);" - " }" - " }" - " method3(int param) {" - " StackFrame.equals(9, StackFrame.frameCount());" - " StackFrame.equals(7, StackFrame.dartFrameCount());" - " StackFrame.validateFrame(0, \"StackFrame_validateFrame\");" - " StackFrame.validateFrame(1, \"First_method3\");" - " StackFrame.validateFrame(2, \"First_staticmethod\");" - " StackFrame.validateFrame(3, \"First_method2\");" - " StackFrame.validateFrame(4, \"First_method1\");" - " StackFrame.validateFrame(5, \"Second_method1\");" - " StackFrame.validateFrame(6, \"StackFrameTest_testMain\");" - " }" - "}" - "class Second {" - " Second() { }" - " int method1(int param) {" - " if (param == 1) {" - " param = method2(200);" - " } else {" - " First obj = new First();" - " param = obj.method1(1);" - " param = obj.method1(2);" - " }" - " }" - " int method2(int param) {" - " Second.staticmethod(this, param);" - " }" - " static int staticmethod(Second obj, int param) {" - " obj.method3(10);" - " }" - " method3(int param) {" - " StackFrame.equals(8, StackFrame.frameCount());" - " StackFrame.equals(6, StackFrame.dartFrameCount());" - " StackFrame.validateFrame(0, \"StackFrame_validateFrame\");" - " StackFrame.validateFrame(1, \"Second_method3\");" - " StackFrame.validateFrame(2, \"Second_staticmethod\");" - " StackFrame.validateFrame(3, \"Second_method2\");" - " StackFrame.validateFrame(4, \"Second_method1\");" - " StackFrame.validateFrame(5, \"StackFrameTest_testMain\");" - " }" - "}" - "class StackFrameTest {" - " static testMain() {" - " Second obj = new Second();" - " obj.method1(1);" - " obj.method1(2);" - " }" - "}"; + bool nullSafety = (FLAG_null_safety == kNullSafetyOptionStrong); + const char* nullableTag = nullSafety ? "?" : ""; + // clang-format off + auto kScriptChars = Utils::CStringUniquePtr( + OS::SCreate( + nullptr, + "class StackFrame {" + " static equals(var obj1, var obj2) native \"StackFrame_equals\";" + " static int frameCount() native \"StackFrame_frameCount\";" + " static int dartFrameCount() native \"StackFrame_dartFrameCount\";" + " static validateFrame(int index," + " String name) native " + "\"StackFrame_validateFrame\";" + "} " + "class First {" + " First() { }" + " int%s method1(int%s param) {" + " if (param == 1) {" + " param = method2(200);" + " } else {" + " param = method2(100);" + " }" + " }" + " int%s method2(int param) {" + " if (param == 200) {" + " First.staticmethod(this, param);" + " } else {" + " First.staticmethod(this, 10);" + " }" + " }" + " static int%s staticmethod(First obj, int param) {" + " if (param == 10) {" + " obj.method3(10);" + " } else {" + " obj.method3(200);" + " }" + " }" + " method3(int param) {" + " StackFrame.equals(9, StackFrame.frameCount());" + " StackFrame.equals(7, StackFrame.dartFrameCount());" + " StackFrame.validateFrame(0, \"StackFrame_validateFrame\");" + " StackFrame.validateFrame(1, \"First_method3\");" + " StackFrame.validateFrame(2, \"First_staticmethod\");" + " StackFrame.validateFrame(3, \"First_method2\");" + " StackFrame.validateFrame(4, \"First_method1\");" + " StackFrame.validateFrame(5, \"Second_method1\");" + " StackFrame.validateFrame(6, \"StackFrameTest_testMain\");" + " }" + "}" + "class Second {" + " Second() { }" + " int%s method1(int%s param) {" + " if (param == 1) {" + " param = method2(200);" + " } else {" + " First obj = new First();" + " param = obj.method1(1);" + " param = obj.method1(2);" + " }" + " }" + " int%s method2(int param) {" + " Second.staticmethod(this, param);" + " }" + " static int%s staticmethod(Second obj, int param) {" + " obj.method3(10);" + " }" + " method3(int param) {" + " StackFrame.equals(8, StackFrame.frameCount());" + " StackFrame.equals(6, StackFrame.dartFrameCount());" + " StackFrame.validateFrame(0, \"StackFrame_validateFrame\");" + " StackFrame.validateFrame(1, \"Second_method3\");" + " StackFrame.validateFrame(2, \"Second_staticmethod\");" + " StackFrame.validateFrame(3, \"Second_method2\");" + " StackFrame.validateFrame(4, \"Second_method1\");" + " StackFrame.validateFrame(5, \"StackFrameTest_testMain\");" + " }" + "}" + "class StackFrameTest {" + " static testMain() {" + " Second obj = new Second();" + " obj.method1(1);" + " obj.method1(2);" + " }" + "}", + nullableTag, nullableTag, nullableTag, nullableTag, nullableTag, + nullableTag, nullableTag, nullableTag), + std::free); + // clang-format on Dart_Handle lib = TestCase::LoadTestScript( - kScriptChars, reinterpret_cast(native_lookup)); + kScriptChars.get(), + reinterpret_cast(native_lookup)); Dart_Handle cls = Dart_GetClass(lib, NewString("StackFrameTest")); EXPECT_VALID(Dart_Invoke(cls, NewString("testMain"), 0, NULL)); } diff --git a/sdk/lib/core/string.dart b/sdk/lib/core/string.dart index de44234a544..b5b010a6ba4 100644 --- a/sdk/lib/core/string.dart +++ b/sdk/lib/core/string.dart @@ -99,6 +99,7 @@ part of dart.core; * for String examples and recipes. * * [Dart Up and Running](https://www.dartlang.org/docs/dart-up-and-running/ch03.html#strings-and-regular-expressions) */ +@pragma('vm:entry-point') abstract class String implements Comparable, Pattern { /** * Allocates a new String for the specified [charCodes]. diff --git a/sdk_nnbd/lib/core/string.dart b/sdk_nnbd/lib/core/string.dart index c9cc8476b09..b7bba3886f7 100644 --- a/sdk_nnbd/lib/core/string.dart +++ b/sdk_nnbd/lib/core/string.dart @@ -97,6 +97,7 @@ part of dart.core; * for String examples and recipes. * * [Dart Up and Running](https://www.dartlang.org/docs/dart-up-and-running/ch03.html#strings-and-regular-expressions) */ +@pragma('vm:entry-point') abstract class String implements Comparable, Pattern { /** * Allocates a new String for the specified [charCodes].