[mtouch] Show warnings when we can't find referenced assemblies. (#4511)
* [mtouch] Show warnings when we can't find referenced assemblies. This would have helped track down #4235. * Improve MT0137 warning to indicate the type of the attribute causing the warning.
This commit is contained in:
Родитель
69eb5cf1a7
Коммит
fd05ba6a79
|
@ -156,6 +156,8 @@ Alternatively, enable the managed [linker](https://docs.microsoft.com/xamarin/ma
|
|||
|
||||
As a last-straw solution, use an older version of Xamarin.Mac that does not require these new SDKs to be present during the build process.
|
||||
|
||||
<!-- 0136 and 0137 used by mtouch -->
|
||||
|
||||
# MM1xxx: file copy / symlinks (project related)
|
||||
|
||||
### <a name="MM1034">MM1034: Could not create symlink '{file}' -> '{target}': error {number}
|
||||
|
|
|
@ -683,6 +683,22 @@ Alternatively, enable the managed [linker](https://docs.microsoft.com/en-us/xama
|
|||
|
||||
As a last-straw solution, use an older version of Xamarin.iOS that does not require these new SDKs to be present during the build process.
|
||||
|
||||
### <a name="MT0136"/>MT0136: Cannot find the assembly {assembly} referenced from {assembly}.
|
||||
|
||||
This warning occurs when an assembly passed to mtouch contains a reference to
|
||||
another assembly that can't be found.
|
||||
|
||||
mtouch may in certain cases still find references at a later point, which
|
||||
means that if the build otherwise succeeds, this warning can be ignored.
|
||||
|
||||
### <a name="MT0137"/>MT0137: Cannot find the assembly {assembly}, referenced by an attribute in {assembly}.
|
||||
|
||||
This warning occurs when an attribute contains a reference to another assembly
|
||||
that can't be found.
|
||||
|
||||
mtouch may in certain cases still find references at a later point, which
|
||||
means that if the build otherwise succeeds, this warning can be ignored.
|
||||
|
||||
# MT1xxx: Project related error messages
|
||||
|
||||
### MT10xx: Installer / mtouch
|
||||
|
|
|
@ -44,6 +44,7 @@ namespace Xamarin.Tests
|
|||
abstract class BundlerTool : Tool
|
||||
{
|
||||
public const string None = "None";
|
||||
public bool AlwaysShowOutput;
|
||||
|
||||
#pragma warning disable 0649 // Field 'X' is never assigned to, and will always have its default value Y
|
||||
// These map directly to mtouch/mmp options
|
||||
|
@ -306,7 +307,7 @@ namespace Xamarin.Tests
|
|||
|
||||
public virtual int Execute ()
|
||||
{
|
||||
return Execute (ToolArguments, always_show_output: Verbosity > 0);
|
||||
return Execute (ToolArguments, always_show_output: Verbosity > 0 || AlwaysShowOutput);
|
||||
}
|
||||
|
||||
public virtual void AssertExecute (string message = null)
|
||||
|
|
|
@ -1716,6 +1716,67 @@ public class TestApp {
|
|||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void MT0136 ()
|
||||
{
|
||||
using (var mtouch = new MTouchTool ()) {
|
||||
var tmpdir = mtouch.CreateTemporaryDirectory ();
|
||||
mtouch.CreateTemporaryCacheDirectory ();
|
||||
|
||||
var codeDll = @"public class A {}";
|
||||
var codeExe = @"public class B : A {}";
|
||||
|
||||
var dllPath = CompileTestAppLibrary (tmpdir, codeDll, profile: Profile.iOS, appName: "A");
|
||||
|
||||
mtouch.CreateTemporaryApp (extraCode: codeExe, extraArg: $"-r:{StringUtils.Quote (dllPath)}");
|
||||
mtouch.Debug = false;
|
||||
mtouch.Linker = MTouchLinker.DontLink;
|
||||
File.Delete (dllPath);
|
||||
mtouch.AssertExecuteFailure (MTouchAction.BuildSim, "build");
|
||||
mtouch.AssertWarningPattern (136, "Cannot find the assembly 'A, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' referenced from '.*/testApp.exe'.");
|
||||
mtouch.AssertError (2002, "Failed to resolve assembly: 'A, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'");
|
||||
mtouch.AssertErrorCount (1);
|
||||
mtouch.AssertWarningCount (1);
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void MT0137 ()
|
||||
{
|
||||
using (var mtouch = new MTouchTool ()) {
|
||||
var tmpdir = mtouch.CreateTemporaryDirectory ();
|
||||
mtouch.CreateTemporaryCacheDirectory ();
|
||||
|
||||
var codeDll = @"public class A {}";
|
||||
var codeExe = @"
|
||||
[assembly: MyCustomAttribute (typeof (A))]
|
||||
|
||||
public class MyCustomAttribute : System.Attribute
|
||||
{
|
||||
public MyCustomAttribute (System.Type type) {}
|
||||
}
|
||||
|
||||
[System.Diagnostics.DebuggerTypeProxyAttribute (typeof (A))]
|
||||
public class B
|
||||
{
|
||||
}
|
||||
";
|
||||
var codeExeFile = Path.Combine (tmpdir, "extraCode.cs");
|
||||
File.WriteAllText (codeExeFile, codeExe);
|
||||
var dllPath = CompileTestAppLibrary (tmpdir, codeDll, profile: Profile.iOS, appName: "A");
|
||||
|
||||
mtouch.CreateTemporaryApp (extraArg: $"-r:{StringUtils.Quote (dllPath)} {StringUtils.Quote (codeExeFile)}");
|
||||
mtouch.Debug = false;
|
||||
mtouch.Linker = MTouchLinker.DontLink;
|
||||
File.Delete (dllPath);
|
||||
mtouch.AlwaysShowOutput = true;
|
||||
mtouch.AssertExecute (MTouchAction.BuildSim, "build");
|
||||
mtouch.AssertWarning (137, "Cannot find the assembly 'A, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null', referenced by a MyCustomAttribute attribute in 'testApp.exe'.");
|
||||
mtouch.AssertWarning (137, "Cannot find the assembly 'A, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null', referenced by a System.Diagnostics.DebuggerTypeProxyAttribute attribute in 'testApp.exe'.");
|
||||
mtouch.AssertWarningCount (2);
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
[TestCase ("all")]
|
||||
[TestCase ("-all")]
|
||||
|
|
|
@ -393,6 +393,10 @@ namespace Xamarin.Bundler
|
|||
}
|
||||
|
||||
var reference_assembly = ManifestResolver.Resolve (reference);
|
||||
if (reference_assembly == null) {
|
||||
ErrorHelper.Warning (136, "Cannot find the assembly '{0}' referenced from '{1}'.", reference.FullName, main.FileName);
|
||||
continue;
|
||||
}
|
||||
ComputeListOfAssemblies (assemblies, reference_assembly, exceptions);
|
||||
}
|
||||
|
||||
|
@ -402,39 +406,36 @@ namespace Xamarin.Bundler
|
|||
// Custom Attribute metadata can include references to other assemblies, e.g. [X (typeof (Y)],
|
||||
// but it is not reflected in AssemblyReferences :-( ref: #37611
|
||||
// so we must scan every custom attribute to look for System.Type
|
||||
GetCustomAttributeReferences (assembly, assemblies, exceptions);
|
||||
GetCustomAttributeReferences (main, assemblies, exceptions);
|
||||
if (main.HasTypes) {
|
||||
foreach (var ca in main.GetCustomAttributes ())
|
||||
GetCustomAttributeReferences (ca, assemblies, exceptions);
|
||||
}
|
||||
GetCustomAttributeReferences (main, main, assemblies, exceptions);
|
||||
foreach (var ca in main.GetCustomAttributes ())
|
||||
GetCustomAttributeReferences (main, ca, assemblies, exceptions);
|
||||
}
|
||||
|
||||
void GetCustomAttributeReferences (ICustomAttributeProvider cap, HashSet<string> assemblies, List<Exception> exceptions)
|
||||
void GetCustomAttributeReferences (ModuleDefinition main, ICustomAttributeProvider cap, HashSet<string> assemblies, List<Exception> exceptions)
|
||||
{
|
||||
if (!cap.HasCustomAttributes)
|
||||
return;
|
||||
foreach (var ca in cap.CustomAttributes)
|
||||
GetCustomAttributeReferences (ca, assemblies, exceptions);
|
||||
GetCustomAttributeReferences (main, ca, assemblies, exceptions);
|
||||
}
|
||||
|
||||
void GetCustomAttributeReferences (CustomAttribute ca, HashSet<string> assemblies, List<Exception> exceptions)
|
||||
void GetCustomAttributeReferences (ModuleDefinition main, CustomAttribute ca, HashSet<string> assemblies, List<Exception> exceptions)
|
||||
{
|
||||
if (ca.HasConstructorArguments) {
|
||||
foreach (var arg in ca.ConstructorArguments)
|
||||
GetCustomAttributeArgumentReference (arg, assemblies, exceptions);
|
||||
GetCustomAttributeArgumentReference (main, ca, arg, assemblies, exceptions);
|
||||
}
|
||||
if (ca.HasFields) {
|
||||
foreach (var arg in ca.Fields)
|
||||
GetCustomAttributeArgumentReference (arg.Argument, assemblies, exceptions);
|
||||
GetCustomAttributeArgumentReference (main, ca, arg.Argument, assemblies, exceptions);
|
||||
}
|
||||
if (ca.HasProperties) {
|
||||
foreach (var arg in ca.Properties)
|
||||
GetCustomAttributeArgumentReference (arg.Argument, assemblies, exceptions);
|
||||
GetCustomAttributeArgumentReference (main, ca, arg.Argument, assemblies, exceptions);
|
||||
}
|
||||
}
|
||||
|
||||
void GetCustomAttributeArgumentReference (CustomAttributeArgument arg, HashSet<string> assemblies, List<Exception> exceptions)
|
||||
void GetCustomAttributeArgumentReference (ModuleDefinition main, CustomAttribute ca, CustomAttributeArgument arg, HashSet<string> assemblies, List<Exception> exceptions)
|
||||
{
|
||||
if (!arg.Type.Is ("System", "Type"))
|
||||
return;
|
||||
|
@ -442,6 +443,10 @@ namespace Xamarin.Bundler
|
|||
if (ar == null)
|
||||
return;
|
||||
var reference_assembly = ManifestResolver.Resolve (ar);
|
||||
if (reference_assembly == null) {
|
||||
ErrorHelper.Warning (137, "Cannot find the assembly '{0}', referenced by a {2} attribute in '{1}'.", ar.FullName, main.Name, ca.AttributeType.FullName);
|
||||
return;
|
||||
}
|
||||
ComputeListOfAssemblies (assemblies, reference_assembly, exceptions);
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче