diff options
-rw-r--r-- | ikvmc/Compiler.cs | 9 | ||||
-rw-r--r-- | ikvmc/CompilerClassLoader.cs | 56 | ||||
-rw-r--r-- | runtime/ClassFile.cs | 13 | ||||
-rw-r--r-- | runtime/ClassLoaderWrapper.cs | 8 | ||||
-rw-r--r-- | runtime/compiler.cs | 12 |
5 files changed, 57 insertions, 41 deletions
diff --git a/ikvmc/Compiler.cs b/ikvmc/Compiler.cs index aa24ab5e..0058bc8f 100644 --- a/ikvmc/Compiler.cs +++ b/ikvmc/Compiler.cs @@ -102,7 +102,7 @@ class IkvmcCompiler { private bool nonleaf; private string manifestMainClass; - private Dictionary<string, byte[]> classes = new Dictionary<string, byte[]>(); + private Dictionary<string, ClassItem> classes = new Dictionary<string, ClassItem>(); private Dictionary<string, List<ResourceItem>> resources = new Dictionary<string, List<ResourceItem>>(); private string defaultAssemblyName; private List<string> classesToExclude = new List<string>(); @@ -455,7 +455,7 @@ class IkvmcCompiler nonleaf = true; IkvmcCompiler nestedLevel = new IkvmcCompiler(); nestedLevel.manifestMainClass = manifestMainClass; - nestedLevel.classes = new Dictionary<string, byte[]>(classes); + nestedLevel.classes = new Dictionary<string, ClassItem>(classes); nestedLevel.resources = CompilerOptions.Copy(resources); nestedLevel.defaultAssemblyName = defaultAssemblyName; nestedLevel.classesToExclude = new List<string>(classesToExclude); @@ -1088,7 +1088,10 @@ class IkvmcCompiler } else { - classes.Add(name, buf); + ClassItem item; + item.data = buf; + item.path = zipEntry == null ? filename : null; + classes.Add(name, item); } } catch(ClassFormatError x) diff --git a/ikvmc/CompilerClassLoader.cs b/ikvmc/CompilerClassLoader.cs index 3ba07581..32270219 100644 --- a/ikvmc/CompilerClassLoader.cs +++ b/ikvmc/CompilerClassLoader.cs @@ -44,7 +44,7 @@ namespace IKVM.Internal { class CompilerClassLoader : ClassLoaderWrapper { - private Dictionary<string, byte[]> classes; + private Dictionary<string, ClassItem> classes; private Dictionary<string, RemapperTypeWrapper> remapped = new Dictionary<string, RemapperTypeWrapper>(); private string assemblyName; private string assemblyFile; @@ -75,7 +75,7 @@ namespace IKVM.Internal private List<string> jarList = new List<string>(); private List<TypeWrapper> allwrappers; - internal CompilerClassLoader(AssemblyClassLoader[] referencedAssemblies, CompilerOptions options, string path, bool targetIsModule, string assemblyName, Dictionary<string, byte[]> classes) + internal CompilerClassLoader(AssemblyClassLoader[] referencedAssemblies, CompilerOptions options, string path, bool targetIsModule, string assemblyName, Dictionary<string, ClassItem> classes) : base(options.codegenoptions, null) { this.referencedAssemblies = referencedAssemblies; @@ -112,14 +112,6 @@ namespace IKVM.Internal peerReferences.Add(ccl); } - internal override string SourcePath - { - get - { - return options.sourcepath; - } - } - internal AssemblyName GetAssemblyName() { return assemblyBuilder.GetName(); @@ -277,7 +269,7 @@ namespace IKVM.Internal } else { - byte[] classdef; + ClassItem classdef; if(classes.TryGetValue(name, out classdef)) { classes.Remove(name); @@ -289,7 +281,7 @@ namespace IKVM.Internal { cfp |= ClassFileParseOptions.LineNumberTable; } - f = new ClassFile(classdef, 0, classdef.Length, name, cfp); + f = new ClassFile(classdef.data, 0, classdef.data.Length, name, cfp); } catch(ClassFormatError x) { @@ -338,6 +330,24 @@ namespace IKVM.Internal { f.SetEffectivelyFinal(); } + if(f.SourceFileAttribute != null) + { + if(classdef.path != null) + { + string sourceFile = Path.GetFullPath(Path.Combine(Path.GetDirectoryName(classdef.path), f.SourceFileAttribute)); + if(File.Exists(sourceFile)) + { + f.SourcePath = sourceFile; + } + } + if(f.SourcePath == null && options.sourcepath != null) + { + string package = f.Name; + int index = package.LastIndexOf('.'); + package = index == -1 ? "" : package.Substring(0, index).Replace('.', '/'); + f.SourcePath = Path.GetFullPath(Path.Combine(options.sourcepath + "/" + package, f.SourceFileAttribute)); + } + } try { TypeWrapper type = DefineClass(f, null); @@ -2729,12 +2739,12 @@ namespace IKVM.Internal List<object> assemblyAnnotations = new List<object>(); Dictionary<string, string> baseClasses = new Dictionary<string, string>(); Tracer.Info(Tracer.Compiler, "Parsing class files"); - foreach(KeyValuePair<string, byte[]> kv in options.classes) + foreach(KeyValuePair<string, ClassItem> kv in options.classes) { ClassFile f; try { - byte[] buf = kv.Value; + byte[] buf = kv.Value.data; f = new ClassFile(buf, 0, buf.Length, null, ClassFileParseOptions.None); if(!f.IsInterface && f.SuperClass != null) { @@ -2764,10 +2774,10 @@ namespace IKVM.Internal } } } - Dictionary<string, byte[]> h = new Dictionary<string, byte[]>(); + Dictionary<string, ClassItem> h = new Dictionary<string, ClassItem>(); // HACK remove "assembly" type that exists only as a placeholder for assembly attributes options.classes.Remove("assembly"); - foreach(KeyValuePair<string, byte[]> kv in options.classes) + foreach(KeyValuePair<string, ClassItem> kv in options.classes) { string name = kv.Key; bool excluded = false; @@ -2984,12 +2994,12 @@ namespace IKVM.Internal { // this function is needed because when using generics a type may be loaded before the stub is seen // and without this check that would cause a spurious IKVMC0109 warning - byte[] classdef; + ClassItem classdef; if (classes.TryGetValue(className, out classdef)) { try { - return new ClassFile(classdef, 0, classdef.Length, className, ClassFileParseOptions.RelaxedClassNameValidation).IKVMAssemblyAttribute != null; + return new ClassFile(classdef.data, 0, classdef.data.Length, className, ClassFileParseOptions.RelaxedClassNameValidation).IKVMAssemblyAttribute != null; } catch (ClassFormatError) { @@ -3360,6 +3370,12 @@ namespace IKVM.Internal } } + struct ClassItem + { + internal byte[] data; + internal string path; + } + struct ResourceItem { internal ICSharpCode.SharpZipLib.Zip.ZipEntry zipEntry; @@ -3385,7 +3401,7 @@ namespace IKVM.Internal internal ApartmentState apartment; internal PEFileKinds target; internal bool guessFileKind; - internal Dictionary<string, byte[]> classes; + internal Dictionary<string, ClassItem> classes; internal string[] unresolvedReferences; // only used during command line parsing internal Assembly[] references; internal string[] peerReferences; @@ -3420,7 +3436,7 @@ namespace IKVM.Internal CompilerOptions copy = (CompilerOptions)MemberwiseClone(); if (classes != null) { - copy.classes = new Dictionary<string, byte[]>(classes); + copy.classes = new Dictionary<string, ClassItem>(classes); } if (resources != null) { diff --git a/runtime/ClassFile.cs b/runtime/ClassFile.cs index 5ca37aec..1245505a 100644 --- a/runtime/ClassFile.cs +++ b/runtime/ClassFile.cs @@ -72,6 +72,9 @@ namespace IKVM.Internal private Field[] fields; private Method[] methods; private string sourceFile; +#if STATIC_COMPILER + private string sourcePath; +#endif private string ikvmAssembly; private InnerClass[] innerClasses; private object[] annotations; @@ -1133,6 +1136,16 @@ namespace IKVM.Internal } } + internal string SourcePath + { +#if STATIC_COMPILER + get { return sourcePath; } + set { sourcePath = value; } +#else + get { return sourceFile; } +#endif + } + internal object[] Annotations { get diff --git a/runtime/ClassLoaderWrapper.cs b/runtime/ClassLoaderWrapper.cs index d38fa813..de3413eb 100644 --- a/runtime/ClassLoaderWrapper.cs +++ b/runtime/ClassLoaderWrapper.cs @@ -282,14 +282,6 @@ namespace IKVM.Internal } #endif // !STATIC_COMPILER && !STUB_GENERATOR - internal virtual string SourcePath - { - get - { - return null; - } - } - protected virtual void CheckDefineClassAllowed(string className) { // this hook exists so that AssemblyClassLoader can prevent DefineClass when the name is already present in the assembly diff --git a/runtime/compiler.cs b/runtime/compiler.cs index c0e7df2f..15952878 100644 --- a/runtime/compiler.cs +++ b/runtime/compiler.cs @@ -852,17 +852,9 @@ sealed class Compiler ClassLoaderWrapper classLoader = clazz.GetClassLoader(); if(classLoader.EmitDebugInfo) { - string sourcefile = classFile.SourceFileAttribute; - if(sourcefile != null) + if(classFile.SourcePath != null) { - if(classLoader.SourcePath != null) - { - string package = clazz.Name; - int index = package.LastIndexOf('.'); - package = index == -1 ? "" : package.Substring(0, index).Replace('.', '/'); - sourcefile = new System.IO.FileInfo(classLoader.SourcePath + "/" + package + "/" + sourcefile).FullName; - } - ilGenerator.DefineSymbolDocument(classLoader.GetTypeWrapperFactory().ModuleBuilder, sourcefile, SymLanguageType.Java, Guid.Empty, SymDocumentType.Text); + ilGenerator.DefineSymbolDocument(classLoader.GetTypeWrapperFactory().ModuleBuilder, classFile.SourcePath, SymLanguageType.Java, Guid.Empty, SymDocumentType.Text); // the very first instruction in the method must have an associated line number, to be able // to step into the method in Visual Studio .NET ClassFile.Method.LineNumberTableEntry[] table = m.LineNumberTableAttribute; |