Skip to content

Commit

Permalink
Turbo module codegen support interface with inheritance in module (#3…
Browse files Browse the repository at this point in the history
…6011)

Summary:
The [previous pull request](#35812) enables defining interfaces and using them in a turbo module, but all members are flattened, this is not the best option for codegen for object oriented languages.

In this pull request, an optional member `baseTypes` is added to aliased objects. Members are still flattened for backward compatibility, if a codegen doesn't care about that nothing needs to be changed.

### Example

```typescript
interface A {
  a : string;
}

interface B extends A {
  b : number;
}
```

#### Before the previous pull request

`interface` is not allowed here, you must use type alias.

#### At the previous pull request

`interface` is allowed, but it is translated to

```typescript
type A = {a : string};
type B = {a : string, b : number};
```

#### At this pull request

Extra information is provided so that you know `B` extends `A`. By comparing `B` to `A` it is easy to know that `B::a` is obtained from `A`.

## Changelog

[GENERAL] [CHANGED] - Turbo module codegen support interface with inheritance in module

Pull Request resolved: #36011

Test Plan: `yarn jest react-native-codegen` passed

Reviewed By: rshest

Differential Revision: D42882650

Pulled By: cipolleschi

fbshipit-source-id: 32d502e8a99c4151fae0a1f4dfa60db9ac827963
  • Loading branch information
ZihanChen-MSFT authored and facebook-github-bot committed Jan 31, 2023
1 parent 597a1ff commit bf34810
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 1 deletion.
3 changes: 3 additions & 0 deletions packages/react-native-codegen/src/CodegenSchema.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ export type VoidTypeAnnotation = $ReadOnly<{
export type ObjectTypeAnnotation<+T> = $ReadOnly<{
type: 'ObjectTypeAnnotation',
properties: $ReadOnlyArray<NamedShape<T>>,

// metadata for objects that generated from interfaces
baseTypes?: $ReadOnlyArray<string>,
}>;

type FunctionTypeAnnotation<+P, +R> = $ReadOnly<{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1521,6 +1521,56 @@ exports[`RN Codegen TypeScript Parser can generate fixture NATIVE_MODULE_WITH_NE
}
]
},
'Base1': {
'type': 'ObjectTypeAnnotation',
'properties': [
{
'name': 'bar1',
'optional': false,
'typeAnnotation': {
'type': 'TypeAliasTypeAnnotation',
'name': 'Bar'
}
}
]
},
'Base2': {
'type': 'ObjectTypeAnnotation',
'properties': [
{
'name': 'bar2',
'optional': false,
'typeAnnotation': {
'type': 'TypeAliasTypeAnnotation',
'name': 'Bar'
}
}
]
},
'Base3': {
'type': 'ObjectTypeAnnotation',
'properties': [
{
'name': 'bar2',
'optional': false,
'typeAnnotation': {
'type': 'TypeAliasTypeAnnotation',
'name': 'Bar'
}
},
{
'name': 'bar3',
'optional': false,
'typeAnnotation': {
'type': 'TypeAliasTypeAnnotation',
'name': 'Bar'
}
}
],
'baseTypes': [
'Base2'
]
},
'Foo': {
'type': 'ObjectTypeAnnotation',
'properties': [
Expand Down Expand Up @@ -1556,6 +1606,10 @@ exports[`RN Codegen TypeScript Parser can generate fixture NATIVE_MODULE_WITH_NE
'name': 'Bar'
}
}
],
'baseTypes': [
'Base1',
'Base3'
]
}
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,26 @@ function translateTypeAnnotation(
}
}
case 'TSInterfaceDeclaration': {
const objectTypeAnnotation = {
const baseTypes = (typeAnnotation.extends ?? []).map(
extend => extend.expression.name,
);
for (const baseType of baseTypes) {
// ensure base types exist and appear in aliasMap
translateTypeAnnotation(
hasteModuleName,
{
type: 'TSTypeReference',
typeName: {type: 'Identifier', name: baseType},
},
types,
aliasMap,
tryParse,
cxxOnly,
parser,
);
}

let objectTypeAnnotation = {
type: 'ObjectTypeAnnotation',
// $FlowFixMe[missing-type-arg]
properties: (flattenProperties(
Expand All @@ -246,8 +265,15 @@ function translateTypeAnnotation(
},
)
.filter(Boolean),
baseTypes,
};

if (objectTypeAnnotation.baseTypes.length === 0) {
// The flow checker does not allow adding a member after an object literal is created
// so here I do it in a reverse way
delete objectTypeAnnotation.baseTypes;
}

return typeAliasResolution(
typeAliasResolutionStatus,
objectTypeAnnotation,
Expand Down

0 comments on commit bf34810

Please sign in to comment.