Use JavaScript functions for Component templates

Summary:
## Rationale
**Disclaimer**: This is an incremental step towards more maintainable/readable react-native-codegen generators. In the future, we may want to replace these templates/string concat logic with *something better*. But until we decide what that *something better* is, let's at least get rid of all this gross string find/replace.

Benefits of using Function templates over String.prototype.replace.
- **Self-documenting**: Template Functions enumerate/describe their exact data dependencies in their signature. You no longer have to read the template implementation to see what data you need to pass into the template.
- **Improved Readability**: JavaScript syntax highlighting makes it really easy to see where/how the data is inserted into the templates. Also template variables used be prefixed/suffixed with ::, which made things really confusing in C++ code (e.g: wtf is `::_CLASSNAME_::EventEmitter::::_EVENT_NAME_::`?).
- **Simpler Interpolation**: Don't have to worry about .replaceAll vs .replace, or calling these replace functions with regexes or strings.
- **Template Type-safety**: Ensure that the correct data types are passed to the component templates (e.g: flow will complain if you accidentally pass null/undefined when a template expects a string).
- **Template Type-safety**: Ensure that we don't pass in extra data to templates (this diff catches/fixes instances of this error). Ensure that we don't forget to pass in data to the template.
- etc.

After this diff, both our Component and NativeModule generators will be using template functions. This string find/replace exists no more in react-native-codegen.

This is also a very surface-level change. I made no efforts to simplify these templates. Let's take a look at that later, as necessary.

Changelog: [Internal]

Reviewed By: yungsters

Differential Revision: D32021441

fbshipit-source-id: f8f27069bcbf9d66dcafb7d1411da1f938eb6dcd
This commit is contained in:
Ramanpreet Nara
2021-11-01 09:00:24 -07:00
committed by Facebook GitHub Bot
parent b0711f1d35
commit 3848f48943
12 changed files with 632 additions and 359 deletions
@@ -26,7 +26,19 @@ const {
// File path -> contents
type FilesOutput = Map<string, string>;
const template = `/**
const FileTemplate = ({
packageName,
imports,
className,
extendClasses,
methods,
}: {
packageName: string,
imports: string,
className: string,
extendClasses: string,
methods: string,
}) => `/**
* ${'C'}opyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
@@ -35,12 +47,12 @@ const template = `/**
* ${'@'}generated by codegen project: GeneratePropsJavaInterface.js
*/
package ::_PACKAGE_NAME_::;
package ${packageName};
::_IMPORTS_::
${imports}
public interface ::_CLASSNAME_::<T extends ::_EXTEND_CLASSES_::> {
::_METHODS_::
public interface ${className}<T extends ${extendClasses}> {
${methods}
}
`;
@@ -253,21 +265,17 @@ module.exports = {
);
const extendString = getClassExtendString(component);
const replacedTemplate = template
.replace(
/::_IMPORTS_::/g,
Array.from(imports)
.sort()
.join('\n'),
)
.replace(/::_PACKAGE_NAME_::/g, normalizedPackageName)
.replace(/::_CLASSNAME_::/g, className)
.replace('::_EXTEND_CLASSES_::', extendString)
.replace(
'::_METHODS_::',
[propsString, commandsString].join('\n' + ' ').trimRight(),
)
.replace('::_COMMAND_HANDLERS_::', commandsString);
const replacedTemplate = FileTemplate({
imports: Array.from(imports)
.sort()
.join('\n'),
packageName: normalizedPackageName,
className,
extendClasses: extendString,
methods: [propsString, commandsString]
.join('\n' + ' ')
.trimRight(),
});
files.set(`${outputDir}/${className}.java`, replacedTemplate);
});