31 changed files with 1141 additions and 197 deletions
@ -0,0 +1,93 @@
@@ -0,0 +1,93 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
using System.IO; |
||||
using System.Linq; |
||||
using System.Text; |
||||
using System.Threading; |
||||
using System.Windows.Media.Animation; |
||||
using ICSharpCode.Core; |
||||
using ICSharpCode.Core.Presentation; |
||||
using ICSharpCode.NRefactory; |
||||
using ICSharpCode.NRefactory.CSharp; |
||||
using ICSharpCode.NRefactory.CSharp.Refactoring; |
||||
using ICSharpCode.NRefactory.CSharp.Resolver; |
||||
using ICSharpCode.NRefactory.CSharp.TypeSystem; |
||||
using ICSharpCode.NRefactory.Editor; |
||||
using ICSharpCode.NRefactory.TypeSystem; |
||||
using ICSharpCode.SharpDevelop; |
||||
using ICSharpCode.SharpDevelop.Dom; |
||||
using ICSharpCode.SharpDevelop.Editor; |
||||
using ICSharpCode.SharpDevelop.Project; |
||||
using ICSharpCode.SharpDevelop.Refactoring; |
||||
|
||||
namespace CSharpBinding.Refactoring |
||||
{ |
||||
/// <summary>
|
||||
/// Description of CSharpCodeGenerator.
|
||||
/// </summary>
|
||||
public class CSharpCodeGenerator : ICodeGenerator |
||||
{ |
||||
CSharpProject project; |
||||
ProjectEntityModelContext model; |
||||
|
||||
public CSharpCodeGenerator(CSharpProject project) |
||||
{ |
||||
if (project == null) |
||||
throw new ArgumentNullException("project"); |
||||
this.project = project; |
||||
this.model = new ProjectEntityModelContext(project, ".cs"); |
||||
} |
||||
|
||||
public void AddAttribute(IEntity target, IAttribute attribute) |
||||
{ |
||||
var view = SD.FileService.OpenFile(new FileName(target.Region.FileName), false); |
||||
var editor = view.GetRequiredService<ITextEditor>(); |
||||
var context = SDRefactoringContext.Create(editor, CancellationToken.None); |
||||
var node = context.RootNode.GetNodeAt<EntityDeclaration>(target.Region.Begin); |
||||
var resolver = context.GetResolverStateBefore(node); |
||||
var builder = new TypeSystemAstBuilder(resolver); |
||||
|
||||
editor.Document.Insert(editor.Document.GetOffset(target.BodyRegion.Begin), |
||||
PrintAst(builder.ConvertAttribute(attribute))); |
||||
} |
||||
|
||||
public void InsertEventHandler(ITypeDefinition target, string name, IEvent eventDefinition, bool jumpTo) |
||||
{ |
||||
IUnresolvedTypeDefinition match = null; |
||||
|
||||
foreach (var part in target.Parts) { |
||||
string fileName = part.UnresolvedFile.FileName; |
||||
if (!".cs".Equals(Path.GetExtension(fileName), StringComparison.OrdinalIgnoreCase)) |
||||
continue; |
||||
if (match == null || model.IsBetterPart(part, match)) |
||||
match = part; |
||||
} |
||||
|
||||
if (match == null) return; |
||||
|
||||
var view = SD.FileService.OpenFile(new FileName(match.Region.FileName), jumpTo); |
||||
var editor = view.GetRequiredService<ITextEditor>(); |
||||
var context = SDRefactoringContext.Create(editor, CancellationToken.None); |
||||
|
||||
IEntity last = (IEntity)target.GetMembers().LastOrDefault() ?? (IEntity)target; |
||||
var node = context.RootNode.GetNodeAt<EntityDeclaration>(last.Region.Begin); |
||||
var resolver = context.GetResolverStateAfter(node); |
||||
var builder = new TypeSystemAstBuilder(resolver); |
||||
|
||||
#warning implement code generation!
|
||||
string eventHandler = "<generated code>"; |
||||
|
||||
editor.Document.Insert(editor.Document.GetOffset(target.Region.End), eventHandler); |
||||
} |
||||
|
||||
string PrintAst(AstNode node) |
||||
{ |
||||
StringBuilder sb = new StringBuilder(); |
||||
CSharpOutputVisitor visitor = new CSharpOutputVisitor(new StringWriter(sb), FormattingOptionsFactory.CreateSharpDevelop()); |
||||
node.AcceptVisitor(visitor); |
||||
return sb.ToString(); |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,135 @@
@@ -0,0 +1,135 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Linq; |
||||
using System.IO; |
||||
using System.Text; |
||||
using System.Threading; |
||||
using System.Threading.Tasks; |
||||
using ICSharpCode.AvalonEdit.Document; |
||||
using ICSharpCode.NRefactory.CSharp; |
||||
using ICSharpCode.NRefactory.CSharp.Refactoring; |
||||
using ICSharpCode.NRefactory.Editor; |
||||
using ICSharpCode.NRefactory.Semantics; |
||||
using ICSharpCode.NRefactory.TypeSystem; |
||||
using ICSharpCode.NRefactory.TypeSystem.Implementation; |
||||
using ICSharpCode.SharpDevelop; |
||||
using ICSharpCode.SharpDevelop.Parser; |
||||
using ICSharpCode.SharpDevelop.Project; |
||||
using ICSharpCode.SharpDevelop.Refactoring; |
||||
using CSharpBinding.Parser; |
||||
|
||||
namespace CSharpBinding.Refactoring |
||||
{ |
||||
[ContextAction("Move type to file", Description = "Moves a selected type into a new file matching the type name.")] |
||||
public class MoveTypeToFileContextAction : ContextAction |
||||
{ |
||||
public override async Task<bool> IsAvailableAsync(EditorRefactoringContext context, CancellationToken cancellationToken) |
||||
{ |
||||
SyntaxTree st = await context.GetSyntaxTreeAsync().ConfigureAwait(false); |
||||
Identifier identifier = (Identifier)st.GetNodeAt(context.CaretLocation, node => node.Role == Roles.Identifier); |
||||
if (identifier == null) return false; |
||||
if (MakeValidFileName(identifier.Name).Equals(Path.GetFileNameWithoutExtension(context.FileName), StringComparison.OrdinalIgnoreCase)) |
||||
return false; |
||||
if (identifier.Parent.Parent is TypeDeclaration) |
||||
return false; |
||||
ParseInformation info = await context.GetParseInformationAsync().ConfigureAwait(false); |
||||
if (info.UnresolvedFile.TopLevelTypeDefinitions.Count == 1) |
||||
return false; |
||||
return identifier.Parent is TypeDeclaration || identifier.Parent is DelegateDeclaration; |
||||
} |
||||
|
||||
public override async void Execute(EditorRefactoringContext context) |
||||
{ |
||||
SyntaxTree st = await context.GetSyntaxTreeAsync().ConfigureAwait(false); |
||||
ICompilation compilation = await context.GetCompilationAsync().ConfigureAwait(false); |
||||
CSharpFullParseInformation info = await context.GetParseInformationAsync().ConfigureAwait(false) as CSharpFullParseInformation; |
||||
EntityDeclaration node = (EntityDeclaration)st.GetNodeAt(context.CaretLocation, n => n is TypeDeclaration || n is DelegateDeclaration); |
||||
IDocument document = context.Editor.Document; |
||||
|
||||
string newFileName = Path.Combine(Path.GetDirectoryName(context.FileName), MakeValidFileName(node.Name)); |
||||
string header = CopyFileHeader(document, info); |
||||
string footer = CopyFileEnd(document, info); |
||||
|
||||
AstNode newNode = node.Clone(); |
||||
|
||||
foreach (var ns in node.Ancestors.OfType<NamespaceDeclaration>()) { |
||||
var newNS = new NamespaceDeclaration(ns.Name); |
||||
newNS.Members.AddRange(ns.Children.Where(ch => ch is UsingDeclaration |
||||
|| ch is UsingAliasDeclaration |
||||
|| ch is ExternAliasDeclaration).Select(usingDecl => usingDecl.Clone())); |
||||
newNS.AddMember(newNode); |
||||
newNode = newNS; |
||||
} |
||||
|
||||
var topLevelUsings = st.Children.Where(ch => ch is UsingDeclaration |
||||
|| ch is UsingAliasDeclaration |
||||
|| ch is ExternAliasDeclaration); |
||||
StringBuilder newCode = new StringBuilder(header); |
||||
CSharpOutputVisitor visitor = new CSharpOutputVisitor(new StringWriter(newCode), FormattingOptionsFactory.CreateSharpDevelop()); |
||||
|
||||
foreach (var topLevelUsing in topLevelUsings) |
||||
topLevelUsing.AcceptVisitor(visitor); |
||||
|
||||
newNode.AcceptVisitor(visitor); |
||||
|
||||
newCode.AppendLine(footer); |
||||
|
||||
IViewContent viewContent = FileService.NewFile(newFileName, newCode.ToString()); |
||||
viewContent.PrimaryFile.SaveToDisk(newFileName); |
||||
// now that the code is saved in the other file, remove it from the original document
|
||||
RemoveExtractedNode(); |
||||
|
||||
IProject project = (IProject)compilation.GetProject(); |
||||
if (project != null) { |
||||
FileProjectItem projectItem = new FileProjectItem(project, ItemType.Compile); |
||||
projectItem.FileName = newFileName; |
||||
ProjectService.AddProjectItem(project, projectItem); |
||||
FileService.FireFileCreated(newFileName, false); |
||||
project.Save(); |
||||
ProjectBrowserPad.RefreshViewAsync(); |
||||
} |
||||
} |
||||
|
||||
void RemoveExtractedNode() |
||||
{ |
||||
//throw new NotImplementedException();
|
||||
} |
||||
|
||||
string CopyFileHeader(IDocument document, CSharpFullParseInformation info) |
||||
{ |
||||
var lastHeadNode = info.SyntaxTree.Children |
||||
.TakeWhile(node => node.NodeType == NodeType.Whitespace && (!(node is Comment) || !((Comment)node).IsDocumentation)) |
||||
.LastOrDefault(); |
||||
if (lastHeadNode == null) |
||||
return ""; |
||||
return document.GetText(0, document.GetOffset(lastHeadNode.EndLocation)); |
||||
} |
||||
|
||||
string CopyFileEnd(IDocument document, CSharpFullParseInformation info) |
||||
{ |
||||
var firstFootNode = info.SyntaxTree.Children.Reverse() |
||||
.TakeWhile(node => node.NodeType == NodeType.Whitespace && (!(node is Comment) || !((Comment)node).IsDocumentation)) |
||||
.LastOrDefault(); |
||||
if (firstFootNode == null) |
||||
return ""; |
||||
int offset = document.GetOffset(firstFootNode.StartLocation); |
||||
return document.GetText(offset, document.TextLength - offset); |
||||
} |
||||
|
||||
string MakeValidFileName(string name) |
||||
{ |
||||
if (name == null) |
||||
throw new ArgumentNullException("name"); |
||||
if (name.IndexOfAny(Path.GetInvalidFileNameChars()) > -1) |
||||
return name.RemoveAny(Path.GetInvalidFileNameChars()) + ".cs"; |
||||
return name + ".cs"; |
||||
} |
||||
|
||||
public override string DisplayName { |
||||
get { return "Move type to file"; } |
||||
} |
||||
} |
||||
} |
||||
@ -1,42 +0,0 @@
@@ -1,42 +0,0 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
using ICSharpCode.SharpDevelop; |
||||
using ICSharpCode.SharpDevelop.Dom; |
||||
using ICSharpCode.SharpDevelop.Editor; |
||||
|
||||
namespace ICSharpCode.WpfDesign.AddIn |
||||
{ |
||||
sealed class CSharpEventHandlerService : AbstractEventHandlerService |
||||
{ |
||||
public CSharpEventHandlerService(WpfViewContent viewContent) : base(viewContent) |
||||
{ |
||||
} |
||||
|
||||
protected override void CreateEventHandlerInternal(Type eventHandlerType, string handlerName) |
||||
{ |
||||
IClass c = GetDesignedClass(); |
||||
if (c != null) { |
||||
foreach (IMethod m in c.Methods) { |
||||
if (m.Name == handlerName) { |
||||
FileService.JumpToFilePosition(m.DeclaringType.CompilationUnit.FileName, |
||||
m.Region.BeginLine, m.Region.BeginColumn); |
||||
return; |
||||
} |
||||
} |
||||
} |
||||
c = GetDesignedClassCodeBehindPart(c); |
||||
if (c != null) { |
||||
ITextEditorProvider tecp = FileService.OpenFile(c.CompilationUnit.FileName) as ITextEditorProvider; |
||||
if (tecp != null) { |
||||
int lineNumber; |
||||
FormsDesigner.CSharpDesignerGenerator.CreateComponentEvent( |
||||
c, tecp.TextEditor, eventHandlerType, handlerName, null, |
||||
out lineNumber); |
||||
tecp.TextEditor.JumpTo(lineNumber, 0); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,18 @@
@@ -0,0 +1,18 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
using System.ComponentModel.Design; |
||||
using System.Reflection; |
||||
using ICSharpCode.SharpDevelop.Project; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.Designer |
||||
{ |
||||
/// <summary>
|
||||
/// Description of IDesignerTypeResolutionService.
|
||||
/// </summary>
|
||||
public interface IDesignerTypeResolutionService : ITypeResolutionService |
||||
{ |
||||
Assembly LoadAssembly(IProject pc); |
||||
} |
||||
} |
||||
@ -0,0 +1,576 @@
@@ -0,0 +1,576 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.ComponentModel.Design; |
||||
using System.Diagnostics; |
||||
using System.IO; |
||||
using System.Linq; |
||||
using System.Reflection; |
||||
using System.Windows.Documents; |
||||
using ICSharpCode.Core; |
||||
using ICSharpCode.NRefactory.TypeSystem; |
||||
using ICSharpCode.SharpDevelop; |
||||
using ICSharpCode.SharpDevelop.Gui; |
||||
using ICSharpCode.SharpDevelop.Gui.XmlForms; |
||||
using ICSharpCode.SharpDevelop.Project; |
||||
using Microsoft.Win32; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.Designer |
||||
{ |
||||
public class TypeResolutionService : IDesignerTypeResolutionService |
||||
{ |
||||
readonly static List<Assembly> designerAssemblies = new List<Assembly>(); |
||||
// hash of file content -> Assembly
|
||||
readonly static Dictionary<string, Assembly> assemblyDict = new Dictionary<string, Assembly>(); |
||||
|
||||
/// <summary>
|
||||
/// List of assemblies used by the form designer. This static list is not an optimal solution,
|
||||
/// but better than using AppDomain.CurrentDomain.GetAssemblies(). See SD2-630.
|
||||
/// </summary>
|
||||
public static List<Assembly> DesignerAssemblies { |
||||
get { |
||||
return designerAssemblies; |
||||
} |
||||
} |
||||
|
||||
static TypeResolutionService() |
||||
{ |
||||
ClearMixedAssembliesTemporaryFiles(); |
||||
DesignerAssemblies.Add(typeof(object).Assembly); |
||||
DesignerAssemblies.Add(typeof(Uri).Assembly); |
||||
DesignerAssemblies.Add(typeof(System.Drawing.Point).Assembly); |
||||
DesignerAssemblies.Add(typeof(System.Windows.Forms.Design.AnchorEditor).Assembly); |
||||
RegisterVSDesignerWorkaround(); |
||||
AppDomain.CurrentDomain.AssemblyResolve += AssemblyResolveEventHandler; |
||||
|
||||
} |
||||
|
||||
[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; |
||||
IProject callingProject; |
||||
/// <summary>
|
||||
/// Dictionary of file name -> hash of loaded assemblies for the currently designed document.
|
||||
/// Used to detect changes in references assemblies.
|
||||
/// </summary>
|
||||
readonly Dictionary<string, string> loadedAssembliesForCurrentDocument = new Dictionary<string, string>(StringComparer.Ordinal); |
||||
|
||||
/// <summary>
|
||||
/// Gets the project content of the project that created this TypeResolutionService.
|
||||
/// Returns null when no calling project was specified.
|
||||
/// </summary>
|
||||
public IProject CallingProject { |
||||
get { |
||||
if (formSourceFileName != null) { |
||||
if (ProjectService.OpenSolution != null) { |
||||
return ProjectService.OpenSolution.FindProjectContainingFile(formSourceFileName); |
||||
} |
||||
formSourceFileName = null; |
||||
} |
||||
return callingProject; |
||||
} |
||||
} |
||||
|
||||
public TypeResolutionService() |
||||
{ |
||||
} |
||||
|
||||
public TypeResolutionService(string formSourceFileName) |
||||
{ |
||||
this.formSourceFileName = formSourceFileName; |
||||
} |
||||
|
||||
readonly HashSet<IProject> projectContentsCurrentlyLoadingAssembly = new HashSet<IProject>(); |
||||
|
||||
/// <summary>
|
||||
/// Loads the assembly represented by the project content. Returns null on failure.
|
||||
/// </summary>
|
||||
public Assembly LoadAssembly(IProject pc) |
||||
{ |
||||
SD.MainThread.VerifyAccess(); |
||||
// prevent StackOverflow when project contents have cyclic dependencies
|
||||
// Very popular example of cyclic dependency: System <-> System.Xml
|
||||
if (!projectContentsCurrentlyLoadingAssembly.Add(pc)) |
||||
return null; |
||||
|
||||
Assembly sdAssembly; |
||||
if (IsSharpDevelopAssembly(pc.ProjectContent, out sdAssembly)) |
||||
return sdAssembly; |
||||
|
||||
ICompilation compilation = SD.ParserService.GetCompilation(pc); |
||||
|
||||
try { |
||||
// load dependencies of current assembly
|
||||
foreach (IAssembly asm in compilation.ReferencedAssemblies) { |
||||
LoadAssembly(asm); |
||||
} |
||||
} finally { |
||||
projectContentsCurrentlyLoadingAssembly.Remove(pc); |
||||
} |
||||
|
||||
return LoadAssembly(pc.OutputAssemblyFullPath); |
||||
} |
||||
|
||||
public Assembly LoadAssembly(IAssembly asm) |
||||
{ |
||||
var project = asm.GetProject(); |
||||
if (project != null) |
||||
return LoadAssembly(project); |
||||
if (asm.IsGacAssembly()) |
||||
return LoadAssembly(new AssemblyName(asm.FullAssemblyName), false); |
||||
return LoadAssembly(asm.GetRuntimeAssemblyLocation()); |
||||
} |
||||
|
||||
readonly string sharpDevelopRoot = Directory.GetParent(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location)).FullName; |
||||
|
||||
bool IsSharpDevelopAssembly(IUnresolvedAssembly pc, out Assembly assembly) |
||||
{ |
||||
assembly = null; |
||||
foreach (var asm in AppDomain.CurrentDomain.GetAssemblies()) { |
||||
if (!asm.IsDynamic && asm.Location.StartsWith(sharpDevelopRoot, StringComparison.OrdinalIgnoreCase) && pc.AssemblyName == asm.GetName().Name) { |
||||
assembly = asm; |
||||
return true; |
||||
} |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
static string GetHash(string fileName) |
||||
{ |
||||
return Path.GetFileName(fileName).ToLowerInvariant() + File.GetLastWriteTimeUtc(fileName).Ticks.ToString(); |
||||
} |
||||
|
||||
static string GetOriginalAssemblyFullPath(Assembly asm) |
||||
{ |
||||
if (asm == null) throw new ArgumentNullException("asm"); |
||||
try { |
||||
return new Uri(asm.CodeBase, UriKind.Absolute).LocalPath; |
||||
} catch (UriFormatException ex) { |
||||
LoggingService.Warn("Could not determine path for assembly '" + asm.ToString() + "', CodeBase='" + asm.CodeBase + "': " + ex.Message); |
||||
return asm.Location; |
||||
} catch (InvalidOperationException ex) { |
||||
LoggingService.Warn("Could not determine path for assembly '" + asm.ToString() + "', CodeBase='" + asm.CodeBase + "': " + ex.Message); |
||||
return asm.Location; |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Loads the file in none-locking mode. Returns null on failure.
|
||||
/// </summary>
|
||||
public Assembly LoadAssembly(string fileName) |
||||
{ |
||||
if (!File.Exists(fileName)) |
||||
return null; |
||||
|
||||
// FIX for SD2-716, remove when designer gets its own AppDomain
|
||||
foreach (Assembly asm in AppDomain.CurrentDomain.GetAssemblies()) { |
||||
try { |
||||
if (string.Equals(GetOriginalAssemblyFullPath(asm), fileName, StringComparison.OrdinalIgnoreCase)) { |
||||
RegisterAssembly(asm); |
||||
return asm; |
||||
} |
||||
} catch (NotSupportedException) { |
||||
// Fixes forum-12823
|
||||
} |
||||
} |
||||
|
||||
string hash = GetHash(fileName); |
||||
lock (assemblyDict) { |
||||
Assembly asm; |
||||
if (assemblyDict.TryGetValue(hash, out asm)) |
||||
return asm; |
||||
LoggingService.Debug("Loading assembly " + fileName + " (hash " + hash + ")"); |
||||
try { |
||||
asm = Assembly.Load(File.ReadAllBytes(fileName)); |
||||
} catch (BadImageFormatException e) { |
||||
if (e.Message.Contains("HRESULT: 0x8013141D")) { |
||||
LoggingService.Debug("Get HRESULt 0x8013141D, loading netmodule"); |
||||
//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), File.ReadAllBytes(fileName)); |
||||
} |
||||
} catch (Exception ex) { |
||||
MessageService.ShowException(ex, "Error calling linker for netmodule"); |
||||
} |
||||
try { |
||||
File.Delete(tempPath); |
||||
} catch {} |
||||
} else { |
||||
// Show other load errors in the compiler message view,
|
||||
// but do not prevent the designer from loading.
|
||||
// The error might be caused by an assembly that is
|
||||
// not even needed for the designer to load.
|
||||
LoggingService.Error("Error loading assembly " + fileName, e); |
||||
WorkbenchSingleton.Workbench.GetPad(typeof(CompilerMessageView)).BringPadToFront(); |
||||
TaskService.BuildMessageViewCategory.AppendText( |
||||
StringParser.Parse("${res:FileUtilityService.ErrorWhileLoading}") |
||||
+ "\r\n" + fileName + "\r\n" + e.Message + "\r\n" |
||||
); |
||||
return null; |
||||
} |
||||
} catch (FileLoadException e) { |
||||
if (e.Message.Contains("HRESULT: 0x80131402")) { |
||||
LoggingService.Debug("Get HRESULt 0x80131402, loading mixed modes asm from disk"); |
||||
//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 if (e.Message.Contains("HRESULT: 0x80131019")) { |
||||
LoggingService.Debug(e.Message); |
||||
LoggingService.Debug("Attempting to load unverifiable assembly. Ignoring."); |
||||
return null; |
||||
} else { |
||||
throw; // don't ignore other load errors
|
||||
} |
||||
} |
||||
|
||||
lock (designerAssemblies) { |
||||
if (!designerAssemblies.Contains(asm)) |
||||
designerAssemblies.Insert(0, asm); |
||||
} |
||||
lock (this.loadedAssembliesForCurrentDocument) { |
||||
this.loadedAssembliesForCurrentDocument[fileName] = hash; |
||||
} |
||||
assemblyDict[hash] = asm; |
||||
return asm; |
||||
} |
||||
} |
||||
|
||||
void RegisterAssembly(Assembly asm) |
||||
{ |
||||
string file = GetOriginalAssemblyFullPath(asm); |
||||
if (!String.IsNullOrEmpty(file)) { |
||||
string hash = GetHash(file); |
||||
lock (assemblyDict) { |
||||
assemblyDict[hash] = asm; |
||||
} |
||||
lock (this.loadedAssembliesForCurrentDocument) { |
||||
this.loadedAssembliesForCurrentDocument[file] = hash; |
||||
} |
||||
} |
||||
lock (designerAssemblies) { |
||||
if (!designerAssemblies.Contains(asm)) |
||||
designerAssemblies.Insert(0, asm); |
||||
} |
||||
} |
||||
|
||||
public Assembly GetAssembly(AssemblyName name) |
||||
{ |
||||
return LoadAssembly(name, false); |
||||
} |
||||
|
||||
public Assembly GetAssembly(AssemblyName name, bool throwOnError) |
||||
{ |
||||
return LoadAssembly(name, throwOnError); |
||||
} |
||||
|
||||
Assembly LoadAssembly(AssemblyName name, bool throwOnError) |
||||
{ |
||||
try { |
||||
Assembly asm = Assembly.Load(name); |
||||
RegisterAssembly(asm); |
||||
return asm; |
||||
} catch (System.IO.FileLoadException) { |
||||
if (throwOnError) |
||||
throw; |
||||
return null; |
||||
} |
||||
} |
||||
|
||||
public string GetPathOfAssembly(AssemblyName name) |
||||
{ |
||||
Assembly assembly = GetAssembly(name); |
||||
if (assembly != null) { |
||||
return GetOriginalAssemblyFullPath(assembly); |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
public Type GetType(string name) |
||||
{ |
||||
return GetType(name, false, false); |
||||
} |
||||
|
||||
public Type GetType(string name, bool throwOnError) |
||||
{ |
||||
return GetType(name, throwOnError, false); |
||||
} |
||||
|
||||
#if DEBUG
|
||||
int count = 0; |
||||
#endif
|
||||
|
||||
Dictionary<string, Type> typeCache = new Dictionary<string, Type>(StringComparer.Ordinal); |
||||
Dictionary<string, Type> typeCacheIgnoreCase = new Dictionary<string, Type>(StringComparer.OrdinalIgnoreCase); |
||||
|
||||
public void ClearCaches() |
||||
{ |
||||
typeCacheIgnoreCase.Clear(); |
||||
typeCache.Clear(); |
||||
} |
||||
|
||||
public Type GetType(string name, bool throwOnError, bool ignoreCase) |
||||
{ |
||||
if (string.IsNullOrEmpty(name)) { |
||||
return null; |
||||
} |
||||
if (IgnoreType(name)) { |
||||
return null; |
||||
} |
||||
if (ignoreCase) { |
||||
Type cachedType; |
||||
if (typeCacheIgnoreCase.TryGetValue(name, out cachedType)) |
||||
return cachedType; |
||||
} else { |
||||
Type cachedType; |
||||
if (typeCache.TryGetValue(name, out cachedType)) |
||||
return cachedType; |
||||
} |
||||
#if DEBUG
|
||||
if (!name.StartsWith("System.", StringComparison.Ordinal)) { |
||||
count++; |
||||
LoggingService.Debug(count + " TypeResolutionService: Looking for " + name); |
||||
} |
||||
#endif
|
||||
try { |
||||
|
||||
Type type = Type.GetType(name, false, ignoreCase); |
||||
|
||||
if (type == null) { |
||||
IProject p = CallingProject; |
||||
if (p != null) { |
||||
ICompilation compilation = SD.ParserService.GetCompilation(p); |
||||
ITypeDefinition definition = ReflectionHelper.ParseReflectionName(name) |
||||
.Resolve(compilation).GetDefinition(); |
||||
if (definition != null) { |
||||
Assembly assembly = LoadAssembly(definition.ParentAssembly); |
||||
if (assembly != null) { |
||||
type = assembly.GetType(name, false, ignoreCase); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
// type lookup for typename, assembly, xyz style lookups
|
||||
if (type == null) { |
||||
int idx = name.IndexOf(",", StringComparison.Ordinal); |
||||
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 e) { |
||||
LoggingService.Error(e); |
||||
} |
||||
if (assembly != null) { |
||||
string fileName = GetOriginalAssemblyFullPath(assembly); |
||||
if (!String.IsNullOrEmpty(fileName)) { |
||||
lock (loadedAssembliesForCurrentDocument) { |
||||
loadedAssembliesForCurrentDocument [fileName] = GetHash(fileName); |
||||
} |
||||
} |
||||
lock (designerAssemblies) { |
||||
if (!designerAssemblies.Contains(assembly)) |
||||
designerAssemblies.Add(assembly); |
||||
} |
||||
type = assembly.GetType(typeName, false, ignoreCase); |
||||
} else { |
||||
type = Type.GetType(typeName, false, ignoreCase); |
||||
} |
||||
} |
||||
} |
||||
|
||||
if (type == null) { |
||||
lock (designerAssemblies) { |
||||
foreach (Assembly asm in DesignerAssemblies) { |
||||
try { |
||||
Type t = asm.GetType(name, false); |
||||
if (t != null) { |
||||
AddToCache(name, t, ignoreCase); |
||||
return t; |
||||
} |
||||
} catch (FileNotFoundException) { |
||||
} catch (FileLoadException) { |
||||
} catch (BadImageFormatException) { |
||||
// ignore assembly load errors
|
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
if (throwOnError && type == null) |
||||
throw new TypeLoadException(name + " not found by TypeResolutionService"); |
||||
AddToCache(name, type, ignoreCase); |
||||
return type; |
||||
} catch (Exception e) { |
||||
LoggingService.Error(e); |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
void AddToCache(string name, Type type, bool ignoreCase) |
||||
{ |
||||
if (type == null) |
||||
return; |
||||
if (ignoreCase) { |
||||
typeCacheIgnoreCase.Add(name, type); |
||||
} else { |
||||
typeCache.Add(name, type); |
||||
} |
||||
} |
||||
|
||||
public void ReferenceAssembly(AssemblyName name) |
||||
{ |
||||
ICSharpCode.Core.LoggingService.Warn("TODO: Add Assembly reference : " + name); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets whether an assembly referenced by the currently designed document
|
||||
/// has been changed since it has been loaded.
|
||||
/// </summary>
|
||||
public bool ReferencedAssemblyChanged { |
||||
get { |
||||
return this.loadedAssembliesForCurrentDocument.Any( |
||||
pair => !File.Exists(pair.Key) || !String.Equals(pair.Value, GetHash(pair.Key), StringComparison.Ordinal) |
||||
); |
||||
} |
||||
} |
||||
|
||||
#region VSDesigner workarounds
|
||||
/// <summary>
|
||||
/// HACK - Ignore any requests for types from the Microsoft.VSDesigner
|
||||
/// assembly. There are smart tag problems if data adapter
|
||||
/// designers are used from this assembly.
|
||||
/// </summary>
|
||||
bool IgnoreType(string name) |
||||
{ |
||||
int idx = name.IndexOf(","); |
||||
if (idx > 0) { |
||||
string[] splitName = name.Split(','); |
||||
string assemblyName = splitName[1].Substring(1); |
||||
if (assemblyName == "Microsoft.VSDesigner") { |
||||
return true; |
||||
} |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
static string vsDesignerIdeDir; |
||||
|
||||
static void RegisterVSDesignerWorkaround() |
||||
{ |
||||
if (vsDesignerIdeDir == null) { |
||||
vsDesignerIdeDir = ""; |
||||
try { |
||||
using(RegistryKey key = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\VisualStudio\8.0\Setup\VS")) { |
||||
if (key != null) { |
||||
vsDesignerIdeDir = key.GetValue("VS7CommonDir") as string ?? ""; |
||||
} |
||||
} |
||||
} catch (System.Security.SecurityException) { |
||||
// registry access might be denied
|
||||
} |
||||
if (vsDesignerIdeDir.Length > 0) { |
||||
vsDesignerIdeDir = Path.Combine(vsDesignerIdeDir, "IDE"); |
||||
AppDomain.CurrentDomain.AssemblyResolve += delegate(object sender, ResolveEventArgs args) { |
||||
string shortName = args.Name; |
||||
if (shortName.IndexOf(',') >= 0) { |
||||
shortName = shortName.Substring(0, shortName.IndexOf(',')); |
||||
} |
||||
if (shortName.StartsWith("Microsoft.") |
||||
&& File.Exists(Path.Combine(vsDesignerIdeDir, shortName + ".dll"))) |
||||
{ |
||||
return Assembly.LoadFrom(Path.Combine(vsDesignerIdeDir, shortName + ".dll")); |
||||
} |
||||
return null; |
||||
}; |
||||
} |
||||
} |
||||
} |
||||
#endregion
|
||||
|
||||
static Assembly AssemblyResolveEventHandler(object sender, ResolveEventArgs args) |
||||
{ |
||||
LoggingService.Debug("TypeResolutionService: AssemblyResolveEventHandler: " + args.Name); |
||||
|
||||
Assembly lastAssembly = null; |
||||
|
||||
foreach (Assembly asm in TypeResolutionService.DesignerAssemblies) { |
||||
if (asm.FullName == args.Name) { |
||||
return asm; |
||||
} |
||||
} |
||||
|
||||
foreach (Assembly asm in AppDomain.CurrentDomain.GetAssemblies()) { |
||||
if (asm.FullName == args.Name) { |
||||
lastAssembly = asm; |
||||
} |
||||
} |
||||
if (lastAssembly != null) { |
||||
TypeResolutionService.DesignerAssemblies.Add(lastAssembly); |
||||
LoggingService.Info("ICSharpAssemblyResolver found..." + args.Name); |
||||
} |
||||
return lastAssembly; |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,18 @@
@@ -0,0 +1,18 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
using ICSharpCode.NRefactory; |
||||
using ICSharpCode.NRefactory.TypeSystem; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.Refactoring |
||||
{ |
||||
/// <summary>
|
||||
/// Description of ICodeGenerator.
|
||||
/// </summary>
|
||||
public interface ICodeGenerator |
||||
{ |
||||
void AddAttribute(IEntity target, IAttribute attribute); |
||||
void InsertEventHandler(ITypeDefinition target, string name, IEvent eventDefinition, bool jumpTo); |
||||
} |
||||
} |
||||
Loading…
Reference in new issue