diff --git a/doc/copyright.txt b/doc/copyright.txt index 8888547538..a37de83939 100644 --- a/doc/copyright.txt +++ b/doc/copyright.txt @@ -1,4 +1,4 @@ -Copyright 2002-2007 by +Copyright 2002-2008 by AlphaSierraPapa, Christoph Wille Vordernberger Strasse 27/8 diff --git a/samples/CSharpCodeCompletion/MainForm.cs b/samples/CSharpCodeCompletion/MainForm.cs index 22c1521f36..88aaa3abbf 100644 --- a/samples/CSharpCodeCompletion/MainForm.cs +++ b/samples/CSharpCodeCompletion/MainForm.cs @@ -64,7 +64,7 @@ namespace CSharpEditor /// 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() { diff --git a/samples/CSharpCodeCompletion/ToolTipProvider.cs b/samples/CSharpCodeCompletion/ToolTipProvider.cs index 86b88dc20e..54d94724a2 100644 --- a/samples/CSharpCodeCompletion/ToolTipProvider.cs +++ b/samples/CSharpCodeCompletion/ToolTipProvider.cs @@ -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 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 } 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 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); diff --git a/src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/CodeCompletion/ResolveVisitor.cs b/src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/CodeCompletion/ResolveVisitor.cs index 54f312d6e3..43a04467de 100644 --- a/src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/CodeCompletion/ResolveVisitor.cs +++ b/src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/CodeCompletion/ResolveVisitor.cs @@ -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 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 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 ClearResult(); } bool resultIsAcceptable; - MakeResult(MemberLookupHelper.FindOverload(methods, new IReturnType[0], types, out resultIsAcceptable)); + MakeResult(MemberLookupHelper.FindOverload(methods, types, out resultIsAcceptable)); } #endregion diff --git a/src/AddIns/BackendBindings/Boo/BooBinding/Test/ResolverTests.cs b/src/AddIns/BackendBindings/Boo/BooBinding/Test/ResolverTests.cs index dfacfdfe34..edd88f96da 100644 --- a/src/AddIns/BackendBindings/Boo/BooBinding/Test/ResolverTests.cs +++ b/src/AddIns/BackendBindings/Boo/BooBinding/Test/ResolverTests.cs @@ -226,7 +226,7 @@ namespace Grunwald.BooBinding.Tests [Test] public void MyMethodCompletion() { - MethodResolveResult rr = Resolve(regressionProg, "MyMethod", "/*1*/"); + MethodGroupResolveResult rr = Resolve(regressionProg, "MyMethod", "/*1*/"); ArrayList arr = rr.GetCompletionData(lastPC); Assert.IsNotNull(arr); bool beginInvoke = false; diff --git a/src/AddIns/BackendBindings/Boo/NRefactoryToBooConverter/Project/ConvertVisitorExpressions.cs b/src/AddIns/BackendBindings/Boo/NRefactoryToBooConverter/Project/ConvertVisitorExpressions.cs index ae73a53e0b..d18a47d675 100644 --- a/src/AddIns/BackendBindings/Boo/NRefactoryToBooConverter/Project/ConvertVisitorExpressions.cs +++ b/src/AddIns/BackendBindings/Boo/NRefactoryToBooConverter/Project/ConvertVisitorExpressions.cs @@ -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) diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/NRefactoryToPythonConverter.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/NRefactoryToPythonConverter.cs index 99c775b38a..f1419d190f 100644 --- a/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/NRefactoryToPythonConverter.cs +++ b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/NRefactoryToPythonConverter.cs @@ -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 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; } diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonResolver.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonResolver.cs index 0922fb052a..d4a042df0c 100644 --- a/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonResolver.cs +++ b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonResolver.cs @@ -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 /// /// Tries to resolve a method in the expression. /// - 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 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; diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Resolver/ResolveConsoleWriteLineTestFixture.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Resolver/ResolveConsoleWriteLineTestFixture.cs index 051dcc9e80..2f88a14cba 100644 --- a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Resolver/ResolveConsoleWriteLineTestFixture.cs +++ b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Resolver/ResolveConsoleWriteLineTestFixture.cs @@ -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 "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] diff --git a/src/AddIns/BackendBindings/XamlBinding/Project/Src/XamlResolver.cs b/src/AddIns/BackendBindings/XamlBinding/Project/Src/XamlResolver.cs index 59eea2f139..858c46c230 100644 --- a/src/AddIns/BackendBindings/XamlBinding/Project/Src/XamlResolver.cs +++ b/src/AddIns/BackendBindings/XamlBinding/Project/Src/XamlResolver.cs @@ -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") { diff --git a/src/AddIns/Misc/HtmlHelp2/Project/src/BaseControls/DynamicHelpPad.cs b/src/AddIns/Misc/HtmlHelp2/Project/src/BaseControls/DynamicHelpPad.cs index 0f0f784835..6b7be689d1 100644 --- a/src/AddIns/Misc/HtmlHelp2/Project/src/BaseControls/DynamicHelpPad.cs +++ b/src/AddIns/Misc/HtmlHelp2/Project/src/BaseControls/DynamicHelpPad.cs @@ -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) { diff --git a/src/AddIns/Misc/ResourceToolkit/Project/Src/Resolver/BclNRefactoryResourceResolver.cs b/src/AddIns/Misc/ResourceToolkit/Project/Src/Resolver/BclNRefactoryResourceResolver.cs index 3f8e8dae64..3a76dfecf2 100644 --- a/src/AddIns/Misc/ResourceToolkit/Project/Src/Resolver/BclNRefactoryResourceResolver.cs +++ b/src/AddIns/Misc/ResourceToolkit/Project/Src/Resolver/BclNRefactoryResourceResolver.cs @@ -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 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 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) { diff --git a/src/AddIns/Misc/ResourceToolkit/Project/Src/Resolver/ICSharpCodeCoreNRefactoryResourceResolver.cs b/src/AddIns/Misc/ResourceToolkit/Project/Src/Resolver/ICSharpCodeCoreNRefactoryResourceResolver.cs index ef77ee1ddc..7a553350a8 100644 --- a/src/AddIns/Misc/ResourceToolkit/Project/Src/Resolver/ICSharpCodeCoreNRefactoryResourceResolver.cs +++ b/src/AddIns/Misc/ResourceToolkit/Project/Src/Resolver/ICSharpCodeCoreNRefactoryResourceResolver.cs @@ -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 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) { diff --git a/src/AddIns/Misc/ResourceToolkit/Project/Src/Resolver/ResourceResolveResult.cs b/src/AddIns/Misc/ResourceToolkit/Project/Src/Resolver/ResourceResolveResult.cs index 2d2a309173..8317ac960e 100644 --- a/src/AddIns/Misc/ResourceToolkit/Project/Src/Resolver/ResourceResolveResult.cs +++ b/src/AddIns/Misc/ResourceToolkit/Project/Src/Resolver/ResourceResolveResult.cs @@ -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); + } } } diff --git a/src/Libraries/ICSharpCode.TextEditor/Project/Src/Gui/TextArea.cs b/src/Libraries/ICSharpCode.TextEditor/Project/Src/Gui/TextArea.cs index 1d0ffddd0e..2160d7cdd1 100644 --- a/src/Libraries/ICSharpCode.TextEditor/Project/Src/Gui/TextArea.cs +++ b/src/Libraries/ICSharpCode.TextEditor/Project/Src/Gui/TextArea.cs @@ -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) diff --git a/src/Libraries/NRefactory/NRefactoryASTGenerator/AST/Expressions.cs b/src/Libraries/NRefactory/NRefactoryASTGenerator/AST/Expressions.cs index 3167267917..e957e8e662 100644 --- a/src/Libraries/NRefactory/NRefactoryASTGenerator/AST/Expressions.cs +++ b/src/Libraries/NRefactory/NRefactoryASTGenerator/AST/Expressions.cs @@ -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 typeArguments; - public MemberReferenceExpression(Expression targetObject, string fieldName) {} + public MemberReferenceExpression(Expression targetObject, string memberName) {} } class PointerReferenceExpression : Expression { diff --git a/src/Libraries/NRefactory/Project/Src/Ast/Generated.cs b/src/Libraries/NRefactory/Project/Src/Ast/Generated.cs index 4b4b63b598..75d3d43279 100644 --- a/src/Libraries/NRefactory/Project/Src/Ast/Generated.cs +++ b/src/Libraries/NRefactory/Project/Src/Ast/Generated.cs @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // // 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 { elseIfSections = new List(); } - - 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 { Expression targetObject; - string fieldName; + string memberName; List typeArguments; @@ -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 { } } - public MemberReferenceExpression(Expression targetObject, string fieldName) { + public MemberReferenceExpression(Expression targetObject, string memberName) { TargetObject = targetObject; - FieldName = fieldName; + MemberName = memberName; typeArguments = new List(); } +[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 Usings = usings; } -public UsingDeclaration(string @namespace) : this(@namespace, null) {} - public UsingDeclaration(string @namespace, TypeReference alias) { usings = new List(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); } diff --git a/src/Libraries/NRefactory/Project/Src/IAstVisitor.cs b/src/Libraries/NRefactory/Project/Src/IAstVisitor.cs index b8a34743a4..a6b0dff461 100644 --- a/src/Libraries/NRefactory/Project/Src/IAstVisitor.cs +++ b/src/Libraries/NRefactory/Project/Src/IAstVisitor.cs @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // // 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. diff --git a/src/Libraries/NRefactory/Project/Src/Parser/CSharp/CSharpParser.cs b/src/Libraries/NRefactory/Project/Src/Parser/CSharp/CSharpParser.cs index 8f000c601e..62d4322b7c 100644 --- a/src/Libraries/NRefactory/Project/Src/Parser/CSharp/CSharpParser.cs +++ b/src/Libraries/NRefactory/Project/Src/Parser/CSharp/CSharpParser.cs @@ -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); } } } diff --git a/src/Libraries/NRefactory/Project/Src/Parser/VBNet/VBNetParser.cs b/src/Libraries/NRefactory/Project/Src/Parser/VBNet/VBNetParser.cs index 34d5fdaa60..7c08d61723 100644 --- a/src/Libraries/NRefactory/Project/Src/Parser/VBNet/VBNetParser.cs +++ b/src/Libraries/NRefactory/Project/Src/Parser/VBNet/VBNetParser.cs @@ -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); diff --git a/src/Libraries/NRefactory/Project/Src/PrettyPrinter/CSharp/CSharpOutputVisitor.cs b/src/Libraries/NRefactory/Project/Src/PrettyPrinter/CSharp/CSharpOutputVisitor.cs index 7a59bf92b3..f2175ade98 100644 --- a/src/Libraries/NRefactory/Project/Src/PrettyPrinter/CSharp/CSharpOutputVisitor.cs +++ b/src/Libraries/NRefactory/Project/Src/PrettyPrinter/CSharp/CSharpOutputVisitor.cs @@ -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 outputFormatter.PrintToken(Tokens.CloseParenthesis); } outputFormatter.PrintToken(Tokens.Dot); - outputFormatter.PrintIdentifier(memberReferenceExpression.FieldName); + outputFormatter.PrintIdentifier(memberReferenceExpression.MemberName); PrintTypeArgumentList(memberReferenceExpression.TypeArguments); return null; } diff --git a/src/Libraries/NRefactory/Project/Src/PrettyPrinter/VBNet/VBNetOutputVisitor.cs b/src/Libraries/NRefactory/Project/Src/PrettyPrinter/VBNet/VBNetOutputVisitor.cs index 08274ca08c..eeeebe9fc2 100644 --- a/src/Libraries/NRefactory/Project/Src/PrettyPrinter/VBNet/VBNetOutputVisitor.cs +++ b/src/Libraries/NRefactory/Project/Src/PrettyPrinter/VBNet/VBNetOutputVisitor.cs @@ -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; } diff --git a/src/Libraries/NRefactory/Project/Src/Visitors/AbstractASTVisitor.cs b/src/Libraries/NRefactory/Project/Src/Visitors/AbstractASTVisitor.cs index 20de547d66..fbbce97492 100644 --- a/src/Libraries/NRefactory/Project/Src/Visitors/AbstractASTVisitor.cs +++ b/src/Libraries/NRefactory/Project/Src/Visitors/AbstractASTVisitor.cs @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // // 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. diff --git a/src/Libraries/NRefactory/Project/Src/Visitors/AbstractAstTransformer.cs b/src/Libraries/NRefactory/Project/Src/Visitors/AbstractAstTransformer.cs index 62ad2f6285..ac9d80d410 100644 --- a/src/Libraries/NRefactory/Project/Src/Visitors/AbstractAstTransformer.cs +++ b/src/Libraries/NRefactory/Project/Src/Visitors/AbstractAstTransformer.cs @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // // 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. diff --git a/src/Libraries/NRefactory/Project/Src/Visitors/CSharpConstructsConvertVisitor.cs b/src/Libraries/NRefactory/Project/Src/Visitors/CSharpConstructsConvertVisitor.cs index 1063642912..184ec09ba3 100644 --- a/src/Libraries/NRefactory/Project/Src/Visitors/CSharpConstructsConvertVisitor.cs +++ b/src/Libraries/NRefactory/Project/Src/Visitors/CSharpConstructsConvertVisitor.cs @@ -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; } diff --git a/src/Libraries/NRefactory/Project/Src/Visitors/CodeDOMOutputVisitor.cs b/src/Libraries/NRefactory/Project/Src/Visitors/CodeDOMOutputVisitor.cs index 3f5511446d..452fdef366 100644 --- a/src/Libraries/NRefactory/Project/Src/Visitors/CodeDOMOutputVisitor.cs +++ b/src/Libraries/NRefactory/Project/Src/Visitors/CodeDOMOutputVisitor.cs @@ -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 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 || 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 { 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 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()); diff --git a/src/Libraries/NRefactory/Project/Src/Visitors/NodeTrackingAstVisitor.cs b/src/Libraries/NRefactory/Project/Src/Visitors/NodeTrackingAstVisitor.cs index ddaf2ca7d4..782921ccf5 100644 --- a/src/Libraries/NRefactory/Project/Src/Visitors/NodeTrackingAstVisitor.cs +++ b/src/Libraries/NRefactory/Project/Src/Visitors/NodeTrackingAstVisitor.cs @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // // 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. diff --git a/src/Libraries/NRefactory/Project/Src/Visitors/PrefixFieldsVisitor.cs b/src/Libraries/NRefactory/Project/Src/Visitors/PrefixFieldsVisitor.cs index 55f6ae379c..a3008fefdd 100644 --- a/src/Libraries/NRefactory/Project/Src/Visitors/PrefixFieldsVisitor.cs +++ b/src/Libraries/NRefactory/Project/Src/Visitors/PrefixFieldsVisitor.cs @@ -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; } } diff --git a/src/Libraries/NRefactory/Project/Src/Visitors/ToVBNetConvertVisitor.cs b/src/Libraries/NRefactory/Project/Src/Visitors/ToVBNetConvertVisitor.cs index 0ad741cf5a..cfaf973d47 100644 --- a/src/Libraries/NRefactory/Project/Src/Visitors/ToVBNetConvertVisitor.cs +++ b/src/Libraries/NRefactory/Project/Src/Visitors/ToVBNetConvertVisitor.cs @@ -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 return false; if ((fre.TargetObject as IdentifierExpression).Identifier != "CharSet") return false; - switch (fre.FieldName) { + switch (fre.MemberName) { case "Unicode": charSet = CharsetModifier.Unicode; break; diff --git a/src/Libraries/NRefactory/Project/Src/Visitors/VBNetConstructsConvertVisitor.cs b/src/Libraries/NRefactory/Project/Src/Visitors/VBNetConstructsConvertVisitor.cs index 160f60cfcb..505b8b9ed1 100644 --- a/src/Libraries/NRefactory/Project/Src/Visitors/VBNetConstructsConvertVisitor.cs +++ b/src/Libraries/NRefactory/Project/Src/Visitors/VBNetConstructsConvertVisitor.cs @@ -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 && 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); diff --git a/src/Libraries/NRefactory/Test/Output/CSharp/CSharpOutputTest.cs b/src/Libraries/NRefactory/Test/Output/CSharp/CSharpOutputTest.cs index 8a0441f35b..d0c279cc50 100644 --- a/src/Libraries/NRefactory/Test/Output/CSharp/CSharpOutputTest.cs +++ b/src/Libraries/NRefactory/Test/Output/CSharp/CSharpOutputTest.cs @@ -267,6 +267,12 @@ namespace ICSharpCode.NRefactory.Tests.PrettyPrinter TestExpression("12.0"); } + [Test] + public void StringWithUnicodeLiteral() + { + TestExpression(@"""\u0001"""); + } + [Test] public void GenericMethodInvocation() { diff --git a/src/Libraries/NRefactory/Test/Parser/Expressions/IdentifierExpressionTests.cs b/src/Libraries/NRefactory/Test/Parser/Expressions/IdentifierExpressionTests.cs index a3224186f5..311808d6b9 100644 --- a/src/Libraries/NRefactory/Test/Parser/Expressions/IdentifierExpressionTests.cs +++ b/src/Libraries/NRefactory/Test/Parser/Expressions/IdentifierExpressionTests.cs @@ -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("TargetMethod"); + Assert.AreEqual("TargetMethod", ident.Identifier); + Assert.AreEqual(1, ident.TypeArguments.Count); + } #endregion #region VB.NET diff --git a/src/Libraries/NRefactory/Test/Parser/Expressions/MemberReferenceExpressionTests.cs b/src/Libraries/NRefactory/Test/Parser/Expressions/MemberReferenceExpressionTests.cs index 8d38e64304..439f6554a6 100644 --- a/src/Libraries/NRefactory/Test/Parser/Expressions/MemberReferenceExpressionTests.cs +++ b/src/Libraries/NRefactory/Test/Parser/Expressions/MemberReferenceExpressionTests.cs @@ -21,7 +21,7 @@ namespace ICSharpCode.NRefactory.Tests.Ast public void CSharpSimpleFieldReferenceExpressionTest() { MemberReferenceExpression fre = ParseUtilCSharp.ParseExpression("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 public void CSharpGenericFieldReferenceExpressionTest() { MemberReferenceExpression fre = ParseUtilCSharp.ParseExpression("SomeClass.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 public void CSharpFullNamespaceGenericFieldReferenceExpressionTest() { MemberReferenceExpression fre = ParseUtilCSharp.ParseExpression("Namespace.Subnamespace.SomeClass.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 public void CSharpGlobalFullNamespaceGenericFieldReferenceExpressionTest() { MemberReferenceExpression fre = ParseUtilCSharp.ParseExpression("global::Namespace.Subnamespace.SomeClass.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 public void CSharpNestedGenericFieldReferenceExpressionTest() { MemberReferenceExpression fre = ParseUtilCSharp.ParseExpression("MyType.InnerClass.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 public void VBNetSimpleFieldReferenceExpressionTest() { MemberReferenceExpression fre = ParseUtilVBNet.ParseExpression("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 public void VBNetFieldReferenceExpressionWithoutTargetTest() { MemberReferenceExpression fre = ParseUtilVBNet.ParseExpression(".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 public void VBNetGenericFieldReferenceExpressionTest() { MemberReferenceExpression fre = ParseUtilVBNet.ParseExpression("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 public void VBNetFullNamespaceGenericFieldReferenceExpressionTest() { MemberReferenceExpression fre = ParseUtilVBNet.ParseExpression("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 public void VBNetGlobalFullNamespaceGenericFieldReferenceExpressionTest() { MemberReferenceExpression fre = ParseUtilVBNet.ParseExpression("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 public void VBNetNestedGenericFieldReferenceExpressionTest() { MemberReferenceExpression fre = ParseUtilVBNet.ParseExpression("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); diff --git a/src/Libraries/NRefactory/Test/Parser/Expressions/PrimitiveExpressionTests.cs b/src/Libraries/NRefactory/Test/Parser/Expressions/PrimitiveExpressionTests.cs index b4164fae88..949870d663 100644 --- a/src/Libraries/NRefactory/Test/Parser/Expressions/PrimitiveExpressionTests.cs +++ b/src/Libraries/NRefactory/Test/Parser/Expressions/PrimitiveExpressionTests.cs @@ -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; diff --git a/src/Libraries/NRefactory/Test/Parser/Expressions/TypeReferenceExpressionTests.cs b/src/Libraries/NRefactory/Test/Parser/Expressions/TypeReferenceExpressionTests.cs index 28d2682631..d3beecc342 100644 --- a/src/Libraries/NRefactory/Test/Parser/Expressions/TypeReferenceExpressionTests.cs +++ b/src/Libraries/NRefactory/Test/Parser/Expressions/TypeReferenceExpressionTests.cs @@ -46,7 +46,7 @@ namespace ICSharpCode.NRefactory.Tests.Ast public void IntReferenceExpression() { MemberReferenceExpression fre = ParseUtilCSharp.ParseExpression("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 // reference, but it has to stay consistent because NRefactoryResolver depends // on this trick. MemberReferenceExpression fre = ParseUtilCSharp.ParseExpression("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 public void VBIntReferenceExpression() { MemberReferenceExpression fre = ParseUtilVBNet.ParseExpression("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 // reference, but it has to stay consistent because NRefactoryResolver depends // on this trick. MemberReferenceExpression fre = ParseUtilVBNet.ParseExpression("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 public void VBObjectReferenceExpression() { MemberReferenceExpression fre = ParseUtilVBNet.ParseExpression("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 // reference, but it has to stay consistent because NRefactoryResolver depends // on this trick. MemberReferenceExpression fre = ParseUtilVBNet.ParseExpression("obJeCt", true); - Assert.AreEqual("", fre.FieldName); + Assert.AreEqual("", fre.MemberName); Assert.AreEqual("System.Object", ((TypeReferenceExpression)fre.TargetObject).TypeReference.SystemType); } #endregion diff --git a/src/Main/Base/Project/Src/Gui/Pads/DefinitionViewPad.cs b/src/Main/Base/Project/Src/Gui/Pads/DefinitionViewPad.cs index 2877a14dbd..1b4427b575 100644 --- a/src/Main/Base/Project/Src/Gui/Pads/DefinitionViewPad.cs +++ b/src/Main/Base/Project/Src/Gui/Pads/DefinitionViewPad.cs @@ -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 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; diff --git a/src/Main/Base/Project/Src/Services/Debugger/DebuggerService.cs b/src/Main/Base/Project/Src/Services/Debugger/DebuggerService.cs index 2abd5d9b64..be11316dfc 100644 --- a/src/Main/Base/Project/Src/Services/Debugger/DebuggerService.cs +++ b/src/Main/Base/Project/Src/Services/Debugger/DebuggerService.cs @@ -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); diff --git a/src/Main/Base/Project/Src/Services/RefactoringService/RefactorMenu.cs b/src/Main/Base/Project/Src/Services/RefactoringService/RefactorMenu.cs index b9c165f003..718201e442 100644 --- a/src/Main/Base/Project/Src/Services/RefactoringService/RefactorMenu.cs +++ b/src/Main/Base/Project/Src/Services/RefactoringService/RefactorMenu.cs @@ -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 { diff --git a/src/Main/Base/Project/Src/Services/RefactoringService/RefactoringMenuBuilder.cs b/src/Main/Base/Project/Src/Services/RefactoringService/RefactoringMenuBuilder.cs index f0ccffbf4a..8c23d00779 100644 --- a/src/Main/Base/Project/Src/Services/RefactoringService/RefactoringMenuBuilder.cs +++ b/src/Main/Base/Project/Src/Services/RefactoringService/RefactoringMenuBuilder.cs @@ -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 + diff --git a/src/Main/Base/Project/Src/Services/RefactoringService/RefactoringService.cs b/src/Main/Base/Project/Src/Services/RefactoringService/RefactoringService.cs index b21c5280c6..2953c97ece 100644 --- a/src/Main/Base/Project/Src/Services/RefactoringService/RefactoringService.cs +++ b/src/Main/Base/Project/Src/Services/RefactoringService/RefactoringService.cs @@ -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 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 } } + diff --git a/src/Main/Base/Project/Src/TextEditor/Gui/Editor/InsightWindow/MethodInsightDataProvider.cs b/src/Main/Base/Project/Src/TextEditor/Gui/Editor/InsightWindow/MethodInsightDataProvider.cs index b7850a67e0..3d61c71675 100644 --- a/src/Main/Base/Project/Src/TextEditor/Gui/Editor/InsightWindow/MethodInsightDataProvider.cs +++ b/src/Main/Base/Project/Src/TextEditor/Gui/Editor/InsightWindow/MethodInsightDataProvider.cs @@ -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 methods.Add(Constructor.CreateDefault(trr.ResolvedClass)); } } else { - MethodResolveResult result = results as MethodResolveResult; + MethodGroupResolveResult result = results as MethodGroupResolveResult; if (result == null) return; bool classIsInInheritanceTree = false; diff --git a/src/Main/Base/Project/Src/TextEditor/Gui/Editor/TextEditorDisplayBinding.cs b/src/Main/Base/Project/Src/TextEditor/Gui/Editor/TextEditorDisplayBinding.cs index 9add8560c8..1b0669b089 100644 --- a/src/Main/Base/Project/Src/TextEditor/Gui/Editor/TextEditorDisplayBinding.cs +++ b/src/Main/Base/Project/Src/TextEditor/Gui/Editor/TextEditorDisplayBinding.cs @@ -71,9 +71,6 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor public bool EnableUndo { get { - #if DEBUG - textEditorControl.Document.UndoStack.AssertNoUndoGroupOpen(); - #endif return textEditorControl.EnableUndo; } } diff --git a/src/Main/Base/Test/CSharpExpressionFinderTests.cs b/src/Main/Base/Test/CSharpExpressionFinderTests.cs index bd69a15271..42c4caed96 100644 --- a/src/Main/Base/Test/CSharpExpressionFinderTests.cs +++ b/src/Main/Base/Test/CSharpExpressionFinderTests.cs @@ -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); + } } } + diff --git a/src/Main/Base/Test/GenericResolverTests.cs b/src/Main/Base/Test/GenericResolverTests.cs index 636d436483..0a19a4cc44 100644 --- a/src/Main/Base/Test/GenericResolverTests.cs +++ b/src/Main/Base/Test/GenericResolverTests.cs @@ -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('a', 1); + d.T('a', 2); + } + protected virtual void T(A a, B b) { + } + protected virtual void T(Y a, X b) { + } +} +class D : Program { + protected override void T(X a, Y b) { + // overrides T - type arguments are identified by position + } +}"; + IAmbience ambience = Dom.CSharp.CSharpAmbience.Instance; + ambience.ConversionFlags = ConversionFlags.UseFullyQualifiedMemberNames | ConversionFlags.ShowTypeParameterList; + MemberResolveResult mrr; + + mrr = Resolve(program, "d.T('a', 2)", 5); + Assert.AreEqual("Program.T", ambience.Convert((IMethod)mrr.ResolvedMember)); + + mrr = Resolve(program, "d.T('a', 1)", 6); + Assert.AreEqual("D.T", ambience.Convert((IMethod)mrr.ResolvedMember)); + + IMember baseMember = MemberLookupHelper.FindBaseMember(mrr.ResolvedMember); + Assert.IsNotNull(baseMember); + Assert.AreEqual("Program.T", ambience.Convert((IMethod)baseMember)); + } #endregion } } diff --git a/src/Main/Base/Test/InnerClassesResolverTests.cs b/src/Main/Base/Test/InnerClassesResolverTests.cs index 5bf678e602..10db0c3581 100644 --- a/src/Main/Base/Test/InnerClassesResolverTests.cs +++ b/src/Main/Base/Test/InnerClassesResolverTests.cs @@ -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(program, "Test(4)", 7); + Assert.AreEqual("A.B.Test", result.ResolvedMember.FullyQualifiedName); + } } } diff --git a/src/Main/Base/Test/NRefactoryResolverTests.cs b/src/Main/Base/Test/NRefactoryResolverTests.cs index c1f86ff6bc..84a2413c01 100644 --- a/src/Main/Base/Test/NRefactoryResolverTests.cs +++ b/src/Main/Base/Test/NRefactoryResolverTests.cs @@ -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 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(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 public T Resolve(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 public T ResolveVB(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 { 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 a) { } +} +"; + MethodGroupResolveResult result = Resolve(program, "TargetMethod", 3); + Assert.AreEqual("TargetMethod", result.Name); + Assert.AreEqual(2, result.Methods.Count); + + result = Resolve(program, "TargetMethod", 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 { { string program = @"using System; class A : B { - void TestMethod(B b) { + static void TestMethod(A a) { } } @@ -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 { 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 { 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 result = ResolveVB(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(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 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(program, "BaseClass.Test()", 4); + Assert.AreEqual("BaseClass.Test", mrr.ResolvedMember.FullyQualifiedName); + + mrr = Resolve(program, "Test", 4); + Assert.AreEqual("DerivedClass.Test", mrr.ResolvedMember.FullyQualifiedName); + + mrr = Resolve(program, "DerivedClass.Test", 4); + Assert.AreEqual("DerivedClass.Test", mrr.ResolvedMember.FullyQualifiedName); + + // returns BaseClass.Test because DerivedClass.Test is not invocable + mrr = Resolve(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(program, "BaseClass.Test()", 4); + Assert.AreEqual("BaseClass.Test", mrr.ResolvedMember.FullyQualifiedName); + + mrr = Resolve(program, "Test", 4); + Assert.AreEqual("DerivedClass.Test", mrr.ResolvedMember.FullyQualifiedName); + + mrr = Resolve(program, "DerivedClass.Test", 4); + Assert.AreEqual("DerivedClass.Test", mrr.ResolvedMember.FullyQualifiedName); + + // returns BaseClass.Test because DerivedClass.Test is not invocable + mrr = Resolve(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(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(program, "Test", 4); + Assert.AreEqual("DerivedClass.Test", mrr.ResolvedMember.FullyQualifiedName); + + mrr = Resolve(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(program, "Test", 4); + Assert.AreEqual("DerivedClass.Test", mrr.ResolvedMember.FullyQualifiedName); + + mrr = Resolve(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(program, "T(a)", 5); + Assert.IsFalse(((IMethod)mrr.ResolvedMember).Parameters[0].IsRef); + + mrr = Resolve(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(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(program, "new DerivedClass().Test(3);", 4); + Assert.AreEqual("MiddleClass.Test", (mrr.ResolvedMember).FullyQualifiedName); + } } } diff --git a/src/Main/ICSharpCode.SharpDevelop.Dom/Project/ICSharpCode.SharpDevelop.Dom.csproj b/src/Main/ICSharpCode.SharpDevelop.Dom/Project/ICSharpCode.SharpDevelop.Dom.csproj index 6fb1dc0637..03b26f1619 100644 --- a/src/Main/ICSharpCode.SharpDevelop.Dom/Project/ICSharpCode.SharpDevelop.Dom.csproj +++ b/src/Main/ICSharpCode.SharpDevelop.Dom/Project/ICSharpCode.SharpDevelop.Dom.csproj @@ -99,6 +99,7 @@ + @@ -183,4 +184,4 @@ - \ No newline at end of file + diff --git a/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/CSharp/ExpressionFinder.cs b/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/CSharp/ExpressionFinder.cs index 0d2aab355f..a251dac0e9 100644 --- a/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/CSharp/ExpressionFinder.cs +++ b/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/CSharp/ExpressionFinder.cs @@ -55,18 +55,61 @@ namespace ICSharpCode.SharpDevelop.Dom.CSharp enum FrameType { Global, + /// + /// "class C { * }" + /// TypeDecl, + /// + /// "interface I { * }" + /// Interface, + /// + /// "enum E { * }" + /// Enum, + /// + /// "void Method(*) {}" + /// ParameterList, + /// + /// "public string Property { * }" + /// Property, + /// + /// "public event EventHandler SomethingChanged { * }" + /// Event, + /// + /// "void Method() { * }" + /// Statements, + /// + /// "if (*) {}" + /// Expression, + /// + /// "new T { * }" + /// ObjectInitializer, + /// + /// "[*] class ..." + /// AttributeSection, + /// + /// "[Obsolete(*)] class ..." + /// AttributeArguments, + /// + /// Type reference frame "typeof(*)" + /// + TypeReference, + /// + /// Type parameter declaration, "class C<*gt;" + /// TypeParameterDecl, + /// + /// The Frame is no longer active. + /// Popped } @@ -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 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 } } + diff --git a/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Implementations/AbstractReturnType.cs b/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Implementations/AbstractReturnType.cs index 89ff4aac83..886ef12c7f 100644 --- a/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Implementations/AbstractReturnType.cs +++ b/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Implementations/AbstractReturnType.cs @@ -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; diff --git a/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Implementations/ConstructedReturnType.cs b/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Implementations/ConstructedReturnType.cs index 8310518819..ed21738cc3 100644 --- a/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Implementations/ConstructedReturnType.cs +++ b/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Implementations/ConstructedReturnType.cs @@ -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 { diff --git a/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Implementations/DefaultReturnType.cs b/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Implementations/DefaultReturnType.cs index c26a81882c..c6c821eca7 100644 --- a/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Implementations/DefaultReturnType.cs +++ b/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Implementations/DefaultReturnType.cs @@ -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 } } if (ok) - l.Add(m); + l.Add(m);*/ + l.Add(m); } } } @@ -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 } } if (ok) - l.Add(p); + l.Add(p);*/ + l.Add(p); } } } diff --git a/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Implementations/GenericReturnType.cs b/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Implementations/GenericReturnType.cs index 62faab54fc..fb11589903 100644 --- a/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Implementations/GenericReturnType.cs +++ b/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Implementations/GenericReturnType.cs @@ -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() @@ -39,11 +50,6 @@ namespace ICSharpCode.SharpDevelop.Dom } } - public override int GetHashCode() - { - return typeParameter.GetHashCode(); - } - public GenericReturnType(ITypeParameter typeParameter) { if (typeParameter == null) diff --git a/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Interfaces/IDecoration.cs b/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Interfaces/IDecoration.cs index cd7388d06b..f38b162362 100644 --- a/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Interfaces/IDecoration.cs +++ b/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/Interfaces/IDecoration.cs @@ -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); } } diff --git a/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/LanguageProperties.cs b/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/LanguageProperties.cs index e1827abfc7..56247c4162 100644 --- a/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/LanguageProperties.cs +++ b/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/LanguageProperties.cs @@ -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 if (member is ArrayReturnType.ArrayIndexer) { return false; } + if (member is IMethod && ((IMethod)member).IsConstructor) { + return false; + } return member.IsStatic || !showStatic; } diff --git a/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/MemberLookupHelper.cs b/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/MemberLookupHelper.cs index 974bb30ca8..8f430f17a1 100644 --- a/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/MemberLookupHelper.cs +++ b/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/MemberLookupHelper.cs @@ -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 /// Class with methods to help finding the correct overload for a member. /// /// - /// 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. /// public static class MemberLookupHelper { + static List GetAllMembers(IReturnType rt) + { + List members = new List(); + 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 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 members; + if (language == LanguageProperties.VBNet && language.NameComparer.Equals(name, "New")) { + members = GetAllMembers(type).OfType().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 + { + 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 cachedHashes = new Dictionary(); + + 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 + { + 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 LookupMember(IEnumerable possibleMembers, IClass callingClass, + bool isClassInInheritanceTree, bool isInvocation) + { +// Console.WriteLine("Possible members:"); +// foreach (IMember m in possibleMembers) { +// Console.WriteLine(" " + m.DotNetName); +// } + + IEnumerable accessibleMembers = possibleMembers.Where(member => member.IsAccessible(callingClass, isClassInInheritanceTree)); + if (isInvocation) { + accessibleMembers = accessibleMembers.Where(IsInvocable); + } + + // base most member => most derived member + //Dictionary overrideDict = new Dictionary(); + + Dictionary overrideMethodDict = new Dictionary(new SignatureComparer()); + IMember nonMethodOverride = null; + + List results = new List(); + 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; + } + + /// + /// Gets all accessible members, including indexers and constructors. + /// + public static List 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 result = new List(); + foreach (var g in GetAllMembers(rt).GroupBy(m => m.Name, language.NameComparer)) { + result.AddRange(LookupMember(g, callingClass, isClassInInheritanceTree, false)); + } + return result; + } + #region FindOverload /// /// Finds the correct overload according to the C# specification. @@ -26,18 +196,17 @@ namespace ICSharpCode.SharpDevelop.Dom /// List with the methods to check.
/// Generic methods in the input type are replaced by methods with have the types substituted! /// - /// The type parameters passed to the method. /// The types of the arguments passed to the method. /// 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. /// The method that will be called. - public static IMethod FindOverload(IList methods, IReturnType[] typeParameters, IReturnType[] arguments, out bool resultIsAcceptable) + public static IMethod FindOverload(IList 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 /// List with the methods to check.
/// Generic methods in the input type are replaced by methods with have the types substituted! /// - /// List with the type parameters passed to the method. - /// Can be null (=no type parameters) /// The types of the arguments passed to the method. /// A null return type means any argument type is allowed. /// Specifies whether the method can have @@ -86,7 +253,6 @@ namespace ICSharpCode.SharpDevelop.Dom /// method is acceptable for a method call (no invalid casts) /// Integer array. Each value in the array public static int[] RankOverloads(IList list, - IReturnType[] typeParameters, IReturnType[] arguments, bool allowAdditionalArguments, out bool acceptableMatch) @@ -94,47 +260,21 @@ namespace ICSharpCode.SharpDevelop.Dom acceptableMatch = false; if (list.Count == 0) return new int[] {}; - List l2 = new List(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 l2 = new List(); + 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 list, IReturnType[][] inferredTypeParameters) @@ -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) { diff --git a/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/NRefactoryResolver/CSharpToVBNetConvertVisitor.cs b/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/NRefactoryResolver/CSharpToVBNetConvertVisitor.cs index 11b4dd8e6b..27c884931c 100644 --- a/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/NRefactoryResolver/CSharpToVBNetConvertVisitor.cs +++ b/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/NRefactoryResolver/CSharpToVBNetConvertVisitor.cs @@ -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 && (parentIE == null || parentIE.TargetObject != fieldReferenceExpression)) { ResolveResult rr = resolver.ResolveInternal(fieldReferenceExpression, ExpressionContext.Default); - if (rr is MethodResolveResult) { + if (rr is MethodGroupResolveResult) { ReplaceCurrentNode(new AddressOfExpression(fieldReferenceExpression)); } } diff --git a/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/NRefactoryResolver/NRefactoryResolver.cs b/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/NRefactoryResolver/NRefactoryResolver.cs index 5c691d8701..a46d4e4005 100644 --- a/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/NRefactoryResolver/NRefactoryResolver.cs +++ b/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/NRefactoryResolver/NRefactoryResolver.cs @@ -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 { 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 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 { 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 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 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 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 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 } return ResolveMethod(type, memberReferenceExpression.FieldName); } + */ public TextReader ExtractCurrentMethod(string fileContent) { @@ -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 } #region Resolve Identifier - public ResolveResult ResolveIdentifier(string identifier, NR.Location position, ExpressionContext context) + internal IReturnType ConstructType(IReturnType baseType, List 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 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 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 } } 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 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 if (languageProperties.ImportModules) { ArrayList list = new ArrayList(); CtrlSpaceResolveHelper.AddImportedNamespaceContents(list, cu, callingClass); + List resultMembers = new List(); 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 } 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 return new MemberResolveResult(callingClass, callingMember, member); } - #region ResolveMethod - ResolveResult ResolveMethod(IReturnType type, string identifier) + #region ResolveMember + internal ResolveResult ResolveMember(IReturnType declaringType, string memberName, + List 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 members = MemberLookupHelper.LookupMember(declaringType, memberName, callingClass, languageProperties, isInvocation); + if (members != null && typeArguments != null && typeArguments.Count != 0) { + List typeArgs = typeArguments.ConvertAll(r => TypeVisitor.CreateReturnType(r, this)); + + members = members.OfType() + .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 members, bool allowExtensionMethods) + { + List methods = new List(); + 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(() => SearchExtensionMethods(memberName))); + } } #endregion @@ -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 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); } /// /// use the usings and the name of the namespace to find a class /// - 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 SearchMethod(string memberName) - { - List 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(); - - 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; - } - - /// - /// Gets the list of methods on the return type that have the specified name. - /// - public List SearchMethod(IReturnType type, string memberName) - { - List methods = new List(); - 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 SearchExtensionMethods(string name) @@ -1072,6 +1041,7 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver ReadOnlyCollection cachedExtensionMethods; IClass cachedExtensionMethods_LastClass; // invalidate cache when callingClass != LastClass + static readonly IMethod[] emptyMethodList = new IMethod[0]; static readonly ReadOnlyCollection emptyMethodOrPropertyList = new ReadOnlyCollection(new IMethodOrProperty[0]); public ReadOnlyCollection SearchAllExtensionMethods() @@ -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 + /* /// /// does the dynamic lookup for the identifier /// @@ -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 return null; } #endregion - #endregion IClass GetPrimitiveClass(string systemType, string newName) { @@ -1364,3 +1291,4 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver } } + diff --git a/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/NRefactoryResolver/ResolveVisitor.cs b/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/NRefactoryResolver/ResolveVisitor.cs new file mode 100644 index 0000000000..4b7c6c2d25 --- /dev/null +++ b/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/NRefactoryResolver/ResolveVisitor.cs @@ -0,0 +1,570 @@ +// +// +// +// +// $Revision$ +// + +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 +{ + /// + /// Resolves expressions. + /// + 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 cachedResults = new Dictionary(); + + 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(); + 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 indexes) + { + if (target == null) + return null; + return MemberLookupHelper.FindOverload( + target.GetProperties().Where((IProperty p) => p.IsIndexer).ToList(), + indexes.Select(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(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 possibleMembers = new List(); + 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 arguments) + { + if (c == null) + return null; + + List methods = c.Methods.Where(m => m.IsConstructor && !m.IsStatic).ToList(); + IReturnType[] argumentTypes = arguments.Select(ResolveType).ToArray(); + bool resultIsAcceptable; + IMethod result = MemberLookupHelper.FindOverload(methods, argumentTypes, out resultIsAcceptable); + return CreateMemberResolveResult(result ?? Constructor.CreateDefault(c)); + } + + DefaultClass CreateAnonymousTypeClass(CollectionInitializerExpression initializer) + { + List fieldTypes = new List(); + List fieldNames = new List(); + + 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); + } + } +} diff --git a/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/NRefactoryResolver/TypeVisitor.cs b/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/NRefactoryResolver/TypeVisitor.cs index 2fdbce440b..5e645ce310 100644 --- a/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/NRefactoryResolver/TypeVisitor.cs +++ b/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/NRefactoryResolver/TypeVisitor.cs @@ -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]; - - /// - /// Find the correct overload from a list of overloads. - /// - /// The list of available methods to call. - /// The type parameters used for the method call. - /// The arguments passed to the method. - /// The chosen overload. - public IMethod FindOverload(IList methods, IReturnType[] typeParameters, IList arguments) - { - return FindOverload(methods, null, null, typeParameters, arguments); - } - - /// - /// Find the correct overload from a list of overloads. - /// - /// The list of available methods to call. - /// The list of available extension methods to call. - /// The type of the expression on which the method is called. Used as first argument to the extension methods. - /// The type parameters used for the method call. - /// The arguments passed to the method. - /// The chosen overload. - public IMethod FindOverload(IList methods, IList extensionMethods, IReturnType targetType, IReturnType[] typeParameters, IList 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 GetTypeArguments(Expression expr) - { - if (expr is IdentifierExpression) - return ((IdentifierExpression)expr).TypeArguments; - else if (expr is MemberReferenceExpression) - return ((MemberReferenceExpression)expr).TypeArguments; - else - return null; - } - - /// - /// Gets the method called by the InvocationExpression. In Visual Basic, the result - /// can also be an Indexer. - /// - 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 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 extensionMethods = new LazyList( - 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 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 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 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 fieldTypes = new List(); - List fieldNames = new List(); - - 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(); - 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 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 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 } return t; } - - public class NamespaceReturnType : AbstractReturnType - { - public NamespaceReturnType(string fullName) - { - this.FullyQualifiedName = fullName; - } - - public override IClass GetUnderlyingClass() { - return null; - } - - public override List GetMethods() { - return new List(); - } - - public override List GetProperties() { - return new List(); - } - - public override List GetFields() { - return new List(); - } - - public override List GetEvents() { - return new List(); - } - } } } diff --git a/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/NRefactoryResolver/VBNetToCSharpConvertVisitor.cs b/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/NRefactoryResolver/VBNetToCSharpConvertVisitor.cs index 043a1ed1e7..cb8422d1c2 100644 --- a/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/NRefactoryResolver/VBNetToCSharpConvertVisitor.cs +++ b/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/NRefactoryResolver/VBNetToCSharpConvertVisitor.cs @@ -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 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 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 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 { 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 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; diff --git a/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/ResolveResult.cs b/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/ResolveResult.cs index 2ce6180f99..27dc1cfca5 100644 --- a/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/ResolveResult.cs +++ b/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/ResolveResult.cs @@ -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. ///
- public class ResolveResult + public class ResolveResult : ICloneable { IClass callingClass; IMember callingMember; @@ -41,9 +41,7 @@ namespace ICSharpCode.SharpDevelop.Dom /// Can be null when the class is unknown. /// public IClass CallingClass { - get { - return callingClass; - } + get { return callingClass; } } /// @@ -52,9 +50,7 @@ namespace ICSharpCode.SharpDevelop.Dom /// Can be null when the expression was not inside a member or the member is unknown. /// public IMember CallingMember { - get { - return callingMember; - } + get { return callingMember; } } /// @@ -63,12 +59,18 @@ namespace ICSharpCode.SharpDevelop.Dom /// expression was a namespace name). /// 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 { 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 } return result; } + + public override ResolveResult Clone() + { + return new MixedResolveResult(primaryResult.Clone(), secondaryResult.Clone()); + } } #endregion @@ -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); + } /// /// Gets the field representing the local variable. @@ -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 { return null; } + + public override ResolveResult Clone() + { + return new IntegerLiteralResolveResult(this.CallingClass, this.CallingMember, this.ResolvedType); + } } #endregion @@ -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); + } + /// /// 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 this.resolvedMember = resolvedMember; } + public override ResolveResult Clone() + { + return new MemberResolveResult(this.CallingClass, this.CallingMember, this.ResolvedMember); + } + /// /// Gets the member that was resolved. /// public IMember ResolvedMember { - get { - return resolvedMember; - } + get { return resolvedMember; } } public override FilePosition GetDefinitionPosition() @@ -494,46 +511,84 @@ namespace ICSharpCode.SharpDevelop.Dom /// "a.Add" (where a is List<string>) /// "SomeMethod" (when SomeMethod is a method in the current class) /// - public class MethodResolveResult : ResolveResult + public class MethodGroupResolveResult : ResolveResult { string name; IReturnType containingType; + IList possibleMethods; + IList 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 possibleMethods, IList 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); } /// /// Gets the name of the method. /// public string Name { - get { - return name; - } + get { return name; } } /// /// Gets the class that contains the method. /// public IReturnType ContainingType { + get { return containingType; } + } + + /// + /// The list of possible methods. + /// + public IList Methods { get { - return containingType; + if (possibleMethods == null) + possibleMethods = containingType.GetMethods().FindAll((IMethod m) => m.Name == this.name); + return possibleMethods; } } + /// + /// The list of possible extension methods. + /// + public IList PossibleExtensionMethods { + get { return possibleExtensionMethods; } + } + public IMethod GetMethodIfSingleOverload() { - List 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 } return res; } + + public override ResolveResult Clone() + { + return new VBBaseOrThisReferenceInConstructorResolveResult(this.CallingClass, this.CallingMember, this.ResolvedType); + } } #endregion @@ -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 } + diff --git a/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/VBNet/VBNetAmbience.cs b/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/VBNet/VBNetAmbience.cs index d3079b70d0..dcef8cb49b 100644 --- a/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/VBNet/VBNetAmbience.cs +++ b/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/VBNet/VBNetAmbience.cs @@ -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"; }