命名空间和类型中的标识符查找
- 来源: https://www.freebasic.net/wiki/wikka.php?wakka=ProPgIdentifierLookup
- 最后更新: 2023-07-09
在程序中遇到对标识符的引用时,将执行查找以定位引入该标识符的声明。
前言:
要查找的标识符可以是非限定的或限定的:
非限定标识符是没有前缀来指定其来源作用域的标识符。
限定标识符包括前缀,通过覆盖默认作用域来澄清解释作用域。
作用域优先级层次结构
非限定标识符查找按以下优先级层次结构进行验证:
- [1] 当前
Namespace/Type。 - [2] 基础类型(通过
Extends),从继承层次结构中最近到最远排列。 - [3] 父命名空间(通过嵌套),从祖先层次结构中最近到最远排列(包括全局命名空间:始终在层次结构中最远)。
- [4] 导入的命名空间(通过
Using),它们之间没有层次结构(不管各自的嵌套级别如何)。
用于查找的非限定标识符可以是:
- 变量标识符。
=> 查找顺序:[1]、[2]、[3]、[4]。
- 过程标识符。
=> 查找顺序:[1]、[2]、[3]、[4]。
- 类型/联合标识符。
=> 查找顺序:[1]、[3]、[4]。
- 枚举标识符,不包括单独的字段符号。
=> 查找顺序:[1]、[3]、[4]。
如果使用带有引用命名空间前缀的限定标识符来代替非限定标识符,则前面关于非限定标识符的规则修订如下:
- 查找从对应于指定前缀的命名空间级别开始(如 [1])。
- 如果失败,则只有导入到此命名空间中的命名空间才能成为查找候选(如 [4])。
- 但此命名空间的父命名空间和全局命名空间永远不能成为候选(不如 [3])。
=> 查找顺序:[1]、[4]。
如果使用带有前缀(object-name/This 或 Base (成员访问))引用类型的限定标识符来代替非限定标识符,则前面关于非限定标识符的规则修订如下:
- 查找从类型或基础类型级别开始,具体取决于指定前缀
object-name/This或Base (成员访问)(类似于 [1])。 - 如果失败,则只有从最近到最远的更高基础类型才能依次成为查找候选(如 [2])。
- 但任何命名空间,包括当前命名空间,都不能成为候选(不如 [3] 或 [4])。
=> 查找顺序:[1]、[2]。
完整过程
完整过程通过将问题分为两个连续阶段来简化:
- 使用上面的作用域优先级层次结构规则,从所有可访问的作用域中选择单个作用域,仅考虑用于查找的标识符,不考虑调用者提供的签名(如果至少有两个包含此标识符的作用域具有等效的可访问优先级,则过程以歧义状态停止)。
- 在保留的单个作用域内(如果存在),进行一次最终的重载解析,考虑完整签名(如果与声明的签名不兼容,则过程停止,不测试其他可访问的作用域)。
这样将问题简化为在同一作用域内进行一次完整的重载解析(而不是在每个候选作用域内进行完整重载解析,然后从候选作用域中难以选择最佳结果)。
对过程标识符的非常优化解析过程(人类智慧的最佳方案)的编码是繁琐的,因为从一开始就必须考虑被调用过程的完整签名(过程标识符+参数的类型和数量+调用约定+返回类型(如果存在))。
此外,必须考虑到从调用推导的签名不一定与候选作用域中声明的某些签名完全相同,而只是兼容。
重载非成员运算符的标识符查找
目前,重载非成员运算符标识符的查找因以下事实而简化:即使用户在命名名称空间中声明这些运算符,编译器也总是在全局命名空间中定义它们。
但全局命名空间在从另一个作用域查找非成员重载运算符标识符时始终是候选作用域,因为此运算符标识符不能与限定前缀一起使用,而是始终作为非限定标识符使用(从运算符调用来看,全局命名空间要么是当前命名空间,要么是父命名空间)。
Using 命令的标识符查找
Using 命令标识符的查找遵循与类型类似的规则。
示例
以下四段代码测试了在不同作用域情况下(从最高到最低优先级层次结构)针对在不同作用域中定义的过程的一个非限定标识符和一个限定标识符的不同查找:
start GeSHi
Sub duplicateSub()
Print " ..duplicateSub"
End Sub
Namespace M
Sub duplicateSub()
Print " M.duplicateSub"
End Sub
End Namespace
Namespace N
Sub duplicateSub()
Print " N.duplicateSub"
End Sub
Namespace P
Using M
Sub duplicateSub()
Print " N.P.duplicateSub"
End Sub
Sub test()
Using M '' useless, but just to demonstrate that does not increase priority level of imported namespace
duplicateSub()
End Sub
End Namespace
End Namespace
Print "From Namespace:"
' "N.P.test()" calls the unqualified identifier "duplicateSub"
' "N.P.duplicateSub()" calls the qualified identifier "N.P.duplicateSub"
N.P.test() '' "N.P.duplicateSub" expected : in (1) current namespace/type
N.P.duplicateSub() '' "N.P.duplicateSub" expected : in (1) current namespace/type
Print
Sleepend GeSHi
start GeSHi
Sub duplicateSub()
Print " ..duplicateSub"
End Sub
Namespace M
Sub duplicateSub()
Print " M.duplicateSub"
End Sub
End Namespace
Namespace N
Sub duplicateSub()
Print " N.duplicateSub"
End Sub
Namespace P
Using M
'Sub duplicateSub()
' Print " N.P.duplicateSub"
'End Sub
Sub test()
Using M '' useless, but just to demonstrate that does not increase priority level of imported namespace
duplicateSub()
End Sub
End Namespace
End Namespace
Print "From Namespace:"
' "N.P.test()" calls the unqualified identifier "duplicateSub"
' "N.P.duplicateSub()" calls the qualified identifier "N.P.duplicateSub"
N.P.test() '' "N.duplicateSub" expected : in [3] parent namespaces (by nesting)
N.P.duplicateSub() '' "M.duplicateSub" expected : in [4] imported namespaces (by 'Using')
Print
Sleepend GeSHi
start GeSHi
Sub duplicateSub()
Print " ..duplicateSub"
End Sub
Namespace M
Sub duplicateSub()
Print " M.duplicateSub"
End Sub
End Namespace
Namespace N
'Sub duplicateSub()
' Print " N.duplicateSub"
'End Sub
Namespace P
Using M
'Sub duplicateSub()
' Print " N.P.duplicateSub"
'End Sub
Sub test()
Using M '' useless, but just to demonstrate that does not increase priority level of imported namespace
duplicateSub()
End Sub
End Namespace
End Namespace
Print "From Namespace:"
' "N.P.test()" calls the unqualified identifier "duplicateSub"
' "N.P.duplicateSub()" calls the qualified identifier "N.P.duplicateSub"
N.P.test() '' "..duplicateSub" expected : in [3] parent namespaces (by nesting)
N.P.duplicateSub() '' "M.duplicateSub" expected : in [4] imported namespaces (by 'Using')
Print
Sleepend GeSHi
start GeSHi
'Sub duplicateSub()
' Print " ..duplicateSub"
'End Sub
Namespace M
Sub duplicateSub()
Print " M.duplicateSub"
End Sub
End Namespace
Namespace N
'Sub duplicateSub()
' Print " N.duplicateSub"
'End Sub
Namespace P
Using M
'Sub duplicateSub()
' Print " N.P.duplicateSub"
'End Sub
Sub test()
Using M '' useless, but just to demonstrate that does not increase priority level of imported namespace
duplicateSub()
End Sub
End Namespace
End Namespace
Print "From Namespace:"
' "N.P.test()" calls the unqualified identifier "duplicateSub"
' "N.P.duplicateSub()" calls the qualified identifier "N.P.duplicateSub"
N.P.test() '' "M.duplicateSub" expected : in [4] imported namespaces (by 'Using')
N.P.duplicateSub() '' "M.duplicateSub" expected : in [4] imported namespaces (by 'Using')
Print
Sleepend GeSHi
以下六段代码测试了在不同作用域情况下(从最高到最低优先级层次结构)针对在不同作用域中定义的变量的一个非限定标识符和一个限定标识符的不同查找:
start GeSHi
Dim Shared As ZString * 32 duplicateVar = " ..duplicateVar"
Namespace M
Dim As ZString *32 duplicateVar = " M.duplicateVar"
End Namespace
Namespace N
Using M
Dim As ZString * 32 duplicateVar = " N.duplicateVar"
Type Parent Extends Object
Dim As ZString * 32 duplicateVar = " N.Parent.duplicateVar"
End Type
Type Child Extends Parent
Dim As ZString * 32 duplicateVar = " N.Child.duplicateVar"
End Type
Type GrandChild Extends Child
Dim As ZString * 32 duplicateVar = " N.GrandChild.duplicateVar"
Declare Sub test()
End Type
Sub GrandChild.test()
Using M '' useless, but just to demonstrate that does not increase priority level of imported namespace
Print duplicateVar
End Sub
End Namespace
Print "From Type:"
Dim As N.GrandChild gc
' "gc.test()" calls the unqualified identifier "duplicateVar"
' "Print gc.duplicateVar" calls the qualified identifier "gc.duplicateVar"
gc.test() '' "N.GrandChild.duplicateVar" expected : in [1] current namespace/type
Print gc.duplicateVar '' "N.GrandChild.duplicateVar" expected : in [1] current namespace/type
Print
Sleepend GeSHi
start GeSHi
Dim Shared As ZString * 32 duplicateVar = " ..duplicateVar"
Namespace M
Dim As ZString *32 duplicateVar = " M.duplicateVar"
End Namespace
Namespace N
Using M
Dim As ZString * 32 duplicateVar = " N.duplicateVar"
Type Parent Extends Object
Dim As ZString * 32 duplicateVar = " N.Parent.duplicateVar"
End Type
Type Child Extends Parent
Dim As ZString * 32 duplicateVar = " N.Child.duplicateVar"
End Type
Type GrandChild Extends Child
'Dim As Zstring * 32 duplicateVar = " N.GrandChild.duplicateVar"
Declare Sub test()
End Type
Sub GrandChild.test()
Using M '' useless, but just to demonstrate that does not increase priority level of imported namespace
Print duplicateVar
End Sub
End Namespace
Print "From Type:"
Dim As N.GrandChild gc
' "gc.test()" calls the unqualified identifier "duplicateVar"
' "Print gc.duplicateVar" calls the qualified identifier "gc.duplicateVar"
gc.test() '' "N.Child.duplicateVar" expected : in [2] base types (by 'Extends')
Print gc.duplicateVar '' "N.Child.duplicateVar" expected : in [2] base types (by 'Extends')
Print
Sleepend GeSHi
start GeSHi
Dim Shared As ZString * 32 duplicateVar = " ..duplicateVar"
Namespace M
Dim As ZString *32 duplicateVar = " M.duplicateVar"
End Namespace
Namespace N
Using M
Dim As ZString * 32 duplicateVar = " N.duplicateVar"
Type Parent Extends Object
Dim As ZString * 32 duplicateVar = " N.Parent.duplicateVar"
End Type
Type Child Extends Parent
'Dim As Zstring * 32 duplicateVar = " N.Child.duplicateVar"
End Type
Type GrandChild Extends Child
'Dim As Zstring * 32 duplicateVar = " N.GrandChild.duplicateVar"
Declare Sub test()
End Type
Sub GrandChild.test()
Using M '' useless, but just to demonstrate that does not increase priority level of imported namespace
Print duplicateVar
End Sub
End Namespace
Print "From Type:"
Dim As N.GrandChild gc
' "gc.test()" calls the unqualified identifier "duplicateVar"
' "Print gc.duplicateVar" calls the qualified identifier "gc.duplicateVar"
gc.test() '' "N.Parent.duplicateVar" expected : in [2] base types (by 'Extends')
Print gc.duplicateVar '' "N.Parent.duplicateVar" expected : in [2] base types (by 'Extends')
Print
Sleepend GeSHi
start GeSHi
Dim Shared As ZString * 32 duplicateVar = " ..duplicateVar"
Namespace M
Dim As ZString *32 duplicateVar = " M.duplicateVar"
End Namespace
Namespace N
Using M
Dim As ZString * 32 duplicateVar = " N.duplicateVar"
Type Parent Extends Object
'Dim As Zstring * 32 duplicateVar = " N.Parent.duplicateVar"
End Type
Type Child Extends Parent
'Dim As Zstring * 32 duplicateVar = " N.Child.duplicateVar"
End Type
Type GrandChild Extends Child
'Dim As Zstring * 32 duplicateVar = " N.GrandChild.duplicateVar"
Declare Sub test()
End Type
Sub GrandChild.test()
Using M '' useless, but just to demonstrate that does not increase priority level of imported namespace
Print duplicateVar
End Sub
End Namespace
Print "From Type:"
Dim As N.GrandChild gc
' "gc.test()" calls the unqualified identifier "duplicateVar"
' "Print gc.duplicateVar" calls the qualified identifier "gc.duplicateVar"
gc.test() '' "N.duplicateVar" expected : in [3] parent namespaces (by nesting)
'Print gc.duplicateVar '' error
Print
Sleepend GeSHi
start GeSHi
Dim Shared As ZString * 32 duplicateVar = " ..duplicateVar"
Namespace M
Dim As ZString *32 duplicateVar = " M.duplicateVar"
End Namespace
Namespace N
Using M
'Dim As Zstring * 32 duplicateVar = " N.duplicateVar"
Type Parent Extends Object
'Dim As Zstring * 32 duplicateVar = " N.Parent.duplicateVar"
End Type
Type Child Extends Parent
'Dim As Zstring * 32 duplicateVar = " N.Child.duplicateVar"
End Type
Type GrandChild Extends Child
'Dim As Zstring * 32 duplicateVar = " N.GrandChild.duplicateVar"
Declare Sub test()
End Type
Sub GrandChild.test()
Using M '' useless, but just to demonstrate that does not increase priority level of imported namespace
Print duplicateVar
End Sub
End Namespace
Print "From Type:"
Dim As N.GrandChild gc
' "gc.test()" calls the unqualified identifier "duplicateVar"
' "Print gc.duplicateVar" calls the qualified identifier "gc.duplicateVar"
gc.test() '' "..duplicateVar" expected : in [3] parent namespaces (by nesting)
'Print gc.duplicateVar '' error
Print
Sleepend GeSHi
start GeSHi
'Dim Shared As Zstring * 32 duplicateVar = " ..duplicateVar"
Namespace M
Dim As ZString *32 duplicateVar = " M.duplicateVar"
End Namespace
Namespace N
Using M
'Dim As Zstring * 32 duplicateVar = " N.duplicateVar"
Type Parent Extends Object
'Dim As Zstring * 32 duplicateVar = " N.Parent.duplicateVar"
End Type
Type Child Extends Parent
'Dim As Zstring * 32 duplicateVar = " N.Child.duplicateVar"
End Type
Type GrandChild Extends Child
'Dim As Zstring * 32 duplicateVar = " N.GrandChild.duplicateVar"
Declare Sub test()
End Type
Sub GrandChild.test()
Using M '' useless, but just to demonstrate that does not increase priority level of imported namespace
Print duplicateVar
End Sub
End Namespace
Print "From Type:"
Dim As N.GrandChild gc
' "gc.test()" calls the unqualified identifier "duplicateVar"
' "Print gc.duplicateVar" calls the qualified identifier "gc.duplicateVar"
gc.test() '' "M.duplicateVar" expected : in [4] imported namespaces (by 'Using')
'Print gc.duplicateVar '' error
Print
Sleepend GeSHi
以下四段代码测试了在不同作用域情况下(从最高到最低优先级层次结构)针对在不同作用域中定义的类型的一个非限定标识符和一个限定标识符的不同查找:
start GeSHi
Type duplicateType
Dim As ZString * 32 root = " ..duplicateType"
End Type
Namespace M
Type duplicateType
Dim As ZString * 32 root = " M.duplicateType"
End Type
End Namespace
Namespace N
Type duplicateType
Dim As ZString * 32 root = " N.duplicateType"
End Type
Namespace P
Using M
Type duplicateType
Dim As ZString * 32 root = " N.P.duplicateType"
End Type
Sub test()
Using M '' useless, but just to demonstrate that does not increase priority level of imported namespace
Print Type`<duplicateType>`.root
End Sub
End Namespace
End Namespace
' "N.P.test()" calls the unqualified identifier "duplicateType"
' "Print Type`<N.P.duplicateType>`.root" calls the qualified identifier "N.P.duplicateType"
Print "From Namespace:"
N.P.test() '' "N.P.duplicateSub" expected : in (1) current namespace/type
Print Type`<N.P.duplicateType>`.root '' "N.P.duplicateSub" expected : in (1) current namespace/type
Print
Sleepend GeSHi
start GeSHi
Type duplicateType
Dim As ZString * 32 root = " ..duplicateType"
End Type
Namespace M
Type duplicateType
Dim As ZString * 32 root = " M.duplicateType"
End Type
End Namespace
Namespace N
Type duplicateType
Dim As ZString * 32 root = " N.duplicateType"
End Type
Namespace P
Using M
'Type duplicateType
' Dim As Zstring * 32 root = " N.P.duplicateType"
'End type
Sub test()
Using M '' useless, but just to demonstrate that does not increase priority level of imported namespace
Print Type`<duplicateType>`.root
End Sub
End Namespace
End Namespace
' "N.P.test()" calls the unqualified identifier "duplicateType"
' "Print Type`<N.P.duplicateType>`.root" calls the qualified identifier "N.P.duplicateType"
Print "From Namespace:"
N.P.test() '' "N.duplicateSub" expected : in [3] parent namespaces (by nesting)
Print Type`<N.P.duplicateType>`.root '' "M.duplicateSub" expected : in [4] imported namespaces (by 'Using')
Print
Sleepend GeSHi
start GeSHi
Type duplicateType
Dim As ZString * 32 root = " ..duplicateType"
End Type
Namespace M
Type duplicateType
Dim As ZString * 32 root = " M.duplicateType"
End Type
End Namespace
Namespace N
'Type duplicateType
' Dim As Zstring * 32 root = " N.duplicateType"
'End type
Namespace P
Using M
'Type duplicateType
' Dim As Zstring * 32 root = " N.P.duplicateType"
'End type
Sub test()
Using M '' useless, but just to demonstrate that does not increase priority level of imported namespace
Print Type`<duplicateType>`.root
End Sub
End Namespace
End Namespace
' "N.P.test()" calls the unqualified identifier "duplicateType"
' "Print Type`<N.P.duplicateType>`.root" calls the qualified identifier "N.P.duplicateType"
Print "From Namespace:"
N.P.test() '' "..duplicateSub" expected : in [3] parent namespaces (by nesting)
Print Type`<N.P.duplicateType>`.root '' "M.duplicateSub" expected : in [4] imported namespaces (by 'Using')
Print
Sleepend GeSHi
start GeSHi
'Type duplicateType
' Dim As Zstring * 32 root = " ..duplicateType"
'End type
Namespace M
Type duplicateType
Dim As ZString * 32 root = " M.duplicateType"
End Type
End Namespace
Namespace N
'Type duplicateType
' Dim As Zstring * 32 root = " N.duplicateType"
'End type
Namespace P
Using M
'Type duplicateType
' Dim As Zstring * 32 root = " N.P.duplicateType"
'End type
Sub test()
Using M '' useless, but just to demonstrate that does not increase priority level of imported namespace
Print Type`<duplicateType>`.root
End Sub
End Namespace
End Namespace
' "N.P.test()" calls the unqualified identifier "duplicateType"
' "Print Type`<N.P.duplicateType>`.root" calls the qualified identifier "N.P.duplicateType"
Print "From Namespace:"
N.P.test() '' "M.duplicateSub" expected : in [4] imported namespaces (by 'Using')
Print Type`<N.P.duplicateType>`.root '' "M.duplicateSub" expected : in [4] imported namespaces (by 'Using')
Print
Sleepend GeSHi
以下四段代码测试了在不同作用域情况下(从最高到最低优先级层次结构)针对在不同作用域中定义的枚举的一个非限定标识符和一个限定标识符的不同查找:
start GeSHi
Dim Shared As ZString * 32 root(...) = {" ..duplicateEnum", " M.duplicateEnum", " N.duplicateEnum", " N.P.duplicateEnum"}
Enum duplicateEnum
nb = 0
End Enum
Namespace M
Enum duplicateEnum
nb = 1
End Enum
End Namespace
Namespace N
Enum duplicateEnum
nb = 2
End Enum
Namespace P
Using M
Enum duplicateEnum
nb = 3
End Enum
Sub test()
Using M '' useless, but just to demonstrate that does not increase priority level of imported namespace
Print root(duplicateEnum.nb)
End Sub
End Namespace
End Namespace
' "N.P.test()" calls the unqualified identifier "duplicateEnum"
' "Print root(N.P.duplicateEnum.nb)" calls the qualified identifier "N.P.duplicateEnum"
Print "From Namespace:"
N.P.test() '' "N.P.duplicateEnum" expected : in (1) current namespace/type
Print root(N.P.duplicateEnum.nb) '' "N.P.duplicateEnum" expected : in (1) current namespace/type
Print
Sleepend GeSHi
start GeSHi
Dim Shared As ZString * 32 root(...) = {" ..duplicateEnum", " M.duplicateEnum", " N.duplicateEnum", " N.P.duplicateEnum"}
Enum duplicateEnum
nb = 0
End Enum
Namespace M
Enum duplicateEnum
nb = 1
End Enum
End Namespace
Namespace N
Enum duplicateEnum
nb = 2
End Enum
Namespace P
Using M
'Enum duplicateEnum
' nb = 3
'End Enum
Sub test()
Using M '' useless, but just to demonstrate that does not increase priority level of imported namespace
Print root(duplicateEnum.nb)
End Sub
End Namespace
End Namespace
' "N.P.test()" calls the unqualified identifier "duplicateEnum"
' "Print root(N.P.duplicateEnum.nb)" calls the qualified identifier "N.P.duplicateEnum"
Print "From Namespace:"
N.P.test() '' "N.duplicateEnum" expected : in [3] parent namespaces (by nesting)
Print root(N.P.duplicateEnum.nb) '' "M.duplicateEnum" expected : in [4] imported namespaces (by 'Using')
Print
Sleepend GeSHi
start GeSHi
Dim Shared As ZString * 32 root(...) = {" ..duplicateEnum", " M.duplicateEnum", " N.duplicateEnum", " N.P.duplicateEnum"}
Enum duplicateEnum
nb = 0
End Enum
Namespace M
Enum duplicateEnum
nb = 1
End Enum
End Namespace
Namespace N
'Enum duplicateEnum
' nb = 2
'End Enum
Namespace P
Using M
'Enum duplicateEnum
' nb = 3
'End Enum
Sub test()
Using M '' useless, but just to demonstrate that does not increase priority level of imported namespace
Print root(duplicateEnum.nb)
End Sub
End Namespace
End Namespace
' "N.P.test()" calls the unqualified identifier "duplicateEnum"
' "Print root(N.P.duplicateEnum.nb)" calls the qualified identifier "N.P.duplicateEnum"
Print "From Namespace:"
N.P.test() '' "..duplicateEnum" expected : in [3] parent namespaces (by nesting)
Print root(N.P.duplicateEnum.nb) '' "M.duplicateEnum" expected : in [4] imported namespaces (by 'Using')
Print
Sleepend GeSHi
start GeSHi
Dim Shared As ZString * 32 root(...) = {" ..duplicateEnum", " M.duplicateEnum", " N.duplicateEnum", " N.P.duplicateEnum"}
'Enum duplicateEnum
' nb = 0
'End Enum
Namespace M
Enum duplicateEnum
nb = 1
End Enum
End Namespace
Namespace N
'Enum duplicateEnum
' nb = 2
'End Enum
Namespace P
Using M
'Enum duplicateEnum
' nb = 3
'End Enum
Sub test()
Using M '' useless, but just to demonstrate that does not increase priority level of imported namespace
Print root(duplicateEnum.nb)
End Sub
End Namespace
End Namespace
' "N.P.test()" calls the unqualified identifier "duplicateEnum"
' "Print root(N.P.duplicateEnum.nb)" calls the qualified identifier "N.P.duplicateEnum"
Print "From Namespace:"
N.P.test() '' "M.duplicateEnum" expected : in [4] imported namespaces (by 'Using')
Print root(N.P.duplicateEnum.nb) '' "M.duplicateEnum" expected : in [4] imported namespaces (by 'Using')
Print
Sleepend GeSHi
版本
- 自 fbc 1.09.0 起。
- 在 fbc 1.09.0 之前,优先级层次结构管理不当,存在不一致性。
另请参阅
返回 目录