From 7b81c4a4caed54eca0a33509cb0d8aabbe9feab6 Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Tue, 16 Jun 2020 22:46:25 +0000 Subject: [PATCH] Support feature settings on descriptor files Fixes https://github.com/mono/linker/issues/1268. --- docs/error-codes.md | 4 +- .../Linker.Steps/BodySubstituterStep.cs | 29 +---- src/linker/Linker.Steps/LinkAttributesStep.cs | 49 +++----- src/linker/Linker.Steps/ResolveFromXmlStep.cs | 111 +++++++++++++----- .../Dependencies/ResourceFile.txt | 0 .../FeatureSettings/FeatureDescriptors.cs | 61 ++++++++++ .../FeatureSettings/FeatureDescriptors.xml | 38 ++++++ .../FeatureDescriptorsGlobalFalse.xml | 8 ++ .../FeatureDescriptorsGlobalTrue.xml | 8 ++ .../FeatureSubstitutions.cs | 2 +- .../FeatureSubstitutions.xml | 2 +- .../FeatureSubstitutionsGlobalFalse.xml | 2 +- .../FeatureSubstitutionsGlobalTrue.xml | 2 +- .../FeatureSubstitutionsInvalid.cs | 6 +- .../FeatureSubstitutionsInvalid.xml | 4 +- .../FeatureSubstitutionsNested.cs | 2 +- .../FeatureSubstitutionsNested.xml | 8 +- .../TestCases/TestDatabase.cs | 5 + .../Mono.Linker.Tests/TestCases/TestSuites.cs | 6 + 19 files changed, 243 insertions(+), 104 deletions(-) rename test/Mono.Linker.Tests.Cases/{Substitutions => FeatureSettings}/Dependencies/ResourceFile.txt (100%) create mode 100644 test/Mono.Linker.Tests.Cases/FeatureSettings/FeatureDescriptors.cs create mode 100644 test/Mono.Linker.Tests.Cases/FeatureSettings/FeatureDescriptors.xml create mode 100644 test/Mono.Linker.Tests.Cases/FeatureSettings/FeatureDescriptorsGlobalFalse.xml create mode 100644 test/Mono.Linker.Tests.Cases/FeatureSettings/FeatureDescriptorsGlobalTrue.xml rename test/Mono.Linker.Tests.Cases/{Substitutions => FeatureSettings}/FeatureSubstitutions.cs (94%) rename test/Mono.Linker.Tests.Cases/{Substitutions => FeatureSettings}/FeatureSubstitutions.xml (77%) rename test/Mono.Linker.Tests.Cases/{Substitutions => FeatureSettings}/FeatureSubstitutionsGlobalFalse.xml (80%) rename test/Mono.Linker.Tests.Cases/{Substitutions => FeatureSettings}/FeatureSubstitutionsGlobalTrue.xml (80%) rename test/Mono.Linker.Tests.Cases/{Substitutions => FeatureSettings}/FeatureSubstitutionsInvalid.cs (82%) rename test/Mono.Linker.Tests.Cases/{Substitutions => FeatureSettings}/FeatureSubstitutionsInvalid.xml (77%) rename test/Mono.Linker.Tests.Cases/{Substitutions => FeatureSettings}/FeatureSubstitutionsNested.cs (97%) rename test/Mono.Linker.Tests.Cases/{Substitutions => FeatureSettings}/FeatureSubstitutionsNested.xml (81%) diff --git a/docs/error-codes.md b/docs/error-codes.md index dd21a0773e9f..ab15ef4a92ee 100644 --- a/docs/error-codes.md +++ b/docs/error-codes.md @@ -7,11 +7,11 @@ error and warning codes. ## Error Codes -#### `IL1001`: Failed to process XML substitution: 'XML document location'. Feature 'feature' does not specify a "featurevalue" attribute +#### `IL1001`: Failed to process 'XML document location'. Feature 'feature' does not specify a "featurevalue" attribute - The substitution in 'XML document location' with feature value 'feature' does not use the `featurevalue` attribute. These attributes have to be used together. -#### `IL1002`: Failed to process XML substitution: 'XML document location'. Unsupported non-boolean feature definition 'feature' +#### `IL1002`: Failed to process 'XML document location'. Unsupported non-boolean feature definition 'feature' - The substitution in 'XML document location' with feature value 'feature' sets the attribute `featurevalue` to a non-boolean value. Only boolean values are supported for this attribute. diff --git a/src/linker/Linker.Steps/BodySubstituterStep.cs b/src/linker/Linker.Steps/BodySubstituterStep.cs index 91f3da6550f3..e67f9aca9aa5 100644 --- a/src/linker/Linker.Steps/BodySubstituterStep.cs +++ b/src/linker/Linker.Steps/BodySubstituterStep.cs @@ -1,4 +1,5 @@ using System; +using System.Diagnostics; using System.Linq; using System.Globalization; using System.Xml.XPath; @@ -41,28 +42,7 @@ protected override void Process () ReadSubstitutions (_document); } - bool ShouldProcessSubstitutions (XPathNavigator nav) - { - var feature = GetAttribute (nav, "feature"); - if (string.IsNullOrEmpty (feature)) - return true; - - var value = GetAttribute (nav, "featurevalue"); - if (string.IsNullOrEmpty (value)) { - Context.LogError ($"Failed to process XML substitution: '{_xmlDocumentLocation}'. Feature {feature} does not specify a 'featurevalue' attribute", 1001); - return false; - } - - if (!bool.TryParse (value, out bool bValue)) { - Context.LogError ($"Failed to process XML substitution: '{_xmlDocumentLocation}'. Unsupported non-boolean feature definition {feature}", 1002); - return false; - } - - if (Context.FeatureSettings == null || !Context.FeatureSettings.TryGetValue (feature, out bool featureSetting)) - return false; - - return bValue == featureSetting; - } + bool ShouldProcessSubstitutions (XPathNavigator nav) => ResolveFromXmlStep.ShouldProcessElement (nav, Context, _xmlDocumentLocation); void ReadSubstitutions (XPathDocument document) { @@ -126,10 +106,9 @@ void ProcessTypes (AssemblyDefinition assembly, XPathNodeIterator iterator) void ProcessType (TypeDefinition type, XPathNavigator nav) { - if (!nav.HasChildren) - return; + Debug.Assert (ShouldProcessSubstitutions (nav)); - if (!ShouldProcessSubstitutions (nav)) + if (!nav.HasChildren) return; XPathNodeIterator methods = nav.SelectChildren ("method", ""); diff --git a/src/linker/Linker.Steps/LinkAttributesStep.cs b/src/linker/Linker.Steps/LinkAttributesStep.cs index 688eaf2b9c2f..de2ab0cfa850 100644 --- a/src/linker/Linker.Steps/LinkAttributesStep.cs +++ b/src/linker/Linker.Steps/LinkAttributesStep.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.Linq; using System.Text; using System.Text.RegularExpressions; @@ -154,7 +155,7 @@ void ProcessAssemblies (LinkContext context, XPathNodeIterator iterator) { while (iterator.MoveNext ()) { if (!ShouldProcessElement (iterator.Current)) - return; + continue; if (GetFullName (iterator.Current) == "*") { foreach (AssemblyDefinition assemblyIterator in context.GetAssemblies ()) { @@ -249,6 +250,8 @@ void ProcessTypePattern (string fullname, AssemblyDefinition assembly, XPathNavi void ProcessType (TypeDefinition type, XPathNavigator nav) { + Debug.Assert (ShouldProcessElement (nav)); + IEnumerable attributes = ProcessAttributes (nav); if (attributes.Count () > 0) Context.CustomAttributes.AddCustomAttributes (type, attributes); @@ -283,9 +286,9 @@ void ProcessSelectedFields (XPathNavigator nav, TypeDefinition type) return; while (fields.MoveNext ()) { - if (!ShouldProcessElement (fields.Current)) { - return; - } + if (!ShouldProcessElement (fields.Current)) + continue; + string value = GetSignature (fields.Current); if (!String.IsNullOrEmpty (value)) ProcessFieldSignature (type, value, fields); @@ -303,9 +306,8 @@ void ProcessSelectedMethods (XPathNavigator nav, TypeDefinition type) return; while (methods.MoveNext ()) { - if (!ShouldProcessElement (methods.Current)) { - return; - } + if (!ShouldProcessElement (methods.Current)) + continue; string value = GetSignature (methods.Current); if (!String.IsNullOrEmpty (value)) @@ -323,9 +325,8 @@ void ProcessSelectedProperties (XPathNavigator nav, TypeDefinition type) if (properties.Count == 0) return; while (properties.MoveNext ()) { - if (!ShouldProcessElement (properties.Current)) { - return; - } + if (!ShouldProcessElement (properties.Current)) + continue; string value = GetSignature (properties.Current); if (!String.IsNullOrEmpty (value)) @@ -343,9 +344,8 @@ void ProcessSelectedEvents (XPathNavigator nav, TypeDefinition type) if (events.Count == 0) return; while (events.MoveNext ()) { - if (!ShouldProcessElement (events.Current)) { - return; - } + if (!ShouldProcessElement (events.Current)) + continue; string value = GetSignature (events.Current); if (!String.IsNullOrEmpty (value)) @@ -600,27 +600,6 @@ static PropertyDefinition GetProperty (TypeDefinition type, string signature) return null; } - bool ShouldProcessElement (XPathNavigator nav) - { - var feature = GetAttribute (nav, "feature"); - if (string.IsNullOrEmpty (feature)) - return true; - - var value = GetAttribute (nav, "featurevalue"); - if (string.IsNullOrEmpty (value)) { - Context.LogError ($"Feature {feature} does not specify a \"featurevalue\" attribute", 1001); - return false; - } - - if (!bool.TryParse (value, out bool bValue)) { - Context.LogError ($"Unsupported non-boolean feature definition {feature}", 1002); - return false; - } - - if (Context.FeatureSettings == null || !Context.FeatureSettings.TryGetValue (feature, out bool featureSetting)) - return false; - - return bValue == featureSetting; - } + bool ShouldProcessElement (XPathNavigator nav) => ResolveFromXmlStep.ShouldProcessElement (nav, Context, _xmlDocumentLocation); } } \ No newline at end of file diff --git a/src/linker/Linker.Steps/ResolveFromXmlStep.cs b/src/linker/Linker.Steps/ResolveFromXmlStep.cs index dbd3f57f2739..07a95eae86aa 100644 --- a/src/linker/Linker.Steps/ResolveFromXmlStep.cs +++ b/src/linker/Linker.Steps/ResolveFromXmlStep.cs @@ -29,6 +29,7 @@ // using System; +using System.Diagnostics; using System.Text; using System.Text.RegularExpressions; using System.Xml.XPath; @@ -71,6 +72,8 @@ public ResolveFromXmlStep (XPathDocument document, EmbeddedResource resource, As _resourceAssembly = resourceAssembly ?? throw new ArgumentNullException (nameof (resourceAssembly)); } + bool ShouldProcessElement (XPathNavigator nav) => ShouldProcessElement (nav, Context, _xmlDocumentLocation); + protected override void Process () { XPathNavigator nav = _document.CreateNavigator (); @@ -86,17 +89,26 @@ protected override void Process () if (Context.IgnoreDescriptors) return; } + + if (!ShouldProcessElement (nav)) + return; + try { - ProcessAssemblies (Context, nav.SelectChildren ("assembly", _ns)); + ProcessAssemblies (nav.SelectChildren ("assembly", _ns)); } catch (Exception ex) when (!(ex is LinkerFatalErrorException)) { throw new LinkerFatalErrorException (MessageContainer.CreateErrorMessage ($"Failed to process description file '{_xmlDocumentLocation}'", 1004), ex); } } - protected virtual void ProcessAssemblies (LinkContext context, XPathNodeIterator iterator) + protected virtual void ProcessAssemblies (XPathNodeIterator iterator) { while (iterator.MoveNext ()) { - AssemblyDefinition assembly = GetAssembly (context, GetAssemblyName (iterator.Current)); + var name = GetAssemblyName (iterator.Current); + + if (!ShouldProcessElement (iterator.Current)) + continue; + + AssemblyDefinition assembly = GetAssembly (Context, name); if (assembly != null) ProcessAssembly (assembly, iterator); } @@ -121,6 +133,9 @@ protected virtual void ProcessAssembly (AssemblyDefinition assembly, XPathNodeIt void ProcessNamespaces (AssemblyDefinition assembly, XPathNodeIterator iterator) { while (iterator.MoveNext ()) { + if (!ShouldProcessElement (iterator.Current)) + continue; + string fullname = GetFullName (iterator.Current); foreach (TypeDefinition type in assembly.MainModule.Types) { if (type.Namespace != fullname) @@ -148,6 +163,9 @@ void ProcessTypes (AssemblyDefinition assembly, XPathNodeIterator iterator) while (iterator.MoveNext ()) { XPathNavigator nav = iterator.Current; + if (!ShouldProcessElement (nav)) + continue; + string fullname = GetFullName (nav); if (IsTypePattern (fullname)) { @@ -230,6 +248,8 @@ void ProcessTypePattern (string fullname, AssemblyDefinition assembly, XPathNavi protected virtual void ProcessType (TypeDefinition type, XPathNavigator nav) { + Debug.Assert (ShouldProcessElement (nav)); + #if !FEATURE_ILLINK if (IsExcluded (nav)) return; @@ -321,22 +341,25 @@ static TypePreserve GetTypePreserve (XPathNavigator nav) void ProcessFields (TypeDefinition type, XPathNodeIterator iterator) { - while (iterator.MoveNext ()) - ProcessField (type, iterator); + while (iterator.MoveNext ()) { + if (!ShouldProcessElement (iterator.Current)) + continue; + ProcessField (type, iterator.Current); + } } - protected virtual void ProcessField (TypeDefinition type, XPathNodeIterator iterator) + protected virtual void ProcessField (TypeDefinition type, XPathNavigator nav) { #if !FEATURE_ILLINK - if (IsExcluded (iterator.Current)) + if (IsExcluded (nav)) return; #endif - string value = GetSignature (iterator.Current); + string value = GetSignature (nav); if (!String.IsNullOrEmpty (value)) ProcessFieldSignature (type, value); - value = GetAttribute (iterator.Current, "name"); + value = GetAttribute (nav, "name"); if (!String.IsNullOrEmpty (value)) ProcessFieldName (type, value); } @@ -389,22 +412,25 @@ static string GetFieldSignature (FieldDefinition field) void ProcessMethods (TypeDefinition type, XPathNodeIterator iterator, bool required) { - while (iterator.MoveNext ()) - ProcessMethod (type, iterator, required); + while (iterator.MoveNext ()) { + if (!ShouldProcessElement (iterator.Current)) + continue; + ProcessMethod (type, iterator.Current, required); + } } - protected virtual void ProcessMethod (TypeDefinition type, XPathNodeIterator iterator, bool required) + protected virtual void ProcessMethod (TypeDefinition type, XPathNavigator nav, bool required) { #if !FEATURE_ILLINK - if (IsExcluded (iterator.Current)) + if (IsExcluded (nav)) return; #endif - string value = GetSignature (iterator.Current); + string value = GetSignature (nav); if (!String.IsNullOrEmpty (value)) ProcessMethodSignature (type, value, required); - value = GetAttribute (iterator.Current, "name"); + value = GetAttribute (nav, "name"); if (!String.IsNullOrEmpty (value)) ProcessMethodName (type, value, required); } @@ -487,22 +513,25 @@ public static string GetMethodSignature (MethodDefinition meth, bool includeGene void ProcessEvents (TypeDefinition type, XPathNodeIterator iterator, bool required) { - while (iterator.MoveNext ()) - ProcessEvent (type, iterator, required); + while (iterator.MoveNext ()) { + if (!ShouldProcessElement (iterator.Current)) + continue; + ProcessEvent (type, iterator.Current, required); + } } - protected virtual void ProcessEvent (TypeDefinition type, XPathNodeIterator iterator, bool required) + protected virtual void ProcessEvent (TypeDefinition type, XPathNavigator nav, bool required) { #if !FEATURE_ILLINK - if (IsExcluded (iterator.Current)) + if (IsExcluded (nav)) return; #endif - string value = GetSignature (iterator.Current); + string value = GetSignature (nav); if (!String.IsNullOrEmpty (value)) ProcessEventSignature (type, value, required); - value = GetAttribute (iterator.Current, "name"); + value = GetAttribute (nav, "name"); if (!String.IsNullOrEmpty (value)) ProcessEventName (type, value, required); } @@ -559,22 +588,25 @@ static string GetEventSignature (EventDefinition @event) void ProcessProperties (TypeDefinition type, XPathNodeIterator iterator, bool required) { - while (iterator.MoveNext ()) - ProcessProperty (type, iterator, required); + while (iterator.MoveNext ()) { + if (!ShouldProcessElement (iterator.Current)) + continue; + ProcessProperty (type, iterator.Current, required); + } } - protected virtual void ProcessProperty (TypeDefinition type, XPathNodeIterator iterator, bool required) + protected virtual void ProcessProperty (TypeDefinition type, XPathNavigator nav, bool required) { #if !FEATURE_ILLINK - if (IsExcluded (iterator.Current)) + if (IsExcluded (nav)) return; #endif - string value = GetSignature (iterator.Current); + string value = GetSignature (nav); if (!String.IsNullOrEmpty (value)) - ProcessPropertySignature (type, value, GetAccessors (iterator.Current), required); + ProcessPropertySignature (type, value, GetAccessors (nav), required); - value = GetAttribute (iterator.Current, "name"); + value = GetAttribute (nav, "name"); if (!String.IsNullOrEmpty (value)) ProcessPropertyName (type, value, _accessorsAll, required); } @@ -720,5 +752,28 @@ public override string ToString () { return "ResolveFromXmlStep: " + _xmlDocumentLocation; } + + public static bool ShouldProcessElement (XPathNavigator nav, LinkContext context, string documentLocation) + { + var feature = GetAttribute (nav, "feature"); + if (string.IsNullOrEmpty (feature)) + return true; + + var value = GetAttribute (nav, "featurevalue"); + if (string.IsNullOrEmpty (value)) { + context.LogError ($"Failed to process '{documentLocation}'. Feature {feature} does not specify a 'featurevalue' attribute", 1001); + return false; + } + + if (!bool.TryParse (value, out bool bValue)) { + context.LogError ($"Failed to process '{documentLocation}'. Unsupported non-boolean feature definition {feature}", 1002); + return false; + } + + if (context.FeatureSettings == null || !context.FeatureSettings.TryGetValue (feature, out bool featureSetting)) + return false; + + return bValue == featureSetting; + } } } diff --git a/test/Mono.Linker.Tests.Cases/Substitutions/Dependencies/ResourceFile.txt b/test/Mono.Linker.Tests.Cases/FeatureSettings/Dependencies/ResourceFile.txt similarity index 100% rename from test/Mono.Linker.Tests.Cases/Substitutions/Dependencies/ResourceFile.txt rename to test/Mono.Linker.Tests.Cases/FeatureSettings/Dependencies/ResourceFile.txt diff --git a/test/Mono.Linker.Tests.Cases/FeatureSettings/FeatureDescriptors.cs b/test/Mono.Linker.Tests.Cases/FeatureSettings/FeatureDescriptors.cs new file mode 100644 index 000000000000..c49430e354d8 --- /dev/null +++ b/test/Mono.Linker.Tests.Cases/FeatureSettings/FeatureDescriptors.cs @@ -0,0 +1,61 @@ +using System; +using Mono.Linker.Tests.Cases.Expectations.Assertions; +using Mono.Linker.Tests.Cases.Expectations.Metadata; + +namespace Mono.Linker.Tests.Cases.FeatureSettings +{ + [SetupLinkerDescriptorFile ("FeatureDescriptorsGlobalTrue.xml")] + [SetupLinkerDescriptorFile ("FeatureDescriptorsGlobalFalse.xml")] + [SetupLinkerDescriptorFile ("FeatureDescriptors.xml")] + [SetupLinkerArgument ("--feature", "GlobalCondition", "true")] + [SetupLinkerArgument ("--feature", "AssemblyCondition", "false")] + [SetupLinkerArgument ("--feature", "TypeCondition", "true")] + [SetupLinkerArgument ("--feature", "MethodCondition", "false")] + [SetupLinkerArgument ("--feature", "FieldCondition", "true")] + [SetupLinkerArgument ("--feature", "PropertyCondition", "false")] + [SetupLinkerArgument ("--feature", "EventCondition", "true")] + public class FeatureDescriptors + { + public static void Main () + { + } + + [Kept] + static bool GlobalConditionTrue; + static bool GlobalConditionFalse; + + static bool AssemblyConditionTrue; + [Kept] + static bool AssemblyConditionFalse; + + [Kept] + static bool TypeConditionTrue; + static bool TypeConditionFalse; + + + static void MethodConditionTrue () + { + } + + [Kept] + static void MethodConditionFalse () + { + } + + [Kept] + static bool FieldConditionTrue; + static bool FieldConditionFalse; + + static bool PropertyConditionTrue { get; set; } + [Kept] + [KeptBackingField] + static bool PropertyConditionFalse { [Kept] get; [Kept] set; } + + [Kept] + [KeptBackingField] + [KeptEventAddMethod] + [KeptEventRemoveMethod] + static event EventHandler EventConditionTrue; + static event EventHandler EVentConditionFalse; + } +} \ No newline at end of file diff --git a/test/Mono.Linker.Tests.Cases/FeatureSettings/FeatureDescriptors.xml b/test/Mono.Linker.Tests.Cases/FeatureSettings/FeatureDescriptors.xml new file mode 100644 index 000000000000..13d3e259ad3e --- /dev/null +++ b/test/Mono.Linker.Tests.Cases/FeatureSettings/FeatureDescriptors.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/Mono.Linker.Tests.Cases/FeatureSettings/FeatureDescriptorsGlobalFalse.xml b/test/Mono.Linker.Tests.Cases/FeatureSettings/FeatureDescriptorsGlobalFalse.xml new file mode 100644 index 000000000000..20a0d37e1370 --- /dev/null +++ b/test/Mono.Linker.Tests.Cases/FeatureSettings/FeatureDescriptorsGlobalFalse.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/test/Mono.Linker.Tests.Cases/FeatureSettings/FeatureDescriptorsGlobalTrue.xml b/test/Mono.Linker.Tests.Cases/FeatureSettings/FeatureDescriptorsGlobalTrue.xml new file mode 100644 index 000000000000..495d8d823e8c --- /dev/null +++ b/test/Mono.Linker.Tests.Cases/FeatureSettings/FeatureDescriptorsGlobalTrue.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/test/Mono.Linker.Tests.Cases/Substitutions/FeatureSubstitutions.cs b/test/Mono.Linker.Tests.Cases/FeatureSettings/FeatureSubstitutions.cs similarity index 94% rename from test/Mono.Linker.Tests.Cases/Substitutions/FeatureSubstitutions.cs rename to test/Mono.Linker.Tests.Cases/FeatureSettings/FeatureSubstitutions.cs index a4ec6bf0e798..be2a4a9610e5 100644 --- a/test/Mono.Linker.Tests.Cases/Substitutions/FeatureSubstitutions.cs +++ b/test/Mono.Linker.Tests.Cases/FeatureSettings/FeatureSubstitutions.cs @@ -1,7 +1,7 @@ using Mono.Linker.Tests.Cases.Expectations.Assertions; using Mono.Linker.Tests.Cases.Expectations.Metadata; -namespace Mono.Linker.Tests.Cases.Substitutions +namespace Mono.Linker.Tests.Cases.FeatureSettings { [SetupLinkerSubstitutionFile ("FeatureSubstitutions.xml")] [SetupLinkerArgument ("--feature", "OptionalFeature", "false")] diff --git a/test/Mono.Linker.Tests.Cases/Substitutions/FeatureSubstitutions.xml b/test/Mono.Linker.Tests.Cases/FeatureSettings/FeatureSubstitutions.xml similarity index 77% rename from test/Mono.Linker.Tests.Cases/Substitutions/FeatureSubstitutions.xml rename to test/Mono.Linker.Tests.Cases/FeatureSettings/FeatureSubstitutions.xml index 44d332d758ef..2aa12b74350a 100644 --- a/test/Mono.Linker.Tests.Cases/Substitutions/FeatureSubstitutions.xml +++ b/test/Mono.Linker.Tests.Cases/FeatureSettings/FeatureSubstitutions.xml @@ -1,6 +1,6 @@ - + diff --git a/test/Mono.Linker.Tests.Cases/Substitutions/FeatureSubstitutionsGlobalFalse.xml b/test/Mono.Linker.Tests.Cases/FeatureSettings/FeatureSubstitutionsGlobalFalse.xml similarity index 80% rename from test/Mono.Linker.Tests.Cases/Substitutions/FeatureSubstitutionsGlobalFalse.xml rename to test/Mono.Linker.Tests.Cases/FeatureSettings/FeatureSubstitutionsGlobalFalse.xml index a9452db383e1..71b53b7fe915 100644 --- a/test/Mono.Linker.Tests.Cases/Substitutions/FeatureSubstitutionsGlobalFalse.xml +++ b/test/Mono.Linker.Tests.Cases/FeatureSettings/FeatureSubstitutionsGlobalFalse.xml @@ -1,7 +1,7 @@ - + diff --git a/test/Mono.Linker.Tests.Cases/Substitutions/FeatureSubstitutionsGlobalTrue.xml b/test/Mono.Linker.Tests.Cases/FeatureSettings/FeatureSubstitutionsGlobalTrue.xml similarity index 80% rename from test/Mono.Linker.Tests.Cases/Substitutions/FeatureSubstitutionsGlobalTrue.xml rename to test/Mono.Linker.Tests.Cases/FeatureSettings/FeatureSubstitutionsGlobalTrue.xml index 3b8d006f921d..9e9f85eb0502 100644 --- a/test/Mono.Linker.Tests.Cases/Substitutions/FeatureSubstitutionsGlobalTrue.xml +++ b/test/Mono.Linker.Tests.Cases/FeatureSettings/FeatureSubstitutionsGlobalTrue.xml @@ -1,7 +1,7 @@ - + diff --git a/test/Mono.Linker.Tests.Cases/Substitutions/FeatureSubstitutionsInvalid.cs b/test/Mono.Linker.Tests.Cases/FeatureSettings/FeatureSubstitutionsInvalid.cs similarity index 82% rename from test/Mono.Linker.Tests.Cases/Substitutions/FeatureSubstitutionsInvalid.cs rename to test/Mono.Linker.Tests.Cases/FeatureSettings/FeatureSubstitutionsInvalid.cs index d050fcf9ceb2..cdd1cc16e779 100644 --- a/test/Mono.Linker.Tests.Cases/Substitutions/FeatureSubstitutionsInvalid.cs +++ b/test/Mono.Linker.Tests.Cases/FeatureSettings/FeatureSubstitutionsInvalid.cs @@ -1,14 +1,14 @@ using Mono.Linker.Tests.Cases.Expectations.Assertions; using Mono.Linker.Tests.Cases.Expectations.Metadata; -namespace Mono.Linker.Tests.Cases.Substitutions +namespace Mono.Linker.Tests.Cases.FeatureSettings { [NoLinkedOutput] [SetupLinkerSubstitutionFile ("FeatureSubstitutionsInvalid.xml")] [SetupLinkerArgument ("--feature", "NoValueFeature", "true")] [LogContains ("Feature NoValueFeature does not specify a 'featurevalue' attribute")] - [LogContains ("warning IL2012: Could not find field 'NonExistentField' in type 'Mono.Linker.Tests.Cases.Substitutions.FeatureSubstitutionsInvalid/Foo'")] - [LogContains ("warning IL2009: Could not find method 'NonExistentMethod' in type 'Mono.Linker.Tests.Cases.Substitutions.FeatureSubstitutionsInvalid/Foo'")] + [LogContains ("warning IL2012: Could not find field 'NonExistentField' in type 'Mono.Linker.Tests.Cases.FeatureSettings.FeatureSubstitutionsInvalid/Foo'")] + [LogContains ("warning IL2009: Could not find method 'NonExistentMethod' in type 'Mono.Linker.Tests.Cases.FeatureSettings.FeatureSubstitutionsInvalid/Foo'")] public class FeatureSubstitutionsInvalid { public static void Main () diff --git a/test/Mono.Linker.Tests.Cases/Substitutions/FeatureSubstitutionsInvalid.xml b/test/Mono.Linker.Tests.Cases/FeatureSettings/FeatureSubstitutionsInvalid.xml similarity index 77% rename from test/Mono.Linker.Tests.Cases/Substitutions/FeatureSubstitutionsInvalid.xml rename to test/Mono.Linker.Tests.Cases/FeatureSettings/FeatureSubstitutionsInvalid.xml index 80fd71a9962a..47d33f980a77 100644 --- a/test/Mono.Linker.Tests.Cases/Substitutions/FeatureSubstitutionsInvalid.xml +++ b/test/Mono.Linker.Tests.Cases/FeatureSettings/FeatureSubstitutionsInvalid.xml @@ -1,11 +1,11 @@ - + - + diff --git a/test/Mono.Linker.Tests.Cases/Substitutions/FeatureSubstitutionsNested.cs b/test/Mono.Linker.Tests.Cases/FeatureSettings/FeatureSubstitutionsNested.cs similarity index 97% rename from test/Mono.Linker.Tests.Cases/Substitutions/FeatureSubstitutionsNested.cs rename to test/Mono.Linker.Tests.Cases/FeatureSettings/FeatureSubstitutionsNested.cs index df69d85c9924..6e7a5592010d 100644 --- a/test/Mono.Linker.Tests.Cases/Substitutions/FeatureSubstitutionsNested.cs +++ b/test/Mono.Linker.Tests.Cases/FeatureSettings/FeatureSubstitutionsNested.cs @@ -2,7 +2,7 @@ using Mono.Linker.Tests.Cases.Expectations.Assertions; using Mono.Linker.Tests.Cases.Expectations.Metadata; -namespace Mono.Linker.Tests.Cases.Substitutions +namespace Mono.Linker.Tests.Cases.FeatureSettings { [SetupCompileResource ("Dependencies/ResourceFile.txt", "ResourceFileRemoveWhenTrue.txt")] [SetupCompileResource ("Dependencies/ResourceFile.txt", "ResourceFileRemoveWhenFalse.txt")] diff --git a/test/Mono.Linker.Tests.Cases/Substitutions/FeatureSubstitutionsNested.xml b/test/Mono.Linker.Tests.Cases/FeatureSettings/FeatureSubstitutionsNested.xml similarity index 81% rename from test/Mono.Linker.Tests.Cases/Substitutions/FeatureSubstitutionsNested.xml rename to test/Mono.Linker.Tests.Cases/FeatureSettings/FeatureSubstitutionsNested.xml index eaf2cb2cd471..224214377266 100644 --- a/test/Mono.Linker.Tests.Cases/Substitutions/FeatureSubstitutionsNested.xml +++ b/test/Mono.Linker.Tests.Cases/FeatureSettings/FeatureSubstitutionsNested.xml @@ -1,11 +1,11 @@ - + - + @@ -17,7 +17,7 @@ - + @@ -27,7 +27,7 @@ - + diff --git a/test/Mono.Linker.Tests/TestCases/TestDatabase.cs b/test/Mono.Linker.Tests/TestCases/TestDatabase.cs index f46086e43d0c..4528ce393781 100644 --- a/test/Mono.Linker.Tests/TestCases/TestDatabase.cs +++ b/test/Mono.Linker.Tests/TestCases/TestDatabase.cs @@ -193,6 +193,11 @@ public static IEnumerable ExtensibilityTests () return NUnitCasesBySuiteName ("Extensibility"); } + public static IEnumerable FeatureSettingsTests () + { + return NUnitCasesBySuiteName ("FeatureSettings"); + } + public static TestCaseCollector CreateCollector () { GetDirectoryPaths (out string rootSourceDirectory, out string testCaseAssemblyPath); diff --git a/test/Mono.Linker.Tests/TestCases/TestSuites.cs b/test/Mono.Linker.Tests/TestCases/TestSuites.cs index 739084f0bd09..55f295dcc0c2 100644 --- a/test/Mono.Linker.Tests/TestCases/TestSuites.cs +++ b/test/Mono.Linker.Tests/TestCases/TestSuites.cs @@ -218,6 +218,12 @@ public void ExtensibilityTests (TestCase testCase) Run (testCase); } + [TestCaseSource (typeof (TestDatabase), nameof (TestDatabase.FeatureSettingsTests))] + public void FeatureSettingsTests (TestCase testCase) + { + Run (testCase); + } + [TestCaseSource (typeof (TestDatabase), nameof (TestDatabase.DataFlowTests))] public void DataFlowTests (TestCase testCase) {