Table of Contents

2.6.4 Rubberduck Core Diagnostics

Rubberduck Core diagnostics are the analyzer findings issued by the RDCore.Diagnostics analyzers. They cover implicit declarations, obsolete syntax, misleading constructs, every inspection that the legacy Rubberduck add-in shipped, and further inspections beyond those.

Code family RDC, defined by RDCoreDiagnosticId; the enum value is the code
Title per finding
Raised by the RDCore.Diagnostics analyzers
Severity spans Hint through Error, per finding

Any other language core diagnostics issued from RDCore.Diagnostics are to be documented under an RDC00000 code; see RD-VBAL §1.1.4 Core Diagnostics.

Published codes

An analyzer is a pure function of facts (IModuleAnalyzer): the environment host runs the semantic analysis pass and says what is true of the code, and an analyzer decides what is worth saying (RD-VBAL §5.0.3 Semantic Analysis). An analyzer that is not given the fact it reads has nothing to say.

What the code means is a fact the host vouches for. How it is written - a keyword that is there or is not, where a name is - is a fact of the syntax tree, which the analyzer is given along with the model: those analyzers read the tree, and a module that did not parse has nothing for them to say.

Not every fact is ready at the same time, and a finding that is ready is not held back for one that is not. An analyzer belongs to a phase (IModuleAnalyzer.Phase, AnalysisPhase): the static phase has the syntax tree and the facts of the host's static pass, which are there as soon as a module is loaded; the runtime phase has the facts that come of evaluating the code of the module, which take longer. The language server asks for the phases in turn and, for a client that is pushed diagnostics, publishes each as soon as it arrives together with the ones before it (a publication replaces the one before it). A client that pulls diagnostics is answered when every phase is. An analyzer that does not say is of the static phase.

The severity of a finding is a choice of the analyzer (RD-VBAL §2.6 Diagnostics): a Hint states a fact, an Information (a suggestion) is a finding that a code action could fix, and a Warning is serious enough to break a build that treats warnings as errors.

Code Title Severity Reads
RDC00101 Implicit declarations enabled Warning ModuleSemanticModel.OptionExplicit
RDC00102 Implicit non-default array base Hint the syntax tree: an Option Base 1 directive
RDC00103 Implicit type declarations enabled Hint the syntax tree: a Def<Type> directive
RDC00104 Implicit ByRef modifier Information the syntax tree: ParameterDeclarationNode.ParameterKind
RDC00105 Implicit Public member Information the syntax tree: MemberDeclarationNode.AccessModifier
RDC00106 Implicit Variant declaration Information the syntax tree: a declaration with no type, and the Def<Type> directives
RDC00107 Implicit Variant return type Information the syntax tree: a function with no type, and the Def<Type> directives
RDC00112 Implicit narrowing conversion Warning ProcedureSemanticModel.Runtime: the ConversionFacts the language core states about the code of the procedure
RDC00114 Implicit array declaration Information ModuleSemanticModel.Declarations: a local whose DeclarationFact.DeclaredBy is ReDim
RDC00115 Implicit result local Information the syntax tree, and ProcedureSemanticModel.Expressions: a name of the procedure, read in its body, bound to it and not a call of it
RDC00201 Integer data type declaration Information the syntax tree: AsTypeExpressionNode
RDC00202 Module-scope Dim declaration Information the syntax tree: a module-level variable with no access modifier
RDC00203 Multiline parameter declaration Information the syntax tree: the range of a ParameterDeclarationNode
RDC00204 Multiple declarations Information the syntax tree: the declarations one statement makes
RDC00205 Misleading ByRef parameter Information the syntax tree: ParameterDeclarationNode.IsByRefIgnored
RDC00206 Not all code paths return a value Warning ProcedureSemanticModel.ReturnValue, from the ControlFlowGraph of the procedure
RDC00207 IsMissing that is always False Warning ValueExpressionSemanticFlags.IsMissingAlwaysFalse
RDC00208 Shadowed declaration Information DeclarationFact.Hides, from the resolver: what the name of a local or a parameter means as seen from the module
RDC00302 Obsolete Call statement Hint ValueExpressionSemanticFlags.ExplicitCallKeyword
RDC00303 Obsolete comment syntax Information ModuleSemanticModel.Language (SupportedLanguage.UsesClassicBasicSyntax), and the comments of the syntax tree
RDC00304 Obsolete error syntax Information ModuleSemanticModel.Language, and the syntax tree: an Error statement
RDC00305 Obsolete Global modifier Information the syntax tree: AccessModifier.Global
RDC00306 Obsolete Let statement Information the syntax tree: AssignmentKind.ExplicitLet
RDC00307 Obsolete type hint Information the syntax tree: the type hints of declarations; ExpressionFact.Binding of the references
RDC00308 Obsolete While…Wend Information the syntax tree: a WhileWendStatementNode
RDC00309 Obsolete On Local Error statement Information the syntax tree: OnErrorGoToStatementNode.IsLocal
RDC00310 Redundant ByVal argument Hint ValueExpressionSemanticFlags.RedundantByVal
RDC00311 Early binding opportunity Information ExpressionFact.Creates (ObjectClassSource.ReferencedLibrary)
RDC00405 Implementations should be private Information DeclarationFact.Role and DeclarationFact.Access
RDC01001 Use meaningful identifier names Information the names the syntax tree declares, and the allow-list in DiagnosticsOptions.MeaningfulNames
RDC01002 Hungarian notation Information the names the syntax tree declares, and the allow-list in DiagnosticsOptions.HungarianNotation
RDC11005 Bitwise operator Hint ProcedureSemanticModel.Runtime: LogicalOperatorSemanticFlags.IsBitwiseSemantics of the LogicalOperatorFacts
RDC11006 Ambiguous concatenation Information ProcedureSemanticModel.Runtime: ArithmeticOperatorSemanticFlags.VBStringEffectiveType of the ArithmeticOperatorFacts of +
RDC11011 Variant number compared with a Variant String Warning ProcedureSemanticModel.Runtime: ComparisonOperatorSemanticFlags.IsVariantStringNumericException of the ComparisonOperatorFacts
RDC11013 Variant compared with a String as text Warning ProcedureSemanticModel.Runtime: ComparisonOperatorSemanticFlags.IsVariantComparedWithStringAsText of the ComparisonOperatorFacts
RDC11014 Case Is compared in the selector's type Warning ProcedureSemanticModel.Runtime: CaseClauseSemanticFlags.ComparisonForm and ComparedInSelectorType of the CaseClauseStatementFacts
RDC11015 Object with no default member used as a value Warning ValueExpressionSemanticFlags.ValueOfObjectWithNoDefaultMember
RDC11016 Empty or Null assigned to an array Warning ValueExpressionSemanticFlags.EmptyLetToArray
RDC11017 Like pattern MS-VBA matches otherwise than specified Warning ProcedureSemanticModel.Runtime: ComparisonOperatorSemanticFlags.LikePatternHasEmptyCharList and LikePatternIsInvalid of the ComparisonOperatorFacts
RDC11020 Variant String that is no number, compared with a number Warning ProcedureSemanticModel.Runtime: ComparisonOperatorSemanticFlags.IsVariantStringThatIsNoValueRanked of the ComparisonOperatorFacts

What the host's static pass found wrong with the code is not an opinion: it is reported as the VBC compile error it is, by the same extension, from the same model. Likewise, a run-time error that evaluating the code finds an instruction raises whenever it runs (RuntimeFacts.Errors) is reported in the runtime phase as the VBR error it is, where the instruction is, with the severity of an error: n = 5678 into a Byte is VBR00006 before the program runs. An error the code raises for itself (Error, Err.Raise) is a fact an analyzer may read, and is not reported; see RD-VBAL §2.6.3 Runtime Errors.

Runtime facts

What an analyzer of the runtime phase reads is ProcedureSemanticModel.Runtime (RuntimeFacts), which travels as RuntimeFactsDto. Every fact is stated by the runtime semantics themselves, as they evaluate each instruction of the procedure once (the sweep), and only when it is true of the code however the procedure is called:

Facts What they say Flags
Conversions (ConversionFact) every let-coercion the code asks for, its site and operand ConversionSemanticFlags
Operations (OperatorFact) every operation of an operator, with its effective type; a comparison says how String values compare (Option Compare) ArithmeticOperatorSemanticFlags, ConcatOperationSemanticFlags, ComparisonOperatorSemanticFlags, LogicalOperatorSemanticFlags
Operations (MemberAccessFact) every member the code accesses: named (a.b, .b), a dictionary access (a!b), the default member of an indexed object, the enumeration member a For Each uses, and the member an assignment writes MemberAccessOperationSemanticFlags
Statements (StatementFact) what an LSet, RSet or With statement is FixedAssignmentSemanticFlags, WithStatementSemanticFlags
Errors every run-time error an instruction raises whenever it runs -

An error is stated only when nothing the instruction did was assumed: the value of a variable or a parameter, what a procedure that is not called returns, the state of the standard library or of the outside world (files, Rnd, CreateObject), or what another instruction left behind (a loop's counter, a With block's target). Dim c As Collection: c.Add 1 raises error 91 when it runs, but the sweep does not follow paths and cannot tell that nothing set c, so it says nothing. The bounds of a fixed-size array are not assumed: they are its declaration's, whatever it holds. Dim a(5) As Long: a(6) = 1 is error 9 whenever it runs, and is stated; what an element holds is assumed, so x = 1 \ a(1) says nothing. MemberAccessOperationSemanticFlags.CallByNameAccess is not stated yet: a CallByName call is a call of the library, which the sweep does not look into.

Language Core Conditions and Analyzer Opinions

The VBC, VBR and VBA diagnostic families describe conditions the language core defines. RDC diagnostics are opinions of the analyzer.

Shadowing of VBA library definitions should be detected in the semantic layer and reported through semantic flags, so that RDCore.Diagnostics can issue shadowed declaration diagnostics; see RD-VBAL §2.3.1.3 Name Resolution and RD-VBAL §1.1.3 Core Semantic Flags.

Extension Diagnostics

🧩 Diagnostics contributed by other extensions must use their own prefix, distinct from RDC, so that codes stay unique and traceable to their source. The RDX00000 format and third-party prefixes are specified in RD-VBAL §1.1.4 Core Diagnostics.


⏮️ RD-VBAL §2.6.3 Runtime Errors | ⏭️ RD-VBAL §2.6.5 Diagnostics Pipeline