Skip to content

Commit 6db3995

Browse files
javachefacebook-github-bot
authored andcommitted
Improve @nullable annotions in Java TurboModule codegen
Summary: Noticed these types could be improved based on the tests added in D40979066 (e81c98c). Changelog: [Android][Fixed] Corrected Nullable annotations for parameters and return values in TurboModules codegen Reviewed By: mdvacca, cipolleschi Differential Revision: D40979940 fbshipit-source-id: cfc352a9e7eb9f59e2cce3d7da110a9a8d32db4b
1 parent 3e44d20 commit 6db3995

File tree

2 files changed

+35
-37
lines changed

2 files changed

+35
-37
lines changed

packages/react-native-codegen/src/generators/modules/GenerateModuleJavaSpec.js

Lines changed: 33 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -104,14 +104,15 @@ function translateFunctionParamToJavaType(
104104
unwrapNullable<NativeModuleParamTypeAnnotation>(nullableTypeAnnotation);
105105
const isRequired = !optional && !nullable;
106106

107-
function wrapIntoNullableIfNeeded(generatedType: string) {
107+
function wrapNullable(javaType: string, nullableType?: string) {
108108
if (!isRequired) {
109109
imports.add('javax.annotation.Nullable');
110-
return `@Nullable ${generatedType}`;
110+
return `@Nullable ${nullableType ?? javaType}`;
111111
}
112-
return generatedType;
112+
return javaType;
113113
}
114114

115+
// FIXME: support class alias for args
115116
let realTypeAnnotation = typeAnnotation;
116117
if (realTypeAnnotation.type === 'TypeAliasTypeAnnotation') {
117118
realTypeAnnotation = resolveAlias(realTypeAnnotation.name);
@@ -121,49 +122,45 @@ function translateFunctionParamToJavaType(
121122
case 'ReservedTypeAnnotation':
122123
switch (realTypeAnnotation.name) {
123124
case 'RootTag':
124-
return !isRequired ? 'Double' : 'double';
125+
return wrapNullable('double', 'Double');
125126
default:
126127
(realTypeAnnotation.name: empty);
127128
throw new Error(createErrorMessage(realTypeAnnotation.name));
128129
}
129130
case 'StringTypeAnnotation':
130-
return wrapIntoNullableIfNeeded('String');
131+
return wrapNullable('String');
131132
case 'NumberTypeAnnotation':
132-
return !isRequired ? 'Double' : 'double';
133+
return wrapNullable('double', 'Double');
133134
case 'FloatTypeAnnotation':
134-
return !isRequired ? 'Double' : 'double';
135+
return wrapNullable('double', 'Double');
135136
case 'DoubleTypeAnnotation':
136-
return !isRequired ? 'Double' : 'double';
137+
return wrapNullable('double', 'Double');
137138
case 'Int32TypeAnnotation':
138-
return !isRequired ? 'Double' : 'double';
139+
return wrapNullable('double', 'Double');
139140
case 'BooleanTypeAnnotation':
140-
return !isRequired ? 'Boolean' : 'boolean';
141+
return wrapNullable('boolean', 'Boolean');
141142
case 'EnumDeclaration':
142143
switch (realTypeAnnotation.memberType) {
143144
case 'NumberTypeAnnotation':
144-
return !isRequired ? 'Double' : 'double';
145+
return wrapNullable('double', 'Double');
145146
case 'StringTypeAnnotation':
146-
return wrapIntoNullableIfNeeded('String');
147+
return wrapNullable('String');
147148
default:
148149
throw new Error(createErrorMessage(realTypeAnnotation.type));
149150
}
150151
case 'ObjectTypeAnnotation':
151152
imports.add('com.facebook.react.bridge.ReadableMap');
152-
if (typeAnnotation.type === 'TypeAliasTypeAnnotation') {
153-
// No class alias for args, so it still falls under ReadableMap.
154-
return 'ReadableMap';
155-
}
156-
return 'ReadableMap';
153+
return wrapNullable('ReadableMap');
157154
case 'GenericObjectTypeAnnotation':
158155
// Treat this the same as ObjectTypeAnnotation for now.
159156
imports.add('com.facebook.react.bridge.ReadableMap');
160-
return 'ReadableMap';
157+
return wrapNullable('ReadableMap');
161158
case 'ArrayTypeAnnotation':
162159
imports.add('com.facebook.react.bridge.ReadableArray');
163-
return 'ReadableArray';
160+
return wrapNullable('ReadableArray');
164161
case 'FunctionTypeAnnotation':
165162
imports.add('com.facebook.react.bridge.Callback');
166-
return 'Callback';
163+
return wrapNullable('Callback');
167164
default:
168165
(realTypeAnnotation.type:
169166
| 'EnumDeclaration'
@@ -184,14 +181,15 @@ function translateFunctionReturnTypeToJavaType(
184181
nullableReturnTypeAnnotation,
185182
);
186183

187-
function wrapIntoNullableIfNeeded(generatedType: string) {
184+
function wrapNullable(javaType: string, nullableType?: string) {
188185
if (nullable) {
189186
imports.add('javax.annotation.Nullable');
190-
return `@Nullable ${generatedType}`;
187+
return `@Nullable ${nullableType ?? javaType}`;
191188
}
192-
return generatedType;
189+
return javaType;
193190
}
194191

192+
// FIXME: support class alias for args
195193
let realTypeAnnotation = returnTypeAnnotation;
196194
if (realTypeAnnotation.type === 'TypeAliasTypeAnnotation') {
197195
realTypeAnnotation = resolveAlias(realTypeAnnotation.name);
@@ -201,7 +199,7 @@ function translateFunctionReturnTypeToJavaType(
201199
case 'ReservedTypeAnnotation':
202200
switch (realTypeAnnotation.name) {
203201
case 'RootTag':
204-
return nullable ? 'Double' : 'double';
202+
return wrapNullable('double', 'Double');
205203
default:
206204
(realTypeAnnotation.name: empty);
207205
throw new Error(createErrorMessage(realTypeAnnotation.name));
@@ -211,35 +209,35 @@ function translateFunctionReturnTypeToJavaType(
211209
case 'PromiseTypeAnnotation':
212210
return 'void';
213211
case 'StringTypeAnnotation':
214-
return wrapIntoNullableIfNeeded('String');
212+
return wrapNullable('String');
215213
case 'NumberTypeAnnotation':
216-
return nullable ? 'Double' : 'double';
214+
return wrapNullable('double', 'Double');
217215
case 'FloatTypeAnnotation':
218-
return nullable ? 'Double' : 'double';
216+
return wrapNullable('double', 'Double');
219217
case 'DoubleTypeAnnotation':
220-
return nullable ? 'Double' : 'double';
218+
return wrapNullable('double', 'Double');
221219
case 'Int32TypeAnnotation':
222-
return nullable ? 'Double' : 'double';
220+
return wrapNullable('double', 'Double');
223221
case 'BooleanTypeAnnotation':
224-
return nullable ? 'Boolean' : 'boolean';
222+
return wrapNullable('boolean', 'Boolean');
225223
case 'EnumDeclaration':
226224
switch (realTypeAnnotation.memberType) {
227225
case 'NumberTypeAnnotation':
228-
return nullable ? 'Double' : 'double';
226+
return wrapNullable('double', 'Double');
229227
case 'StringTypeAnnotation':
230-
return wrapIntoNullableIfNeeded('String');
228+
return wrapNullable('String');
231229
default:
232230
throw new Error(createErrorMessage(realTypeAnnotation.type));
233231
}
234232
case 'ObjectTypeAnnotation':
235233
imports.add('com.facebook.react.bridge.WritableMap');
236-
return wrapIntoNullableIfNeeded('WritableMap');
234+
return wrapNullable('WritableMap');
237235
case 'GenericObjectTypeAnnotation':
238236
imports.add('com.facebook.react.bridge.WritableMap');
239-
return wrapIntoNullableIfNeeded('WritableMap');
237+
return wrapNullable('WritableMap');
240238
case 'ArrayTypeAnnotation':
241239
imports.add('com.facebook.react.bridge.WritableArray');
242-
return wrapIntoNullableIfNeeded('WritableArray');
240+
return wrapNullable('WritableArray');
243241
default:
244242
(realTypeAnnotation.type:
245243
| 'EnumDeclaration'

packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateModuleJavaSpec-test.js.snap

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ public abstract class NativeSampleTurboModuleSpec extends ReactContextBaseJavaMo
7878
7979
@ReactMethod
8080
@DoNotStrip
81-
public void optionalMethod(ReadableMap options, Callback callback, ReadableArray extras) {}
81+
public void optionalMethod(ReadableMap options, Callback callback, @Nullable ReadableArray extras) {}
8282
8383
@ReactMethod
8484
@DoNotStrip
@@ -379,7 +379,7 @@ public abstract class NativeSampleTurboModuleSpec extends ReactContextBaseJavaMo
379379
380380
@ReactMethod
381381
@DoNotStrip
382-
public abstract void getValueWithOptionalArg(ReadableMap parameter, Promise promise);
382+
public abstract void getValueWithOptionalArg(@Nullable ReadableMap parameter, Promise promise);
383383
384384
@ReactMethod(isBlockingSynchronousMethod = true)
385385
@DoNotStrip

0 commit comments

Comments
 (0)