Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/linker.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/ILLink.RoslynAnalyzer/AnalyzerOptionsExtensions.cs31
-rw-r--r--src/ILLink.RoslynAnalyzer/DiagnosticCategory.cs12
-rw-r--r--src/ILLink.RoslynAnalyzer/MSBuildPropertyOptionNames.cs13
-rw-r--r--src/ILLink.RoslynAnalyzer/RequiresUnreferencedCodeAnalyzer.cs27
-rw-r--r--src/ILLink.RoslynAnalyzer/Resources.resx12
-rw-r--r--src/ILLink.RoslynAnalyzer/SingleFileAnalyzer.cs141
-rw-r--r--src/ILLink.RoslynAnalyzer/xlf/Resources.cs.xlf20
-rw-r--r--src/ILLink.RoslynAnalyzer/xlf/Resources.de.xlf20
-rw-r--r--src/ILLink.RoslynAnalyzer/xlf/Resources.es.xlf20
-rw-r--r--src/ILLink.RoslynAnalyzer/xlf/Resources.fr.xlf20
-rw-r--r--src/ILLink.RoslynAnalyzer/xlf/Resources.it.xlf20
-rw-r--r--src/ILLink.RoslynAnalyzer/xlf/Resources.ja.xlf20
-rw-r--r--src/ILLink.RoslynAnalyzer/xlf/Resources.ko.xlf20
-rw-r--r--src/ILLink.RoslynAnalyzer/xlf/Resources.pl.xlf20
-rw-r--r--src/ILLink.RoslynAnalyzer/xlf/Resources.pt-BR.xlf20
-rw-r--r--src/ILLink.RoslynAnalyzer/xlf/Resources.ru.xlf20
-rw-r--r--src/ILLink.RoslynAnalyzer/xlf/Resources.tr.xlf20
-rw-r--r--src/ILLink.RoslynAnalyzer/xlf/Resources.zh-Hans.xlf20
-rw-r--r--src/ILLink.RoslynAnalyzer/xlf/Resources.zh-Hant.xlf20
-rw-r--r--test/ILLink.RoslynAnalyzer.Tests/AvoidAssemblyLocationInSingleFileTests.cs144
-rw-r--r--test/ILLink.RoslynAnalyzer.Tests/LinkerTestCases.cs4
-rw-r--r--test/ILLink.RoslynAnalyzer.Tests/RequiresUnreferencedCodeAnalyzerTests.cs (renamed from test/ILLink.RoslynAnalyzer.Tests/AnalyzerTests.cs)21
-rw-r--r--test/ILLink.RoslynAnalyzer.Tests/TestCaseUtils.cs9
-rw-r--r--test/ILLink.RoslynAnalyzer.Tests/Verifiers/CSharpAnalyzerVerifier`1.cs4
24 files changed, 650 insertions, 28 deletions
diff --git a/src/ILLink.RoslynAnalyzer/AnalyzerOptionsExtensions.cs b/src/ILLink.RoslynAnalyzer/AnalyzerOptionsExtensions.cs
new file mode 100644
index 000000000..f5781802f
--- /dev/null
+++ b/src/ILLink.RoslynAnalyzer/AnalyzerOptionsExtensions.cs
@@ -0,0 +1,31 @@
+// 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.Linq;
+using Microsoft.CodeAnalysis;
+using Microsoft.CodeAnalysis.Diagnostics;
+
+namespace ILLink.RoslynAnalyzer
+{
+ internal static class AnalyzerOptionsExtensions
+ {
+ public static string? GetMSBuildPropertyValue (
+ this AnalyzerOptions options,
+ string optionName,
+ Compilation compilation)
+ {
+ // MSBuild property values should be set at compilation level, and cannot have different values per-tree.
+ // So, we default to first syntax tree.
+ var tree = compilation.SyntaxTrees.FirstOrDefault ();
+ if (tree is null) {
+ return null;
+ }
+
+ return options.AnalyzerConfigOptionsProvider.GlobalOptions.TryGetValue (
+ $"build_property.{optionName}", out var value)
+ ? value
+ : null;
+ }
+ }
+}
diff --git a/src/ILLink.RoslynAnalyzer/DiagnosticCategory.cs b/src/ILLink.RoslynAnalyzer/DiagnosticCategory.cs
new file mode 100644
index 000000000..28cf0f031
--- /dev/null
+++ b/src/ILLink.RoslynAnalyzer/DiagnosticCategory.cs
@@ -0,0 +1,12 @@
+// 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.
+
+namespace ILLink.RoslynAnalyzer
+{
+ internal static class DiagnosticCategory
+ {
+ public const string SingleFile = nameof (SingleFile);
+ public const string Trimming = nameof (Trimming);
+ }
+}
diff --git a/src/ILLink.RoslynAnalyzer/MSBuildPropertyOptionNames.cs b/src/ILLink.RoslynAnalyzer/MSBuildPropertyOptionNames.cs
new file mode 100644
index 000000000..1f0b40459
--- /dev/null
+++ b/src/ILLink.RoslynAnalyzer/MSBuildPropertyOptionNames.cs
@@ -0,0 +1,13 @@
+// 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.
+
+namespace ILLink.RoslynAnalyzer
+{
+ public static class MSBuildPropertyOptionNames
+ {
+ public const string PublishSingleFile = nameof (PublishSingleFile);
+ public const string IncludeAllContentForSelfExtract = nameof (IncludeAllContentForSelfExtract);
+ public const string PublishTrimmed = nameof (PublishTrimmed);
+ }
+}
diff --git a/src/ILLink.RoslynAnalyzer/RequiresUnreferencedCodeAnalyzer.cs b/src/ILLink.RoslynAnalyzer/RequiresUnreferencedCodeAnalyzer.cs
index 1dd287114..8b9c1cd7b 100644
--- a/src/ILLink.RoslynAnalyzer/RequiresUnreferencedCodeAnalyzer.cs
+++ b/src/ILLink.RoslynAnalyzer/RequiresUnreferencedCodeAnalyzer.cs
@@ -4,7 +4,6 @@
using System;
using System.Collections.Immutable;
-using System.Diagnostics;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Diagnostics;
using Microsoft.CodeAnalysis.Operations;
@@ -16,21 +15,13 @@ namespace ILLink.RoslynAnalyzer
{
public const string DiagnosticId = "IL2026";
- private static readonly LocalizableString s_title = new LocalizableResourceString (
- nameof (RequiresUnreferencedCodeAnalyzer) + "Title",
- Resources.ResourceManager,
- typeof (Resources));
- private static readonly LocalizableString s_messageFormat = new LocalizableResourceString (
- nameof (RequiresUnreferencedCodeAnalyzer) + "Message",
- Resources.ResourceManager,
- typeof (Resources));
- private const string s_category = "Trimming";
-
private static readonly DiagnosticDescriptor s_rule = new DiagnosticDescriptor (
DiagnosticId,
- s_title,
- s_messageFormat,
- s_category,
+ new LocalizableResourceString (nameof (Resources.RequiresUnreferencedCodeAnalyzerTitle),
+ Resources.ResourceManager, typeof (Resources)),
+ new LocalizableResourceString (nameof (Resources.RequiresUnreferencedCodeAnalyzerMessage),
+ Resources.ResourceManager, typeof (Resources)),
+ DiagnosticCategory.Trimming,
DiagnosticSeverity.Warning,
isEnabledByDefault: true);
@@ -44,8 +35,16 @@ namespace ILLink.RoslynAnalyzer
context.RegisterCompilationStartAction (context => {
var compilation = context.Compilation;
+ var isPublishTrimmed = context.Options.GetMSBuildPropertyValue (MSBuildPropertyOptionNames.PublishTrimmed, compilation);
+ if (!string.Equals (isPublishTrimmed?.Trim (), "true", StringComparison.OrdinalIgnoreCase)) {
+ return;
+ }
+
context.RegisterOperationAction (operationContext => {
var call = (IInvocationOperation) operationContext.Operation;
+ if (call.IsVirtual && call.TargetMethod.OverriddenMethod != null)
+ return;
+
CheckMethodOrCtorCall (operationContext, call.TargetMethod, call.Syntax.GetLocation ());
}, OperationKind.Invocation);
diff --git a/src/ILLink.RoslynAnalyzer/Resources.resx b/src/ILLink.RoslynAnalyzer/Resources.resx
index 0c0780e4d..202514e6d 100644
--- a/src/ILLink.RoslynAnalyzer/Resources.resx
+++ b/src/ILLink.RoslynAnalyzer/Resources.resx
@@ -123,4 +123,16 @@
<data name="RequiresUnreferencedCodeAnalyzerMessage" xml:space="preserve">
<value>Calling '{0}' which has `RequiresUnreferencedCodeAttribute` can break functionality when trimming application code. {1}. {2}</value>
</data>
+ <data name="AvoidAssemblyLocationInSingleFileTitle" xml:space="preserve">
+ <value>Avoid accessing Assembly file path when publishing as a single file</value>
+ </data>
+ <data name="AvoidAssemblyLocationInSingleFileMessage" xml:space="preserve">
+ <value>'{0}' always returns an empty string for assemblies embedded in a single-file app. If the path to the app directory is needed, consider calling 'System.AppContext.BaseDirectory'.</value>
+ </data>
+ <data name="AvoidAssemblyGetFilesInSingleFileTitle" xml:space="preserve">
+ <value>Avoid accessing Assembly file path when publishing as a single file</value>
+ </data>
+ <data name="AvoidAssemblyGetFilesInSingleFileMessage" xml:space="preserve">
+ <value>'{0}' will throw for assemblies embedded in a single-file app</value>
+ </data>
</root> \ No newline at end of file
diff --git a/src/ILLink.RoslynAnalyzer/SingleFileAnalyzer.cs b/src/ILLink.RoslynAnalyzer/SingleFileAnalyzer.cs
new file mode 100644
index 000000000..536cd82f2
--- /dev/null
+++ b/src/ILLink.RoslynAnalyzer/SingleFileAnalyzer.cs
@@ -0,0 +1,141 @@
+// 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 System.Collections.Generic;
+using System.Collections.Immutable;
+using Microsoft.CodeAnalysis;
+using Microsoft.CodeAnalysis.Diagnostics;
+using Microsoft.CodeAnalysis.Operations;
+
+namespace ILLink.RoslynAnalyzer
+{
+ /// <summary>
+ /// IL3000, IL3001: Do not use Assembly file path in single-file publish
+ /// </summary>
+ [DiagnosticAnalyzer (LanguageNames.CSharp, LanguageNames.VisualBasic)]
+ public sealed class AvoidAssemblyLocationInSingleFile : DiagnosticAnalyzer
+ {
+ public const string IL3000 = nameof (IL3000);
+ public const string IL3001 = nameof (IL3001);
+
+ private static readonly DiagnosticDescriptor LocationRule = new DiagnosticDescriptor (
+ IL3000,
+ new LocalizableResourceString (nameof (Resources.AvoidAssemblyLocationInSingleFileTitle),
+ Resources.ResourceManager, typeof (Resources)),
+ new LocalizableResourceString (nameof (Resources.AvoidAssemblyLocationInSingleFileMessage),
+ Resources.ResourceManager, typeof (Resources)),
+ DiagnosticCategory.SingleFile,
+ DiagnosticSeverity.Warning,
+ isEnabledByDefault: true);
+
+ private static readonly DiagnosticDescriptor GetFilesRule = new DiagnosticDescriptor (
+ IL3001,
+ new LocalizableResourceString (nameof (Resources.AvoidAssemblyGetFilesInSingleFileTitle),
+ Resources.ResourceManager, typeof (Resources)),
+ new LocalizableResourceString (nameof (Resources.AvoidAssemblyGetFilesInSingleFileMessage),
+ Resources.ResourceManager, typeof (Resources)),
+ DiagnosticCategory.SingleFile,
+ DiagnosticSeverity.Warning,
+ isEnabledByDefault: true);
+
+ public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics => ImmutableArray.Create (LocationRule, GetFilesRule);
+
+ public override void Initialize (AnalysisContext context)
+ {
+ context.EnableConcurrentExecution ();
+ context.ConfigureGeneratedCodeAnalysis (GeneratedCodeAnalysisFlags.ReportDiagnostics);
+
+ context.RegisterCompilationStartAction (context => {
+ var compilation = context.Compilation;
+
+ var isSingleFilePublish = context.Options.GetMSBuildPropertyValue (MSBuildPropertyOptionNames.PublishSingleFile, compilation);
+ if (!string.Equals (isSingleFilePublish?.Trim (), "true", StringComparison.OrdinalIgnoreCase)) {
+ return;
+ }
+ var includesAllContent = context.Options.GetMSBuildPropertyValue (MSBuildPropertyOptionNames.IncludeAllContentForSelfExtract, compilation);
+ if (string.Equals (includesAllContent?.Trim (), "true", StringComparison.OrdinalIgnoreCase)) {
+ return;
+ }
+
+ var propertiesBuilder = ImmutableArray.CreateBuilder<IPropertySymbol> ();
+ var methodsBuilder = ImmutableArray.CreateBuilder<IMethodSymbol> ();
+
+ var assemblyType = compilation.GetTypeByMetadataName ("System.Reflection.Assembly");
+ if (assemblyType != null) {
+ // properties
+ AddIfNotNull (propertiesBuilder, TryGetSingleSymbol<IPropertySymbol> (assemblyType.GetMembers ("Location")));
+
+ // methods
+ methodsBuilder.AddRange (assemblyType.GetMembers ("GetFile").OfType<IMethodSymbol> ());
+ methodsBuilder.AddRange (assemblyType.GetMembers ("GetFiles").OfType<IMethodSymbol> ());
+ }
+
+ var assemblyNameType = compilation.GetTypeByMetadataName ("System.Reflection.AssemblyName");
+ if (assemblyNameType != null) {
+ AddIfNotNull (propertiesBuilder, TryGetSingleSymbol<IPropertySymbol> (assemblyNameType.GetMembers ("CodeBase")));
+ AddIfNotNull (propertiesBuilder, TryGetSingleSymbol<IPropertySymbol> (assemblyNameType.GetMembers ("EscapedCodeBase")));
+ }
+
+ var properties = propertiesBuilder.ToImmutable ();
+ var methods = methodsBuilder.ToImmutable ();
+
+ context.RegisterOperationAction (operationContext => {
+ var access = (IPropertyReferenceOperation) operationContext.Operation;
+ var property = access.Property;
+ if (!Contains (properties, property, SymbolEqualityComparer.Default)) {
+ return;
+ }
+
+ operationContext.ReportDiagnostic (Diagnostic.Create (LocationRule, access.Syntax.GetLocation (), property));
+ }, OperationKind.PropertyReference);
+
+ context.RegisterOperationAction (operationContext => {
+ var invocation = (IInvocationOperation) operationContext.Operation;
+ var targetMethod = invocation.TargetMethod;
+ if (!Contains (methods, targetMethod, SymbolEqualityComparer.Default)) {
+ return;
+ }
+
+ operationContext.ReportDiagnostic (Diagnostic.Create (GetFilesRule, invocation.Syntax.GetLocation (), targetMethod));
+ }, OperationKind.Invocation);
+
+ return;
+
+ static bool Contains<T, TComp> (ImmutableArray<T> list, T elem, TComp comparer)
+ where TComp : IEqualityComparer<T>
+ {
+ foreach (var e in list) {
+ if (comparer.Equals (e, elem)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ static TSymbol? TryGetSingleSymbol<TSymbol> (ImmutableArray<ISymbol> members) where TSymbol : class, ISymbol
+ {
+ TSymbol? candidate = null;
+ foreach (var m in members) {
+ if (m is TSymbol tsym) {
+ if (candidate is null) {
+ candidate = tsym;
+ } else {
+ return null;
+ }
+ }
+ }
+ return candidate;
+ }
+
+ static void AddIfNotNull<TSymbol> (ImmutableArray<TSymbol>.Builder properties, TSymbol? p) where TSymbol : class, ISymbol
+ {
+ if (p != null) {
+ properties.Add (p);
+ }
+ }
+ });
+ }
+ }
+}
diff --git a/src/ILLink.RoslynAnalyzer/xlf/Resources.cs.xlf b/src/ILLink.RoslynAnalyzer/xlf/Resources.cs.xlf
index 5c5e4af14..1c0aab648 100644
--- a/src/ILLink.RoslynAnalyzer/xlf/Resources.cs.xlf
+++ b/src/ILLink.RoslynAnalyzer/xlf/Resources.cs.xlf
@@ -2,6 +2,26 @@
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.2" xsi:schemaLocation="urn:oasis:names:tc:xliff:document:1.2 xliff-core-1.2-transitional.xsd">
<file datatype="xml" source-language="en" target-language="cs" original="../Resources.resx">
<body>
+ <trans-unit id="AvoidAssemblyGetFilesInSingleFileMessage">
+ <source>'{0}' will throw for assemblies embedded in a single-file app</source>
+ <target state="new">'{0}' will throw for assemblies embedded in a single-file app</target>
+ <note />
+ </trans-unit>
+ <trans-unit id="AvoidAssemblyGetFilesInSingleFileTitle">
+ <source>Avoid accessing Assembly file path when publishing as a single file</source>
+ <target state="new">Avoid accessing Assembly file path when publishing as a single file</target>
+ <note />
+ </trans-unit>
+ <trans-unit id="AvoidAssemblyLocationInSingleFileMessage">
+ <source>'{0}' always returns an empty string for assemblies embedded in a single-file app. If the path to the app directory is needed, consider calling 'System.AppContext.BaseDirectory'.</source>
+ <target state="new">'{0}' always returns an empty string for assemblies embedded in a single-file app. If the path to the app directory is needed, consider calling 'System.AppContext.BaseDirectory'.</target>
+ <note />
+ </trans-unit>
+ <trans-unit id="AvoidAssemblyLocationInSingleFileTitle">
+ <source>Avoid accessing Assembly file path when publishing as a single file</source>
+ <target state="new">Avoid accessing Assembly file path when publishing as a single file</target>
+ <note />
+ </trans-unit>
<trans-unit id="RequiresUnreferencedCodeAnalyzerMessage">
<source>Calling '{0}' which has `RequiresUnreferencedCodeAttribute` can break functionality when trimming application code. {1}. {2}</source>
<target state="new">Calling '{0}' which has `RequiresUnreferencedCodeAttribute` can break functionality when trimming application code. {1}. {2}</target>
diff --git a/src/ILLink.RoslynAnalyzer/xlf/Resources.de.xlf b/src/ILLink.RoslynAnalyzer/xlf/Resources.de.xlf
index a80b9d4fa..30f09f0f3 100644
--- a/src/ILLink.RoslynAnalyzer/xlf/Resources.de.xlf
+++ b/src/ILLink.RoslynAnalyzer/xlf/Resources.de.xlf
@@ -2,6 +2,26 @@
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.2" xsi:schemaLocation="urn:oasis:names:tc:xliff:document:1.2 xliff-core-1.2-transitional.xsd">
<file datatype="xml" source-language="en" target-language="de" original="../Resources.resx">
<body>
+ <trans-unit id="AvoidAssemblyGetFilesInSingleFileMessage">
+ <source>'{0}' will throw for assemblies embedded in a single-file app</source>
+ <target state="new">'{0}' will throw for assemblies embedded in a single-file app</target>
+ <note />
+ </trans-unit>
+ <trans-unit id="AvoidAssemblyGetFilesInSingleFileTitle">
+ <source>Avoid accessing Assembly file path when publishing as a single file</source>
+ <target state="new">Avoid accessing Assembly file path when publishing as a single file</target>
+ <note />
+ </trans-unit>
+ <trans-unit id="AvoidAssemblyLocationInSingleFileMessage">
+ <source>'{0}' always returns an empty string for assemblies embedded in a single-file app. If the path to the app directory is needed, consider calling 'System.AppContext.BaseDirectory'.</source>
+ <target state="new">'{0}' always returns an empty string for assemblies embedded in a single-file app. If the path to the app directory is needed, consider calling 'System.AppContext.BaseDirectory'.</target>
+ <note />
+ </trans-unit>
+ <trans-unit id="AvoidAssemblyLocationInSingleFileTitle">
+ <source>Avoid accessing Assembly file path when publishing as a single file</source>
+ <target state="new">Avoid accessing Assembly file path when publishing as a single file</target>
+ <note />
+ </trans-unit>
<trans-unit id="RequiresUnreferencedCodeAnalyzerMessage">
<source>Calling '{0}' which has `RequiresUnreferencedCodeAttribute` can break functionality when trimming application code. {1}. {2}</source>
<target state="new">Calling '{0}' which has `RequiresUnreferencedCodeAttribute` can break functionality when trimming application code. {1}. {2}</target>
diff --git a/src/ILLink.RoslynAnalyzer/xlf/Resources.es.xlf b/src/ILLink.RoslynAnalyzer/xlf/Resources.es.xlf
index 46cf19175..10648e7f4 100644
--- a/src/ILLink.RoslynAnalyzer/xlf/Resources.es.xlf
+++ b/src/ILLink.RoslynAnalyzer/xlf/Resources.es.xlf
@@ -2,6 +2,26 @@
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.2" xsi:schemaLocation="urn:oasis:names:tc:xliff:document:1.2 xliff-core-1.2-transitional.xsd">
<file datatype="xml" source-language="en" target-language="es" original="../Resources.resx">
<body>
+ <trans-unit id="AvoidAssemblyGetFilesInSingleFileMessage">
+ <source>'{0}' will throw for assemblies embedded in a single-file app</source>
+ <target state="new">'{0}' will throw for assemblies embedded in a single-file app</target>
+ <note />
+ </trans-unit>
+ <trans-unit id="AvoidAssemblyGetFilesInSingleFileTitle">
+ <source>Avoid accessing Assembly file path when publishing as a single file</source>
+ <target state="new">Avoid accessing Assembly file path when publishing as a single file</target>
+ <note />
+ </trans-unit>
+ <trans-unit id="AvoidAssemblyLocationInSingleFileMessage">
+ <source>'{0}' always returns an empty string for assemblies embedded in a single-file app. If the path to the app directory is needed, consider calling 'System.AppContext.BaseDirectory'.</source>
+ <target state="new">'{0}' always returns an empty string for assemblies embedded in a single-file app. If the path to the app directory is needed, consider calling 'System.AppContext.BaseDirectory'.</target>
+ <note />
+ </trans-unit>
+ <trans-unit id="AvoidAssemblyLocationInSingleFileTitle">
+ <source>Avoid accessing Assembly file path when publishing as a single file</source>
+ <target state="new">Avoid accessing Assembly file path when publishing as a single file</target>
+ <note />
+ </trans-unit>
<trans-unit id="RequiresUnreferencedCodeAnalyzerMessage">
<source>Calling '{0}' which has `RequiresUnreferencedCodeAttribute` can break functionality when trimming application code. {1}. {2}</source>
<target state="new">Calling '{0}' which has `RequiresUnreferencedCodeAttribute` can break functionality when trimming application code. {1}. {2}</target>
diff --git a/src/ILLink.RoslynAnalyzer/xlf/Resources.fr.xlf b/src/ILLink.RoslynAnalyzer/xlf/Resources.fr.xlf
index c147c8c1d..1d4195817 100644
--- a/src/ILLink.RoslynAnalyzer/xlf/Resources.fr.xlf
+++ b/src/ILLink.RoslynAnalyzer/xlf/Resources.fr.xlf
@@ -2,6 +2,26 @@
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.2" xsi:schemaLocation="urn:oasis:names:tc:xliff:document:1.2 xliff-core-1.2-transitional.xsd">
<file datatype="xml" source-language="en" target-language="fr" original="../Resources.resx">
<body>
+ <trans-unit id="AvoidAssemblyGetFilesInSingleFileMessage">
+ <source>'{0}' will throw for assemblies embedded in a single-file app</source>
+ <target state="new">'{0}' will throw for assemblies embedded in a single-file app</target>
+ <note />
+ </trans-unit>
+ <trans-unit id="AvoidAssemblyGetFilesInSingleFileTitle">
+ <source>Avoid accessing Assembly file path when publishing as a single file</source>
+ <target state="new">Avoid accessing Assembly file path when publishing as a single file</target>
+ <note />
+ </trans-unit>
+ <trans-unit id="AvoidAssemblyLocationInSingleFileMessage">
+ <source>'{0}' always returns an empty string for assemblies embedded in a single-file app. If the path to the app directory is needed, consider calling 'System.AppContext.BaseDirectory'.</source>
+ <target state="new">'{0}' always returns an empty string for assemblies embedded in a single-file app. If the path to the app directory is needed, consider calling 'System.AppContext.BaseDirectory'.</target>
+ <note />
+ </trans-unit>
+ <trans-unit id="AvoidAssemblyLocationInSingleFileTitle">
+ <source>Avoid accessing Assembly file path when publishing as a single file</source>
+ <target state="new">Avoid accessing Assembly file path when publishing as a single file</target>
+ <note />
+ </trans-unit>
<trans-unit id="RequiresUnreferencedCodeAnalyzerMessage">
<source>Calling '{0}' which has `RequiresUnreferencedCodeAttribute` can break functionality when trimming application code. {1}. {2}</source>
<target state="new">Calling '{0}' which has `RequiresUnreferencedCodeAttribute` can break functionality when trimming application code. {1}. {2}</target>
diff --git a/src/ILLink.RoslynAnalyzer/xlf/Resources.it.xlf b/src/ILLink.RoslynAnalyzer/xlf/Resources.it.xlf
index 6c3fbcd90..5090e344e 100644
--- a/src/ILLink.RoslynAnalyzer/xlf/Resources.it.xlf
+++ b/src/ILLink.RoslynAnalyzer/xlf/Resources.it.xlf
@@ -2,6 +2,26 @@
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.2" xsi:schemaLocation="urn:oasis:names:tc:xliff:document:1.2 xliff-core-1.2-transitional.xsd">
<file datatype="xml" source-language="en" target-language="it" original="../Resources.resx">
<body>
+ <trans-unit id="AvoidAssemblyGetFilesInSingleFileMessage">
+ <source>'{0}' will throw for assemblies embedded in a single-file app</source>
+ <target state="new">'{0}' will throw for assemblies embedded in a single-file app</target>
+ <note />
+ </trans-unit>
+ <trans-unit id="AvoidAssemblyGetFilesInSingleFileTitle">
+ <source>Avoid accessing Assembly file path when publishing as a single file</source>
+ <target state="new">Avoid accessing Assembly file path when publishing as a single file</target>
+ <note />
+ </trans-unit>
+ <trans-unit id="AvoidAssemblyLocationInSingleFileMessage">
+ <source>'{0}' always returns an empty string for assemblies embedded in a single-file app. If the path to the app directory is needed, consider calling 'System.AppContext.BaseDirectory'.</source>
+ <target state="new">'{0}' always returns an empty string for assemblies embedded in a single-file app. If the path to the app directory is needed, consider calling 'System.AppContext.BaseDirectory'.</target>
+ <note />
+ </trans-unit>
+ <trans-unit id="AvoidAssemblyLocationInSingleFileTitle">
+ <source>Avoid accessing Assembly file path when publishing as a single file</source>
+ <target state="new">Avoid accessing Assembly file path when publishing as a single file</target>
+ <note />
+ </trans-unit>
<trans-unit id="RequiresUnreferencedCodeAnalyzerMessage">
<source>Calling '{0}' which has `RequiresUnreferencedCodeAttribute` can break functionality when trimming application code. {1}. {2}</source>
<target state="new">Calling '{0}' which has `RequiresUnreferencedCodeAttribute` can break functionality when trimming application code. {1}. {2}</target>
diff --git a/src/ILLink.RoslynAnalyzer/xlf/Resources.ja.xlf b/src/ILLink.RoslynAnalyzer/xlf/Resources.ja.xlf
index 38814260c..8c07ebe5d 100644
--- a/src/ILLink.RoslynAnalyzer/xlf/Resources.ja.xlf
+++ b/src/ILLink.RoslynAnalyzer/xlf/Resources.ja.xlf
@@ -2,6 +2,26 @@
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.2" xsi:schemaLocation="urn:oasis:names:tc:xliff:document:1.2 xliff-core-1.2-transitional.xsd">
<file datatype="xml" source-language="en" target-language="ja" original="../Resources.resx">
<body>
+ <trans-unit id="AvoidAssemblyGetFilesInSingleFileMessage">
+ <source>'{0}' will throw for assemblies embedded in a single-file app</source>
+ <target state="new">'{0}' will throw for assemblies embedded in a single-file app</target>
+ <note />
+ </trans-unit>
+ <trans-unit id="AvoidAssemblyGetFilesInSingleFileTitle">
+ <source>Avoid accessing Assembly file path when publishing as a single file</source>
+ <target state="new">Avoid accessing Assembly file path when publishing as a single file</target>
+ <note />
+ </trans-unit>
+ <trans-unit id="AvoidAssemblyLocationInSingleFileMessage">
+ <source>'{0}' always returns an empty string for assemblies embedded in a single-file app. If the path to the app directory is needed, consider calling 'System.AppContext.BaseDirectory'.</source>
+ <target state="new">'{0}' always returns an empty string for assemblies embedded in a single-file app. If the path to the app directory is needed, consider calling 'System.AppContext.BaseDirectory'.</target>
+ <note />
+ </trans-unit>
+ <trans-unit id="AvoidAssemblyLocationInSingleFileTitle">
+ <source>Avoid accessing Assembly file path when publishing as a single file</source>
+ <target state="new">Avoid accessing Assembly file path when publishing as a single file</target>
+ <note />
+ </trans-unit>
<trans-unit id="RequiresUnreferencedCodeAnalyzerMessage">
<source>Calling '{0}' which has `RequiresUnreferencedCodeAttribute` can break functionality when trimming application code. {1}. {2}</source>
<target state="new">Calling '{0}' which has `RequiresUnreferencedCodeAttribute` can break functionality when trimming application code. {1}. {2}</target>
diff --git a/src/ILLink.RoslynAnalyzer/xlf/Resources.ko.xlf b/src/ILLink.RoslynAnalyzer/xlf/Resources.ko.xlf
index db861065b..363b9c427 100644
--- a/src/ILLink.RoslynAnalyzer/xlf/Resources.ko.xlf
+++ b/src/ILLink.RoslynAnalyzer/xlf/Resources.ko.xlf
@@ -2,6 +2,26 @@
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.2" xsi:schemaLocation="urn:oasis:names:tc:xliff:document:1.2 xliff-core-1.2-transitional.xsd">
<file datatype="xml" source-language="en" target-language="ko" original="../Resources.resx">
<body>
+ <trans-unit id="AvoidAssemblyGetFilesInSingleFileMessage">
+ <source>'{0}' will throw for assemblies embedded in a single-file app</source>
+ <target state="new">'{0}' will throw for assemblies embedded in a single-file app</target>
+ <note />
+ </trans-unit>
+ <trans-unit id="AvoidAssemblyGetFilesInSingleFileTitle">
+ <source>Avoid accessing Assembly file path when publishing as a single file</source>
+ <target state="new">Avoid accessing Assembly file path when publishing as a single file</target>
+ <note />
+ </trans-unit>
+ <trans-unit id="AvoidAssemblyLocationInSingleFileMessage">
+ <source>'{0}' always returns an empty string for assemblies embedded in a single-file app. If the path to the app directory is needed, consider calling 'System.AppContext.BaseDirectory'.</source>
+ <target state="new">'{0}' always returns an empty string for assemblies embedded in a single-file app. If the path to the app directory is needed, consider calling 'System.AppContext.BaseDirectory'.</target>
+ <note />
+ </trans-unit>
+ <trans-unit id="AvoidAssemblyLocationInSingleFileTitle">
+ <source>Avoid accessing Assembly file path when publishing as a single file</source>
+ <target state="new">Avoid accessing Assembly file path when publishing as a single file</target>
+ <note />
+ </trans-unit>
<trans-unit id="RequiresUnreferencedCodeAnalyzerMessage">
<source>Calling '{0}' which has `RequiresUnreferencedCodeAttribute` can break functionality when trimming application code. {1}. {2}</source>
<target state="new">Calling '{0}' which has `RequiresUnreferencedCodeAttribute` can break functionality when trimming application code. {1}. {2}</target>
diff --git a/src/ILLink.RoslynAnalyzer/xlf/Resources.pl.xlf b/src/ILLink.RoslynAnalyzer/xlf/Resources.pl.xlf
index 7ba7c0e27..927764ec5 100644
--- a/src/ILLink.RoslynAnalyzer/xlf/Resources.pl.xlf
+++ b/src/ILLink.RoslynAnalyzer/xlf/Resources.pl.xlf
@@ -2,6 +2,26 @@
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.2" xsi:schemaLocation="urn:oasis:names:tc:xliff:document:1.2 xliff-core-1.2-transitional.xsd">
<file datatype="xml" source-language="en" target-language="pl" original="../Resources.resx">
<body>
+ <trans-unit id="AvoidAssemblyGetFilesInSingleFileMessage">
+ <source>'{0}' will throw for assemblies embedded in a single-file app</source>
+ <target state="new">'{0}' will throw for assemblies embedded in a single-file app</target>
+ <note />
+ </trans-unit>
+ <trans-unit id="AvoidAssemblyGetFilesInSingleFileTitle">
+ <source>Avoid accessing Assembly file path when publishing as a single file</source>
+ <target state="new">Avoid accessing Assembly file path when publishing as a single file</target>
+ <note />
+ </trans-unit>
+ <trans-unit id="AvoidAssemblyLocationInSingleFileMessage">
+ <source>'{0}' always returns an empty string for assemblies embedded in a single-file app. If the path to the app directory is needed, consider calling 'System.AppContext.BaseDirectory'.</source>
+ <target state="new">'{0}' always returns an empty string for assemblies embedded in a single-file app. If the path to the app directory is needed, consider calling 'System.AppContext.BaseDirectory'.</target>
+ <note />
+ </trans-unit>
+ <trans-unit id="AvoidAssemblyLocationInSingleFileTitle">
+ <source>Avoid accessing Assembly file path when publishing as a single file</source>
+ <target state="new">Avoid accessing Assembly file path when publishing as a single file</target>
+ <note />
+ </trans-unit>
<trans-unit id="RequiresUnreferencedCodeAnalyzerMessage">
<source>Calling '{0}' which has `RequiresUnreferencedCodeAttribute` can break functionality when trimming application code. {1}. {2}</source>
<target state="new">Calling '{0}' which has `RequiresUnreferencedCodeAttribute` can break functionality when trimming application code. {1}. {2}</target>
diff --git a/src/ILLink.RoslynAnalyzer/xlf/Resources.pt-BR.xlf b/src/ILLink.RoslynAnalyzer/xlf/Resources.pt-BR.xlf
index 3c748ed32..f0c021bcc 100644
--- a/src/ILLink.RoslynAnalyzer/xlf/Resources.pt-BR.xlf
+++ b/src/ILLink.RoslynAnalyzer/xlf/Resources.pt-BR.xlf
@@ -2,6 +2,26 @@
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.2" xsi:schemaLocation="urn:oasis:names:tc:xliff:document:1.2 xliff-core-1.2-transitional.xsd">
<file datatype="xml" source-language="en" target-language="pt-BR" original="../Resources.resx">
<body>
+ <trans-unit id="AvoidAssemblyGetFilesInSingleFileMessage">
+ <source>'{0}' will throw for assemblies embedded in a single-file app</source>
+ <target state="new">'{0}' will throw for assemblies embedded in a single-file app</target>
+ <note />
+ </trans-unit>
+ <trans-unit id="AvoidAssemblyGetFilesInSingleFileTitle">
+ <source>Avoid accessing Assembly file path when publishing as a single file</source>
+ <target state="new">Avoid accessing Assembly file path when publishing as a single file</target>
+ <note />
+ </trans-unit>
+ <trans-unit id="AvoidAssemblyLocationInSingleFileMessage">
+ <source>'{0}' always returns an empty string for assemblies embedded in a single-file app. If the path to the app directory is needed, consider calling 'System.AppContext.BaseDirectory'.</source>
+ <target state="new">'{0}' always returns an empty string for assemblies embedded in a single-file app. If the path to the app directory is needed, consider calling 'System.AppContext.BaseDirectory'.</target>
+ <note />
+ </trans-unit>
+ <trans-unit id="AvoidAssemblyLocationInSingleFileTitle">
+ <source>Avoid accessing Assembly file path when publishing as a single file</source>
+ <target state="new">Avoid accessing Assembly file path when publishing as a single file</target>
+ <note />
+ </trans-unit>
<trans-unit id="RequiresUnreferencedCodeAnalyzerMessage">
<source>Calling '{0}' which has `RequiresUnreferencedCodeAttribute` can break functionality when trimming application code. {1}. {2}</source>
<target state="new">Calling '{0}' which has `RequiresUnreferencedCodeAttribute` can break functionality when trimming application code. {1}. {2}</target>
diff --git a/src/ILLink.RoslynAnalyzer/xlf/Resources.ru.xlf b/src/ILLink.RoslynAnalyzer/xlf/Resources.ru.xlf
index 4820e55e8..afbc27f9b 100644
--- a/src/ILLink.RoslynAnalyzer/xlf/Resources.ru.xlf
+++ b/src/ILLink.RoslynAnalyzer/xlf/Resources.ru.xlf
@@ -2,6 +2,26 @@
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.2" xsi:schemaLocation="urn:oasis:names:tc:xliff:document:1.2 xliff-core-1.2-transitional.xsd">
<file datatype="xml" source-language="en" target-language="ru" original="../Resources.resx">
<body>
+ <trans-unit id="AvoidAssemblyGetFilesInSingleFileMessage">
+ <source>'{0}' will throw for assemblies embedded in a single-file app</source>
+ <target state="new">'{0}' will throw for assemblies embedded in a single-file app</target>
+ <note />
+ </trans-unit>
+ <trans-unit id="AvoidAssemblyGetFilesInSingleFileTitle">
+ <source>Avoid accessing Assembly file path when publishing as a single file</source>
+ <target state="new">Avoid accessing Assembly file path when publishing as a single file</target>
+ <note />
+ </trans-unit>
+ <trans-unit id="AvoidAssemblyLocationInSingleFileMessage">
+ <source>'{0}' always returns an empty string for assemblies embedded in a single-file app. If the path to the app directory is needed, consider calling 'System.AppContext.BaseDirectory'.</source>
+ <target state="new">'{0}' always returns an empty string for assemblies embedded in a single-file app. If the path to the app directory is needed, consider calling 'System.AppContext.BaseDirectory'.</target>
+ <note />
+ </trans-unit>
+ <trans-unit id="AvoidAssemblyLocationInSingleFileTitle">
+ <source>Avoid accessing Assembly file path when publishing as a single file</source>
+ <target state="new">Avoid accessing Assembly file path when publishing as a single file</target>
+ <note />
+ </trans-unit>
<trans-unit id="RequiresUnreferencedCodeAnalyzerMessage">
<source>Calling '{0}' which has `RequiresUnreferencedCodeAttribute` can break functionality when trimming application code. {1}. {2}</source>
<target state="new">Calling '{0}' which has `RequiresUnreferencedCodeAttribute` can break functionality when trimming application code. {1}. {2}</target>
diff --git a/src/ILLink.RoslynAnalyzer/xlf/Resources.tr.xlf b/src/ILLink.RoslynAnalyzer/xlf/Resources.tr.xlf
index 9b85a9a3b..c1cf60671 100644
--- a/src/ILLink.RoslynAnalyzer/xlf/Resources.tr.xlf
+++ b/src/ILLink.RoslynAnalyzer/xlf/Resources.tr.xlf
@@ -2,6 +2,26 @@
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.2" xsi:schemaLocation="urn:oasis:names:tc:xliff:document:1.2 xliff-core-1.2-transitional.xsd">
<file datatype="xml" source-language="en" target-language="tr" original="../Resources.resx">
<body>
+ <trans-unit id="AvoidAssemblyGetFilesInSingleFileMessage">
+ <source>'{0}' will throw for assemblies embedded in a single-file app</source>
+ <target state="new">'{0}' will throw for assemblies embedded in a single-file app</target>
+ <note />
+ </trans-unit>
+ <trans-unit id="AvoidAssemblyGetFilesInSingleFileTitle">
+ <source>Avoid accessing Assembly file path when publishing as a single file</source>
+ <target state="new">Avoid accessing Assembly file path when publishing as a single file</target>
+ <note />
+ </trans-unit>
+ <trans-unit id="AvoidAssemblyLocationInSingleFileMessage">
+ <source>'{0}' always returns an empty string for assemblies embedded in a single-file app. If the path to the app directory is needed, consider calling 'System.AppContext.BaseDirectory'.</source>
+ <target state="new">'{0}' always returns an empty string for assemblies embedded in a single-file app. If the path to the app directory is needed, consider calling 'System.AppContext.BaseDirectory'.</target>
+ <note />
+ </trans-unit>
+ <trans-unit id="AvoidAssemblyLocationInSingleFileTitle">
+ <source>Avoid accessing Assembly file path when publishing as a single file</source>
+ <target state="new">Avoid accessing Assembly file path when publishing as a single file</target>
+ <note />
+ </trans-unit>
<trans-unit id="RequiresUnreferencedCodeAnalyzerMessage">
<source>Calling '{0}' which has `RequiresUnreferencedCodeAttribute` can break functionality when trimming application code. {1}. {2}</source>
<target state="new">Calling '{0}' which has `RequiresUnreferencedCodeAttribute` can break functionality when trimming application code. {1}. {2}</target>
diff --git a/src/ILLink.RoslynAnalyzer/xlf/Resources.zh-Hans.xlf b/src/ILLink.RoslynAnalyzer/xlf/Resources.zh-Hans.xlf
index 80c654eb5..7ca61b715 100644
--- a/src/ILLink.RoslynAnalyzer/xlf/Resources.zh-Hans.xlf
+++ b/src/ILLink.RoslynAnalyzer/xlf/Resources.zh-Hans.xlf
@@ -2,6 +2,26 @@
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.2" xsi:schemaLocation="urn:oasis:names:tc:xliff:document:1.2 xliff-core-1.2-transitional.xsd">
<file datatype="xml" source-language="en" target-language="zh-Hans" original="../Resources.resx">
<body>
+ <trans-unit id="AvoidAssemblyGetFilesInSingleFileMessage">
+ <source>'{0}' will throw for assemblies embedded in a single-file app</source>
+ <target state="new">'{0}' will throw for assemblies embedded in a single-file app</target>
+ <note />
+ </trans-unit>
+ <trans-unit id="AvoidAssemblyGetFilesInSingleFileTitle">
+ <source>Avoid accessing Assembly file path when publishing as a single file</source>
+ <target state="new">Avoid accessing Assembly file path when publishing as a single file</target>
+ <note />
+ </trans-unit>
+ <trans-unit id="AvoidAssemblyLocationInSingleFileMessage">
+ <source>'{0}' always returns an empty string for assemblies embedded in a single-file app. If the path to the app directory is needed, consider calling 'System.AppContext.BaseDirectory'.</source>
+ <target state="new">'{0}' always returns an empty string for assemblies embedded in a single-file app. If the path to the app directory is needed, consider calling 'System.AppContext.BaseDirectory'.</target>
+ <note />
+ </trans-unit>
+ <trans-unit id="AvoidAssemblyLocationInSingleFileTitle">
+ <source>Avoid accessing Assembly file path when publishing as a single file</source>
+ <target state="new">Avoid accessing Assembly file path when publishing as a single file</target>
+ <note />
+ </trans-unit>
<trans-unit id="RequiresUnreferencedCodeAnalyzerMessage">
<source>Calling '{0}' which has `RequiresUnreferencedCodeAttribute` can break functionality when trimming application code. {1}. {2}</source>
<target state="new">Calling '{0}' which has `RequiresUnreferencedCodeAttribute` can break functionality when trimming application code. {1}. {2}</target>
diff --git a/src/ILLink.RoslynAnalyzer/xlf/Resources.zh-Hant.xlf b/src/ILLink.RoslynAnalyzer/xlf/Resources.zh-Hant.xlf
index 80d60776b..64d933978 100644
--- a/src/ILLink.RoslynAnalyzer/xlf/Resources.zh-Hant.xlf
+++ b/src/ILLink.RoslynAnalyzer/xlf/Resources.zh-Hant.xlf
@@ -2,6 +2,26 @@
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.2" xsi:schemaLocation="urn:oasis:names:tc:xliff:document:1.2 xliff-core-1.2-transitional.xsd">
<file datatype="xml" source-language="en" target-language="zh-Hant" original="../Resources.resx">
<body>
+ <trans-unit id="AvoidAssemblyGetFilesInSingleFileMessage">
+ <source>'{0}' will throw for assemblies embedded in a single-file app</source>
+ <target state="new">'{0}' will throw for assemblies embedded in a single-file app</target>
+ <note />
+ </trans-unit>
+ <trans-unit id="AvoidAssemblyGetFilesInSingleFileTitle">
+ <source>Avoid accessing Assembly file path when publishing as a single file</source>
+ <target state="new">Avoid accessing Assembly file path when publishing as a single file</target>
+ <note />
+ </trans-unit>
+ <trans-unit id="AvoidAssemblyLocationInSingleFileMessage">
+ <source>'{0}' always returns an empty string for assemblies embedded in a single-file app. If the path to the app directory is needed, consider calling 'System.AppContext.BaseDirectory'.</source>
+ <target state="new">'{0}' always returns an empty string for assemblies embedded in a single-file app. If the path to the app directory is needed, consider calling 'System.AppContext.BaseDirectory'.</target>
+ <note />
+ </trans-unit>
+ <trans-unit id="AvoidAssemblyLocationInSingleFileTitle">
+ <source>Avoid accessing Assembly file path when publishing as a single file</source>
+ <target state="new">Avoid accessing Assembly file path when publishing as a single file</target>
+ <note />
+ </trans-unit>
<trans-unit id="RequiresUnreferencedCodeAnalyzerMessage">
<source>Calling '{0}' which has `RequiresUnreferencedCodeAttribute` can break functionality when trimming application code. {1}. {2}</source>
<target state="new">Calling '{0}' which has `RequiresUnreferencedCodeAttribute` can break functionality when trimming application code. {1}. {2}</target>
diff --git a/test/ILLink.RoslynAnalyzer.Tests/AvoidAssemblyLocationInSingleFileTests.cs b/test/ILLink.RoslynAnalyzer.Tests/AvoidAssemblyLocationInSingleFileTests.cs
new file mode 100644
index 000000000..0ea712f97
--- /dev/null
+++ b/test/ILLink.RoslynAnalyzer.Tests/AvoidAssemblyLocationInSingleFileTests.cs
@@ -0,0 +1,144 @@
+// 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.Threading.Tasks;
+using Microsoft.CodeAnalysis.Testing;
+using Xunit;
+using VerifyCS = ILLink.RoslynAnalyzer.Tests.CSharpAnalyzerVerifier<
+ ILLink.RoslynAnalyzer.AvoidAssemblyLocationInSingleFile>;
+
+namespace ILLink.RoslynAnalyzer.Tests
+{
+ public class AvoidAssemblyLocationInSingleFileTests
+ {
+ static Task VerifySingleFileAnalyzer (string source, params DiagnosticResult[] expected)
+ {
+ return VerifyCS.VerifyAnalyzerAsync (source,
+ TestCaseUtils.UseMSBuildProperties (MSBuildPropertyOptionNames.PublishSingleFile),
+ expected);
+ }
+
+ [Fact]
+ public Task GetExecutingAssemblyLocation ()
+ {
+ const string src = @"
+using System.Reflection;
+class C
+{
+ public string M() => Assembly.GetExecutingAssembly().Location;
+}";
+
+ return VerifySingleFileAnalyzer (src,
+ // (5,26): warning IL3000: 'System.Reflection.Assembly.Location' always returns an empty string for assemblies embedded in a single-file app. If the path to the app directory is needed, consider calling 'System.AppContext.BaseDirectory'.
+ VerifyCS.Diagnostic (AvoidAssemblyLocationInSingleFile.IL3000).WithSpan (5, 26, 5, 66).WithArguments ("System.Reflection.Assembly.Location"));
+ }
+
+ [Fact]
+ public Task AssemblyProperties ()
+ {
+ var src = @"
+using System.Reflection;
+class C
+{
+ public void M()
+ {
+ var a = Assembly.GetExecutingAssembly();
+ _ = a.Location;
+ // below methods are marked as obsolete in 5.0
+ // _ = a.CodeBase;
+ // _ = a.EscapedCodeBase;
+ }
+}";
+ return VerifySingleFileAnalyzer (src,
+ // (8,13): warning IL3000: 'System.Reflection.Assembly.Location' always returns an empty string for assemblies embedded in a single-file app. If the path to the app directory is needed, consider calling 'System.AppContext.BaseDirectory'.
+ VerifyCS.Diagnostic (AvoidAssemblyLocationInSingleFile.IL3000).WithSpan (8, 13, 8, 23).WithArguments ("System.Reflection.Assembly.Location")
+ );
+ }
+
+ [Fact]
+ public Task AssemblyMethods ()
+ {
+ var src = @"
+using System.Reflection;
+class C
+{
+ public void M()
+ {
+ var a = Assembly.GetExecutingAssembly();
+ _ = a.GetFile(""/some/file/path"");
+ _ = a.GetFiles();
+ }
+}";
+ return VerifySingleFileAnalyzer (src,
+ // (8,13): warning IL3001: Assemblies embedded in a single-file app cannot have additional files in the manifest.
+ VerifyCS.Diagnostic (AvoidAssemblyLocationInSingleFile.IL3001).WithSpan (8, 13, 8, 41).WithArguments ("System.Reflection.Assembly.GetFile(string)"),
+ // (9,13): warning IL3001: Assemblies embedded in a single-file app cannot have additional files in the manifest.
+ VerifyCS.Diagnostic (AvoidAssemblyLocationInSingleFile.IL3001).WithSpan (9, 13, 9, 25).WithArguments ("System.Reflection.Assembly.GetFiles()")
+ );
+ }
+
+ [Fact]
+ public Task AssemblyNameAttributes ()
+ {
+ var src = @"
+using System.Reflection;
+class C
+{
+ public void M()
+ {
+ var a = Assembly.GetExecutingAssembly().GetName();
+ _ = a.CodeBase;
+ _ = a.EscapedCodeBase;
+ }
+}";
+ return VerifySingleFileAnalyzer (src,
+ // (8,13): warning IL3000: 'System.Reflection.AssemblyName.CodeBase' always returns an empty string for assemblies embedded in a single-file app. If the path to the app directory is needed, consider calling 'System.AppContext.BaseDirectory'.
+ VerifyCS.Diagnostic (AvoidAssemblyLocationInSingleFile.IL3000).WithSpan (8, 13, 8, 23).WithArguments ("System.Reflection.AssemblyName.CodeBase"),
+ // (9,13): warning IL3000: 'System.Reflection.AssemblyName.EscapedCodeBase' always returns an empty string for assemblies embedded in a single-file app. If the path to the app directory is needed, consider calling 'System.AppContext.BaseDirectory'.
+ VerifyCS.Diagnostic (AvoidAssemblyLocationInSingleFile.IL3000).WithSpan (9, 13, 9, 30).WithArguments ("System.Reflection.AssemblyName.EscapedCodeBase")
+ );
+ }
+
+ [Fact]
+ public Task FalsePositive ()
+ {
+ // This is an OK use of Location and GetFile since these assemblies were loaded from
+ // a file, but the analyzer is conservative
+ var src = @"
+using System.Reflection;
+class C
+{
+ public void M()
+ {
+ var a = Assembly.LoadFrom(""/some/path/not/in/bundle"");
+ _ = a.Location;
+ _ = a.GetFiles();
+ }
+}";
+ return VerifySingleFileAnalyzer (src,
+ // (8,13): warning IL3000: 'System.Reflection.Assembly.Location' always returns an empty string for assemblies embedded in a single-file app. If the path to the app directory is needed, consider calling 'System.AppContext.BaseDirectory'.
+ VerifyCS.Diagnostic (AvoidAssemblyLocationInSingleFile.IL3000).WithSpan (8, 13, 8, 23).WithArguments ("System.Reflection.Assembly.Location"),
+ // (9,13): warning IL3001: Assemblies embedded in a single-file app cannot have additional files in the manifest.
+ VerifyCS.Diagnostic (AvoidAssemblyLocationInSingleFile.IL3001).WithSpan (9, 13, 9, 25).WithArguments ("System.Reflection.Assembly.GetFiles()")
+ );
+ }
+
+ [Fact]
+ public Task PublishSingleFileIsNotSet ()
+ {
+ var src = @"
+using System.Reflection;
+class C
+{
+ public void M()
+ {
+ var a = Assembly.GetExecutingAssembly().Location;
+ }
+}";
+ // If 'PublishSingleFile' is not set to true, no diagnostics should be produced by the analyzer. This will
+ // effectively verify that the number of produced diagnostics matches the number of expected ones (zero).
+ return VerifyCS.VerifyAnalyzerAsync (src);
+ }
+ }
+}
diff --git a/test/ILLink.RoslynAnalyzer.Tests/LinkerTestCases.cs b/test/ILLink.RoslynAnalyzer.Tests/LinkerTestCases.cs
index e63d2c02f..f205fb25e 100644
--- a/test/ILLink.RoslynAnalyzer.Tests/LinkerTestCases.cs
+++ b/test/ILLink.RoslynAnalyzer.Tests/LinkerTestCases.cs
@@ -3,8 +3,6 @@
// See the LICENSE file in the project root for more information.
using System.Collections.Generic;
-using System.Collections.Immutable;
-using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Xunit;
@@ -24,7 +22,7 @@ namespace ILLink.RoslynAnalyzer.Tests
case "MethodWithDuplicateRequiresAttribute":
return;
}
- RunTest (m, attrs);
+ RunTest (m, attrs, UseMSBuildProperties (MSBuildPropertyOptionNames.PublishTrimmed));
}
}
}
diff --git a/test/ILLink.RoslynAnalyzer.Tests/AnalyzerTests.cs b/test/ILLink.RoslynAnalyzer.Tests/RequiresUnreferencedCodeAnalyzerTests.cs
index fc1ee182d..81899e890 100644
--- a/test/ILLink.RoslynAnalyzer.Tests/AnalyzerTests.cs
+++ b/test/ILLink.RoslynAnalyzer.Tests/RequiresUnreferencedCodeAnalyzerTests.cs
@@ -3,14 +3,22 @@
// See the LICENSE file in the project root for more information.
using System.Threading.Tasks;
+using Microsoft.CodeAnalysis.Testing;
using Xunit;
using VerifyCS = ILLink.RoslynAnalyzer.Tests.CSharpAnalyzerVerifier<
ILLink.RoslynAnalyzer.RequiresUnreferencedCodeAnalyzer>;
namespace ILLink.RoslynAnalyzer.Tests
{
- public class AnalyzerTests
+ public class RequiresUnreferencedCodeAnalyzerTests
{
+ static Task VerifyRequiresUnreferencedCodeAnalyzer (string source, params DiagnosticResult[] expected)
+ {
+ return VerifyCS.VerifyAnalyzerAsync (source,
+ TestCaseUtils.UseMSBuildProperties (MSBuildPropertyOptionNames.PublishTrimmed),
+ expected);
+ }
+
[Fact]
public Task SimpleDiagnostic ()
{
@@ -23,10 +31,9 @@ class C
int M1() => 0;
int M2() => M1();
}";
- return VerifyCS.VerifyAnalyzerAsync (TestRequiresWithMessageOnlyOnMethod,
+ return VerifyRequiresUnreferencedCodeAnalyzer (TestRequiresWithMessageOnlyOnMethod,
// (8,17): warning IL2026: Calling 'System.Int32 C::M1()' which has `RequiresUnreferencedCodeAttribute` can break functionality when trimming application code. message.
- VerifyCS.Diagnostic ().WithSpan (8, 17, 8, 21).WithArguments ("C.M1()", "message", "")
- );
+ VerifyCS.Diagnostic ().WithSpan (8, 17, 8, 21).WithArguments ("C.M1()", "message", ""));
}
[Fact]
@@ -46,7 +53,7 @@ class C
{
}
}";
- return VerifyCS.VerifyAnalyzerAsync (MessageAndUrlOnMethod,
+ return VerifyRequiresUnreferencedCodeAnalyzer (MessageAndUrlOnMethod,
// (8,3): warning IL2026: Calling 'C.RequiresWithMessageAndUrl()' which has `RequiresUnreferencedCodeAttribute` can break functionality when trimming application code. Message for --RequiresWithMessageAndUrl--.
VerifyCS.Diagnostic ().WithSpan (8, 3, 8, 31).WithArguments ("C.RequiresWithMessageAndUrl()", "Message for --RequiresWithMessageAndUrl--", "https://helpurl")
);
@@ -70,7 +77,7 @@ class C
get { return 42; }
}
}";
- return VerifyCS.VerifyAnalyzerAsync (PropertyRequires,
+ return VerifyRequiresUnreferencedCodeAnalyzer (PropertyRequires,
// (8,7): warning IL2026: Calling 'C.PropertyRequires.get' which has `RequiresUnreferencedCodeAttribute` can break functionality when trimming application code. Message for --getter PropertyRequires--.
VerifyCS.Diagnostic ().WithSpan (8, 7, 8, 23).WithArguments ("C.PropertyRequires.get", "Message for --getter PropertyRequires--", "")
);
@@ -94,7 +101,7 @@ class C
set { }
}
}";
- return VerifyCS.VerifyAnalyzerAsync (PropertyRequires,
+ return VerifyRequiresUnreferencedCodeAnalyzer (PropertyRequires,
// (8,3): warning IL2026: Calling 'C.PropertyRequires.set' which has `RequiresUnreferencedCodeAttribute` can break functionality when trimming application code. Message for --setter PropertyRequires--.
VerifyCS.Diagnostic ().WithSpan (8, 3, 8, 19).WithArguments ("C.PropertyRequires.set", "Message for --setter PropertyRequires--", "")
);
diff --git a/test/ILLink.RoslynAnalyzer.Tests/TestCaseUtils.cs b/test/ILLink.RoslynAnalyzer.Tests/TestCaseUtils.cs
index 003823c02..c62c2d762 100644
--- a/test/ILLink.RoslynAnalyzer.Tests/TestCaseUtils.cs
+++ b/test/ILLink.RoslynAnalyzer.Tests/TestCaseUtils.cs
@@ -53,9 +53,9 @@ namespace ILLink.RoslynAnalyzer.Tests
}
}
- internal static void RunTest (MethodDeclarationSyntax m, List<AttributeSyntax> attrs)
+ internal static void RunTest (MethodDeclarationSyntax m, List<AttributeSyntax> attrs, params (string, string)[] MSBuildProperties)
{
- var comp = CSharpAnalyzerVerifier<RequiresUnreferencedCodeAnalyzer>.CreateCompilation (m.SyntaxTree).Result;
+ var comp = CSharpAnalyzerVerifier<RequiresUnreferencedCodeAnalyzer>.CreateCompilation (m.SyntaxTree, MSBuildProperties).Result;
var diags = comp.GetAnalyzerDiagnosticsAsync ().Result;
var filtered = diags.Where (d => d.Location.SourceSpan.IntersectsWith (m.Span))
@@ -181,6 +181,11 @@ In diagnostics:
}
}
+ internal static (string, string)[] UseMSBuildProperties (params string[] MSBuildProperties)
+ {
+ return MSBuildProperties.Select (msbp => ($"build_property.{msbp}", "true")).ToArray ();
+ }
+
internal static void GetDirectoryPaths (out string rootSourceDirectory, out string testAssemblyPath, [CallerFilePath] string thisFile = null)
{
diff --git a/test/ILLink.RoslynAnalyzer.Tests/Verifiers/CSharpAnalyzerVerifier`1.cs b/test/ILLink.RoslynAnalyzer.Tests/Verifiers/CSharpAnalyzerVerifier`1.cs
index 91b28b1aa..4d96f37d8 100644
--- a/test/ILLink.RoslynAnalyzer.Tests/Verifiers/CSharpAnalyzerVerifier`1.cs
+++ b/test/ILLink.RoslynAnalyzer.Tests/Verifiers/CSharpAnalyzerVerifier`1.cs
@@ -71,9 +71,9 @@ namespace ILLink.RoslynAnalyzer.Tests
}
/// <inheritdoc cref="AnalyzerVerifier{TAnalyzer, TTest, TVerifier}.VerifyAnalyzerAsync(string, DiagnosticResult[])"/>
- public static async Task VerifyAnalyzerAsync (string src, params DiagnosticResult[] expected)
+ public static async Task VerifyAnalyzerAsync (string src, (string, string)[]? analyzerOptions = null, params DiagnosticResult[] expected)
{
- var diags = await (await CreateCompilation (src)).GetAllDiagnosticsAsync ();
+ var diags = await (await CreateCompilation (src, analyzerOptions)).GetAllDiagnosticsAsync ();
var analyzers = ImmutableArray.Create<DiagnosticAnalyzer> (new TAnalyzer ());
VerifyDiagnosticResults (diags, analyzers, expected, DefaultVerifier);