| File: Syntax\DirectiveTriviaSyntax.cs | Web Access |
| Project: src\roslyn\src\Compilers\CSharp\Portable\Microsoft.CodeAnalysis.CSharp.csproj (Microsoft.CodeAnalysis.CSharp) |
// 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. using System; using System.Collections.Generic; using System.Linq; using Microsoft.CodeAnalysis.CSharp.Symbols; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Text; using Roslyn.Utilities; namespace Microsoft.CodeAnalysis.CSharp.Syntax { public partial class DirectiveTriviaSyntax { public SyntaxToken DirectiveNameToken { get { switch (this.Kind()) { case SyntaxKind.IfDirectiveTrivia: return ((IfDirectiveTriviaSyntax)this).IfKeyword; case SyntaxKind.ElifDirectiveTrivia: return ((ElifDirectiveTriviaSyntax)this).ElifKeyword; case SyntaxKind.ElseDirectiveTrivia: return ((ElseDirectiveTriviaSyntax)this).ElseKeyword; case SyntaxKind.EndIfDirectiveTrivia: return ((EndIfDirectiveTriviaSyntax)this).EndIfKeyword; case SyntaxKind.RegionDirectiveTrivia: return ((RegionDirectiveTriviaSyntax)this).RegionKeyword; case SyntaxKind.EndRegionDirectiveTrivia: return ((EndRegionDirectiveTriviaSyntax)this).EndRegionKeyword; case SyntaxKind.ErrorDirectiveTrivia: return ((ErrorDirectiveTriviaSyntax)this).ErrorKeyword; case SyntaxKind.WarningDirectiveTrivia: return ((WarningDirectiveTriviaSyntax)this).WarningKeyword; case SyntaxKind.BadDirectiveTrivia: return ((BadDirectiveTriviaSyntax)this).Identifier; case SyntaxKind.DefineDirectiveTrivia: return ((DefineDirectiveTriviaSyntax)this).DefineKeyword; case SyntaxKind.UndefDirectiveTrivia: return ((UndefDirectiveTriviaSyntax)this).UndefKeyword; case SyntaxKind.LineDirectiveTrivia: return ((LineDirectiveTriviaSyntax)this).LineKeyword; case SyntaxKind.LineSpanDirectiveTrivia: return ((LineSpanDirectiveTriviaSyntax)this).LineKeyword; case SyntaxKind.PragmaWarningDirectiveTrivia: return ((PragmaWarningDirectiveTriviaSyntax)this).PragmaKeyword; case SyntaxKind.PragmaChecksumDirectiveTrivia: return ((PragmaChecksumDirectiveTriviaSyntax)this).PragmaKeyword; case SyntaxKind.ReferenceDirectiveTrivia: return ((ReferenceDirectiveTriviaSyntax)this).ReferenceKeyword; case SyntaxKind.LoadDirectiveTrivia: return ((LoadDirectiveTriviaSyntax)this).LoadKeyword; case SyntaxKind.ShebangDirectiveTrivia: return ((ShebangDirectiveTriviaSyntax)this).ExclamationToken; case SyntaxKind.IgnoredDirectiveTrivia: return ((IgnoredDirectiveTriviaSyntax)this).ColonToken; case SyntaxKind.NullableDirectiveTrivia: return ((NullableDirectiveTriviaSyntax)this).NullableKeyword; default: throw ExceptionUtilities.UnexpectedValue(this.Kind()); } } } public DirectiveTriviaSyntax? GetNextDirective(Func<DirectiveTriviaSyntax, bool>? predicate = null) { var token = (SyntaxToken)this.ParentTrivia.Token; bool next = false; while (token.Kind() != SyntaxKind.None) { foreach (var tr in token.LeadingTrivia) { if (tr.IsDirective) { var d = (DirectiveTriviaSyntax)tr.GetStructure()!; if (next) { if (predicate == null || predicate(d)) { return d; } } else if (tr.UnderlyingNode == this.Green && tr.SpanStart == this.SpanStart && (object)d == this) { next = true; } } } token = token.GetNextToken(s_hasDirectivesFunction); } return null; } public DirectiveTriviaSyntax? GetPreviousDirective(Func<DirectiveTriviaSyntax, bool>? predicate = null) { var token = (SyntaxToken)this.ParentTrivia.Token; bool next = false; while (token.Kind() != SyntaxKind.None) { foreach (var tr in token.LeadingTrivia.Reverse()) { if (tr.IsDirective) { var d = (DirectiveTriviaSyntax)tr.GetStructure()!; if (next) { if (predicate == null || predicate(d)) { return d; } } else if (tr.UnderlyingNode == this.Green && tr.SpanStart == this.SpanStart && (object)d == this) { next = true; } } } token = token.GetPreviousToken(s_hasDirectivesFunction); } return null; } public List<DirectiveTriviaSyntax> GetRelatedDirectives() { var list = new List<DirectiveTriviaSyntax>(); this.GetRelatedDirectives(list); return list; } private void GetRelatedDirectives(List<DirectiveTriviaSyntax> list) { list.Clear(); var p = this.GetPreviousRelatedDirective(); while (p != null) { list.Add(p); p = p.GetPreviousRelatedDirective(); } list.Reverse(); list.Add(this); var n = this.GetNextRelatedDirective(); while (n != null) { list.Add(n); n = n.GetNextRelatedDirective(); } } private DirectiveTriviaSyntax? GetNextRelatedDirective() { DirectiveTriviaSyntax? d = this; switch (d.Kind()) { case SyntaxKind.IfDirectiveTrivia: while (d != null) { switch (d.Kind()) { case SyntaxKind.ElifDirectiveTrivia: case SyntaxKind.ElseDirectiveTrivia: case SyntaxKind.EndIfDirectiveTrivia: return d; } d = d.GetNextPossiblyRelatedDirective(); } break; case SyntaxKind.ElifDirectiveTrivia: d = d.GetNextPossiblyRelatedDirective(); while (d != null) { switch (d.Kind()) { case SyntaxKind.ElifDirectiveTrivia: case SyntaxKind.ElseDirectiveTrivia: case SyntaxKind.EndIfDirectiveTrivia: return d; } d = d.GetNextPossiblyRelatedDirective(); } break; case SyntaxKind.ElseDirectiveTrivia: while (d != null) { if (d.Kind() == SyntaxKind.EndIfDirectiveTrivia) { return d; } d = d.GetNextPossiblyRelatedDirective(); } break; case SyntaxKind.RegionDirectiveTrivia: while (d != null) { if (d.Kind() == SyntaxKind.EndRegionDirectiveTrivia) { return d; } d = d.GetNextPossiblyRelatedDirective(); } break; } return null; } private DirectiveTriviaSyntax? GetNextPossiblyRelatedDirective() { DirectiveTriviaSyntax? d = this; while (d != null) { d = d.GetNextDirective(); if (d != null) { // skip matched sets switch (d.Kind()) { case SyntaxKind.IfDirectiveTrivia: while (d != null && d.Kind() != SyntaxKind.EndIfDirectiveTrivia) { d = d.GetNextRelatedDirective(); } continue; case SyntaxKind.RegionDirectiveTrivia: while (d != null && d.Kind() != SyntaxKind.EndRegionDirectiveTrivia) { d = d.GetNextRelatedDirective(); } continue; } } return d; } return null; } private DirectiveTriviaSyntax? GetPreviousRelatedDirective() { DirectiveTriviaSyntax? d = this; switch (d.Kind()) { case SyntaxKind.EndIfDirectiveTrivia: while (d != null) { switch (d.Kind()) { case SyntaxKind.IfDirectiveTrivia: case SyntaxKind.ElifDirectiveTrivia: case SyntaxKind.ElseDirectiveTrivia: return d; } d = d.GetPreviousPossiblyRelatedDirective(); } break; case SyntaxKind.ElifDirectiveTrivia: d = d.GetPreviousPossiblyRelatedDirective(); while (d != null) { switch (d.Kind()) { case SyntaxKind.IfDirectiveTrivia: case SyntaxKind.ElifDirectiveTrivia: return d; } d = d.GetPreviousPossiblyRelatedDirective(); } break; case SyntaxKind.ElseDirectiveTrivia: while (d != null) { switch (d.Kind()) { case SyntaxKind.IfDirectiveTrivia: case SyntaxKind.ElifDirectiveTrivia: return d; } d = d.GetPreviousPossiblyRelatedDirective(); } break; case SyntaxKind.EndRegionDirectiveTrivia: while (d != null) { if (d.Kind() == SyntaxKind.RegionDirectiveTrivia) { return d; } d = d.GetPreviousPossiblyRelatedDirective(); } break; } return null; } private DirectiveTriviaSyntax? GetPreviousPossiblyRelatedDirective() { DirectiveTriviaSyntax? d = this; while (d != null) { d = d.GetPreviousDirective(); if (d != null) { // skip matched sets switch (d.Kind()) { case SyntaxKind.EndIfDirectiveTrivia: while (d != null && d.Kind() != SyntaxKind.IfDirectiveTrivia) { d = d.GetPreviousRelatedDirective(); } continue; case SyntaxKind.EndRegionDirectiveTrivia: while (d != null && d.Kind() != SyntaxKind.RegionDirectiveTrivia) { d = d.GetPreviousRelatedDirective(); } continue; } } return d; } return null; } private static readonly Func<SyntaxToken, bool> s_hasDirectivesFunction = t => t.ContainsDirectives; } }