Browse Source

Fixed SD2-636: NRefactory -> CodeDom converter might not work on first try.

Applied assembly loading patch by Alex Prudkiy.

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@971 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
Daniel Grunwald 20 years ago
parent
commit
21de318a25
  1. 1
      src/AddIns/DisplayBindings/FormsDesigner/Project/Src/DesignerLoader/NRefactoryDesignerLoader.cs
  2. 102
      src/AddIns/DisplayBindings/FormsDesigner/Project/Src/Services/TypeResolutionService.cs
  3. 1
      src/Libraries/NRefactory/Project/NRefactory.csproj
  4. 61
      src/Libraries/NRefactory/Project/Src/Output/CodeDOM/CodeDOMOutputVisitor.cs
  5. 31
      src/Libraries/NRefactory/Project/Src/Output/EnvironmentInformationProvider.cs
  6. 1
      src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj
  7. 43
      src/Main/Base/Project/Src/Dom/NRefactoryResolver/NRefactoryInformationProvider.cs
  8. 2
      src/Main/Base/Project/Src/Project/AbstractProject.cs

1
src/AddIns/DisplayBindings/FormsDesigner/Project/Src/DesignerLoader/NRefactoryDesignerLoader.cs

@ -223,6 +223,7 @@ namespace ICSharpCode.FormsDesigner @@ -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 :

102
src/AddIns/DisplayBindings/FormsDesigner/Project/Src/Services/TypeResolutionService.cs

@ -16,6 +16,9 @@ using System.ComponentModel.Design; @@ -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 @@ -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 @@ -79,6 +110,16 @@ namespace ICSharpCode.FormsDesigner.Services
/// </summary>
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 @@ -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);

1
src/Libraries/NRefactory/Project/NRefactory.csproj

@ -204,6 +204,7 @@ @@ -204,6 +204,7 @@
<Compile Include="Src\Parser\Visitors\CSharpConstructsVisitor.cs" />
<Compile Include="Src\Parser\Visitors\ToCSharpConvertVisitor.cs" />
<Compile Include="Src\Parser\Visitors\ToVBNetConvertVisitor.cs" />
<Compile Include="Src\Output\EnvironmentInformationProvider.cs" />
</ItemGroup>
<ItemGroup>
<Content Include="Src\Lexer\CSharp\KeywordList.txt" />

61
src/Libraries/NRefactory/Project/Src/Output/CodeDOM/CodeDOMOutputVisitor.cs

@ -13,6 +13,7 @@ using System.Collections; @@ -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 @@ -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 @@ -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 @@ -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;
}
}
}

31
src/Libraries/NRefactory/Project/Src/Output/EnvironmentInformationProvider.cs

@ -0,0 +1,31 @@ @@ -0,0 +1,31 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
// <version>$Revision$</version>
// </file>
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;
}
}
}

1
src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj

@ -741,6 +741,7 @@ @@ -741,6 +741,7 @@
<Compile Include="Src\Gui\Pads\ProjectBrowser\TreeNodes\WebReferenceNode.cs" />
<Compile Include="Src\Gui\Dialogs\ReferenceDialog\WebReferenceChanges.cs" />
<Compile Include="Src\TextEditor\Commands\CodeGenerators\CodeGenerationForm.cs" />
<Compile Include="Src\Dom\NRefactoryResolver\NRefactoryInformationProvider.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\Libraries\DockPanel_Src\WinFormsUI\WinFormsUI.csproj">

43
src/Main/Base/Project/Src/Dom/NRefactoryResolver/NRefactoryInformationProvider.cs

@ -0,0 +1,43 @@ @@ -0,0 +1,43 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
// <version>$Revision$</version>
// </file>
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;
}
}
}

2
src/Main/Base/Project/Src/Project/AbstractProject.cs

@ -293,6 +293,8 @@ namespace ICSharpCode.SharpDevelop.Project @@ -293,6 +293,8 @@ namespace ICSharpCode.SharpDevelop.Project
case OutputType.WinExe:
case OutputType.Exe:
return ".exe";
case OutputType.Module:
return ".netmodule";
default:
return ".dll";
}

Loading…
Cancel
Save