diff --git a/ICSharpCode.NRefactory/CSharp/Ast/Expressions/BinaryOperatorExpression.cs b/ICSharpCode.NRefactory/CSharp/Ast/Expressions/BinaryOperatorExpression.cs
index 171e3e31c2..cef22fecd2 100644
--- a/ICSharpCode.NRefactory/CSharp/Ast/Expressions/BinaryOperatorExpression.cs
+++ b/ICSharpCode.NRefactory/CSharp/Ast/Expressions/BinaryOperatorExpression.cs
@@ -128,11 +128,15 @@ namespace ICSharpCode.NRefactory.CSharp
public enum BinaryOperatorType
{
+ ///
+ /// Any binary operator (used in pattern matching)
+ ///
+ Any,
+
// We avoid 'logical or' on purpose, because it's not clear if that refers to the bitwise
// or to the short-circuiting (conditional) operator:
// MCS and old NRefactory used bitwise='|', logical='||'
// but the C# spec uses logical='|', conditional='||'
-
/// left & right
BitwiseAnd,
/// left | right
@@ -174,11 +178,6 @@ namespace ICSharpCode.NRefactory.CSharp
ShiftRight,
/// left ?? right
- NullCoalescing,
-
- ///
- /// Any binary operator (used in pattern matching)
- ///
- Any
+ NullCoalescing
}
}
diff --git a/ICSharpCode.NRefactory/CSharp/Ast/Expressions/UnaryOperatorExpression.cs b/ICSharpCode.NRefactory/CSharp/Ast/Expressions/UnaryOperatorExpression.cs
index 2cc7256d88..c99d4ea941 100644
--- a/ICSharpCode.NRefactory/CSharp/Ast/Expressions/UnaryOperatorExpression.cs
+++ b/ICSharpCode.NRefactory/CSharp/Ast/Expressions/UnaryOperatorExpression.cs
@@ -1,6 +1,6 @@
//
// UnaryOperatorExpression.cs
-//
+//
// Author:
// Mike Krüger
//
@@ -67,7 +67,8 @@ namespace ICSharpCode.NRefactory.CSharp
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
UnaryOperatorExpression o = other as UnaryOperatorExpression;
- return o != null && this.Operator == o.Operator && this.Expression.DoMatch(o.Expression, match);
+ return o != null && (this.Operator == UnaryOperatorType.Any || this.Operator == o.Operator)
+ && this.Expression.DoMatch(o.Expression, match);
}
public static string GetOperatorSymbol(UnaryOperatorType op)
@@ -101,6 +102,11 @@ namespace ICSharpCode.NRefactory.CSharp
public enum UnaryOperatorType
{
+ ///
+ /// Any unary operator (used in pattern matching)
+ ///
+ Any,
+
/// Logical not (!a)
Not,
/// Bitwise not (~a)
diff --git a/ICSharpCode.NRefactory/CSharp/Resolver/Conversions.cs b/ICSharpCode.NRefactory/CSharp/Resolver/Conversions.cs
index 5465213dcc..7c1ba5ba0b 100644
--- a/ICSharpCode.NRefactory/CSharp/Resolver/Conversions.cs
+++ b/ICSharpCode.NRefactory/CSharp/Resolver/Conversions.cs
@@ -86,16 +86,22 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
public static Conversion UserDefinedImplicitConversion(IMethod operatorMethod, bool isLifted)
{
+ if (operatorMethod == null)
+ throw new ArgumentNullException("operatorMethod");
return new Conversion(isLifted ? liftedUserDefinedImplicitConversionKind : userDefinedImplicitConversionKind, operatorMethod);
}
public static Conversion UserDefinedExplicitConversion(IMethod operatorMethod, bool isLifted)
{
+ if (operatorMethod == null)
+ throw new ArgumentNullException("operatorMethod");
return new Conversion(isLifted ? liftedUserDefinedExplicitConversionKind : userDefinedExplicitConversionKind, operatorMethod);
}
public static Conversion MethodGroupConversion(IMethod chosenMethod)
{
+ if (chosenMethod == null)
+ throw new ArgumentNullException("chosenMethod");
return new Conversion(methodGroupConversionKind, chosenMethod);
}
diff --git a/ICSharpCode.NRefactory/CSharp/Resolver/FindReferencedEntities.cs b/ICSharpCode.NRefactory/CSharp/Resolver/FindReferencedEntities.cs
new file mode 100644
index 0000000000..e3c5d6e693
--- /dev/null
+++ b/ICSharpCode.NRefactory/CSharp/Resolver/FindReferencedEntities.cs
@@ -0,0 +1,64 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this
+// software and associated documentation files (the "Software"), to deal in the Software
+// without restriction, including without limitation the rights to use, copy, modify, merge,
+// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
+// to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or
+// substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
+// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+using System;
+using ICSharpCode.NRefactory.TypeSystem;
+
+namespace ICSharpCode.NRefactory.CSharp.Resolver
+{
+ ///
+ /// Find all entities that are referenced in the scanned AST.
+ ///
+ public sealed class FindReferencedEntities : IResolveVisitorNavigator
+ {
+ readonly Action referenceFound;
+
+ public FindReferencedEntities(Action referenceFound)
+ {
+ if (referenceFound == null)
+ throw new ArgumentNullException("referenceFound");
+ this.referenceFound = referenceFound;
+ }
+
+ public ResolveVisitorNavigationMode Scan(AstNode node)
+ {
+ return ResolveVisitorNavigationMode.Resolve;
+ }
+
+ public void Resolved(AstNode node, ResolveResult result)
+ {
+ MemberResolveResult mrr = result as MemberResolveResult;
+ if (mrr != null) {
+ referenceFound(node, mrr.Member);
+ }
+ TypeResolveResult trr = result as TypeResolveResult;
+ if (trr != null) {
+ ITypeDefinition typeDef = trr.Type.GetDefinition();
+ if (typeDef != null)
+ referenceFound(node, typeDef);
+ }
+ }
+
+ public void ProcessConversion(Expression expression, ResolveResult result, Conversion conversion, IType targetType)
+ {
+ if (conversion.IsUserDefined || conversion.IsMethodGroupConversion) {
+ referenceFound(expression, conversion.Method);
+ }
+ }
+ }
+}
diff --git a/ICSharpCode.NRefactory/CSharp/Resolver/Log.cs b/ICSharpCode.NRefactory/CSharp/Resolver/Log.cs
index 11053b90df..c3d43c2f4d 100644
--- a/ICSharpCode.NRefactory/CSharp/Resolver/Log.cs
+++ b/ICSharpCode.NRefactory/CSharp/Resolver/Log.cs
@@ -35,7 +35,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
///
static class Log
{
- const bool logEnabled = true;
+ const bool logEnabled = false;
[Conditional(logEnabled ? "DEBUG" : "LOG_DISABLED")]
internal static void WriteLine(string text)
diff --git a/ICSharpCode.NRefactory/CSharp/Resolver/ResolveVisitor.cs b/ICSharpCode.NRefactory/CSharp/Resolver/ResolveVisitor.cs
index 8b52443f19..edfaaa977b 100644
--- a/ICSharpCode.NRefactory/CSharp/Resolver/ResolveVisitor.cs
+++ b/ICSharpCode.NRefactory/CSharp/Resolver/ResolveVisitor.cs
@@ -359,6 +359,9 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
///
public ResolveResult GetResolveResult(AstNode node)
{
+ if (IsUnresolvableNode(node))
+ return null;
+
MergeUndecidedLambdas();
ResolveResult result;
if (resolveResultCache.TryGetValue(node, out result))
@@ -385,6 +388,28 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
return null;
}
+ ///
+ /// Gets whether the specified node is unresolvable.
+ ///
+ public static bool IsUnresolvableNode(AstNode node)
+ {
+ return (node.NodeType == NodeType.Whitespace || node is ArraySpecifier || node is NamedArgumentExpression);
+ }
+
+ ///
+ /// Gets the resolve result for the specified node.
+ /// If the node was not resolved by the navigator, this method will return null.
+ ///
+ public ResolveResult GetResolveResultIfResolved(AstNode node)
+ {
+ MergeUndecidedLambdas();
+ ResolveResult result;
+ if (resolveResultCache.TryGetValue(node, out result))
+ return result;
+ else
+ return null;
+ }
+
CSharpResolver GetPreviouslyScannedContext(AstNode node, out AstNode parent)
{
parent = node;
@@ -577,7 +602,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
if (aie != null && arrayType != null) {
StoreState(aie, resolver.Clone());
List initializerElements = new List();
- UnpackArrayInitializer(initializerElements, aie, arrayType.Dimensions);
+ UnpackArrayInitializer(initializerElements, aie, arrayType.Dimensions, true);
ResolveResult[] initializerElementResults = new ResolveResult[initializerElements.Count];
for (int i = 0; i < initializerElementResults.Length; i++) {
initializerElementResults[i] = Resolve(initializerElements[i]);
@@ -916,11 +941,12 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
initializerElementResults = null;
} else {
initializerElements = new List();
- UnpackArrayInitializer(initializerElements, arrayCreateExpression.Initializer, dimensions);
+ UnpackArrayInitializer(initializerElements, arrayCreateExpression.Initializer, dimensions, true);
initializerElementResults = new ResolveResult[initializerElements.Count];
for (int i = 0; i < initializerElementResults.Length; i++) {
initializerElementResults[i] = Resolve(initializerElements[i]);
}
+ StoreResult(arrayCreateExpression.Initializer, voidResult);
}
ArrayCreateResolveResult acrr;
@@ -936,16 +962,19 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
return acrr;
}
- void UnpackArrayInitializer(List elementList, ArrayInitializerExpression initializer, int dimensions)
+ void UnpackArrayInitializer(List elementList, ArrayInitializerExpression initializer, int dimensions, bool resolveNestedInitializesToVoid)
{
Debug.Assert(dimensions >= 1);
if (dimensions > 1) {
foreach (var node in initializer.Elements) {
ArrayInitializerExpression aie = node as ArrayInitializerExpression;
- if (aie != null)
- UnpackArrayInitializer(elementList, aie, dimensions - 1);
- else
+ if (aie != null) {
+ if (resolveNestedInitializesToVoid)
+ StoreResult(aie, voidResult);
+ UnpackArrayInitializer(elementList, aie, dimensions - 1, resolveNestedInitializesToVoid);
+ } else {
elementList.Add(node);
+ }
}
} else {
foreach (var expr in initializer.Elements)
@@ -1215,6 +1244,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
}
}
resolver.PopInitializerType();
+ StoreResult(initializer, voidResult);
}
ResolveResult IAstVisitor