File: DataFlow\FeatureContextLattice.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.Collections.Generic;
using System.Diagnostics;
using System.Runtime.InteropServices;
using ILLink.Shared;
using ILLink.Shared.DataFlow;
using Microsoft.CodeAnalysis.Diagnostics;
 
namespace ILLink.RoslynAnalyzer.DataFlow
{
	public struct FeatureContext : IEquatable<FeatureContext>, IDeepCopyValue<FeatureContext>
	{
		// The set of features known to be enabled in this context.
		// Unknown represents "all possible features".
		public ValueSet<string> EnabledFeatures;
 
		public static readonly FeatureContext All = new FeatureContext (ValueSet<string>.Unknown);
 
		public static readonly FeatureContext None = new FeatureContext (ValueSet<string>.Empty);
 
		public FeatureContext (ValueSet<string> enabled)
		{
			EnabledFeatures = enabled;
		}
 
		public bool IsEnabled (string feature)
		{
			return EnabledFeatures.IsUnknown () || EnabledFeatures.Contains (feature);
		}
 
		public bool Equals (FeatureContext other) => EnabledFeatures == other.EnabledFeatures;
		public override bool Equals (object? obj) => obj is FeatureContext other && Equals (other);
		public override int GetHashCode () => EnabledFeatures.GetHashCode ();
 
		public static bool operator == (FeatureContext left, FeatureContext right) => left.Equals (right);
		public static bool operator != (FeatureContext left, FeatureContext right) => !left.Equals (right);
 
		public FeatureContext DeepCopy ()
		{
			return new FeatureContext (EnabledFeatures.DeepCopy ());
		}
 
		public FeatureContext Intersection (FeatureContext other)
		{
			return new FeatureContext (ValueSet<string>.Intersection (EnabledFeatures, other.EnabledFeatures));
		}
 
		public FeatureContext Union (FeatureContext other)
		{
			return new FeatureContext (ValueSet<string>.Union (EnabledFeatures, other.EnabledFeatures));
		}
 
		public override string ToString ()
		{
			if (EnabledFeatures.IsUnknown ())
				return "All";
			if (EnabledFeatures.IsEmpty ())
				return "None";
			return string.Join (", ", EnabledFeatures.GetKnownValues ());
		}
	}
 
	public readonly struct FeatureContextLattice : ILattice<FeatureContext>
	{
		public FeatureContextLattice () { }
 
		// The top value is the identity of meet (intersection), the set of all features.
		public FeatureContext Top { get; } = FeatureContext.All;
 
		// We are interested in features which are known to be enabled for all paths through the CFG,
		// so the meet operator is set intersection.
		public FeatureContext Meet (FeatureContext left, FeatureContext right) => left.Intersection (right);
	}
}