Skip to content

fix: ensure that identical types in set/get are deduper from ctor #243

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

Merged
merged 1 commit into from
Oct 2, 2023
Merged
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
37 changes: 35 additions & 2 deletions src/dynamic-param-interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,21 @@ const ignoreDescriptions = <T extends EventParameterDocumentation>(
return toReturn;
}).sort((a, b) => a.name.localeCompare(b.name));

const noDescriptionCache = new WeakMap();
const unsetDescriptions = (o: any): any => {
if (noDescriptionCache.has(o)) return noDescriptionCache.get(o);
if (typeof o !== 'object' || !o) return o;
const val = Array.isArray(o)
? o.map(item => unsetDescriptions(item))
: Object.keys(o).reduce((accum: any, key: string) => {
if (key === 'description') return accum;
accum[key] = unsetDescriptions(o[key]);
return accum;
}, {});
noDescriptionCache.set(o, val);
return val;
};

// Given a parameter create a new interface and return it's name + array modifier
// IName is the proposed interface name prefix
// backupIName is a slightly longer IName in case IName is already taken
Expand All @@ -53,13 +68,31 @@ const createParamInterface = (
finalBackupIName = '',
): string => {
const maybeArray = (type: string) => (param.collection ? `Array<${type}>` : type);
const potentialExistingArgType = polite(IName);
const potentialExistingArgName = _.lowerFirst(polite(IName));
let argType = polite(IName) + _.upperFirst(_.camelCase(param.name));
let argName = param.name;
// TODO: Note. It is still possible for even backupIName to be already used
let usingExistingParamInterface = false;
_.forIn(paramInterfacesToDeclare, (value, key) => {
const test = _.assign({}, param, { name: argName, tName: argType });
if (_.isEqual(test, value)) {
const test = unsetDescriptions(
_.assign({}, param, {
name: argName,
tName: argType,
required: value.required,
additionalTags: (param as any).additionalTags || [],
}),
);
const potentialTest = unsetDescriptions(
_.assign({}, param, {
name: potentialExistingArgName,
tName: potentialExistingArgType,
required: value.required,
additionalTags: (param as any).additionalTags || [],
}),
);
const unsetValue = unsetDescriptions(value);
if (_.isEqual(test, unsetValue) || _.isEqual(potentialTest, unsetValue)) {
usingExistingParamInterface = true;
debug(
chalk.cyan(
Expand Down
30 changes: 21 additions & 9 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,22 +86,34 @@ export async function generateDefinitions({ electronApi: API }: GenerateOptions)

// generate module declaration for every class, module, structure, element, etc
const declaredStructs: string[] = [];
API.sort((m1, m2) => m1.name.localeCompare(m2.name)).forEach((module, index) => {
API.sort((m1, m2) => {
// Ensure constructor options are declared first so as to ensure that
// setters and getters for constructor options have de-duped types
if (m1.name.endsWith('ConstructorOptions') && !m2.name.endsWith('ConstructorOptions')) {
return -1;
}
if (!m1.name.endsWith('ConstructorOptions') && m2.name.endsWith('ConstructorOptions')) {
return 1;
}
return m1.name.localeCompare(m2.name);
}).forEach((module, index) => {
if (module.type === 'Structure') {
declaredStructs.push(module.name);
}
generateModuleDeclaration(module, index, API);
});

// fetch everything that's been made and pop it into the actual API
Object.keys(getModuleDeclarations()).forEach(moduleKey => {
if (moduleKey === 'Process') return;
const moduleAPI = getModuleDeclarations()[moduleKey];
moduleAPI.push('}');
addToOutput(
moduleAPI.map((l, index) => (index === 0 || index === moduleAPI.length - 1 ? l : ` ${l}`)),
);
});
Object.keys(getModuleDeclarations())
.sort((m1, m2) => m1.localeCompare(m2))
.forEach(moduleKey => {
if (moduleKey === 'Process') return;
const moduleAPI = getModuleDeclarations()[moduleKey];
moduleAPI.push('}');
addToOutput(
moduleAPI.map((l, index) => (index === 0 || index === moduleAPI.length - 1 ? l : ` ${l}`)),
);
});

const keys = DynamicParamInterfaces.flushParamInterfaces(API, addToOutput);
generatePrimaryInterfaces(API, [...keys, ...declaredStructs], addToOutput);
Expand Down