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
61 changes: 49 additions & 12 deletions packages/react-native-codegen/src/CodegenSchema.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ export interface FloatTypeAnnotation {
readonly type: 'FloatTypeAnnotation';
}

export interface NumberTypeAnnotation {
readonly type: 'NumberTypeAnnotation';
}

export interface BooleanTypeAnnotation {
readonly type: 'BooleanTypeAnnotation';
}
Expand All @@ -42,13 +46,40 @@ export interface VoidTypeAnnotation {
readonly type: 'VoidTypeAnnotation';
}

export interface NumberLiteralTypeAnnotation {
readonly type: 'NumberLiteralTypeAnnotation';
readonly value: number;
}

export interface StringLiteralTypeAnnotation {
readonly type: 'StringLiteralTypeAnnotation';
readonly value: string;
}

export interface BooleanLiteralTypeAnnotation {
readonly type: 'BooleanLiteralTypeAnnotation';
readonly value: boolean;
}

export interface ObjectTypeAnnotation<T> {
readonly type: 'ObjectTypeAnnotation';
readonly properties: readonly NamedShape<T>[];
// metadata for objects that generated from interfaces
readonly baseTypes?: readonly string[] | undefined;
}

export interface UnionTypeAnnotation<T> {
readonly type: 'UnionTypeAnnotation';
readonly types: readonly T[];
}

// TODO(T72031674): TupleTypeAnnotation is added for parity with UnionTypeAnnotation
// to support future implementation. Currently limited to String and Number literals.
export interface TupleTypeAnnotation {
readonly type: 'TupleTypeAnnotation';
readonly types: StringLiteralTypeAnnotation | NumberLiteralTypeAnnotation;
}

export interface MixedTypeAnnotation {
readonly type: 'MixedTypeAnnotation';
}
Expand Down Expand Up @@ -304,10 +335,14 @@ export interface NativeModuleStringLiteralTypeAnnotation {
readonly value: string;
}

export interface StringLiteralUnionTypeAnnotation {
readonly type: 'StringLiteralUnionTypeAnnotation';
readonly types: NativeModuleStringLiteralTypeAnnotation[];
}
export type StringLiteralUnionTypeAnnotation =
UnionTypeAnnotation<StringLiteralTypeAnnotation>;

export type NumberLiteralUnionTypeAnnotation =
UnionTypeAnnotation<NumberLiteralTypeAnnotation>;

export type BooleanLiteralUnionTypeAnnotation =
UnionTypeAnnotation<BooleanLiteralTypeAnnotation>;

export interface NativeModuleNumberTypeAnnotation {
readonly type: 'NumberTypeAnnotation';
Expand Down Expand Up @@ -369,15 +404,17 @@ export interface NativeModulePromiseTypeAnnotation {
readonly elementType: Nullable<NativeModuleBaseTypeAnnotation> | VoidTypeAnnotation;
}

export type UnionTypeAnnotationMemberType =
| 'NumberTypeAnnotation'
| 'ObjectTypeAnnotation'
| 'StringTypeAnnotation';
export type NativeModuleUnionTypeAnnotationMemberType =
| NativeModuleObjectTypeAnnotation
| StringLiteralTypeAnnotation
| NumberLiteralTypeAnnotation
| BooleanLiteralTypeAnnotation
| BooleanTypeAnnotation
| StringTypeAnnotation
| NumberTypeAnnotation;

export interface NativeModuleUnionTypeAnnotation {
readonly type: 'UnionTypeAnnotation';
readonly memberType: UnionTypeAnnotationMemberType;
}
export type NativeModuleUnionTypeAnnotation =
UnionTypeAnnotation<NativeModuleUnionTypeAnnotationMemberType>;

export interface NativeModuleMixedTypeAnnotation {
readonly type: 'MixedTypeAnnotation';
Expand Down
50 changes: 39 additions & 11 deletions packages/react-native-codegen/src/CodegenSchema.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ export type FloatTypeAnnotation = $ReadOnly<{
type: 'FloatTypeAnnotation',
}>;

export type NumberTypeAnnotation = $ReadOnly<{
type: 'NumberTypeAnnotation',
}>;

export type BooleanTypeAnnotation = $ReadOnly<{
type: 'BooleanTypeAnnotation',
}>;
Expand All @@ -52,11 +56,20 @@ export type StringLiteralTypeAnnotation = $ReadOnly<{
value: string,
}>;

export type StringLiteralUnionTypeAnnotation = $ReadOnly<{
type: 'StringLiteralUnionTypeAnnotation',
types: $ReadOnlyArray<StringLiteralTypeAnnotation>,
export type BooleanLiteralTypeAnnotation = $ReadOnly<{
type: 'BooleanLiteralTypeAnnotation',
value: boolean,
}>;

export type StringLiteralUnionTypeAnnotation =
UnionTypeAnnotation<StringLiteralTypeAnnotation>;

export type NumberLiteralUnionTypeAnnotation =
UnionTypeAnnotation<NumberLiteralTypeAnnotation>;

export type BooleanLiteralUnionTypeAnnotation =
UnionTypeAnnotation<BooleanLiteralTypeAnnotation>;

export type VoidTypeAnnotation = $ReadOnly<{
type: 'VoidTypeAnnotation',
}>;
Expand All @@ -68,6 +81,18 @@ export type ObjectTypeAnnotation<+T> = $ReadOnly<{
baseTypes?: $ReadOnlyArray<string>,
}>;

export type UnionTypeAnnotation<+T> = $ReadOnly<{
type: 'UnionTypeAnnotation',
types: $ReadOnlyArray<T>,
}>;

// TODO(T72031674): TupleTypeAnnotation is added for parity with UnionTypeAnnotation
// to support future implementation. Currently limited to String and Number literals.
export type TupleTypeAnnotation = $ReadOnly<{
type: 'TupleTypeAnnotation',
types: StringLiteralTypeAnnotation | NumberLiteralTypeAnnotation,
}>;

export type MixedTypeAnnotation = $ReadOnly<{
type: 'MixedTypeAnnotation',
}>;
Expand Down Expand Up @@ -358,15 +383,17 @@ export type NativeModulePromiseTypeAnnotation = $ReadOnly<{
elementType: VoidTypeAnnotation | Nullable<NativeModuleBaseTypeAnnotation>,
}>;

export type UnionTypeAnnotationMemberType =
| 'NumberTypeAnnotation'
| 'ObjectTypeAnnotation'
| 'StringTypeAnnotation';
export type NativeModuleUnionTypeAnnotationMemberType =
| NativeModuleObjectTypeAnnotation
| StringLiteralTypeAnnotation
| NumberLiteralTypeAnnotation
| BooleanLiteralTypeAnnotation
| BooleanTypeAnnotation
| StringTypeAnnotation
| NumberTypeAnnotation;

export type NativeModuleUnionTypeAnnotation = $ReadOnly<{
type: 'UnionTypeAnnotation',
memberType: UnionTypeAnnotationMemberType,
}>;
export type NativeModuleUnionTypeAnnotation =
UnionTypeAnnotation<NativeModuleUnionTypeAnnotationMemberType>;

export type NativeModuleMixedTypeAnnotation = $ReadOnly<{
type: 'MixedTypeAnnotation',
Expand Down Expand Up @@ -396,6 +423,7 @@ export type NativeModuleBaseTypeAnnotation =
| StringLiteralUnionTypeAnnotation
| NativeModuleNumberTypeAnnotation
| NumberLiteralTypeAnnotation
| BooleanLiteralTypeAnnotation
| Int32TypeAnnotation
| DoubleTypeAnnotation
| FloatTypeAnnotation
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
'use strict';

import type {
BooleanLiteralTypeAnnotation,
BooleanTypeAnnotation,
DoubleTypeAnnotation,
FloatTypeAnnotation,
Expand Down Expand Up @@ -65,6 +66,7 @@ export type StructTypeAnnotation =
| StringLiteralUnionTypeAnnotation
| NativeModuleNumberTypeAnnotation
| NumberLiteralTypeAnnotation
| BooleanLiteralTypeAnnotation
| Int32TypeAnnotation
| DoubleTypeAnnotation
| FloatTypeAnnotation
Expand Down
12 changes: 2 additions & 10 deletions packages/react-native-codegen/src/parsers/parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@ import type {
NativeModuleEnumMember,
NativeModuleEnumMemberType,
NativeModuleParamTypeAnnotation,
NativeModuleUnionTypeAnnotationMemberType,
Nullable,
PropTypeAnnotation,
SchemaType,
UnionTypeAnnotationMemberType,
} from '../CodegenSchema';
import type {ParserType} from './errors';
import type {
Expand Down Expand Up @@ -146,15 +146,7 @@ export interface Parser {
*/
remapUnionTypeAnnotationMemberNames(
types: $FlowFixMe,
): UnionTypeAnnotationMemberType[];
/**
* Given a union annotation members types, it returns an array of string literals.
* @parameter membersTypes: union annotation members types
* @returns: an array of string literals.
*/
getStringLiteralUnionTypeAnnotationStringLiterals(
types: $FlowFixMe,
): string[];
): NativeModuleUnionTypeAnnotationMemberType[];
/**
* Given the name of a file, it returns a Schema.
* @parameter filename: the name of the file.
Expand Down
10 changes: 2 additions & 8 deletions packages/react-native-codegen/src/parsers/parserMock.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@ import type {
NativeModuleEnumMember,
NativeModuleEnumMemberType,
NativeModuleParamTypeAnnotation,
NativeModuleUnionTypeAnnotationMemberType,
Nullable,
PropTypeAnnotation,
SchemaType,
UnionTypeAnnotationMemberType,
} from '../CodegenSchema';
import type {ParserType} from './errors';
import type {
Expand Down Expand Up @@ -105,13 +105,7 @@ export class MockedParser implements Parser {

remapUnionTypeAnnotationMemberNames(
membersTypes: $FlowFixMe[],
): UnionTypeAnnotationMemberType[] {
return [];
}

getStringLiteralUnionTypeAnnotationStringLiterals(
membersTypes: $FlowFixMe[],
): string[] {
): NativeModuleUnionTypeAnnotationMemberType[] {
return [];
}

Expand Down
99 changes: 42 additions & 57 deletions packages/react-native-codegen/src/parsers/parsers-primitives.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,12 @@ import type {
NativeModuleTypeAliasTypeAnnotation,
NativeModuleTypeAnnotation,
NativeModuleUnionTypeAnnotation,
NativeModuleUnionTypeAnnotationMemberType,
Nullable,
NumberLiteralTypeAnnotation,
ObjectTypeAnnotation,
ReservedTypeAnnotation,
StringLiteralTypeAnnotation,
StringLiteralUnionTypeAnnotation,
StringTypeAnnotation,
VoidTypeAnnotation,
} from '../CodegenSchema';
Expand All @@ -51,11 +51,7 @@ const {
throwIfPartialNotAnnotatingTypeParameter,
throwIfPartialWithMoreParameter,
} = require('./error-utils');
const {
ParserError,
UnsupportedTypeAnnotationParserError,
UnsupportedUnionTypeAnnotationParserError,
} = require('./errors');
const {ParserError, UnsupportedTypeAnnotationParserError} = require('./errors');
const {
assertGenericTypeAnnotationHasExactlyOneTypeParameter,
translateFunctionTypeAnnotation,
Expand Down Expand Up @@ -420,61 +416,50 @@ function emitUnion(
nullable: boolean,
hasteModuleName: string,
typeAnnotation: $FlowFixMe,
types: TypeDeclarationMap,
aliasMap: {...NativeModuleAliasMap},
enumMap: {...NativeModuleEnumMap},
tryParse: ParserErrorCapturer,
cxxOnly: boolean,
translateTypeAnnotation: $FlowFixMe,
parser: Parser,
): Nullable<
NativeModuleUnionTypeAnnotation | StringLiteralUnionTypeAnnotation,
> {
// Get all the literals by type
// Verify they are all the same
// If string, persist as StringLiteralUnionType
// If number, persist as NumberTypeAnnotation (TODO: Number literal)

const unionTypes = parser.remapUnionTypeAnnotationMemberNames(
typeAnnotation.types,
): Nullable<NativeModuleUnionTypeAnnotation> {
const unparsedMemberTypes: $ReadOnlyArray<$FlowFixMe> =
(typeAnnotation.types: $ReadOnlyArray<$FlowFixMe>);

const memberTypes = unparsedMemberTypes.map(
(memberType: $FlowFixMe): NativeModuleUnionTypeAnnotationMemberType => {
switch (memberType.type) {
case 'NumberLiteralTypeAnnotation':
case 'StringLiteralTypeAnnotation':
case 'BooleanLiteralTypeAnnotation':
case 'TSLiteralType':
case 'GenericTypeAnnotation':
case 'TSTypeLiteral':
case 'ObjectTypeAnnotation':
return translateTypeAnnotation(
hasteModuleName,
memberType,
types,
aliasMap,
enumMap,
tryParse,
cxxOnly,
parser,
);
default:
throw new UnsupportedTypeAnnotationParserError(
hasteModuleName,
memberType,
parser.language(),
);
}
},
);

// Only support unionTypes of the same kind
if (unionTypes.length > 1) {
throw new UnsupportedUnionTypeAnnotationParserError(
hasteModuleName,
typeAnnotation,
unionTypes,
);
}

if (unionTypes[0] === 'StringTypeAnnotation') {
// Reprocess as a string literal union
return emitStringLiteralUnion(
nullable,
hasteModuleName,
typeAnnotation,
parser,
);
}

return wrapNullable(nullable, {
type: 'UnionTypeAnnotation',
memberType: unionTypes[0],
});
}

function emitStringLiteralUnion(
nullable: boolean,
hasteModuleName: string,
typeAnnotation: $FlowFixMe,
parser: Parser,
): Nullable<StringLiteralUnionTypeAnnotation> {
const stringLiterals =
parser.getStringLiteralUnionTypeAnnotationStringLiterals(
typeAnnotation.types,
);

return wrapNullable(nullable, {
type: 'StringLiteralUnionTypeAnnotation',
types: stringLiterals.map(stringLiteral => ({
type: 'StringLiteralTypeAnnotation',
value: stringLiteral,
})),
types: memberTypes,
});
}

Expand Down Expand Up @@ -752,7 +737,7 @@ function emitUnionProp(
name,
optional,
typeAnnotation: {
type: 'StringLiteralUnionTypeAnnotation',
type: 'UnionTypeAnnotation',
types: typeAnnotation.types.map(option => ({
type: 'StringLiteralTypeAnnotation',
value: parser.getLiteralValue(option),
Expand Down
Loading