diff --git a/src/AddIns/DisplayBindings/FormsDesigner/Project/Src/DesignerLoader/NRefactoryDesignerLoader.cs b/src/AddIns/DisplayBindings/FormsDesigner/Project/Src/DesignerLoader/NRefactoryDesignerLoader.cs index 6ae69e5440..fdefb5affc 100644 --- a/src/AddIns/DisplayBindings/FormsDesigner/Project/Src/DesignerLoader/NRefactoryDesignerLoader.cs +++ b/src/AddIns/DisplayBindings/FormsDesigner/Project/Src/DesignerLoader/NRefactoryDesignerLoader.cs @@ -223,6 +223,7 @@ namespace ICSharpCode.FormsDesigner } CodeDOMVisitor visitor = new CodeDOMVisitor(); + visitor.EnvironmentInformationProvider = new ICSharpCode.SharpDevelop.Dom.NRefactoryResolver.NRefactoryInformationProvider(formClass.ProjectContent, formClass); visitor.Visit(combinedCu, null); // output generated CodeDOM to the console : diff --git a/src/AddIns/DisplayBindings/FormsDesigner/Project/Src/Services/TypeResolutionService.cs b/src/AddIns/DisplayBindings/FormsDesigner/Project/Src/Services/TypeResolutionService.cs index e6eaa8cf78..b1f081d681 100644 --- a/src/AddIns/DisplayBindings/FormsDesigner/Project/Src/Services/TypeResolutionService.cs +++ b/src/AddIns/DisplayBindings/FormsDesigner/Project/Src/Services/TypeResolutionService.cs @@ -16,6 +16,9 @@ using System.ComponentModel.Design; using ICSharpCode.SharpDevelop.Project; using ICSharpCode.SharpDevelop.Dom; using ICSharpCode.Core; +using System.Diagnostics ; + + using HashFunction = System.Security.Cryptography.SHA1Managed; namespace ICSharpCode.FormsDesigner.Services @@ -38,11 +41,39 @@ namespace ICSharpCode.FormsDesigner.Services static TypeResolutionService() { + ClearMixedAssembliesTemporaryFiles(); DesignerAssemblies.Add(ProjectContentRegistry.MscorlibAssembly); DesignerAssemblies.Add(ProjectContentRegistry.SystemAssembly); DesignerAssemblies.Add(typeof(System.Drawing.Point).Assembly); } + [System.Runtime.InteropServices.DllImport("kernel32.dll")] + private static extern bool MoveFileEx(string lpExistingFileName, string lpNewFileName, int dwFlags); + const int MOVEFILE_DELAY_UNTIL_REBOOT = 0x00000004; + + static void MarkFileToDeleteOnReboot(string fileName) + { + MoveFileEx(fileName, null, MOVEFILE_DELAY_UNTIL_REBOOT); + } + + static void ClearMixedAssembliesTemporaryFiles() + { + string[] files = Directory.GetFiles(Path.GetTempPath(), "*.sd_forms_designer_mixed_assembly.dll"); + foreach (string fileName in files) { + try { + File.Delete(fileName); + } catch {} + } + /* We don't need to debug controls inside the forms designer + files = Directory.GetFiles(Path.GetTempPath(), "*.pdb"); + foreach (string fileName in files) { + try { + File.Delete(fileName); + } catch {} + }*/ + } + + string formSourceFileName; IProjectContent callingProject; @@ -79,6 +110,16 @@ namespace ICSharpCode.FormsDesigner.Services /// public static Assembly LoadAssembly(IProjectContent pc) { + // load dependencies of current assembly + foreach (IProjectContent rpc in pc.ReferencedContents) { + if (rpc is ParseProjectContent) { + LoadAssembly(rpc); + } else if (rpc is ReflectionProjectContent) { + if (!(rpc as ReflectionProjectContent).IsGacAssembly) + LoadAssembly(rpc); + } + } + if (pc.Project != null) { return LoadAssembly(pc.Project.OutputAssemblyFullPath); } else if (pc is ReflectionProjectContent) { @@ -104,7 +145,66 @@ namespace ICSharpCode.FormsDesigner.Services Assembly asm; if (assemblyDict.TryGetValue(hash, out asm)) return asm; - asm = Assembly.Load(data); + try { + asm = Assembly.Load(data); + } catch (BadImageFormatException e) { + if (e.Message.Contains("HRESULT: 0x8013141D")) { + //netmodule + string tempPath = Path.GetTempFileName(); + File.Delete(tempPath); + tempPath += ".sd_forms_designer_netmodule_assembly.dll"; + + try { + //convert netmodule to assembly + Process p = new Process(); + p.StartInfo.UseShellExecute = false; + p.StartInfo.FileName = Path.GetDirectoryName(typeof(object).Module.FullyQualifiedName) + Path.DirectorySeparatorChar + "al.exe"; + p.StartInfo.Arguments = "\"" + fileName +"\" /out:\"" + tempPath + "\""; + p.StartInfo.CreateNoWindow = true; + p.Start(); + p.WaitForExit(); + + if(p.ExitCode == 0 && File.Exists(tempPath)) { + byte[] asm_data = File.ReadAllBytes(tempPath); + asm = Assembly.Load(asm_data); + asm.LoadModule(Path.GetFileName(fileName), data); + Type[] types = asm.GetTypes(); + } + } catch (Exception ex) { + MessageService.ShowError(ex, "Error calling linker for netmodule"); + } + try { + File.Delete(tempPath); + } catch {} + } else { + throw; // don't ignore other load errors + } + } catch (FileLoadException e) { + if (e.Message.Contains("HRESULT: 0x80131402")) { + //this is C++/CLI Mixed assembly which can only be loaded from disk, not in-memory + string tempPath = Path.GetTempFileName(); + File.Delete(tempPath); + tempPath += ".sd_forms_designer_mixed_assembly.dll"; + File.Copy(fileName, tempPath); + + /* We don't need to debug controls inside the forms designer + string pdbpath = Path.GetDirectoryName(fileName) + Path.DirectorySeparatorChar + Path.GetFileNameWithoutExtension(fileName) + ".pdb"; + if (File.Exists(pdbpath)) { + string newpdbpath = Path.GetTempPath() + Path.DirectorySeparatorChar + Path.GetFileName(pdbpath); + try { + File.Copy(pdbpath, newpdbpath); + MarkFileToDeleteOnReboot(newpdbpath); + } catch { + } + } + */ + asm = Assembly.LoadFile(tempPath); + MarkFileToDeleteOnReboot(tempPath); + } else { + throw; // don't ignore other load errors + } + } + lock (designerAssemblies) { if (!designerAssemblies.Contains(asm)) designerAssemblies.Add(asm); diff --git a/src/Libraries/NRefactory/Project/NRefactory.csproj b/src/Libraries/NRefactory/Project/NRefactory.csproj index aa458e48ae..a3820a3983 100644 --- a/src/Libraries/NRefactory/Project/NRefactory.csproj +++ b/src/Libraries/NRefactory/Project/NRefactory.csproj @@ -204,6 +204,7 @@ + diff --git a/src/Libraries/NRefactory/Project/Src/Output/CodeDOM/CodeDOMOutputVisitor.cs b/src/Libraries/NRefactory/Project/Src/Output/CodeDOM/CodeDOMOutputVisitor.cs index ead8d1df25..65f9f57517 100644 --- a/src/Libraries/NRefactory/Project/Src/Output/CodeDOM/CodeDOMOutputVisitor.cs +++ b/src/Libraries/NRefactory/Project/Src/Output/CodeDOM/CodeDOMOutputVisitor.cs @@ -13,6 +13,7 @@ using System.Collections; using System.Collections.Generic; using ICSharpCode.NRefactory.Parser.AST; +using ICSharpCode.NRefactory.PrettyPrinter; namespace ICSharpCode.NRefactory.Parser { @@ -25,6 +26,17 @@ namespace ICSharpCode.NRefactory.Parser TypeDeclaration currentTypeDeclaration = null; + IEnvironmentInformationProvider environmentInformationProvider = new DummyEnvironmentInformationProvider(); + + public IEnvironmentInformationProvider EnvironmentInformationProvider { + get { + return environmentInformationProvider; + } + set { + environmentInformationProvider = value; + } + } + // dummy collection used to swallow statements CodeStatementCollection NullStmtCollection = new CodeStatementCollection(); @@ -821,11 +833,8 @@ namespace ICSharpCode.NRefactory.Parser bool IsField(string type, string fieldName) { - Type t = null; - - t = this.GetType(type); // search in all currently loaded assemblies + bool isField = environmentInformationProvider.HasField(type, fieldName); - bool isField = t != null && (t.IsEnum || t.GetField(fieldName) != null); if (!isField) { int idx = type.LastIndexOf('.'); if (idx >= 0) { @@ -970,48 +979,6 @@ namespace ICSharpCode.NRefactory.Parser return list; } - //copy from TypeResolutionService.cs because from this point impossible to access TypeResolutionService - //TODO create universal way for getting types - public Type GetType(string name) - { - bool throwOnError = false; - bool ignoreCase = false; - if (name == null || name.Length == 0) { - return null; - } - Assembly lastAssembly = null; - foreach (Assembly asm in AppDomain.CurrentDomain.GetAssemblies()) { - Type t = asm.GetType(name, throwOnError); - if (t != null) { - lastAssembly = asm; - } - } - if (lastAssembly != null) { - return lastAssembly.GetType(name, throwOnError, ignoreCase); - } - - Type type = Type.GetType(name, throwOnError, ignoreCase); - - // type lookup for typename, assembly, xyz style lookups - if (type == null) { - int idx = name.IndexOf(","); - if (idx > 0) { - string[] splitName = name.Split(','); - string typeName = splitName[0]; - string assemblyName = splitName[1].Substring(1); - Assembly assembly = null; - try { - assembly = Assembly.Load(assemblyName); - } catch (Exception) {} - if (assembly != null) { - type = assembly.GetType(typeName, throwOnError, ignoreCase); - } else { - type = Type.GetType(typeName, throwOnError, ignoreCase); - } - } - } - - return type; - } + } } diff --git a/src/Libraries/NRefactory/Project/Src/Output/EnvironmentInformationProvider.cs b/src/Libraries/NRefactory/Project/Src/Output/EnvironmentInformationProvider.cs new file mode 100644 index 0000000000..7f3ca24591 --- /dev/null +++ b/src/Libraries/NRefactory/Project/Src/Output/EnvironmentInformationProvider.cs @@ -0,0 +1,31 @@ +// +// +// +// +// $Revision$ +// + +using System; +using System.Text; +using System.Collections; +using System.Diagnostics; + +using ICSharpCode.NRefactory.Parser; +using ICSharpCode.NRefactory.Parser.CSharp; +using ICSharpCode.NRefactory.Parser.AST; + +namespace ICSharpCode.NRefactory.PrettyPrinter +{ + public interface IEnvironmentInformationProvider + { + bool HasField(string fullTypeName, string fieldName); + } + + class DummyEnvironmentInformationProvider : IEnvironmentInformationProvider + { + public bool HasField(string fullTypeName, string fieldName) + { + return false; + } + } +} diff --git a/src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj b/src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj index 3d12310be2..32bc838bad 100644 --- a/src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj +++ b/src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj @@ -741,6 +741,7 @@ + diff --git a/src/Main/Base/Project/Src/Dom/NRefactoryResolver/NRefactoryInformationProvider.cs b/src/Main/Base/Project/Src/Dom/NRefactoryResolver/NRefactoryInformationProvider.cs new file mode 100644 index 0000000000..180eab73e6 --- /dev/null +++ b/src/Main/Base/Project/Src/Dom/NRefactoryResolver/NRefactoryInformationProvider.cs @@ -0,0 +1,43 @@ +// +// +// +// +// $Revision$ +// + +using System; +using System.Collections; +using System.Collections.Generic; + +using ICSharpCode.NRefactory.Parser; +using ICSharpCode.NRefactory.PrettyPrinter; + +using ICSharpCode.SharpDevelop.Dom; +using ICSharpCode.Core; + +namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver +{ + public class NRefactoryInformationProvider : IEnvironmentInformationProvider + { + IProjectContent pc; + IClass callingClass; + + public NRefactoryInformationProvider(IProjectContent pc, IClass callingClass) + { + this.pc = pc; + this.callingClass = callingClass; + } + + public bool HasField(string fullTypeName, string fieldName) + { + IClass c = pc.GetClass(fullTypeName); + if (c == null) + return false; + foreach (IField field in c.DefaultReturnType.GetFields()) { + if (field.Name == fieldName) + return true; + } + return false; + } + } +} diff --git a/src/Main/Base/Project/Src/Project/AbstractProject.cs b/src/Main/Base/Project/Src/Project/AbstractProject.cs index 45e1c9d2c8..0a23be0616 100644 --- a/src/Main/Base/Project/Src/Project/AbstractProject.cs +++ b/src/Main/Base/Project/Src/Project/AbstractProject.cs @@ -293,6 +293,8 @@ namespace ICSharpCode.SharpDevelop.Project case OutputType.WinExe: case OutputType.Exe: return ".exe"; + case OutputType.Module: + return ".netmodule"; default: return ".dll"; }