| File: DataFlow\UnexpectedOperationHandler.cs | Web Access |
| Project: src\runtime\src\tools\illink\src\ILLink.RoslynAnalyzer\ILLink.RoslynAnalyzer.csproj (ILLink.RoslynAnalyzer) |
// Copyright (c) .NET Foundation and contributors. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. using System; using System.Diagnostics; using Microsoft.CodeAnalysis.Operations; namespace Microsoft.CodeAnalysis { internal static class UnexpectedOperationHandler { // No-op in release builds, but fails in debug builds when // encountering an unexpected operation. InvalidOperation is skipped because // it is expected that any part of the control-flow graph may contain an // InvalidOperation for code that doesn't compile (for example, in an intermediate // state while editing). [Conditional("DEBUG")] public static void Handle(IOperation operation) { // NoneOperation represents operations which are unimplemented by Roslyn // (don't have specific I*Operation types), such as pointer dereferences. if (operation.Kind is OperationKind.None) return; if (operation.Kind is OperationKind.Invalid) return; // It's also possible to hit a case where the operation is an unexpected operation kind, // but the code is in an invalid state where the unexpected operation is not IInvalidOperation, yet one // of its child operations is. For example: // // a + = 3; // // This is represented as an assignment where the target is an IBinaryOperation (a +) whose right-hand side // is an IInvalidOperation. The assignment logic doesn't support assigning to a binary operation, // but this should still not fail. foreach (var descendant in operation.Descendants()) { if (descendant.Kind is OperationKind.Invalid) return; } // Throw on anything else as it means we need to implement support for it // but do not throw in Release builds as it means new Roslyn version could cause the analyzer to crash // which is not fixable by the user. The analyzer is not going to be 100% correct no // matter what we do so effectively ignoring constructs it doesn't understand is OK. // This is surfaced as warning AD0001 in Debug builds. throw new NotImplementedException($"Unexpected operation type {operation.GetType()}: {operation.Syntax.GetLocation().GetLineSpan()}"); } } }