private static TupleExpressionSyntax CreateTupleExpression(ITypeSymbol typeSymbol) { if (!typeSymbol.SupportsExplicitDeclaration()) { throw new ArgumentException($"Type '{typeSymbol.ToDisplayString()}' does not support explicit declaration.", nameof(typeSymbol)); } var tupleExpression = (TupleExpressionSyntax)ParseExpression(typeSymbol.ToDisplayString(SymbolDisplayFormats.FullName)); SeparatedSyntaxList <ArgumentSyntax> newArguments = tupleExpression .Arguments .Select(f => { if (f.Expression is DeclarationExpressionSyntax declarationExpression) { return(f.WithExpression(declarationExpression.WithType(declarationExpression.Type.WithSimplifierAnnotation()))); } SyntaxDebug.Fail(f.Expression); return(f); }) .ToSeparatedSyntaxList(); return(tupleExpression.WithArguments(newArguments)); }
public static Task <Document> ChangeTypeAsync( Document document, TypeSyntax type, ITypeSymbol typeSymbol, CancellationToken cancellationToken = default) { if (type.IsVar && type.Parent is DeclarationExpressionSyntax declarationExpression && declarationExpression.Designation.IsKind(SyntaxKind.ParenthesizedVariableDesignation)) { #if DEBUG SyntaxNode parent = declarationExpression.Parent; switch (parent.Kind()) { case SyntaxKind.SimpleAssignmentExpression: { var assignmentExpression = (AssignmentExpressionSyntax)parent; Debug.Assert(object.ReferenceEquals(assignmentExpression.Left, declarationExpression)); break; } case SyntaxKind.ForEachVariableStatement: { var forEachStatement = (ForEachVariableStatementSyntax)parent; Debug.Assert(object.ReferenceEquals(forEachStatement.Variable, declarationExpression)); break; } default: { SyntaxDebug.Fail(parent); break; } } #endif TupleExpressionSyntax tupleExpression = CreateTupleExpression(typeSymbol) .WithTriviaFrom(declarationExpression); return(document.ReplaceNodeAsync(declarationExpression, tupleExpression, cancellationToken)); } TypeSyntax newType = ChangeType(type, typeSymbol); return(document.ReplaceNodeAsync(type, newType, cancellationToken)); }
public override Accessibility GetAccessibility(AccessorDeclarationSyntax declaration) { if (declaration == null) { throw new ArgumentNullException(nameof(declaration)); } Accessibility accessibility = SyntaxAccessibility.GetExplicitAccessibility(declaration.Modifiers); SyntaxNode containingDeclaration = declaration.Parent?.Parent; if (containingDeclaration == null) { return(accessibility); } Accessibility containingAccessibility = GetAccessibility(); if (containingAccessibility == Accessibility.NotApplicable) { return(accessibility); } return((accessibility.IsMoreRestrictiveThan(containingAccessibility)) ? accessibility : containingAccessibility); Accessibility GetAccessibility() { switch (containingDeclaration.Kind()) { case SyntaxKind.PropertyDeclaration: return(SyntaxAccessibility <PropertyDeclarationSyntax> .Instance.GetAccessibility((PropertyDeclarationSyntax)containingDeclaration)); case SyntaxKind.IndexerDeclaration: return(SyntaxAccessibility <IndexerDeclarationSyntax> .Instance.GetAccessibility((IndexerDeclarationSyntax)containingDeclaration)); case SyntaxKind.EventDeclaration: return(SyntaxAccessibility <EventDeclarationSyntax> .Instance.GetAccessibility((EventDeclarationSyntax)containingDeclaration)); } SyntaxDebug.Fail(containingDeclaration); return(Accessibility.NotApplicable); } }
internal static string GetTitle(SyntaxNode node) { switch (node.Kind()) { case SyntaxKind.IfStatement: return("if statement"); case SyntaxKind.ElseClause: return("else clause"); case SyntaxKind.DoStatement: return("do statement"); case SyntaxKind.ForEachStatement: case SyntaxKind.ForEachVariableStatement: return("foreach statement"); case SyntaxKind.ForStatement: return("for statement"); case SyntaxKind.UsingStatement: return("using statement"); case SyntaxKind.WhileStatement: return("while statement"); case SyntaxKind.LockStatement: return("lock statement"); case SyntaxKind.FixedStatement: return("fixed statement"); case SyntaxKind.SwitchStatement: return("switch statement"); case SyntaxKind.BreakStatement: return("break statement"); case SyntaxKind.ContinueStatement: return("continue statement"); case SyntaxKind.ReturnStatement: return("return statement"); case SyntaxKind.YieldReturnStatement: return("yield return statement"); case SyntaxKind.YieldBreakStatement: return("yield break statement"); case SyntaxKind.MethodDeclaration: return("method"); case SyntaxKind.OperatorDeclaration: return("operator"); case SyntaxKind.ConversionOperatorDeclaration: return("conversion operator"); case SyntaxKind.ConstructorDeclaration: return("constructor"); case SyntaxKind.DestructorDeclaration: return("destructor"); case SyntaxKind.PropertyDeclaration: return("property"); case SyntaxKind.IndexerDeclaration: return("indexer"); case SyntaxKind.EventDeclaration: case SyntaxKind.EventFieldDeclaration: return("event"); case SyntaxKind.FieldDeclaration: return((((FieldDeclarationSyntax)node).Modifiers.Contains(SyntaxKind.ConstKeyword)) ? "const" : "field"); case SyntaxKind.DelegateDeclaration: return("delegate"); case SyntaxKind.NamespaceDeclaration: return("namespace"); case SyntaxKind.ClassDeclaration: return("class"); case SyntaxKind.StructDeclaration: return("struct"); case SyntaxKind.InterfaceDeclaration: return("interface"); case SyntaxKind.EnumDeclaration: return("enum"); case SyntaxKind.RecordDeclaration: case SyntaxKind.RecordStructDeclaration: return("record"); case SyntaxKind.IncompleteMember: return("member"); case SyntaxKind.GetAccessorDeclaration: case SyntaxKind.SetAccessorDeclaration: case SyntaxKind.InitAccessorDeclaration: case SyntaxKind.AddAccessorDeclaration: case SyntaxKind.RemoveAccessorDeclaration: case SyntaxKind.UnknownAccessorDeclaration: return("accessor"); case SyntaxKind.LocalDeclarationStatement: return("local declaration"); case SyntaxKind.LocalFunctionStatement: return("local function"); case SyntaxKind.Parameter: return("parameter"); default: { SyntaxDebug.Fail(node); if (node is StatementSyntax) { return("statement"); } if (node is MemberDeclarationSyntax) { return("member"); } throw new ArgumentException("", nameof(node)); } } }
/// <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); } }
/// <summary> /// Returns an explicit accessibility of the specified declaration. /// </summary> /// <param name="declaration"></param> public static Accessibility GetExplicitAccessibility(SyntaxNode declaration) { if (declaration == null) { throw new ArgumentNullException(nameof(declaration)); } switch (declaration.Kind()) { case SyntaxKind.ConstructorDeclaration: return(SyntaxAccessibility <ConstructorDeclarationSyntax> .Instance.GetExplicitAccessibility((ConstructorDeclarationSyntax)declaration)); case SyntaxKind.DestructorDeclaration: return(SyntaxAccessibility <DestructorDeclarationSyntax> .Instance.GetExplicitAccessibility((DestructorDeclarationSyntax)declaration)); case SyntaxKind.MethodDeclaration: return(SyntaxAccessibility <MethodDeclarationSyntax> .Instance.GetExplicitAccessibility((MethodDeclarationSyntax)declaration)); case SyntaxKind.PropertyDeclaration: return(SyntaxAccessibility <PropertyDeclarationSyntax> .Instance.GetExplicitAccessibility((PropertyDeclarationSyntax)declaration)); case SyntaxKind.IndexerDeclaration: return(SyntaxAccessibility <IndexerDeclarationSyntax> .Instance.GetExplicitAccessibility((IndexerDeclarationSyntax)declaration)); case SyntaxKind.EventDeclaration: return(SyntaxAccessibility <EventDeclarationSyntax> .Instance.GetExplicitAccessibility((EventDeclarationSyntax)declaration)); case SyntaxKind.EventFieldDeclaration: return(SyntaxAccessibility <EventFieldDeclarationSyntax> .Instance.GetExplicitAccessibility((EventFieldDeclarationSyntax)declaration)); case SyntaxKind.FieldDeclaration: return(SyntaxAccessibility <FieldDeclarationSyntax> .Instance.GetExplicitAccessibility((FieldDeclarationSyntax)declaration)); case SyntaxKind.OperatorDeclaration: return(SyntaxAccessibility <OperatorDeclarationSyntax> .Instance.GetExplicitAccessibility((OperatorDeclarationSyntax)declaration)); case SyntaxKind.ConversionOperatorDeclaration: return(SyntaxAccessibility <ConversionOperatorDeclarationSyntax> .Instance.GetExplicitAccessibility((ConversionOperatorDeclarationSyntax)declaration)); case SyntaxKind.ClassDeclaration: return(SyntaxAccessibility <ClassDeclarationSyntax> .Instance.GetExplicitAccessibility((ClassDeclarationSyntax)declaration)); case SyntaxKind.RecordDeclaration: case SyntaxKind.RecordStructDeclaration: return(SyntaxAccessibility <RecordDeclarationSyntax> .Instance.GetExplicitAccessibility((RecordDeclarationSyntax)declaration)); case SyntaxKind.StructDeclaration: return(SyntaxAccessibility <StructDeclarationSyntax> .Instance.GetExplicitAccessibility((StructDeclarationSyntax)declaration)); case SyntaxKind.InterfaceDeclaration: return(SyntaxAccessibility <InterfaceDeclarationSyntax> .Instance.GetExplicitAccessibility((InterfaceDeclarationSyntax)declaration)); case SyntaxKind.EnumDeclaration: return(SyntaxAccessibility <EnumDeclarationSyntax> .Instance.GetExplicitAccessibility((EnumDeclarationSyntax)declaration)); case SyntaxKind.DelegateDeclaration: return(SyntaxAccessibility <DelegateDeclarationSyntax> .Instance.GetExplicitAccessibility((DelegateDeclarationSyntax)declaration)); case SyntaxKind.EnumMemberDeclaration: return(SyntaxAccessibility <EnumMemberDeclarationSyntax> .Instance.GetExplicitAccessibility((EnumMemberDeclarationSyntax)declaration)); case SyntaxKind.NamespaceDeclaration: return(SyntaxAccessibility <NamespaceDeclarationSyntax> .Instance.GetExplicitAccessibility((NamespaceDeclarationSyntax)declaration)); case SyntaxKind.GetAccessorDeclaration: case SyntaxKind.SetAccessorDeclaration: case SyntaxKind.AddAccessorDeclaration: case SyntaxKind.RemoveAccessorDeclaration: case SyntaxKind.UnknownAccessorDeclaration: return(SyntaxAccessibility <AccessorDeclarationSyntax> .Instance.GetExplicitAccessibility((AccessorDeclarationSyntax)declaration)); case SyntaxKind.IncompleteMember: return(SyntaxAccessibility <IncompleteMemberSyntax> .Instance.GetExplicitAccessibility((IncompleteMemberSyntax)declaration)); } SyntaxDebug.Fail(declaration); return(Accessibility.NotApplicable); }
private static SourceText RemovePreprocessorDirectives( SourceText sourceText, IEnumerable <DirectiveTriviaSyntax> directives, PreprocessorDirectiveFilter directiveFilter) { return(sourceText.WithChanges(GetTextChanges())); IEnumerable <TextChange> GetTextChanges() { TextLineCollection lines = sourceText.Lines; foreach (DirectiveTriviaSyntax directive in directives) { if (ShouldRemoveDirective(directive)) { int startLine = directive.GetSpanStartLine(); yield return(new TextChange(lines[startLine].SpanIncludingLineBreak, "")); } } } bool ShouldRemoveDirective(DirectiveTriviaSyntax directive) { switch (directive.Kind()) { case SyntaxKind.IfDirectiveTrivia: return((directiveFilter & PreprocessorDirectiveFilter.If) != 0); case SyntaxKind.ElifDirectiveTrivia: return((directiveFilter & PreprocessorDirectiveFilter.Elif) != 0); case SyntaxKind.ElseDirectiveTrivia: return((directiveFilter & PreprocessorDirectiveFilter.Else) != 0); case SyntaxKind.EndIfDirectiveTrivia: return((directiveFilter & PreprocessorDirectiveFilter.EndIf) != 0); case SyntaxKind.RegionDirectiveTrivia: return((directiveFilter & PreprocessorDirectiveFilter.Region) != 0); case SyntaxKind.EndRegionDirectiveTrivia: return((directiveFilter & PreprocessorDirectiveFilter.EndRegion) != 0); case SyntaxKind.DefineDirectiveTrivia: return((directiveFilter & PreprocessorDirectiveFilter.Define) != 0); case SyntaxKind.UndefDirectiveTrivia: return((directiveFilter & PreprocessorDirectiveFilter.Undef) != 0); case SyntaxKind.ErrorDirectiveTrivia: return((directiveFilter & PreprocessorDirectiveFilter.Error) != 0); case SyntaxKind.WarningDirectiveTrivia: return((directiveFilter & PreprocessorDirectiveFilter.Warning) != 0); case SyntaxKind.LineDirectiveTrivia: return((directiveFilter & PreprocessorDirectiveFilter.Line) != 0); case SyntaxKind.PragmaWarningDirectiveTrivia: return((directiveFilter & PreprocessorDirectiveFilter.PragmaWarning) != 0); case SyntaxKind.PragmaChecksumDirectiveTrivia: return((directiveFilter & PreprocessorDirectiveFilter.PragmaChecksum) != 0); case SyntaxKind.ReferenceDirectiveTrivia: return((directiveFilter & PreprocessorDirectiveFilter.Reference) != 0); case SyntaxKind.BadDirectiveTrivia: return((directiveFilter & PreprocessorDirectiveFilter.Bad) != 0); case SyntaxKind.ShebangDirectiveTrivia: return((directiveFilter & PreprocessorDirectiveFilter.Shebang) != 0); case SyntaxKind.LoadDirectiveTrivia: return((directiveFilter & PreprocessorDirectiveFilter.Load) != 0); case SyntaxKind.NullableDirectiveTrivia: return((directiveFilter & PreprocessorDirectiveFilter.Nullable) != 0); } SyntaxDebug.Fail(directive); return(false); } }
public static Task <Document> ToSingleLineAsync( Document document, InitializerExpressionSyntax initializer, bool removeTrailingComma = false, CancellationToken cancellationToken = default) { InitializerExpressionSyntax newInitializer = initializer .ReplaceWhitespace(ElasticSpace, TextSpan.FromBounds(initializer.SpanStart, initializer.Span.End)) .WithFormatterAnnotation(); newInitializer = newInitializer.WithOpenBraceToken(newInitializer.OpenBraceToken.WithoutLeadingTrivia().WithTrailingTrivia(Space)); newInitializer = newInitializer.WithCloseBraceToken(newInitializer.CloseBraceToken.WithoutLeadingTrivia()); SeparatedSyntaxList <ExpressionSyntax> expressions = newInitializer.Expressions; if (expressions.Any()) { ExpressionSyntax firstExpression = expressions[0]; newInitializer = newInitializer.WithExpressions(expressions.Replace(firstExpression, firstExpression.WithoutLeadingTrivia())); expressions = newInitializer.Expressions; SyntaxToken trailingComma = expressions.GetTrailingSeparator(); if (trailingComma.IsKind(SyntaxKind.CommaToken)) { if (removeTrailingComma) { expressions = expressions.ReplaceSeparator(trailingComma, MissingToken(SyntaxKind.CommaToken)); ExpressionSyntax lastExpression = expressions.Last(); expressions = expressions.Replace(lastExpression, lastExpression.WithTrailingTrivia(Space)); newInitializer = newInitializer.WithExpressions(expressions); } else { newInitializer = newInitializer.WithExpressions(expressions.ReplaceSeparator(trailingComma, trailingComma.WithTrailingTrivia(Space))); } } else { ExpressionSyntax lastExpression = expressions.Last(); newInitializer = newInitializer.WithExpressions(expressions.Replace(lastExpression, lastExpression.WithTrailingTrivia(Space))); } } SyntaxNode parent = initializer.Parent; SyntaxNode newParent; switch (parent.Kind()) { case SyntaxKind.ObjectCreationExpression: { var expression = (ObjectCreationExpressionSyntax)parent; expression = expression.WithInitializer(newInitializer); ArgumentListSyntax argumentList = expression.ArgumentList; if (argumentList != null) { newParent = expression.WithArgumentList(argumentList.WithTrailingTrivia(Space)); } else { newParent = expression.WithType(expression.Type.WithTrailingTrivia(Space)); } break; } case SyntaxKind.ImplicitObjectCreationExpression: { var expression = (ImplicitObjectCreationExpressionSyntax)parent; expression = expression.WithInitializer(newInitializer); ArgumentListSyntax argumentList = expression.ArgumentList; if (argumentList != null) { newParent = expression.WithArgumentList(argumentList.WithTrailingTrivia(Space)); } else { newParent = expression.WithNewKeyword(expression.NewKeyword.WithTrailingTrivia(Space)); } break; } case SyntaxKind.ArrayCreationExpression: { var expression = (ArrayCreationExpressionSyntax)parent; newParent = expression .WithInitializer(newInitializer) .WithType(expression.Type.WithTrailingTrivia(Space)); break; } case SyntaxKind.ImplicitArrayCreationExpression: { var expression = (ImplicitArrayCreationExpressionSyntax)parent; newParent = expression .WithInitializer(newInitializer) .WithCloseBracketToken(expression.CloseBracketToken.WithTrailingTrivia(Space)); break; } case SyntaxKind.EqualsValueClause: { var equalsValueClause = (EqualsValueClauseSyntax)parent; newParent = equalsValueClause .WithValue(newInitializer) .WithEqualsToken(equalsValueClause.EqualsToken.WithTrailingTrivia(Space)); break; } case SyntaxKind.SimpleAssignmentExpression: { var simpleAssignment = (AssignmentExpressionSyntax)parent; newParent = simpleAssignment .WithRight(newInitializer) .WithOperatorToken(simpleAssignment.OperatorToken.WithTrailingTrivia(Space)); break; } default: { SyntaxDebug.Fail(parent); return(document.ReplaceNodeAsync(initializer, newInitializer, cancellationToken)); } } return(document.ReplaceNodeAsync(parent, newParent, cancellationToken)); }