Add generating of objcpp headers
Summary: In this diff I add generator for Objcpp headers Reviewed By: RSNara Differential Revision: D16438346 fbshipit-source-id: 63a632d4bf40811a8838f3dcd2a92b2f7cf3ce3a
This commit is contained in:
Родитель
81ec2112a1
Коммит
69888b0820
180
packages/react-native-codegen/src/generators/modules/GenerateModuleHObjCpp.js
поставляемый
Normal file
180
packages/react-native-codegen/src/generators/modules/GenerateModuleHObjCpp.js
поставляемый
Normal file
|
@ -0,0 +1,180 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) Facebook, Inc. and its 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';
|
||||||
|
|
||||||
|
import type {
|
||||||
|
SchemaType,
|
||||||
|
FunctionTypeAnnotationParamTypeAnnotation,
|
||||||
|
FunctionTypeAnnotationReturn,
|
||||||
|
} from '../../CodegenSchema';
|
||||||
|
|
||||||
|
type FilesOutput = Map<string, string>;
|
||||||
|
|
||||||
|
const moduleTemplate = `
|
||||||
|
class JSI_EXPORT Native::_MODULE_NAME_::SpecJSI : public ObjCTurboModule {
|
||||||
|
public:
|
||||||
|
Native::_MODULE_NAME_::SpecJSI(id<RCTTurboModule> instance, std::shared_ptr<JSCallInvoker> jsInvoker);
|
||||||
|
};`;
|
||||||
|
|
||||||
|
const protolocTemplate = `
|
||||||
|
@protocol Native::_MODULE_NAME_::Spec <RCTBridgeModule, RCTTurboModule>
|
||||||
|
::_MODULE_PROPERTIES_::
|
||||||
|
@end
|
||||||
|
`;
|
||||||
|
|
||||||
|
const callbackArgs = prop =>
|
||||||
|
prop.typeAnnotation.returnTypeAnnotation.type ===
|
||||||
|
'GenericPromiseTypeAnnotation'
|
||||||
|
? `${
|
||||||
|
prop.typeAnnotation.params.length === 0 ? '' : '\n resolve'
|
||||||
|
}:(RCTPromiseResolveBlock)resolve
|
||||||
|
reject:(RCTPromiseRejectBlock)reject`
|
||||||
|
: '';
|
||||||
|
|
||||||
|
const template = `
|
||||||
|
/**
|
||||||
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the MIT license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// NOTE: This entire file should be codegen'ed.
|
||||||
|
|
||||||
|
#import <vector>
|
||||||
|
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
|
||||||
|
#import <React/RCTBridgeModule.h>
|
||||||
|
|
||||||
|
#import <ReactCommon/RCTTurboModule.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The ObjC protocol based on the JS Flow type for SampleTurboModule.
|
||||||
|
*/
|
||||||
|
|
||||||
|
::_PROTOCOLS_::
|
||||||
|
|
||||||
|
namespace facebook {
|
||||||
|
namespace react {
|
||||||
|
::_MODULES_::
|
||||||
|
|
||||||
|
} // namespace react
|
||||||
|
} // namespace facebook
|
||||||
|
`;
|
||||||
|
|
||||||
|
function translatePrimitiveJSTypeToObjCType(
|
||||||
|
type:
|
||||||
|
| FunctionTypeAnnotationParamTypeAnnotation
|
||||||
|
| FunctionTypeAnnotationReturn,
|
||||||
|
error: string,
|
||||||
|
) {
|
||||||
|
switch (type.type) {
|
||||||
|
case 'VoidTypeAnnotation':
|
||||||
|
case 'GenericPromiseTypeAnnotation':
|
||||||
|
return 'void';
|
||||||
|
case 'StringTypeAnnotation':
|
||||||
|
return 'NSString *';
|
||||||
|
case 'NumberTypeAnnotation':
|
||||||
|
case 'FloatTypeAnnotation':
|
||||||
|
case 'Int32TypeAnnotation':
|
||||||
|
return 'NSNumber *';
|
||||||
|
case 'BooleanTypeAnnotation':
|
||||||
|
return 'BOOL';
|
||||||
|
case 'GenericObjectTypeAnnotation':
|
||||||
|
case 'ObjectTypeAnnotation':
|
||||||
|
return 'NSDictionary *';
|
||||||
|
case 'ArrayTypeAnnotation':
|
||||||
|
return 'NSArray<id<NSObject>> *';
|
||||||
|
case 'FunctionTypeAnnotation':
|
||||||
|
return 'RCTResponseSenderBlock';
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw new Error(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const methodImplementationTemplate =
|
||||||
|
'- (::_RETURN_VALUE_::) ::_PROPERTY_NAME_::::_ARGS_::;';
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
generate(libraryName: string, schema: SchemaType): FilesOutput {
|
||||||
|
const nativeModules = Object.keys(schema.modules)
|
||||||
|
.map(moduleName => {
|
||||||
|
const modules = schema.modules[moduleName].nativeModules;
|
||||||
|
if (modules == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return modules;
|
||||||
|
})
|
||||||
|
.filter(Boolean)
|
||||||
|
.reduce((acc, components) => Object.assign(acc, components), {});
|
||||||
|
|
||||||
|
const modules = Object.keys(nativeModules)
|
||||||
|
.map(name => moduleTemplate.replace(/::_MODULE_NAME_::/g, name))
|
||||||
|
.join('\n');
|
||||||
|
|
||||||
|
const protocols = Object.keys(nativeModules)
|
||||||
|
.map(name => {
|
||||||
|
const {properties} = nativeModules[name];
|
||||||
|
const implementations = properties
|
||||||
|
.map(prop => {
|
||||||
|
const nativeArgs = prop.typeAnnotation.params
|
||||||
|
.map((param, i) => {
|
||||||
|
const paramObjCType = translatePrimitiveJSTypeToObjCType(
|
||||||
|
param.typeAnnotation,
|
||||||
|
`Unspopported type for param "${param.name}" in ${
|
||||||
|
prop.name
|
||||||
|
}. Found: ${param.typeAnnotation.type}`,
|
||||||
|
);
|
||||||
|
return `${i === 0 ? '' : param.name}:(${paramObjCType})${
|
||||||
|
param.name
|
||||||
|
}`;
|
||||||
|
})
|
||||||
|
.join('\n ')
|
||||||
|
.concat(callbackArgs(prop));
|
||||||
|
const implementation = methodImplementationTemplate
|
||||||
|
.replace('::_PROPERTY_NAME_::', prop.name)
|
||||||
|
.replace(
|
||||||
|
'::_RETURN_VALUE_::',
|
||||||
|
translatePrimitiveJSTypeToObjCType(
|
||||||
|
prop.typeAnnotation.returnTypeAnnotation,
|
||||||
|
`Unspopported return type for ${prop.name}. Found: ${
|
||||||
|
prop.typeAnnotation.returnTypeAnnotation.type
|
||||||
|
}`,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.replace('::_ARGS_::', nativeArgs);
|
||||||
|
if (prop.name === 'getConstants') {
|
||||||
|
return (
|
||||||
|
implementation +
|
||||||
|
'\n' +
|
||||||
|
implementation.replace('getConstants', 'constantsToExport')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return implementation;
|
||||||
|
})
|
||||||
|
.join('\n');
|
||||||
|
return protolocTemplate
|
||||||
|
.replace(/::_MODULE_PROPERTIES_::/g, implementations)
|
||||||
|
.replace(/::_MODULE_NAME_::/g, name)
|
||||||
|
.replace('::_PROPERTIES_MAP_::', '');
|
||||||
|
})
|
||||||
|
.join('\n');
|
||||||
|
|
||||||
|
const fileName = 'RCTNativeModules.h';
|
||||||
|
const replacedTemplate = template
|
||||||
|
.replace(/::_MODULES_::/g, modules)
|
||||||
|
.replace(/::_PROTOCOLS_::/g, protocols);
|
||||||
|
|
||||||
|
return new Map([[fileName, replacedTemplate]]);
|
||||||
|
},
|
||||||
|
};
|
27
packages/react-native-codegen/src/generators/modules/__tests__/GenerateModuleHObjCpp-test.js
поставляемый
Normal file
27
packages/react-native-codegen/src/generators/modules/__tests__/GenerateModuleHObjCpp-test.js
поставляемый
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the MIT license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree.
|
||||||
|
*
|
||||||
|
* @emails oncall+react_native
|
||||||
|
* @flow strict-local
|
||||||
|
* @format
|
||||||
|
*/
|
||||||
|
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
const fixtures = require('../__test_fixtures__/fixtures.js');
|
||||||
|
const generator = require('../GenerateModuleHObjCpp.js');
|
||||||
|
|
||||||
|
describe('GenerateModuleHObjCpp', () => {
|
||||||
|
Object.keys(fixtures)
|
||||||
|
.sort()
|
||||||
|
.forEach(fixtureName => {
|
||||||
|
const fixture = fixtures[fixtureName];
|
||||||
|
|
||||||
|
it(`can generate fixture ${fixtureName}`, () => {
|
||||||
|
expect(generator.generate(fixtureName, fixture)).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,211 @@
|
||||||
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
|
exports[`GenerateModuleHObjCpp can generate fixture EMPTY_NATIVE_MODULES 1`] = `
|
||||||
|
Map {
|
||||||
|
"RCTNativeModules.h" => "
|
||||||
|
/**
|
||||||
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the MIT license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// NOTE: This entire file should be codegen'ed.
|
||||||
|
|
||||||
|
#import <vector>
|
||||||
|
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
|
||||||
|
#import <React/RCTBridgeModule.h>
|
||||||
|
|
||||||
|
#import <ReactCommon/RCTTurboModule.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The ObjC protocol based on the JS Flow type for SampleTurboModule.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
@protocol NativeSampleTurboModuleSpec <RCTBridgeModule, RCTTurboModule>
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
|
||||||
|
namespace facebook {
|
||||||
|
namespace react {
|
||||||
|
|
||||||
|
class JSI_EXPORT NativeSampleTurboModuleSpecJSI : public ObjCTurboModule {
|
||||||
|
public:
|
||||||
|
NativeSampleTurboModuleSpecJSI(id<RCTTurboModule> instance, std::shared_ptr<JSCallInvoker> jsInvoker);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace react
|
||||||
|
} // namespace facebook
|
||||||
|
",
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`GenerateModuleHObjCpp can generate fixture SIMPLE_NATIVE_MODULES 1`] = `
|
||||||
|
Map {
|
||||||
|
"RCTNativeModules.h" => "
|
||||||
|
/**
|
||||||
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the MIT license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// NOTE: This entire file should be codegen'ed.
|
||||||
|
|
||||||
|
#import <vector>
|
||||||
|
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
|
||||||
|
#import <React/RCTBridgeModule.h>
|
||||||
|
|
||||||
|
#import <ReactCommon/RCTTurboModule.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The ObjC protocol based on the JS Flow type for SampleTurboModule.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
@protocol NativeSampleTurboModuleSpec <RCTBridgeModule, RCTTurboModule>
|
||||||
|
- (NSDictionary *) getConstants;
|
||||||
|
- (NSDictionary *) constantsToExport;
|
||||||
|
- (void) voidFunc;
|
||||||
|
- (BOOL) getBool:(BOOL)arg;
|
||||||
|
- (NSNumber *) getNumber:(NSNumber *)arg;
|
||||||
|
- (NSString *) getString:(NSString *)arg;
|
||||||
|
- (NSArray<id<NSObject>> *) getArray:(NSArray<id<NSObject>> *)arg;
|
||||||
|
- (NSDictionary *) getObject:(NSDictionary *)arg;
|
||||||
|
- (NSDictionary *) getValue:(NSNumber *)x
|
||||||
|
y:(NSString *)y
|
||||||
|
z:(NSDictionary *)z;
|
||||||
|
- (void) getValueWithCallback:(RCTResponseSenderBlock)callback;
|
||||||
|
- (void) getValueWithPromise:(BOOL)error
|
||||||
|
resolve:(RCTPromiseResolveBlock)resolve
|
||||||
|
reject:(RCTPromiseRejectBlock)reject;
|
||||||
|
@end
|
||||||
|
|
||||||
|
|
||||||
|
namespace facebook {
|
||||||
|
namespace react {
|
||||||
|
|
||||||
|
class JSI_EXPORT NativeSampleTurboModuleSpecJSI : public ObjCTurboModule {
|
||||||
|
public:
|
||||||
|
NativeSampleTurboModuleSpecJSI(id<RCTTurboModule> instance, std::shared_ptr<JSCallInvoker> jsInvoker);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace react
|
||||||
|
} // namespace facebook
|
||||||
|
",
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`GenerateModuleHObjCpp can generate fixture TWO_MODULES_DIFFERENT_FILES 1`] = `
|
||||||
|
Map {
|
||||||
|
"RCTNativeModules.h" => "
|
||||||
|
/**
|
||||||
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the MIT license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// NOTE: This entire file should be codegen'ed.
|
||||||
|
|
||||||
|
#import <vector>
|
||||||
|
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
|
||||||
|
#import <React/RCTBridgeModule.h>
|
||||||
|
|
||||||
|
#import <ReactCommon/RCTTurboModule.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The ObjC protocol based on the JS Flow type for SampleTurboModule.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
@protocol NativeSampleTurboModuleSpec <RCTBridgeModule, RCTTurboModule>
|
||||||
|
- (void) voidFunc;
|
||||||
|
@end
|
||||||
|
|
||||||
|
|
||||||
|
@protocol NativeSample2TurboModuleSpec <RCTBridgeModule, RCTTurboModule>
|
||||||
|
- (void) voidFunc;
|
||||||
|
@end
|
||||||
|
|
||||||
|
|
||||||
|
namespace facebook {
|
||||||
|
namespace react {
|
||||||
|
|
||||||
|
class JSI_EXPORT NativeSampleTurboModuleSpecJSI : public ObjCTurboModule {
|
||||||
|
public:
|
||||||
|
NativeSampleTurboModuleSpecJSI(id<RCTTurboModule> instance, std::shared_ptr<JSCallInvoker> jsInvoker);
|
||||||
|
};
|
||||||
|
|
||||||
|
class JSI_EXPORT NativeSample2TurboModuleSpecJSI : public ObjCTurboModule {
|
||||||
|
public:
|
||||||
|
NativeSample2TurboModuleSpecJSI(id<RCTTurboModule> instance, std::shared_ptr<JSCallInvoker> jsInvoker);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace react
|
||||||
|
} // namespace facebook
|
||||||
|
",
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`GenerateModuleHObjCpp can generate fixture TWO_MODULES_SAME_FILE 1`] = `
|
||||||
|
Map {
|
||||||
|
"RCTNativeModules.h" => "
|
||||||
|
/**
|
||||||
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the MIT license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// NOTE: This entire file should be codegen'ed.
|
||||||
|
|
||||||
|
#import <vector>
|
||||||
|
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
|
||||||
|
#import <React/RCTBridgeModule.h>
|
||||||
|
|
||||||
|
#import <ReactCommon/RCTTurboModule.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The ObjC protocol based on the JS Flow type for SampleTurboModule.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
@protocol NativeSampleTurboModuleSpec <RCTBridgeModule, RCTTurboModule>
|
||||||
|
- (void) voidFunc;
|
||||||
|
@end
|
||||||
|
|
||||||
|
|
||||||
|
@protocol NativeSample2TurboModuleSpec <RCTBridgeModule, RCTTurboModule>
|
||||||
|
- (void) voidFunc;
|
||||||
|
@end
|
||||||
|
|
||||||
|
|
||||||
|
namespace facebook {
|
||||||
|
namespace react {
|
||||||
|
|
||||||
|
class JSI_EXPORT NativeSampleTurboModuleSpecJSI : public ObjCTurboModule {
|
||||||
|
public:
|
||||||
|
NativeSampleTurboModuleSpecJSI(id<RCTTurboModule> instance, std::shared_ptr<JSCallInvoker> jsInvoker);
|
||||||
|
};
|
||||||
|
|
||||||
|
class JSI_EXPORT NativeSample2TurboModuleSpecJSI : public ObjCTurboModule {
|
||||||
|
public:
|
||||||
|
NativeSample2TurboModuleSpecJSI(id<RCTTurboModule> instance, std::shared_ptr<JSCallInvoker> jsInvoker);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace react
|
||||||
|
} // namespace facebook
|
||||||
|
",
|
||||||
|
}
|
||||||
|
`;
|
Загрузка…
Ссылка в новой задаче