Browse Source

Merge 3.0 to trunk.

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@5015 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
Daniel Grunwald 17 years ago
parent
commit
e2fbe21758
  1. 5
      src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/CodeCompletion/ResolveVisitor.cs
  2. 4
      src/AddIns/BackendBindings/Python/PythonBinding/Project/PythonBinding.addin
  3. 1
      src/AddIns/BackendBindings/Python/PythonBinding/Project/PythonBinding.csproj
  4. 7
      src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonDesignerGenerator.cs
  5. 76
      src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonFormattingStrategy.cs
  6. 8
      src/AddIns/BackendBindings/Python/PythonBinding/Test/AddInFileTestFixture.cs
  7. 4
      src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/InsertEventHandlerTestFixtureBase.cs
  8. 65
      src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/InsertEventHandlerWithSpaceIndentTestFixture.cs
  9. 2
      src/AddIns/BackendBindings/Python/PythonBinding/Test/PythonBinding.Tests.csproj
  10. 205
      src/AddIns/BackendBindings/Python/PythonBinding/Test/PythonIndentationTests.cs
  11. 1
      src/AddIns/BackendBindings/Python/PythonBinding/Test/Utils/MockTextEditorProperties.cs
  12. 24
      src/AddIns/Misc/Profiler/Controller/Data/CallTreeNode.cs
  13. 79
      src/AddIns/Misc/Profiler/Controller/Data/ProfilingDataSQLiteProvider.cs
  14. 21
      src/AddIns/Misc/Profiler/Controller/Data/SQLiteCallTreeNode.cs
  15. 39
      src/AddIns/Misc/Profiler/Controller/Data/UnitTestRootCallTreeNode.cs
  16. 6
      src/AddIns/Misc/Profiler/Controller/Data/UnmanagedCallTreeNode.cs
  17. 16
      src/AddIns/Misc/Profiler/Frontend/Controls/CallTreeNodeViewModel.cs
  18. 34
      src/AddIns/Misc/Profiler/Frontend/Controls/QueryView.xaml.cs
  19. 18
      src/AddIns/Misc/Profiler/Hook/ProfilerMetaData.cpp
  20. 9
      src/Libraries/NRefactory/Project/Src/Parser/CSharp/CSharpParser.cs
  21. 2245
      src/Libraries/NRefactory/Project/Src/Parser/CSharp/Parser.cs
  22. 7
      src/Libraries/NRefactory/Project/Src/Parser/CSharp/cs.ATG
  23. 84
      src/Libraries/NRefactory/Test/Parser/Expressions/InvocationExpressionTests.cs
  24. 22
      src/Libraries/NRefactory/Test/Parser/GlobalScope/TypeDeclarationTests.cs
  25. 17
      src/Main/Base/Project/Src/Services/RefactoringService/NamespaceRefactoringService.cs
  26. 1
      src/Main/Base/Project/Src/Services/RefactoringService/RefactoringMenuBuilder.cs
  27. 2
      src/Main/Base/Project/Src/TextEditor/Commands/ClassMemberMenuBuilder.cs
  28. 5
      src/Main/Base/Project/Src/TextEditor/Gui/Editor/InsightWindow/MethodInsightDataProvider.cs
  29. 7
      src/Main/Base/Test/GenerateOverrideMethodTests.cs
  30. 39
      src/Main/Base/Test/NRefactoryResolverTests.cs
  31. 16
      src/Main/Base/Test/ReflectionLayerTests.cs
  32. 17
      src/Main/Core/Project/Src/Services/FileUtility/FileUtility.cs
  33. 2
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/CSharp/CSharpAmbience.cs
  34. 1
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/CecilReader.cs
  35. 2
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Implementations/CompoundClass.cs
  36. 28
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Implementations/DefaultClass.cs
  37. 9
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Implementations/DefaultMethod.cs
  38. 10
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Implementations/DefaultReturnType.cs
  39. 26
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Interfaces/IClass.cs
  40. 5
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/NRefactoryResolver/ResolveVisitor.cs
  41. 6
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/ReflectionLayer/DomPersistence.cs
  42. 1
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/ReflectionLayer/ReflectionClass.cs
  43. 2
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/VBNet/VBNetAmbience.cs
  44. 63
      src/Main/ICSharpCode.SharpDevelop.Dom/Tests/ICSharpCode.SharpDevelop.Dom.Tests/NRefactoryAstConverterTests.cs

5
src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/CodeCompletion/ResolveVisitor.cs

@ -418,16 +418,13 @@ namespace Grunwald.BooBinding.CodeCompletion
if (callingClass != null) if (callingClass != null)
isClassInInheritanceTree = callingClass.IsTypeInInheritanceTree(trr.ResolvedClass); isClassInInheritanceTree = callingClass.IsTypeInInheritanceTree(trr.ResolvedClass);
foreach (IMethod m in trr.ResolvedClass.Methods) { foreach (IMethod m in trr.ResolvedClass.DefaultReturnType.GetMethods()) {
if (m.IsConstructor && !m.IsStatic if (m.IsConstructor && !m.IsStatic
&& m.IsAccessible(callingClass, isClassInInheritanceTree)) && m.IsAccessible(callingClass, isClassInInheritanceTree))
{ {
methods.Add(m); methods.Add(m);
} }
} }
if (methods.Count == 0) {
methods.Add(ICSharpCode.SharpDevelop.Dom.Constructor.CreateDefault(trr.ResolvedClass));
}
ResolveInvocation(methods, node.Arguments); ResolveInvocation(methods, node.Arguments);
if (resolveResult != null) if (resolveResult != null)
resolveResult.ResolvedType = trr.ResolvedType; resolveResult.ResolvedType = trr.ResolvedType;

4
src/AddIns/BackendBindings/Python/PythonBinding/Project/PythonBinding.addin

@ -24,6 +24,10 @@
resource="ICSharpCode.PythonBinding.Resources.Python.xshd"/> resource="ICSharpCode.PythonBinding.Resources.Python.xshd"/>
</Path> </Path>
<Path name="/AddIns/DefaultTextEditor/Formatter/Python">
<Class id="PythonFormatter" class="ICSharpCode.PythonBinding.PythonFormattingStrategy"/>
</Path>
<!-- Add the "Python" entry to the Open File Dialog --> <!-- Add the "Python" entry to the Open File Dialog -->
<Path name="/SharpDevelop/Workbench/FileFilter"> <Path name="/SharpDevelop/Workbench/FileFilter">
<FileFilter id="Python" <FileFilter id="Python"

1
src/AddIns/BackendBindings/Python/PythonBinding/Project/PythonBinding.csproj

@ -96,6 +96,7 @@
<Compile Include="Src\PythonDesignerLoader.cs" /> <Compile Include="Src\PythonDesignerLoader.cs" />
<Compile Include="Src\PythonDesignerLoaderProvider.cs" /> <Compile Include="Src\PythonDesignerLoaderProvider.cs" />
<Compile Include="Src\PythonExpressionFinder.cs" /> <Compile Include="Src\PythonExpressionFinder.cs" />
<Compile Include="Src\PythonFormattingStrategy.cs" />
<Compile Include="Src\PythonFormsDesignerDisplayBinding.cs" /> <Compile Include="Src\PythonFormsDesignerDisplayBinding.cs" />
<Compile Include="Src\PythonComponentWalker.cs" /> <Compile Include="Src\PythonComponentWalker.cs" />
<Compile Include="Src\PythonComponentWalkerException.cs" /> <Compile Include="Src\PythonComponentWalkerException.cs" />

7
src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonDesignerGenerator.cs

@ -131,7 +131,7 @@ namespace ICSharpCode.PythonBinding
// Insert the event handler at the end of the class with an extra // Insert the event handler at the end of the class with an extra
// new line before it. // new line before it.
IDocument doc = viewContent.DesignerCodeFileDocument; IDocument doc = viewContent.DesignerCodeFileDocument;
string eventHandler = CreateEventHandler(eventMethodName, body, "\t"); string eventHandler = CreateEventHandler(eventMethodName, body, NRefactoryToPythonConverter.GetIndentString(textEditorProperties));
int line = doc.TotalNumberOfLines; int line = doc.TotalNumberOfLines;
IDocumentLine lastLineSegment = doc.GetLine(line); IDocumentLine lastLineSegment = doc.GetLine(line);
int offset = lastLineSegment.Offset + lastLineSegment.Length; int offset = lastLineSegment.Offset + lastLineSegment.Length;
@ -228,6 +228,7 @@ namespace ICSharpCode.PythonBinding
/// <summary> /// <summary>
/// Returns the generated event handler. /// Returns the generated event handler.
/// </summary> /// </summary>
/// <param name="indentation">The indent string to use for the event handler.</param>
protected string CreateEventHandler(string eventMethodName, string body, string indentation) protected string CreateEventHandler(string eventMethodName, string body, string indentation)
{ {
if (String.IsNullOrEmpty(body)) { if (String.IsNullOrEmpty(body)) {
@ -240,9 +241,9 @@ namespace ICSharpCode.PythonBinding
eventHandler.Append("def "); eventHandler.Append("def ");
eventHandler.Append(eventMethodName); eventHandler.Append(eventMethodName);
eventHandler.Append("(self, sender, e):"); eventHandler.Append("(self, sender, e):");
eventHandler.AppendLine(); eventHandler.AppendLine();
eventHandler.Append(indentation); eventHandler.Append(indentation);
eventHandler.Append("\t"); eventHandler.Append(NRefactoryToPythonConverter.GetIndentString(textEditorProperties));
eventHandler.Append(body); eventHandler.Append(body);
return eventHandler.ToString(); return eventHandler.ToString();

76
src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonFormattingStrategy.cs

@ -0,0 +1,76 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Matthew Ward" email="mrward@users.sourceforge.net"/>
// <version>$Revision$</version>
// </file>
using System;
using ICSharpCode.TextEditor;
using ICSharpCode.TextEditor.Actions;
using ICSharpCode.TextEditor.Document;
namespace ICSharpCode.PythonBinding
{
public class PythonFormattingStrategy : DefaultFormattingStrategy
{
public PythonFormattingStrategy()
{
}
protected override int SmartIndentLine(TextArea textArea, int line)
{
IDocument document = textArea.Document;
LineSegment previousLine = document.GetLineSegment(line - 1);
string previousLineText = document.GetText(previousLine).Trim();
if (previousLineText.EndsWith(":")) {
return IncreaseLineIndent(textArea, line);
} else if (previousLineText == "pass") {
return DecreaseLineIndent(textArea, line);
} else if ((previousLineText == "return") || (previousLineText.StartsWith("return "))) {
return DecreaseLineIndent(textArea, line);
} else if ((previousLineText == "raise") || (previousLineText.StartsWith("raise "))) {
return DecreaseLineIndent(textArea, line);
} else if (previousLineText == "break") {
return DecreaseLineIndent(textArea, line);
}
return base.SmartIndentLine(textArea, line);
}
int IncreaseLineIndent(TextArea textArea, int line)
{
return ModifyLineIndent(textArea, line, true);
}
int DecreaseLineIndent(TextArea textArea, int line)
{
return ModifyLineIndent(textArea, line, false);
}
int ModifyLineIndent(TextArea textArea, int line, bool increaseIndent)
{
IDocument document = textArea.Document;
LineSegment currentLine = document.GetLineSegment(line);
string indentation = GetIndentation(textArea, line - 1);
indentation = GetNewLineIndentation(indentation, Tab.GetIndentationString(document), increaseIndent);
string newIndentedText = indentation + document.GetText(currentLine);
SmartReplaceLine(document, currentLine, newIndentedText);
return indentation.Length;
}
string GetNewLineIndentation(string previousLineIndentation, string singleIndent, bool increaseIndent)
{
if (increaseIndent) {
return previousLineIndentation + singleIndent;
}
// Decrease the new line indentation.
int decreaselength = previousLineIndentation.Length - singleIndent.Length;
if (decreaselength < 0) {
decreaselength = 0;
}
return previousLineIndentation.Substring(0, decreaselength);
}
}
}

8
src/AddIns/BackendBindings/Python/PythonBinding/Test/AddInFileTestFixture.cs

@ -51,6 +51,7 @@ namespace PythonBinding.Tests
Codon pythonProjectIconCodon; Codon pythonProjectIconCodon;
Codon convertCSharpProjectCodon; Codon convertCSharpProjectCodon;
Codon convertVBNetProjectCodon; Codon convertVBNetProjectCodon;
Codon formattingStrategyCodon;
[TestFixtureSetUp] [TestFixtureSetUp]
public void SetupFixture() public void SetupFixture()
@ -83,6 +84,7 @@ namespace PythonBinding.Tests
pythonProjectIconCodon = GetCodon("/Workspace/Icons", "PythonProjectIcon"); pythonProjectIconCodon = GetCodon("/Workspace/Icons", "PythonProjectIcon");
convertCSharpProjectCodon = GetCodon("/SharpDevelop/Pads/ProjectBrowser/ContextMenu/ProjectActions/Convert", "CSharpProjectToPythonProjectConverter"); convertCSharpProjectCodon = GetCodon("/SharpDevelop/Pads/ProjectBrowser/ContextMenu/ProjectActions/Convert", "CSharpProjectToPythonProjectConverter");
convertVBNetProjectCodon = GetCodon("/SharpDevelop/Pads/ProjectBrowser/ContextMenu/ProjectActions/Convert", "VBNetProjectToPythonProjectConverter"); convertVBNetProjectCodon = GetCodon("/SharpDevelop/Pads/ProjectBrowser/ContextMenu/ProjectActions/Convert", "VBNetProjectToPythonProjectConverter");
formattingStrategyCodon = GetCodon("/AddIns/DefaultTextEditor/Formatter/Python", "PythonFormatter");
// Get the PythonBinding runtime. // Get the PythonBinding runtime.
foreach (Runtime runtime in addin.Runtimes) { foreach (Runtime runtime in addin.Runtimes) {
@ -749,6 +751,12 @@ namespace PythonBinding.Tests
{ {
Assert.AreEqual(pythonWithoutDebuggerRunMenuItemCodon.Conditions[0], pythonRunMenuItemCodon.Conditions[0]); Assert.AreEqual(pythonWithoutDebuggerRunMenuItemCodon.Conditions[0], pythonRunMenuItemCodon.Conditions[0]);
} }
[Test]
public void PythonFormatterClass()
{
Assert.AreEqual("ICSharpCode.PythonBinding.PythonFormattingStrategy", formattingStrategyCodon["class"]);
}
Codon GetCodon(string name, string extensionPath) Codon GetCodon(string name, string extensionPath)
{ {

4
src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/InsertEventHandlerTestFixtureBase.cs

@ -26,11 +26,13 @@ namespace PythonBinding.Tests.Designer
protected DerivedFormDesignerViewContent viewContent; protected DerivedFormDesignerViewContent viewContent;
protected string fileName = @"C:\Projects\Python\mainform.py"; protected string fileName = @"C:\Projects\Python\mainform.py";
protected DerivedPythonDesignerGenerator generator; protected DerivedPythonDesignerGenerator generator;
protected MockTextEditorProperties textEditorProperties;
[TestFixtureSetUp] [TestFixtureSetUp]
public void SetUpFixture() public void SetUpFixture()
{ {
generator = new DerivedPythonDesignerGenerator(); textEditorProperties = new MockTextEditorProperties();
generator = new DerivedPythonDesignerGenerator(textEditorProperties);
mockViewContent = new MockTextEditorViewContent(); mockViewContent = new MockTextEditorViewContent();
viewContent = new DerivedFormDesignerViewContent(mockViewContent, new MockOpenedFile(fileName)); viewContent = new DerivedFormDesignerViewContent(mockViewContent, new MockOpenedFile(fileName));
generator.Attach(viewContent); generator.Attach(viewContent);

65
src/AddIns/BackendBindings/Python/PythonBinding/Test/Designer/InsertEventHandlerWithSpaceIndentTestFixture.cs

@ -0,0 +1,65 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Matthew Ward" email="mrward@users.sourceforge.net"/>
// <version>$Revision$</version>
// </file>
using System;
using ICSharpCode.PythonBinding;
using ICSharpCode.FormsDesigner;
using ICSharpCode.SharpDevelop.Dom;
using NUnit.Framework;
using PythonBinding.Tests.Utils;
namespace PythonBinding.Tests.Designer
{
/// <summary>
/// Tests the PythonDesignerGenerator uses the text editor properties for indentation when
/// inserting an event handler into the document.
/// </summary>
[TestFixture]
public class InsertEventHandlerWithSpaceIndentTestFixture : InsertEventHandlerTestFixtureBase
{
public override void AfterSetUpFixture()
{
textEditorProperties.ConvertTabsToSpaces = true;
textEditorProperties.IndentationSize = 4;
MockEventDescriptor mockEventDescriptor = new MockEventDescriptor("Click");
insertedEventHandler = generator.InsertComponentEvent(null, mockEventDescriptor, "button1_click", String.Empty, out file, out position);
}
[Test]
public void ExpectedCodeAfterEventHandlerInserted()
{
string expectedCode = GetTextEditorCode();
string eventHandler = " def button1_click(self, sender, e):\r\n" +
" pass";
expectedCode = expectedCode + "\r\n" + eventHandler;
Assert.AreEqual(expectedCode, viewContent.DesignerCodeFileContent);
}
/// <summary>
/// Note that the text editor code already has the
/// statement:
///
/// "self._button1.Click += button1_click"
///
/// This is generated by the form designer framework and not
/// by the designer generator.
/// </summary>
protected override string GetTextEditorCode()
{
return "from System.Windows.Forms import Form\r\n" +
"\r\n" +
"class MainForm(Form):\r\n" +
" def __init__(self):\r\n" +
" self.InitializeComponents()\r\n" +
" \r\n" +
" def InitializeComponents(self):\r\n" +
" self._button1 = System.Windows.Forms.Button()\r\n" +
" self.Controls.Add(self._button1)\r\n";
}
}
}

2
src/AddIns/BackendBindings/Python/PythonBinding/Test/PythonBinding.Tests.csproj

@ -242,6 +242,7 @@
<Compile Include="Designer\GetResourcesFromDesignerLoaderTestFixture.cs" /> <Compile Include="Designer\GetResourcesFromDesignerLoaderTestFixture.cs" />
<Compile Include="Designer\IgnoreDesignTimePropertiesTestFixture.cs" /> <Compile Include="Designer\IgnoreDesignTimePropertiesTestFixture.cs" />
<Compile Include="Designer\InsertEventHandlerTestFixtureBase.cs" /> <Compile Include="Designer\InsertEventHandlerTestFixtureBase.cs" />
<Compile Include="Designer\InsertEventHandlerWithSpaceIndentTestFixture.cs" />
<Compile Include="Designer\InsertNewEventHandlerTestFixture.cs" /> <Compile Include="Designer\InsertNewEventHandlerTestFixture.cs" />
<Compile Include="Designer\InsertSecondEventHandlerTestFixture.cs" /> <Compile Include="Designer\InsertSecondEventHandlerTestFixture.cs" />
<Compile Include="Designer\IsFullyQualifiedBaseClassFormDesignableTestFixture.cs" /> <Compile Include="Designer\IsFullyQualifiedBaseClassFormDesignableTestFixture.cs" />
@ -315,6 +316,7 @@
<Compile Include="Parsing\ParseSingleClassTestFixture.cs" /> <Compile Include="Parsing\ParseSingleClassTestFixture.cs" />
<Compile Include="Parsing\InvalidClassTestFixture.cs" /> <Compile Include="Parsing\InvalidClassTestFixture.cs" />
<Compile Include="PythonBindingAddInFile.cs" /> <Compile Include="PythonBindingAddInFile.cs" />
<Compile Include="PythonIndentationTests.cs" />
<Compile Include="PythonLanguagePropertiesTests.cs" /> <Compile Include="PythonLanguagePropertiesTests.cs" />
<Compile Include="PythonOptionsPanelTestFixture.cs" /> <Compile Include="PythonOptionsPanelTestFixture.cs" />
<Compile Include="CreateNewPythonProjectTestFixture.cs" /> <Compile Include="CreateNewPythonProjectTestFixture.cs" />

205
src/AddIns/BackendBindings/Python/PythonBinding/Test/PythonIndentationTests.cs

@ -0,0 +1,205 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Matthew Ward" email="mrward@users.sourceforge.net"/>
// <version>$Revision$</version>
// </file>
using System;
using ICSharpCode.PythonBinding;
using ICSharpCode.TextEditor;
using ICSharpCode.TextEditor.Document;
using ICSharpCode.TextEditor.Actions;
using NUnit.Framework;
using PythonBinding.Tests.Utils;
namespace PythonBinding.Tests.Indentation
{
/// <summary>
/// Tests that the PythonFormattingStrategy indents the new line added after pressing the ':' character.
/// </summary>
[TestFixture]
public class PythonNewMethodIndentationTestFixture
{
TextEditorControl textEditor;
PythonFormattingStrategy formattingStrategy;
[SetUp]
public void Init()
{
MockTextEditorProperties textEditorProperties = new MockTextEditorProperties();
textEditorProperties.IndentStyle = IndentStyle.Smart;
textEditorProperties.TabIndent = 4;
textEditor = new TextEditorControl();
textEditor.TextEditorProperties = textEditorProperties;
formattingStrategy = new PythonFormattingStrategy();
}
[TearDown]
public void TearDown()
{
textEditor.Dispose();
}
[Test]
public void NewMethodDefinition()
{
textEditor.Text = "def newMethod:\r\n" +
"";
int indentResult = formattingStrategy.IndentLine(textEditor.ActiveTextAreaControl.TextArea, 1);
string expectedText = "def newMethod:\r\n" +
"\t";
Assert.AreEqual(expectedText, textEditor.Text);
Assert.AreEqual(1, indentResult);
}
[Test]
public void NoExtraIndentationRequired()
{
textEditor.Text = "\tprint 'abc'\r\n" +
"";
int indentResult = formattingStrategy.IndentLine(textEditor.ActiveTextAreaControl.TextArea, 1);
string expectedText = "\tprint 'abc'\r\n" +
"\t";
Assert.AreEqual(expectedText, textEditor.Text);
Assert.AreEqual(1, indentResult);
}
[Test]
public void PassStatementDecreasesIndentOnThirdLine()
{
textEditor.Text = "def method1:\r\n" +
"\tpass\r\n" +
"";
int indentResult = formattingStrategy.IndentLine(textEditor.ActiveTextAreaControl.TextArea, 2);
string expectedText = "def method1:\r\n" +
"\tpass\r\n" +
"";
Assert.AreEqual(expectedText, textEditor.Text);
}
[Test]
public void ReturnValueStatementDecreasesIndentOnThirdLine()
{
textEditor.Text = "def method1:\r\n" +
"\treturn 0\r\n" +
"";
int indentResult = formattingStrategy.IndentLine(textEditor.ActiveTextAreaControl.TextArea, 2);
string expectedText = "def method1:\r\n" +
"\treturn 0\r\n" +
"";
Assert.AreEqual(expectedText, textEditor.Text);
}
[Test]
public void ReturnStatementDecreasesIndentOnThirdLine()
{
textEditor.Text = "def method1:\r\n" +
"\treturn\r\n" +
"";
int indentResult = formattingStrategy.IndentLine(textEditor.ActiveTextAreaControl.TextArea, 2);
string expectedText = "def method1:\r\n" +
"\treturn\r\n" +
"";
Assert.AreEqual(expectedText, textEditor.Text);
}
[Test]
public void ReturnStatementWithNoIndentOnPreviousLine()
{
textEditor.Text = "return\r\n" +
"";
int indentResult = formattingStrategy.IndentLine(textEditor.ActiveTextAreaControl.TextArea, 1);
string expectedText = "return\r\n" +
"";
Assert.AreEqual(expectedText, textEditor.Text);
}
[Test]
public void StatementIsNotAReturnOnPreviousLine()
{
textEditor.Text = "\treturnValue\r\n" +
"";
int indentResult = formattingStrategy.IndentLine(textEditor.ActiveTextAreaControl.TextArea, 1);
string expectedText = "\treturnValue\r\n" +
"\t";
Assert.AreEqual(expectedText, textEditor.Text);
}
[Test]
public void RaiseStatementWithObjectDecreasesIndentOnThirdLine()
{
textEditor.Text = "def method1:\r\n" +
"\traise 'a'\r\n" +
"";
int indentResult = formattingStrategy.IndentLine(textEditor.ActiveTextAreaControl.TextArea, 2);
string expectedText = "def method1:\r\n" +
"\traise 'a'\r\n" +
"";
Assert.AreEqual(expectedText, textEditor.Text);
}
[Test]
public void RaiseStatementDecreasesIndentOnThirdLine()
{
textEditor.Text = "def method1:\r\n" +
"\traise\r\n" +
"";
int indentResult = formattingStrategy.IndentLine(textEditor.ActiveTextAreaControl.TextArea, 2);
string expectedText = "def method1:\r\n" +
"\traise\r\n" +
"";
Assert.AreEqual(expectedText, textEditor.Text);
}
[Test]
public void StatementIsNotARaiseStatementOnPreviousLine()
{
textEditor.Text = "def method1:\r\n" +
"\traiseThis\r\n" +
"";
int indentResult = formattingStrategy.IndentLine(textEditor.ActiveTextAreaControl.TextArea, 2);
string expectedText = "def method1:\r\n" +
"\traiseThis\r\n" +
"\t";
Assert.AreEqual(expectedText, textEditor.Text);
}
[Test]
public void BreakStatementDecreasesIndentOnThirdLine()
{
textEditor.Text = "def method1:\r\n" +
"\tbreak\r\n" +
"";
int indentResult = formattingStrategy.IndentLine(textEditor.ActiveTextAreaControl.TextArea, 2);
string expectedText = "def method1:\r\n" +
"\tbreak\r\n" +
"";
Assert.AreEqual(expectedText, textEditor.Text);
}
[Test]
public void StatementIsNotABreakStatementOnPreviousLine()
{
textEditor.Text = "def method1:\r\n" +
"\tbreakThis\r\n" +
"";
int indentResult = formattingStrategy.IndentLine(textEditor.ActiveTextAreaControl.TextArea, 2);
string expectedText = "def method1:\r\n" +
"\tbreakThis\r\n" +
"\t";
Assert.AreEqual(expectedText, textEditor.Text);
}
}
}

1
src/AddIns/BackendBindings/Python/PythonBinding/Test/Utils/MockTextEditorProperties.cs

@ -17,6 +17,7 @@ namespace PythonBinding.Tests.Utils
{ {
public MockTextEditorProperties() public MockTextEditorProperties()
{ {
FontContainer = new FontContainer(SystemFonts.MenuFont);
} }
public bool CaretLine { get; set; } public bool CaretLine { get; set; }

24
src/AddIns/Misc/Profiler/Controller/Data/CallTreeNode.cs

@ -79,12 +79,17 @@ namespace ICSharpCode.Profiler.Controller.Data
/// </summary> /// </summary>
public abstract long CpuCyclesSpent { get; } public abstract long CpuCyclesSpent { get; }
long cpuCyclesSpentSelf = -1;
/// <summary> /// <summary>
/// Gets how many CPU cycles were spent inside this method, excluding sub calls. /// Gets how many CPU cycles were spent inside this method, excluding sub calls.
/// </summary> /// </summary>
public virtual long CpuCyclesSpentSelf { public virtual long CpuCyclesSpentSelf {
get { get {
return GetCpuCyclesSelf(); if (cpuCyclesSpentSelf == -1)
cpuCyclesSpentSelf = GetCpuCyclesSelf();
return cpuCyclesSpentSelf;
} }
} }
@ -116,11 +121,19 @@ namespace ICSharpCode.Profiler.Controller.Data
/// <summary> /// <summary>
/// Determines whether this node is a thread node or not. /// Determines whether this node is a thread node or not.
/// </summary> /// </summary>
public bool IsThread public bool IsThread {
{
get { return this.Name.StartsWith("Thread#", StringComparison.Ordinal); } get { return this.Name.StartsWith("Thread#", StringComparison.Ordinal); }
} }
/// <summary>
/// Determines whether this node has chil
/// </summary>
public virtual bool HasChildren {
get {
return this.Children.Any();
}
}
/// <summary> /// <summary>
/// Gets a readonly list of the string representation of the parameters. /// Gets a readonly list of the string representation of the parameters.
/// </summary> /// </summary>
@ -136,6 +149,11 @@ namespace ICSharpCode.Profiler.Controller.Data
/// </summary> /// </summary>
public abstract double TimeSpent { get; } public abstract double TimeSpent { get; }
/// <summary>
/// Gets the time spent inside the method (excluding sub calls) in milliseconds.
/// </summary>
public abstract double TimeSpentSelf { get; }
/// <summary> /// <summary>
/// Gets a reference to the parent of this CallTreeNode. /// Gets a reference to the parent of this CallTreeNode.
/// </summary> /// </summary>

79
src/AddIns/Misc/Profiler/Controller/Data/ProfilingDataSQLiteProvider.cs

@ -59,39 +59,6 @@ namespace ICSharpCode.Profiler.Controller.Data
this.Dispose(); this.Dispose();
} }
internal IQueryable<CallTreeNode> GetChildren(SQLiteCallTreeNode parent)
{
SQLiteCommand cmd;
using (LockAndCreateCommand(out cmd)) {
cmd.CommandText = @"SELECT id, nameid, callcount, timespent, isactiveatstart
FROM FunctionData
WHERE parentid IN(" + string.Join(",", parent.ids.Select(a => a.ToString(CultureInfo.InvariantCulture.NumberFormat)).ToArray()) + @")
ORDER BY id;";
using (SQLiteDataReader reader = cmd.ExecuteReader()) {
List<SQLiteCallTreeNode> items = new List<SQLiteCallTreeNode>();
while (reader.Read()) {
int childNameId = reader.GetInt32(1);
SQLiteCallTreeNode newItem = items.Find(node => node.nameId == childNameId);
if (newItem == null) {
newItem = new SQLiteCallTreeNode(childNameId, (parent.nameId == 0) ? null : parent, this);
items.Add(newItem);
// works because of ORDER BY id
newItem.isActiveAtStart = reader.GetBoolean(4);
}
newItem.callCount += reader.GetInt32(2);
newItem.cpuCyclesSpent += (ulong)reader.GetInt64(3);
newItem.ids.Add(reader.GetInt32(0));
}
return items.Cast<CallTreeNode>().AsQueryable();
}
}
}
internal IQueryable<CallTreeNode> GetCallers(SQLiteCallTreeNode item) internal IQueryable<CallTreeNode> GetCallers(SQLiteCallTreeNode item)
{ {
SQLiteCommand cmd; SQLiteCommand cmd;
@ -115,6 +82,7 @@ namespace ICSharpCode.Profiler.Controller.Data
SQLiteCallTreeNode newItem = items.Find(node => node.nameId == childNameId); SQLiteCallTreeNode newItem = items.Find(node => node.nameId == childNameId);
if (newItem == null) { if (newItem == null) {
newItem = new SQLiteCallTreeNode(childNameId, null, this); newItem = new SQLiteCallTreeNode(childNameId, null, this);
newItem.selectionStartIndex = item.selectionStartIndex;
items.Add(newItem); items.Add(newItem);
// works because of ORDER BY id // works because of ORDER BY id
@ -292,6 +260,8 @@ namespace ICSharpCode.Profiler.Controller.Data
using (SQLiteDataReader reader = cmd.ExecuteReader()) { using (SQLiteDataReader reader = cmd.ExecuteReader()) {
SQLiteCallTreeNode root = new SQLiteCallTreeNode(0, null, this); SQLiteCallTreeNode root = new SQLiteCallTreeNode(0, null, this);
root.selectionStartIndex = startIndex;
while (reader.Read()) { while (reader.Read()) {
root.callCount += reader.GetInt32(2); root.callCount += reader.GetInt32(2);
@ -304,6 +274,7 @@ namespace ICSharpCode.Profiler.Controller.Data
} }
} }
#region Properties
/// <inheritdoc/> /// <inheritdoc/>
public override void SetProperty(string name, string value) public override void SetProperty(string name, string value)
{ {
@ -350,6 +321,7 @@ namespace ICSharpCode.Profiler.Controller.Data
return null; return null;
} }
#endregion
int processorFrequency = -1; int processorFrequency = -1;
@ -376,45 +348,54 @@ namespace ICSharpCode.Profiler.Controller.Data
/// <inheritdoc/> /// <inheritdoc/>
public override IQueryable<CallTreeNode> GetFunctions(int startIndex, int endIndex) public override IQueryable<CallTreeNode> GetFunctions(int startIndex, int endIndex)
{ {
Expression<Func<SingleCall, bool>> filterLambda = c => startIndex <= c.DataSetID && c.DataSetID <= endIndex;
return CreateQuery(new MergeByName(new Filter(AllCalls.Instance, filterLambda)));
}
/*
if (startIndex < 0 || startIndex >= this.dataSets.Count) if (startIndex < 0 || startIndex >= this.dataSets.Count)
throw new ArgumentOutOfRangeException("startIndex", startIndex, "Value must be between 0 and " + endIndex); throw new ArgumentOutOfRangeException("startIndex", startIndex, "Value must be between 0 and " + endIndex);
if (endIndex < startIndex || endIndex >= this.DataSets.Count) if (endIndex < startIndex || endIndex >= this.DataSets.Count)
throw new ArgumentOutOfRangeException("endIndex", endIndex, "Value must be between " + startIndex + " and " + (this.DataSets.Count - 1)); throw new ArgumentOutOfRangeException("endIndex", endIndex, "Value must be between " + startIndex + " and " + (this.DataSets.Count - 1));
IList<CallTreeNode> functions = new List<CallTreeNode>(); Expression<Func<SingleCall, bool>> filterLambda = c => startIndex <= c.DataSetID && c.DataSetID <= endIndex;
return from c in CreateQuery(new MergeByName(new Filter(AllCalls.Instance, filterLambda)))
where c.NameMapping.Id != 0 && !c.NameMapping.Name.StartsWith("Thread#", StringComparison.Ordinal)
select c;
}
/*
IQueryable<CallTreeNode> GetMergedFunctionData(string condition, int startIndex)
{
IList<CallTreeNode> result = new List<CallTreeNode>();
SQLiteCommand cmd; SQLiteCommand cmd;
using (LockAndCreateCommand(out cmd)) { using (LockAndCreateCommand(out cmd)) {
cmd.CommandText = @"SELECT GROUP_CONCAT(id), nameid, SUM(timespent), SUM(callcount) cmd.CommandText = @"SELECT
FROM FunctionData GROUP_CONCAT(id),
WHERE datasetid BETWEEN @start AND @end nameid,
GROUP BY nameid;"; SUM(timespent),
cmd.Parameters.Add(new SQLiteParameter("@start", startIndex)); SUM(callcount),
cmd.Parameters.Add(new SQLiteParameter("@end", endIndex)); MAX(id != endid) AS hasChildren,
SUM((datasetid = " + startIndex + @") AND isActiveAtStart) AS activeCallCount
FROM FunctionData
WHERE " + condition + @"
GROUP BY nameid;";
using (SQLiteDataReader reader = cmd.ExecuteReader()) { using (SQLiteDataReader reader = cmd.ExecuteReader()) {
while (reader.Read()) { while (reader.Read()) {
SQLiteCallTreeNode node = new SQLiteCallTreeNode(reader.GetInt32(1), null, this); SQLiteCallTreeNode node = new SQLiteCallTreeNode(reader.GetInt32(1), null, this);
node.selectionStartIndex = startIndex;
node.callCount = reader.GetInt32(3); node.callCount = reader.GetInt32(3);
node.cpuCyclesSpent = (ulong)reader.GetInt64(2); node.cpuCyclesSpent = (ulong)reader.GetInt64(2);
node.ids = reader.GetString(0).Split(',').Select(s => int.Parse(s)).ToList(); node.ids = reader.GetString(0).Split(',').Select(s => int.Parse(s)).ToList();
node.ids.Sort(); node.ids.Sort();
node.hasChildren = reader.GetBoolean(4);
node.activeCallCount = reader.GetInt32(5);
// Can not do filtering of root and thread nodes here, // Can not do filtering of root and thread nodes here,
// because retrieval of names needs access to DB // because retrieval of names needs access to DB
// which is forbidden now (we are inside the lock!) // which is forbidden now (we are inside the lock!)
functions.Add(node); result.Add(node);
} }
} }
} }
// Do filtering now via LINQ return result.AsQueryable();
return functions.SkipWhile(i => i.NameMapping.Id == 0 || i.NameMapping.Name.StartsWith("Thread#", StringComparison.Ordinal)).AsQueryable();
} }
*/ */

21
src/AddIns/Misc/Profiler/Controller/Data/SQLiteCallTreeNode.cs

@ -29,6 +29,9 @@ namespace ICSharpCode.Profiler.Controller.Data
CallTreeNode parent; CallTreeNode parent;
ProfilingDataSQLiteProvider provider; ProfilingDataSQLiteProvider provider;
internal List<int> ids = new List<int>(); internal List<int> ids = new List<int>();
internal bool hasChildren;
internal int activeCallCount;
internal int selectionStartIndex;
/// <summary> /// <summary>
/// Creates a new CallTreeNode. /// Creates a new CallTreeNode.
@ -95,6 +98,12 @@ namespace ICSharpCode.Profiler.Controller.Data
return CpuCyclesSpent / (1000.0 * this.provider.ProcessorFrequency); return CpuCyclesSpent / (1000.0 * this.provider.ProcessorFrequency);
} }
} }
public override double TimeSpentSelf {
get {
return CpuCyclesSpentSelf / (1000.0 * this.provider.ProcessorFrequency);
}
}
/// <summary> /// <summary>
/// Gets whether the function call started in a previous data set that's not selected. /// Gets whether the function call started in a previous data set that's not selected.
@ -105,8 +114,12 @@ namespace ICSharpCode.Profiler.Controller.Data
} }
} }
public override int CallCount {
get { return callCount + activeCallCount; }
}
/// <summary> /// <summary>
/// Merges a collection of CallTreeNodes into one CallTreeNode, all valuess are accumulated. /// Merges a collection of CallTreeNodes into one CallTreeNode, all values are accumulated.
/// </summary> /// </summary>
/// <param name="nodes">The collection of nodes to process.</param> /// <param name="nodes">The collection of nodes to process.</param>
/// <returns>A new CallTreeNode.</returns> /// <returns>A new CallTreeNode.</returns>
@ -114,8 +127,10 @@ namespace ICSharpCode.Profiler.Controller.Data
{ {
SQLiteCallTreeNode mergedNode = new SQLiteCallTreeNode(0, null, this.provider); SQLiteCallTreeNode mergedNode = new SQLiteCallTreeNode(0, null, this.provider);
bool initialised = false; bool initialised = false;
foreach (SQLiteCallTreeNode node in nodes) { foreach (SQLiteCallTreeNode node in nodes) {
mergedNode.ids.AddRange(node.ids); mergedNode.ids.AddRange(node.ids);
mergedNode.selectionStartIndex = Math.Min(mergedNode.selectionStartIndex, node.selectionStartIndex);
mergedNode.callCount += node.callCount; mergedNode.callCount += node.callCount;
mergedNode.cpuCyclesSpent += node.cpuCyclesSpent; mergedNode.cpuCyclesSpent += node.cpuCyclesSpent;
if (!initialised || mergedNode.nameId == node.nameId) if (!initialised || mergedNode.nameId == node.nameId)
@ -172,5 +187,9 @@ namespace ICSharpCode.Profiler.Controller.Data
return hash; return hash;
} }
public override bool HasChildren {
get { return this.hasChildren; }
}
} }
} }

39
src/AddIns/Misc/Profiler/Controller/Data/UnitTestRootCallTreeNode.cs

@ -18,7 +18,7 @@ namespace ICSharpCode.Profiler.Controller.Data
List<CallTreeNode> unitTests; List<CallTreeNode> unitTests;
/// <summary> /// <summary>
/// Creates a new UnitTestRootCallTreeNode. /// Creates a new UnitTestRootCallTreeNode.
/// </summary> /// </summary>
public UnitTestRootCallTreeNode(IEnumerable<CallTreeNode> unitTests) public UnitTestRootCallTreeNode(IEnumerable<CallTreeNode> unitTests)
{ {
@ -46,58 +46,65 @@ namespace ICSharpCode.Profiler.Controller.Data
} }
} }
/// <inheritdoc/> /// <inheritdoc/>
public override double TimeSpent { public override double TimeSpent {
get { get {
return 0; return 0;
} }
} }
/// <inheritdoc/> /// <inheritdoc/>
public override int RawCallCount { public override int RawCallCount {
get { get {
return 0; return 0;
} }
} }
/// <inheritdoc/> /// <inheritdoc/>
public override CallTreeNode Parent { public override CallTreeNode Parent {
get { get {
return null; return null;
} }
} }
/// <inheritdoc/> /// <inheritdoc/>
public override CallTreeNode Merge(System.Collections.Generic.IEnumerable<CallTreeNode> nodes) public override CallTreeNode Merge(System.Collections.Generic.IEnumerable<CallTreeNode> nodes)
{ {
// throw new ShouldNeverHappenException(); // throw new ShouldNeverHappenException();
throw new NotSupportedException("Cannot merge a UnitTestRootCallTreeNode (should never be possible)"); throw new NotSupportedException("Cannot merge a UnitTestRootCallTreeNode (should never be possible)");
} }
/// <inheritdoc/> /// <inheritdoc/>
public override int GetHashCode() public override int GetHashCode()
{ {
return this.unitTests.Aggregate(0, (sum, item) => sum ^= item.GetHashCode()); return this.unitTests.Aggregate(0, (sum, item) => sum ^= item.GetHashCode());
} }
/// <inheritdoc/> /// <inheritdoc/>
public override bool Equals(CallTreeNode other) public override bool Equals(CallTreeNode other)
{ {
return (other is UnitTestRootCallTreeNode) && (other as UnitTestRootCallTreeNode).unitTests.SequenceEqual(unitTests); return (other is UnitTestRootCallTreeNode) && (other as UnitTestRootCallTreeNode).unitTests.SequenceEqual(unitTests);
} }
/// <inheritdoc/> /// <inheritdoc/>
public override IQueryable<CallTreeNode> Callers { public override IQueryable<CallTreeNode> Callers {
get { get {
return Enumerable.Empty<CallTreeNode>().AsQueryable(); return Enumerable.Empty<CallTreeNode>().AsQueryable();
} }
} }
/// <inheritdoc/> /// <inheritdoc/>
public override IQueryable<CallTreeNode> Children { public override IQueryable<CallTreeNode> Children {
get { get {
return unitTests.AsQueryable(); return unitTests.AsQueryable();
} }
} }
/// <inheritdoc/>
public override double TimeSpentSelf {
get {
return 0;
}
}
} }
} }

6
src/AddIns/Misc/Profiler/Controller/Data/UnmanagedCallTreeNode.cs

@ -94,6 +94,12 @@ namespace ICSharpCode.Profiler.Controller.Data
return this.CpuCyclesSpent / (1000.0 * this.dataSet.ProcessorFrequency); return this.CpuCyclesSpent / (1000.0 * this.dataSet.ProcessorFrequency);
} }
} }
public override double TimeSpentSelf {
get {
return this.CpuCyclesSpentSelf / (1000.0 * this.dataSet.ProcessorFrequency);
}
}
public override CallTreeNode Merge(IEnumerable<CallTreeNode> nodes) public override CallTreeNode Merge(IEnumerable<CallTreeNode> nodes)
{ {

16
src/AddIns/Misc/Profiler/Frontend/Controls/CallTreeNodeViewModel.cs

@ -330,20 +330,18 @@ namespace ICSharpCode.Profiler.Controls
public string TimeSpentSelf { public string TimeSpentSelf {
get { get {
if (!node.IsThread) { if (!node.IsThread)
double value = node.TimeSpent - node.Children.Aggregate(0.0, (sum, item) => sum + item.TimeSpent); return node.TimeSpentSelf.ToString("f6") + "ms";
return value.ToString("f6") + "ms"; else
} else
return null; return null;
} }
} }
public string TimeSpentSelfPerCall { public string TimeSpentSelfPerCall {
get { get {
if (!node.IsThread) { if (!node.IsThread)
double value = node.TimeSpent - node.Children.Aggregate(0.0, (sum, item) => sum + item.TimeSpent); return (node.TimeSpentSelf / node.CallCount).ToString("f6") + "ms";
return (value / node.CallCount).ToString("f6") + "ms"; else
} else
return null; return null;
} }
} }
@ -369,7 +367,7 @@ namespace ICSharpCode.Profiler.Controls
public Visibility CheckBoxVisibility public Visibility CheckBoxVisibility
{ {
get { get {
if (this.Children.Count > 0) if (node.HasChildren)
return Visibility.Visible; return Visibility.Visible;
else else
return Visibility.Hidden; return Visibility.Hidden;

34
src/AddIns/Misc/Profiler/Frontend/Controls/QueryView.xaml.cs

@ -190,16 +190,26 @@ namespace ICSharpCode.Profiler.Controls
this.visibleColumnsSelection.ItemsSource = this.gridView.Columns.Select(col => new GridViewColumnModel(col)); this.visibleColumnsSelection.ItemsSource = this.gridView.Columns.Select(col => new GridViewColumnModel(col));
this.treeView.SizeChanged += delegate(object sender, SizeChangedEventArgs e) { this.treeView.SizeChanged += delegate(object sender, SizeChangedEventArgs e) {
if (e.NewSize.Width > 0 && e.PreviousSize.Width > 0 && if (e.NewSize.Width > 0 && e.PreviousSize.Width > 0) {
(nameColumn.Width + (e.NewSize.Width - e.PreviousSize.Width)) > 0) { double adjustedNameColumnWidth = nameColumn.Width + e.NewSize.Width - e.PreviousSize.Width;
double newValue = e.NewSize.Width - this.callCountColumn.Width double matchingNameColumnWidth = e.NewSize.Width - this.callCountColumn.Width
- this.percentColumn.Width - this.timeSpentColumn.Width - this.percentColumn.Width - this.timeSpentColumn.Width
- this.timeSpentSelfColumn.Width - this.timeSpentPerCallColumn.Width - this.timeSpentSelfColumn.Width - this.timeSpentPerCallColumn.Width
- this.timeSpentSelfPerCallColumn.Width; - this.timeSpentSelfPerCallColumn.Width - 25;
if ((nameColumn.Width + (e.NewSize.Width - e.PreviousSize.Width)) >= newValue)
this.nameColumn.Width = newValue - 25; // always keep name column at least 75 pixels wide
else if (matchingNameColumnWidth < 75)
nameColumn.Width += (e.NewSize.Width - e.PreviousSize.Width); matchingNameColumnWidth = 75;
if (e.NewSize.Width >= e.PreviousSize.Width) {
// treeView got wider: also make name column wider if there's space free
if (adjustedNameColumnWidth <= matchingNameColumnWidth)
nameColumn.Width = adjustedNameColumnWidth;
} else {
// treeView got smaller: make column smaller unless there's space free
if (adjustedNameColumnWidth >= matchingNameColumnWidth)
nameColumn.Width = adjustedNameColumnWidth;
}
} }
}; };
} }
@ -332,17 +342,17 @@ namespace ICSharpCode.Profiler.Controls
void BtnExpandHotPathSubtreeClick(object sender, RoutedEventArgs e) void BtnExpandHotPathSubtreeClick(object sender, RoutedEventArgs e)
{ {
foreach (CallTreeNodeViewModel node in this.SelectedItems.ToArray()) { foreach (CallTreeNodeViewModel node in this.SelectedItems.ToArray()) {
ExpandHotPathItems(node); ExpandHotPathItems(node, node);
} }
} }
void ExpandHotPathItems(CallTreeNodeViewModel parent) void ExpandHotPathItems(CallTreeNodeViewModel parent, CallTreeNodeViewModel selectedRoot)
{ {
if (parent.HotPathIndicatorVisibility == Visibility.Visible) { if ((parent.CpuCyclesSpent / (double)selectedRoot.CpuCyclesSpent) >= 0.2) {
parent.IsExpanded = true; parent.IsExpanded = true;
foreach (CallTreeNodeViewModel node in parent.Children) foreach (CallTreeNodeViewModel node in parent.Children)
ExpandHotPathItems(node); ExpandHotPathItems(node, selectedRoot);
} }
} }

18
src/AddIns/Misc/Profiler/Hook/ProfilerMetaData.cpp

@ -528,8 +528,10 @@ bool SignatureReader::ReadCompressedInt(int *out)
return true; return true;
} }
// public key token: b77a5c561934e089
const byte mscorlibkey[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; const byte mscorlibkey[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
// public key token: b03f5f7f11d50a3a
const byte systemdrawingkey[] = { const byte systemdrawingkey[] = {
0x00, 0x24, 0x00, 0x00, 0x04, 0x80, 0x00, 0x00, 0x94, 0x00, 0x00, 0x00, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x04, 0x80, 0x00, 0x00, 0x94, 0x00, 0x00, 0x00, 0x06, 0x02, 0x00, 0x00, 0x00,
0x24, 0x00, 0x00, 0x52, 0x53, 0x41, 0x31, 0x00, 0x04, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x07, 0xD1, 0x24, 0x00, 0x00, 0x52, 0x53, 0x41, 0x31, 0x00, 0x04, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x07, 0xD1,
@ -543,6 +545,20 @@ const byte systemdrawingkey[] = {
0xC0, 0x93, 0x34, 0x4D, 0x5A, 0xD2, 0x93 0xC0, 0x93, 0x34, 0x4D, 0x5A, 0xD2, 0x93
}; };
// public key token: 31bf3856ad364e35
const byte wpfassemblieskey[] = {
0x00, 0x24, 0x00, 0x00, 0x04, 0x80, 0x00, 0x00, 0x94, 0x00, 0x00, 0x00, 0x06, 0x02, 0x00, 0x00, 0x00,
0x24, 0x00, 0x00, 0x52, 0x53, 0x41, 0x31, 0x00, 0x04, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0xB5, 0xFC,
0x90, 0xE7, 0x02, 0x7F, 0x67, 0x87, 0x1E, 0x77, 0x3A, 0x8F, 0xDE, 0x89, 0x38, 0xC8, 0x1D, 0xD4, 0x02,
0xBA, 0x65, 0xB9, 0x20, 0x1D, 0x60, 0x59, 0x3E, 0x96, 0xC4, 0x92, 0x65, 0x1E, 0x88, 0x9C, 0xC1, 0x3F,
0x14, 0x15, 0xEB, 0xB5, 0x3F, 0xAC, 0x11, 0x31, 0xAE, 0x0B, 0xD3, 0x33, 0xC5, 0xEE, 0x60, 0x21, 0x67,
0x2D, 0x97, 0x18, 0xEA, 0x31, 0xA8, 0xAE, 0xBD, 0x0D, 0xA0, 0x07, 0x2F, 0x25, 0xD8, 0x7D, 0xBA, 0x6F,
0xC9, 0x0F, 0xFD, 0x59, 0x8E, 0xD4, 0xDA, 0x35, 0xE4, 0x4C, 0x39, 0x8C, 0x45, 0x43, 0x07, 0xE8, 0xE3,
0x3B, 0x84, 0x26, 0x14, 0x3D, 0xAE, 0xC9, 0xF5, 0x96, 0x83, 0x6F, 0x97, 0xC8, 0xF7, 0x47, 0x50, 0xE5,
0x97, 0x5C, 0x64, 0xE2, 0x18, 0x9F, 0x45, 0xDE, 0xF4, 0x6B, 0x2A, 0x2B, 0x12, 0x47, 0xAD, 0xC3, 0x65,
0x2B, 0xF5, 0xC3, 0x08, 0x05, 0x5D, 0xA9
};
bool SignatureReader::IsNetInternal(FunctionID fid) bool SignatureReader::IsNetInternal(FunctionID fid)
{ {
@ -567,6 +583,8 @@ bool SignatureReader::IsNetInternal(FunctionID fid)
return true; return true;
if (pKLength == sizeof(systemdrawingkey) && memcmp(systemdrawingkey, b, sizeof(systemdrawingkey)) == 0) if (pKLength == sizeof(systemdrawingkey) && memcmp(systemdrawingkey, b, sizeof(systemdrawingkey)) == 0)
return true; return true;
if (pKLength == sizeof(wpfassemblieskey) && memcmp(wpfassemblieskey, b, sizeof(wpfassemblieskey)) == 0)
return true;
} }
} }

9
src/Libraries/NRefactory/Project/Src/Parser/CSharp/CSharpParser.cs

@ -503,9 +503,7 @@ namespace ICSharpCode.NRefactory.Parser.CSharp
string val = la.val; string val = la.val;
return (cur == Tokens.Event || cur == Tokens.Return || return (cur == Tokens.Event || cur == Tokens.Return ||
(Tokens.IdentifierTokens[cur] && Tokens.IdentifierTokens[cur]) &&
(val == "field" || val == "method" || val == "module" ||
val == "param" || val == "property" || val == "type"))) &&
Peek(1).kind == Tokens.Colon; Peek(1).kind == Tokens.Colon;
} }
@ -551,8 +549,9 @@ namespace ICSharpCode.NRefactory.Parser.CSharp
TypeReference targetType = GetTypeReferenceFromExpression(member.TargetObject); TypeReference targetType = GetTypeReferenceFromExpression(member.TargetObject);
if (targetType != null) { if (targetType != null) {
if (targetType.GenericTypes.Count == 0 && targetType.IsArrayType == false) { if (targetType.GenericTypes.Count == 0 && targetType.IsArrayType == false) {
TypeReference tr = new TypeReference(targetType.Type + "." + member.MemberName, member.TypeArguments); TypeReference tr = targetType.Clone();
tr.IsGlobal = targetType.IsGlobal; tr.Type = tr.Type + "." + member.MemberName;
tr.GenericTypes.AddRange(member.TypeArguments);
return tr; return tr;
} else { } else {
return new InnerClassTypeReference(targetType, member.MemberName, member.TypeArguments); return new InnerClassTypeReference(targetType, member.MemberName, member.TypeArguments);

2245
src/Libraries/NRefactory/Project/Src/Parser/CSharp/Parser.cs

File diff suppressed because it is too large Load Diff

7
src/Libraries/NRefactory/Project/Src/Parser/CSharp/cs.ATG

@ -297,12 +297,7 @@ AttributeSection<out AttributeSection section>
[ IF (IsLocalAttrTarget()) [ IF (IsLocalAttrTarget())
( "event" (. attributeTarget = "event";.) ( "event" (. attributeTarget = "event";.)
| "return" (. attributeTarget = "return";.) | "return" (. attributeTarget = "return";.)
| Identifier (. if (t.val != "field" && t.val != "method" && | Identifier (. attributeTarget = t.val; .)
t.val != "param" &&
t.val != "property" && t.val != "type")
Error("attribute target specifier (field, event, method, param, property, return or type) expected");
attributeTarget = t.val;
.)
) ":" ) ":"
] ]
/*--- attribute list: */ /*--- attribute list: */

84
src/Libraries/NRefactory/Test/Parser/Expressions/InvocationExpressionTests.cs

@ -117,6 +117,47 @@ namespace ICSharpCode.NRefactory.Tests.Ast
Assert.AreEqual(new Location(4, 1), mre.TargetObject.StartLocation); Assert.AreEqual(new Location(4, 1), mre.TargetObject.StartLocation);
Assert.AreEqual(new Location(6, 1), mre.TargetObject.EndLocation); Assert.AreEqual(new Location(6, 1), mre.TargetObject.EndLocation);
} }
[Test]
public void InvocationOnGenericType()
{
InvocationExpression expr = ParseUtilCSharp.ParseExpression<InvocationExpression>("A<T>.Foo()");
MemberReferenceExpression mre = (MemberReferenceExpression)expr.TargetObject;
Assert.AreEqual("Foo", mre.MemberName);
TypeReferenceExpression tre = (TypeReferenceExpression)mre.TargetObject;
Assert.AreEqual("A", tre.TypeReference.Type);
Assert.AreEqual("T", tre.TypeReference.GenericTypes[0].Type);
}
[Test]
public void InvocationOnInnerClassInGenericType()
{
InvocationExpression expr = ParseUtilCSharp.ParseExpression<InvocationExpression>("A<T>.B.Foo()");
MemberReferenceExpression mre = (MemberReferenceExpression)expr.TargetObject;
Assert.AreEqual("Foo", mre.MemberName);
MemberReferenceExpression mre2 = (MemberReferenceExpression)mre.TargetObject;
Assert.AreEqual("B", mre2.MemberName);
TypeReferenceExpression tre = (TypeReferenceExpression)mre2.TargetObject;
Assert.AreEqual("A", tre.TypeReference.Type);
Assert.AreEqual("T", tre.TypeReference.GenericTypes[0].Type);
}
[Test]
public void InvocationOnGenericInnerClassInGenericType()
{
InvocationExpression expr = ParseUtilCSharp.ParseExpression<InvocationExpression>("A<T>.B.C<U>.Foo()");
MemberReferenceExpression mre = (MemberReferenceExpression)expr.TargetObject;
Assert.AreEqual("Foo", mre.MemberName);
TypeReferenceExpression tre = (TypeReferenceExpression)mre.TargetObject;
InnerClassTypeReference ictr = (InnerClassTypeReference)tre.TypeReference;
Assert.AreEqual("B.C", ictr.Type);
Assert.AreEqual(1, ictr.GenericTypes.Count);
Assert.AreEqual("U", ictr.GenericTypes[0].Type);
Assert.AreEqual("A", ictr.BaseType.Type);
Assert.AreEqual(1, ictr.BaseType.GenericTypes.Count);
Assert.AreEqual("T", ictr.BaseType.GenericTypes[0].Type);
}
#endregion #endregion
#region VB.NET #region VB.NET
@ -145,6 +186,49 @@ namespace ICSharpCode.NRefactory.Tests.Ast
Assert.AreEqual(0, ie.Arguments.Count); Assert.AreEqual(0, ie.Arguments.Count);
} }
[Test]
public void VBInvocationOnGenericType()
{
InvocationExpression expr = ParseUtilVBNet.ParseExpression<InvocationExpression>("A(Of T).Foo()");
MemberReferenceExpression mre = (MemberReferenceExpression)expr.TargetObject;
Assert.AreEqual("Foo", mre.MemberName);
IdentifierExpression tre = (IdentifierExpression)mre.TargetObject;
Assert.AreEqual("A", tre.Identifier);
Assert.AreEqual("T", tre.TypeArguments[0].Type);
}
[Test]
public void VBInvocationOnInnerClassInGenericType()
{
InvocationExpression expr = ParseUtilVBNet.ParseExpression<InvocationExpression>("A(Of T).B.Foo()");
MemberReferenceExpression mre = (MemberReferenceExpression)expr.TargetObject;
Assert.AreEqual("Foo", mre.MemberName);
MemberReferenceExpression mre2 = (MemberReferenceExpression)mre.TargetObject;
Assert.AreEqual("B", mre2.MemberName);
IdentifierExpression tre = (IdentifierExpression)mre2.TargetObject;
Assert.AreEqual("A", tre.Identifier);
Assert.AreEqual("T", tre.TypeArguments[0].Type);
}
[Test]
public void VBInvocationOnGenericInnerClassInGenericType()
{
InvocationExpression expr = ParseUtilVBNet.ParseExpression<InvocationExpression>("A(Of T).B.C(Of U).Foo()");
MemberReferenceExpression mre = (MemberReferenceExpression)expr.TargetObject;
Assert.AreEqual("Foo", mre.MemberName);
MemberReferenceExpression mre2 = (MemberReferenceExpression)mre.TargetObject;
Assert.AreEqual("C", mre2.MemberName);
Assert.AreEqual("U", mre2.TypeArguments[0].Type);
MemberReferenceExpression mre3 = (MemberReferenceExpression)mre2.TargetObject;
Assert.AreEqual("B", mre3.MemberName);
IdentifierExpression tre = (IdentifierExpression)mre3.TargetObject;
Assert.AreEqual("A", tre.Identifier);
Assert.AreEqual("T", tre.TypeArguments[0].Type);
}
#endregion #endregion
} }
} }

22
src/Libraries/NRefactory/Test/Parser/GlobalScope/TypeDeclarationTests.cs

@ -179,6 +179,28 @@ public abstract class MyClass : MyBase, Interface1, My.Test.Interface2
Assert.AreEqual(ClassType.Enum, td.Type); Assert.AreEqual(ClassType.Enum, td.Type);
Assert.AreEqual("MyEnum", td.Name); Assert.AreEqual("MyEnum", td.Name);
} }
[Test]
public void ContextSensitiveKeywordTest()
{
TypeDeclaration td = ParseUtilCSharp.ParseGlobal<TypeDeclaration>("partial class partial<[partial: where] where> where where : partial<where> { }");
Assert.AreEqual(Modifiers.Partial, td.Modifier);
Assert.AreEqual("partial", td.Name);
Assert.AreEqual(1, td.Templates.Count);
TemplateDefinition tp = td.Templates[0];
Assert.AreEqual("where", tp.Name);
Assert.AreEqual(1, tp.Attributes.Count);
Assert.AreEqual("partial", tp.Attributes[0].AttributeTarget);
Assert.AreEqual(1, tp.Attributes[0].Attributes.Count);
Assert.AreEqual("where", tp.Attributes[0].Attributes[0].Name);
Assert.AreEqual(1, tp.Bases.Count);
Assert.AreEqual("partial", tp.Bases[0].Type);
Assert.AreEqual("where", tp.Bases[0].GenericTypes[0].Type);
}
#endregion #endregion
#region VB.NET #region VB.NET

17
src/Main/Base/Project/Src/Services/RefactoringService/NamespaceRefactoringService.cs

@ -33,7 +33,7 @@ namespace ICSharpCode.SharpDevelop.Refactoring
} else if (!IsSystemNamespace(u1) && IsSystemNamespace(u2)) { } else if (!IsSystemNamespace(u1) && IsSystemNamespace(u2)) {
return 1; return 1;
} }
return a.Usings[0].CompareTo(b.Usings[0]); return u1.CompareTo(u2);
} }
if (a.Aliases.Count != 0 && b.Aliases.Count != 0) { if (a.Aliases.Count != 0 && b.Aliases.Count != 0) {
return a.Aliases.Keys.First().CompareTo(b.Aliases.Keys.First()); return a.Aliases.Keys.First().CompareTo(b.Aliases.Keys.First());
@ -96,6 +96,17 @@ namespace ICSharpCode.SharpDevelop.Refactoring
public static void AddUsingDeclaration(ICompilationUnit cu, IDocument document, string newNamespace, bool sortExistingUsings) public static void AddUsingDeclaration(ICompilationUnit cu, IDocument document, string newNamespace, bool sortExistingUsings)
{ {
if (cu == null)
throw new ArgumentNullException("cu");
if (document == null)
throw new ArgumentNullException("document");
if (newNamespace == null)
throw new ArgumentNullException("newNamespace");
ParseInformation info = ParserService.ParseFile(cu.FileName, document);
if (info != null)
cu = info.CompilationUnit;
IUsing newUsingDecl = new DefaultUsing(cu.ProjectContent); IUsing newUsingDecl = new DefaultUsing(cu.ProjectContent);
newUsingDecl.Usings.Add(newNamespace); newUsingDecl.Usings.Add(newNamespace);
@ -105,9 +116,7 @@ namespace ICSharpCode.SharpDevelop.Refactoring
} }
bool inserted = false; bool inserted = false;
for (int i = 0; i < newUsings.Count; i++) { for (int i = 0; i < newUsings.Count; i++) {
if (newUsings[i].Usings.Count >= 1 if (CompareUsings(newUsingDecl, newUsings[i]) <= 0) {
&& cu.ProjectContent.Language.NameComparer.Compare(newNamespace, newUsings[i].Usings[0]) <= 0)
{
newUsings.Insert(i, newUsingDecl); newUsings.Insert(i, newUsingDecl);
inserted = true; inserted = true;
break; break;

1
src/Main/Base/Project/Src/Services/RefactoringService/RefactoringMenuBuilder.cs

@ -196,6 +196,7 @@ namespace ICSharpCode.SharpDevelop.Refactoring
item.Items.Add(subItem); item.Items.Add(subItem);
subItem.Click += delegate { subItem.Click += delegate {
NamespaceRefactoringService.AddUsingDeclaration(callingClass.CompilationUnit, textArea.Document, newNamespace, true); NamespaceRefactoringService.AddUsingDeclaration(callingClass.CompilationUnit, textArea.Document, newNamespace, true);
ParserService.BeginParse(textArea.FileName, textArea.Document);
}; };
} }
return item; return item;

2
src/Main/Base/Project/Src/TextEditor/Commands/ClassMemberMenuBuilder.cs

@ -52,7 +52,7 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Commands
member.DeclaringType.ProjectContent.Language.CodeGenerator != null member.DeclaringType.ProjectContent.Language.CodeGenerator != null
&& !FindReferencesAndRenameHelper.IsReadOnly(member.DeclaringType); && !FindReferencesAndRenameHelper.IsReadOnly(member.DeclaringType);
if (method == null || !method.IsConstructor) { if (method == null || !method.IsConstructor && !method.IsOperator) {
if (!FindReferencesAndRenameHelper.IsReadOnly(member.DeclaringType) && if (!FindReferencesAndRenameHelper.IsReadOnly(member.DeclaringType) &&
!(member is IProperty && ((IProperty)member).IsIndexer)) { !(member is IProperty && ((IProperty)member).IsIndexer)) {
cmd = new MenuCommand("${res:SharpDevelop.Refactoring.RenameCommand}", Rename); cmd = new MenuCommand("${res:SharpDevelop.Refactoring.RenameCommand}", Rename);

5
src/Main/Base/Project/Src/TextEditor/Gui/Editor/InsightWindow/MethodInsightDataProvider.cs

@ -144,11 +144,6 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor
if (trr != null || expressionResult.Context == ExpressionContext.BaseConstructorCall) { if (trr != null || expressionResult.Context == ExpressionContext.BaseConstructorCall) {
if (results.ResolvedType != null) { if (results.ResolvedType != null) {
methods.AddRange(GetConstructorMethods(results.ResolvedType.GetMethods())); methods.AddRange(GetConstructorMethods(results.ResolvedType.GetMethods()));
IClass resolvedClass = (trr != null) ? trr.ResolvedClass : results.ResolvedType.GetUnderlyingClass();
if (methods.Count == 0 && resolvedClass != null && !resolvedClass.IsStatic) {
// add default constructor
methods.Add(Constructor.CreateDefault(resolvedClass));
}
} }
} }
} else { } else {

7
src/Main/Base/Test/GenerateOverrideMethodTests.cs

@ -6,6 +6,7 @@
// </file> // </file>
using System; using System;
using System.Linq;
using ICSharpCode.NRefactory.Ast; using ICSharpCode.NRefactory.Ast;
using ICSharpCode.SharpDevelop.Dom; using ICSharpCode.SharpDevelop.Dom;
using ICSharpCode.SharpDevelop.Dom.Refactoring; using ICSharpCode.SharpDevelop.Dom.Refactoring;
@ -28,10 +29,10 @@ namespace ICSharpCode.SharpDevelop.Tests
Assert.AreEqual(2, cu.Classes.Count); Assert.AreEqual(2, cu.Classes.Count);
Assert.AreEqual(1, cu.Classes[0].Methods.Count + cu.Classes[0].Properties.Count); Assert.AreEqual(1, cu.Classes[0].Methods.Count + cu.Classes[0].Properties.Count);
IMember virtualMember; IMember virtualMember;
if (cu.Classes[0].Methods.Count > 0) if (cu.Classes[0].Properties.Count > 0)
virtualMember = cu.Classes[0].Methods[0];
else //if (cu.Classes[0].Properties.Count > 0)
virtualMember = cu.Classes[0].Properties[0]; virtualMember = cu.Classes[0].Properties[0];
else
virtualMember = cu.Classes[0].Methods[0];
CSharpCodeGenerator ccg = new CSharpCodeGenerator(); CSharpCodeGenerator ccg = new CSharpCodeGenerator();
AttributedNode result = ccg.GetOverridingMethod(virtualMember, new ClassFinder(cu.Classes[1], 3, 1)); AttributedNode result = ccg.GetOverridingMethod(virtualMember, new ClassFinder(cu.Classes[1], 3, 1));
Assert.IsNotNull(result); Assert.IsNotNull(result);

39
src/Main/Base/Test/NRefactoryResolverTests.cs

@ -579,11 +579,50 @@ class A {
IMethod m = (IMethod)result.ResolvedMember; IMethod m = (IMethod)result.ResolvedMember;
Assert.IsNotNull(m); Assert.IsNotNull(m);
Assert.AreEqual("A", result.ResolvedType.FullyQualifiedName); Assert.AreEqual("A", result.ResolvedType.FullyQualifiedName);
Assert.AreEqual(0, m.Parameters.Count);
var ar = result.GetCompletionData(result.CallingClass.ProjectContent); var ar = result.GetCompletionData(result.CallingClass.ProjectContent);
Assert.IsTrue(ContainsMember(ar, "A.Method")); Assert.IsTrue(ContainsMember(ar, "A.Method"));
} }
[Test]
public void DefaultStructCTorOverloadLookupTest()
{
string program = @"struct A {
void Method() {
}
public A(int x) {}
}
";
MemberResolveResult result = Resolve<MemberResolveResult>(program, "new A()", 3);
IMethod m = (IMethod)result.ResolvedMember;
Assert.IsNotNull(m);
Assert.AreEqual("A", result.ResolvedType.FullyQualifiedName);
Assert.AreEqual(0, m.Parameters.Count);
var ar = result.GetCompletionData(result.CallingClass.ProjectContent);
Assert.IsTrue(ContainsMember(ar, "A.Method"));
}
[Test]
public void ReflectionStructCTorOverloadLookupTest()
{
string program = @"using System;
class A {
void Method() {
}
}
";
MemberResolveResult result = Resolve<MemberResolveResult>(program, "new DateTime()", 4);
IMethod m = (IMethod)result.ResolvedMember;
Assert.IsNotNull(m);
Assert.AreEqual("System.DateTime", result.ResolvedType.FullyQualifiedName);
Assert.AreEqual(0, m.Parameters.Count);
}
[Test] [Test]
public void ValueInsideSetterTest() public void ValueInsideSetterTest()
{ {

16
src/Main/Base/Test/ReflectionLayerTests.cs

@ -171,6 +171,22 @@ namespace ICSharpCode.SharpDevelop.Tests
Assert.AreEqual("System.Void", prt.BaseType.FullyQualifiedName); Assert.AreEqual("System.Void", prt.BaseType.FullyQualifiedName);
} }
[Test]
public void DateTimeDefaultConstructor()
{
IClass c = mscorlib.GetClass("System.DateTime", 0);
Assert.IsFalse(c.Methods.Any(p => p.IsConstructor && p.Parameters.Count == 0));
Assert.IsTrue(c.GetAddDefaultConstructorIfRequired());
}
[Test]
public void NoEncodingInfoDefaultConstructor()
{
IClass c = mscorlib.GetClass("System.Text.EncodingInfo", 0);
Assert.IsFalse(c.Methods.Any(p => p.IsConstructor)); // EncodingInfo only has an internal constructor
Assert.IsFalse(c.GetAddDefaultConstructorIfRequired());
}
[Test] [Test]
public void ParameterComparisonTest() public void ParameterComparisonTest()
{ {

17
src/Main/Core/Project/Src/Services/FileUtility/FileUtility.cs

@ -131,6 +131,19 @@ namespace ICSharpCode.Core
} }
} }
static string windowsSdk70InstallRoot = null;
/// <summary>
/// Location of the .NET 3.5 SP1 SDK (Windows SDK 7.0) install root.
/// </summary>
public static string WindowsSdk70InstallRoot {
get {
if (windowsSdk70InstallRoot == null) {
windowsSdk70InstallRoot = GetPathFromRegistry(@"SOFTWARE\Microsoft\Microsoft SDKs\Windows\v7.0", "InstallationFolder") ?? string.Empty;
}
return windowsSdk70InstallRoot;
}
}
#endregion #endregion
public static string Combine(params string[] paths) public static string Combine(params string[] paths)
@ -187,6 +200,10 @@ namespace ICSharpCode.Core
/// <returns>The path of the executable, or null if the exe is not found.</returns> /// <returns>The path of the executable, or null if the exe is not found.</returns>
public static string GetSdkPath(string exeName) { public static string GetSdkPath(string exeName) {
string execPath; string execPath;
if (!string.IsNullOrEmpty(WindowsSdk70InstallRoot)) {
execPath = Path.Combine(WindowsSdk70InstallRoot, "bin\\" + exeName);
if (File.Exists(execPath)) { return execPath; }
}
if (!string.IsNullOrEmpty(WindowsSdk61InstallRoot)) { if (!string.IsNullOrEmpty(WindowsSdk61InstallRoot)) {
execPath = Path.Combine(WindowsSdk61InstallRoot, "bin\\" + exeName); execPath = Path.Combine(WindowsSdk61InstallRoot, "bin\\" + exeName);
if (File.Exists(execPath)) { return execPath; } if (File.Exists(execPath)) { return execPath; }

2
src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/CSharp/CSharpAmbience.cs

@ -534,6 +534,8 @@ namespace ICSharpCode.SharpDevelop.Dom.CSharp
static IReturnType GetElementType(IReturnType potentialArrayType) static IReturnType GetElementType(IReturnType potentialArrayType)
{ {
if (potentialArrayType == null)
return null;
ArrayReturnType result; ArrayReturnType result;
while ((result = potentialArrayType.CastToArrayReturnType()) != null) { while ((result = potentialArrayType.CastToArrayReturnType()) != null) {
potentialArrayType = result.ArrayElementType; potentialArrayType = result.ArrayElementType;

1
src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/CecilReader.cs

@ -324,6 +324,7 @@ namespace ICSharpCode.SharpDevelop.Dom
foreach (MethodDefinition method in type.Constructors) { foreach (MethodDefinition method in type.Constructors) {
AddMethod(method); AddMethod(method);
} }
this.AddDefaultConstructorIfRequired = (this.ClassType == ClassType.Struct || this.ClassType == ClassType.Enum);
foreach (MethodDefinition method in type.Methods) { foreach (MethodDefinition method in type.Methods) {
if (!method.IsSpecialName) { if (!method.IsSpecialName) {
AddMethod(method); AddMethod(method);

2
src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Implementations/CompoundClass.cs

@ -107,6 +107,8 @@ namespace ICSharpCode.SharpDevelop.Dom
this.Properties.AddRange(part.Properties); this.Properties.AddRange(part.Properties);
this.Events.AddRange(part.Events); this.Events.AddRange(part.Events);
this.Fields.AddRange(part.Fields); this.Fields.AddRange(part.Fields);
this.AddDefaultConstructorIfRequired |= part.GetAddDefaultConstructorIfRequired();
} }
this.CompilationUnit.FileName = shortestFileName; this.CompilationUnit.FileName = shortestFileName;
if ((modifier & ModifierEnum.VisibilityMask) == ModifierEnum.None) { if ((modifier & ModifierEnum.VisibilityMask) == ModifierEnum.None) {

28
src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Implementations/DefaultClass.cs

@ -12,7 +12,7 @@ using System.Threading;
namespace ICSharpCode.SharpDevelop.Dom namespace ICSharpCode.SharpDevelop.Dom
{ {
public class DefaultClass : AbstractEntity, IClass, IComparable public class DefaultClass : AbstractEntity, IClass2, IComparable
{ {
ClassType classType; ClassType classType;
DomRegion region; DomRegion region;
@ -64,13 +64,16 @@ namespace ICSharpCode.SharpDevelop.Dom
} }
*/ */
byte flags; byte flags = addDefaultConstructorIfRequiredFlag;
const byte calculatedFlagsReady = 0x01;
const byte hasPublicOrInternalStaticMembersFlag = 0x02; const byte hasPublicOrInternalStaticMembersFlag = 0x02;
const byte hasExtensionMethodsFlag = 0x04; const byte hasExtensionMethodsFlag = 0x04;
internal byte Flags { const byte addDefaultConstructorIfRequiredFlag = 0x08;
internal byte CalculatedFlags {
get { get {
if (flags == 0) { if ((flags & calculatedFlagsReady) == 0) {
flags = 1; flags |= calculatedFlagsReady;
foreach (IMember m in this.Fields) { foreach (IMember m in this.Fields) {
if (m.IsStatic && (m.IsPublic || m.IsInternal)) { if (m.IsStatic && (m.IsPublic || m.IsInternal)) {
flags |= hasPublicOrInternalStaticMembersFlag; flags |= hasPublicOrInternalStaticMembersFlag;
@ -112,12 +115,23 @@ namespace ICSharpCode.SharpDevelop.Dom
} }
public bool HasPublicOrInternalStaticMembers { public bool HasPublicOrInternalStaticMembers {
get { get {
return (Flags & hasPublicOrInternalStaticMembersFlag) == hasPublicOrInternalStaticMembersFlag; return (CalculatedFlags & hasPublicOrInternalStaticMembersFlag) == hasPublicOrInternalStaticMembersFlag;
} }
} }
public bool HasExtensionMethods { public bool HasExtensionMethods {
get { get {
return (Flags & hasExtensionMethodsFlag) == hasExtensionMethodsFlag; return (CalculatedFlags & hasExtensionMethodsFlag) == hasExtensionMethodsFlag;
}
}
public bool AddDefaultConstructorIfRequired {
get {
return (flags & addDefaultConstructorIfRequiredFlag) == addDefaultConstructorIfRequiredFlag;
}
set {
if (value)
flags |= addDefaultConstructorIfRequiredFlag;
else
flags &= unchecked((byte)~addDefaultConstructorIfRequiredFlag);
} }
} }

9
src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Implementations/DefaultMethod.cs

@ -7,6 +7,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Text; using System.Text;
namespace ICSharpCode.SharpDevelop.Dom namespace ICSharpCode.SharpDevelop.Dom
@ -36,7 +37,13 @@ namespace ICSharpCode.SharpDevelop.Dom
if (c == null) if (c == null)
throw new ArgumentNullException("c"); throw new ArgumentNullException("c");
Constructor con = new Constructor(ModifierEnum.Public, c.Region, c.Region, c); ModifierEnum modifiers = ModifierEnum.Synthetic;
if (c.IsAbstract)
modifiers |= ModifierEnum.Protected;
else
modifiers |= ModifierEnum.Public;
DomRegion region = new DomRegion(c.Region.BeginLine, c.Region.BeginColumn, c.Region.BeginLine, c.Region.BeginColumn);
Constructor con = new Constructor(modifiers, region, region, c);
con.Documentation = "Default constructor of " + c.Name; con.Documentation = "Default constructor of " + c.Name;
return con; return con;
} }

10
src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Implementations/DefaultReturnType.cs

@ -81,6 +81,16 @@ namespace ICSharpCode.SharpDevelop.Dom
using (var busyLock = busyManager.Enter(this)) { using (var busyLock = busyManager.Enter(this)) {
if (busyLock.Success) { if (busyLock.Success) {
l.AddRange(c.Methods); l.AddRange(c.Methods);
if (c.GetAddDefaultConstructorIfRequired() && !c.IsStatic) {
// A constructor is added for classes that do not have a default constructor;
// and for all structs.
if (c.ClassType == ClassType.Class && !l.Exists(m => m.IsConstructor)) {
l.Add(Constructor.CreateDefault(c));
} else if (c.ClassType == ClassType.Struct || c.ClassType == ClassType.Enum) {
l.Add(Constructor.CreateDefault(c));
}
}
if (c.ClassType == ClassType.Interface) { if (c.ClassType == ClassType.Interface) {
if (c.BaseTypes.Count == 0) { if (c.BaseTypes.Count == 0) {
AddMethodsFromBaseType(l, c.ProjectContent.SystemTypes.Object); AddMethodsFromBaseType(l, c.ProjectContent.SystemTypes.Object);

26
src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Interfaces/IClass.cs

@ -148,4 +148,30 @@ namespace ICSharpCode.SharpDevelop.Dom
///// </summary> ///// </summary>
//IClass Unfreeze(); //IClass Unfreeze();
} }
public interface IClass2 : IClass
{
/// <summary>
/// Gets whether a default constructor should be added to this class if it is required.
/// Such automatic default constructors will not appear in IClass.Methods, but will be present
/// in IClass.DefaultReturnType.GetMethods().
/// </summary>
/// <remarks>This way of creating the default constructor is necessary because
/// we cannot create it directly in the IClass - we need to consider partial classes.</remarks>
bool AddDefaultConstructorIfRequired {
get;
}
}
public static class Class2Compatibility
{
public static bool GetAddDefaultConstructorIfRequired(this IClass c)
{
IClass2 c2 = c as IClass2;
if (c2 != null)
return c2.AddDefaultConstructorIfRequired;
else
return false;
}
}
} }

5
src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/NRefactoryResolver/ResolveVisitor.cs

@ -444,11 +444,6 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
bool resultIsAcceptable; bool resultIsAcceptable;
IMethod result = MemberLookupHelper.FindOverload(methods, argumentTypes, out resultIsAcceptable); IMethod result = MemberLookupHelper.FindOverload(methods, argumentTypes, out resultIsAcceptable);
if (result == null) {
IClass c = rt.GetUnderlyingClass();
if (c != null)
result = Constructor.CreateDefault(c);
}
ResolveResult rr = CreateMemberResolveResult(result); ResolveResult rr = CreateMemberResolveResult(result);
if (rr != null) if (rr != null)
rr.ResolvedType = rt; rr.ResolvedType = rt;

6
src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/ReflectionLayer/DomPersistence.cs

@ -20,7 +20,7 @@ namespace ICSharpCode.SharpDevelop.Dom
{ {
public const long FileMagic = 0x11635233ED2F428C; public const long FileMagic = 0x11635233ED2F428C;
public const long IndexFileMagic = 0x11635233ED2F427D; public const long IndexFileMagic = 0x11635233ED2F427D;
public const short FileVersion = 24; public const short FileVersion = 25;
ProjectContentRegistry registry; ProjectContentRegistry registry;
string cacheDirectory; string cacheDirectory;
@ -384,7 +384,7 @@ namespace ICSharpCode.SharpDevelop.Dom
} }
writer.Write((int)c.Modifiers); writer.Write((int)c.Modifiers);
if (c is DefaultClass) { if (c is DefaultClass) {
writer.Write(((DefaultClass)c).Flags); writer.Write(((DefaultClass)c).CalculatedFlags);
} else { } else {
writer.Write((byte)0); writer.Write((byte)0);
} }
@ -453,7 +453,7 @@ namespace ICSharpCode.SharpDevelop.Dom
c.BaseTypes.Add(ReadType()); c.BaseTypes.Add(ReadType());
} }
c.Modifiers = (ModifierEnum)reader.ReadInt32(); c.Modifiers = (ModifierEnum)reader.ReadInt32();
c.Flags = reader.ReadByte(); c.CalculatedFlags = reader.ReadByte();
c.ClassType = (ClassType)reader.ReadByte(); c.ClassType = (ClassType)reader.ReadByte();
ReadAttributes(c); ReadAttributes(c);
count = reader.ReadInt32(); count = reader.ReadInt32();

1
src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/ReflectionLayer/ReflectionClass.cs

@ -55,6 +55,7 @@ namespace ICSharpCode.SharpDevelop.Dom.ReflectionLayer
Methods.Add(new ReflectionMethod(methodInfo, this)); Methods.Add(new ReflectionMethod(methodInfo, this));
} }
} }
this.AddDefaultConstructorIfRequired = (this.ClassType == ClassType.Struct || this.ClassType == ClassType.Enum);
foreach (EventInfo eventInfo in type.GetEvents(flags)) { foreach (EventInfo eventInfo in type.GetEvents(flags)) {
Events.Add(new ReflectionEvent(eventInfo, this)); Events.Add(new ReflectionEvent(eventInfo, this));

2
src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/VBNet/VBNetAmbience.cs

@ -552,6 +552,8 @@ namespace ICSharpCode.SharpDevelop.Dom.VBNet
static IReturnType GetElementType(IReturnType potentialArrayType) static IReturnType GetElementType(IReturnType potentialArrayType)
{ {
if (potentialArrayType == null)
return null;
ArrayReturnType result; ArrayReturnType result;
while ((result = potentialArrayType.CastToArrayReturnType()) != null) { while ((result = potentialArrayType.CastToArrayReturnType()) != null) {
potentialArrayType = result.ArrayElementType; potentialArrayType = result.ArrayElementType;

63
src/Main/ICSharpCode.SharpDevelop.Dom/Tests/ICSharpCode.SharpDevelop.Dom.Tests/NRefactoryAstConverterTests.cs

@ -6,6 +6,7 @@
// </file> // </file>
using System; using System;
using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.IO; using System.IO;
using ICSharpCode.NRefactory; using ICSharpCode.NRefactory;
@ -242,5 +243,67 @@ class Outer<T1> where T1 : IDisposable {
Assert.AreSame(inner.TypeParameters[1], method.TypeParameters[0].Constraints[0].CastToGenericReturnType().TypeParameter); Assert.AreSame(inner.TypeParameters[1], method.TypeParameters[0].Constraints[0].CastToGenericReturnType().TypeParameter);
} }
[Test]
public void DefaultConstructorTest()
{
ICompilationUnit cu = Parse("class X { }", SupportedLanguage.CSharp, true);
Assert.AreEqual(0, cu.Classes[0].Methods.Count);
IMethod ctor = cu.Classes[0].DefaultReturnType.GetMethods().Single(m => m.IsConstructor);
Assert.AreEqual(ModifierEnum.Public | ModifierEnum.Synthetic, ctor.Modifiers);
Assert.AreEqual(0, ctor.Parameters.Count);
}
[Test]
public void DefaultConstructorOnAbstractClassTest()
{
ICompilationUnit cu = Parse("abstract class X { }", SupportedLanguage.CSharp, true);
Assert.AreEqual(0, cu.Classes[0].Methods.Count);
IMethod ctor = cu.Classes[0].DefaultReturnType.GetMethods().Single(m => m.IsConstructor);
Assert.AreEqual(ModifierEnum.Protected | ModifierEnum.Synthetic, ctor.Modifiers);
Assert.AreEqual(0, ctor.Parameters.Count);
}
[Test]
public void NoDefaultConstructorWithExplicitConstructorTest()
{
ICompilationUnit cu = Parse("class X { private X(int a) {} }", SupportedLanguage.CSharp, true);
Assert.AreEqual(1, cu.Classes[0].Methods.Count);
IMethod ctor = cu.Classes[0].DefaultReturnType.GetMethods().Single(m => m.IsConstructor);
Assert.AreEqual(ModifierEnum.Private, ctor.Modifiers);
Assert.AreEqual(1, ctor.Parameters.Count);
}
[Test]
public void DefaultConstructorWithExplicitConstructorOnStructTest()
{
ICompilationUnit cu = Parse("struct X { private X(int a) {} }", SupportedLanguage.CSharp, true);
Assert.AreEqual(1, cu.Classes[0].Methods.Count);
List<IMethod> ctors = cu.Classes[0].DefaultReturnType.GetMethods().FindAll(m => m.IsConstructor);
Assert.AreEqual(2, ctors.Count);
Assert.AreEqual(ModifierEnum.Private, ctors[0].Modifiers);
Assert.AreEqual(1, ctors[0].Parameters.Count);
Assert.AreEqual(ModifierEnum.Public | ModifierEnum.Synthetic, ctors[1].Modifiers);
Assert.AreEqual(0, ctors[1].Parameters.Count);
}
[Test]
public void NoDefaultConstructorOnStaticClassTest()
{
ICompilationUnit cu = Parse("static class X { }", SupportedLanguage.CSharp, true);
Assert.AreEqual(0, cu.Classes[0].Methods.Count);
Assert.IsFalse(cu.Classes[0].DefaultReturnType.GetMethods().Any(m => m.IsConstructor));
}
} }
} }

Loading…
Cancel
Save