Skip to content
This repository has been archived by the owner on Jul 3, 2024. It is now read-only.

Commit

Permalink
merge: #156 feature/50-solidity-linter-rules/111-named-parameters-map…
Browse files Browse the repository at this point in the history
…ping-rule-staging

111 - Named Parameters Mapping Rule
  • Loading branch information
0xtekgrinder authored and 0xSwapFeeder committed Oct 9, 2023
2 parents 23a5be0 + 8a9b29c commit 440221c
Show file tree
Hide file tree
Showing 11 changed files with 236 additions and 32 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,7 @@ pub struct ExplicitTypesVisitor {
type_inits: Vec<SolIdent>,
}

impl <'ast> Visit<'ast> for ExplicitTypesVisitor {

impl<'ast> Visit<'ast> for ExplicitTypesVisitor {
fn visit_type(&mut self, ty: &'ast Type) {
match ty {
Type::Int(_, _) => {
Expand All @@ -27,17 +26,16 @@ impl <'ast> Visit<'ast> for ExplicitTypesVisitor {
Type::Uint(_, _) => {
self.type_names.push(ty.clone());
}
_ => {visit::visit_type(self, ty)}
_ => visit::visit_type(self, ty),
}
}

fn visit_variable_definition(&mut self, var: &'ast VariableDefinition) {
if let Some((_, expr)) = &var.initializer {
if let Some((_, expr)) = &var.initializer {
visit::visit_expr(self, expr);
}
visit::visit_variable_definition(self, var);
}

}

impl ExplicitTypes {
Expand Down Expand Up @@ -70,7 +68,8 @@ impl ExplicitTypes {

fn _check_type(&self, ty: &str, file: &SolidFile, span: Box<dyn Spanned>) -> Option<LintDiag> {
if (self.rule == "explicit" && (ty == "int" || ty == "uint"))
|| (self.rule == "implicit" && (ty != "int" && ty != "uint")) {
|| (self.rule == "implicit" && (ty != "int" && ty != "uint"))
{
return Some(self.create_diag(file, span, ty));
}
None
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@ use std::collections::HashMap;
pub mod line_maxlen;
pub mod custom_errors;
pub mod empty_block;
pub mod explicit_types;
pub mod function_max_lines;
pub mod global_import;
pub mod max_states_count;
pub mod no_console;
pub mod one_contract_per_file;
pub mod payable_fallback;
pub mod reason_string;
mod explicit_types;
pub mod visibility_modifier_order;

// List all rules
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@ use crate::rules::naming::event_name_camelcase::EventNameCamelCase;
use crate::rules::naming::func_name_camelcase::FuncNameCamelCase;
use crate::rules::naming::func_param_name_camelcase::FuncParamNameCamelcase;
use crate::rules::naming::func_visibility::FuncVisibility;
use crate::rules::naming::modifier_name_mixedcase::ModifierNameMixedcase;
use crate::rules::naming::named_parameters_mapping::NamedParametersMapping;
use crate::rules::naming::use_forbidden_name::UseForbiddenName;
use crate::rules::naming::var_name_mixedcase::VarNameMixedCase;
use crate::rules::types::{RuleEntry, RulesMap};
use crate::rules::RuleBuilder;
use std::collections::HashMap;
use crate::rules::naming::modifier_name_mixedcase::ModifierNameMixedcase;

#[macro_use]
pub(crate) mod func_param_name_camelcase;
Expand All @@ -18,9 +19,10 @@ pub(crate) mod contract_name_pascalcase;
pub(crate) mod event_name_camelcase;
pub(crate) mod func_name_camelcase;
pub(crate) mod func_visibility;
pub(crate) mod modifier_name_mixedcase;
pub(crate) mod named_parameters_mapping;
pub(crate) mod use_forbidden_name;
pub(crate) mod var_name_mixedcase;
pub(crate) mod modifier_name_mixedcase;

// List all rules

Expand All @@ -35,6 +37,7 @@ pub fn create_default_rules() -> Vec<RuleEntry> {
ConstNameSnakeCase::create_default(),
VarNameMixedCase::create_default(),
ModifierNameMixedcase::create_default(),
NamedParametersMapping::create_default(),
]
}

Expand All @@ -45,6 +48,10 @@ pub fn create_rules() -> RulesMap {
contract_name_pascalcase::RULE_ID.to_string(),
ContractNamePascalCase::create,
);
rules.insert(
named_parameters_mapping::RULE_ID.to_string(),
NamedParametersMapping::create,
);
rules.insert(
func_name_camelcase::RULE_ID.to_string(),
FuncNameCamelCase::create,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,6 @@ impl RuleType for ModifierNameMixedcase {
let mut res = Vec::new();
let contracts = retriever::retrieve_contract_nodes(&file.data);


for contract in contracts.iter() {
let functions = retriever::retrieve_functions_nodes(contract);

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
use crate::linter::SolidFile;
use crate::rules::types::*;
use crate::types::*;
use ast_extractor::*;

pub const RULE_ID: &str = "named-parameters-mapping";

pub struct NamedParametersMapping {
data: RuleEntry,
}

pub struct MappingsVisitor {
mappings: Vec<TypeMapping>,
}

impl MappingsVisitor {
pub fn new() -> Self {
Self {
mappings: Vec::new(),
}
}
}

impl<'ast> Visit<'ast> for MappingsVisitor {
fn visit_type(&mut self, t: &Type) {
if let Type::Mapping(ty) = t {
self.mappings.push(ty.clone());
}
visit::visit_type(self, t)
}
}

impl NamedParametersMapping {
fn create_diag(
&self,
location: (LineColumn, LineColumn),
message: &str,
file: &SolidFile,
) -> LintDiag {
LintDiag {
id: RULE_ID.to_string(),
range: Range {
start: Position {
line: location.0.line,
character: location.0.column,
},
end: Position {
line: location.1.line,
character: location.1.column,
},
},
message: message.to_string(),
severity: Some(self.data.severity),
code: None,
source: None,
uri: file.path.clone(),
source_file_content: file.content.clone(),
}
}
}

impl RuleType for NamedParametersMapping {
fn diagnose(&self, file: &SolidFile, _files: &[SolidFile]) -> Vec<LintDiag> {
let mut res = Vec::new();
let mut visitor = MappingsVisitor::new();
for contract in ast_extractor::retriever::retrieve_contract_nodes(&file.data) {
visitor.visit_item_contract(&contract);
}

for mapping in visitor.mappings.iter() {
if mapping.key_name.is_none() {
let span = mapping.key.span();
res.push(self.create_diag(
(span.start(), span.end()),
format!("{} parameter is not named", mapping.key).as_str(),
file,
));
}
if mapping.value_name.is_none() {
let span = mapping.value.span();
res.push(self.create_diag(
(span.start(), span.end()),
format!("{} parameter is not named", mapping.value).as_str(),
file,
));
}
}
res
}
}

impl NamedParametersMapping {
pub(crate) fn create(data: RuleEntry) -> Box<dyn RuleType> {
let rule = NamedParametersMapping { data };
Box::new(rule)
}

pub(crate) fn create_default() -> RuleEntry {
RuleEntry {
id: RULE_ID.to_string(),
severity: Severity::WARNING,
data: vec![],
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,20 @@ use std::collections::HashMap;

#[macro_use]
pub(crate) mod no_inline_assembly;
pub(crate) mod state_visibility;
pub(crate) mod not_rely_on_time;
pub(crate) mod state_visibility;

// List all rules
use crate::rules::security::no_inline_assembly::NoInlineAssembly;
use crate::rules::security::state_visibility::StateVisibility;
use crate::rules::security::not_rely_on_time::NotRelyOnTime;
use crate::rules::security::state_visibility::StateVisibility;
use crate::rules::RuleBuilder;

pub fn create_default_rules() -> Vec<RuleEntry> {
vec![
NoInlineAssembly::create_default(),
StateVisibility::create_default(),
NotRelyOnTime::create_default()
NotRelyOnTime::create_default(),
]
}

Expand All @@ -33,10 +33,7 @@ pub fn create_rules() -> RulesMap {
StateVisibility::create,
);

rules.insert(
not_rely_on_time::RULE_ID.to_string(),
NotRelyOnTime::create,
);
rules.insert(not_rely_on_time::RULE_ID.to_string(), NotRelyOnTime::create);

rules
}
Original file line number Diff line number Diff line change
Expand Up @@ -45,22 +45,34 @@ impl RuleType for NotRelyOnTime {

for line in file.content.lines() {
if let Some(index) = line.find("now") {
res.push(self.create_diag((LineColumn {
line: i,
column: index,
}, LineColumn {
line: i,
column: index + 3,
}), file));
res.push(self.create_diag(
(
LineColumn {
line: i,
column: index,
},
LineColumn {
line: i,
column: index + 3,
},
),
file,
));
}
if let Some(index) = line.find("block.timestamp") {
res.push(self.create_diag((LineColumn {
line: i,
column: index,
}, LineColumn {
line: i,
column: index + 15,
}), file));
res.push(self.create_diag(
(
LineColumn {
line: i,
column: index,
},
LineColumn {
line: i,
column: index + 15,
},
),
file,
));
}
i += 1;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
{
"name": "solidhunter",
"includes": [],
"plugins": [],
"rules": [
{
"id": "line-max-len",
"severity": "WARNING",
"data": [
"80"
]
},
{
"id": "no-inline-assembly",
"severity": "WARNING",
"data": []
},
{
"id": "named-parameters-mapping",
"severity": "WARNING",
"data": []
},
{
"id": "max-states-count",
"severity": "WARNING",
"data": [
"15"
]
},
{
"id": "function-max-lines",
"severity": "WARNING",
"data": [
"20"
]
},
{
"id": "reason-string",
"severity": "WARNING",
"data": [
"32"
]
},
{
"id": "contract-name-pascalcase",
"severity": "WARNING",
"data": []
},
{
"id": "func-name-camelcase",
"severity": "WARNING",
"data": []
},
{
"id": "func-param-name-camelcase",
"severity": "WARNING",
"data": []
},
{
"id": "use-forbidden-name",
"severity": "WARNING",
"data": []
},
{
"id": "import-on-top",
"severity": "WARNING",
"data": []
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
pragma solidity 0.8.0;

contract Test {
mapping(address ok => uint256) public balances;
mapping(address => uint256 no) public balances;
mapping(address => uint256) public balances;
mapping(address named => mapping(uint256 ok => address) wow) public balan;
mapping(address balance => uint256 amount) public balances;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
named-parameters-mapping:4:26:4:33
named-parameters-mapping:5:12:5:19
named-parameters-mapping:6:12:6:19
named-parameters-mapping:6:23:6:30
named-parameters-mapping:7:51:7:58
Original file line number Diff line number Diff line change
Expand Up @@ -165,5 +165,6 @@ test_directories! {
VarNameMixedCase,
ModifierNameMixedcase,
GlobalImport,
NotRelyOnTime
NotRelyOnTime,
NamedParametersMapping,
}

0 comments on commit 440221c

Please sign in to comment.