diff --git a/src/EditorFeatures/VisualBasicTest/EndConstructGeneration/PropertyBlockTests.vb b/src/EditorFeatures/VisualBasicTest/EndConstructGeneration/PropertyBlockTests.vb index 8fc339cde5fcfe064dbad524fa7ec2ff407599af..e7072a20c50090fc1494460a7811c7e2f52dcee7 100644 --- a/src/EditorFeatures/VisualBasicTest/EndConstructGeneration/PropertyBlockTests.vb +++ b/src/EditorFeatures/VisualBasicTest/EndConstructGeneration/PropertyBlockTests.vb @@ -6,7 +6,6 @@ Imports Microsoft.CodeAnalysis.VisualBasic Imports Microsoft.CodeAnalysis.VisualBasic.Symbols Imports Microsoft.CodeAnalysis.VisualBasic.Syntax Imports Microsoft.VisualStudio.Text -Imports Roslyn.Test.EditorUtilities Imports Roslyn.Test.Utilities Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.UnitTests.EndConstructGeneration diff --git a/src/Features/VisualBasic/CodeFixes/GenerateEndConstruct/GenerateEndConstructCodeFixProvider.vb b/src/Features/VisualBasic/CodeFixes/GenerateEndConstruct/GenerateEndConstructCodeFixProvider.vb index eeb7aa55ac46b24a3a5f0cc87f1db722052d4502..d04a9f2923826a7d07b1a8aa87fb233dad243b80 100644 --- a/src/Features/VisualBasic/CodeFixes/GenerateEndConstruct/GenerateEndConstructCodeFixProvider.vb +++ b/src/Features/VisualBasic/CodeFixes/GenerateEndConstruct/GenerateEndConstructCodeFixProvider.vb @@ -163,37 +163,14 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeFixes.GenerateEndConstruct updatedProperty = updatedProperty.ReplaceNode(setter, setter.WithEndBlockStatement(SyntaxFactory.EndSetStatement())) End If - Dim semanticModel = Await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(False) - Dim propertySymbol = TryCast(semanticModel.GetDeclaredSymbol(node), IPropertySymbol) - - If propertySymbol IsNot Nothing Then - Dim codeGenService = document.GetLanguageService(Of ICodeGenerationService)() - Dim syntaxFactory = document.GetLanguageService(Of SyntaxGenerator)() - - Dim generatedAccessor = CodeGenerationSymbolFactory.CreateAccessorSymbol(SpecializedCollections.EmptyList(Of AttributeData)(), - Accessibility.Public, - SpecializedCollections.EmptyList(Of SyntaxNode)()) - - Dim generatedProperty = CodeGenerationSymbolFactory.CreatePropertySymbol(attributes:=SpecializedCollections.EmptyList(Of AttributeData)(), - accessibility:=Accessibility.Public, - modifiers:=New DeclarationModifiers(), - explicitInterfaceSymbol:=Nothing, - name:=propertySymbol.Name, - type:=propertySymbol.Type, - parameters:=propertySymbol.Parameters, - getMethod:=generatedAccessor, - setMethod:=generatedAccessor, - isIndexer:=propertySymbol.IsIndexer) - ' Generate any missing setter or getter - Dim generatedPropertyCode = DirectCast(codeGenService.CreatePropertyDeclaration(generatedProperty, options:=CodeGenerationOptions.Default), PropertyBlockSyntax) - - If getter Is Nothing AndAlso Not updatedProperty.PropertyStatement.Modifiers.Any(SyntaxKind.WriteOnlyKeyword) Then - updatedProperty = updatedProperty.AddAccessors(generatedPropertyCode.Accessors.FirstOrDefault(Function(n) n.Kind = SyntaxKind.GetAccessorBlock)) - End If + Dim gen = document.GetLanguageService(Of SyntaxGenerator)() - If setter Is Nothing AndAlso Not updatedProperty.PropertyStatement.Modifiers.Any(SyntaxKind.ReadOnlyKeyword) Then - updatedProperty = updatedProperty.AddAccessors(generatedPropertyCode.Accessors.FirstOrDefault(Function(n) n.Kind = SyntaxKind.SetAccessorBlock)) - End If + If getter Is Nothing AndAlso Not updatedProperty.PropertyStatement.Modifiers.Any(SyntaxKind.WriteOnlyKeyword) Then + updatedProperty = DirectCast(gen.WithGetAccessorStatements(updatedProperty, {}), PropertyBlockSyntax) + End If + + If setter Is Nothing AndAlso Not updatedProperty.PropertyStatement.Modifiers.Any(SyntaxKind.ReadOnlyKeyword) Then + updatedProperty = DirectCast(gen.WithSetAccessorStatements(updatedProperty, {}), PropertyBlockSyntax) End If Dim updatedDocument = Await document.ReplaceNodeAsync(node, updatedProperty.WithAdditionalAnnotations(Formatter.Annotation), cancellationToken).ConfigureAwait(False) diff --git a/src/Workspaces/CSharp/Portable/CodeGeneration/CSharpSyntaxGenerator.cs b/src/Workspaces/CSharp/Portable/CodeGeneration/CSharpSyntaxGenerator.cs index cc7b8efb7497d953ccf326b05203d768fb9a40e6..a579fab8bbd8eb9e9b4702699a2626f31b2302ff 100644 --- a/src/Workspaces/CSharp/Portable/CodeGeneration/CSharpSyntaxGenerator.cs +++ b/src/Workspaces/CSharp/Portable/CodeGeneration/CSharpSyntaxGenerator.cs @@ -92,6 +92,9 @@ public override SyntaxNode NamespaceDeclaration(SyntaxNode name, IEnumerable), AsModifierList(accessibility, modifiers, SyntaxKind.FieldDeclaration), @@ -106,6 +109,9 @@ public override SyntaxNode NamespaceDeclaration(SyntaxNode name, IEnumerable), GetParameterModifiers(refKind), @@ -137,6 +143,9 @@ private SyntaxTokenList GetParameterModifiers(RefKind refKind) DeclarationModifiers modifiers, IEnumerable statements) { + parameters = this.ClearTrivia(parameters); + returnType = this.ClearTrivia(returnType); + bool hasBody = !modifiers.IsAbstract; return SyntaxFactory.MethodDeclaration( @@ -167,6 +176,9 @@ private ParameterListSyntax AsParameterList(IEnumerable parameters) IEnumerable baseConstructorArguments, IEnumerable statements) { + parameters = this.ClearTrivia(parameters); + baseConstructorArguments = this.ClearTrivia(baseConstructorArguments); + return SyntaxFactory.ConstructorDeclaration( default(SyntaxList), AsModifierList(accessibility, modifiers, SyntaxKind.ConstructorDeclaration), @@ -184,6 +196,8 @@ private ParameterListSyntax AsParameterList(IEnumerable parameters) IEnumerable getAccessorStatements, IEnumerable setAccessorStatements) { + type = this.ClearTrivia(type); + var accessors = new List(); var hasSetter = !modifiers.IsReadOnly; @@ -229,6 +243,8 @@ private ParameterListSyntax AsParameterList(IEnumerable parameters) IEnumerable getAccessorStatements, IEnumerable setAccessorStatements) { + type = this.ClearTrivia(type); + var accessors = new List(); var hasSetter = !modifiers.IsReadOnly; @@ -293,6 +309,8 @@ private AccessorDeclarationSyntax AccessorDeclaration(SyntaxKind kind, IEnumerab Accessibility accessibility, DeclarationModifiers modifiers) { + type = this.ClearTrivia(type); + return SyntaxFactory.EventFieldDeclaration( default(SyntaxList), AsModifierList(accessibility, modifiers, SyntaxKind.EventFieldDeclaration), @@ -311,6 +329,9 @@ private AccessorDeclarationSyntax AccessorDeclaration(SyntaxKind kind, IEnumerab IEnumerable addAccessorStatements, IEnumerable removeAccessorStatements) { + type = this.ClearTrivia(type); + parameters = this.ClearTrivia(parameters); + var accessors = new List(); if (modifiers.IsAbstract) { @@ -350,6 +371,8 @@ public override SyntaxNode AsPublicInterfaceImplementation(SyntaxNode declaratio public override SyntaxNode AsPrivateInterfaceImplementation(SyntaxNode declaration, SyntaxNode typeName) { + typeName = this.ClearTrivia(typeName); + return PreserveTrivia(declaration, d => { var specifier = SyntaxFactory.ExplicitInterfaceSpecifier((NameSyntax)typeName); @@ -468,9 +491,12 @@ private AccessorDeclarationSyntax WithoutBody(AccessorDeclarationSyntax accessor Accessibility accessibility, DeclarationModifiers modifiers, SyntaxNode baseType, - IEnumerable interfaceTypes, + IEnumerable interfaceTypes, IEnumerable members) { + baseType = this.ClearTrivia(baseType); + interfaceTypes = this.ClearTrivia(interfaceTypes); + List baseTypes = null; if (baseType != null || interfaceTypes != null) { @@ -534,6 +560,8 @@ private MemberDeclarationSyntax AsClassMember(SyntaxNode node, string className) IEnumerable interfaceTypes, IEnumerable members) { + interfaceTypes = this.ClearTrivia(interfaceTypes); + var itypes = interfaceTypes != null ? interfaceTypes.Select(i => (BaseTypeSyntax)SyntaxFactory.SimpleBaseType((TypeSyntax)i)).ToList() : null; if (itypes != null && itypes.Count == 0) { @@ -557,6 +585,8 @@ private MemberDeclarationSyntax AsClassMember(SyntaxNode node, string className) IEnumerable interfaceTypes = null, IEnumerable members = null) { + interfaceTypes = this.ClearTrivia(interfaceTypes); + var itypes = interfaceTypes != null ? interfaceTypes.Select(i => (BaseTypeSyntax)SyntaxFactory.SimpleBaseType((TypeSyntax)i)).ToList() : null; if (itypes != null && itypes.Count == 0) { @@ -649,6 +679,8 @@ private SyntaxNode AsInterfaceMember(SyntaxNode m) public override SyntaxNode EnumMember(string name, SyntaxNode expression) { + expression = this.ClearTrivia(expression); + return SyntaxFactory.EnumMemberDeclaration( default(SyntaxList), name.ToIdentifierToken(), @@ -689,6 +721,9 @@ private SeparatedSyntaxList AsEnumMembers(IEnumerab Accessibility accessibility = Accessibility.NotApplicable, DeclarationModifiers modifiers = default(DeclarationModifiers)) { + parameters = this.ClearTrivia(parameters); + returnType = this.ClearTrivia(returnType); + return SyntaxFactory.DelegateDeclaration( default(SyntaxList), AsModifierList(accessibility, modifiers), @@ -742,8 +777,15 @@ private AttributeArgumentSyntax AsAttributeArgument(SyntaxNode node) protected override TNode ClearTrivia(TNode node) { - return node.WithLeadingTrivia(SyntaxFactory.ElasticMarker) - .WithTrailingTrivia(SyntaxFactory.ElasticMarker); + if (node != null) + { + return node.WithLeadingTrivia(SyntaxFactory.ElasticMarker) + .WithTrailingTrivia(SyntaxFactory.ElasticMarker); + } + else + { + return null; + } } private SyntaxList AsAttributeLists(IEnumerable attributes) diff --git a/src/Workspaces/VisualBasic/Portable/CodeGeneration/VisualBasicSyntaxGenerator.vb b/src/Workspaces/VisualBasic/Portable/CodeGeneration/VisualBasicSyntaxGenerator.vb index 683af0535026bb958c41bb974916b7185d75bb42..3fe8da512fc6657629090659316bab75310317d4 100644 --- a/src/Workspaces/VisualBasic/Portable/CodeGeneration/VisualBasicSyntaxGenerator.vb +++ b/src/Workspaces/VisualBasic/Portable/CodeGeneration/VisualBasicSyntaxGenerator.vb @@ -576,6 +576,9 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeGeneration End Function Public Overrides Function FieldDeclaration(name As String, type As SyntaxNode, Optional accessibility As Accessibility = Nothing, Optional modifiers As DeclarationModifiers = Nothing, Optional initializer As SyntaxNode = Nothing) As SyntaxNode + type = Me.ClearTrivia(type) + initializer = Me.ClearTrivia(initializer) + Return SyntaxFactory.FieldDeclaration( attributeLists:=Nothing, modifiers:=GetModifierList(accessibility, modifiers And fieldModifiers, isField:=True), @@ -591,6 +594,9 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeGeneration Optional modifiers As DeclarationModifiers = Nothing, Optional statements As IEnumerable(Of SyntaxNode) = Nothing) As SyntaxNode + parameters = MyBase.ClearTrivia(parameters) + returnType = Me.ClearTrivia(returnType) + Dim statement = SyntaxFactory.MethodStatement( kind:=If(returnType Is Nothing, SyntaxKind.SubStatement, SyntaxKind.FunctionStatement), attributeLists:=Nothing, @@ -619,6 +625,8 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeGeneration End Function Public Overrides Function ParameterDeclaration(name As String, Optional type As SyntaxNode = Nothing, Optional initializer As SyntaxNode = Nothing, Optional refKind As RefKind = Nothing) As SyntaxNode + type = Me.ClearTrivia(type) + Return SyntaxFactory.Parameter( attributeLists:=Nothing, modifiers:=GetParameterModifiers(refKind, initializer), @@ -646,6 +654,8 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeGeneration Optional getAccessorStatements As IEnumerable(Of SyntaxNode) = Nothing, Optional setAccessorStatements As IEnumerable(Of SyntaxNode) = Nothing) As SyntaxNode + type = Me.ClearTrivia(type) + Dim asClause = SyntaxFactory.SimpleAsClause(DirectCast(type, TypeSyntax)) Dim statement = SyntaxFactory.PropertyStatement( attributeLists:=Nothing, @@ -682,6 +692,9 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeGeneration Optional getAccessorStatements As IEnumerable(Of SyntaxNode) = Nothing, Optional setAccessorStatements As IEnumerable(Of SyntaxNode) = Nothing) As SyntaxNode + type = ClearTrivia(type) + parameters = MyBase.ClearTrivia(parameters) + Dim asClause = SyntaxFactory.SimpleAsClause(DirectCast(type, TypeSyntax)) Dim statement = SyntaxFactory.PropertyStatement( attributeLists:=Nothing, @@ -711,6 +724,8 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeGeneration End Function Private Function AccessorBlock(kind As SyntaxKind, statements As IEnumerable(Of SyntaxNode), type As SyntaxNode) As AccessorBlockSyntax + type = Me.ClearTrivia(type) + Select Case kind Case SyntaxKind.GetAccessorBlock Return CreateGetAccessorBlock(statements) @@ -734,6 +749,8 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeGeneration End Function Private Function CreateSetAccessorBlock(type As SyntaxNode, statements As IEnumerable(Of SyntaxNode)) As AccessorBlockSyntax + type = Me.ClearTrivia(type) + Dim asClause = SyntaxFactory.SimpleAsClause(DirectCast(type, TypeSyntax)) Dim valueParameter = SyntaxFactory.Parameter( @@ -756,6 +773,8 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeGeneration End Function Private Function CreateAddHandlerAccessorBlock(delegateType As SyntaxNode, statements As IEnumerable(Of SyntaxNode)) As AccessorBlockSyntax + delegateType = Me.ClearTrivia(delegateType) + Dim asClause = SyntaxFactory.SimpleAsClause(DirectCast(delegateType, TypeSyntax)) Dim valueParameter = SyntaxFactory.Parameter( @@ -778,6 +797,8 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeGeneration End Function Private Function CreateRemoveHandlerAccessorBlock(delegateType As SyntaxNode, statements As IEnumerable(Of SyntaxNode)) As AccessorBlockSyntax + delegateType = Me.ClearTrivia(delegateType) + Dim asClause = SyntaxFactory.SimpleAsClause(DirectCast(delegateType, TypeSyntax)) Dim valueParameter = SyntaxFactory.Parameter( @@ -800,6 +821,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeGeneration End Function Private Function CreateRaiseEventAccessorBlock(parameters As IEnumerable(Of SyntaxNode), statements As IEnumerable(Of SyntaxNode)) As AccessorBlockSyntax + parameters = MyBase.ClearTrivia(parameters) Dim parameterList = GetParameterList(parameters) Return SyntaxFactory.AccessorBlock( @@ -815,6 +837,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeGeneration End Function Public Overrides Function AsPublicInterfaceImplementation(declaration As SyntaxNode, typeName As SyntaxNode) As SyntaxNode + typeName = Me.ClearTrivia(typeName) Dim type = DirectCast(typeName, NameSyntax) declaration = AsImplementation(declaration, Accessibility.Public, allowDefault:=True) @@ -837,6 +860,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeGeneration End Function Public Overrides Function AsPrivateInterfaceImplementation(declaration As SyntaxNode, typeName As SyntaxNode) As SyntaxNode + typeName = Me.ClearTrivia(typeName) Dim type = DirectCast(typeName, NameSyntax) ' convert declaration statements to blocks @@ -947,6 +971,9 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeGeneration Optional baseConstructorArguments As IEnumerable(Of SyntaxNode) = Nothing, Optional statements As IEnumerable(Of SyntaxNode) = Nothing) As SyntaxNode + parameters = MyBase.ClearTrivia(parameters) + baseConstructorArguments = MyBase.ClearTrivia(baseConstructorArguments) + Dim stats = GetStatementList(statements) If (baseConstructorArguments IsNot Nothing) Then @@ -971,6 +998,9 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeGeneration Optional interfaceTypes As IEnumerable(Of SyntaxNode) = Nothing, Optional members As IEnumerable(Of SyntaxNode) = Nothing) As SyntaxNode + baseType = Me.ClearTrivia(baseType) + interfaceTypes = MyBase.ClearTrivia(interfaceTypes) + Dim itypes = If(interfaceTypes IsNot Nothing, interfaceTypes.Cast(Of TypeSyntax), Nothing) If itypes IsNot Nothing AndAlso itypes.Count = 0 Then itypes = Nothing @@ -1007,6 +1037,8 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeGeneration Optional interfaceTypes As IEnumerable(Of SyntaxNode) = Nothing, Optional members As IEnumerable(Of SyntaxNode) = Nothing) As SyntaxNode + interfaceTypes = MyBase.ClearTrivia(interfaceTypes) + Dim itypes = If(interfaceTypes IsNot Nothing, interfaceTypes.Cast(Of TypeSyntax), Nothing) If itypes IsNot Nothing AndAlso itypes.Count = 0 Then itypes = Nothing @@ -1042,6 +1074,8 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeGeneration Optional interfaceTypes As IEnumerable(Of SyntaxNode) = Nothing, Optional members As IEnumerable(Of SyntaxNode) = Nothing) As SyntaxNode + interfaceTypes = MyBase.ClearTrivia(interfaceTypes) + Dim itypes = If(interfaceTypes IsNot Nothing, interfaceTypes.Cast(Of TypeSyntax), Nothing) If itypes IsNot Nothing AndAlso itypes.Count = 0 Then itypes = Nothing @@ -1135,6 +1169,8 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeGeneration Optional accessibility As Accessibility = Accessibility.NotApplicable, Optional modifiers As DeclarationModifiers = Nothing) As SyntaxNode + parameters = MyBase.ClearTrivia(parameters) + Dim kind = If(returnType Is Nothing, SyntaxKind.DelegateSubStatement, SyntaxKind.DelegateFunctionStatement) Return SyntaxFactory.DelegateStatement( @@ -1169,10 +1205,13 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeGeneration End Function Public Overrides Function NamespaceImportDeclaration(name As SyntaxNode) As SyntaxNode + name = Me.ClearTrivia(name) Return SyntaxFactory.ImportsStatement(SyntaxFactory.SingletonSeparatedList(Of ImportsClauseSyntax)(SyntaxFactory.SimpleImportsClause(DirectCast(name, NameSyntax)))) End Function Public Overrides Function NamespaceDeclaration(name As SyntaxNode, nestedDeclarations As IEnumerable(Of SyntaxNode)) As SyntaxNode + name = Me.ClearTrivia(name) + Dim imps As IEnumerable(Of StatementSyntax) = AsImports(nestedDeclarations) Dim members As IEnumerable(Of StatementSyntax) = AsNamespaceMembers(nestedDeclarations) @@ -1185,6 +1224,9 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeGeneration End Function Public Overrides Function Attribute(name As SyntaxNode, Optional attributeArguments As IEnumerable(Of SyntaxNode) = Nothing) As SyntaxNode + name = Me.ClearTrivia(name) + attributeArguments = MyBase.ClearTrivia(attributeArguments) + Dim attr = SyntaxFactory.Attribute( target:=Nothing, name:=DirectCast(name, TypeSyntax), @@ -1202,6 +1244,8 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeGeneration End Function Public Overrides Function AttributeArgument(name As String, expression As SyntaxNode) As SyntaxNode + expression = Me.ClearTrivia(expression) + Return Argument(name, RefKind.None, expression) End Function