I'm struggling with what seems to be a bug in Visual Basic. I'm probably missing something. Hopefully someone can point out what it is.
Section 7.5 of the Visual Basic Specification for version 10.0 says that this is the grammar for class declaration. Forgive the lack of italics that indicates the difference between literals and grammar nodes.
ClassDeclaration ::=
[ Attributes ] [ ClassModifier+ ] Class Identifier [ TypeParameterList ] StatementTerminator
[ ClassBase ]
[ TypeImplementsClause+ ]
[ ClassMemberDeclaration+ ]
End Class StatementTerminator
ClassModifier ::= TypeModifier | MustInherit | NotInheritable | Partial
So the minimal class declaration would be
Class Identifier StatementTerminator
End Class StatementTerminator
The grammar for Identifier and some other supporting nodes are specified in 13.1.2,
Identifier ::=
NonEscapedIdentifier [ TypeCharacter ] |
Keyword TypeCharacter |
EscapedIdentifier
NonEscapedIdentifier ::= < IdentifierName but not Keyword >
TypeCharacter ::=
IntegerTypeCharacter |
LongTypeCharacter |
DecimalTypeCharacter |
SingleTypeCharacter |
DoubleTypeCharacter |
StringTypeCharacter
IntegerTypeCharacter ::= %
LongTypeCharacter ::= &
DecimalTypeCharacter ::= @
SingleTypeCharacter ::= !
DoubleTypeCharacter ::= #
StringTypeCharacter ::= $
Based on my reading of this foo! should be a legal identifier because ! is a TypeCharacter.
So, based on the minimal legal class declaration above, this should be legal.
Class foo!
End Class
But Visual Studio 2010 gives this:
Type declaration characters are not valid in this context.
Am I missing something in the spec, or does the compiler disagree with the spec?
The grammar doesn’t stand on its own, the describing text is part of the specification. This is important here, because otherwise you’d be right. But as competent_tech has noted in his answer, the TypeCharacter production, while forming part of the Identifier production, is not a valid character in an identifier – except to denote a variable’s (or function’s) type.
This is specified in 2.2.1:
A type character denotes the type of the preceding identifier. The type character is not considered part of the identifier. If a declaration includes a type character, the type character must agree with the type specified in the declaration itself; otherwise, a compile-time error occurs.
Appending a type character to an identifier that conceptually does not have a type (for example, a namespace name) or to an identifier whose type disagrees with the type of the type character causes a compile-time error.
(Emphasis mine.)
The section even gives an explicit example of an invalid use that is equivalent to your use. So the specification explicitly forbids this.
The TypeIdentifier is used to declare the data type of a property, variable, function, etc.
Public Class Foo
Dim x!
' The above declaration is the same as
'Dim x As Single
End Class
Since there is no data type for a class, adding a type identifier does not make any sense. Based on this, it seems like the spec may not be entirely correct.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With