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. 5
      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. 7
      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. 2243
      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 @@ -418,16 +418,13 @@ namespace Grunwald.BooBinding.CodeCompletion
if (callingClass != null)
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
&& m.IsAccessible(callingClass, isClassInInheritanceTree))
{
methods.Add(m);
}
}
if (methods.Count == 0) {
methods.Add(ICSharpCode.SharpDevelop.Dom.Constructor.CreateDefault(trr.ResolvedClass));
}
ResolveInvocation(methods, node.Arguments);
if (resolveResult != null)
resolveResult.ResolvedType = trr.ResolvedType;

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

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

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

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

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

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

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

@ -0,0 +1,76 @@ @@ -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 @@ -51,6 +51,7 @@ namespace PythonBinding.Tests
Codon pythonProjectIconCodon;
Codon convertCSharpProjectCodon;
Codon convertVBNetProjectCodon;
Codon formattingStrategyCodon;
[TestFixtureSetUp]
public void SetupFixture()
@ -83,6 +84,7 @@ namespace PythonBinding.Tests @@ -83,6 +84,7 @@ namespace PythonBinding.Tests
pythonProjectIconCodon = GetCodon("/Workspace/Icons", "PythonProjectIcon");
convertCSharpProjectCodon = GetCodon("/SharpDevelop/Pads/ProjectBrowser/ContextMenu/ProjectActions/Convert", "CSharpProjectToPythonProjectConverter");
convertVBNetProjectCodon = GetCodon("/SharpDevelop/Pads/ProjectBrowser/ContextMenu/ProjectActions/Convert", "VBNetProjectToPythonProjectConverter");
formattingStrategyCodon = GetCodon("/AddIns/DefaultTextEditor/Formatter/Python", "PythonFormatter");
// Get the PythonBinding runtime.
foreach (Runtime runtime in addin.Runtimes) {
@ -750,6 +752,12 @@ namespace PythonBinding.Tests @@ -750,6 +752,12 @@ namespace PythonBinding.Tests
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)
{
return AddInHelper.GetCodon(addin, name, extensionPath);

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

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

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

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

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

@ -0,0 +1,205 @@ @@ -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 @@ -17,6 +17,7 @@ namespace PythonBinding.Tests.Utils
{
public MockTextEditorProperties()
{
FontContainer = new FontContainer(SystemFonts.MenuFont);
}
public bool CaretLine { get; set; }

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

@ -79,12 +79,17 @@ namespace ICSharpCode.Profiler.Controller.Data @@ -79,12 +79,17 @@ namespace ICSharpCode.Profiler.Controller.Data
/// </summary>
public abstract long CpuCyclesSpent { get; }
long cpuCyclesSpentSelf = -1;
/// <summary>
/// Gets how many CPU cycles were spent inside this method, excluding sub calls.
/// </summary>
public virtual long CpuCyclesSpentSelf {
get {
return GetCpuCyclesSelf();
if (cpuCyclesSpentSelf == -1)
cpuCyclesSpentSelf = GetCpuCyclesSelf();
return cpuCyclesSpentSelf;
}
}
@ -116,11 +121,19 @@ namespace ICSharpCode.Profiler.Controller.Data @@ -116,11 +121,19 @@ namespace ICSharpCode.Profiler.Controller.Data
/// <summary>
/// Determines whether this node is a thread node or not.
/// </summary>
public bool IsThread
{
public bool IsThread {
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>
/// Gets a readonly list of the string representation of the parameters.
/// </summary>
@ -136,6 +149,11 @@ namespace ICSharpCode.Profiler.Controller.Data @@ -136,6 +149,11 @@ namespace ICSharpCode.Profiler.Controller.Data
/// </summary>
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>
/// Gets a reference to the parent of this CallTreeNode.
/// </summary>

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

@ -59,39 +59,6 @@ namespace ICSharpCode.Profiler.Controller.Data @@ -59,39 +59,6 @@ namespace ICSharpCode.Profiler.Controller.Data
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)
{
SQLiteCommand cmd;
@ -115,6 +82,7 @@ namespace ICSharpCode.Profiler.Controller.Data @@ -115,6 +82,7 @@ namespace ICSharpCode.Profiler.Controller.Data
SQLiteCallTreeNode newItem = items.Find(node => node.nameId == childNameId);
if (newItem == null) {
newItem = new SQLiteCallTreeNode(childNameId, null, this);
newItem.selectionStartIndex = item.selectionStartIndex;
items.Add(newItem);
// works because of ORDER BY id
@ -293,6 +261,8 @@ namespace ICSharpCode.Profiler.Controller.Data @@ -293,6 +261,8 @@ namespace ICSharpCode.Profiler.Controller.Data
using (SQLiteDataReader reader = cmd.ExecuteReader()) {
SQLiteCallTreeNode root = new SQLiteCallTreeNode(0, null, this);
root.selectionStartIndex = startIndex;
while (reader.Read()) {
root.callCount += reader.GetInt32(2);
root.cpuCyclesSpent += (ulong)reader.GetInt64(3);
@ -304,6 +274,7 @@ namespace ICSharpCode.Profiler.Controller.Data @@ -304,6 +274,7 @@ namespace ICSharpCode.Profiler.Controller.Data
}
}
#region Properties
/// <inheritdoc/>
public override void SetProperty(string name, string value)
{
@ -350,6 +321,7 @@ namespace ICSharpCode.Profiler.Controller.Data @@ -350,6 +321,7 @@ namespace ICSharpCode.Profiler.Controller.Data
return null;
}
#endregion
int processorFrequency = -1;
@ -376,45 +348,54 @@ namespace ICSharpCode.Profiler.Controller.Data @@ -376,45 +348,54 @@ namespace ICSharpCode.Profiler.Controller.Data
/// <inheritdoc/>
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)
throw new ArgumentOutOfRangeException("startIndex", startIndex, "Value must be between 0 and " + endIndex);
if (endIndex < startIndex || endIndex >= this.DataSets.Count)
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;
using (LockAndCreateCommand(out cmd)) {
cmd.CommandText = @"SELECT GROUP_CONCAT(id), nameid, SUM(timespent), SUM(callcount)
FROM FunctionData
WHERE datasetid BETWEEN @start AND @end
GROUP BY nameid;";
cmd.Parameters.Add(new SQLiteParameter("@start", startIndex));
cmd.Parameters.Add(new SQLiteParameter("@end", endIndex));
cmd.CommandText = @"SELECT
GROUP_CONCAT(id),
nameid,
SUM(timespent),
SUM(callcount),
MAX(id != endid) AS hasChildren,
SUM((datasetid = " + startIndex + @") AND isActiveAtStart) AS activeCallCount
FROM FunctionData
WHERE " + condition + @"
GROUP BY nameid;";
using (SQLiteDataReader reader = cmd.ExecuteReader()) {
while (reader.Read()) {
SQLiteCallTreeNode node = new SQLiteCallTreeNode(reader.GetInt32(1), null, this);
node.selectionStartIndex = startIndex;
node.callCount = reader.GetInt32(3);
node.cpuCyclesSpent = (ulong)reader.GetInt64(2);
node.ids = reader.GetString(0).Split(',').Select(s => int.Parse(s)).ToList();
node.ids.Sort();
node.hasChildren = reader.GetBoolean(4);
node.activeCallCount = reader.GetInt32(5);
// Can not do filtering of root and thread nodes here,
// because retrieval of names needs access to DB
// which is forbidden now (we are inside the lock!)
functions.Add(node);
result.Add(node);
}
}
}
// Do filtering now via LINQ
return functions.SkipWhile(i => i.NameMapping.Id == 0 || i.NameMapping.Name.StartsWith("Thread#", StringComparison.Ordinal)).AsQueryable();
return result.AsQueryable();
}
*/

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

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

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

@ -99,5 +99,12 @@ namespace ICSharpCode.Profiler.Controller.Data @@ -99,5 +99,12 @@ namespace ICSharpCode.Profiler.Controller.Data
return unitTests.AsQueryable();
}
}
/// <inheritdoc/>
public override double TimeSpentSelf {
get {
return 0;
}
}
}
}

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

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

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

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

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

@ -190,16 +190,26 @@ namespace ICSharpCode.Profiler.Controls @@ -190,16 +190,26 @@ namespace ICSharpCode.Profiler.Controls
this.visibleColumnsSelection.ItemsSource = this.gridView.Columns.Select(col => new GridViewColumnModel(col));
this.treeView.SizeChanged += delegate(object sender, SizeChangedEventArgs e) {
if (e.NewSize.Width > 0 && e.PreviousSize.Width > 0 &&
(nameColumn.Width + (e.NewSize.Width - e.PreviousSize.Width)) > 0) {
double newValue = e.NewSize.Width - this.callCountColumn.Width
if (e.NewSize.Width > 0 && e.PreviousSize.Width > 0) {
double adjustedNameColumnWidth = nameColumn.Width + e.NewSize.Width - e.PreviousSize.Width;
double matchingNameColumnWidth = e.NewSize.Width - this.callCountColumn.Width
- this.percentColumn.Width - this.timeSpentColumn.Width
- this.timeSpentSelfColumn.Width - this.timeSpentPerCallColumn.Width
- this.timeSpentSelfPerCallColumn.Width;
if ((nameColumn.Width + (e.NewSize.Width - e.PreviousSize.Width)) >= newValue)
this.nameColumn.Width = newValue - 25;
else
nameColumn.Width += (e.NewSize.Width - e.PreviousSize.Width);
- this.timeSpentSelfPerCallColumn.Width - 25;
// always keep name column at least 75 pixels wide
if (matchingNameColumnWidth < 75)
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 @@ -332,17 +342,17 @@ namespace ICSharpCode.Profiler.Controls
void BtnExpandHotPathSubtreeClick(object sender, RoutedEventArgs e)
{
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;
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) @@ -528,8 +528,10 @@ bool SignatureReader::ReadCompressedInt(int *out)
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 };
// public key token: b03f5f7f11d50a3a
const byte systemdrawingkey[] = {
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,
@ -543,6 +545,20 @@ const byte systemdrawingkey[] = { @@ -543,6 +545,20 @@ const byte systemdrawingkey[] = {
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)
{
@ -567,6 +583,8 @@ bool SignatureReader::IsNetInternal(FunctionID fid) @@ -567,6 +583,8 @@ bool SignatureReader::IsNetInternal(FunctionID fid)
return true;
if (pKLength == sizeof(systemdrawingkey) && memcmp(systemdrawingkey, b, sizeof(systemdrawingkey)) == 0)
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 @@ -503,9 +503,7 @@ namespace ICSharpCode.NRefactory.Parser.CSharp
string val = la.val;
return (cur == Tokens.Event || cur == Tokens.Return ||
(Tokens.IdentifierTokens[cur] &&
(val == "field" || val == "method" || val == "module" ||
val == "param" || val == "property" || val == "type"))) &&
Tokens.IdentifierTokens[cur]) &&
Peek(1).kind == Tokens.Colon;
}
@ -551,8 +549,9 @@ namespace ICSharpCode.NRefactory.Parser.CSharp @@ -551,8 +549,9 @@ namespace ICSharpCode.NRefactory.Parser.CSharp
TypeReference targetType = GetTypeReferenceFromExpression(member.TargetObject);
if (targetType != null) {
if (targetType.GenericTypes.Count == 0 && targetType.IsArrayType == false) {
TypeReference tr = new TypeReference(targetType.Type + "." + member.MemberName, member.TypeArguments);
tr.IsGlobal = targetType.IsGlobal;
TypeReference tr = targetType.Clone();
tr.Type = tr.Type + "." + member.MemberName;
tr.GenericTypes.AddRange(member.TypeArguments);
return tr;
} else {
return new InnerClassTypeReference(targetType, member.MemberName, member.TypeArguments);

2243
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> @@ -297,12 +297,7 @@ AttributeSection<out AttributeSection section>
[ IF (IsLocalAttrTarget())
( "event" (. attributeTarget = "event";.)
| "return" (. attributeTarget = "return";.)
| Identifier (. if (t.val != "field" && t.val != "method" &&
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;
.)
| Identifier (. attributeTarget = t.val; .)
) ":"
]
/*--- attribute list: */

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

@ -117,6 +117,47 @@ namespace ICSharpCode.NRefactory.Tests.Ast @@ -117,6 +117,47 @@ namespace ICSharpCode.NRefactory.Tests.Ast
Assert.AreEqual(new Location(4, 1), mre.TargetObject.StartLocation);
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
#region VB.NET
@ -145,6 +186,49 @@ namespace ICSharpCode.NRefactory.Tests.Ast @@ -145,6 +186,49 @@ namespace ICSharpCode.NRefactory.Tests.Ast
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
}
}

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

@ -179,6 +179,28 @@ public abstract class MyClass : MyBase, Interface1, My.Test.Interface2 @@ -179,6 +179,28 @@ public abstract class MyClass : MyBase, Interface1, My.Test.Interface2
Assert.AreEqual(ClassType.Enum, td.Type);
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
#region VB.NET

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

@ -33,7 +33,7 @@ namespace ICSharpCode.SharpDevelop.Refactoring @@ -33,7 +33,7 @@ namespace ICSharpCode.SharpDevelop.Refactoring
} else if (!IsSystemNamespace(u1) && IsSystemNamespace(u2)) {
return 1;
}
return a.Usings[0].CompareTo(b.Usings[0]);
return u1.CompareTo(u2);
}
if (a.Aliases.Count != 0 && b.Aliases.Count != 0) {
return a.Aliases.Keys.First().CompareTo(b.Aliases.Keys.First());
@ -96,6 +96,17 @@ namespace ICSharpCode.SharpDevelop.Refactoring @@ -96,6 +96,17 @@ namespace ICSharpCode.SharpDevelop.Refactoring
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);
newUsingDecl.Usings.Add(newNamespace);
@ -105,9 +116,7 @@ namespace ICSharpCode.SharpDevelop.Refactoring @@ -105,9 +116,7 @@ namespace ICSharpCode.SharpDevelop.Refactoring
}
bool inserted = false;
for (int i = 0; i < newUsings.Count; i++) {
if (newUsings[i].Usings.Count >= 1
&& cu.ProjectContent.Language.NameComparer.Compare(newNamespace, newUsings[i].Usings[0]) <= 0)
{
if (CompareUsings(newUsingDecl, newUsings[i]) <= 0) {
newUsings.Insert(i, newUsingDecl);
inserted = true;
break;

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

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

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

@ -52,7 +52,7 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Commands @@ -52,7 +52,7 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Commands
member.DeclaringType.ProjectContent.Language.CodeGenerator != null
&& !FindReferencesAndRenameHelper.IsReadOnly(member.DeclaringType);
if (method == null || !method.IsConstructor) {
if (method == null || !method.IsConstructor && !method.IsOperator) {
if (!FindReferencesAndRenameHelper.IsReadOnly(member.DeclaringType) &&
!(member is IProperty && ((IProperty)member).IsIndexer)) {
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 @@ -144,11 +144,6 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor
if (trr != null || expressionResult.Context == ExpressionContext.BaseConstructorCall) {
if (results.ResolvedType != null) {
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 {

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

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

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

@ -579,11 +579,50 @@ class A { @@ -579,11 +579,50 @@ class A {
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 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]
public void ValueInsideSetterTest()
{

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

@ -171,6 +171,22 @@ namespace ICSharpCode.SharpDevelop.Tests @@ -171,6 +171,22 @@ namespace ICSharpCode.SharpDevelop.Tests
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]
public void ParameterComparisonTest()
{

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

@ -131,6 +131,19 @@ namespace ICSharpCode.Core @@ -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
public static string Combine(params string[] paths)
@ -187,6 +200,10 @@ namespace ICSharpCode.Core @@ -187,6 +200,10 @@ namespace ICSharpCode.Core
/// <returns>The path of the executable, or null if the exe is not found.</returns>
public static string GetSdkPath(string exeName) {
string execPath;
if (!string.IsNullOrEmpty(WindowsSdk70InstallRoot)) {
execPath = Path.Combine(WindowsSdk70InstallRoot, "bin\\" + exeName);
if (File.Exists(execPath)) { return execPath; }
}
if (!string.IsNullOrEmpty(WindowsSdk61InstallRoot)) {
execPath = Path.Combine(WindowsSdk61InstallRoot, "bin\\" + exeName);
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 @@ -534,6 +534,8 @@ namespace ICSharpCode.SharpDevelop.Dom.CSharp
static IReturnType GetElementType(IReturnType potentialArrayType)
{
if (potentialArrayType == null)
return null;
ArrayReturnType result;
while ((result = potentialArrayType.CastToArrayReturnType()) != null) {
potentialArrayType = result.ArrayElementType;

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

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

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

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

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

@ -12,7 +12,7 @@ using System.Threading; @@ -12,7 +12,7 @@ using System.Threading;
namespace ICSharpCode.SharpDevelop.Dom
{
public class DefaultClass : AbstractEntity, IClass, IComparable
public class DefaultClass : AbstractEntity, IClass2, IComparable
{
ClassType classType;
DomRegion region;
@ -64,13 +64,16 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -64,13 +64,16 @@ namespace ICSharpCode.SharpDevelop.Dom
}
*/
byte flags;
byte flags = addDefaultConstructorIfRequiredFlag;
const byte calculatedFlagsReady = 0x01;
const byte hasPublicOrInternalStaticMembersFlag = 0x02;
const byte hasExtensionMethodsFlag = 0x04;
internal byte Flags {
const byte addDefaultConstructorIfRequiredFlag = 0x08;
internal byte CalculatedFlags {
get {
if (flags == 0) {
flags = 1;
if ((flags & calculatedFlagsReady) == 0) {
flags |= calculatedFlagsReady;
foreach (IMember m in this.Fields) {
if (m.IsStatic && (m.IsPublic || m.IsInternal)) {
flags |= hasPublicOrInternalStaticMembersFlag;
@ -112,12 +115,23 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -112,12 +115,23 @@ namespace ICSharpCode.SharpDevelop.Dom
}
public bool HasPublicOrInternalStaticMembers {
get {
return (Flags & hasPublicOrInternalStaticMembersFlag) == hasPublicOrInternalStaticMembersFlag;
return (CalculatedFlags & hasPublicOrInternalStaticMembersFlag) == hasPublicOrInternalStaticMembersFlag;
}
}
public bool HasExtensionMethods {
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 @@ @@ -7,6 +7,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ICSharpCode.SharpDevelop.Dom
@ -36,7 +37,13 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -36,7 +37,13 @@ namespace ICSharpCode.SharpDevelop.Dom
if (c == null)
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;
return con;
}

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

@ -81,6 +81,16 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -81,6 +81,16 @@ namespace ICSharpCode.SharpDevelop.Dom
using (var busyLock = busyManager.Enter(this)) {
if (busyLock.Success) {
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.BaseTypes.Count == 0) {
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 @@ -148,4 +148,30 @@ namespace ICSharpCode.SharpDevelop.Dom
///// </summary>
//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 @@ -444,11 +444,6 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
bool 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);
if (rr != null)
rr.ResolvedType = rt;

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

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

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

@ -55,6 +55,7 @@ namespace ICSharpCode.SharpDevelop.Dom.ReflectionLayer @@ -55,6 +55,7 @@ namespace ICSharpCode.SharpDevelop.Dom.ReflectionLayer
Methods.Add(new ReflectionMethod(methodInfo, this));
}
}
this.AddDefaultConstructorIfRequired = (this.ClassType == ClassType.Struct || this.ClassType == ClassType.Enum);
foreach (EventInfo eventInfo in type.GetEvents(flags)) {
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 @@ -552,6 +552,8 @@ namespace ICSharpCode.SharpDevelop.Dom.VBNet
static IReturnType GetElementType(IReturnType potentialArrayType)
{
if (potentialArrayType == null)
return null;
ArrayReturnType result;
while ((result = potentialArrayType.CastToArrayReturnType()) != null) {
potentialArrayType = result.ArrayElementType;

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

@ -6,6 +6,7 @@ @@ -6,6 +6,7 @@
// </file>
using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using ICSharpCode.NRefactory;
@ -242,5 +243,67 @@ class Outer<T1> where T1 : IDisposable { @@ -242,5 +243,67 @@ class Outer<T1> where T1 : IDisposable {
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