Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Codegen 78 & 79]: Merge TS & Flow parsers' logic for Partial case to emitPartial fn & commonTypes cases into emitCommonTypes fn #36450

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,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why don't we pass directly typeAnnotation.id.name?

Copy link
Contributor Author

@Pranav-yadav Pranav-yadav Mar 13, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, the emitPartial requires typeAnnotation as param :)

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