Skip to content

Commit

Permalink
Merge TS & Flow parsers' logic for Partial case to emitPartial fn…
Browse files Browse the repository at this point in the history
… & `commonTypes` cases into `emitCommonTypes` fn (#36450)

Summary:
> [Codegen 78 - Assigned to Pranav-yadav] It depends on [Codegen 75][Codegen 76][Codegen 77] Extract the logic that emits Partial values in an emitPartial function, which takes the Parsers as parameter.

>[Codegen 79 - Assigned to Pranav-yadav] It depends on [Codegen 78] Extract the basic cases logics (case Stringish, case Int32, case Double, ..., case Partial. `Flow` lines and `TypeScript` lines into a function emitCommonTypes in `parsers-primitives.js`. Make sure that the default case returns `null`. Call this function in the default: case `Flow`, `TypeScript` of the `index.js` file: if the function return something, return that from the default case; otherwise if the `emitCommonTypes` returns `null`, keep the current default implementation (throw the error).

### Changes

- merged TS & Flow parsers' logic for `Partial` case to `emitPatial` fn
- merged TS & Flow parsers' logic for below cases:
  - `Stringish`
  - `Int32`
  - `Double`
  - `Float`
  - `UnsafeObject`
  - `Object`
  - `Partial`
- into an `emitCommonTypes` fn into `parsers-primitives.js`
- add **_tests_** for `emitPartial` and `emitCommonTypes` fn's
- add `getAnnotatedElementProperties` fn to parser & impl to both TS & Flow parsers

## Changelog:

[INTERNAL] [CHANGED] - Merge TS & Flow parsers' logic for `Partial` case to `emitPatial` fn & `commonTypes` cases into `emitCommonTypes` fn

Pull Request resolved: #36450

Test Plan: - `yarn lint && yarn run flow && yarn jest react-native` ⇒ �

Reviewed By: rshest

Differential Revision: D44132308

Pulled By: cipolleschi

fbshipit-source-id: f965e85ecc5d94e57ad85334ce565a55c512fde4
  • Loading branch information
Pranav-yadav authored and facebook-github-bot committed Mar 20, 2023
1 parent 4b6b706 commit 2f25261
Show file tree
Hide file tree
Showing 8 changed files with 380 additions and 98 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ const {
emitString,
emitStringish,
emitMixed,
emitPartial,
emitCommonTypes,
typeAliasResolution,
typeEnumResolution,
Visitor,
Expand Down Expand Up @@ -1253,3 +1255,243 @@ describe('Visitor', () => {
});
});
});

describe('emitPartial', () => {
const hasteModuleName = 'SampleTurboModule';
function emitPartialForUnitTest(
typeAnnotation: $FlowFixMe,
nullable: boolean,
): $FlowFixMe {
return emitPartial(
hasteModuleName,
typeAnnotation,
/* types: TypeDeclarationMap */
{},
/* aliasMap: {...NativeModuleAliasMap} */
{},
/* enumMap: {...NativeModuleEnumMap} */
{},
/* tryParse: ParserErrorCapturer */
// $FlowFixMe[missing-local-annot]
function <T>(_: () => T) {
return null;
},
/* cxxOnly: boolean */
false,
nullable,
parser,
);
}

describe("when 'typeAnnotation' doesn't have exactly 'one' typeParameter", () => {
const nullable = false;
const typeAnnotation = {
typeParameters: {
params: [1, 2],
type: 'TypeParameterInstantiation',
},
id: {
name: 'typeAnnotationName',
},
};

it('throws an error', () => {
expect(() => emitPartialForUnitTest(typeAnnotation, nullable)).toThrow(
'Partials only support annotating exactly one parameter.',
);
});
});

describe('when Partial Not annotating type parameter', () => {
const nullable = false;
const typeAnnotation = {
typeParameters: {
params: [
{
id: {
name: 'TypeDeclaration',
},
},
],
},
id: {
name: 'typeAnnotationName',
},
};

it('throws an error', () => {
expect(() => emitPartialForUnitTest(typeAnnotation, nullable)).toThrow(
'Partials only support annotating a type parameter.',
);
});
});
});

describe('emitCommonTypes', () => {
const hasteModuleName = 'SampleTurboModule';

function emitCommonTypesForUnitTest(
typeAnnotation: $FlowFixMe,
nullable: boolean,
): $FlowFixMe {
return emitCommonTypes(
hasteModuleName,
/* types: TypeDeclarationMap */
{},
typeAnnotation,
/* aliasMap: {...NativeModuleAliasMap} */
{},
/* enumMap: {...NativeModuleEnumMap} */
{},
/* tryParse: ParserErrorCapturer */
// $FlowFixMe[missing-local-annot]
function <T>(_: () => T) {
return null;
},
/* cxxOnly: boolean */
false,
nullable,
parser,
);
}

describe("when 'typeAnnotation.id.name' is 'Stringish'", () => {
const typeAnnotation = {
typeParameters: {
params: [1, 2],
type: 'StringTypeAnnotation',
},
id: {
name: 'Stringish',
},
};
const expected = {
type: 'StringTypeAnnotation',
};
const result = emitCommonTypesForUnitTest(typeAnnotation, false);

it("returns 'StringTypeAnnotation'", () => {
expect(result).toEqual(expected);
});
});

describe("when 'typeAnnotation.id.name' is 'Int32'", () => {
const typeAnnotation = {
typeParameters: {
params: [1, 2],
type: 'Int32TypeAnnotation',
},
id: {
name: 'Int32',
},
};
const expected = {
type: 'Int32TypeAnnotation',
};
const result = emitCommonTypesForUnitTest(typeAnnotation, false);

it("returns 'Int32TypeAnnotation'", () => {
expect(result).toEqual(expected);
});
});

describe("when 'typeAnnotation.id.name' is 'Double'", () => {
const typeAnnotation = {
typeParameters: {
params: [1, 2],
type: 'DoubleTypeAnnotation',
},
id: {
name: 'Double',
},
};
const expected = {
type: 'DoubleTypeAnnotation',
};
const result = emitCommonTypesForUnitTest(typeAnnotation, false);

it("returns 'DoubleTypeAnnotation'", () => {
expect(result).toEqual(expected);
});
});

describe("when 'typeAnnotation.id.name' is 'Float'", () => {
const typeAnnotation = {
typeParameters: {
params: [1, 2],
type: 'FloatTypeAnnotation',
},
id: {
name: 'Float',
},
};
const expected = {
type: 'FloatTypeAnnotation',
};
const result = emitCommonTypesForUnitTest(typeAnnotation, false);

it("returns 'FloatTypeAnnotation'", () => {
expect(result).toEqual(expected);
});
});

describe("when 'typeAnnotation.id.name' is 'UnsafeObject'", () => {
const typeAnnotation = {
typeParameters: {
params: [1, 2],
type: 'GenericObjectTypeAnnotation',
},
id: {
name: 'UnsafeObject',
},
};
const expected = {
type: 'GenericObjectTypeAnnotation',
};
const result = emitCommonTypesForUnitTest(typeAnnotation, false);

it("returns 'GenericObjectTypeAnnotation'", () => {
expect(result).toEqual(expected);
});
});

describe("when 'typeAnnotation.id.name' is 'Object'", () => {
const typeAnnotation = {
typeParameters: {
params: [1, 2],
type: 'GenericObjectTypeAnnotation',
},
id: {
name: 'Object',
},
};
const expected = {
type: 'GenericObjectTypeAnnotation',
};
const result = emitCommonTypesForUnitTest(typeAnnotation, false);

it("returns 'GenericObjectTypeAnnotation'", () => {
expect(result).toEqual(expected);
});
});

describe("when 'typeAnnotation.id.name' is '$Partial' i.e. Object", () => {
const typeAnnotation = {
typeParameters: {
params: [1],
type: 'GenericObjectTypeAnnotation',
},
id: {
name: 'Object',
},
};
const expected = {
type: 'GenericObjectTypeAnnotation',
};
const result = emitCommonTypesForUnitTest(typeAnnotation, false);

it("returns 'GenericObjectTypeAnnotation'", () => {
expect(result).toEqual(expected);
});
});
});
65 changes: 14 additions & 51 deletions packages/react-native-codegen/src/parsers/flow/modules/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,20 +32,16 @@ const {
const {
emitArrayType,
emitBoolean,
emitDouble,
emitFloat,
emitFunction,
emitNumber,
emitInt32,
emitGenericObject,
emitObject,
emitPromise,
emitRootTag,
emitVoid,
emitString,
emitStringish,
emitMixed,
emitUnion,
emitCommonTypes,
typeAliasResolution,
typeEnumResolution,
} = require('../../parsers-primitives');
Expand All @@ -55,11 +51,6 @@ const {
UnsupportedGenericParserError,
} = require('../../errors');

const {
throwIfPartialNotAnnotatingTypeParameter,
throwIfPartialWithMoreParameter,
} = require('../../error-utils');

function translateTypeAnnotation(
hasteModuleName: string,
/**
Expand Down Expand Up @@ -132,55 +123,27 @@ function translateTypeAnnotation(

return wrapNullable(nullable || isParamNullable, paramType);
}
case 'Stringish': {
return emitStringish(nullable);
}
case 'Int32': {
return emitInt32(nullable);
}
case 'Double': {
return emitDouble(nullable);
}
case 'Float': {
return emitFloat(nullable);
}
case 'UnsafeObject':
case 'Object': {
return emitGenericObject(nullable);
}
case 'Partial':
case '$Partial': {
throwIfPartialWithMoreParameter(typeAnnotation);

const annotatedElement = parser.extractAnnotatedElement(
typeAnnotation,
types,
);

throwIfPartialNotAnnotatingTypeParameter(
typeAnnotation,
types,
parser,
);

const properties = parser.computePartialProperties(
annotatedElement.right.properties,
default: {
const commonType = emitCommonTypes(
hasteModuleName,
types,
typeAnnotation,
aliasMap,
enumMap,
tryParse,
cxxOnly,
);

return emitObject(nullable, properties);
}
default: {
throw new UnsupportedGenericParserError(
hasteModuleName,
typeAnnotation,
nullable,
parser,
);

if (!commonType) {
throw new UnsupportedGenericParserError(
hasteModuleName,
typeAnnotation,
parser,
);
}
return commonType;
}
}
}
Expand Down
4 changes: 4 additions & 0 deletions packages/react-native-codegen/src/parsers/flow/parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,10 @@ class FlowParser implements Parser {
componentName: funcArgumentParams[0].value,
};
}

getAnnotatedElementProperties(annotatedElement: $FlowFixMe): $FlowFixMe {
return annotatedElement.right.properties;
}
}

module.exports = {
Expand Down
7 changes: 7 additions & 0 deletions packages/react-native-codegen/src/parsers/parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -229,4 +229,11 @@ export interface Parser {
typeArgumentParams: $FlowFixMe,
funcArgumentParams: $FlowFixMe,
): {[string]: string};

/**
* Given a annotatedElement, it returns the properties of annotated element.
* @parameter annotatedElement: the annotated element.
* @returns: the properties of annotated element.
*/
getAnnotatedElementProperties(annotatedElement: $FlowFixMe): $FlowFixMe;
}
4 changes: 4 additions & 0 deletions packages/react-native-codegen/src/parsers/parserMock.js
Original file line number Diff line number Diff line change
Expand Up @@ -227,4 +227,8 @@ export class MockedParser implements Parser {
componentName: funcArgumentParams[0].value,
};
}

getAnnotatedElementProperties(annotatedElement: $FlowFixMe): $FlowFixMe {
return annotatedElement.right.properties;
}
}
Loading

0 comments on commit 2f25261

Please sign in to comment.