create-expo-cljs-app
Version:
Create a react native application with Expo and Shadow-CLJS!
268 lines (228 loc) • 7.6 kB
JavaScript
/**
* 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.
*
*
* @format
*/
;
function _slicedToArray(arr, i) {
return (
_arrayWithHoles(arr) ||
_iterableToArrayLimit(arr, i) ||
_unsupportedIterableToArray(arr, i) ||
_nonIterableRest()
);
}
function _nonIterableRest() {
throw new TypeError(
'Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.',
);
}
function _unsupportedIterableToArray(o, minLen) {
if (!o) return;
if (typeof o === 'string') return _arrayLikeToArray(o, minLen);
var n = Object.prototype.toString.call(o).slice(8, -1);
if (n === 'Object' && o.constructor) n = o.constructor.name;
if (n === 'Map' || n === 'Set') return Array.from(o);
if (n === 'Arguments' || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))
return _arrayLikeToArray(o, minLen);
}
function _arrayLikeToArray(arr, len) {
if (len == null || len > arr.length) len = arr.length;
for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];
return arr2;
}
function _iterableToArrayLimit(arr, i) {
if (typeof Symbol === 'undefined' || !(Symbol.iterator in Object(arr)))
return;
var _arr = [];
var _n = true;
var _d = false;
var _e = undefined;
try {
for (
var _i = arr[Symbol.iterator](), _s;
!(_n = (_s = _i.next()).done);
_n = true
) {
_arr.push(_s.value);
if (i && _arr.length === i) break;
}
} catch (err) {
_d = true;
_e = err;
} finally {
try {
if (!_n && _i['return'] != null) _i['return']();
} finally {
if (_d) throw _e;
}
}
return _arr;
}
function _arrayWithHoles(arr) {
if (Array.isArray(arr)) return arr;
}
const _require = require('./Utils'),
createAliasResolver = _require.createAliasResolver,
getModules = _require.getModules;
const _require2 = require('../../parsers/flow/modules/utils'),
unwrapNullable = _require2.unwrapNullable;
const HostFunctionTemplate = ({hasteModuleName, methodName, isVoid, args}) => {
const methodCallArgs = ['rt', ...args].join(', ');
const methodCall = `static_cast<${hasteModuleName}CxxSpecJSI *>(&turboModule)->${methodName}(${methodCallArgs});`;
return `static jsi::Value __hostFunction_${hasteModuleName}CxxSpecJSI_${methodName}(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {${
isVoid ? `\n ${methodCall}` : ''
}
return ${isVoid ? 'jsi::Value::undefined();' : methodCall}
}`;
};
const ModuleTemplate = ({
hasteModuleName,
hostFunctions,
moduleName,
methods,
}) => {
return `${hostFunctions.join('\n')}
${hasteModuleName}CxxSpecJSI::${hasteModuleName}CxxSpecJSI(std::shared_ptr<CallInvoker> jsInvoker)
: TurboModule("${moduleName}", jsInvoker) {
${methods
.map(({methodName, paramCount}) => {
return ` methodMap_["${methodName}"] = MethodMetadata {${paramCount}, __hostFunction_${hasteModuleName}CxxSpecJSI_${methodName}};`;
})
.join('\n')}
}`;
};
const FileTemplate = ({libraryName, modules}) => {
return `/**
* ${'C'}opyright (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.
*
* ${'@'}generated by codegen project: GenerateModuleH.js
*/
#include <react/modules/${libraryName}/NativeModules.h>
namespace facebook {
namespace react {
${modules}
} // namespace react
} // namespace facebook
`;
};
function serializeArg(arg, index, resolveAlias) {
function wrap(suffix) {
return `args[${index}]${suffix}`;
}
const nullableTypeAnnotation = arg.typeAnnotation;
const _unwrapNullable = unwrapNullable(nullableTypeAnnotation),
_unwrapNullable2 = _slicedToArray(_unwrapNullable, 1),
typeAnnotation = _unwrapNullable2[0];
let realTypeAnnotation = typeAnnotation;
if (realTypeAnnotation.type === 'TypeAliasTypeAnnotation') {
realTypeAnnotation = resolveAlias(realTypeAnnotation.name);
}
switch (realTypeAnnotation.type) {
case 'ReservedTypeAnnotation':
switch (realTypeAnnotation.name) {
case 'RootTag':
return wrap('.getNumber()');
default:
realTypeAnnotation.name;
throw new Error(
`Unknown prop type for "${arg.name}, found: ${realTypeAnnotation.name}"`,
);
}
case 'StringTypeAnnotation':
return wrap('.getString(rt)');
case 'BooleanTypeAnnotation':
return wrap('.getBool()');
case 'NumberTypeAnnotation':
return wrap('.getNumber()');
case 'FloatTypeAnnotation':
return wrap('.getNumber()');
case 'DoubleTypeAnnotation':
return wrap('.getNumber()');
case 'Int32TypeAnnotation':
return wrap('.getNumber()');
case 'ArrayTypeAnnotation':
return wrap('.getObject(rt).getArray(rt)');
case 'FunctionTypeAnnotation':
return `std::move(${wrap('.getObject(rt).getFunction(rt)')})`;
case 'GenericObjectTypeAnnotation':
return wrap('.getObject(rt)');
case 'ObjectTypeAnnotation':
return wrap('.getObject(rt)');
default:
realTypeAnnotation.type;
throw new Error(
`Unknown prop type for "${arg.name}, found: ${realTypeAnnotation.type}"`,
);
}
}
function serializePropertyIntoHostFunction(
hasteModuleName,
property,
resolveAlias,
) {
const _unwrapNullable3 = unwrapNullable(property.typeAnnotation),
_unwrapNullable4 = _slicedToArray(_unwrapNullable3, 1),
propertyTypeAnnotation = _unwrapNullable4[0];
const isVoid =
propertyTypeAnnotation.returnTypeAnnotation.type === 'VoidTypeAnnotation';
return HostFunctionTemplate({
hasteModuleName,
methodName: property.name,
isVoid,
args: propertyTypeAnnotation.params.map((p, i) =>
serializeArg(p, i, resolveAlias),
),
});
}
module.exports = {
generate(libraryName, schema, moduleSpecName, packageName) {
const nativeModules = getModules(schema);
const modules = Object.keys(nativeModules)
.map(hasteModuleName => {
const nativeModule = nativeModules[hasteModuleName];
const aliases = nativeModule.aliases,
properties = nativeModule.spec.properties,
moduleNames = nativeModule.moduleNames;
const resolveAlias = createAliasResolver(aliases);
const hostFunctions = properties.map(property =>
serializePropertyIntoHostFunction(
hasteModuleName,
property,
resolveAlias,
),
);
return ModuleTemplate({
hasteModuleName,
hostFunctions,
// TODO: What happens when there are more than one NativeModule requires?
moduleName: moduleNames[0],
methods: properties.map(
({name: propertyName, typeAnnotation: nullableTypeAnnotation}) => {
const _unwrapNullable5 = unwrapNullable(nullableTypeAnnotation),
_unwrapNullable6 = _slicedToArray(_unwrapNullable5, 1),
params = _unwrapNullable6[0].params;
return {
methodName: propertyName,
paramCount: params.length,
};
},
),
});
})
.join('\n');
const fileName = 'NativeModules.cpp';
const replacedTemplate = FileTemplate({
modules,
libraryName,
});
return new Map([[fileName, replacedTemplate]]);
},
};