diff --git a/src/AddIns/BackendBindings/CSharpBinding/Project/CSharpBinding.csproj b/src/AddIns/BackendBindings/CSharpBinding/Project/CSharpBinding.csproj
index 413773e546..cb3de8ebaf 100644
--- a/src/AddIns/BackendBindings/CSharpBinding/Project/CSharpBinding.csproj
+++ b/src/AddIns/BackendBindings/CSharpBinding/Project/CSharpBinding.csproj
@@ -78,6 +78,7 @@
+
diff --git a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/ExtensionMethods.cs b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/ExtensionMethods.cs
index c43732370f..2a0aea4ea6 100644
--- a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/ExtensionMethods.cs
+++ b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/ExtensionMethods.cs
@@ -54,23 +54,5 @@ namespace CSharpBinding
return new CSharpAstResolver(compilation, new SyntaxTree(), new CSharpUnresolvedFile { FileName = ec.FileName });
});
}
-
- ///
- /// Retrieves the declaration for the specified entity.
- /// Returns null if the entity is not defined in C# source code.
- ///
- public static EntityDeclaration GetDeclaration(this IEntity entity, out CSharpFullParseInformation parseInfo)
- {
- if (entity == null || string.IsNullOrEmpty(entity.Region.FileName)) {
- parseInfo = null;
- return null;
- }
- parseInfo = SD.ParserService.Parse(FileName.Create(entity.Region.FileName),
- parentProject: entity.ParentAssembly.GetProject())
- as CSharpFullParseInformation;
- if (parseInfo == null)
- return null;
- return parseInfo.SyntaxTree.GetNodeAt(entity.Region.Begin);
- }
}
}
diff --git a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/FormsDesigner/CSharpDesignerGenerator.cs b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/FormsDesigner/CSharpDesignerGenerator.cs
new file mode 100644
index 0000000000..fd5b2e52a5
--- /dev/null
+++ b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/FormsDesigner/CSharpDesignerGenerator.cs
@@ -0,0 +1,329 @@
+// 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.CodeDom;
+using System.CodeDom.Compiler;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Diagnostics;
+using System.IO;
+using System.Linq;
+using ICSharpCode.Core;
+using ICSharpCode.FormsDesigner;
+using ICSharpCode.NRefactory;
+using ICSharpCode.NRefactory.CSharp;
+using ICSharpCode.NRefactory.CSharp.Refactoring;
+using ICSharpCode.NRefactory.Editor;
+using ICSharpCode.NRefactory.TypeSystem;
+using ICSharpCode.SharpDevelop;
+using ICSharpCode.SharpDevelop.Editor;
+using ICSharpCode.SharpDevelop.Project;
+using Microsoft.CSharp;
+using CSharpBinding.Parser;
+using CSharpBinding.Refactoring;
+
+namespace CSharpBinding.FormsDesigner
+{
+ public class CSharpDesignerGenerator
+ {
+ readonly CSharpFullParseInformation primaryParseInfo;
+ readonly ICSharpDesignerLoaderContext context;
+ readonly ICompilation compilation;
+ readonly IUnresolvedTypeDefinition primaryPart;
+ readonly ITypeDefinition formClass;
+ readonly IMethod initializeComponents;
+
+ public CSharpDesignerGenerator(ICSharpDesignerLoaderContext context)
+ {
+ this.context = context;
+ this.primaryParseInfo = context.GetPrimaryFileParseInformation();
+ this.compilation = context.GetCompilation();
+
+ // Find designer class
+ formClass = FormsDesignerSecondaryDisplayBinding.GetDesignableClass(primaryParseInfo.UnresolvedFile, compilation, out primaryPart);
+ initializeComponents = FormsDesignerSecondaryDisplayBinding.GetInitializeComponents(formClass);
+ if (initializeComponents == null)
+ throw new FormsDesignerLoadException("Could not find InitializeComponents");
+ }
+
+ public void MergeFormChanges(CodeCompileUnit codeUnit)
+ {
+ var codeNamespace = codeUnit.Namespaces.Cast().Single();
+ var codeClass = codeNamespace.Types.Cast().Single();
+ var codeMethod = codeClass.Members.OfType().Single(m => m.Name == "InitializeComponent");
+ var codeFields = codeClass.Members.OfType().ToList();
+ RemoveUnsupportedCode(codeClass, codeMethod);
+
+ SaveInitializeComponents(codeMethod);
+ MergeFields(codeFields);
+ ApplyScripts();
+ }
+
+ #region RemoveUnsupportedCode
+ ///
+ /// This method solves all problems that are caused if the designer generates
+ /// code that is not supported in a previous version of .NET. (3.5 and below)
+ /// Currently it fixes:
+ /// - remove calls to ISupportInitialize.BeginInit/EndInit, if the interface is not implemented by the type in the target framework.
+ ///
+ /// When adding new workarounds make sure that the code does not remove too much code!
+ void RemoveUnsupportedCode(CodeTypeDeclaration codeClass, CodeMemberMethod initializeComponent)
+ {
+ if (compilation.GetProject() is MSBuildBasedProject) {
+ MSBuildBasedProject p = (MSBuildBasedProject)compilation.GetProject();
+ string v = (p.GetEvaluatedProperty("TargetFrameworkVersion") ?? "").Trim('v');
+ Version version;
+ if (!Version.TryParse(v, out version) || version.Major >= 4)
+ return;
+ }
+
+ List stmtsToRemove = new List();
+ var iSupportInitializeInterface = compilation.FindType(typeof(ISupportInitialize)).GetDefinition();
+
+ if (iSupportInitializeInterface == null)
+ return;
+
+ foreach (var stmt in initializeComponent.Statements.OfType().Where(ces => ces.Expression is CodeMethodInvokeExpression)) {
+ CodeMethodInvokeExpression invocation = (CodeMethodInvokeExpression)stmt.Expression;
+ CodeCastExpression expr = invocation.Method.TargetObject as CodeCastExpression;
+ if (expr != null) {
+ if (expr.TargetType.BaseType != "System.ComponentModel.ISupportInitialize")
+ continue;
+ var fieldType = GetTypeOfControl(expr.Expression, initializeComponent, codeClass).GetDefinition();
+ if (fieldType == null)
+ continue;
+ if (!fieldType.IsDerivedFrom(iSupportInitializeInterface))
+ stmtsToRemove.Add(stmt);
+ }
+ }
+
+ foreach (var stmt in stmtsToRemove) {
+ initializeComponent.Statements.Remove(stmt);
+ }
+ }
+
+ ///
+ /// Tries to find the type of the expression.
+ ///
+ IType GetTypeOfControl(CodeExpression expression, CodeMemberMethod initializeComponentMethod, CodeTypeDeclaration formTypeDeclaration)
+ {
+ if (expression is CodeVariableReferenceExpression) {
+ string name = ((CodeVariableReferenceExpression)expression).VariableName;
+ var decl = initializeComponentMethod.Statements.OfType().Single(v => v.Name == name);
+ return ReflectionHelper.ParseReflectionName(decl.Type.BaseType).Resolve(compilation);
+ }
+ if (expression is CodeFieldReferenceExpression && ((CodeFieldReferenceExpression)expression).TargetObject is CodeThisReferenceExpression) {
+ string name = ((CodeFieldReferenceExpression)expression).FieldName;
+ var decl = formTypeDeclaration.Members.OfType().FirstOrDefault(f => name == f.Name);
+ if (decl != null)
+ return ReflectionHelper.ParseReflectionName(decl.Type.BaseType).Resolve(compilation);
+ var field = formClass.GetFields(f => f.Name == name).LastOrDefault();
+ if (field == null)
+ return SpecialType.UnknownType;
+ return field.Type;
+ }
+ return SpecialType.UnknownType;
+ }
+ #endregion
+
+ #region Script management
+ Dictionary scripts = new Dictionary();
+
+ DocumentScript GetScript(string fileName)
+ {
+ DocumentScript script;
+ var fileNameObj = FileName.Create(fileName);
+ if (scripts.TryGetValue(fileNameObj, out script))
+ return script;
+
+ IDocument document = context.GetDocument(fileNameObj);
+ var ctx = SDRefactoringContext.Create(fileNameObj, document);
+ script = new DocumentScript(document, FormattingOptionsFactory.CreateSharpDevelop(), new TextEditorOptions());
+ scripts.Add(fileNameObj, script);
+ return script;
+ }
+
+ void ApplyScripts()
+ {
+ foreach (var pair in scripts) {
+ var script = pair.Value;
+ IDocument newDocument = script.CurrentDocument;
+ script.Dispose();
+ SD.ParserService.ParseFileAsync(pair.Key, newDocument).FireAndForget();
+ Debug.Assert(FileName.Create(newDocument.FileName) == pair.Key);
+ }
+ scripts.Clear();
+ }
+ #endregion
+
+ #region SaveInitializeComponents
+ void SaveInitializeComponents(CodeMemberMethod codeMethod)
+ {
+ var bodyRegion = initializeComponents.BodyRegion;
+ DocumentScript script = GetScript(bodyRegion.FileName);
+
+ string newline = DocumentUtilities.GetLineTerminator(script.OriginalDocument, bodyRegion.BeginLine);
+ string indentation = DocumentUtilities.GetIndentation(script.OriginalDocument, bodyRegion.BeginLine);
+ string code = "{" + newline + GenerateInitializeComponents(codeMethod, indentation, newline) + indentation + "}";
+
+ int startOffset = script.GetCurrentOffset(bodyRegion.Begin);
+ int endOffset = script.GetCurrentOffset(bodyRegion.End);
+ script.Replace(startOffset, endOffset - startOffset, code);
+ }
+
+ string GenerateInitializeComponents(CodeMemberMethod codeMethod, string indentation, string newline)
+ {
+ var writer = new StringWriter();
+ writer.NewLine = newline;
+ var options = new CodeGeneratorOptions();
+ options.IndentString = SD.EditorControlService.GlobalOptions.IndentationString;
+ var codeProvider = new CSharpCodeProvider();
+ foreach (CodeStatement statement in codeMethod.Statements) {
+ writer.Write(indentation);
+ // indentation isn't generated when calling GenerateCodeFromStatement
+ writer.Write(options.IndentString);
+ try {
+ codeProvider.GenerateCodeFromStatement(statement, writer, options);
+ } catch (Exception e) {
+ writer.WriteLine("// TODO: Error while generating statement : " + e.Message);
+ SD.Log.Error(e);
+ }
+ }
+
+ return writer.ToString();
+ }
+ #endregion
+
+ #region MergeFields
+ void MergeFields(List codeFields)
+ {
+ // apply changes the designer made to field declarations
+ // first loop looks for added and changed fields
+ foreach (CodeMemberField newField in codeFields) {
+ IField oldField = formClass.Fields.FirstOrDefault(f => f.Name == newField.Name);
+ if (oldField == null) {
+ CreateField(newField);
+ } else if (FieldChanged(oldField, newField)) {
+ UpdateField(oldField, newField);
+ }
+ }
+
+ // second loop looks for removed fields
+ foreach (IField field in formClass.Fields) {
+ if (!codeFields.Any(f => f.Name == field.Name)) {
+ RemoveField(field);
+ }
+ }
+ }
+
+ ///
+ /// Compares the SharpDevelop.Dom field declaration oldField to
+ /// the CodeDom field declaration newField.
+ ///
+ /// true, if the fields are different in type or modifiers, otherwise false.
+ static bool FieldChanged(IField oldField, CodeMemberField newField)
+ {
+ // compare types
+ if (AreTypesDifferent(oldField.ReturnType, newField.Type)) {
+ SD.Log.Debug("FieldChanged (type): "+oldField.Name+", "+oldField.ReturnType.FullName+" -> "+newField.Type.BaseType);
+ return true;
+ }
+
+ // compare accessibility modifiers
+ Accessibility oldModifiers = oldField.Accessibility;
+ MemberAttributes newModifiers = newField.Attributes & MemberAttributes.AccessMask;
+
+ // SharpDevelop.Dom always adds Private modifier, even if not specified
+ // CodeDom omits Private modifier if not present (although it is the default)
+ if (oldModifiers == Accessibility.Private) {
+ if (newModifiers != 0 && newModifiers != MemberAttributes.Private) {
+ return true;
+ }
+ }
+
+ Accessibility[] sdModifiers = {Accessibility.Protected, Accessibility.ProtectedAndInternal, Accessibility.Internal, Accessibility.Public};
+ MemberAttributes[] cdModifiers = {MemberAttributes.Family, MemberAttributes.FamilyOrAssembly, MemberAttributes.Assembly, MemberAttributes.Public};
+ for (int i = 0; i < sdModifiers.Length; i++) {
+ if ((oldModifiers == sdModifiers[i]) ^ (newModifiers == cdModifiers[i])) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ static bool AreTypesDifferent(IType oldType, CodeTypeReference newType)
+ {
+ IType oldClass = oldType.GetDefinition();
+ if (oldClass == null) {
+ // ignore type changes to fields with unresolved type
+ return false;
+ }
+ if (newType == null || newType.BaseType == "System.Void") {
+ // field types get replaced with System.Void if the type cannot be resolved
+ // (e.g. generic fields in the Boo designer which aren't converted to CodeDom)
+ // we'll ignore such type changes (fields should never have the type void)
+ return false;
+ }
+
+ return oldType.ReflectionName != newType.BaseType;
+ }
+
+ string GenerateField(CodeMemberField newField)
+ {
+ StringWriter writer = new StringWriter();
+ var provider = new CSharpCodeProvider();
+ provider.GenerateCodeFromMember(newField, writer, new CodeGeneratorOptions());
+ return writer.ToString().Trim();
+ }
+
+ void CreateField(CodeMemberField newField)
+ {
+ // insert new field below InitializeComponents()
+
+ var bodyRegion = initializeComponents.BodyRegion;
+ DocumentScript script = GetScript(bodyRegion.FileName);
+ string newline = DocumentUtilities.GetLineTerminator(script.OriginalDocument, bodyRegion.BeginLine);
+ string indentation = DocumentUtilities.GetIndentation(script.OriginalDocument, bodyRegion.BeginLine);
+
+ var insertionLocation = new TextLocation(bodyRegion.EndLine + 1, 1);
+ int insertionOffset = script.GetCurrentOffset(insertionLocation);
+ string code = indentation + GenerateField(newField) + newline;
+ script.InsertText(insertionOffset, code);
+ }
+
+ void UpdateField(IField oldField, CodeMemberField newField)
+ {
+ DomRegion region = oldField.Region;
+ DocumentScript script = GetScript(region.FileName);
+
+ int offset = script.GetCurrentOffset(region.Begin);
+ int endOffset = script.GetCurrentOffset(region.End);
+ string code = GenerateField(newField);
+ script.Replace(offset, endOffset - offset, code);
+ }
+
+ void RemoveField(IField field)
+ {
+ DomRegion region = field.Region;
+ DocumentScript script = GetScript(region.FileName);
+ int offset = script.GetCurrentOffset(region.Begin);
+ int endOffset = script.GetCurrentOffset(region.End);
+ IDocumentLine line = script.CurrentDocument.GetLineByOffset(endOffset);
+ if (endOffset == line.EndOffset) {
+ endOffset += line.DelimiterLength; // delete the whole line
+ // delete indentation in front of the line
+ while (offset > 0 && IsTabOrSpace(script.CurrentDocument.GetCharAt(offset - 1)))
+ offset--;
+ }
+ script.RemoveText(offset, endOffset - offset);
+ }
+
+ static bool IsTabOrSpace(char c)
+ {
+ return c == '\t' || c == ' ';
+ }
+ #endregion
+ }
+}
diff --git a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/FormsDesigner/CSharpDesignerLoader.cs b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/FormsDesigner/CSharpDesignerLoader.cs
index 5f660efec4..a570709dc8 100644
--- a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/FormsDesigner/CSharpDesignerLoader.cs
+++ b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/FormsDesigner/CSharpDesignerLoader.cs
@@ -16,6 +16,7 @@ using ICSharpCode.NRefactory.TypeSystem;
using ICSharpCode.SharpDevelop;
using Microsoft.CSharp;
using CSharpBinding.Parser;
+using CSharpBinding.Refactoring;
namespace CSharpBinding.FormsDesigner
{
@@ -29,11 +30,6 @@ namespace CSharpBinding.FormsDesigner
this.context = context;
}
- protected override void Write(CodeCompileUnit unit)
- {
- throw new NotImplementedException();
- }
-
protected override CodeDomProvider CodeDomProvider {
get {
return codeDomProvider;
@@ -47,8 +43,6 @@ namespace CSharpBinding.FormsDesigner
return base.IsReloadNeeded() || context.DesignerCodeFileDocument.Version.Equals(lastTextContentVersion);
}
- IUnresolvedTypeDefinition primaryPart;
-
// Steps to load the designer:
// - Parse main file
// - Find other files containing parts of the form
@@ -65,17 +59,9 @@ namespace CSharpBinding.FormsDesigner
var compilation = context.GetCompilation();
// Find designer class
- ITypeDefinition designerClass = null;
- IMethod initializeComponents = null;
- foreach (var utd in primaryParseInfo.UnresolvedFile.TopLevelTypeDefinitions) {
- var td = utd.Resolve(new SimpleTypeResolveContext(compilation.MainAssembly)).GetDefinition();
- if (td != null && FormsDesignerSecondaryDisplayBinding.IsDesignable(td)) {
- primaryPart = utd;
- designerClass = td;
- initializeComponents = FormsDesignerSecondaryDisplayBinding.GetInitializeComponents(td);
- break;
- }
- }
+ IUnresolvedTypeDefinition primaryPart;
+ ITypeDefinition designerClass = FormsDesignerSecondaryDisplayBinding.GetDesignableClass(primaryParseInfo.UnresolvedFile, compilation, out primaryPart);
+ IMethod initializeComponents = FormsDesignerSecondaryDisplayBinding.GetInitializeComponents(designerClass);
if (initializeComponents == null) {
throw new FormsDesignerLoadException("The InitializeComponent method was not found. Designer cannot be loaded.");
@@ -135,5 +121,23 @@ namespace CSharpBinding.FormsDesigner
return codeUnit;
}
+
+ protected override void Write(CodeCompileUnit unit)
+ {
+ LoggingService.Info("DesignerLoader.Write called");
+ // output generated CodeDOM to the console :
+ #if DEBUG
+ if ((Control.ModifierKeys & Keys.Control) == Keys.Control) {
+ this.CodeDomProvider.GenerateCodeFromCompileUnit(unit, Console.Out, null);
+ }
+ #endif
+ try {
+ var generator = new CSharpDesignerGenerator(context);
+ generator.MergeFormChanges(unit);
+ } catch (Exception ex) {
+ SD.AnalyticsMonitor.TrackException(ex);
+ MessageService.ShowException(ex);
+ }
+ }
}
}
diff --git a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/FormsDesigner/CSharpFormsDesignerLoaderContext.cs b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/FormsDesigner/CSharpFormsDesignerLoaderContext.cs
index f09f4c56c9..6c96e32500 100644
--- a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/FormsDesigner/CSharpFormsDesignerLoaderContext.cs
+++ b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/FormsDesigner/CSharpFormsDesignerLoaderContext.cs
@@ -2,6 +2,7 @@
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System;
+using ICSharpCode.Core;
using ICSharpCode.FormsDesigner;
using ICSharpCode.NRefactory.Editor;
using ICSharpCode.NRefactory.TypeSystem;
@@ -13,7 +14,7 @@ namespace CSharpBinding.FormsDesigner
class CSharpFormsDesignerLoaderContext : ICSharpDesignerLoaderContext
{
readonly FormsDesignerViewContent viewContent;
-
+
public CSharpFormsDesignerLoaderContext(FormsDesignerViewContent viewContent)
{
this.viewContent = viewContent;
@@ -41,6 +42,15 @@ namespace CSharpBinding.FormsDesigner
{
return SD.ParserService.GetCompilationForFile(viewContent.PrimaryFileName);
}
+
+ public IDocument GetDocument(FileName fileName)
+ {
+ foreach (var pair in viewContent.SourceFiles) {
+ if (pair.Key.FileName == fileName)
+ return pair.Value;
+ }
+ throw new InvalidOperationException("Designer file not found");
+ }
}
}
diff --git a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/FormsDesigner/ICSharpDesignerLoaderContext.cs b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/FormsDesigner/ICSharpDesignerLoaderContext.cs
index e92fd99d44..930c264fd3 100644
--- a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/FormsDesigner/ICSharpDesignerLoaderContext.cs
+++ b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/FormsDesigner/ICSharpDesignerLoaderContext.cs
@@ -2,20 +2,19 @@
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System;
+using ICSharpCode.Core;
using ICSharpCode.NRefactory.Editor;
using ICSharpCode.NRefactory.TypeSystem;
using CSharpBinding.Parser;
namespace CSharpBinding.FormsDesigner
{
- ///
- /// Description of ICSharpDesignerLoaderContext.
- ///
public interface ICSharpDesignerLoaderContext
{
//IDocument PrimaryFileDocument { get; }
IDocument DesignerCodeFileDocument { get; }
CSharpFullParseInformation GetPrimaryFileParseInformation();
ICompilation GetCompilation();
+ IDocument GetDocument(FileName fileName);
}
}
diff --git a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/FormsDesigner/SecondaryDisplayBinding.cs b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/FormsDesigner/SecondaryDisplayBinding.cs
index 423cd1fdee..5f827ea68a 100644
--- a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/FormsDesigner/SecondaryDisplayBinding.cs
+++ b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/FormsDesigner/SecondaryDisplayBinding.cs
@@ -31,6 +31,8 @@ namespace CSharpBinding.FormsDesigner
public static IMethod GetInitializeComponents(ITypeDefinition c)
{
+ if (c == null)
+ return null;
foreach (IMethod method in c.Methods) {
if (IsInitializeComponentsMethodName(method.Name) && method.Parameters.Count == 0) {
return method;
@@ -62,15 +64,23 @@ namespace CSharpBinding.FormsDesigner
public static bool IsDesignable(IUnresolvedFile parsedFile, ICompilation compilation)
{
+ IUnresolvedTypeDefinition td;
+ return GetDesignableClass(parsedFile, compilation, out td) != null;
+ }
+
+ public static ITypeDefinition GetDesignableClass(IUnresolvedFile parsedFile, ICompilation compilation, out IUnresolvedTypeDefinition primaryPart)
+ {
+ primaryPart = null;
if (parsedFile == null)
- return false;
+ return null;
foreach (var utd in parsedFile.TopLevelTypeDefinitions) {
var td = utd.Resolve(new SimpleTypeResolveContext(compilation.MainAssembly)).GetDefinition();
if (IsDesignable(td)) {
- return true;
+ primaryPart = utd;
+ return td;
}
}
- return false;
+ return null;
}
public bool CanAttachTo(IViewContent viewContent)
diff --git a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/RefactoringExtensions.cs b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/RefactoringExtensions.cs
index b24086bb6a..0fba0bf336 100644
--- a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/RefactoringExtensions.cs
+++ b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/RefactoringExtensions.cs
@@ -2,7 +2,11 @@
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System;
+using ICSharpCode.Core;
+using ICSharpCode.NRefactory.CSharp;
using ICSharpCode.NRefactory.TypeSystem;
+using ICSharpCode.SharpDevelop;
+using CSharpBinding.Parser;
namespace CSharpBinding.Refactoring
{
@@ -26,5 +30,23 @@ namespace CSharpBinding.Refactoring
return property.CanGet && !property.Getter.HasBody && property.CanSet && !property.Setter.HasBody;
}
+
+ ///
+ /// Retrieves the declaration for the specified entity.
+ /// Returns null if the entity is not defined in C# source code.
+ ///
+ public static EntityDeclaration GetDeclaration(this IEntity entity, out CSharpFullParseInformation parseInfo)
+ {
+ if (entity == null || string.IsNullOrEmpty(entity.Region.FileName)) {
+ parseInfo = null;
+ return null;
+ }
+ parseInfo = SD.ParserService.Parse(FileName.Create(entity.Region.FileName),
+ parentProject: entity.ParentAssembly.GetProject())
+ as CSharpFullParseInformation;
+ if (parseInfo == null)
+ return null;
+ return parseInfo.SyntaxTree.GetNodeAt(entity.Region.Begin);
+ }
}
}
diff --git a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/SDRefactoringContext.cs b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/SDRefactoringContext.cs
index a5d807bec4..2f097687b5 100644
--- a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/SDRefactoringContext.cs
+++ b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/SDRefactoringContext.cs
@@ -36,7 +36,7 @@ namespace CSharpBinding.Refactoring
return Create(editor.FileName, editor.Document, editor.Caret.Location, cancellationToken);
}
- public static SDRefactoringContext Create(FileName fileName, ITextSource textSource, TextLocation location, CancellationToken cancellationToken)
+ public static SDRefactoringContext Create(FileName fileName, ITextSource textSource, TextLocation location = default(TextLocation), CancellationToken cancellationToken = default(CancellationToken))
{
var parseInfo = SD.ParserService.Parse(fileName, textSource, cancellationToken: cancellationToken) as CSharpFullParseInformation;
var compilation = SD.ParserService.GetCompilationForFile(fileName);
diff --git a/src/AddIns/DisplayBindings/FormsDesigner/Project/Src/DesignerSourceCodeStorage.cs b/src/AddIns/DisplayBindings/FormsDesigner/Project/Src/DesignerSourceCodeStorage.cs
index faa7e4f480..8e7cdfd597 100644
--- a/src/AddIns/DisplayBindings/FormsDesigner/Project/Src/DesignerSourceCodeStorage.cs
+++ b/src/AddIns/DisplayBindings/FormsDesigner/Project/Src/DesignerSourceCodeStorage.cs
@@ -6,6 +6,7 @@ using System.Collections.Generic;
using System.IO;
using System.Text;
using ICSharpCode.AvalonEdit.Document;
+using ICSharpCode.Core;
using ICSharpCode.NRefactory.Editor;
using ICSharpCode.SharpDevelop;
using ICSharpCode.SharpDevelop.Editor;
@@ -73,7 +74,7 @@ namespace ICSharpCode.FormsDesigner
FileContent c;
if (!this.fileContents.TryGetValue(file, out c)) {
- c = new FileContent();
+ c = new FileContent(file.FileName);
this.fileContents.Add(file, c);
}
c.LoadFrom(stream);
@@ -98,7 +99,7 @@ namespace ICSharpCode.FormsDesigner
///
public void AddFile(OpenedFile file)
{
- this.fileContents.Add(file, new FileContent());
+ this.fileContents.Add(file, new FileContent(file.FileName));
}
///
@@ -106,7 +107,7 @@ namespace ICSharpCode.FormsDesigner
///
public void AddFile(OpenedFile file, Encoding encoding)
{
- this.fileContents.Add(file, new FileContent(encoding));
+ this.fileContents.Add(file, new FileContent(file.FileName, encoding));
}
///
@@ -159,13 +160,13 @@ namespace ICSharpCode.FormsDesigner
readonly IDocument document;
readonly bool doNotLoad;
- public FileContent()
- : this(SD.FileService.DefaultFileEncoding)
+ public FileContent(FileName fileName)
+ : this(fileName, SD.FileService.DefaultFileEncoding)
{
}
- public FileContent(Encoding encoding)
- : this(new TextDocument(), encoding)
+ public FileContent(FileName fileName, Encoding encoding)
+ : this(new TextDocument { FileName = fileName }, encoding)
{
}
diff --git a/src/AddIns/DisplayBindings/XmlEditor/Project/Src/XmlFormattingStrategy.cs b/src/AddIns/DisplayBindings/XmlEditor/Project/Src/XmlFormattingStrategy.cs
index b991d0c966..22cf9c87bb 100644
--- a/src/AddIns/DisplayBindings/XmlEditor/Project/Src/XmlFormattingStrategy.cs
+++ b/src/AddIns/DisplayBindings/XmlEditor/Project/Src/XmlFormattingStrategy.cs
@@ -161,7 +161,7 @@ namespace ICSharpCode.XmlEditor
if (r.NodeType == XmlNodeType.Element) {
tagStack.Push(currentIndentation);
if (r.LineNumber < begin)
- currentIndentation = DocumentUtilities.GetWhitespaceAfter(editor.Document, editor.Document.PositionToOffset(r.LineNumber, 1));
+ currentIndentation = DocumentUtilities.GetIndentation(editor.Document, r.LineNumber);
if (r.Name.Length < 16)
attribIndent = currentIndentation + new string(' ', 2 + r.Name.Length);
else
diff --git a/src/Main/Base/Project/Editor/DocumentUtilities.cs b/src/Main/Base/Project/Editor/DocumentUtilities.cs
index f043823bda..818c9b22ea 100644
--- a/src/Main/Base/Project/Editor/DocumentUtilities.cs
+++ b/src/Main/Base/Project/Editor/DocumentUtilities.cs
@@ -146,6 +146,11 @@ namespace ICSharpCode.SharpDevelop.Editor
return char.IsLetterOrDigit(ch) || ch == '_';
}
+ public static string GetIndentation(IDocument document, int line)
+ {
+ return DocumentUtilities.GetWhitespaceAfter(document, document.GetLineByNumber(line).Offset);
+ }
+
///
/// Gets all indentation starting at offset.
///
diff --git a/src/Main/Base/Project/Src/Editor/Commands/PasteAsCommands.cs b/src/Main/Base/Project/Src/Editor/Commands/PasteAsCommands.cs
index f910de89f1..db8521b673 100644
--- a/src/Main/Base/Project/Src/Editor/Commands/PasteAsCommands.cs
+++ b/src/Main/Base/Project/Src/Editor/Commands/PasteAsCommands.cs
@@ -31,11 +31,6 @@ namespace ICSharpCode.SharpDevelop.Editor.Commands
}
protected abstract void Run(ITextEditor editor, string clipboardText);
-
- protected string GetIndentation(IDocument document, int line)
- {
- return DocumentUtilities.GetWhitespaceAfter(document, document.GetLineByNumber(line).Offset);
- }
}
///
@@ -52,7 +47,7 @@ namespace ICSharpCode.SharpDevelop.Editor.Commands
{
protected override void Run(ITextEditor editor, string clipboardText)
{
- string indentation = GetIndentation(editor.Document, editor.Caret.Line);
+ string indentation = DocumentUtilities.GetIndentation(editor.Document, editor.Caret.Line);
IAmbience ambience = AmbienceService.GetCurrentAmbience();
int maxLineLength = editor.Options.VerticalRulerColumn - VisualIndentationLength(editor, indentation);
StringWriter insertedText = new StringWriter();
@@ -154,7 +149,7 @@ namespace ICSharpCode.SharpDevelop.Editor.Commands
}
if (expression == null)
return;
- string indentation = GetIndentation(editor.Document, editor.Caret.Line);
+ string indentation = DocumentUtilities.GetIndentation(editor.Document, editor.Caret.Line);
CodeGeneratorOptions options = new CodeGeneratorOptions();
options.IndentString = editor.Options.IndentationString;
StringWriter writer = new StringWriter();
diff --git a/src/Main/SharpDevelop/Workbench/WorkbenchStartup.cs b/src/Main/SharpDevelop/Workbench/WorkbenchStartup.cs
index 02e18f49c1..797cd92585 100644
--- a/src/Main/SharpDevelop/Workbench/WorkbenchStartup.cs
+++ b/src/Main/SharpDevelop/Workbench/WorkbenchStartup.cs
@@ -11,6 +11,7 @@ using System.Windows.Interop;
using System.Windows.Threading;
using ICSharpCode.Core;
+using ICSharpCode.Core.WinForms;
using ICSharpCode.SharpDevelop.Gui;
using ICSharpCode.SharpDevelop.Parser;
using ICSharpCode.SharpDevelop.Project;
@@ -52,6 +53,12 @@ namespace ICSharpCode.SharpDevelop.Workbench
workbench.SetMemento(PropertyService.NestedProperties(workbenchMemento));
workbench.WorkbenchLayout = layout;
+ var dlgMsgService = SD.MessageService as IDialogMessageService;
+ if (dlgMsgService != null) {
+ dlgMsgService.DialogSynchronizeInvoke = SD.MainThread.SynchronizingObject;
+ dlgMsgService.DialogOwner = workbench.MainWin32Window;
+ }
+
var applicationStateInfoService = SD.GetService();
if (applicationStateInfoService != null) {
applicationStateInfoService.RegisterStateGetter(activeContentState, delegate { return SD.Workbench.ActiveContent; });