// 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); }
// 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)); * } * } * }*/ }
// 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); } }
// 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); }
// 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); }