| File: Parser\BlockContexts\PropertyBlockContext.vb | Web Access |
| Project: src\roslyn\src\Compilers\VisualBasic\Portable\Microsoft.CodeAnalysis.VisualBasic.vbproj (Microsoft.CodeAnalysis.VisualBasic) |
' Licensed to the .NET Foundation under one or more agreements. ' The .NET Foundation licenses this file to you under the MIT license. ' See the LICENSE file in the project root for more information. Imports Microsoft.CodeAnalysis.Text Imports Microsoft.CodeAnalysis.VisualBasic.Symbols Imports Microsoft.CodeAnalysis.VisualBasic.Syntax '----------------------------------------------------------------------------- ' Contains the definition of the BlockContext '----------------------------------------------------------------------------- Namespace Microsoft.CodeAnalysis.VisualBasic.Syntax.InternalSyntax Friend NotInheritable Class PropertyBlockContext Inherits DeclarationContext Private ReadOnly _isPropertyBlock As Boolean Friend Sub New(statement As StatementSyntax, prevContext As BlockContext, isPropertyBlock As Boolean) MyBase.New(SyntaxKind.PropertyBlock, statement, prevContext) _isPropertyBlock = isPropertyBlock End Sub Private ReadOnly Property IsPropertyBlock As Boolean Get Return _isPropertyBlock OrElse Statements.Count > 0 End Get End Property Friend Overrides Function CreateBlockSyntax(endStmt As StatementSyntax) As VisualBasicSyntaxNode Dim beginBlockStmt As PropertyStatementSyntax = Nothing Dim endBlockStmt As EndBlockStatementSyntax = DirectCast(endStmt, EndBlockStatementSyntax) GetBeginEndStatements(beginBlockStmt, endBlockStmt) Dim accessors = _statements.ToList(Of AccessorBlockSyntax)() FreeStatements() ' We can only get here if this is a block property but still check accessor count. If accessors.Any Then ' Only auto properties can be initialized. If there is a Get or Set accessor then it is an error. beginBlockStmt = ReportErrorIfHasInitializer(beginBlockStmt) End If Return SyntaxFactory.PropertyBlock(beginBlockStmt, accessors, endBlockStmt) End Function Friend Overrides Function ProcessSyntax(node As VisualBasicSyntaxNode) As BlockContext Select Case node.Kind Case SyntaxKind.GetAccessorStatement Return New MethodBlockContext(SyntaxKind.GetAccessorBlock, DirectCast(node, StatementSyntax), Me) Case SyntaxKind.SetAccessorStatement ' Checks for duplicate GET/SET are deferred to declared per Dev10 code Return New MethodBlockContext(SyntaxKind.SetAccessorBlock, DirectCast(node, StatementSyntax), Me) Case SyntaxKind.GetAccessorBlock, SyntaxKind.SetAccessorBlock ' Handle any block created by this context Add(node) Case Else ' TODO - In Dev10, the code tries to report ERRID_PropertyMemberSyntax. This would occur prior to auto properties ' when the statement was a malformed declaration. However, due to autoproperties this no longer seems possible. ' test should confirm that this error can no longer be produced in Dev10. Is it worth trying to preserve this behavior? Dim context As BlockContext = EndBlock(Nothing) Debug.Assert(context Is PrevBlock) If IsPropertyBlock Then ' Property blocks can only contain Get and Set. node = Parser.ReportSyntaxError(node, ERRID.ERR_InvInsideEndsProperty) End If ' Let the outer context process this statement Return context.ProcessSyntax(node) End Select Return Me End Function Friend Overrides Function TryLinkSyntax(node As VisualBasicSyntaxNode, ByRef newContext As BlockContext) As LinkResult newContext = Nothing If KindEndsBlock(node.Kind) Then Return UseSyntax(node, newContext) End If Select Case node.Kind Case _ SyntaxKind.GetAccessorStatement, SyntaxKind.SetAccessorStatement Return UseSyntax(node, newContext) Case SyntaxKind.GetAccessorBlock, SyntaxKind.SetAccessorBlock Return UseSyntax(node, newContext, DirectCast(node, AccessorBlockSyntax).End.IsMissing) Case Else newContext = Me Return LinkResult.Crumble End Select End Function Friend Overrides Function EndBlock(endStmt As StatementSyntax) As BlockContext If IsPropertyBlock OrElse endStmt IsNot Nothing Then Return MyBase.EndBlock(endStmt) End If ' This is an auto property. Do not create a block. Just add the property statement to the outer block ' TODO - Consider changing the kind to AutoProperty. For now auto properties are just PropertyStatement ' whose parent is not a PropertyBlock. Don't create a missing end for an auto property Debug.Assert(PrevBlock IsNot Nothing) Debug.Assert(Statements.Count = 0) Dim beginBlockStmt As PropertyStatementSyntax = DirectCast(BeginStatement, PropertyStatementSyntax) ' Check if auto property has params If beginBlockStmt.ParameterList IsNot Nothing AndAlso beginBlockStmt.ParameterList.Parameters.Count > 0 Then beginBlockStmt = New PropertyStatementSyntax(beginBlockStmt.Kind, beginBlockStmt.AttributeLists.Node, beginBlockStmt.Modifiers.Node, beginBlockStmt.PropertyKeyword, beginBlockStmt.Identifier, Parser.ReportSyntaxError(beginBlockStmt.ParameterList, ERRID.ERR_AutoPropertyCantHaveParams), beginBlockStmt.AsClause, beginBlockStmt.Initializer, beginBlockStmt.ImplementsClause) End If 'Add auto property to Prev context. DO NOT call ProcessSyntax because that will create a PropertyContext. ' Just add the statement to the context. Dim context = PrevBlock context.Add(beginBlockStmt) Return context End Function Friend Shared Function ReportErrorIfHasInitializer(propertyStatement As PropertyStatementSyntax) As PropertyStatementSyntax If propertyStatement.Initializer IsNot Nothing OrElse ( propertyStatement.AsClause IsNot Nothing AndAlso TryCast(propertyStatement.AsClause, AsNewClauseSyntax) IsNot Nothing ) Then propertyStatement = Parser.ReportSyntaxError(propertyStatement, ERRID.ERR_InitializedExpandedProperty) 'TODO - In Dev10 resources there is an unused resource ERRID.ERR_NewExpandedProperty for the new case. ' Is it worthwhile adding to Dev12? End If Return propertyStatement End Function End Class End Namespace