Make ObjCPP Generator handle NullableTypeAnnotation

Summary:
See title.
Changelog: [Internal]

Reviewed By: hramos

Differential Revision: D24027243

fbshipit-source-id: 4e03a14fd23c1f5f3d282fc14a760d7549cdd6b9
This commit is contained in:
Ramanpreet Nara authored and Facebook GitHub Bot committed 2020-10-01 19:30:08 -07:00
1 parent 6d7e763e85
commit 5122e33f4e
4 files changed
+92 -57

No files matched your search

@@ -14,6 +14,7 @@ import type {
NativeModuleMethodParamSchema,
NativeModuleReturnTypeAnnotation,
NativeModulePropertySchema,
Nullable,
} from '../../../CodegenSchema';
import type {AliasResolver} from '../Utils';
@@ -21,6 +22,10 @@ import type {AliasResolver} from '../Utils';
const invariant = require('invariant');
const {StructCollector} = require('./StructCollector');
const {capitalize, getNamespacedStructName} = require('./Utils');
const {
wrapNullable,
unwrapNullable,
} = require('../../../parsers/flow/modules/utils');
const ProtocolMethodTemplate = ({
returnObjCType,
@@ -60,10 +65,9 @@ function serializeMethod(
structCollector: StructCollector,
resolveAlias: AliasResolver,
): $ReadOnlyArray<MethodSerializationOutput> {
const {
name: methodName,
typeAnnotation: {params, returnTypeAnnotation},
} = property;
const {name: methodName, typeAnnotation: nullableTypeAnnotation} = property;
const [propertyTypeAnnotation] = unwrapNullable(nullableTypeAnnotation);
const {params} = propertyTypeAnnotation;
if (methodName === 'getConstants') {
return serializeConstantsProtocolMethods(
@@ -95,6 +99,12 @@ function serializeMethod(
}
});
// Unwrap returnTypeAnnotation, so we check if the return type is Promise
// TODO(T76719514): Disallow nullable PromiseTypeAnnotations
const [returnTypeAnnotation] = unwrapNullable(
propertyTypeAnnotation.returnTypeAnnotation,
);
if (returnTypeAnnotation.type === 'PromiseTypeAnnotation') {
methodParams.push(
{paramName: 'resolve', objCType: 'RCTPromiseResolveBlock'},
@@ -105,7 +115,10 @@ function serializeMethod(
/**
* Build Protocol Method
**/
const returnObjCType = getReturnObjCType(methodName, returnTypeAnnotation);
const returnObjCType = getReturnObjCType(
methodName,
propertyTypeAnnotation.returnTypeAnnotation,
);
const paddingMax = `- (${returnObjCType})${methodName}`.length;
const objCParams = methodParams.reduce(
@@ -155,8 +168,9 @@ function getParamStructName(
methodName: string,
param: NativeModuleMethodParamSchema,
): string {
if (param.typeAnnotation.type === 'TypeAliasTypeAnnotation') {
return param.typeAnnotation.name;
const [typeAnnotation] = unwrapNullable(param.typeAnnotation);
if (typeAnnotation.type === 'TypeAliasTypeAnnotation') {
return typeAnnotation.name;
}
return `Spec${capitalize(methodName)}${capitalize(param.name)}`;
@@ -170,13 +184,12 @@ function getParamObjCType(
structCollector: StructCollector,
resolveAlias: AliasResolver,
): $ReadOnly<{|objCType: string, isStruct: boolean|}> {
const {name: paramName, typeAnnotation} = param;
const notRequired = param.optional || typeAnnotation.nullable;
const {name: paramName, typeAnnotation: nullableTypeAnnotation} = param;
const [typeAnnotation, nullable] = unwrapNullable(nullableTypeAnnotation);
const notRequired = param.optional || nullable;
function wrapIntoNullableIfNeeded(generatedType: string) {
return typeAnnotation.nullable
? `${generatedType} _Nullable`
: generatedType;
return nullable ? `${generatedType} _Nullable` : generatedType;
}
const isStruct = (objCType: string) => ({
@@ -209,11 +222,13 @@ function getParamObjCType(
}
}
const structTypeAnnotation = structCollector.process(
structName,
'REGULAR',
resolveAlias,
typeAnnotation,
const [structTypeAnnotation] = unwrapNullable(
structCollector.process(
structName,
'REGULAR',
resolveAlias,
wrapNullable(nullable, typeAnnotation),
),
);
invariant(
@@ -264,12 +279,12 @@ function getParamObjCType(
function getReturnObjCType(
methodName: string,
typeAnnotation: NativeModuleReturnTypeAnnotation,
nullableTypeAnnotation: Nullable<NativeModuleReturnTypeAnnotation>,
) {
const [typeAnnotation, nullable] = unwrapNullable(nullableTypeAnnotation);
function wrapIntoNullableIfNeeded(generatedType: string) {
return typeAnnotation.nullable
? `${generatedType} _Nullable`
: generatedType;
return nullable ? `${generatedType} _Nullable` : generatedType;
}
switch (typeAnnotation.type) {
@@ -328,8 +343,9 @@ function getReturnObjCType(
function getReturnJSType(
methodName: string,
typeAnnotation: NativeModuleReturnTypeAnnotation,
nullableTypeAnnotation: Nullable<NativeModuleReturnTypeAnnotation>,
): ReturnJSType {
const [typeAnnotation] = unwrapNullable(nullableTypeAnnotation);
switch (typeAnnotation.type) {
case 'VoidTypeAnnotation':
return 'VoidKind';
@@ -371,13 +387,14 @@ function serializeConstantsProtocolMethods(
structCollector: StructCollector,
resolveAlias: AliasResolver,
): $ReadOnlyArray<MethodSerializationOutput> {
if (property.typeAnnotation.params.length !== 0) {
const [propertyTypeAnnotation] = unwrapNullable(property.typeAnnotation);
if (propertyTypeAnnotation.params.length !== 0) {
throw new Error(
`${moduleName}.getConstants() may only accept 0 arguments.`,
);
}
const {returnTypeAnnotation} = property.typeAnnotation;
const {returnTypeAnnotation} = propertyTypeAnnotation;
if (returnTypeAnnotation.type !== 'ObjectTypeAnnotation') {
throw new Error(
`${moduleName}.getConstants() may only return an object literal: {|...|}.`,