Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Legal class names in VB? Spec suggests `class foo!` should be legal

Tags:

syntax

vb.net

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?

like image 833
recursive Avatar asked Dec 30 '25 18:12

recursive


2 Answers

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.

like image 101
Konrad Rudolph Avatar answered Jan 02 '26 10:01

Konrad Rudolph


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.

like image 40
competent_tech Avatar answered Jan 02 '26 09:01

competent_tech



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!