AdamSpeight2008 / roslyn-AdamSpeight2008

The .NET Compiler Platform ("Roslyn") provides open-source C# and Visual Basic compilers with rich code analysis APIs.
MIT License
0 stars 0 forks source link

[Feature] Implicit Default Value On Optional Parameter #9

Closed AdamSpeight2008 closed 7 years ago

AdamSpeight2008 commented 8 years ago

Implicit Default Value On Optional Parameter

The aim of the proposal is to see if it possible to make the default value, that currently as to explicitly expressed can be made optional.

Examples

The existing code

Public Function Example( Optional x As Integer = 0, Optional s As String = Nothing )

End Function

can written as

Public Function Example( Optional x As Integer, Optional s As String )

End Function

This would reduce a lot of boiler-plate code for the likely common usage of just needing the default value of the type (eg parameter = default(T) ). Will still permitting the expressing of a different value, should the coder require one.


Research

Grammar Definition

Parameter
    : Attributes? ParameterModifier* ParameterIdentifier ( 'As' TypeName )?
      ( Equals ConstantExpression )?
    ;

So the Visual Basic Grammer (VB14) allows for an optional default value ( Equals ConstantExpression )?.

Errors

Default Value For Non Optional Parameter

Method( x As Integer = 0)

Obsolete Optional Without Value

Method( Optional x As Integer)

==Compat== Must maintain this when language version doesn't support Implicit Default Value On Optional Parameter.

Caller Information Attributes

( <CallerLineNumber> Optional line As Integer = 0 )
( <CallerMethodName> Optional method As String = Nothing )
( <CallerFilename>   Optional filename As String = Nothing )

(Compat) These should continue work, even when using the feature.


Code Examination

Parser

After a search of the Parser code

Dim equals As PunctuationSyntax = Nothing
Dim value As ExpressionSyntax = Nothing

' TODO - Move these errors (ERRID.ERR_DefaultValueForNonOptionalParamout, ERRID.ERR_ObsoleteOptionalWithoutValue) of the parser. 
' These are semantic errors. The grammar allows the syntax. 
If TryGetTokenAndEatNewLine(SyntaxKind.EqualsToken, equals) Then

    If Not (modifiers.Any AndAlso modifiers.Any(SyntaxKind.OptionalKeyword)) Then
        equals = ReportSyntaxError(equals, ERRID.ERR_DefaultValueForNonOptionalParam)
    End If

    value = ParseExpressionCore()

ElseIf modifiers.Any AndAlso modifiers.Any(SyntaxKind.OptionalKeyword) Then

    equals = ReportSyntaxError(InternalSyntaxFactory.MissingPunctuation(SyntaxKind.EqualsToken), ERRID.ERR_ObsoleteOptionalWithoutValue)
    value = ParseExpressionCore()

End If

Make the body of the second condition dependant on the feature's availability.

Dim initializer As EqualsValueSyntax = Nothing

If value IsNot Nothing Then

    If value.ContainsDiagnostics Then
        value = ResyncAt(value, SyntaxKind.CommaToken, SyntaxKind.CloseParenToken)
    End If

    initializer = SyntaxFactory.EqualsValue(equals, value)
End If

Return SyntaxFactory.Parameter(attributes, modifiers, paramName, optionalAsClause, initializer)

Depending on the code change, the following could be null value = nothing and equals = nothing. We would require to modify these conditions.

I do not see any potential issue within this function, when using the feature.

Syntax

SyntaxFactory.Parameter

Semantics

Overload Resolution

OverloadResolution.OptionalArgument (Potential Issue)

ParameterSymbol (Potential Issue)

''' <summary>
''' Returns the default value of this parameter. If <see cref="HasExplicitDefaultValue"/>
''' returns false, then this property throws an InvalidOperationException.
''' </summary>
Public ReadOnly Property ExplicitDefaultValue As Object
    Get
        If HasExplicitDefaultValue Then
            Return ExplicitDefaultConstantValue.Value
        End If

        Throw New InvalidOperationException
    End Get
End Property

This feature would not have an explicit default value, as it let's the coder not declare one. So the options are:-

Binding.Binder_Invocation (Potential Issue)

ljw1004 commented 8 years ago

I really like this feature. @AnthonyDGreen what do you think? @AdamSpeight2008 There are a few further areas of research to investigate...

  1. Metadata export. How would we export such a thing?
  2. Metadata import. I seem to remember that the VB compiler currently imports optional parameters that lack values, with the semantics you describe. Is this right? (Why? Under what circumstances? What exactly is the encoding in metadata?)
  3. COM. I seem to remember that COM is the chief area where there might be metadata that has optional parameters without default values. Is this right?
AdamSpeight2008 commented 8 years ago

@ljw1004 The current emit and metadata unit test pass. The major block is #12690, which is affects the ExpressionEvaluator unit tests. Overload resolution issue I think I fixed in [#12629](. commit: link

Analyser and CodeFix need a way of validating the presence of the Feature flag. (currently not of github) Or I could do a sample parse and check for the error, BC30812 Optional parameters must specify a default value. I think that is kind of hacky

AdamSpeight2008 commented 8 years ago

@ljw1004 @AnthonyDGreen

Reran the unit test after merging in Roslyn PR. They pass (No Failures) locally, waiting on the results of the Roslyn PR Build. When they pass I'll do a tidy up of the code to reduce the size of the pull request. Refactor some of the method names.