From c41d245fdd70233b2d690acdeffe959e000d3520 Mon Sep 17 00:00:00 2001 From: cguerre-giordano Date: Mon, 25 Nov 2024 16:11:14 +0100 Subject: [PATCH] feat: BACK-8055 Detect unused definitions --- src/erc7730/lint/__init__.py | 3 ++- src/erc7730/lint/lint.py | 9 ++++++--- src/erc7730/lint/lint_base.py | 3 ++- .../lint/lint_transaction_type_classifier.py | 20 ++++++++++--------- src/erc7730/lint/lint_validate_abi.py | 3 ++- src/erc7730/lint/lint_validate_definitions.py | 13 ++++++------ .../lint/lint_validate_display_fields.py | 8 +++++--- 7 files changed, 35 insertions(+), 24 deletions(-) diff --git a/src/erc7730/lint/__init__.py b/src/erc7730/lint/__init__.py index b86ecbf..bda4599 100644 --- a/src/erc7730/lint/__init__.py +++ b/src/erc7730/lint/__init__.py @@ -1,6 +1,7 @@ from abc import ABC, abstractmethod from erc7730.common.output import OutputAdder +from erc7730.model.input.descriptor import InputERC7730Descriptor from erc7730.model.resolved.descriptor import ResolvedERC7730Descriptor @@ -13,5 +14,5 @@ class ERC7730Linter(ABC): """ @abstractmethod - def lint(self, descriptor: ResolvedERC7730Descriptor, out: OutputAdder) -> None: + def lint(self, descriptor: ResolvedERC7730Descriptor | InputERC7730Descriptor, out: OutputAdder) -> None: raise NotImplementedError() diff --git a/src/erc7730/lint/lint.py b/src/erc7730/lint/lint.py index 534b2e5..9224613 100644 --- a/src/erc7730/lint/lint.py +++ b/src/erc7730/lint/lint.py @@ -88,6 +88,9 @@ def lint_file(path: Path, linter: ERC7730Linter, out: OutputAdder, show_as: Path with BufferAdder(file_out, prolog=f"➡️ checking [bold]{label}[/bold]…", epilog="") as out, ExceptionsToOutput(out): input_descriptor = InputERC7730Descriptor.load(path) - resolved_descriptor = ERC7730InputToResolved().convert(input_descriptor, out) - if resolved_descriptor is not None: - linter.lint(resolved_descriptor, out) + if isinstance(linter, DefinitionLinter): + linter.lint(input_descriptor, out) + else: + resolved_descriptor = ERC7730InputToResolved().convert(input_descriptor, out) + if resolved_descriptor is not None: + linter.lint(resolved_descriptor, out) diff --git a/src/erc7730/lint/lint_base.py b/src/erc7730/lint/lint_base.py index e7e519a..fbf1cb0 100644 --- a/src/erc7730/lint/lint_base.py +++ b/src/erc7730/lint/lint_base.py @@ -2,6 +2,7 @@ from erc7730.common.output import OutputAdder from erc7730.lint import ERC7730Linter +from erc7730.model.input.descriptor import InputERC7730Descriptor from erc7730.model.resolved.descriptor import ResolvedERC7730Descriptor @@ -13,6 +14,6 @@ def __init__(self, linters: list[ERC7730Linter]): self.lints = linters @override - def lint(self, descriptor: ResolvedERC7730Descriptor, out: OutputAdder) -> None: + def lint(self, descriptor: ResolvedERC7730Descriptor | InputERC7730Descriptor, out: OutputAdder) -> None: for linter in self.lints: linter.lint(descriptor, out) diff --git a/src/erc7730/lint/lint_transaction_type_classifier.py b/src/erc7730/lint/lint_transaction_type_classifier.py index 547a3d9..e4ae83b 100644 --- a/src/erc7730/lint/lint_transaction_type_classifier.py +++ b/src/erc7730/lint/lint_transaction_type_classifier.py @@ -5,6 +5,7 @@ from erc7730.lint.classifier import TxClass from erc7730.lint.classifier.abi_classifier import ABIClassifier from erc7730.lint.classifier.eip712_classifier import EIP712Classifier +from erc7730.model.input.descriptor import InputERC7730Descriptor from erc7730.model.resolved.context import EIP712Schema, ResolvedContractContext, ResolvedEIP712Context from erc7730.model.resolved.descriptor import ResolvedERC7730Descriptor from erc7730.model.resolved.display import ResolvedDisplay, ResolvedFormat @@ -18,15 +19,16 @@ class ClassifyTransactionTypeLinter(ERC7730Linter): """ @override - def lint(self, descriptor: ResolvedERC7730Descriptor, out: OutputAdder) -> None: - if descriptor.context is None: - return None - if (tx_class := self._determine_tx_class(descriptor)) is None: - # could not determine transaction type - return None - if (display := descriptor.display) is None: - return None - DisplayFormatChecker(tx_class, display).check(out) + def lint(self, descriptor: ResolvedERC7730Descriptor | InputERC7730Descriptor, out: OutputAdder) -> None: + if isinstance(descriptor, ResolvedERC7730Descriptor): + if descriptor.context is None: + return None + if (tx_class := self._determine_tx_class(descriptor)) is None: + # could not determine transaction type + return None + if (display := descriptor.display) is None: + return None + DisplayFormatChecker(tx_class, display).check(out) @classmethod def _determine_tx_class(cls, descriptor: ResolvedERC7730Descriptor) -> TxClass | None: diff --git a/src/erc7730/lint/lint_validate_abi.py b/src/erc7730/lint/lint_validate_abi.py index a5672d6..83571cd 100644 --- a/src/erc7730/lint/lint_validate_abi.py +++ b/src/erc7730/lint/lint_validate_abi.py @@ -4,6 +4,7 @@ from erc7730.common.abi import compute_signature, get_functions from erc7730.common.output import OutputAdder from erc7730.lint import ERC7730Linter +from erc7730.model.input.descriptor import InputERC7730Descriptor from erc7730.model.resolved.context import ResolvedContractContext, ResolvedEIP712Context from erc7730.model.resolved.descriptor import ResolvedERC7730Descriptor @@ -17,7 +18,7 @@ class ValidateABILinter(ERC7730Linter): """ @override - def lint(self, descriptor: ResolvedERC7730Descriptor, out: OutputAdder) -> None: + def lint(self, descriptor: ResolvedERC7730Descriptor | InputERC7730Descriptor, out: OutputAdder) -> None: if isinstance(descriptor.context, ResolvedEIP712Context): return self._validate_eip712_schemas(descriptor.context, out) if isinstance(descriptor.context, ResolvedContractContext): diff --git a/src/erc7730/lint/lint_validate_definitions.py b/src/erc7730/lint/lint_validate_definitions.py index b4b4b7e..ceaa013 100644 --- a/src/erc7730/lint/lint_validate_definitions.py +++ b/src/erc7730/lint/lint_validate_definitions.py @@ -2,7 +2,8 @@ from erc7730.common.output import OutputAdder from erc7730.lint import ERC7730Linter -from erc7730.model.resolved.context import ResolvedEIP712Context +from erc7730.model.input.descriptor import InputERC7730Descriptor +from erc7730.model.input.display import InputReference from erc7730.model.resolved.descriptor import ResolvedERC7730Descriptor @@ -11,17 +12,17 @@ class DefinitionLinter(ERC7730Linter): """Check that parameters under definitions are used in formats section""" @override - def lint(self, descriptor: ResolvedERC7730Descriptor, out: OutputAdder) -> None: - if isinstance(descriptor.context, ResolvedEIP712Context) and descriptor.display.definitions is not None: - for name, _ in descriptor.display.definitions.items(): + def lint(self, descriptor: ResolvedERC7730Descriptor | InputERC7730Descriptor, out: OutputAdder) -> None: + if isinstance(descriptor, InputERC7730Descriptor) and descriptor.display.definitions is not None: + for _, definition in descriptor.display.definitions.items(): found = False for _, format in descriptor.display.formats.items(): if found is False: for field in format.fields: - if field.path == name: + if isinstance(field, InputReference) and field.ref == definition.label: found = True if found is False: out.error( title="Unused field definition", - message=f"Field {name} is not used in descriptor formats.", + message=f"Field {definition.label} is not used in descriptor formats.", ) diff --git a/src/erc7730/lint/lint_validate_display_fields.py b/src/erc7730/lint/lint_validate_display_fields.py index 34bfa43..a0722d3 100644 --- a/src/erc7730/lint/lint_validate_display_fields.py +++ b/src/erc7730/lint/lint_validate_display_fields.py @@ -3,6 +3,7 @@ from erc7730.common.abi import function_to_selector from erc7730.common.output import OutputAdder from erc7730.lint import ERC7730Linter +from erc7730.model.input.descriptor import InputERC7730Descriptor from erc7730.model.paths import DataPath, Field from erc7730.model.paths.path_ops import data_path_ends_with, path_starts_with, to_absolute from erc7730.model.paths.path_schemas import ( @@ -27,9 +28,10 @@ class ValidateDisplayFieldsLinter(ERC7730Linter): """ @override - def lint(self, descriptor: ResolvedERC7730Descriptor, out: OutputAdder) -> None: - self._validate_eip712_paths(descriptor, out) - self._validate_abi_paths(descriptor, out) + def lint(self, descriptor: ResolvedERC7730Descriptor | InputERC7730Descriptor, out: OutputAdder) -> None: + if isinstance(descriptor, ResolvedERC7730Descriptor): + self._validate_eip712_paths(descriptor, out) + self._validate_abi_paths(descriptor, out) @classmethod def _validate_eip712_paths(cls, descriptor: ResolvedERC7730Descriptor, out: OutputAdder) -> None: