Browse Source

NRefactoryResolver rewrite: remove code duplication between NRefactoryResolver and TypeVisitor. Changed handling of method groups to follow C# specification more closely.

This fixes several bugs in overload resolution.

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@2819 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
Daniel Grunwald 19 years ago
parent
commit
9b4679edf1
  1. 2
      doc/copyright.txt
  2. 2
      samples/CSharpCodeCompletion/MainForm.cs
  3. 14
      samples/CSharpCodeCompletion/ToolTipProvider.cs
  4. 14
      src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/CodeCompletion/ResolveVisitor.cs
  5. 2
      src/AddIns/BackendBindings/Boo/BooBinding/Test/ResolverTests.cs
  6. 2
      src/AddIns/BackendBindings/Boo/NRefactoryToBooConverter/Project/ConvertVisitorExpressions.cs
  7. 4
      src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/NRefactoryToPythonConverter.cs
  8. 6
      src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonResolver.cs
  9. 4
      src/AddIns/BackendBindings/Python/PythonBinding/Test/Resolver/ResolveConsoleWriteLineTestFixture.cs
  10. 2
      src/AddIns/BackendBindings/XamlBinding/Project/Src/XamlResolver.cs
  11. 8
      src/AddIns/Misc/HtmlHelp2/Project/src/BaseControls/DynamicHelpPad.cs
  12. 6
      src/AddIns/Misc/ResourceToolkit/Project/Src/Resolver/BclNRefactoryResourceResolver.cs
  13. 4
      src/AddIns/Misc/ResourceToolkit/Project/Src/Resolver/ICSharpCodeCoreNRefactoryResourceResolver.cs
  14. 5
      src/AddIns/Misc/ResourceToolkit/Project/Src/Resolver/ResourceResolveResult.cs
  15. 39
      src/Libraries/ICSharpCode.TextEditor/Project/Src/Gui/TextArea.cs
  16. 5
      src/Libraries/NRefactory/NRefactoryASTGenerator/AST/Expressions.cs
  17. 46
      src/Libraries/NRefactory/Project/Src/Ast/Generated.cs
  18. 2
      src/Libraries/NRefactory/Project/Src/IAstVisitor.cs
  19. 4
      src/Libraries/NRefactory/Project/Src/Parser/CSharp/CSharpParser.cs
  20. 2
      src/Libraries/NRefactory/Project/Src/Parser/VBNet/VBNetParser.cs
  21. 4
      src/Libraries/NRefactory/Project/Src/PrettyPrinter/CSharp/CSharpOutputVisitor.cs
  22. 2
      src/Libraries/NRefactory/Project/Src/PrettyPrinter/VBNet/VBNetOutputVisitor.cs
  23. 2
      src/Libraries/NRefactory/Project/Src/Visitors/AbstractASTVisitor.cs
  24. 2
      src/Libraries/NRefactory/Project/Src/Visitors/AbstractAstTransformer.cs
  25. 2
      src/Libraries/NRefactory/Project/Src/Visitors/CSharpConstructsConvertVisitor.cs
  26. 22
      src/Libraries/NRefactory/Project/Src/Visitors/CodeDOMOutputVisitor.cs
  27. 2
      src/Libraries/NRefactory/Project/Src/Visitors/NodeTrackingAstVisitor.cs
  28. 4
      src/Libraries/NRefactory/Project/Src/Visitors/PrefixFieldsVisitor.cs
  29. 4
      src/Libraries/NRefactory/Project/Src/Visitors/ToVBNetConvertVisitor.cs
  30. 4
      src/Libraries/NRefactory/Project/Src/Visitors/VBNetConstructsConvertVisitor.cs
  31. 6
      src/Libraries/NRefactory/Test/Output/CSharp/CSharpOutputTest.cs
  32. 8
      src/Libraries/NRefactory/Test/Parser/Expressions/IdentifierExpressionTests.cs
  33. 22
      src/Libraries/NRefactory/Test/Parser/Expressions/MemberReferenceExpressionTests.cs
  34. 2
      src/Libraries/NRefactory/Test/Parser/Expressions/PrimitiveExpressionTests.cs
  35. 12
      src/Libraries/NRefactory/Test/Parser/Expressions/TypeReferenceExpressionTests.cs
  36. 18
      src/Main/Base/Project/Src/Gui/Pads/DefinitionViewPad.cs
  37. 4
      src/Main/Base/Project/Src/Services/Debugger/DebuggerService.cs
  38. 4
      src/Main/Base/Project/Src/Services/RefactoringService/RefactorMenu.cs
  39. 5
      src/Main/Base/Project/Src/Services/RefactoringService/RefactoringMenuBuilder.cs
  40. 9
      src/Main/Base/Project/Src/Services/RefactoringService/RefactoringService.cs
  41. 8
      src/Main/Base/Project/Src/TextEditor/Gui/Editor/InsightWindow/MethodInsightDataProvider.cs
  42. 3
      src/Main/Base/Project/Src/TextEditor/Gui/Editor/TextEditorDisplayBinding.cs
  43. 40
      src/Main/Base/Test/CSharpExpressionFinderTests.cs
  44. 36
      src/Main/Base/Test/GenericResolverTests.cs
  45. 18
      src/Main/Base/Test/InnerClassesResolverTests.cs
  46. 271
      src/Main/Base/Test/NRefactoryResolverTests.cs
  47. 3
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/ICSharpCode.SharpDevelop.Dom.csproj
  48. 54
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/CSharp/ExpressionFinder.cs
  49. 5
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Implementations/AbstractReturnType.cs
  50. 8
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Implementations/ConstructedReturnType.cs
  51. 10
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Implementations/DefaultReturnType.cs
  52. 18
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Implementations/GenericReturnType.cs
  53. 2
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Interfaces/IDecoration.cs
  54. 6
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/LanguageProperties.cs
  55. 231
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/MemberLookupHelper.cs
  56. 4
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/NRefactoryResolver/CSharpToVBNetConvertVisitor.cs
  57. 328
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/NRefactoryResolver/NRefactoryResolver.cs
  58. 570
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/NRefactoryResolver/ResolveVisitor.cs
  59. 602
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/NRefactoryResolver/TypeVisitor.cs
  60. 12
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/NRefactoryResolver/VBNetToCSharpConvertVisitor.cs
  61. 154
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/ResolveResult.cs
  62. 2
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/VBNet/VBNetAmbience.cs

2
doc/copyright.txt

@ -1,4 +1,4 @@ @@ -1,4 +1,4 @@
Copyright 2002-2007 by
Copyright 2002-2008 by
AlphaSierraPapa, Christoph Wille
Vordernberger Strasse 27/8

2
samples/CSharpCodeCompletion/MainForm.cs

@ -64,7 +64,7 @@ namespace CSharpEditor @@ -64,7 +64,7 @@ namespace CSharpEditor
/// </summary>
public const string DummyFileName = "edited.cs";
static readonly Dom.LanguageProperties CurrentLanguageProperties = Dom.LanguageProperties.CSharp;
static readonly Dom.LanguageProperties CurrentLanguageProperties = IsVisualBasic ? Dom.LanguageProperties.VBNet : Dom.LanguageProperties.CSharp;
public MainForm()
{

14
samples/CSharpCodeCompletion/ToolTipProvider.cs

@ -29,6 +29,7 @@ using System; @@ -29,6 +29,7 @@ using System;
using System.Text;
using ICSharpCode.SharpDevelop.Dom;
using ICSharpCode.SharpDevelop.Dom.CSharp;
using ICSharpCode.SharpDevelop.Dom.VBNet;
using TextEditor = ICSharpCode.TextEditor;
using NRefactoryResolver = ICSharpCode.SharpDevelop.Dom.NRefactoryResolver.NRefactoryResolver;
@ -54,7 +55,12 @@ namespace CSharpEditor @@ -54,7 +55,12 @@ namespace CSharpEditor
void OnToolTipRequest(object sender, TextEditor.ToolTipRequestEventArgs e)
{
if (e.InDocument && !e.ToolTipShown) {
CSharpExpressionFinder expressionFinder = new CSharpExpressionFinder(mainForm.parseInformation);
IExpressionFinder expressionFinder;
if (MainForm.IsVisualBasic) {
expressionFinder = new VBExpressionFinder();
} else {
expressionFinder = new CSharpExpressionFinder(mainForm.parseInformation);
}
ExpressionResult expression = expressionFinder.FindFullExpression(
editor.Text,
editor.Document.PositionToOffset(e.LogicalPosition));
@ -78,7 +84,7 @@ namespace CSharpEditor @@ -78,7 +84,7 @@ namespace CSharpEditor
}
if (result is MixedResolveResult)
return GetText(((MixedResolveResult)result).PrimaryResult);
IAmbience ambience = new CSharpAmbience();
IAmbience ambience = MainForm.IsVisualBasic ? (IAmbience)new VBNetAmbience() : new CSharpAmbience();
ambience.ConversionFlags = ConversionFlags.StandardConversionFlags | ConversionFlags.ShowAccessibility;
if (result is MemberResolveResult) {
return GetMemberText(ambience, ((MemberResolveResult)result).ResolvedMember);
@ -101,8 +107,8 @@ namespace CSharpEditor @@ -101,8 +107,8 @@ namespace CSharpEditor
return GetMemberText(ambience, c);
else
return ambience.Convert(result.ResolvedType);
} else if (result is MethodResolveResult) {
MethodResolveResult mrr = result as MethodResolveResult;
} else if (result is MethodGroupResolveResult) {
MethodGroupResolveResult mrr = result as MethodGroupResolveResult;
IMethod m = mrr.GetMethodIfSingleOverload();
if (m != null)
return GetMemberText(ambience, m);

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

@ -89,8 +89,8 @@ namespace Grunwald.BooBinding.CodeCompletion @@ -89,8 +89,8 @@ namespace Grunwald.BooBinding.CodeCompletion
void MakeMethodResult(IReturnType type, string methodName)
{
resolveResult = new MethodResolveResult(callingClass, resolver.CallingMember, type, methodName);
IMethod m = (resolveResult as MethodResolveResult).GetMethodIfSingleOverload();
resolveResult = new MethodGroupResolveResult(callingClass, resolver.CallingMember, type, methodName);
IMethod m = (resolveResult as MethodGroupResolveResult).GetMethodIfSingleOverload();
if (m != null) {
AnonymousMethodReturnType amrt = new AnonymousMethodReturnType(cu);
amrt.MethodReturnType = m.ReturnType;
@ -389,7 +389,7 @@ namespace Grunwald.BooBinding.CodeCompletion @@ -389,7 +389,7 @@ namespace Grunwald.BooBinding.CodeCompletion
MixedResolveResult mixed = (MixedResolveResult)resolveResult;
resolveResult = mixed.TypeResult;
foreach (ResolveResult rr in mixed.Results) {
if (rr is MethodResolveResult) {
if (rr is MethodGroupResolveResult) {
resolveResult = rr;
break;
}
@ -398,10 +398,10 @@ namespace Grunwald.BooBinding.CodeCompletion @@ -398,10 +398,10 @@ namespace Grunwald.BooBinding.CodeCompletion
if (resolveResult == null)
return;
if (resolveResult is MethodResolveResult) {
if (resolveResult is MethodGroupResolveResult) {
// normal method call
string methodName = ((MethodResolveResult)resolveResult).Name;
IReturnType containingType = ((MethodResolveResult)resolveResult).ContainingType;
string methodName = ((MethodGroupResolveResult)resolveResult).Name;
IReturnType containingType = ((MethodGroupResolveResult)resolveResult).ContainingType;
ResolveMethodInType(containingType, methodName, node.Arguments);
} else if (resolveResult is TypeResolveResult) {
@ -513,7 +513,7 @@ namespace Grunwald.BooBinding.CodeCompletion @@ -513,7 +513,7 @@ namespace Grunwald.BooBinding.CodeCompletion
ClearResult();
}
bool resultIsAcceptable;
MakeResult(MemberLookupHelper.FindOverload(methods, new IReturnType[0], types, out resultIsAcceptable));
MakeResult(MemberLookupHelper.FindOverload(methods, types, out resultIsAcceptable));
}
#endregion

2
src/AddIns/BackendBindings/Boo/BooBinding/Test/ResolverTests.cs

@ -226,7 +226,7 @@ namespace Grunwald.BooBinding.Tests @@ -226,7 +226,7 @@ namespace Grunwald.BooBinding.Tests
[Test]
public void MyMethodCompletion()
{
MethodResolveResult rr = Resolve<MethodResolveResult>(regressionProg, "MyMethod", "/*1*/");
MethodGroupResolveResult rr = Resolve<MethodGroupResolveResult>(regressionProg, "MyMethod", "/*1*/");
ArrayList arr = rr.GetCompletionData(lastPC);
Assert.IsNotNull(arr);
bool beginInvoke = false;

2
src/AddIns/BackendBindings/Boo/NRefactoryToBooConverter/Project/ConvertVisitorExpressions.cs

@ -146,7 +146,7 @@ namespace NRefactoryToBooConverter @@ -146,7 +146,7 @@ namespace NRefactoryToBooConverter
target = (B.Expression)mre.TargetObject.AcceptVisitor(this, data);
if (target == null) return null;
}
return new B.MemberReferenceExpression(GetLexicalInfo(mre), target, mre.FieldName);
return new B.MemberReferenceExpression(GetLexicalInfo(mre), target, mre.MemberName);
}
public object VisitClassReferenceExpression(ClassReferenceExpression classReferenceExpression, object data)

4
src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/NRefactoryToPythonConverter.cs

@ -700,7 +700,7 @@ namespace ICSharpCode.PythonBinding @@ -700,7 +700,7 @@ namespace ICSharpCode.PythonBinding
// Create method ref.
CodeMethodReferenceExpression methodRef = new CodeMethodReferenceExpression();
methodRef.MethodName = memberRefExpression.FieldName;
methodRef.MethodName = memberRefExpression.MemberName;
methodRef.TargetObject = targetObjectExpression;
// Create method invoke.
@ -1147,7 +1147,7 @@ namespace ICSharpCode.PythonBinding @@ -1147,7 +1147,7 @@ namespace ICSharpCode.PythonBinding
public object VisitMemberReferenceExpression(MemberReferenceExpression memberReferenceExpression, object data)
{
CodeFieldReferenceExpression codeFieldReferenceExpression = new CodeFieldReferenceExpression();
codeFieldReferenceExpression.FieldName = memberReferenceExpression.FieldName;
codeFieldReferenceExpression.FieldName = memberReferenceExpression.MemberName;
codeFieldReferenceExpression.TargetObject = (CodeExpression)memberReferenceExpression.TargetObject.AcceptVisitor(this, data);
return codeFieldReferenceExpression;
}

6
src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonResolver.cs

@ -47,7 +47,7 @@ namespace ICSharpCode.PythonBinding @@ -47,7 +47,7 @@ namespace ICSharpCode.PythonBinding
}
// Search for a method.
MethodResolveResult resolveResult = GetMethodResolveResult(expressionResult.Expression);
MethodGroupResolveResult resolveResult = GetMethodResolveResult(expressionResult.Expression);
if (resolveResult != null) {
return resolveResult;
}
@ -246,7 +246,7 @@ namespace ICSharpCode.PythonBinding @@ -246,7 +246,7 @@ namespace ICSharpCode.PythonBinding
/// <summary>
/// Tries to resolve a method in the expression.
/// </summary>
MethodResolveResult GetMethodResolveResult(string expression)
MethodGroupResolveResult GetMethodResolveResult(string expression)
{
// Remove last part of the expression and try to
// find this class.
@ -256,7 +256,7 @@ namespace ICSharpCode.PythonBinding @@ -256,7 +256,7 @@ namespace ICSharpCode.PythonBinding
IClass matchingClass = GetClass(className);
if (matchingClass != null) {
string methodName = GetMethodName(expression);
return new MethodResolveResult(null, null, matchingClass.DefaultReturnType, methodName);
return new MethodGroupResolveResult(null, null, matchingClass.DefaultReturnType, methodName);
}
}
return null;

4
src/AddIns/BackendBindings/Python/PythonBinding/Test/Resolver/ResolveConsoleWriteLineTestFixture.cs

@ -27,7 +27,7 @@ namespace PythonBinding.Tests.Resolver @@ -27,7 +27,7 @@ namespace PythonBinding.Tests.Resolver
ResolveResult resolveResult;
ICompilationUnit compilationUnit;
MockClass systemConsoleClass;
MethodResolveResult methodResolveResult;
MethodGroupResolveResult methodResolveResult;
[TestFixtureSetUp]
public void SetUpFixture()
@ -47,7 +47,7 @@ namespace PythonBinding.Tests.Resolver @@ -47,7 +47,7 @@ namespace PythonBinding.Tests.Resolver
"Console.WriteLine\r\n";
ExpressionResult expressionResult = new ExpressionResult("Console.WriteLine", new DomRegion(2, 2), null, null);
resolveResult = resolver.Resolve(expressionResult, parseInfo, python);
methodResolveResult = resolveResult as MethodResolveResult;
methodResolveResult = resolveResult as MethodGroupResolveResult;
}
[Test]

2
src/AddIns/BackendBindings/XamlBinding/Project/Src/XamlResolver.cs

@ -146,7 +146,7 @@ namespace XamlBinding @@ -146,7 +146,7 @@ namespace XamlBinding
if (propertyOrEvent == null)
return null;
if (propertyOrEvent is IEvent) {
return new MethodResolveResult(callingClass, null, callingClass.DefaultReturnType, expression);
return new MethodGroupResolveResult(callingClass, null, callingClass.DefaultReturnType, expression);
}
if (propertyOrEvent.Name == "Name") {

8
src/AddIns/Misc/HtmlHelp2/Project/src/BaseControls/DynamicHelpPad.cs

@ -165,10 +165,10 @@ namespace HtmlHelp2 @@ -165,10 +165,10 @@ namespace HtmlHelp2
this.AddToStringCollection(res.ResolvedType.FullyQualifiedName);
}
MemberResolveResult member = res as MemberResolveResult;
NamespaceResolveResult nspace = res as NamespaceResolveResult;
MethodResolveResult method = res as MethodResolveResult;
TypeResolveResult types = res as TypeResolveResult;
MemberResolveResult member = res as MemberResolveResult;
NamespaceResolveResult nspace = res as NamespaceResolveResult;
MethodGroupResolveResult method = res as MethodGroupResolveResult;
TypeResolveResult types = res as TypeResolveResult;
if (member != null && member.ResolvedMember != null)
{

6
src/AddIns/Misc/ResourceToolkit/Project/Src/Resolver/BclNRefactoryResourceResolver.cs

@ -63,7 +63,7 @@ namespace Hornung.ResourceToolkit.Resolver @@ -63,7 +63,7 @@ namespace Hornung.ResourceToolkit.Resolver
// (MemberResolveResult) to the method reference by passing '(' as
// charTyped explicitly.
MethodResolveResult methrr = resolveResult as MethodResolveResult;
MethodGroupResolveResult methrr = resolveResult as MethodGroupResolveResult;
if (methrr != null) {
if ((methrr.Name == "GetString" || methrr.Name == "GetObject" || methrr.Name == "GetStream") &&
(resolveResult = NRefactoryAstCacheService.ResolveNextOuterExpression(ref expressionResult, caretLine, caretColumn, fileName, expressionFinder)) != null) {
@ -108,7 +108,7 @@ namespace Hornung.ResourceToolkit.Resolver @@ -108,7 +108,7 @@ namespace Hornung.ResourceToolkit.Resolver
if ((resolveResult = NRefactoryAstCacheService.ResolveNextOuterExpression(ref expressionResult, caretLine, caretColumn, fileName, expressionFinder)) != null) {
if (resolveResult is MethodResolveResult) {
if (resolveResult is MethodGroupResolveResult) {
return this.Resolve(expressionResult, expr, resolveResult, caretLine, caretColumn, fileName, fileContent, expressionFinder, '(');
} else {
return ResolveResource(resolveResult, expr);
@ -689,7 +689,7 @@ namespace Hornung.ResourceToolkit.Resolver @@ -689,7 +689,7 @@ namespace Hornung.ResourceToolkit.Resolver
if (invocation != null) {
MemberReferenceExpression fre = invocation.TargetObject as MemberReferenceExpression;
if (fre != null) {
if (fre.FieldName == "GetString" || fre.FieldName == "GetObject" || fre.FieldName == "GetStream") {
if (fre.MemberName == "GetString" || fre.MemberName == "GetObject" || fre.MemberName == "GetStream") {
if (invocation.Arguments.Count > 0) {
PrimitiveExpression p = invocation.Arguments[0] as PrimitiveExpression;
if (p != null) {

4
src/AddIns/Misc/ResourceToolkit/Project/Src/Resolver/ICSharpCodeCoreNRefactoryResourceResolver.cs

@ -56,7 +56,7 @@ namespace Hornung.ResourceToolkit.Resolver @@ -56,7 +56,7 @@ namespace Hornung.ResourceToolkit.Resolver
} else {
MethodResolveResult methrr = resolveResult as MethodResolveResult;
MethodGroupResolveResult methrr = resolveResult as MethodGroupResolveResult;
if (methrr != null) {
// If it is a MethodResolveResult, the expression is incomplete.
@ -102,7 +102,7 @@ namespace Hornung.ResourceToolkit.Resolver @@ -102,7 +102,7 @@ namespace Hornung.ResourceToolkit.Resolver
if (invocation != null) {
MemberReferenceExpression fre = invocation.TargetObject as MemberReferenceExpression;
if (fre != null) {
if (fre.FieldName == "GetString") {
if (fre.MemberName == "GetString") {
if (invocation.Arguments.Count > 0) {
PrimitiveExpression p = invocation.Arguments[0] as PrimitiveExpression;
if (p != null) {

5
src/AddIns/Misc/ResourceToolkit/Project/Src/Resolver/ResourceResolveResult.cs

@ -84,5 +84,10 @@ namespace Hornung.ResourceToolkit.Resolver @@ -84,5 +84,10 @@ namespace Hornung.ResourceToolkit.Resolver
this.key = key;
}
public override ResolveResult Clone()
{
return new ResourceResolveResult(this.CallingClass, this.CallingMember, this.ResolvedType,
this.ResourceSetReference, this.Key);
}
}
}

39
src/Libraries/ICSharpCode.TextEditor/Project/Src/Gui/TextArea.cs

@ -604,26 +604,29 @@ namespace ICSharpCode.TextEditor @@ -604,26 +604,29 @@ namespace ICSharpCode.TextEditor
motherTextEditorControl.BeginUpdate();
Document.UndoStack.StartUndoGroup();
// INSERT char
if (!HandleKeyPress(ch)) {
switch (Caret.CaretMode) {
case CaretMode.InsertMode:
InsertChar(ch);
break;
case CaretMode.OverwriteMode:
ReplaceChar(ch);
break;
default:
Debug.Assert(false, "Unknown caret mode " + Caret.CaretMode);
break;
try {
// INSERT char
if (!HandleKeyPress(ch)) {
switch (Caret.CaretMode) {
case CaretMode.InsertMode:
InsertChar(ch);
break;
case CaretMode.OverwriteMode:
ReplaceChar(ch);
break;
default:
Debug.Assert(false, "Unknown caret mode " + Caret.CaretMode);
break;
}
}
int currentLineNr = Caret.Line;
Document.FormattingStrategy.FormatLine(this, currentLineNr, Document.PositionToOffset(Caret.Position), ch);
motherTextEditorControl.EndUpdate();
} finally {
Document.UndoStack.EndUndoGroup();
}
int currentLineNr = Caret.Line;
Document.FormattingStrategy.FormatLine(this, currentLineNr, Document.PositionToOffset(Caret.Position), ch);
motherTextEditorControl.EndUpdate();
Document.UndoStack.EndUndoGroup();
}
protected override void OnKeyPress(KeyPressEventArgs e)

5
src/Libraries/NRefactory/NRefactoryASTGenerator/AST/Expressions.cs

@ -101,13 +101,14 @@ namespace NRefactoryASTGenerator.Ast @@ -101,13 +101,14 @@ namespace NRefactoryASTGenerator.Ast
public CastExpression(TypeReference castTo, Expression expression, CastType castType) {}
}
[IncludeMember("[Obsolete] public string FieldName { get { return MemberName; } set { MemberName = value; } }")]
class MemberReferenceExpression : Expression
{
Expression targetObject;
string fieldName;
string memberName;
List<TypeReference> typeArguments;
public MemberReferenceExpression(Expression targetObject, string fieldName) {}
public MemberReferenceExpression(Expression targetObject, string memberName) {}
}
class PointerReferenceExpression : Expression {

46
src/Libraries/NRefactory/Project/Src/Ast/Generated.cs

@ -1,7 +1,7 @@ @@ -1,7 +1,7 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:2.0.50727.1378
// Runtime Version:2.0.50727.1433
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
@ -2205,30 +2205,30 @@ namespace ICSharpCode.NRefactory.Ast { @@ -2205,30 +2205,30 @@ namespace ICSharpCode.NRefactory.Ast {
elseIfSections = new List<ElseIfSection>();
}
public IfElseStatement(Expression condition, Statement trueStatement)
: this(condition) {
this.trueStatement.Add(Statement.CheckNull(trueStatement));
}
public bool HasElseIfSections {
get {
return elseIfSections.Count > 0;
}
}
public bool HasElseStatements {
get {
return falseStatement.Count > 0;
}
}
public IfElseStatement(Expression condition, Statement trueStatement, Statement falseStatement)
public IfElseStatement(Expression condition, Statement trueStatement)
: this(condition) {
this.trueStatement.Add(Statement.CheckNull(trueStatement));
this.falseStatement.Add(Statement.CheckNull(falseStatement));
}
public bool HasElseStatements {
get {
return falseStatement.Count > 0;
public IfElseStatement(Expression condition, Statement trueStatement, Statement falseStatement)
: this(condition) {
this.trueStatement.Add(Statement.CheckNull(trueStatement));
this.falseStatement.Add(Statement.CheckNull(falseStatement));
}
}
public override object AcceptVisitor(IAstVisitor visitor, object data) {
return visitor.VisitIfElseStatement(this, data);
@ -2648,7 +2648,7 @@ namespace ICSharpCode.NRefactory.Ast { @@ -2648,7 +2648,7 @@ namespace ICSharpCode.NRefactory.Ast {
Expression targetObject;
string fieldName;
string memberName;
List<TypeReference> typeArguments;
@ -2662,12 +2662,12 @@ namespace ICSharpCode.NRefactory.Ast { @@ -2662,12 +2662,12 @@ namespace ICSharpCode.NRefactory.Ast {
}
}
public string FieldName {
public string MemberName {
get {
return fieldName;
return memberName;
}
set {
fieldName = value ?? "";
memberName = value ?? "";
}
}
@ -2680,18 +2680,20 @@ namespace ICSharpCode.NRefactory.Ast { @@ -2680,18 +2680,20 @@ namespace ICSharpCode.NRefactory.Ast {
}
}
public MemberReferenceExpression(Expression targetObject, string fieldName) {
public MemberReferenceExpression(Expression targetObject, string memberName) {
TargetObject = targetObject;
FieldName = fieldName;
MemberName = memberName;
typeArguments = new List<TypeReference>();
}
[Obsolete] public string FieldName { get { return MemberName; } set { MemberName = value; } }
public override object AcceptVisitor(IAstVisitor visitor, object data) {
return visitor.VisitMemberReferenceExpression(this, data);
}
public override string ToString() {
return string.Format("[MemberReferenceExpression TargetObject={0} FieldName={1} TypeArguments={2}]", TargetObject, FieldName, GetCollectionString(TypeArguments));
return string.Format("[MemberReferenceExpression TargetObject={0} MemberName={1} TypeArguments={2}]", TargetObject, MemberName, GetCollectionString(TypeArguments));
}
}
@ -4753,10 +4755,10 @@ public TypeReferenceExpression(string typeName) : this(new TypeReference(typeNam @@ -4753,10 +4755,10 @@ public TypeReferenceExpression(string typeName) : this(new TypeReference(typeNam
Usings = usings;
}
public UsingDeclaration(string @namespace) : this(@namespace, null) {}
public UsingDeclaration(string @namespace, TypeReference alias) { usings = new List<Using>(1); usings.Add(new Using(@namespace, alias)); }
public UsingDeclaration(string @namespace) : this(@namespace, null) {}
public override object AcceptVisitor(IAstVisitor visitor, object data) {
return visitor.VisitUsingDeclaration(this, data);
}

2
src/Libraries/NRefactory/Project/Src/IAstVisitor.cs

@ -1,7 +1,7 @@ @@ -1,7 +1,7 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:2.0.50727.1378
// Runtime Version:2.0.50727.1433
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.

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

@ -533,11 +533,11 @@ namespace ICSharpCode.NRefactory.Parser.CSharp @@ -533,11 +533,11 @@ 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.FieldName, member.TypeArguments);
TypeReference tr = new TypeReference(targetType.Type + "." + member.MemberName, member.TypeArguments);
tr.IsGlobal = targetType.IsGlobal;
return tr;
} else {
return new InnerClassTypeReference(targetType, member.FieldName, member.TypeArguments);
return new InnerClassTypeReference(targetType, member.MemberName, member.TypeArguments);
}
}
}

2
src/Libraries/NRefactory/Project/Src/Parser/VBNet/VBNetParser.cs

@ -246,7 +246,7 @@ namespace ICSharpCode.NRefactory.Parser.VB @@ -246,7 +246,7 @@ namespace ICSharpCode.NRefactory.Parser.VB
if (fre != null) {
bool result = WriteFullTypeName(b, fre.TargetObject);
if (b.Length > 0) b.Append('.');
b.Append(fre.FieldName);
b.Append(fre.MemberName);
return result;
} else if (expr is IdentifierExpression) {
b.Append(((IdentifierExpression)expr).Identifier);

4
src/Libraries/NRefactory/Project/Src/PrettyPrinter/CSharp/CSharpOutputVisitor.cs

@ -1712,7 +1712,7 @@ namespace ICSharpCode.NRefactory.PrettyPrinter @@ -1712,7 +1712,7 @@ namespace ICSharpCode.NRefactory.PrettyPrinter
return "\\v";
default:
if (char.IsControl(ch)) {
return "\\u" + (int)ch;
return "\\u" + ((int)ch).ToString("x4");
} else {
return ch.ToString();
}
@ -2435,7 +2435,7 @@ namespace ICSharpCode.NRefactory.PrettyPrinter @@ -2435,7 +2435,7 @@ namespace ICSharpCode.NRefactory.PrettyPrinter
outputFormatter.PrintToken(Tokens.CloseParenthesis);
}
outputFormatter.PrintToken(Tokens.Dot);
outputFormatter.PrintIdentifier(memberReferenceExpression.FieldName);
outputFormatter.PrintIdentifier(memberReferenceExpression.MemberName);
PrintTypeArgumentList(memberReferenceExpression.TypeArguments);
return null;
}

2
src/Libraries/NRefactory/Project/Src/PrettyPrinter/VBNet/VBNetOutputVisitor.cs

@ -2555,7 +2555,7 @@ namespace ICSharpCode.NRefactory.PrettyPrinter @@ -2555,7 +2555,7 @@ namespace ICSharpCode.NRefactory.PrettyPrinter
{
TrackedVisit(memberReferenceExpression.TargetObject, data);
outputFormatter.PrintToken(Tokens.Dot);
outputFormatter.PrintIdentifier(memberReferenceExpression.FieldName);
outputFormatter.PrintIdentifier(memberReferenceExpression.MemberName);
PrintTypeArguments(memberReferenceExpression.TypeArguments);
return null;
}

2
src/Libraries/NRefactory/Project/Src/Visitors/AbstractASTVisitor.cs

@ -1,7 +1,7 @@ @@ -1,7 +1,7 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:2.0.50727.1378
// Runtime Version:2.0.50727.1433
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.

2
src/Libraries/NRefactory/Project/Src/Visitors/AbstractAstTransformer.cs

@ -1,7 +1,7 @@ @@ -1,7 +1,7 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:2.0.50727.1378
// Runtime Version:2.0.50727.1433
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.

2
src/Libraries/NRefactory/Project/Src/Visitors/CSharpConstructsConvertVisitor.cs

@ -109,7 +109,7 @@ namespace ICSharpCode.NRefactory.Visitors @@ -109,7 +109,7 @@ namespace ICSharpCode.NRefactory.Visitors
return ident.Identifier;
MemberReferenceExpression fre = expression as MemberReferenceExpression;
if (fre != null && fre.TargetObject is ThisReferenceExpression)
return fre.FieldName;
return fre.MemberName;
return null;
}

22
src/Libraries/NRefactory/Project/Src/Visitors/CodeDOMOutputVisitor.cs

@ -1126,7 +1126,7 @@ namespace ICSharpCode.NRefactory.Visitors @@ -1126,7 +1126,7 @@ namespace ICSharpCode.NRefactory.Visitors
if (targetExpr == null)
targetExpr = (CodeExpression)fRef.TargetObject.AcceptVisitor(this, data);
methodName = fRef.FieldName;
methodName = fRef.MemberName;
// HACK for : Microsoft.VisualBasic.ChrW(NUMBER)
if (methodName == "ChrW") {
return new CodeCastExpression("System.Char", GetExpressionList(invocationExpression.Arguments)[0]);
@ -1306,7 +1306,7 @@ namespace ICSharpCode.NRefactory.Visitors @@ -1306,7 +1306,7 @@ namespace ICSharpCode.NRefactory.Visitors
methodInvoker));
} else {
MemberReferenceExpression fr = (MemberReferenceExpression)eventExpr;
AddStmt(new CodeAttachEventStatement(new CodeEventReferenceExpression((CodeExpression)fr.TargetObject.AcceptVisitor(this, data), fr.FieldName),
AddStmt(new CodeAttachEventStatement(new CodeEventReferenceExpression((CodeExpression)fr.TargetObject.AcceptVisitor(this, data), fr.MemberName),
methodInvoker));
}
}
@ -1531,7 +1531,7 @@ namespace ICSharpCode.NRefactory.Visitors @@ -1531,7 +1531,7 @@ namespace ICSharpCode.NRefactory.Visitors
|| fieldReferenceExpression.TargetObject is BaseReferenceExpression)
{
//field detection for fields\props inherited from base classes
return IsField(fieldReferenceExpression.FieldName);
return IsField(fieldReferenceExpression.MemberName);
}
return false;
}
@ -1540,28 +1540,28 @@ namespace ICSharpCode.NRefactory.Visitors @@ -1540,28 +1540,28 @@ namespace ICSharpCode.NRefactory.Visitors
{
if (methodReference) {
methodReference = false;
return new CodeMethodReferenceExpression((CodeExpression)fieldReferenceExpression.TargetObject.AcceptVisitor(this, data), fieldReferenceExpression.FieldName);
return new CodeMethodReferenceExpression((CodeExpression)fieldReferenceExpression.TargetObject.AcceptVisitor(this, data), fieldReferenceExpression.MemberName);
}
if (IsFieldReferenceExpression(fieldReferenceExpression)) {
return new CodeFieldReferenceExpression((CodeExpression)fieldReferenceExpression.TargetObject.AcceptVisitor(this, data),
fieldReferenceExpression.FieldName);
fieldReferenceExpression.MemberName);
} else {
if (fieldReferenceExpression.TargetObject is MemberReferenceExpression) {
if (IsPossibleTypeReference((MemberReferenceExpression)fieldReferenceExpression.TargetObject)) {
CodeTypeReferenceExpression typeRef = ConvertToTypeReference((MemberReferenceExpression)fieldReferenceExpression.TargetObject);
if (IsField(typeRef.Type.BaseType, typeRef.Type.TypeArguments.Count, fieldReferenceExpression.FieldName)) {
if (IsField(typeRef.Type.BaseType, typeRef.Type.TypeArguments.Count, fieldReferenceExpression.MemberName)) {
return new CodeFieldReferenceExpression(typeRef,
fieldReferenceExpression.FieldName);
fieldReferenceExpression.MemberName);
} else {
return new CodePropertyReferenceExpression(typeRef,
fieldReferenceExpression.FieldName);
fieldReferenceExpression.MemberName);
}
}
}
CodeExpression codeExpression = (CodeExpression)fieldReferenceExpression.TargetObject.AcceptVisitor(this, data);
return new CodePropertyReferenceExpression(codeExpression,
fieldReferenceExpression.FieldName);
fieldReferenceExpression.MemberName);
}
}
@ -1623,12 +1623,12 @@ namespace ICSharpCode.NRefactory.Visitors @@ -1623,12 +1623,12 @@ namespace ICSharpCode.NRefactory.Visitors
while (fieldReferenceExpression.TargetObject is MemberReferenceExpression) {
type.Insert(0,'.');
type.Insert(1,fieldReferenceExpression.FieldName.ToCharArray());
type.Insert(1,fieldReferenceExpression.MemberName.ToCharArray());
fieldReferenceExpression = (MemberReferenceExpression)fieldReferenceExpression.TargetObject;
}
type.Insert(0,'.');
type.Insert(1,fieldReferenceExpression.FieldName.ToCharArray());
type.Insert(1,fieldReferenceExpression.MemberName.ToCharArray());
if (fieldReferenceExpression.TargetObject is IdentifierExpression) {
type.Insert(0, ((IdentifierExpression)fieldReferenceExpression.TargetObject).Identifier.ToCharArray());

2
src/Libraries/NRefactory/Project/Src/Visitors/NodeTrackingAstVisitor.cs

@ -1,7 +1,7 @@ @@ -1,7 +1,7 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:2.0.50727.1378
// Runtime Version:2.0.50727.1433
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.

4
src/Libraries/NRefactory/Project/Src/Visitors/PrefixFieldsVisitor.cs

@ -124,10 +124,10 @@ namespace ICSharpCode.NRefactory.Visitors @@ -124,10 +124,10 @@ namespace ICSharpCode.NRefactory.Visitors
public override object VisitMemberReferenceExpression(MemberReferenceExpression fieldReferenceExpression, object data)
{
if (fieldReferenceExpression.TargetObject is ThisReferenceExpression) {
string name = fieldReferenceExpression.FieldName;
string name = fieldReferenceExpression.MemberName;
foreach (VariableDeclaration var in fields) {
if (var.Name == name) {
fieldReferenceExpression.FieldName = prefix + name;
fieldReferenceExpression.MemberName = prefix + name;
break;
}
}

4
src/Libraries/NRefactory/Project/Src/Visitors/ToVBNetConvertVisitor.cs

@ -126,7 +126,7 @@ namespace ICSharpCode.NRefactory.Visitors @@ -126,7 +126,7 @@ namespace ICSharpCode.NRefactory.Visitors
return ident.Identifier;
MemberReferenceExpression fre = expr as MemberReferenceExpression;
if (fre != null && fre.TargetObject is ThisReferenceExpression)
return fre.FieldName;
return fre.MemberName;
return null;
}
@ -261,7 +261,7 @@ namespace ICSharpCode.NRefactory.Visitors @@ -261,7 +261,7 @@ namespace ICSharpCode.NRefactory.Visitors
return false;
if ((fre.TargetObject as IdentifierExpression).Identifier != "CharSet")
return false;
switch (fre.FieldName) {
switch (fre.MemberName) {
case "Unicode":
charSet = CharsetModifier.Unicode;
break;

4
src/Libraries/NRefactory/Project/Src/Visitors/VBNetConstructsConvertVisitor.cs

@ -109,7 +109,7 @@ namespace ICSharpCode.NRefactory.Visitors @@ -109,7 +109,7 @@ namespace ICSharpCode.NRefactory.Visitors
InvocationExpression ie = se.Expression as InvocationExpression;
if (ie != null) {
MemberReferenceExpression fre = ie.TargetObject as MemberReferenceExpression;
if (fre != null && "New".Equals(fre.FieldName, StringComparison.InvariantCultureIgnoreCase)) {
if (fre != null && "New".Equals(fre.MemberName, StringComparison.InvariantCultureIgnoreCase)) {
if (fre.TargetObject is BaseReferenceExpression || fre.TargetObject is ClassReferenceExpression || fre.TargetObject is ThisReferenceExpression) {
body.Children.RemoveAt(0);
ConstructorInitializer ci = new ConstructorInitializer();
@ -209,7 +209,7 @@ namespace ICSharpCode.NRefactory.Visitors @@ -209,7 +209,7 @@ namespace ICSharpCode.NRefactory.Visitors
&& ie.Arguments.Count == 0
&& ie.TargetObject is MemberReferenceExpression
&& (ie.TargetObject as MemberReferenceExpression).TargetObject is BaseReferenceExpression
&& "Finalize".Equals((ie.TargetObject as MemberReferenceExpression).FieldName, StringComparison.InvariantCultureIgnoreCase))
&& "Finalize".Equals((ie.TargetObject as MemberReferenceExpression).MemberName, StringComparison.InvariantCultureIgnoreCase))
{
DestructorDeclaration des = new DestructorDeclaration("Destructor", Modifiers.None, methodDeclaration.Attributes);
ReplaceCurrentNode(des);

6
src/Libraries/NRefactory/Test/Output/CSharp/CSharpOutputTest.cs

@ -267,6 +267,12 @@ namespace ICSharpCode.NRefactory.Tests.PrettyPrinter @@ -267,6 +267,12 @@ namespace ICSharpCode.NRefactory.Tests.PrettyPrinter
TestExpression("12.0");
}
[Test]
public void StringWithUnicodeLiteral()
{
TestExpression(@"""\u0001""");
}
[Test]
public void GenericMethodInvocation()
{

8
src/Libraries/NRefactory/Test/Parser/Expressions/IdentifierExpressionTests.cs

@ -38,6 +38,14 @@ namespace ICSharpCode.NRefactory.Tests.Ast @@ -38,6 +38,14 @@ namespace ICSharpCode.NRefactory.Tests.Ast
Assert.AreEqual("M", ident.Identifier);
Assert.AreEqual(1, ident.TypeArguments.Count);
}
[Test]
public void CSharpGenericMethodReference2()
{
IdentifierExpression ident = ParseUtilCSharp.ParseExpression<IdentifierExpression>("TargetMethod<string>");
Assert.AreEqual("TargetMethod", ident.Identifier);
Assert.AreEqual(1, ident.TypeArguments.Count);
}
#endregion
#region VB.NET

22
src/Libraries/NRefactory/Test/Parser/Expressions/MemberReferenceExpressionTests.cs

@ -21,7 +21,7 @@ namespace ICSharpCode.NRefactory.Tests.Ast @@ -21,7 +21,7 @@ namespace ICSharpCode.NRefactory.Tests.Ast
public void CSharpSimpleFieldReferenceExpressionTest()
{
MemberReferenceExpression fre = ParseUtilCSharp.ParseExpression<MemberReferenceExpression>("myTargetObject.myField");
Assert.AreEqual("myField", fre.FieldName);
Assert.AreEqual("myField", fre.MemberName);
Assert.IsTrue(fre.TargetObject is IdentifierExpression);
Assert.AreEqual("myTargetObject", ((IdentifierExpression)fre.TargetObject).Identifier);
}
@ -30,7 +30,7 @@ namespace ICSharpCode.NRefactory.Tests.Ast @@ -30,7 +30,7 @@ namespace ICSharpCode.NRefactory.Tests.Ast
public void CSharpGenericFieldReferenceExpressionTest()
{
MemberReferenceExpression fre = ParseUtilCSharp.ParseExpression<MemberReferenceExpression>("SomeClass<string>.myField");
Assert.AreEqual("myField", fre.FieldName);
Assert.AreEqual("myField", fre.MemberName);
Assert.IsTrue(fre.TargetObject is TypeReferenceExpression);
TypeReference tr = ((TypeReferenceExpression)fre.TargetObject).TypeReference;
Assert.AreEqual("SomeClass", tr.Type);
@ -42,7 +42,7 @@ namespace ICSharpCode.NRefactory.Tests.Ast @@ -42,7 +42,7 @@ namespace ICSharpCode.NRefactory.Tests.Ast
public void CSharpFullNamespaceGenericFieldReferenceExpressionTest()
{
MemberReferenceExpression fre = ParseUtilCSharp.ParseExpression<MemberReferenceExpression>("Namespace.Subnamespace.SomeClass<string>.myField");
Assert.AreEqual("myField", fre.FieldName);
Assert.AreEqual("myField", fre.MemberName);
Assert.IsTrue(fre.TargetObject is TypeReferenceExpression);
TypeReference tr = ((TypeReferenceExpression)fre.TargetObject).TypeReference;
Assert.AreEqual("Namespace.Subnamespace.SomeClass", tr.Type);
@ -54,7 +54,7 @@ namespace ICSharpCode.NRefactory.Tests.Ast @@ -54,7 +54,7 @@ namespace ICSharpCode.NRefactory.Tests.Ast
public void CSharpGlobalFullNamespaceGenericFieldReferenceExpressionTest()
{
MemberReferenceExpression fre = ParseUtilCSharp.ParseExpression<MemberReferenceExpression>("global::Namespace.Subnamespace.SomeClass<string>.myField");
Assert.AreEqual("myField", fre.FieldName);
Assert.AreEqual("myField", fre.MemberName);
Assert.IsTrue(fre.TargetObject is TypeReferenceExpression);
TypeReference tr = ((TypeReferenceExpression)fre.TargetObject).TypeReference;
Assert.IsFalse(tr is InnerClassTypeReference);
@ -68,7 +68,7 @@ namespace ICSharpCode.NRefactory.Tests.Ast @@ -68,7 +68,7 @@ namespace ICSharpCode.NRefactory.Tests.Ast
public void CSharpNestedGenericFieldReferenceExpressionTest()
{
MemberReferenceExpression fre = ParseUtilCSharp.ParseExpression<MemberReferenceExpression>("MyType<string>.InnerClass<int>.myField");
Assert.AreEqual("myField", fre.FieldName);
Assert.AreEqual("myField", fre.MemberName);
Assert.IsTrue(fre.TargetObject is TypeReferenceExpression);
InnerClassTypeReference ic = (InnerClassTypeReference)((TypeReferenceExpression)fre.TargetObject).TypeReference;
Assert.AreEqual("InnerClass", ic.Type);
@ -85,7 +85,7 @@ namespace ICSharpCode.NRefactory.Tests.Ast @@ -85,7 +85,7 @@ namespace ICSharpCode.NRefactory.Tests.Ast
public void VBNetSimpleFieldReferenceExpressionTest()
{
MemberReferenceExpression fre = ParseUtilVBNet.ParseExpression<MemberReferenceExpression>("myTargetObject.myField");
Assert.AreEqual("myField", fre.FieldName);
Assert.AreEqual("myField", fre.MemberName);
Assert.IsTrue(fre.TargetObject is IdentifierExpression);
Assert.AreEqual("myTargetObject", ((IdentifierExpression)fre.TargetObject).Identifier);
}
@ -94,7 +94,7 @@ namespace ICSharpCode.NRefactory.Tests.Ast @@ -94,7 +94,7 @@ namespace ICSharpCode.NRefactory.Tests.Ast
public void VBNetFieldReferenceExpressionWithoutTargetTest()
{
MemberReferenceExpression fre = ParseUtilVBNet.ParseExpression<MemberReferenceExpression>(".myField");
Assert.AreEqual("myField", fre.FieldName);
Assert.AreEqual("myField", fre.MemberName);
Assert.IsTrue(fre.TargetObject.IsNull);
}
@ -102,7 +102,7 @@ namespace ICSharpCode.NRefactory.Tests.Ast @@ -102,7 +102,7 @@ namespace ICSharpCode.NRefactory.Tests.Ast
public void VBNetGenericFieldReferenceExpressionTest()
{
MemberReferenceExpression fre = ParseUtilVBNet.ParseExpression<MemberReferenceExpression>("SomeClass(of string).myField");
Assert.AreEqual("myField", fre.FieldName);
Assert.AreEqual("myField", fre.MemberName);
Assert.IsTrue(fre.TargetObject is TypeReferenceExpression);
TypeReference tr = ((TypeReferenceExpression)fre.TargetObject).TypeReference;
Assert.AreEqual("SomeClass", tr.Type);
@ -114,7 +114,7 @@ namespace ICSharpCode.NRefactory.Tests.Ast @@ -114,7 +114,7 @@ namespace ICSharpCode.NRefactory.Tests.Ast
public void VBNetFullNamespaceGenericFieldReferenceExpressionTest()
{
MemberReferenceExpression fre = ParseUtilVBNet.ParseExpression<MemberReferenceExpression>("System.Subnamespace.SomeClass(of string).myField");
Assert.AreEqual("myField", fre.FieldName);
Assert.AreEqual("myField", fre.MemberName);
Assert.IsTrue(fre.TargetObject is TypeReferenceExpression);
TypeReference tr = ((TypeReferenceExpression)fre.TargetObject).TypeReference;
Assert.AreEqual("System.Subnamespace.SomeClass", tr.Type);
@ -126,7 +126,7 @@ namespace ICSharpCode.NRefactory.Tests.Ast @@ -126,7 +126,7 @@ namespace ICSharpCode.NRefactory.Tests.Ast
public void VBNetGlobalFullNamespaceGenericFieldReferenceExpressionTest()
{
MemberReferenceExpression fre = ParseUtilVBNet.ParseExpression<MemberReferenceExpression>("Global.System.Subnamespace.SomeClass(of string).myField");
Assert.AreEqual("myField", fre.FieldName);
Assert.AreEqual("myField", fre.MemberName);
Assert.IsTrue(fre.TargetObject is TypeReferenceExpression);
TypeReference tr = ((TypeReferenceExpression)fre.TargetObject).TypeReference;
Assert.IsFalse(tr is InnerClassTypeReference);
@ -140,7 +140,7 @@ namespace ICSharpCode.NRefactory.Tests.Ast @@ -140,7 +140,7 @@ namespace ICSharpCode.NRefactory.Tests.Ast
public void VBNetNestedGenericFieldReferenceExpressionTest()
{
MemberReferenceExpression fre = ParseUtilVBNet.ParseExpression<MemberReferenceExpression>("MyType(of string).InnerClass(of integer).myField");
Assert.AreEqual("myField", fre.FieldName);
Assert.AreEqual("myField", fre.MemberName);
Assert.IsTrue(fre.TargetObject is TypeReferenceExpression);
InnerClassTypeReference ic = (InnerClassTypeReference)((TypeReferenceExpression)fre.TargetObject).TypeReference;
Assert.AreEqual("InnerClass", ic.Type);

2
src/Libraries/NRefactory/Test/Parser/Expressions/PrimitiveExpressionTests.cs

@ -24,7 +24,7 @@ namespace ICSharpCode.NRefactory.Tests.Ast @@ -24,7 +24,7 @@ namespace ICSharpCode.NRefactory.Tests.Ast
Assert.AreEqual(0, invExpr.Arguments.Count);
Assert.IsTrue(invExpr.TargetObject is MemberReferenceExpression);
MemberReferenceExpression fre = invExpr.TargetObject as MemberReferenceExpression;
Assert.AreEqual("ToString", fre.FieldName);
Assert.AreEqual("ToString", fre.MemberName);
Assert.IsTrue(fre.TargetObject is PrimitiveExpression);
PrimitiveExpression pe = fre.TargetObject as PrimitiveExpression;

12
src/Libraries/NRefactory/Test/Parser/Expressions/TypeReferenceExpressionTests.cs

@ -46,7 +46,7 @@ namespace ICSharpCode.NRefactory.Tests.Ast @@ -46,7 +46,7 @@ namespace ICSharpCode.NRefactory.Tests.Ast
public void IntReferenceExpression()
{
MemberReferenceExpression fre = ParseUtilCSharp.ParseExpression<MemberReferenceExpression>("int.MaxValue");
Assert.AreEqual("MaxValue", fre.FieldName);
Assert.AreEqual("MaxValue", fre.MemberName);
Assert.AreEqual("System.Int32", ((TypeReferenceExpression)fre.TargetObject).TypeReference.SystemType);
}
@ -57,7 +57,7 @@ namespace ICSharpCode.NRefactory.Tests.Ast @@ -57,7 +57,7 @@ namespace ICSharpCode.NRefactory.Tests.Ast
// reference, but it has to stay consistent because NRefactoryResolver depends
// on this trick.
MemberReferenceExpression fre = ParseUtilCSharp.ParseExpression<MemberReferenceExpression>("int", true);
Assert.AreEqual("", fre.FieldName);
Assert.AreEqual("", fre.MemberName);
Assert.AreEqual("System.Int32", ((TypeReferenceExpression)fre.TargetObject).TypeReference.SystemType);
}
#endregion
@ -67,7 +67,7 @@ namespace ICSharpCode.NRefactory.Tests.Ast @@ -67,7 +67,7 @@ namespace ICSharpCode.NRefactory.Tests.Ast
public void VBIntReferenceExpression()
{
MemberReferenceExpression fre = ParseUtilVBNet.ParseExpression<MemberReferenceExpression>("inTeGer.MaxValue");
Assert.AreEqual("MaxValue", fre.FieldName);
Assert.AreEqual("MaxValue", fre.MemberName);
Assert.AreEqual("System.Int32", ((TypeReferenceExpression)fre.TargetObject).TypeReference.SystemType);
}
@ -78,7 +78,7 @@ namespace ICSharpCode.NRefactory.Tests.Ast @@ -78,7 +78,7 @@ namespace ICSharpCode.NRefactory.Tests.Ast
// reference, but it has to stay consistent because NRefactoryResolver depends
// on this trick.
MemberReferenceExpression fre = ParseUtilVBNet.ParseExpression<MemberReferenceExpression>("inTeGer", true);
Assert.AreEqual("", fre.FieldName);
Assert.AreEqual("", fre.MemberName);
Assert.AreEqual("System.Int32", ((TypeReferenceExpression)fre.TargetObject).TypeReference.SystemType);
}
@ -86,7 +86,7 @@ namespace ICSharpCode.NRefactory.Tests.Ast @@ -86,7 +86,7 @@ namespace ICSharpCode.NRefactory.Tests.Ast
public void VBObjectReferenceExpression()
{
MemberReferenceExpression fre = ParseUtilVBNet.ParseExpression<MemberReferenceExpression>("Object.ReferenceEquals");
Assert.AreEqual("ReferenceEquals", fre.FieldName);
Assert.AreEqual("ReferenceEquals", fre.MemberName);
Assert.AreEqual("System.Object", ((TypeReferenceExpression)fre.TargetObject).TypeReference.SystemType);
}
@ -97,7 +97,7 @@ namespace ICSharpCode.NRefactory.Tests.Ast @@ -97,7 +97,7 @@ namespace ICSharpCode.NRefactory.Tests.Ast
// reference, but it has to stay consistent because NRefactoryResolver depends
// on this trick.
MemberReferenceExpression fre = ParseUtilVBNet.ParseExpression<MemberReferenceExpression>("obJeCt", true);
Assert.AreEqual("", fre.FieldName);
Assert.AreEqual("", fre.MemberName);
Assert.AreEqual("System.Object", ((TypeReferenceExpression)fre.TargetObject).TypeReference.SystemType);
}
#endregion

18
src/Main/Base/Project/Src/Gui/Pads/DefinitionViewPad.cs

@ -83,8 +83,12 @@ namespace ICSharpCode.SharpDevelop.Gui @@ -83,8 +83,12 @@ namespace ICSharpCode.SharpDevelop.Gui
OpenFile(pos);
}
bool disableDefinitionView;
ResolveResult ResolveAtCaret(ParserUpdateStepEventArgs e)
{
if (disableDefinitionView)
return null;
IWorkbenchWindow window = WorkbenchSingleton.Workbench.ActiveWorkbenchWindow;
if (window == null) return null;
ITextEditorControlProvider provider = window.ActiveViewContent as ITextEditorControlProvider;
@ -102,9 +106,17 @@ namespace ICSharpCode.SharpDevelop.Gui @@ -102,9 +106,17 @@ namespace ICSharpCode.SharpDevelop.Gui
LoggingService.Debug("caret.Offset = " + caret.Offset + ", content.Length=" + content.Length);
return null;
}
ExpressionResult expr = expressionFinder.FindFullExpression(content, caret.Offset);
if (expr.Expression == null) return null;
return ParserService.Resolve(expr, caret.Line + 1, caret.Column + 1, fileName, content);
try {
ExpressionResult expr = expressionFinder.FindFullExpression(content, caret.Offset);
if (expr.Expression == null) return null;
return ParserService.Resolve(expr, caret.Line + 1, caret.Column + 1, fileName, content);
} catch (Exception ex) {
disableDefinitionView = true;
this.Control.Visible = false;
MessageService.ShowError(ex, "Error resolving at " + (caret.Line + 1) + "/" + (caret.Column + 1)
+ ". DefinitionViewPad is disabled until you restart SharpDevelop.");
return null;
}
}
FilePosition oldPosition;

4
src/Main/Base/Project/Src/Services/Debugger/DebuggerService.cs

@ -448,8 +448,8 @@ namespace ICSharpCode.SharpDevelop.Debugging @@ -448,8 +448,8 @@ namespace ICSharpCode.SharpDevelop.Debugging
return GetMemberText(ambience, c, expression, out debuggerCanShowValue);
else
return ambience.Convert(result.ResolvedType);
} else if (result is MethodResolveResult) {
MethodResolveResult mrr = result as MethodResolveResult;
} else if (result is MethodGroupResolveResult) {
MethodGroupResolveResult mrr = result as MethodGroupResolveResult;
IMethod m = mrr.GetMethodIfSingleOverload();
if (m != null)
return GetMemberText(ambience, m, expression, out debuggerCanShowValue);

4
src/Main/Base/Project/Src/Services/RefactoringService/RefactorMenu.cs

@ -117,8 +117,8 @@ namespace ICSharpCode.SharpDevelop.Refactoring @@ -117,8 +117,8 @@ namespace ICSharpCode.SharpDevelop.Refactoring
Rename((rr as TypeResolveResult).ResolvedClass);
} else if (rr is MemberResolveResult) {
Rename((rr as MemberResolveResult).ResolvedMember);
} else if (rr is MethodResolveResult) {
Rename((rr as MethodResolveResult).GetMethodIfSingleOverload());
} else if (rr is MethodGroupResolveResult) {
Rename((rr as MethodGroupResolveResult).GetMethodIfSingleOverload());
} else if (rr is LocalResolveResult) {
RenameLocalVariableCommand.Run(rr as LocalResolveResult);
} else {

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

@ -76,8 +76,8 @@ namespace ICSharpCode.SharpDevelop.Refactoring @@ -76,8 +76,8 @@ namespace ICSharpCode.SharpDevelop.Refactoring
repeatResolve:
rr = ResolveExpressionAtCaret(textArea, expressionResult);
item = null;
if (rr is MethodResolveResult) {
item = MakeItem(definitions, ((MethodResolveResult)rr).GetMethodIfSingleOverload());
if (rr is MethodGroupResolveResult) {
item = MakeItem(definitions, ((MethodGroupResolveResult)rr).GetMethodIfSingleOverload());
} else if (rr is MemberResolveResult) {
MemberResolveResult mrr = (MemberResolveResult)rr;
item = MakeItem(definitions, mrr.ResolvedMember);
@ -282,3 +282,4 @@ namespace ICSharpCode.SharpDevelop.Refactoring @@ -282,3 +282,4 @@ namespace ICSharpCode.SharpDevelop.Refactoring

9
src/Main/Base/Project/Src/Services/RefactoringService/RefactoringService.cs

@ -108,8 +108,8 @@ namespace ICSharpCode.SharpDevelop.Refactoring @@ -108,8 +108,8 @@ namespace ICSharpCode.SharpDevelop.Refactoring
return FindReferences((entity as TypeResolveResult).ResolvedClass, progressMonitor);
} else if (entity is MemberResolveResult) {
return FindReferences((entity as MemberResolveResult).ResolvedMember, progressMonitor);
} else if (entity is MethodResolveResult) {
IMethod method = (entity as MethodResolveResult).GetMethodIfSingleOverload();
} else if (entity is MethodGroupResolveResult) {
IMethod method = (entity as MethodGroupResolveResult).GetMethodIfSingleOverload();
if (method != null) {
return FindReferences(method, progressMonitor);
}
@ -416,8 +416,8 @@ namespace ICSharpCode.SharpDevelop.Refactoring @@ -416,8 +416,8 @@ namespace ICSharpCode.SharpDevelop.Refactoring
MemberResolveResult mrr = rr as MemberResolveResult;
if (mrr != null) {
return MemberLookupHelper.IsSimilarMember(mrr.ResolvedMember, member);
} else if (rr is MethodResolveResult) {
return MemberLookupHelper.IsSimilarMember((rr as MethodResolveResult).GetMethodIfSingleOverload(), member);
} else if (rr is MethodGroupResolveResult) {
return MemberLookupHelper.IsSimilarMember((rr as MethodGroupResolveResult).GetMethodIfSingleOverload(), member);
} else {
return false;
}
@ -426,3 +426,4 @@ namespace ICSharpCode.SharpDevelop.Refactoring @@ -426,3 +426,4 @@ namespace ICSharpCode.SharpDevelop.Refactoring
}
}

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

@ -115,10 +115,10 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor @@ -115,10 +115,10 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor
LoggingService.DebugFormatted("ShowInsight for >>{0}<<, context={1}", expressionResult.Expression, expressionResult.Context);
}
int caretLineNumber = document.GetLineNumberForOffset(useOffset);
int caretColumn = useOffset - document.GetLineSegment(caretLineNumber).Offset;
// the parser works with 1 based coordinates
int caretLineNumber = document.GetLineNumberForOffset(useOffset) + 1;
int caretColumn = useOffset - document.GetLineSegment(caretLineNumber).Offset + 1;
SetupDataProvider(fileName, document, expressionResult, caretLineNumber, caretColumn);
SetupDataProvider(fileName, document, expressionResult, caretLineNumber + 1, caretColumn + 1);
}
protected virtual void SetupDataProvider(string fileName, IDocument document, ExpressionResult expressionResult, int caretLineNumber, int caretColumn)
@ -155,7 +155,7 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor @@ -155,7 +155,7 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor
methods.Add(Constructor.CreateDefault(trr.ResolvedClass));
}
} else {
MethodResolveResult result = results as MethodResolveResult;
MethodGroupResolveResult result = results as MethodGroupResolveResult;
if (result == null)
return;
bool classIsInInheritanceTree = false;

3
src/Main/Base/Project/Src/TextEditor/Gui/Editor/TextEditorDisplayBinding.cs

@ -71,9 +71,6 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor @@ -71,9 +71,6 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor
public bool EnableUndo {
get {
#if DEBUG
textEditorControl.Document.UndoStack.AssertNoUndoGroupOpen();
#endif
return textEditorControl.EnableUndo;
}
}

40
src/Main/Base/Test/CSharpExpressionFinderTests.cs

@ -834,6 +834,46 @@ class Main { @@ -834,6 +834,46 @@ class Main {
Assert.IsNull(result.Expression);
Assert.AreEqual(ExpressionContext.Default, result.Context);
}
[Test]
public void IsOperatorTest()
{
const string program = @"using System;
class Main {
void M() {
if (x is ";
ExpressionResult result = ef.FindExpression(program, program.Length);
Assert.IsNull(result.Expression);
Assert.AreEqual(ExpressionContext.Type, result.Context);
}
[Test]
public void TypeOfTest()
{
const string program = @"using System;
class Main {
void M() {
Type t = typeof(";
ExpressionResult result = ef.FindExpression(program, program.Length);
Assert.IsNull(result.Expression);
Assert.AreEqual(ExpressionContext.Type, result.Context);
}
[Test]
public void AsOperatorTest()
{
const string program = @"using System;
class Main {
void M() {
X x = a as ";
ExpressionResult result = ef.FindExpression(program, program.Length);
Assert.IsNull(result.Expression);
Assert.AreEqual(ExpressionContext.Type, result.Context);
}
}
}

36
src/Main/Base/Test/GenericResolverTests.cs

@ -322,6 +322,42 @@ class TestClass { @@ -322,6 +322,42 @@ class TestClass {
Assert.IsTrue(Refactoring.RefactoringService.IsReferenceToMember(genericMethod, mrr));
Assert.IsFalse(Refactoring.RefactoringService.IsReferenceToMember(nonGenericMethod, mrr));
}
[Test]
public void OverrideGenericMethodTest()
{
string program = @"using System;
class Program {
public static void Main() {
D d = new D();
d.T<char, int>('a', 1);
d.T<int, char>('a', 2);
}
protected virtual void T<A, B>(A a, B b) {
}
protected virtual void T<X, Y>(Y a, X b) {
}
}
class D : Program {
protected override void T<X, Y>(X a, Y b) {
// overrides T<A,B> - type arguments are identified by position
}
}";
IAmbience ambience = Dom.CSharp.CSharpAmbience.Instance;
ambience.ConversionFlags = ConversionFlags.UseFullyQualifiedMemberNames | ConversionFlags.ShowTypeParameterList;
MemberResolveResult mrr;
mrr = Resolve<MemberResolveResult>(program, "d.T<int, char>('a', 2)", 5);
Assert.AreEqual("Program.T<X, Y>", ambience.Convert((IMethod)mrr.ResolvedMember));
mrr = Resolve<MemberResolveResult>(program, "d.T<char, int>('a', 1)", 6);
Assert.AreEqual("D.T<X, Y>", ambience.Convert((IMethod)mrr.ResolvedMember));
IMember baseMember = MemberLookupHelper.FindBaseMember(mrr.ResolvedMember);
Assert.IsNotNull(baseMember);
Assert.AreEqual("Program.T<A, B>", ambience.Convert((IMethod)baseMember));
}
#endregion
}
}

18
src/Main/Base/Test/InnerClassesResolverTests.cs

@ -162,5 +162,23 @@ class C : A { @@ -162,5 +162,23 @@ class C : A {
}
Assert.Fail("Inherited inner class not visible.");
}
[Test]
public void NestedClassHidingHidesAllMethods()
{
string program = @"using System;
class A {
static void Test(int arg) {}
static void Test(string arg) {}
class B {
void MyMethod() {
}
static void Test(long arg) {}
}
}";
MemberResolveResult result = Resolve<MemberResolveResult>(program, "Test(4)", 7);
Assert.AreEqual("A.B.Test", result.ResolvedMember.FullyQualifiedName);
}
}
}

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

@ -91,9 +91,8 @@ namespace ICSharpCode.SharpDevelop.Tests @@ -91,9 +91,8 @@ namespace ICSharpCode.SharpDevelop.Tests
ParseInformation parseInfo = AddCompilationUnit(Parse("a.cs", program), "a.cs");
NRefactoryResolver resolver = new NRefactoryResolver(LanguageProperties.CSharp);
return resolver.Resolve(new ExpressionResult(expression, new DomRegion(line, column), context, null),
parseInfo,
program);
ExpressionResult expressionResult = new ExpressionResult(expression, new DomRegion(line, column), context, null);
return resolver.Resolve(expressionResult, parseInfo, program);
}
public ResolveResult ResolveVB(string program, string expression, int line)
@ -101,15 +100,14 @@ namespace ICSharpCode.SharpDevelop.Tests @@ -101,15 +100,14 @@ namespace ICSharpCode.SharpDevelop.Tests
ParseInformation parseInfo = AddCompilationUnit(ParseVB("a.vb", program), "a.vb");
NRefactoryResolver resolver = new NRefactoryResolver(LanguageProperties.VBNet);
return resolver.Resolve(new ExpressionResult(expression, new DomRegion(line, 0), ExpressionContext.Default, null),
parseInfo,
program);
ExpressionResult expressionResult = new ExpressionResult(expression, new DomRegion(line, 0), ExpressionContext.Default, null);
return resolver.Resolve(expressionResult, parseInfo, program);
}
public T Resolve<T>(string program, string expression, int line) where T : ResolveResult
{
ResolveResult rr = Resolve(program, expression, line);
Assert.IsNotNull(rr, "Resolve returned null");
Assert.IsNotNull(rr, "Resolve returned null (expression=" + expression + ")");
Assert.AreEqual(typeof(T), rr.GetType());
return (T)rr;
}
@ -117,7 +115,7 @@ namespace ICSharpCode.SharpDevelop.Tests @@ -117,7 +115,7 @@ namespace ICSharpCode.SharpDevelop.Tests
public T Resolve<T>(string program, string expression, int line, int column, ExpressionContext context) where T : ResolveResult
{
ResolveResult rr = Resolve(program, expression, line, column, context);
Assert.IsNotNull(rr, "Resolve returned null");
Assert.IsNotNull(rr, "Resolve returned null (expression=" + expression + ")");
Assert.AreEqual(typeof(T), rr.GetType());
return (T)rr;
}
@ -125,7 +123,7 @@ namespace ICSharpCode.SharpDevelop.Tests @@ -125,7 +123,7 @@ namespace ICSharpCode.SharpDevelop.Tests
public T ResolveVB<T>(string program, string expression, int line) where T : ResolveResult
{
ResolveResult rr = ResolveVB(program, expression, line);
Assert.IsNotNull(rr, "Resolve returned null");
Assert.IsNotNull(rr, "Resolve returned null (expression=" + expression + ")");
Assert.AreEqual(typeof(T), rr.GetType());
return (T)rr;
}
@ -298,6 +296,28 @@ interface IInterface2 { @@ -298,6 +296,28 @@ interface IInterface2 {
Assert.AreEqual("System.Int32", result.ResolvedType.FullyQualifiedName, "'TargetMethod()'");
}
[Test]
public void MethodGroupResolveTest()
{
string program = @"class A {
void Method() {
}
void TargetMethod(int a) { }
void TargetMethod<T>(T a) { }
}
";
MethodGroupResolveResult result = Resolve<MethodGroupResolveResult>(program, "TargetMethod", 3);
Assert.AreEqual("TargetMethod", result.Name);
Assert.AreEqual(2, result.Methods.Count);
result = Resolve<MethodGroupResolveResult>(program, "TargetMethod<string>", 3);
Assert.AreEqual("TargetMethod", result.Name);
Assert.AreEqual(1, result.Methods.Count);
Assert.AreEqual("System.String", result.GetMethodIfSingleOverload().Parameters[0].ReturnType.FullyQualifiedName);
}
[Test]
public void ThisMethodCallTest()
{
@ -1050,7 +1070,7 @@ class B { @@ -1050,7 +1070,7 @@ class B {
{
string program = @"using System;
class A : B {
void TestMethod(B b) {
static void TestMethod(A a) {
}
}
@ -1058,11 +1078,11 @@ class B { @@ -1058,11 +1078,11 @@ class B {
protected int member;
}
";
ResolveResult result = Resolve(program, "b", 4);
ResolveResult result = Resolve(program, "a", 4);
Assert.IsNotNull(result);
ArrayList cd = result.GetCompletionData(lastPC);
Assert.IsTrue(MemberExists(cd, "member"), "member should be in completion lookup");
result = Resolve(program, "b.member", 4);
result = Resolve(program, "a.member", 4);
Assert.IsNotNull(result, "member should be found!");
}
@ -1087,6 +1107,27 @@ class B { @@ -1087,6 +1107,27 @@ class B {
Assert.IsNotNull(result, "member should be found even though it is not visible!");
}
[Test]
public void ProtectedMemberInvisibleWhenNotUsingReferenceOfCurrentTypeTest()
{
string program = @"using System;
class A : B {
void TestMethod(B b) {
}
}
class B {
protected int member;
}
";
ResolveResult result = Resolve(program, "b", 4);
Assert.IsNotNull(result);
ArrayList cd = result.GetCompletionData(lastPC);
Assert.IsFalse(MemberExists(cd, "member"), "member should not be in completion lookup");
result = Resolve(program, "b.member", 4);
Assert.IsNotNull(result, "member should be found even though it is not visible!");
}
bool MemberExists(ArrayList members, string name)
{
foreach (object o in members) {
@ -1113,11 +1154,11 @@ class B { @@ -1113,11 +1154,11 @@ class B {
ResolveResult result = Resolve(program, "(Child)someVar", 6);
Assert.AreEqual("Child", result.ResolvedType.FullyQualifiedName);
int count = 0;
foreach (IMethod m in result.ResolvedType.GetMethods()) {
if (m.Name == "OverrideMe")
count += 1;
}
Assert.AreEqual(1, count);
// foreach (IMethod m in result.ResolvedType.GetMethods()) {
// if (m.Name == "OverrideMe")
// count += 1;
// }
// Assert.AreEqual(1, count);
count = 0;
foreach (object o in result.GetCompletionData(lastPC)) {
IMethod m = o as IMethod;
@ -1145,6 +1186,25 @@ End Class @@ -1145,6 +1186,25 @@ End Class
result = ResolveVB<MemberResolveResult>(program, "MyBase.CancelButton", 5);
Assert.AreEqual("System.Windows.Forms.Form.CancelButton", result.ResolvedMember.FullyQualifiedName);
}
[Test]
public void PreferExtensionMethodToInaccessibleMethod()
{
string program = @"static class Program {
static void Main() {
new BaseClass().Test(3);
Console.ReadKey();
}
}
class BaseClass {
private void Test(int a) { }
}
static class Extensions {
public static void Test(this BaseClass b, object a) { }
}";
MemberResolveResult result = Resolve<MemberResolveResult>(program, "new BaseClass().Test(3)", 4);
Assert.AreEqual("Extensions.Test", result.ResolvedMember.FullyQualifiedName);
}
#endregion
#region MixedType tests
@ -1495,5 +1555,182 @@ public class MyCollectionType : System.Collections.IEnumerable @@ -1495,5 +1555,182 @@ public class MyCollectionType : System.Collections.IEnumerable
Assert.AreEqual("r1", lrr.Field.Name);
}
#endregion
[Test]
public void InvocableRule()
{
string program = @"using System;
class DerivedClass : BaseClass {
static void X() {
}
private static new int Test;
}
class BaseClass {
public static string Test() {}
}";
MemberResolveResult mrr = Resolve<MemberResolveResult>(program, "BaseClass.Test()", 4);
Assert.AreEqual("BaseClass.Test", mrr.ResolvedMember.FullyQualifiedName);
mrr = Resolve<MemberResolveResult>(program, "Test", 4);
Assert.AreEqual("DerivedClass.Test", mrr.ResolvedMember.FullyQualifiedName);
mrr = Resolve<MemberResolveResult>(program, "DerivedClass.Test", 4);
Assert.AreEqual("DerivedClass.Test", mrr.ResolvedMember.FullyQualifiedName);
// returns BaseClass.Test because DerivedClass.Test is not invocable
mrr = Resolve<MemberResolveResult>(program, "DerivedClass.Test()", 4);
Assert.AreEqual("BaseClass.Test", mrr.ResolvedMember.FullyQualifiedName);
}
[Test]
public void InvocableRule2()
{
string program = @"using System;
class DerivedClass : BaseClass {
static void X() {
}
private static new int Test;
}
delegate string SomeDelegate();
class BaseClass {
public static SomeDelegate Test;
}";
MemberResolveResult mrr = Resolve<MemberResolveResult>(program, "BaseClass.Test()", 4);
Assert.AreEqual("BaseClass.Test", mrr.ResolvedMember.FullyQualifiedName);
mrr = Resolve<MemberResolveResult>(program, "Test", 4);
Assert.AreEqual("DerivedClass.Test", mrr.ResolvedMember.FullyQualifiedName);
mrr = Resolve<MemberResolveResult>(program, "DerivedClass.Test", 4);
Assert.AreEqual("DerivedClass.Test", mrr.ResolvedMember.FullyQualifiedName);
// returns BaseClass.Test because DerivedClass.Test is not invocable
mrr = Resolve<MemberResolveResult>(program, "DerivedClass.Test()", 4);
Assert.AreEqual("BaseClass.Test", mrr.ResolvedMember.FullyQualifiedName);
}
[Test]
public void AccessibleRule()
{
string program = @"using System;
class BaseClass {
static void X() {
}
public static int Test;
}
class DerivedClass : BaseClass {
private static new int Test;
}
";
// returns BaseClass.Test because DerivedClass.Test is not accessible
MemberResolveResult mrr = Resolve<MemberResolveResult>(program, "DerivedClass.Test", 4);
Assert.AreEqual("BaseClass.Test", mrr.ResolvedMember.FullyQualifiedName);
}
[Test]
public void FieldHidingProperty()
{
string program = @"using System;
class DerivedClass : BaseClass {
static void X() {
}
public static new int Test;
}
class BaseClass {
public static int Test { get { return 0; } }
}
";
MemberResolveResult mrr = Resolve<MemberResolveResult>(program, "Test", 4);
Assert.AreEqual("DerivedClass.Test", mrr.ResolvedMember.FullyQualifiedName);
mrr = Resolve<MemberResolveResult>(program, "DerivedClass.Test", 4);
Assert.AreEqual("DerivedClass.Test", mrr.ResolvedMember.FullyQualifiedName);
}
[Test]
public void PropertyHidingField()
{
string program = @"using System;
class DerivedClass : BaseClass {
static void X() {
}
public static new int Test { get { return 0; } }
}
class BaseClass {
public static int Test;
}
";
MemberResolveResult mrr = Resolve<MemberResolveResult>(program, "Test", 4);
Assert.AreEqual("DerivedClass.Test", mrr.ResolvedMember.FullyQualifiedName);
mrr = Resolve<MemberResolveResult>(program, "DerivedClass.Test", 4);
Assert.AreEqual("DerivedClass.Test", mrr.ResolvedMember.FullyQualifiedName);
}
[Test]
[Ignore("not implemented")]
public void TestOverloadingByRef()
{
string program = @"using System;
class Program {
public static void Main() {
int a = 42;
T(a);
T(ref a);
}
static void T(int x) {}
static void T(ref int y) {}
}";
MemberResolveResult mrr = Resolve<MemberResolveResult>(program, "T(a)", 5);
Assert.IsFalse(((IMethod)mrr.ResolvedMember).Parameters[0].IsRef);
mrr = Resolve<MemberResolveResult>(program, "T(ref a)", 5);
Assert.IsTrue(((IMethod)mrr.ResolvedMember).Parameters[0].IsRef);
}
[Test]
public void AddedOverload()
{
string program = @"class BaseClass {
static void Main() {
new DerivedClass().Test(3);
Console.ReadKey();
}
public void Test(int a) { }
}
class DerivedClass : BaseClass {
public void Test(object a) { }
}";
MemberResolveResult mrr = Resolve<MemberResolveResult>(program, "new DerivedClass().Test(3);", 4);
Assert.AreEqual("DerivedClass.Test", (mrr.ResolvedMember).FullyQualifiedName);
}
[Test]
public void OverrideShadowed()
{
string program = @"using System;
class BaseClass {
static void Main() {
new DerivedClass().Test(3);
Console.ReadKey();
}
public virtual void Test(int a) { }
}
class MiddleClass : BaseClass {
public void Test(object a) { }
}
class DerivedClass : MiddleClass {
public override void Test(int a) { }
}";
MemberResolveResult mrr = Resolve<MemberResolveResult>(program, "new DerivedClass().Test(3);", 4);
Assert.AreEqual("MiddleClass.Test", (mrr.ResolvedMember).FullyQualifiedName);
}
}
}

3
src/Main/ICSharpCode.SharpDevelop.Dom/Project/ICSharpCode.SharpDevelop.Dom.csproj

@ -99,6 +99,7 @@ @@ -99,6 +99,7 @@
<Compile Include="Src\NRefactoryResolver\NRefactoryASTConvertVisitor.cs" />
<Compile Include="Src\NRefactoryResolver\NRefactoryInformationProvider.cs" />
<Compile Include="Src\NRefactoryResolver\NRefactoryResolver.cs" />
<Compile Include="Src\NRefactoryResolver\ResolveVisitor.cs" />
<Compile Include="Src\NRefactoryResolver\TypeVisitor.cs" />
<Compile Include="Src\NRefactoryResolver\VBNetToCSharpConvertVisitor.cs" />
<Compile Include="Src\ProjectContent\DomAssemblyName.cs" />
@ -183,4 +184,4 @@ @@ -183,4 +184,4 @@
<Folder Include="Src\VBNet" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.Targets" />
</Project>
</Project>

54
src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/CSharp/ExpressionFinder.cs

@ -55,18 +55,61 @@ namespace ICSharpCode.SharpDevelop.Dom.CSharp @@ -55,18 +55,61 @@ namespace ICSharpCode.SharpDevelop.Dom.CSharp
enum FrameType
{
Global,
/// <summary>
/// "class C { * }"
/// </summary>
TypeDecl,
/// <summary>
/// "interface I { * }"
/// </summary>
Interface,
/// <summary>
/// "enum E { * }"
/// </summary>
Enum,
/// <summary>
/// "void Method(*) {}"
/// </summary>
ParameterList,
/// <summary>
/// "public string Property { * }"
/// </summary>
Property,
/// <summary>
/// "public event EventHandler SomethingChanged { * }"
/// </summary>
Event,
/// <summary>
/// "void Method() { * }"
/// </summary>
Statements,
/// <summary>
/// "if (*) {}"
/// </summary>
Expression,
/// <summary>
/// "new T { * }"
/// </summary>
ObjectInitializer,
/// <summary>
/// "[*] class ..."
/// </summary>
AttributeSection,
/// <summary>
/// "[Obsolete(*)] class ..."
/// </summary>
AttributeArguments,
/// <summary>
/// Type reference frame "typeof(*)"
/// </summary>
TypeReference,
/// <summary>
/// Type parameter declaration, "class C&lt;*gt;"
/// </summary>
TypeParameterDecl,
/// <summary>
/// The Frame is no longer active.
/// </summary>
Popped
}
@ -208,6 +251,9 @@ namespace ICSharpCode.SharpDevelop.Dom.CSharp @@ -208,6 +251,9 @@ namespace ICSharpCode.SharpDevelop.Dom.CSharp
case FrameType.AttributeSection:
SetContext(ExpressionContext.Attribute);
break;
case FrameType.TypeReference:
SetContext(ExpressionContext.Type);
break;
default:
SetContext(ExpressionContext.Default);
break;
@ -610,6 +656,13 @@ namespace ICSharpCode.SharpDevelop.Dom.CSharp @@ -610,6 +656,13 @@ namespace ICSharpCode.SharpDevelop.Dom.CSharp
case Tokens.Goto:
frame.SetContext(ExpressionContext.IdentifierExpected);
break;
case Tokens.As:
case Tokens.Is:
frame.SetContext(ExpressionContext.Type);
break;
case Tokens.Typeof:
frame.parenthesisChildType = FrameType.TypeReference;
break;
default:
if (Tokens.SimpleTypeName[token.kind]) {
if (frame.type == FrameType.Interface || frame.type == FrameType.TypeDecl) {
@ -934,3 +987,4 @@ namespace ICSharpCode.SharpDevelop.Dom.CSharp @@ -934,3 +987,4 @@ namespace ICSharpCode.SharpDevelop.Dom.CSharp
}
}

5
src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Implementations/AbstractReturnType.cs

@ -41,7 +41,10 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -41,7 +41,10 @@ namespace ICSharpCode.SharpDevelop.Dom
public override int GetHashCode()
{
return fullyQualifiedName.GetHashCode();
if (fullyQualifiedName == null)
return 0;
else
return fullyQualifiedName.GetHashCode();
}
string fullyQualifiedName = null;

8
src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Implementations/ConstructedReturnType.cs

@ -60,13 +60,7 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -60,13 +60,7 @@ namespace ICSharpCode.SharpDevelop.Dom
public override int GetHashCode()
{
int code = baseType.GetHashCode();
foreach (IReturnType t in typeArguments) {
if (t != null) {
code ^= t.GetHashCode();
}
}
return code;
return this.DotNetName.GetHashCode();
}
public override IReturnType BaseType {

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

@ -90,7 +90,7 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -90,7 +90,7 @@ namespace ICSharpCode.SharpDevelop.Dom
if (m.IsConstructor)
continue;
bool ok = true;
/*bool ok = true;
if (m.IsOverridable) {
StringComparer comparer = m.DeclaringType.ProjectContent.Language.NameComparer;
foreach (IMethod oldMethod in c.Methods) {
@ -105,7 +105,8 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -105,7 +105,8 @@ namespace ICSharpCode.SharpDevelop.Dom
}
}
if (ok)
l.Add(m);
l.Add(m);*/
l.Add(m);
}
}
}
@ -131,7 +132,7 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -131,7 +132,7 @@ namespace ICSharpCode.SharpDevelop.Dom
{
if (baseType != null) {
foreach (IProperty p in baseType.GetProperties()) {
bool ok = true;
/*bool ok = true;
if (p.IsOverridable) {
StringComparer comparer = p.DeclaringType.ProjectContent.Language.NameComparer;
foreach (IProperty oldProperty in c.Properties) {
@ -146,7 +147,8 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -146,7 +147,8 @@ namespace ICSharpCode.SharpDevelop.Dom
}
}
if (ok)
l.Add(p);
l.Add(p);*/
l.Add(p);
}
}
}

18
src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Implementations/GenericReturnType.cs

@ -27,7 +27,18 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -27,7 +27,18 @@ namespace ICSharpCode.SharpDevelop.Dom
{
if (rt == null || !rt.IsGenericReturnType)
return false;
return typeParameter.Equals(rt.CastToGenericReturnType().typeParameter);
GenericReturnType grt = rt.CastToGenericReturnType();
if ((typeParameter.Method == null) != (grt.typeParameter.Method == null))
return false;
return typeParameter.Index == grt.typeParameter.Index;
}
public override int GetHashCode()
{
if (typeParameter.Method != null)
return 17491 + typeParameter.Index;
else
return 81871 + typeParameter.Index;
}
public override T CastToDecoratingReturnType<T>()
@ -39,11 +50,6 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -39,11 +50,6 @@ namespace ICSharpCode.SharpDevelop.Dom
}
}
public override int GetHashCode()
{
return typeParameter.GetHashCode();
}
public GenericReturnType(ITypeParameter typeParameter)
{
if (typeParameter == null)

2
src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Interfaces/IDecoration.cs

@ -105,6 +105,6 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -105,6 +105,6 @@ namespace ICSharpCode.SharpDevelop.Dom
}
bool IsAccessible(IClass callingClass, bool isClassInInheritanceTree);
bool MustBeShown(IClass callingClass, bool showStatic, bool isClassInInheritanceTree);
//bool MustBeShown(IClass callingClass, bool showStatic, bool isClassInInheritanceTree);
}
}

6
src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/LanguageProperties.cs

@ -209,6 +209,9 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -209,6 +209,9 @@ namespace ICSharpCode.SharpDevelop.Dom
if (member is IProperty && ((IProperty)member).IsIndexer) {
return false;
}
if (member is IMethod && ((IMethod)member).IsConstructor) {
return false;
}
return member.IsStatic == showStatic;
}
#endregion
@ -303,6 +306,9 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -303,6 +306,9 @@ namespace ICSharpCode.SharpDevelop.Dom
if (member is ArrayReturnType.ArrayIndexer) {
return false;
}
if (member is IMethod && ((IMethod)member).IsConstructor) {
return false;
}
return member.IsStatic || !showStatic;
}

231
src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/MemberLookupHelper.cs

@ -7,6 +7,7 @@ @@ -7,6 +7,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
namespace ICSharpCode.SharpDevelop.Dom
{
@ -14,11 +15,180 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -14,11 +15,180 @@ namespace ICSharpCode.SharpDevelop.Dom
/// Class with methods to help finding the correct overload for a member.
/// </summary>
/// <remarks>
/// This class does member lookup like specified by the C# spec (ECMA-334, § 14.3).
/// This class does member lookup as specified by the C# spec (ECMA-334, § 14.3).
/// Other languages might need custom lookup methods.
/// </remarks>
public static class MemberLookupHelper
{
static List<IMember> GetAllMembers(IReturnType rt)
{
List<IMember> members = new List<IMember>();
if (rt != null) {
rt.GetMethods().ForEach(members.Add);
rt.GetProperties().ForEach(members.Add);
rt.GetFields().ForEach(members.Add);
rt.GetEvents().ForEach(members.Add);
}
return members;
}
public static List<IMember> LookupMember(IReturnType type, string name, IClass callingClass, LanguageProperties language, bool isInvocation)
{
if (language == null)
throw new ArgumentNullException("language");
bool isClassInInheritanceTree = false;
IClass underlyingClass = type.GetUnderlyingClass();
if (underlyingClass != null)
isClassInInheritanceTree = underlyingClass.IsTypeInInheritanceTree(callingClass);
IEnumerable<IMember> members;
if (language == LanguageProperties.VBNet && language.NameComparer.Equals(name, "New")) {
members = GetAllMembers(type).OfType<IMethod>().Where(m => m.IsConstructor).Select(m=>(IMember)m);
} else {
members = GetAllMembers(type).Where(m => language.NameComparer.Equals(m.Name, name));
}
return LookupMember(members, callingClass, isClassInInheritanceTree, isInvocation);
}
class SignatureComparer : IEqualityComparer<IMethod>
{
public bool Equals(IMethod x, IMethod y)
{
if (GetHashCode(x) != GetHashCode(y))
return false;
var paramsX = x.Parameters;
var paramsY = y.Parameters;
if (paramsX.Count != paramsY.Count)
return false;
if (x.TypeParameters.Count != y.TypeParameters.Count)
return false;
for (int i = 0; i < paramsX.Count; i++) {
IParameter px = paramsX[i];
IParameter py = paramsY[i];
if ((px.IsOut || px.IsRef) != (py.IsOut || py.IsRef))
return false;
if (!object.Equals(px.ReturnType, py.ReturnType))
return false;
}
return true;
}
Dictionary<IMethod, int> cachedHashes = new Dictionary<IMethod, int>();
public int GetHashCode(IMethod obj)
{
int hashCode;
if (cachedHashes.TryGetValue(obj, out hashCode))
return hashCode;
hashCode = obj.TypeParameters.Count;
unchecked {
foreach (IParameter p in obj.Parameters) {
hashCode *= 1000000579;
if (p.IsOut || p.IsRef)
hashCode += 1;
hashCode += p.ReturnType.GetHashCode();
}
}
cachedHashes[obj] = hashCode;
return hashCode;
}
}
sealed class InheritanceLevelComparer : IComparer<IClass>
{
public readonly static InheritanceLevelComparer Instance = new InheritanceLevelComparer();
public int Compare(IClass x, IClass y)
{
if (x == y)
return 0;
if (x.IsTypeInInheritanceTree(y))
return 1;
else
return -1;
}
}
public static List<IMember> LookupMember(IEnumerable<IMember> possibleMembers, IClass callingClass,
bool isClassInInheritanceTree, bool isInvocation)
{
// Console.WriteLine("Possible members:");
// foreach (IMember m in possibleMembers) {
// Console.WriteLine(" " + m.DotNetName);
// }
IEnumerable<IMember> accessibleMembers = possibleMembers.Where(member => member.IsAccessible(callingClass, isClassInInheritanceTree));
if (isInvocation) {
accessibleMembers = accessibleMembers.Where(IsInvocable);
}
// base most member => most derived member
//Dictionary<IMember, IMember> overrideDict = new Dictionary<IMember, IMember>();
Dictionary<IMethod, IMethod> overrideMethodDict = new Dictionary<IMethod, IMethod>(new SignatureComparer());
IMember nonMethodOverride = null;
List<IMember> results = new List<IMember>();
foreach (var group in accessibleMembers
.GroupBy((IMember m) => m.DeclaringType.GetCompoundClass())
.OrderByDescending(g => g.Key, InheritanceLevelComparer.Instance))
{
//Console.WriteLine("Member group " + group.Key);
foreach (IMember m in group) {
//Console.WriteLine(" " + m.DotNetName);
if (m.IsOverride) {
IMethod method = m as IMethod;
if (method != null)
overrideMethodDict[method] = method;
else
nonMethodOverride = m;
} else {
IMethod method = m as IMethod;
if (method != null && overrideMethodDict.TryGetValue(method, out method))
results.Add(method);
else
results.Add(m);
}
}
if (results.Count > 0)
break;
}
return results;
}
static bool IsInvocable(IMember member)
{
if (member is IMethod || member is IEvent)
return true;
IProperty p = member as IProperty;
if (p != null && p.Parameters.Count > 0)
return true;
IClass c = member.ReturnType.GetUnderlyingClass();
return c != null && c.ClassType == ClassType.Delegate;
}
/// <summary>
/// Gets all accessible members, including indexers and constructors.
/// </summary>
public static List<IMember> GetAccessibleMembers(IReturnType rt, IClass callingClass, LanguageProperties language)
{
if (language == null)
throw new ArgumentNullException("language");
bool isClassInInheritanceTree = false;
IClass underlyingClass = rt.GetUnderlyingClass();
if (underlyingClass != null)
isClassInInheritanceTree = underlyingClass.IsTypeInInheritanceTree(callingClass);
List<IMember> result = new List<IMember>();
foreach (var g in GetAllMembers(rt).GroupBy(m => m.Name, language.NameComparer)) {
result.AddRange(LookupMember(g, callingClass, isClassInInheritanceTree, false));
}
return result;
}
#region FindOverload
/// <summary>
/// Finds the correct overload according to the C# specification.
@ -26,18 +196,17 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -26,18 +196,17 @@ namespace ICSharpCode.SharpDevelop.Dom
/// <param name="methods">List with the methods to check.<br/>
/// <b>Generic methods in the input type are replaced by methods with have the types substituted!</b>
/// </param>
/// <param name="typeParameters">The type parameters passed to the method.</param>
/// <param name="arguments">The types of the arguments passed to the method.</param>
/// <param name="resultIsAcceptable">Out parameter. Will be true if the resulting method
/// is an acceptable match, false if the resulting method is just a guess and will lead
/// to a compile error.</param>
/// <returns>The method that will be called.</returns>
public static IMethod FindOverload(IList<IMethod> methods, IReturnType[] typeParameters, IReturnType[] arguments, out bool resultIsAcceptable)
public static IMethod FindOverload(IList<IMethod> methods, IReturnType[] arguments, out bool resultIsAcceptable)
{
resultIsAcceptable = false;
if (methods.Count == 0)
return null;
int[] ranking = RankOverloads(methods, typeParameters, arguments, false, out resultIsAcceptable);
int[] ranking = RankOverloads(methods, arguments, false, out resultIsAcceptable);
int bestRanking = -1;
int best = 0;
for (int i = 0; i < ranking.Length; i++) {
@ -76,8 +245,6 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -76,8 +245,6 @@ namespace ICSharpCode.SharpDevelop.Dom
/// <param name="list">List with the methods to check.<br/>
/// <b>Generic methods in the input type are replaced by methods with have the types substituted!</b>
/// </param>
/// <param name="typeParameters">List with the type parameters passed to the method.
/// Can be null (=no type parameters)</param>
/// <param name="arguments">The types of the arguments passed to the method.
/// A null return type means any argument type is allowed.</param>
/// <param name="allowAdditionalArguments">Specifies whether the method can have
@ -86,7 +253,6 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -86,7 +253,6 @@ namespace ICSharpCode.SharpDevelop.Dom
/// method is acceptable for a method call (no invalid casts)</param>
/// <returns>Integer array. Each value in the array </returns>
public static int[] RankOverloads(IList<IMethod> list,
IReturnType[] typeParameters,
IReturnType[] arguments,
bool allowAdditionalArguments,
out bool acceptableMatch)
@ -94,47 +260,21 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -94,47 +260,21 @@ namespace ICSharpCode.SharpDevelop.Dom
acceptableMatch = false;
if (list.Count == 0) return new int[] {};
List<IMethodOrProperty> l2 = new List<IMethodOrProperty>(list.Count);
IReturnType[][] inferredTypeParameters;
// See ECMA-334, § 14.3
// If type parameters are specified, remove all methods from the list that do not
// use the specified number of parameters.
if (typeParameters != null && typeParameters.Length > 0) {
for (int i = 0; i < list.Count; i++) {
IMethod m = list[i];
if (m.TypeParameters.Count == typeParameters.Length) {
m = (IMethod)m.CreateSpecializedMember();
m.ReturnType = ConstructedReturnType.TranslateType(m.ReturnType, typeParameters, true);
for (int j = 0; j < m.Parameters.Count; ++j) {
m.Parameters[j].ReturnType = ConstructedReturnType.TranslateType(m.Parameters[j].ReturnType, typeParameters, true);
}
list[i] = m;
l2.Add(m);
}
}
int[] innerRanking = RankOverloads(l2, arguments, allowAdditionalArguments, out acceptableMatch, out inferredTypeParameters);
int[] ranking = new int[list.Count];
int innerIndex = 0;
for (int i = 0; i < ranking.Length; i++) {
if (list[i].TypeParameters.Count == typeParameters.Length) {
ranking[i] = innerRanking[innerIndex++];
} else {
ranking[i] = 0;
}
}
return ranking;
} else {
// Note that when there are no type parameters, methods having type parameters
// are not removed, since the type inference process might be able to infer the
// type arguments.
foreach (IMethod m in list) l2.Add(m);
int[] ranking = RankOverloads(l2, arguments, allowAdditionalArguments, out acceptableMatch, out inferredTypeParameters);
ApplyInferredTypeParameters(list, inferredTypeParameters);
return ranking;
}
// We longer pass the explicit type arguments to RankOverloads, this is now done when
// the method group is constructed.
// Note that when there are no type parameters, methods having type parameters
// are not removed, since the type inference process might be able to infer the
// type arguments.
List<IMethodOrProperty> l2 = new List<IMethodOrProperty>();
foreach (IMethod m in list) l2.Add(m);
int[] ranking = RankOverloads(l2, arguments, allowAdditionalArguments, out acceptableMatch, out inferredTypeParameters);
ApplyInferredTypeParameters(list, inferredTypeParameters);
return ranking;
}
static void ApplyInferredTypeParameters(IList<IMethod> list, IReturnType[][] inferredTypeParameters)
@ -939,6 +1079,7 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -939,6 +1079,7 @@ namespace ICSharpCode.SharpDevelop.Dom
public static IMember FindSimilarMember(IClass type, IMember member)
{
member = GetGenericMember(member);
if (member is IMethod) {
IMethod parentMethod = (IMethod)member;
foreach (IMethod m in type.Methods) {

4
src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/NRefactoryResolver/CSharpToVBNetConvertVisitor.cs

@ -366,7 +366,7 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver @@ -366,7 +366,7 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
&& (parentIE == null || parentIE.TargetObject != identifierExpression))
{
ResolveResult rr = resolver.ResolveInternal(identifierExpression, ExpressionContext.Default);
if (rr is MethodResolveResult) {
if (rr is MethodGroupResolveResult) {
ReplaceCurrentNode(new AddressOfExpression(identifierExpression));
}
}
@ -385,7 +385,7 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver @@ -385,7 +385,7 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
&& (parentIE == null || parentIE.TargetObject != fieldReferenceExpression))
{
ResolveResult rr = resolver.ResolveInternal(fieldReferenceExpression, ExpressionContext.Default);
if (rr is MethodResolveResult) {
if (rr is MethodGroupResolveResult) {
ReplaceCurrentNode(new AddressOfExpression(fieldReferenceExpression));
}
}

328
src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/NRefactoryResolver/NRefactoryResolver.cs

@ -11,6 +11,7 @@ using System.Collections.ObjectModel; @@ -11,6 +11,7 @@ using System.Collections.ObjectModel;
using System.Collections.Generic;
using System.IO;
using System.Diagnostics;
using System.Linq;
using ICSharpCode.NRefactory.Ast;
using ICSharpCode.NRefactory.Visitors;
@ -115,6 +116,9 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver @@ -115,6 +116,9 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
{
Expression expr = SpecialConstructs(expression);
if (expr == null) {
// SEMICOLON HACK: Parsing expressions without trailing semicolon does not work correctly
if (language == NR.SupportedLanguage.CSharp && !expression.EndsWith(";"))
expression += ";";
using (NR.IParser p = NR.ParserFactory.CreateParser(language, new System.IO.StringReader(expression))) {
expr = p.ParseExpression();
if (expr != null) {
@ -330,11 +334,11 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver @@ -330,11 +334,11 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
if (expr is IdentifierExpression) {
return (expr as IdentifierExpression).Identifier;
} else if (expr is MemberReferenceExpression) {
TypeVisitor typeVisitor = new TypeVisitor(this);
ResolveVisitor typeVisitor = new ResolveVisitor(this);
MemberReferenceExpression fieldReferenceExpression = (MemberReferenceExpression)expr;
IReturnType type = fieldReferenceExpression.TargetObject.AcceptVisitor(typeVisitor, null) as IReturnType;
if (type is TypeVisitor.NamespaceReturnType) {
return type.FullyQualifiedName + "." + fieldReferenceExpression.FieldName;
ResolveResult rr = typeVisitor.Resolve(fieldReferenceExpression.TargetObject);
if (rr is NamespaceResolveResult) {
return ((NamespaceResolveResult)rr).Name + "." + fieldReferenceExpression.MemberName;
}
}
return null;
@ -344,12 +348,12 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver @@ -344,12 +348,12 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
{
if (name == null)
return null;
IClass c = SearchClass(name, position);
IClass c = SearchClass(name, 0, position);
if (c != null) {
if (c.IsTypeInInheritanceTree(c.ProjectContent.SystemTypes.Attribute.GetUnderlyingClass()))
return c;
}
return SearchClass(name + "Attribute", position);
return SearchClass(name + "Attribute", 0, position);
}
ResolveResult ResolveAttribute(Expression expr, NR.Location position)
@ -375,8 +379,8 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver @@ -375,8 +379,8 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
if (m.IsConstructor && !m.IsStatic)
ctors.Add(m);
}
TypeVisitor typeVisitor = new TypeVisitor(this);
return CreateMemberResolveResult(typeVisitor.FindOverload(ctors, null, ie.Arguments));
//TypeVisitor typeVisitor = new TypeVisitor(this);
//return CreateMemberResolveResult(typeVisitor.FindOverload(ctors, null, ie.Arguments));
}
}
return null;
@ -384,6 +388,12 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver @@ -384,6 +388,12 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
public ResolveResult ResolveInternal(Expression expr, ExpressionContext context)
{
if (expr is IdentifierExpression)
return ResolveIdentifier(expr as IdentifierExpression, context);
ResolveVisitor resolveVisitor = new ResolveVisitor(this);
return resolveVisitor.Resolve(expr);
/*
TypeVisitor typeVisitor = new TypeVisitor(this);
IReturnType type;
@ -437,7 +447,7 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver @@ -437,7 +447,7 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
return result;
}
} else if (expr is IdentifierExpression) {
ResolveResult result = ResolveIdentifier(((IdentifierExpression)expr).Identifier, expr.StartLocation, context);
ResolveResult result = ResolveIdentifier(((IdentifierExpression)expr), context);
if (result != null)
return result;
else
@ -490,9 +500,11 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver @@ -490,9 +500,11 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
return rr;
}
return new ResolveResult(callingClass, callingMember, type);
*/
}
ResolveResult ResolveMemberReferenceExpression(IReturnType type, MemberReferenceExpression memberReferenceExpression)
/*
internal ResolveResult ResolveMemberReferenceExpression(IReturnType type, MemberReferenceExpression memberReferenceExpression)
{
IClass c;
IMember member;
@ -538,6 +550,7 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver @@ -538,6 +550,7 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
}
return ResolveMethod(type, memberReferenceExpression.FieldName);
}
*/
public TextReader ExtractCurrentMethod(string fileContent)
{
@ -588,8 +601,8 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver @@ -588,8 +601,8 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
// Fix for SD2-511 (Code completion in inserted line)
if (language == NR.SupportedLanguage.CSharp) {
// Do not do this for VB: the parser does not correct create the
// ForEachStatement when the method in truncated in the middle
// Do not do this for VB: the parser does not correctly create the
// ForEachStatement when the method in truncated in the middle.
// VB does not have the "inserted line looks like variable declaration"-problem
// anyways.
if (caretLine > startLine && caretLine < endLine)
@ -624,17 +637,27 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver @@ -624,17 +637,27 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
}
#region Resolve Identifier
public ResolveResult ResolveIdentifier(string identifier, NR.Location position, ExpressionContext context)
internal IReturnType ConstructType(IReturnType baseType, List<TypeReference> typeArguments)
{
ResolveResult result = ResolveIdentifierInternal(identifier, position);
if (typeArguments == null || typeArguments.Count == 0)
return baseType;
return new ConstructedReturnType(baseType,
typeArguments.ConvertAll(r => TypeVisitor.CreateReturnType(r, this)));
}
public ResolveResult ResolveIdentifier(IdentifierExpression expr, ExpressionContext context)
{
ResolveResult result = ResolveIdentifierInternal(expr);
if (result is TypeResolveResult)
return result;
NR.Location position = expr.StartLocation;
string identifier = expr.Identifier;
ResolveResult result2 = null;
IReturnType t = SearchType(identifier, position);
IReturnType t = SearchType(identifier, expr.TypeArguments.Count, position);
if (t != null) {
result2 = new TypeResolveResult(callingClass, callingMember, t);
result2 = new TypeResolveResult(callingClass, callingMember, ConstructType(t, expr.TypeArguments));
} else {
if (callingClass != null) {
if (callingMember is IMethod) {
@ -659,6 +682,11 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver @@ -659,6 +682,11 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
return new MixedResolveResult(result, result2);
}
public ResolveResult ResolveIdentifier(string identifier, NR.Location position, ExpressionContext context)
{
return ResolveIdentifier(new IdentifierExpression(identifier) { StartLocation = position }, context);
}
IField CreateLocalVariableField(LocalLookupVariable var)
{
IReturnType type = GetVariableType(var);
@ -669,8 +697,10 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver @@ -669,8 +697,10 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
return f;
}
ResolveResult ResolveIdentifierInternal(string identifier, NR.Location position)
ResolveResult ResolveIdentifierInternal(IdentifierExpression identifierExpression)
{
NR.Location position = identifierExpression.StartLocation;
string identifier = identifierExpression.Identifier;
if (callingMember != null) { // LocalResolveResult requires callingMember to be set
LocalLookupVariable var = SearchVariable(identifier, position);
if (var != null) {
@ -690,23 +720,17 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver @@ -690,23 +720,17 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
}
}
if (callingClass != null) {
IMember member = GetMember(callingClass.DefaultReturnType, identifier);
if (member != null) {
return CreateMemberResolveResult(member);
}
ResolveResult result = ResolveMethod(callingClass.DefaultReturnType, identifier);
if (result != null)
return result;
// try if there exists a static member in outer classes named typeName
IClass tmp = callingClass.DeclaringType;
while (tmp != null) {
member = GetMember(tmp.DefaultReturnType, identifier);
if (member != null && member.IsStatic) {
return new MemberResolveResult(callingClass, callingMember, member);
}
IClass tmp = callingClass;
do {
ResolveResult rr = ResolveMember(tmp.DefaultReturnType, identifier,
identifierExpression.TypeArguments,
identifierExpression.Parent is InvocationExpression,
false);
if (rr != null && rr.IsValid)
return rr;
// also try to resolve the member in outer classes
tmp = tmp.DeclaringType;
}
} while (tmp != null);
}
string namespaceName = SearchNamespace(identifier, position);
@ -717,15 +741,14 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver @@ -717,15 +741,14 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
if (languageProperties.CanImportClasses) {
foreach (IUsing @using in cu.Usings) {
foreach (string import in @using.Usings) {
IClass c = GetClass(import);
IClass c = GetClass(import, 0);
if (c != null) {
IMember member = GetMember(c.DefaultReturnType, identifier);
if (member != null) {
return CreateMemberResolveResult(member);
}
ResolveResult result = ResolveMethod(c.DefaultReturnType, identifier);
if (result != null)
return result;
ResolveResult rr = ResolveMember(c.DefaultReturnType, identifier,
identifierExpression.TypeArguments,
identifierExpression.Parent is InvocationExpression,
false);
if (rr != null && rr.IsValid)
return rr;
}
}
}
@ -734,6 +757,7 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver @@ -734,6 +757,7 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
if (languageProperties.ImportModules) {
ArrayList list = new ArrayList();
CtrlSpaceResolveHelper.AddImportedNamespaceContents(list, cu, callingClass);
List<IMember> resultMembers = new List<IMember>();
foreach (object o in list) {
IClass c = o as IClass;
if (c != null && IsSameName(identifier, c.Name)) {
@ -741,13 +765,10 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver @@ -741,13 +765,10 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
}
IMember member = o as IMember;
if (member != null && IsSameName(identifier, member.Name)) {
if (member is IMethod) {
return new MethodResolveResult(callingClass, callingMember, member.DeclaringType.DefaultReturnType, member.Name);
} else {
return CreateMemberResolveResult(member);
}
resultMembers.Add(member);
}
}
return CreateMemberOrMethodGroupResolveResult(null, identifier, resultMembers, false);
}
return null;
@ -760,25 +781,59 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver @@ -760,25 +781,59 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
return new MemberResolveResult(callingClass, callingMember, member);
}
#region ResolveMethod
ResolveResult ResolveMethod(IReturnType type, string identifier)
#region ResolveMember
internal ResolveResult ResolveMember(IReturnType declaringType, string memberName,
List<TypeReference> typeArguments, bool isInvocation,
bool allowExtensionMethods)
{
if (type == null)
return null;
foreach (IMethod method in type.GetMethods()) {
if (IsSameName(identifier, method.Name))
return new MethodResolveResult(callingClass, callingMember, type, method.Name);
}
if (languageProperties.SupportsExtensionMethods && callingClass != null) {
ArrayList list = new ArrayList();
ResolveResult.AddExtensions(languageProperties, list, callingClass, type);
foreach (IMethodOrProperty mp in list) {
if (mp is IMethod && IsSameName(mp.Name, identifier)) {
return new MethodResolveResult(callingClass, callingMember, type, mp.Name);
}
List<IMember> members = MemberLookupHelper.LookupMember(declaringType, memberName, callingClass, languageProperties, isInvocation);
if (members != null && typeArguments != null && typeArguments.Count != 0) {
List<IReturnType> typeArgs = typeArguments.ConvertAll(r => TypeVisitor.CreateReturnType(r, this));
members = members.OfType<IMethod>()
.Where((IMethod m) => m.TypeParameters.Count == typeArgs.Count)
.Select((IMethod originalMethod) => {
IMethod m = (IMethod)originalMethod.CreateSpecializedMember();
m.ReturnType = ConstructedReturnType.TranslateType(m.ReturnType, typeArgs, true);
for (int j = 0; j < m.Parameters.Count; ++j) {
m.Parameters[j].ReturnType = ConstructedReturnType.TranslateType(m.Parameters[j].ReturnType, typeArgs, true);
}
return (IMember)m;
})
.ToList();
}
if (language == NR.SupportedLanguage.VBNet && members != null && members.Count > 0) {
// use the correct casing of the member name
memberName = members[0].Name;
}
return CreateMemberOrMethodGroupResolveResult(declaringType, memberName, members, allowExtensionMethods);
}
internal ResolveResult CreateMemberOrMethodGroupResolveResult(IReturnType declaringType, string memberName, List<IMember> members, bool allowExtensionMethods)
{
List<IMethod> methods = new List<IMethod>();
if (members != null) {
foreach (IMember m in members) {
if (m is IMethod)
methods.Add(m as IMethod);
else
return new MemberResolveResult(callingClass, callingMember, m);
}
}
return null;
if (allowExtensionMethods == false || declaringType == null) {
if (methods.Count == 0)
return null;
else
return new MethodGroupResolveResult(callingClass, callingMember,
declaringType ?? methods[0].DeclaringTypeReference,
memberName, methods,
emptyMethodList);
} else {
return new MethodGroupResolveResult(callingClass, callingMember,
declaringType,
memberName, methods,
new LazyList<IMethod>(() => SearchExtensionMethods(memberName)));
}
}
#endregion
@ -896,15 +951,6 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver @@ -896,15 +951,6 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
} else if ("myclass".Equals(expression, StringComparison.InvariantCultureIgnoreCase)) {
return new ClassReferenceExpression();
} // Global is handled in Resolve() because we don't need an expression for that
} else if (language == NR.SupportedLanguage.CSharp) {
// generic type names are no expressions, only property access on them is an expression
if (expression.EndsWith(">")) {
MemberReferenceExpression expr = ParseExpression(expression + ".Prop") as MemberReferenceExpression;
if (expr != null) {
return expr.TargetObject;
}
}
return null;
}
return null;
}
@ -959,103 +1005,26 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver @@ -959,103 +1005,26 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
return projectContent.SearchNamespace(name, callingClass, cu, position.Line, position.Column);
}
public IClass GetClass(string fullName)
public IClass GetClass(string fullName, int typeArgumentCount)
{
return projectContent.GetClass(fullName, 0);
return projectContent.GetClass(fullName, typeArgumentCount);
}
/// <remarks>
/// use the usings and the name of the namespace to find a class
/// </remarks>
public IClass SearchClass(string name, NR.Location position)
public IClass SearchClass(string name, int typeArgumentCount, NR.Location position)
{
IReturnType t = SearchType(name, position);
IReturnType t = SearchType(name, typeArgumentCount, position);
return (t != null) ? t.GetUnderlyingClass() : null;
}
public IReturnType SearchType(string name, NR.Location position)
public IReturnType SearchType(string name, int typeArgumentCount, NR.Location position)
{
if (position.IsEmpty)
return projectContent.SearchType(new SearchTypeRequest(name, 0, callingClass, cu, caretLine, caretColumn)).Result;
return projectContent.SearchType(new SearchTypeRequest(name, typeArgumentCount, callingClass, cu, caretLine, caretColumn)).Result;
else
return projectContent.SearchType(new SearchTypeRequest(name, 0, callingClass, cu, position.Line, position.Column)).Result;
}
#region Helper for TypeVisitor
#region SearchMethod
public List<IMethod> SearchMethod(string memberName)
{
List<IMethod> methods = null;
// Search for the method in the callingClass and outer classes
IClass tmp = callingClass;
while (tmp != null) {
methods = SearchMethod(tmp.DefaultReturnType, memberName);
if (methods.Count > 0)
return methods;
tmp = tmp.DeclaringType;
}
if (languageProperties.CanImportClasses) {
foreach (IUsing @using in cu.Usings) {
foreach (string import in @using.Usings) {
IClass c = projectContent.GetClass(import, 0);
if (c != null) {
methods = SearchMethod(c.DefaultReturnType, memberName);
if (methods.Count > 0)
return methods;
}
}
}
}
if (methods == null)
methods = new List<IMethod>();
if (languageProperties.ImportModules) {
ArrayList list = new ArrayList();
CtrlSpaceResolveHelper.AddImportedNamespaceContents(list, cu, callingClass);
foreach (object o in list) {
IMethod m = o as IMethod;
if (m != null && IsSameName(m.Name, memberName)) {
methods.Add(m);
}
}
}
return methods;
}
/// <summary>
/// Gets the list of methods on the return type that have the specified name.
/// </summary>
public List<IMethod> SearchMethod(IReturnType type, string memberName)
{
List<IMethod> methods = new List<IMethod>();
if (type == null)
return methods;
bool isClassInInheritanceTree = false;
if (callingClass != null)
isClassInInheritanceTree = callingClass.IsTypeInInheritanceTree(type.GetUnderlyingClass());
if (language == NR.SupportedLanguage.VBNet && IsSameName(memberName, "New")) {
foreach (IMethod m in type.GetMethods()) {
if (m.IsConstructor && m.IsAccessible(callingClass, isClassInInheritanceTree)) {
methods.Add(m);
}
}
}
foreach (IMethod m in type.GetMethods()) {
if (IsSameName(m.Name, memberName)
&& m.IsAccessible(callingClass, isClassInInheritanceTree)
) {
methods.Add(m);
}
}
return methods;
return projectContent.SearchType(new SearchTypeRequest(name, typeArgumentCount, callingClass, cu, position.Line, position.Column)).Result;
}
public IList<IMethod> SearchExtensionMethods(string name)
@ -1072,6 +1041,7 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver @@ -1072,6 +1041,7 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
ReadOnlyCollection<IMethodOrProperty> cachedExtensionMethods;
IClass cachedExtensionMethods_LastClass; // invalidate cache when callingClass != LastClass
static readonly IMethod[] emptyMethodList = new IMethod[0];
static readonly ReadOnlyCollection<IMethodOrProperty> emptyMethodOrPropertyList = new ReadOnlyCollection<IMethodOrProperty>(new IMethodOrProperty[0]);
public ReadOnlyCollection<IMethodOrProperty> SearchAllExtensionMethods()
@ -1084,52 +1054,9 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver @@ -1084,52 +1054,9 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
}
return cachedExtensionMethods;
}
#endregion
#region SearchMember
// no methods or indexer
public IMember GetMember(IReturnType type, string memberName)
{
if (type == null)
return null;
bool isClassInInheritanceTree = false;
if (callingClass != null)
isClassInInheritanceTree = callingClass.IsTypeInInheritanceTree(type.GetUnderlyingClass());
// when there are multiple possible members, use the member from the more derived class
// (this is necessary to support a field shadowing a property)
IMember result = null;
foreach (IProperty p in type.GetProperties()) {
if (IsSameName(p.Name, memberName)) {
result = GetMoreDerivedMember(result, p);
}
}
foreach (IField f in type.GetFields()) {
if (IsSameName(f.Name, memberName)) {
result = GetMoreDerivedMember(result, f);
}
}
foreach (IEvent e in type.GetEvents()) {
if (IsSameName(e.Name, memberName)) {
result = GetMoreDerivedMember(result, e);
}
}
return result;
}
IMember GetMoreDerivedMember(IMember m1, IMember m2)
{
if (m1 == null) return m2;
if (m2 == null) return m1;
if (m1.DeclaringType.IsTypeInInheritanceTree(m2.DeclaringType))
return m1;
else
return m2;
}
#endregion
#region DynamicLookup
/*
/// <remarks>
/// does the dynamic lookup for the identifier
/// </remarks>
@ -1141,6 +1068,7 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver @@ -1141,6 +1068,7 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
}
return (rr != null) ? rr.ResolvedType : null;
}
*/
IParameter SearchMethodParameter(string parameter)
{
@ -1191,7 +1119,6 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver @@ -1191,7 +1119,6 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
return null;
}
#endregion
#endregion
IClass GetPrimitiveClass(string systemType, string newName)
{
@ -1364,3 +1291,4 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver @@ -1364,3 +1291,4 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
}
}

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

@ -0,0 +1,570 @@ @@ -0,0 +1,570 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Daniel Grunwald"/>
// <version>$Revision$</version>
// </file>
using System;
using System.Collections.Generic;
using System.Text;
using System.Linq;
using ICSharpCode.NRefactory;
using ICSharpCode.NRefactory.Ast;
using ICSharpCode.NRefactory.Visitors;
namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
{
/// <summary>
/// Resolves expressions.
/// </summary>
sealed class ResolveVisitor : AbstractAstVisitor
{
NRefactoryResolver resolver;
public ResolveVisitor(NRefactoryResolver resolver)
{
this.resolver = resolver;
}
ResolveResult CreateResolveResult(TypeReference reference)
{
return CreateResolveResult(TypeVisitor.CreateReturnType(reference, resolver));
}
ResolveResult CreateResolveResult(Expression expression)
{
return CreateResolveResult(ResolveType(expression));
}
ResolveResult CreateResolveResult(IReturnType resolvedType)
{
if (resolvedType == null)
return null;
else
return new ResolveResult(resolver.CallingClass, resolver.CallingMember, resolvedType);
}
TypeResolveResult CreateTypeResolveResult(IReturnType resolvedType)
{
if (resolvedType == null)
return null;
else
return new TypeResolveResult(resolver.CallingClass, resolver.CallingMember, resolvedType);
}
MemberResolveResult CreateMemberResolveResult(IMember member)
{
if (member == null)
return null;
else
return new MemberResolveResult(resolver.CallingClass, resolver.CallingMember, member);
}
readonly Dictionary<Expression, ResolveResult> cachedResults = new Dictionary<Expression, ResolveResult>();
public ResolveResult Resolve(Expression expression)
{
ResolveResult rr;
if (!cachedResults.TryGetValue(expression, out rr)) {
rr = (ResolveResult)expression.AcceptVisitor(this, null);
cachedResults[expression] = rr;
}
return rr;
}
public IReturnType ResolveType(Expression expression)
{
ResolveResult rr = Resolve(expression);
if (rr != null)
return rr.ResolvedType;
else
return null;
}
public override object VisitAnonymousMethodExpression(AnonymousMethodExpression anonymousMethodExpression, object data)
{
AnonymousMethodReturnType amrt = new AnonymousMethodReturnType(resolver.CompilationUnit);
if (anonymousMethodExpression.HasParameterList) {
amrt.MethodParameters = new List<IParameter>();
foreach (ParameterDeclarationExpression param in anonymousMethodExpression.Parameters) {
amrt.MethodParameters.Add(NRefactoryASTConvertVisitor.CreateParameter(param, resolver.CallingMember as IMethod, resolver.CallingClass, resolver.CompilationUnit));
}
}
return CreateResolveResult(amrt);
}
public override object VisitArrayCreateExpression(ArrayCreateExpression arrayCreateExpression, object data)
{
if (arrayCreateExpression.IsImplicitlyTyped) {
return CreateResolveResult(arrayCreateExpression.ArrayInitializer);
} else {
return CreateResolveResult(arrayCreateExpression.CreateType);
}
}
public override object VisitAssignmentExpression(AssignmentExpression assignmentExpression, object data)
{
return CreateResolveResult(assignmentExpression.Left);
}
public override object VisitBaseReferenceExpression(BaseReferenceExpression baseReferenceExpression, object data)
{
if (resolver.CallingClass == null) {
return null;
}
if (resolver.Language == SupportedLanguage.VBNet && IsInstanceConstructor(resolver.CallingMember)) {
return new VBBaseOrThisReferenceInConstructorResolveResult(
resolver.CallingClass, resolver.CallingMember, resolver.CallingClass.BaseType);
} else {
return CreateResolveResult(resolver.CallingClass.BaseType);
}
}
public override object VisitBinaryOperatorExpression(BinaryOperatorExpression binaryOperatorExpression, object data)
{
switch (binaryOperatorExpression.Op) {
case BinaryOperatorType.NullCoalescing:
return CreateResolveResult(binaryOperatorExpression.Right);
case BinaryOperatorType.DivideInteger:
return CreateResolveResult(resolver.ProjectContent.SystemTypes.Int32);
case BinaryOperatorType.Concat:
return CreateResolveResult(resolver.ProjectContent.SystemTypes.String);
case BinaryOperatorType.Equality:
case BinaryOperatorType.InEquality:
case BinaryOperatorType.ReferenceEquality:
case BinaryOperatorType.ReferenceInequality:
case BinaryOperatorType.LogicalAnd:
case BinaryOperatorType.LogicalOr:
case BinaryOperatorType.LessThan:
case BinaryOperatorType.LessThanOrEqual:
case BinaryOperatorType.GreaterThan:
case BinaryOperatorType.GreaterThanOrEqual:
return CreateResolveResult(resolver.ProjectContent.SystemTypes.Boolean);
default:
return CreateResolveResult(MemberLookupHelper.GetCommonType(
resolver.ProjectContent,
ResolveType(binaryOperatorExpression.Left),
ResolveType(binaryOperatorExpression.Right)));
}
}
public override object VisitCastExpression(CastExpression castExpression, object data)
{
return CreateResolveResult(castExpression.CastTo);
}
public override object VisitCheckedExpression(CheckedExpression checkedExpression, object data)
{
return CreateResolveResult(checkedExpression.Expression);
}
public override object VisitClassReferenceExpression(ClassReferenceExpression classReferenceExpression, object data)
{
if (resolver.CallingClass != null)
return CreateResolveResult(resolver.CallingClass.DefaultReturnType);
else
return null;
}
public override object VisitCollectionInitializerExpression(CollectionInitializerExpression collectionInitializerExpression, object data)
{
// used for implicitly typed arrays
if (collectionInitializerExpression.CreateExpressions.Count == 0)
return null;
IReturnType combinedRT = ResolveType(collectionInitializerExpression.CreateExpressions[0]);
for (int i = 1; i < collectionInitializerExpression.CreateExpressions.Count; i++) {
IReturnType rt = ResolveType(collectionInitializerExpression.CreateExpressions[i]);
combinedRT = MemberLookupHelper.GetCommonType(resolver.ProjectContent, combinedRT, rt);
}
return CreateResolveResult(new ArrayReturnType(resolver.ProjectContent, combinedRT, 1));
}
public override object VisitConditionalExpression(ConditionalExpression conditionalExpression, object data)
{
return CreateResolveResult(MemberLookupHelper.GetCommonType(
resolver.ProjectContent,
ResolveType(conditionalExpression.TrueExpression),
ResolveType(conditionalExpression.FalseExpression)));
}
public override object VisitConstructorInitializer(ConstructorInitializer constructorInitializer, object data)
{
return null;
}
public override object VisitDefaultValueExpression(DefaultValueExpression defaultValueExpression, object data)
{
return CreateResolveResult(defaultValueExpression.TypeReference);
}
public override object VisitDirectionExpression(DirectionExpression directionExpression, object data)
{
return CreateResolveResult(directionExpression.Expression);
}
public override object VisitIdentifierExpression(IdentifierExpression identifierExpression, object data)
{
ResolveResult result = resolver.ResolveIdentifier(identifierExpression, ExpressionContext.Default);
if (result != null)
return result;
else
return new UnknownIdentifierResolveResult(resolver.CallingClass, resolver.CallingMember, identifierExpression.Identifier);
}
public override object VisitIndexerExpression(IndexerExpression indexerExpression, object data)
{
IReturnType target = ResolveType(indexerExpression.TargetObject);
return CreateMemberResolveResult(
GetIndexer(target, indexerExpression.Indexes)
);
}
IProperty GetIndexer(IReturnType target, List<Expression> indexes)
{
if (target == null)
return null;
return MemberLookupHelper.FindOverload(
target.GetProperties().Where((IProperty p) => p.IsIndexer).ToList(),
indexes.Select<Expression, IReturnType>(ResolveType).ToArray()
);
}
IProperty GetVisualBasicIndexer(InvocationExpression invocationExpression)
{
ResolveResult targetRR = Resolve(invocationExpression.TargetObject);
if (targetRR != null) {
// Visual Basic can call indexers in two ways:
// collection(index) - use indexer
// collection.Item(index) - use parametrized property
if (invocationExpression.TargetObject is IdentifierExpression || invocationExpression.TargetObject is MemberReferenceExpression) {
// only IdentifierExpression/MemberReferenceExpression can represent a parametrized property
// - the check is necessary because collection.Items and collection.Item(index) both
// resolve to the same property, but we want to use the default indexer for the second call in
// collection.Item(index1)(index2)
MemberResolveResult memberRR = targetRR as MemberResolveResult;
if (memberRR != null) {
IProperty p = memberRR.ResolvedMember as IProperty;
if (p != null && p.Parameters.Count > 0) {
// this is a parametrized property
return p;
}
}
}
// not a parametrized property - try normal indexer
return GetIndexer(targetRR.ResolvedType, invocationExpression.Arguments);
} else {
return null;
}
}
public override object VisitInvocationExpression(InvocationExpression invocationExpression, object data)
{
if (resolver.Language == SupportedLanguage.CSharp && resolver.CallingClass != null) {
if (invocationExpression.TargetObject is ThisReferenceExpression) {
// call to constructor
return ResolveConstructorOverload(resolver.CallingClass, invocationExpression.Arguments);
} else if (invocationExpression.TargetObject is BaseReferenceExpression) {
return ResolveConstructorOverload(resolver.CallingClass.BaseClass, invocationExpression.Arguments);
}
}
ResolveResult rr = Resolve(invocationExpression.TargetObject);
MethodGroupResolveResult mgrr = rr as MethodGroupResolveResult;
if (mgrr != null) {
if (mgrr.Methods.Count == 0 && resolver.Language == SupportedLanguage.VBNet && mgrr.PossibleExtensionMethods.Count == 0)
return CreateMemberResolveResult(GetVisualBasicIndexer(invocationExpression));
IReturnType[] argumentTypes = invocationExpression.Arguments.Select<Expression, IReturnType>(ResolveType).ToArray();
bool resultIsAcceptable;
IMethod result = MemberLookupHelper.FindOverload(mgrr.Methods, argumentTypes, out resultIsAcceptable);
if (resultIsAcceptable)
return CreateMemberResolveResult(result);
if (mgrr.PossibleExtensionMethods.Count > 0) {
IReturnType[] extendedTypes = new IReturnType[argumentTypes.Length + 1];
extendedTypes[0] = mgrr.ContainingType;
argumentTypes.CopyTo(extendedTypes, 1);
IMethod extensionResult = MemberLookupHelper.FindOverload(mgrr.PossibleExtensionMethods, extendedTypes, out resultIsAcceptable);
if (resultIsAcceptable)
return CreateMemberResolveResult(extensionResult);
else
return CreateMemberResolveResult(result ?? extensionResult);
} else {
return CreateMemberResolveResult(result);
}
} else if (rr != null && rr.ResolvedType != null) {
IClass c = rr.ResolvedType.GetUnderlyingClass();
if (c != null && c.ClassType == ClassType.Delegate) {
// We don't want to show "System.EventHandler.Invoke" in the tooltip
// of "EventCall(this, EventArgs.Empty)", we just show the event/delegate for now
// but for DelegateCall(params).* completion, we use the delegate's
// return type instead of the delegate type itself
IMethod method = c.Methods.Find(innerMethod => innerMethod.Name == "Invoke");
if (method != null) {
rr = rr.Clone();
rr.ResolvedType = method.ReturnType;
return rr;
}
}
}
if (resolver.Language == SupportedLanguage.VBNet) {
return CreateMemberResolveResult(GetVisualBasicIndexer(invocationExpression));
}
return null;
}
public override object VisitLambdaExpression(LambdaExpression lambdaExpression, object data)
{
return null;
}
public override object VisitMemberReferenceExpression(MemberReferenceExpression memberReferenceExpression, object data)
{
IReturnType type;
if (string.IsNullOrEmpty(memberReferenceExpression.MemberName)) {
// NRefactory creates this "dummy" fieldReferenceExpression when it should
// parse a primitive type name (int, short; Integer, Decimal)
if (memberReferenceExpression.TargetObject is TypeReferenceExpression) {
type = TypeVisitor.CreateReturnType(((TypeReferenceExpression)memberReferenceExpression.TargetObject).TypeReference, resolver);
return CreateTypeResolveResult(type);
}
}
ResolveResult targetRR = Resolve(memberReferenceExpression.TargetObject);
if (targetRR == null)
return null;
type = targetRR.ResolvedType;
if (targetRR is NamespaceResolveResult) {
return ResolveMemberInNamespace(((NamespaceResolveResult)targetRR).Name, memberReferenceExpression);
} else if (type != null) {
TypeResolveResult typeRR = targetRR as TypeResolveResult;
if (typeRR != null && typeRR.ResolvedClass != null) {
foreach (IClass c1 in typeRR.ResolvedClass.ClassInheritanceTree) {
foreach (IClass c in c1.InnerClasses) {
if (resolver.IsSameName(memberReferenceExpression.MemberName, c.Name)
&& c.TypeParameters.Count == memberReferenceExpression.TypeArguments.Count)
{
return CreateTypeResolveResult(resolver.ConstructType(c.DefaultReturnType, memberReferenceExpression.TypeArguments));
}
}
}
}
return resolver.ResolveMember(type, memberReferenceExpression.MemberName,
memberReferenceExpression.TypeArguments,
memberReferenceExpression.Parent is InvocationExpression,
typeRR == null /* allow extension methods only for non-static method calls */);
}
return null;
}
ResolveResult ResolveMemberInNamespace(string namespaceName, MemberReferenceExpression mre)
{
string combinedName;
if (string.IsNullOrEmpty(namespaceName))
combinedName = mre.MemberName;
else
combinedName = namespaceName + "." + mre.MemberName;
if (resolver.ProjectContent.NamespaceExists(combinedName)) {
return new NamespaceResolveResult(resolver.CallingClass, resolver.CallingMember, combinedName);
}
IClass c = resolver.GetClass(combinedName, mre.TypeArguments.Count);
if (c != null) {
return CreateTypeResolveResult(resolver.ConstructType(c.DefaultReturnType, mre.TypeArguments));
}
if (resolver.LanguageProperties.ImportModules) {
// go through the members of the modules
List<IMember> possibleMembers = new List<IMember>();
foreach (object o in resolver.ProjectContent.GetNamespaceContents(namespaceName)) {
IMember member = o as IMember;
if (member != null && resolver.IsSameName(member.Name, mre.MemberName)) {
possibleMembers.Add(member);
}
}
return resolver.CreateMemberOrMethodGroupResolveResult(null, mre.MemberName, possibleMembers, false);
}
return null;
}
public override object VisitObjectCreateExpression(ObjectCreateExpression objectCreateExpression, object data)
{
if (objectCreateExpression.IsAnonymousType) {
return CreateResolveResult(CreateAnonymousTypeClass(objectCreateExpression.ObjectInitializer).DefaultReturnType);
} else {
IReturnType rt = TypeVisitor.CreateReturnType(objectCreateExpression.CreateType, resolver);
if (rt == null)
return null;
return ResolveConstructorOverload(rt.GetUnderlyingClass(), objectCreateExpression.Parameters)
?? CreateResolveResult(rt);
}
}
ResolveResult ResolveConstructorOverload(IClass c, List<Expression> arguments)
{
if (c == null)
return null;
List<IMethod> methods = c.Methods.Where(m => m.IsConstructor && !m.IsStatic).ToList();
IReturnType[] argumentTypes = arguments.Select<Expression, IReturnType>(ResolveType).ToArray();
bool resultIsAcceptable;
IMethod result = MemberLookupHelper.FindOverload(methods, argumentTypes, out resultIsAcceptable);
return CreateMemberResolveResult(result ?? Constructor.CreateDefault(c));
}
DefaultClass CreateAnonymousTypeClass(CollectionInitializerExpression initializer)
{
List<IReturnType> fieldTypes = new List<IReturnType>();
List<string> fieldNames = new List<string>();
foreach (Expression expr in initializer.CreateExpressions) {
if (expr is AssignmentExpression) {
// use right part only
fieldTypes.Add( ResolveType(((AssignmentExpression)expr).Right) );
} else {
fieldTypes.Add( ResolveType(expr) );
}
fieldNames.Add(GetAnonymousTypeFieldName(expr));
}
StringBuilder nameBuilder = new StringBuilder();
nameBuilder.Append('{');
for (int i = 0; i < fieldTypes.Count; i++) {
if (i > 0) nameBuilder.Append(", ");
nameBuilder.Append(fieldNames[i]);
nameBuilder.Append(" : ");
if (fieldTypes[i] != null) {
nameBuilder.Append(fieldTypes[i].DotNetName);
}
}
nameBuilder.Append('}');
DefaultClass c = new DefaultClass(new DefaultCompilationUnit(resolver.ProjectContent), nameBuilder.ToString());
c.Modifiers = ModifierEnum.Internal | ModifierEnum.Synthetic | ModifierEnum.Sealed;
for (int i = 0; i < fieldTypes.Count; i++) {
DefaultProperty p = new DefaultProperty(fieldNames[i], fieldTypes[i], ModifierEnum.Public | ModifierEnum.Synthetic, DomRegion.Empty, DomRegion.Empty, c);
p.CanGet = true;
p.CanSet = false;
c.Properties.Add(p);
}
return c;
}
static string GetAnonymousTypeFieldName(Expression expr)
{
if (expr is MemberReferenceExpression) {
return ((MemberReferenceExpression)expr).MemberName;
}
if (expr is AssignmentExpression) {
expr = ((AssignmentExpression)expr).Left; // use left side if it is an IdentifierExpression
}
if (expr is IdentifierExpression) {
return ((IdentifierExpression)expr).Identifier;
} else {
return "?";
}
}
public override object VisitParenthesizedExpression(ParenthesizedExpression parenthesizedExpression, object data)
{
return CreateResolveResult(parenthesizedExpression.Expression);
}
public override object VisitPointerReferenceExpression(PointerReferenceExpression pointerReferenceExpression, object data)
{
return null;
}
public override object VisitPrimitiveExpression(PrimitiveExpression primitiveExpression, object data)
{
if (primitiveExpression.Value == null) {
return CreateResolveResult(NullReturnType.Instance);
} else if (primitiveExpression.Value is int) {
return new IntegerLiteralResolveResult(resolver.CallingClass, resolver.CallingMember, resolver.ProjectContent.SystemTypes.Int32);
} else {
return CreateResolveResult(resolver.ProjectContent.SystemTypes.CreatePrimitive(primitiveExpression.Value.GetType()));
}
}
public override object VisitQueryExpression(QueryExpression queryExpression, object data)
{
IReturnType type = null;
QueryExpressionSelectClause selectClause = queryExpression.SelectOrGroupClause as QueryExpressionSelectClause;
QueryExpressionGroupClause groupClause = queryExpression.SelectOrGroupClause as QueryExpressionGroupClause;
if (selectClause != null) {
type = ResolveType(selectClause.Projection);
} else if (groupClause != null) {
type = new ConstructedReturnType(
new GetClassReturnType(resolver.ProjectContent, "System.Linq.IGrouping", 2),
new IReturnType[] { ResolveType(groupClause.GroupBy), ResolveType(groupClause.Projection) }
);
}
if (type != null) {
return CreateResolveResult(new ConstructedReturnType(
new GetClassReturnType(resolver.ProjectContent, "System.Collections.Generic.IEnumerable", 1),
new IReturnType[] { type }
));
} else {
return null;
}
}
public override object VisitSizeOfExpression(SizeOfExpression sizeOfExpression, object data)
{
return CreateResolveResult(resolver.ProjectContent.SystemTypes.Int32);
}
public override object VisitStackAllocExpression(StackAllocExpression stackAllocExpression, object data)
{
return null;
}
public override object VisitThisReferenceExpression(ThisReferenceExpression thisReferenceExpression, object data)
{
if (resolver.CallingClass == null)
return null;
if (resolver.Language == SupportedLanguage.VBNet && IsInstanceConstructor(resolver.CallingMember)) {
return new VBBaseOrThisReferenceInConstructorResolveResult(
resolver.CallingClass, resolver.CallingMember, resolver.CallingClass.DefaultReturnType);
} else {
return CreateResolveResult(resolver.CallingClass.DefaultReturnType);
}
}
static bool IsInstanceConstructor(IMember member)
{
IMethod m = member as IMethod;
return m != null && m.IsConstructor && !m.IsStatic;
}
public override object VisitTypeOfExpression(TypeOfExpression typeOfExpression, object data)
{
return CreateResolveResult(resolver.ProjectContent.SystemTypes.Type);
}
public override object VisitTypeOfIsExpression(TypeOfIsExpression typeOfIsExpression, object data)
{
return CreateResolveResult(resolver.ProjectContent.SystemTypes.Boolean);
}
public override object VisitTypeReferenceExpression(TypeReferenceExpression typeReferenceExpression, object data)
{
return CreateResolveResult(typeReferenceExpression.TypeReference);
}
public override object VisitUnaryOperatorExpression(UnaryOperatorExpression unaryOperatorExpression, object data)
{
return CreateResolveResult(unaryOperatorExpression.Expression);
}
public override object VisitUncheckedExpression(UncheckedExpression uncheckedExpression, object data)
{
return CreateResolveResult(uncheckedExpression.Expression);
}
}
}

602
src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/NRefactoryResolver/TypeVisitor.cs

@ -17,571 +17,9 @@ using ICSharpCode.NRefactory.Visitors; @@ -17,571 +17,9 @@ using ICSharpCode.NRefactory.Visitors;
namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
{
public class TypeVisitor : AbstractAstVisitor
// TODO: Rename this class, the visitor functionality was moved to ResolveVisitor
public static class TypeVisitor
{
NRefactoryResolver resolver;
public TypeVisitor(NRefactoryResolver resolver)
{
this.resolver = resolver;
}
public override object VisitPrimitiveExpression(PrimitiveExpression primitiveExpression, object data)
{
if (primitiveExpression.Value == null) {
return NullReturnType.Instance;
} else {
return resolver.ProjectContent.SystemTypes.CreatePrimitive(primitiveExpression.Value.GetType());
}
}
public override object VisitQueryExpression(QueryExpression queryExpression, object data)
{
IReturnType type = queryExpression.SelectOrGroupClause.AcceptVisitor(this, data) as IReturnType;
if (type != null) {
return new ConstructedReturnType(
new GetClassReturnType(resolver.ProjectContent, "System.Collections.Generic.IEnumerable", 1),
new IReturnType[] { type }
);
} else {
return null;
}
}
public override object VisitBinaryOperatorExpression(BinaryOperatorExpression binaryOperatorExpression, object data)
{
switch (binaryOperatorExpression.Op) {
case BinaryOperatorType.NullCoalescing:
return binaryOperatorExpression.Right.AcceptVisitor(this, data);
case BinaryOperatorType.DivideInteger:
return resolver.ProjectContent.SystemTypes.Int32;
case BinaryOperatorType.Concat:
return resolver.ProjectContent.SystemTypes.String;
case BinaryOperatorType.Equality:
case BinaryOperatorType.InEquality:
case BinaryOperatorType.ReferenceEquality:
case BinaryOperatorType.ReferenceInequality:
case BinaryOperatorType.LogicalAnd:
case BinaryOperatorType.LogicalOr:
case BinaryOperatorType.LessThan:
case BinaryOperatorType.LessThanOrEqual:
case BinaryOperatorType.GreaterThan:
case BinaryOperatorType.GreaterThanOrEqual:
return resolver.ProjectContent.SystemTypes.Boolean;
default:
return MemberLookupHelper.GetCommonType(resolver.ProjectContent,
binaryOperatorExpression.Left.AcceptVisitor(this, data) as IReturnType,
binaryOperatorExpression.Right.AcceptVisitor(this, data) as IReturnType);
}
}
public override object VisitParenthesizedExpression(ParenthesizedExpression parenthesizedExpression, object data)
{
return parenthesizedExpression.Expression.AcceptVisitor(this, data);
}
public override object VisitInvocationExpression(InvocationExpression invocationExpression, object data)
{
IMethodOrProperty m = GetMethod(invocationExpression);
if (m == null) {
// This might also be a delegate invocation:
// get the delegate's Invoke method
IReturnType targetType = invocationExpression.TargetObject.AcceptVisitor(this, data) as IReturnType;
if (targetType != null) {
IClass c = targetType.GetUnderlyingClass();
if (c != null && c.ClassType == ClassType.Delegate) {
// find the delegate's return type
m = c.Methods.Find(delegate(IMethod innerMethod) { return innerMethod.Name == "Invoke"; });
}
}
}
if (m != null)
return m.ReturnType;
else
return null;
}
public override object VisitIndexerExpression(IndexerExpression indexerExpression, object data)
{
IProperty i = GetIndexer(indexerExpression);
if (i != null)
return i.ReturnType;
else
return null;
}
static readonly IMethod[] emptyMethodsArray = new IMethod[0];
/// <summary>
/// Find the correct overload from a list of overloads.
/// </summary>
/// <param name="methods">The list of available methods to call.</param>
/// <param name="typeParameters">The type parameters used for the method call.</param>
/// <param name="arguments">The arguments passed to the method.</param>
/// <returns>The chosen overload.</returns>
public IMethod FindOverload(IList<IMethod> methods, IReturnType[] typeParameters, IList<Expression> arguments)
{
return FindOverload(methods, null, null, typeParameters, arguments);
}
/// <summary>
/// Find the correct overload from a list of overloads.
/// </summary>
/// <param name="methods">The list of available methods to call.</param>
/// <param name="extensionMethods">The list of available extension methods to call.</param>
/// <param name="targetType">The type of the expression on which the method is called. Used as first argument to the extension methods.</param>
/// <param name="typeParameters">The type parameters used for the method call.</param>
/// <param name="arguments">The arguments passed to the method.</param>
/// <returns>The chosen overload.</returns>
public IMethod FindOverload(IList<IMethod> methods, IList<IMethod> extensionMethods, IReturnType targetType, IReturnType[] typeParameters, IList<Expression> arguments)
{
if (extensionMethods == null) extensionMethods = emptyMethodsArray;
if (methods.Count == 0 && extensionMethods.Count == 0) {
return null;
}
// We must call FindOverload even if there is only one possible match
// because MemberLookupHelper does type inference and type substitution for us
IReturnType[] types = new IReturnType[arguments.Count];
for (int i = 0; i < types.Length; ++i) {
types[i] = arguments[i].AcceptVisitor(this, null) as IReturnType;
}
bool matchIsAcceptable;
IMethod result = MemberLookupHelper.FindOverload(methods, typeParameters, types, out matchIsAcceptable);
if (matchIsAcceptable) return result;
if (extensionMethods.Count > 0) {
IReturnType[] extendedTypes = new IReturnType[types.Length + 1];
extendedTypes[0] = targetType;
types.CopyTo(extendedTypes, 1);
IMethod extensionResult = MemberLookupHelper.FindOverload(extensionMethods, typeParameters, extendedTypes, out matchIsAcceptable);
if (matchIsAcceptable)
return extensionResult;
else
return result ?? extensionResult;
} else {
return result;
}
}
List<TypeReference> GetTypeArguments(Expression expr)
{
if (expr is IdentifierExpression)
return ((IdentifierExpression)expr).TypeArguments;
else if (expr is MemberReferenceExpression)
return ((MemberReferenceExpression)expr).TypeArguments;
else
return null;
}
/// <summary>
/// Gets the method called by the InvocationExpression. In Visual Basic, the result
/// can also be an Indexer.
/// </summary>
public IMethodOrProperty GetMethod(InvocationExpression invocationExpression)
{
IReturnType[] typeParameters = CreateReturnTypes(GetTypeArguments(invocationExpression.TargetObject));
if (invocationExpression.TargetObject is MemberReferenceExpression) {
MemberReferenceExpression field = (MemberReferenceExpression)invocationExpression.TargetObject;
IReturnType targetType = field.TargetObject.AcceptVisitor(this, null) as IReturnType;
List<IMethod> methods = resolver.SearchMethod(targetType, field.FieldName);
// FindOverload does not need the extensionMethods if a normal method is applicable,
// so we use a LazyList because SearchExtensionMethods is expensive and we don't want to call it
// if it is not required.
IList<IMethod> extensionMethods = new LazyList<IMethod>(
delegate { return resolver.SearchExtensionMethods(field.FieldName); });
if (methods.Count == 0 && extensionMethods.Count == 0 && resolver.Language == SupportedLanguage.VBNet)
return GetVisualBasicIndexer(invocationExpression);
return FindOverload(methods, extensionMethods, targetType, typeParameters, invocationExpression.Arguments);
} else if (invocationExpression.TargetObject is IdentifierExpression) {
string id = ((IdentifierExpression)invocationExpression.TargetObject).Identifier;
if (resolver.CallingClass == null) {
return null;
}
List<IMethod> methods = resolver.SearchMethod(id);
if (methods.Count == 0 && resolver.Language == SupportedLanguage.VBNet)
return GetVisualBasicIndexer(invocationExpression);
return FindOverload(methods, typeParameters, invocationExpression.Arguments);
} else {
if (resolver.Language == SupportedLanguage.CSharp && resolver.CallingClass != null) {
if (invocationExpression.TargetObject is ThisReferenceExpression) {
// call to constructor
return FindOverload(GetConstructors(resolver.CallingClass), typeParameters, invocationExpression.Arguments);
} else if (invocationExpression.TargetObject is BaseReferenceExpression) {
return FindOverload(GetConstructors(resolver.CallingClass.BaseClass), typeParameters, invocationExpression.Arguments);
}
}
// this could be a nested indexer access
if (resolver.Language == SupportedLanguage.VBNet)
return GetVisualBasicIndexer(invocationExpression);
}
return null;
}
IList<IMethod> GetConstructors(IClass c)
{
if (c == null)
return emptyMethodsArray;
return c.Methods.FindAll(delegate(IMethod m) { return m.IsConstructor; });
}
public IProperty GetIndexer(IndexerExpression indexerExpression)
{
IReturnType targetObjectType = (IReturnType)indexerExpression.TargetObject.AcceptVisitor(this, null);
return GetIndexer(indexerExpression, targetObjectType);
}
IProperty GetVisualBasicIndexer(InvocationExpression invocationExpression)
{
ResolveResult targetRR = resolver.ResolveInternal(invocationExpression.TargetObject, ExpressionContext.Default);
if (targetRR != null) {
// Visual Basic can call indexers in two ways:
// collection(index) - use indexer
// collection.Item(index) - use parametrized property
if (invocationExpression.TargetObject is IdentifierExpression || invocationExpression.TargetObject is MemberReferenceExpression) {
// only IdentifierExpression/MemberReferenceExpression can represent a parametrized property
// - the check is necessary because collection.Items and collection.Item(index) both
// resolve to the same property, but we want to use the default indexer for the second call in
// collection.Item(index1)(index2)
MemberResolveResult memberRR = targetRR as MemberResolveResult;
if (memberRR != null) {
IProperty p = memberRR.ResolvedMember as IProperty;
if (p != null && p.Parameters.Count > 0) {
// this is a parametrized property
return p;
}
}
}
// not a parametrized property - try normal indexer
return GetIndexer(new IndexerExpression(invocationExpression.TargetObject, invocationExpression.Arguments),
targetRR.ResolvedType);
} else {
return null;
}
}
IProperty GetIndexer(IndexerExpression indexerExpression, IReturnType targetObjectType)
{
if (targetObjectType == null) {
return null;
}
List<IProperty> indexers = targetObjectType.GetProperties();
// remove non-indexers:
for (int i = 0; i < indexers.Count; i++) {
if (!indexers[i].IsIndexer)
indexers.RemoveAt(i--);
}
IReturnType[] parameters = new IReturnType[indexerExpression.Indexes.Count];
for (int i = 0; i < parameters.Length; i++) {
Expression expr = indexerExpression.Indexes[i] as Expression;
if (expr != null)
parameters[i] = (IReturnType)expr.AcceptVisitor(this, null);
}
return MemberLookupHelper.FindOverload(indexers.ToArray(), parameters);
}
public override object VisitMemberReferenceExpression(MemberReferenceExpression memberReferenceExpression, object data)
{
if (memberReferenceExpression == null) {
return null;
}
// int. generates a FieldreferenceExpression with TargetObject TypeReferenceExpression and no FieldName
if (memberReferenceExpression.FieldName == null || memberReferenceExpression.FieldName == "") {
if (memberReferenceExpression.TargetObject is TypeReferenceExpression) {
return CreateReturnType(((TypeReferenceExpression)memberReferenceExpression.TargetObject).TypeReference);
}
}
IReturnType returnType = memberReferenceExpression.TargetObject.AcceptVisitor(this, data) as IReturnType;
if (returnType != null) {
if (returnType is NamespaceReturnType) {
string name = returnType.FullyQualifiedName;
string combinedName;
if (name.Length == 0)
combinedName = memberReferenceExpression.FieldName;
else
combinedName = name + "." + memberReferenceExpression.FieldName;
if (resolver.ProjectContent.NamespaceExists(combinedName)) {
return new NamespaceReturnType(combinedName);
}
IClass c = resolver.GetClass(combinedName);
if (c != null) {
return c.DefaultReturnType;
}
if (resolver.LanguageProperties.ImportModules) {
// go through the members of the modules
foreach (object o in resolver.ProjectContent.GetNamespaceContents(name)) {
IMember member = o as IMember;
if (member != null && resolver.IsSameName(member.Name, memberReferenceExpression.FieldName))
return member.ReturnType;
}
}
} else {
IMember member = resolver.GetMember(returnType, memberReferenceExpression.FieldName);
if (member != null) {
return member.ReturnType;
} else {
IClass c = returnType.GetUnderlyingClass();
if (c != null) {
foreach (IClass innerClass in c.InnerClasses) {
if (resolver.IsSameName(innerClass.Name, memberReferenceExpression.FieldName)) {
return innerClass.DefaultReturnType;
}
}
}
}
}
}
return null;
}
public override object VisitPointerReferenceExpression(PointerReferenceExpression pointerReferenceExpression, object data)
{
return null;
/*
ReturnType type = pointerReferenceExpression.TargetObject.AcceptVisitor(this, data) as ReturnType;
if (type == null) {
return null;
}
type = type.Clone();
--type.PointerNestingLevel;
if (type.PointerNestingLevel != 0) {
return null;
}
return resolver.SearchMember(type, pointerReferenceExpression.Identifier);
*/
}
public override object VisitIdentifierExpression(IdentifierExpression identifierExpression, object data)
{
if (identifierExpression == null) {
return null;
}
IClass c = resolver.SearchClass(identifierExpression.Identifier, identifierExpression.StartLocation);
if (c != null) {
return c.DefaultReturnType;
}
return resolver.DynamicLookup(identifierExpression.Identifier, identifierExpression.StartLocation);
}
public override object VisitTypeReferenceExpression(TypeReferenceExpression typeReferenceExpression, object data)
{
return CreateReturnType(typeReferenceExpression.TypeReference);
}
public override object VisitUnaryOperatorExpression(UnaryOperatorExpression unaryOperatorExpression, object data)
{
if (unaryOperatorExpression == null) {
return null;
}
IReturnType expressionType = unaryOperatorExpression.Expression.AcceptVisitor(this, data) as IReturnType;
// TODO: Little bug: unary operator MAY change the return type,
// but that is only a minor issue
switch (unaryOperatorExpression.Op) {
case UnaryOperatorType.Star: // dereference
//--expressionType.PointerNestingLevel;
break;
case UnaryOperatorType.BitWiseAnd: // get reference
//++expressionType.PointerNestingLevel;
break;
}
return expressionType;
}
public override object VisitAssignmentExpression(AssignmentExpression assignmentExpression, object data)
{
return assignmentExpression.Left.AcceptVisitor(this, data);
}
public override object VisitSizeOfExpression(SizeOfExpression sizeOfExpression, object data)
{
return resolver.ProjectContent.SystemTypes.Int32;
}
public override object VisitTypeOfExpression(TypeOfExpression typeOfExpression, object data)
{
return resolver.ProjectContent.SystemTypes.Type;
}
public override object VisitCheckedExpression(CheckedExpression checkedExpression, object data)
{
return checkedExpression.Expression.AcceptVisitor(this, data);
}
public override object VisitUncheckedExpression(UncheckedExpression uncheckedExpression, object data)
{
return uncheckedExpression.Expression.AcceptVisitor(this, data);
}
public override object VisitCastExpression(CastExpression castExpression, object data)
{
return CreateReturnType(castExpression.CastTo);
}
public override object VisitStackAllocExpression(StackAllocExpression stackAllocExpression, object data)
{
/*ReturnType returnType = new ReturnType(stackAllocExpression.TypeReference);
++returnType.PointerNestingLevel;
return returnType;*/
return null;
}
public override object VisitClassReferenceExpression(ClassReferenceExpression classReferenceExpression, object data)
{
if (resolver.CallingClass == null) {
return null;
}
return resolver.CallingClass.DefaultReturnType;
}
public override object VisitThisReferenceExpression(ThisReferenceExpression thisReferenceExpression, object data)
{
if (resolver.CallingClass == null) {
return null;
}
return resolver.CallingClass.DefaultReturnType;
}
public override object VisitBaseReferenceExpression(BaseReferenceExpression baseReferenceExpression, object data)
{
if (resolver.CallingClass == null) {
return null;
}
return resolver.CallingClass.BaseType;
}
public override object VisitObjectCreateExpression(ObjectCreateExpression objectCreateExpression, object data)
{
if (objectCreateExpression.IsAnonymousType) {
return CreateAnonymousTypeClass(objectCreateExpression.ObjectInitializer).DefaultReturnType;
} else {
return CreateReturnType(objectCreateExpression.CreateType);
}
}
DefaultClass CreateAnonymousTypeClass(CollectionInitializerExpression initializer)
{
List<IReturnType> fieldTypes = new List<IReturnType>();
List<string> fieldNames = new List<string>();
foreach (Expression expr in initializer.CreateExpressions) {
if (expr is AssignmentExpression) {
// use right part only
fieldTypes.Add( ((AssignmentExpression)expr).Right.AcceptVisitor(this, null) as IReturnType );
} else {
fieldTypes.Add( expr.AcceptVisitor(this, null) as IReturnType );
}
fieldNames.Add(GetAnonymousTypeFieldName(expr));
}
StringBuilder nameBuilder = new StringBuilder();
nameBuilder.Append('{');
for (int i = 0; i < fieldTypes.Count; i++) {
if (i > 0) nameBuilder.Append(", ");
nameBuilder.Append(fieldNames[i]);
nameBuilder.Append(" : ");
if (fieldTypes[i] != null) {
nameBuilder.Append(fieldTypes[i].DotNetName);
}
}
nameBuilder.Append('}');
DefaultClass c = new DefaultClass(new DefaultCompilationUnit(resolver.ProjectContent), nameBuilder.ToString());
c.Modifiers = ModifierEnum.Internal | ModifierEnum.Synthetic | ModifierEnum.Sealed;
for (int i = 0; i < fieldTypes.Count; i++) {
DefaultProperty p = new DefaultProperty(fieldNames[i], fieldTypes[i], ModifierEnum.Public | ModifierEnum.Synthetic, DomRegion.Empty, DomRegion.Empty, c);
p.CanGet = true;
p.CanSet = false;
c.Properties.Add(p);
}
return c;
}
static string GetAnonymousTypeFieldName(Expression expr)
{
if (expr is MemberReferenceExpression) {
return ((MemberReferenceExpression)expr).FieldName;
}
if (expr is AssignmentExpression) {
expr = ((AssignmentExpression)expr).Left; // use left side if it is an IdentifierExpression
}
if (expr is IdentifierExpression) {
return ((IdentifierExpression)expr).Identifier;
} else {
return "?";
}
}
public override object VisitArrayCreateExpression(ArrayCreateExpression arrayCreateExpression, object data)
{
if (arrayCreateExpression.IsImplicitlyTyped) {
return arrayCreateExpression.ArrayInitializer.AcceptVisitor(this, data);
} else {
return CreateReturnType(arrayCreateExpression.CreateType);
}
}
public override object VisitTypeOfIsExpression(TypeOfIsExpression typeOfIsExpression, object data)
{
return resolver.ProjectContent.SystemTypes.Boolean;
}
public override object VisitDefaultValueExpression(DefaultValueExpression defaultValueExpression, object data)
{
return CreateReturnType(defaultValueExpression.TypeReference);
}
public override object VisitAnonymousMethodExpression(AnonymousMethodExpression anonymousMethodExpression, object data)
{
AnonymousMethodReturnType amrt = new AnonymousMethodReturnType(resolver.CompilationUnit);
if (anonymousMethodExpression.HasParameterList) {
amrt.MethodParameters = new List<IParameter>();
foreach (ParameterDeclarationExpression param in anonymousMethodExpression.Parameters) {
amrt.MethodParameters.Add(NRefactoryASTConvertVisitor.CreateParameter(param, resolver.CallingMember as IMethod, resolver.CallingClass, resolver.CompilationUnit));
}
}
return amrt;
}
public override object VisitCollectionInitializerExpression(CollectionInitializerExpression collectionInitializerExpression, object data)
{
// used for implicitly typed arrays
if (collectionInitializerExpression.CreateExpressions.Count == 0)
return null;
IReturnType combinedRT = collectionInitializerExpression.CreateExpressions[0].AcceptVisitor(this, data) as IReturnType;
for (int i = 1; i < collectionInitializerExpression.CreateExpressions.Count; i++) {
IReturnType rt = collectionInitializerExpression.CreateExpressions[i].AcceptVisitor(this, data) as IReturnType;
combinedRT = MemberLookupHelper.GetCommonType(resolver.ProjectContent, combinedRT, rt);
}
return new ArrayReturnType(resolver.ProjectContent, combinedRT, 1);
}
IReturnType CreateReturnType(TypeReference reference)
{
return CreateReturnType(reference, resolver);
}
IReturnType[] CreateReturnTypes(List<TypeReference> references)
{
if (references == null) return new IReturnType[0];
IReturnType[] types = new IReturnType[references.Count];
for (int i = 0; i < types.Length; i++) {
types[i] = CreateReturnType(references[i]);
}
return types;
}
public static IReturnType CreateReturnType(TypeReference reference, NRefactoryResolver resolver)
{
return CreateReturnType(reference,
@ -645,12 +83,12 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver @@ -645,12 +83,12 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
if (reference.GenericTypes.Count == 0 && !reference.IsArrayType) {
// reference to namespace is possible
if (reference.IsGlobal) {
if (projectContent.NamespaceExists(reference.Type))
return new NamespaceReturnType(reference.Type);
//if (projectContent.NamespaceExists(reference.Type))
// return new NamespaceReturnType(reference.Type);
} else {
string name = projectContent.SearchNamespace(reference.Type, callingClass, (callingClass == null) ? null : callingClass.CompilationUnit, caretLine, caretColumn);
if (name != null)
return new NamespaceReturnType(name);
//if (name != null)
// return new NamespaceReturnType(name);
}
}
return null;
@ -680,33 +118,5 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver @@ -680,33 +118,5 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
}
return t;
}
public class NamespaceReturnType : AbstractReturnType
{
public NamespaceReturnType(string fullName)
{
this.FullyQualifiedName = fullName;
}
public override IClass GetUnderlyingClass() {
return null;
}
public override List<IMethod> GetMethods() {
return new List<IMethod>();
}
public override List<IProperty> GetProperties() {
return new List<IProperty>();
}
public override List<IField> GetFields() {
return new List<IField>();
}
public override List<IEvent> GetEvents() {
return new List<IEvent>();
}
}
}
}

12
src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/NRefactoryResolver/VBNetToCSharpConvertVisitor.cs

@ -357,7 +357,7 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver @@ -357,7 +357,7 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
ResolveResult rr = Resolve(memberReferenceExpression);
string ident = GetIdentifierFromResult(rr);
if (ident != null) {
memberReferenceExpression.FieldName = ident;
memberReferenceExpression.MemberName = ident;
}
if (ReplaceWithInvocation(memberReferenceExpression, rr)) {}
else if (FullyQualifyModuleMemberReference(memberReferenceExpression, rr)) {}
@ -370,7 +370,7 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver @@ -370,7 +370,7 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
MemberResolveResult memberRR = rr as MemberResolveResult;
if (memberRR != null)
return memberRR.ResolvedMember.IsStatic == false;
MethodResolveResult methodRR = rr as MethodResolveResult;
MethodGroupResolveResult methodRR = rr as MethodGroupResolveResult;
if (methodRR != null && methodRR.ContainingType != null) {
foreach (IMethod m in methodRR.ContainingType.GetMethods()) {
if (resolver.IsSameName(m.Name, methodRR.Name)) {
@ -383,7 +383,7 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver @@ -383,7 +383,7 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
bool ReplaceWithInvocation(Expression expression, ResolveResult rr)
{
if (rr is MethodResolveResult
if (rr is MethodGroupResolveResult
&& !(expression.Parent is AddressOfExpression)
&& !(expression.Parent is InvocationExpression))
{
@ -396,7 +396,7 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver @@ -396,7 +396,7 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
IReturnType GetContainingTypeOfStaticMember(ResolveResult rr)
{
MethodResolveResult methodRR = rr as MethodResolveResult;
MethodGroupResolveResult methodRR = rr as MethodGroupResolveResult;
if (methodRR != null) {
return methodRR.ContainingType;
}
@ -602,7 +602,7 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver @@ -602,7 +602,7 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
{
if (resolver.CompilationUnit == null) return null;
if (tr.IsNull) return null;
IReturnType rt = resolver.SearchType(tr.SystemType, loc);
IReturnType rt = resolver.SearchType(tr.SystemType, tr.GenericTypes.Count, loc);
if (rt != null) {
IClass c = rt.GetUnderlyingClass();
if (c != null) {
@ -622,7 +622,7 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver @@ -622,7 +622,7 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
MemberResolveResult mrr = rr as MemberResolveResult;
if (mrr != null)
return mrr.ResolvedMember.Name;
MethodResolveResult mtrr = rr as MethodResolveResult;
MethodGroupResolveResult mtrr = rr as MethodGroupResolveResult;
if (mtrr != null)
return mtrr.Name;
TypeResolveResult trr = rr as TypeResolveResult;

154
src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/ResolveResult.cs

@ -19,7 +19,7 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -19,7 +19,7 @@ namespace ICSharpCode.SharpDevelop.Dom
/// The ResolveResult specified the location where Resolve was called (Class+Member)
/// and the type of the resolved expression.
/// </summary>
public class ResolveResult
public class ResolveResult : ICloneable
{
IClass callingClass;
IMember callingMember;
@ -41,9 +41,7 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -41,9 +41,7 @@ namespace ICSharpCode.SharpDevelop.Dom
/// Can be null when the class is unknown.
/// </summary>
public IClass CallingClass {
get {
return callingClass;
}
get { return callingClass; }
}
/// <summary>
@ -52,9 +50,7 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -52,9 +50,7 @@ namespace ICSharpCode.SharpDevelop.Dom
/// Can be null when the expression was not inside a member or the member is unknown.
/// </summary>
public IMember CallingMember {
get {
return callingMember;
}
get { return callingMember; }
}
/// <summary>
@ -63,12 +59,18 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -63,12 +59,18 @@ namespace ICSharpCode.SharpDevelop.Dom
/// expression was a namespace name).
/// </summary>
public IReturnType ResolvedType {
get {
return resolvedType;
}
set {
resolvedType = value;
}
get { return resolvedType; }
set { resolvedType = value; }
}
public virtual ResolveResult Clone()
{
return new ResolveResult(callingClass, callingMember, resolvedType);
}
object ICloneable.Clone()
{
return this.Clone();
}
public virtual ArrayList GetCompletionData(IProjectContent projectContent)
@ -80,25 +82,11 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -80,25 +82,11 @@ namespace ICSharpCode.SharpDevelop.Dom
{
if (resolvedType == null) return null;
ArrayList res = new ArrayList();
bool isClassInInheritanceTree = false;
if (callingClass != null)
isClassInInheritanceTree = callingClass.IsTypeInInheritanceTree(resolvedType.GetUnderlyingClass());
foreach (IMethod m in resolvedType.GetMethods()) {
if (language.ShowMember(m, showStatic) && m.IsAccessible(callingClass, isClassInInheritanceTree) && !m.IsConstructor)
foreach (IMember m in MemberLookupHelper.GetAccessibleMembers(resolvedType, callingClass, language)) {
if (language.ShowMember(m, showStatic))
res.Add(m);
}
foreach (IEvent e in resolvedType.GetEvents()) {
if (language.ShowMember(e, showStatic) && e.IsAccessible(callingClass, isClassInInheritanceTree))
res.Add(e);
}
foreach (IField f in resolvedType.GetFields()) {
if (language.ShowMember(f, showStatic) && f.IsAccessible(callingClass, isClassInInheritanceTree))
res.Add(f);
}
foreach (IProperty p in resolvedType.GetProperties()) {
if (language.ShowMember(p, showStatic) && p.IsAccessible(callingClass, isClassInInheritanceTree))
res.Add(p);
}
if (!showStatic && callingClass != null) {
AddExtensions(language, res, callingClass, resolvedType);
@ -213,6 +201,11 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -213,6 +201,11 @@ namespace ICSharpCode.SharpDevelop.Dom
}
return result;
}
public override ResolveResult Clone()
{
return new MixedResolveResult(primaryResult.Clone(), secondaryResult.Clone());
}
}
#endregion
@ -246,7 +239,13 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -246,7 +239,13 @@ namespace ICSharpCode.SharpDevelop.Dom
public LocalResolveResult(IMember callingMember, IParameter parameter)
: this(callingMember, new DefaultField.ParameterField(parameter.ReturnType, parameter.Name, parameter.Region, callingMember.DeclaringType))
{}
{
}
public override ResolveResult Clone()
{
return new LocalResolveResult(this.CallingMember, this.Field);
}
/// <summary>
/// Gets the field representing the local variable.
@ -322,6 +321,11 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -322,6 +321,11 @@ namespace ICSharpCode.SharpDevelop.Dom
{
return projectContent.GetNamespaceContents(name);
}
public override ResolveResult Clone()
{
return new NamespaceResolveResult(this.CallingClass, this.CallingMember, this.Name);
}
}
#endregion
@ -342,6 +346,11 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -342,6 +346,11 @@ namespace ICSharpCode.SharpDevelop.Dom
{
return null;
}
public override ResolveResult Clone()
{
return new IntegerLiteralResolveResult(this.CallingClass, this.CallingMember, this.ResolvedType);
}
}
#endregion
@ -378,6 +387,11 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -378,6 +387,11 @@ namespace ICSharpCode.SharpDevelop.Dom
this.resolvedClass = resolvedType.GetUnderlyingClass();
}
public override ResolveResult Clone()
{
return new TypeResolveResult(this.CallingClass, this.CallingMember, this.ResolvedType, this.ResolvedClass);
}
/// <summary>
/// Gets the class corresponding to the resolved type.
/// This property can be null when the type has no class (for example a type parameter).
@ -446,13 +460,16 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -446,13 +460,16 @@ namespace ICSharpCode.SharpDevelop.Dom
this.resolvedMember = resolvedMember;
}
public override ResolveResult Clone()
{
return new MemberResolveResult(this.CallingClass, this.CallingMember, this.ResolvedMember);
}
/// <summary>
/// Gets the member that was resolved.
/// </summary>
public IMember ResolvedMember {
get {
return resolvedMember;
}
get { return resolvedMember; }
}
public override FilePosition GetDefinitionPosition()
@ -494,46 +511,84 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -494,46 +511,84 @@ namespace ICSharpCode.SharpDevelop.Dom
/// "a.Add" (where a is List&lt;string&gt;)
/// "SomeMethod" (when SomeMethod is a method in the current class)
/// </example>
public class MethodResolveResult : ResolveResult
public class MethodGroupResolveResult : ResolveResult
{
string name;
IReturnType containingType;
IList<IMethod> possibleMethods;
IList<IMethod> possibleExtensionMethods;
public MethodGroupResolveResult(IClass callingClass, IMember callingMember, IReturnType containingType, string name)
: base(callingClass, callingMember, null)
{
if (containingType == null)
throw new ArgumentNullException("containingType");
if (name == null)
throw new ArgumentNullException("name");
this.containingType = containingType;
this.name = name;
this.possibleExtensionMethods = new IMethod[0];
}
public MethodResolveResult(IClass callingClass, IMember callingMember, IReturnType containingType, string name)
public MethodGroupResolveResult(IClass callingClass, IMember callingMember, IReturnType containingType, string name,
IList<IMethod> possibleMethods, IList<IMethod> possibleExtensionMethods)
: base(callingClass, callingMember, null)
{
if (containingType == null)
throw new ArgumentNullException("containingType");
if (name == null)
throw new ArgumentNullException("name");
if (possibleMethods == null)
throw new ArgumentNullException("possibleMethods");
if (possibleExtensionMethods == null)
throw new ArgumentNullException("possibleExtensionMethods");
this.containingType = containingType;
this.name = name;
this.possibleMethods = possibleMethods;
this.possibleExtensionMethods = possibleExtensionMethods;
}
public override ResolveResult Clone()
{
return new MethodGroupResolveResult(this.CallingClass, this.CallingMember, this.ContainingType, this.Name, this.Methods, this.PossibleExtensionMethods);
}
/// <summary>
/// Gets the name of the method.
/// </summary>
public string Name {
get {
return name;
}
get { return name; }
}
/// <summary>
/// Gets the class that contains the method.
/// </summary>
public IReturnType ContainingType {
get { return containingType; }
}
/// <summary>
/// The list of possible methods.
/// </summary>
public IList<IMethod> Methods {
get {
return containingType;
if (possibleMethods == null)
possibleMethods = containingType.GetMethods().FindAll((IMethod m) => m.Name == this.name);
return possibleMethods;
}
}
/// <summary>
/// The list of possible extension methods.
/// </summary>
public IList<IMethod> PossibleExtensionMethods {
get { return possibleExtensionMethods; }
}
public IMethod GetMethodIfSingleOverload()
{
List<IMethod> methods = containingType.GetMethods();
methods = methods.FindAll(delegate(IMethod m) { return m.Name == this.Name; });
if (methods.Count == 1)
return methods[0];
if (this.Methods.Count == 1)
return this.Methods[0];
else
return null;
}
@ -569,6 +624,11 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -569,6 +624,11 @@ namespace ICSharpCode.SharpDevelop.Dom
}
return res;
}
public override ResolveResult Clone()
{
return new VBBaseOrThisReferenceInConstructorResolveResult(this.CallingClass, this.CallingMember, this.ResolvedType);
}
}
#endregion
@ -590,7 +650,13 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -590,7 +650,13 @@ namespace ICSharpCode.SharpDevelop.Dom
public override bool IsValid {
get { return false; }
}
public override ResolveResult Clone()
{
return new UnknownIdentifierResolveResult(this.CallingClass, this.CallingMember, this.Identifier);
}
}
#endregion
}

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

@ -406,7 +406,7 @@ namespace ICSharpCode.SharpDevelop.Dom.VBNet @@ -406,7 +406,7 @@ namespace ICSharpCode.SharpDevelop.Dom.VBNet
}
string dispName = UseFullyQualifiedMemberNames ? m.FullyQualifiedName : m.Name;
if (m.Name == "#ctor" || m.Name == "#cctor" || m.IsConstructor) {
if (m.IsConstructor) {
dispName = "New";
}

Loading…
Cancel
Save