Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -28,17 +28,32 @@ const argv = yargs
alias: 'exclude',
default: null,
})
.option('exclude-interface-only', {
describe: 'Exclude components with interfaceOnly: true',
type: 'boolean',
default: false,
})
.option('exclude-unimplemented', {
describe:
'Exclude component named UnimplementedNativeViewNativeComponent.js',
type: 'boolean',
default: false,
})
.parseSync();

const [outfile, ...fileList] = argv._;
const platform: ?string = argv.platform;
const exclude: string = argv.exclude;
const excludeRegExp: ?RegExp =
exclude != null && exclude !== '' ? new RegExp(exclude) : null;
const excludeInterfaceOnly: boolean = argv['exclude-interface-only'];
const excludeUnimplemented: boolean = argv['exclude-unimplemented'];

combineSchemasInFileListAndWriteToFile(
fileList,
platform != null ? platform.toLowerCase() : platform,
outfile,
excludeRegExp,
excludeInterfaceOnly,
excludeUnimplemented,
);
127 changes: 103 additions & 24 deletions packages/react-native-codegen/src/cli/combine/combine-js-to-schema.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,31 +21,69 @@ const path = require('path');
const flowParser = new FlowParser();
const typescriptParser = new TypeScriptParser();

function combineSchemas(files: Array<string>): SchemaType {
return files.reduce(
(merged, filename) => {
const contents = fs.readFileSync(filename, 'utf8');
function combineSchemas(
files: Array<string>,
excludeInterfaceOnly?: boolean,
excludeUnimplemented?: boolean,
): {
interfaceOnly: SchemaType,
unimplemented: SchemaType,
everythingElse: SchemaType,
} {
let interfaceOnly: SchemaType = {modules: {}};
let unimplemented: SchemaType = {modules: {}};
let everythingElse: SchemaType = {modules: {}};

if (
contents &&
(/export\s+default\s+\(?codegenNativeComponent</.test(contents) ||
/extends TurboModule/.test(contents))
) {
const isTypeScript =
path.extname(filename) === '.ts' || path.extname(filename) === '.tsx';
files.forEach(filename => {
const contents = fs.readFileSync(filename, 'utf8');

const parser = isTypeScript ? typescriptParser : flowParser;
if (
contents &&
(/export\s+default\s+\(?codegenNativeComponent</.test(contents) ||
/extends TurboModule/.test(contents))
) {
const isTypeScript =
path.extname(filename) === '.ts' || path.extname(filename) === '.tsx';
const parser = isTypeScript ? typescriptParser : flowParser;
const schema = parser.parseFile(filename);

const schema = parser.parseFile(filename);
if (!schema || !schema.modules) {
return;
}

const isInterfaceOnly = /interfaceOnly:\s*true/.test(contents);
const isUnimplemented =
/UnimplementedNativeViewNativeComponent\.js$/.test(filename);

if (schema && schema.modules) {
merged.modules = {...merged.modules, ...schema.modules};
if (isInterfaceOnly) {
if (excludeInterfaceOnly !== true) {
interfaceOnly = {
modules: {...interfaceOnly.modules, ...schema.modules},
};
} else {
console.log(`Excluding interfaceOnly component: ${filename}`);
}
} else if (isUnimplemented) {
if (excludeUnimplemented !== true) {
unimplemented = {
modules: {...unimplemented.modules, ...schema.modules},
};
} else {
console.log(`Excluding unimplemented component: ${filename}`);
}
} else {
everythingElse = {
modules: {...everythingElse.modules, ...schema.modules},
};
}
return merged;
},
{modules: {}},
);
}
});

return {
interfaceOnly,
unimplemented,
everythingElse,
};
}

function expandDirectoriesIntoFiles(
Expand Down Expand Up @@ -74,14 +112,28 @@ function combineSchemasInFileList(
fileList: Array<string>,
platform: ?string,
exclude: ?RegExp,
): SchemaType {
excludeInterfaceOnly: boolean,
excludeUnimplemented: boolean,
): {
interfaceOnly: SchemaType,
unimplemented: SchemaType,
everythingElse: SchemaType,
} {
const expandedFileList = expandDirectoriesIntoFiles(
fileList,
platform,
exclude,
);
const combined = combineSchemas(expandedFileList);
if (Object.keys(combined.modules).length === 0) {
const combined = combineSchemas(
expandedFileList,
excludeInterfaceOnly,
excludeUnimplemented,
);
if (
Object.keys(combined.interfaceOnly.modules).length === 0 &&
Object.keys(combined.unimplemented.modules).length === 0 &&
Object.keys(combined.everythingElse.modules).length === 0
) {
console.error(
'No modules to process in combine-js-to-schema-cli. If this is unexpected, please check if you set up your NativeComponent correctly. See combine-js-to-schema.js for how codegen finds modules.',
);
Expand All @@ -94,9 +146,36 @@ function combineSchemasInFileListAndWriteToFile(
platform: ?string,
outfile: string,
exclude: ?RegExp,
excludeInterfaceOnly: boolean,
excludeUnimplemented: boolean,
): void {
const combined = combineSchemasInFileList(fileList, platform, exclude);
const formattedSchema = JSON.stringify(combined);
const combined = combineSchemasInFileList(
fileList,
platform,
exclude,
excludeInterfaceOnly,
excludeUnimplemented,
);

// Determine which schema to write based on flags
let schemaToWrite;
if (excludeInterfaceOnly && excludeUnimplemented) {
schemaToWrite = combined.everythingElse;
} else if (excludeInterfaceOnly) {
schemaToWrite = combined.unimplemented;
} else if (excludeUnimplemented) {
schemaToWrite = combined.interfaceOnly;
} else {
// If no exclusions, combine all schemas
schemaToWrite = {
modules: {
...combined.interfaceOnly.modules,
...combined.unimplemented.modules,
...combined.everythingElse.modules,
},
};
}
const formattedSchema = JSON.stringify(schemaToWrite);
fs.writeFileSync(outfile, formattedSchema);
}

Expand Down
Loading