CodeGuard

Syntax-Übersicht

Die DSL als kompakte Referenz.

Syntax-Übersicht

Die CodeGuard-DSL ist eine Untermenge von LINQ. Wenn du C# kennst, kennst du fast alles was du brauchst.

Datei-Anatomie

@name "..."                # Pflicht
@severity warn             # Pflicht, info | warn | error
@category "..."            # optional, frei wählbar
@description "..."         # optional
@recommendation "..."      # optional

# Leerzeile, dann der Query-Body
<linq-expression>

Query-Formen

Query-Syntax

from t in Types
where t.Kind == "Class"
where t.IsAbstract
select t

Method-Syntax

Types.Where(t => t.Kind == "Class" && t.IsAbstract)

Beide ergeben das gleiche Ergebnis. Bei mehr als einer Bedingung ist Query-Syntax meist lesbarer.

Top-Level-Collections

Collection Element
Types TypeModel
Methods MethodModel
Properties PropertyModel
Fields FieldModel
Events EventModel
Namespaces NamespaceModel
Assemblies AssemblyModel
TypeDependencies TypeDependency
SyntaxIssues SyntaxIssue

TypeModel-Properties (Auswahl)

Name                       string
FullName                   string
Namespace                  string
Kind                       string ("Class" | "Interface" | "Struct" | "Enum")
IsAbstract                 bool
IsSealed                   bool
IsStatic                   bool
IsPartial                  bool
AccessModifier             string ("Public" | "Internal" | "Private" | "Protected")
LinesOfCode                int
NumberOfMethods            int
NumberOfFields             int
NumberOfDerivedTypes       int
WeightedMethodsPerClass    int
DepthOfInheritance         int
LackOfCohesion             double
ResponseForClass           int
Abstractness               double
Instability                double
DistanceFromMainSequence   double
MaintainabilityIndex       double
CouplingEfferent           int
CouplingAfferent           int
BaseType                   TypeModel
Methods                    collection<MethodModel>
Constructors               collection<MethodModel>
Properties                 collection<PropertyModel>
Fields                     collection<FieldModel>
NestedTypes                collection<TypeModel>
DerivedTypes               collection<TypeModel>
UsedTypes                  collection<TypeModel>
UsedByTypes                collection<TypeModel>
ImplementedInterfaces      collection<TypeModel>
Attributes                 collection<AttributeModel>

MethodModel-Properties (Auswahl)

Name                       string
FullName                   string
ShortName                  string
AccessModifier             string
IsAsync                    bool
IsStatic                   bool
IsOverride                 bool
IsInterfaceImplementation  bool
IsConstructor              bool
IsExtensionMethod          bool
IsVirtual                  bool
ReturnType                 string
ReturnTypeShortName        string
Parameters                 collection<ParameterModel>
LinesOfCode                int
CognitiveComplexity        int
CyclomaticComplexity       int
NestingDepth               int
NumberOfLocalVariables     int
NumberOfParameters         int
DeclaringType              TypeModel
CalledMethods              collection<MethodModel>
CalledByMethods            collection<MethodModel>
Attributes                 collection<AttributeModel>

Operatoren

LINQ-Standard:

==  !=  <  <=  >  >=
&&  ||  !
+ - * /

Strings:

.StartsWith("...")
.EndsWith("...")
.Contains("...")
.Matches("regex")           # Regex-Match

Collections:

.Any(x => ...)
.All(x => ...)
.Count
.Count > 5
.Where(x => ...).Count

Spezielle Sub-Modelle

BaseType.FullName

where t.BaseType.FullName.Contains("ControllerBase")

Parameters[i].TypeShortName

where m.Parameters.Any(p => p.TypeShortName == "CancellationToken")

SyntaxIssue.Kind

Diskrete Werte für vor-analysierte Pattern. Bekannte Kinds:

"DateTimeDirectUsage"
"EmptyCatch"
"ExplicitTypeInsteadOfVar"
"FireAndForgetAsync"
"GenericExceptionCatch"
"MagicNumber"
"MissingGuardClause"
"MissingInheritDoc"
"MissingParamDoc"
"MissingXmlDoc"
"NewInConstructor"
"NullEqualityCheck"
"StringConcatenation"
"TodoComment"
"UnusedParameter"
"UnusedUsing"

Common Pitfalls

  • .Count statt .Count(). Bei Collections ist Count ein Property, nicht eine Methode.
  • Kind == "Class" ist case-sensitive. "class" matcht nicht.
  • AccessModifier == "Public" mit großem P. Wir folgen der C#-Konvention.
  • Parameters enthält nur formale Parameter, nicht den this-Receiver bei Instanz-Methoden.