File: System\Xml\Xsl\Xslt\Scripts.cs
Web Access
Project: src\src\libraries\System.Private.Xml\src\System.Private.Xml.csproj (System.Private.Xml)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
 
// <spec>http://devdiv/Documents/Whidbey/CLR/CurrentSpecs/BCL/CodeDom%20Activation.doc</spec>
//------------------------------------------------------------------------------
 
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Xml.Xsl.Runtime;
 
namespace System.Xml.Xsl.Xslt
{
    internal sealed class Scripts
    {
        private readonly Compiler _compiler;
        private readonly TrimSafeDictionary _nsToType = new TrimSafeDictionary();
        private readonly XmlExtensionFunctionTable _extFuncs = new XmlExtensionFunctionTable();
        internal const string ExtensionFunctionCannotBeStaticallyAnalyzed = "The extension function referenced will be called from the stylesheet which cannot be statically analyzed.";
 
        public Scripts(Compiler compiler)
        {
            _compiler = compiler;
        }
 
        public TrimSafeDictionary ScriptClasses
        {
            get { return _nsToType; }
        }
 
        [RequiresUnreferencedCode(ExtensionFunctionCannotBeStaticallyAnalyzed)]
        public XmlExtensionFunction? ResolveFunction(string name, string ns, int numArgs, IErrorHelper errorHelper)
        {
            Type? type;
            if (_nsToType.TryGetValue(ns, out type))
            {
                try
                {
                    return _extFuncs.Bind(name, ns, numArgs, type, XmlQueryRuntime.EarlyBoundFlags);
                }
                catch (XslTransformException e)
                {
                    errorHelper.ReportError(e.Message);
                }
            }
            return null;
        }
 
        internal sealed class TrimSafeDictionary
        {
            private readonly Dictionary<string, Type?> _backingDictionary = new Dictionary<string, Type?>();
 
            public Type? this[string key]
            {
                [UnconditionalSuppressMessage("TrimAnalysis", "IL2073:MissingDynamicallyAccessedMembers",
                    Justification = "The getter of the dictionary is not annotated to preserve the constructor, but the sources that are adding the items to " +
                    "the dictionary are annotated so we can suppress the message as we know the constructor will be preserved.")]
                [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)]
                get => _backingDictionary[key];
                [param: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)]
                set => _backingDictionary[key] = value;
            }
 
            public ICollection<string> Keys => _backingDictionary.Keys;
 
            public int Count => _backingDictionary.Count;
 
            public bool ContainsKey(string key) => _backingDictionary.ContainsKey(key);
 
            public bool TryGetValue(string key, [MaybeNullWhen(false)] out Type value) => _backingDictionary.TryGetValue(key, out value);
        }
    }
}