Skip to content

Commit

Permalink
Only consider internal parent initializers, and non private child ini…
Browse files Browse the repository at this point in the history
…tializers
  • Loading branch information
ericglau committed Dec 10, 2024
1 parent e17b5c4 commit d8bcedd
Showing 1 changed file with 8 additions and 5 deletions.
13 changes: 8 additions & 5 deletions packages/core/src/validate/run.ts
Original file line number Diff line number Diff line change
Expand Up @@ -678,15 +678,15 @@ function* getInitializerErrors(
deref('ContractDefinition', base.baseName.referencedDeclaration),
);
const baseContractsInitializersMap = new Map(
baseContractDefs.map(base => [base.name, getPossibleInitializers(base, { ignorePublicInitializers: true })]),
baseContractDefs.map(base => [base.name, getPossibleInitializers(base, true)]),
);
const baseContractsWithInitializers = baseContractDefs
.filter(base => hasInitializers(base.name, baseContractsInitializersMap))
.map(base => base.name);

if (baseContractsWithInitializers.length > 0) {
// Check for missing initializers
const contractInitializers = getPossibleInitializers(contractDef);
const contractInitializers = getPossibleInitializers(contractDef, false);
if (contractInitializers.length === 0 && !skipCheck('missing-initializer', contractDef)) {
yield {
kind: 'missing-initializer',
Expand Down Expand Up @@ -773,16 +773,19 @@ function hasInitializers(baseName: string, baseContractsInitializersMap: Map<str
return initializers !== undefined && initializers.length > 0;
}

function getPossibleInitializers(contractDef: ContractDefinition, { ignorePublicInitializers = false } = {}) {
function getPossibleInitializers(contractDef: ContractDefinition, isParentContract: boolean) {
const fns = [...findAll('FunctionDefinition', contractDef)];
return fns.filter(
fnDef =>
(fnDef.modifiers.some(modifier =>
['initializer', 'reinitializer', 'onlyInitializing'].includes(modifier.modifierName.name),
) ||
['initialize', 'initializer', 'reinitialize', 'reinitializer'].includes(fnDef.name)) &&
!(fnDef.virtual && !fnDef.body) && // Skip virtual functions without a body, since that indicates an abstract function and is not itself an initializer
(!ignorePublicInitializers || (fnDef.visibility !== 'public' && fnDef.visibility !== 'external')), // For parent contracts, ignore public initializers since they do not strictly need to be called from the child
// Skip virtual functions without a body, since that indicates an abstract function and is not itself an initializer
!(fnDef.virtual && !fnDef.body) &&
// For parent contracts, only treat internal functions as initializers (since they MUST be called by the child)
// For child contracts, treat all non-private functions as initializers (since they can be called by another contract or externally)
(isParentContract ? fnDef.visibility === 'internal' : fnDef.visibility !== 'private'),
);
}

Expand Down

0 comments on commit d8bcedd

Please sign in to comment.