Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 0 additions & 6 deletions packages/react-native-codegen/src/generators/RNCodegen.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,6 @@

'use strict';

/*
TODO:

- ViewConfigs should spread in View's valid attributes
*/

import type {SchemaType} from '../CodegenSchema';

const schemaValidator = require('../SchemaValidator.js');
Expand Down
155 changes: 155 additions & 0 deletions packages/react-native-codegen/src/generators/ReservedPrimitiveTypes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow strict
* @format
*/

'use strict';

/**
* Single source of truth for the 6 reserved primitive types used in
* React Native component props. Each type maps to its per-language
* representation (C++ type name, C++ includes, Java imports).
*
* Previously these mappings were scattered across CppHelpers.js,
* ComponentsGeneratorUtils.js, and JavaHelpers.js.
*/

export type ReservedPrimitiveName =
| 'ColorPrimitive'
| 'EdgeInsetsPrimitive'
| 'ImageRequestPrimitive'
| 'ImageSourcePrimitive'
| 'PointPrimitive'
| 'DimensionPrimitive';

type CppTypeInfo = {
+typeName: string,
+localIncludes: ReadonlyArray<string>,
+conversionIncludes: ReadonlyArray<string>,
};

type JavaImportInfo = {
+interfaceImports: ReadonlyArray<string>,
+delegateImports: ReadonlyArray<string>,
};

type ReservedTypeMapping = {
+cpp: CppTypeInfo,
+java: JavaImportInfo,
};

const RESERVED_TYPES: {+[ReservedPrimitiveName]: ReservedTypeMapping} = {
ColorPrimitive: {
cpp: {
typeName: 'SharedColor',
localIncludes: ['#include <react/renderer/graphics/Color.h>'],
conversionIncludes: [],
},
java: {
interfaceImports: [],
delegateImports: ['import com.facebook.react.bridge.ColorPropConverter;'],
},
},
ImageSourcePrimitive: {
cpp: {
typeName: 'ImageSource',
localIncludes: ['#include <react/renderer/imagemanager/primitives.h>'],
conversionIncludes: [
'#include <react/renderer/components/image/conversions.h>',
],
},
java: {
interfaceImports: ['import com.facebook.react.bridge.ReadableMap;'],
delegateImports: ['import com.facebook.react.bridge.ReadableMap;'],
},
},
ImageRequestPrimitive: {
cpp: {
typeName: 'ImageRequest',
localIncludes: ['#include <react/renderer/imagemanager/ImageRequest.h>'],
conversionIncludes: [],
},
java: {
// ImageRequestPrimitive is not used in Java component props
interfaceImports: [],
delegateImports: [],
},
},
PointPrimitive: {
cpp: {
typeName: 'Point',
localIncludes: ['#include <react/renderer/graphics/Point.h>'],
conversionIncludes: [],
},
java: {
interfaceImports: ['import com.facebook.react.bridge.ReadableMap;'],
delegateImports: ['import com.facebook.react.bridge.ReadableMap;'],
},
},
EdgeInsetsPrimitive: {
cpp: {
typeName: 'EdgeInsets',
localIncludes: ['#include <react/renderer/graphics/RectangleEdges.h>'],
conversionIncludes: [],
},
java: {
interfaceImports: ['import com.facebook.react.bridge.ReadableMap;'],
delegateImports: ['import com.facebook.react.bridge.ReadableMap;'],
},
},
DimensionPrimitive: {
cpp: {
typeName: 'YGValue',
localIncludes: [
'#include <yoga/Yoga.h>',
'#include <react/renderer/core/graphicsConversions.h>',
],
conversionIncludes: [
'#include <react/renderer/components/view/conversions.h>',
],
},
java: {
interfaceImports: ['import com.facebook.yoga.YogaValue;'],
delegateImports: [
'import com.facebook.react.bridge.DimensionPropConverter;',
],
},
},
};

function getCppTypeForReservedPrimitive(name: ReservedPrimitiveName): string {
return RESERVED_TYPES[name].cpp.typeName;
}

function getCppLocalIncludesForReservedPrimitive(
name: ReservedPrimitiveName,
): ReadonlyArray<string> {
return RESERVED_TYPES[name].cpp.localIncludes;
}

function getCppConversionIncludesForReservedPrimitive(
name: ReservedPrimitiveName,
): ReadonlyArray<string> {
return RESERVED_TYPES[name].cpp.conversionIncludes;
}

function getJavaImportsForReservedPrimitive(
name: ReservedPrimitiveName,
type: 'interface' | 'delegate',
): ReadonlyArray<string> {
const info = RESERVED_TYPES[name].java;
return type === 'interface' ? info.interfaceImports : info.delegateImports;
}

module.exports = {
RESERVED_TYPES,
getCppTypeForReservedPrimitive,
getCppLocalIncludesForReservedPrimitive,
getCppConversionIncludesForReservedPrimitive,
getJavaImportsForReservedPrimitive,
};
13 changes: 11 additions & 2 deletions packages/react-native-codegen/src/generators/Utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,19 @@ function toPascalCase(inString: string): string {
return inString;
}

return inString[0].toUpperCase() + inString.slice(1);
return capitalize(inString);
}

function toSafeIdentifier(input: string, shouldCapitalize: boolean): string {
const parts = input.split('-');
if (!shouldCapitalize) {
return parts.join('');
}
return parts.map(toPascalCase).join('');
}

function toSafeCppString(input: string): string {
return input.split('-').map(toPascalCase).join('');
return toSafeIdentifier(input, true);
}

function getEnumName(moduleName: string, origEnumName: string): string {
Expand Down Expand Up @@ -105,6 +113,7 @@ module.exports = {
indent,
parseValidUnionType,
toPascalCase,
toSafeIdentifier,
toSafeCppString,
getEnumName,
HeterogeneousUnionError,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ import type {
StringTypeAnnotation,
} from '../../CodegenSchema';

const {
getCppLocalIncludesForReservedPrimitive,
getCppTypeForReservedPrimitive,
} = require('../ReservedPrimitiveTypes');
const {getEnumName} = require('../Utils');
const {
generateStructName,
Expand Down Expand Up @@ -66,23 +70,7 @@ function getNativeTypeFromAnnotation(
case 'FloatTypeAnnotation':
return getCppTypeForAnnotation(typeAnnotation.type);
case 'ReservedPropTypeAnnotation':
switch (typeAnnotation.name) {
case 'ColorPrimitive':
return 'SharedColor';
case 'ImageSourcePrimitive':
return 'ImageSource';
case 'ImageRequestPrimitive':
return 'ImageRequest';
case 'PointPrimitive':
return 'Point';
case 'EdgeInsetsPrimitive':
return 'EdgeInsets';
case 'DimensionPrimitive':
return 'YGValue';
default:
(typeAnnotation.name: empty);
throw new Error('Received unknown ReservedPropTypeAnnotation');
}
return getCppTypeForReservedPrimitive(typeAnnotation.name);
case 'ArrayTypeAnnotation': {
const arrayType = typeAnnotation.elementType.type;
if (arrayType === 'ArrayTypeAnnotation') {
Expand Down Expand Up @@ -175,43 +163,25 @@ function convertVariableToPointer(
return value;
}

const convertCtorParamToAddressType = (type: string): string => {
const typesToConvert: Set<string> = new Set();
typesToConvert.add('ImageSource');
// Configuration for C++ type conversions of reserved types.
// Centralizes the knowledge of which types need special pointer/address handling.
const CTOR_PARAM_ADDRESS_TYPES: Set<string> = new Set(['ImageSource']);
const SHARED_POINTER_TYPES: Set<string> = new Set(['ImageRequest']);

return convertTypesToConstAddressIfNeeded(type, typesToConvert);
};
const convertCtorParamToAddressType = (type: string): string =>
convertTypesToConstAddressIfNeeded(type, CTOR_PARAM_ADDRESS_TYPES);

const convertCtorInitToSharedPointers = (
type: string,
value: string,
): string => {
const typesToConvert: Set<string> = new Set();
typesToConvert.add('ImageRequest');
const convertCtorInitToSharedPointers = (type: string, value: string): string =>
convertValueToSharedPointerWithMove(type, value, SHARED_POINTER_TYPES);

return convertValueToSharedPointerWithMove(type, value, typesToConvert);
};
const convertGettersReturnTypeToAddressType = (type: string): string =>
convertTypesToConstAddressIfNeeded(type, SHARED_POINTER_TYPES);

const convertGettersReturnTypeToAddressType = (type: string): string => {
const typesToConvert: Set<string> = new Set();
typesToConvert.add('ImageRequest');
const convertVarTypeToSharedPointer = (type: string): string =>
convertVariableToSharedPointer(type, SHARED_POINTER_TYPES);

return convertTypesToConstAddressIfNeeded(type, typesToConvert);
};

const convertVarTypeToSharedPointer = (type: string): string => {
const typesToConvert: Set<string> = new Set();
typesToConvert.add('ImageRequest');

return convertVariableToSharedPointer(type, typesToConvert);
};

const convertVarValueToPointer = (type: string, value: string): string => {
const typesToConvert: Set<string> = new Set();
typesToConvert.add('ImageRequest');

return convertVariableToPointer(type, value, typesToConvert);
};
const convertVarValueToPointer = (type: string, value: string): string =>
convertVariableToPointer(type, value, SHARED_POINTER_TYPES);

function getLocalImports(
properties: ReadonlyArray<NamedShape<PropTypeAnnotation>>,
Expand All @@ -227,29 +197,8 @@ function getLocalImports(
| 'ImageRequestPrimitive'
| 'DimensionPrimitive',
) {
switch (name) {
case 'ColorPrimitive':
imports.add('#include <react/renderer/graphics/Color.h>');
return;
case 'ImageSourcePrimitive':
imports.add('#include <react/renderer/imagemanager/primitives.h>');
return;
case 'ImageRequestPrimitive':
imports.add('#include <react/renderer/imagemanager/ImageRequest.h>');
return;
case 'PointPrimitive':
imports.add('#include <react/renderer/graphics/Point.h>');
return;
case 'EdgeInsetsPrimitive':
imports.add('#include <react/renderer/graphics/RectangleEdges.h>');
return;
case 'DimensionPrimitive':
imports.add('#include <yoga/Yoga.h>');
imports.add('#include <react/renderer/core/graphicsConversions.h>');
return;
default:
(name: empty);
throw new Error(`Invalid ReservedPropTypeAnnotation name, got ${name}`);
for (const include of getCppLocalIncludesForReservedPrimitive(name)) {
imports.add(include);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ import type {
PropTypeAnnotation,
} from '../../CodegenSchema';

const {
getCppConversionIncludesForReservedPrimitive,
} = require('../ReservedPrimitiveTypes');
const {getEnumName, parseValidUnionType, toSafeCppString} = require('../Utils');

function toIntEnumValueName(propName: string, value: number): string {
Expand Down Expand Up @@ -134,24 +137,8 @@ function getImports(
| 'PointPrimitive'
| 'DimensionPrimitive',
) {
switch (name) {
case 'ColorPrimitive':
return;
case 'PointPrimitive':
return;
case 'EdgeInsetsPrimitive':
return;
case 'ImageRequestPrimitive':
return;
case 'ImageSourcePrimitive':
imports.add('#include <react/renderer/components/image/conversions.h>');
return;
case 'DimensionPrimitive':
imports.add('#include <react/renderer/components/view/conversions.h>');
return;
default:
(name: empty);
throw new Error(`Invalid name, got ${name}`);
for (const include of getCppConversionIncludesForReservedPrimitive(name)) {
imports.add(include);
}
}

Expand Down
Loading
Loading