Class SymbolResolverNameExtensions
Resolves a name the way it was written, type-declaration character and all.
public static class SymbolResolverNameExtensions
- Inheritance
-
SymbolResolverNameExtensions
- Inherited Members
Remarks
Environ$ and Environ are two members of the library, one that answers a String and one that answers a Variant, and a call that
resolved the first to the second would be analysed, and run, with the wrong type. A simple name finds the library's member named with the character whenever its
identifier binds a member of the library, or nothing (ResolveValue(ISymbolResolver, SimpleNameExpressionNode, ScopeKind, Uri)); a member after a dot is looked for as it was written first, and only when
the owner has no member of that name is it the member of the identifier (ResolveMember(ISymbolResolver, Symbol, SimpleNameExpressionNode, Uri)).
Methods
ResolveMember(ISymbolResolver, Symbol, SimpleNameExpressionNode, Uri)
Resolves a member written as member of owner, as ResolveMember(Symbol, string, Uri) would.
public static SymbolResolutionResult ResolveMember(this ISymbolResolver resolver, Symbol owner, SimpleNameExpressionNode member, Uri handle)
Parameters
resolverISymbolResolverThe resolver.
ownerSymbolThe symbol whose member it is.
memberSimpleNameExpressionNodeThe name of the member, with the type-declaration character it was written with.
handleUriThe Uri the member is resolved from.
Returns
Remarks
A member written with a type-declaration character is looked for as written first, because a member of the library can be named with one
(Strings.Left$), and is a different member from the one without it. Failing that it is the member of the identifier, which a field declared
Public n% is: its symbol is n, and % is how its type was said. When neither is declared, the answer is that the identifier is not.
ResolveValue(ISymbolResolver, SimpleNameExpressionNode, ScopeKind, Uri)
Resolves a name written as name, as ResolveValue(string, ScopeKind, Uri) would.
public static SymbolResolutionResult ResolveValue(this ISymbolResolver resolver, SimpleNameExpressionNode name, ScopeKind scope, Uri handle)
Parameters
resolverISymbolResolverThe resolver.
nameSimpleNameExpressionNodeThe name, with the type-declaration character it was written with.
scopeScopeKindThe scope the name is written in.
handleUriThe Uri the name is resolved from.
Returns
Remarks
MS-VBAL §5.6.10 picks "the first tier where the name value of <name> matches", and only then judges the character: "If <name>
specifies a type character, and this type character's associated type does not match the declared type of the match, the simple name expression is
invalid." The character is not part of the name being matched, so a typed name binds through the same tiers its identifier does: a local, a parameter, a
field or a procedure named Left is what Left$ means wherever it is what Left means.
The library is where that is not the whole answer. It declares its $ functions as members of their own, named with the character (Hex$
beside Hex), each returning a String where its twin returns a Variant. So when the identifier binds a member of the library, or binds
nothing at all, the name as written binds the library's member named with the character, if there is one; when there is none, it is the identifier's
result - which is how n% finds the variable n. An ambiguous or duplicated identifier is an error, and is the answer as it stands.
👉 Only the library names a member with the character in it: a workspace declaration's name is its identifier without one (Dim s$ declares
s), so the name as written can only ever find a library member. A library constant carries no ExternalTarget, so
the identifier's constant is the answer (vbCrLf$ is vbCrLf). The workspace's own names outrank the library's at the project tier, so a
public Left of another module is what Left$ means too. A member of a referenced library carries an
ExternalTarget as well, but it is that library's (Library), not the standard library's,
and its twins are not the standard library's to stand in for it: it is the answer as it stands.