File: DataFlow\UnexpectedOperationHandler.cs
Web Access
Project: src\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 ()}");
		}
	}
}