Browse Source

Make CSharpResolver immutable.

newNRvisualizers
Daniel Grunwald 14 years ago
parent
commit
b84c06e5b6
  1. 2
      ICSharpCode.NRefactory.CSharp/Resolver/CSharpAstResolver.cs
  2. 160
      ICSharpCode.NRefactory.CSharp/Resolver/CSharpResolver.cs
  3. 191
      ICSharpCode.NRefactory.CSharp/Resolver/ResolveVisitor.cs
  4. 8
      ICSharpCode.NRefactory.CSharp/TypeSystem/ConstantValues.cs
  5. 4
      ICSharpCode.NRefactory.Tests/CSharp/CodeDomConvertVisitorTests.cs
  6. 7
      ICSharpCode.NRefactory.Tests/CSharp/Refactoring/TypeSystemAstBuilderTests.cs
  7. 6
      ICSharpCode.NRefactory.Tests/CSharp/Resolver/BinaryOperatorTests.cs
  8. 9
      ICSharpCode.NRefactory.Tests/CSharp/Resolver/CastTests.cs
  9. 60
      ICSharpCode.NRefactory.Tests/CSharp/Resolver/NameLookupTests.cs
  10. 3
      ICSharpCode.NRefactory.Tests/CSharp/Resolver/UnaryOperatorTests.cs

2
ICSharpCode.NRefactory.CSharp/Resolver/CSharpAstResolver.cs

@ -70,7 +70,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -70,7 +70,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
throw new ArgumentNullException("resolver");
if (rootNode == null)
throw new ArgumentNullException("rootNode");
this.initialResolverState = resolver.Clone();
this.initialResolverState = resolver;
this.rootNode = rootNode;
this.parsedFile = parsedFile;
}

160
ICSharpCode.NRefactory.CSharp/Resolver/CSharpResolver.cs

@ -43,7 +43,9 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -43,7 +43,9 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
readonly ICompilation compilation;
internal readonly Conversions conversions;
CSharpTypeResolveContext context;
readonly CSharpTypeResolveContext context;
readonly bool checkForOverflow;
readonly bool isWithinLambdaExpression;
#region Constructor
public CSharpResolver(ICompilation compilation)
@ -65,6 +67,18 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -65,6 +67,18 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
if (context.CurrentTypeDefinition != null)
currentTypeDefinitionCache = new TypeDefinitionCache(context.CurrentTypeDefinition);
}
private CSharpResolver(ICompilation compilation, Conversions conversions, CSharpTypeResolveContext context, bool checkForOverflow, bool isWithinLambdaExpression, TypeDefinitionCache currentTypeDefinitionCache, ImmutableStack<IVariable> localVariableStack, ObjectInitializerContext objectInitializerStack)
{
this.compilation = compilation;
this.conversions = conversions;
this.context = context;
this.checkForOverflow = checkForOverflow;
this.isWithinLambdaExpression = isWithinLambdaExpression;
this.currentTypeDefinitionCache = currentTypeDefinitionCache;
this.localVariableStack = localVariableStack;
this.objectInitializerStack = objectInitializerStack;
}
#endregion
#region Properties
@ -82,53 +96,101 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -82,53 +96,101 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
get { return context; }
}
CSharpResolver WithContext(CSharpTypeResolveContext newContext)
{
return new CSharpResolver(compilation, conversions, newContext, checkForOverflow, isWithinLambdaExpression, currentTypeDefinitionCache, localVariableStack, objectInitializerStack);
}
/// <summary>
/// Gets/Sets whether the current context is <c>checked</c>.
/// Gets whether the current context is <c>checked</c>.
/// </summary>
public bool CheckForOverflow { get; set; }
public bool CheckForOverflow {
get { return checkForOverflow; }
}
/// <summary>
/// Sets whether the current context is <c>checked</c>.
/// </summary>
public CSharpResolver WithCheckForOverflow(bool checkForOverflow)
{
return new CSharpResolver(compilation, conversions, context, checkForOverflow, isWithinLambdaExpression, currentTypeDefinitionCache, localVariableStack, objectInitializerStack);
}
/// <summary>
/// Gets/Sets the current member definition that is used to look up identifiers as parameters
/// Gets whether the resolver is currently within a lambda expression.
/// </summary>
public bool IsWithinLambdaExpression {
get { return isWithinLambdaExpression; }
}
/// <summary>
/// Sets whether the resolver is currently within a lambda expression.
/// </summary>
public CSharpResolver WithIsWithinLambdaExpression(bool isWithinLambdaExpression)
{
return new CSharpResolver(compilation, conversions, context, checkForOverflow, isWithinLambdaExpression, currentTypeDefinitionCache, localVariableStack, objectInitializerStack);
}
/// <summary>
/// Gets the current member definition that is used to look up identifiers as parameters
/// or type parameters.
/// </summary>
/// <remarks>Don't forget to also set CurrentTypeDefinition when setting CurrentMember;
/// setting one of the properties does not automatically set the other.</remarks>
public IMember CurrentMember {
get { return context.CurrentMember; }
set {
context = context.WithCurrentMember(value);
}
}
/// <summary>
/// Gets/Sets the current using scope that is used to look up identifiers as class names.
/// Sets the current member definition.
/// </summary>
/// <remarks>Don't forget to also set CurrentTypeDefinition when setting CurrentMember;
/// setting one of the properties does not automatically set the other.</remarks>
public CSharpResolver WithCurrentMember(IMember member)
{
return WithContext(context.WithCurrentMember(member));
}
/// <summary>
/// Gets the current using scope that is used to look up identifiers as class names.
/// </summary>
public ResolvedUsingScope CurrentUsingScope {
get { return context.CurrentUsingScope; }
set {
context = context.WithUsingScope(value);
}
}
/// <summary>
/// Sets the current using scope that is used to look up identifiers as class names.
/// </summary>
public CSharpResolver WithCurrentUsingScope(ResolvedUsingScope usingScope)
{
return WithContext(context.WithUsingScope(usingScope));
}
#endregion
#region Per-CurrentTypeDefinition Cache
TypeDefinitionCache currentTypeDefinitionCache;
readonly TypeDefinitionCache currentTypeDefinitionCache;
/// <summary>
/// Gets/Sets the current type definition that is used to look up identifiers as simple members.
/// Gets the current type definition.
/// </summary>
public ITypeDefinition CurrentTypeDefinition {
get { return context.CurrentTypeDefinition; }
set {
context = context.WithCurrentTypeDefinition(value);
if (value == null) {
currentTypeDefinitionCache = null;
} else {
if (currentTypeDefinitionCache == null || currentTypeDefinitionCache.TypeDefinition != value) {
currentTypeDefinitionCache = new TypeDefinitionCache(value);
}
}
}
}
/// <summary>
/// Sets the current type definition.
/// </summary>
public CSharpResolver WithCurrentTypeDefinition(ITypeDefinition typeDefinition)
{
if (this.CurrentTypeDefinition == typeDefinition)
return this;
TypeDefinitionCache newTypeDefinitionCache;
if (typeDefinition != null)
newTypeDefinitionCache = new TypeDefinitionCache(typeDefinition);
else
newTypeDefinitionCache = null;
return new CSharpResolver(compilation, conversions, context.WithCurrentTypeDefinition(typeDefinition),
checkForOverflow, isWithinLambdaExpression, newTypeDefinitionCache, localVariableStack, objectInitializerStack);
}
sealed class TypeDefinitionCache
@ -151,36 +213,43 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -151,36 +213,43 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
// The beginning of a block is marked by a null entry.
// This data structure is used to allow efficient cloning of the resolver with its local variable context.
ImmutableStack<IVariable> localVariableStack = ImmutableStack<IVariable>.Empty;
readonly ImmutableStack<IVariable> localVariableStack = ImmutableStack<IVariable>.Empty;
CSharpResolver WithLocalVariableStack(ImmutableStack<IVariable> stack)
{
return new CSharpResolver(compilation, conversions, context, checkForOverflow, isWithinLambdaExpression, currentTypeDefinitionCache, stack, objectInitializerStack);
}
/// <summary>
/// Opens a new scope for local variables.
/// </summary>
public void PushBlock()
public CSharpResolver PushBlock()
{
localVariableStack = localVariableStack.Push(null);
return WithLocalVariableStack(localVariableStack.Push(null));
}
/// <summary>
/// Closes the current scope for local variables; removing all variables in that scope.
/// </summary>
public void PopBlock()
public CSharpResolver PopBlock()
{
var stack = localVariableStack;
IVariable removedVar;
do {
removedVar = localVariableStack.Peek();
localVariableStack = localVariableStack.Pop();
removedVar = stack.Peek();
stack = stack.Pop();
} while (removedVar != null);
return WithLocalVariableStack(stack);
}
/// <summary>
/// Adds a new variable or lambda parameter to the current block.
/// </summary>
public void AddVariable(IVariable variable)
public CSharpResolver AddVariable(IVariable variable)
{
if (variable == null)
throw new ArgumentNullException("variable");
localVariableStack = localVariableStack.Push(variable);
return WithLocalVariableStack(localVariableStack.Push(variable));
}
/// <summary>
@ -191,11 +260,6 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -191,11 +260,6 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
return localVariableStack.Where(v => v != null);
}
}
/// <summary>
/// Gets whether the resolver is currently within a lambda expression.
/// </summary>
public bool IsWithinLambdaExpression { get; set; }
#endregion
#region Object Initializer Context
@ -211,23 +275,28 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -211,23 +275,28 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
}
}
ObjectInitializerContext objectInitializerStack;
readonly ObjectInitializerContext objectInitializerStack;
CSharpResolver WithObjectInitializerStack(ObjectInitializerContext stack)
{
return new CSharpResolver(compilation, conversions, context, checkForOverflow, isWithinLambdaExpression, currentTypeDefinitionCache, localVariableStack, stack);
}
/// <summary>
/// Pushes the type of the object that is currently being initialized.
/// </summary>
public void PushInitializerType(IType type)
public CSharpResolver PushInitializerType(IType type)
{
if (type == null)
throw new ArgumentNullException("type");
objectInitializerStack = new ObjectInitializerContext(type, objectInitializerStack);
return WithObjectInitializerStack(new ObjectInitializerContext(type, objectInitializerStack));
}
public void PopInitializerType()
public CSharpResolver PopInitializerType()
{
if (objectInitializerStack == null)
throw new InvalidOperationException();
objectInitializerStack = objectInitializerStack.prev;
return WithObjectInitializerStack(objectInitializerStack.prev);
}
/// <summary>
@ -244,9 +313,10 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -244,9 +313,10 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
/// <summary>
/// Creates a copy of this CSharp resolver.
/// </summary>
[Obsolete("CSharpResolver is immutable, cloning is no longer necessary")]
public CSharpResolver Clone()
{
return (CSharpResolver)MemberwiseClone();
return this;
}
#endregion
@ -1410,7 +1480,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -1410,7 +1480,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
if (mgrr != null) {
Debug.Assert(mgrr.extensionMethods == null);
// set the values that are necessary to make MethodGroupResolveResult.GetExtensionMethods() work
mgrr.resolver = this.Clone();
mgrr.resolver = this;
}
}
return result;

191
ICSharpCode.NRefactory.CSharp/Resolver/ResolveVisitor.cs

@ -97,7 +97,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -97,7 +97,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
{
if (resolver == null)
throw new ArgumentNullException("resolver");
this.resolver = resolver.Clone();
this.resolver = resolver;
this.parsedFile = parsedFile;
this.navigator = navigator ?? new ConstantModeResolveVisitorNavigator(ResolveVisitorNavigationMode.Skip, null);
this.voidResult = new ResolveResult(resolver.Compilation.FindType(KnownTypeCode.Void));
@ -219,7 +219,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -219,7 +219,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
{
// It's possible that we re-visit an expression that we scanned over earlier,
// so we might have to overwrite an existing state.
resolverBeforeDict[node] = resolver.Clone();
resolverBeforeDict[node] = resolver;
}
void StoreResult(AstNode node, ResolveResult result)
@ -383,7 +383,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -383,7 +383,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
AstNode parent;
CSharpResolver storedResolver = GetPreviouslyScannedContext(nodeToResolve, out parent);
ResetContext(
storedResolver.Clone(),
storedResolver,
delegate {
navigator = new NodeListResolveVisitorNavigator(node, nodeToResolve);
if (parent == nodeToResolve) {
@ -442,7 +442,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -442,7 +442,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
AstNode parent;
CSharpResolver storedResolver = GetPreviouslyScannedContext(node, out parent);
ResetContext(
storedResolver.Clone(),
storedResolver,
delegate {
navigator = new NodeListResolveVisitorNavigator(new[] { node }, scanOnly: true);
Debug.Assert(!resolverEnabled);
@ -462,23 +462,23 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -462,23 +462,23 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
#region Track UsingScope
ResolveResult IAstVisitor<object, ResolveResult>.VisitCompilationUnit(CompilationUnit unit, object data)
{
ResolvedUsingScope previousUsingScope = resolver.CurrentUsingScope;
CSharpResolver previousResolver = resolver;
try {
if (parsedFile != null)
resolver.CurrentUsingScope = parsedFile.RootUsingScope.Resolve(resolver.Compilation);
resolver = resolver.WithCurrentUsingScope(parsedFile.RootUsingScope.Resolve(resolver.Compilation));
ScanChildren(unit);
return voidResult;
} finally {
resolver.CurrentUsingScope = previousUsingScope;
resolver = previousResolver;
}
}
ResolveResult IAstVisitor<object, ResolveResult>.VisitNamespaceDeclaration(NamespaceDeclaration namespaceDeclaration, object data)
{
ResolvedUsingScope previousUsingScope = resolver.CurrentUsingScope;
CSharpResolver previousResolver = resolver;
try {
if (parsedFile != null) {
resolver.CurrentUsingScope = parsedFile.GetUsingScope(namespaceDeclaration.StartLocation).Resolve(resolver.Compilation);
resolver = resolver.WithCurrentUsingScope(parsedFile.GetUsingScope(namespaceDeclaration.StartLocation).Resolve(resolver.Compilation));
}
ScanChildren(namespaceDeclaration);
// merge undecided lambdas before leaving the using scope so that
@ -489,7 +489,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -489,7 +489,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
else
return null;
} finally {
resolver.CurrentUsingScope = previousUsingScope;
resolver = previousResolver;
}
}
#endregion
@ -497,7 +497,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -497,7 +497,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
#region Track CurrentTypeDefinition
ResolveResult VisitTypeOrDelegate(AstNode typeDeclaration, string name, int typeParameterCount)
{
ITypeDefinition previousTypeDefinition = resolver.CurrentTypeDefinition;
CSharpResolver previousResolver = resolver;
try {
ITypeDefinition newTypeDefinition = null;
if (resolver.CurrentTypeDefinition != null) {
@ -512,7 +512,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -512,7 +512,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
newTypeDefinition = resolver.CurrentUsingScope.Namespace.GetTypeDefinition(name, typeParameterCount);
}
if (newTypeDefinition != null)
resolver.CurrentTypeDefinition = newTypeDefinition;
resolver = resolver.WithCurrentTypeDefinition(newTypeDefinition);
for (AstNode child = typeDeclaration.FirstChild; child != null; child = child.NextSibling) {
if (child.Role == TypeDeclaration.BaseTypeRole) {
@ -530,7 +530,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -530,7 +530,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
return newTypeDefinition != null ? new TypeResolveResult(newTypeDefinition) : errorResult;
} finally {
resolver.CurrentTypeDefinition = previousTypeDefinition;
resolver = previousResolver;
}
}
@ -564,13 +564,14 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -564,13 +564,14 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
ResolveResult VisitFieldOrEventDeclaration(AttributedNode fieldOrEventDeclaration)
{
//int initializerCount = fieldOrEventDeclaration.GetChildrenByRole(FieldDeclaration.Roles.Variable).Count;
CSharpResolver oldResolver = resolver;
for (AstNode node = fieldOrEventDeclaration.FirstChild; node != null; node = node.NextSibling) {
if (node.Role == FieldDeclaration.Roles.Variable) {
resolver.CurrentMember = GetMemberFromLocation(node.StartLocation);
resolver = resolver.WithCurrentMember(GetMemberFromLocation(node.StartLocation));
Scan(node);
resolver.CurrentMember = null;
resolver = oldResolver;
} else {
Scan(node);
}
@ -643,8 +644,9 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -643,8 +644,9 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
ResolveResult VisitMethodMember(AttributedNode member)
{
CSharpResolver oldResolver = resolver;
try {
resolver.CurrentMember = GetMemberFromLocation(member.StartLocation);
resolver = resolver.WithCurrentMember(GetMemberFromLocation(member.StartLocation));
ScanChildren(member);
@ -653,7 +655,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -653,7 +655,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
else
return errorResult;
} finally {
resolver.CurrentMember = null;
resolver = oldResolver;
}
}
@ -680,15 +682,16 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -680,15 +682,16 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
// handle properties/indexers
ResolveResult VisitPropertyMember(MemberDeclaration propertyOrIndexerDeclaration)
{
CSharpResolver oldResolver = resolver;
try {
resolver.CurrentMember = GetMemberFromLocation(propertyOrIndexerDeclaration.StartLocation);
resolver = resolver.WithCurrentMember(GetMemberFromLocation(propertyOrIndexerDeclaration.StartLocation));
for (AstNode node = propertyOrIndexerDeclaration.FirstChild; node != null; node = node.NextSibling) {
if (node.Role == PropertyDeclaration.SetterRole && resolver.CurrentMember != null) {
resolver.PushBlock();
resolver.AddVariable(new DefaultParameter(resolver.CurrentMember.ReturnType, "value"));
resolver = resolver.PushBlock();
resolver = resolver.AddVariable(new DefaultParameter(resolver.CurrentMember.ReturnType, "value"));
Scan(node);
resolver.PopBlock();
resolver = resolver.PopBlock();
} else {
Scan(node);
}
@ -698,7 +701,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -698,7 +701,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
else
return errorResult;
} finally {
resolver.CurrentMember = null;
resolver = oldResolver;
}
}
@ -714,14 +717,14 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -714,14 +717,14 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
ResolveResult IAstVisitor<object, ResolveResult>.VisitCustomEventDeclaration(CustomEventDeclaration eventDeclaration, object data)
{
CSharpResolver oldResolver = resolver;
try {
resolver.CurrentMember = GetMemberFromLocation(eventDeclaration.StartLocation);
resolver = resolver.WithCurrentMember(GetMemberFromLocation(eventDeclaration.StartLocation));
if (resolver.CurrentMember != null) {
resolver.PushBlock();
resolver.AddVariable(new DefaultParameter(resolver.CurrentMember.ReturnType, "value"));
resolver = resolver.PushBlock();
resolver = resolver.AddVariable(new DefaultParameter(resolver.CurrentMember.ReturnType, "value"));
ScanChildren(eventDeclaration);
resolver.PopBlock();
} else {
ScanChildren(eventDeclaration);
}
@ -731,7 +734,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -731,7 +734,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
else
return errorResult;
} finally {
resolver.CurrentMember = null;
resolver = oldResolver;
}
}
@ -794,6 +797,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -794,6 +797,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
ResolveResult IAstVisitor<object, ResolveResult>.VisitEnumMemberDeclaration(EnumMemberDeclaration enumMemberDeclaration, object data)
{
CSharpResolver oldResolver = resolver;
try {
// Scan enum member attributes before setting resolver.CurrentMember, so that
// enum values used as attribute arguments have the correct type.
@ -801,7 +805,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -801,7 +805,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
foreach (var attributeSection in enumMemberDeclaration.Attributes)
Scan(attributeSection);
resolver.CurrentMember = GetMemberFromLocation(enumMemberDeclaration.StartLocation);
resolver = resolver.WithCurrentMember(GetMemberFromLocation(enumMemberDeclaration.StartLocation));
if (resolverEnabled && resolver.CurrentTypeDefinition != null) {
ResolveAndProcessConversion(enumMemberDeclaration.Initializer, resolver.CurrentTypeDefinition.EnumUnderlyingType);
@ -814,7 +818,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -814,7 +818,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
return errorResult;
}
} finally {
resolver.CurrentMember = null;
resolver = oldResolver;
}
}
#endregion
@ -822,9 +826,9 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -822,9 +826,9 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
#region Track CheckForOverflow
ResolveResult IAstVisitor<object, ResolveResult>.VisitCheckedExpression(CheckedExpression checkedExpression, object data)
{
bool oldCheckForOverflow = resolver.CheckForOverflow;
CSharpResolver oldResolver = resolver;
try {
resolver.CheckForOverflow = true;
resolver = resolver.WithCheckForOverflow(true);
if (resolverEnabled) {
return Resolve(checkedExpression.Expression);
} else {
@ -832,15 +836,15 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -832,15 +836,15 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
return null;
}
} finally {
resolver.CheckForOverflow = oldCheckForOverflow;
resolver = oldResolver;
}
}
ResolveResult IAstVisitor<object, ResolveResult>.VisitUncheckedExpression(UncheckedExpression uncheckedExpression, object data)
{
bool oldCheckForOverflow = resolver.CheckForOverflow;
CSharpResolver oldResolver = resolver;
try {
resolver.CheckForOverflow = false;
resolver = resolver.WithCheckForOverflow(false);
if (resolverEnabled) {
return Resolve(uncheckedExpression.Expression);
} else {
@ -848,31 +852,31 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -848,31 +852,31 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
return null;
}
} finally {
resolver.CheckForOverflow = oldCheckForOverflow;
resolver = oldResolver;
}
}
ResolveResult IAstVisitor<object, ResolveResult>.VisitCheckedStatement(CheckedStatement checkedStatement, object data)
{
bool oldCheckForOverflow = resolver.CheckForOverflow;
CSharpResolver oldResolver = resolver;
try {
resolver.CheckForOverflow = true;
resolver = resolver.WithCheckForOverflow(true);
ScanChildren(checkedStatement);
return voidResult;
} finally {
resolver.CheckForOverflow = oldCheckForOverflow;
resolver = oldResolver;
}
}
ResolveResult IAstVisitor<object, ResolveResult>.VisitUncheckedStatement(UncheckedStatement uncheckedStatement, object data)
{
bool oldCheckForOverflow = resolver.CheckForOverflow;
CSharpResolver oldResolver = resolver;
try {
resolver.CheckForOverflow = false;
resolver = resolver.WithCheckForOverflow(false);
ScanChildren(uncheckedStatement);
return voidResult;
} finally {
resolver.CheckForOverflow = oldCheckForOverflow;
resolver = oldResolver;
}
}
#endregion
@ -910,7 +914,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -910,7 +914,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
var property = new DefaultUnresolvedProperty {
Name = name,
Accessibility = Accessibility.Public,
ReturnType = new VarTypeReference(this, resolver.Clone(), resolveExpr),
ReturnType = new VarTypeReference(this, resolver, resolveExpr),
Getter = DefaultUnresolvedAccessor.GetFromAccessibility(Accessibility.Public)
};
properties.Add(property);
@ -1261,7 +1265,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -1261,7 +1265,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
void HandleObjectInitializer(IType type, ArrayInitializerExpression initializer)
{
StoreCurrentState(initializer);
resolver.PushInitializerType(type);
resolver = resolver.PushInitializerType(type);
foreach (Expression element in initializer.Elements) {
ArrayInitializerExpression aie = element as ArrayInitializerExpression;
if (aie != null) {
@ -1294,7 +1298,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -1294,7 +1298,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
Scan(element);
}
}
resolver.PopInitializerType();
resolver = resolver.PopInitializerType();
if (!resolveResultCache.ContainsKey(initializer))
StoreResult(initializer, voidResult);
}
@ -1673,10 +1677,10 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -1673,10 +1677,10 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
AstNodeCollection<ParameterDeclaration> parameterDeclarations,
AstNode body, bool isAnonymousMethod, bool hasParameterList, bool isAsync)
{
CSharpResolver oldResolver = resolver;
List<IParameter> parameters = (hasParameterList || parameterDeclarations.Any()) ? new List<IParameter>() : null;
resolver.PushBlock();
bool oldIsWithinLambdaExpression = resolver.IsWithinLambdaExpression;
resolver.IsWithinLambdaExpression = true;
resolver = resolver.WithIsWithinLambdaExpression(true);
foreach (var pd in parameterDeclarations) {
IType type = ResolveType(pd.Type);
if (pd.ParameterModifier == ParameterModifier.Ref || pd.ParameterModifier == ParameterModifier.Out)
@ -1685,17 +1689,16 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -1685,17 +1689,16 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
IParameter p = new DefaultParameter(type, pd.Name, MakeRegion(pd),
isRef: pd.ParameterModifier == ParameterModifier.Ref,
isOut: pd.ParameterModifier == ParameterModifier.Out);
resolver.AddVariable(p);
resolver = resolver.AddVariable(p);
parameters.Add(p);
Scan(pd);
}
var lambda = new ExplicitlyTypedLambda(parameters, isAnonymousMethod, isAsync, resolver.Clone(), this, body);
var lambda = new ExplicitlyTypedLambda(parameters, isAnonymousMethod, isAsync, resolver, this, body);
// Don't scan the lambda body here - we'll do that later when analyzing the ExplicitlyTypedLambda.
resolver.PopBlock();
resolver.IsWithinLambdaExpression = oldIsWithinLambdaExpression;
resolver = oldResolver;
return lambda;
}
@ -1907,7 +1910,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -1907,7 +1910,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
private ImplicitlyTypedLambda(ResolveVisitor parentVisitor)
{
this.parentVisitor = parentVisitor;
this.storedContext = parentVisitor.resolver.Clone();
this.storedContext = parentVisitor.resolver;
this.parsedFile = parentVisitor.parsedFile;
this.bodyResult = parentVisitor.voidResult;
}
@ -1976,7 +1979,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -1976,7 +1979,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
return h;
}
var resolveAll = new ConstantModeResolveVisitorNavigator(ResolveVisitorNavigationMode.Resolve, null);
ResolveVisitor visitor = new ResolveVisitor(storedContext.Clone(), parsedFile, resolveAll);
ResolveVisitor visitor = new ResolveVisitor(storedContext, parsedFile, resolveAll);
var newHypothesis = new LambdaTypeHypothesis(this, parameterTypes, visitor, lambda != null ? lambda.Parameters : null);
hypotheses.Add(newHypothesis);
return newHypothesis;
@ -2073,15 +2076,14 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -2073,15 +2076,14 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
Log.WriteLine("Analyzing " + ToString() + "...");
Log.Indent();
bool oldInsideLambda = visitor.resolver.IsWithinLambdaExpression;
visitor.resolver.PushBlock();
visitor.resolver.IsWithinLambdaExpression = true;
CSharpResolver oldResolver = visitor.resolver;
visitor.resolver = visitor.resolver.WithIsWithinLambdaExpression(true);
lambdaParameters = new IParameter[parameterTypes.Length];
if (parameterDeclarations != null) {
int i = 0;
foreach (var pd in parameterDeclarations) {
lambdaParameters[i] = new DefaultParameter(parameterTypes[i], pd.Name, visitor.MakeRegion(pd));
visitor.resolver.AddVariable(lambdaParameters[i]);
visitor.resolver = visitor.resolver.AddVariable(lambdaParameters[i]);
i++;
visitor.Scan(pd);
}
@ -2089,13 +2091,12 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -2089,13 +2091,12 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
for (int i = 0; i < parameterTypes.Length; i++) {
var p = lambda.Parameters[i];
lambdaParameters[i] = new DefaultParameter(parameterTypes[i], p.Name, p.Region);
visitor.resolver.AddVariable(lambdaParameters[i]);
visitor.resolver = visitor.resolver.AddVariable(lambdaParameters[i]);
}
}
visitor.AnalyzeLambda(lambda.BodyExpression, lambda.IsAsync, out success, out isValidAsVoidMethod, out inferredReturnType, out returnExpressions, out returnValues);
visitor.resolver.PopBlock();
visitor.resolver.IsWithinLambdaExpression = false;
visitor.resolver = oldResolver;
Log.Unindent();
Log.WriteLine("Finished analyzing " + ToString());
}
@ -2200,7 +2201,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -2200,7 +2201,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
if (parent != null && resolverBeforeDict.TryGetValue(parent, out storedResolver)) {
Log.WriteLine("Trying to resolve '" + parent + "' in order to merge the lambda...");
Log.Indent();
ResetContext(storedResolver.Clone(), delegate { Resolve(parent); });
ResetContext(storedResolver, delegate { Resolve(parent); });
Log.Unindent();
} else {
Log.WriteLine("Could not find a suitable parent for '" + lambda);
@ -2392,15 +2393,15 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -2392,15 +2393,15 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
#region Local Variable Scopes (Block Statements)
ResolveResult IAstVisitor<object, ResolveResult>.VisitBlockStatement(BlockStatement blockStatement, object data)
{
resolver.PushBlock();
resolver = resolver.PushBlock();
ScanChildren(blockStatement);
resolver.PopBlock();
resolver = resolver.PopBlock();
return voidResult;
}
ResolveResult IAstVisitor<object, ResolveResult>.VisitUsingStatement(UsingStatement usingStatement, object data)
{
resolver.PushBlock();
resolver = resolver.PushBlock();
if (resolverEnabled) {
for (AstNode child = usingStatement.FirstChild; child != null; child = child.NextSibling) {
if (child.Role == UsingStatement.ResourceAcquisitionRole && child is Expression) {
@ -2412,28 +2413,28 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -2412,28 +2413,28 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
} else {
ScanChildren(usingStatement);
}
resolver.PopBlock();
resolver = resolver.PopBlock();
return voidResult;
}
ResolveResult IAstVisitor<object, ResolveResult>.VisitFixedStatement(FixedStatement fixedStatement, object data)
{
resolver.PushBlock();
resolver = resolver.PushBlock();
AstType type = fixedStatement.Type;
for (AstNode node = fixedStatement.FirstChild; node != null; node = node.NextSibling) {
if (node.Role == FixedStatement.Roles.Variable) {
VariableInitializer vi = (VariableInitializer)node;
resolver.AddVariable(MakeVariable(type, vi.NameToken));
resolver = resolver.AddVariable(MakeVariable(type, vi.NameToken));
}
Scan(node);
}
resolver.PopBlock();
resolver = resolver.PopBlock();
return voidResult;
}
ResolveResult IAstVisitor<object, ResolveResult>.VisitForeachStatement(ForeachStatement foreachStatement, object data)
{
resolver.PushBlock();
resolver = resolver.PushBlock();
IVariable v;
if (IsVar(foreachStatement.VariableType)) {
if (navigator.Scan(foreachStatement.VariableType) == ResolveVisitorNavigationMode.Resolve) {
@ -2451,33 +2452,33 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -2451,33 +2452,33 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
v = MakeVariable(foreachStatement.VariableType, foreachStatement.VariableNameToken);
}
StoreCurrentState(foreachStatement.VariableNameToken);
resolver.AddVariable(v);
resolver = resolver.AddVariable(v);
StoreResult(foreachStatement.VariableNameToken, new LocalResolveResult(v));
Scan(foreachStatement.EmbeddedStatement);
resolver.PopBlock();
resolver = resolver.PopBlock();
return voidResult;
}
ResolveResult IAstVisitor<object, ResolveResult>.VisitSwitchStatement(SwitchStatement switchStatement, object data)
{
resolver.PushBlock();
resolver = resolver.PushBlock();
ScanChildren(switchStatement);
resolver.PopBlock();
resolver = resolver.PopBlock();
return voidResult;
}
ResolveResult IAstVisitor<object, ResolveResult>.VisitCatchClause(CatchClause catchClause, object data)
{
resolver.PushBlock();
resolver = resolver.PushBlock();
if (!string.IsNullOrEmpty(catchClause.VariableName)) {
DomRegion region = MakeRegion(catchClause.VariableNameToken);
StoreCurrentState(catchClause.VariableNameToken);
IVariable v = MakeVariable(catchClause.Type, catchClause.VariableNameToken);
resolver.AddVariable(v);
resolver = resolver.AddVariable(v);
StoreResult(catchClause.VariableNameToken, new LocalResolveResult(v));
}
ScanChildren(catchClause);
resolver.PopBlock();
resolver = resolver.PopBlock();
return voidResult;
}
#endregion
@ -2504,7 +2505,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -2504,7 +2505,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
v = MakeImplicitlyTypedVariable(vi.NameToken, vi.Initializer, false);
}
StoreCurrentState(vi);
resolver.AddVariable(v);
resolver = resolver.AddVariable(v);
if (needResolve) {
ResolveResult result;
if (!resolveResultCache.TryGetValue(vi, out result)) {
@ -2519,9 +2520,9 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -2519,9 +2520,9 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
VariableInitializer vi = (VariableInitializer)node;
if (isConst) {
resolver.AddVariable(MakeConstant(type, vi.NameToken, vi.Initializer));
resolver = resolver.AddVariable(MakeConstant(type, vi.NameToken, vi.Initializer));
} else {
resolver.AddVariable(MakeVariable(type, vi.NameToken));
resolver = resolver.AddVariable(MakeVariable(type, vi.NameToken));
}
}
Scan(node);
@ -2534,9 +2535,9 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -2534,9 +2535,9 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
#region Condition Statements
ResolveResult IAstVisitor<object, ResolveResult>.VisitForStatement(ForStatement forStatement, object data)
{
resolver.PushBlock();
resolver = resolver.PushBlock();
HandleConditionStatement(forStatement);
resolver.PopBlock();
resolver = resolver.PopBlock();
return voidResult;
}
@ -2690,17 +2691,17 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -2690,17 +2691,17 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
IVariable MakeVariable(AstType type, Identifier variableName)
{
return new ExplicitlyTypedVariable(this, resolver.Clone(), MakeRegion(variableName), type, variableName.Name, null);
return new ExplicitlyTypedVariable(this, resolver, MakeRegion(variableName), type, variableName.Name, null);
}
IVariable MakeConstant(AstType type, Identifier variableName, Expression initializer)
{
return new ExplicitlyTypedVariable(this, resolver.Clone(), MakeRegion(variableName), type, variableName.Name, initializer);
return new ExplicitlyTypedVariable(this, resolver, MakeRegion(variableName), type, variableName.Name, initializer);
}
IVariable MakeImplicitlyTypedVariable(Identifier variableName, Expression initializer, bool isForEach)
{
return new ImplicitlyTypedVariable(this, resolver.Clone(), MakeRegion(variableName), variableName.Name, initializer, isForEach);
return new ImplicitlyTypedVariable(this, resolver, MakeRegion(variableName), variableName.Name, initializer, isForEach);
}
sealed class SimpleVariable : IVariable
@ -3005,10 +3006,10 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -3005,10 +3006,10 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
var nonConstructorArguments = attribute.Arguments.Where(a => a is NamedExpression);
// Scan the non-constructor arguments
resolver.PushInitializerType(type);
resolver = resolver.PushInitializerType(type);
foreach (var arg in nonConstructorArguments)
Scan(arg);
resolver.PopInitializerType();
resolver = resolver.PopInitializerType();
if (resolverEnabled) {
// Resolve the ctor arguments and find the matching ctor overload
@ -3141,7 +3142,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -3141,7 +3142,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
#region Query Expressions
ResolveResult IAstVisitor<object, ResolveResult>.VisitQueryExpression(QueryExpression queryExpression, object data)
{
resolver.PushBlock();
resolver = resolver.PushBlock();
ResolveResult oldQueryResult = currentQueryResult;
try {
currentQueryResult = null;
@ -3151,7 +3152,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -3151,7 +3152,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
return currentQueryResult;
} finally {
currentQueryResult = oldQueryResult;
resolver.PopBlock();
resolver = resolver.PopBlock();
}
}
@ -3259,7 +3260,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -3259,7 +3260,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
}
StoreCurrentState(queryFromClause.IdentifierToken);
resolver.AddVariable(v);
resolver = resolver.AddVariable(v);
StoreResult(queryFromClause.IdentifierToken, new LocalResolveResult(v));
if (resolverEnabled && currentQueryResult != null) {
@ -3289,7 +3290,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -3289,7 +3290,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
IType variableType = GetTypeForQueryVariable(rr.Type);
StoreCurrentState(queryContinuationClause.IdentifierToken);
IVariable v = MakeVariable(variableType, queryContinuationClause.IdentifierToken);
resolver.AddVariable(v);
resolver = resolver.AddVariable(v);
StoreResult(queryContinuationClause.IdentifierToken, new LocalResolveResult(v));
return rr;
}
@ -3299,7 +3300,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -3299,7 +3300,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
ResolveResult expr = Resolve(queryLetClause.Expression);
StoreCurrentState(queryLetClause.IdentifierToken);
IVariable v = MakeVariable(expr.Type, queryLetClause.IdentifierToken);
resolver.AddVariable(v);
resolver = resolver.AddVariable(v);
StoreResult(queryLetClause.IdentifierToken, new LocalResolveResult(v));
if (resolverEnabled && currentQueryResult != null) {
// resolve the .Select() call
@ -3334,10 +3335,10 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -3334,10 +3335,10 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
ResolveResult onResult = Resolve(queryJoinClause.OnExpression);
// scan the 'Equals' expression in a context that contains only the variable 'v'
CSharpResolver resolverOutsideQuery = resolver.Clone();
resolverOutsideQuery.PopBlock(); // pop all variables from the current query expression
CSharpResolver resolverOutsideQuery = resolver;
resolverOutsideQuery = resolverOutsideQuery.PopBlock(); // pop all variables from the current query expression
IVariable v = MakeVariable(variableType, queryJoinClause.JoinIdentifierToken);
resolverOutsideQuery.AddVariable(v);
resolverOutsideQuery = resolverOutsideQuery.AddVariable(v);
ResolveResult equalsResult = errorResult;
ResetContext(resolverOutsideQuery, delegate {
equalsResult = Resolve(queryJoinClause.EqualsExpression);
@ -3348,7 +3349,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -3348,7 +3349,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
if (queryJoinClause.IsGroupJoin) {
return ResolveGroupJoin(queryJoinClause, inResult, onResult, equalsResult);
} else {
resolver.AddVariable(v);
resolver = resolver.AddVariable(v);
if (resolverEnabled && currentQueryResult != null) {
QuerySelectClause selectClause = GetNextQueryClause(queryJoinClause) as QuerySelectClause;
ResolveResult selectResult;
@ -3451,7 +3452,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -3451,7 +3452,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
StoreCurrentState(queryJoinClause.IntoIdentifierToken);
groupVariable = MakeVariable(groupParameterType, queryJoinClause.IntoIdentifierToken);
resolver.AddVariable(groupVariable);
resolver = resolver.AddVariable(groupVariable);
}
if (groupVariable != null) {

8
ICSharpCode.NRefactory.CSharp/TypeSystem/ConstantValues.cs

@ -432,13 +432,7 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem.ConstantValues @@ -432,13 +432,7 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem.ConstantValues
public override ResolveResult Resolve(CSharpResolver resolver)
{
bool oldCheckForOverflow = resolver.CheckForOverflow;
try {
resolver.CheckForOverflow = this.checkForOverflow;
return expression.Resolve(resolver);
} finally {
resolver.CheckForOverflow = oldCheckForOverflow;
}
return expression.Resolve(resolver.WithCheckForOverflow(checkForOverflow));
}
void ISupportsInterning.PrepareForInterning(IInterningProvider provider)

4
ICSharpCode.NRefactory.Tests/CSharp/CodeDomConvertVisitorTests.cs

@ -51,8 +51,8 @@ namespace ICSharpCode.NRefactory.CSharp @@ -51,8 +51,8 @@ namespace ICSharpCode.NRefactory.CSharp
string Convert(Expression expr)
{
CSharpResolver resolver = new CSharpResolver(compilation);
resolver.CurrentUsingScope = parsedFile.RootUsingScope.Resolve(compilation);
resolver.CurrentTypeDefinition = compilation.FindType(KnownTypeCode.Object).GetDefinition();
resolver = resolver.WithCurrentUsingScope(parsedFile.RootUsingScope.Resolve(compilation));
resolver = resolver.WithCurrentTypeDefinition(compilation.FindType(KnownTypeCode.Object).GetDefinition());
var codeExpr = (CodeExpression)convertVisitor.Convert(expr, new CSharpAstResolver(resolver, expr, parsedFile));
StringWriter writer = new StringWriter();

7
ICSharpCode.NRefactory.Tests/CSharp/Refactoring/TypeSystemAstBuilderTests.cs

@ -78,11 +78,8 @@ namespace OtherNS { @@ -78,11 +78,8 @@ namespace OtherNS {
TypeSystemAstBuilder CreateBuilder(ITypeDefinition currentTypeDef = null)
{
UsingScope usingScope = currentTypeDef != null ? parsedFile.GetUsingScope(currentTypeDef.Region.Begin) : parsedFile.RootUsingScope;
return new TypeSystemAstBuilder(
new CSharpResolver(compilation) {
CurrentUsingScope = usingScope.Resolve(compilation),
CurrentTypeDefinition = currentTypeDef
});
return new TypeSystemAstBuilder(new CSharpResolver(
new CSharpTypeResolveContext(compilation.MainAssembly, usingScope.Resolve(compilation), currentTypeDef)));
}
string TypeToString(IType type, ITypeDefinition currentTypeDef = null)

6
ICSharpCode.NRefactory.Tests/CSharp/Resolver/BinaryOperatorTests.cs

@ -152,12 +152,10 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -152,12 +152,10 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
[Test]
public void AdditionWithOverflow()
{
resolver.CheckForOverflow = false;
AssertConstant(int.MinValue, resolver.ResolveBinaryOperator(
AssertConstant(int.MinValue, resolver.WithCheckForOverflow(false).ResolveBinaryOperator(
BinaryOperatorType.Add, MakeConstant(int.MaxValue), MakeConstant(1)));
resolver.CheckForOverflow = true;
AssertError(typeof(int), resolver.ResolveBinaryOperator(
AssertError(typeof(int), resolver.WithCheckForOverflow(true).ResolveBinaryOperator(
BinaryOperatorType.Add, MakeConstant(int.MaxValue), MakeConstant(1)));
}

9
ICSharpCode.NRefactory.Tests/CSharp/Resolver/CastTests.cs

@ -81,10 +81,8 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -81,10 +81,8 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
[Test]
public void OverflowingCast()
{
resolver.CheckForOverflow = false;
AssertConstant(uint.MaxValue, resolver.ResolveCast(ResolveType(typeof(uint)), MakeConstant(-1.6)));
resolver.CheckForOverflow = true;
AssertError(typeof(uint), resolver.ResolveCast(ResolveType(typeof(uint)), MakeConstant(-1.6)));
AssertConstant(uint.MaxValue, resolver.WithCheckForOverflow(false).ResolveCast(ResolveType(typeof(uint)), MakeConstant(-1.6)));
AssertError(typeof(uint), resolver.WithCheckForOverflow(true).ResolveCast(ResolveType(typeof(uint)), MakeConstant(-1.6)));
}
[Test]
@ -96,8 +94,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -96,8 +94,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
[Test]
public void OverflowingCastToEnum()
{
resolver.CheckForOverflow = true;
AssertError(typeof(StringComparison), resolver.ResolveCast(ResolveType(typeof(StringComparison)), MakeConstant(long.MaxValue)));
AssertError(typeof(StringComparison), resolver.WithCheckForOverflow(true).ResolveCast(ResolveType(typeof(StringComparison)), MakeConstant(long.MaxValue)));
}
}
}

60
ICSharpCode.NRefactory.Tests/CSharp/Resolver/NameLookupTests.cs

@ -36,8 +36,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -36,8 +36,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
public override void SetUp()
{
base.SetUp();
resolver = new CSharpResolver(compilation);
resolver.CurrentUsingScope = MakeUsingScope(string.Empty);
resolver = new CSharpResolver(compilation).WithCurrentUsingScope(MakeUsingScope(string.Empty));
}
ResolvedUsingScope MakeUsingScope(string namespaceName = "", string[] usings = null, KeyValuePair<string, string>[] usingAliases = null)
@ -56,15 +55,14 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -56,15 +55,14 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
foreach (var pair in usingAliases)
usingScope.UsingAliases.Add(new KeyValuePair<string, TypeOrNamespaceReference>(pair.Key, MakeReference(pair.Value)));
}
return usingScope.Resolve(resolver.Compilation);
return usingScope.Resolve(compilation);
}
[Test]
public void SimpleNameLookupWithoutContext()
{
// nothing should be found without specifying any UsingScope - however, the resolver also must not crash
resolver.CurrentUsingScope = null;
Assert.IsTrue(resolver.ResolveSimpleName("System", new IType[0]).IsError);
Assert.IsTrue(resolver.WithCurrentUsingScope(null).ResolveSimpleName("System", new IType[0]).IsError);
}
[Test]
@ -78,23 +76,23 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -78,23 +76,23 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
[Test]
public void NamespaceInParentNamespaceLookup()
{
resolver.CurrentUsingScope = MakeUsingScope("System.Collections.Generic");
NamespaceResolveResult nrr = (NamespaceResolveResult)resolver.ResolveSimpleName("Text", new IType[0]);
var resolverWithUsing = resolver.WithCurrentUsingScope(MakeUsingScope("System.Collections.Generic"));
NamespaceResolveResult nrr = (NamespaceResolveResult)resolverWithUsing.ResolveSimpleName("Text", new IType[0]);
Assert.AreEqual("System.Text", nrr.NamespaceName);
}
[Test]
public void NamespacesAreNotImported()
{
resolver.CurrentUsingScope = MakeUsingScope(usings: new [] { "System" });
Assert.IsTrue(resolver.ResolveSimpleName("Collections", new IType[0]).IsError);
var resolverWithUsing = resolver.WithCurrentUsingScope(MakeUsingScope(usings: new [] { "System" }));
Assert.IsTrue(resolverWithUsing.ResolveSimpleName("Collections", new IType[0]).IsError);
}
[Test]
public void ImportedType()
{
resolver.CurrentUsingScope = MakeUsingScope(usings: new [] { "System" });
TypeResolveResult trr = (TypeResolveResult)resolver.ResolveSimpleName("String", new IType[0]);
var resolverWithUsing = resolver.WithCurrentUsingScope(MakeUsingScope(usings: new [] { "System" }));
TypeResolveResult trr = (TypeResolveResult)resolverWithUsing.ResolveSimpleName("String", new IType[0]);
Assert.AreEqual("System.String", trr.Type.FullName);
}
@ -122,8 +120,8 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -122,8 +120,8 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
[Test]
public void AliasToImportedType()
{
resolver.CurrentUsingScope = MakeUsingScope(usings: new [] { "System" }, usingAliases: new [] { new KeyValuePair<string, string>( "x", "String" )});
UnknownIdentifierResolveResult rr = (UnknownIdentifierResolveResult)resolver.ResolveSimpleName("x", new IType[0]);
var resolverWithUsing = resolver.WithCurrentUsingScope(MakeUsingScope(usings: new [] { "System" }, usingAliases: new [] { new KeyValuePair<string, string>( "x", "String" )}));
UnknownIdentifierResolveResult rr = (UnknownIdentifierResolveResult)resolverWithUsing.ResolveSimpleName("x", new IType[0]);
// Unknown identifier (as String isn't looked up in System)
Assert.AreEqual("String", rr.Identifier);
}
@ -135,24 +133,24 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -135,24 +133,24 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
mainUsingScope.Usings.Add(MakeReference("System"));
UsingScope nestedUsingScope = new UsingScope(mainUsingScope, "SomeNamespace");
nestedUsingScope.UsingAliases.Add(new KeyValuePair<string, TypeOrNamespaceReference>("x", MakeReference("String")));
resolver.CurrentUsingScope = nestedUsingScope.Resolve(compilation);
var resolverWithUsing = resolver.WithCurrentUsingScope(nestedUsingScope.Resolve(compilation));
TypeResolveResult trr = (TypeResolveResult)resolver.ResolveSimpleName("x", new IType[0]);
TypeResolveResult trr = (TypeResolveResult)resolverWithUsing.ResolveSimpleName("x", new IType[0]);
Assert.AreEqual("System.String", trr.Type.FullName);
}
[Test]
public void AliasOperatorOnTypeAlias()
{
resolver.CurrentUsingScope = MakeUsingScope(usingAliases: new [] { new KeyValuePair<string, string>( "x", "System.String" )});
Assert.IsTrue(resolver.ResolveAlias("x").IsError);
var resolverWithUsing = resolver.WithCurrentUsingScope(MakeUsingScope(usingAliases: new [] { new KeyValuePair<string, string>( "x", "System.String" )}));
Assert.IsTrue(resolverWithUsing.ResolveAlias("x").IsError);
}
[Test]
public void AliasOperatorOnNamespaceAlias()
{
resolver.CurrentUsingScope = MakeUsingScope(usingAliases: new [] { new KeyValuePair<string, string>( "x", "System.Collections.Generic" )});
NamespaceResolveResult nrr = (NamespaceResolveResult)resolver.ResolveAlias("x");
var resolverWithUsing = resolver.WithCurrentUsingScope(MakeUsingScope(usingAliases: new [] { new KeyValuePair<string, string>( "x", "System.Collections.Generic" )}));
NamespaceResolveResult nrr = (NamespaceResolveResult)resolverWithUsing.ResolveAlias("x");
Assert.AreEqual("System.Collections.Generic", nrr.NamespaceName);
}
@ -165,32 +163,34 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -165,32 +163,34 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
[Test]
public void FindClassInCurrentNamespace()
{
resolver.CurrentUsingScope = MakeUsingScope("System.Collections");
TypeResolveResult trr = (TypeResolveResult)resolver.ResolveSimpleName("String", new IType[0]);
var resolverWithUsing = resolver.WithCurrentUsingScope(MakeUsingScope("System.Collections"));
TypeResolveResult trr = (TypeResolveResult)resolverWithUsing.ResolveSimpleName("String", new IType[0]);
Assert.AreEqual("System.String", trr.Type.FullName);
}
[Test]
public void FindNeighborNamespace()
{
resolver.CurrentUsingScope = MakeUsingScope("System.Collections");
NamespaceResolveResult nrr = (NamespaceResolveResult)resolver.ResolveSimpleName("Text", new IType[0]);
var resolverWithUsing = resolver.WithCurrentUsingScope(MakeUsingScope("System.Collections"));
NamespaceResolveResult nrr = (NamespaceResolveResult)resolverWithUsing.ResolveSimpleName("Text", new IType[0]);
Assert.AreEqual("System.Text", nrr.NamespaceName);
}
[Test]
public void FindTypeParameters()
{
resolver.CurrentUsingScope = MakeUsingScope("System.Collections.Generic");
resolver.CurrentTypeDefinition = compilation.FindType(typeof(List<>)).GetDefinition();
resolver.CurrentMember = resolver.CurrentTypeDefinition.Methods.Single(m => m.Name == "ConvertAll");
var listOfT = compilation.FindType(typeof(List<>)).GetDefinition();
var resolverWithContext = resolver
.WithCurrentUsingScope(MakeUsingScope("System.Collections.Generic"))
.WithCurrentTypeDefinition(listOfT)
.WithCurrentMember(listOfT.Methods.Single(m => m.Name == "ConvertAll"));
TypeResolveResult trr;
trr = (TypeResolveResult)resolver.ResolveSimpleName("TOutput", new IType[0]);
Assert.AreSame(((IMethod)resolver.CurrentMember).TypeParameters[0], trr.Type);
trr = (TypeResolveResult)resolverWithContext.ResolveSimpleName("TOutput", new IType[0]);
Assert.AreSame(((IMethod)resolverWithContext.CurrentMember).TypeParameters[0], trr.Type);
trr = (TypeResolveResult)resolver.ResolveSimpleName("T", new IType[0]);
Assert.AreSame(resolver.CurrentTypeDefinition.TypeParameters[0], trr.Type);
trr = (TypeResolveResult)resolverWithContext.ResolveSimpleName("T", new IType[0]);
Assert.AreSame(resolverWithContext.CurrentTypeDefinition.TypeParameters[0], trr.Type);
}
[Test]

3
ICSharpCode.NRefactory.Tests/CSharp/Resolver/UnaryOperatorTests.cs

@ -141,8 +141,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -141,8 +141,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
[Test]
public void TestUnaryMinusCheckedOverflow()
{
resolver.CheckForOverflow = true;
AssertError(typeof(int), resolver.ResolveUnaryOperator(UnaryOperatorType.Minus, MakeConstant(-2147483648)));
AssertError(typeof(int), resolver.WithCheckForOverflow(true).ResolveUnaryOperator(UnaryOperatorType.Minus, MakeConstant(-2147483648)));
}
[Test]

Loading…
Cancel
Save