File: Linker.Steps\MarkStep.NodeFactory.cs
Web Access
Project: src\src\tools\illink\src\linker\Mono.Linker.csproj (illink)
// 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.Concurrent;
using System.Collections.Generic;
using Mono.Cecil;
 
namespace Mono.Linker.Steps
{
	public partial class MarkStep
	{
		internal sealed class NodeFactory (MarkStep markStep)
		{
			public MarkStep MarkStep { get; } = markStep;
			readonly NodeCache<TypeDefinition, TypeDefinitionNode> _typeNodes = new (static t => new TypeDefinitionNode(t));
			readonly NodeCache<MethodDefinition, MethodDefinitionNode> _methodNodes = new (static _ => throw new InvalidOperationException ("Creation of node requires more than the key."));
			readonly NodeCache<PropertyDefinition, PropertyDefinitionNode> _propertyNodes = new (static p => new PropertyDefinitionNode(p));
			readonly NodeCache<TypeDefinition, TypeIsRelevantToVariantCastingNode> _typeIsRelevantToVariantCastingNodes = new (static (t) => new TypeIsRelevantToVariantCastingNode (t));
 
			internal TypeDefinitionNode GetTypeNode (TypeDefinition definition)
			{
				return _typeNodes.GetOrAdd (definition);
			}
 
			internal MethodDefinitionNode GetMethodDefinitionNode (MethodDefinition method, DependencyInfo reason)
			{
				return _methodNodes.GetOrAdd (method, (k) => new MethodDefinitionNode (k, reason));
			}
 
			internal TypeIsRelevantToVariantCastingNode GetTypeIsRelevantToVariantCastingNode (TypeDefinition type)
			{
				return _typeIsRelevantToVariantCastingNodes.GetOrAdd (type);
			}
 
			internal PropertyDefinitionNode GetPropertyNode (PropertyDefinition prop)
			{
				return _propertyNodes.GetOrAdd (prop);
			}
 
			struct NodeCache<TKey, TValue> where TKey : notnull
			{
				// Change to concurrent dictionary if/when multithreaded marking is enabled
				readonly Dictionary<TKey, TValue> _cache;
				readonly Func<TKey, TValue> _creator;
 
				public NodeCache (Func<TKey, TValue> creator, IEqualityComparer<TKey> comparer)
				{
					_creator = creator;
					_cache = new (comparer);
				}
 
				public NodeCache (Func<TKey, TValue> creator)
				{
					_creator = creator;
					_cache = new ();
				}
 
				public TValue GetOrAdd (TKey key)
				{
					return _cache.GetOrAdd (key, _creator);
				}
 
				public TValue GetOrAdd (TKey key, Func<TKey, TValue> creator)
				{
					return _cache.GetOrAdd (key, creator);
				}
			}
		}
	}
}