// Given the ordered list of all pragma warning directives in the syntax tree, return a list of mapping entries, 
        // containing the cumulative set of warnings that are disabled for that point in the source.
        // This mapping also contains a global warning option, accumulated of all #pragma up to the current line position.
        private static WarningStateMapEntry[] CreatePragmaWarningStateEntries(ImmutableArray<PragmaWarningDirectiveTriviaSyntax> directiveList)
        {
            var entries = new WarningStateMapEntry[directiveList.Length + 1];
            var current = new WarningStateMapEntry(0, ReportDiagnostic.Default, null);
            var index = 0;
            entries[index] = current;

            // Captures the general reporting option, accumulated of all #pragma up to the current directive.
            var accumulatedGeneralWarningState = ReportDiagnostic.Default;

            // Captures the mapping of a warning number to the reporting option, accumulated of all #pragma up to the current directive.
            var accumulatedSpecificWarningState = ImmutableDictionary.Create<string, ReportDiagnostic>();

            while (index < directiveList.Length)
            {
                var currentDirective = directiveList[index];

                // Compute the directive state (either Disable or Restore)
                var directiveState = currentDirective.DisableOrRestoreKeyword.CSharpKind() == SyntaxKind.DisableKeyword ? ReportDiagnostic.Suppress : ReportDiagnostic.Default;

                // Check if this directive applies for all (e.g., #pragma warning disable)
                if (currentDirective.ErrorCodes.Count == 0)
                {
                    // Update the warning state and reset the specific one
                    accumulatedGeneralWarningState = directiveState;
                    accumulatedSpecificWarningState = ImmutableDictionary.Create<string, ReportDiagnostic>();
                }
                else
                {
                    // Compute warning numbers from the current directive's codes
                    for (int x = 0; x < currentDirective.ErrorCodes.Count; x++)
                    {
                        if (currentDirective.ErrorCodes[x].IsMissing || currentDirective.ErrorCodes[x].ContainsDiagnostics)
                            continue;

                        var token = ((LiteralExpressionSyntax)currentDirective.ErrorCodes[x]).Token;
                        string errorId = token.CSharpKind() == SyntaxKind.NumericLiteralToken ?
                            MessageProvider.Instance.GetIdForErrorCode((int)token.Value) :
                            (string)token.Value;

                        // Update the state of this error code with the current directive state
                        accumulatedSpecificWarningState = accumulatedSpecificWarningState.SetItem(errorId, directiveState);
                    }
                }

                current = new WarningStateMapEntry(currentDirective.Location.SourceSpan.End, accumulatedGeneralWarningState, accumulatedSpecificWarningState);
                ++index;
                entries[index] = current;
            }

#if DEBUG
            // Make sure the entries array is correctly sorted. 
            for (int i = 1; i < entries.Length - 1; ++i)
            {
                Debug.Assert(entries[i].CompareTo(entries[i + 1]) < 0);
            }
#endif

            return entries;
        }
        /// <summary>
        /// Returns the reporting state for the supplied diagnostic id at the supplied position
        /// in the associated syntax tree.
        /// </summary>
        public ReportDiagnostic GetWarningState(string id, int position)
        {
            WarningStateMapEntry entry = GetEntryAtOrBeforePosition(position);

            if (entry.SpecificWarningOption.TryGetValue(id, out ReportDiagnostic state))
            {
                return(state);
            }

            return(entry.GeneralWarningOption);
        }
示例#3
0
        // Given the ordered list of all pragma warning and nullable directives in the syntax tree, return a list of mapping entries,
        // containing the cumulative set of warnings that are disabled for that point in the source.
        // This mapping also contains a global warning option, accumulated of all #pragma up to the current line position.
        private static WarningStateMapEntry[] CreatePragmaWarningStateEntries(ArrayBuilder <DirectiveTriviaSyntax> directiveList)
        {
            var entries = new WarningStateMapEntry[directiveList.Count + 1];
            var current = new WarningStateMapEntry(0, PragmaWarningState.Default, null);
            var index   = 0;

            entries[index] = current;

            // Captures the general reporting option, accumulated of all #pragma up to the current directive.
            var accumulatedGeneralWarningState = PragmaWarningState.Default;

            // Captures the mapping of a warning number to the reporting option, accumulated of all #pragma up to the current directive.
            var accumulatedSpecificWarningState = ImmutableDictionary.Create <string, PragmaWarningState>();

            while (index < directiveList.Count)
            {
                var currentDirective = directiveList[index];

                if (currentDirective.IsKind(SyntaxKind.PragmaWarningDirectiveTrivia))
                {
                    var currentPragmaDirective = (PragmaWarningDirectiveTriviaSyntax)currentDirective;

                    if (currentPragmaDirective.NullableKeyword.IsKind(SyntaxKind.NullableKeyword))
                    {
                        accumulatedNullableWarningState(currentPragmaDirective.DisableOrRestoreKeyword);
                    }
                    else
                    {
                        // Compute the directive state
                        PragmaWarningState directiveState;

                        switch (currentPragmaDirective.DisableOrRestoreKeyword.Kind())
                        {
                        case SyntaxKind.DisableKeyword:
                            directiveState = PragmaWarningState.Disabled;
                            break;

                        case SyntaxKind.RestoreKeyword:
                            directiveState = PragmaWarningState.Default;
                            break;

                        case SyntaxKind.EnableKeyword:
                            directiveState = PragmaWarningState.Enabled;
                            break;

                        case SyntaxKind.SafeOnlyKeyword:
                        default:
                            throw ExceptionUtilities.UnexpectedValue(currentPragmaDirective.DisableOrRestoreKeyword.Kind());
                        }

                        // Check if this directive applies for all (e.g., #pragma warning disable)
                        if (currentPragmaDirective.ErrorCodes.Count == 0)
                        {
                            // Update the warning state and reset the specific one
                            accumulatedGeneralWarningState  = directiveState;
                            accumulatedSpecificWarningState = ImmutableDictionary.Create <string, PragmaWarningState>();
                        }
                        else
                        {
                            // Compute warning numbers from the current directive's codes
                            for (int x = 0; x < currentPragmaDirective.ErrorCodes.Count; x++)
                            {
                                var currentErrorCode = currentPragmaDirective.ErrorCodes[x];
                                if (currentErrorCode.IsMissing || currentErrorCode.ContainsDiagnostics)
                                {
                                    continue;
                                }

                                var errorId = string.Empty;
                                if (currentErrorCode.Kind() == SyntaxKind.NumericLiteralExpression)
                                {
                                    var token = ((LiteralExpressionSyntax)currentErrorCode).Token;
                                    errorId = MessageProvider.Instance.GetIdForErrorCode((int)token.Value);
                                }
                                else if (currentErrorCode.Kind() == SyntaxKind.IdentifierName)
                                {
                                    errorId = ((IdentifierNameSyntax)currentErrorCode).Identifier.ValueText;
                                }

                                if (!string.IsNullOrWhiteSpace(errorId))
                                {
                                    // Update the state of this error code with the current directive state
                                    accumulatedSpecificWarningState = accumulatedSpecificWarningState.SetItem(errorId, directiveState);
                                }
                            }
                        }
                    }
                }
                else
                {
                    var currentNullableDirective = (NullableDirectiveTriviaSyntax)currentDirective;
                    accumulatedNullableWarningState(currentNullableDirective.SettingToken);
                }

                current = new WarningStateMapEntry(currentDirective.Location.SourceSpan.End, accumulatedGeneralWarningState, accumulatedSpecificWarningState);
                ++index;
                entries[index] = current;
            }

#if DEBUG
            // Make sure the entries array is correctly sorted.
            for (int i = 1; i < entries.Length - 1; ++i)
            {
                Debug.Assert(entries[i].CompareTo(entries[i + 1]) < 0);
            }
#endif

            return(entries);

            void accumulatedNullableWarningState(SyntaxToken nullableAction)
            {
                PragmaWarningState safetyState;
                PragmaWarningState nonSafetyState;

                switch (nullableAction.Kind())
                {
                case SyntaxKind.DisableKeyword:
                    safetyState    = PragmaWarningState.Disabled;
                    nonSafetyState = PragmaWarningState.Disabled;
                    break;

                case SyntaxKind.EnableKeyword:
                    safetyState    = PragmaWarningState.Enabled;
                    nonSafetyState = PragmaWarningState.Enabled;
                    break;

                case SyntaxKind.SafeOnlyKeyword:
                    safetyState    = PragmaWarningState.Enabled;
                    nonSafetyState = PragmaWarningState.Disabled;
                    break;

                case SyntaxKind.RestoreKeyword:
                    safetyState    = PragmaWarningState.Default;
                    nonSafetyState = PragmaWarningState.Default;
                    break;

                default:
                    throw ExceptionUtilities.UnexpectedValue(nullableAction.Kind());
                }

                var builder = ArrayBuilder <KeyValuePair <string, PragmaWarningState> > .GetInstance(ErrorFacts.NullableFlowAnalysisSafetyWarnings.Count + ErrorFacts.NullableFlowAnalysisNonSafetyWarnings.Count);

                // Update the state of the error codes with the current directive state
                addNewStates(safetyState, ErrorFacts.NullableFlowAnalysisSafetyWarnings);
                addNewStates(nonSafetyState, ErrorFacts.NullableFlowAnalysisNonSafetyWarnings);

                accumulatedSpecificWarningState = accumulatedSpecificWarningState.SetItems(builder);
                builder.Free();

                void addNewStates(PragmaWarningState directiveState, ImmutableHashSet <string> warnings)
                {
                    foreach (string id in warnings)
                    {
                        builder.Add(new KeyValuePair <string, PragmaWarningState>(id, directiveState));
                    }
                }
            }
        }
        // Given the ordered list of all pragma warning and nullable directives in the syntax tree, return a list of mapping entries,
        // containing the cumulative set of warnings that are disabled for that point in the source.
        // This mapping also contains a global warning option, accumulated of all #pragma up to the current line position.
        private static WarningStateMapEntry[] CreatePragmaWarningStateEntries(ArrayBuilder <IDirectiveTriviaSyntax> directiveList, bool isGeneratedCode)
        {
            var entries = new WarningStateMapEntry[1];
            var index   = 0;
            var accumulatedSpecificWarningState = ImmutableDictionary.Create <string, PragmaWarningState>();
            var current = new WarningStateMapEntry(0, PragmaWarningState.Default, accumulatedSpecificWarningState);

            entries[index] = current;
            return(entries);

            /* TODO:MetaDslx
             * var entries = new WarningStateMapEntry[directiveList.Count + 1];
             * var index = 0;
             *
             * // Captures the mapping of a warning number to the reporting option, accumulated of all #pragma up to the current directive.
             * var accumulatedSpecificWarningState = ImmutableDictionary.Create<string, PragmaWarningState>();
             *
             * // Captures the general reporting option, accumulated of all #pragma up to the current directive.
             * var accumulatedGeneralWarningState = PragmaWarningState.Default;
             *
             * // Generated files have a default nullable warning state that is "disabled".
             * if (isGeneratedCode)
             * {
             *  accumulatedNullableWarningState(SyntaxKind.DisableKeyword);
             * }
             *
             * var current = new WarningStateMapEntry(0, PragmaWarningState.Default, accumulatedSpecificWarningState);
             * entries[index] = current;
             *
             * while (index < directiveList.Count)
             * {
             *  var currentDirective = directiveList[index].Directive;
             *
             *  if (currentDirective.Kind == DirectiveKind.PragmaWarning)
             *  {
             *      var currentPragmaDirective = (PragmaWarningDirective)currentDirective;
             *
             *      if (currentPragmaDirective.PragmaWarningKind == PragmaWarningKind.Nullable)
             *      {
             *          accumulatedNullableWarningState(currentPragmaDirective.DisableOrRestoreKeyword.Kind());
             *      }
             *      else
             *      {
             *          // Compute the directive state
             *          PragmaWarningState directiveState;
             *
             *          switch (currentPragmaDirective.DisableOrRestoreKeyword.Kind())
             *          {
             *              case SyntaxKind.DisableKeyword:
             *                  directiveState = PragmaWarningState.Disabled;
             *                  break;
             *              case SyntaxKind.RestoreKeyword:
             *                  directiveState = PragmaWarningState.Default;
             *                  break;
             *              case SyntaxKind.EnableKeyword:
             *                  directiveState = PragmaWarningState.Enabled;
             *                  break;
             *              case SyntaxKind.SafeOnlyKeyword:
             *              default:
             *                  throw ExceptionUtilities.UnexpectedValue(currentPragmaDirective.DisableOrRestoreKeyword.Kind());
             *          }
             *
             *          // Check if this directive applies for all (e.g., #pragma warning disable)
             *          if (currentPragmaDirective.ErrorCodes.Count == 0)
             *          {
             *              // Update the warning state and reset the specific one
             *              accumulatedGeneralWarningState = directiveState;
             *              accumulatedSpecificWarningState = ImmutableDictionary.Create<string, PragmaWarningState>();
             *          }
             *          else
             *          {
             *              // Compute warning numbers from the current directive's codes
             *              for (int x = 0; x < currentPragmaDirective.ErrorCodes.Count; x++)
             *              {
             *                  var currentErrorCode = currentPragmaDirective.ErrorCodes[x];
             *                  if (currentErrorCode.IsMissing || currentErrorCode.ContainsDiagnostics)
             *                      continue;
             *
             *                  var errorId = string.Empty;
             *                  if (currentErrorCode.Kind() == SyntaxKind.NumericLiteralExpression)
             *                  {
             *                      var token = ((LiteralExpressionSyntax)currentErrorCode).Token;
             *                      errorId = MessageProvider.Instance.GetIdForErrorCode((int)token.Value);
             *                  }
             *                  else if (currentErrorCode.Kind() == SyntaxKind.IdentifierName)
             *                  {
             *                      errorId = ((IdentifierNameSyntax)currentErrorCode).Identifier.ValueText;
             *                  }
             *
             *                  if (!string.IsNullOrWhiteSpace(errorId))
             *                  {
             *                      // Update the state of this error code with the current directive state
             *                      accumulatedSpecificWarningState = accumulatedSpecificWarningState.SetItem(errorId, directiveState);
             *                  }
             *              }
             *          }
             *      }
             *  }
             *  else
             *  {
             *      var currentNullableDirective = (NullableDirectiveTriviaSyntax)currentDirective;
             *      accumulatedNullableWarningState(currentNullableDirective.SettingToken.Kind());
             *  }
             *
             *  current = new WarningStateMapEntry(currentDirective.Location.SourceSpan.End, accumulatedGeneralWarningState, accumulatedSpecificWarningState);
             ++index;
             *  entries[index] = current;
             * }
             *
             #if DEBUG
             * // Make sure the entries array is correctly sorted.
             * for (int i = 1; i < entries.Length - 1; ++i)
             * {
             *  Debug.Assert(entries[i].CompareTo(entries[i + 1]) < 0);
             * }
             #endif
             *
             * return entries;
             *
             * void accumulatedNullableWarningState(SyntaxKind nullableAction)
             * {
             *  PragmaWarningState safetyState;
             *  PragmaWarningState nonSafetyState;
             *
             *  switch (nullableAction)
             *  {
             *      case SyntaxKind.DisableKeyword:
             *          safetyState = PragmaWarningState.Disabled;
             *          nonSafetyState = PragmaWarningState.Disabled;
             *          break;
             *
             *      case SyntaxKind.EnableKeyword:
             *          safetyState = PragmaWarningState.Enabled;
             *          nonSafetyState = PragmaWarningState.Enabled;
             *          break;
             *
             *      case SyntaxKind.SafeOnlyKeyword:
             *          safetyState = PragmaWarningState.Enabled;
             *          nonSafetyState = PragmaWarningState.Disabled;
             *          break;
             *
             *      case SyntaxKind.RestoreKeyword:
             *          safetyState = PragmaWarningState.Default;
             *          nonSafetyState = PragmaWarningState.Default;
             *          break;
             *
             *      default:
             *          throw ExceptionUtilities.UnexpectedValue(nullableAction);
             *  }
             *
             *  var builder = ArrayBuilder<KeyValuePair<string, PragmaWarningState>>.GetInstance(ErrorFacts.NullableFlowAnalysisSafetyWarnings.Count + ErrorFacts.NullableFlowAnalysisNonSafetyWarnings.Count);
             *  // Update the state of the error codes with the current directive state
             *  addNewStates(safetyState, ErrorFacts.NullableFlowAnalysisSafetyWarnings);
             *  addNewStates(nonSafetyState, ErrorFacts.NullableFlowAnalysisNonSafetyWarnings);
             *
             *  accumulatedSpecificWarningState = accumulatedSpecificWarningState.SetItems(builder);
             *  builder.Free();
             *
             *  void addNewStates(PragmaWarningState directiveState, ImmutableHashSet<string> warnings)
             *  {
             *      foreach (string id in warnings)
             *      {
             *          builder.Add(new KeyValuePair<string, PragmaWarningState>(id, directiveState));
             *      }
             *  }
             * }*/
        }
示例#5
0
        // Given the ordered list of all pragma warning and nullable directives in the syntax tree, return a list of mapping entries,
        // containing the cumulative set of warnings that are disabled for that point in the source.
        // This mapping also contains a global warning option, accumulated of all #pragma up to the current line position.
        private static WarningStateMapEntry[] CreatePragmaWarningStateEntries(ArrayBuilder <DirectiveTriviaSyntax> directiveList)
        {
            var entries = new WarningStateMapEntry[directiveList.Count + 1];
            var index   = 0;

            // Captures the mapping of a warning number to the reporting option, accumulated of all #pragma up to the current directive.
            var accumulatedSpecificWarningState = ImmutableDictionary.Create <string, PragmaWarningState>();

            // Captures the general reporting option, accumulated of all #pragma up to the current directive.
            var accumulatedGeneralWarningState = PragmaWarningState.Default;

            var current = new WarningStateMapEntry(0, PragmaWarningState.Default, accumulatedSpecificWarningState);

            entries[index] = current;

            while (index < directiveList.Count)
            {
                var currentDirective       = directiveList[index];
                var currentPragmaDirective = (PragmaWarningDirectiveTriviaSyntax)currentDirective;

                // Compute the directive state
                PragmaWarningState directiveState = currentPragmaDirective.DisableOrRestoreKeyword.Kind() switch
                {
                    SyntaxKind.DisableKeyword => PragmaWarningState.Disabled,
                    SyntaxKind.RestoreKeyword => PragmaWarningState.Default,
                    SyntaxKind.EnableKeyword => PragmaWarningState.Enabled,
                    var kind => throw ExceptionUtilities.UnexpectedValue(kind)
                };

                // Check if this directive applies for all (e.g., #pragma warning disable)
                if (currentPragmaDirective.ErrorCodes.Count == 0)
                {
                    // Update the warning state and reset the specific one
                    accumulatedGeneralWarningState  = directiveState;
                    accumulatedSpecificWarningState = ImmutableDictionary.Create <string, PragmaWarningState>();
                }
                else
                {
                    // Compute warning numbers from the current directive's codes
                    for (int x = 0; x < currentPragmaDirective.ErrorCodes.Count; x++)
                    {
                        var currentErrorCode = currentPragmaDirective.ErrorCodes[x];
                        if (currentErrorCode.IsMissing || currentErrorCode.ContainsDiagnostics)
                        {
                            continue;
                        }

                        var errorId = string.Empty;
                        if (currentErrorCode.Kind() == SyntaxKind.NumericLiteralExpression)
                        {
                            var token = ((LiteralExpressionSyntax)currentErrorCode).Token;
                            errorId = MessageProvider.Instance.GetIdForErrorCode((int)token.Value !);
                        }
                        else if (currentErrorCode.Kind() == SyntaxKind.IdentifierName)
                        {
                            errorId = ((IdentifierNameSyntax)currentErrorCode).Identifier.ValueText;
                        }

                        if (!string.IsNullOrWhiteSpace(errorId))
                        {
                            // Update the state of this error code with the current directive state
                            accumulatedSpecificWarningState = accumulatedSpecificWarningState.SetItem(errorId, directiveState);
                        }
                    }
                }

                current = new WarningStateMapEntry(currentDirective.Location.SourceSpan.End, accumulatedGeneralWarningState, accumulatedSpecificWarningState);
                ++index;
                entries[index] = current;
            }

#if DEBUG
            // Make sure the entries array is correctly sorted.
            for (int i = 1; i < entries.Length - 1; ++i)
            {
                Debug.Assert(entries[i].CompareTo(entries[i + 1]) < 0);
            }
#endif

            return(entries);
        }
    }
示例#6
0
        // Given the ordered list of all pragma warning directives in the syntax tree, return a list of mapping entries,
        // containing the cumulative set of warnings that are disabled for that point in the source.
        // This mapping also contains a global warning option, accumulated of all #pragma up to the current line position.
        private static WarningStateMapEntry[] CreatePragmaWarningStateEntries(ImmutableArray <PragmaWarningDirectiveTriviaSyntax> directiveList)
        {
            var entries = new WarningStateMapEntry[directiveList.Length + 1];
            var current = new WarningStateMapEntry(0, ReportDiagnostic.Default, null);
            var index   = 0;

            entries[index] = current;

            // Captures the general reporting option, accumulated of all #pragma up to the current directive.
            var accumulatedGeneralWarningState = ReportDiagnostic.Default;

            // Captures the mapping of a warning number to the reporting option, accumulated of all #pragma up to the current directive.
            var accumulatedSpecificWarningState = ImmutableDictionary.Create <string, ReportDiagnostic>();

            while (index < directiveList.Length)
            {
                var currentDirective = directiveList[index];

                // Compute the directive state (either Disable or Restore)
                var directiveState = currentDirective.DisableOrRestoreKeyword.Kind() == SyntaxKind.DisableKeyword ? ReportDiagnostic.Suppress : ReportDiagnostic.Default;

                // Check if this directive applies for all (e.g., #pragma warning disable)
                if (currentDirective.ErrorCodes.Count == 0)
                {
                    // Update the warning state and reset the specific one
                    accumulatedGeneralWarningState  = directiveState;
                    accumulatedSpecificWarningState = ImmutableDictionary.Create <string, ReportDiagnostic>();
                }
                else
                {
                    // Compute warning numbers from the current directive's codes
                    for (int x = 0; x < currentDirective.ErrorCodes.Count; x++)
                    {
                        var currentErrorCode = currentDirective.ErrorCodes[x];
                        if (currentErrorCode.IsMissing || currentErrorCode.ContainsDiagnostics)
                        {
                            continue;
                        }

                        var errorId = string.Empty;
                        if (currentErrorCode.Kind() == SyntaxKind.NumericLiteralExpression)
                        {
                            var token = ((LiteralExpressionSyntax)currentErrorCode).Token;
                            errorId = MessageProvider.Instance.GetIdForErrorCode((int)token.Value);
                        }
                        else if (currentErrorCode.Kind() == SyntaxKind.IdentifierName)
                        {
                            errorId = ((IdentifierNameSyntax)currentErrorCode).Identifier.ValueText;
                        }

                        if (!string.IsNullOrWhiteSpace(errorId))
                        {
                            // Update the state of this error code with the current directive state
                            accumulatedSpecificWarningState = accumulatedSpecificWarningState.SetItem(errorId, directiveState);
                        }
                    }
                }
#if XSHARP
                // X# does not include the pragma directives in the SyntaxTree
                // That is why we can't compare positions, but we use line numbers in stead.
                var line = currentDirective.Position;
                current = new WarningStateMapEntry(line, accumulatedGeneralWarningState, accumulatedSpecificWarningState);
#else
                current = new WarningStateMapEntry(currentDirective.Location.SourceSpan.End, accumulatedGeneralWarningState, accumulatedSpecificWarningState);
#endif
                ++index;
                entries[index] = current;
            }

#if DEBUG
            // Make sure the entries array is correctly sorted.
            for (int i = 1; i < entries.Length - 1; ++i)
            {
                Debug.Assert(entries[i].CompareTo(entries[i + 1]) < 0);
            }
#endif

            return(entries);
        }
示例#7
0
        // Given the ordered list of all pragma warning directives in the syntax tree, return a list of mapping entries,
        // containing the cumulative set of warnings that are disabled for that point in the source.
        // This mapping also contains a global warning option, accumulated of all #pragma up to the current line position.
        private static WarningStateMapEntry[] CreatePragmaWarningStateEntries(ImmutableArray <PragmaWarningDirectiveTriviaSyntax> directiveList)
        {
            var entries = new WarningStateMapEntry[directiveList.Length + 1];
            var current = new WarningStateMapEntry(0, ReportDiagnostic.Default, null);
            var index   = 0;

            entries[index] = current;

            // Captures the general reporting option, accumulated of all #pragma up to the current directive.
            var accumulatedGeneralWarningState = ReportDiagnostic.Default;

            // Captures the mapping of a warning number to the reporting option, accumulated of all #pragma up to the current directive.
            var accumulatedSpecificWarningState = ImmutableDictionary.Create <string, ReportDiagnostic>();

            while (index < directiveList.Length)
            {
                var currentDirective = directiveList[index];

                // Compute the directive state (either Disable or Restore)
                var directiveState = currentDirective.DisableOrRestoreKeyword.CSharpKind() == SyntaxKind.DisableKeyword ? ReportDiagnostic.Suppress : ReportDiagnostic.Default;

                // Check if this directive applies for all (e.g., #pragma warning disable)
                if (currentDirective.ErrorCodes.Count == 0)
                {
                    // Update the warning state and reset the specific one
                    accumulatedGeneralWarningState  = directiveState;
                    accumulatedSpecificWarningState = ImmutableDictionary.Create <string, ReportDiagnostic>();
                }
                else
                {
                    // Compute warning numbers from the current directive's codes
                    for (int x = 0; x < currentDirective.ErrorCodes.Count; x++)
                    {
                        if (currentDirective.ErrorCodes[x].IsMissing || currentDirective.ErrorCodes[x].ContainsDiagnostics)
                        {
                            continue;
                        }

                        var    token   = ((LiteralExpressionSyntax)currentDirective.ErrorCodes[x]).Token;
                        string errorId = token.CSharpKind() == SyntaxKind.NumericLiteralToken ?
                                         MessageProvider.Instance.GetIdForErrorCode((int)token.Value) :
                                         (string)token.Value;

                        // Update the state of this error code with the current directive state
                        accumulatedSpecificWarningState = accumulatedSpecificWarningState.SetItem(errorId, directiveState);
                    }
                }

                current = new WarningStateMapEntry(currentDirective.Location.SourceSpan.End, accumulatedGeneralWarningState, accumulatedSpecificWarningState);
                ++index;
                entries[index] = current;
            }

#if DEBUG
            // Make sure the entries array is correctly sorted.
            for (int i = 1; i < entries.Length - 1; ++i)
            {
                Debug.Assert(entries[i].CompareTo(entries[i + 1]) < 0);
            }
#endif

            return(entries);
        }