Skip to content

Commit 06f86bf

Browse files
bkonyicommit-bot@chromium.org
authored andcommitted
[ VM ] Added nullability aware Type methods in embedding API
Added the following methods to the VM embedding API: * Dart_GetNonNullableType * Dart_GetNullableType * Dart_TypeToNonNullable * Dart_TypeToNullable * Dart_IsLegacyType * Dart_IsNonNullableType * Dart_IsNullableType Change-Id: I7de1a99179c4d16a0e6a040bb209de18db379436 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/135484 Reviewed-by: Ryan Macnak <[email protected]> Commit-Queue: Ben Konyi <[email protected]>
1 parent 0c5b98b commit 06f86bf

File tree

4 files changed

+379
-46
lines changed

4 files changed

+379
-46
lines changed

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,14 @@ used (see Issue [39627][]).
3333

3434
* Added `Dart_TypeDynamic`, `Dart_TypeVoid` and `Dart_TypeNever`. Type dynamic
3535
can no longer by reached by `Dart_GetType(dart:core, dynamic)`.
36+
* Added the following methods to the VM embedding API:
37+
* `Dart_GetNonNullableType`
38+
* `Dart_GetNullableType`
39+
* `Dart_TypeToNonNullable`
40+
* `Dart_TypeToNullable`
41+
* `Dart_IsLegacyType`
42+
* `Dart_IsNonNullableType`
43+
* `Dart_IsNullableType`
3644

3745
### Tools
3846

runtime/include/dart_api.h

Lines changed: 74 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3046,7 +3046,8 @@ DART_EXPORT Dart_Handle Dart_RootLibrary();
30463046
DART_EXPORT Dart_Handle Dart_SetRootLibrary(Dart_Handle library);
30473047

30483048
/**
3049-
* Lookup or instantiate a type by name and type arguments from a Library.
3049+
* Lookup or instantiate a legacy type by name and type arguments from a
3050+
* Library.
30503051
*
30513052
* \param library The library containing the class or interface.
30523053
* \param class_name The class name for the type.
@@ -3063,6 +3064,78 @@ DART_EXPORT Dart_Handle Dart_GetType(Dart_Handle library,
30633064
intptr_t number_of_type_arguments,
30643065
Dart_Handle* type_arguments);
30653066

3067+
/**
3068+
* Lookup or instantiate a nullable type by name and type arguments from
3069+
* Library.
3070+
*
3071+
* \param library The library containing the class or interface.
3072+
* \param class_name The class name for the type.
3073+
* \param number_of_type_arguments Number of type arguments.
3074+
* For non parametric types the number of type arguments would be 0.
3075+
* \param type_arguments Pointer to an array of type arguments.
3076+
* For non parameteric types a NULL would be passed in for this argument.
3077+
*
3078+
* \return If no error occurs, the type is returned.
3079+
* Otherwise an error handle is returned.
3080+
*/
3081+
DART_EXPORT Dart_Handle Dart_GetNullableType(Dart_Handle library,
3082+
Dart_Handle class_name,
3083+
intptr_t number_of_type_arguments,
3084+
Dart_Handle* type_arguments);
3085+
3086+
/**
3087+
* Lookup or instantiate a non-nullable type by name and type arguments from
3088+
* Library.
3089+
*
3090+
* \param library The library containing the class or interface.
3091+
* \param class_name The class name for the type.
3092+
* \param number_of_type_arguments Number of type arguments.
3093+
* For non parametric types the number of type arguments would be 0.
3094+
* \param type_arguments Pointer to an array of type arguments.
3095+
* For non parameteric types a NULL would be passed in for this argument.
3096+
*
3097+
* \return If no error occurs, the type is returned.
3098+
* Otherwise an error handle is returned.
3099+
*/
3100+
DART_EXPORT Dart_Handle
3101+
Dart_GetNonNullableType(Dart_Handle library,
3102+
Dart_Handle class_name,
3103+
intptr_t number_of_type_arguments,
3104+
Dart_Handle* type_arguments);
3105+
3106+
/**
3107+
* Creates a nullable version of the provided type.
3108+
*
3109+
* \param type The type to be converted to a nullable type.
3110+
*
3111+
* \return If no error occurs, a nullable type is returned.
3112+
* Otherwise an error handle is returned.
3113+
*/
3114+
DART_EXPORT Dart_Handle Dart_TypeToNullableType(Dart_Handle type);
3115+
3116+
/**
3117+
* Creates a non-nullable version of the provided type.
3118+
*
3119+
* \param type The type to be converted to a non-nullable type.
3120+
*
3121+
* \return If no error occurs, a non-nullable type is returned.
3122+
* Otherwise an error handle is returned.
3123+
*/
3124+
DART_EXPORT Dart_Handle Dart_TypeToNonNullableType(Dart_Handle type);
3125+
3126+
/**
3127+
* A type's nullability.
3128+
*
3129+
* \param type A Dart type.
3130+
* \param result An out parameter containing the result of the check. True if
3131+
* the type is of the specified nullability, false otherwise.
3132+
*
3133+
* \return Returns an error handle if type is not of type Type.
3134+
*/
3135+
DART_EXPORT Dart_Handle Dart_IsNullableType(Dart_Handle type, bool* result);
3136+
DART_EXPORT Dart_Handle Dart_IsNonNullableType(Dart_Handle type, bool* result);
3137+
DART_EXPORT Dart_Handle Dart_IsLegacyType(Dart_Handle type, bool* result);
3138+
30663139
/**
30673140
* Lookup a class or interface by name from a Library.
30683141
*

runtime/vm/dart_api_impl.cc

Lines changed: 114 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -5261,12 +5261,12 @@ DART_EXPORT Dart_Handle Dart_GetClass(Dart_Handle library,
52615261
return Api::NewHandle(T, cls.RareType());
52625262
}
52635263

5264-
DART_EXPORT Dart_Handle Dart_GetType(Dart_Handle library,
5265-
Dart_Handle class_name,
5266-
intptr_t number_of_type_arguments,
5267-
Dart_Handle* type_arguments) {
5264+
static Dart_Handle GetTypeCommon(Dart_Handle library,
5265+
Dart_Handle class_name,
5266+
intptr_t number_of_type_arguments,
5267+
Dart_Handle* type_arguments,
5268+
Nullability nullability) {
52685269
DARTSCOPE(Thread::Current());
5269-
52705270
// Validate the input arguments.
52715271
const Library& lib = Api::UnwrapLibraryHandle(Z, library);
52725272
if (lib.IsNull()) {
@@ -5288,51 +5288,125 @@ DART_EXPORT Dart_Handle Dart_GetType(Dart_Handle library,
52885288
}
52895289
cls.EnsureDeclarationLoaded();
52905290
CHECK_ERROR_HANDLE(cls.VerifyEntryPoint());
5291+
5292+
Type& type = Type::Handle();
52915293
if (cls.NumTypeArguments() == 0) {
52925294
if (number_of_type_arguments != 0) {
52935295
return Api::NewError(
52945296
"Invalid number of type arguments specified, "
52955297
"got %" Pd " expected 0",
52965298
number_of_type_arguments);
52975299
}
5298-
return Api::NewHandle(T, Type::NewNonParameterizedType(cls));
5299-
}
5300-
intptr_t num_expected_type_arguments = cls.NumTypeParameters();
5301-
TypeArguments& type_args_obj = TypeArguments::Handle();
5302-
if (number_of_type_arguments > 0) {
5303-
if (type_arguments == NULL) {
5304-
RETURN_NULL_ERROR(type_arguments);
5305-
}
5306-
if (num_expected_type_arguments != number_of_type_arguments) {
5307-
return Api::NewError(
5308-
"Invalid number of type arguments specified, "
5309-
"got %" Pd " expected %" Pd,
5310-
number_of_type_arguments, num_expected_type_arguments);
5311-
}
5312-
const Array& array = Api::UnwrapArrayHandle(Z, *type_arguments);
5313-
if (array.IsNull()) {
5314-
RETURN_TYPE_ERROR(Z, *type_arguments, Array);
5315-
}
5316-
if (array.Length() != num_expected_type_arguments) {
5317-
return Api::NewError(
5318-
"Invalid type arguments specified, expected an "
5319-
"array of len %" Pd " but got an array of len %" Pd,
5320-
number_of_type_arguments, array.Length());
5321-
}
5322-
// Set up the type arguments array.
5323-
type_args_obj = TypeArguments::New(num_expected_type_arguments);
5324-
AbstractType& type_arg = AbstractType::Handle();
5325-
for (intptr_t i = 0; i < number_of_type_arguments; i++) {
5326-
type_arg ^= array.At(i);
5327-
type_args_obj.SetTypeAt(i, type_arg);
5300+
type ^= Type::NewNonParameterizedType(cls);
5301+
type ^= type.ToNullability(nullability, Heap::kOld);
5302+
} else {
5303+
intptr_t num_expected_type_arguments = cls.NumTypeParameters();
5304+
TypeArguments& type_args_obj = TypeArguments::Handle();
5305+
if (number_of_type_arguments > 0) {
5306+
if (type_arguments == NULL) {
5307+
RETURN_NULL_ERROR(type_arguments);
5308+
}
5309+
if (num_expected_type_arguments != number_of_type_arguments) {
5310+
return Api::NewError(
5311+
"Invalid number of type arguments specified, "
5312+
"got %" Pd " expected %" Pd,
5313+
number_of_type_arguments, num_expected_type_arguments);
5314+
}
5315+
const Array& array = Api::UnwrapArrayHandle(Z, *type_arguments);
5316+
if (array.IsNull()) {
5317+
RETURN_TYPE_ERROR(Z, *type_arguments, Array);
5318+
}
5319+
if (array.Length() != num_expected_type_arguments) {
5320+
return Api::NewError(
5321+
"Invalid type arguments specified, expected an "
5322+
"array of len %" Pd " but got an array of len %" Pd,
5323+
number_of_type_arguments, array.Length());
5324+
}
5325+
// Set up the type arguments array.
5326+
type_args_obj = TypeArguments::New(num_expected_type_arguments);
5327+
AbstractType& type_arg = AbstractType::Handle();
5328+
for (intptr_t i = 0; i < number_of_type_arguments; i++) {
5329+
type_arg ^= array.At(i);
5330+
type_args_obj.SetTypeAt(i, type_arg);
5331+
}
53285332
}
5333+
5334+
// Construct the type object, canonicalize it and return.
5335+
type ^=
5336+
Type::New(cls, type_args_obj, TokenPosition::kNoSource, nullability);
53295337
}
5338+
type ^= ClassFinalizer::FinalizeType(cls, type);
5339+
return Api::NewHandle(T, type.raw());
5340+
}
5341+
5342+
DART_EXPORT Dart_Handle Dart_GetType(Dart_Handle library,
5343+
Dart_Handle class_name,
5344+
intptr_t number_of_type_arguments,
5345+
Dart_Handle* type_arguments) {
5346+
return GetTypeCommon(library, class_name, number_of_type_arguments,
5347+
type_arguments, Nullability::kLegacy);
5348+
}
5349+
5350+
DART_EXPORT Dart_Handle Dart_GetNullableType(Dart_Handle library,
5351+
Dart_Handle class_name,
5352+
intptr_t number_of_type_arguments,
5353+
Dart_Handle* type_arguments) {
5354+
return GetTypeCommon(library, class_name, number_of_type_arguments,
5355+
type_arguments, Nullability::kNullable);
5356+
}
5357+
5358+
DART_EXPORT Dart_Handle
5359+
Dart_GetNonNullableType(Dart_Handle library,
5360+
Dart_Handle class_name,
5361+
intptr_t number_of_type_arguments,
5362+
Dart_Handle* type_arguments) {
5363+
return GetTypeCommon(library, class_name, number_of_type_arguments,
5364+
type_arguments, Nullability::kNonNullable);
5365+
}
5366+
5367+
static Dart_Handle TypeToHelper(Dart_Handle type, Nullability nullability) {
5368+
DARTSCOPE(Thread::Current());
5369+
const Type& ty = Api::UnwrapTypeHandle(Z, type);
5370+
if (ty.IsNull()) {
5371+
RETURN_TYPE_ERROR(Z, type, Type);
5372+
}
5373+
if (ty.nullability() == nullability) {
5374+
return type;
5375+
}
5376+
return Api::NewHandle(T, ty.ToNullability(nullability, Heap::kOld));
5377+
}
5378+
5379+
DART_EXPORT Dart_Handle Dart_TypeToNullableType(Dart_Handle type) {
5380+
return TypeToHelper(type, Nullability::kNullable);
5381+
}
5382+
5383+
DART_EXPORT Dart_Handle Dart_TypeToNonNullableType(Dart_Handle type) {
5384+
return TypeToHelper(type, Nullability::kNonNullable);
5385+
}
5386+
5387+
static Dart_Handle IsOfTypeNullabilityHelper(Dart_Handle type,
5388+
Nullability nullability,
5389+
bool* result) {
5390+
DARTSCOPE(Thread::Current());
5391+
const Type& ty = Api::UnwrapTypeHandle(Z, type);
5392+
if (ty.IsNull()) {
5393+
*result = false;
5394+
RETURN_TYPE_ERROR(Z, type, Type);
5395+
}
5396+
*result = (ty.nullability() == nullability);
5397+
return Api::Success();
5398+
}
5399+
5400+
DART_EXPORT Dart_Handle Dart_IsNullableType(Dart_Handle type, bool* result) {
5401+
return IsOfTypeNullabilityHelper(type, Nullability::kNullable, result);
5402+
}
5403+
5404+
DART_EXPORT Dart_Handle Dart_IsNonNullableType(Dart_Handle type, bool* result) {
5405+
return IsOfTypeNullabilityHelper(type, Nullability::kNonNullable, result);
5406+
}
53305407

5331-
// Construct the type object, canonicalize it and return.
5332-
Type& instantiated_type =
5333-
Type::Handle(Type::New(cls, type_args_obj, TokenPosition::kNoSource));
5334-
instantiated_type ^= ClassFinalizer::FinalizeType(cls, instantiated_type);
5335-
return Api::NewHandle(T, instantiated_type.raw());
5408+
DART_EXPORT Dart_Handle Dart_IsLegacyType(Dart_Handle type, bool* result) {
5409+
return IsOfTypeNullabilityHelper(type, Nullability::kLegacy, result);
53365410
}
53375411

53385412
DART_EXPORT Dart_Handle Dart_LibraryUrl(Dart_Handle library) {

0 commit comments

Comments
 (0)