From 538bb290d40d8d5af5256a88c56f1f3e50ccc37e Mon Sep 17 00:00:00 2001 From: Jose Perez Rodriguez Date: Tue, 9 Mar 2021 19:55:25 -0800 Subject: [PATCH 1/5] Resolving ILLink warnings on System.Private.Xml (Part 1) --- .../src/ILLink/ILLink.Suppressions.xml | 14 ++---- .../System/Xml/Xsl/IlGen/StaticDataManager.cs | 3 +- .../src/System/Xml/Xsl/IlGen/XmlIlVisitor.cs | 6 +++ .../System/Xml/Xsl/Runtime/EarlyBoundInfo.cs | 12 ++++- .../Xml/Xsl/Runtime/XmlExtensionFunction.cs | 4 +- .../Xml/Xsl/Runtime/XmlQueryStaticData.cs | 3 ++ .../src/System/Xml/Xsl/XmlIlGenerator.cs | 1 + .../src/System/Xml/Xsl/Xslt/QilGenerator.cs | 9 ++-- .../src/System/Xml/Xsl/Xslt/Scripts.cs | 45 ++++++++++++++++++- .../System/Xml/Xslt/XslCompiledTransform.cs | 11 ++++- 10 files changed, 87 insertions(+), 21 deletions(-) diff --git a/src/libraries/System.Private.Xml/src/ILLink/ILLink.Suppressions.xml b/src/libraries/System.Private.Xml/src/ILLink/ILLink.Suppressions.xml index 5cc8e589f0faa..7c1b30ac9e2a9 100644 --- a/src/libraries/System.Private.Xml/src/ILLink/ILLink.Suppressions.xml +++ b/src/libraries/System.Private.Xml/src/ILLink/ILLink.Suppressions.xml @@ -139,12 +139,6 @@ member M:System.Xml.Serialization.XmlReflectionImporter.GetMethodFromSchemaProvider(System.Xml.Serialization.XmlSchemaProviderAttribute,System.Type) - - ILLink - IL2070 - member - M:System.Xml.Xsl.Runtime.EarlyBoundInfo.#ctor(System.String,System.Type) - ILLink IL2070 @@ -345,15 +339,15 @@ ILLink - IL2080 + IL2067 member - M:System.Xml.Xsl.Runtime.XmlExtensionFunction.Bind + M:System.Xml.Xsl.Runtime.XmlExtensionFunction.#ctor(System.String,System.String,System.Int32,System.Type,System.Reflection.BindingFlags) ILLink - IL2080 + IL2067 member - M:System.Xml.Xsl.Runtime.XmlExtensionFunction.CanBind + M:System.Xml.Xsl.Runtime.XmlExtensionFunctionTable.Bind(System.String,System.String,System.Int32,System.Type,System.Reflection.BindingFlags) diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/IlGen/StaticDataManager.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/IlGen/StaticDataManager.cs index c9e25cdad922b..8a163206ea3a4 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/IlGen/StaticDataManager.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/IlGen/StaticDataManager.cs @@ -4,6 +4,7 @@ using System.Collections; using System.Collections.Generic; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Reflection; using System.Xml.Xsl.Qil; using System.Xml.Xsl.Runtime; @@ -172,7 +173,7 @@ public int DeclareGlobalValue(string name) /// Add early bound information to a list that is used by this query. Return the index of /// the early bound information in the list. /// - public int DeclareEarlyBound(string namespaceUri, Type ebType) + public int DeclareEarlyBound(string namespaceUri, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] Type ebType) { if (_earlyInfo == null) _earlyInfo = new UniqueList(); diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/IlGen/XmlIlVisitor.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/IlGen/XmlIlVisitor.cs index 10443b3ef29ea..58e8e9582fb0e 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/IlGen/XmlIlVisitor.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/IlGen/XmlIlVisitor.cs @@ -35,6 +35,9 @@ internal class XmlILVisitor : QilVisitor private IteratorDescriptor? _iterNested; private int _indexId; + [RequiresUnreferencedCode("Method VisitXsltInvokeEarlyBound will require code that cannot be statically analyzed.")] + public XmlILVisitor() + { } //----------------------------------------------- // Entry @@ -3597,6 +3600,9 @@ protected override QilNode VisitXsltInvokeLateBound(QilInvokeLateBound ndInvoke) /// /// Generate code for QilNodeType.XsltInvokeEarlyBound. /// + [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2072:MissingRequiresUnreferencedCodeAttribute", + Justification = "Supressing warning about not having the RequiresUnreferencedCode attribute since we added " + + "the attribute to this subclass' constructor. This allows us to not have to annotate the whole QilNode hirerarchy.")] protected override QilNode VisitXsltInvokeEarlyBound(QilInvokeEarlyBound ndInvoke) { QilName ndName = ndInvoke.Name; diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Runtime/EarlyBoundInfo.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Runtime/EarlyBoundInfo.cs index 9b44a9fe557d9..aaa6586727914 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Runtime/EarlyBoundInfo.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Runtime/EarlyBoundInfo.cs @@ -3,6 +3,7 @@ #nullable disable using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Reflection; namespace System.Xml.Xsl.Runtime @@ -14,13 +15,16 @@ internal sealed class EarlyBoundInfo { private readonly string _namespaceUri; // Namespace Uri mapped to these early bound functions private readonly ConstructorInfo _constrInfo; // Constructor for the early bound function object + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] + private readonly Type _ebType; - public EarlyBoundInfo(string namespaceUri, Type ebType) + public EarlyBoundInfo(string namespaceUri, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] Type ebType) { Debug.Assert(namespaceUri != null && ebType != null); // Get the default constructor _namespaceUri = namespaceUri; + _ebType = ebType; _constrInfo = ebType.GetConstructor(Type.EmptyTypes); Debug.Assert(_constrInfo != null, "The early bound object type " + ebType.FullName + " must have a public default constructor"); } @@ -33,7 +37,11 @@ public EarlyBoundInfo(string namespaceUri, Type ebType) /// /// Return the Clr Type of the early bound object. /// - public Type EarlyBoundType { get { return _constrInfo.DeclaringType; } } + [property: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] + public Type EarlyBoundType + { + get { return _ebType; } + } /// /// Create an instance of the early bound object. diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Runtime/XmlExtensionFunction.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Runtime/XmlExtensionFunction.cs index 1707aa9d56099..6340197f07011 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Runtime/XmlExtensionFunction.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Runtime/XmlExtensionFunction.cs @@ -9,6 +9,7 @@ using System.Reflection; using System.Globalization; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; namespace System.Xml.Xsl.Runtime { @@ -57,6 +58,7 @@ internal class XmlExtensionFunction private string _namespaceUri; // Extension object identifier private string _name; // Name of this method private int _numArgs; // Argument count + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)] private Type _objectType; // Type of the object which will be searched for matching methods private BindingFlags _flags; // Modifiers that were used to search for a matching signature private int _hashCode; // Pre-computed hashcode @@ -95,7 +97,7 @@ public XmlExtensionFunction(string name, string namespaceUri, int numArgs, Type /// /// Initialize, but do not bind. /// - public void Init(string name, string namespaceUri, int numArgs, Type objectType, BindingFlags flags) + public void Init(string name, string namespaceUri, int numArgs, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.PublicMethods)] Type objectType, BindingFlags flags) { _name = name; _namespaceUri = namespaceUri; diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Runtime/XmlQueryStaticData.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Runtime/XmlQueryStaticData.cs index 6f0fd48703b77..53387597f2db4 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Runtime/XmlQueryStaticData.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Runtime/XmlQueryStaticData.cs @@ -4,6 +4,7 @@ #nullable disable using System.Collections.Generic; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.IO; using System.Xml.Xsl.IlGen; using System.Xml.Xsl.Qil; @@ -35,6 +36,7 @@ internal class XmlQueryStaticData /// /// Constructor. /// + [RequiresUnreferencedCode("This method will create a copy that uses earlybound types which cannot be statically analyzed.")] public XmlQueryStaticData(XmlWriterSettings defaultWriterSettings, IList whitespaceRules, StaticDataManager staticData) { Debug.Assert(defaultWriterSettings != null && staticData != null); @@ -70,6 +72,7 @@ public XmlQueryStaticData(XmlWriterSettings defaultWriterSettings, IList /// Deserialize XmlQueryStaticData object from a byte array. /// + [RequiresUnreferencedCode("This method will create EarlyBoundInfo from passed in ebTypes array which cannot be statically analyzed.")] public XmlQueryStaticData(byte[] data, Type[] ebTypes) { MemoryStream dataStream = new MemoryStream(data, /*writable:*/false); diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XmlIlGenerator.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XmlIlGenerator.cs index 610a883ecfb0e..698d65f46e3d3 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XmlIlGenerator.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XmlIlGenerator.cs @@ -70,6 +70,7 @@ public XmlILGenerator() // SxS Note: The way the trace file names are created (hardcoded) is NOT SxS safe. However the files are // created only for internal tracing purposes. In addition XmlILTrace class is not compiled into retail // builds. As a result it is fine to suppress the FxCop SxS warning. + [RequiresUnreferencedCode("This method will use the XmlILVisitor which will use types that cannot be statically analyzed.")] public XmlILCommand? Generate(QilExpression query, TypeBuilder? typeBldr) { _qil = query; diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Xslt/QilGenerator.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Xslt/QilGenerator.cs index d7d3d3740534d..3dd322bfb4dd7 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Xslt/QilGenerator.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Xslt/QilGenerator.cs @@ -196,13 +196,14 @@ private QilExpression Compile(Compiler compiler) } // Create list of all early bound objects - Dictionary scriptClasses = compiler.Scripts.ScriptClasses; + Scripts.LinkerSafeDictionary scriptClasses = compiler.Scripts.ScriptClasses; List ebTypes = new List(scriptClasses.Count); - foreach (KeyValuePair pair in scriptClasses) + foreach (string key in scriptClasses.Keys) { - if (pair.Value != null) + Type? value = scriptClasses[key]; + if (value != null) { - ebTypes.Add(new EarlyBoundInfo(pair.Key, pair.Value)); + ebTypes.Add(new EarlyBoundInfo(key, value)); } } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Xslt/Scripts.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Xslt/Scripts.cs index cbc8e315b3a92..c12b03b6a438c 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Xslt/Scripts.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Xslt/Scripts.cs @@ -4,7 +4,9 @@ // http://devdiv/Documents/Whidbey/CLR/CurrentSpecs/BCL/CodeDom%20Activation.doc //------------------------------------------------------------------------------ +using System.Collections; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.Xml.Xsl.Runtime; namespace System.Xml.Xsl.Xslt @@ -12,7 +14,7 @@ namespace System.Xml.Xsl.Xslt internal class Scripts { private readonly Compiler _compiler; - private readonly Dictionary _nsToType = new Dictionary(); + private readonly LinkerSafeDictionary _nsToType = new LinkerSafeDictionary(); private readonly XmlExtensionFunctionTable _extFuncs = new XmlExtensionFunctionTable(); public Scripts(Compiler compiler) @@ -20,7 +22,7 @@ public Scripts(Compiler compiler) _compiler = compiler; } - public Dictionary ScriptClasses + public LinkerSafeDictionary ScriptClasses { get { return _nsToType; } } @@ -41,5 +43,44 @@ public Scripts(Compiler compiler) } return null; } + + internal class LinkerSafeDictionary : IDictionary + { + private readonly Dictionary _backingDictionary = new Dictionary(); + + public Type? this[string key] + { + [UnconditionalSuppressMessage("TrimAnalysis", "IL2093:MissingAttributeOnBaseClass", Justification = "This implementation of IDictionary must have extra annotation attributes in order to be trim safe")] + [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 supress the message as we know the constructor will be preserved.")] + [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] + get => ((IDictionary)_backingDictionary)[key]; + [UnconditionalSuppressMessage("TrimAnalysis", "IL2092:MissingAttributeOnBaseClass", Justification = "This implementation of IDictionary must have extra annotation attributes in order to be trim safe")] + [param: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] + set => ((IDictionary)_backingDictionary)[key] = value; + } + + public ICollection Keys => ((IDictionary)_backingDictionary).Keys; + + public ICollection Values => ((IDictionary)_backingDictionary).Values; + + public int Count => ((ICollection>)_backingDictionary).Count; + + public bool IsReadOnly => ((ICollection>)_backingDictionary).IsReadOnly; + + [UnconditionalSuppressMessage("TrimAnalysis", "IL2092:MissingAttributeOnBaseClass", Justification = "This implementation of IDictionary must have extra annotation attributes in order to be trim safe")] + public void Add(string key, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] Type? value) => ((IDictionary)_backingDictionary).Add(key, value); + public void Add(KeyValuePair item) => ((ICollection>)_backingDictionary).Add(item); + public void Clear() => ((ICollection>)_backingDictionary).Clear(); + public bool Contains(KeyValuePair item) => ((ICollection>)_backingDictionary).Contains(item); + public bool ContainsKey(string key) => ((IDictionary)_backingDictionary).ContainsKey(key); + public void CopyTo(KeyValuePair[] array, int arrayIndex) => ((ICollection>)_backingDictionary).CopyTo(array, arrayIndex); + public IEnumerator> GetEnumerator() => ((IEnumerable>)_backingDictionary).GetEnumerator(); + public bool Remove(string key) => ((IDictionary)_backingDictionary).Remove(key); + public bool Remove(KeyValuePair item) => ((ICollection>)_backingDictionary).Remove(item); + public bool TryGetValue(string key, [MaybeNullWhen(false)] out Type? value) => ((IDictionary)_backingDictionary).TryGetValue(key, out value); + IEnumerator IEnumerable.GetEnumerator() => ((IEnumerable)_backingDictionary).GetEnumerator(); + } } } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xslt/XslCompiledTransform.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xslt/XslCompiledTransform.cs index 6ed5b7ace1a74..0beca4113712c 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xslt/XslCompiledTransform.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xslt/XslCompiledTransform.cs @@ -89,6 +89,7 @@ private void Reset() // SxS: This method does not take any resource name and does not expose any resources to the caller. // It's OK to suppress the SxS warning. + [RequiresUnreferencedCode("This method requires a call to LoadInternal which might use types that cannot be statically analyzed.")] public void Load(XmlReader stylesheet) { Reset(); @@ -97,6 +98,7 @@ public void Load(XmlReader stylesheet) // SxS: This method does not take any resource name and does not expose any resources to the caller. // It's OK to suppress the SxS warning. + [RequiresUnreferencedCode("This method requires a call to LoadInternal which might use types that cannot be statically analyzed.")] public void Load(XmlReader stylesheet, XsltSettings? settings, XmlResolver? stylesheetResolver) { Reset(); @@ -105,6 +107,7 @@ public void Load(XmlReader stylesheet, XsltSettings? settings, XmlResolver? styl // SxS: This method does not take any resource name and does not expose any resources to the caller. // It's OK to suppress the SxS warning. + [RequiresUnreferencedCode("This method requires a call to LoadInternal which might use types that cannot be statically analyzed.")] public void Load(IXPathNavigable stylesheet) { Reset(); @@ -113,12 +116,14 @@ public void Load(IXPathNavigable stylesheet) // SxS: This method does not take any resource name and does not expose any resources to the caller. // It's OK to suppress the SxS warning. + [RequiresUnreferencedCode("This method requires a call to LoadInternal which might use types that cannot be statically analyzed.")] public void Load(IXPathNavigable stylesheet, XsltSettings? settings, XmlResolver? stylesheetResolver) { Reset(); LoadInternal(stylesheet, settings, stylesheetResolver); } + [RequiresUnreferencedCode("This method requires a call to LoadInternal which might use types that cannot be statically analyzed.")] public void Load(string stylesheetUri) { Reset(); @@ -129,6 +134,7 @@ public void Load(string stylesheetUri) LoadInternal(stylesheetUri, XsltSettings.Default, CreateDefaultResolver()); } + [RequiresUnreferencedCode("This method requires a call to LoadInternal which might use types that cannot be statically analyzed.")] public void Load(string stylesheetUri, XsltSettings? settings, XmlResolver? stylesheetResolver) { Reset(); @@ -139,6 +145,7 @@ public void Load(string stylesheetUri, XsltSettings? settings, XmlResolver? styl LoadInternal(stylesheetUri, settings, stylesheetResolver); } + [RequiresUnreferencedCode("This method calles CompileQilToMsil method which might use types that cannot be statically analyzed.")] private CompilerErrorCollection LoadInternal(object stylesheet, XsltSettings? settings, XmlResolver? stylesheetResolver) { if (stylesheet == null) @@ -184,6 +191,7 @@ private void CompileXsltToQil(object stylesheet, XsltSettings settings, XmlResol return null; } + [RequiresUnreferencedCode("This method calls XmlILGenerator.Generate which might require types that cannot be statically analyzed.")] private void CompileQilToMsil(XsltSettings settings) { _command = new XmlILGenerator().Generate(_qil!, /*typeBuilder:*/null)!; @@ -194,7 +202,7 @@ private void CompileQilToMsil(XsltSettings settings) //------------------------------------------------ // Load compiled stylesheet from a Type //------------------------------------------------ - + [RequiresUnreferencedCode("This method uses the types that are grabbed from the compileStylesheet which cannot be statically analyzed.")] public void Load(Type compiledStylesheet) { Reset(); @@ -238,6 +246,7 @@ public void Load(Type compiledStylesheet) throw new ArgumentException(SR.Format(SR.Xslt_NotCompiledStylesheet, compiledStylesheet.FullName), nameof(compiledStylesheet)); } + [RequiresUnreferencedCode("This method uses the constructors of the passed in earlyBoundTypes which cannot be statically analyzed.")] public void Load(MethodInfo executeMethod, byte[] queryData, Type[]? earlyBoundTypes) { Reset(); From f688780cea997accec914986bfea585b2c27c542 Mon Sep 17 00:00:00 2001 From: Jose Perez Rodriguez Date: Thu, 11 Mar 2021 13:54:52 -0800 Subject: [PATCH 2/5] Only annotate the unsafe Load overload methods from XslCompiledTransform type --- .../src/System/Xml/Xsl/XmlIlGenerator.cs | 5 ++++- .../src/System/Xml/Xslt/XslCompiledTransform.cs | 12 ++---------- .../ref/System.Xml.ReaderWriter.cs | 2 ++ 3 files changed, 8 insertions(+), 11 deletions(-) diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XmlIlGenerator.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XmlIlGenerator.cs index 698d65f46e3d3..1ef849f2ee944 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XmlIlGenerator.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XmlIlGenerator.cs @@ -70,7 +70,10 @@ public XmlILGenerator() // SxS Note: The way the trace file names are created (hardcoded) is NOT SxS safe. However the files are // created only for internal tracing purposes. In addition XmlILTrace class is not compiled into retail // builds. As a result it is fine to suppress the FxCop SxS warning. - [RequiresUnreferencedCode("This method will use the XmlILVisitor which will use types that cannot be statically analyzed.")] + [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:MissingRequiresUnreferencedCode", + Justification = "This method will generate the IL methods using RefEmit at runtime, which will then try to call them " + + "using methods that are annotated as RequiresUnreferencedCode. In this case, these uses can be suppressed as the " + + "linker won't be able to trim any IL that gets generated at runtime.")] public XmlILCommand? Generate(QilExpression query, TypeBuilder? typeBldr) { _qil = query; diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xslt/XslCompiledTransform.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xslt/XslCompiledTransform.cs index 0beca4113712c..60356889441fd 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xslt/XslCompiledTransform.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xslt/XslCompiledTransform.cs @@ -89,7 +89,6 @@ private void Reset() // SxS: This method does not take any resource name and does not expose any resources to the caller. // It's OK to suppress the SxS warning. - [RequiresUnreferencedCode("This method requires a call to LoadInternal which might use types that cannot be statically analyzed.")] public void Load(XmlReader stylesheet) { Reset(); @@ -98,7 +97,6 @@ public void Load(XmlReader stylesheet) // SxS: This method does not take any resource name and does not expose any resources to the caller. // It's OK to suppress the SxS warning. - [RequiresUnreferencedCode("This method requires a call to LoadInternal which might use types that cannot be statically analyzed.")] public void Load(XmlReader stylesheet, XsltSettings? settings, XmlResolver? stylesheetResolver) { Reset(); @@ -107,7 +105,6 @@ public void Load(XmlReader stylesheet, XsltSettings? settings, XmlResolver? styl // SxS: This method does not take any resource name and does not expose any resources to the caller. // It's OK to suppress the SxS warning. - [RequiresUnreferencedCode("This method requires a call to LoadInternal which might use types that cannot be statically analyzed.")] public void Load(IXPathNavigable stylesheet) { Reset(); @@ -116,14 +113,12 @@ public void Load(IXPathNavigable stylesheet) // SxS: This method does not take any resource name and does not expose any resources to the caller. // It's OK to suppress the SxS warning. - [RequiresUnreferencedCode("This method requires a call to LoadInternal which might use types that cannot be statically analyzed.")] public void Load(IXPathNavigable stylesheet, XsltSettings? settings, XmlResolver? stylesheetResolver) { Reset(); LoadInternal(stylesheet, settings, stylesheetResolver); } - [RequiresUnreferencedCode("This method requires a call to LoadInternal which might use types that cannot be statically analyzed.")] public void Load(string stylesheetUri) { Reset(); @@ -134,7 +129,6 @@ public void Load(string stylesheetUri) LoadInternal(stylesheetUri, XsltSettings.Default, CreateDefaultResolver()); } - [RequiresUnreferencedCode("This method requires a call to LoadInternal which might use types that cannot be statically analyzed.")] public void Load(string stylesheetUri, XsltSettings? settings, XmlResolver? stylesheetResolver) { Reset(); @@ -145,7 +139,6 @@ public void Load(string stylesheetUri, XsltSettings? settings, XmlResolver? styl LoadInternal(stylesheetUri, settings, stylesheetResolver); } - [RequiresUnreferencedCode("This method calles CompileQilToMsil method which might use types that cannot be statically analyzed.")] private CompilerErrorCollection LoadInternal(object stylesheet, XsltSettings? settings, XmlResolver? stylesheetResolver) { if (stylesheet == null) @@ -191,7 +184,6 @@ private void CompileXsltToQil(object stylesheet, XsltSettings settings, XmlResol return null; } - [RequiresUnreferencedCode("This method calls XmlILGenerator.Generate which might require types that cannot be statically analyzed.")] private void CompileQilToMsil(XsltSettings settings) { _command = new XmlILGenerator().Generate(_qil!, /*typeBuilder:*/null)!; @@ -202,7 +194,7 @@ private void CompileQilToMsil(XsltSettings settings) //------------------------------------------------ // Load compiled stylesheet from a Type //------------------------------------------------ - [RequiresUnreferencedCode("This method uses the types that are grabbed from the compileStylesheet which cannot be statically analyzed.")] + [RequiresUnreferencedCode("This method will get fields and types from the assembly of the passed in compiledStylesheet and call their constructors which cannot be statically analyzed")] public void Load(Type compiledStylesheet) { Reset(); @@ -246,7 +238,7 @@ public void Load(Type compiledStylesheet) throw new ArgumentException(SR.Format(SR.Xslt_NotCompiledStylesheet, compiledStylesheet.FullName), nameof(compiledStylesheet)); } - [RequiresUnreferencedCode("This method uses the constructors of the passed in earlyBoundTypes which cannot be statically analyzed.")] + [RequiresUnreferencedCode("This method will call into constructors of the earlyBoundTypes array which cannot be statically analized.")] public void Load(MethodInfo executeMethod, byte[] queryData, Type[]? earlyBoundTypes) { Reset(); diff --git a/src/libraries/System.Xml.ReaderWriter/ref/System.Xml.ReaderWriter.cs b/src/libraries/System.Xml.ReaderWriter/ref/System.Xml.ReaderWriter.cs index 01cedbb200edd..4f3491be55f9d 100644 --- a/src/libraries/System.Xml.ReaderWriter/ref/System.Xml.ReaderWriter.cs +++ b/src/libraries/System.Xml.ReaderWriter/ref/System.Xml.ReaderWriter.cs @@ -2787,9 +2787,11 @@ public sealed partial class XslCompiledTransform public XslCompiledTransform() { } public XslCompiledTransform(bool enableDebug) { } public System.Xml.XmlWriterSettings? OutputSettings { get { throw null; } } + [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("This method will call into constructors of the earlyBoundTypes array which cannot be statically analized.")] public void Load(System.Reflection.MethodInfo executeMethod, byte[] queryData, System.Type[]? earlyBoundTypes) { } public void Load(string stylesheetUri) { } public void Load(string stylesheetUri, System.Xml.Xsl.XsltSettings? settings, System.Xml.XmlResolver? stylesheetResolver) { } + [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("This method will get fields and types from the assembly of the passed in compiledStylesheet and call their constructors which cannot be statically analyzed")] public void Load(System.Type compiledStylesheet) { } public void Load(System.Xml.XmlReader stylesheet) { } public void Load(System.Xml.XmlReader stylesheet, System.Xml.Xsl.XsltSettings? settings, System.Xml.XmlResolver? stylesheetResolver) { } From 7cbd9588796cfec0eff483854754b2beef2addf9 Mon Sep 17 00:00:00 2001 From: Jose Perez Rodriguez Date: Fri, 12 Mar 2021 15:58:13 -0800 Subject: [PATCH 3/5] Address feedback and fix one more warning --- .../src/ILLink/ILLink.Suppressions.xml | 30 ++++--------------- .../src/System/Xml/Xsl/Xslt/QilGenerator.cs | 2 +- .../src/System/Xml/Xsl/Xslt/Scripts.cs | 23 +++----------- .../src/System/Xml/Xsl/XsltOld/Processor.cs | 11 ++----- 4 files changed, 14 insertions(+), 52 deletions(-) diff --git a/src/libraries/System.Private.Xml/src/ILLink/ILLink.Suppressions.xml b/src/libraries/System.Private.Xml/src/ILLink/ILLink.Suppressions.xml index 7c1b30ac9e2a9..991377561048d 100644 --- a/src/libraries/System.Private.Xml/src/ILLink/ILLink.Suppressions.xml +++ b/src/libraries/System.Private.Xml/src/ILLink/ILLink.Suppressions.xml @@ -139,12 +139,6 @@ member M:System.Xml.Serialization.XmlReflectionImporter.GetMethodFromSchemaProvider(System.Xml.Serialization.XmlSchemaProviderAttribute,System.Type) - - ILLink - IL2070 - member - M:System.Xml.Xsl.XslCompiledTransform.Load(System.Type) - ILLink IL2072 @@ -169,12 +163,6 @@ member M:System.Xml.Serialization.XmlSerializationILGen.GenerateTypedSerializer(System.String,System.String,System.Xml.Serialization.XmlMapping,System.Xml.Serialization.CodeIdentifiers,System.String,System.String,System.String) - - ILLink - IL2072 - member - M:System.Xml.Xsl.XsltOld.Processor.#ctor(System.Xml.XPath.XPathNavigator,System.Xml.Xsl.XsltArgumentList,System.Xml.XmlResolver,System.Xml.Xsl.XsltOld.Stylesheet,System.Collections.Generic.List{System.Xml.Xsl.XsltOld.TheQuery},System.Xml.Xsl.XsltOld.RootAction,System.Xml.Xsl.XsltOld.Debugger.IXsltDebugger) - ILLink IL2075 @@ -313,18 +301,6 @@ member M:System.Xml.Serialization.XmlSerializationWriterILGen.WriteElement(System.Xml.Serialization.SourceInfo,System.Xml.Serialization.ElementAccessor,System.String,System.Boolean) - - ILLink - IL2075 - member - M:System.Xml.Xsl.IlGen.XmlILModule.BakeMethods - - - ILLink - IL2075 - member - M:System.Xml.Xsl.XsltOld.XsltCompileContext.GetExtentionMethod(System.String,System.String,System.Xml.XPath.XPathResultType[],System.Object@) - ILLink IL2077 @@ -349,5 +325,11 @@ member M:System.Xml.Xsl.Runtime.XmlExtensionFunctionTable.Bind(System.String,System.String,System.Int32,System.Type,System.Reflection.BindingFlags) + + ILLink + IL2075 + member + M:System.Xml.Xsl.XsltOld.XsltCompileContext.GetExtentionMethod(System.String,System.String,System.Xml.XPath.XPathResultType[],System.Object@) + diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Xslt/QilGenerator.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Xslt/QilGenerator.cs index 3dd322bfb4dd7..8f3526024e0ae 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Xslt/QilGenerator.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Xslt/QilGenerator.cs @@ -196,7 +196,7 @@ private QilExpression Compile(Compiler compiler) } // Create list of all early bound objects - Scripts.LinkerSafeDictionary scriptClasses = compiler.Scripts.ScriptClasses; + Scripts.TrimSafeDictionary scriptClasses = compiler.Scripts.ScriptClasses; List ebTypes = new List(scriptClasses.Count); foreach (string key in scriptClasses.Keys) { diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Xslt/Scripts.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Xslt/Scripts.cs index c12b03b6a438c..b457f6a062b43 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Xslt/Scripts.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Xslt/Scripts.cs @@ -14,7 +14,7 @@ namespace System.Xml.Xsl.Xslt internal class Scripts { private readonly Compiler _compiler; - private readonly LinkerSafeDictionary _nsToType = new LinkerSafeDictionary(); + private readonly TrimSafeDictionary _nsToType = new TrimSafeDictionary(); private readonly XmlExtensionFunctionTable _extFuncs = new XmlExtensionFunctionTable(); public Scripts(Compiler compiler) @@ -22,7 +22,7 @@ public Scripts(Compiler compiler) _compiler = compiler; } - public LinkerSafeDictionary ScriptClasses + public TrimSafeDictionary ScriptClasses { get { return _nsToType; } } @@ -44,43 +44,28 @@ public LinkerSafeDictionary ScriptClasses return null; } - internal class LinkerSafeDictionary : IDictionary + internal class TrimSafeDictionary { private readonly Dictionary _backingDictionary = new Dictionary(); public Type? this[string key] { - [UnconditionalSuppressMessage("TrimAnalysis", "IL2093:MissingAttributeOnBaseClass", Justification = "This implementation of IDictionary must have extra annotation attributes in order to be trim safe")] [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 supress the message as we know the constructor will be preserved.")] [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] get => ((IDictionary)_backingDictionary)[key]; - [UnconditionalSuppressMessage("TrimAnalysis", "IL2092:MissingAttributeOnBaseClass", Justification = "This implementation of IDictionary must have extra annotation attributes in order to be trim safe")] [param: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] set => ((IDictionary)_backingDictionary)[key] = value; } public ICollection Keys => ((IDictionary)_backingDictionary).Keys; - public ICollection Values => ((IDictionary)_backingDictionary).Values; - public int Count => ((ICollection>)_backingDictionary).Count; - public bool IsReadOnly => ((ICollection>)_backingDictionary).IsReadOnly; - - [UnconditionalSuppressMessage("TrimAnalysis", "IL2092:MissingAttributeOnBaseClass", Justification = "This implementation of IDictionary must have extra annotation attributes in order to be trim safe")] - public void Add(string key, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] Type? value) => ((IDictionary)_backingDictionary).Add(key, value); - public void Add(KeyValuePair item) => ((ICollection>)_backingDictionary).Add(item); - public void Clear() => ((ICollection>)_backingDictionary).Clear(); - public bool Contains(KeyValuePair item) => ((ICollection>)_backingDictionary).Contains(item); public bool ContainsKey(string key) => ((IDictionary)_backingDictionary).ContainsKey(key); - public void CopyTo(KeyValuePair[] array, int arrayIndex) => ((ICollection>)_backingDictionary).CopyTo(array, arrayIndex); - public IEnumerator> GetEnumerator() => ((IEnumerable>)_backingDictionary).GetEnumerator(); - public bool Remove(string key) => ((IDictionary)_backingDictionary).Remove(key); - public bool Remove(KeyValuePair item) => ((ICollection>)_backingDictionary).Remove(item); + public bool TryGetValue(string key, [MaybeNullWhen(false)] out Type? value) => ((IDictionary)_backingDictionary).TryGetValue(key, out value); - IEnumerator IEnumerable.GetEnumerator() => ((IEnumerable)_backingDictionary).GetEnumerator(); } } } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XsltOld/Processor.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XsltOld/Processor.cs index 8ef9fb4acef42..e9274d40a16a7 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XsltOld/Processor.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XsltOld/Processor.cs @@ -371,15 +371,10 @@ internal XsltOutput Output _scriptExtensions = new Hashtable(_stylesheet.ScriptObjectTypes.Count); { - foreach (DictionaryEntry entry in _stylesheet.ScriptObjectTypes) + // Scripts are not supported on stylesheets + if (_stylesheet.ScriptObjectTypes.Count > 0) { - string namespaceUri = (string)entry.Key; - if (GetExtensionObject(namespaceUri) != null) - { - throw XsltException.Create(SR.Xslt_ScriptDub, namespaceUri); - } - _scriptExtensions.Add(namespaceUri, Activator.CreateInstance((Type)entry.Value!, - BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, null, null)); + throw new PlatformNotSupportedException(SR.CompilingScriptsNotSupported); } } From 8b57fe5dc995da4d1d6a08aeb9eee8ef65d5815e Mon Sep 17 00:00:00 2001 From: Jose Perez Rodriguez Date: Mon, 15 Mar 2021 15:52:33 -0700 Subject: [PATCH 4/5] Update src/libraries/System.Private.Xml/src/System/Xml/Xsl/Runtime/EarlyBoundInfo.cs Co-authored-by: Eric Erhardt --- .../src/System/Xml/Xsl/Runtime/EarlyBoundInfo.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Runtime/EarlyBoundInfo.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Runtime/EarlyBoundInfo.cs index aaa6586727914..b63284285b45c 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Runtime/EarlyBoundInfo.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Runtime/EarlyBoundInfo.cs @@ -37,7 +37,7 @@ public EarlyBoundInfo(string namespaceUri, [DynamicallyAccessedMembers(Dynamical /// /// Return the Clr Type of the early bound object. /// - [property: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] public Type EarlyBoundType { get { return _ebType; } From 6656141d7d6c131314b02e53107e18db5d7da78a Mon Sep 17 00:00:00 2001 From: Jose Perez Rodriguez Date: Thu, 18 Mar 2021 15:19:43 -0700 Subject: [PATCH 5/5] PR Feedback --- .../src/System/Xml/Xsl/IlGen/XmlIlVisitor.cs | 2 +- .../src/System/Xml/Xsl/XmlIlGenerator.cs | 4 +-- .../src/System/Xml/Xsl/Xslt/Scripts.cs | 12 ++++---- .../System/Xml/Xslt/XslCompiledTransform.cs | 2 +- .../Xslt/XslTransformApi/CXslTransform.cs | 28 +++++++++++++++++++ .../ref/System.Xml.ReaderWriter.cs | 2 +- 6 files changed, 39 insertions(+), 11 deletions(-) diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/IlGen/XmlIlVisitor.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/IlGen/XmlIlVisitor.cs index 58e8e9582fb0e..49e6f3df25e30 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/IlGen/XmlIlVisitor.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/IlGen/XmlIlVisitor.cs @@ -3600,7 +3600,7 @@ protected override QilNode VisitXsltInvokeLateBound(QilInvokeLateBound ndInvoke) /// /// Generate code for QilNodeType.XsltInvokeEarlyBound. /// - [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2072:MissingRequiresUnreferencedCodeAttribute", + [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2072:RequiresUnreferencedCode", Justification = "Supressing warning about not having the RequiresUnreferencedCode attribute since we added " + "the attribute to this subclass' constructor. This allows us to not have to annotate the whole QilNode hirerarchy.")] protected override QilNode VisitXsltInvokeEarlyBound(QilInvokeEarlyBound ndInvoke) diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XmlIlGenerator.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XmlIlGenerator.cs index 1ef849f2ee944..0e4272fb3d899 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XmlIlGenerator.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XmlIlGenerator.cs @@ -70,10 +70,10 @@ public XmlILGenerator() // SxS Note: The way the trace file names are created (hardcoded) is NOT SxS safe. However the files are // created only for internal tracing purposes. In addition XmlILTrace class is not compiled into retail // builds. As a result it is fine to suppress the FxCop SxS warning. - [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:MissingRequiresUnreferencedCode", + [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode", Justification = "This method will generate the IL methods using RefEmit at runtime, which will then try to call them " + "using methods that are annotated as RequiresUnreferencedCode. In this case, these uses can be suppressed as the " + - "linker won't be able to trim any IL that gets generated at runtime.")] + "trimmer won't be able to trim any IL that gets generated at runtime.")] public XmlILCommand? Generate(QilExpression query, TypeBuilder? typeBldr) { _qil = query; diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Xslt/Scripts.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Xslt/Scripts.cs index b457f6a062b43..d486470c823df 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Xslt/Scripts.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Xslt/Scripts.cs @@ -54,18 +54,18 @@ internal class TrimSafeDictionary 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 supress the message as we know the constructor will be preserved.")] [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] - get => ((IDictionary)_backingDictionary)[key]; + get => _backingDictionary[key]; [param: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] - set => ((IDictionary)_backingDictionary)[key] = value; + set => _backingDictionary[key] = value; } - public ICollection Keys => ((IDictionary)_backingDictionary).Keys; + public ICollection Keys => _backingDictionary.Keys; - public int Count => ((ICollection>)_backingDictionary).Count; + public int Count => _backingDictionary.Count; - public bool ContainsKey(string key) => ((IDictionary)_backingDictionary).ContainsKey(key); + public bool ContainsKey(string key) => _backingDictionary.ContainsKey(key); - public bool TryGetValue(string key, [MaybeNullWhen(false)] out Type? value) => ((IDictionary)_backingDictionary).TryGetValue(key, out value); + public bool TryGetValue(string key, [MaybeNullWhen(false)] out Type? value) => _backingDictionary.TryGetValue(key, out value); } } } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xslt/XslCompiledTransform.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xslt/XslCompiledTransform.cs index 60356889441fd..f9abc50023f24 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xslt/XslCompiledTransform.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xslt/XslCompiledTransform.cs @@ -238,7 +238,7 @@ public void Load(Type compiledStylesheet) throw new ArgumentException(SR.Format(SR.Xslt_NotCompiledStylesheet, compiledStylesheet.FullName), nameof(compiledStylesheet)); } - [RequiresUnreferencedCode("This method will call into constructors of the earlyBoundTypes array which cannot be statically analized.")] + [RequiresUnreferencedCode("This method will call into constructors of the earlyBoundTypes array which cannot be statically analyzed.")] public void Load(MethodInfo executeMethod, byte[] queryData, Type[]? earlyBoundTypes) { Reset(); diff --git a/src/libraries/System.Private.Xml/tests/Xslt/XslTransformApi/CXslTransform.cs b/src/libraries/System.Private.Xml/tests/Xslt/XslTransformApi/CXslTransform.cs index 2a71cb87072ef..141c830925b1b 100644 --- a/src/libraries/System.Private.Xml/tests/Xslt/XslTransformApi/CXslTransform.cs +++ b/src/libraries/System.Private.Xml/tests/Xslt/XslTransformApi/CXslTransform.cs @@ -871,6 +871,34 @@ public void LoadGeneric12(InputType inputType, ReaderType readerType) _output.WriteLine("Did not throw compile exception for stylesheet"); Assert.True(false); } + + [Fact] + public void XslTransformThrowsPNSEWhenUsingScripts() + { + using StringReader xslFile = new StringReader( + @" + + + + + + + + +"); + + using XmlReader reader = XmlReader.Create(xslFile); + XslTransform xslt = new XslTransform(); + XsltCompileException compilationException = Assert.Throws(() => xslt.Load(reader)); + Assert.True(compilationException.InnerException != null && compilationException.InnerException is PlatformNotSupportedException); + } } /**************************************************************************/ diff --git a/src/libraries/System.Xml.ReaderWriter/ref/System.Xml.ReaderWriter.cs b/src/libraries/System.Xml.ReaderWriter/ref/System.Xml.ReaderWriter.cs index 4f3491be55f9d..b5d4ab5dc9311 100644 --- a/src/libraries/System.Xml.ReaderWriter/ref/System.Xml.ReaderWriter.cs +++ b/src/libraries/System.Xml.ReaderWriter/ref/System.Xml.ReaderWriter.cs @@ -2787,7 +2787,7 @@ public sealed partial class XslCompiledTransform public XslCompiledTransform() { } public XslCompiledTransform(bool enableDebug) { } public System.Xml.XmlWriterSettings? OutputSettings { get { throw null; } } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("This method will call into constructors of the earlyBoundTypes array which cannot be statically analized.")] + [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("This method will call into constructors of the earlyBoundTypes array which cannot be statically analyzed.")] public void Load(System.Reflection.MethodInfo executeMethod, byte[] queryData, System.Type[]? earlyBoundTypes) { } public void Load(string stylesheetUri) { } public void Load(string stylesheetUri, System.Xml.Xsl.XsltSettings? settings, System.Xml.XmlResolver? stylesheetResolver) { }