public static Task <Document> ChangeTypeAndAddAwaitAsync( Document document, VariableDeclarationSyntax variableDeclaration, VariableDeclaratorSyntax variableDeclarator, SyntaxNode containingDeclaration, ITypeSymbol newTypeSymbol, CancellationToken cancellationToken) { TypeSyntax type = variableDeclaration.Type; ExpressionSyntax value = variableDeclarator.Initializer.Value; AwaitExpressionSyntax newValue = AwaitExpression(value.WithoutTrivia()).WithTriviaFrom(value); TypeSyntax newType = ChangeType(type, newTypeSymbol); VariableDeclarationSyntax newVariableDeclaration = variableDeclaration .ReplaceNode(value, newValue) .WithType(newType); if (!SyntaxInfo.ModifierListInfo(containingDeclaration).IsAsync) { SyntaxNode newDeclaration = containingDeclaration .ReplaceNode(variableDeclaration, newVariableDeclaration) .InsertModifier(SyntaxKind.AsyncKeyword); return(document.ReplaceNodeAsync(containingDeclaration, newDeclaration, cancellationToken)); } return(document.ReplaceNodeAsync(variableDeclaration, newVariableDeclaration, cancellationToken)); }
/// <summary> /// Creates a new node with the specified explicit accessibility updated. /// </summary> /// <typeparam name="TNode"></typeparam> /// <param name="node"></param> /// <param name="newAccessibility"></param> /// <param name="comparer"></param> public static TNode WithExplicitAccessibility <TNode>( TNode node, Accessibility newAccessibility, IComparer <SyntaxKind> comparer = null) where TNode : SyntaxNode { if (node == null) { throw new ArgumentNullException(nameof(node)); } ModifierListInfo info = SyntaxInfo.ModifierListInfo(node); if (!info.Success) { throw new ArgumentException($"'{node.Kind()}' cannot have modifiers.", nameof(node)); } ModifierListInfo newInfo = info.WithExplicitAccessibility(newAccessibility, comparer); return((TNode)newInfo.Parent); }
public static Task <Document> ChangeTypeAndAddAwaitAsync( Document document, VariableDeclarationSyntax variableDeclaration, VariableDeclaratorSyntax variableDeclarator, SyntaxNode containingDeclaration, ITypeSymbol newTypeSymbol, CancellationToken cancellationToken) { VariableDeclarationSyntax newVariableDeclaration = SyntaxRefactorings.ChangeTypeAndAddAwait(variableDeclaration, variableDeclarator, newTypeSymbol); if (!SyntaxInfo.ModifierListInfo(containingDeclaration).IsAsync) { SyntaxNode newDeclaration = containingDeclaration .ReplaceNode(variableDeclaration, newVariableDeclaration) .InsertModifier(SyntaxKind.AsyncKeyword); return(document.ReplaceNodeAsync(containingDeclaration, newDeclaration, cancellationToken)); } return(document.ReplaceNodeAsync(variableDeclaration, newVariableDeclaration, cancellationToken)); }
/// <summary> /// Returns true if the node can have specified accessibility. /// </summary> /// <param name="node"></param> /// <param name="accessibility"></param> /// <param name="ignoreOverride">Ignore "override" modifier.</param> public static bool IsValidAccessibility(SyntaxNode node, Accessibility accessibility, bool ignoreOverride = false) { if (node == null) { throw new ArgumentNullException(nameof(node)); } switch (node.Parent?.Kind()) { case SyntaxKind.NamespaceDeclaration: case SyntaxKind.CompilationUnit: { return(accessibility.Is(Accessibility.Public, Accessibility.Internal)); } case SyntaxKind.StructDeclaration: case SyntaxKind.RecordStructDeclaration: { if (accessibility.ContainsProtected()) { return(false); } break; } } switch (node.Kind()) { case SyntaxKind.ClassDeclaration: case SyntaxKind.InterfaceDeclaration: case SyntaxKind.RecordDeclaration: case SyntaxKind.StructDeclaration: case SyntaxKind.RecordStructDeclaration: case SyntaxKind.EnumDeclaration: { return(true); } case SyntaxKind.EventDeclaration: { var eventDeclaration = (EventDeclarationSyntax)node; ModifierFilter filter = SyntaxInfo.ModifierListInfo(eventDeclaration).GetFilter(); return((ignoreOverride || !filter.HasAnyFlag(ModifierFilter.Override)) && (accessibility != Accessibility.Private || !filter.HasAnyFlag(ModifierFilter.AbstractVirtualOverride)) && CheckProtectedInStaticOrSealedClass(node) && CheckAccessorAccessibility(eventDeclaration.AccessorList)); } case SyntaxKind.IndexerDeclaration: { var indexerDeclaration = (IndexerDeclarationSyntax)node; ModifierFilter filter = SyntaxInfo.ModifierListInfo(indexerDeclaration).GetFilter(); return((ignoreOverride || !filter.HasAnyFlag(ModifierFilter.Override)) && (accessibility != Accessibility.Private || !filter.HasAnyFlag(ModifierFilter.AbstractVirtualOverride)) && CheckProtectedInStaticOrSealedClass(node) && CheckAccessorAccessibility(indexerDeclaration.AccessorList)); } case SyntaxKind.PropertyDeclaration: { var propertyDeclaration = (PropertyDeclarationSyntax)node; ModifierFilter filter = SyntaxInfo.ModifierListInfo(propertyDeclaration).GetFilter(); return((ignoreOverride || !filter.HasAnyFlag(ModifierFilter.Override)) && (accessibility != Accessibility.Private || !filter.HasAnyFlag(ModifierFilter.AbstractVirtualOverride)) && CheckProtectedInStaticOrSealedClass(node) && CheckAccessorAccessibility(propertyDeclaration.AccessorList)); } case SyntaxKind.MethodDeclaration: { var methodDeclaration = (MethodDeclarationSyntax)node; ModifierFilter filter = SyntaxInfo.ModifierListInfo(methodDeclaration).GetFilter(); return((ignoreOverride || !filter.HasAnyFlag(ModifierFilter.Override)) && (accessibility != Accessibility.Private || !filter.HasAnyFlag(ModifierFilter.AbstractVirtualOverride)) && CheckProtectedInStaticOrSealedClass(node)); } case SyntaxKind.EventFieldDeclaration: { var eventFieldDeclaration = (EventFieldDeclarationSyntax)node; ModifierFilter filter = SyntaxInfo.ModifierListInfo(eventFieldDeclaration).GetFilter(); return((ignoreOverride || !filter.HasAnyFlag(ModifierFilter.Override)) && (accessibility != Accessibility.Private || !filter.HasAnyFlag(ModifierFilter.AbstractVirtualOverride)) && CheckProtectedInStaticOrSealedClass(node)); } case SyntaxKind.ConstructorDeclaration: case SyntaxKind.DelegateDeclaration: case SyntaxKind.FieldDeclaration: case SyntaxKind.IncompleteMember: { return(CheckProtectedInStaticOrSealedClass(node)); } case SyntaxKind.OperatorDeclaration: case SyntaxKind.ConversionOperatorDeclaration: { return(accessibility == Accessibility.Public); } case SyntaxKind.GetAccessorDeclaration: case SyntaxKind.SetAccessorDeclaration: case SyntaxKind.AddAccessorDeclaration: case SyntaxKind.RemoveAccessorDeclaration: case SyntaxKind.InitAccessorDeclaration: case SyntaxKind.UnknownAccessorDeclaration: { var memberDeclaration = node.Parent?.Parent as MemberDeclarationSyntax; SyntaxDebug.Assert(memberDeclaration != null, node); if (memberDeclaration != null) { if (!CheckProtectedInStaticOrSealedClass(memberDeclaration)) { return(false); } return(accessibility.IsMoreRestrictiveThan(GetAccessibility(memberDeclaration))); } return(false); } case SyntaxKind.LocalFunctionStatement: { return(false); } default: { SyntaxDebug.Fail(node); return(false); } } bool CheckProtectedInStaticOrSealedClass(SyntaxNode declaration) { return(!accessibility.ContainsProtected() || (declaration.Parent as ClassDeclarationSyntax)? .Modifiers .ContainsAny(SyntaxKind.StaticKeyword, SyntaxKind.SealedKeyword) != true); } bool CheckAccessorAccessibility(AccessorListSyntax accessorList) { if (accessorList != null) { foreach (AccessorDeclarationSyntax accessor in accessorList.Accessors) { Accessibility accessorAccessibility = GetExplicitAccessibility(accessor.Modifiers); if (accessorAccessibility != Accessibility.NotApplicable) { return(accessorAccessibility.IsMoreRestrictiveThan(accessibility)); } } } return(true); } }