Table of Contents

Class DeclarationStaticSemanticsEvaluator

Namespace
RDCore.SDK.Semantics.Static
Assembly
RDCore.SDK.dll

The static semantics of what a module declares, apart from what its procedures' bodies say: the declarations themselves.

public static class DeclarationStaticSemanticsEvaluator
Inheritance
DeclarationStaticSemanticsEvaluator
Inherited Members

Remarks

A module whose every procedure is valid is not a valid module: a name declared twice, an event that is wrong, an interface that is not implemented are all errors of a declaration, which no body shows. They are found here, once for the module, and a module model holds them next to the models of its procedures (DeclarationErrors).

  • A name is declared once in the scope of a module (MS-VBAL §5.2, AmbiguousName). That is a rule of the declarations as they are written, and not of the symbols they become (CheckSyntax(ModuleNode, ConditionalCompilationBlocks)).
  • A declared type is a name that resolves to a type (UserDefinedTypeNotDefined): of a variable, a constant of the module, a parameter, a function's or a property's result, and a local variable. A name that resolves to a procedural module or a project does not: neither is a type (MS-VBAL §5.6.16.7, ModuleIsNotAValidType, AutomationTypeNotSupported for a library's module, ExpectedUserDefinedTypeNotProject). Of a field of a user-defined type and of a local constant, only that much is checked: a procedural module is refused there, and a name that does not resolve is not. Whether a name resolves can only be told once everything the declaration can see is defined, which is why this rule is one a caller asks for (DeclaredTypes).
  • What a module exposes (PublicMemberSemantics): a public member is not declared with a private type, and a class module exposes no constant, array, user-defined type or Declare. A rule of the declared types too, and asked for with them.
  • A class module is also checked for what it declares about events (ClassModuleEventSemantics) and for what its Implements directives require (ImplementsSemantics).

Methods

CheckDesigner(ModuleNode, FormDescriptor?)

Checks that the code of a form module declares no member with the name of one of the form's controls (MemberAlreadyExistsInDesigner): the form's designer already declares a field of the form's class of that name.

public static ImmutableArray<VBCompileErrorInfo> CheckDesigner(ModuleNode module, FormDescriptor? designer)

Parameters

module ModuleNode

The parsed module.

designer FormDescriptor

What the module's designer declares (ModuleParseResult.Designer), or null when it is no form.

Returns

ImmutableArray<VBCompileErrorInfo>

One error for each declaration of a control's name, at the declaration; empty when there is none, or no designer.

Remarks

MS-VBA reports a variable, a constant, a procedure or a Declare of a control's name (Excel-measured, oracle\s30 C09/C10). It compiles a WithEvents variable of a control's name and class (C17), which reads as though it shadowed the control and does not: RD-VBA refuses it with the same error, which is the error it should have been all along (the author's ruling).

CheckSyntax(ModuleNode, ConditionalCompilationBlocks)

Checks that a name is declared once in the scope of a module (MS-VBAL §5.2, AmbiguousName), from what the module's source declares.

public static ImmutableArray<VBCompileErrorInfo> CheckSyntax(ModuleNode module, ConditionalCompilationBlocks blocks)

Parameters

module ModuleNode

The parsed module.

blocks ConditionalCompilationBlocks

The #If blocks of the module, which say which declarations are alternatives of one another.

Returns

ImmutableArray<VBCompileErrorInfo>

One error for each declaration of a name that is already declared, at the repeated declaration; empty when each is declared once.

Remarks

Read off the declarations of the syntax tree and not the symbols they become, because a symbol is one per identity: a name declared twice as the same kind of thing (Public Total As Long twice, a Sub of one name twice) is, by then, one symbol, and a rule that read symbols could only find the names that collide as different kinds. The Get, Let and Set accessors of a property are the one declaration of it; an event is checked for its own uniqueness by the rule of events, which says what it is that is declared twice; and a name declared in each branch of a #If block is declared once, whichever branch compiles.

Evaluate(Symbol, IReadOnlyList<VBTypeMemberSymbol>, ISymbolResolver, DeclarationRules)

Checks everything module declares.

public static ImmutableArray<VBCompileErrorInfo> Evaluate(Symbol module, IReadOnlyList<VBTypeMemberSymbol> members, ISymbolResolver resolver, DeclarationRules rules = DeclarationRules.Default)

Parameters

module Symbol

The module, as the session or the workspace composed it: a class module with its members.

members IReadOnlyList<VBTypeMemberSymbol>

The members declared by the module (MembersOf(Uri)).

resolver ISymbolResolver

What finds the classes the module's declarations name, as they are now.

rules DeclarationRules

Which of the rules that depend on what else is defined are checked.

Returns

ImmutableArray<VBCompileErrorInfo>

Every error found, in declaration order within each rule; empty when the declarations are valid.