Class ScopeTreeSymbolResolver
The compile-time ISymbolResolver: binds an identifier by walking a ScopeTree from the scope a lookup originates in — the first tier that declares the name binds it (MS-VBAL §5.6.10, RD-VBAL §2.3.1.2). A name declared more than once in a single module or procedure scope resolves as Duplicate(IEnumerable<Symbol>); more than once at the project or global tier resolves as Ambiguous(IEnumerable<Symbol>).
public sealed class ScopeTreeSymbolResolver : ISymbolResolver
- Inheritance
-
ScopeTreeSymbolResolver
- Implements
- Inherited Members
- Extension Methods
Remarks
ResolveValue(string, ScopeKind, Uri) and ResolveType(string, ScopeKind, Uri) walk the same tree under the two binding contexts MS-VBAL §5.6.4 distinguishes, each with its own candidates: a user-defined type or a class module is only ever bound by ResolveType(string, ScopeKind, Uri) (or, for a class module and the project, as the qualifier of a qualified type name, by ResolveQualifier(string, ScopeKind, Uri)), and a local, parameter, constant, variable or procedure only ever by ResolveValue(string, ScopeKind, Uri). A class module that has a predeclared instance (VBPredeclaredInstanceSymbol) is also a name in the default binding context — as that instance, a variable of the class's type.
A name-resolution service only — the value-binding members throw, matching the intent of a design-time resolver that holds no run-time bindings. Where the candidates of one tier of the project or global scope are of different projects, the workspace's own shadow every library's, and a library shadows one whose reference ranks below it in the project (LibraryPriority); candidates that still share the top rank are an ambiguous name, a result that carries AmbiguousName and the candidates rather than an unbound one.
Constructors
ScopeTreeSymbolResolver(ScopeTree)
The compile-time ISymbolResolver: binds an identifier by walking a ScopeTree from the scope a lookup originates in — the first tier that declares the name binds it (MS-VBAL §5.6.10, RD-VBAL §2.3.1.2). A name declared more than once in a single module or procedure scope resolves as Duplicate(IEnumerable<Symbol>); more than once at the project or global tier resolves as Ambiguous(IEnumerable<Symbol>).
public ScopeTreeSymbolResolver(ScopeTree scopeTree)
Parameters
scopeTreeScopeTreeThe tree to resolve against.
Remarks
ResolveValue(string, ScopeKind, Uri) and ResolveType(string, ScopeKind, Uri) walk the same tree under the two binding contexts MS-VBAL §5.6.4 distinguishes, each with its own candidates: a user-defined type or a class module is only ever bound by ResolveType(string, ScopeKind, Uri) (or, for a class module and the project, as the qualifier of a qualified type name, by ResolveQualifier(string, ScopeKind, Uri)), and a local, parameter, constant, variable or procedure only ever by ResolveValue(string, ScopeKind, Uri). A class module that has a predeclared instance (VBPredeclaredInstanceSymbol) is also a name in the default binding context — as that instance, a variable of the class's type.
A name-resolution service only — the value-binding members throw, matching the intent of a design-time resolver that holds no run-time bindings. Where the candidates of one tier of the project or global scope are of different projects, the workspace's own shadow every library's, and a library shadows one whose reference ranks below it in the project (LibraryPriority); candidates that still share the top rank are an ambiguous name, a result that carries AmbiguousName and the candidates rather than an unbound one.
Methods
GetValue(Symbol)
Gets the IBindingHandle currently associated with the specified Symbol.
public IBindingHandle GetValue(Symbol symbol)
Parameters
Returns
ResolveConditionalConstant(string, ScopeKind, Uri)
Resolves name as a conditional compilation constant. The tiers are §3.4.1's own
shadowing rule: the enclosing module's own #Const declarations, then the project-level ones,
which the global scope carries. scope is not consulted.
public SymbolResolutionResult ResolveConditionalConstant(string name, ScopeKind scope, Uri handle)
Parameters
Returns
ResolveMember(Symbol, string, Uri)
Resolves name as a member of owner, a project or a procedural module
(MS-VBAL §5.6.12), as seen from the scope the symbol at handle belongs to.
public SymbolResolutionResult ResolveMember(Symbol owner, string name, Uri handle)
Parameters
Returns
Remarks
A module's members are what its own scope declares, less any that are Private to a lookup that does not
originate inside the module. A project's are, in the specification's order: a project, when the owner is the
enclosing project; a procedural module of the project; then the project tier's one accessible member of that
name — which is a tier of exactly the members "exactly one of the procedural modules" may have, so two modules
declaring the name collide there as an ambiguous name, as they do unqualified. The project tier is shared by
every module of the tree, a library's included, so which project a candidate is in is read off its
Library.
ResolveProjectType(VBProjectSymbol, string)
Resolves the type name that project declares (MS-VBAL §5.6.12): the candidates are the project's
own before the name is decided to be ambiguous, so the types of the other projects that share the tier are not in the way.
public SymbolResolutionResult ResolveProjectType(VBProjectSymbol project, string name)
Parameters
projectVBProjectSymbolnamestring
Returns
ResolveQualifier(string, ScopeKind, Uri)
Resolves name as the qualifier of a qualified type name (the A in A.B), as
seen from the scope the symbol at handle belongs to. A qualifier is a namespace, and neither
a user-defined type nor an Enum type can contain a type: the enclosing module's own types and the types of
the project's other modules are not tiers here, and what is left is the enclosing project itself, or a
procedural or class module in it. scope is not consulted.
public SymbolResolutionResult ResolveQualifier(string name, ScopeKind scope, Uri handle)
Parameters
Returns
ResolveType(string, ScopeKind, Uri)
Resolves name in the type binding context, as seen from the scope the symbol
at handle belongs to. The tiers, in order of precedence
(MS-VBAL §5.6.4, §5.6.10): a user-defined type or Enum declared at the level of the
enclosing module; then the enclosing project itself, a referenced project, a procedural or class module of the
enclosing project, or a library's class; then an accessible user-defined type or Enum declared in another module of
the project; then a procedural module of a referenced project (a library's); then a user-defined type or Enum of a
library. The procedure scope is never consulted — no local is a type. scope is not consulted.
public SymbolResolutionResult ResolveType(string name, ScopeKind scope, Uri handle)
Parameters
Returns
Remarks
The project scope holds the types of the enclosing project's modules and those of every library's alike, so it is two tiers, as it is for ResolveValue(string, ScopeKind, Uri): a library's procedural module ranks between them, after the project's own types and before the libraries'. A library's class keeps its place among the enclosing project's modules, ahead of the project's own types, where §5.6.10 ranks it with the library's procedural modules.
ResolveValue(string, ScopeKind, Uri)
Resolves name in the default binding context, as seen from the scope the
symbol at handle belongs to. The tiers, in order of precedence
(MS-VBAL §5.6.10): the enclosing procedure; the enclosing module; the enclosing
project itself, a referenced project, or a procedural module of the enclosing project; an accessible
member of another procedural module of the project; a procedural module of a referenced project (a
library's); an accessible member of a library's procedural module; then whatever else the global scope
declares, which includes a class module's predeclared instance. Neither a user-defined type nor a class
module is a candidate in any tier. scope is not consulted.
public SymbolResolutionResult ResolveValue(string name, ScopeKind scope, Uri handle)
Parameters
Returns
Remarks
The project scope holds the members of the enclosing project's procedural modules and those of every library's alike, so it is two tiers, the enclosing project's (a symbol of no Library) and then the libraries': a library's procedural module ranks between them, after the project's own members and before its own.
A name is resolved once for each place it is looked up from, and the tree keeps the resolution (RDCore.SDK.Model.Symbols.ScopeTree.ValueResolutions): code that reads a variable a million times resolves its name once.
TryAllocate(Symbol, VBTypedValue, out MemoryAddress)
Reserves storage sized for value and binds it to symbol —
a Static local's own first-call allocation (MS-VBAL §5.4.3.1: module
extent, so it must persist past its own frame popping) chiefly. This is a storage-only
operation: it never affects name resolution, so it is never how a symbol's name itself becomes
resolvable — that rides on its own declaring symbol instead (a procedure's own
Locals/Parameters), the same way calling this twice for an already-allocated
symbol is safe (a fresh allocation, the previous one freed first) but never necessary.
public bool TryAllocate(Symbol symbol, VBTypedValue value, out MemoryAddress address)
Parameters
symbolSymbolThe symbol to reserve storage for.
valueVBTypedValueThe value to seed the new storage with.
addressMemoryAddressThe reserved address, on success.
Returns
- bool
falseif the underlying memory space is exhausted.
TryGetAddress(Symbol, out MemoryAddress)
Gets the MemoryAddress currently reserved for symbol, if any —
what a ByRef argument binds to (MS-VBAL §5.3.1.11: "a reference parameter
binding... referring to the variable referenced by the argument's expression").
public bool TryGetAddress(Symbol symbol, out MemoryAddress address)
Parameters
symbolSymbolThe Symbol whose address to look up.
addressMemoryAddressThe reserved address, if
symbolis currently allocated.
Returns
TryRead(MemoryAddress, out IBindingHandle?)
Gets the IBindingHandle at the specified address in the runtime memory map.
public bool TryRead(MemoryAddress address, out IBindingHandle? value)
Parameters
addressMemoryAddressThe memory address to read.
valueIBindingHandleThe retrieved binding, if successful.