diff --git a/ikvmc/AssemblyResolver.cs b/ikvmc/AssemblyResolver.cs index a43724c7..131500d6 100644 --- a/ikvmc/AssemblyResolver.cs +++ b/ikvmc/AssemblyResolver.cs @@ -1,5 +1,5 @@ /* - Copyright (C) 2010 Jeroen Frijters + Copyright (C) 2010-2013 Jeroen Frijters This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -83,7 +83,11 @@ namespace IKVM.Internal { mscorlibVersion = universe.Load("mscorlib").GetName().Version; } - universe.AssemblyResolve += new IKVM.Reflection.ResolveEventHandler(universe_AssemblyResolve); +#if STATIC_COMPILER + universe.AssemblyResolve += AssemblyResolve; +#else + universe.AssemblyResolve += LegacyAssemblyResolve; +#endif } internal Assembly LoadFile(string path) @@ -244,7 +248,49 @@ namespace IKVM.Internal } } - private Assembly universe_AssemblyResolve(object sender, IKVM.Reflection.ResolveEventArgs args) + private Assembly AssemblyResolve(object sender, IKVM.Reflection.ResolveEventArgs args) + { + AssemblyName name = new AssemblyName(args.Name); + AssemblyName previousMatch = null; + int previousMatchLevel = 0; + foreach (Assembly asm in universe.GetAssemblies()) + { + if (Match(asm.GetName(), name, ref previousMatch, ref previousMatchLevel)) + { + return asm; + } + } + if (previousMatch != null) + { + if (previousMatchLevel == 2) + { + EmitWarning(WarningId.HigherVersion, "assuming assembly reference \"{0}\" matches \"{1}\", you may need to supply runtime policy", previousMatch.FullName, name.FullName); + return universe.Load(previousMatch.FullName); + } + else if (args.RequestingAssembly != null) + { + Console.Error.WriteLine("Error: Assembly '{0}' uses '{1}' which has a higher version than referenced assembly '{2}'", args.RequestingAssembly.FullName, name.FullName, previousMatch.FullName); + Environment.Exit(1); + return null; + } + else + { + Console.Error.WriteLine("Error: Assembly '{0}' was requested which is a higher version than referenced assembly '{1}'", name.FullName, previousMatch.FullName); + Environment.Exit(1); + return null; + } + } + else if (args.RequestingAssembly != null) + { + return universe.CreateMissingAssembly(args.Name); + } + else + { + return null; + } + } + + private Assembly LegacyAssemblyResolve(object sender, IKVM.Reflection.ResolveEventArgs args) { return LegacyLoad(new AssemblyName(args.Name), args.RequestingAssembly); } diff --git a/ikvmc/Compiler.cs b/ikvmc/Compiler.cs index 275ecd33..0f9f260e 100644 --- a/ikvmc/Compiler.cs +++ b/ikvmc/Compiler.cs @@ -152,6 +152,8 @@ sealed class FatalCompilerErrorException : Exception return "Unable to resolve interface '{0}' on type '{1}'"; case IKVM.Internal.Message.MissingBaseType: return "The base class or interface '{0}' in assembly '{1}' referenced by type '{2}' in '{3}' could not be resolved"; + case IKVM.Internal.Message.MissingBaseTypeReference: + return "The type '{0}' is defined in an assembly that is not referenced. You must add a reference to assembly '{1}'"; default: return "Missing Error Message. Please file a bug."; } diff --git a/ikvmc/CompilerClassLoader.cs b/ikvmc/CompilerClassLoader.cs index 6c96644e..f221c8ce 100644 --- a/ikvmc/CompilerClassLoader.cs +++ b/ikvmc/CompilerClassLoader.cs @@ -3086,7 +3086,7 @@ namespace IKVM.Internal } catch (IKVM.Reflection.MissingMemberException x) { - StaticCompiler.IssueMessage(Message.MissingType, ((Type)x.MemberInfo).FullName, x.MemberInfo.Module.Assembly.FullName); + StaticCompiler.IssueMissingTypeMessage((Type)x.MemberInfo); return 1; } } @@ -3462,6 +3462,7 @@ namespace IKVM.Internal InvalidPropertySignatureInMapFile = 4012, NonPrimaryAssemblyReference = 4013, MissingType = 4014, + MissingReference = 4015, // Fatal errors ResponseFileDepthExceeded = 5000, ErrorReadingFile = 5001, @@ -3517,6 +3518,7 @@ namespace IKVM.Internal CallerIDRequiresHasCallerIDAnnotation = 5051, UnableToResolveInterface = 5052, MissingBaseType = 5053, + MissingBaseTypeReference = 5054, } static class StaticCompiler @@ -3542,7 +3544,12 @@ namespace IKVM.Internal internal static Assembly Load(string assemblyString) { - return Universe.Load(assemblyString); + Assembly asm = Universe.Load(assemblyString); + if (asm.__IsMissing) + { + throw new FileNotFoundException(assemblyString); + } + return asm; } internal static Assembly LoadFile(string path) @@ -3753,6 +3760,9 @@ namespace IKVM.Internal case Message.MissingType: msg = "Reference to type \"{0}\" claims it is defined in \"{1}\", but it could not be found"; break; + case Message.MissingReference: + msg = "The type '{0}' is defined in an assembly that is not referenced. You must add a reference to assembly '{1}'"; + break; case Message.DuplicateAssemblyReference: msg = "Duplicate assembly reference \"{0}\""; break; @@ -3857,5 +3867,11 @@ namespace IKVM.Internal } return tw.Name + " (unknown assembly)"; } + + internal static void IssueMissingTypeMessage(Type type) + { + type = ReflectUtil.GetMissingType(type); + StaticCompiler.IssueMessage(type.Assembly.__IsMissing ? Message.MissingReference : Message.MissingType, type.FullName, type.Assembly.FullName); + } } } diff --git a/openjdk/openjdk.build b/openjdk/openjdk.build index 87305752..c1573a53 100644 --- a/openjdk/openjdk.build +++ b/openjdk/openjdk.build @@ -206,6 +206,7 @@ + diff --git a/runtime/DynamicTypeWrapper.cs b/runtime/DynamicTypeWrapper.cs index 976894fb..f60f1ad5 100644 --- a/runtime/DynamicTypeWrapper.cs +++ b/runtime/DynamicTypeWrapper.cs @@ -80,6 +80,10 @@ namespace IKVM.Internal if (missing != null) { Type mt = ReflectUtil.GetMissingType(missing.MissingType); + if (mt.Assembly.__IsMissing) + { + throw new FatalCompilerErrorException(Message.MissingBaseTypeReference, mt.FullName, mt.Assembly.FullName); + } throw new FatalCompilerErrorException(Message.MissingBaseType, mt.FullName, mt.Assembly.FullName, prev.TypeAsBaseType.FullName, prev.TypeAsBaseType.Module.Name); } diff --git a/runtime/TypeWrapper.cs b/runtime/TypeWrapper.cs index e9a171aa..161fb311 100644 --- a/runtime/TypeWrapper.cs +++ b/runtime/TypeWrapper.cs @@ -2433,8 +2433,7 @@ namespace IKVM.Internal { if (type.__ContainsMissingType) { - type = ReflectUtil.GetMissingType(type); - StaticCompiler.IssueMessage(Message.MissingType, type.FullName, type.Assembly.FullName); + StaticCompiler.IssueMissingTypeMessage(type); return false; } bool ok = true;