public static async Task <Document> RefactorAsync( Document document, RegionDirectiveTriviaSyntax regionDirective, CancellationToken cancellationToken = default(CancellationToken)) { return(await Remover.RemoveRegionAsync(document, regionDirective, cancellationToken).ConfigureAwait(false)); }
public static Task <Document> RefactorAsync( Document document, RegionDirectiveTriviaSyntax regionDirective, CancellationToken cancellationToken = default(CancellationToken)) { return(document.RemoveRegionAsync(regionDirective, cancellationToken)); }
public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context) { SyntaxNode root = await context.GetSyntaxRootAsync().ConfigureAwait(false); EndRegionDirectiveTriviaSyntax endRegionDirective = root .FindNode(context.Span, findInsideTrivia: true, getInnermostNodeForTie: true)? .FirstAncestorOrSelf <EndRegionDirectiveTriviaSyntax>(); Debug.Assert(endRegionDirective != null, $"{nameof(endRegionDirective)} is null"); if (endRegionDirective == null) { return; } RegionDirectiveTriviaSyntax regionDirective = endRegionDirective.GetRegionDirective(); SyntaxTrivia trivia = regionDirective.GetPreprocessingMessageTrivia(); CodeAction codeAction = CodeAction.Create( (trivia.IsKind(SyntaxKind.PreprocessingMessageTrivia)) ? "Add region name to #endregion" : "Remove region name from #endregion", cancellationToken => AddOrRemoveRegionNameRefactoring.RefactorAsync(context.Document, endRegionDirective, trivia, cancellationToken), DiagnosticIdentifiers.AddOrRemoveRegionName + EquivalenceKeySuffix); context.RegisterCodeFix(codeAction, context.Diagnostics); }
/// <summary> /// Checks if a region is completely part of a body. That means that the <c>#region</c> and <c>#endregion</c> /// tags both have to have a common <see cref="BlockSyntax"/> as one of their ancestors. /// </summary> /// <param name="regionSyntax">The <see cref="RegionDirectiveTriviaSyntax"/> that should be analyzed.</param> /// <returns><see langword="true"/>, if both tags have a common <see cref="BlockSyntax"/> as one of their /// ancestors; otherwise, <see langword="false"/>.</returns> /// <exception cref="ArgumentNullException"> /// If <paramref name="regionSyntax"/> is <see langword="null"/>. /// </exception> internal static bool IsCompletelyContainedInBody(RegionDirectiveTriviaSyntax regionSyntax) { if (regionSyntax == null) { throw new ArgumentNullException(nameof(regionSyntax)); } BlockSyntax syntax = null; foreach (var directive in regionSyntax.GetRelatedDirectives()) { BlockSyntax blockSyntax = directive.AncestorsAndSelf().OfType<BlockSyntax>().LastOrDefault(); if (blockSyntax == null) { return false; } else if (syntax == null) { syntax = blockSyntax; } else if (blockSyntax != syntax) { return false; } } return true; }
public static void AnalyzeEndRegionDirectiveTrivia(SyntaxNodeAnalysisContext context) { var endRegionDirective = (EndRegionDirectiveTriviaSyntax)context.Node; RegionDirectiveTriviaSyntax regionDirective = endRegionDirective.GetRegionDirective(); if (regionDirective == null) { return; } SyntaxTrivia trivia = regionDirective.GetPreprocessingMessageTrivia(); SyntaxTrivia endTrivia = endRegionDirective.GetPreprocessingMessageTrivia(); if (trivia.Kind() == SyntaxKind.PreprocessingMessageTrivia) { if (endTrivia.Kind() != SyntaxKind.PreprocessingMessageTrivia || !string.Equals(trivia.ToString(), endTrivia.ToString(), StringComparison.Ordinal)) { context.ReportDiagnostic(DiagnosticDescriptors.AddOrRemoveRegionName, endRegionDirective, "Add", "to"); } } else if (endTrivia.Kind() == SyntaxKind.PreprocessingMessageTrivia) { context.ReportDiagnostic(DiagnosticDescriptors.AddOrRemoveRegionName, endRegionDirective, "Remove", "from"); } }
private static void AnalyzeEndRegionDirectiveTrivia(SyntaxNodeAnalysisContext context) { var endRegionDirective = (EndRegionDirectiveTriviaSyntax)context.Node; RegionDirectiveTriviaSyntax regionDirective = endRegionDirective.GetRegionDirective(); if (regionDirective == null) { return; } SyntaxTrivia trivia = regionDirective.GetPreprocessingMessageTrivia(); SyntaxTrivia endTrivia = endRegionDirective.GetPreprocessingMessageTrivia(); if (trivia.IsKind(SyntaxKind.PreprocessingMessageTrivia)) { if (!endTrivia.IsKind(SyntaxKind.PreprocessingMessageTrivia) || !string.Equals(trivia.ToString(), endTrivia.ToString(), StringComparison.Ordinal)) { DiagnosticHelpers.ReportDiagnostic(context, DiagnosticRules.AddOrRemoveRegionName, endRegionDirective, "Add", "to"); } } else if (endTrivia.IsKind(SyntaxKind.PreprocessingMessageTrivia)) { DiagnosticHelpers.ReportDiagnostic(context, DiagnosticRules.AddOrRemoveRegionName, endRegionDirective, "Remove", "from"); } }
public override SyntaxNode VisitRegionDirectiveTrivia(RegionDirectiveTriviaSyntax node) { node = (RegionDirectiveTriviaSyntax)base.VisitRegionDirectiveTrivia(node); var region = _stack.Peek(); var content = node.ToString().Trim(); var match = _regionRegex.Match(content); if (match.Success) { var tags = match.Groups[1].Value.Trim().Split(TagSeparators, StringSplitOptions.RemoveEmptyEntries); var tagString = string.Join(" ", tags); if (region.Annotation != null) { tagString = region.Annotation.Data + " " + tagString; } region = new RegionInfo(new SyntaxAnnotation("MDK", tagString)); _stack.Push(region); return(node); } _stack.Push(region.AsCopy()); if (region.Annotation != null) { return(node.WithAdditionalAnnotations(region.Annotation)); } return(node); }
private static IEnumerable <TextSpan> GetExistingRegionSpans(SyntaxNode root) { IEnumerable <SyntaxNode> regionNodes = root.DescendantNodesAndSelf(descendIntoTrivia: true) .Where(node => node.IsKind(SyntaxKind.RegionDirectiveTrivia) || node.IsKind(SyntaxKind.EndRegionDirectiveTrivia)); // In a perfect world, the #region and #endregion directives will be balanced (even if they're nested). // But we have to gracefully handle if they're mismatched or out of order. var regionBounds = new List <Tuple <RegionDirectiveTriviaSyntax, EndRegionDirectiveTriviaSyntax> >(); Stack <RegionDirectiveTriviaSyntax> regionStack = new Stack <RegionDirectiveTriviaSyntax>(); foreach (SyntaxNode node in regionNodes) { if (node.IsKind(SyntaxKind.RegionDirectiveTrivia)) { regionStack.Push((RegionDirectiveTriviaSyntax)node); } else if (regionStack.Count > 0) { RegionDirectiveTriviaSyntax regionStart = regionStack.Pop(); regionBounds.Add(Tuple.Create(regionStart, (EndRegionDirectiveTriviaSyntax)node)); } } IEnumerable <TextSpan> result = regionBounds .Where(tuple => !DesignerGeneratedRegions.Contains(tuple.Item1.DirectiveNameToken.ValueText ?? string.Empty)) .Select(tuple => TextSpan.FromBounds(tuple.Item1.FullSpan.Start, tuple.Item2.FullSpan.End)); return(result); }
public static async Task <Document> RemoveRegionAsync( this Document document, RegionDirectiveTriviaSyntax regionDirective, CancellationToken cancellationToken = default(CancellationToken)) { if (document == null) { throw new ArgumentNullException(nameof(document)); } if (regionDirective == null) { throw new ArgumentNullException(nameof(regionDirective)); } List <DirectiveTriviaSyntax> list = regionDirective.GetRelatedDirectives(); if (list.Count == 2 && list[1].IsKind(SyntaxKind.EndRegionDirectiveTrivia)) { var endRegionDirective = (EndRegionDirectiveTriviaSyntax)list[1]; return(await RemoveRegionAsync(document, regionDirective, endRegionDirective, cancellationToken).ConfigureAwait(false)); } return(document); }
/// <summary> /// Checks if a region is completely part of a body. That means that the <c>#region</c> and <c>#endregion</c> /// tags both have to have a common <see cref="BlockSyntax"/> as one of their ancestors. /// </summary> /// <param name="regionSyntax">The <see cref="RegionDirectiveTriviaSyntax"/> that should be analyzed.</param> /// <returns><see langword="true"/>, if both tags have a common <see cref="BlockSyntax"/> as one of their /// ancestors; otherwise, <see langword="false"/>.</returns> /// <exception cref="ArgumentNullException"> /// If <paramref name="regionSyntax"/> is <see langword="null"/>. /// </exception> internal static bool IsCompletelyContainedInBody(RegionDirectiveTriviaSyntax regionSyntax) { if (regionSyntax == null) { throw new ArgumentNullException(nameof(regionSyntax)); } BlockSyntax syntax = null; foreach (var directive in regionSyntax.GetRelatedDirectives()) { BlockSyntax blockSyntax = directive.AncestorsAndSelf().OfType <BlockSyntax>().LastOrDefault(); if (blockSyntax == null) { return(false); } else if (syntax == null) { syntax = blockSyntax; } else if (blockSyntax != syntax) { return(false); } } return(true); }
public static void Analyze(SyntaxNodeAnalysisContext context, RegionDirectiveTriviaSyntax region) { if (region.IsKind(SyntaxKind.RegionDirectiveTrivia)) { List <DirectiveTriviaSyntax> relatedDirectives = region.GetRelatedDirectives(); if (relatedDirectives.Count == 2 && relatedDirectives[1].IsKind(SyntaxKind.EndRegionDirectiveTrivia)) { DirectiveTriviaSyntax endRegion = relatedDirectives[1]; if (endRegion.IsKind(SyntaxKind.EndRegionDirectiveTrivia)) { SyntaxTrivia trivia = region.ParentTrivia; SyntaxTriviaList list = trivia.GetContainingList(); if (list.Any()) { EndRegionDirectiveTriviaSyntax endRegion2 = FindEndRegion(list, list.IndexOf(trivia)); if (endRegion == endRegion2) { context.ReportDiagnostic( DiagnosticDescriptors.RemoveEmptyRegion, region.GetLocation(), endRegion.GetLocation()); } } } } } }
/* ## Creating Macros ## The visitor methods for regions handle creating new macros. When a region ## is opened, we read its name and push a new macro with that name to the stack. ## When the visitor methods are called, we have already added the new block which ## starts the macro, so we can take its reference from the `_newBlock` field. */ public override void VisitRegionDirectiveTrivia( RegionDirectiveTriviaSyntax node) { _macros.Push(Macro.Add( node.EndOfDirectiveToken.LeadingTrivia.First().ToString(), _newBlock, null, _currentFile)); }
private string ParseRegionName(RegionDirectiveTriviaSyntax node) { var preprocessingMessage = node .DescendantTrivia() .FirstOrDefault(t => t.Kind() == SyntaxKind.PreprocessingMessageTrivia); return(preprocessingMessage.ToString()); }
private static void HandleRegionDirectiveTrivia(SyntaxNodeAnalysisContext context) { RegionDirectiveTriviaSyntax regionSyntax = (RegionDirectiveTriviaSyntax)context.Node; if (IsCompletelyContainedInBody(regionSyntax)) { // Region must not be located within a code element. context.ReportDiagnostic(Diagnostic.Create(Descriptor, regionSyntax.GetLocation())); } }
public override void VisitRegionDirectiveTrivia(RegionDirectiveTriviaSyntax node) { // if (debug) Console.WriteLine(node.ToFullString()); // Todo("RegionDirectiveTrivia"); var nl = OurLine.NewLine(LineKind.Decl, "RegionDirectiveTrivia"); // nl.Source = node.ToFullString(); // nl.ParentKind = node.Parent.RawKind; // nl.RawKind = node.RawKind; // LogCommand(nl); base.VisitRegionDirectiveTrivia(node); }
public override void VisitRegionDirectiveTrivia(RegionDirectiveTriviaSyntax node) { if (_RegionStack is null) { _RegionStack = new Stack <RegionDirectiveTriviaSyntax>(); } _RegionStack.Push(node); base.VisitRegionDirectiveTrivia(node); }
public static void ComputeRefactorings(RefactoringContext context, RegionDirectiveTriviaSyntax regionDirective) { if (context.IsRefactoringEnabled(RefactoringIdentifiers.RemoveRegion) && context.IsRootCompilationUnit) { context.RegisterRefactoring( "Remove region", cancellationToken => context.Document.RemoveRegionAsync(regionDirective, cancellationToken)); } }
private void HandleRegionDirectiveTrivia(SyntaxNodeAnalysisContext context) { RegionDirectiveTriviaSyntax regionSyntax = context.Node as RegionDirectiveTriviaSyntax; // regions that are completely inside a body are handled by SA1123. if (regionSyntax != null && !SA1123DoNotPlaceRegionsWithinElements.IsCompletelyContainedInBody(regionSyntax)) { // Regions must not be used. context.ReportDiagnostic(Diagnostic.Create(Descriptor, regionSyntax.GetLocation())); } }
public override void VisitRegionDirectiveTrivia(RegionDirectiveTriviaSyntax node) { if (!PreVisit(node)) { return; } base.VisitRegionDirectiveTrivia(node); PostVisit(node); }
public override void VisitRegionDirectiveTrivia(RegionDirectiveTriviaSyntax node) { var region = new CodeRegion { StartIndex = node.FullSpan.Start, Name = ParseRegionName(node) }; _stack.Push(region); base.VisitRegionDirectiveTrivia(node); }
public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context) { SyntaxNode root = await context.GetSyntaxRootAsync().ConfigureAwait(false); RegionDirectiveTriviaSyntax region = root .FindNode(context.Span, findInsideTrivia: true, getInnermostNodeForTie: true)? .FirstAncestorOrSelf <RegionDirectiveTriviaSyntax>(); CodeAction codeAction = CodeAction.Create( "Remove empty region", cancellationToken => RemoveEmptyRegionRefactoring.RefactorAsync(context.Document, region, cancellationToken), DiagnosticIdentifiers.RemoveEmptyRegion + EquivalenceKeySuffix); context.RegisterCodeFix(codeAction, context.Diagnostics); }
public static void ComputeRefactorings(RefactoringContext context, RegionDirectiveTriviaSyntax regionDirective) { if (context.IsRefactoringEnabled(RefactoringDescriptors.RemoveRegion) && context.IsRootCompilationUnit) { RegionInfo region = SyntaxInfo.RegionInfo(regionDirective); if (region.Success) { context.RegisterRefactoring( "Remove region", ct => context.Document.RemoveRegionAsync(region, ct), RefactoringDescriptors.RemoveRegion); } } }
public override void VisitRegionDirectiveTrivia(RegionDirectiveTriviaSyntax regionDirective) { if (cancellationToken.IsCancellationRequested) { return; } regionsStack.Push(regionDirective); string regionNameUpperCase = GetRegionName(regionDirective).ToUpperInvariant(); if (regionNameUpperCase.Contains(identifierToRemove)) { RegionNodesToRemove.Add(regionDirective); } base.VisitRegionDirectiveTrivia(regionDirective); }
private static async Task <Document> RemoveRegionAsync(Document document, RegionDirectiveTriviaSyntax regionDirective, EndRegionDirectiveTriviaSyntax endRegionDirective, CancellationToken cancellationToken) { SourceText sourceText = await document.GetTextAsync(cancellationToken).ConfigureAwait(false); int startLine = regionDirective.GetSpanStartLine(); int endLine = endRegionDirective.GetSpanEndLine(); TextLineCollection lines = sourceText.Lines; TextSpan span = TextSpan.FromBounds( lines[startLine].Start, lines[endLine].EndIncludingLineBreak); var textChange = new TextChange(span, ""); SourceText newSourceText = sourceText.WithChanges(textChange); return(document.WithText(newSourceText)); }
public static async Task <Document> RemoveRegionAsync( Document document, RegionDirectiveTriviaSyntax regionDirective, CancellationToken cancellationToken = default(CancellationToken)) { if (document == null) { throw new ArgumentNullException(nameof(document)); } if (regionDirective == null) { throw new ArgumentNullException(nameof(regionDirective)); } List <DirectiveTriviaSyntax> list = regionDirective.GetRelatedDirectives(); if (list.Count == 2 && list[1].IsKind(SyntaxKind.EndRegionDirectiveTrivia)) { var endRegionDirective = (EndRegionDirectiveTriviaSyntax)list[1]; SourceText sourceText = await document.GetTextAsync(cancellationToken).ConfigureAwait(false); int startLine = regionDirective.GetSpanStartLine(); int endLine = endRegionDirective.GetSpanEndLine(); TextLineCollection lines = sourceText.Lines; TextSpan span = TextSpan.FromBounds( lines[startLine].Start, lines[endLine].EndIncludingLineBreak); var textChange = new TextChange(span, string.Empty); SourceText newSourceText = sourceText.WithChanges(textChange); return(document.WithText(newSourceText)); } return(document); }
public override async Task ComputeRefactoringsAsync(CodeRefactoringContext context) { SyntaxNode root = await context.Document.GetSyntaxRootAsync(context.CancellationToken); RegionDirectiveTriviaSyntax regionDirectiveTrivia = root .FindNode(context.Span, findInsideTrivia: true, getInnermostNodeForTie: true)? .FirstAncestorOrSelf <RegionDirectiveTriviaSyntax>(); if (regionDirectiveTrivia == null) { return; } if (root.IsKind(SyntaxKind.CompilationUnit)) { context.RegisterRefactoring( "Remove all regions", cancellationToken => RemoveAllRegionsAsync(context.Document, cancellationToken)); } }
internal static RegionInfo Create(RegionDirectiveTriviaSyntax regionDirective) { if (regionDirective == null) { return(Default); } List <DirectiveTriviaSyntax> list = regionDirective.GetRelatedDirectives(); if (list.Count != 2) { return(Default); } if (list[1].Kind() != SyntaxKind.EndRegionDirectiveTrivia) { return(Default); } return(new RegionInfo(regionDirective, (EndRegionDirectiveTriviaSyntax)list[1])); }
public static EndRegionDirectiveTriviaSyntax GetEndRegion(this RegionDirectiveTriviaSyntax syntax) { DirectiveTriviaSyntax region = syntax; int c = 1; while ((region = region.GetNextDirective()) != null) { if (region.IsKind(SyntaxKind.EndRegionDirectiveTrivia)) { --c; if (c == 0) { return(region as EndRegionDirectiveTriviaSyntax); } } else if (region.IsKind(SyntaxKind.RegionDirectiveTrivia)) { ++c; } } return(null); }
public override void VisitEndRegionDirectiveTrivia(EndRegionDirectiveTriviaSyntax endRegionDirective) { if (regionsStack.Count == 0 || cancellationToken.IsCancellationRequested) { if (!cancellationToken.IsCancellationRequested) { base.VisitEndRegionDirectiveTrivia(endRegionDirective); } return; } RegionDirectiveTriviaSyntax regionDirective = regionsStack.Pop(); string regionNameUpperCase = GetRegionName(regionDirective).ToUpperInvariant(); if (regionNameUpperCase.Contains(identifierToRemove)) { RegionNodesToRemove.Add(endRegionDirective); } base.VisitEndRegionDirectiveTrivia(endRegionDirective); }
public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context) { SyntaxNode root = await context.GetSyntaxRootAsync().ConfigureAwait(false); if (!TryFindFirstAncestorOrSelf(root, context.Span, out EndRegionDirectiveTriviaSyntax endRegionDirective, findInsideTrivia: true)) { return; } RegionDirectiveTriviaSyntax regionDirective = endRegionDirective.GetRegionDirective(); SyntaxTrivia trivia = regionDirective.GetPreprocessingMessageTrivia(); CodeAction codeAction = CodeAction.Create( (trivia.IsKind(SyntaxKind.PreprocessingMessageTrivia)) ? "Add region name to #endregion" : "Remove region name from #endregion", cancellationToken => AddOrRemoveRegionNameRefactoring.RefactorAsync(context.Document, endRegionDirective, trivia, cancellationToken), GetEquivalenceKey(DiagnosticIdentifiers.AddOrRemoveRegionName)); context.RegisterCodeFix(codeAction, context.Diagnostics); }
private void ClassifyRegionDirective(RegionDirectiveTriviaSyntax node) { AddClassification(node.HashToken, ClassificationTypeNames.PreprocessorKeyword); AddClassification(node.RegionKeyword, ClassificationTypeNames.PreprocessorKeyword); ClassifyDirectiveTrivia(node, allowComments: false); }
public override void VisitRegionDirectiveTrivia(RegionDirectiveTriviaSyntax node) { base.VisitRegionDirectiveTrivia(node); this.RegionCount++; }
/// <summary> /// /// </summary> /// <param name="node"></param> public override sealed void VisitRegionDirectiveTrivia(RegionDirectiveTriviaSyntax node) { this.OnNodeVisited(node); if (!this.traverseRootOnly) base.VisitRegionDirectiveTrivia(node); }
/// <summary> /// /// </summary> /// <param name="node"></param> public override sealed void VisitRegionDirectiveTrivia(RegionDirectiveTriviaSyntax node) { this.OnNodeVisited(node, this.type.IsInstanceOfType(node)); base.VisitRegionDirectiveTrivia(node); }
public override SyntaxNode VisitRegionDirectiveTrivia(RegionDirectiveTriviaSyntax node) { return null; }
public override SyntaxNode VisitRegionDirectiveTrivia(RegionDirectiveTriviaSyntax node) { return SyntaxFactory.SkippedTokensTrivia(); }