diff --git a/README.md b/README.md index 5761761..3e55f1b 100644 --- a/README.md +++ b/README.md @@ -78,6 +78,7 @@ you do not want to use the one created by the "--defaultConfig" option. * Class, struct, and union member variables whose names conflict with built-in type properties. * Confusing asm syntax. * Placement of const, immutable, or inout before a function return type instead of after the parameters. +* Functions in interface declarations redundantly marked 'abstract'. #### Wishlish * Assigning to foreach variables that are not "ref". diff --git a/src/analysis/function_attributes.d b/src/analysis/function_attributes.d index 041ca2e..32fc7d1 100644 --- a/src/analysis/function_attributes.d +++ b/src/analysis/function_attributes.d @@ -30,6 +30,13 @@ class FunctionAttributeCheck : BaseAnalyzer super(fileName); } + override void visit(const InterfaceDeclaration dec) + { + inInterface++; + dec.accept(this); + inInterface--; + } + override void visit(const Declaration dec) { if (dec.functionDeclaration is null) @@ -40,6 +47,14 @@ class FunctionAttributeCheck : BaseAnalyzer { if (attr.storageClass is null) continue; + if (attr.storageClass.token == tok!"abstract" && inInterface > 0) + { + addErrorMessage(dec.functionDeclaration.name.line, + dec.functionDeclaration.name.column, KEY, + "'abstract' attribute on interface function has" + ~ " no effect."); + continue; + } if (attr.storageClass.token == tok!"const" || attr.storageClass.token == tok!"inout" || attr.storageClass.token == tok!"immutable") @@ -56,5 +71,7 @@ class FunctionAttributeCheck : BaseAnalyzer dec.accept(this); } + int inInterface; + private enum KEY = "dscanner.confusing.function_attributes"; }