Attribute targets in VB

Topics: VB Language Design
May 13, 2014 at 9:46 PM

Attribute targets in VB

Request

Please let me specify attribute targets in VB, like I can with C#. Actually, the main need I have isn't even yet possible in C# today: I want to put attributes on the backing-field of auto-properties:
   <Field: Serializable> Property p As Integer
At the moment, all I can write is the following, which puts the attribute on the property not the backing field. That's sometimes what I want, but not always
   <Serializable> Property p As Integer

Background

VB currently allows the target modifiers Assembly and Module on attributes ($5.2), but only on top-level attributes.

Note that Assembly isn't a reserved keyword, but the parser treats it as reserved in the attribute-name position unless prefixed by a target-modifier, and hence sometimes you have to escape it <[Assembly]>

VB philosophy is that attribute targets are a pain. It's better just to "do the right thing", and place the attribute where it should "obviously" go. (that's the philosophy, and it mostly has worked, except in cases where it hasn't…)
  1. Attributes on autoprops implicitly apply to the property, not the backing field. [this is a big gap]
  2. Attributes on Subs implicitly apply to the method, not the return type
  3. Attributes on events implicitly apply to the event, not the backing field
    3.1. Except: the <NonSerialized> event goes to the backing field, not the event
  4. Attributes on WithEvents implicitly apply to the backing field (??), not the property or the event. [There had been asks to be able to apply DebuggerBrowsable to the property]

Proposal

$5.2 will be amended to allow additional AttributeModifiers:
   AttributeModifier ::= … | Field
The parser will recognize <Field as an attribute-modifier if and only if it's followed by a colon. If it's followed by anything else, it will be considered an attribute name as happens today.

The Field attribute is allowed only on AutoProps, Events and WithEvents. It is an error to apply it elsewhere. It is an error to apply it to an attribute that doesn't allow a field target.

The compiler will not give warnings about places where Field: is redundant, and will not give warnings about places where Field: might usefully be added.

When the compiler emits metadata, it will emit all <Field:> targeted attributes onto the backing field of the AutoProp, Event or WithEvent.

Suggested IDE experience: In places where you can type an attribute, intellisense will also show the contextual keyword "Field" as an option, and it will be colorized blue in anticipation of the user typing a colon, since few people will have attributes named Field, but more will want to specify properties on attributes.

Discussion

I deliberately scoped this proposal down. This proposal doesn't have a "Property" modifier (hence doesn't capture full expressivity requested for WithEvents). It doesn't have other modifiers like "Method", and doesn't allow "Field" to be applied to fields (hence doesn't allow the full redundancy that C# allows).

I did this because I think it's better to add a small scoped part of the wider vision that will be used in the right places, rather than implementing the full wider vision from the start.

Reference

Here's the toy code I was playing with to write this proposal.
<Assembly: Assembly>
<Module: Assembly>
Module Module1

    <[Assembly]>
    Sub Main()
        Dim [Assembly] = 1
        q = 15
    End Sub

    <Fred("autoprop")> Property q As Integer


    <Fred("prop")>
    Property p(<Fred("index")> i As Integer) As <Fred("type")> Integer
        <Fred("get")>
        Get
            Return 1
        End Get
        <Fred("set")>
        Set(<Fred("value")> value As Integer)
        End Set
    End Property

    <Fred("event")>
    Event e As Action

    <Fred("withevent")>
    WithEvents c As New C

End Module

Class C
    Public Event E As Action
End Class

Class AssemblyAttribute : Inherits Attribute : End Class
Class FredAttribute : Inherits Attribute
    Sub New()
    End Sub
    Sub New(s As String)
    End Sub
End Class
May 14, 2014 at 7:17 PM
It does sound like field targeting is planned for C#:

Field-targetted Attributes for Auto-Properties

As for VB, if it's a question of philosophy and trying to implicitly "do the right thing", I would think that at minimum it would be acceptable for the language to treat auto-properties in the same manner as events when using the NonSerializedAttribute, which is probably the main attribute that a developer would want to target to the backing field. That's definitely the attribute I had in mind when requesting the feature in the C# forums.

That said, I am more of a fan of allowing the developer to be explicit, so supporting a Field target for attributes does sound like the appropriate course of action.