diff --git a/docs/error-codes.md b/docs/error-codes.md
index 401a26ef5cc8..3f622124d32e 100644
--- a/docs/error-codes.md
+++ b/docs/error-codes.md
@@ -1467,3 +1467,29 @@ This is technically possible if a custom assembly defines `DynamicDependencyAttr
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)]
object TestProperty { get; set; }
```
+
+### 'IL2100': XML contains unsupported wildcard for assembly "fullname" attribute
+
+- A wildcard "fullname" for an assembly in XML is only valid for link attribute XML on the command-line, not for descriptor or substitution XML or for embedded attribute XML. Specify a specific assembly name instead.
+
+ ```XML
+
+
+
+
+
+
+ ```
+
+### 'IL2101': Embedded XML in assembly 'assembly' contains assembly "fullname" attribute for another assembly 'assembly'
+
+- Embedded attribute or substitution XML may only contain elements that apply to the containing assembly. Attempting to modify another assembly will not have any effect.
+
+ ```XML
+
+
+
+
+
+
+ ```
\ No newline at end of file
diff --git a/src/linker/Linker.Steps/BodySubstituterStep.cs b/src/linker/Linker.Steps/BodySubstituterStep.cs
index 5901f80e8c60..09039c9f0b63 100644
--- a/src/linker/Linker.Steps/BodySubstituterStep.cs
+++ b/src/linker/Linker.Steps/BodySubstituterStep.cs
@@ -24,10 +24,10 @@ protected override void Process ()
ProcessXml (Context.StripSubstitutions, Context.IgnoreSubstitutions);
}
- protected override void ProcessAssembly (AssemblyDefinition assembly, XPathNodeIterator iterator, bool warnOnUnresolvedTypes)
+ protected override void ProcessAssembly (AssemblyDefinition assembly, XPathNavigator nav, bool warnOnUnresolvedTypes)
{
- ProcessTypes (assembly, iterator, warnOnUnresolvedTypes);
- ProcessResources (assembly, iterator.Current.SelectChildren ("resource", ""));
+ ProcessTypes (assembly, nav, warnOnUnresolvedTypes);
+ ProcessResources (assembly, nav.SelectChildren ("resource", ""));
}
protected override TypeDefinition ProcessExportedType (ExportedType exported, AssemblyDefinition assembly) => null;
diff --git a/src/linker/Linker.Steps/LinkAttributesStep.cs b/src/linker/Linker.Steps/LinkAttributesStep.cs
index e0be36e38bec..fb70da000dad 100644
--- a/src/linker/Linker.Steps/LinkAttributesStep.cs
+++ b/src/linker/Linker.Steps/LinkAttributesStep.cs
@@ -197,14 +197,30 @@ protected override void Process ()
ProcessXml (Context.StripLinkAttributes, Context.IgnoreLinkAttributes);
}
- protected override bool AllowAllAssembliesSelector { get => true; }
+ protected override AllowedAssemblies AllowedAssemblySelector {
+ get {
+ if (_resourceAssembly == null)
+ return AllowedAssemblies.AllAssemblies;
+
+ // Corelib XML may contain assembly wildcard to support compiler-injected attribute types
+#if NETCOREAPP
+ const string coreLib = "System.Private.CoreLib";
+#else
+ const string coreLib = "mscorlib";
+#endif
+ if (_resourceAssembly.Name.Name == coreLib)
+ return AllowedAssemblies.AllAssemblies;
+
+ return AllowedAssemblies.ContainingAssembly;
+ }
+ }
- protected override void ProcessAssembly (AssemblyDefinition assembly, XPathNodeIterator iterator, bool warnOnUnresolvedTypes)
+ protected override void ProcessAssembly (AssemblyDefinition assembly, XPathNavigator nav, bool warnOnUnresolvedTypes)
{
- IEnumerable attributes = ProcessAttributes (iterator.Current, assembly);
+ IEnumerable attributes = ProcessAttributes (nav, assembly);
if (attributes.Any ())
Context.CustomAttributes.AddCustomAttributes (assembly, attributes);
- ProcessTypes (assembly, iterator, warnOnUnresolvedTypes);
+ ProcessTypes (assembly, nav, warnOnUnresolvedTypes);
}
protected override void ProcessType (TypeDefinition type, XPathNavigator nav)
diff --git a/src/linker/Linker.Steps/ProcessLinkerXmlStepBase.cs b/src/linker/Linker.Steps/ProcessLinkerXmlStepBase.cs
index 264bd821b2f7..7a65547c9045 100644
--- a/src/linker/Linker.Steps/ProcessLinkerXmlStepBase.cs
+++ b/src/linker/Linker.Steps/ProcessLinkerXmlStepBase.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using System.Globalization;
using System.Linq;
using System.Text.RegularExpressions;
@@ -7,6 +7,14 @@
namespace Mono.Linker.Steps
{
+ [Flags]
+ public enum AllowedAssemblies
+ {
+ ContainingAssembly = 0x1,
+ AnyAssembly = 0x2 | ContainingAssembly,
+ AllAssemblies = 0x4 | AnyAssembly
+ }
+
public abstract class ProcessLinkerXmlStepBase : LoadReferencesStep
{
const string FullNameAttributeName = "fullname";
@@ -25,7 +33,7 @@ public abstract class ProcessLinkerXmlStepBase : LoadReferencesStep
protected readonly string _xmlDocumentLocation;
readonly XPathDocument _document;
readonly EmbeddedResource _resource;
- readonly AssemblyDefinition _resourceAssembly;
+ protected readonly AssemblyDefinition _resourceAssembly;
protected ProcessLinkerXmlStepBase (XPathDocument document, string xmlDocumentLocation)
{
@@ -44,6 +52,9 @@ protected ProcessLinkerXmlStepBase (XPathDocument document, EmbeddedResource res
protected virtual void ProcessXml (bool stripResource, bool ignoreResource)
{
+ if (!AllowedAssemblySelector.HasFlag (AllowedAssemblies.AnyAssembly) && _resourceAssembly == null)
+ throw new InvalidOperationException ("The containing assembly must be specified for XML which is restricted to modifying that assembly only.");
+
try {
XPathNavigator nav = _document.CreateNavigator ();
@@ -63,48 +74,65 @@ protected virtual void ProcessXml (bool stripResource, bool ignoreResource)
ProcessAssemblies (nav.SelectChildren ("assembly", ""));
+ // For embedded XML, allow not specifying the assembly explicitly in XML.
+ if (_resourceAssembly != null)
+ ProcessAssembly (_resourceAssembly, nav, warnOnUnresolvedTypes: true);
+
} catch (Exception ex) when (!(ex is LinkerFatalErrorException)) {
throw new LinkerFatalErrorException (MessageContainer.CreateErrorMessage ($"Error processing '{_xmlDocumentLocation}'", 1013), ex);
}
}
- protected virtual bool AllowAllAssembliesSelector { get => false; }
+ protected virtual AllowedAssemblies AllowedAssemblySelector { get => _resourceAssembly != null ? AllowedAssemblies.ContainingAssembly : AllowedAssemblies.AnyAssembly; }
protected virtual void ProcessAssemblies (XPathNodeIterator iterator)
{
while (iterator.MoveNext ()) {
- bool processAllAssemblies = AllowAllAssembliesSelector && GetFullName (iterator.Current) == AllAssembliesFullName;
+ bool processAllAssemblies = GetFullName (iterator.Current) == AllAssembliesFullName;
+ if (processAllAssemblies && AllowedAssemblySelector != AllowedAssemblies.AllAssemblies) {
+ Context.LogWarning ($"XML contains unsupported wildcard for assembly \"fullname\" attribute", 2100, _xmlDocumentLocation);
+ continue;
+ }
// Errors for invalid assembly names should show up even if this element will be
// skipped due to feature conditions.
var name = processAllAssemblies ? null : GetAssemblyName (iterator.Current);
+ AssemblyDefinition assemblyToProcess = null;
+ if (!AllowedAssemblySelector.HasFlag (AllowedAssemblies.AnyAssembly)) {
+ if (_resourceAssembly.Name.Name != name.Name) {
+ Context.LogWarning ($"Embedded XML in assembly '{_resourceAssembly.Name.Name}' contains assembly \"fullname\" attribute for another assembly '{name}'", 2101, _xmlDocumentLocation);
+ continue;
+ }
+ assemblyToProcess = _resourceAssembly;
+ }
+
if (!ShouldProcessElement (iterator.Current))
continue;
if (processAllAssemblies) {
foreach (AssemblyDefinition assembly in Context.GetAssemblies ())
- ProcessAssembly (assembly, iterator, warnOnUnresolvedTypes: false);
+ ProcessAssembly (assembly, iterator.Current, warnOnUnresolvedTypes: false);
} else {
- AssemblyDefinition assembly = GetAssembly (Context, name);
+ AssemblyDefinition assembly = assemblyToProcess ?? GetAssembly (Context, name);
if (assembly == null) {
Context.LogWarning ($"Could not resolve assembly '{name.Name}'", 2007, _xmlDocumentLocation);
continue;
}
- ProcessAssembly (assembly, iterator, warnOnUnresolvedTypes: true);
+ ProcessAssembly (assembly, iterator.Current, warnOnUnresolvedTypes: true);
}
}
}
- protected abstract void ProcessAssembly (AssemblyDefinition assembly, XPathNodeIterator iterator, bool warnOnUnresolvedTypes);
+ protected abstract void ProcessAssembly (AssemblyDefinition assembly, XPathNavigator nav, bool warnOnUnresolvedTypes);
- protected virtual void ProcessTypes (AssemblyDefinition assembly, XPathNodeIterator iterator, bool warnOnUnresolvedTypes)
+ protected virtual void ProcessTypes (AssemblyDefinition assembly, XPathNavigator nav, bool warnOnUnresolvedTypes)
{
- iterator = iterator.Current.SelectChildren (TypeElementName, XmlNamespace);
+ var iterator = nav.SelectChildren (TypeElementName, XmlNamespace);
while (iterator.MoveNext ()) {
- XPathNavigator nav = iterator.Current;
+ nav = iterator.Current;
if (!ShouldProcessElement (nav))
continue;
diff --git a/src/linker/Linker.Steps/ResolveFromXmlStep.cs b/src/linker/Linker.Steps/ResolveFromXmlStep.cs
index f7cd9a5e59ff..ff8ab43780d4 100644
--- a/src/linker/Linker.Steps/ResolveFromXmlStep.cs
+++ b/src/linker/Linker.Steps/ResolveFromXmlStep.cs
@@ -67,25 +67,27 @@ protected override void Process ()
ProcessXml (Context.StripDescriptors, Context.IgnoreDescriptors);
}
- protected override void ProcessAssembly (AssemblyDefinition assembly, XPathNodeIterator iterator, bool warnOnUnresolvedTypes)
+ protected override AllowedAssemblies AllowedAssemblySelector { get => AllowedAssemblies.AnyAssembly; }
+
+ protected override void ProcessAssembly (AssemblyDefinition assembly, XPathNavigator nav, bool warnOnUnresolvedTypes)
{
#if !FEATURE_ILLINK
- if (IsExcluded (iterator.Current))
+ if (IsExcluded (nav))
return;
#endif
- if (GetTypePreserve (iterator.Current) == TypePreserve.All) {
+ if (GetTypePreserve (nav) == TypePreserve.All) {
foreach (var type in assembly.MainModule.Types)
MarkAndPreserveAll (type);
} else {
- ProcessTypes (assembly, iterator, warnOnUnresolvedTypes);
- ProcessNamespaces (assembly, iterator);
+ ProcessTypes (assembly, nav, warnOnUnresolvedTypes);
+ ProcessNamespaces (assembly, nav);
}
}
- void ProcessNamespaces (AssemblyDefinition assembly, XPathNodeIterator iterator)
+ void ProcessNamespaces (AssemblyDefinition assembly, XPathNavigator nav)
{
- iterator = iterator.Current.SelectChildren (NamespaceElementName, XmlNamespace);
+ var iterator = nav.SelectChildren (NamespaceElementName, XmlNamespace);
while (iterator.MoveNext ()) {
if (!ShouldProcessElement (iterator.Current))
continue;
diff --git a/test/Mono.Linker.Tests.Cases.Expectations/Metadata/SetupCompileAfterAttribute.cs b/test/Mono.Linker.Tests.Cases.Expectations/Metadata/SetupCompileAfterAttribute.cs
index 60a54a1a8b75..199d9b4951a4 100644
--- a/test/Mono.Linker.Tests.Cases.Expectations/Metadata/SetupCompileAfterAttribute.cs
+++ b/test/Mono.Linker.Tests.Cases.Expectations/Metadata/SetupCompileAfterAttribute.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
namespace Mono.Linker.Tests.Cases.Expectations.Metadata
{
@@ -8,13 +8,26 @@ namespace Mono.Linker.Tests.Cases.Expectations.Metadata
[AttributeUsage (AttributeTargets.Class, AllowMultiple = true)]
public class SetupCompileAfterAttribute : BaseMetadataAttribute
{
- public SetupCompileAfterAttribute (string outputName, string[] sourceFiles, string[] references = null, string[] defines = null, string[] resources = null, string additionalArguments = null, string compilerToUse = null)
+ public SetupCompileAfterAttribute (string outputName, string[] sourceFiles, string[] references = null, string[] defines = null, object[] resources = null, string additionalArguments = null, string compilerToUse = null)
{
if (sourceFiles == null)
throw new ArgumentNullException (nameof (sourceFiles));
if (string.IsNullOrEmpty (outputName))
throw new ArgumentException ("Value cannot be null or empty.", nameof (outputName));
+
+ if (resources != null) {
+ foreach (var res in resources) {
+ if (res is string)
+ continue;
+ if (res is string[] stringArray) {
+ if (stringArray.Length != 2)
+ throw new ArgumentException ("Entry in object[] cannot be a string[] unless it has exactly two elements, for the resource path and name", nameof (resources));
+ continue;
+ }
+ throw new ArgumentException ("Each value in the object[] must be a string or a string[], either a resource path, or a path and name", nameof (resources));
+ }
+ }
}
}
}
diff --git a/test/Mono.Linker.Tests.Cases.Expectations/Metadata/SetupCompileBeforeAttribute.cs b/test/Mono.Linker.Tests.Cases.Expectations/Metadata/SetupCompileBeforeAttribute.cs
index 0ede197cf061..bad07736de2f 100644
--- a/test/Mono.Linker.Tests.Cases.Expectations/Metadata/SetupCompileBeforeAttribute.cs
+++ b/test/Mono.Linker.Tests.Cases.Expectations/Metadata/SetupCompileBeforeAttribute.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
namespace Mono.Linker.Tests.Cases.Expectations.Metadata
{
@@ -8,22 +8,48 @@ namespace Mono.Linker.Tests.Cases.Expectations.Metadata
[AttributeUsage (AttributeTargets.Class, AllowMultiple = true)]
public class SetupCompileBeforeAttribute : BaseMetadataAttribute
{
- public SetupCompileBeforeAttribute (string outputName, string[] sourceFiles, string[] references = null, string[] defines = null, string[] resources = null, string additionalArguments = null, string compilerToUse = null, bool addAsReference = true, bool removeFromLinkerInput = false)
+ public SetupCompileBeforeAttribute (string outputName, string[] sourceFiles, string[] references = null, string[] defines = null, object[] resources = null, string additionalArguments = null, string compilerToUse = null, bool addAsReference = true, bool removeFromLinkerInput = false)
{
if (sourceFiles == null)
throw new ArgumentNullException (nameof (sourceFiles));
if (string.IsNullOrEmpty (outputName))
throw new ArgumentException ("Value cannot be null or empty.", nameof (outputName));
+
+ if (resources != null) {
+ foreach (var res in resources) {
+ if (res is string)
+ continue;
+ if (res is string[] stringArray) {
+ if (stringArray.Length != 2)
+ throw new ArgumentException ("Entry in object[] cannot be a string[] unless it has exactly two elements, for the resource path and name", nameof (resources));
+ continue;
+ }
+ throw new ArgumentException ("Each value in the object[] must be a string or a string[], either a resource path, or a path and name", nameof (resources));
+ }
+ }
}
- public SetupCompileBeforeAttribute (string outputName, Type[] typesToIncludeSourceFor, string[] references = null, string[] defines = null, string[] resources = null, string additionalArguments = null, string compilerToUse = null, bool addAsReference = true, bool removeFromLinkerInput = false)
+ public SetupCompileBeforeAttribute (string outputName, Type[] typesToIncludeSourceFor, string[] references = null, string[] defines = null, object[] resources = null, string additionalArguments = null, string compilerToUse = null, bool addAsReference = true, bool removeFromLinkerInput = false)
{
if (typesToIncludeSourceFor == null)
throw new ArgumentNullException (nameof (typesToIncludeSourceFor));
if (string.IsNullOrEmpty (outputName))
throw new ArgumentException ("Value cannot be null or empty.", nameof (outputName));
+
+ if (resources != null) {
+ foreach (var res in resources) {
+ if (res is string)
+ continue;
+ if (res is string[] stringArray) {
+ if (stringArray.Length != 2)
+ throw new ArgumentException ("Entry in object[] cannot be a string[] unless it has exactly two elements, for the resource path and name", nameof (resources));
+ continue;
+ }
+ throw new ArgumentException ("Each value in the object[] must be a string or a string[], either a resource path, or a path and name", nameof (resources));
+ }
+ }
}
}
}
diff --git a/test/Mono.Linker.Tests.Cases/DynamicDependencies/DynamicDependencyMethodInNonReferencedAssemblyWithEmbeddedXml.cs b/test/Mono.Linker.Tests.Cases/DynamicDependencies/DynamicDependencyMethodInNonReferencedAssemblyWithEmbeddedXml.cs
index b596ad04c671..bc66f59da446 100644
--- a/test/Mono.Linker.Tests.Cases/DynamicDependencies/DynamicDependencyMethodInNonReferencedAssemblyWithEmbeddedXml.cs
+++ b/test/Mono.Linker.Tests.Cases/DynamicDependencies/DynamicDependencyMethodInNonReferencedAssemblyWithEmbeddedXml.cs
@@ -1,4 +1,4 @@
-using System.Diagnostics.CodeAnalysis;
+using System.Diagnostics.CodeAnalysis;
using System.Runtime.CompilerServices;
using Mono.Linker.Tests.Cases.DynamicDependencies.Dependencies;
using Mono.Linker.Tests.Cases.Expectations.Assertions;
@@ -15,7 +15,7 @@ namespace Mono.Linker.Tests.Cases.DynamicDependencies
"DynamicDependencyMethodInNonReferencedAssemblyLibrary.dll",
new[] { "Dependencies/DynamicDependencyMethodInNonReferencedAssemblyLibrary.cs" },
references: new[] { "base.dll" },
- resources: new[] { "Dependencies/DynamicDependencyMethodInNonReferencedAssemblyLibrary.xml" },
+ resources: new object[] { "Dependencies/DynamicDependencyMethodInNonReferencedAssemblyLibrary.xml" },
addAsReference: false)]
[KeptAssembly ("base.dll")]
[RemovedMemberInAssembly ("DynamicDependencyMethodInNonReferencedAssemblyLibrary.dll", "Mono.Linker.Tests.Cases.DynamicDependencies.Dependencies.DynamicDependencyMethodInNonReferencedAssemblyLibrary", "UnusedMethod()")]
diff --git a/test/Mono.Linker.Tests.Cases/DynamicDependencies/DynamicDependencyOnUnusedMethodInNonReferencedAssemblyWithEmbeddedXml.cs b/test/Mono.Linker.Tests.Cases/DynamicDependencies/DynamicDependencyOnUnusedMethodInNonReferencedAssemblyWithEmbeddedXml.cs
index 747e3362da22..a1bbb263dcb5 100644
--- a/test/Mono.Linker.Tests.Cases/DynamicDependencies/DynamicDependencyOnUnusedMethodInNonReferencedAssemblyWithEmbeddedXml.cs
+++ b/test/Mono.Linker.Tests.Cases/DynamicDependencies/DynamicDependencyOnUnusedMethodInNonReferencedAssemblyWithEmbeddedXml.cs
@@ -1,4 +1,4 @@
-using System.Diagnostics.CodeAnalysis;
+using System.Diagnostics.CodeAnalysis;
using System.Runtime.CompilerServices;
using Mono.Linker.Tests.Cases.DynamicDependencies.Dependencies;
using Mono.Linker.Tests.Cases.Expectations.Assertions;
@@ -15,7 +15,7 @@ namespace Mono.Linker.Tests.Cases.DynamicDependencies
"DynamicDependencyMethodInNonReferencedAssemblyLibrary.dll",
new[] { "Dependencies/DynamicDependencyMethodInNonReferencedAssemblyLibrary.cs" },
references: new[] { "base.dll" },
- resources: new[] { "Dependencies/DynamicDependencyMethodInNonReferencedAssemblyLibrary.xml" },
+ resources: new object[] { "Dependencies/DynamicDependencyMethodInNonReferencedAssemblyLibrary.xml" },
addAsReference: false)]
[KeptAssembly ("base.dll")]
[RemovedAssembly ("DynamicDependencyMethodInNonReferencedAssemblyLibrary.dll")]
diff --git a/test/Mono.Linker.Tests.Cases/LinkAttributes/Dependencies/EmbeddedAttributeErrorCases.cs b/test/Mono.Linker.Tests.Cases/LinkAttributes/Dependencies/EmbeddedAttributeErrorCases.cs
new file mode 100644
index 000000000000..9943876b4284
--- /dev/null
+++ b/test/Mono.Linker.Tests.Cases/LinkAttributes/Dependencies/EmbeddedAttributeErrorCases.cs
@@ -0,0 +1,6 @@
+namespace Mono.Linker.Tests.Cases.LinkAttributes.Dependencies
+{
+ public class EmbeddedAttributeErrorCases
+ {
+ }
+}
diff --git a/test/Mono.Linker.Tests.Cases/LinkAttributes/Dependencies/EmbeddedAttributeErrorCases.xml b/test/Mono.Linker.Tests.Cases/LinkAttributes/Dependencies/EmbeddedAttributeErrorCases.xml
new file mode 100644
index 000000000000..bdf245917a7e
--- /dev/null
+++ b/test/Mono.Linker.Tests.Cases/LinkAttributes/Dependencies/EmbeddedAttributeErrorCases.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/test/Mono.Linker.Tests.Cases/LinkAttributes/Dependencies/MockCorelib.cs b/test/Mono.Linker.Tests.Cases/LinkAttributes/Dependencies/MockCorelib.cs
new file mode 100644
index 000000000000..cd6e37a01c39
--- /dev/null
+++ b/test/Mono.Linker.Tests.Cases/LinkAttributes/Dependencies/MockCorelib.cs
@@ -0,0 +1,14 @@
+#if INCLUDE_MOCK_CORELIB
+
+using System;
+
+[assembly: MockCorelibAttributeToRemove]
+
+namespace System
+{
+ public class MockCorelibAttributeToRemove : Attribute
+ {
+ }
+}
+
+#endif
\ No newline at end of file
diff --git a/test/Mono.Linker.Tests.Cases/LinkAttributes/Dependencies/MockCorelib.xml b/test/Mono.Linker.Tests.Cases/LinkAttributes/Dependencies/MockCorelib.xml
new file mode 100644
index 000000000000..203be555ed03
--- /dev/null
+++ b/test/Mono.Linker.Tests.Cases/LinkAttributes/Dependencies/MockCorelib.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/test/Mono.Linker.Tests.Cases/LinkAttributes/EmbeddedLinkAttributes.cs b/test/Mono.Linker.Tests.Cases/LinkAttributes/EmbeddedLinkAttributes.cs
index 5a5f8e6811a8..b4c5f8d3ac93 100644
--- a/test/Mono.Linker.Tests.Cases/LinkAttributes/EmbeddedLinkAttributes.cs
+++ b/test/Mono.Linker.Tests.Cases/LinkAttributes/EmbeddedLinkAttributes.cs
@@ -3,9 +3,7 @@
// See the LICENSE file in the project root for more information.
using System;
-using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
-using System.Text;
using Mono.Linker.Tests.Cases.Expectations.Assertions;
using Mono.Linker.Tests.Cases.Expectations.Metadata;
@@ -22,6 +20,7 @@ public static void Main ()
var instance = new EmbeddedLinkAttributes ();
instance.ReadFromInstanceField ();
+ instance.ReadFromInstanceField2 ();
}
Type _typeWithPublicParameterlessConstructor;
@@ -52,5 +51,21 @@ private void ReadFromInstanceField ()
Type type)
{
}
+
+ Type _typeWithPublicFields;
+
+ [UnrecognizedReflectionAccessPattern (typeof (EmbeddedLinkAttributes), nameof (RequirePublicConstructors), new Type[] { typeof (Type) })]
+ [RecognizedReflectionAccessPattern]
+ private void ReadFromInstanceField2 ()
+ {
+ RequirePublicConstructors (_typeWithPublicFields);
+ RequirePublicFields (_typeWithPublicFields);
+ }
+
+ private static void RequirePublicFields (
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields)]
+ Type type)
+ {
+ }
}
}
diff --git a/test/Mono.Linker.Tests.Cases/LinkAttributes/EmbeddedLinkAttributes.xml b/test/Mono.Linker.Tests.Cases/LinkAttributes/EmbeddedLinkAttributes.xml
index 6a3c143dca95..00916a33816d 100644
--- a/test/Mono.Linker.Tests.Cases/LinkAttributes/EmbeddedLinkAttributes.xml
+++ b/test/Mono.Linker.Tests.Cases/LinkAttributes/EmbeddedLinkAttributes.xml
@@ -8,4 +8,11 @@
+
+
+
+ PublicFields
+
+
+
diff --git a/test/Mono.Linker.Tests.Cases/LinkAttributes/EmbeddedLinkAttributesInCorelib.cs b/test/Mono.Linker.Tests.Cases/LinkAttributes/EmbeddedLinkAttributesInCorelib.cs
new file mode 100644
index 000000000000..3453597c29c9
--- /dev/null
+++ b/test/Mono.Linker.Tests.Cases/LinkAttributes/EmbeddedLinkAttributesInCorelib.cs
@@ -0,0 +1,52 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+using System;
+using Mono.Linker.Tests.Cases.Expectations.Assertions;
+using Mono.Linker.Tests.Cases.Expectations.Metadata;
+
+namespace System
+{
+ public class MockCorelibAttributeToRemove : Attribute
+ {
+ }
+}
+
+namespace Mono.Linker.Tests.Cases.LinkAttributes
+{
+ [IgnoreLinkAttributes (false)]
+ [SetupLinkerCoreAction ("link")] // Ensure that corelib gets linked so that its attribtues are processed
+ [SetupLinkerArgument ("--skip-unresolved", "true")] // Allow unresolved references to types missing from mock corelib
+ [SetupCompileBefore (PlatformAssemblies.CoreLib, new string[] { "Dependencies/MockCorelib.cs" },
+ resources: new object[] { new string[] { "Dependencies/MockCorelib.xml", "ILLink.LinkAttributes.xml" } },
+ defines: new[] { "INCLUDE_MOCK_CORELIB" })]
+ [SkipPeVerify]
+#if NETCOREAPP
+ [RemovedAttributeInAssembly ("System.Private.CoreLib", "System.MockCorelibAttributeToRemove")]
+ [RemovedTypeInAssembly ("System.Private.CoreLib", "System.MockCorelibAttributeToRemove")]
+#else
+ [RemovedAttributeInAssembly ("mscorlib", "System.MockCorelibAttributeToRemove")]
+ [RemovedTypeInAssembly ("mscorlib", "System.MockCorelibAttributeToRemove")]
+#endif
+ class EmbeddedLinkAttributesInCorelib
+ {
+ public static void Main ()
+ {
+ AttributedMethod ();
+ var _ = new AttributedClass ();
+ }
+
+ [Kept]
+ [MockCorelibAttributeToRemove]
+ public static void AttributedMethod ()
+ {
+ }
+
+ [Kept]
+ [KeptMember (".ctor()")]
+ [MockCorelibAttributeToRemove]
+ public class AttributedClass
+ {
+ }
+ }
+}
diff --git a/test/Mono.Linker.Tests.Cases/LinkAttributes/LinkAttributeErrorCases.cs b/test/Mono.Linker.Tests.Cases/LinkAttributes/LinkAttributeErrorCases.cs
index 3d9e90262064..6f2e214f7d2b 100644
--- a/test/Mono.Linker.Tests.Cases/LinkAttributes/LinkAttributeErrorCases.cs
+++ b/test/Mono.Linker.Tests.Cases/LinkAttributes/LinkAttributeErrorCases.cs
@@ -1,14 +1,15 @@
using System;
-using System.Collections.Generic;
-using System.Text;
using Mono.Linker.Tests.Cases.Expectations.Assertions;
using Mono.Linker.Tests.Cases.Expectations.Metadata;
+using Mono.Linker.Tests.Cases.LinkAttributes.Dependencies;
namespace Mono.Linker.Tests.Cases.LinkAttributes
{
[SetupLinkAttributesFile ("LinkAttributeErrorCases.xml")]
[IgnoreLinkAttributes (false)]
[SetupLinkerArgument ("--skip-unresolved", "true")]
+ [SetupCompileBefore ("library.dll", new string[] { "Dependencies/EmbeddedAttributeErrorCases.cs" },
+ resources: new object[] { new string[] { "Dependencies/EmbeddedAttributeErrorCases.xml", "ILLink.LinkAttributes.xml" } })]
[ExpectedWarning ("IL2007", "NonExistentAssembly2", FileName = "LinkAttributeErrorCases.xml")]
[ExpectedWarning ("IL2030", "NonExistentAssembly1", FileName = "LinkAttributeErrorCases.xml")]
@@ -24,11 +25,13 @@ namespace Mono.Linker.Tests.Cases.LinkAttributes
[ExpectedWarning ("IL2051", FileName = "LinkAttributeErrorCases.xml")]
[ExpectedWarning ("IL2052", "NonExistentPropertyName", FileName = "LinkAttributeErrorCases.xml")]
[ExpectedWarning ("IL2053", "StringValue", "IntProperty", FileName = "LinkAttributeErrorCases.xml")]
+ [ExpectedWarning ("IL2100", FileName = "ILLink.LinkAttributes.xml")]
+ [ExpectedWarning ("IL2101", "library", "test", FileName = "ILLink.LinkAttributes.xml")]
class LinkAttributeErrorCases
{
public static void Main ()
{
-
+ var _ = new EmbeddedAttributeErrorCases ();
}
public enum AttributeEnum
@@ -72,5 +75,9 @@ public class SecondAttribute : Attribute { }
public Type GetTypeMethod () => null;
public void MethodWithParameter (int methodParameter) { }
+
+ public class ReferencedFromOtherAssembly
+ {
+ }
}
}
diff --git a/test/Mono.Linker.Tests.Cases/LinkXml/EmbeddedLinkXmlFromCopyAssemblyIsProcessed.cs b/test/Mono.Linker.Tests.Cases/LinkXml/EmbeddedLinkXmlFromCopyAssemblyIsProcessed.cs
index a5e3271042de..96d7e941f6a4 100644
--- a/test/Mono.Linker.Tests.Cases/LinkXml/EmbeddedLinkXmlFromCopyAssemblyIsProcessed.cs
+++ b/test/Mono.Linker.Tests.Cases/LinkXml/EmbeddedLinkXmlFromCopyAssemblyIsProcessed.cs
@@ -8,7 +8,7 @@ namespace Mono.Linker.Tests.Cases.LinkXml
new[] { "Dependencies/EmbeddedLinkXmlFromCopyAssemblyIsProcessed/OtherLibrary.cs" })]
[SetupCompileBefore ("CopyLibrary.dll",
new[] { "Dependencies/EmbeddedLinkXmlFromCopyAssemblyIsProcessed/CopyLibrary.cs" },
- resources: new[] { "Dependencies/EmbeddedLinkXmlFromCopyAssemblyIsProcessed/CopyLibrary.xml" })]
+ resources: new object[] { "Dependencies/EmbeddedLinkXmlFromCopyAssemblyIsProcessed/CopyLibrary.xml" })]
[IgnoreDescriptors (false)]
[SetupLinkerAction ("copy", "CopyLibrary")]
diff --git a/test/Mono.Linker.Tests.Cases/LinkXml/EmbeddedLinkXmlPreservesAdditionalAssemblyWithOverriddenMethod.cs b/test/Mono.Linker.Tests.Cases/LinkXml/EmbeddedLinkXmlPreservesAdditionalAssemblyWithOverriddenMethod.cs
index 37a8265ea0a7..99fa7f39e150 100644
--- a/test/Mono.Linker.Tests.Cases/LinkXml/EmbeddedLinkXmlPreservesAdditionalAssemblyWithOverriddenMethod.cs
+++ b/test/Mono.Linker.Tests.Cases/LinkXml/EmbeddedLinkXmlPreservesAdditionalAssemblyWithOverriddenMethod.cs
@@ -1,4 +1,4 @@
-using Mono.Linker.Tests.Cases.Expectations.Assertions;
+using Mono.Linker.Tests.Cases.Expectations.Assertions;
using Mono.Linker.Tests.Cases.Expectations.Metadata;
using Mono.Linker.Tests.Cases.LinkXml.Dependencies.EmbeddedLinkXmlPreservesAdditionalAssemblyWithOverriddenMethod;
@@ -9,7 +9,7 @@ namespace Mono.Linker.Tests.Cases.LinkXml
[SetupCompileBefore ("Library1.dll",
new[] { "Dependencies/EmbeddedLinkXmlPreservesAdditionalAssemblyWithOverriddenMethod/Library1.cs" },
new[] { "Base.dll" },
- resources: new[] { "Dependencies/EmbeddedLinkXmlPreservesAdditionalAssemblyWithOverriddenMethod/Library1.xml" })]
+ resources: new object[] { "Dependencies/EmbeddedLinkXmlPreservesAdditionalAssemblyWithOverriddenMethod/Library1.xml" })]
[SetupCompileBefore ("Library2.dll",
new[] { "Dependencies/EmbeddedLinkXmlPreservesAdditionalAssemblyWithOverriddenMethod/Library2.cs" },
new[] { "Base.dll" },
diff --git a/test/Mono.Linker.Tests.Cases/LinkXml/LinkXmlErrorCases.cs b/test/Mono.Linker.Tests.Cases/LinkXml/LinkXmlErrorCases.cs
index 6b5303a5dfea..cd737ab4cd9a 100644
--- a/test/Mono.Linker.Tests.Cases/LinkXml/LinkXmlErrorCases.cs
+++ b/test/Mono.Linker.Tests.Cases/LinkXml/LinkXmlErrorCases.cs
@@ -20,6 +20,7 @@ namespace Mono.Linker.Tests.Cases.LinkXml
[ExpectedWarning ("IL2025", "Event", FileName = "LinkXmlErrorCases.xml")]
[ExpectedWarning ("IL2025", "Field", FileName = "LinkXmlErrorCases.xml")]
[ExpectedWarning ("IL2025", "Property", FileName = "LinkXmlErrorCases.xml")]
+ [ExpectedWarning ("IL2100", FileName = "LinkXmlErrorCases.xml")]
class LinkXmlErrorCases
{
public static void Main ()
diff --git a/test/Mono.Linker.Tests.Cases/LinkXml/LinkXmlErrorCases.xml b/test/Mono.Linker.Tests.Cases/LinkXml/LinkXmlErrorCases.xml
index dca7c7d2d735..9ae9842be0e3 100644
--- a/test/Mono.Linker.Tests.Cases/LinkXml/LinkXmlErrorCases.xml
+++ b/test/Mono.Linker.Tests.Cases/LinkXml/LinkXmlErrorCases.xml
@@ -43,4 +43,7 @@
+
+
+
diff --git a/test/Mono.Linker.Tests.Cases/PreserveDependencies/PreserveDependencyMethodInNonReferencedAssemblyWithEmbeddedXml.cs b/test/Mono.Linker.Tests.Cases/PreserveDependencies/PreserveDependencyMethodInNonReferencedAssemblyWithEmbeddedXml.cs
index d7bd3c54fedc..2c3e4cebef42 100644
--- a/test/Mono.Linker.Tests.Cases/PreserveDependencies/PreserveDependencyMethodInNonReferencedAssemblyWithEmbeddedXml.cs
+++ b/test/Mono.Linker.Tests.Cases/PreserveDependencies/PreserveDependencyMethodInNonReferencedAssemblyWithEmbeddedXml.cs
@@ -1,4 +1,4 @@
-using System.Runtime.CompilerServices;
+using System.Runtime.CompilerServices;
using Mono.Linker.Tests.Cases.Expectations.Assertions;
using Mono.Linker.Tests.Cases.Expectations.Metadata;
using Mono.Linker.Tests.Cases.PreserveDependencies.Dependencies;
@@ -15,7 +15,7 @@ namespace Mono.Linker.Tests.Cases.PreserveDependencies
"PreserveDependencyMethodInNonReferencedAssemblyLibrary.dll",
new[] { "Dependencies/PreserveDependencyMethodInNonReferencedAssemblyLibrary.cs" },
references: new[] { "base.dll" },
- resources: new[] { "Dependencies/PreserveDependencyMethodInNonReferencedAssemblyLibrary.xml" },
+ resources: new object[] { "Dependencies/PreserveDependencyMethodInNonReferencedAssemblyLibrary.xml" },
addAsReference: false)]
[KeptAssembly ("base.dll")]
[RemovedMemberInAssembly ("PreserveDependencyMethodInNonReferencedAssemblyLibrary.dll", "Mono.Linker.Tests.Cases.PreserveDependencies.Dependencies.PreserveDependencyMethodInNonReferencedAssemblyLibrary", "UnusedMethod()")]
diff --git a/test/Mono.Linker.Tests.Cases/PreserveDependencies/PreserveDependencyOnUnusedMethodInNonReferencedAssemblyWithEmbeddedXml.cs b/test/Mono.Linker.Tests.Cases/PreserveDependencies/PreserveDependencyOnUnusedMethodInNonReferencedAssemblyWithEmbeddedXml.cs
index 770657112366..b9faa471676c 100644
--- a/test/Mono.Linker.Tests.Cases/PreserveDependencies/PreserveDependencyOnUnusedMethodInNonReferencedAssemblyWithEmbeddedXml.cs
+++ b/test/Mono.Linker.Tests.Cases/PreserveDependencies/PreserveDependencyOnUnusedMethodInNonReferencedAssemblyWithEmbeddedXml.cs
@@ -1,4 +1,4 @@
-using System.Runtime.CompilerServices;
+using System.Runtime.CompilerServices;
using Mono.Linker.Tests.Cases.Expectations.Assertions;
using Mono.Linker.Tests.Cases.Expectations.Metadata;
using Mono.Linker.Tests.Cases.PreserveDependencies.Dependencies;
@@ -15,7 +15,7 @@ namespace Mono.Linker.Tests.Cases.PreserveDependencies
"PreserveDependencyMethodInNonReferencedAssemblyLibrary.dll",
new[] { "Dependencies/PreserveDependencyMethodInNonReferencedAssemblyLibrary.cs" },
references: new[] { "base.dll" },
- resources: new[] { "Dependencies/PreserveDependencyMethodInNonReferencedAssemblyLibrary.xml" },
+ resources: new object[] { "Dependencies/PreserveDependencyMethodInNonReferencedAssemblyLibrary.xml" },
addAsReference: false)]
[KeptAssembly ("base.dll")]
[RemovedAssembly ("PreserveDependencyMethodInNonReferencedAssemblyLibrary.dll")]
diff --git a/test/Mono.Linker.Tests.Cases/Resources/Dependencies/EmbeddedLinkXmlFileIsProcessed.xml b/test/Mono.Linker.Tests.Cases/Resources/Dependencies/EmbeddedLinkXmlFileIsProcessed.xml
index 518addf3df29..2b04a8f94926 100644
--- a/test/Mono.Linker.Tests.Cases/Resources/Dependencies/EmbeddedLinkXmlFileIsProcessed.xml
+++ b/test/Mono.Linker.Tests.Cases/Resources/Dependencies/EmbeddedLinkXmlFileIsProcessed.xml
@@ -2,4 +2,5 @@
+
\ No newline at end of file
diff --git a/test/Mono.Linker.Tests.Cases/Resources/EmbeddedLinkXmlFileInReferencedAssemblyIsNotProcessedIfActionIsCopy.cs b/test/Mono.Linker.Tests.Cases/Resources/EmbeddedLinkXmlFileInReferencedAssemblyIsNotProcessedIfActionIsCopy.cs
index ebf100b07cc3..2fdd8238d6da 100644
--- a/test/Mono.Linker.Tests.Cases/Resources/EmbeddedLinkXmlFileInReferencedAssemblyIsNotProcessedIfActionIsCopy.cs
+++ b/test/Mono.Linker.Tests.Cases/Resources/EmbeddedLinkXmlFileInReferencedAssemblyIsNotProcessedIfActionIsCopy.cs
@@ -1,4 +1,4 @@
-using Mono.Linker.Tests.Cases.Expectations.Assertions;
+using Mono.Linker.Tests.Cases.Expectations.Assertions;
using Mono.Linker.Tests.Cases.Expectations.Metadata;
using Mono.Linker.Tests.Cases.Resources.Dependencies;
@@ -7,7 +7,7 @@ namespace Mono.Linker.Tests.Cases.Resources
[SetupCompileBefore (
"EmbeddedLinkXmlFileInReferencedAssemblyIsNotProcessedIfActionIsCopy_Lib1.dll",
new[] { "Dependencies/EmbeddedLinkXmlFileInReferencedAssemblyIsNotProcessedIfActionIsCopy_Lib1.cs" },
- resources: new[] { "Dependencies/EmbeddedLinkXmlFileInReferencedAssemblyIsNotProcessedIfActionIsCopy_Lib1.xml" })]
+ resources: new object[] { "Dependencies/EmbeddedLinkXmlFileInReferencedAssemblyIsNotProcessedIfActionIsCopy_Lib1.xml" })]
[SetupLinkerAction ("copy", "EmbeddedLinkXmlFileInReferencedAssemblyIsNotProcessedIfActionIsCopy_Lib1")]
[IgnoreDescriptors (false)]
diff --git a/test/Mono.Linker.Tests.Cases/Resources/EmbeddedLinkXmlFileInReferencedAssemblyIsNotProcessedIfNameDoesNotMatchAnAssembly.cs b/test/Mono.Linker.Tests.Cases/Resources/EmbeddedLinkXmlFileInReferencedAssemblyIsNotProcessedIfNameDoesNotMatchAnAssembly.cs
index 1dcbe78704b1..1dc2741862df 100644
--- a/test/Mono.Linker.Tests.Cases/Resources/EmbeddedLinkXmlFileInReferencedAssemblyIsNotProcessedIfNameDoesNotMatchAnAssembly.cs
+++ b/test/Mono.Linker.Tests.Cases/Resources/EmbeddedLinkXmlFileInReferencedAssemblyIsNotProcessedIfNameDoesNotMatchAnAssembly.cs
@@ -1,4 +1,4 @@
-using Mono.Linker.Tests.Cases.Expectations.Assertions;
+using Mono.Linker.Tests.Cases.Expectations.Assertions;
using Mono.Linker.Tests.Cases.Expectations.Metadata;
using Mono.Linker.Tests.Cases.Resources.Dependencies;
@@ -7,7 +7,7 @@ namespace Mono.Linker.Tests.Cases.Resources
[SetupCompileBefore (
"library.dll",
new[] { "Dependencies/EmbeddedLinkXmlFileInReferencedAssemblyIsNotProcessedIfNameDoesNotMatchAnAssembly_Lib1.cs" },
- resources: new[] { "Dependencies/EmbeddedLinkXmlFileInReferencedAssemblyIsNotProcessedIfNameDoesNotMatchAnAssembly_Lib1_NotMatchingName.xml" })]
+ resources: new object[] { "Dependencies/EmbeddedLinkXmlFileInReferencedAssemblyIsNotProcessedIfNameDoesNotMatchAnAssembly_Lib1_NotMatchingName.xml" })]
[IgnoreDescriptors (false)]
[KeptResourceInAssembly ("library.dll", "EmbeddedLinkXmlFileInReferencedAssemblyIsNotProcessedIfNameDoesNotMatchAnAssembly_Lib1_NotMatchingName.xml")]
diff --git a/test/Mono.Linker.Tests.Cases/Resources/EmbeddedLinkXmlFileInReferencedAssemblyIsProcessedIfActionIsLink.cs b/test/Mono.Linker.Tests.Cases/Resources/EmbeddedLinkXmlFileInReferencedAssemblyIsProcessedIfActionIsLink.cs
index c8926980b39d..b1e45f2506f5 100644
--- a/test/Mono.Linker.Tests.Cases/Resources/EmbeddedLinkXmlFileInReferencedAssemblyIsProcessedIfActionIsLink.cs
+++ b/test/Mono.Linker.Tests.Cases/Resources/EmbeddedLinkXmlFileInReferencedAssemblyIsProcessedIfActionIsLink.cs
@@ -1,4 +1,4 @@
-using Mono.Linker.Tests.Cases.Expectations.Assertions;
+using Mono.Linker.Tests.Cases.Expectations.Assertions;
using Mono.Linker.Tests.Cases.Expectations.Metadata;
using Mono.Linker.Tests.Cases.Resources.Dependencies;
@@ -7,7 +7,7 @@ namespace Mono.Linker.Tests.Cases.Resources
[SetupCompileBefore (
"EmbeddedLinkXmlFileInReferencedAssemblyIsProcessedIfActionIsLink_Lib1.dll",
new[] { "Dependencies/EmbeddedLinkXmlFileInReferencedAssemblyIsProcessedIfActionIsLink_Lib1.cs" },
- resources: new[] { "Dependencies/EmbeddedLinkXmlFileInReferencedAssemblyIsProcessedIfActionIsLink_Lib1.xml" })]
+ resources: new object[] { "Dependencies/EmbeddedLinkXmlFileInReferencedAssemblyIsProcessedIfActionIsLink_Lib1.xml" })]
[SetupLinkerAction ("link", "EmbeddedLinkXmlFileInReferencedAssemblyIsProcessedIfActionIsLink_Lib1")]
[IgnoreDescriptors (false)]
diff --git a/test/Mono.Linker.Tests.Cases/Resources/EmbeddedLinkXmlFileIsProcessed.cs b/test/Mono.Linker.Tests.Cases/Resources/EmbeddedLinkXmlFileIsProcessed.cs
index ae502329cdc0..170ad28ddfd0 100644
--- a/test/Mono.Linker.Tests.Cases/Resources/EmbeddedLinkXmlFileIsProcessed.cs
+++ b/test/Mono.Linker.Tests.Cases/Resources/EmbeddedLinkXmlFileIsProcessed.cs
@@ -19,5 +19,11 @@ public static void Main ()
public class Unused
{
}
+
+ [Kept]
+ [KeptMember (".ctor()")]
+ public class Unused2
+ {
+ }
}
}
diff --git a/test/Mono.Linker.Tests.Cases/Substitutions/Dependencies/EmbeddedSubstitutions.xml b/test/Mono.Linker.Tests.Cases/Substitutions/Dependencies/EmbeddedSubstitutions.xml
index 3bd0175a6485..00c9a0e583a7 100644
--- a/test/Mono.Linker.Tests.Cases/Substitutions/Dependencies/EmbeddedSubstitutions.xml
+++ b/test/Mono.Linker.Tests.Cases/Substitutions/Dependencies/EmbeddedSubstitutions.xml
@@ -4,4 +4,7 @@
+
+
+
\ No newline at end of file
diff --git a/test/Mono.Linker.Tests.Cases/Substitutions/Dependencies/EmbeddedSubstitutionsErrorCases.cs b/test/Mono.Linker.Tests.Cases/Substitutions/Dependencies/EmbeddedSubstitutionsErrorCases.cs
new file mode 100644
index 000000000000..ad0331b4fe62
--- /dev/null
+++ b/test/Mono.Linker.Tests.Cases/Substitutions/Dependencies/EmbeddedSubstitutionsErrorCases.cs
@@ -0,0 +1,6 @@
+namespace Mono.Linker.Tests.Cases.Substitutions.Dependencies
+{
+ public class EmbeddedSubstitutionsErrorCases
+ {
+ }
+}
diff --git a/test/Mono.Linker.Tests.Cases/Substitutions/Dependencies/EmbeddedSubstitutionsErrorCases.xml b/test/Mono.Linker.Tests.Cases/Substitutions/Dependencies/EmbeddedSubstitutionsErrorCases.xml
new file mode 100644
index 000000000000..fdf8c332a264
--- /dev/null
+++ b/test/Mono.Linker.Tests.Cases/Substitutions/Dependencies/EmbeddedSubstitutionsErrorCases.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/test/Mono.Linker.Tests.Cases/Substitutions/EmbeddedSubstitutions.cs b/test/Mono.Linker.Tests.Cases/Substitutions/EmbeddedSubstitutions.cs
index 3306aee24d1b..3faba8259c33 100644
--- a/test/Mono.Linker.Tests.Cases/Substitutions/EmbeddedSubstitutions.cs
+++ b/test/Mono.Linker.Tests.Cases/Substitutions/EmbeddedSubstitutions.cs
@@ -11,6 +11,7 @@ public class EmbeddedSubstitutions
public static void Main ()
{
ConvertToThrowMethod ();
+ ConvertToThrowMethod2 ();
}
[Kept]
@@ -22,5 +23,15 @@ public static void Main ()
public static void ConvertToThrowMethod ()
{
}
+
+ [Kept]
+ [ExpectedInstructionSequence (new[] {
+ "ldstr",
+ "newobj",
+ "throw"
+ })]
+ public static void ConvertToThrowMethod2 ()
+ {
+ }
}
}
diff --git a/test/Mono.Linker.Tests.Cases/Substitutions/SubstitutionsErrorCases.cs b/test/Mono.Linker.Tests.Cases/Substitutions/SubstitutionsErrorCases.cs
index 1789eb9634d4..2aa9c306488c 100644
--- a/test/Mono.Linker.Tests.Cases/Substitutions/SubstitutionsErrorCases.cs
+++ b/test/Mono.Linker.Tests.Cases/Substitutions/SubstitutionsErrorCases.cs
@@ -1,10 +1,13 @@
-using System;
-using Mono.Linker.Tests.Cases.Expectations.Assertions;
+using Mono.Linker.Tests.Cases.Expectations.Assertions;
using Mono.Linker.Tests.Cases.Expectations.Metadata;
+using Mono.Linker.Tests.Cases.Substitutions.Dependencies;
namespace Mono.Linker.Tests.Cases.Substitutions
{
[SetupLinkerSubstitutionFile ("SubstitutionsErrorCases.xml")]
+ [IgnoreSubstitutions (false)]
+ [SetupCompileBefore ("library.dll", new string[] { "Dependencies/EmbeddedSubstitutionsErrorCases.cs" },
+ resources: new object[] { new string[] { "Dependencies/EmbeddedSubstitutionsErrorCases.xml", "ILLink.Substitutions.xml" } })]
[ExpectedWarning ("IL2010", "TestMethod_1", "stub", FileName = "SubstitutionsErrorCases.xml")]
[ExpectedWarning ("IL2011", "TestMethod_2", "noaction", FileName = "SubstitutionsErrorCases.xml")]
@@ -12,6 +15,8 @@ namespace Mono.Linker.Tests.Cases.Substitutions
[ExpectedWarning ("IL2014", "SubstitutionsErrorCases::IntField", FileName = "SubstitutionsErrorCases.xml")]
[ExpectedWarning ("IL2015", "SubstitutionsErrorCases::IntField", "NonNumber", FileName = "SubstitutionsErrorCases.xml")]
[ExpectedWarning ("IL2007", "NonExistentAssembly", FileName = "SubstitutionsErrorCases.xml")]
+ [ExpectedWarning ("IL2100", FileName = "SubstitutionsErrorCases.xml")]
+ [ExpectedWarning ("IL2101", "library", "test", FileName = "ILLink.Substitutions.xml")]
[KeptMember (".ctor()")]
class SubstitutionsErrorCases
@@ -24,6 +29,8 @@ public static void Main ()
var instance = new SubstitutionsErrorCases ();
instance.InstanceField = 42;
IntField = 42;
+
+ var _ = new EmbeddedSubstitutionsErrorCases ();
}
[Kept]
@@ -37,5 +44,10 @@ public static void Main ()
[Kept]
public static int IntField;
+
+ public class ReferencedFromOtherAssembly
+ {
+ public static int TestMethod () { return 42; }
+ }
}
}
diff --git a/test/Mono.Linker.Tests.Cases/Substitutions/SubstitutionsErrorCases.xml b/test/Mono.Linker.Tests.Cases/Substitutions/SubstitutionsErrorCases.xml
index 272ccbc30af3..f39691a204a5 100644
--- a/test/Mono.Linker.Tests.Cases/Substitutions/SubstitutionsErrorCases.xml
+++ b/test/Mono.Linker.Tests.Cases/Substitutions/SubstitutionsErrorCases.xml
@@ -11,4 +11,6 @@
+
+
\ No newline at end of file
diff --git a/test/Mono.Linker.Tests.Cases/TestFramework/CanCompileReferencesWithResources.cs b/test/Mono.Linker.Tests.Cases/TestFramework/CanCompileReferencesWithResources.cs
index b6bfba94abcd..bcbc70ec5418 100644
--- a/test/Mono.Linker.Tests.Cases/TestFramework/CanCompileReferencesWithResources.cs
+++ b/test/Mono.Linker.Tests.Cases/TestFramework/CanCompileReferencesWithResources.cs
@@ -1,4 +1,4 @@
-using Mono.Linker.Tests.Cases.Expectations.Assertions;
+using Mono.Linker.Tests.Cases.Expectations.Assertions;
using Mono.Linker.Tests.Cases.Expectations.Metadata;
using Mono.Linker.Tests.Cases.TestFramework.Dependencies;
@@ -6,12 +6,12 @@ namespace Mono.Linker.Tests.Cases.TestFramework
{
[SetupCompileBefore ("library.dll",
new[] { "Dependencies/CanCompileReferencesWithResources_Lib1.cs" },
- resources: new[] { "Dependencies/CanCompileReferencesWithResources_Lib1.txt" })]
+ resources: new object[] { "Dependencies/CanCompileReferencesWithResources_Lib1.txt" })]
// Compile the same assembly again with another resource to get coverage on SetupCompileAfter
[SetupCompileAfter ("library.dll",
new[] { "Dependencies/CanCompileReferencesWithResources_Lib1.cs" },
- resources: new[] { "Dependencies/CanCompileReferencesWithResources_Lib1.txt", "Dependencies/CanCompileReferencesWithResources_Lib1.log" })]
+ resources: new object[] { "Dependencies/CanCompileReferencesWithResources_Lib1.txt", "Dependencies/CanCompileReferencesWithResources_Lib1.log" })]
[KeptResourceInAssembly ("library.dll", "CanCompileReferencesWithResources_Lib1.txt")]
[KeptResourceInAssembly ("library.dll", "CanCompileReferencesWithResources_Lib1.log")]
diff --git a/test/Mono.Linker.Tests.Cases/TestFramework/CanCompileReferencesWithResourcesWithCsc.cs b/test/Mono.Linker.Tests.Cases/TestFramework/CanCompileReferencesWithResourcesWithCsc.cs
index 62431c05b152..845f353dadcb 100644
--- a/test/Mono.Linker.Tests.Cases/TestFramework/CanCompileReferencesWithResourcesWithCsc.cs
+++ b/test/Mono.Linker.Tests.Cases/TestFramework/CanCompileReferencesWithResourcesWithCsc.cs
@@ -1,4 +1,4 @@
-using Mono.Linker.Tests.Cases.Expectations.Assertions;
+using Mono.Linker.Tests.Cases.Expectations.Assertions;
using Mono.Linker.Tests.Cases.Expectations.Metadata;
using Mono.Linker.Tests.Cases.TestFramework.Dependencies;
@@ -6,13 +6,13 @@ namespace Mono.Linker.Tests.Cases.TestFramework
{
[SetupCompileBefore ("library.dll",
new[] { "Dependencies/CanCompileReferencesWithResources_Lib1.cs" },
- resources: new[] { "Dependencies/CanCompileReferencesWithResources_Lib1.txt" },
+ resources: new object[] { "Dependencies/CanCompileReferencesWithResources_Lib1.txt" },
compilerToUse: "csc")]
// Compile the same assembly again with another resource to get coverage on SetupCompileAfter
[SetupCompileAfter ("library.dll",
new[] { "Dependencies/CanCompileReferencesWithResources_Lib1.cs" },
- resources: new[] { "Dependencies/CanCompileReferencesWithResources_Lib1.txt", "Dependencies/CanCompileReferencesWithResources_Lib1.log" },
+ resources: new object[] { "Dependencies/CanCompileReferencesWithResources_Lib1.txt", "Dependencies/CanCompileReferencesWithResources_Lib1.log" },
compilerToUse: "csc")]
[KeptResourceInAssembly ("library.dll", "CanCompileReferencesWithResources_Lib1.txt")]
diff --git a/test/Mono.Linker.Tests.Cases/TestFramework/CanCompileReferencesWithResourcesWithMcs.cs b/test/Mono.Linker.Tests.Cases/TestFramework/CanCompileReferencesWithResourcesWithMcs.cs
index 4b6a828d08a1..d166fb115a8c 100644
--- a/test/Mono.Linker.Tests.Cases/TestFramework/CanCompileReferencesWithResourcesWithMcs.cs
+++ b/test/Mono.Linker.Tests.Cases/TestFramework/CanCompileReferencesWithResourcesWithMcs.cs
@@ -1,4 +1,4 @@
-using Mono.Linker.Tests.Cases.Expectations.Assertions;
+using Mono.Linker.Tests.Cases.Expectations.Assertions;
using Mono.Linker.Tests.Cases.Expectations.Metadata;
using Mono.Linker.Tests.Cases.TestFramework.Dependencies;
@@ -9,13 +9,13 @@ namespace Mono.Linker.Tests.Cases.TestFramework
#endif
[SetupCompileBefore ("library.dll",
new[] { "Dependencies/CanCompileReferencesWithResources_Lib1.cs" },
- resources: new[] { "Dependencies/CanCompileReferencesWithResources_Lib1.txt" },
+ resources: new object[] { "Dependencies/CanCompileReferencesWithResources_Lib1.txt" },
compilerToUse: "mcs")]
// Compile the same assembly again with another resource to get coverage on SetupCompileAfter
[SetupCompileAfter ("library.dll",
new[] { "Dependencies/CanCompileReferencesWithResources_Lib1.cs" },
- resources: new[] { "Dependencies/CanCompileReferencesWithResources_Lib1.txt", "Dependencies/CanCompileReferencesWithResources_Lib1.log" },
+ resources: new object[] { "Dependencies/CanCompileReferencesWithResources_Lib1.txt", "Dependencies/CanCompileReferencesWithResources_Lib1.log" },
compilerToUse: "mcs")]
[KeptResourceInAssembly ("library.dll", "CanCompileReferencesWithResources_Lib1.txt")]
diff --git a/test/Mono.Linker.Tests/Extensions/CecilExtensions.cs b/test/Mono.Linker.Tests/Extensions/CecilExtensions.cs
index 598d28789484..f188033773ac 100644
--- a/test/Mono.Linker.Tests/Extensions/CecilExtensions.cs
+++ b/test/Mono.Linker.Tests/Extensions/CecilExtensions.cs
@@ -109,7 +109,7 @@ public static bool DerivesFrom (this TypeDefinition type, string baseTypeName)
if (type.BaseType.Name == baseTypeName)
return true;
- return type.BaseType.Resolve ().DerivesFrom (baseTypeName);
+ return type.BaseType.Resolve ()?.DerivesFrom (baseTypeName) ?? false;
}
public static PropertyDefinition GetPropertyDefinition (this MethodDefinition method)
diff --git a/test/Mono.Linker.Tests/TestCasesRunner/ResultChecker.cs b/test/Mono.Linker.Tests/TestCasesRunner/ResultChecker.cs
index d4024f24f284..ab7eb2da6027 100644
--- a/test/Mono.Linker.Tests/TestCasesRunner/ResultChecker.cs
+++ b/test/Mono.Linker.Tests/TestCasesRunner/ResultChecker.cs
@@ -708,7 +708,7 @@ void VerifyRecordedDependencies (AssemblyDefinition original, TestDependencyReco
{
foreach (var typeWithRemoveInAssembly in original.AllDefinedTypes ()) {
foreach (var attr in typeWithRemoveInAssembly.CustomAttributes) {
- if (attr.AttributeType.Resolve ().Name == nameof (DependencyRecordedAttribute)) {
+ if (attr.AttributeType.Resolve ()?.Name == nameof (DependencyRecordedAttribute)) {
var expectedSource = (string) attr.ConstructorArguments[0].Value;
var expectedTarget = (string) attr.ConstructorArguments[1].Value;
var expectedMarked = (string) attr.ConstructorArguments[2].Value;
@@ -758,7 +758,7 @@ void VerifyRecordedReflectionPatterns (AssemblyDefinition original, TestReflecti
foreach (var expectedSourceMemberDefinition in original.MainModule.AllDefinedTypes ().SelectMany (t => t.AllMembers ().Append (t)).Distinct ()) {
bool foundAttributesToVerify = false;
foreach (var attr in expectedSourceMemberDefinition.CustomAttributes) {
- if (attr.AttributeType.Resolve ().Name == nameof (RecognizedReflectionAccessPatternAttribute)) {
+ if (attr.AttributeType.Resolve ()?.Name == nameof (RecognizedReflectionAccessPatternAttribute)) {
foundAttributesToVerify = true;
// Special case for default .ctor - just trigger the overall verification on the method
@@ -800,7 +800,7 @@ void VerifyRecordedReflectionPatterns (AssemblyDefinition original, TestReflecti
$"Potential patterns matching the reflection member: {Environment.NewLine}{reflectionMemberCandidates}{Environment.NewLine}" +
$"If there's no matches, try to specify just a part of the source member or reflection member name and rerun the test to get potential matches.");
}
- } else if (attr.AttributeType.Resolve ().Name == nameof (UnrecognizedReflectionAccessPatternAttribute) &&
+ } else if (attr.AttributeType.Resolve ()?.Name == nameof (UnrecognizedReflectionAccessPatternAttribute) &&
attr.ConstructorArguments[0].Type.MetadataType != MetadataType.String) {
foundAttributesToVerify = true;
string expectedSourceMember = GetFullMemberNameFromDefinition (expectedSourceMemberDefinition);
@@ -881,7 +881,7 @@ void VerifyRecordedReflectionPatterns (AssemblyDefinition original, TestReflecti
foreach (var typeToVerify in original.MainModule.AllDefinedTypes ()) {
foreach (var attr in typeToVerify.CustomAttributes) {
- if (attr.AttributeType.Resolve ().Name == nameof (VerifyAllReflectionAccessPatternsAreValidatedAttribute)) {
+ if (attr.AttributeType.Resolve ()?.Name == nameof (VerifyAllReflectionAccessPatternsAreValidatedAttribute)) {
// By now all verified recorded patterns were removed from the test recorder lists, so validate
// that there are no remaining patterns for this type.
var recognizedPatternsForType = reflectionPatternRecorder.RecognizedPatterns
@@ -1071,7 +1071,7 @@ protected virtual void UnhandledOtherAssemblyAssertion (string expectedTypeName,
bool IsTypeInOtherAssemblyAssertion (CustomAttribute attr)
{
- return attr.AttributeType.Resolve ().DerivesFrom (nameof (BaseInAssemblyAttribute));
+ return attr.AttributeType.Resolve ()?.DerivesFrom (nameof (BaseInAssemblyAttribute)) ?? false;
}
bool HasAttribute (ICustomAttributeProvider caProvider, string attributeName)
diff --git a/test/Mono.Linker.Tests/TestCasesRunner/SetupCompileInfo.cs b/test/Mono.Linker.Tests/TestCasesRunner/SetupCompileInfo.cs
index 7f1e92b6439e..da329fbb1f79 100644
--- a/test/Mono.Linker.Tests/TestCasesRunner/SetupCompileInfo.cs
+++ b/test/Mono.Linker.Tests/TestCasesRunner/SetupCompileInfo.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using Mono.Linker.Tests.Extensions;
namespace Mono.Linker.Tests.TestCasesRunner
@@ -9,7 +9,7 @@ public class SetupCompileInfo
public NPath[] SourceFiles;
public string[] Defines;
public string[] References;
- public NPath[] Resources;
+ public SourceAndDestinationPair[] Resources;
public string AdditionalArguments;
public string CompilerToUse;
public bool AddAsReference;
diff --git a/test/Mono.Linker.Tests/TestCasesRunner/TestCaseMetadaProvider.cs b/test/Mono.Linker.Tests/TestCasesRunner/TestCaseMetadaProvider.cs
index e1474914d695..5f0e362ec35b 100644
--- a/test/Mono.Linker.Tests/TestCasesRunner/TestCaseMetadaProvider.cs
+++ b/test/Mono.Linker.Tests/TestCasesRunner/TestCaseMetadaProvider.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
@@ -329,7 +329,7 @@ private SetupCompileInfo CreateSetupCompileAssemblyInfo (CustomAttribute attribu
SourceFiles = SourceFilesForAttributeArgument (ctorArguments[1]),
References = ((CustomAttributeArgument[]) ctorArguments[2].Value)?.Select (arg => arg.Value.ToString ()).ToArray (),
Defines = ((CustomAttributeArgument[]) ctorArguments[3].Value)?.Select (arg => arg.Value.ToString ()).ToArray (),
- Resources = ((CustomAttributeArgument[]) ctorArguments[4].Value)?.Select (arg => MakeSourceTreeFilePathAbsolute (arg.Value.ToString ())).ToArray (),
+ Resources = ResourcesForAttributeArgument (ctorArguments[4]),
AdditionalArguments = (string) ctorArguments[5].Value,
CompilerToUse = (string) ctorArguments[6].Value,
AddAsReference = ctorArguments.Count >= 8 ? (bool) ctorArguments[7].Value : true,
@@ -350,6 +350,27 @@ protected NPath[] SourceFilesForAttributeArgument (CustomAttributeArgument attri
.ToArray ();
}
+ protected SourceAndDestinationPair[] ResourcesForAttributeArgument (CustomAttributeArgument attributeArgument)
+ {
+ return ((CustomAttributeArgument[]) attributeArgument.Value)
+ ?.Select (arg => {
+ var referenceArg = (CustomAttributeArgument) arg.Value;
+ if (referenceArg.Value is string source) {
+ var fullSource = MakeSourceTreeFilePathAbsolute (source);
+ return new SourceAndDestinationPair {
+ Source = fullSource,
+ DestinationFileName = fullSource.FileName
+ };
+ }
+ var sourceAndDestination = (CustomAttributeArgument[]) referenceArg.Value;
+ return new SourceAndDestinationPair {
+ Source = MakeSourceTreeFilePathAbsolute (sourceAndDestination[0].Value.ToString ()),
+ DestinationFileName = sourceAndDestination[1].Value.ToString ()
+ };
+ })
+ ?.ToArray ();
+ }
+
protected virtual NPath SourceFileForAttributeArgumentValue (object value)
{
if (value is TypeReference valueAsTypeRef) {
diff --git a/test/Mono.Linker.Tests/TestCasesRunner/TestCaseSandbox.cs b/test/Mono.Linker.Tests/TestCasesRunner/TestCaseSandbox.cs
index 5c8b2900f67f..5ad5eed4df50 100644
--- a/test/Mono.Linker.Tests/TestCasesRunner/TestCaseSandbox.cs
+++ b/test/Mono.Linker.Tests/TestCasesRunner/TestCaseSandbox.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using System.Collections.Generic;
using System.IO;
using Mono.Linker.Tests.Cases.Expectations.Assertions;
@@ -113,7 +113,12 @@ public virtual void Populate (TestCaseMetadaProvider metadataProvider)
compileRefInfo.SourceFiles.Copy (destination);
destination = BeforeReferenceResourceDirectoryFor (compileRefInfo.OutputName).EnsureDirectoryExists ();
- compileRefInfo.Resources?.Copy (destination);
+
+ if (compileRefInfo.Resources == null)
+ continue;
+
+ foreach (var res in compileRefInfo.Resources)
+ res.Source.FileMustExist ().Copy (destination.Combine (res.DestinationFileName));
}
foreach (var compileRefInfo in metadataProvider.GetSetupCompileAssembliesAfter ()) {
@@ -121,7 +126,12 @@ public virtual void Populate (TestCaseMetadaProvider metadataProvider)
compileRefInfo.SourceFiles.Copy (destination);
destination = AfterReferenceResourceDirectoryFor (compileRefInfo.OutputName).EnsureDirectoryExists ();
- compileRefInfo.Resources?.Copy (destination);
+
+ if (compileRefInfo.Resources == null)
+ continue;
+
+ foreach (var res in compileRefInfo.Resources)
+ res.Source.FileMustExist ().Copy (destination.Combine (res.DestinationFileName));
}
}